[PATCH 2/8] Documentation: kvx: Wrap diagrams in literal code block

Bagas Sanjaya
2023-01-09T09:54:07Z

Wrap code path diagrams in literal code block, just like other diagrams
in the kernel documentation. This avoids confusion with other constructs
(tables, block quotes, and inline substitutions).

Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
---
Documentation/kvx/kvx-exceptions.rst | 241 ++++++++++++++-------------
Documentation/kvx/kvx-iommu.rst | 64 +++----
Documentation/kvx/kvx-mmu.rst | 41 +++--
Documentation/kvx/kvx.rst | 96 +++++------
4 files changed, 225 insertions(+), 217 deletions(-)

diff --git a/Documentation/kvx/kvx-exceptions.rst b/Documentation/kvx/kvx-exceptions.rst
index d3e52f30285223..bb9010efb14196 100644
--- a/Documentation/kvx/kvx-exceptions.rst
+++ b/Documentation/kvx/kvx-exceptions.rst
@@ -10,21 +10,21 @@ The offset depends on which exception vector the cpu wants to jump to:
* $ev + 0x80 for interrupt
* $ev + 0xc0 for syscall

-Then, handlers are laid in the following order:
+Then, handlers are laid in the following order::

- +-------------+
- | |
- | Syscall |
- +-------------+
- | |
- | Interrupts |
- +-------------+
- | |
- | Traps |
- +-------------+
- | | ^
- | Debug | | Stride
-BASE -> +-------------+ v
+ +-------------+
+ | |
+ | Syscall |
+ +-------------+
+ | |
+ | Interrupts |
+ +-------------+
+ | |
+ | Traps |
+ +-------------+
+ | | ^
+ | Debug | | Stride
+ BASE -> +-------------+ v

Interrupts, and traps are serviced similarly, ie:
@@ -99,65 +99,66 @@ When handling a signal, the path is the following:
7 - User application is restored at the exact point it was interrupted
before.

+ ::

- +----------+
- | 1 |
- | User app | @func
- | (user) |
- +---+------+
- |
- | it/trap/scall
- |
- +---v-------+
- | 2 |
- | exception |
- | handling |
- | (kernel) |
- +---+-------+
- |
- | Check if signal are pending, if so, handle signals
- |
- +---v--------+
- | 3 |
- | do_signal |
- | handling |
- | (kernel) |
- +----+-------+
- |
- | Return to user signal handler
- |
- +----v------+
- | 4 |
- | signal |
- | handler |
- | (user) |
- +----+------+
- |
- | Return to sigreturn trampoline
- |
- +----v-------+
- | 5 |
- | syscall |
- |rt_sigreturn|
- | (user) |
- +----+-------+
- |
- | Syscall to rt_sigreturn
- |
- +----v-------+
- | 6 |
- | sigreturn |
- | handler |
- | (kernel) |
- +----+-------+
- |
- | Modify context to return to original func
- |
- +----v-----+
- | 7 |
- | User app | @func
- | (user) |
- +----------+
+ +----------+
+ | 1 |
+ | User app | @func
+ | (user) |
+ +---+------+
+ |
+ | it/trap/scall
+ |
+ +---v-------+
+ | 2 |
+ | exception |
+ | handling |
+ | (kernel) |
+ +---+-------+
+ |
+ | Check if signal are pending, if so, handle signals
+ |
+ +---v--------+
+ | 3 |
+ | do_signal |
+ | handling |
+ | (kernel) |
+ +----+-------+
+ |
+ | Return to user signal handler
+ |
+ +----v------+
+ | 4 |
+ | signal |
+ | handler |
+ | (user) |
+ +----+------+
+ |
+ | Return to sigreturn trampoline
+ |
+ +----v-------+
+ | 5 |
+ | syscall |
+ |rt_sigreturn|
+ | (user) |
+ +----+-------+
+ |
+ | Syscall to rt_sigreturn
+ |
+ +----v-------+
+ | 6 |
+ | sigreturn |
+ | handler |
+ | (kernel) |
+ +----+-------+
+ |
+ | Modify context to return to original func
+ |
+ +----v-----+
+ | 7 |
+ | User app | @func
+ | (user) |
+ +----------+

Registers handling
==================
@@ -174,62 +175,62 @@ Interrupts and traps

When interrupt and traps are triggered, we only save the caller-saved registers.
Indeed, we rely on the fact that C code will save and restore callee-saved and
-hence, there is no need to save them. This path is the following:
+hence, there is no need to save them. This path is the following::

