Merge tag 'v6.6-rc1' into android-mainline
Linux 6.6-rc1 Change-Id: Ib546c774b9f655bf99270260d5ecbec13462f7e9 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -88,6 +88,11 @@ data bandwidth::
|
||||
-e ali_drw_27080/hif_rmw/ \
|
||||
-e ali_drw_27080/cycle/ -- sleep 10
|
||||
|
||||
Example usage of counting all memory read/write bandwidth by metric::
|
||||
|
||||
perf stat -M ddr_read_bandwidth.all -- sleep 10
|
||||
perf stat -M ddr_write_bandwidth.all -- sleep 10
|
||||
|
||||
The average DRAM bandwidth can be calculated as follows:
|
||||
|
||||
- Read Bandwidth = perf_hif_rd * DDRC_WIDTH * DDRC_Freq / DDRC_Cycle
|
||||
|
||||
@@ -450,6 +450,35 @@ this allows system administrators to override the
|
||||
``IA64_THREAD_UAC_NOPRINT`` ``prctl`` and avoid logs being flooded.
|
||||
|
||||
|
||||
io_uring_disabled
|
||||
=================
|
||||
|
||||
Prevents all processes from creating new io_uring instances. Enabling this
|
||||
shrinks the kernel's attack surface.
|
||||
|
||||
= ======================================================================
|
||||
0 All processes can create io_uring instances as normal. This is the
|
||||
default setting.
|
||||
1 io_uring creation is disabled (io_uring_setup() will fail with
|
||||
-EPERM) for unprivileged processes not in the io_uring_group group.
|
||||
Existing io_uring instances can still be used. See the
|
||||
documentation for io_uring_group for more information.
|
||||
2 io_uring creation is disabled for all processes. io_uring_setup()
|
||||
always fails with -EPERM. Existing io_uring instances can still be
|
||||
used.
|
||||
= ======================================================================
|
||||
|
||||
|
||||
io_uring_group
|
||||
==============
|
||||
|
||||
When io_uring_disabled is set to 1, a process must either be
|
||||
privileged (CAP_SYS_ADMIN) or be in the io_uring_group group in order
|
||||
to create an io_uring instance. If io_uring_group is set to -1 (the
|
||||
default), only processes with the CAP_SYS_ADMIN capability may create
|
||||
io_uring instances.
|
||||
|
||||
|
||||
kexec_load_disabled
|
||||
===================
|
||||
|
||||
|
||||
@@ -726,8 +726,8 @@ same as the one describe in :ref:`BTF_Type_String`.
|
||||
4.2 .BTF.ext section
|
||||
--------------------
|
||||
|
||||
The .BTF.ext section encodes func_info and line_info which needs loader
|
||||
manipulation before loading into the kernel.
|
||||
The .BTF.ext section encodes func_info, line_info and CO-RE relocations
|
||||
which needs loader manipulation before loading into the kernel.
|
||||
|
||||
The specification for .BTF.ext section is defined at ``tools/lib/bpf/btf.h``
|
||||
and ``tools/lib/bpf/btf.c``.
|
||||
@@ -745,15 +745,20 @@ The current header of .BTF.ext section::
|
||||
__u32 func_info_len;
|
||||
__u32 line_info_off;
|
||||
__u32 line_info_len;
|
||||
|
||||
/* optional part of .BTF.ext header */
|
||||
__u32 core_relo_off;
|
||||
__u32 core_relo_len;
|
||||
};
|
||||
|
||||
It is very similar to .BTF section. Instead of type/string section, it
|
||||
contains func_info and line_info section. See :ref:`BPF_Prog_Load` for details
|
||||
about func_info and line_info record format.
|
||||
contains func_info, line_info and core_relo sub-sections.
|
||||
See :ref:`BPF_Prog_Load` for details about func_info and line_info
|
||||
record format.
|
||||
|
||||
The func_info is organized as below.::
|
||||
|
||||
func_info_rec_size
|
||||
func_info_rec_size /* __u32 value */
|
||||
btf_ext_info_sec for section #1 /* func_info for section #1 */
|
||||
btf_ext_info_sec for section #2 /* func_info for section #2 */
|
||||
...
|
||||
@@ -773,7 +778,7 @@ Here, num_info must be greater than 0.
|
||||
|
||||
The line_info is organized as below.::
|
||||
|
||||
line_info_rec_size
|
||||
line_info_rec_size /* __u32 value */
|
||||
btf_ext_info_sec for section #1 /* line_info for section #1 */
|
||||
btf_ext_info_sec for section #2 /* line_info for section #2 */
|
||||
...
|
||||
@@ -787,6 +792,20 @@ kernel API, the ``insn_off`` is the instruction offset in the unit of ``struct
|
||||
bpf_insn``. For ELF API, the ``insn_off`` is the byte offset from the
|
||||
beginning of section (``btf_ext_info_sec->sec_name_off``).
|
||||
|
||||
The core_relo is organized as below.::
|
||||
|
||||
core_relo_rec_size /* __u32 value */
|
||||
btf_ext_info_sec for section #1 /* core_relo for section #1 */
|
||||
btf_ext_info_sec for section #2 /* core_relo for section #2 */
|
||||
|
||||
``core_relo_rec_size`` specifies the size of ``bpf_core_relo``
|
||||
structure when .BTF.ext is generated. All ``bpf_core_relo`` structures
|
||||
within a single ``btf_ext_info_sec`` describe relocations applied to
|
||||
section named by ``btf_ext_info_sec->sec_name_off``.
|
||||
|
||||
See :ref:`Documentation/bpf/llvm_reloc.rst <btf-co-re-relocations>`
|
||||
for more information on CO-RE relocations.
|
||||
|
||||
4.2 .BTF_ids section
|
||||
--------------------
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ that goes into great technical depth about the BPF Architecture.
|
||||
bpf_licensing
|
||||
test_debug
|
||||
clang-notes
|
||||
linux-notes
|
||||
other
|
||||
redirect
|
||||
|
||||
|
||||
@@ -240,3 +240,307 @@ The .BTF/.BTF.ext sections has R_BPF_64_NODYLD32 relocations::
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
000000000000002c 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text
|
||||
0000000000000040 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text
|
||||
|
||||
.. _btf-co-re-relocations:
|
||||
|
||||
=================
|
||||
CO-RE Relocations
|
||||
=================
|
||||
|
||||
From object file point of view CO-RE mechanism is implemented as a set
|
||||
of CO-RE specific relocation records. These relocation records are not
|
||||
related to ELF relocations and are encoded in .BTF.ext section.
|
||||
See :ref:`Documentation/bpf/btf.rst <BTF_Ext_Section>` for more
|
||||
information on .BTF.ext structure.
|
||||
|
||||
CO-RE relocations are applied to BPF instructions to update immediate
|
||||
or offset fields of the instruction at load time with information
|
||||
relevant for target kernel.
|
||||
|
||||
Field to patch is selected basing on the instruction class:
|
||||
|
||||
* For BPF_ALU, BPF_ALU64, BPF_LD `immediate` field is patched;
|
||||
* For BPF_LDX, BPF_STX, BPF_ST `offset` field is patched;
|
||||
* BPF_JMP, BPF_JMP32 instructions **should not** be patched.
|
||||
|
||||
Relocation kinds
|
||||
================
|
||||
|
||||
There are several kinds of CO-RE relocations that could be split in
|
||||
three groups:
|
||||
|
||||
* Field-based - patch instruction with field related information, e.g.
|
||||
change offset field of the BPF_LDX instruction to reflect offset
|
||||
of a specific structure field in the target kernel.
|
||||
|
||||
* Type-based - patch instruction with type related information, e.g.
|
||||
change immediate field of the BPF_ALU move instruction to 0 or 1 to
|
||||
reflect if specific type is present in the target kernel.
|
||||
|
||||
* Enum-based - patch instruction with enum related information, e.g.
|
||||
change immediate field of the BPF_LD_IMM64 instruction to reflect
|
||||
value of a specific enum literal in the target kernel.
|
||||
|
||||
The complete list of relocation kinds is represented by the following enum:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
enum bpf_core_relo_kind {
|
||||
BPF_CORE_FIELD_BYTE_OFFSET = 0, /* field byte offset */
|
||||
BPF_CORE_FIELD_BYTE_SIZE = 1, /* field size in bytes */
|
||||
BPF_CORE_FIELD_EXISTS = 2, /* field existence in target kernel */
|
||||
BPF_CORE_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */
|
||||
BPF_CORE_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */
|
||||
BPF_CORE_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */
|
||||
BPF_CORE_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */
|
||||
BPF_CORE_TYPE_ID_TARGET = 7, /* type ID in target kernel */
|
||||
BPF_CORE_TYPE_EXISTS = 8, /* type existence in target kernel */
|
||||
BPF_CORE_TYPE_SIZE = 9, /* type size in bytes */
|
||||
BPF_CORE_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */
|
||||
BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */
|
||||
BPF_CORE_TYPE_MATCHES = 12, /* type match in target kernel */
|
||||
};
|
||||
|
||||
Notes:
|
||||
|
||||
* ``BPF_CORE_FIELD_LSHIFT_U64`` and ``BPF_CORE_FIELD_RSHIFT_U64`` are
|
||||
supposed to be used to read bitfield values using the following
|
||||
algorithm:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// To read bitfield ``f`` from ``struct s``
|
||||
is_signed = relo(s->f, BPF_CORE_FIELD_SIGNED)
|
||||
off = relo(s->f, BPF_CORE_FIELD_BYTE_OFFSET)
|
||||
sz = relo(s->f, BPF_CORE_FIELD_BYTE_SIZE)
|
||||
l = relo(s->f, BPF_CORE_FIELD_LSHIFT_U64)
|
||||
r = relo(s->f, BPF_CORE_FIELD_RSHIFT_U64)
|
||||
// define ``v`` as signed or unsigned integer of size ``sz``
|
||||
v = *({s|u}<sz> *)((void *)s + off)
|
||||
v <<= l
|
||||
v >>= r
|
||||
|
||||
* The ``BPF_CORE_TYPE_MATCHES`` queries matching relation, defined as
|
||||
follows:
|
||||
|
||||
* for integers: types match if size and signedness match;
|
||||
* for arrays & pointers: target types are recursively matched;
|
||||
* for structs & unions:
|
||||
|
||||
* local members need to exist in target with the same name;
|
||||
|
||||
* for each member we recursively check match unless it is already behind a
|
||||
pointer, in which case we only check matching names and compatible kind;
|
||||
|
||||
* for enums:
|
||||
|
||||
* local variants have to have a match in target by symbolic name (but not
|
||||
numeric value);
|
||||
|
||||
* size has to match (but enum may match enum64 and vice versa);
|
||||
|
||||
* for function pointers:
|
||||
|
||||
* number and position of arguments in local type has to match target;
|
||||
* for each argument and the return value we recursively check match.
|
||||
|
||||
CO-RE Relocation Record
|
||||
=======================
|
||||
|
||||
Relocation record is encoded as the following structure:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct bpf_core_relo {
|
||||
__u32 insn_off;
|
||||
__u32 type_id;
|
||||
__u32 access_str_off;
|
||||
enum bpf_core_relo_kind kind;
|
||||
};
|
||||
|
||||
* ``insn_off`` - instruction offset (in bytes) within a code section
|
||||
associated with this relocation;
|
||||
|
||||
* ``type_id`` - BTF type ID of the "root" (containing) entity of a
|
||||
relocatable type or field;
|
||||
|
||||
* ``access_str_off`` - offset into corresponding .BTF string section.
|
||||
String interpretation depends on specific relocation kind:
|
||||
|
||||
* for field-based relocations, string encodes an accessed field using
|
||||
a sequence of field and array indices, separated by colon (:). It's
|
||||
conceptually very close to LLVM's `getelementptr <GEP_>`_ instruction's
|
||||
arguments for identifying offset to a field. For example, consider the
|
||||
following C code:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct sample {
|
||||
int a;
|
||||
int b;
|
||||
struct { int c[10]; };
|
||||
} __attribute__((preserve_access_index));
|
||||
struct sample *s;
|
||||
|
||||
* Access to ``s[0].a`` would be encoded as ``0:0``:
|
||||
|
||||
* ``0``: first element of ``s`` (as if ``s`` is an array);
|
||||
* ``0``: index of field ``a`` in ``struct sample``.
|
||||
|
||||
* Access to ``s->a`` would be encoded as ``0:0`` as well.
|
||||
* Access to ``s->b`` would be encoded as ``0:1``:
|
||||
|
||||
* ``0``: first element of ``s``;
|
||||
* ``1``: index of field ``b`` in ``struct sample``.
|
||||
|
||||
* Access to ``s[1].c[5]`` would be encoded as ``1:2:0:5``:
|
||||
|
||||
* ``1``: second element of ``s``;
|
||||
* ``2``: index of anonymous structure field in ``struct sample``;
|
||||
* ``0``: index of field ``c`` in anonymous structure;
|
||||
* ``5``: access to array element #5.
|
||||
|
||||
* for type-based relocations, string is expected to be just "0";
|
||||
|
||||
* for enum value-based relocations, string contains an index of enum
|
||||
value within its enum type;
|
||||
|
||||
* ``kind`` - one of ``enum bpf_core_relo_kind``.
|
||||
|
||||
.. _GEP: https://llvm.org/docs/LangRef.html#getelementptr-instruction
|
||||
|
||||
.. _btf_co_re_relocation_examples:
|
||||
|
||||
CO-RE Relocation Examples
|
||||
=========================
|
||||
|
||||
For the following C code:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct foo {
|
||||
int a;
|
||||
int b;
|
||||
unsigned c:15;
|
||||
} __attribute__((preserve_access_index));
|
||||
|
||||
enum bar { U, V };
|
||||
|
||||
With the following BTF definitions:
|
||||
|
||||
.. code-block::
|
||||
|
||||
...
|
||||
[2] STRUCT 'foo' size=8 vlen=2
|
||||
'a' type_id=3 bits_offset=0
|
||||
'b' type_id=3 bits_offset=32
|
||||
'c' type_id=4 bits_offset=64 bitfield_size=15
|
||||
[3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
|
||||
[4] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)
|
||||
...
|
||||
[16] ENUM 'bar' encoding=UNSIGNED size=4 vlen=2
|
||||
'U' val=0
|
||||
'V' val=1
|
||||
|
||||
Field offset relocations are generated automatically when
|
||||
``__attribute__((preserve_access_index))`` is used, for example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void alpha(struct foo *s, volatile unsigned long *g) {
|
||||
*g = s->a;
|
||||
s->a = 1;
|
||||
}
|
||||
|
||||
00 <alpha>:
|
||||
0: r3 = *(s32 *)(r1 + 0x0)
|
||||
00: CO-RE <byte_off> [2] struct foo::a (0:0)
|
||||
1: *(u64 *)(r2 + 0x0) = r3
|
||||
2: *(u32 *)(r1 + 0x0) = 0x1
|
||||
10: CO-RE <byte_off> [2] struct foo::a (0:0)
|
||||
3: exit
|
||||
|
||||
|
||||
All relocation kinds could be requested via built-in functions.
|
||||
E.g. field-based relocations:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void bravo(struct foo *s, volatile unsigned long *g) {
|
||||
*g = __builtin_preserve_field_info(s->b, 0 /* field byte offset */);
|
||||
*g = __builtin_preserve_field_info(s->b, 1 /* field byte size */);
|
||||
*g = __builtin_preserve_field_info(s->b, 2 /* field existence */);
|
||||
*g = __builtin_preserve_field_info(s->b, 3 /* field signedness */);
|
||||
*g = __builtin_preserve_field_info(s->c, 4 /* bitfield left shift */);
|
||||
*g = __builtin_preserve_field_info(s->c, 5 /* bitfield right shift */);
|
||||
}
|
||||
|
||||
20 <bravo>:
|
||||
4: r1 = 0x4
|
||||
20: CO-RE <byte_off> [2] struct foo::b (0:1)
|
||||
5: *(u64 *)(r2 + 0x0) = r1
|
||||
6: r1 = 0x4
|
||||
30: CO-RE <byte_sz> [2] struct foo::b (0:1)
|
||||
7: *(u64 *)(r2 + 0x0) = r1
|
||||
8: r1 = 0x1
|
||||
40: CO-RE <field_exists> [2] struct foo::b (0:1)
|
||||
9: *(u64 *)(r2 + 0x0) = r1
|
||||
10: r1 = 0x1
|
||||
50: CO-RE <signed> [2] struct foo::b (0:1)
|
||||
11: *(u64 *)(r2 + 0x0) = r1
|
||||
12: r1 = 0x31
|
||||
60: CO-RE <lshift_u64> [2] struct foo::c (0:2)
|
||||
13: *(u64 *)(r2 + 0x0) = r1
|
||||
14: r1 = 0x31
|
||||
70: CO-RE <rshift_u64> [2] struct foo::c (0:2)
|
||||
15: *(u64 *)(r2 + 0x0) = r1
|
||||
16: exit
|
||||
|
||||
|
||||
Type-based relocations:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void charlie(struct foo *s, volatile unsigned long *g) {
|
||||
*g = __builtin_preserve_type_info(*s, 0 /* type existence */);
|
||||
*g = __builtin_preserve_type_info(*s, 1 /* type size */);
|
||||
*g = __builtin_preserve_type_info(*s, 2 /* type matches */);
|
||||
*g = __builtin_btf_type_id(*s, 0 /* type id in this object file */);
|
||||
*g = __builtin_btf_type_id(*s, 1 /* type id in target kernel */);
|
||||
}
|
||||
|
||||
88 <charlie>:
|
||||
17: r1 = 0x1
|
||||
88: CO-RE <type_exists> [2] struct foo
|
||||
18: *(u64 *)(r2 + 0x0) = r1
|
||||
19: r1 = 0xc
|
||||
98: CO-RE <type_size> [2] struct foo
|
||||
20: *(u64 *)(r2 + 0x0) = r1
|
||||
21: r1 = 0x1
|
||||
a8: CO-RE <type_matches> [2] struct foo
|
||||
22: *(u64 *)(r2 + 0x0) = r1
|
||||
23: r1 = 0x2 ll
|
||||
b8: CO-RE <local_type_id> [2] struct foo
|
||||
25: *(u64 *)(r2 + 0x0) = r1
|
||||
26: r1 = 0x2 ll
|
||||
d0: CO-RE <target_type_id> [2] struct foo
|
||||
28: *(u64 *)(r2 + 0x0) = r1
|
||||
29: exit
|
||||
|
||||
Enum-based relocations:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void delta(struct foo *s, volatile unsigned long *g) {
|
||||
*g = __builtin_preserve_enum_value(*(enum bar *)U, 0 /* enum literal existence */);
|
||||
*g = __builtin_preserve_enum_value(*(enum bar *)V, 1 /* enum literal value */);
|
||||
}
|
||||
|
||||
f0 <delta>:
|
||||
30: r1 = 0x1 ll
|
||||
f0: CO-RE <enumval_exists> [16] enum bar::U = 0
|
||||
32: *(u64 *)(r2 + 0x0) = r1
|
||||
33: r1 = 0x1 ll
|
||||
108: CO-RE <enumval_value> [16] enum bar::V = 1
|
||||
35: *(u64 *)(r2 + 0x0) = r1
|
||||
36: exit
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
.. contents::
|
||||
.. sectnum::
|
||||
|
||||
===================================================
|
||||
BPF ABI Recommended Conventions and Guidelines v1.0
|
||||
===================================================
|
||||
|
||||
This is version 1.0 of an informational document containing recommended
|
||||
conventions and guidelines for producing portable BPF program binaries.
|
||||
|
||||
Registers and calling convention
|
||||
================================
|
||||
|
||||
BPF has 10 general purpose registers and a read-only frame pointer register,
|
||||
all of which are 64-bits wide.
|
||||
|
||||
The BPF calling convention is defined as:
|
||||
|
||||
* R0: return value from function calls, and exit value for BPF programs
|
||||
* R1 - R5: arguments for function calls
|
||||
* R6 - R9: callee saved registers that function calls will preserve
|
||||
* R10: read-only frame pointer to access stack
|
||||
|
||||
R0 - R5 are scratch registers and BPF programs needs to spill/fill them if
|
||||
necessary across calls.
|
||||
@@ -12,7 +12,7 @@ for the working group charter, documents, and more.
|
||||
:maxdepth: 1
|
||||
|
||||
instruction-set
|
||||
linux-notes
|
||||
abi
|
||||
|
||||
.. Links:
|
||||
.. _IETF BPF Working Group: https://datatracker.ietf.org/wg/bpf/about/
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
.. contents::
|
||||
.. sectnum::
|
||||
|
||||
========================================
|
||||
eBPF Instruction Set Specification, v1.0
|
||||
========================================
|
||||
=======================================
|
||||
BPF Instruction Set Specification, v1.0
|
||||
=======================================
|
||||
|
||||
This document specifies version 1.0 of the eBPF instruction set.
|
||||
This document specifies version 1.0 of the BPF instruction set.
|
||||
|
||||
Documentation conventions
|
||||
=========================
|
||||
@@ -97,26 +97,10 @@ Definitions
|
||||
A: 10000110
|
||||
B: 11111111 10000110
|
||||
|
||||
Registers and calling convention
|
||||
================================
|
||||
|
||||
eBPF has 10 general purpose registers and a read-only frame pointer register,
|
||||
all of which are 64-bits wide.
|
||||
|
||||
The eBPF calling convention is defined as:
|
||||
|
||||
* R0: return value from function calls, and exit value for eBPF programs
|
||||
* R1 - R5: arguments for function calls
|
||||
* R6 - R9: callee saved registers that function calls will preserve
|
||||
* R10: read-only frame pointer to access stack
|
||||
|
||||
R0 - R5 are scratch registers and eBPF programs needs to spill/fill them if
|
||||
necessary across calls.
|
||||
|
||||
Instruction encoding
|
||||
====================
|
||||
|
||||
eBPF has two instruction encodings:
|
||||
BPF has two instruction encodings:
|
||||
|
||||
* the basic instruction encoding, which uses 64 bits to encode an instruction
|
||||
* the wide instruction encoding, which appends a second 64-bit immediate (i.e.,
|
||||
@@ -260,7 +244,7 @@ BPF_END 0xd0 0 byte swap operations (see `Byte swap instructions`_ b
|
||||
========= ===== ======= ==========================================================
|
||||
|
||||
Underflow and overflow are allowed during arithmetic operations, meaning
|
||||
the 64-bit or 32-bit value will wrap. If eBPF program execution would
|
||||
the 64-bit or 32-bit value will wrap. If BPF program execution would
|
||||
result in division by zero, the destination register is instead set to zero.
|
||||
If execution would result in modulo by zero, for ``BPF_ALU64`` the value of
|
||||
the destination register is unchanged whereas for ``BPF_ALU`` the upper
|
||||
@@ -373,7 +357,7 @@ BPF_JNE 0x5 any PC += offset if dst != src
|
||||
BPF_JSGT 0x6 any PC += offset if dst > src signed
|
||||
BPF_JSGE 0x7 any PC += offset if dst >= src signed
|
||||
BPF_CALL 0x8 0x0 call helper function by address see `Helper functions`_
|
||||
BPF_CALL 0x8 0x1 call PC += offset see `Program-local functions`_
|
||||
BPF_CALL 0x8 0x1 call PC += imm see `Program-local functions`_
|
||||
BPF_CALL 0x8 0x2 call helper function by BTF ID see `Helper functions`_
|
||||
BPF_EXIT 0x9 0x0 return BPF_JMP only
|
||||
BPF_JLT 0xa any PC += offset if dst < src unsigned
|
||||
@@ -382,7 +366,7 @@ BPF_JSLT 0xc any PC += offset if dst < src signed
|
||||
BPF_JSLE 0xd any PC += offset if dst <= src signed
|
||||
======== ===== === =========================================== =========================================
|
||||
|
||||
The eBPF program needs to store the return value into register R0 before doing a
|
||||
The BPF program needs to store the return value into register R0 before doing a
|
||||
``BPF_EXIT``.
|
||||
|
||||
Example:
|
||||
@@ -424,8 +408,8 @@ Program-local functions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Program-local functions are functions exposed by the same BPF program as the
|
||||
caller, and are referenced by offset from the call instruction, similar to
|
||||
``BPF_JA``. A ``BPF_EXIT`` within the program-local function will return to
|
||||
the caller.
|
||||
``BPF_JA``. The offset is encoded in the imm field of the call instruction.
|
||||
A ``BPF_EXIT`` within the program-local function will return to the caller.
|
||||
|
||||
Load and store instructions
|
||||
===========================
|
||||
@@ -502,9 +486,9 @@ Atomic operations
|
||||
|
||||
Atomic operations are operations that operate on memory and can not be
|
||||
interrupted or corrupted by other access to the same memory region
|
||||
by other eBPF programs or means outside of this specification.
|
||||
by other BPF programs or means outside of this specification.
|
||||
|
||||
All atomic operations supported by eBPF are encoded as store operations
|
||||
All atomic operations supported by BPF are encoded as store operations
|
||||
that use the ``BPF_ATOMIC`` mode modifier as follows:
|
||||
|
||||
* ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations
|
||||
@@ -594,7 +578,7 @@ where
|
||||
Maps
|
||||
~~~~
|
||||
|
||||
Maps are shared memory regions accessible by eBPF programs on some platforms.
|
||||
Maps are shared memory regions accessible by BPF programs on some platforms.
|
||||
A map can have various semantics as defined in a separate document, and may or
|
||||
may not have a single contiguous memory region, but the 'map_val(map)' is
|
||||
currently only defined for maps that do have a single contiguous memory region.
|
||||
@@ -616,6 +600,6 @@ identified by the given id.
|
||||
Legacy BPF Packet access instructions
|
||||
-------------------------------------
|
||||
|
||||
eBPF previously introduced special instructions for access to packet data that were
|
||||
BPF previously introduced special instructions for access to packet data that were
|
||||
carried over from classic BPF. However, these instructions are
|
||||
deprecated and should no longer be used.
|
||||
|
||||
@@ -41,8 +41,8 @@ Support
|
||||
Architectures
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Generic KASAN is supported on x86_64, arm, arm64, powerpc, riscv, s390, and
|
||||
xtensa, and the tag-based KASAN modes are supported only on arm64.
|
||||
Generic KASAN is supported on x86_64, arm, arm64, powerpc, riscv, s390, xtensa,
|
||||
and loongarch, and the tag-based KASAN modes are supported only on arm64.
|
||||
|
||||
Compilers
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright (C) 2023 Renesas Electronics Corp.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/cache/andestech,ax45mp-cache.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Andestech AX45MP L2 Cache Controller
|
||||
|
||||
maintainers:
|
||||
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
|
||||
|
||||
description:
|
||||
A level-2 cache (L2C) is used to improve the system performance by providing
|
||||
a large amount of cache line entries and reasonable access delays. The L2C
|
||||
is shared between cores, and a non-inclusive non-exclusive policy is used.
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- andestech,ax45mp-cache
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: andestech,ax45mp-cache
|
||||
- const: cache
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
cache-line-size:
|
||||
const: 64
|
||||
|
||||
cache-level:
|
||||
const: 2
|
||||
|
||||
cache-sets:
|
||||
const: 1024
|
||||
|
||||
cache-size:
|
||||
enum: [131072, 262144, 524288, 1048576, 2097152]
|
||||
|
||||
cache-unified: true
|
||||
|
||||
next-level-cache: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- cache-line-size
|
||||
- cache-level
|
||||
- cache-sets
|
||||
- cache-size
|
||||
- cache-unified
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
cache-controller@2010000 {
|
||||
compatible = "andestech,ax45mp-cache", "cache";
|
||||
reg = <0x13400000 0x100000>;
|
||||
interrupts = <508 IRQ_TYPE_LEVEL_HIGH>;
|
||||
cache-line-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-sets = <1024>;
|
||||
cache-size = <262144>;
|
||||
cache-unified;
|
||||
};
|
||||
@@ -269,6 +269,7 @@ examples:
|
||||
port {
|
||||
ov7251_ep: endpoint {
|
||||
data-lanes = <0 1>;
|
||||
link-frequencies = /bits/ 64 <240000000 319200000>;
|
||||
remote-endpoint = <&csiphy3_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -135,9 +135,10 @@ patternProperties:
|
||||
minimum: 0x1
|
||||
maximum: 0xff
|
||||
description: |
|
||||
Dynamic address to be assigned to this device. This property is only
|
||||
valid if the I3C device has a static address (first cell of the reg
|
||||
property != 0).
|
||||
Dynamic address to be assigned to this device. In case static address is
|
||||
present (first cell of the reg property != 0), this address is assigned
|
||||
through SETDASA. If static address is not present, this address is assigned
|
||||
through SETNEWDA after assigning a temporary address via ENTDAA.
|
||||
|
||||
required:
|
||||
- reg
|
||||
@@ -163,12 +164,18 @@ examples:
|
||||
pagesize = <0x8>;
|
||||
};
|
||||
|
||||
/* I3C device with a static I2C address. */
|
||||
/* I3C device with a static I2C address and assigned address. */
|
||||
thermal_sensor: sensor@68,39200144004 {
|
||||
reg = <0x68 0x392 0x144004>;
|
||||
assigned-address = <0xa>;
|
||||
};
|
||||
|
||||
/* I3C device with only assigned address. */
|
||||
pressure_sensor: sensor@0,39200124004 {
|
||||
reg = <0x0 0x392 0x124000>;
|
||||
assigned-address = <0xc>;
|
||||
};
|
||||
|
||||
/*
|
||||
* I3C device without a static I2C address but requiring
|
||||
* resources described in the DT.
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
$id: http://devicetree.org/schemas/input/azoteq,iqs7222.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Azoteq IQS7222A/B/C Capacitive Touch Controller
|
||||
title: Azoteq IQS7222A/B/C/D Capacitive Touch Controller
|
||||
|
||||
maintainers:
|
||||
- Jeff LaBundy <jeff@labundy.com>
|
||||
|
||||
description: |
|
||||
The Azoteq IQS7222A, IQS7222B and IQS7222C are multichannel capacitive touch
|
||||
controllers that feature additional sensing capabilities.
|
||||
The Azoteq IQS7222A, IQS7222B, IQS7222C and IQS7222D are multichannel
|
||||
capacitive touch controllers that feature additional sensing capabilities.
|
||||
|
||||
Link to datasheets: https://www.azoteq.com/
|
||||
|
||||
@@ -21,6 +21,7 @@ properties:
|
||||
- azoteq,iqs7222a
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
- azoteq,iqs7222d
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -173,6 +174,152 @@ properties:
|
||||
maximum: 3000
|
||||
description: Specifies the report rate (in ms) during ultra-low-power mode.
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
touchscreen-inverted-y: true
|
||||
touchscreen-swapped-x-y: true
|
||||
|
||||
trackpad:
|
||||
type: object
|
||||
description: Represents all channels associated with the trackpad.
|
||||
|
||||
properties:
|
||||
azoteq,channel-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 13
|
||||
description:
|
||||
Specifies the order of the channels that participate in the trackpad.
|
||||
Specify 255 to omit a given channel for the purpose of mapping a non-
|
||||
rectangular trackpad.
|
||||
|
||||
azoteq,num-rows:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 12
|
||||
description: Specifies the number of rows that comprise the trackpad.
|
||||
|
||||
azoteq,num-cols:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 12
|
||||
description: Specifies the number of columns that comprise the trackpad.
|
||||
|
||||
azoteq,top-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 4
|
||||
minimum: 0
|
||||
maximum: 1020
|
||||
description:
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is no longer applied.
|
||||
|
||||
azoteq,bottom-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description:
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is linearly reduced.
|
||||
|
||||
azoteq,use-prox:
|
||||
type: boolean
|
||||
description:
|
||||
Directs the trackpad to respond to the proximity states of the
|
||||
selected channels instead of their corresponding touch states.
|
||||
Note the trackpad cannot report granular coordinates during a
|
||||
state of proximity.
|
||||
|
||||
patternProperties:
|
||||
"^azoteq,lower-cal-(x|y)$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's lower starting points.
|
||||
|
||||
"^azoteq,upper-cal-(x|y)$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's upper starting points.
|
||||
|
||||
"^event-(press|tap|(swipe|flick)-(x|y)-(pos|neg))$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a press or gesture event reported by the trackpad. Specify
|
||||
'linux,code' under the press event to report absolute coordinates.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
azoteq,gesture-angle-tighten:
|
||||
type: boolean
|
||||
description:
|
||||
Limits the tangent of the gesture angle to 0.5 (axial gestures
|
||||
only). If specified in one direction, the effect is applied in
|
||||
either direction.
|
||||
|
||||
azoteq,gesture-max-ms:
|
||||
multipleOf: 16
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the length of time (in ms) within which a tap, swipe
|
||||
or flick gesture must be completed in order to be acknowledged
|
||||
by the device. The number specified for any one swipe or flick
|
||||
gesture applies to all other swipe or flick gestures.
|
||||
|
||||
azoteq,gesture-min-ms:
|
||||
multipleOf: 16
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the length of time (in ms) for which a tap gesture must
|
||||
be held in order to be acknowledged by the device.
|
||||
|
||||
azoteq,gesture-dist:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the distance (in coordinates) across which a swipe or
|
||||
flick gesture must travel in order to be acknowledged by the
|
||||
device. The number specified for any one swipe or flick gesture
|
||||
applies to all remaining swipe or flick gestures.
|
||||
|
||||
For tap gestures, this property specifies the distance from the
|
||||
original point of contact across which the contact is permitted
|
||||
to travel before the gesture is rejected by the device.
|
||||
|
||||
azoteq,gpio-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
trackpad gesture).
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- azoteq,channel-select
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^cycle-[0-9]$":
|
||||
type: object
|
||||
@@ -288,6 +435,10 @@ patternProperties:
|
||||
Activates the reference channel in response to proximity events
|
||||
instead of touch events.
|
||||
|
||||
azoteq,counts-filt-enable:
|
||||
type: boolean
|
||||
description: Applies counts filtering to the channel.
|
||||
|
||||
azoteq,ati-band:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3]
|
||||
@@ -432,12 +583,12 @@ patternProperties:
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3 (IQS7222C only)
|
||||
2: GPIO4 (IQS7222C only)
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
slider gesture).
|
||||
slider/trackpad gesture).
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@@ -521,16 +672,16 @@ patternProperties:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the speed of movement after which coordinate filtering is
|
||||
no longer applied.
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is no longer applied.
|
||||
|
||||
azoteq,bottom-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description:
|
||||
Specifies the speed of movement after which coordinate filtering is
|
||||
linearly reduced.
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is linearly reduced.
|
||||
|
||||
azoteq,bottom-beta:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@@ -595,10 +746,10 @@ patternProperties:
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the distance across which a swipe or flick gesture must
|
||||
travel in order to be acknowledged by the device. The number spec-
|
||||
ified for any one swipe or flick gesture applies to all remaining
|
||||
swipe or flick gestures.
|
||||
Specifies the distance (in coordinates) across which a swipe or
|
||||
flick gesture must travel in order to be acknowledged by the
|
||||
device. The number specified for any one swipe or flick gesture
|
||||
applies to all remaining swipe or flick gestures.
|
||||
|
||||
azoteq,gpio-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
@@ -610,8 +761,8 @@ patternProperties:
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3 (IQS7222C only)
|
||||
2: GPIO4 (IQS7222C only)
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
@@ -629,8 +780,8 @@ patternProperties:
|
||||
description: |
|
||||
Represents a GPIO mapped to one or more events as follows:
|
||||
gpio-0: GPIO0
|
||||
gpio-1: GPIO3 (IQS7222C only)
|
||||
gpio-2: GPIO4 (IQS7222C only)
|
||||
gpio-1: GPIO3
|
||||
gpio-2: GPIO4
|
||||
|
||||
allOf:
|
||||
- $ref: ../pinctrl/pincfg-node.yaml#
|
||||
@@ -641,11 +792,53 @@ patternProperties:
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: touchscreen/touchscreen.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7222b
|
||||
enum:
|
||||
- azoteq,iqs7222a
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
|
||||
then:
|
||||
properties:
|
||||
touchscreen-size-x: false
|
||||
touchscreen-size-y: false
|
||||
touchscreen-inverted-x: false
|
||||
touchscreen-inverted-y: false
|
||||
touchscreen-swapped-x-y: false
|
||||
|
||||
trackpad: false
|
||||
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,counts-filt-enable: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,ulp-allow: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222d
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
@@ -657,13 +850,22 @@ allOf:
|
||||
properties:
|
||||
azoteq,ref-select: false
|
||||
|
||||
"^slider-[0-1]$": false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7222b
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
patternProperties:
|
||||
"^event-(prox|touch)$":
|
||||
properties:
|
||||
azoteq,gpio-select: false
|
||||
|
||||
"^slider-[0-1]$": false
|
||||
|
||||
"^gpio-[0-2]$": false
|
||||
|
||||
- if:
|
||||
@@ -704,10 +906,6 @@ allOf:
|
||||
|
||||
else:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,ulp-allow: false
|
||||
|
||||
"^slider-[0-1]$":
|
||||
patternProperties:
|
||||
"^event-(press|tap|(swipe|flick)-(pos|neg))$":
|
||||
|
||||
@@ -0,0 +1,769 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/touchscreen/azoteq,iqs7211.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Azoteq IQS7210A/7211A/E Trackpad/Touchscreen Controller
|
||||
|
||||
maintainers:
|
||||
- Jeff LaBundy <jeff@labundy.com>
|
||||
|
||||
description: |
|
||||
The Azoteq IQS7210A, IQS7211A and IQS7211E trackpad and touchscreen control-
|
||||
lers employ projected-capacitance sensing and can track two contacts.
|
||||
|
||||
Link to datasheets: https://www.azoteq.com/
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- azoteq,iqs7210a
|
||||
- azoteq,iqs7211a
|
||||
- azoteq,iqs7211e
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
irq-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Specifies the GPIO connected to the device's active-low RDY output. The
|
||||
pin doubles as the IQS7211E's active-low MCLR input, in which case this
|
||||
GPIO must be configured as open-drain.
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Specifies the GPIO connected to the device's active-low MCLR input. The
|
||||
device is temporarily held in hardware reset prior to initialization if
|
||||
this property is present.
|
||||
|
||||
azoteq,forced-comms:
|
||||
type: boolean
|
||||
description:
|
||||
Enables forced communication; to be used with host adapters that cannot
|
||||
tolerate clock stretching.
|
||||
|
||||
azoteq,forced-comms-default:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
Indicates if the device's OTP memory enables (1) or disables (0) forced
|
||||
communication by default. Specifying this property can expedite startup
|
||||
time if the default value is known.
|
||||
|
||||
If this property is not specified, communication is not initiated until
|
||||
the device asserts its RDY pin shortly after exiting hardware reset. At
|
||||
that point, forced communication is either enabled or disabled based on
|
||||
the presence or absence of the 'azoteq,forced-comms' property.
|
||||
|
||||
azoteq,rate-active-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during active mode.
|
||||
|
||||
azoteq,rate-touch-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during idle-touch mode.
|
||||
|
||||
azoteq,rate-idle-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during idle mode.
|
||||
|
||||
azoteq,rate-lp1-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during low-power mode 1.
|
||||
|
||||
azoteq,rate-lp2-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during low-power mode 2.
|
||||
|
||||
azoteq,timeout-active-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from active mode to idle or idle-touch modes.
|
||||
|
||||
azoteq,timeout-touch-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from idle-touch mode to idle mode.
|
||||
|
||||
azoteq,timeout-idle-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from idle mode to low-power mode 1.
|
||||
|
||||
azoteq,timeout-lp1-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from low-power mode 1 to low-power mode 2.
|
||||
|
||||
azoteq,timeout-lp2-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the rate (in ms) at which the trackpad reference values
|
||||
are updated during low-power modes 1 and 2.
|
||||
|
||||
azoteq,timeout-ati-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the delay (in ms) before the automatic tuning implementation
|
||||
(ATI) is retried in the event it fails to complete.
|
||||
|
||||
azoteq,timeout-comms-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the delay (in ms) before a communication window is closed.
|
||||
|
||||
azoteq,timeout-press-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait before automatically
|
||||
releasing a press event. Specify zero to allow the press state to
|
||||
persist indefinitely.
|
||||
|
||||
azoteq,fosc-freq:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the device's core clock frequency as follows:
|
||||
0: 14 MHz
|
||||
1: 18 MHz
|
||||
|
||||
azoteq,fosc-trim:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the device's core clock frequency trim.
|
||||
|
||||
azoteq,num-contacts:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
default: 0
|
||||
description: Specifies the number of contacts reported by the device.
|
||||
|
||||
azoteq,contact-split:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the contact (finger) split factor.
|
||||
|
||||
azoteq,trim-x:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the horizontal trim width.
|
||||
|
||||
azoteq,trim-y:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the vertical trim height.
|
||||
|
||||
trackpad:
|
||||
type: object
|
||||
description: Represents all channels associated with the trackpad.
|
||||
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
Specifies the order of the CRx pin(s) associated with the trackpad.
|
||||
|
||||
azoteq,tx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 11
|
||||
description:
|
||||
Specifies the order of the CTx pin(s) associated with the trackpad.
|
||||
|
||||
azoteq,channel-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 36
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: |
|
||||
Specifies the channels mapped to each cycle in the following order:
|
||||
Cycle 0, slot 0
|
||||
Cycle 0, slot 1
|
||||
Cycle 1, slot 0
|
||||
Cycle 1, slot 1
|
||||
...and so on. Specify 255 to disable a given slot.
|
||||
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the trackpad's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the trackpad's ATI target.
|
||||
|
||||
azoteq,touch-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's touch entrance factor.
|
||||
|
||||
azoteq,touch-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's touch exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's stationary touch threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's conversion frequency fraction.
|
||||
|
||||
patternProperties:
|
||||
"^event-(tap(-double|-triple)?|hold|palm|swipe-(x|y)-(pos|neg)(-hold)?)$":
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description:
|
||||
Represents a gesture event reported by the trackpad. In the case of
|
||||
axial gestures, the duration or distance specified in one direction
|
||||
applies to both directions along the same axis.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
azoteq,gesture-max-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the maximum duration of tap/swipe gestures.
|
||||
|
||||
azoteq,gesture-mid-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the maximum duration between subsequent tap gestures
|
||||
(IQS7211E only).
|
||||
|
||||
azoteq,gesture-min-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the minimum duration of hold gestures.
|
||||
|
||||
azoteq,gesture-dist:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the minimum (swipe) or maximum (tap and hold) distance
|
||||
a finger may travel to be considered a gesture.
|
||||
|
||||
azoteq,gesture-dist-rep:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the minimum distance a finger must travel to elicit a
|
||||
repeated swipe gesture (IQS7211E only).
|
||||
|
||||
azoteq,gesture-angle:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 75
|
||||
description:
|
||||
Specifies the maximum angle (in degrees) a finger may travel to
|
||||
be considered a swipe gesture.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 42
|
||||
description: Specifies the palm gesture threshold (IQS7211E only).
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
dependencies:
|
||||
azoteq,rx-enable: ["azoteq,tx-enable"]
|
||||
azoteq,tx-enable: ["azoteq,rx-enable"]
|
||||
azoteq,channel-select: ["azoteq,rx-enable"]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
alp:
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description: Represents the alternate low-power channel (ALP).
|
||||
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
Specifies the CRx pin(s) associated with the ALP in no particular
|
||||
order.
|
||||
|
||||
azoteq,tx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 11
|
||||
description:
|
||||
Specifies the CTx pin(s) associated with the ALP in no particular
|
||||
order.
|
||||
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the ALP's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the ALP's ATI target.
|
||||
|
||||
azoteq,ati-base:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 8
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's ATI base.
|
||||
|
||||
azoteq,ati-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the ALP's ATI mode as follows:
|
||||
0: Partial
|
||||
1: Full
|
||||
|
||||
azoteq,sense-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the ALP's sensing mode as follows:
|
||||
0: Self capacitive
|
||||
1: Mutual capacitive
|
||||
|
||||
azoteq,debounce-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's debounce entrance factor.
|
||||
|
||||
azoteq,debounce-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's debounce exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the ALP's proximity or touch threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's conversion frequency fraction.
|
||||
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
button:
|
||||
type: object
|
||||
description: Represents the inductive or capacitive button.
|
||||
|
||||
properties:
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the button's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the button's ATI target.
|
||||
|
||||
azoteq,ati-base:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 8
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's ATI base.
|
||||
|
||||
azoteq,ati-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the button's ATI mode as follows:
|
||||
0: Partial
|
||||
1: Full
|
||||
|
||||
azoteq,sense-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description: |
|
||||
Specifies the button's sensing mode as follows:
|
||||
0: Self capacitive
|
||||
1: Mutual capacitive
|
||||
2: Inductive
|
||||
|
||||
azoteq,touch-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's touch entrance factor.
|
||||
|
||||
azoteq,touch-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's touch exit factor.
|
||||
|
||||
azoteq,debounce-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's debounce entrance factor.
|
||||
|
||||
azoteq,debounce-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's debounce exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the button's proximity threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's conversion frequency fraction.
|
||||
|
||||
patternProperties:
|
||||
"^event-(prox|touch)$":
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description:
|
||||
Represents a proximity or touch event reported by the button.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
touchscreen-inverted-y: true
|
||||
touchscreen-swapped-x-y: true
|
||||
|
||||
dependencies:
|
||||
touchscreen-size-x: ["azoteq,num-contacts"]
|
||||
touchscreen-size-y: ["azoteq,num-contacts"]
|
||||
touchscreen-inverted-x: ["azoteq,num-contacts"]
|
||||
touchscreen-inverted-y: ["azoteq,num-contacts"]
|
||||
touchscreen-swapped-x-y: ["azoteq,num-contacts"]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- irq-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: touchscreen.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7210a
|
||||
|
||||
then:
|
||||
properties:
|
||||
alp:
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
maxItems: 4
|
||||
items:
|
||||
minimum: 4
|
||||
|
||||
else:
|
||||
properties:
|
||||
azoteq,timeout-press-ms: false
|
||||
|
||||
alp:
|
||||
properties:
|
||||
azoteq,ati-mode: false
|
||||
|
||||
button: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7211e
|
||||
|
||||
then:
|
||||
properties:
|
||||
reset-gpios: false
|
||||
|
||||
trackpad:
|
||||
properties:
|
||||
azoteq,tx-enable:
|
||||
maxItems: 13
|
||||
items:
|
||||
maximum: 12
|
||||
|
||||
alp:
|
||||
properties:
|
||||
azoteq,tx-enable:
|
||||
maxItems: 13
|
||||
items:
|
||||
maximum: 12
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
touch@56 {
|
||||
compatible = "azoteq,iqs7210a";
|
||||
reg = <0x56>;
|
||||
irq-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||
reset-gpios = <&gpio 17 (GPIO_ACTIVE_LOW |
|
||||
GPIO_PUSH_PULL)>;
|
||||
azoteq,num-contacts = <2>;
|
||||
|
||||
trackpad {
|
||||
azoteq,rx-enable = <6>, <5>, <4>, <3>, <2>;
|
||||
azoteq,tx-enable = <1>, <7>, <8>, <9>, <10>;
|
||||
};
|
||||
|
||||
button {
|
||||
azoteq,sense-mode = <2>;
|
||||
azoteq,touch-enter = <40>;
|
||||
azoteq,touch-exit = <36>;
|
||||
|
||||
event-touch {
|
||||
linux,code = <KEY_HOME>;
|
||||
};
|
||||
};
|
||||
|
||||
alp {
|
||||
azoteq,sense-mode = <1>;
|
||||
linux,code = <KEY_POWER>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
touch@56 {
|
||||
compatible = "azoteq,iqs7211e";
|
||||
reg = <0x56>;
|
||||
irq-gpios = <&gpio 4 (GPIO_ACTIVE_LOW |
|
||||
GPIO_OPEN_DRAIN)>;
|
||||
|
||||
trackpad {
|
||||
event-tap {
|
||||
linux,code = <KEY_PLAYPAUSE>;
|
||||
};
|
||||
|
||||
event-tap-double {
|
||||
linux,code = <KEY_SHUFFLE>;
|
||||
};
|
||||
|
||||
event-tap-triple {
|
||||
linux,code = <KEY_AGAIN>;
|
||||
};
|
||||
|
||||
event-hold {
|
||||
linux,code = <KEY_STOP>;
|
||||
};
|
||||
|
||||
event-palm {
|
||||
linux,code = <KEY_EXIT>;
|
||||
};
|
||||
|
||||
event-swipe-x-pos {
|
||||
linux,code = <KEY_REWIND>;
|
||||
};
|
||||
|
||||
event-swipe-x-pos-hold {
|
||||
linux,code = <KEY_PREVIOUS>;
|
||||
};
|
||||
|
||||
event-swipe-x-neg {
|
||||
linux,code = <KEY_FASTFORWARD>;
|
||||
};
|
||||
|
||||
event-swipe-x-neg-hold {
|
||||
linux,code = <KEY_NEXT>;
|
||||
};
|
||||
|
||||
event-swipe-y-pos {
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
};
|
||||
|
||||
event-swipe-y-pos-hold {
|
||||
linux,code = <KEY_MUTE>;
|
||||
};
|
||||
|
||||
event-swipe-y-neg {
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
};
|
||||
|
||||
event-swipe-y-neg-hold {
|
||||
linux,code = <KEY_MUTE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -93,6 +93,12 @@ properties:
|
||||
minimum: 1
|
||||
maximum: 255
|
||||
|
||||
threshold:
|
||||
description: Allows setting the "click"-threshold in the range from 0 to 255.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-fuzz-x: true
|
||||
|
||||
@@ -24,6 +24,8 @@ properties:
|
||||
maxItems: 1
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
vdd-supply:
|
||||
description: Power supply regulator for the chip
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
|
||||
@@ -52,6 +52,11 @@ properties:
|
||||
touchscreen-swapped-x-y: true
|
||||
touchscreen-max-pressure: true
|
||||
|
||||
linux,keycodes:
|
||||
description: Keycodes for the touch keys
|
||||
minItems: 1
|
||||
maxItems: 15
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
STMicroelectronics STi System Configuration Controlled IRQs
|
||||
-----------------------------------------------------------
|
||||
|
||||
On STi based systems; External, CTI (Core Sight), PMU (Performance Management),
|
||||
and PL310 L2 Cache IRQs are controlled using System Configuration registers.
|
||||
This driver is used to unmask them prior to use.
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "st,stih407-irq-syscfg"
|
||||
- st,syscfg : Phandle to Cortex-A9 IRQ system config registers
|
||||
- st,irq-device : Array of IRQs to enable - should be 2 in length
|
||||
- st,fiq-device : Array of FIQs to enable - should be 2 in length
|
||||
|
||||
Optional properties:
|
||||
- st,invert-ext : External IRQs can be inverted at will. This property inverts
|
||||
these IRQs using bitwise logic. A number of defines have been
|
||||
provided for convenience:
|
||||
ST_IRQ_SYSCFG_EXT_1_INV
|
||||
ST_IRQ_SYSCFG_EXT_2_INV
|
||||
ST_IRQ_SYSCFG_EXT_3_INV
|
||||
Example:
|
||||
|
||||
irq-syscfg {
|
||||
compatible = "st,stih407-irq-syscfg";
|
||||
st,syscfg = <&syscfg_cpu>;
|
||||
st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
|
||||
<ST_IRQ_SYSCFG_PMU_1>;
|
||||
st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
|
||||
<ST_IRQ_SYSCFG_DISABLED>;
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/interrupt-controller/st,stih407-irq-syscfg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STi System Configuration Controlled IRQs
|
||||
|
||||
maintainers:
|
||||
- Patrice Chotard <patrice.chotard@foss.st.com>
|
||||
|
||||
description:
|
||||
On STi based systems; External, CTI (Core Sight), PMU (Performance
|
||||
Management), and PL310 L2 Cache IRQs are controlled using System
|
||||
Configuration registers. This device is used to unmask them prior to use.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stih407-irq-syscfg
|
||||
|
||||
st,syscfg:
|
||||
description: Phandle to Cortex-A9 IRQ system config registers
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
st,irq-device:
|
||||
description: Array of IRQs to enable.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: Enable the IRQ of the channel one.
|
||||
- description: Enable the IRQ of the channel two.
|
||||
|
||||
st,fiq-device:
|
||||
description: Array of FIQs to enable.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: Enable the IRQ of the channel one.
|
||||
- description: Enable the IRQ of the channel two.
|
||||
|
||||
st,invert-ext:
|
||||
description: External IRQs can be inverted at will. This property inverts
|
||||
these three IRQs using bitwise logic, each one being encoded respectively
|
||||
on the first, second and fourth bit.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 1, 2, 3, 4, 5, 6 ]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- st,syscfg
|
||||
- st,irq-device
|
||||
- st,fiq-device
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq-st.h>
|
||||
irq-syscfg {
|
||||
compatible = "st,stih407-irq-syscfg";
|
||||
st,syscfg = <&syscfg_cpu>;
|
||||
st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
|
||||
<ST_IRQ_SYSCFG_PMU_1>;
|
||||
st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
|
||||
<ST_IRQ_SYSCFG_DISABLED>;
|
||||
};
|
||||
...
|
||||
@@ -1,41 +0,0 @@
|
||||
* Omnivision OV5695 MIPI CSI-2 sensor
|
||||
|
||||
Required Properties:
|
||||
- compatible: shall be "ovti,ov5695"
|
||||
- clocks: reference to the xvclk input clock
|
||||
- clock-names: shall be "xvclk"
|
||||
- avdd-supply: Analog voltage supply, 2.8 volts
|
||||
- dovdd-supply: Digital I/O voltage supply, 1.8 volts
|
||||
- dvdd-supply: Digital core voltage supply, 1.2 volts
|
||||
- reset-gpios: Low active reset gpio
|
||||
|
||||
The device node shall contain one 'port' child node with an
|
||||
'endpoint' subnode for its digital output video port,
|
||||
in accordance with the video interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
The endpoint optional property 'data-lanes' shall be "<1 2>".
|
||||
|
||||
Example:
|
||||
&i2c7 {
|
||||
ov5695: camera-sensor@36 {
|
||||
compatible = "ovti,ov5695";
|
||||
reg = <0x36>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&clk_24m_cam>;
|
||||
|
||||
clocks = <&cru SCLK_TESTCLKOUT1>;
|
||||
clock-names = "xvclk";
|
||||
|
||||
avdd-supply = <&pp2800_cam>;
|
||||
dovdd-supply = <&pp1800>;
|
||||
dvdd-supply = <&pp1250_cam>;
|
||||
reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
wcam_out: endpoint {
|
||||
remote-endpoint = <&mipi_in_wcam>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
* Omnivision 1/7.5-Inch B&W VGA CMOS Digital Image Sensor
|
||||
|
||||
The Omnivision OV7251 is a 1/7.5-Inch CMOS active pixel digital image sensor
|
||||
with an active array size of 640H x 480V. It is programmable through a serial
|
||||
I2C interface.
|
||||
|
||||
Required Properties:
|
||||
- compatible: Value should be "ovti,ov7251".
|
||||
- clocks: Reference to the xclk clock.
|
||||
- clock-names: Should be "xclk".
|
||||
- clock-frequency: Frequency of the xclk clock.
|
||||
- enable-gpios: Chip enable GPIO. Polarity is GPIO_ACTIVE_HIGH. This corresponds
|
||||
to the hardware pin XSHUTDOWN which is physically active low.
|
||||
- vdddo-supply: Chip digital IO regulator.
|
||||
- vdda-supply: Chip analog regulator.
|
||||
- vddd-supply: Chip digital core regulator.
|
||||
|
||||
The device node shall contain one 'port' child node with a single 'endpoint'
|
||||
subnode for its digital output video port, in accordance with the video
|
||||
interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Example:
|
||||
|
||||
&i2c1 {
|
||||
...
|
||||
|
||||
ov7251: camera-sensor@60 {
|
||||
compatible = "ovti,ov7251";
|
||||
reg = <0x60>;
|
||||
|
||||
enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&camera_bw_default>;
|
||||
|
||||
clocks = <&clks 200>;
|
||||
clock-names = "xclk";
|
||||
clock-frequency = <24000000>;
|
||||
|
||||
vdddo-supply = <&camera_dovdd_1v8>;
|
||||
vdda-supply = <&camera_avdd_2v8>;
|
||||
vddd-supply = <&camera_dvdd_1v2>;
|
||||
|
||||
port {
|
||||
ov7251_ep: endpoint {
|
||||
clock-lanes = <1>;
|
||||
data-lanes = <0>;
|
||||
remote-endpoint = <&csi0_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -5,26 +5,41 @@
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov5693.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Omnivision OV5693 CMOS Sensor
|
||||
title: Omnivision OV5693/OV5695 CMOS Sensors
|
||||
|
||||
maintainers:
|
||||
- Tommaso Merciai <tommaso.merciai@amarulasolutions.com>
|
||||
|
||||
description: |
|
||||
The Omnivision OV5693 is a high performance, 1/4-inch, 5 megapixel, CMOS
|
||||
image sensor that delivers 2592x1944 at 30fps. It provides full-frame,
|
||||
The Omnivision OV5693/OV5695 are high performance, 1/4-inch, 5 megapixel, CMOS
|
||||
image sensors that deliver 2592x1944 at 30fps. It provides full-frame,
|
||||
sub-sampled, and windowed 10-bit MIPI images in various formats via the
|
||||
Serial Camera Control Bus (SCCB) interface.
|
||||
|
||||
OV5693 is controlled via I2C and two-wire Serial Camera Control Bus (SCCB).
|
||||
The sensor output is available via CSI-2 serial data output (up to 2-lane).
|
||||
OV5693/OV5695 are controlled via I2C and two-wire Serial Camera Control Bus
|
||||
(SCCB). The sensor output is available via CSI-2 serial data output (up to
|
||||
2-lane).
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ovti,ov5693
|
||||
then:
|
||||
properties:
|
||||
port:
|
||||
properties:
|
||||
endpoint:
|
||||
required:
|
||||
- link-frequencies
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov5693
|
||||
enum:
|
||||
- ovti,ov5693
|
||||
- ovti,ov5695
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -34,6 +49,9 @@ properties:
|
||||
System input clock (aka XVCLK). From 6 to 27 MHz.
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: xvclk
|
||||
|
||||
dovdd-supply:
|
||||
description:
|
||||
Digital I/O voltage supply, 1.8V.
|
||||
@@ -72,7 +90,6 @@ properties:
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov7251.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: OmniVision OV7251 Image Sensor
|
||||
|
||||
description:
|
||||
The Omnivision OV7251 is a 1/7.5-Inch CMOS active pixel digital image sensor
|
||||
with an active array size of 640H x 480V. It is programmable through a serial
|
||||
I2C interface.
|
||||
|
||||
maintainers:
|
||||
- Todor Tomov <todor.too@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov7251
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: XCLK Input Clock
|
||||
|
||||
clock-names:
|
||||
const: xclk
|
||||
|
||||
clock-frequency:
|
||||
description: Frequency of the xclk clock in Hz.
|
||||
|
||||
vdda-supply:
|
||||
description: Analog voltage supply, 2.8 volts
|
||||
|
||||
vddd-supply:
|
||||
description: Digital core voltage supply, 1.2 volts
|
||||
|
||||
vdddo-supply:
|
||||
description: Digital I/O voltage supply, 1.8 volts
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Reference to the GPIO connected to the XSHUTDOWN pin, if any. Polarity
|
||||
is GPIO_ACTIVE_HIGH.
|
||||
|
||||
port:
|
||||
description: Digital Output Port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
clock-lanes:
|
||||
maximum: 1
|
||||
|
||||
data-lanes:
|
||||
maxItems: 1
|
||||
|
||||
link-frequencies: true
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- vdddo-supply
|
||||
- vdda-supply
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera@3c {
|
||||
compatible = "ovti,ov7251";
|
||||
reg = <0x3c>;
|
||||
clocks = <&clks 1>;
|
||||
clock-frequency = <24000000>;
|
||||
vdddo-supply = <&ov7251_vdddo_1v8>;
|
||||
vdda-supply = <&ov7251_vdda_2v8>;
|
||||
vddd-supply = <&ov7251_vddd_1v5>;
|
||||
enable-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
port {
|
||||
ov7251_ep: endpoint {
|
||||
remote-endpoint = <&csi0_ep>;
|
||||
clock-lanes = <1>;
|
||||
data-lanes = <0>;
|
||||
link-frequencies = /bits/ 64 <240000000 319200000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -199,6 +199,7 @@ examples:
|
||||
wcam: camera@36 {
|
||||
compatible = "ovti,ov5695";
|
||||
reg = <0x36>;
|
||||
clocks = <&cru SCLK_TESTCLKOUT1>;
|
||||
|
||||
port {
|
||||
wcam_out: endpoint {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
Broadcom Kona PWM controller device tree bindings
|
||||
|
||||
This controller has 6 channels.
|
||||
|
||||
Required Properties :
|
||||
- compatible: should contain "brcm,kona-pwm"
|
||||
- reg: physical base address and length of the controller's registers
|
||||
- clocks: phandle + clock specifier pair for the external clock
|
||||
- #pwm-cells: Should be 3. See pwm.yaml in this directory for a
|
||||
description of the cells format.
|
||||
|
||||
Refer to clocks/clock-bindings.txt for generic clock consumer properties.
|
||||
|
||||
Example:
|
||||
|
||||
pwm: pwm@3e01a000 {
|
||||
compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm";
|
||||
reg = <0x3e01a000 0xc4>;
|
||||
clocks = <&pwm_clk>;
|
||||
#pwm-cells = <3>;
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pwm/brcm,kona-pwm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom Kona family PWM controller
|
||||
|
||||
description:
|
||||
This controller has 6 channels.
|
||||
|
||||
maintainers:
|
||||
- Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: pwm.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- brcm,bcm11351-pwm
|
||||
- const: brcm,kona-pwm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
'#pwm-cells':
|
||||
const: 3
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/bcm281xx.h>
|
||||
|
||||
pwm@3e01a000 {
|
||||
compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm";
|
||||
reg = <0x3e01a000 0xcc>;
|
||||
clocks = <&slave_ccu BCM281XX_SLAVE_CCU_PWM>;
|
||||
#pwm-cells = <3>;
|
||||
};
|
||||
...
|
||||
@@ -14,13 +14,17 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- atmel,at91rm9200-rtc
|
||||
- atmel,at91sam9x5-rtc
|
||||
- atmel,sama5d4-rtc
|
||||
- atmel,sama5d2-rtc
|
||||
- microchip,sam9x60-rtc
|
||||
- microchip,sama7g5-rtc
|
||||
oneOf:
|
||||
- enum:
|
||||
- atmel,at91rm9200-rtc
|
||||
- atmel,at91sam9x5-rtc
|
||||
- atmel,sama5d4-rtc
|
||||
- atmel,sama5d2-rtc
|
||||
- microchip,sam9x60-rtc
|
||||
- microchip,sama7g5-rtc
|
||||
- items:
|
||||
- const: microchip,sam9x7-rtc
|
||||
- const: microchip,sam9x60-rtc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/intersil,isl12022.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Intersil ISL12022 Real-time Clock
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: isil,isl12022
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
isil,battery-trip-levels-microvolt:
|
||||
description:
|
||||
The battery voltages at which the first alarm and second alarm
|
||||
should trigger (normally ~85% and ~75% of nominal V_BAT).
|
||||
items:
|
||||
- enum: [2125000, 2295000, 2550000, 2805000, 3060000, 4250000, 4675000]
|
||||
- enum: [1875000, 2025000, 2250000, 2475000, 2700000, 3750000, 4125000]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
# If #clock-cells is present, interrupts must not be present
|
||||
- if:
|
||||
required:
|
||||
- '#clock-cells'
|
||||
then:
|
||||
properties:
|
||||
interrupts: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
rtc@6f {
|
||||
compatible = "isil,isl12022";
|
||||
reg = <0x6f>;
|
||||
interrupts-extended = <&gpio1 5 IRQ_TYPE_LEVEL_LOW>;
|
||||
isil,battery-trip-levels-microvolt = <2550000>, <2250000>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -1,38 +0,0 @@
|
||||
* Maxim DS3231 Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "maxim,ds3231".
|
||||
- reg: I2C address for chip.
|
||||
|
||||
Optional property:
|
||||
- #clock-cells: Should be 1.
|
||||
- clock-output-names:
|
||||
overwrite the default clock names "ds3231_clk_sqw" and "ds3231_clk_32khz".
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. Following indices are allowed:
|
||||
- 0: square-wave output on the SQW pin
|
||||
- 1: square-wave output on the 32kHz pin
|
||||
|
||||
- interrupts: rtc alarm/event interrupt. When this property is selected,
|
||||
clock on the SQW pin cannot be used.
|
||||
|
||||
Example:
|
||||
|
||||
ds3231: ds3231@51 {
|
||||
compatible = "maxim,ds3231";
|
||||
reg = <0x68>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
device1 {
|
||||
...
|
||||
clocks = <&ds3231 0>;
|
||||
...
|
||||
};
|
||||
|
||||
device2 {
|
||||
...
|
||||
clocks = <&ds3231 1>;
|
||||
...
|
||||
};
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- nxp,pca2129
|
||||
- nxp,pcf2127
|
||||
- nxp,pcf2129
|
||||
- nxp,pcf2131
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/st,m48t86.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ST M48T86 / Dallas DS12887 RTC with SRAM
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- st,m48t86
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: index register
|
||||
- description: data register
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
rtc@10800000 {
|
||||
compatible = "st,m48t86";
|
||||
reg = <0x10800000 0x1>, <0x11700000 0x1>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -45,8 +45,6 @@ properties:
|
||||
- isil,isl1208
|
||||
# Intersil ISL1218 Low Power RTC with Battery Backed SRAM
|
||||
- isil,isl1218
|
||||
# Intersil ISL12022 Real-time Clock
|
||||
- isil,isl12022
|
||||
# Real Time Clock Module with I2C-Bus
|
||||
- microcrystal,rv3029
|
||||
# Real Time Clock
|
||||
|
||||
@@ -14,7 +14,13 @@ properties:
|
||||
pattern: "^easrc@.*"
|
||||
|
||||
compatible:
|
||||
const: fsl,imx8mn-easrc
|
||||
oneOf:
|
||||
- enum:
|
||||
- fsl,imx8mn-easrc
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx8mp-easrc
|
||||
- const: fsl,imx8mn-easrc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson-gxbb-wdt
|
||||
- amlogic,t7-wdt
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/watchdog/marvell,cn10624-wdt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell Global Timer (GTI) system watchdog
|
||||
|
||||
maintainers:
|
||||
- Bharat Bhushan <bbhushan2@marvell.com>
|
||||
|
||||
allOf:
|
||||
- $ref: watchdog.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- marvell,cn9670-wdt
|
||||
- marvell,cn10624-wdt
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- marvell,cn9880-wdt
|
||||
- marvell,cnf9535-wdt
|
||||
- const: marvell,cn9670-wdt
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- marvell,cn10308-wdt
|
||||
- marvell,cnf10518-wdt
|
||||
- const: marvell,cn10624-wdt
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: refclk
|
||||
|
||||
marvell,wdt-timer-index:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 63
|
||||
description:
|
||||
An SoC have many timers (up to 64), firmware can reserve one or more timer
|
||||
for some other use case and configures one of the global timer as watchdog
|
||||
timer. Firmware will update this field with the timer number configured
|
||||
as watchdog timer.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
watchdog@802000040000 {
|
||||
compatible = "marvell,cn9670-wdt";
|
||||
reg = <0x00008020 0x00040000 0x00000000 0x00020000>;
|
||||
interrupts = <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&sclk>;
|
||||
clock-names = "refclk";
|
||||
marvell,wdt-timer-index = <63>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,kpss-wdt-ipq4019
|
||||
- qcom,apss-wdt-ipq5018
|
||||
- qcom,apss-wdt-ipq5332
|
||||
- qcom,apss-wdt-ipq9574
|
||||
- qcom,apss-wdt-msm8994
|
||||
|
||||
@@ -34,6 +34,20 @@ properties:
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
description:
|
||||
Contains the watchdog reserved memory. It is optional.
|
||||
In the reserved memory, the specified values, which are
|
||||
PON_REASON_SOF_NUM(0xBBBBCCCC), PON_REASON_MAGIC_NUM(0xDDDDDDDD),
|
||||
and PON_REASON_EOF_NUM(0xCCCCBBBB), are pre-stored at the first
|
||||
3 * 4 bytes to tell that last boot was caused by watchdog reset.
|
||||
Once the PON reason is captured by driver(rti_wdt.c), the driver
|
||||
is supposed to wipe the whole memory region. Surely, if this
|
||||
property is set, at least 12 bytes reserved memory starting from
|
||||
specific memory address(0xa220000) should be set. More please
|
||||
refer to example.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -47,7 +61,18 @@ examples:
|
||||
/*
|
||||
* RTI WDT in main domain on J721e SoC. Assigned clocks are used to
|
||||
* select the source clock for the watchdog, forcing it to tick with
|
||||
* a 32kHz clock in this case.
|
||||
* a 32kHz clock in this case. Add a reserved memory(optional) to keep
|
||||
* the watchdog reset cause persistent, which was be written in 12 bytes
|
||||
* starting from 0xa2200000 by RTI Watchdog Firmware, then make it
|
||||
* possible to get watchdog reset cause in driver.
|
||||
*
|
||||
* Reserved memory should be defined as follows:
|
||||
* reserved-memory {
|
||||
* wdt_reset_memory_region: wdt-memory@a2200000 {
|
||||
* reg = <0x00 0xa2200000 0x00 0x1000>;
|
||||
* no-map;
|
||||
* };
|
||||
* }
|
||||
*/
|
||||
#include <dt-bindings/soc/ti,sci_pm_domain.h>
|
||||
|
||||
@@ -58,4 +83,5 @@ examples:
|
||||
power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>;
|
||||
assigned-clocks = <&k3_clks 252 1>;
|
||||
assigned-clock-parents = <&k3_clks 252 5>;
|
||||
memory-region = <&wdt_reset_memory_region>;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| csky: | TODO |
|
||||
| hexagon: | TODO |
|
||||
| ia64: | TODO |
|
||||
| loongarch: | TODO |
|
||||
| loongarch: | ok |
|
||||
| m68k: | TODO |
|
||||
| microblaze: | TODO |
|
||||
| mips: | TODO |
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| csky: | TODO |
|
||||
| hexagon: | TODO |
|
||||
| ia64: | TODO |
|
||||
| loongarch: | TODO |
|
||||
| loongarch: | ok |
|
||||
| m68k: | TODO |
|
||||
| microblaze: | TODO |
|
||||
| mips: | ok |
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| csky: | TODO |
|
||||
| hexagon: | ok |
|
||||
| ia64: | TODO |
|
||||
| loongarch: | TODO |
|
||||
| loongarch: | ok |
|
||||
| m68k: | TODO |
|
||||
| microblaze: | ok |
|
||||
| mips: | ok |
|
||||
|
||||
@@ -57,6 +57,16 @@ a snapshot on any subdirectory (and its nested contents) in the
|
||||
system. Snapshot creation and deletion are as simple as 'mkdir
|
||||
.snap/foo' and 'rmdir .snap/foo'.
|
||||
|
||||
Snapshot names have two limitations:
|
||||
|
||||
* They can not start with an underscore ('_'), as these names are reserved
|
||||
for internal usage by the MDS.
|
||||
* They can not exceed 240 characters in size. This is because the MDS makes
|
||||
use of long snapshot names internally, which follow the format:
|
||||
`_<SNAPSHOT-NAME>_<INODE-NUMBER>`. Since filenames in general can't have
|
||||
more than 255 characters, and `<node-id>` takes 13 characters, the long
|
||||
snapshot names can take as much as 255 - 1 - 1 - 13 = 240.
|
||||
|
||||
Ceph also provides some recursive accounting on directories for nested
|
||||
files and bytes. That is, a 'getfattr -d foo' on any directory in the
|
||||
system will reveal the total number of nested regular files and
|
||||
|
||||
@@ -20,8 +20,7 @@ The gl_holders list contains all the queued lock requests (not
|
||||
just the holders) associated with the glock. If there are any
|
||||
held locks, then they will be contiguous entries at the head
|
||||
of the list. Locks are granted in strictly the order that they
|
||||
are queued, except for those marked LM_FLAG_PRIORITY which are
|
||||
used only during recovery, and even then only for journal locks.
|
||||
are queued.
|
||||
|
||||
There are three lock states that users of the glock layer can request,
|
||||
namely shared (SH), deferred (DF) and exclusive (EX). Those translate
|
||||
|
||||
@@ -11,19 +11,19 @@ via sysfs
|
||||
product_name
|
||||
------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
|
||||
:doc: product_name
|
||||
|
||||
product_number
|
||||
--------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: product_name
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
|
||||
:doc: product_number
|
||||
|
||||
serial_number
|
||||
-------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
|
||||
:doc: serial_number
|
||||
|
||||
unique_id
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
=========================================
|
||||
Automated testing of the DRM subsystem
|
||||
=========================================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Making sure that changes to the core or drivers don't introduce regressions can
|
||||
be very time-consuming when lots of different hardware configurations need to
|
||||
be tested. Moreover, it isn't practical for each person interested in this
|
||||
testing to have to acquire and maintain what can be a considerable amount of
|
||||
hardware.
|
||||
|
||||
Also, it is desirable for developers to check for regressions in their code by
|
||||
themselves, instead of relying on the maintainers to find them and then
|
||||
reporting back.
|
||||
|
||||
There are facilities in gitlab.freedesktop.org to automatically test Mesa that
|
||||
can be used as well for testing the DRM subsystem. This document explains how
|
||||
people interested in testing it can use this shared infrastructure to save
|
||||
quite some time and effort.
|
||||
|
||||
|
||||
Relevant files
|
||||
==============
|
||||
|
||||
drivers/gpu/drm/ci/gitlab-ci.yml
|
||||
--------------------------------
|
||||
|
||||
This is the root configuration file for GitLab CI. Among other less interesting
|
||||
bits, it specifies the specific version of the scripts to be used. There are
|
||||
some variables that can be modified to change the behavior of the pipeline:
|
||||
|
||||
DRM_CI_PROJECT_PATH
|
||||
Repository that contains the Mesa software infrastructure for CI
|
||||
|
||||
DRM_CI_COMMIT_SHA
|
||||
A particular revision to use from that repository
|
||||
|
||||
UPSTREAM_REPO
|
||||
URL to git repository containing the target branch
|
||||
|
||||
TARGET_BRANCH
|
||||
Branch to which this branch is to be merged into
|
||||
|
||||
IGT_VERSION
|
||||
Revision of igt-gpu-tools being used, from
|
||||
https://gitlab.freedesktop.org/drm/igt-gpu-tools
|
||||
|
||||
drivers/gpu/drm/ci/testlist.txt
|
||||
-------------------------------
|
||||
|
||||
IGT tests to be run on all drivers (unless mentioned in a driver's \*-skips.txt
|
||||
file, see below).
|
||||
|
||||
drivers/gpu/drm/ci/${DRIVER_NAME}-${HW_REVISION}-fails.txt
|
||||
----------------------------------------------------------
|
||||
|
||||
Lists the known failures for a given driver on a specific hardware revision.
|
||||
|
||||
drivers/gpu/drm/ci/${DRIVER_NAME}-${HW_REVISION}-flakes.txt
|
||||
-----------------------------------------------------------
|
||||
|
||||
Lists the tests that for a given driver on a specific hardware revision are
|
||||
known to behave unreliably. These tests won't cause a job to fail regardless of
|
||||
the result. They will still be run.
|
||||
|
||||
drivers/gpu/drm/ci/${DRIVER_NAME}-${HW_REVISION}-skips.txt
|
||||
-----------------------------------------------------------
|
||||
|
||||
Lists the tests that won't be run for a given driver on a specific hardware
|
||||
revision. These are usually tests that interfere with the running of the test
|
||||
list due to hanging the machine, causing OOM, taking too long, etc.
|
||||
|
||||
|
||||
How to enable automated testing on your tree
|
||||
============================================
|
||||
|
||||
1. Create a Linux tree in https://gitlab.freedesktop.org/ if you don't have one
|
||||
yet
|
||||
|
||||
2. In your kernel repo's configuration (eg.
|
||||
https://gitlab.freedesktop.org/janedoe/linux/-/settings/ci_cd), change the
|
||||
CI/CD configuration file from .gitlab-ci.yml to
|
||||
drivers/gpu/drm/ci/gitlab-ci.yml.
|
||||
|
||||
3. Next time you push to this repository, you will see a CI pipeline being
|
||||
created (eg. https://gitlab.freedesktop.org/janedoe/linux/-/pipelines)
|
||||
|
||||
4. The various jobs will be run and when the pipeline is finished, all jobs
|
||||
should be green unless a regression has been found.
|
||||
|
||||
|
||||
How to update test expectations
|
||||
===============================
|
||||
|
||||
If your changes to the code fix any tests, you will have to remove one or more
|
||||
lines from one or more of the files in
|
||||
drivers/gpu/drm/ci/${DRIVER_NAME}_*_fails.txt, for each of the test platforms
|
||||
affected by the change.
|
||||
|
||||
|
||||
How to expand coverage
|
||||
======================
|
||||
|
||||
If your code changes make it possible to run more tests (by solving reliability
|
||||
issues, for example), you can remove tests from the flakes and/or skips lists,
|
||||
and then the expected results if there are any known failures.
|
||||
|
||||
If there is a need for updating the version of IGT being used (maybe you have
|
||||
added more tests to it), update the IGT_VERSION variable at the top of the
|
||||
gitlab-ci.yml file.
|
||||
|
||||
|
||||
How to test your changes to the scripts
|
||||
=======================================
|
||||
|
||||
For testing changes to the scripts in the drm-ci repo, change the
|
||||
DRM_CI_PROJECT_PATH and DRM_CI_COMMIT_SHA variables in
|
||||
drivers/gpu/drm/ci/gitlab-ci.yml to match your fork of the project (eg.
|
||||
janedoe/drm-ci). This fork needs to be in https://gitlab.freedesktop.org/.
|
||||
|
||||
|
||||
How to incorporate external fixes in your testing
|
||||
=================================================
|
||||
|
||||
Often, regressions in other trees will prevent testing changes local to the
|
||||
tree under test. These fixes will be automatically merged in during the build
|
||||
jobs from a branch in the target tree that is named as
|
||||
${TARGET_BRANCH}-external-fixes.
|
||||
|
||||
If the pipeline is not in a merge request and a branch with the same name
|
||||
exists in the local tree, commits from that branch will be merged in as well.
|
||||
|
||||
|
||||
How to deal with automated testing labs that may be down
|
||||
========================================================
|
||||
|
||||
If a hardware farm is down and thus causing pipelines to fail that would
|
||||
otherwise pass, one can disable all jobs that would be submitted to that farm
|
||||
by editing the file at
|
||||
https://gitlab.freedesktop.org/gfx-ci/lab-status/-/blob/main/lab-status.yml.
|
||||
@@ -17,6 +17,7 @@ GPU Driver Developer's Guide
|
||||
backlight
|
||||
vga-switcheroo
|
||||
vgaarbiter
|
||||
automated_testing
|
||||
todo
|
||||
rfc/index
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ If you aren't subscribed to netdev and/or are simply unsure if
|
||||
repository link above for any new networking-related commits. You may
|
||||
also check the following website for the current status:
|
||||
|
||||
https://patchwork.hopto.org/net-next.html
|
||||
https://netdev.bots.linux.dev/net-next.html
|
||||
|
||||
The ``net`` tree continues to collect fixes for the vX.Y content, and is
|
||||
fed back to Linus at regular (~weekly) intervals. Meaning that the
|
||||
@@ -120,7 +120,37 @@ queue for netdev:
|
||||
https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
|
||||
The "State" field will tell you exactly where things are at with your
|
||||
patch. Patches are indexed by the ``Message-ID`` header of the emails
|
||||
patch:
|
||||
|
||||
================== =============================================================
|
||||
Patch state Description
|
||||
================== =============================================================
|
||||
New, Under review pending review, patch is in the maintainer’s queue for
|
||||
review; the two states are used interchangeably (depending on
|
||||
the exact co-maintainer handling patchwork at the time)
|
||||
Accepted patch was applied to the appropriate networking tree, this is
|
||||
usually set automatically by the pw-bot
|
||||
Needs ACK waiting for an ack from an area expert or testing
|
||||
Changes requested patch has not passed the review, new revision is expected
|
||||
with appropriate code and commit message changes
|
||||
Rejected patch has been rejected and new revision is not expected
|
||||
Not applicable patch is expected to be applied outside of the networking
|
||||
subsystem
|
||||
Awaiting upstream patch should be reviewed and handled by appropriate
|
||||
sub-maintainer, who will send it on to the networking trees;
|
||||
patches set to ``Awaiting upstream`` in netdev's patchwork
|
||||
will usually remain in this state, whether the sub-maintainer
|
||||
requested changes, accepted or rejected the patch
|
||||
Deferred patch needs to be reposted later, usually due to dependency
|
||||
or because it was posted for a closed tree
|
||||
Superseded new version of the patch was posted, usually set by the
|
||||
pw-bot
|
||||
RFC not to be applied, usually not in maintainer’s review queue,
|
||||
pw-bot can automatically set patches to this state based
|
||||
on subject tags
|
||||
================== =============================================================
|
||||
|
||||
Patches are indexed by the ``Message-ID`` header of the emails
|
||||
which carried them so if you have trouble finding your patch append
|
||||
the value of ``Message-ID`` to the URL above.
|
||||
|
||||
@@ -155,7 +185,7 @@ must match the MAINTAINERS entry) and a handful of senior reviewers.
|
||||
|
||||
Bot records its activity here:
|
||||
|
||||
https://patchwork.hopto.org/pw-bot.html
|
||||
https://netdev.bots.linux.dev/pw-bot.html
|
||||
|
||||
Review timelines
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -87,13 +87,12 @@ The following keys are defined:
|
||||
emulated via software, either in or below the kernel. These accesses are
|
||||
always extremely slow.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_MISALIGNED_SLOW`: Misaligned accesses are supported
|
||||
in hardware, but are slower than the corresponding aligned accesses
|
||||
sequences.
|
||||
* :c:macro:`RISCV_HWPROBE_MISALIGNED_SLOW`: Misaligned accesses are slower
|
||||
than equivalent byte accesses. Misaligned accesses may be supported
|
||||
directly in hardware, or trapped and emulated by software.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_MISALIGNED_FAST`: Misaligned accesses are supported
|
||||
in hardware and are faster than the corresponding aligned accesses
|
||||
sequences.
|
||||
* :c:macro:`RISCV_HWPROBE_MISALIGNED_FAST`: Misaligned accesses are faster
|
||||
than equivalent byte accesses.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_MISALIGNED_UNSUPPORTED`: Misaligned accesses are
|
||||
not supported at all and will generate a misaligned address fault.
|
||||
|
||||
@@ -42,7 +42,7 @@ KASAN有三种模式:
|
||||
体系架构
|
||||
~~~~~~~~
|
||||
|
||||
在x86_64、arm、arm64、powerpc、riscv、s390和xtensa上支持通用KASAN,
|
||||
在x86_64、arm、arm64、powerpc、riscv、s390、xtensa和loongarch上支持通用KASAN,
|
||||
而基于标签的KASAN模式只在arm64上支持。
|
||||
|
||||
编译器
|
||||
|
||||
@@ -528,6 +528,8 @@ families may, however, require a larger buffer. 32kB buffer is recommended
|
||||
for most efficient handling of dumps (larger buffer fits more dumped
|
||||
objects and therefore fewer recvmsg() calls are needed).
|
||||
|
||||
.. _classic_netlink:
|
||||
|
||||
Classic Netlink
|
||||
===============
|
||||
|
||||
|
||||
@@ -2259,6 +2259,8 @@ Errors:
|
||||
EINVAL invalid register ID, or no such register or used with VMs in
|
||||
protected virtualization mode on s390
|
||||
EPERM (arm64) register access not allowed before vcpu finalization
|
||||
EBUSY (riscv) changing register value not allowed after the vcpu
|
||||
has run at least once
|
||||
====== ============================================================
|
||||
|
||||
(These error codes are indicative only: do not rely on a specific error
|
||||
@@ -3499,7 +3501,7 @@ VCPU matching underlying host.
|
||||
---------------------
|
||||
|
||||
:Capability: basic
|
||||
:Architectures: arm64, mips
|
||||
:Architectures: arm64, mips, riscv
|
||||
:Type: vcpu ioctl
|
||||
:Parameters: struct kvm_reg_list (in/out)
|
||||
:Returns: 0 on success; -1 on error
|
||||
|
||||
+22
-4
@@ -6118,7 +6118,7 @@ F: include/video/udlfb.h
|
||||
DISTRIBUTED LOCK MANAGER (DLM)
|
||||
M: Christine Caulfield <ccaulfie@redhat.com>
|
||||
M: David Teigland <teigland@redhat.com>
|
||||
L: cluster-devel@redhat.com
|
||||
L: gfs2@lists.linux.dev
|
||||
S: Supported
|
||||
W: http://sources.redhat.com/cluster/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
|
||||
@@ -7165,6 +7165,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: drivers/gpu/drm/ttm/
|
||||
F: include/drm/ttm/
|
||||
|
||||
DRM AUTOMATED TESTING
|
||||
M: Helen Koike <helen.koike@collabora.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: Documentation/gpu/automated_testing.rst
|
||||
F: drivers/gpu/drm/ci/
|
||||
|
||||
DSBR100 USB FM RADIO DRIVER
|
||||
M: Alexey Klimov <klimov.linux@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
@@ -8774,7 +8782,7 @@ F: scripts/get_maintainer.pl
|
||||
GFS2 FILE SYSTEM
|
||||
M: Bob Peterson <rpeterso@redhat.com>
|
||||
M: Andreas Gruenbacher <agruenba@redhat.com>
|
||||
L: cluster-devel@redhat.com
|
||||
L: gfs2@lists.linux.dev
|
||||
S: Supported
|
||||
B: https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&component=gfs2
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git
|
||||
@@ -11596,6 +11604,8 @@ F: arch/x86/include/uapi/asm/svm.h
|
||||
F: arch/x86/include/uapi/asm/vmx.h
|
||||
F: arch/x86/kvm/
|
||||
F: arch/x86/kvm/*/
|
||||
F: tools/testing/selftests/kvm/*/x86_64/
|
||||
F: tools/testing/selftests/kvm/x86_64/
|
||||
|
||||
KERNFS
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
@@ -16768,6 +16778,8 @@ L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://perf.wiki.kernel.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools.git perf-tools
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
|
||||
F: arch/*/events/*
|
||||
F: arch/*/events/*/*
|
||||
F: arch/*/include/asm/perf_event.h
|
||||
@@ -18089,7 +18101,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git
|
||||
F: Documentation/admin-guide/rtc.rst
|
||||
F: Documentation/devicetree/bindings/rtc/
|
||||
F: drivers/rtc/
|
||||
F: include/linux/platform_data/rtc-*
|
||||
F: include/linux/rtc.h
|
||||
F: include/linux/rtc/
|
||||
F: include/uapi/linux/rtc.h
|
||||
@@ -20412,6 +20423,13 @@ S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
|
||||
F: drivers/staging/
|
||||
|
||||
STANDALONE CACHE CONTROLLER DRIVERS
|
||||
M: Conor Dooley <conor@kernel.org>
|
||||
L: linux-riscv@lists.infradead.org
|
||||
S: Maintained
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||
F: drivers/cache
|
||||
|
||||
STARFIRE/DURALAN NETWORK DRIVER
|
||||
M: Ion Badulescu <ionut@badula.org>
|
||||
S: Odd Fixes
|
||||
@@ -21250,7 +21268,7 @@ F: sound/soc/ti/
|
||||
TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS
|
||||
M: Shenghao Ding <shenghao-ding@ti.com>
|
||||
M: Kevin Lu <kevin-lu@ti.com>
|
||||
M: Baojun Xu <x1077012@ti.com>
|
||||
M: Baojun Xu <baojun.xu@ti.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/tas2552.txt
|
||||
|
||||
@@ -227,6 +227,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void kvm_vcpu_pmu_resync_el0(void) {}
|
||||
|
||||
/* PMU Version in DFR Register */
|
||||
#define ARMV8_PMU_DFR_VER_NI 0
|
||||
#define ARMV8_PMU_DFR_VER_V3P4 0x5
|
||||
|
||||
@@ -156,4 +156,6 @@ static inline void efi_capsule_flush_cache_range(void *addr, int size)
|
||||
|
||||
efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f);
|
||||
|
||||
void efi_icache_sync(unsigned long start, unsigned long end);
|
||||
|
||||
#endif /* _ASM_EFI_H */
|
||||
|
||||
@@ -18,10 +18,19 @@
|
||||
#define HCR_DCT (UL(1) << 57)
|
||||
#define HCR_ATA_SHIFT 56
|
||||
#define HCR_ATA (UL(1) << HCR_ATA_SHIFT)
|
||||
#define HCR_TTLBOS (UL(1) << 55)
|
||||
#define HCR_TTLBIS (UL(1) << 54)
|
||||
#define HCR_ENSCXT (UL(1) << 53)
|
||||
#define HCR_TOCU (UL(1) << 52)
|
||||
#define HCR_AMVOFFEN (UL(1) << 51)
|
||||
#define HCR_TICAB (UL(1) << 50)
|
||||
#define HCR_TID4 (UL(1) << 49)
|
||||
#define HCR_FIEN (UL(1) << 47)
|
||||
#define HCR_FWB (UL(1) << 46)
|
||||
#define HCR_NV2 (UL(1) << 45)
|
||||
#define HCR_AT (UL(1) << 44)
|
||||
#define HCR_NV1 (UL(1) << 43)
|
||||
#define HCR_NV (UL(1) << 42)
|
||||
#define HCR_API (UL(1) << 41)
|
||||
#define HCR_APK (UL(1) << 40)
|
||||
#define HCR_TEA (UL(1) << 37)
|
||||
@@ -89,7 +98,6 @@
|
||||
HCR_BSU_IS | HCR_FB | HCR_TACR | \
|
||||
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
|
||||
HCR_FMO | HCR_IMO | HCR_PTW | HCR_TID3)
|
||||
#define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
|
||||
#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
|
||||
#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
|
||||
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
|
||||
@@ -324,6 +332,47 @@
|
||||
BIT(18) | \
|
||||
GENMASK(16, 15))
|
||||
|
||||
/*
|
||||
* FGT register definitions
|
||||
*
|
||||
* RES0 and polarity masks as of DDI0487J.a, to be updated as needed.
|
||||
* We're not using the generated masks as they are usually ahead of
|
||||
* the published ARM ARM, which we use as a reference.
|
||||
*
|
||||
* Once we get to a point where the two describe the same thing, we'll
|
||||
* merge the definitions. One day.
|
||||
*/
|
||||
#define __HFGRTR_EL2_RES0 (GENMASK(63, 56) | GENMASK(53, 51))
|
||||
#define __HFGRTR_EL2_MASK GENMASK(49, 0)
|
||||
#define __HFGRTR_EL2_nMASK (GENMASK(55, 54) | BIT(50))
|
||||
|
||||
#define __HFGWTR_EL2_RES0 (GENMASK(63, 56) | GENMASK(53, 51) | \
|
||||
BIT(46) | BIT(42) | BIT(40) | BIT(28) | \
|
||||
GENMASK(26, 25) | BIT(21) | BIT(18) | \
|
||||
GENMASK(15, 14) | GENMASK(10, 9) | BIT(2))
|
||||
#define __HFGWTR_EL2_MASK GENMASK(49, 0)
|
||||
#define __HFGWTR_EL2_nMASK (GENMASK(55, 54) | BIT(50))
|
||||
|
||||
#define __HFGITR_EL2_RES0 GENMASK(63, 57)
|
||||
#define __HFGITR_EL2_MASK GENMASK(54, 0)
|
||||
#define __HFGITR_EL2_nMASK GENMASK(56, 55)
|
||||
|
||||
#define __HDFGRTR_EL2_RES0 (BIT(49) | BIT(42) | GENMASK(39, 38) | \
|
||||
GENMASK(21, 20) | BIT(8))
|
||||
#define __HDFGRTR_EL2_MASK ~__HDFGRTR_EL2_nMASK
|
||||
#define __HDFGRTR_EL2_nMASK GENMASK(62, 59)
|
||||
|
||||
#define __HDFGWTR_EL2_RES0 (BIT(63) | GENMASK(59, 58) | BIT(51) | BIT(47) | \
|
||||
BIT(43) | GENMASK(40, 38) | BIT(34) | BIT(30) | \
|
||||
BIT(22) | BIT(9) | BIT(6))
|
||||
#define __HDFGWTR_EL2_MASK ~__HDFGWTR_EL2_nMASK
|
||||
#define __HDFGWTR_EL2_nMASK GENMASK(62, 60)
|
||||
|
||||
/* Similar definitions for HCRX_EL2 */
|
||||
#define __HCRX_EL2_RES0 (GENMASK(63, 16) | GENMASK(13, 12))
|
||||
#define __HCRX_EL2_MASK (0)
|
||||
#define __HCRX_EL2_nMASK (GENMASK(15, 14) | GENMASK(4, 0))
|
||||
|
||||
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
|
||||
#define HPFAR_MASK (~UL(0xf))
|
||||
/*
|
||||
|
||||
@@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa_nsh,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr,
|
||||
@@ -229,6 +230,8 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
|
||||
extern void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t ipa,
|
||||
int level);
|
||||
extern void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t start, unsigned long pages);
|
||||
extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
|
||||
|
||||
extern void __kvm_timer_set_cntvoff(u64 cntvoff);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
|
||||
#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
|
||||
#define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
|
||||
#define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
|
||||
|
||||
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
|
||||
KVM_DIRTY_LOG_INITIALLY_SET)
|
||||
@@ -380,6 +381,7 @@ enum vcpu_sysreg {
|
||||
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
|
||||
HSTR_EL2, /* Hypervisor System Trap Register */
|
||||
HACR_EL2, /* Hypervisor Auxiliary Control Register */
|
||||
HCRX_EL2, /* Extended Hypervisor Configuration Register */
|
||||
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
|
||||
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
|
||||
TCR_EL2, /* Translation Control Register (EL2) */
|
||||
@@ -400,6 +402,11 @@ enum vcpu_sysreg {
|
||||
TPIDR_EL2, /* EL2 Software Thread ID Register */
|
||||
CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
|
||||
SP_EL2, /* EL2 Stack Pointer */
|
||||
HFGRTR_EL2,
|
||||
HFGWTR_EL2,
|
||||
HFGITR_EL2,
|
||||
HDFGRTR_EL2,
|
||||
HDFGWTR_EL2,
|
||||
CNTHP_CTL_EL2,
|
||||
CNTHP_CVAL_EL2,
|
||||
CNTHV_CTL_EL2,
|
||||
@@ -567,8 +574,7 @@ struct kvm_vcpu_arch {
|
||||
/* Cache some mmu pages needed inside spinlock regions */
|
||||
struct kvm_mmu_memory_cache mmu_page_cache;
|
||||
|
||||
/* Target CPU and feature flags */
|
||||
int target;
|
||||
/* feature flags */
|
||||
DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES);
|
||||
|
||||
/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
|
||||
@@ -669,6 +675,8 @@ struct kvm_vcpu_arch {
|
||||
#define VCPU_SVE_FINALIZED __vcpu_single_flag(cflags, BIT(1))
|
||||
/* PTRAUTH exposed to guest */
|
||||
#define GUEST_HAS_PTRAUTH __vcpu_single_flag(cflags, BIT(2))
|
||||
/* KVM_ARM_VCPU_INIT completed */
|
||||
#define VCPU_INITIALIZED __vcpu_single_flag(cflags, BIT(3))
|
||||
|
||||
/* Exception pending */
|
||||
#define PENDING_EXCEPTION __vcpu_single_flag(iflags, BIT(0))
|
||||
@@ -899,7 +907,6 @@ struct kvm_vcpu_stat {
|
||||
u64 exits;
|
||||
};
|
||||
|
||||
void kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
|
||||
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
|
||||
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
|
||||
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
|
||||
@@ -967,8 +974,6 @@ void kvm_arm_resume_guest(struct kvm *kvm);
|
||||
#define kvm_call_hyp_nvhe(f, ...) f(__VA_ARGS__)
|
||||
#endif /* __KVM_NVHE_HYPERVISOR__ */
|
||||
|
||||
void force_vm_exit(const cpumask_t *mask);
|
||||
|
||||
int handle_exit(struct kvm_vcpu *vcpu, int exception_index);
|
||||
void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index);
|
||||
|
||||
@@ -983,6 +988,7 @@ int kvm_handle_cp10_id(struct kvm_vcpu *vcpu);
|
||||
void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
|
||||
|
||||
int __init kvm_sys_reg_table_init(void);
|
||||
int __init populate_nv_trap_config(void);
|
||||
|
||||
bool lock_all_vcpus(struct kvm *kvm);
|
||||
void unlock_all_vcpus(struct kvm *kvm);
|
||||
@@ -1049,8 +1055,6 @@ static inline bool kvm_system_needs_idmapped_vectors(void)
|
||||
return cpus_have_const_cap(ARM64_SPECTRE_V3A);
|
||||
}
|
||||
|
||||
void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu);
|
||||
|
||||
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
|
||||
static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
|
||||
|
||||
@@ -1113,13 +1117,15 @@ int __init kvm_set_ipa_limit(void);
|
||||
#define __KVM_HAVE_ARCH_VM_ALLOC
|
||||
struct kvm *kvm_arch_alloc_vm(void);
|
||||
|
||||
#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS
|
||||
|
||||
#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE
|
||||
|
||||
static inline bool kvm_vm_is_protected(struct kvm *kvm)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void kvm_init_protected_traps(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
|
||||
bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
|
||||
void __iomem **haddr);
|
||||
int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
|
||||
void **haddr);
|
||||
int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr);
|
||||
void __init free_hyp_pgds(void);
|
||||
|
||||
void stage2_unmap_vm(struct kvm *kvm);
|
||||
|
||||
@@ -11,6 +11,8 @@ static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
|
||||
test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
|
||||
}
|
||||
|
||||
extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu);
|
||||
|
||||
struct sys_reg_params;
|
||||
struct sys_reg_desc;
|
||||
|
||||
|
||||
@@ -746,4 +746,14 @@ enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte);
|
||||
* kvm_pgtable_prot format.
|
||||
*/
|
||||
enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte);
|
||||
|
||||
/**
|
||||
* kvm_tlb_flush_vmid_range() - Invalidate/flush a range of TLB entries
|
||||
*
|
||||
* @mmu: Stage-2 KVM MMU struct
|
||||
* @addr: The base Intermediate physical address from which to invalidate
|
||||
* @size: Size of the range from the base to invalidate
|
||||
*/
|
||||
void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t addr, size_t size);
|
||||
#endif /* __ARM64_KVM_PGTABLE_H__ */
|
||||
|
||||
@@ -124,6 +124,37 @@
|
||||
#define SYS_DC_CIGSW sys_insn(1, 0, 7, 14, 4)
|
||||
#define SYS_DC_CIGDSW sys_insn(1, 0, 7, 14, 6)
|
||||
|
||||
#define SYS_IC_IALLUIS sys_insn(1, 0, 7, 1, 0)
|
||||
#define SYS_IC_IALLU sys_insn(1, 0, 7, 5, 0)
|
||||
#define SYS_IC_IVAU sys_insn(1, 3, 7, 5, 1)
|
||||
|
||||
#define SYS_DC_IVAC sys_insn(1, 0, 7, 6, 1)
|
||||
#define SYS_DC_IGVAC sys_insn(1, 0, 7, 6, 3)
|
||||
#define SYS_DC_IGDVAC sys_insn(1, 0, 7, 6, 5)
|
||||
|
||||
#define SYS_DC_CVAC sys_insn(1, 3, 7, 10, 1)
|
||||
#define SYS_DC_CGVAC sys_insn(1, 3, 7, 10, 3)
|
||||
#define SYS_DC_CGDVAC sys_insn(1, 3, 7, 10, 5)
|
||||
|
||||
#define SYS_DC_CVAU sys_insn(1, 3, 7, 11, 1)
|
||||
|
||||
#define SYS_DC_CVAP sys_insn(1, 3, 7, 12, 1)
|
||||
#define SYS_DC_CGVAP sys_insn(1, 3, 7, 12, 3)
|
||||
#define SYS_DC_CGDVAP sys_insn(1, 3, 7, 12, 5)
|
||||
|
||||
#define SYS_DC_CVADP sys_insn(1, 3, 7, 13, 1)
|
||||
#define SYS_DC_CGVADP sys_insn(1, 3, 7, 13, 3)
|
||||
#define SYS_DC_CGDVADP sys_insn(1, 3, 7, 13, 5)
|
||||
|
||||
#define SYS_DC_CIVAC sys_insn(1, 3, 7, 14, 1)
|
||||
#define SYS_DC_CIGVAC sys_insn(1, 3, 7, 14, 3)
|
||||
#define SYS_DC_CIGDVAC sys_insn(1, 3, 7, 14, 5)
|
||||
|
||||
/* Data cache zero operations */
|
||||
#define SYS_DC_ZVA sys_insn(1, 3, 7, 4, 1)
|
||||
#define SYS_DC_GVA sys_insn(1, 3, 7, 4, 3)
|
||||
#define SYS_DC_GZVA sys_insn(1, 3, 7, 4, 4)
|
||||
|
||||
/*
|
||||
* Automatically generated definitions for system registers, the
|
||||
* manual encodings below are in the process of being converted to
|
||||
@@ -163,6 +194,82 @@
|
||||
#define SYS_DBGDTRTX_EL0 sys_reg(2, 3, 0, 5, 0)
|
||||
#define SYS_DBGVCR32_EL2 sys_reg(2, 4, 0, 7, 0)
|
||||
|
||||
#define SYS_BRBINF_EL1(n) sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
|
||||
#define SYS_BRBINFINJ_EL1 sys_reg(2, 1, 9, 1, 0)
|
||||
#define SYS_BRBSRC_EL1(n) sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
|
||||
#define SYS_BRBSRCINJ_EL1 sys_reg(2, 1, 9, 1, 1)
|
||||
#define SYS_BRBTGT_EL1(n) sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
|
||||
#define SYS_BRBTGTINJ_EL1 sys_reg(2, 1, 9, 1, 2)
|
||||
#define SYS_BRBTS_EL1 sys_reg(2, 1, 9, 0, 2)
|
||||
|
||||
#define SYS_BRBCR_EL1 sys_reg(2, 1, 9, 0, 0)
|
||||
#define SYS_BRBFCR_EL1 sys_reg(2, 1, 9, 0, 1)
|
||||
#define SYS_BRBIDR0_EL1 sys_reg(2, 1, 9, 2, 0)
|
||||
|
||||
#define SYS_TRCITECR_EL1 sys_reg(3, 0, 1, 2, 3)
|
||||
#define SYS_TRCACATR(m) sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
|
||||
#define SYS_TRCACVR(m) sys_reg(2, 1, 2, ((m & 7) << 1), (0 | (m >> 3)))
|
||||
#define SYS_TRCAUTHSTATUS sys_reg(2, 1, 7, 14, 6)
|
||||
#define SYS_TRCAUXCTLR sys_reg(2, 1, 0, 6, 0)
|
||||
#define SYS_TRCBBCTLR sys_reg(2, 1, 0, 15, 0)
|
||||
#define SYS_TRCCCCTLR sys_reg(2, 1, 0, 14, 0)
|
||||
#define SYS_TRCCIDCCTLR0 sys_reg(2, 1, 3, 0, 2)
|
||||
#define SYS_TRCCIDCCTLR1 sys_reg(2, 1, 3, 1, 2)
|
||||
#define SYS_TRCCIDCVR(m) sys_reg(2, 1, 3, ((m & 7) << 1), 0)
|
||||
#define SYS_TRCCLAIMCLR sys_reg(2, 1, 7, 9, 6)
|
||||
#define SYS_TRCCLAIMSET sys_reg(2, 1, 7, 8, 6)
|
||||
#define SYS_TRCCNTCTLR(m) sys_reg(2, 1, 0, (4 | (m & 3)), 5)
|
||||
#define SYS_TRCCNTRLDVR(m) sys_reg(2, 1, 0, (0 | (m & 3)), 5)
|
||||
#define SYS_TRCCNTVR(m) sys_reg(2, 1, 0, (8 | (m & 3)), 5)
|
||||
#define SYS_TRCCONFIGR sys_reg(2, 1, 0, 4, 0)
|
||||
#define SYS_TRCDEVARCH sys_reg(2, 1, 7, 15, 6)
|
||||
#define SYS_TRCDEVID sys_reg(2, 1, 7, 2, 7)
|
||||
#define SYS_TRCEVENTCTL0R sys_reg(2, 1, 0, 8, 0)
|
||||
#define SYS_TRCEVENTCTL1R sys_reg(2, 1, 0, 9, 0)
|
||||
#define SYS_TRCEXTINSELR(m) sys_reg(2, 1, 0, (8 | (m & 3)), 4)
|
||||
#define SYS_TRCIDR0 sys_reg(2, 1, 0, 8, 7)
|
||||
#define SYS_TRCIDR10 sys_reg(2, 1, 0, 2, 6)
|
||||
#define SYS_TRCIDR11 sys_reg(2, 1, 0, 3, 6)
|
||||
#define SYS_TRCIDR12 sys_reg(2, 1, 0, 4, 6)
|
||||
#define SYS_TRCIDR13 sys_reg(2, 1, 0, 5, 6)
|
||||
#define SYS_TRCIDR1 sys_reg(2, 1, 0, 9, 7)
|
||||
#define SYS_TRCIDR2 sys_reg(2, 1, 0, 10, 7)
|
||||
#define SYS_TRCIDR3 sys_reg(2, 1, 0, 11, 7)
|
||||
#define SYS_TRCIDR4 sys_reg(2, 1, 0, 12, 7)
|
||||
#define SYS_TRCIDR5 sys_reg(2, 1, 0, 13, 7)
|
||||
#define SYS_TRCIDR6 sys_reg(2, 1, 0, 14, 7)
|
||||
#define SYS_TRCIDR7 sys_reg(2, 1, 0, 15, 7)
|
||||
#define SYS_TRCIDR8 sys_reg(2, 1, 0, 0, 6)
|
||||
#define SYS_TRCIDR9 sys_reg(2, 1, 0, 1, 6)
|
||||
#define SYS_TRCIMSPEC(m) sys_reg(2, 1, 0, (m & 7), 7)
|
||||
#define SYS_TRCITEEDCR sys_reg(2, 1, 0, 2, 1)
|
||||
#define SYS_TRCOSLSR sys_reg(2, 1, 1, 1, 4)
|
||||
#define SYS_TRCPRGCTLR sys_reg(2, 1, 0, 1, 0)
|
||||
#define SYS_TRCQCTLR sys_reg(2, 1, 0, 1, 1)
|
||||
#define SYS_TRCRSCTLR(m) sys_reg(2, 1, 1, (m & 15), (0 | (m >> 4)))
|
||||
#define SYS_TRCRSR sys_reg(2, 1, 0, 10, 0)
|
||||
#define SYS_TRCSEQEVR(m) sys_reg(2, 1, 0, (m & 3), 4)
|
||||
#define SYS_TRCSEQRSTEVR sys_reg(2, 1, 0, 6, 4)
|
||||
#define SYS_TRCSEQSTR sys_reg(2, 1, 0, 7, 4)
|
||||
#define SYS_TRCSSCCR(m) sys_reg(2, 1, 1, (m & 7), 2)
|
||||
#define SYS_TRCSSCSR(m) sys_reg(2, 1, 1, (8 | (m & 7)), 2)
|
||||
#define SYS_TRCSSPCICR(m) sys_reg(2, 1, 1, (m & 7), 3)
|
||||
#define SYS_TRCSTALLCTLR sys_reg(2, 1, 0, 11, 0)
|
||||
#define SYS_TRCSTATR sys_reg(2, 1, 0, 3, 0)
|
||||
#define SYS_TRCSYNCPR sys_reg(2, 1, 0, 13, 0)
|
||||
#define SYS_TRCTRACEIDR sys_reg(2, 1, 0, 0, 1)
|
||||
#define SYS_TRCTSCTLR sys_reg(2, 1, 0, 12, 0)
|
||||
#define SYS_TRCVICTLR sys_reg(2, 1, 0, 0, 2)
|
||||
#define SYS_TRCVIIECTLR sys_reg(2, 1, 0, 1, 2)
|
||||
#define SYS_TRCVIPCSSCTLR sys_reg(2, 1, 0, 3, 2)
|
||||
#define SYS_TRCVISSCTLR sys_reg(2, 1, 0, 2, 2)
|
||||
#define SYS_TRCVMIDCCTLR0 sys_reg(2, 1, 3, 2, 2)
|
||||
#define SYS_TRCVMIDCCTLR1 sys_reg(2, 1, 3, 3, 2)
|
||||
#define SYS_TRCVMIDCVR(m) sys_reg(2, 1, 3, ((m & 7) << 1), 1)
|
||||
|
||||
/* ETM */
|
||||
#define SYS_TRCOSLAR sys_reg(2, 1, 1, 0, 4)
|
||||
|
||||
#define SYS_MIDR_EL1 sys_reg(3, 0, 0, 0, 0)
|
||||
#define SYS_MPIDR_EL1 sys_reg(3, 0, 0, 0, 5)
|
||||
#define SYS_REVIDR_EL1 sys_reg(3, 0, 0, 0, 6)
|
||||
@@ -203,8 +310,13 @@
|
||||
#define SYS_ERXCTLR_EL1 sys_reg(3, 0, 5, 4, 1)
|
||||
#define SYS_ERXSTATUS_EL1 sys_reg(3, 0, 5, 4, 2)
|
||||
#define SYS_ERXADDR_EL1 sys_reg(3, 0, 5, 4, 3)
|
||||
#define SYS_ERXPFGF_EL1 sys_reg(3, 0, 5, 4, 4)
|
||||
#define SYS_ERXPFGCTL_EL1 sys_reg(3, 0, 5, 4, 5)
|
||||
#define SYS_ERXPFGCDN_EL1 sys_reg(3, 0, 5, 4, 6)
|
||||
#define SYS_ERXMISC0_EL1 sys_reg(3, 0, 5, 5, 0)
|
||||
#define SYS_ERXMISC1_EL1 sys_reg(3, 0, 5, 5, 1)
|
||||
#define SYS_ERXMISC2_EL1 sys_reg(3, 0, 5, 5, 2)
|
||||
#define SYS_ERXMISC3_EL1 sys_reg(3, 0, 5, 5, 3)
|
||||
#define SYS_TFSR_EL1 sys_reg(3, 0, 5, 6, 0)
|
||||
#define SYS_TFSRE0_EL1 sys_reg(3, 0, 5, 6, 1)
|
||||
|
||||
@@ -275,6 +387,8 @@
|
||||
#define SYS_ICC_IGRPEN0_EL1 sys_reg(3, 0, 12, 12, 6)
|
||||
#define SYS_ICC_IGRPEN1_EL1 sys_reg(3, 0, 12, 12, 7)
|
||||
|
||||
#define SYS_ACCDATA_EL1 sys_reg(3, 0, 13, 0, 5)
|
||||
|
||||
#define SYS_CNTKCTL_EL1 sys_reg(3, 0, 14, 1, 0)
|
||||
|
||||
#define SYS_AIDR_EL1 sys_reg(3, 1, 0, 0, 7)
|
||||
@@ -383,8 +497,6 @@
|
||||
#define SYS_VTCR_EL2 sys_reg(3, 4, 2, 1, 2)
|
||||
|
||||
#define SYS_TRFCR_EL2 sys_reg(3, 4, 1, 2, 1)
|
||||
#define SYS_HDFGRTR_EL2 sys_reg(3, 4, 3, 1, 4)
|
||||
#define SYS_HDFGWTR_EL2 sys_reg(3, 4, 3, 1, 5)
|
||||
#define SYS_HAFGRTR_EL2 sys_reg(3, 4, 3, 1, 6)
|
||||
#define SYS_SPSR_EL2 sys_reg(3, 4, 4, 0, 0)
|
||||
#define SYS_ELR_EL2 sys_reg(3, 4, 4, 0, 1)
|
||||
@@ -478,6 +590,158 @@
|
||||
|
||||
#define SYS_SP_EL2 sys_reg(3, 6, 4, 1, 0)
|
||||
|
||||
/* AT instructions */
|
||||
#define AT_Op0 1
|
||||
#define AT_CRn 7
|
||||
|
||||
#define OP_AT_S1E1R sys_insn(AT_Op0, 0, AT_CRn, 8, 0)
|
||||
#define OP_AT_S1E1W sys_insn(AT_Op0, 0, AT_CRn, 8, 1)
|
||||
#define OP_AT_S1E0R sys_insn(AT_Op0, 0, AT_CRn, 8, 2)
|
||||
#define OP_AT_S1E0W sys_insn(AT_Op0, 0, AT_CRn, 8, 3)
|
||||
#define OP_AT_S1E1RP sys_insn(AT_Op0, 0, AT_CRn, 9, 0)
|
||||
#define OP_AT_S1E1WP sys_insn(AT_Op0, 0, AT_CRn, 9, 1)
|
||||
#define OP_AT_S1E2R sys_insn(AT_Op0, 4, AT_CRn, 8, 0)
|
||||
#define OP_AT_S1E2W sys_insn(AT_Op0, 4, AT_CRn, 8, 1)
|
||||
#define OP_AT_S12E1R sys_insn(AT_Op0, 4, AT_CRn, 8, 4)
|
||||
#define OP_AT_S12E1W sys_insn(AT_Op0, 4, AT_CRn, 8, 5)
|
||||
#define OP_AT_S12E0R sys_insn(AT_Op0, 4, AT_CRn, 8, 6)
|
||||
#define OP_AT_S12E0W sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
|
||||
|
||||
/* TLBI instructions */
|
||||
#define OP_TLBI_VMALLE1OS sys_insn(1, 0, 8, 1, 0)
|
||||
#define OP_TLBI_VAE1OS sys_insn(1, 0, 8, 1, 1)
|
||||
#define OP_TLBI_ASIDE1OS sys_insn(1, 0, 8, 1, 2)
|
||||
#define OP_TLBI_VAAE1OS sys_insn(1, 0, 8, 1, 3)
|
||||
#define OP_TLBI_VALE1OS sys_insn(1, 0, 8, 1, 5)
|
||||
#define OP_TLBI_VAALE1OS sys_insn(1, 0, 8, 1, 7)
|
||||
#define OP_TLBI_RVAE1IS sys_insn(1, 0, 8, 2, 1)
|
||||
#define OP_TLBI_RVAAE1IS sys_insn(1, 0, 8, 2, 3)
|
||||
#define OP_TLBI_RVALE1IS sys_insn(1, 0, 8, 2, 5)
|
||||
#define OP_TLBI_RVAALE1IS sys_insn(1, 0, 8, 2, 7)
|
||||
#define OP_TLBI_VMALLE1IS sys_insn(1, 0, 8, 3, 0)
|
||||
#define OP_TLBI_VAE1IS sys_insn(1, 0, 8, 3, 1)
|
||||
#define OP_TLBI_ASIDE1IS sys_insn(1, 0, 8, 3, 2)
|
||||
#define OP_TLBI_VAAE1IS sys_insn(1, 0, 8, 3, 3)
|
||||
#define OP_TLBI_VALE1IS sys_insn(1, 0, 8, 3, 5)
|
||||
#define OP_TLBI_VAALE1IS sys_insn(1, 0, 8, 3, 7)
|
||||
#define OP_TLBI_RVAE1OS sys_insn(1, 0, 8, 5, 1)
|
||||
#define OP_TLBI_RVAAE1OS sys_insn(1, 0, 8, 5, 3)
|
||||
#define OP_TLBI_RVALE1OS sys_insn(1, 0, 8, 5, 5)
|
||||
#define OP_TLBI_RVAALE1OS sys_insn(1, 0, 8, 5, 7)
|
||||
#define OP_TLBI_RVAE1 sys_insn(1, 0, 8, 6, 1)
|
||||
#define OP_TLBI_RVAAE1 sys_insn(1, 0, 8, 6, 3)
|
||||
#define OP_TLBI_RVALE1 sys_insn(1, 0, 8, 6, 5)
|
||||
#define OP_TLBI_RVAALE1 sys_insn(1, 0, 8, 6, 7)
|
||||
#define OP_TLBI_VMALLE1 sys_insn(1, 0, 8, 7, 0)
|
||||
#define OP_TLBI_VAE1 sys_insn(1, 0, 8, 7, 1)
|
||||
#define OP_TLBI_ASIDE1 sys_insn(1, 0, 8, 7, 2)
|
||||
#define OP_TLBI_VAAE1 sys_insn(1, 0, 8, 7, 3)
|
||||
#define OP_TLBI_VALE1 sys_insn(1, 0, 8, 7, 5)
|
||||
#define OP_TLBI_VAALE1 sys_insn(1, 0, 8, 7, 7)
|
||||
#define OP_TLBI_VMALLE1OSNXS sys_insn(1, 0, 9, 1, 0)
|
||||
#define OP_TLBI_VAE1OSNXS sys_insn(1, 0, 9, 1, 1)
|
||||
#define OP_TLBI_ASIDE1OSNXS sys_insn(1, 0, 9, 1, 2)
|
||||
#define OP_TLBI_VAAE1OSNXS sys_insn(1, 0, 9, 1, 3)
|
||||
#define OP_TLBI_VALE1OSNXS sys_insn(1, 0, 9, 1, 5)
|
||||
#define OP_TLBI_VAALE1OSNXS sys_insn(1, 0, 9, 1, 7)
|
||||
#define OP_TLBI_RVAE1ISNXS sys_insn(1, 0, 9, 2, 1)
|
||||
#define OP_TLBI_RVAAE1ISNXS sys_insn(1, 0, 9, 2, 3)
|
||||
#define OP_TLBI_RVALE1ISNXS sys_insn(1, 0, 9, 2, 5)
|
||||
#define OP_TLBI_RVAALE1ISNXS sys_insn(1, 0, 9, 2, 7)
|
||||
#define OP_TLBI_VMALLE1ISNXS sys_insn(1, 0, 9, 3, 0)
|
||||
#define OP_TLBI_VAE1ISNXS sys_insn(1, 0, 9, 3, 1)
|
||||
#define OP_TLBI_ASIDE1ISNXS sys_insn(1, 0, 9, 3, 2)
|
||||
#define OP_TLBI_VAAE1ISNXS sys_insn(1, 0, 9, 3, 3)
|
||||
#define OP_TLBI_VALE1ISNXS sys_insn(1, 0, 9, 3, 5)
|
||||
#define OP_TLBI_VAALE1ISNXS sys_insn(1, 0, 9, 3, 7)
|
||||
#define OP_TLBI_RVAE1OSNXS sys_insn(1, 0, 9, 5, 1)
|
||||
#define OP_TLBI_RVAAE1OSNXS sys_insn(1, 0, 9, 5, 3)
|
||||
#define OP_TLBI_RVALE1OSNXS sys_insn(1, 0, 9, 5, 5)
|
||||
#define OP_TLBI_RVAALE1OSNXS sys_insn(1, 0, 9, 5, 7)
|
||||
#define OP_TLBI_RVAE1NXS sys_insn(1, 0, 9, 6, 1)
|
||||
#define OP_TLBI_RVAAE1NXS sys_insn(1, 0, 9, 6, 3)
|
||||
#define OP_TLBI_RVALE1NXS sys_insn(1, 0, 9, 6, 5)
|
||||
#define OP_TLBI_RVAALE1NXS sys_insn(1, 0, 9, 6, 7)
|
||||
#define OP_TLBI_VMALLE1NXS sys_insn(1, 0, 9, 7, 0)
|
||||
#define OP_TLBI_VAE1NXS sys_insn(1, 0, 9, 7, 1)
|
||||
#define OP_TLBI_ASIDE1NXS sys_insn(1, 0, 9, 7, 2)
|
||||
#define OP_TLBI_VAAE1NXS sys_insn(1, 0, 9, 7, 3)
|
||||
#define OP_TLBI_VALE1NXS sys_insn(1, 0, 9, 7, 5)
|
||||
#define OP_TLBI_VAALE1NXS sys_insn(1, 0, 9, 7, 7)
|
||||
#define OP_TLBI_IPAS2E1IS sys_insn(1, 4, 8, 0, 1)
|
||||
#define OP_TLBI_RIPAS2E1IS sys_insn(1, 4, 8, 0, 2)
|
||||
#define OP_TLBI_IPAS2LE1IS sys_insn(1, 4, 8, 0, 5)
|
||||
#define OP_TLBI_RIPAS2LE1IS sys_insn(1, 4, 8, 0, 6)
|
||||
#define OP_TLBI_ALLE2OS sys_insn(1, 4, 8, 1, 0)
|
||||
#define OP_TLBI_VAE2OS sys_insn(1, 4, 8, 1, 1)
|
||||
#define OP_TLBI_ALLE1OS sys_insn(1, 4, 8, 1, 4)
|
||||
#define OP_TLBI_VALE2OS sys_insn(1, 4, 8, 1, 5)
|
||||
#define OP_TLBI_VMALLS12E1OS sys_insn(1, 4, 8, 1, 6)
|
||||
#define OP_TLBI_RVAE2IS sys_insn(1, 4, 8, 2, 1)
|
||||
#define OP_TLBI_RVALE2IS sys_insn(1, 4, 8, 2, 5)
|
||||
#define OP_TLBI_ALLE2IS sys_insn(1, 4, 8, 3, 0)
|
||||
#define OP_TLBI_VAE2IS sys_insn(1, 4, 8, 3, 1)
|
||||
#define OP_TLBI_ALLE1IS sys_insn(1, 4, 8, 3, 4)
|
||||
#define OP_TLBI_VALE2IS sys_insn(1, 4, 8, 3, 5)
|
||||
#define OP_TLBI_VMALLS12E1IS sys_insn(1, 4, 8, 3, 6)
|
||||
#define OP_TLBI_IPAS2E1OS sys_insn(1, 4, 8, 4, 0)
|
||||
#define OP_TLBI_IPAS2E1 sys_insn(1, 4, 8, 4, 1)
|
||||
#define OP_TLBI_RIPAS2E1 sys_insn(1, 4, 8, 4, 2)
|
||||
#define OP_TLBI_RIPAS2E1OS sys_insn(1, 4, 8, 4, 3)
|
||||
#define OP_TLBI_IPAS2LE1OS sys_insn(1, 4, 8, 4, 4)
|
||||
#define OP_TLBI_IPAS2LE1 sys_insn(1, 4, 8, 4, 5)
|
||||
#define OP_TLBI_RIPAS2LE1 sys_insn(1, 4, 8, 4, 6)
|
||||
#define OP_TLBI_RIPAS2LE1OS sys_insn(1, 4, 8, 4, 7)
|
||||
#define OP_TLBI_RVAE2OS sys_insn(1, 4, 8, 5, 1)
|
||||
#define OP_TLBI_RVALE2OS sys_insn(1, 4, 8, 5, 5)
|
||||
#define OP_TLBI_RVAE2 sys_insn(1, 4, 8, 6, 1)
|
||||
#define OP_TLBI_RVALE2 sys_insn(1, 4, 8, 6, 5)
|
||||
#define OP_TLBI_ALLE2 sys_insn(1, 4, 8, 7, 0)
|
||||
#define OP_TLBI_VAE2 sys_insn(1, 4, 8, 7, 1)
|
||||
#define OP_TLBI_ALLE1 sys_insn(1, 4, 8, 7, 4)
|
||||
#define OP_TLBI_VALE2 sys_insn(1, 4, 8, 7, 5)
|
||||
#define OP_TLBI_VMALLS12E1 sys_insn(1, 4, 8, 7, 6)
|
||||
#define OP_TLBI_IPAS2E1ISNXS sys_insn(1, 4, 9, 0, 1)
|
||||
#define OP_TLBI_RIPAS2E1ISNXS sys_insn(1, 4, 9, 0, 2)
|
||||
#define OP_TLBI_IPAS2LE1ISNXS sys_insn(1, 4, 9, 0, 5)
|
||||
#define OP_TLBI_RIPAS2LE1ISNXS sys_insn(1, 4, 9, 0, 6)
|
||||
#define OP_TLBI_ALLE2OSNXS sys_insn(1, 4, 9, 1, 0)
|
||||
#define OP_TLBI_VAE2OSNXS sys_insn(1, 4, 9, 1, 1)
|
||||
#define OP_TLBI_ALLE1OSNXS sys_insn(1, 4, 9, 1, 4)
|
||||
#define OP_TLBI_VALE2OSNXS sys_insn(1, 4, 9, 1, 5)
|
||||
#define OP_TLBI_VMALLS12E1OSNXS sys_insn(1, 4, 9, 1, 6)
|
||||
#define OP_TLBI_RVAE2ISNXS sys_insn(1, 4, 9, 2, 1)
|
||||
#define OP_TLBI_RVALE2ISNXS sys_insn(1, 4, 9, 2, 5)
|
||||
#define OP_TLBI_ALLE2ISNXS sys_insn(1, 4, 9, 3, 0)
|
||||
#define OP_TLBI_VAE2ISNXS sys_insn(1, 4, 9, 3, 1)
|
||||
#define OP_TLBI_ALLE1ISNXS sys_insn(1, 4, 9, 3, 4)
|
||||
#define OP_TLBI_VALE2ISNXS sys_insn(1, 4, 9, 3, 5)
|
||||
#define OP_TLBI_VMALLS12E1ISNXS sys_insn(1, 4, 9, 3, 6)
|
||||
#define OP_TLBI_IPAS2E1OSNXS sys_insn(1, 4, 9, 4, 0)
|
||||
#define OP_TLBI_IPAS2E1NXS sys_insn(1, 4, 9, 4, 1)
|
||||
#define OP_TLBI_RIPAS2E1NXS sys_insn(1, 4, 9, 4, 2)
|
||||
#define OP_TLBI_RIPAS2E1OSNXS sys_insn(1, 4, 9, 4, 3)
|
||||
#define OP_TLBI_IPAS2LE1OSNXS sys_insn(1, 4, 9, 4, 4)
|
||||
#define OP_TLBI_IPAS2LE1NXS sys_insn(1, 4, 9, 4, 5)
|
||||
#define OP_TLBI_RIPAS2LE1NXS sys_insn(1, 4, 9, 4, 6)
|
||||
#define OP_TLBI_RIPAS2LE1OSNXS sys_insn(1, 4, 9, 4, 7)
|
||||
#define OP_TLBI_RVAE2OSNXS sys_insn(1, 4, 9, 5, 1)
|
||||
#define OP_TLBI_RVALE2OSNXS sys_insn(1, 4, 9, 5, 5)
|
||||
#define OP_TLBI_RVAE2NXS sys_insn(1, 4, 9, 6, 1)
|
||||
#define OP_TLBI_RVALE2NXS sys_insn(1, 4, 9, 6, 5)
|
||||
#define OP_TLBI_ALLE2NXS sys_insn(1, 4, 9, 7, 0)
|
||||
#define OP_TLBI_VAE2NXS sys_insn(1, 4, 9, 7, 1)
|
||||
#define OP_TLBI_ALLE1NXS sys_insn(1, 4, 9, 7, 4)
|
||||
#define OP_TLBI_VALE2NXS sys_insn(1, 4, 9, 7, 5)
|
||||
#define OP_TLBI_VMALLS12E1NXS sys_insn(1, 4, 9, 7, 6)
|
||||
|
||||
/* Misc instructions */
|
||||
#define OP_BRB_IALL sys_insn(1, 1, 7, 2, 4)
|
||||
#define OP_BRB_INJ sys_insn(1, 1, 7, 2, 5)
|
||||
#define OP_CFP_RCTX sys_insn(1, 3, 7, 3, 4)
|
||||
#define OP_DVP_RCTX sys_insn(1, 3, 7, 3, 5)
|
||||
#define OP_CPP_RCTX sys_insn(1, 3, 7, 3, 7)
|
||||
|
||||
/* Common SCTLR_ELx flags. */
|
||||
#define SCTLR_ELx_ENTP2 (BIT(60))
|
||||
#define SCTLR_ELx_DSSBS (BIT(44))
|
||||
|
||||
@@ -335,14 +335,77 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
|
||||
*/
|
||||
#define MAX_TLBI_OPS PTRS_PER_PTE
|
||||
|
||||
/*
|
||||
* __flush_tlb_range_op - Perform TLBI operation upon a range
|
||||
*
|
||||
* @op: TLBI instruction that operates on a range (has 'r' prefix)
|
||||
* @start: The start address of the range
|
||||
* @pages: Range as the number of pages from 'start'
|
||||
* @stride: Flush granularity
|
||||
* @asid: The ASID of the task (0 for IPA instructions)
|
||||
* @tlb_level: Translation Table level hint, if known
|
||||
* @tlbi_user: If 'true', call an additional __tlbi_user()
|
||||
* (typically for user ASIDs). 'flase' for IPA instructions
|
||||
*
|
||||
* When the CPU does not support TLB range operations, flush the TLB
|
||||
* entries one by one at the granularity of 'stride'. If the TLB
|
||||
* range ops are supported, then:
|
||||
*
|
||||
* 1. If 'pages' is odd, flush the first page through non-range
|
||||
* operations;
|
||||
*
|
||||
* 2. For remaining pages: the minimum range granularity is decided
|
||||
* by 'scale', so multiple range TLBI operations may be required.
|
||||
* Start from scale = 0, flush the corresponding number of pages
|
||||
* ((num+1)*2^(5*scale+1) starting from 'addr'), then increase it
|
||||
* until no pages left.
|
||||
*
|
||||
* Note that certain ranges can be represented by either num = 31 and
|
||||
* scale or num = 0 and scale + 1. The loop below favours the latter
|
||||
* since num is limited to 30 by the __TLBI_RANGE_NUM() macro.
|
||||
*/
|
||||
#define __flush_tlb_range_op(op, start, pages, stride, \
|
||||
asid, tlb_level, tlbi_user) \
|
||||
do { \
|
||||
int num = 0; \
|
||||
int scale = 0; \
|
||||
unsigned long addr; \
|
||||
\
|
||||
while (pages > 0) { \
|
||||
if (!system_supports_tlb_range() || \
|
||||
pages % 2 == 1) { \
|
||||
addr = __TLBI_VADDR(start, asid); \
|
||||
__tlbi_level(op, addr, tlb_level); \
|
||||
if (tlbi_user) \
|
||||
__tlbi_user_level(op, addr, tlb_level); \
|
||||
start += stride; \
|
||||
pages -= stride >> PAGE_SHIFT; \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
num = __TLBI_RANGE_NUM(pages, scale); \
|
||||
if (num >= 0) { \
|
||||
addr = __TLBI_VADDR_RANGE(start, asid, scale, \
|
||||
num, tlb_level); \
|
||||
__tlbi(r##op, addr); \
|
||||
if (tlbi_user) \
|
||||
__tlbi_user(r##op, addr); \
|
||||
start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
|
||||
pages -= __TLBI_RANGE_PAGES(num, scale); \
|
||||
} \
|
||||
scale++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
|
||||
__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false)
|
||||
|
||||
static inline void __flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long stride, bool last_level,
|
||||
int tlb_level)
|
||||
{
|
||||
int num = 0;
|
||||
int scale = 0;
|
||||
unsigned long asid, addr, pages;
|
||||
unsigned long asid, pages;
|
||||
|
||||
start = round_down(start, stride);
|
||||
end = round_up(end, stride);
|
||||
@@ -364,56 +427,11 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
|
||||
dsb(ishst);
|
||||
asid = ASID(vma->vm_mm);
|
||||
|
||||
/*
|
||||
* When the CPU does not support TLB range operations, flush the TLB
|
||||
* entries one by one at the granularity of 'stride'. If the TLB
|
||||
* range ops are supported, then:
|
||||
*
|
||||
* 1. If 'pages' is odd, flush the first page through non-range
|
||||
* operations;
|
||||
*
|
||||
* 2. For remaining pages: the minimum range granularity is decided
|
||||
* by 'scale', so multiple range TLBI operations may be required.
|
||||
* Start from scale = 0, flush the corresponding number of pages
|
||||
* ((num+1)*2^(5*scale+1) starting from 'addr'), then increase it
|
||||
* until no pages left.
|
||||
*
|
||||
* Note that certain ranges can be represented by either num = 31 and
|
||||
* scale or num = 0 and scale + 1. The loop below favours the latter
|
||||
* since num is limited to 30 by the __TLBI_RANGE_NUM() macro.
|
||||
*/
|
||||
while (pages > 0) {
|
||||
if (!system_supports_tlb_range() ||
|
||||
pages % 2 == 1) {
|
||||
addr = __TLBI_VADDR(start, asid);
|
||||
if (last_level) {
|
||||
__tlbi_level(vale1is, addr, tlb_level);
|
||||
__tlbi_user_level(vale1is, addr, tlb_level);
|
||||
} else {
|
||||
__tlbi_level(vae1is, addr, tlb_level);
|
||||
__tlbi_user_level(vae1is, addr, tlb_level);
|
||||
}
|
||||
start += stride;
|
||||
pages -= stride >> PAGE_SHIFT;
|
||||
continue;
|
||||
}
|
||||
if (last_level)
|
||||
__flush_tlb_range_op(vale1is, start, pages, stride, asid, tlb_level, true);
|
||||
else
|
||||
__flush_tlb_range_op(vae1is, start, pages, stride, asid, tlb_level, true);
|
||||
|
||||
num = __TLBI_RANGE_NUM(pages, scale);
|
||||
if (num >= 0) {
|
||||
addr = __TLBI_VADDR_RANGE(start, asid, scale,
|
||||
num, tlb_level);
|
||||
if (last_level) {
|
||||
__tlbi(rvale1is, addr);
|
||||
__tlbi_user(rvale1is, addr);
|
||||
} else {
|
||||
__tlbi(rvae1is, addr);
|
||||
__tlbi_user(rvae1is, addr);
|
||||
}
|
||||
start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT;
|
||||
pages -= __TLBI_RANGE_PAGES(num, scale);
|
||||
}
|
||||
scale++;
|
||||
}
|
||||
dsb(ish);
|
||||
mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
|
||||
}
|
||||
|
||||
@@ -2628,6 +2628,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
.matches = has_cpuid_feature,
|
||||
ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LRCPC, IMP)
|
||||
},
|
||||
{
|
||||
.desc = "Fine Grained Traps",
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
.capability = ARM64_HAS_FGT,
|
||||
.matches = has_cpuid_feature,
|
||||
ARM64_CPUID_FIELDS(ID_AA64MMFR0_EL1, FGT, IMP)
|
||||
},
|
||||
#ifdef CONFIG_ARM64_SME
|
||||
{
|
||||
.desc = "Scalable Matrix Extension",
|
||||
|
||||
@@ -262,9 +262,9 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
len = strscpy(buf, cmdline, ARRAY_SIZE(buf));
|
||||
if (len == -E2BIG)
|
||||
len = ARRAY_SIZE(buf) - 1;
|
||||
len = min(len, ARRAY_SIZE(buf) - 1);
|
||||
memcpy(buf, cmdline, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
if (strcmp(buf, "--") == 0)
|
||||
return;
|
||||
|
||||
@@ -25,7 +25,6 @@ menuconfig KVM
|
||||
select MMU_NOTIFIER
|
||||
select PREEMPT_NOTIFIERS
|
||||
select HAVE_KVM_CPU_RELAX_INTERCEPT
|
||||
select HAVE_KVM_ARCH_TLB_FLUSH_ALL
|
||||
select KVM_MMIO
|
||||
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
|
||||
select KVM_XFER_TO_GUEST_WORK
|
||||
@@ -43,6 +42,7 @@ menuconfig KVM
|
||||
select SCHED_INFO
|
||||
select GUEST_PERF_EVENTS if PERF_EVENTS
|
||||
select INTERVAL_TREE
|
||||
select XARRAY_MULTI
|
||||
help
|
||||
Support hosting virtualized guest machines.
|
||||
|
||||
|
||||
+20
-45
@@ -36,6 +36,7 @@
|
||||
#include <asm/kvm_arm.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_mmu.h>
|
||||
#include <asm/kvm_nested.h>
|
||||
#include <asm/kvm_pkvm.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/sections.h>
|
||||
@@ -365,7 +366,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
#endif
|
||||
|
||||
/* Force users to call KVM_ARM_VCPU_INIT */
|
||||
vcpu->arch.target = -1;
|
||||
vcpu_clear_flag(vcpu, VCPU_INITIALIZED);
|
||||
bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
|
||||
|
||||
vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
|
||||
@@ -462,7 +463,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
vcpu_ptrauth_disable(vcpu);
|
||||
kvm_arch_vcpu_load_debug_state_flags(vcpu);
|
||||
|
||||
if (!cpumask_test_cpu(smp_processor_id(), vcpu->kvm->arch.supported_cpus))
|
||||
if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
|
||||
vcpu_set_on_unsupported_cpu(vcpu);
|
||||
}
|
||||
|
||||
@@ -574,7 +575,7 @@ unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu->arch.target >= 0;
|
||||
return vcpu_get_flag(vcpu, VCPU_INITIALIZED);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -803,6 +804,9 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
|
||||
kvm_pmu_handle_pmcr(vcpu,
|
||||
__vcpu_sys_reg(vcpu, PMCR_EL0));
|
||||
|
||||
if (kvm_check_request(KVM_REQ_RESYNC_PMU_EL0, vcpu))
|
||||
kvm_vcpu_pmu_restore_guest(vcpu);
|
||||
|
||||
if (kvm_check_request(KVM_REQ_SUSPEND, vcpu))
|
||||
return kvm_vcpu_suspend(vcpu);
|
||||
|
||||
@@ -818,6 +822,9 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)
|
||||
if (likely(!vcpu_mode_is_32bit(vcpu)))
|
||||
return false;
|
||||
|
||||
if (vcpu_has_nv(vcpu))
|
||||
return true;
|
||||
|
||||
return !kvm_supports_32bit_el0();
|
||||
}
|
||||
|
||||
@@ -1058,7 +1065,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
|
||||
* invalid. The VMM can try and fix it by issuing a
|
||||
* KVM_ARM_VCPU_INIT if it really wants to.
|
||||
*/
|
||||
vcpu->arch.target = -1;
|
||||
vcpu_clear_flag(vcpu, VCPU_INITIALIZED);
|
||||
ret = ARM_EXCEPTION_IL;
|
||||
}
|
||||
|
||||
@@ -1219,8 +1226,7 @@ static bool kvm_vcpu_init_changed(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
unsigned long features = init->features[0];
|
||||
|
||||
return !bitmap_equal(vcpu->arch.features, &features, KVM_VCPU_MAX_FEATURES) ||
|
||||
vcpu->arch.target != init->target;
|
||||
return !bitmap_equal(vcpu->arch.features, &features, KVM_VCPU_MAX_FEATURES);
|
||||
}
|
||||
|
||||
static int __kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
|
||||
@@ -1236,20 +1242,18 @@ static int __kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
|
||||
!bitmap_equal(kvm->arch.vcpu_features, &features, KVM_VCPU_MAX_FEATURES))
|
||||
goto out_unlock;
|
||||
|
||||
vcpu->arch.target = init->target;
|
||||
bitmap_copy(vcpu->arch.features, &features, KVM_VCPU_MAX_FEATURES);
|
||||
|
||||
/* Now we know what it is, we can reset it. */
|
||||
ret = kvm_reset_vcpu(vcpu);
|
||||
if (ret) {
|
||||
vcpu->arch.target = -1;
|
||||
bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
bitmap_copy(kvm->arch.vcpu_features, &features, KVM_VCPU_MAX_FEATURES);
|
||||
set_bit(KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED, &kvm->arch.flags);
|
||||
|
||||
vcpu_set_flag(vcpu, VCPU_INITIALIZED);
|
||||
out_unlock:
|
||||
mutex_unlock(&kvm->arch.config_lock);
|
||||
return ret;
|
||||
@@ -1260,14 +1264,15 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (init->target != kvm_target_cpu())
|
||||
if (init->target != KVM_ARM_TARGET_GENERIC_V8 &&
|
||||
init->target != kvm_target_cpu())
|
||||
return -EINVAL;
|
||||
|
||||
ret = kvm_vcpu_init_check_features(vcpu, init);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (vcpu->arch.target == -1)
|
||||
if (!kvm_vcpu_initialized(vcpu))
|
||||
return __kvm_vcpu_set_target(vcpu, init);
|
||||
|
||||
if (kvm_vcpu_init_changed(vcpu, init))
|
||||
@@ -1532,12 +1537,6 @@ void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
|
||||
|
||||
}
|
||||
|
||||
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
|
||||
const struct kvm_memory_slot *memslot)
|
||||
{
|
||||
kvm_flush_remote_tlbs(kvm);
|
||||
}
|
||||
|
||||
static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
|
||||
struct kvm_arm_device_addr *dev_addr)
|
||||
{
|
||||
@@ -1595,9 +1594,9 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
|
||||
return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr);
|
||||
}
|
||||
case KVM_ARM_PREFERRED_TARGET: {
|
||||
struct kvm_vcpu_init init;
|
||||
|
||||
kvm_vcpu_preferred_target(&init);
|
||||
struct kvm_vcpu_init init = {
|
||||
.target = KVM_ARM_TARGET_GENERIC_V8,
|
||||
};
|
||||
|
||||
if (copy_to_user(argp, &init, sizeof(init)))
|
||||
return -EFAULT;
|
||||
@@ -2276,30 +2275,8 @@ static int __init init_hyp_mode(void)
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
|
||||
char *stack_page = (char *)per_cpu(kvm_arm_hyp_stack_page, cpu);
|
||||
unsigned long hyp_addr;
|
||||
|
||||
/*
|
||||
* Allocate a contiguous HYP private VA range for the stack
|
||||
* and guard page. The allocation is also aligned based on
|
||||
* the order of its size.
|
||||
*/
|
||||
err = hyp_alloc_private_va_range(PAGE_SIZE * 2, &hyp_addr);
|
||||
if (err) {
|
||||
kvm_err("Cannot allocate hyp stack guard page\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the stack grows downwards, map the stack to the page
|
||||
* at the higher address and leave the lower guard page
|
||||
* unbacked.
|
||||
*
|
||||
* Any valid stack address now has the PAGE_SHIFT bit as 1
|
||||
* and addresses corresponding to the guard page have the
|
||||
* PAGE_SHIFT bit as 0 - this is used for overflow detection.
|
||||
*/
|
||||
err = __create_hyp_mappings(hyp_addr + PAGE_SIZE, PAGE_SIZE,
|
||||
__pa(stack_page), PAGE_HYP);
|
||||
err = create_hyp_stack(__pa(stack_page), ¶ms->stack_hyp_va);
|
||||
if (err) {
|
||||
kvm_err("Cannot map hyp stack\n");
|
||||
goto out_err;
|
||||
@@ -2312,8 +2289,6 @@ static int __init init_hyp_mode(void)
|
||||
* has been mapped in the flexible private VA space.
|
||||
*/
|
||||
params->stack_pa = __pa(stack_page);
|
||||
|
||||
params->stack_hyp_va = hyp_addr + (2 * PAGE_SIZE);
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -884,21 +884,6 @@ u32 __attribute_const__ kvm_target_cpu(void)
|
||||
return KVM_ARM_TARGET_GENERIC_V8;
|
||||
}
|
||||
|
||||
void kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
|
||||
{
|
||||
u32 target = kvm_target_cpu();
|
||||
|
||||
memset(init, 0, sizeof(*init));
|
||||
|
||||
/*
|
||||
* For now, we don't return any features.
|
||||
* In future, we might use features to return target
|
||||
* specific features available for the preferred
|
||||
* target type.
|
||||
*/
|
||||
init->target = (__u32)target;
|
||||
}
|
||||
|
||||
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
||||
@@ -222,7 +222,33 @@ static int kvm_handle_eret(struct kvm_vcpu *vcpu)
|
||||
if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
|
||||
return kvm_handle_ptrauth(vcpu);
|
||||
|
||||
kvm_emulate_nested_eret(vcpu);
|
||||
/*
|
||||
* If we got here, two possibilities:
|
||||
*
|
||||
* - the guest is in EL2, and we need to fully emulate ERET
|
||||
*
|
||||
* - the guest is in EL1, and we need to reinject the
|
||||
* exception into the L1 hypervisor.
|
||||
*
|
||||
* If KVM ever traps ERET for its own use, we'll have to
|
||||
* revisit this.
|
||||
*/
|
||||
if (is_hyp_ctxt(vcpu))
|
||||
kvm_emulate_nested_eret(vcpu);
|
||||
else
|
||||
kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int handle_svc(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
/*
|
||||
* So far, SVC traps only for NV via HFGITR_EL2. A SVC from a
|
||||
* 32bit guest would be caught by vpcu_mode_is_bad_32bit(), so
|
||||
* we should only have to deal with a 64 bit exception.
|
||||
*/
|
||||
kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -239,6 +265,7 @@ static exit_handle_fn arm_exit_handlers[] = {
|
||||
[ESR_ELx_EC_SMC32] = handle_smc,
|
||||
[ESR_ELx_EC_HVC64] = handle_hvc,
|
||||
[ESR_ELx_EC_SMC64] = handle_smc,
|
||||
[ESR_ELx_EC_SVC64] = handle_svc,
|
||||
[ESR_ELx_EC_SYS64] = kvm_handle_sys_reg,
|
||||
[ESR_ELx_EC_SVE] = handle_sve,
|
||||
[ESR_ELx_EC_ERET] = kvm_handle_eret,
|
||||
|
||||
@@ -70,20 +70,26 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool __hfgxtr_traps_required(void)
|
||||
{
|
||||
if (cpus_have_final_cap(ARM64_SME))
|
||||
return true;
|
||||
|
||||
if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void __activate_traps_hfgxtr(void)
|
||||
#define compute_clr_set(vcpu, reg, clr, set) \
|
||||
do { \
|
||||
u64 hfg; \
|
||||
hfg = __vcpu_sys_reg(vcpu, reg) & ~__ ## reg ## _RES0; \
|
||||
set |= hfg & __ ## reg ## _MASK; \
|
||||
clr |= ~hfg & __ ## reg ## _nMASK; \
|
||||
} while(0)
|
||||
|
||||
|
||||
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
|
||||
u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
|
||||
u64 r_val, w_val;
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT))
|
||||
return;
|
||||
|
||||
ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
|
||||
ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
|
||||
|
||||
if (cpus_have_final_cap(ARM64_SME)) {
|
||||
tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
|
||||
@@ -98,26 +104,72 @@ static inline void __activate_traps_hfgxtr(void)
|
||||
if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
|
||||
w_set |= HFGxTR_EL2_TCR_EL1_MASK;
|
||||
|
||||
sysreg_clear_set_s(SYS_HFGRTR_EL2, r_clr, r_set);
|
||||
sysreg_clear_set_s(SYS_HFGWTR_EL2, w_clr, w_set);
|
||||
}
|
||||
|
||||
static inline void __deactivate_traps_hfgxtr(void)
|
||||
{
|
||||
u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
|
||||
|
||||
if (cpus_have_final_cap(ARM64_SME)) {
|
||||
tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
|
||||
|
||||
r_set |= tmp;
|
||||
w_set |= tmp;
|
||||
if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
|
||||
compute_clr_set(vcpu, HFGRTR_EL2, r_clr, r_set);
|
||||
compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
|
||||
}
|
||||
|
||||
if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
|
||||
w_clr |= HFGxTR_EL2_TCR_EL1_MASK;
|
||||
/* The default is not to trap anything but ACCDATA_EL1 */
|
||||
r_val = __HFGRTR_EL2_nMASK & ~HFGxTR_EL2_nACCDATA_EL1;
|
||||
r_val |= r_set;
|
||||
r_val &= ~r_clr;
|
||||
|
||||
sysreg_clear_set_s(SYS_HFGRTR_EL2, r_clr, r_set);
|
||||
sysreg_clear_set_s(SYS_HFGWTR_EL2, w_clr, w_set);
|
||||
w_val = __HFGWTR_EL2_nMASK & ~HFGxTR_EL2_nACCDATA_EL1;
|
||||
w_val |= w_set;
|
||||
w_val &= ~w_clr;
|
||||
|
||||
write_sysreg_s(r_val, SYS_HFGRTR_EL2);
|
||||
write_sysreg_s(w_val, SYS_HFGWTR_EL2);
|
||||
|
||||
if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
|
||||
return;
|
||||
|
||||
ctxt_sys_reg(hctxt, HFGITR_EL2) = read_sysreg_s(SYS_HFGITR_EL2);
|
||||
|
||||
r_set = r_clr = 0;
|
||||
compute_clr_set(vcpu, HFGITR_EL2, r_clr, r_set);
|
||||
r_val = __HFGITR_EL2_nMASK;
|
||||
r_val |= r_set;
|
||||
r_val &= ~r_clr;
|
||||
|
||||
write_sysreg_s(r_val, SYS_HFGITR_EL2);
|
||||
|
||||
ctxt_sys_reg(hctxt, HDFGRTR_EL2) = read_sysreg_s(SYS_HDFGRTR_EL2);
|
||||
ctxt_sys_reg(hctxt, HDFGWTR_EL2) = read_sysreg_s(SYS_HDFGWTR_EL2);
|
||||
|
||||
r_clr = r_set = w_clr = w_set = 0;
|
||||
|
||||
compute_clr_set(vcpu, HDFGRTR_EL2, r_clr, r_set);
|
||||
compute_clr_set(vcpu, HDFGWTR_EL2, w_clr, w_set);
|
||||
|
||||
r_val = __HDFGRTR_EL2_nMASK;
|
||||
r_val |= r_set;
|
||||
r_val &= ~r_clr;
|
||||
|
||||
w_val = __HDFGWTR_EL2_nMASK;
|
||||
w_val |= w_set;
|
||||
w_val &= ~w_clr;
|
||||
|
||||
write_sysreg_s(r_val, SYS_HDFGRTR_EL2);
|
||||
write_sysreg_s(w_val, SYS_HDFGWTR_EL2);
|
||||
}
|
||||
|
||||
static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT))
|
||||
return;
|
||||
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
|
||||
|
||||
if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
|
||||
return;
|
||||
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
|
||||
}
|
||||
|
||||
static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
||||
@@ -145,8 +197,21 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
||||
vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
|
||||
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
|
||||
|
||||
if (__hfgxtr_traps_required())
|
||||
__activate_traps_hfgxtr();
|
||||
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
|
||||
u64 hcrx = HCRX_GUEST_FLAGS;
|
||||
if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
|
||||
u64 clr = 0, set = 0;
|
||||
|
||||
compute_clr_set(vcpu, HCRX_EL2, clr, set);
|
||||
|
||||
hcrx |= set;
|
||||
hcrx &= ~clr;
|
||||
}
|
||||
|
||||
write_sysreg_s(hcrx, SYS_HCRX_EL2);
|
||||
}
|
||||
|
||||
__activate_traps_hfgxtr(vcpu);
|
||||
}
|
||||
|
||||
static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
|
||||
@@ -162,8 +227,10 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
|
||||
vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU);
|
||||
}
|
||||
|
||||
if (__hfgxtr_traps_required())
|
||||
__deactivate_traps_hfgxtr();
|
||||
if (cpus_have_final_cap(ARM64_HAS_HCX))
|
||||
write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2);
|
||||
|
||||
__deactivate_traps_hfgxtr(vcpu);
|
||||
}
|
||||
|
||||
static inline void ___activate_traps(struct kvm_vcpu *vcpu)
|
||||
@@ -177,9 +244,6 @@ static inline void ___activate_traps(struct kvm_vcpu *vcpu)
|
||||
|
||||
if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE))
|
||||
write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
|
||||
|
||||
if (cpus_have_final_cap(ARM64_HAS_HCX))
|
||||
write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2);
|
||||
}
|
||||
|
||||
static inline void ___deactivate_traps(struct kvm_vcpu *vcpu)
|
||||
@@ -194,9 +258,6 @@ static inline void ___deactivate_traps(struct kvm_vcpu *vcpu)
|
||||
vcpu->arch.hcr_el2 &= ~HCR_VSE;
|
||||
vcpu->arch.hcr_el2 |= read_sysreg(hcr_el2) & HCR_VSE;
|
||||
}
|
||||
|
||||
if (cpus_have_final_cap(ARM64_HAS_HCX))
|
||||
write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2);
|
||||
}
|
||||
|
||||
static inline bool __populate_fault_info(struct kvm_vcpu *vcpu)
|
||||
|
||||
@@ -26,6 +26,7 @@ int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot
|
||||
int __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
|
||||
enum kvm_pgtable_prot prot,
|
||||
unsigned long *haddr);
|
||||
int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr);
|
||||
int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr);
|
||||
|
||||
#endif /* __KVM_HYP_MM_H */
|
||||
|
||||
@@ -135,6 +135,16 @@ static void handle___kvm_tlb_flush_vmid_ipa_nsh(struct kvm_cpu_context *host_ctx
|
||||
__kvm_tlb_flush_vmid_ipa_nsh(kern_hyp_va(mmu), ipa, level);
|
||||
}
|
||||
|
||||
static void
|
||||
handle___kvm_tlb_flush_vmid_range(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
|
||||
DECLARE_REG(phys_addr_t, start, host_ctxt, 2);
|
||||
DECLARE_REG(unsigned long, pages, host_ctxt, 3);
|
||||
|
||||
__kvm_tlb_flush_vmid_range(kern_hyp_va(mmu), start, pages);
|
||||
}
|
||||
|
||||
static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
|
||||
@@ -327,6 +337,7 @@ static const hcall_t host_hcall[] = {
|
||||
HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa),
|
||||
HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa_nsh),
|
||||
HANDLE_FUNC(__kvm_tlb_flush_vmid),
|
||||
HANDLE_FUNC(__kvm_tlb_flush_vmid_range),
|
||||
HANDLE_FUNC(__kvm_flush_cpu_context),
|
||||
HANDLE_FUNC(__kvm_timer_set_cntvoff),
|
||||
HANDLE_FUNC(__vgic_v3_read_vmcr),
|
||||
|
||||
@@ -44,6 +44,27 @@ static int __pkvm_create_mappings(unsigned long start, unsigned long size,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __pkvm_alloc_private_va_range(unsigned long start, size_t size)
|
||||
{
|
||||
unsigned long cur;
|
||||
|
||||
hyp_assert_lock_held(&pkvm_pgd_lock);
|
||||
|
||||
if (!start || start < __io_map_base)
|
||||
return -EINVAL;
|
||||
|
||||
/* The allocated size is always a multiple of PAGE_SIZE */
|
||||
cur = start + PAGE_ALIGN(size);
|
||||
|
||||
/* Are we overflowing on the vmemmap ? */
|
||||
if (cur > __hyp_vmemmap)
|
||||
return -ENOMEM;
|
||||
|
||||
__io_map_base = cur;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pkvm_alloc_private_va_range - Allocates a private VA range.
|
||||
* @size: The size of the VA range to reserve.
|
||||
@@ -56,27 +77,16 @@ static int __pkvm_create_mappings(unsigned long start, unsigned long size,
|
||||
*/
|
||||
int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr)
|
||||
{
|
||||
unsigned long base, addr;
|
||||
int ret = 0;
|
||||
unsigned long addr;
|
||||
int ret;
|
||||
|
||||
hyp_spin_lock(&pkvm_pgd_lock);
|
||||
|
||||
/* Align the allocation based on the order of its size */
|
||||
addr = ALIGN(__io_map_base, PAGE_SIZE << get_order(size));
|
||||
|
||||
/* The allocated size is always a multiple of PAGE_SIZE */
|
||||
base = addr + PAGE_ALIGN(size);
|
||||
|
||||
/* Are we overflowing on the vmemmap ? */
|
||||
if (!addr || base > __hyp_vmemmap)
|
||||
ret = -ENOMEM;
|
||||
else {
|
||||
__io_map_base = base;
|
||||
*haddr = addr;
|
||||
}
|
||||
|
||||
addr = __io_map_base;
|
||||
ret = __pkvm_alloc_private_va_range(addr, size);
|
||||
hyp_spin_unlock(&pkvm_pgd_lock);
|
||||
|
||||
*haddr = addr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -340,6 +350,45 @@ int hyp_create_idmap(u32 hyp_va_bits)
|
||||
return __pkvm_create_mappings(start, end - start, start, PAGE_HYP_EXEC);
|
||||
}
|
||||
|
||||
int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr)
|
||||
{
|
||||
unsigned long addr, prev_base;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
hyp_spin_lock(&pkvm_pgd_lock);
|
||||
|
||||
prev_base = __io_map_base;
|
||||
/*
|
||||
* Efficient stack verification using the PAGE_SHIFT bit implies
|
||||
* an alignment of our allocation on the order of the size.
|
||||
*/
|
||||
size = PAGE_SIZE * 2;
|
||||
addr = ALIGN(__io_map_base, size);
|
||||
|
||||
ret = __pkvm_alloc_private_va_range(addr, size);
|
||||
if (!ret) {
|
||||
/*
|
||||
* Since the stack grows downwards, map the stack to the page
|
||||
* at the higher address and leave the lower guard page
|
||||
* unbacked.
|
||||
*
|
||||
* Any valid stack address now has the PAGE_SHIFT bit as 1
|
||||
* and addresses corresponding to the guard page have the
|
||||
* PAGE_SHIFT bit as 0 - this is used for overflow detection.
|
||||
*/
|
||||
ret = kvm_pgtable_hyp_map(&pkvm_pgtable, addr + PAGE_SIZE,
|
||||
PAGE_SIZE, phys, PAGE_HYP);
|
||||
if (ret)
|
||||
__io_map_base = prev_base;
|
||||
}
|
||||
hyp_spin_unlock(&pkvm_pgd_lock);
|
||||
|
||||
*haddr = addr + size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *admit_host_page(void *arg)
|
||||
{
|
||||
struct kvm_hyp_memcache *host_mc = arg;
|
||||
|
||||
@@ -113,7 +113,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
|
||||
|
||||
for (i = 0; i < hyp_nr_cpus; i++) {
|
||||
struct kvm_nvhe_init_params *params = per_cpu_ptr(&kvm_init_params, i);
|
||||
unsigned long hyp_addr;
|
||||
|
||||
start = (void *)kern_hyp_va(per_cpu_base[i]);
|
||||
end = start + PAGE_ALIGN(hyp_percpu_size);
|
||||
@@ -121,33 +120,9 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Allocate a contiguous HYP private VA range for the stack
|
||||
* and guard page. The allocation is also aligned based on
|
||||
* the order of its size.
|
||||
*/
|
||||
ret = pkvm_alloc_private_va_range(PAGE_SIZE * 2, &hyp_addr);
|
||||
ret = pkvm_create_stack(params->stack_pa, ¶ms->stack_hyp_va);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Since the stack grows downwards, map the stack to the page
|
||||
* at the higher address and leave the lower guard page
|
||||
* unbacked.
|
||||
*
|
||||
* Any valid stack address now has the PAGE_SHIFT bit as 1
|
||||
* and addresses corresponding to the guard page have the
|
||||
* PAGE_SHIFT bit as 0 - this is used for overflow detection.
|
||||
*/
|
||||
hyp_spin_lock(&pkvm_pgd_lock);
|
||||
ret = kvm_pgtable_hyp_map(&pkvm_pgtable, hyp_addr + PAGE_SIZE,
|
||||
PAGE_SIZE, params->stack_pa, PAGE_HYP);
|
||||
hyp_spin_unlock(&pkvm_pgd_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update stack_hyp_va to end of the stack's private VA range */
|
||||
params->stack_hyp_va = hyp_addr + (2 * PAGE_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -236,7 +236,7 @@ static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
|
||||
* KVM_ARM_VCPU_INIT, however, this is likely not possible for
|
||||
* protected VMs.
|
||||
*/
|
||||
vcpu->arch.target = -1;
|
||||
vcpu_clear_flag(vcpu, VCPU_INITIALIZED);
|
||||
*exit_code &= BIT(ARM_EXIT_WITH_SERROR_BIT);
|
||||
*exit_code |= ARM_EXCEPTION_IL;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,36 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
|
||||
__tlb_switch_to_host(&cxt);
|
||||
}
|
||||
|
||||
void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t start, unsigned long pages)
|
||||
{
|
||||
struct tlb_inv_context cxt;
|
||||
unsigned long stride;
|
||||
|
||||
/*
|
||||
* Since the range of addresses may not be mapped at
|
||||
* the same level, assume the worst case as PAGE_SIZE
|
||||
*/
|
||||
stride = PAGE_SIZE;
|
||||
start = round_down(start, stride);
|
||||
|
||||
/* Switch to requested VMID */
|
||||
__tlb_switch_to_guest(mmu, &cxt, false);
|
||||
|
||||
__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
|
||||
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
isb();
|
||||
|
||||
/* See the comment in __kvm_tlb_flush_vmid_ipa() */
|
||||
if (icache_is_vpipt())
|
||||
icache_inval_all_pou();
|
||||
|
||||
__tlb_switch_to_host(&cxt);
|
||||
}
|
||||
|
||||
void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
|
||||
{
|
||||
struct tlb_inv_context cxt;
|
||||
|
||||
@@ -670,6 +670,26 @@ static bool stage2_has_fwb(struct kvm_pgtable *pgt)
|
||||
return !(pgt->flags & KVM_PGTABLE_S2_NOFWB);
|
||||
}
|
||||
|
||||
void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t addr, size_t size)
|
||||
{
|
||||
unsigned long pages, inval_pages;
|
||||
|
||||
if (!system_supports_tlb_range()) {
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid, mmu);
|
||||
return;
|
||||
}
|
||||
|
||||
pages = size >> PAGE_SHIFT;
|
||||
while (pages > 0) {
|
||||
inval_pages = min(pages, MAX_TLBI_RANGE_PAGES);
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid_range, mmu, addr, inval_pages);
|
||||
|
||||
addr += inval_pages << PAGE_SHIFT;
|
||||
pages -= inval_pages;
|
||||
}
|
||||
}
|
||||
|
||||
#define KVM_S2_MEMATTR(pgt, attr) PAGE_S2_MEMATTR(attr, stage2_has_fwb(pgt))
|
||||
|
||||
static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
|
||||
@@ -786,7 +806,8 @@ static bool stage2_try_break_pte(const struct kvm_pgtable_visit_ctx *ctx,
|
||||
* evicted pte value (if any).
|
||||
*/
|
||||
if (kvm_pte_table(ctx->old, ctx->level))
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid, mmu);
|
||||
kvm_tlb_flush_vmid_range(mmu, ctx->addr,
|
||||
kvm_granule_size(ctx->level));
|
||||
else if (kvm_pte_valid(ctx->old))
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
|
||||
ctx->addr, ctx->level);
|
||||
@@ -810,16 +831,36 @@ static void stage2_make_pte(const struct kvm_pgtable_visit_ctx *ctx, kvm_pte_t n
|
||||
smp_store_release(ctx->ptep, new);
|
||||
}
|
||||
|
||||
static void stage2_put_pte(const struct kvm_pgtable_visit_ctx *ctx, struct kvm_s2_mmu *mmu,
|
||||
struct kvm_pgtable_mm_ops *mm_ops)
|
||||
static bool stage2_unmap_defer_tlb_flush(struct kvm_pgtable *pgt)
|
||||
{
|
||||
/*
|
||||
* Clear the existing PTE, and perform break-before-make with
|
||||
* TLB maintenance if it was valid.
|
||||
* If FEAT_TLBIRANGE is implemented, defer the individual
|
||||
* TLB invalidations until the entire walk is finished, and
|
||||
* then use the range-based TLBI instructions to do the
|
||||
* invalidations. Condition deferred TLB invalidation on the
|
||||
* system supporting FWB as the optimization is entirely
|
||||
* pointless when the unmap walker needs to perform CMOs.
|
||||
*/
|
||||
return system_supports_tlb_range() && stage2_has_fwb(pgt);
|
||||
}
|
||||
|
||||
static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx,
|
||||
struct kvm_s2_mmu *mmu,
|
||||
struct kvm_pgtable_mm_ops *mm_ops)
|
||||
{
|
||||
struct kvm_pgtable *pgt = ctx->arg;
|
||||
|
||||
/*
|
||||
* Clear the existing PTE, and perform break-before-make if it was
|
||||
* valid. Depending on the system support, defer the TLB maintenance
|
||||
* for the same until the entire unmap walk is completed.
|
||||
*/
|
||||
if (kvm_pte_valid(ctx->old)) {
|
||||
kvm_clear_pte(ctx->ptep);
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr, ctx->level);
|
||||
|
||||
if (!stage2_unmap_defer_tlb_flush(pgt))
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
|
||||
ctx->addr, ctx->level);
|
||||
}
|
||||
|
||||
mm_ops->put_page(ctx->ptep);
|
||||
@@ -1077,7 +1118,7 @@ static int stage2_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
|
||||
* block entry and rely on the remaining portions being faulted
|
||||
* back lazily.
|
||||
*/
|
||||
stage2_put_pte(ctx, mmu, mm_ops);
|
||||
stage2_unmap_put_pte(ctx, mmu, mm_ops);
|
||||
|
||||
if (need_flush && mm_ops->dcache_clean_inval_poc)
|
||||
mm_ops->dcache_clean_inval_poc(kvm_pte_follow(ctx->old, mm_ops),
|
||||
@@ -1091,13 +1132,19 @@ static int stage2_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
|
||||
|
||||
int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
|
||||
{
|
||||
int ret;
|
||||
struct kvm_pgtable_walker walker = {
|
||||
.cb = stage2_unmap_walker,
|
||||
.arg = pgt,
|
||||
.flags = KVM_PGTABLE_WALK_LEAF | KVM_PGTABLE_WALK_TABLE_POST,
|
||||
};
|
||||
|
||||
return kvm_pgtable_walk(pgt, addr, size, &walker);
|
||||
ret = kvm_pgtable_walk(pgt, addr, size, &walker);
|
||||
if (stage2_unmap_defer_tlb_flush(pgt))
|
||||
/* Perform the deferred TLB invalidations */
|
||||
kvm_tlb_flush_vmid_range(pgt->mmu, addr, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct stage2_attr_data {
|
||||
|
||||
@@ -143,6 +143,34 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
|
||||
__tlb_switch_to_host(&cxt);
|
||||
}
|
||||
|
||||
void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
||||
phys_addr_t start, unsigned long pages)
|
||||
{
|
||||
struct tlb_inv_context cxt;
|
||||
unsigned long stride;
|
||||
|
||||
/*
|
||||
* Since the range of addresses may not be mapped at
|
||||
* the same level, assume the worst case as PAGE_SIZE
|
||||
*/
|
||||
stride = PAGE_SIZE;
|
||||
start = round_down(start, stride);
|
||||
|
||||
dsb(ishst);
|
||||
|
||||
/* Switch to requested VMID */
|
||||
__tlb_switch_to_guest(mmu, &cxt);
|
||||
|
||||
__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
|
||||
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
isb();
|
||||
|
||||
__tlb_switch_to_host(&cxt);
|
||||
}
|
||||
|
||||
void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
|
||||
{
|
||||
struct tlb_inv_context cxt;
|
||||
|
||||
+81
-23
@@ -161,15 +161,23 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_flush_remote_tlbs() - flush all VM TLB entries for v7/8
|
||||
* kvm_arch_flush_remote_tlbs() - flush all VM TLB entries for v7/8
|
||||
* @kvm: pointer to kvm structure.
|
||||
*
|
||||
* Interface to HYP function to flush all VM TLB entries
|
||||
*/
|
||||
void kvm_flush_remote_tlbs(struct kvm *kvm)
|
||||
int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
|
||||
{
|
||||
++kvm->stat.generic.remote_tlb_flush_requests;
|
||||
kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
|
||||
gfn_t gfn, u64 nr_pages)
|
||||
{
|
||||
kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
|
||||
gfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool kvm_is_device_pfn(unsigned long pfn)
|
||||
@@ -592,6 +600,25 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __hyp_alloc_private_va_range(unsigned long base)
|
||||
{
|
||||
lockdep_assert_held(&kvm_hyp_pgd_mutex);
|
||||
|
||||
if (!PAGE_ALIGNED(base))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Verify that BIT(VA_BITS - 1) hasn't been flipped by
|
||||
* allocating the new area, as it would indicate we've
|
||||
* overflowed the idmap/IO address range.
|
||||
*/
|
||||
if ((base ^ io_map_base) & BIT(VA_BITS - 1))
|
||||
return -ENOMEM;
|
||||
|
||||
io_map_base = base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hyp_alloc_private_va_range - Allocates a private VA range.
|
||||
@@ -612,26 +639,16 @@ int hyp_alloc_private_va_range(size_t size, unsigned long *haddr)
|
||||
|
||||
/*
|
||||
* This assumes that we have enough space below the idmap
|
||||
* page to allocate our VAs. If not, the check below will
|
||||
* kick. A potential alternative would be to detect that
|
||||
* overflow and switch to an allocation above the idmap.
|
||||
* page to allocate our VAs. If not, the check in
|
||||
* __hyp_alloc_private_va_range() will kick. A potential
|
||||
* alternative would be to detect that overflow and switch
|
||||
* to an allocation above the idmap.
|
||||
*
|
||||
* The allocated size is always a multiple of PAGE_SIZE.
|
||||
*/
|
||||
base = io_map_base - PAGE_ALIGN(size);
|
||||
|
||||
/* Align the allocation based on the order of its size */
|
||||
base = ALIGN_DOWN(base, PAGE_SIZE << get_order(size));
|
||||
|
||||
/*
|
||||
* Verify that BIT(VA_BITS - 1) hasn't been flipped by
|
||||
* allocating the new area, as it would indicate we've
|
||||
* overflowed the idmap/IO address range.
|
||||
*/
|
||||
if ((base ^ io_map_base) & BIT(VA_BITS - 1))
|
||||
ret = -ENOMEM;
|
||||
else
|
||||
*haddr = io_map_base = base;
|
||||
size = PAGE_ALIGN(size);
|
||||
base = io_map_base - size;
|
||||
ret = __hyp_alloc_private_va_range(base);
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
|
||||
@@ -668,6 +685,48 @@ static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr)
|
||||
{
|
||||
unsigned long base;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&kvm_hyp_pgd_mutex);
|
||||
/*
|
||||
* Efficient stack verification using the PAGE_SHIFT bit implies
|
||||
* an alignment of our allocation on the order of the size.
|
||||
*/
|
||||
size = PAGE_SIZE * 2;
|
||||
base = ALIGN_DOWN(io_map_base - size, size);
|
||||
|
||||
ret = __hyp_alloc_private_va_range(base);
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
|
||||
if (ret) {
|
||||
kvm_err("Cannot allocate hyp stack guard page\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the stack grows downwards, map the stack to the page
|
||||
* at the higher address and leave the lower guard page
|
||||
* unbacked.
|
||||
*
|
||||
* Any valid stack address now has the PAGE_SHIFT bit as 1
|
||||
* and addresses corresponding to the guard page have the
|
||||
* PAGE_SHIFT bit as 0 - this is used for overflow detection.
|
||||
*/
|
||||
ret = __create_hyp_mappings(base + PAGE_SIZE, PAGE_SIZE, phys_addr,
|
||||
PAGE_HYP);
|
||||
if (ret)
|
||||
kvm_err("Cannot map hyp stack\n");
|
||||
|
||||
*haddr = base + size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_hyp_io_mappings - Map IO into both kernel and HYP
|
||||
* @phys_addr: The physical start address which gets mapped
|
||||
@@ -1075,7 +1134,7 @@ static void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
|
||||
write_lock(&kvm->mmu_lock);
|
||||
stage2_wp_range(&kvm->arch.mmu, start, end);
|
||||
write_unlock(&kvm->mmu_lock);
|
||||
kvm_flush_remote_tlbs(kvm);
|
||||
kvm_flush_remote_tlbs_memslot(kvm, memslot);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1541,7 +1600,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
||||
|
||||
out_unlock:
|
||||
read_unlock(&kvm->mmu_lock);
|
||||
kvm_set_pfn_accessed(pfn);
|
||||
kvm_release_pfn_clean(pfn);
|
||||
return ret != -EAGAIN ? ret : 0;
|
||||
}
|
||||
@@ -1721,7 +1779,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
|
||||
|
||||
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
|
||||
{
|
||||
kvm_pfn_t pfn = pte_pfn(range->pte);
|
||||
kvm_pfn_t pfn = pte_pfn(range->arg.pte);
|
||||
|
||||
if (!kvm->arch.mmu.pgt)
|
||||
return false;
|
||||
|
||||
@@ -71,8 +71,9 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
|
||||
break;
|
||||
|
||||
case SYS_ID_AA64MMFR0_EL1:
|
||||
/* Hide ECV, FGT, ExS, Secure Memory */
|
||||
val &= ~(GENMASK_ULL(63, 43) |
|
||||
/* Hide ECV, ExS, Secure Memory */
|
||||
val &= ~(NV_FTR(MMFR0, ECV) |
|
||||
NV_FTR(MMFR0, EXS) |
|
||||
NV_FTR(MMFR0, TGRAN4_2) |
|
||||
NV_FTR(MMFR0, TGRAN16_2) |
|
||||
NV_FTR(MMFR0, TGRAN64_2) |
|
||||
@@ -116,7 +117,8 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
|
||||
break;
|
||||
|
||||
case SYS_ID_AA64MMFR1_EL1:
|
||||
val &= (NV_FTR(MMFR1, PAN) |
|
||||
val &= (NV_FTR(MMFR1, HCX) |
|
||||
NV_FTR(MMFR1, PAN) |
|
||||
NV_FTR(MMFR1, LO) |
|
||||
NV_FTR(MMFR1, HPDS) |
|
||||
NV_FTR(MMFR1, VH) |
|
||||
@@ -124,8 +126,7 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
|
||||
break;
|
||||
|
||||
case SYS_ID_AA64MMFR2_EL1:
|
||||
val &= ~(NV_FTR(MMFR2, EVT) |
|
||||
NV_FTR(MMFR2, BBM) |
|
||||
val &= ~(NV_FTR(MMFR2, BBM) |
|
||||
NV_FTR(MMFR2, TTL) |
|
||||
GENMASK_ULL(47, 44) |
|
||||
NV_FTR(MMFR2, ST) |
|
||||
|
||||
+26
-11
@@ -14,6 +14,7 @@
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <kvm/arm_pmu.h>
|
||||
#include <kvm/arm_vgic.h>
|
||||
#include <asm/arm_pmuv3.h>
|
||||
|
||||
#define PERF_ATTR_CFG1_COUNTER_64BIT BIT(0)
|
||||
|
||||
@@ -35,12 +36,8 @@ static struct kvm_pmc *kvm_vcpu_idx_to_pmc(struct kvm_vcpu *vcpu, int cnt_idx)
|
||||
return &vcpu->arch.pmu.pmc[cnt_idx];
|
||||
}
|
||||
|
||||
static u32 kvm_pmu_event_mask(struct kvm *kvm)
|
||||
static u32 __kvm_pmu_event_mask(unsigned int pmuver)
|
||||
{
|
||||
unsigned int pmuver;
|
||||
|
||||
pmuver = kvm->arch.arm_pmu->pmuver;
|
||||
|
||||
switch (pmuver) {
|
||||
case ID_AA64DFR0_EL1_PMUVer_IMP:
|
||||
return GENMASK(9, 0);
|
||||
@@ -55,6 +52,14 @@ static u32 kvm_pmu_event_mask(struct kvm *kvm)
|
||||
}
|
||||
}
|
||||
|
||||
static u32 kvm_pmu_event_mask(struct kvm *kvm)
|
||||
{
|
||||
u64 dfr0 = IDREG(kvm, SYS_ID_AA64DFR0_EL1);
|
||||
u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, dfr0);
|
||||
|
||||
return __kvm_pmu_event_mask(pmuver);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_pmc_is_64bit - determine if counter is 64bit
|
||||
* @pmc: counter context
|
||||
@@ -672,8 +677,11 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
|
||||
{
|
||||
struct arm_pmu_entry *entry;
|
||||
|
||||
if (pmu->pmuver == ID_AA64DFR0_EL1_PMUVer_NI ||
|
||||
pmu->pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
|
||||
/*
|
||||
* Check the sanitised PMU version for the system, as KVM does not
|
||||
* support implementations where PMUv3 exists on a subset of CPUs.
|
||||
*/
|
||||
if (!pmuv3_implemented(kvm_arm_pmu_get_pmuver_limit()))
|
||||
return;
|
||||
|
||||
mutex_lock(&arm_pmus_lock);
|
||||
@@ -750,11 +758,12 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
|
||||
} else {
|
||||
val = read_sysreg(pmceid1_el0);
|
||||
/*
|
||||
* Don't advertise STALL_SLOT, as PMMIR_EL0 is handled
|
||||
* Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
|
||||
* as RAZ
|
||||
*/
|
||||
if (vcpu->kvm->arch.arm_pmu->pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P4)
|
||||
val &= ~BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32);
|
||||
val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
|
||||
BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
|
||||
BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
|
||||
base = 32;
|
||||
}
|
||||
|
||||
@@ -950,11 +959,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
|
||||
return 0;
|
||||
}
|
||||
case KVM_ARM_VCPU_PMU_V3_FILTER: {
|
||||
u8 pmuver = kvm_arm_pmu_get_pmuver_limit();
|
||||
struct kvm_pmu_event_filter __user *uaddr;
|
||||
struct kvm_pmu_event_filter filter;
|
||||
int nr_events;
|
||||
|
||||
nr_events = kvm_pmu_event_mask(kvm) + 1;
|
||||
/*
|
||||
* Allow userspace to specify an event filter for the entire
|
||||
* event range supported by PMUVer of the hardware, rather
|
||||
* than the guest's PMUVer for KVM backward compatibility.
|
||||
*/
|
||||
nr_events = __kvm_pmu_event_mask(pmuver) + 1;
|
||||
|
||||
uaddr = (struct kvm_pmu_event_filter __user *)(long)attr->addr;
|
||||
|
||||
|
||||
@@ -236,3 +236,21 @@ bool kvm_set_pmuserenr(u64 val)
|
||||
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we interrupted the guest to update the host PMU context, make
|
||||
* sure we re-apply the guest EL0 state.
|
||||
*/
|
||||
void kvm_vcpu_pmu_resync_el0(void)
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
|
||||
if (!has_vhe() || !in_interrupt())
|
||||
return;
|
||||
|
||||
vcpu = kvm_get_running_vcpu();
|
||||
if (!vcpu)
|
||||
return;
|
||||
|
||||
kvm_make_request(KVM_REQ_RESYNC_PMU_EL0, vcpu);
|
||||
}
|
||||
|
||||
+9
-14
@@ -248,21 +248,16 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
switch (vcpu->arch.target) {
|
||||
default:
|
||||
if (vcpu_el1_is_32bit(vcpu)) {
|
||||
pstate = VCPU_RESET_PSTATE_SVC;
|
||||
} else if (vcpu_has_nv(vcpu)) {
|
||||
pstate = VCPU_RESET_PSTATE_EL2;
|
||||
} else {
|
||||
pstate = VCPU_RESET_PSTATE_EL1;
|
||||
}
|
||||
if (vcpu_el1_is_32bit(vcpu))
|
||||
pstate = VCPU_RESET_PSTATE_SVC;
|
||||
else if (vcpu_has_nv(vcpu))
|
||||
pstate = VCPU_RESET_PSTATE_EL2;
|
||||
else
|
||||
pstate = VCPU_RESET_PSTATE_EL1;
|
||||
|
||||
if (kvm_vcpu_has_pmu(vcpu) && !kvm_arm_support_pmu_v3()) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
if (kvm_vcpu_has_pmu(vcpu) && !kvm_arm_support_pmu_v3()) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reset core registers */
|
||||
|
||||
@@ -2151,6 +2151,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
{ SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 },
|
||||
{ SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 },
|
||||
|
||||
{ SYS_DESC(SYS_ACCDATA_EL1), undef_access },
|
||||
|
||||
{ SYS_DESC(SYS_SCXTNUM_EL1), undef_access },
|
||||
|
||||
{ SYS_DESC(SYS_CNTKCTL_EL1), NULL, reset_val, CNTKCTL_EL1, 0},
|
||||
@@ -2365,8 +2367,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
|
||||
EL2_REG(HSTR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(HFGRTR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(HFGWTR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(HFGITR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(HACR_EL2, access_rw, reset_val, 0),
|
||||
|
||||
EL2_REG(HCRX_EL2, access_rw, reset_val, 0),
|
||||
|
||||
EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
|
||||
@@ -2374,6 +2381,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
EL2_REG(VTCR_EL2, access_rw, reset_val, 0),
|
||||
|
||||
{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
|
||||
EL2_REG(HDFGRTR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(HDFGWTR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(SPSR_EL2, access_rw, reset_val, 0),
|
||||
EL2_REG(ELR_EL2, access_rw, reset_val, 0),
|
||||
{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
|
||||
@@ -3170,6 +3179,9 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
|
||||
|
||||
trace_kvm_handle_sys_reg(esr);
|
||||
|
||||
if (__check_nv_sr_forward(vcpu))
|
||||
return 1;
|
||||
|
||||
params = esr_sys64_to_params(esr);
|
||||
params.regval = vcpu_get_reg(vcpu, Rt);
|
||||
|
||||
@@ -3587,5 +3599,8 @@ int __init kvm_sys_reg_table_init(void)
|
||||
if (!first_idreg)
|
||||
return -EINVAL;
|
||||
|
||||
if (kvm_get_mode() == KVM_MODE_NV)
|
||||
return populate_nv_trap_config();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -364,6 +364,32 @@ TRACE_EVENT(kvm_inject_nested_exception,
|
||||
__entry->hcr_el2)
|
||||
);
|
||||
|
||||
TRACE_EVENT(kvm_forward_sysreg_trap,
|
||||
TP_PROTO(struct kvm_vcpu *vcpu, u32 sysreg, bool is_read),
|
||||
TP_ARGS(vcpu, sysreg, is_read),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u64, pc)
|
||||
__field(u32, sysreg)
|
||||
__field(bool, is_read)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->pc = *vcpu_pc(vcpu);
|
||||
__entry->sysreg = sysreg;
|
||||
__entry->is_read = is_read;
|
||||
),
|
||||
|
||||
TP_printk("%llx %c (%d,%d,%d,%d,%d)",
|
||||
__entry->pc,
|
||||
__entry->is_read ? 'R' : 'W',
|
||||
sys_reg_Op0(__entry->sysreg),
|
||||
sys_reg_Op1(__entry->sysreg),
|
||||
sys_reg_CRn(__entry->sysreg),
|
||||
sys_reg_CRm(__entry->sysreg),
|
||||
sys_reg_Op2(__entry->sysreg))
|
||||
);
|
||||
|
||||
#endif /* _TRACE_ARM_ARM64_KVM_H */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
||||
@@ -199,7 +199,6 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu);
|
||||
void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
|
||||
void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr);
|
||||
void vgic_v2_set_underflow(struct kvm_vcpu *vcpu);
|
||||
void vgic_v2_set_npie(struct kvm_vcpu *vcpu);
|
||||
int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr);
|
||||
int vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
|
||||
int offset, u32 *val);
|
||||
@@ -233,7 +232,6 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
|
||||
void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
|
||||
void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr);
|
||||
void vgic_v3_set_underflow(struct kvm_vcpu *vcpu);
|
||||
void vgic_v3_set_npie(struct kvm_vcpu *vcpu);
|
||||
void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
|
||||
void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
|
||||
void vgic_v3_enable(struct kvm_vcpu *vcpu);
|
||||
|
||||
@@ -24,7 +24,7 @@ unsigned int __no_sanitize_address do_csum(const unsigned char *buff, int len)
|
||||
const u64 *ptr;
|
||||
u64 data, sum64 = 0;
|
||||
|
||||
if (unlikely(len == 0))
|
||||
if (unlikely(len <= 0))
|
||||
return 0;
|
||||
|
||||
offset = (unsigned long)buff & 7;
|
||||
|
||||
@@ -26,6 +26,7 @@ HAS_ECV
|
||||
HAS_ECV_CNTPOFF
|
||||
HAS_EPAN
|
||||
HAS_EVT
|
||||
HAS_FGT
|
||||
HAS_GENERIC_AUTH
|
||||
HAS_GENERIC_AUTH_ARCH_QARMA3
|
||||
HAS_GENERIC_AUTH_ARCH_QARMA5
|
||||
|
||||
@@ -2156,6 +2156,135 @@ Field 1 ICIALLU
|
||||
Field 0 ICIALLUIS
|
||||
EndSysreg
|
||||
|
||||
Sysreg HDFGRTR_EL2 3 4 3 1 4
|
||||
Field 63 PMBIDR_EL1
|
||||
Field 62 nPMSNEVFR_EL1
|
||||
Field 61 nBRBDATA
|
||||
Field 60 nBRBCTL
|
||||
Field 59 nBRBIDR
|
||||
Field 58 PMCEIDn_EL0
|
||||
Field 57 PMUSERENR_EL0
|
||||
Field 56 TRBTRG_EL1
|
||||
Field 55 TRBSR_EL1
|
||||
Field 54 TRBPTR_EL1
|
||||
Field 53 TRBMAR_EL1
|
||||
Field 52 TRBLIMITR_EL1
|
||||
Field 51 TRBIDR_EL1
|
||||
Field 50 TRBBASER_EL1
|
||||
Res0 49
|
||||
Field 48 TRCVICTLR
|
||||
Field 47 TRCSTATR
|
||||
Field 46 TRCSSCSRn
|
||||
Field 45 TRCSEQSTR
|
||||
Field 44 TRCPRGCTLR
|
||||
Field 43 TRCOSLSR
|
||||
Res0 42
|
||||
Field 41 TRCIMSPECn
|
||||
Field 40 TRCID
|
||||
Res0 39:38
|
||||
Field 37 TRCCNTVRn
|
||||
Field 36 TRCCLAIM
|
||||
Field 35 TRCAUXCTLR
|
||||
Field 34 TRCAUTHSTATUS
|
||||
Field 33 TRC
|
||||
Field 32 PMSLATFR_EL1
|
||||
Field 31 PMSIRR_EL1
|
||||
Field 30 PMSIDR_EL1
|
||||
Field 29 PMSICR_EL1
|
||||
Field 28 PMSFCR_EL1
|
||||
Field 27 PMSEVFR_EL1
|
||||
Field 26 PMSCR_EL1
|
||||
Field 25 PMBSR_EL1
|
||||
Field 24 PMBPTR_EL1
|
||||
Field 23 PMBLIMITR_EL1
|
||||
Field 22 PMMIR_EL1
|
||||
Res0 21:20
|
||||
Field 19 PMSELR_EL0
|
||||
Field 18 PMOVS
|
||||
Field 17 PMINTEN
|
||||
Field 16 PMCNTEN
|
||||
Field 15 PMCCNTR_EL0
|
||||
Field 14 PMCCFILTR_EL0
|
||||
Field 13 PMEVTYPERn_EL0
|
||||
Field 12 PMEVCNTRn_EL0
|
||||
Field 11 OSDLR_EL1
|
||||
Field 10 OSECCR_EL1
|
||||
Field 9 OSLSR_EL1
|
||||
Res0 8
|
||||
Field 7 DBGPRCR_EL1
|
||||
Field 6 DBGAUTHSTATUS_EL1
|
||||
Field 5 DBGCLAIM
|
||||
Field 4 MDSCR_EL1
|
||||
Field 3 DBGWVRn_EL1
|
||||
Field 2 DBGWCRn_EL1
|
||||
Field 1 DBGBVRn_EL1
|
||||
Field 0 DBGBCRn_EL1
|
||||
EndSysreg
|
||||
|
||||
Sysreg HDFGWTR_EL2 3 4 3 1 5
|
||||
Res0 63
|
||||
Field 62 nPMSNEVFR_EL1
|
||||
Field 61 nBRBDATA
|
||||
Field 60 nBRBCTL
|
||||
Res0 59:58
|
||||
Field 57 PMUSERENR_EL0
|
||||
Field 56 TRBTRG_EL1
|
||||
Field 55 TRBSR_EL1
|
||||
Field 54 TRBPTR_EL1
|
||||
Field 53 TRBMAR_EL1
|
||||
Field 52 TRBLIMITR_EL1
|
||||
Res0 51
|
||||
Field 50 TRBBASER_EL1
|
||||
Field 49 TRFCR_EL1
|
||||
Field 48 TRCVICTLR
|
||||
Res0 47
|
||||
Field 46 TRCSSCSRn
|
||||
Field 45 TRCSEQSTR
|
||||
Field 44 TRCPRGCTLR
|
||||
Res0 43
|
||||
Field 42 TRCOSLAR
|
||||
Field 41 TRCIMSPECn
|
||||
Res0 40:38
|
||||
Field 37 TRCCNTVRn
|
||||
Field 36 TRCCLAIM
|
||||
Field 35 TRCAUXCTLR
|
||||
Res0 34
|
||||
Field 33 TRC
|
||||
Field 32 PMSLATFR_EL1
|
||||
Field 31 PMSIRR_EL1
|
||||
Res0 30
|
||||
Field 29 PMSICR_EL1
|
||||
Field 28 PMSFCR_EL1
|
||||
Field 27 PMSEVFR_EL1
|
||||
Field 26 PMSCR_EL1
|
||||
Field 25 PMBSR_EL1
|
||||
Field 24 PMBPTR_EL1
|
||||
Field 23 PMBLIMITR_EL1
|
||||
Res0 22
|
||||
Field 21 PMCR_EL0
|
||||
Field 20 PMSWINC_EL0
|
||||
Field 19 PMSELR_EL0
|
||||
Field 18 PMOVS
|
||||
Field 17 PMINTEN
|
||||
Field 16 PMCNTEN
|
||||
Field 15 PMCCNTR_EL0
|
||||
Field 14 PMCCFILTR_EL0
|
||||
Field 13 PMEVTYPERn_EL0
|
||||
Field 12 PMEVCNTRn_EL0
|
||||
Field 11 OSDLR_EL1
|
||||
Field 10 OSECCR_EL1
|
||||
Res0 9
|
||||
Field 8 OSLAR_EL1
|
||||
Field 7 DBGPRCR_EL1
|
||||
Res0 6
|
||||
Field 5 DBGCLAIM
|
||||
Field 4 MDSCR_EL1
|
||||
Field 3 DBGWVRn_EL1
|
||||
Field 2 DBGWCRn_EL1
|
||||
Field 1 DBGBVRn_EL1
|
||||
Field 0 DBGBCRn_EL1
|
||||
EndSysreg
|
||||
|
||||
Sysreg ZCR_EL2 3 4 1 2 0
|
||||
Fields ZCR_ELx
|
||||
EndSysreg
|
||||
|
||||
@@ -8,11 +8,13 @@ config LOONGARCH
|
||||
select ACPI_PPTT if ACPI
|
||||
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
|
||||
select ARCH_BINFMT_ELF_STATE
|
||||
select ARCH_DISABLE_KASAN_INLINE
|
||||
select ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
select ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
|
||||
select ARCH_HAS_CPU_FINALIZE_INIT
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
|
||||
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
@@ -91,6 +93,9 @@ config LOONGARCH
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_ARCH_JUMP_LABEL_RELATIVE
|
||||
select HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KFENCE
|
||||
select HAVE_ARCH_KGDB if PERF_EVENTS
|
||||
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
@@ -115,6 +120,7 @@ config LOONGARCH
|
||||
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_GENERIC_VDSO
|
||||
select HAVE_HW_BREAKPOINT if PERF_EVENTS
|
||||
select HAVE_IOREMAP_PROT
|
||||
@@ -254,6 +260,9 @@ config AS_HAS_LSX_EXTENSION
|
||||
config AS_HAS_LASX_EXTENSION
|
||||
def_bool $(as-instr,xvld \$xr0$(comma)\$a0$(comma)0)
|
||||
|
||||
config AS_HAS_LBT_EXTENSION
|
||||
def_bool $(as-instr,movscr2gr \$a0$(comma)\$scr0)
|
||||
|
||||
menu "Kernel type and options"
|
||||
|
||||
source "kernel/Kconfig.hz"
|
||||
@@ -534,6 +543,18 @@ config CPU_HAS_LASX
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config CPU_HAS_LBT
|
||||
bool "Support for the Loongson Binary Translation Extension"
|
||||
depends on AS_HAS_LBT_EXTENSION
|
||||
help
|
||||
Loongson Binary Translation (LBT) introduces 4 scratch registers (SCR0
|
||||
to SCR3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop).
|
||||
Enabling this option allows the kernel to allocate and switch registers
|
||||
specific to LBT.
|
||||
|
||||
If you want to use this feature, such as the Loongson Architecture
|
||||
Translator (LAT), say Y.
|
||||
|
||||
config CPU_HAS_PREFETCH
|
||||
bool
|
||||
default y
|
||||
@@ -638,6 +659,11 @@ config ARCH_MMAP_RND_BITS_MAX
|
||||
config ARCH_SUPPORTS_UPROBES
|
||||
def_bool y
|
||||
|
||||
config KASAN_SHADOW_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
depends on KASAN
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
config ARCH_SUSPEND_POSSIBLE
|
||||
|
||||
@@ -84,7 +84,10 @@ LDFLAGS_vmlinux += -static -pie --no-dynamic-linker -z notext
|
||||
endif
|
||||
|
||||
cflags-y += $(call cc-option, -mno-check-zero-division)
|
||||
|
||||
ifndef CONFIG_KASAN
|
||||
cflags-y += -fno-builtin-memcpy -fno-builtin-memmove -fno-builtin-memset
|
||||
endif
|
||||
|
||||
load-y = 0x9000000000200000
|
||||
bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y)
|
||||
|
||||
@@ -30,7 +30,6 @@ CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EXPERT=y
|
||||
@@ -47,8 +46,12 @@ CONFIG_SMP=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_CPU_HAS_FPU=y
|
||||
CONFIG_CPU_HAS_LSX=y
|
||||
CONFIG_CPU_HAS_LASX=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_RANDOMIZE_BASE=y
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_ACPI=y
|
||||
@@ -63,6 +66,7 @@ CONFIG_EFI_ZBOOT=y
|
||||
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
|
||||
CONFIG_EFI_CAPSULE_LOADER=m
|
||||
CONFIG_EFI_TEST=m
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
@@ -108,7 +112,12 @@ CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE_DEMUX=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_IPGRE_BROADCAST=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_UDP_DIAG=y
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
@@ -137,7 +146,6 @@ CONFIG_NFT_MASQ=m
|
||||
CONFIG_NFT_REDIR=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_TUNNEL=m
|
||||
CONFIG_NFT_OBJREF=m
|
||||
CONFIG_NFT_QUEUE=m
|
||||
CONFIG_NFT_QUOTA=m
|
||||
CONFIG_NFT_REJECT=m
|
||||
@@ -208,7 +216,11 @@ CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_IPV6=y
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_PROTO_ESP=y
|
||||
CONFIG_IP_VS_PROTO_AH=y
|
||||
CONFIG_IP_VS_PROTO_SCTP=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_WRR=m
|
||||
CONFIG_IP_VS_NFCT=y
|
||||
CONFIG_NF_TABLES_IPV4=y
|
||||
CONFIG_NFT_DUP_IPV4=m
|
||||
@@ -227,7 +239,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_TARGET_NETMAP=m
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
@@ -363,6 +374,8 @@ CONFIG_MTD_CFI_AMDSTD=m
|
||||
CONFIG_MTD_CFI_STAA=m
|
||||
CONFIG_MTD_RAM=m
|
||||
CONFIG_MTD_ROM=m
|
||||
CONFIG_MTD_UBI=m
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
CONFIG_PARPORT=y
|
||||
CONFIG_PARPORT_PC=y
|
||||
CONFIG_PARPORT_SERIAL=y
|
||||
@@ -370,6 +383,7 @@ CONFIG_PARPORT_PC_FIFO=y
|
||||
CONFIG_ZRAM=m
|
||||
CONFIG_ZRAM_DEF_COMP_ZSTD=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_DRBD=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
@@ -516,6 +530,8 @@ CONFIG_STMMAC_ETH=y
|
||||
# CONFIG_NET_VENDOR_TEHUTI is not set
|
||||
# CONFIG_NET_VENDOR_TI is not set
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
CONFIG_NGBE=y
|
||||
CONFIG_TXGBE=y
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
# CONFIG_NET_VENDOR_XILINX is not set
|
||||
CONFIG_PPP=m
|
||||
@@ -602,9 +618,15 @@ CONFIG_HW_RANDOM_VIRTIO=m
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_PIIX4=y
|
||||
CONFIG_I2C_GPIO=y
|
||||
CONFIG_I2C_LS2X=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_LOONGSON_PCI=m
|
||||
CONFIG_SPI_LOONGSON_PLATFORM=m
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_LOONGSON2=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_LOONGSON=y
|
||||
CONFIG_GPIO_LOONGSON_64BIT=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_RESTART=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
@@ -614,6 +636,7 @@ CONFIG_SENSORS_LM75=m
|
||||
CONFIG_SENSORS_LM93=m
|
||||
CONFIG_SENSORS_W83795=m
|
||||
CONFIG_SENSORS_W83627HF=m
|
||||
CONFIG_LOONGSON2_THERMAL=m
|
||||
CONFIG_RC_CORE=m
|
||||
CONFIG_LIRC=y
|
||||
CONFIG_RC_DECODERS=y
|
||||
@@ -643,6 +666,7 @@ CONFIG_DRM_AMDGPU_USERPTR=y
|
||||
CONFIG_DRM_AST=y
|
||||
CONFIG_DRM_QXL=m
|
||||
CONFIG_DRM_VIRTIO_GPU=m
|
||||
CONFIG_DRM_LOONGSON=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_FB_RADEON=y
|
||||
@@ -712,6 +736,7 @@ CONFIG_UCSI_ACPI=m
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_EFI=y
|
||||
CONFIG_RTC_DRV_LOONGSON=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_UIO=m
|
||||
CONFIG_UIO_PDRV_GENIRQ=m
|
||||
@@ -745,7 +770,9 @@ CONFIG_COMEDI_NI_LABPC_PCI=m
|
||||
CONFIG_COMEDI_NI_PCIDIO=m
|
||||
CONFIG_COMEDI_NI_PCIMIO=m
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_R8188EU=m
|
||||
CONFIG_COMMON_CLK_LOONGSON2=y
|
||||
CONFIG_LOONGSON2_GUTS=y
|
||||
CONFIG_LOONGSON2_PM=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
|
||||
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
|
||||
@@ -759,10 +786,17 @@ CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
CONFIG_JFS_SECURITY=y
|
||||
CONFIG_XFS_FS=y
|
||||
CONFIG_XFS_QUOTA=y
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_GFS2_FS=m
|
||||
CONFIG_GFS2_FS_LOCKING_DLM=y
|
||||
CONFIG_OCFS2_FS=m
|
||||
CONFIG_BTRFS_FS=y
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA=y
|
||||
@@ -771,11 +805,14 @@ CONFIG_QFMT_V1=m
|
||||
CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_VIRTIO_FS=m
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_OVERLAY_FS_INDEX=y
|
||||
CONFIG_OVERLAY_FS_XINO_AUTO=y
|
||||
CONFIG_OVERLAY_FS_METACOPY=y
|
||||
CONFIG_FSCACHE=y
|
||||
CONFIG_CACHEFILES=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
@@ -784,19 +821,42 @@ CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
CONFIG_FAT_DEFAULT_CODEPAGE=936
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="gb2312"
|
||||
CONFIG_EXFAT_FS=m
|
||||
CONFIG_NTFS3_FS=m
|
||||
CONFIG_NTFS3_64BIT_CLUSTER=y
|
||||
CONFIG_NTFS3_LZX_XPRESS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_ORANGEFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_ECRYPT_FS_MESSAGING=y
|
||||
CONFIG_HFS_FS=m
|
||||
CONFIG_HFSPLUS_FS=m
|
||||
CONFIG_UBIFS_FS=m
|
||||
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=y
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZ4=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_MINIX_FS=m
|
||||
CONFIG_ROMFS_FS=m
|
||||
CONFIG_PSTORE=m
|
||||
CONFIG_PSTORE_LZO_COMPRESS=m
|
||||
CONFIG_PSTORE_LZ4_COMPRESS=m
|
||||
CONFIG_PSTORE_LZ4HC_COMPRESS=m
|
||||
CONFIG_PSTORE_842_COMPRESS=y
|
||||
CONFIG_PSTORE_ZSTD_COMPRESS=y
|
||||
CONFIG_PSTORE_ZSTD_COMPRESS_DEFAULT=y
|
||||
CONFIG_SYSV_FS=m
|
||||
CONFIG_UFS_FS=m
|
||||
CONFIG_EROFS_FS=m
|
||||
CONFIG_EROFS_FS_ZIP_LZMA=y
|
||||
CONFIG_EROFS_FS_PCPU_KTHREAD=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=y
|
||||
@@ -807,6 +867,10 @@ CONFIG_NFSD=y
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_BLOCKLAYOUT=y
|
||||
CONFIG_CEPH_FS=m
|
||||
CONFIG_CEPH_FSCACHE=y
|
||||
CONFIG_CEPH_FS_POSIX_ACL=y
|
||||
CONFIG_CEPH_FS_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_9P_FS=y
|
||||
@@ -814,6 +878,7 @@ CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_936=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_DLM=m
|
||||
CONFIG_KEY_DH_OPERATIONS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
@@ -847,6 +912,7 @@ CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
CONFIG_CRYPTO_USER_API_RNG=m
|
||||
CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
CONFIG_CRYPTO_CRC32_LOONGARCH=m
|
||||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/lbt.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
@@ -10,113 +10,6 @@
|
||||
#include <asm/fpregdef.h>
|
||||
#include <asm/loongarch.h>
|
||||
|
||||
.macro parse_v var val
|
||||
\var = \val
|
||||
.endm
|
||||
|
||||
.macro parse_r var r
|
||||
\var = -1
|
||||
.ifc \r, $r0
|
||||
\var = 0
|
||||
.endif
|
||||
.ifc \r, $r1
|
||||
\var = 1
|
||||
.endif
|
||||
.ifc \r, $r2
|
||||
\var = 2
|
||||
.endif
|
||||
.ifc \r, $r3
|
||||
\var = 3
|
||||
.endif
|
||||
.ifc \r, $r4
|
||||
\var = 4
|
||||
.endif
|
||||
.ifc \r, $r5
|
||||
\var = 5
|
||||
.endif
|
||||
.ifc \r, $r6
|
||||
\var = 6
|
||||
.endif
|
||||
.ifc \r, $r7
|
||||
\var = 7
|
||||
.endif
|
||||
.ifc \r, $r8
|
||||
\var = 8
|
||||
.endif
|
||||
.ifc \r, $r9
|
||||
\var = 9
|
||||
.endif
|
||||
.ifc \r, $r10
|
||||
\var = 10
|
||||
.endif
|
||||
.ifc \r, $r11
|
||||
\var = 11
|
||||
.endif
|
||||
.ifc \r, $r12
|
||||
\var = 12
|
||||
.endif
|
||||
.ifc \r, $r13
|
||||
\var = 13
|
||||
.endif
|
||||
.ifc \r, $r14
|
||||
\var = 14
|
||||
.endif
|
||||
.ifc \r, $r15
|
||||
\var = 15
|
||||
.endif
|
||||
.ifc \r, $r16
|
||||
\var = 16
|
||||
.endif
|
||||
.ifc \r, $r17
|
||||
\var = 17
|
||||
.endif
|
||||
.ifc \r, $r18
|
||||
\var = 18
|
||||
.endif
|
||||
.ifc \r, $r19
|
||||
\var = 19
|
||||
.endif
|
||||
.ifc \r, $r20
|
||||
\var = 20
|
||||
.endif
|
||||
.ifc \r, $r21
|
||||
\var = 21
|
||||
.endif
|
||||
.ifc \r, $r22
|
||||
\var = 22
|
||||
.endif
|
||||
.ifc \r, $r23
|
||||
\var = 23
|
||||
.endif
|
||||
.ifc \r, $r24
|
||||
\var = 24
|
||||
.endif
|
||||
.ifc \r, $r25
|
||||
\var = 25
|
||||
.endif
|
||||
.ifc \r, $r26
|
||||
\var = 26
|
||||
.endif
|
||||
.ifc \r, $r27
|
||||
\var = 27
|
||||
.endif
|
||||
.ifc \r, $r28
|
||||
\var = 28
|
||||
.endif
|
||||
.ifc \r, $r29
|
||||
\var = 29
|
||||
.endif
|
||||
.ifc \r, $r30
|
||||
\var = 30
|
||||
.endif
|
||||
.ifc \r, $r31
|
||||
\var = 31
|
||||
.endif
|
||||
.iflt \var
|
||||
.error "Unable to parse register name \r"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro cpu_save_nonscratch thread
|
||||
stptr.d s0, \thread, THREAD_REG23
|
||||
stptr.d s1, \thread, THREAD_REG24
|
||||
@@ -148,12 +41,51 @@
|
||||
|
||||
.macro fpu_save_csr thread tmp
|
||||
movfcsr2gr \tmp, fcsr0
|
||||
stptr.w \tmp, \thread, THREAD_FCSR
|
||||
stptr.w \tmp, \thread, THREAD_FCSR
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
/* TM bit is always 0 if LBT not supported */
|
||||
andi \tmp, \tmp, FPU_CSR_TM
|
||||
beqz \tmp, 1f
|
||||
/* Save FTOP */
|
||||
x86mftop \tmp
|
||||
stptr.w \tmp, \thread, THREAD_FTOP
|
||||
/* Turn off TM to ensure the order of FPR in memory independent of TM */
|
||||
x86clrtm
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro fpu_restore_csr thread tmp
|
||||
ldptr.w \tmp, \thread, THREAD_FCSR
|
||||
movgr2fcsr fcsr0, \tmp
|
||||
.macro fpu_restore_csr thread tmp0 tmp1
|
||||
ldptr.w \tmp0, \thread, THREAD_FCSR
|
||||
movgr2fcsr fcsr0, \tmp0
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
/* TM bit is always 0 if LBT not supported */
|
||||
andi \tmp0, \tmp0, FPU_CSR_TM
|
||||
beqz \tmp0, 2f
|
||||
/* Restore FTOP */
|
||||
ldptr.w \tmp0, \thread, THREAD_FTOP
|
||||
andi \tmp0, \tmp0, 0x7
|
||||
la.pcrel \tmp1, 1f
|
||||
alsl.d \tmp1, \tmp0, \tmp1, 3
|
||||
jr \tmp1
|
||||
1:
|
||||
x86mttop 0
|
||||
b 2f
|
||||
x86mttop 1
|
||||
b 2f
|
||||
x86mttop 2
|
||||
b 2f
|
||||
x86mttop 3
|
||||
b 2f
|
||||
x86mttop 4
|
||||
b 2f
|
||||
x86mttop 5
|
||||
b 2f
|
||||
x86mttop 6
|
||||
b 2f
|
||||
x86mttop 7
|
||||
2:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro fpu_save_cc thread tmp0 tmp1
|
||||
@@ -353,7 +285,7 @@
|
||||
.macro lsx_restore_all thread tmp0 tmp1
|
||||
lsx_restore_data \thread, \tmp0
|
||||
fpu_restore_cc \thread, \tmp0, \tmp1
|
||||
fpu_restore_csr \thread, \tmp0
|
||||
fpu_restore_csr \thread, \tmp0, \tmp1
|
||||
.endm
|
||||
|
||||
.macro lsx_save_upper vd base tmp off
|
||||
@@ -563,7 +495,7 @@
|
||||
.macro lasx_restore_all thread tmp0 tmp1
|
||||
lasx_restore_data \thread, \tmp0
|
||||
fpu_restore_cc \thread, \tmp0, \tmp1
|
||||
fpu_restore_csr \thread, \tmp0
|
||||
fpu_restore_csr \thread, \tmp0, \tmp1
|
||||
.endm
|
||||
|
||||
.macro lasx_save_upper xd base tmp off
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_KASAN_H
|
||||
#define __ASM_KASAN_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define __HAVE_ARCH_SHADOW_MAP
|
||||
|
||||
#define KASAN_SHADOW_SCALE_SHIFT 3
|
||||
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
|
||||
|
||||
#define XRANGE_SHIFT (48)
|
||||
|
||||
/* Valid address length */
|
||||
#define XRANGE_SHADOW_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3)
|
||||
/* Used for taking out the valid address */
|
||||
#define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0)
|
||||
/* One segment whole address space size */
|
||||
#define XRANGE_SIZE (XRANGE_SHADOW_MASK + 1)
|
||||
|
||||
/* 64-bit segment value. */
|
||||
#define XKPRANGE_UC_SEG (0x8000)
|
||||
#define XKPRANGE_CC_SEG (0x9000)
|
||||
#define XKVRANGE_VC_SEG (0xffff)
|
||||
|
||||
/* Cached */
|
||||
#define XKPRANGE_CC_START CACHE_BASE
|
||||
#define XKPRANGE_CC_SIZE XRANGE_SIZE
|
||||
#define XKPRANGE_CC_KASAN_OFFSET (0)
|
||||
#define XKPRANGE_CC_SHADOW_SIZE (XKPRANGE_CC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
#define XKPRANGE_CC_SHADOW_END (XKPRANGE_CC_KASAN_OFFSET + XKPRANGE_CC_SHADOW_SIZE)
|
||||
|
||||
/* UnCached */
|
||||
#define XKPRANGE_UC_START UNCACHE_BASE
|
||||
#define XKPRANGE_UC_SIZE XRANGE_SIZE
|
||||
#define XKPRANGE_UC_KASAN_OFFSET XKPRANGE_CC_SHADOW_END
|
||||
#define XKPRANGE_UC_SHADOW_SIZE (XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
#define XKPRANGE_UC_SHADOW_END (XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE)
|
||||
|
||||
/* VMALLOC (Cached or UnCached) */
|
||||
#define XKVRANGE_VC_START MODULES_VADDR
|
||||
#define XKVRANGE_VC_SIZE round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE)
|
||||
#define XKVRANGE_VC_KASAN_OFFSET XKPRANGE_UC_SHADOW_END
|
||||
#define XKVRANGE_VC_SHADOW_SIZE (XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
#define XKVRANGE_VC_SHADOW_END (XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE)
|
||||
|
||||
/* KAsan shadow memory start right after vmalloc. */
|
||||
#define KASAN_SHADOW_START round_up(KFENCE_AREA_END, PGDIR_SIZE)
|
||||
#define KASAN_SHADOW_SIZE (XKVRANGE_VC_SHADOW_END - XKPRANGE_CC_KASAN_OFFSET)
|
||||
#define KASAN_SHADOW_END round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE)
|
||||
|
||||
#define XKPRANGE_CC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET)
|
||||
#define XKPRANGE_UC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET)
|
||||
#define XKVRANGE_VC_SHADOW_OFFSET (KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET)
|
||||
|
||||
extern bool kasan_early_stage;
|
||||
extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
|
||||
|
||||
#define kasan_arch_is_ready kasan_arch_is_ready
|
||||
static __always_inline bool kasan_arch_is_ready(void)
|
||||
{
|
||||
return !kasan_early_stage;
|
||||
}
|
||||
|
||||
static inline void *kasan_mem_to_shadow(const void *addr)
|
||||
{
|
||||
if (!kasan_arch_is_ready()) {
|
||||
return (void *)(kasan_early_shadow_page);
|
||||
} else {
|
||||
unsigned long maddr = (unsigned long)addr;
|
||||
unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff;
|
||||
unsigned long offset = 0;
|
||||
|
||||
maddr &= XRANGE_SHADOW_MASK;
|
||||
switch (xrange) {
|
||||
case XKPRANGE_CC_SEG:
|
||||
offset = XKPRANGE_CC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKPRANGE_UC_SEG:
|
||||
offset = XKPRANGE_UC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKVRANGE_VC_SEG:
|
||||
offset = XKVRANGE_VC_SHADOW_OFFSET;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset);
|
||||
}
|
||||
}
|
||||
|
||||
static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)shadow_addr;
|
||||
|
||||
if (unlikely(addr > KASAN_SHADOW_END) ||
|
||||
unlikely(addr < KASAN_SHADOW_START)) {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
|
||||
else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
|
||||
else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START);
|
||||
else {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void kasan_init(void);
|
||||
asmlinkage void kasan_early_init(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* KFENCE support for LoongArch.
|
||||
*
|
||||
* Author: Enze Li <lienze@kylinos.cn>
|
||||
* Copyright (C) 2022-2023 KylinSoft Corporation.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_LOONGARCH_KFENCE_H
|
||||
#define _ASM_LOONGARCH_KFENCE_H
|
||||
|
||||
#include <linux/kfence.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlb.h>
|
||||
|
||||
static inline bool arch_kfence_init_pool(void)
|
||||
{
|
||||
int err;
|
||||
char *kfence_pool = __kfence_pool;
|
||||
struct vm_struct *area;
|
||||
|
||||
area = __get_vm_area_caller(KFENCE_POOL_SIZE, VM_IOREMAP,
|
||||
KFENCE_AREA_START, KFENCE_AREA_END,
|
||||
__builtin_return_address(0));
|
||||
if (!area)
|
||||
return false;
|
||||
|
||||
__kfence_pool = (char *)area->addr;
|
||||
err = ioremap_page_range((unsigned long)__kfence_pool,
|
||||
(unsigned long)__kfence_pool + KFENCE_POOL_SIZE,
|
||||
virt_to_phys((void *)kfence_pool), PAGE_KERNEL);
|
||||
if (err) {
|
||||
free_vm_area(area);
|
||||
__kfence_pool = kfence_pool;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Protect the given page and flush TLB. */
|
||||
static inline bool kfence_protect_page(unsigned long addr, bool protect)
|
||||
{
|
||||
pte_t *pte = virt_to_kpte(addr);
|
||||
|
||||
if (WARN_ON(!pte) || pte_none(*pte))
|
||||
return false;
|
||||
|
||||
if (protect)
|
||||
set_pte(pte, __pte(pte_val(*pte) & ~(_PAGE_VALID | _PAGE_PRESENT)));
|
||||
else
|
||||
set_pte(pte, __pte(pte_val(*pte) | (_PAGE_VALID | _PAGE_PRESENT)));
|
||||
|
||||
preempt_disable();
|
||||
local_flush_tlb_one(addr);
|
||||
preempt_enable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* _ASM_LOONGARCH_KFENCE_H */
|
||||
@@ -0,0 +1,97 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2023 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#ifndef _ASM_LOONGARCH_KGDB_H
|
||||
#define _ASM_LOONGARCH_KGDB_H
|
||||
|
||||
#define GDB_SIZEOF_REG sizeof(u64)
|
||||
|
||||
/* gdb remote procotol expects the following register layout. */
|
||||
|
||||
/*
|
||||
* General purpose registers:
|
||||
* r0-r31: 64 bit
|
||||
* orig_a0: 64 bit
|
||||
* pc : 64 bit
|
||||
* csr_badvaddr: 64 bit
|
||||
*/
|
||||
#define DBG_PT_REGS_BASE 0
|
||||
#define DBG_PT_REGS_NUM 35
|
||||
#define DBG_PT_REGS_END (DBG_PT_REGS_BASE + DBG_PT_REGS_NUM - 1)
|
||||
|
||||
/*
|
||||
* Floating point registers:
|
||||
* f0-f31: 64 bit
|
||||
*/
|
||||
#define DBG_FPR_BASE (DBG_PT_REGS_END + 1)
|
||||
#define DBG_FPR_NUM 32
|
||||
#define DBG_FPR_END (DBG_FPR_BASE + DBG_FPR_NUM - 1)
|
||||
|
||||
/*
|
||||
* Condition Flag registers:
|
||||
* fcc0-fcc8: 8 bit
|
||||
*/
|
||||
#define DBG_FCC_BASE (DBG_FPR_END + 1)
|
||||
#define DBG_FCC_NUM 8
|
||||
#define DBG_FCC_END (DBG_FCC_BASE + DBG_FCC_NUM - 1)
|
||||
|
||||
/*
|
||||
* Floating-point Control and Status registers:
|
||||
* fcsr: 32 bit
|
||||
*/
|
||||
#define DBG_FCSR_NUM 1
|
||||
#define DBG_FCSR (DBG_FCC_END + 1)
|
||||
|
||||
#define DBG_MAX_REG_NUM (DBG_FCSR + 1)
|
||||
|
||||
/*
|
||||
* Size of I/O buffer for gdb packet.
|
||||
* considering to hold all register contents, size is set
|
||||
*/
|
||||
#define BUFMAX 2048
|
||||
|
||||
/*
|
||||
* Number of bytes required for gdb_regs buffer.
|
||||
* PT_REGS and FPR: 8 bytes; FCSR: 4 bytes; FCC: 1 bytes.
|
||||
* GDB fails to connect for size beyond this with error
|
||||
* "'g' packet reply is too long"
|
||||
*/
|
||||
#define NUMREGBYTES ((DBG_PT_REGS_NUM + DBG_FPR_NUM) * GDB_SIZEOF_REG + DBG_FCC_NUM * 1 + DBG_FCSR_NUM * 4)
|
||||
|
||||
#define BREAK_INSTR_SIZE 4
|
||||
#define CACHE_FLUSH_IS_SAFE 0
|
||||
|
||||
/* Register numbers of various important registers. */
|
||||
enum dbg_loongarch_regnum {
|
||||
DBG_LOONGARCH_ZERO = 0,
|
||||
DBG_LOONGARCH_RA,
|
||||
DBG_LOONGARCH_TP,
|
||||
DBG_LOONGARCH_SP,
|
||||
DBG_LOONGARCH_A0,
|
||||
DBG_LOONGARCH_FP = 22,
|
||||
DBG_LOONGARCH_S0,
|
||||
DBG_LOONGARCH_S1,
|
||||
DBG_LOONGARCH_S2,
|
||||
DBG_LOONGARCH_S3,
|
||||
DBG_LOONGARCH_S4,
|
||||
DBG_LOONGARCH_S5,
|
||||
DBG_LOONGARCH_S6,
|
||||
DBG_LOONGARCH_S7,
|
||||
DBG_LOONGARCH_S8,
|
||||
DBG_LOONGARCH_ORIG_A0,
|
||||
DBG_LOONGARCH_PC,
|
||||
DBG_LOONGARCH_BADV
|
||||
};
|
||||
|
||||
void kgdb_breakinst(void);
|
||||
void arch_kgdb_breakpoint(void);
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
bool kgdb_breakpoint_handler(struct pt_regs *regs);
|
||||
#else /* !CONFIG_KGDB */
|
||||
static inline bool kgdb_breakpoint_handler(struct pt_regs *regs) { return false; }
|
||||
#endif /* CONFIG_KGDB */
|
||||
|
||||
#endif /* __ASM_KGDB_H_ */
|
||||
@@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Author: Qi Hu <huqi@loongson.cn>
|
||||
* Huacai Chen <chenhuacai@loongson.cn>
|
||||
* Copyright (C) 2020-2023 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _ASM_LBT_H
|
||||
#define _ASM_LBT_H
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
extern void _init_lbt(void);
|
||||
extern void _save_lbt(struct loongarch_lbt *);
|
||||
extern void _restore_lbt(struct loongarch_lbt *);
|
||||
|
||||
static inline int is_lbt_enabled(void)
|
||||
{
|
||||
if (!cpu_has_lbt)
|
||||
return 0;
|
||||
|
||||
return (csr_read32(LOONGARCH_CSR_EUEN) & CSR_EUEN_LBTEN) ?
|
||||
1 : 0;
|
||||
}
|
||||
|
||||
static inline int is_lbt_owner(void)
|
||||
{
|
||||
return test_thread_flag(TIF_USEDLBT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
|
||||
static inline void enable_lbt(void)
|
||||
{
|
||||
if (cpu_has_lbt)
|
||||
csr_xchg32(CSR_EUEN_LBTEN, CSR_EUEN_LBTEN, LOONGARCH_CSR_EUEN);
|
||||
}
|
||||
|
||||
static inline void disable_lbt(void)
|
||||
{
|
||||
if (cpu_has_lbt)
|
||||
csr_xchg32(0, CSR_EUEN_LBTEN, LOONGARCH_CSR_EUEN);
|
||||
}
|
||||
|
||||
static inline void __own_lbt(void)
|
||||
{
|
||||
enable_lbt();
|
||||
set_thread_flag(TIF_USEDLBT);
|
||||
KSTK_EUEN(current) |= CSR_EUEN_LBTEN;
|
||||
}
|
||||
|
||||
static inline void own_lbt_inatomic(int restore)
|
||||
{
|
||||
if (cpu_has_lbt && !is_lbt_owner()) {
|
||||
__own_lbt();
|
||||
if (restore)
|
||||
_restore_lbt(¤t->thread.lbt);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void own_lbt(int restore)
|
||||
{
|
||||
preempt_disable();
|
||||
own_lbt_inatomic(restore);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline void lose_lbt_inatomic(int save, struct task_struct *tsk)
|
||||
{
|
||||
if (cpu_has_lbt && is_lbt_owner()) {
|
||||
if (save)
|
||||
_save_lbt(&tsk->thread.lbt);
|
||||
|
||||
disable_lbt();
|
||||
clear_tsk_thread_flag(tsk, TIF_USEDLBT);
|
||||
}
|
||||
KSTK_EUEN(tsk) &= ~(CSR_EUEN_LBTEN);
|
||||
}
|
||||
|
||||
static inline void lose_lbt(int save)
|
||||
{
|
||||
preempt_disable();
|
||||
lose_lbt_inatomic(save, current);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline void init_lbt(void)
|
||||
{
|
||||
__own_lbt();
|
||||
_init_lbt();
|
||||
}
|
||||
#else
|
||||
static inline void own_lbt_inatomic(int restore) {}
|
||||
static inline void lose_lbt_inatomic(int save, struct task_struct *tsk) {}
|
||||
static inline void init_lbt(void) {}
|
||||
static inline void lose_lbt(int save) {}
|
||||
#endif
|
||||
|
||||
static inline int thread_lbt_context_live(void)
|
||||
{
|
||||
if (!cpu_has_lbt)
|
||||
return 0;
|
||||
|
||||
return test_thread_flag(TIF_LBT_CTX_LIVE);
|
||||
}
|
||||
|
||||
#endif /* _ASM_LBT_H */
|
||||
@@ -12,49 +12,6 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <larchintrin.h>
|
||||
|
||||
/*
|
||||
* parse_r var, r - Helper assembler macro for parsing register names.
|
||||
*
|
||||
* This converts the register name in $n form provided in \r to the
|
||||
* corresponding register number, which is assigned to the variable \var. It is
|
||||
* needed to allow explicit encoding of instructions in inline assembly where
|
||||
* registers are chosen by the compiler in $n form, allowing us to avoid using
|
||||
* fixed register numbers.
|
||||
*
|
||||
* It also allows newer instructions (not implemented by the assembler) to be
|
||||
* transparently implemented using assembler macros, instead of needing separate
|
||||
* cases depending on toolchain support.
|
||||
*
|
||||
* Simple usage example:
|
||||
* __asm__ __volatile__("parse_r addr, %0\n\t"
|
||||
* "#invtlb op, 0, %0\n\t"
|
||||
* ".word ((0x6498000) | (addr << 10) | (0 << 5) | op)"
|
||||
* : "=r" (status);
|
||||
*/
|
||||
|
||||
/* Match an individual register number and assign to \var */
|
||||
#define _IFC_REG(n) \
|
||||
".ifc \\r, $r" #n "\n\t" \
|
||||
"\\var = " #n "\n\t" \
|
||||
".endif\n\t"
|
||||
|
||||
__asm__(".macro parse_r var r\n\t"
|
||||
"\\var = -1\n\t"
|
||||
_IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3)
|
||||
_IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7)
|
||||
_IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11)
|
||||
_IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
|
||||
_IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
|
||||
_IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
|
||||
_IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
|
||||
_IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
|
||||
".iflt \\var\n\t"
|
||||
".error \"Unable to parse register name \\r\"\n\t"
|
||||
".endif\n\t"
|
||||
".endm");
|
||||
|
||||
#undef _IFC_REG
|
||||
|
||||
/* CPUCFG */
|
||||
#define read_cpucfg(reg) __cpucfg(reg)
|
||||
|
||||
@@ -1453,6 +1410,10 @@ __BUILD_CSR_OP(tlbidx)
|
||||
#define FPU_CSR_RU 0x200 /* towards +Infinity */
|
||||
#define FPU_CSR_RD 0x300 /* towards -Infinity */
|
||||
|
||||
/* Bit 6 of FPU Status Register specify the LBT TOP simulation mode */
|
||||
#define FPU_CSR_TM_SHIFT 0x6
|
||||
#define FPU_CSR_TM (_ULCAST_(1) << FPU_CSR_TM_SHIFT)
|
||||
|
||||
#define read_fcsr(source) \
|
||||
({ \
|
||||
unsigned int __res; \
|
||||
|
||||
@@ -13,6 +13,4 @@ extern struct pglist_data *node_data[];
|
||||
|
||||
#define NODE_DATA(nid) (node_data[(nid)])
|
||||
|
||||
extern void setup_zero_pages(void);
|
||||
|
||||
#endif /* _ASM_MMZONE_H_ */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user