mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
Add RSPI support for RZ/T2H and RZ/N2H
Merge series from Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>: Add support for RZ/T2H and RZ/N2H.
This commit is contained in:
7
.mailmap
7
.mailmap
@@ -206,6 +206,7 @@ Danilo Krummrich <dakr@kernel.org> <dakr@redhat.com>
|
||||
David Brownell <david-b@pacbell.net>
|
||||
David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org>
|
||||
David Heidelberg <david@ixit.cz> <d.okias@gmail.com>
|
||||
David Hildenbrand <david@kernel.org> <david@redhat.com>
|
||||
David Rheinsberg <david@readahead.eu> <dh.herrmann@gmail.com>
|
||||
David Rheinsberg <david@readahead.eu> <dh.herrmann@googlemail.com>
|
||||
David Rheinsberg <david@readahead.eu> <david.rheinsberg@gmail.com>
|
||||
@@ -426,7 +427,7 @@ Kenneth W Chen <kenneth.w.chen@intel.com>
|
||||
Kenneth Westfield <quic_kwestfie@quicinc.com> <kwestfie@codeaurora.org>
|
||||
Kiran Gunda <quic_kgunda@quicinc.com> <kgunda@codeaurora.org>
|
||||
Kirill Tkhai <tkhai@ya.ru> <ktkhai@virtuozzo.com>
|
||||
Kirill A. Shutemov <kas@kernel.org> <kirill.shutemov@linux.intel.com>
|
||||
Kiryl Shutsemau <kas@kernel.org> <kirill.shutemov@linux.intel.com>
|
||||
Kishon Vijay Abraham I <kishon@kernel.org> <kishon@ti.com>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@linaro.org>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@somainline.org>
|
||||
@@ -437,6 +438,7 @@ Krishna Manikandan <quic_mkrishn@quicinc.com> <mkrishn@codeaurora.org>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@linaro.org>
|
||||
Krzysztof Wilczyński <kwilczynski@kernel.org> <krzysztof.wilczynski@linux.com>
|
||||
Krzysztof Wilczyński <kwilczynski@kernel.org> <kw@linux.com>
|
||||
Kshitiz Godara <quic_kgodara@quicinc.com> <kgodara@codeaurora.org>
|
||||
@@ -605,7 +607,8 @@ Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
Oleksij Rempel <o.rempel@pengutronix.de> <ore@pengutronix.de>
|
||||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver.hartkopp@volkswagen.de>
|
||||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
|
||||
Oliver Upton <oliver.upton@linux.dev> <oupton@google.com>
|
||||
Oliver Upton <oupton@kernel.org> <oupton@google.com>
|
||||
Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev>
|
||||
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>
|
||||
|
||||
@@ -50,18 +50,20 @@ patternProperties:
|
||||
groups:
|
||||
description:
|
||||
Name of the pin group to use for the functions.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp,
|
||||
i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp,
|
||||
spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp,
|
||||
spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp,
|
||||
uart0_grp, uart1_grp, uart2_grp, uart3_grp,
|
||||
pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp,
|
||||
pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp,
|
||||
pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp,
|
||||
pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp,
|
||||
pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp,
|
||||
pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp]
|
||||
items:
|
||||
enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp,
|
||||
i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp,
|
||||
spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp,
|
||||
spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp,
|
||||
uart0_grp, uart1_grp, uart2_grp, uart3_grp,
|
||||
pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp,
|
||||
pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp,
|
||||
pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp,
|
||||
pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp,
|
||||
pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp,
|
||||
pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp]
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
|
||||
drive-strength:
|
||||
enum: [2, 4, 6, 8, 16, 24, 32]
|
||||
|
||||
@@ -74,6 +74,7 @@ patternProperties:
|
||||
|
||||
'^conf':
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Pinctrl node's client devices use subnodes for pin configurations,
|
||||
which in turn use the standard properties below.
|
||||
|
||||
@@ -9,12 +9,15 @@ title: Renesas RZ/V2H(P) Renesas Serial Peripheral Interface (RSPI)
|
||||
maintainers:
|
||||
- Fabrizio Castro <fabrizio.castro.jz@renesas.com>
|
||||
|
||||
allOf:
|
||||
- $ref: spi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a09g057-rspi # RZ/V2H(P)
|
||||
oneOf:
|
||||
- enum:
|
||||
- renesas,r9a09g057-rspi # RZ/V2H(P)
|
||||
- renesas,r9a09g077-rspi # RZ/T2H
|
||||
- items:
|
||||
- const: renesas,r9a09g087-rspi # RZ/N2H
|
||||
- const: renesas,r9a09g077-rspi # RZ/T2H
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -36,13 +39,12 @@ properties:
|
||||
- const: tx
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: pclk_sfr
|
||||
- const: tclk
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
@@ -62,12 +64,52 @@ required:
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
allOf:
|
||||
- $ref: spi-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r9a09g057-rspi
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: pclk_sfr
|
||||
- const: tclk
|
||||
|
||||
required:
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r9a09g077-rspi
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: pclkspi
|
||||
|
||||
resets: false
|
||||
reset-names: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -400,19 +400,30 @@ can report through the rotational axes (absolute and/or relative rx, ry, rz).
|
||||
All other axes retain their meaning. A device must not mix
|
||||
regular directional axes and accelerometer axes on the same event node.
|
||||
|
||||
INPUT_PROP_HAPTIC_TOUCHPAD
|
||||
--------------------------
|
||||
INPUT_PROP_PRESSUREPAD
|
||||
----------------------
|
||||
|
||||
The INPUT_PROP_PRESSUREPAD property indicates that the device provides
|
||||
simulated haptic feedback (e.g. a vibrator motor situated below the surface)
|
||||
instead of physical haptic feedback (e.g. a hinge). This property is only set
|
||||
if the device:
|
||||
|
||||
The INPUT_PROP_HAPTIC_TOUCHPAD property indicates that device:
|
||||
- supports simple haptic auto and manual triggering
|
||||
- can differentiate between at least 5 fingers
|
||||
- uses correct resolution for the X/Y (units and value)
|
||||
- reports correct force per touch, and correct units for them (newtons or grams)
|
||||
- follows the MT protocol type B
|
||||
|
||||
If the simulated haptic feedback is controllable by userspace the device must:
|
||||
|
||||
- support simple haptic auto and manual triggering, and
|
||||
- report correct force per touch, and correct units for them (newtons or grams), and
|
||||
- provide the EV_FF FF_HAPTIC force feedback effect.
|
||||
|
||||
Summing up, such devices follow the MS spec for input devices in
|
||||
Win8 and Win8.1, and in addition support the Simple haptic controller HID table,
|
||||
and report correct units for the pressure.
|
||||
Win8 and Win8.1, and in addition may support the Simple haptic controller HID
|
||||
table, and report correct units for the pressure.
|
||||
|
||||
Where applicable, this property is set in addition to INPUT_PROP_BUTTONPAD, it
|
||||
does not replace that property.
|
||||
|
||||
Guidelines
|
||||
==========
|
||||
|
||||
@@ -105,10 +105,10 @@ In this example the SSID is 10280c63.
|
||||
|
||||
The format of the firmware file names is:
|
||||
|
||||
SoundWire (except CS35L56 Rev B0):
|
||||
SoundWire:
|
||||
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-l?u?
|
||||
|
||||
SoundWire CS35L56 Rev B0:
|
||||
SoundWire CS35L56 Rev B0 firmware released before kernel version 6.16:
|
||||
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN
|
||||
|
||||
Non-SoundWire (HDA and I2S):
|
||||
@@ -127,9 +127,8 @@ Where:
|
||||
* spkidX is an optional part, used for laptops that have firmware
|
||||
configurations for different makes and models of internal speakers.
|
||||
|
||||
The CS35L56 Rev B0 continues to use the old filename scheme because a
|
||||
large number of firmware files have already been published with these
|
||||
names.
|
||||
Early firmware for CS35L56 Rev B0 used the ALSA prefix (ampN) as the
|
||||
filename qualifier. Support for the l?u? qualifier was added in kernel 6.16.
|
||||
|
||||
Sound Open Firmware and ALSA topology files
|
||||
-------------------------------------------
|
||||
|
||||
@@ -13,10 +13,10 @@ Simple CLI
|
||||
Kernel comes with a simple CLI tool which should be useful when
|
||||
developing Netlink related code. The tool is implemented in Python
|
||||
and can use a YAML specification to issue Netlink requests
|
||||
to the kernel. Only Generic Netlink is supported.
|
||||
to the kernel.
|
||||
|
||||
The tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts
|
||||
a handul of arguments, the most important ones are:
|
||||
a handful of arguments, the most important ones are:
|
||||
|
||||
- ``--spec`` - point to the spec file
|
||||
- ``--do $name`` / ``--dump $name`` - issue request ``$name``
|
||||
|
||||
@@ -54,6 +54,7 @@ to matching WMI devices using a struct wmi_device_id table:
|
||||
::
|
||||
|
||||
static const struct wmi_device_id foo_id_table[] = {
|
||||
/* Only use uppercase letters! */
|
||||
{ "936DA01F-9ABD-4D9D-80C7-02AF85C822A8", NULL },
|
||||
{ }
|
||||
};
|
||||
|
||||
65
MAINTAINERS
65
MAINTAINERS
@@ -915,6 +915,7 @@ F: drivers/staging/media/sunxi/cedrus/
|
||||
ALPHA PORT
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
M: Matt Turner <mattst88@gmail.com>
|
||||
M: Magnus Lindholm <linmag7@gmail.com>
|
||||
L: linux-alpha@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
F: arch/alpha/
|
||||
@@ -3925,7 +3926,7 @@ F: crypto/async_tx/
|
||||
F: include/linux/async_tx.h
|
||||
|
||||
AT24 EEPROM DRIVER
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
|
||||
@@ -4398,7 +4399,7 @@ BLOCK LAYER
|
||||
M: Jens Axboe <axboe@kernel.dk>
|
||||
L: linux-block@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git
|
||||
F: Documentation/ABI/stable/sysfs-block
|
||||
F: Documentation/block/
|
||||
F: block/
|
||||
@@ -9208,6 +9209,7 @@ R: Yue Hu <zbestahu@gmail.com>
|
||||
R: Jeffle Xu <jefflexu@linux.alibaba.com>
|
||||
R: Sandeep Dhavale <dhavale@google.com>
|
||||
R: Hongbo Li <lihongbo22@huawei.com>
|
||||
R: Chunhai Guo <guochunhai@vivo.com>
|
||||
L: linux-erofs@lists.ozlabs.org
|
||||
S: Maintained
|
||||
W: https://erofs.docs.kernel.org
|
||||
@@ -9264,7 +9266,6 @@ M: Ido Schimmel <idosch@nvidia.com>
|
||||
L: bridge@lists.linux.dev
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.linuxfoundation.org/en/Net:Bridge
|
||||
F: include/linux/if_bridge.h
|
||||
F: include/uapi/linux/if_bridge.h
|
||||
F: include/linux/netfilter_bridge/
|
||||
@@ -10677,7 +10678,7 @@ F: tools/gpio/gpio-sloppy-logic-analyzer.sh
|
||||
|
||||
GPIO SUBSYSTEM
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
|
||||
@@ -10694,7 +10695,7 @@ K: GPIOD_FLAGS_BIT_NONEXCLUSIVE
|
||||
K: devm_gpiod_unhinge
|
||||
|
||||
GPIO UAPI
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
R: Kent Gibson <warthog618@gmail.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
@@ -11526,7 +11527,7 @@ F: include/linux/platform_data/huawei-gaokun-ec.h
|
||||
HUGETLB SUBSYSTEM
|
||||
M: Muchun Song <muchun.song@linux.dev>
|
||||
M: Oscar Salvador <osalvador@suse.de>
|
||||
R: David Hildenbrand <david@redhat.com>
|
||||
R: David Hildenbrand <david@kernel.org>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages
|
||||
@@ -13659,7 +13660,7 @@ F: virt/kvm/*
|
||||
|
||||
KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
|
||||
M: Marc Zyngier <maz@kernel.org>
|
||||
M: Oliver Upton <oliver.upton@linux.dev>
|
||||
M: Oliver Upton <oupton@kernel.org>
|
||||
R: Joey Gouly <joey.gouly@arm.com>
|
||||
R: Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
R: Zenghui Yu <yuzenghui@huawei.com>
|
||||
@@ -13733,7 +13734,7 @@ KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Janosch Frank <frankja@linux.ibm.com>
|
||||
M: Claudio Imbrenda <imbrenda@linux.ibm.com>
|
||||
R: David Hildenbrand <david@redhat.com>
|
||||
R: David Hildenbrand <david@kernel.org>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git
|
||||
@@ -15308,7 +15309,7 @@ F: drivers/pwm/pwm-max7360.c
|
||||
F: include/linux/mfd/max7360.h
|
||||
|
||||
MAXIM MAX77650 PMIC MFD DRIVER
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/*/*max77650.yaml
|
||||
@@ -16204,7 +16205,7 @@ MEMORY CONTROLLER DRIVERS
|
||||
M: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
B: mailto:krzysztof.kozlowski@linaro.org
|
||||
B: mailto:krzk@kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
|
||||
F: Documentation/devicetree/bindings/memory-controllers/
|
||||
F: drivers/memory/
|
||||
@@ -16220,7 +16221,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
|
||||
F: drivers/devfreq/tegra30-devfreq.c
|
||||
|
||||
MEMORY HOT(UN)PLUG
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Oscar Salvador <osalvador@suse.de>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
@@ -16245,7 +16246,7 @@ F: tools/mm/
|
||||
|
||||
MEMORY MANAGEMENT - CORE
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
@@ -16301,7 +16302,7 @@ F: mm/execmem.c
|
||||
|
||||
MEMORY MANAGEMENT - GUP (GET USER PAGES)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Jason Gunthorpe <jgg@nvidia.com>
|
||||
R: John Hubbard <jhubbard@nvidia.com>
|
||||
R: Peter Xu <peterx@redhat.com>
|
||||
@@ -16317,7 +16318,7 @@ F: tools/testing/selftests/mm/gup_test.c
|
||||
|
||||
MEMORY MANAGEMENT - KSM (Kernel Samepage Merging)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Xu Xin <xu.xin16@zte.com.cn>
|
||||
R: Chengming Zhou <chengming.zhou@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
@@ -16333,7 +16334,7 @@ F: mm/mm_slot.h
|
||||
|
||||
MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
R: Matthew Brost <matthew.brost@intel.com>
|
||||
R: Joshua Hahn <joshua.hahnjy@gmail.com>
|
||||
@@ -16373,7 +16374,7 @@ F: mm/workingset.c
|
||||
|
||||
MEMORY MANAGEMENT - MISC
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
@@ -16461,7 +16462,7 @@ F: mm/shuffle.h
|
||||
MEMORY MANAGEMENT - RECLAIM
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Johannes Weiner <hannes@cmpxchg.org>
|
||||
R: David Hildenbrand <david@redhat.com>
|
||||
R: David Hildenbrand <david@kernel.org>
|
||||
R: Michal Hocko <mhocko@kernel.org>
|
||||
R: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
@@ -16474,7 +16475,7 @@ F: mm/workingset.c
|
||||
|
||||
MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Rik van Riel <riel@surriel.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
@@ -16498,12 +16499,12 @@ F: mm/secretmem.c
|
||||
|
||||
MEMORY MANAGEMENT - SWAP
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Chris Li <chrisl@kernel.org>
|
||||
M: Kairui Song <kasong@tencent.com>
|
||||
R: Kemeng Shi <shikemeng@huaweicloud.com>
|
||||
R: Kairui Song <kasong@tencent.com>
|
||||
R: Nhat Pham <nphamcs@gmail.com>
|
||||
R: Baoquan He <bhe@redhat.com>
|
||||
R: Barry Song <baohua@kernel.org>
|
||||
R: Chris Li <chrisl@kernel.org>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: Documentation/mm/swap-table.rst
|
||||
@@ -16519,7 +16520,7 @@ F: mm/swapfile.c
|
||||
|
||||
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
||||
@@ -16621,7 +16622,7 @@ MEMORY MAPPING - MADVISE (MEMORY ADVICE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
L: linux-mm@kvack.org
|
||||
@@ -18779,6 +18780,10 @@ S: Maintained
|
||||
F: arch/arm/*omap*/*clock*
|
||||
|
||||
OMAP DEVICE TREE SUPPORT
|
||||
M: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
M: Andreas Kemnade <andreas@kemnade.info>
|
||||
M: Kevin Hilman <khilman@baylibre.com>
|
||||
M: Roger Quadros <rogerq@kernel.org>
|
||||
M: Tony Lindgren <tony@atomide.com>
|
||||
L: linux-omap@vger.kernel.org
|
||||
L: devicetree@vger.kernel.org
|
||||
@@ -19898,7 +19903,7 @@ F: drivers/pci/p2pdma.c
|
||||
F: include/linux/pci-p2pdma.h
|
||||
|
||||
PCI POWER CONTROL
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
|
||||
@@ -20495,7 +20500,7 @@ F: include/linux/powercap.h
|
||||
F: kernel/configs/nopm.config
|
||||
|
||||
POWER SEQUENCING
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
|
||||
@@ -21177,7 +21182,7 @@ F: Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
|
||||
F: drivers/i2c/busses/i2c-qcom-cci.c
|
||||
|
||||
QUALCOMM INTERCONNECT BWMON DRIVER
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
M: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
|
||||
@@ -21298,7 +21303,7 @@ F: Documentation/tee/qtee.rst
|
||||
F: drivers/tee/qcomtee/
|
||||
|
||||
QUALCOMM TRUST ZONE MEMORY ALLOCATOR
|
||||
M: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/firmware/qcom/qcom_tzmem.c
|
||||
@@ -25667,7 +25672,7 @@ F: Documentation/devicetree/bindings/crypto/ti,am62l-dthev2.yaml
|
||||
F: drivers/crypto/ti/
|
||||
|
||||
TI DAVINCI MACHINE SUPPORT
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
|
||||
@@ -27089,7 +27094,7 @@ F: net/vmw_vsock/virtio_transport_common.c
|
||||
|
||||
VIRTIO BALLOON
|
||||
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
L: virtualization@lists.linux.dev
|
||||
S: Maintained
|
||||
F: drivers/virtio/virtio_balloon.c
|
||||
@@ -27244,7 +27249,7 @@ F: drivers/iommu/virtio-iommu.c
|
||||
F: include/uapi/linux/virtio_iommu.h
|
||||
|
||||
VIRTIO MEM DRIVER
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
L: virtualization@lists.linux.dev
|
||||
S: Maintained
|
||||
W: https://virtio-mem.gitlab.io/
|
||||
@@ -27850,7 +27855,7 @@ F: arch/x86/kernel/stacktrace.c
|
||||
F: arch/x86/kernel/unwind_*.c
|
||||
|
||||
X86 TRUST DOMAIN EXTENSIONS (TDX)
|
||||
M: Kirill A. Shutemov <kas@kernel.org>
|
||||
M: Kiryl Shutsemau <kas@kernel.org>
|
||||
R: Dave Hansen <dave.hansen@linux.intel.com>
|
||||
R: Rick Edgecombe <rick.p.edgecombe@intel.com>
|
||||
L: x86@kernel.org
|
||||
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -1254,3 +1254,17 @@ &emmc {
|
||||
max-frequency = <25000000>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: rgmii delay is introduced by MAC (configured in u-boot now)
|
||||
* instead of PCB on fuji board, so the "phy-mode" should be updated to
|
||||
* "rgmii-[tx|rx]id" when the aspeed-mac driver can handle the delay
|
||||
* properly.
|
||||
*/
|
||||
&mac3 {
|
||||
status = "okay";
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <ðphy3>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_rgmii4_default>;
|
||||
};
|
||||
|
||||
@@ -55,8 +55,8 @@ &gmac0 {
|
||||
mdio {
|
||||
/delete-node/ switch@1e;
|
||||
|
||||
bcm54210e: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
bcm54210e: ethernet-phy@25 {
|
||||
reg = <25>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -259,7 +259,7 @@ &audmux {
|
||||
pinctrl-0 = <&pinctrl_audmux>;
|
||||
status = "okay";
|
||||
|
||||
ssi2 {
|
||||
mux-ssi2 {
|
||||
fsl,audmux-port = <1>;
|
||||
fsl,port-config = <
|
||||
(IMX_AUDMUX_V2_PTCR_SYN |
|
||||
@@ -271,7 +271,7 @@ IMX_AUDMUX_V2_PDCR_RXDSEL(2)
|
||||
>;
|
||||
};
|
||||
|
||||
aud3 {
|
||||
mux-aud3 {
|
||||
fsl,audmux-port = <2>;
|
||||
fsl,port-config = <
|
||||
IMX_AUDMUX_V2_PTCR_SYN
|
||||
|
||||
@@ -136,7 +136,7 @@ touchscreen: touchscreen@38 {
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
|
||||
reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
|
||||
report-rate-hz = <6>;
|
||||
report-rate-hz = <60>;
|
||||
/* settings valid only for Hycon touchscreen */
|
||||
touchscreen-size-x = <1280>;
|
||||
touchscreen-size-y = <800>;
|
||||
|
||||
@@ -18,11 +18,21 @@
|
||||
|
||||
#include "bcm2712-rpi-5-b-ovl-rp1.dts"
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
ethernet0 = &rp1_eth;
|
||||
};
|
||||
};
|
||||
|
||||
&pcie2 {
|
||||
#include "rp1-nexus.dtsi"
|
||||
};
|
||||
|
||||
&rp1_eth {
|
||||
assigned-clocks = <&rp1_clocks RP1_CLK_ETH_TSU>,
|
||||
<&rp1_clocks RP1_CLK_ETH>;
|
||||
assigned-clock-rates = <50000000>,
|
||||
<125000000>;
|
||||
status = "okay";
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <&phy1>;
|
||||
|
||||
@@ -67,7 +67,6 @@ irqsteer_csi0: irqsteer@58220000 {
|
||||
power-domains = <&pd IMX_SC_R_CSI_0>;
|
||||
fsl,channel = <0>;
|
||||
fsl,num-irqs = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio0_mipi_csi0: gpio@58222000 {
|
||||
@@ -144,7 +143,6 @@ irqsteer_csi1: irqsteer@58240000 {
|
||||
power-domains = <&pd IMX_SC_R_CSI_1>;
|
||||
fsl,channel = <0>;
|
||||
fsl,num-irqs = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio0_mipi_csi1: gpio@58242000 {
|
||||
|
||||
@@ -16,11 +16,20 @@ aliases {
|
||||
ethernet1 = &eqos;
|
||||
};
|
||||
|
||||
extcon_usbc: usbc {
|
||||
compatible = "linux,extcon-usb-gpio";
|
||||
connector {
|
||||
compatible = "gpio-usb-b-connector", "usb-b-connector";
|
||||
id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
|
||||
label = "Type-C";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usb1_id>;
|
||||
id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
|
||||
type = "micro";
|
||||
vbus-supply = <®_usb1_vbus>;
|
||||
|
||||
port {
|
||||
usb_dr_connector: endpoint {
|
||||
remote-endpoint = <&usb3_dwc>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
@@ -244,9 +253,15 @@ &usb_dwc3_0 {
|
||||
hnp-disable;
|
||||
srp-disable;
|
||||
dr_mode = "otg";
|
||||
extcon = <&extcon_usbc>;
|
||||
usb-role-switch;
|
||||
role-switch-default-mode = "peripheral";
|
||||
status = "okay";
|
||||
|
||||
port {
|
||||
usb3_dwc: endpoint {
|
||||
remote-endpoint = <&usb_dr_connector>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&usb_dwc3_1 {
|
||||
@@ -273,7 +288,6 @@ &usb3_1 {
|
||||
};
|
||||
|
||||
&usb3_phy0 {
|
||||
vbus-supply = <®_usb1_vbus>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -1886,7 +1886,7 @@ pcie0_ep: pcie-ep@4c300000 {
|
||||
assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
|
||||
assigned-clock-parents = <0>, <0>,
|
||||
<&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
|
||||
msi-map = <0x0 &its 0x98 0x1>;
|
||||
msi-map = <0x0 &its 0x10 0x1>;
|
||||
power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -1963,6 +1963,7 @@ pcie1_ep: pcie-ep@4c380000 {
|
||||
assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
|
||||
assigned-clock-parents = <0>, <0>,
|
||||
<&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
|
||||
msi-map = <0x0 &its 0x98 0x1>;
|
||||
power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@ phy: ethernet-phy@0 {
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA194_MAIN_GPIO(G, 4) IRQ_TYPE_LEVEL_LOW>;
|
||||
#phy-cells = <0>;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -598,7 +598,6 @@ tsadc: tsadc@ff250000 {
|
||||
pinctrl-2 = <&otp_pin>;
|
||||
resets = <&cru SRST_TSADC>;
|
||||
reset-names = "tsadc-apb";
|
||||
rockchip,grf = <&grf>;
|
||||
rockchip,hw-tshut-temp = <100000>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
status = "disabled";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include "rk3399.dtsi"
|
||||
#include "rk3399-base.dtsi"
|
||||
|
||||
/ {
|
||||
cluster0_opp: opp-table-0 {
|
||||
|
||||
@@ -45,11 +45,11 @@ cam_avdd_2v8: regulator-cam-avdd-2v8 {
|
||||
|
||||
cam_dovdd_1v8: regulator-cam-dovdd-1v8 {
|
||||
compatible = "regulator-fixed";
|
||||
gpio = <&pca9670 3 GPIO_ACTIVE_LOW>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-name = "cam-dovdd-1v8";
|
||||
vin-supply = <&vcc1v8_video>;
|
||||
gpio = <&pca9670 3 GPIO_ACTIVE_LOW>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-name = "cam-dovdd-1v8";
|
||||
vin-supply = <&vcc1v8_video>;
|
||||
};
|
||||
|
||||
cam_dvdd_1v2: regulator-cam-dvdd-1v2 {
|
||||
|
||||
@@ -120,7 +120,7 @@ vcc3v3_pcie: regulator-vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
enable-active-high;
|
||||
gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie_drv>;
|
||||
regulator-always-on;
|
||||
@@ -187,7 +187,7 @@ vcc5v0_usb: regulator-vcc5v0-usb {
|
||||
vcc5v0_usb2b: regulator-vcc5v0-usb2b {
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
|
||||
gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vcc5v0_usb2b_en>;
|
||||
regulator-name = "vcc5v0_usb2b";
|
||||
@@ -199,7 +199,7 @@ vcc5v0_usb2b: regulator-vcc5v0-usb2b {
|
||||
vcc5v0_usb2t: regulator-vcc5v0-usb2t {
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vcc5v0_usb2t_en>;
|
||||
regulator-name = "vcc5v0_usb2t";
|
||||
|
||||
@@ -789,7 +789,7 @@ &pmu_io_domains {
|
||||
vccio1-supply = <&vccio_acodec>;
|
||||
vccio2-supply = <&vcc_1v8>;
|
||||
vccio3-supply = <&vccio_sd>;
|
||||
vccio4-supply = <&vcc_1v8>;
|
||||
vccio4-supply = <&vcca1v8_pmu>;
|
||||
vccio5-supply = <&vcc_1v8>;
|
||||
vccio6-supply = <&vcc1v8_dvp>;
|
||||
vccio7-supply = <&vcc_3v3>;
|
||||
|
||||
@@ -482,6 +482,8 @@ &i2s0_8ch {
|
||||
};
|
||||
|
||||
&i2s1_8ch {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
|
||||
rockchip,trcm-sync-tx-only;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -276,12 +276,6 @@ opp-2016000000 {
|
||||
opp-microvolt = <900000 900000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
|
||||
opp-2208000000 {
|
||||
opp-hz = /bits/ 64 <2208000000>;
|
||||
opp-microvolt = <950000 950000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
};
|
||||
|
||||
cluster1_opp_table: opp-table-cluster1 {
|
||||
@@ -348,12 +342,6 @@ opp-2208000000 {
|
||||
opp-microvolt = <925000 925000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
|
||||
opp-2304000000 {
|
||||
opp-hz = /bits/ 64 <2304000000>;
|
||||
opp-microvolt = <950000 950000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
};
|
||||
|
||||
gpu_opp_table: opp-table-gpu {
|
||||
@@ -2561,8 +2549,6 @@ i2c9: i2c@2ae80000 {
|
||||
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c9m0_xfer>;
|
||||
resets = <&cru SRST_I2C9>, <&cru SRST_P_I2C9>;
|
||||
reset-names = "i2c", "apb";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
@@ -115,7 +115,7 @@ opp-2400000000 {
|
||||
};
|
||||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
gpu_opp_table: opp-table-gpu {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-300000000 {
|
||||
|
||||
@@ -382,14 +382,12 @@ &sdhci {
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
mmc-pwrseq = <&emmc_pwrseq>;
|
||||
no-sdio;
|
||||
no-sd;
|
||||
non-removable;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
|
||||
pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk>;
|
||||
vmmc-supply = <&vcc_3v3_s3>;
|
||||
vqmmc-supply = <&vcc_1v8_s3>;
|
||||
status = "okay";
|
||||
|
||||
@@ -66,7 +66,7 @@ opp-1608000000 {
|
||||
};
|
||||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
gpu_opp_table: opp-table-gpu {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-300000000 {
|
||||
|
||||
@@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 {
|
||||
gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
regulator-name = "vcc3v3_pcie20";
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
startup-delay-us = <50000>;
|
||||
vin-supply = <&vcc5v0_sys>;
|
||||
};
|
||||
|
||||
@@ -1341,7 +1341,7 @@ CONFIG_COMMON_CLK_RS9_PCIE=y
|
||||
CONFIG_COMMON_CLK_VC3=y
|
||||
CONFIG_COMMON_CLK_VC5=y
|
||||
CONFIG_COMMON_CLK_BD718XX=m
|
||||
CONFIG_CLK_RASPBERRYPI=m
|
||||
CONFIG_CLK_RASPBERRYPI=y
|
||||
CONFIG_CLK_IMX8MM=y
|
||||
CONFIG_CLK_IMX8MN=y
|
||||
CONFIG_CLK_IMX8MP=y
|
||||
|
||||
@@ -26,9 +26,12 @@ void __init apply_alternatives_all(void);
|
||||
bool alternative_is_applied(u16 cpucap);
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
void apply_alternatives_module(void *start, size_t length);
|
||||
int apply_alternatives_module(void *start, size_t length);
|
||||
#else
|
||||
static inline void apply_alternatives_module(void *start, size_t length) { }
|
||||
static inline int apply_alternatives_module(void *start, size_t length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void alt_cb_patch_nops(struct alt_instr *alt, __le32 *origptr,
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
static inline bool arch_kfence_init_pool(void) { return true; }
|
||||
|
||||
static inline bool kfence_protect_page(unsigned long addr, bool protect)
|
||||
{
|
||||
set_memory_valid(addr, 1, !protect);
|
||||
@@ -25,6 +23,7 @@ static inline bool arm64_kfence_can_set_direct_map(void)
|
||||
{
|
||||
return !kfence_early_init;
|
||||
}
|
||||
bool arch_kfence_init_pool(void);
|
||||
#else /* CONFIG_KFENCE */
|
||||
static inline bool arm64_kfence_can_set_direct_map(void) { return false; }
|
||||
#endif /* CONFIG_KFENCE */
|
||||
|
||||
@@ -33,8 +33,8 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||
unsigned long vaddr);
|
||||
#define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
|
||||
|
||||
void tag_clear_highpage(struct page *to);
|
||||
#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGE
|
||||
bool tag_clear_highpages(struct page *to, int numpages);
|
||||
#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
||||
|
||||
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||
|
||||
@@ -77,7 +77,7 @@ __percpu_##name##_case_##sz(void *ptr, unsigned long val) \
|
||||
" stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n" \
|
||||
" cbnz %w[loop], 1b", \
|
||||
/* LSE atomics */ \
|
||||
#op_lse "\t%" #w "[val], %[ptr]\n" \
|
||||
#op_lse "\t%" #w "[val], %" #w "[tmp], %[ptr]\n" \
|
||||
__nops(3)) \
|
||||
: [loop] "=&r" (loop), [tmp] "=&r" (tmp), \
|
||||
[ptr] "+Q"(*(u##sz *)ptr) \
|
||||
@@ -124,9 +124,16 @@ PERCPU_RW_OPS(8)
|
||||
PERCPU_RW_OPS(16)
|
||||
PERCPU_RW_OPS(32)
|
||||
PERCPU_RW_OPS(64)
|
||||
PERCPU_OP(add, add, stadd)
|
||||
PERCPU_OP(andnot, bic, stclr)
|
||||
PERCPU_OP(or, orr, stset)
|
||||
|
||||
/*
|
||||
* Use value-returning atomics for CPU-local ops as they are more likely
|
||||
* to execute "near" to the CPU (e.g. in L1$).
|
||||
*
|
||||
* https://lore.kernel.org/r/e7d539ed-ced0-4b96-8ecd-048a5b803b85@paulmck-laptop
|
||||
*/
|
||||
PERCPU_OP(add, add, ldadd)
|
||||
PERCPU_OP(andnot, bic, ldclr)
|
||||
PERCPU_OP(or, orr, ldset)
|
||||
PERCPU_RET_OP(add, add, ldadd)
|
||||
|
||||
#undef PERCPU_RW_OPS
|
||||
|
||||
@@ -53,7 +53,7 @@ enum {
|
||||
EDYNSCS_INVALID_CFA_OPCODE = 4,
|
||||
};
|
||||
|
||||
int __pi_scs_patch(const u8 eh_frame[], int size);
|
||||
int __pi_scs_patch(const u8 eh_frame[], int size, bool skip_dry_run);
|
||||
|
||||
#endif /* __ASSEMBLY __ */
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ void spectre_bhb_patch_wa3(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr, int nr_inst);
|
||||
void spectre_bhb_patch_clearbhb(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr, int nr_inst);
|
||||
void spectre_print_disabled_mitigations(void);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASM_SPECTRE_H */
|
||||
|
||||
@@ -197,8 +197,6 @@ static int __init acpi_fadt_sanity_check(void)
|
||||
*/
|
||||
void __init acpi_boot_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Enable ACPI instead of device tree unless
|
||||
* - ACPI has been disabled explicitly (acpi=off), or
|
||||
@@ -252,12 +250,8 @@ void __init acpi_boot_table_init(void)
|
||||
* behaviour, use acpi=nospcr to disable console in ACPI SPCR
|
||||
* table as default serial console.
|
||||
*/
|
||||
ret = acpi_parse_spcr(earlycon_acpi_spcr_enable,
|
||||
acpi_parse_spcr(earlycon_acpi_spcr_enable,
|
||||
!param_acpi_nospcr);
|
||||
if (!ret || param_acpi_nospcr || !IS_ENABLED(CONFIG_ACPI_SPCR_TABLE))
|
||||
pr_info("Use ACPI SPCR as default console: No\n");
|
||||
else
|
||||
pr_info("Use ACPI SPCR as default console: Yes\n");
|
||||
|
||||
if (IS_ENABLED(CONFIG_ACPI_BGRT))
|
||||
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
|
||||
|
||||
@@ -139,9 +139,9 @@ static noinstr void clean_dcache_range_nopatch(u64 start, u64 end)
|
||||
} while (cur += d_size, cur < end);
|
||||
}
|
||||
|
||||
static void __apply_alternatives(const struct alt_region *region,
|
||||
bool is_module,
|
||||
unsigned long *cpucap_mask)
|
||||
static int __apply_alternatives(const struct alt_region *region,
|
||||
bool is_module,
|
||||
unsigned long *cpucap_mask)
|
||||
{
|
||||
struct alt_instr *alt;
|
||||
__le32 *origptr, *updptr;
|
||||
@@ -166,10 +166,13 @@ static void __apply_alternatives(const struct alt_region *region,
|
||||
updptr = is_module ? origptr : lm_alias(origptr);
|
||||
nr_inst = alt->orig_len / AARCH64_INSN_SIZE;
|
||||
|
||||
if (ALT_HAS_CB(alt))
|
||||
if (ALT_HAS_CB(alt)) {
|
||||
alt_cb = ALT_REPL_PTR(alt);
|
||||
else
|
||||
if (is_module && !core_kernel_text((unsigned long)alt_cb))
|
||||
return -ENOEXEC;
|
||||
} else {
|
||||
alt_cb = patch_alternative;
|
||||
}
|
||||
|
||||
alt_cb(alt, origptr, updptr, nr_inst);
|
||||
|
||||
@@ -193,6 +196,8 @@ static void __apply_alternatives(const struct alt_region *region,
|
||||
bitmap_and(applied_alternatives, applied_alternatives,
|
||||
system_cpucaps, ARM64_NCAPS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init apply_alternatives_vdso(void)
|
||||
@@ -277,7 +282,7 @@ void __init apply_boot_alternatives(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
void apply_alternatives_module(void *start, size_t length)
|
||||
int apply_alternatives_module(void *start, size_t length)
|
||||
{
|
||||
struct alt_region region = {
|
||||
.begin = start,
|
||||
@@ -287,7 +292,7 @@ void apply_alternatives_module(void *start, size_t length)
|
||||
|
||||
bitmap_fill(all_capabilities, ARM64_NCAPS);
|
||||
|
||||
__apply_alternatives(®ion, true, &all_capabilities[0]);
|
||||
return __apply_alternatives(®ion, true, &all_capabilities[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#include <asm/vectors.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
#include <asm/spectre.h>
|
||||
/* Kernel representation of AT_HWCAP and AT_HWCAP2 */
|
||||
static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly;
|
||||
|
||||
@@ -3875,6 +3876,11 @@ static void __init setup_system_capabilities(void)
|
||||
*/
|
||||
if (system_uses_ttbr0_pan())
|
||||
pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
|
||||
|
||||
/*
|
||||
* Report Spectre mitigations status.
|
||||
*/
|
||||
spectre_print_disabled_mitigations();
|
||||
}
|
||||
|
||||
void __init setup_system_features(void)
|
||||
|
||||
@@ -489,16 +489,29 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
int ret;
|
||||
|
||||
s = find_section(hdr, sechdrs, ".altinstructions");
|
||||
if (s)
|
||||
apply_alternatives_module((void *)s->sh_addr, s->sh_size);
|
||||
if (s) {
|
||||
ret = apply_alternatives_module((void *)s->sh_addr, s->sh_size);
|
||||
if (ret < 0) {
|
||||
pr_err("module %s: error occurred when applying alternatives\n", me->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (scs_is_dynamic()) {
|
||||
s = find_section(hdr, sechdrs, ".init.eh_frame");
|
||||
if (s) {
|
||||
ret = __pi_scs_patch((void *)s->sh_addr, s->sh_size);
|
||||
if (ret)
|
||||
/*
|
||||
* Because we can reject modules that are malformed
|
||||
* so SCS patching fails, skip dry run and try to patch
|
||||
* it in place. If patching fails, the module would not
|
||||
* be loaded anyway.
|
||||
*/
|
||||
ret = __pi_scs_patch((void *)s->sh_addr, s->sh_size, true);
|
||||
if (ret) {
|
||||
pr_err("module %s: error occurred during dynamic SCS patching (%d)\n",
|
||||
me->name, ret);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -476,7 +476,8 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
|
||||
|
||||
folio = page_folio(page);
|
||||
if (folio_test_hugetlb(folio))
|
||||
WARN_ON_ONCE(!folio_test_hugetlb_mte_tagged(folio));
|
||||
WARN_ON_ONCE(!folio_test_hugetlb_mte_tagged(folio) &&
|
||||
!is_huge_zero_folio(folio));
|
||||
else
|
||||
WARN_ON_ONCE(!page_mte_tagged(page) && !is_zero_page(page));
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
|
||||
|
||||
if (enable_scs) {
|
||||
scs_patch(__eh_frame_start + va_offset,
|
||||
__eh_frame_end - __eh_frame_start);
|
||||
__eh_frame_end - __eh_frame_start, false);
|
||||
asm("ic ialluis");
|
||||
|
||||
dynamic_scs_is_enabled = true;
|
||||
|
||||
@@ -225,7 +225,7 @@ static int scs_handle_fde_frame(const struct eh_frame *frame,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scs_patch(const u8 eh_frame[], int size)
|
||||
int scs_patch(const u8 eh_frame[], int size, bool skip_dry_run)
|
||||
{
|
||||
int code_alignment_factor = 1;
|
||||
bool fde_use_sdata8 = false;
|
||||
@@ -277,11 +277,13 @@ int scs_patch(const u8 eh_frame[], int size)
|
||||
}
|
||||
} else {
|
||||
ret = scs_handle_fde_frame(frame, code_alignment_factor,
|
||||
fde_use_sdata8, true);
|
||||
fde_use_sdata8, !skip_dry_run);
|
||||
if (ret)
|
||||
return ret;
|
||||
scs_handle_fde_frame(frame, code_alignment_factor,
|
||||
fde_use_sdata8, false);
|
||||
|
||||
if (!skip_dry_run)
|
||||
scs_handle_fde_frame(frame, code_alignment_factor,
|
||||
fde_use_sdata8, false);
|
||||
}
|
||||
|
||||
p += sizeof(frame->size) + frame->size;
|
||||
|
||||
@@ -27,7 +27,7 @@ extern pgd_t init_pg_dir[], init_pg_end[];
|
||||
void init_feature_override(u64 boot_status, const void *fdt, int chosen);
|
||||
u64 kaslr_early_init(void *fdt, int chosen);
|
||||
void relocate_kernel(u64 offset);
|
||||
int scs_patch(const u8 eh_frame[], int size);
|
||||
int scs_patch(const u8 eh_frame[], int size, bool skip_dry_run);
|
||||
|
||||
void map_range(phys_addr_t *pte, u64 start, u64 end, phys_addr_t pa,
|
||||
pgprot_t prot, int level, pte_t *tbl, bool may_use_cont,
|
||||
|
||||
@@ -49,7 +49,10 @@ void *alloc_insn_page(void)
|
||||
addr = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
set_memory_rox((unsigned long)addr, 1);
|
||||
if (set_memory_rox((unsigned long)addr, 1)) {
|
||||
execmem_free(addr);
|
||||
return NULL;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,12 +91,7 @@ early_param("nospectre_v2", parse_spectre_v2_param);
|
||||
|
||||
static bool spectre_v2_mitigations_off(void)
|
||||
{
|
||||
bool ret = __nospectre_v2 || cpu_mitigations_off();
|
||||
|
||||
if (ret)
|
||||
pr_info_once("spectre-v2 mitigation disabled by command line option\n");
|
||||
|
||||
return ret;
|
||||
return __nospectre_v2 || cpu_mitigations_off();
|
||||
}
|
||||
|
||||
static const char *get_bhb_affected_string(enum mitigation_state bhb_state)
|
||||
@@ -421,13 +416,8 @@ early_param("ssbd", parse_spectre_v4_param);
|
||||
*/
|
||||
static bool spectre_v4_mitigations_off(void)
|
||||
{
|
||||
bool ret = cpu_mitigations_off() ||
|
||||
__spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DISABLED;
|
||||
|
||||
if (ret)
|
||||
pr_info_once("spectre-v4 mitigation disabled by command-line option\n");
|
||||
|
||||
return ret;
|
||||
return cpu_mitigations_off() ||
|
||||
__spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DISABLED;
|
||||
}
|
||||
|
||||
/* Do we need to toggle the mitigation state on entry to/exit from the kernel? */
|
||||
@@ -1042,10 +1032,6 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
||||
|
||||
if (arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) {
|
||||
/* No point mitigating Spectre-BHB alone. */
|
||||
} else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) {
|
||||
pr_info_once("spectre-bhb mitigation disabled by compile time option\n");
|
||||
} else if (cpu_mitigations_off() || __nospectre_bhb) {
|
||||
pr_info_once("spectre-bhb mitigation disabled by command line option\n");
|
||||
} else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
|
||||
state = SPECTRE_MITIGATED;
|
||||
set_bit(BHB_HW, &system_bhb_mitigations);
|
||||
@@ -1199,3 +1185,18 @@ void unpriv_ebpf_notify(int new_state)
|
||||
pr_err("WARNING: %s", EBPF_WARN);
|
||||
}
|
||||
#endif
|
||||
|
||||
void spectre_print_disabled_mitigations(void)
|
||||
{
|
||||
/* Keep a single copy of the common message suffix to avoid duplication. */
|
||||
const char *spectre_disabled_suffix = "mitigation disabled by command-line option\n";
|
||||
|
||||
if (spectre_v2_mitigations_off())
|
||||
pr_info("spectre-v2 %s", spectre_disabled_suffix);
|
||||
|
||||
if (spectre_v4_mitigations_off())
|
||||
pr_info("spectre-v4 %s", spectre_disabled_suffix);
|
||||
|
||||
if (__nospectre_bhb || cpu_mitigations_off())
|
||||
pr_info("spectre-bhb %s", spectre_disabled_suffix);
|
||||
}
|
||||
|
||||
@@ -624,6 +624,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
kvm_timer_vcpu_load(vcpu);
|
||||
kvm_vgic_load(vcpu);
|
||||
kvm_vcpu_load_debug(vcpu);
|
||||
kvm_vcpu_load_fgt(vcpu);
|
||||
if (has_vhe())
|
||||
kvm_vcpu_load_vhe(vcpu);
|
||||
kvm_arch_vcpu_load_fp(vcpu);
|
||||
@@ -642,7 +643,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
vcpu->arch.hcr_el2 |= HCR_TWI;
|
||||
|
||||
vcpu_set_pauth_traps(vcpu);
|
||||
kvm_vcpu_load_fgt(vcpu);
|
||||
|
||||
if (is_protected_kvm_enabled()) {
|
||||
kvm_call_hyp_nvhe(__pkvm_vcpu_load,
|
||||
|
||||
@@ -479,7 +479,7 @@ static void __do_ffa_mem_xfer(const u64 func_id,
|
||||
struct ffa_mem_region_attributes *ep_mem_access;
|
||||
struct ffa_composite_mem_region *reg;
|
||||
struct ffa_mem_region *buf;
|
||||
u32 offset, nr_ranges;
|
||||
u32 offset, nr_ranges, checked_offset;
|
||||
int ret = 0;
|
||||
|
||||
if (addr_mbz || npages_mbz || fraglen > len ||
|
||||
@@ -516,7 +516,12 @@ static void __do_ffa_mem_xfer(const u64 func_id,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (fraglen < offset + sizeof(struct ffa_composite_mem_region)) {
|
||||
if (check_add_overflow(offset, sizeof(struct ffa_composite_mem_region), &checked_offset)) {
|
||||
ret = FFA_RET_INVALID_PARAMETERS;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (fraglen < checked_offset) {
|
||||
ret = FFA_RET_INVALID_PARAMETERS;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
@@ -367,6 +367,19 @@ static int host_stage2_unmap_dev_all(void)
|
||||
return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the PFN range is contained within PA-range.
|
||||
*
|
||||
* This check is also robust to overflows and is therefore a requirement before
|
||||
* using a pfn/nr_pages pair from an untrusted source.
|
||||
*/
|
||||
static bool pfn_range_is_valid(u64 pfn, u64 nr_pages)
|
||||
{
|
||||
u64 limit = BIT(kvm_phys_shift(&host_mmu.arch.mmu) - PAGE_SHIFT);
|
||||
|
||||
return pfn < limit && ((limit - pfn) >= nr_pages);
|
||||
}
|
||||
|
||||
struct kvm_mem_range {
|
||||
u64 start;
|
||||
u64 end;
|
||||
@@ -776,6 +789,9 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
|
||||
void *virt = __hyp_va(phys);
|
||||
int ret;
|
||||
|
||||
if (!pfn_range_is_valid(pfn, nr_pages))
|
||||
return -EINVAL;
|
||||
|
||||
host_lock_component();
|
||||
hyp_lock_component();
|
||||
|
||||
@@ -804,6 +820,9 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages)
|
||||
u64 virt = (u64)__hyp_va(phys);
|
||||
int ret;
|
||||
|
||||
if (!pfn_range_is_valid(pfn, nr_pages))
|
||||
return -EINVAL;
|
||||
|
||||
host_lock_component();
|
||||
hyp_lock_component();
|
||||
|
||||
@@ -887,6 +906,9 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages)
|
||||
u64 size = PAGE_SIZE * nr_pages;
|
||||
int ret;
|
||||
|
||||
if (!pfn_range_is_valid(pfn, nr_pages))
|
||||
return -EINVAL;
|
||||
|
||||
host_lock_component();
|
||||
ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED);
|
||||
if (!ret)
|
||||
@@ -902,6 +924,9 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
|
||||
u64 size = PAGE_SIZE * nr_pages;
|
||||
int ret;
|
||||
|
||||
if (!pfn_range_is_valid(pfn, nr_pages))
|
||||
return -EINVAL;
|
||||
|
||||
host_lock_component();
|
||||
ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED);
|
||||
if (!ret)
|
||||
@@ -945,6 +970,9 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu
|
||||
if (prot & ~KVM_PGTABLE_PROT_RWX)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pfn_range_is_valid(pfn, nr_pages))
|
||||
return -EINVAL;
|
||||
|
||||
ret = __guest_check_transition_size(phys, ipa, nr_pages, &size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2595,19 +2595,23 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
|
||||
.val = 0, \
|
||||
}
|
||||
|
||||
/* sys_reg_desc initialiser for known cpufeature ID registers */
|
||||
#define AA32_ID_SANITISED(name) { \
|
||||
ID_DESC(name), \
|
||||
.visibility = aa32_id_visibility, \
|
||||
.val = 0, \
|
||||
}
|
||||
|
||||
/* sys_reg_desc initialiser for writable ID registers */
|
||||
#define ID_WRITABLE(name, mask) { \
|
||||
ID_DESC(name), \
|
||||
.val = mask, \
|
||||
}
|
||||
|
||||
/*
|
||||
* 32bit ID regs are fully writable when the guest is 32bit
|
||||
* capable. Nothing in the KVM code should rely on 32bit features
|
||||
* anyway, only 64bit, so let the VMM do its worse.
|
||||
*/
|
||||
#define AA32_ID_WRITABLE(name) { \
|
||||
ID_DESC(name), \
|
||||
.visibility = aa32_id_visibility, \
|
||||
.val = GENMASK(31, 0), \
|
||||
}
|
||||
|
||||
/* sys_reg_desc initialiser for cpufeature ID registers that need filtering */
|
||||
#define ID_FILTERED(sysreg, name, mask) { \
|
||||
ID_DESC(sysreg), \
|
||||
@@ -3128,40 +3132,39 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
|
||||
/* AArch64 mappings of the AArch32 ID registers */
|
||||
/* CRm=1 */
|
||||
AA32_ID_SANITISED(ID_PFR0_EL1),
|
||||
AA32_ID_SANITISED(ID_PFR1_EL1),
|
||||
AA32_ID_WRITABLE(ID_PFR0_EL1),
|
||||
AA32_ID_WRITABLE(ID_PFR1_EL1),
|
||||
{ SYS_DESC(SYS_ID_DFR0_EL1),
|
||||
.access = access_id_reg,
|
||||
.get_user = get_id_reg,
|
||||
.set_user = set_id_dfr0_el1,
|
||||
.visibility = aa32_id_visibility,
|
||||
.reset = read_sanitised_id_dfr0_el1,
|
||||
.val = ID_DFR0_EL1_PerfMon_MASK |
|
||||
ID_DFR0_EL1_CopDbg_MASK, },
|
||||
.val = GENMASK(31, 0) },
|
||||
ID_HIDDEN(ID_AFR0_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR0_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR1_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR2_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR3_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR0_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR1_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR2_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR3_EL1),
|
||||
|
||||
/* CRm=2 */
|
||||
AA32_ID_SANITISED(ID_ISAR0_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR1_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR2_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR3_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR4_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR5_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR4_EL1),
|
||||
AA32_ID_SANITISED(ID_ISAR6_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR0_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR1_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR2_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR3_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR4_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR5_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR4_EL1),
|
||||
AA32_ID_WRITABLE(ID_ISAR6_EL1),
|
||||
|
||||
/* CRm=3 */
|
||||
AA32_ID_SANITISED(MVFR0_EL1),
|
||||
AA32_ID_SANITISED(MVFR1_EL1),
|
||||
AA32_ID_SANITISED(MVFR2_EL1),
|
||||
AA32_ID_WRITABLE(MVFR0_EL1),
|
||||
AA32_ID_WRITABLE(MVFR1_EL1),
|
||||
AA32_ID_WRITABLE(MVFR2_EL1),
|
||||
ID_UNALLOCATED(3,3),
|
||||
AA32_ID_SANITISED(ID_PFR2_EL1),
|
||||
AA32_ID_WRITABLE(ID_PFR2_EL1),
|
||||
ID_HIDDEN(ID_DFR1_EL1),
|
||||
AA32_ID_SANITISED(ID_MMFR5_EL1),
|
||||
AA32_ID_WRITABLE(ID_MMFR5_EL1),
|
||||
ID_UNALLOCATED(3,7),
|
||||
|
||||
/* AArch64 ID registers */
|
||||
@@ -5606,11 +5609,17 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
|
||||
|
||||
guard(mutex)(&kvm->arch.config_lock);
|
||||
|
||||
if (!(static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
|
||||
irqchip_in_kernel(kvm) &&
|
||||
kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)) {
|
||||
kvm->arch.id_regs[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] &= ~ID_AA64PFR0_EL1_GIC_MASK;
|
||||
kvm->arch.id_regs[IDREG_IDX(SYS_ID_PFR1_EL1)] &= ~ID_PFR1_EL1_GIC_MASK;
|
||||
/*
|
||||
* This hacks into the ID registers, so only perform it when the
|
||||
* first vcpu runs, or the kvm_set_vm_id_reg() helper will scream.
|
||||
*/
|
||||
if (!irqchip_in_kernel(kvm) && !kvm_vm_has_ran_once(kvm)) {
|
||||
u64 val;
|
||||
|
||||
val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC;
|
||||
kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, val);
|
||||
val = kvm_read_vm_id_reg(kvm, SYS_ID_PFR1_EL1) & ~ID_PFR1_EL1_GIC;
|
||||
kvm_set_vm_id_reg(kvm, SYS_ID_PFR1_EL1, val);
|
||||
}
|
||||
|
||||
if (vcpu_has_nv(vcpu)) {
|
||||
|
||||
@@ -64,29 +64,37 @@ static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter)
|
||||
static int iter_mark_lpis(struct kvm *kvm)
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
unsigned long intid, flags;
|
||||
struct vgic_irq *irq;
|
||||
unsigned long intid;
|
||||
int nr_lpis = 0;
|
||||
|
||||
xa_lock_irqsave(&dist->lpi_xa, flags);
|
||||
|
||||
xa_for_each(&dist->lpi_xa, intid, irq) {
|
||||
if (!vgic_try_get_irq_ref(irq))
|
||||
continue;
|
||||
|
||||
xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
|
||||
__xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
|
||||
nr_lpis++;
|
||||
}
|
||||
|
||||
xa_unlock_irqrestore(&dist->lpi_xa, flags);
|
||||
|
||||
return nr_lpis;
|
||||
}
|
||||
|
||||
static void iter_unmark_lpis(struct kvm *kvm)
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
unsigned long intid, flags;
|
||||
struct vgic_irq *irq;
|
||||
unsigned long intid;
|
||||
|
||||
xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) {
|
||||
xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
|
||||
xa_lock_irqsave(&dist->lpi_xa, flags);
|
||||
__xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
|
||||
xa_unlock_irqrestore(&dist->lpi_xa, flags);
|
||||
|
||||
/* vgic_put_irq() expects to be called outside of the xa_lock */
|
||||
vgic_put_irq(kvm, irq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void kvm_vgic_early_init(struct kvm *kvm)
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
|
||||
xa_init(&dist->lpi_xa);
|
||||
xa_init_flags(&dist->lpi_xa, XA_FLAGS_LOCK_IRQ);
|
||||
}
|
||||
|
||||
/* CREATION */
|
||||
@@ -71,6 +71,7 @@ static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu, u32 type);
|
||||
int kvm_vgic_create(struct kvm *kvm, u32 type)
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
u64 aa64pfr0, pfr1;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
|
||||
@@ -161,10 +162,19 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
|
||||
|
||||
kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
|
||||
|
||||
if (type == KVM_DEV_TYPE_ARM_VGIC_V2)
|
||||
aa64pfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC;
|
||||
pfr1 = kvm_read_vm_id_reg(kvm, SYS_ID_PFR1_EL1) & ~ID_PFR1_EL1_GIC;
|
||||
|
||||
if (type == KVM_DEV_TYPE_ARM_VGIC_V2) {
|
||||
kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
|
||||
else
|
||||
} else {
|
||||
INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
|
||||
aa64pfr0 |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, GIC, IMP);
|
||||
pfr1 |= SYS_FIELD_PREP_ENUM(ID_PFR1_EL1, GIC, GICv3);
|
||||
}
|
||||
|
||||
kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, aa64pfr0);
|
||||
kvm_set_vm_id_reg(kvm, SYS_ID_PFR1_EL1, pfr1);
|
||||
|
||||
if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
|
||||
kvm->arch.vgic.nassgicap = system_supports_direct_sgis();
|
||||
|
||||
@@ -78,6 +78,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
struct vgic_irq *irq = vgic_get_irq(kvm, intid), *oldirq;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* In this case there is no put, since we keep the reference. */
|
||||
@@ -88,7 +89,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
|
||||
if (!irq)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = xa_reserve(&dist->lpi_xa, intid, GFP_KERNEL_ACCOUNT);
|
||||
ret = xa_reserve_irq(&dist->lpi_xa, intid, GFP_KERNEL_ACCOUNT);
|
||||
if (ret) {
|
||||
kfree(irq);
|
||||
return ERR_PTR(ret);
|
||||
@@ -103,7 +104,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
|
||||
irq->target_vcpu = vcpu;
|
||||
irq->group = 1;
|
||||
|
||||
xa_lock(&dist->lpi_xa);
|
||||
xa_lock_irqsave(&dist->lpi_xa, flags);
|
||||
|
||||
/*
|
||||
* There could be a race with another vgic_add_lpi(), so we need to
|
||||
@@ -114,21 +115,18 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
|
||||
/* Someone was faster with adding this LPI, lets use that. */
|
||||
kfree(irq);
|
||||
irq = oldirq;
|
||||
|
||||
goto out_unlock;
|
||||
} else {
|
||||
ret = xa_err(__xa_store(&dist->lpi_xa, intid, irq, 0));
|
||||
}
|
||||
|
||||
ret = xa_err(__xa_store(&dist->lpi_xa, intid, irq, 0));
|
||||
xa_unlock_irqrestore(&dist->lpi_xa, flags);
|
||||
|
||||
if (ret) {
|
||||
xa_release(&dist->lpi_xa, intid);
|
||||
kfree(irq);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
xa_unlock(&dist->lpi_xa);
|
||||
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* We "cache" the configuration table entries in our struct vgic_irq's.
|
||||
|
||||
@@ -301,7 +301,8 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu)
|
||||
return;
|
||||
|
||||
/* Hide GICv3 sysreg if necessary */
|
||||
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) {
|
||||
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2 ||
|
||||
!irqchip_in_kernel(vcpu->kvm)) {
|
||||
vgic_v3->vgic_hcr |= (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 |
|
||||
ICH_HCR_EL2_TC);
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,7 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
|
||||
* kvm->arch.config_lock (mutex)
|
||||
* its->cmd_lock (mutex)
|
||||
* its->its_lock (mutex)
|
||||
* vgic_dist->lpi_xa.xa_lock
|
||||
* vgic_dist->lpi_xa.xa_lock must be taken with IRQs disabled
|
||||
* vgic_cpu->ap_list_lock must be taken with IRQs disabled
|
||||
* vgic_irq->irq_lock must be taken with IRQs disabled
|
||||
*
|
||||
@@ -141,32 +141,39 @@ static __must_check bool vgic_put_irq_norelease(struct kvm *kvm, struct vgic_irq
|
||||
void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
unsigned long flags;
|
||||
|
||||
if (irq->intid >= VGIC_MIN_LPI)
|
||||
might_lock(&dist->lpi_xa.xa_lock);
|
||||
/*
|
||||
* Normally the lock is only taken when the refcount drops to 0.
|
||||
* Acquire/release it early on lockdep kernels to make locking issues
|
||||
* in rare release paths a bit more obvious.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_LOCKDEP) && irq->intid >= VGIC_MIN_LPI) {
|
||||
guard(spinlock_irqsave)(&dist->lpi_xa.xa_lock);
|
||||
}
|
||||
|
||||
if (!__vgic_put_irq(kvm, irq))
|
||||
return;
|
||||
|
||||
xa_lock(&dist->lpi_xa);
|
||||
xa_lock_irqsave(&dist->lpi_xa, flags);
|
||||
vgic_release_lpi_locked(dist, irq);
|
||||
xa_unlock(&dist->lpi_xa);
|
||||
xa_unlock_irqrestore(&dist->lpi_xa, flags);
|
||||
}
|
||||
|
||||
static void vgic_release_deleted_lpis(struct kvm *kvm)
|
||||
{
|
||||
struct vgic_dist *dist = &kvm->arch.vgic;
|
||||
unsigned long intid;
|
||||
unsigned long flags, intid;
|
||||
struct vgic_irq *irq;
|
||||
|
||||
xa_lock(&dist->lpi_xa);
|
||||
xa_lock_irqsave(&dist->lpi_xa, flags);
|
||||
|
||||
xa_for_each(&dist->lpi_xa, intid, irq) {
|
||||
if (irq->pending_release)
|
||||
vgic_release_lpi_locked(dist, irq);
|
||||
}
|
||||
|
||||
xa_unlock(&dist->lpi_xa);
|
||||
xa_unlock_irqrestore(&dist->lpi_xa, flags);
|
||||
}
|
||||
|
||||
void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
|
||||
|
||||
@@ -967,10 +967,21 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||
return vma_alloc_folio(flags, 0, vma, vaddr);
|
||||
}
|
||||
|
||||
void tag_clear_highpage(struct page *page)
|
||||
bool tag_clear_highpages(struct page *page, int numpages)
|
||||
{
|
||||
/* Newly allocated page, shouldn't have been tagged yet */
|
||||
WARN_ON_ONCE(!try_page_mte_tagging(page));
|
||||
mte_zero_clear_page_tags(page_address(page));
|
||||
set_page_mte_tagged(page);
|
||||
/*
|
||||
* Check if MTE is supported and fall back to clear_highpage().
|
||||
* get_huge_zero_folio() unconditionally passes __GFP_ZEROTAGS and
|
||||
* post_alloc_hook() will invoke tag_clear_highpages().
|
||||
*/
|
||||
if (!system_supports_mte())
|
||||
return false;
|
||||
|
||||
/* Newly allocated pages, shouldn't have been tagged yet */
|
||||
for (int i = 0; i < numpages; i++, page++) {
|
||||
WARN_ON_ONCE(!try_page_mte_tagging(page));
|
||||
mte_zero_clear_page_tags(page_address(page));
|
||||
set_page_mte_tagged(page);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -708,6 +708,30 @@ static int split_kernel_leaf_mapping_locked(unsigned long addr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool force_pte_mapping(void)
|
||||
{
|
||||
const bool bbml2 = system_capabilities_finalized() ?
|
||||
system_supports_bbml2_noabort() : cpu_supports_bbml2_noabort();
|
||||
|
||||
if (debug_pagealloc_enabled())
|
||||
return true;
|
||||
if (bbml2)
|
||||
return false;
|
||||
return rodata_full || arm64_kfence_can_set_direct_map() || is_realm_world();
|
||||
}
|
||||
|
||||
static inline bool split_leaf_mapping_possible(void)
|
||||
{
|
||||
/*
|
||||
* !BBML2_NOABORT systems should never run into scenarios where we would
|
||||
* have to split. So exit early and let calling code detect it and raise
|
||||
* a warning.
|
||||
*/
|
||||
if (!system_supports_bbml2_noabort())
|
||||
return false;
|
||||
return !force_pte_mapping();
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(pgtable_split_lock);
|
||||
|
||||
int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
|
||||
@@ -715,12 +739,11 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* !BBML2_NOABORT systems should not be trying to change permissions on
|
||||
* anything that is not pte-mapped in the first place. Just return early
|
||||
* and let the permission change code raise a warning if not already
|
||||
* pte-mapped.
|
||||
* Exit early if the region is within a pte-mapped area or if we can't
|
||||
* split. For the latter case, the permission change code will raise a
|
||||
* warning if not already pte-mapped.
|
||||
*/
|
||||
if (!system_supports_bbml2_noabort())
|
||||
if (!split_leaf_mapping_possible() || is_kfence_address((void *)start))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -758,30 +781,30 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init split_to_ptes_pud_entry(pud_t *pudp, unsigned long addr,
|
||||
unsigned long next,
|
||||
struct mm_walk *walk)
|
||||
static int split_to_ptes_pud_entry(pud_t *pudp, unsigned long addr,
|
||||
unsigned long next, struct mm_walk *walk)
|
||||
{
|
||||
gfp_t gfp = *(gfp_t *)walk->private;
|
||||
pud_t pud = pudp_get(pudp);
|
||||
int ret = 0;
|
||||
|
||||
if (pud_leaf(pud))
|
||||
ret = split_pud(pudp, pud, GFP_ATOMIC, false);
|
||||
ret = split_pud(pudp, pud, gfp, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr,
|
||||
unsigned long next,
|
||||
struct mm_walk *walk)
|
||||
static int split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr,
|
||||
unsigned long next, struct mm_walk *walk)
|
||||
{
|
||||
gfp_t gfp = *(gfp_t *)walk->private;
|
||||
pmd_t pmd = pmdp_get(pmdp);
|
||||
int ret = 0;
|
||||
|
||||
if (pmd_leaf(pmd)) {
|
||||
if (pmd_cont(pmd))
|
||||
split_contpmd(pmdp);
|
||||
ret = split_pmd(pmdp, pmd, GFP_ATOMIC, false);
|
||||
ret = split_pmd(pmdp, pmd, gfp, false);
|
||||
|
||||
/*
|
||||
* We have split the pmd directly to ptes so there is no need to
|
||||
@@ -793,9 +816,8 @@ static int __init split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr,
|
||||
unsigned long next,
|
||||
struct mm_walk *walk)
|
||||
static int split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr,
|
||||
unsigned long next, struct mm_walk *walk)
|
||||
{
|
||||
pte_t pte = __ptep_get(ptep);
|
||||
|
||||
@@ -805,12 +827,24 @@ static int __init split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mm_walk_ops split_to_ptes_ops __initconst = {
|
||||
static const struct mm_walk_ops split_to_ptes_ops = {
|
||||
.pud_entry = split_to_ptes_pud_entry,
|
||||
.pmd_entry = split_to_ptes_pmd_entry,
|
||||
.pte_entry = split_to_ptes_pte_entry,
|
||||
};
|
||||
|
||||
static int range_split_to_ptes(unsigned long start, unsigned long end, gfp_t gfp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
arch_enter_lazy_mmu_mode();
|
||||
ret = walk_kernel_page_table_range_lockless(start, end,
|
||||
&split_to_ptes_ops, NULL, &gfp);
|
||||
arch_leave_lazy_mmu_mode();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool linear_map_requires_bbml2 __initdata;
|
||||
|
||||
u32 idmap_kpti_bbml2_flag;
|
||||
@@ -847,11 +881,9 @@ static int __init linear_map_split_to_ptes(void *__unused)
|
||||
* PTE. The kernel alias remains static throughout runtime so
|
||||
* can continue to be safely mapped with large mappings.
|
||||
*/
|
||||
ret = walk_kernel_page_table_range_lockless(lstart, kstart,
|
||||
&split_to_ptes_ops, NULL, NULL);
|
||||
ret = range_split_to_ptes(lstart, kstart, GFP_ATOMIC);
|
||||
if (!ret)
|
||||
ret = walk_kernel_page_table_range_lockless(kend, lend,
|
||||
&split_to_ptes_ops, NULL, NULL);
|
||||
ret = range_split_to_ptes(kend, lend, GFP_ATOMIC);
|
||||
if (ret)
|
||||
panic("Failed to split linear map\n");
|
||||
flush_tlb_kernel_range(lstart, lend);
|
||||
@@ -1002,6 +1034,33 @@ static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp)
|
||||
memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
|
||||
__kfence_pool = phys_to_virt(kfence_pool);
|
||||
}
|
||||
|
||||
bool arch_kfence_init_pool(void)
|
||||
{
|
||||
unsigned long start = (unsigned long)__kfence_pool;
|
||||
unsigned long end = start + KFENCE_POOL_SIZE;
|
||||
int ret;
|
||||
|
||||
/* Exit early if we know the linear map is already pte-mapped. */
|
||||
if (!split_leaf_mapping_possible())
|
||||
return true;
|
||||
|
||||
/* Kfence pool is already pte-mapped for the early init case. */
|
||||
if (kfence_early_init)
|
||||
return true;
|
||||
|
||||
mutex_lock(&pgtable_split_lock);
|
||||
ret = range_split_to_ptes(start, end, GFP_PGTABLE_KERNEL);
|
||||
mutex_unlock(&pgtable_split_lock);
|
||||
|
||||
/*
|
||||
* Since the system supports bbml2_noabort, tlb invalidation is not
|
||||
* required here; the pgtable mappings have been split to pte but larger
|
||||
* entries may safely linger in the TLB.
|
||||
*/
|
||||
|
||||
return !ret;
|
||||
}
|
||||
#else /* CONFIG_KFENCE */
|
||||
|
||||
static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; }
|
||||
@@ -1009,16 +1068,6 @@ static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) {
|
||||
|
||||
#endif /* CONFIG_KFENCE */
|
||||
|
||||
static inline bool force_pte_mapping(void)
|
||||
{
|
||||
bool bbml2 = system_capabilities_finalized() ?
|
||||
system_supports_bbml2_noabort() : cpu_supports_bbml2_noabort();
|
||||
|
||||
return (!bbml2 && (rodata_full || arm64_kfence_can_set_direct_map() ||
|
||||
is_realm_world())) ||
|
||||
debug_pagealloc_enabled();
|
||||
}
|
||||
|
||||
static void __init map_mem(pgd_t *pgdp)
|
||||
{
|
||||
static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN);
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
#define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR)
|
||||
#define cpu_has_ptw cpu_opt(LOONGARCH_CPU_PTW)
|
||||
#define cpu_has_lspw cpu_opt(LOONGARCH_CPU_LSPW)
|
||||
#define cpu_has_msgint cpu_opt(LOONGARCH_CPU_MSGINT)
|
||||
#define cpu_has_avecint cpu_opt(LOONGARCH_CPU_AVECINT)
|
||||
#define cpu_has_redirectint cpu_opt(LOONGARCH_CPU_REDIRECTINT)
|
||||
|
||||
#endif /* __ASM_CPU_FEATURES_H */
|
||||
|
||||
@@ -55,6 +55,27 @@ enum cpu_type_enum {
|
||||
CPU_LAST
|
||||
};
|
||||
|
||||
static inline char *id_to_core_name(unsigned int id)
|
||||
{
|
||||
if ((id & PRID_COMP_MASK) != PRID_COMP_LOONGSON)
|
||||
return "Unknown";
|
||||
|
||||
switch (id & PRID_SERIES_MASK) {
|
||||
case PRID_SERIES_LA132:
|
||||
return "LA132";
|
||||
case PRID_SERIES_LA264:
|
||||
return "LA264";
|
||||
case PRID_SERIES_LA364:
|
||||
return "LA364";
|
||||
case PRID_SERIES_LA464:
|
||||
return "LA464";
|
||||
case PRID_SERIES_LA664:
|
||||
return "LA664";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/*
|
||||
@@ -101,7 +122,9 @@ enum cpu_type_enum {
|
||||
#define CPU_FEATURE_HYPERVISOR 26 /* CPU has hypervisor (running in VM) */
|
||||
#define CPU_FEATURE_PTW 27 /* CPU has hardware page table walker */
|
||||
#define CPU_FEATURE_LSPW 28 /* CPU has LSPW (lddir/ldpte instructions) */
|
||||
#define CPU_FEATURE_AVECINT 29 /* CPU has AVEC interrupt */
|
||||
#define CPU_FEATURE_MSGINT 29 /* CPU has MSG interrupt */
|
||||
#define CPU_FEATURE_AVECINT 30 /* CPU has AVEC interrupt */
|
||||
#define CPU_FEATURE_REDIRECTINT 31 /* CPU has interrupt remapping */
|
||||
|
||||
#define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
|
||||
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
|
||||
@@ -132,6 +155,8 @@ enum cpu_type_enum {
|
||||
#define LOONGARCH_CPU_HYPERVISOR BIT_ULL(CPU_FEATURE_HYPERVISOR)
|
||||
#define LOONGARCH_CPU_PTW BIT_ULL(CPU_FEATURE_PTW)
|
||||
#define LOONGARCH_CPU_LSPW BIT_ULL(CPU_FEATURE_LSPW)
|
||||
#define LOONGARCH_CPU_MSGINT BIT_ULL(CPU_FEATURE_MSGINT)
|
||||
#define LOONGARCH_CPU_AVECINT BIT_ULL(CPU_FEATURE_AVECINT)
|
||||
#define LOONGARCH_CPU_REDIRECTINT BIT_ULL(CPU_FEATURE_REDIRECTINT)
|
||||
|
||||
#endif /* _ASM_CPU_H */
|
||||
|
||||
@@ -134,13 +134,13 @@ static inline void hw_breakpoint_thread_switch(struct task_struct *next)
|
||||
/* Determine number of BRP registers available. */
|
||||
static inline int get_num_brps(void)
|
||||
{
|
||||
return csr_read64(LOONGARCH_CSR_FWPC) & CSR_FWPC_NUM;
|
||||
return csr_read32(LOONGARCH_CSR_FWPC) & CSR_FWPC_NUM;
|
||||
}
|
||||
|
||||
/* Determine number of WRP registers available. */
|
||||
static inline int get_num_wrps(void)
|
||||
{
|
||||
return csr_read64(LOONGARCH_CSR_MWPC) & CSR_MWPC_NUM;
|
||||
return csr_read32(LOONGARCH_CSR_MWPC) & CSR_MWPC_NUM;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <asm/pgtable-bits.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
extern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size);
|
||||
extern void __init __iomem *early_ioremap(phys_addr_t phys_addr, unsigned long size);
|
||||
extern void __init early_iounmap(void __iomem *addr, unsigned long size);
|
||||
|
||||
#define early_memremap early_ioremap
|
||||
@@ -25,6 +25,9 @@ extern void __init early_iounmap(void __iomem *addr, unsigned long size);
|
||||
static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
|
||||
pgprot_t prot)
|
||||
{
|
||||
if (offset > TO_PHYS_MASK)
|
||||
return NULL;
|
||||
|
||||
switch (pgprot_val(prot) & _CACHE_MASK) {
|
||||
case _CACHE_CC:
|
||||
return (void __iomem *)(unsigned long)(CACHE_BASE + offset);
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
#define CPUCFG6_PMNUM GENMASK(7, 4)
|
||||
#define CPUCFG6_PMNUM_SHIFT 4
|
||||
#define CPUCFG6_PMBITS GENMASK(13, 8)
|
||||
#define CPUCFG6_PMBITS_SHIFT 8
|
||||
#define CPUCFG6_UPM BIT(14)
|
||||
|
||||
#define LOONGARCH_CPUCFG16 0x10
|
||||
@@ -1137,6 +1138,7 @@
|
||||
#define IOCSRF_FLATMODE BIT_ULL(10)
|
||||
#define IOCSRF_VM BIT_ULL(11)
|
||||
#define IOCSRF_AVEC BIT_ULL(15)
|
||||
#define IOCSRF_REDIRECT BIT_ULL(16)
|
||||
|
||||
#define LOONGARCH_IOCSR_VENDOR 0x10
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
|
||||
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
pud_t *pud;
|
||||
struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
|
||||
struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
|
||||
|
||||
if (!ptdesc)
|
||||
return NULL;
|
||||
|
||||
@@ -424,6 +424,9 @@ static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
|
||||
|
||||
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
{
|
||||
if (pte_val(pte) & _PAGE_DIRTY)
|
||||
pte_val(pte) |= _PAGE_MODIFIED;
|
||||
|
||||
return __pte((pte_val(pte) & _PAGE_CHG_MASK) |
|
||||
(pgprot_val(newprot) & ~_PAGE_CHG_MASK));
|
||||
}
|
||||
@@ -547,9 +550,11 @@ static inline struct page *pmd_page(pmd_t pmd)
|
||||
|
||||
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||
{
|
||||
pmd_val(pmd) = (pmd_val(pmd) & _HPAGE_CHG_MASK) |
|
||||
(pgprot_val(newprot) & ~_HPAGE_CHG_MASK);
|
||||
return pmd;
|
||||
if (pmd_val(pmd) & _PAGE_DIRTY)
|
||||
pmd_val(pmd) |= _PAGE_MODIFIED;
|
||||
|
||||
return __pmd((pmd_val(pmd) & _HPAGE_CHG_MASK) |
|
||||
(pgprot_val(newprot) & ~_HPAGE_CHG_MASK));
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mkinvalid(pmd_t pmd)
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For PTRACE_{POKE,PEEK}USR. 0 - 31 are GPRs,
|
||||
* 32 is syscall's original ARG0, 33 is PC, 34 is BADVADDR.
|
||||
@@ -41,44 +37,44 @@ struct user_pt_regs {
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct user_fp_state {
|
||||
uint64_t fpr[32];
|
||||
uint64_t fcc;
|
||||
uint32_t fcsr;
|
||||
__u64 fpr[32];
|
||||
__u64 fcc;
|
||||
__u32 fcsr;
|
||||
};
|
||||
|
||||
struct user_lsx_state {
|
||||
/* 32 registers, 128 bits width per register. */
|
||||
uint64_t vregs[32*2];
|
||||
__u64 vregs[32*2];
|
||||
};
|
||||
|
||||
struct user_lasx_state {
|
||||
/* 32 registers, 256 bits width per register. */
|
||||
uint64_t vregs[32*4];
|
||||
__u64 vregs[32*4];
|
||||
};
|
||||
|
||||
struct user_lbt_state {
|
||||
uint64_t scr[4];
|
||||
uint32_t eflags;
|
||||
uint32_t ftop;
|
||||
__u64 scr[4];
|
||||
__u32 eflags;
|
||||
__u32 ftop;
|
||||
};
|
||||
|
||||
struct user_watch_state {
|
||||
uint64_t dbg_info;
|
||||
__u64 dbg_info;
|
||||
struct {
|
||||
uint64_t addr;
|
||||
uint64_t mask;
|
||||
uint32_t ctrl;
|
||||
uint32_t pad;
|
||||
__u64 addr;
|
||||
__u64 mask;
|
||||
__u32 ctrl;
|
||||
__u32 pad;
|
||||
} dbg_regs[8];
|
||||
};
|
||||
|
||||
struct user_watch_state_v2 {
|
||||
uint64_t dbg_info;
|
||||
__u64 dbg_info;
|
||||
struct {
|
||||
uint64_t addr;
|
||||
uint64_t mask;
|
||||
uint32_t ctrl;
|
||||
uint32_t pad;
|
||||
__u64 addr;
|
||||
__u64 mask;
|
||||
__u32 ctrl;
|
||||
__u32 pad;
|
||||
} dbg_regs[14];
|
||||
};
|
||||
|
||||
|
||||
@@ -157,6 +157,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
|
||||
c->options |= LOONGARCH_CPU_TLB;
|
||||
if (config & CPUCFG1_IOCSR)
|
||||
c->options |= LOONGARCH_CPU_IOCSR;
|
||||
if (config & CPUCFG1_MSGINT)
|
||||
c->options |= LOONGARCH_CPU_MSGINT;
|
||||
if (config & CPUCFG1_UAL) {
|
||||
c->options |= LOONGARCH_CPU_UAL;
|
||||
elf_hwcap |= HWCAP_LOONGARCH_UAL;
|
||||
@@ -275,7 +277,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
|
||||
uint32_t config;
|
||||
uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]);
|
||||
uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]);
|
||||
const char *core_name = "Unknown";
|
||||
const char *core_name = id_to_core_name(c->processor_id);
|
||||
|
||||
switch (BIT(fls(c->isa_level) - 1)) {
|
||||
case LOONGARCH_CPU_ISA_LA32R:
|
||||
@@ -289,35 +291,23 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c->processor_id & PRID_SERIES_MASK) {
|
||||
case PRID_SERIES_LA132:
|
||||
core_name = "LA132";
|
||||
break;
|
||||
case PRID_SERIES_LA264:
|
||||
core_name = "LA264";
|
||||
break;
|
||||
case PRID_SERIES_LA364:
|
||||
core_name = "LA364";
|
||||
break;
|
||||
case PRID_SERIES_LA464:
|
||||
core_name = "LA464";
|
||||
break;
|
||||
case PRID_SERIES_LA664:
|
||||
core_name = "LA664";
|
||||
break;
|
||||
}
|
||||
|
||||
pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name);
|
||||
|
||||
if (!cpu_has_iocsr)
|
||||
if (!cpu_has_iocsr) {
|
||||
__cpu_full_name[cpu] = "Unknown";
|
||||
return;
|
||||
|
||||
if (!__cpu_full_name[cpu])
|
||||
__cpu_full_name[cpu] = cpu_full_name;
|
||||
}
|
||||
|
||||
*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
|
||||
*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
|
||||
|
||||
if (!__cpu_full_name[cpu]) {
|
||||
if (((char *)vendor)[0] == 0)
|
||||
__cpu_full_name[cpu] = "Unknown";
|
||||
else
|
||||
__cpu_full_name[cpu] = cpu_full_name;
|
||||
}
|
||||
|
||||
config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
|
||||
if (config & IOCSRF_CSRIPI)
|
||||
c->options |= LOONGARCH_CPU_CSRIPI;
|
||||
@@ -331,6 +321,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
|
||||
c->options |= LOONGARCH_CPU_EIODECODE;
|
||||
if (config & IOCSRF_AVEC)
|
||||
c->options |= LOONGARCH_CPU_AVECINT;
|
||||
if (config & IOCSRF_REDIRECT)
|
||||
c->options |= LOONGARCH_CPU_REDIRECTINT;
|
||||
if (config & IOCSRF_VM)
|
||||
c->options |= LOONGARCH_CPU_HYPERVISOR;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ static void *efi_kexec_load(struct kimage *image,
|
||||
{
|
||||
int ret;
|
||||
unsigned long text_offset, kernel_segment_number;
|
||||
struct kexec_buf kbuf;
|
||||
struct kexec_buf kbuf = {};
|
||||
struct kexec_segment *kernel_segment;
|
||||
struct loongarch_image_header *h;
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ static void *elf_kexec_load(struct kimage *image,
|
||||
int ret;
|
||||
unsigned long text_offset, kernel_segment_number;
|
||||
struct elfhdr ehdr;
|
||||
struct kexec_buf kbuf;
|
||||
struct kexec_buf kbuf = {};
|
||||
struct kexec_elf_info elf_info;
|
||||
struct kexec_segment *kernel_segment;
|
||||
|
||||
|
||||
@@ -39,34 +39,12 @@ static unsigned long systable_ptr;
|
||||
static unsigned long start_addr;
|
||||
static unsigned long first_ind_entry;
|
||||
|
||||
static void kexec_image_info(const struct kimage *kimage)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
pr_debug("kexec kimage info:\n");
|
||||
pr_debug("\ttype: %d\n", kimage->type);
|
||||
pr_debug("\tstart: %lx\n", kimage->start);
|
||||
pr_debug("\thead: %lx\n", kimage->head);
|
||||
pr_debug("\tnr_segments: %lu\n", kimage->nr_segments);
|
||||
|
||||
for (i = 0; i < kimage->nr_segments; i++) {
|
||||
pr_debug("\t segment[%lu]: %016lx - %016lx", i,
|
||||
kimage->segment[i].mem,
|
||||
kimage->segment[i].mem + kimage->segment[i].memsz);
|
||||
pr_debug("\t\t0x%lx bytes, %lu pages\n",
|
||||
(unsigned long)kimage->segment[i].memsz,
|
||||
(unsigned long)kimage->segment[i].memsz / PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
int machine_kexec_prepare(struct kimage *kimage)
|
||||
{
|
||||
int i;
|
||||
char *bootloader = "kexec";
|
||||
void *cmdline_ptr = (void *)KEXEC_CMDLINE_ADDR;
|
||||
|
||||
kexec_image_info(kimage);
|
||||
|
||||
kimage->arch.efi_boot = fw_arg0;
|
||||
kimage->arch.systable_ptr = fw_arg2;
|
||||
|
||||
@@ -259,6 +237,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
|
||||
#ifdef CONFIG_SMP
|
||||
crash_smp_send_stop();
|
||||
#endif
|
||||
machine_kexec_mask_interrupts();
|
||||
cpumask_set_cpu(crashing_cpu, &cpus_in_crash);
|
||||
|
||||
pr_info("Starting crashdump kernel...\n");
|
||||
@@ -296,6 +275,7 @@ void machine_kexec(struct kimage *image)
|
||||
|
||||
/* We do not want to be bothered. */
|
||||
local_irq_disable();
|
||||
machine_kexec_mask_interrupts();
|
||||
|
||||
pr_notice("EFI boot flag: 0x%lx\n", efi_boot);
|
||||
pr_notice("Command line addr: 0x%lx\n", cmdline_ptr);
|
||||
|
||||
@@ -143,7 +143,7 @@ int load_other_segments(struct kimage *image,
|
||||
unsigned long initrd_load_addr = 0;
|
||||
unsigned long orig_segments = image->nr_segments;
|
||||
char *modified_cmdline = NULL;
|
||||
struct kexec_buf kbuf;
|
||||
struct kexec_buf kbuf = {};
|
||||
|
||||
kbuf.image = image;
|
||||
/* Don't allocate anything below the kernel */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
void __init memblock_init(void)
|
||||
{
|
||||
u32 mem_type;
|
||||
u64 mem_start, mem_end, mem_size;
|
||||
u64 mem_start, mem_size;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
/* Parse memory information */
|
||||
@@ -21,7 +21,6 @@ void __init memblock_init(void)
|
||||
mem_type = md->type;
|
||||
mem_start = md->phys_addr;
|
||||
mem_size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
mem_end = mem_start + mem_size;
|
||||
|
||||
switch (mem_type) {
|
||||
case EFI_LOADER_CODE:
|
||||
@@ -31,8 +30,6 @@ void __init memblock_init(void)
|
||||
case EFI_PERSISTENT_MEMORY:
|
||||
case EFI_CONVENTIONAL_MEMORY:
|
||||
memblock_add(mem_start, mem_size);
|
||||
if (max_low_pfn < (mem_end >> PAGE_SHIFT))
|
||||
max_low_pfn = mem_end >> PAGE_SHIFT;
|
||||
break;
|
||||
case EFI_PAL_CODE:
|
||||
case EFI_UNUSABLE_MEMORY:
|
||||
@@ -49,6 +46,8 @@ void __init memblock_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||
max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn);
|
||||
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||
|
||||
/* Reserve the first 2MB */
|
||||
|
||||
@@ -158,35 +158,9 @@ static void __init node_mem_init(unsigned int node)
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
|
||||
/*
|
||||
* add_numamem_region
|
||||
*
|
||||
* Add a uasable memory region described by BIOS. The
|
||||
* routine gets each intersection between BIOS's region
|
||||
* and node's region, and adds them into node's memblock
|
||||
* pool.
|
||||
*
|
||||
*/
|
||||
static void __init add_numamem_region(u64 start, u64 end, u32 type)
|
||||
{
|
||||
u32 node = pa_to_nid(start);
|
||||
u64 size = end - start;
|
||||
static unsigned long num_physpages;
|
||||
static unsigned long num_physpages;
|
||||
|
||||
if (start >= end) {
|
||||
pr_debug("Invalid region: %016llx-%016llx\n", start, end);
|
||||
return;
|
||||
}
|
||||
|
||||
num_physpages += (size >> PAGE_SHIFT);
|
||||
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
|
||||
node, type, start, size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
start >> PAGE_SHIFT, end >> PAGE_SHIFT, num_physpages);
|
||||
memblock_set_node(start, size, &memblock.memory, node);
|
||||
}
|
||||
|
||||
static void __init init_node_memblock(void)
|
||||
static void __init info_node_memblock(void)
|
||||
{
|
||||
u32 mem_type;
|
||||
u64 mem_end, mem_start, mem_size;
|
||||
@@ -206,12 +180,20 @@ static void __init init_node_memblock(void)
|
||||
case EFI_BOOT_SERVICES_DATA:
|
||||
case EFI_PERSISTENT_MEMORY:
|
||||
case EFI_CONVENTIONAL_MEMORY:
|
||||
add_numamem_region(mem_start, mem_end, mem_type);
|
||||
num_physpages += (mem_size >> PAGE_SHIFT);
|
||||
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
|
||||
(u32)pa_to_nid(mem_start), mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
mem_start >> PAGE_SHIFT, mem_end >> PAGE_SHIFT, num_physpages);
|
||||
break;
|
||||
case EFI_PAL_CODE:
|
||||
case EFI_UNUSABLE_MEMORY:
|
||||
case EFI_ACPI_RECLAIM_MEMORY:
|
||||
add_numamem_region(mem_start, mem_end, mem_type);
|
||||
num_physpages += (mem_size >> PAGE_SHIFT);
|
||||
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n",
|
||||
(u32)pa_to_nid(mem_start), mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
mem_start >> PAGE_SHIFT, mem_end >> PAGE_SHIFT, num_physpages);
|
||||
fallthrough;
|
||||
case EFI_RESERVED_TYPE:
|
||||
case EFI_RUNTIME_SERVICES_CODE:
|
||||
@@ -249,22 +231,16 @@ int __init init_numa_memory(void)
|
||||
for (i = 0; i < NR_CPUS; i++)
|
||||
set_cpuid_to_node(i, NUMA_NO_NODE);
|
||||
|
||||
numa_reset_distance();
|
||||
nodes_clear(numa_nodes_parsed);
|
||||
nodes_clear(node_possible_map);
|
||||
nodes_clear(node_online_map);
|
||||
WARN_ON(memblock_clear_hotplug(0, PHYS_ADDR_MAX));
|
||||
|
||||
/* Parse SRAT and SLIT if provided by firmware. */
|
||||
ret = acpi_disabled ? fake_numa_init() : acpi_numa_init();
|
||||
if (!acpi_disabled)
|
||||
ret = numa_memblks_init(acpi_numa_init, false);
|
||||
else
|
||||
ret = numa_memblks_init(fake_numa_init, false);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
node_possible_map = numa_nodes_parsed;
|
||||
if (WARN_ON(nodes_empty(node_possible_map)))
|
||||
return -EINVAL;
|
||||
|
||||
init_node_memblock();
|
||||
info_node_memblock();
|
||||
if (!memblock_validate_numa_coverage(SZ_1M))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -272,7 +248,8 @@ int __init init_numa_memory(void)
|
||||
node_mem_init(node);
|
||||
node_set_online(node);
|
||||
}
|
||||
max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
|
||||
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||
max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn);
|
||||
|
||||
setup_nr_node_ids();
|
||||
loongson_sysconf.nr_nodes = nr_node_ids;
|
||||
@@ -283,26 +260,6 @@ int __init init_numa_memory(void)
|
||||
|
||||
#endif
|
||||
|
||||
void __init paging_init(void)
|
||||
{
|
||||
unsigned int node;
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {0, };
|
||||
|
||||
for_each_online_node(node) {
|
||||
unsigned long start_pfn, end_pfn;
|
||||
|
||||
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
|
||||
|
||||
if (end_pfn > max_low_pfn)
|
||||
max_low_pfn = end_pfn;
|
||||
}
|
||||
#ifdef CONFIG_ZONE_DMA32
|
||||
zones_size[ZONE_DMA32] = MAX_DMA32_PFN;
|
||||
#endif
|
||||
zones_size[ZONE_NORMAL] = max_low_pfn;
|
||||
free_area_init(zones_size);
|
||||
}
|
||||
|
||||
int pcibus_to_node(struct pci_bus *bus)
|
||||
{
|
||||
return dev_to_node(&bus->dev);
|
||||
|
||||
@@ -845,13 +845,14 @@ static const struct loongarch_perf_event *loongarch_pmu_map_raw_event(u64 config
|
||||
|
||||
static int __init init_hw_perf_events(void)
|
||||
{
|
||||
int counters;
|
||||
int bits, counters;
|
||||
|
||||
if (!cpu_has_pmp)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("Performance counters: ");
|
||||
counters = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMNUM) >> 4) + 1;
|
||||
bits = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMBITS) >> CPUCFG6_PMBITS_SHIFT) + 1;
|
||||
counters = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT) + 1;
|
||||
|
||||
loongarch_pmu.num_counters = counters;
|
||||
loongarch_pmu.max_period = (1ULL << 63) - 1;
|
||||
@@ -867,7 +868,7 @@ static int __init init_hw_perf_events(void)
|
||||
on_each_cpu(reset_counters, NULL, 1);
|
||||
|
||||
pr_cont("%s PMU enabled, %d %d-bit counters available to each CPU.\n",
|
||||
loongarch_pmu.name, counters, 64);
|
||||
loongarch_pmu.name, counters, bits);
|
||||
|
||||
perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
{
|
||||
unsigned long n = (unsigned long) v - 1;
|
||||
unsigned int isa = cpu_data[n].isa_level;
|
||||
unsigned int prid = cpu_data[n].processor_id;
|
||||
unsigned int version = cpu_data[n].processor_id & 0xff;
|
||||
unsigned int fp_version = cpu_data[n].fpu_vers;
|
||||
|
||||
@@ -37,6 +38,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
seq_printf(m, "global_id\t\t: %d\n", cpu_data[n].global_id);
|
||||
seq_printf(m, "CPU Family\t\t: %s\n", __cpu_family[n]);
|
||||
seq_printf(m, "Model Name\t\t: %s\n", __cpu_full_name[n]);
|
||||
seq_printf(m, "PRID\t\t\t: %s (%08x)\n", id_to_core_name(prid), prid);
|
||||
seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version);
|
||||
seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version);
|
||||
seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n",
|
||||
|
||||
@@ -294,8 +294,6 @@ static void __init fdt_setup(void)
|
||||
|
||||
early_init_dt_scan(fdt_pointer, __pa(fdt_pointer));
|
||||
early_init_fdt_reserve_self();
|
||||
|
||||
max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -390,7 +388,8 @@ static void __init check_kernel_sections_mem(void)
|
||||
static void __init arch_mem_init(char **cmdline_p)
|
||||
{
|
||||
/* Recalculate max_low_pfn for "mem=xxx" */
|
||||
max_pfn = max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
|
||||
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||
max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn);
|
||||
|
||||
if (usermem)
|
||||
pr_info("User-defined physical RAM map overwrite\n");
|
||||
|
||||
@@ -1131,8 +1131,8 @@ static void configure_exception_vector(void)
|
||||
tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE;
|
||||
|
||||
csr_write64(eentry, LOONGARCH_CSR_EENTRY);
|
||||
csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
|
||||
csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
|
||||
csr_write64(__pa(eentry), LOONGARCH_CSR_MERRENTRY);
|
||||
csr_write64(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY);
|
||||
}
|
||||
|
||||
void per_cpu_trap_init(int cpu)
|
||||
|
||||
@@ -439,7 +439,7 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
|
||||
spin_lock_irqsave(&s->lock, flags);
|
||||
switch (type) {
|
||||
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
|
||||
if (val >= EIOINTC_ROUTE_MAX_VCPUS)
|
||||
if (val > EIOINTC_ROUTE_MAX_VCPUS)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
s->num_cpu = val;
|
||||
|
||||
@@ -857,7 +857,7 @@ static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
|
||||
|
||||
if (writeable) {
|
||||
prot_bits = kvm_pte_mkwriteable(prot_bits);
|
||||
if (write)
|
||||
if (write || !kvm_slot_dirty_track_enabled(memslot))
|
||||
prot_bits = kvm_pte_mkdirty(prot_bits);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/kvm_csr.h>
|
||||
#include <asm/kvm_vcpu.h>
|
||||
|
||||
@@ -95,6 +96,7 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
|
||||
* and set CSR TVAL with -1
|
||||
*/
|
||||
write_gcsr_timertick(0);
|
||||
__delay(2); /* Wait cycles until timer interrupt injected */
|
||||
|
||||
/*
|
||||
* Writing CSR_TINTCLR_TI to LOONGARCH_CSR_TINTCLR will clear
|
||||
|
||||
@@ -132,6 +132,9 @@ static void kvm_lose_pmu(struct kvm_vcpu *vcpu)
|
||||
* Clear KVM_LARCH_PMU if the guest is not using PMU CSRs when
|
||||
* exiting the guest, so that the next time trap into the guest.
|
||||
* We don't need to deal with PMU CSRs contexts.
|
||||
*
|
||||
* Otherwise set the request bit KVM_REQ_PMU to restore guest PMU
|
||||
* before entering guest VM
|
||||
*/
|
||||
val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0);
|
||||
val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1);
|
||||
@@ -139,16 +142,12 @@ static void kvm_lose_pmu(struct kvm_vcpu *vcpu)
|
||||
val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3);
|
||||
if (!(val & KVM_PMU_EVENT_ENABLED))
|
||||
vcpu->arch.aux_inuse &= ~KVM_LARCH_PMU;
|
||||
else
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
|
||||
kvm_restore_host_pmu(vcpu);
|
||||
}
|
||||
|
||||
static void kvm_restore_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if ((vcpu->arch.aux_inuse & KVM_LARCH_PMU))
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
}
|
||||
|
||||
static void kvm_check_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_check_request(KVM_REQ_PMU, vcpu)) {
|
||||
@@ -299,7 +298,10 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu)
|
||||
vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
|
||||
|
||||
if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) {
|
||||
kvm_lose_pmu(vcpu);
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_PMU) {
|
||||
kvm_lose_pmu(vcpu);
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
}
|
||||
/* make sure the vcpu mode has been written */
|
||||
smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE);
|
||||
local_irq_enable();
|
||||
@@ -1604,9 +1606,6 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
kvm_restore_timer(vcpu);
|
||||
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
|
||||
|
||||
/* Restore hardware PMU CSRs */
|
||||
kvm_restore_pmu(vcpu);
|
||||
|
||||
/* Don't bother restoring registers multiple times unless necessary */
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_HWCSR_USABLE)
|
||||
return 0;
|
||||
|
||||
@@ -60,7 +60,6 @@ int __ref page_is_ram(unsigned long pfn)
|
||||
return memblock_is_memory(addr) && !memblock_is_reserved(addr);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NUMA
|
||||
void __init paging_init(void)
|
||||
{
|
||||
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||||
@@ -72,7 +71,6 @@ void __init paging_init(void)
|
||||
|
||||
free_area_init(max_zone_pfns);
|
||||
}
|
||||
#endif /* !CONFIG_NUMA */
|
||||
|
||||
void __ref free_initmem(void)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm-generic/early_ioremap.h>
|
||||
|
||||
void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size)
|
||||
void __init __iomem *early_ioremap(phys_addr_t phys_addr, unsigned long size)
|
||||
{
|
||||
return ((void __iomem *)TO_CACHE(phys_addr));
|
||||
}
|
||||
|
||||
@@ -1624,6 +1624,9 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
||||
/* Direct jump skips 5 NOP instructions */
|
||||
else if (is_bpf_text_address((unsigned long)orig_call))
|
||||
orig_call += LOONGARCH_BPF_FENTRY_NBYTES;
|
||||
/* Module tracing not supported - cause kernel lockups */
|
||||
else if (is_module_text_address((unsigned long)orig_call))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (flags & BPF_TRAMP_F_CALL_ORIG) {
|
||||
move_addr(ctx, LOONGARCH_GPR_A0, (const u64)im);
|
||||
|
||||
@@ -50,11 +50,11 @@ static int __init pcibios_init(void)
|
||||
*/
|
||||
lsize = cpu_last_level_cache_line_size();
|
||||
|
||||
BUG_ON(!lsize);
|
||||
if (lsize) {
|
||||
pci_dfl_cache_line_size = lsize >> 2;
|
||||
|
||||
pci_dfl_cache_line_size = lsize >> 2;
|
||||
|
||||
pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
|
||||
pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ cpus: cpus {
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips24KEc";
|
||||
compatible = "mips,mips34Kc";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -692,7 +692,7 @@ unsigned long mips_stack_top(void)
|
||||
/* Space for the VDSO, data page & GIC user page */
|
||||
if (current->thread.abi) {
|
||||
top -= PAGE_ALIGN(current->thread.abi->vdso->size);
|
||||
top -= PAGE_SIZE;
|
||||
top -= VDSO_NR_PAGES * PAGE_SIZE;
|
||||
top -= mips_gic_present() ? PAGE_SIZE : 0;
|
||||
|
||||
/* Space to randomize the VDSO base */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-type.h>
|
||||
@@ -508,54 +509,78 @@ static int __init set_ntlb(char *str)
|
||||
|
||||
__setup("ntlb=", set_ntlb);
|
||||
|
||||
/* Initialise all TLB entries with unique values */
|
||||
|
||||
/* Comparison function for EntryHi VPN fields. */
|
||||
static int r4k_vpn_cmp(const void *a, const void *b)
|
||||
{
|
||||
long v = *(unsigned long *)a - *(unsigned long *)b;
|
||||
int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0;
|
||||
return s ? (v != 0) | v >> s : v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise all TLB entries with unique values that do not clash with
|
||||
* what we have been handed over and what we'll be using ourselves.
|
||||
*/
|
||||
static void r4k_tlb_uniquify(void)
|
||||
{
|
||||
int entry = num_wired_entries();
|
||||
unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE];
|
||||
int tlbsize = current_cpu_data.tlbsize;
|
||||
int start = num_wired_entries();
|
||||
unsigned long vpn_mask;
|
||||
int cnt, ent, idx, i;
|
||||
|
||||
vpn_mask = GENMASK(cpu_vmbits - 1, 13);
|
||||
vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31;
|
||||
|
||||
htw_stop();
|
||||
|
||||
for (i = start, cnt = 0; i < tlbsize; i++, cnt++) {
|
||||
unsigned long vpn;
|
||||
|
||||
write_c0_index(i);
|
||||
mtc0_tlbr_hazard();
|
||||
tlb_read();
|
||||
tlb_read_hazard();
|
||||
vpn = read_c0_entryhi();
|
||||
vpn &= vpn_mask & PAGE_MASK;
|
||||
tlb_vpns[cnt] = vpn;
|
||||
|
||||
/* Prevent any large pages from overlapping regular ones. */
|
||||
write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK);
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_write_indexed();
|
||||
tlbw_use_hazard();
|
||||
}
|
||||
|
||||
sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL);
|
||||
|
||||
write_c0_pagemask(PM_DEFAULT_MASK);
|
||||
write_c0_entrylo0(0);
|
||||
write_c0_entrylo1(0);
|
||||
|
||||
while (entry < current_cpu_data.tlbsize) {
|
||||
unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data);
|
||||
unsigned long asid = 0;
|
||||
int idx;
|
||||
idx = 0;
|
||||
ent = tlbsize;
|
||||
for (i = start; i < tlbsize; i++)
|
||||
while (1) {
|
||||
unsigned long entryhi, vpn;
|
||||
|
||||
/* Skip wired MMID to make ginvt_mmid work */
|
||||
if (cpu_has_mmid)
|
||||
asid = MMID_KERNEL_WIRED + 1;
|
||||
entryhi = UNIQUE_ENTRYHI(ent);
|
||||
vpn = entryhi & vpn_mask & PAGE_MASK;
|
||||
|
||||
/* Check for match before using UNIQUE_ENTRYHI */
|
||||
do {
|
||||
if (cpu_has_mmid) {
|
||||
write_c0_memorymapid(asid);
|
||||
write_c0_entryhi(UNIQUE_ENTRYHI(entry));
|
||||
} else {
|
||||
write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid);
|
||||
}
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_probe();
|
||||
tlb_probe_hazard();
|
||||
idx = read_c0_index();
|
||||
/* No match or match is on current entry */
|
||||
if (idx < 0 || idx == entry)
|
||||
if (idx >= cnt || vpn < tlb_vpns[idx]) {
|
||||
write_c0_entryhi(entryhi);
|
||||
write_c0_index(i);
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_write_indexed();
|
||||
ent++;
|
||||
break;
|
||||
/*
|
||||
* If we hit a match, we need to try again with
|
||||
* a different ASID.
|
||||
*/
|
||||
asid++;
|
||||
} while (asid < asid_mask);
|
||||
|
||||
if (idx >= 0 && idx != entry)
|
||||
panic("Unable to uniquify TLB entry %d", idx);
|
||||
|
||||
write_c0_index(entry);
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_write_indexed();
|
||||
entry++;
|
||||
}
|
||||
} else if (vpn == tlb_vpns[idx]) {
|
||||
ent++;
|
||||
} else {
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
tlbw_use_hazard();
|
||||
htw_start();
|
||||
@@ -602,6 +627,7 @@ static void r4k_tlb_configure(void)
|
||||
|
||||
/* From this point on the ARC firmware is dead. */
|
||||
r4k_tlb_uniquify();
|
||||
local_flush_tlb_all();
|
||||
|
||||
/* Did I tell you that ARC SUCKS? */
|
||||
}
|
||||
|
||||
@@ -241,16 +241,22 @@ void __init prom_init(void)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the Malta max (2GB) memory for PCI DMA in host bridge
|
||||
* in transparent addressing mode.
|
||||
* Set up memory mapping in host bridge for PCI DMA masters,
|
||||
* in transparent addressing mode. For EVA use the Malta
|
||||
* maximum of 2 GiB memory in the alias space at 0x80000000
|
||||
* as per PHYS_OFFSET. Otherwise use 256 MiB of memory in
|
||||
* the regular space, avoiding mapping the PCI MMIO window
|
||||
* for DMA as it seems to confuse the system controller's
|
||||
* logic, causing PCI MMIO to stop working.
|
||||
*/
|
||||
mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH;
|
||||
MSC_WRITE(MSC01_PCI_BAR0, mask);
|
||||
MSC_WRITE(MSC01_PCI_HEAD4, mask);
|
||||
mask = PHYS_OFFSET ? PHYS_OFFSET : 0xf0000000;
|
||||
MSC_WRITE(MSC01_PCI_BAR0,
|
||||
mask | PCI_BASE_ADDRESS_MEM_PREFETCH);
|
||||
MSC_WRITE(MSC01_PCI_HEAD4,
|
||||
PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH);
|
||||
|
||||
mask &= MSC01_PCI_BAR0_SIZE_MSK;
|
||||
MSC_WRITE(MSC01_PCI_P2SCMSKL, mask);
|
||||
MSC_WRITE(MSC01_PCI_P2SCMAPL, mask);
|
||||
MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET);
|
||||
|
||||
/* Don't handle target retries indefinitely. */
|
||||
if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
|
||||
|
||||
@@ -137,6 +137,7 @@ config PPC
|
||||
select ARCH_HAS_DMA_OPS if PPC64
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
select ARCH_HAS_GIGANTIC_PAGE if ARCH_SUPPORTS_HUGETLBFS
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_KERNEL_FPU_SUPPORT if PPC64 && PPC_FPU
|
||||
select ARCH_HAS_MEMBARRIER_CALLBACKS
|
||||
|
||||
@@ -423,7 +423,6 @@ config PPC_64S_HASH_MMU
|
||||
config PPC_RADIX_MMU
|
||||
bool "Radix MMU Support"
|
||||
depends on PPC_BOOK3S_64
|
||||
select ARCH_HAS_GIGANTIC_PAGE
|
||||
default y
|
||||
help
|
||||
Enable support for the Power ISA 3.0 Radix style MMU. Currently this
|
||||
|
||||
@@ -367,7 +367,7 @@ config RISCV_NONSTANDARD_CACHE_OPS
|
||||
systems to handle cache management.
|
||||
|
||||
config AS_HAS_INSN
|
||||
def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
|
||||
def_bool $(as-instr,.insn 0x100000f)
|
||||
|
||||
config AS_HAS_OPTION_ARCH
|
||||
# https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4
|
||||
|
||||
@@ -134,21 +134,6 @@ endif
|
||||
CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS)
|
||||
|
||||
# Default target when executing plain make
|
||||
boot := arch/riscv/boot
|
||||
ifeq ($(CONFIG_XIP_KERNEL),y)
|
||||
KBUILD_IMAGE := $(boot)/xipImage
|
||||
else
|
||||
ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN_K210),yy)
|
||||
KBUILD_IMAGE := $(boot)/loader.bin
|
||||
else
|
||||
ifeq ($(CONFIG_EFI_ZBOOT),)
|
||||
KBUILD_IMAGE := $(boot)/Image.gz
|
||||
else
|
||||
KBUILD_IMAGE := $(boot)/vmlinuz.efi
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
boot := arch/riscv/boot
|
||||
boot-image-y := Image
|
||||
boot-image-$(CONFIG_KERNEL_BZIP2) := Image.bz2
|
||||
@@ -159,7 +144,7 @@ boot-image-$(CONFIG_KERNEL_LZO) := Image.lzo
|
||||
boot-image-$(CONFIG_KERNEL_ZSTD) := Image.zst
|
||||
boot-image-$(CONFIG_KERNEL_XZ) := Image.xz
|
||||
ifdef CONFIG_RISCV_M_MODE
|
||||
boot-image-$(CONFIG_ARCH_CANAAN) := loader.bin
|
||||
boot-image-$(CONFIG_SOC_CANAAN_K210) := loader.bin
|
||||
endif
|
||||
boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi
|
||||
boot-image-$(CONFIG_XIP_KERNEL) := xipImage
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#define ANDES_VENDOR_ID 0x31e
|
||||
#define MICROCHIP_VENDOR_ID 0x029
|
||||
#define MIPS_VENDOR_ID 0x127
|
||||
#define SIFIVE_VENDOR_ID 0x489
|
||||
#define THEAD_VENDOR_ID 0x5b7
|
||||
#define MIPS_VENDOR_ID 0x722
|
||||
|
||||
#endif
|
||||
|
||||
@@ -648,9 +648,9 @@ int sbi_debug_console_read(char *bytes, unsigned int num_bytes)
|
||||
|
||||
void __init sbi_init(void)
|
||||
{
|
||||
bool srst_power_off = false;
|
||||
int ret;
|
||||
|
||||
sbi_set_power_off();
|
||||
ret = sbi_get_spec_version();
|
||||
if (ret > 0)
|
||||
sbi_spec_version = ret;
|
||||
@@ -683,6 +683,7 @@ void __init sbi_init(void)
|
||||
sbi_probe_extension(SBI_EXT_SRST)) {
|
||||
pr_info("SBI SRST extension detected\n");
|
||||
register_platform_power_off(sbi_srst_power_off);
|
||||
srst_power_off = true;
|
||||
sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot;
|
||||
sbi_srst_reboot_nb.priority = 192;
|
||||
register_restart_handler(&sbi_srst_reboot_nb);
|
||||
@@ -702,4 +703,7 @@ void __init sbi_init(void)
|
||||
__sbi_send_ipi = __sbi_send_ipi_v01;
|
||||
__sbi_rfence = __sbi_rfence_v01;
|
||||
}
|
||||
|
||||
if (!srst_power_off)
|
||||
sbi_set_power_off();
|
||||
}
|
||||
|
||||
@@ -689,8 +689,20 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
|
||||
read_lock_irqsave(&imsic->vsfile_lock, flags);
|
||||
if (imsic->vsfile_cpu > -1)
|
||||
ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
|
||||
if (imsic->vsfile_cpu > -1) {
|
||||
/*
|
||||
* This function is typically called from kvm_vcpu_block() via
|
||||
* kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block()
|
||||
* can be preempted and the blocking VCPU might resume on a
|
||||
* different CPU. This means it is possible that current CPU
|
||||
* does not match the imsic->vsfile_cpu hence this function
|
||||
* must check imsic->vsfile_cpu before accessing HGEIP CSR.
|
||||
*/
|
||||
if (imsic->vsfile_cpu != vcpu->cpu)
|
||||
ret = true;
|
||||
else
|
||||
ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
|
||||
}
|
||||
read_unlock_irqrestore(&imsic->vsfile_lock, flags);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -171,7 +171,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
enum kvm_mr_change change)
|
||||
{
|
||||
hva_t hva, reg_end, size;
|
||||
gpa_t base_gpa;
|
||||
bool writable;
|
||||
int ret = 0;
|
||||
|
||||
@@ -190,15 +189,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
hva = new->userspace_addr;
|
||||
size = new->npages << PAGE_SHIFT;
|
||||
reg_end = hva + size;
|
||||
base_gpa = new->base_gfn << PAGE_SHIFT;
|
||||
writable = !(new->flags & KVM_MEM_READONLY);
|
||||
|
||||
mmap_read_lock(current->mm);
|
||||
|
||||
/*
|
||||
* A memory region could potentially cover multiple VMAs, and
|
||||
* any holes between them, so iterate over all of them to find
|
||||
* out if we can map any of them right now.
|
||||
* any holes between them, so iterate over all of them.
|
||||
*
|
||||
* +--------------------------------------------+
|
||||
* +---------------+----------------+ +----------------+
|
||||
@@ -209,7 +206,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
*/
|
||||
do {
|
||||
struct vm_area_struct *vma;
|
||||
hva_t vm_start, vm_end;
|
||||
hva_t vm_end;
|
||||
|
||||
vma = find_vma_intersection(current->mm, hva, reg_end);
|
||||
if (!vma)
|
||||
@@ -225,36 +222,18 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
}
|
||||
|
||||
/* Take the intersection of this VMA with the memory region */
|
||||
vm_start = max(hva, vma->vm_start);
|
||||
vm_end = min(reg_end, vma->vm_end);
|
||||
|
||||
if (vma->vm_flags & VM_PFNMAP) {
|
||||
gpa_t gpa = base_gpa + (vm_start - hva);
|
||||
phys_addr_t pa;
|
||||
|
||||
pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
pa += vm_start - vma->vm_start;
|
||||
|
||||
/* IO region dirty page logging not allowed */
|
||||
if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = kvm_riscv_mmu_ioremap(kvm, gpa, pa, vm_end - vm_start,
|
||||
writable, false);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
hva = vm_end;
|
||||
} while (hva < reg_end);
|
||||
|
||||
if (change == KVM_MR_FLAGS_ONLY)
|
||||
goto out;
|
||||
|
||||
if (ret)
|
||||
kvm_riscv_mmu_iounmap(kvm, base_gpa, size);
|
||||
|
||||
out:
|
||||
mmap_read_unlock(current->mm);
|
||||
return ret;
|
||||
|
||||
@@ -212,7 +212,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
|
||||
|
||||
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) &&
|
||||
return (kvm_riscv_vcpu_has_interrupts(vcpu, -1ULL) &&
|
||||
!kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1154,17 +1154,15 @@ static inline pte_t pte_mkhuge(pte_t pte)
|
||||
#define IPTE_NODAT 0x400
|
||||
#define IPTE_GUEST_ASCE 0x800
|
||||
|
||||
static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, int local)
|
||||
{
|
||||
unsigned long pto;
|
||||
|
||||
pto = __pa(ptep) & ~(PTRS_PER_PTE * sizeof(pte_t) - 1);
|
||||
asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%[asce],%[m4]"
|
||||
asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%%r0,%[m4]"
|
||||
: "+m" (*ptep)
|
||||
: [r1] "a" (pto), [r2] "a" ((addr & PAGE_MASK) | opt),
|
||||
[asce] "a" (asce), [m4] "i" (local));
|
||||
: [r1] "a" (pto), [r2] "a" (addr & PAGE_MASK),
|
||||
[m4] "i" (local));
|
||||
}
|
||||
|
||||
static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep,
|
||||
@@ -1348,7 +1346,7 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
|
||||
* A local RDP can be used to do the flush.
|
||||
*/
|
||||
if (cpu_has_rdp() && !(pte_val(*ptep) & _PAGE_PROTECT))
|
||||
__ptep_rdp(address, ptep, 0, 0, 1);
|
||||
__ptep_rdp(address, ptep, 1);
|
||||
}
|
||||
#define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault
|
||||
|
||||
|
||||
@@ -274,9 +274,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
|
||||
preempt_disable();
|
||||
atomic_inc(&mm->context.flush_count);
|
||||
if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
|
||||
__ptep_rdp(addr, ptep, 0, 0, 1);
|
||||
__ptep_rdp(addr, ptep, 1);
|
||||
else
|
||||
__ptep_rdp(addr, ptep, 0, 0, 0);
|
||||
__ptep_rdp(addr, ptep, 0);
|
||||
/*
|
||||
* PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That
|
||||
* means it is still valid and active, and must not be changed according
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user