- +------------+ +-----------+ +---------------+
-IT | Save caller| C Call | Execute C | Ret | Restore caller| Ret from IT
-+--->+ saved +--------->+ handler +------->+ saved +----->
- | registers | +-----------+ | registers |
- +------------+ +---------------+
+ +------------+ +-----------+ +---------------+
+ IT | Save caller| C Call | Execute C | Ret | Restore caller| Ret from IT
+ +--->+ saved +--------->+ handler +------->+ saved +----->
+ | registers | +-----------+ | registers |
+ +------------+ +---------------+

However, when returning to user, we check if there is work_pending. If a signal
is pending and there is a signal handler to be called, then we need all
registers to be saved on the stack in the pt_regs before executing the signal
handler and restored after that. Since we only saved caller-saved registers, we
need to also save callee-saved registers to restore them correctly when
-returning to user. This path is the following (a bit more complicated !):
+returning to user. This path is the following (a bit more complicated !)::

- +------------+
- | Save caller| +-----------+ Ret +------------+
- IT | saved | C Call | Execute C | to asm | Check work |
- +--->+ registers +--------->+ handler +------->+ pending |
- | to pt_regs | +-----------+ +--+---+-----+
- +------------+ | |
- Work pending | | No work pending
- +--------------------------------------------+ |
- | |
- | +------------+
- v |
- +------+------+ v
- | Save callee | +-------+-------+
- | saved | | Restore caller| RFE from IT
- | registers | | saved +------->
- | to pt_regs | | registers |
- +--+-------+--+ | from pt_regs |
- | | +-------+-------+
- | | +---------+ ^
- | | | Execute | |
- | +-------->+ needed +-----------+
- | | work |
- | +---------+
- |Signal handler ?
- v
-+----+----------+ RFE to user +-------------+ +--------------+
-| Copy all | handler | Execute | ret | rt_sigreturn |
-| registers +------------>+ user signal +------>+ trampoline |
-| from pt_regs | | handler | | to kernel |
-| to user stack | +-------------+ +------+-------+
-+---------------+ |
- syscall rt_sigreturn |
- +-------------------------------------------------+
- |
- v
-+--------+-------+ +-------------+
-| Recopy all | | Restore all | RFE
-| registers from +--------------------->+ saved +------->
-| user stack | Return | registers |
-| to pt_regs | from sigreturn |from pt_regs |
-+----------------+ (via ret_from_fork) +-------------+
+ +------------+
+ | Save caller| +-----------+ Ret +------------+
+ IT | saved | C Call | Execute C | to asm | Check work |
+ +--->+ registers +--------->+ handler +------->+ pending |
+ | to pt_regs | +-----------+ +--+---+-----+
+ +------------+ | |
+ Work pending | | No work pending
+ +--------------------------------------------+ |
+ | |
+ | +------------+
+ v |
+ +------+------+ v
+ | Save callee | +-------+-------+
+ | saved | | Restore caller| RFE from IT
+ | registers | | saved +------->
+ | to pt_regs | | registers |
+ +--+-------+--+ | from pt_regs |
+ | | +-------+-------+
+ | | +---------+ ^
+ | | | Execute | |
+ | +-------->+ needed +-----------+
+ | | work |
+ | +---------+
+ |Signal handler ?
+ v
+ +----+----------+ RFE to user +-------------+ +--------------+
+ | Copy all | handler | Execute | ret | rt_sigreturn |
+ | registers +------------>+ user signal +------>+ trampoline |
+ | from pt_regs | | handler | | to kernel |
+ | to user stack | +-------------+ +------+-------+
+ +---------------+ |
+ syscall rt_sigreturn |
+ +-------------------------------------------------+
+ |
+ v
+ +--------+-------+ +-------------+
+ | Recopy all | | Restore all | RFE
+ | registers from +--------------------->+ saved +------->
+ | user stack | Return | registers |
+ | to pt_regs | from sigreturn |from pt_regs |
+ +----------------+ (via ret_from_fork) +-------------+

Syscalls
diff --git a/Documentation/kvx/kvx-iommu.rst b/Documentation/kvx/kvx-iommu.rst
index 96b74ce71acb3e..69eca8d1bc37a1 100644
--- a/Documentation/kvx/kvx-iommu.rst
+++ b/Documentation/kvx/kvx-iommu.rst
@@ -63,39 +63,39 @@ IOMMU implementation
--------------------

The kvx is providing several IOMMUs. Here is a simplified view of all IOMMUs
-and translations that occurs between memory and devices:
+and translations that occurs between memory and devices::

- +---------------------------------------------------------------------+
- | +------------+ +---------+ | CLUSTER X |
- | | Cores 0-15 +---->+ Crypto | +-----------|
- | +-----+------+ +----+----+ |
- | | | |
- | v v |
- | +-------+ +------------------------------+ |
- | | MMU | +----+ IOMMU x4 (secure + insecure) | |
- | +---+---+ | +------------------------------+ |
- | | | |
- +--------------------+ |
- | | | |
- v v | |
- +---+--------+-+ | |
- | MEMORY | | +----------+ +--------+ +-------+ |
- | +<-|-----+ IOMMU Rx |<----+ DMA Rx |<----+ | |
- | | | +----------+ +--------+ | | |
- | | | | NoC | |
- | | | +----------+ +--------+ | | |
- | +--|---->| IOMMU Tx +---->| DMA Tx +---->+ | |
- | | | +----------+ +--------+ +-------+ |
- | | +------------------------------------------------+
- | |
- | | +--------------+ +------+
- | |<--->+ IOMMU Rx/Tx +<--->+ PCIe +
- | | +--------------+ +------+
- | |
- | | +--------------+ +------------------------+
- | |<--->+ IOMMU Rx/Tx +<--->+ master Soc Peripherals |
- | | +--------------+ +------------------------+
- +--------------+
+ +---------------------------------------------------------------------+
+ | +------------+ +---------+ | CLUSTER X |
+ | | Cores 0-15 +---->+ Crypto | +-----------|
+ | +-----+------+ +----+----+ |
+ | | | |
+ | v v |
+ | +-------+ +------------------------------+ |
+ | | MMU | +----+ IOMMU x4 (secure + insecure) | |
+ | +---+---+ | +------------------------------+ |
+ | | | |
+ +--------------------+ |
+ | | | |
+ v v | |
+ +---+--------+-+ | |
+ | MEMORY | | +----------+ +--------+ +-------+ |
+ | +<-|-----+ IOMMU Rx |<----+ DMA Rx |<----+ | |
+ | | | +----------+ +--------+ | | |
+ | | | | NoC | |
+ | | | +----------+ +--------+ | | |
+ | +--|---->| IOMMU Tx +---->| DMA Tx +---->+ | |
+ | | | +----------+ +--------+ +-------+ |
+ | | +------------------------------------------------+
+ | |
+ | | +--------------+ +------+
+ | |<--->+ IOMMU Rx/Tx +<--->+ PCIe +
+ | | +--------------+ +------+
+ | |
+ | | +--------------+ +------------------------+
+ | |<--->+ IOMMU Rx/Tx +<--->+ master Soc Peripherals |
+ | | +--------------+ +------------------------+
+ +--------------+

There is also an IOMMU dedicated to the crypto module but this module will not
diff --git a/Documentation/kvx/kvx-mmu.rst b/Documentation/kvx/kvx-mmu.rst
index 59bda2afc9abde..832fb7c41a49d8 100644
--- a/Documentation/kvx/kvx-mmu.rst
+++ b/Documentation/kvx/kvx-mmu.rst
@@ -157,14 +157,17 @@ We only support three levels for the page table and 4KB for page size.
3 levels page table
-------------------

-...-----+--------+--------+--------+--------+--------+
- 40|39 32|31 24|23 16|15 8|7 0|
-...-----++-------+--+-----+---+----+----+---+--------+
- | | | |
- | | | +---> [11:0] Offset (12 bits)
- | | +-------------> [20:12] PTE offset (9 bits)
- | +-----------------------> [29:21] PMD offset (9 bits)
- +----------------------------------> [39:30] PGD offset (10 bits)
+::
+
+ ...-----+--------+--------+--------+--------+--------+
+ 40|39 32|31 24|23 16|15 8|7 0|
+ ...-----++-------+--+-----+---+----+----+---+--------+
+ | | | |
+ | | | +---> [11:0] Offset (12 bits)
+ | | +-------------> [20:12] PTE offset (9 bits)
+ | +-----------------------> [29:21] PMD offset (9 bits)
+ +----------------------------------> [39:30] PGD offset (10 bits)
+
Bits 40 to 64 are signed extended according to bit 39. If bit 39 is equal to 1
we are in kernel space.

@@ -175,12 +178,14 @@ PTE format

About the format of the PTE entry, as we are not forced by hardware for choices,
we choose to follow the format described in the RiscV implementation as a
-starting point.
+starting point::
+
+ +---------+--------+----+--------+---+---+---+---+---+---+------+---+---+
+ | 63..23 | 22..13 | 12 | 11..10 | 9 | 8 | 7 | 6 | 5 | 4 | 3..2 | 1 | 0 |
+ +---------+--------+----+--------+---+---+---+---+---+---+------+---+---+
+ PFN Unused S PageSZ H G X W R D CP A P
+

- +---------+--------+----+--------+---+---+---+---+---+---+------+---+---+
- | 63..23 | 22..13 | 12 | 11..10 | 9 | 8 | 7 | 6 | 5 | 4 | 3..2 | 1 | 0 |
- +---------+--------+----+--------+---+---+---+---+---+---+------+---+---+
- PFN Unused S PageSZ H G X W R D CP A P
where:
P: Present
A: Accessed
@@ -231,10 +236,12 @@ kvx implementation to use them is based on other architectures (such as arc
or xtensa) and uses a wrapping ASN counter containing both cycle/generation and
asn.

-+---------+--------+
-|63 10|9 0|
-+---------+--------+
- Cycle ASN
+::
+
+ +---------+--------+
+ |63 10|9 0|
+ +---------+--------+
+ Cycle ASN

This ASN counter is incremented monotonously to allocate new ASNs. When the
counter reaches 511 (9 bit), TLB is completely flushed and a new cycle is
diff --git a/Documentation/kvx/kvx.rst b/Documentation/kvx/kvx.rst
index 8ce0703de6813b..20c3666f445e26 100644
--- a/Documentation/kvx/kvx.rst
+++ b/Documentation/kvx/kvx.rst
@@ -15,17 +15,17 @@ On kvx, we have 4 levels of privilege level starting from 0 (most
privileged one) to 3 (less privilege one). A system of owners allows
to delegate ownership of resources by using specials system registers.

-The 2 main software stacks for Linux Kernel are the following:
+The 2 main software stacks for Linux Kernel are the following::

-+-------------+ +-------------+
-| PL0: Debug | | PL0: Debug |
-+-------------+ +-------------+
-| PL1: Linux | | PL1: HyperV |
-+-------------+ +-------------+
-| PL2: User | | PL2: Linux |
-+-------------+ +-------------+
-| | | PL3: User |
-+-------------+ +-------------+
+ +-------------+ +-------------+
+ | PL0: Debug | | PL0: Debug |
+ +-------------+ +-------------+
+ | PL1: Linux | | PL1: HyperV |
+ +-------------+ +-------------+
+ | PL2: User | | PL2: Linux |
+ +-------------+ +-------------+
+ | | | PL3: User |
+ +-------------+ +-------------+

In both cases, the kvx support for privileges has been designed using
only relative PL and thus should work on both configurations without
@@ -201,45 +201,45 @@ to it, the kernel sends an interrupt using a mailbox.
If the L2$ node is not present in the device tree, then, the RM will directly go
into sleeping.

-Boot diagram:
+Boot diagram::

- RM PE 0
- +
- +---------+ |
- | Boot | |
- +----+----+ |
- | |
- v |
- +-----+-----+ |
- | Prepare | |
- | L2 shared | |
- | memory | |
- |(registers)| |
- +-----+-----+ |
- | | +-----------+
- +------------------->+ Boot |
- | | +-----+-----+
- v | |
- +--------+---------+ | |
- | L2 firmware | | |
- | parameters: | | |
- | r0 = registers | | |
- | r1 = DTB | | |
- +--------+---------+ | |
- | | |
- v | |
- +-------+--------+ | +------+------+
- | L2 firmware | | | Wait for L2 |
- | execution | | | to be ready |
- +-------+--------+ | +------+------+
- | | |
- +------v-------+ | v
- | L2 requests | | +------+------+
-+--->+ handling | | | Enable |
-| +-------+------+ | | L2 caching |
-| | | +------+------+
-| | | |
-+------------+ + v
+ RM PE 0
+ +
+ +---------+ |
+ | Boot | |
+ +----+----+ |
+ | |
+ v |
+ +-----+-----+ |
+ | Prepare | |
+ | L2 shared | |
+ | memory | |
+ |(registers)| |
+ +-----+-----+ |
+ | | +-----------+
+ +------------------->+ Boot |
+ | | +-----+-----+
+ v | |
+ +--------+---------+ | |
+ | L2 firmware | | |
+ | parameters: | | |
+ | r0 = registers | | |
+ | r1 = DTB | | |
+ +--------+---------+ | |
+ | | |
+ v | |
+ +-------+--------+ | +------+------+
+ | L2 firmware | | | Wait for L2 |
+ | execution | | | to be ready |
+ +-------+--------+ | +------+------+
+ | | |
+ +------v-------+ | v
+ | L2 requests | | +------+------+
+ +--->+ handling | | | Enable |
+ | +-------+------+ | | L2 caching |
+ | | | +------+------+
+ | | | |
+ +------------+ + v

Since this driver is started early (before SMP boot), A lot of drivers are not
--
An old man doll... just what I always wanted! - Clara