Previously the kernel did not call vcpu_switch on the fastpath since the fastpath avoids
calling setVMRoot, so when sending an IPC message from a guest thread to a native thread,
if the IPC was small enough to go on the fastpath the kernel would fail to disable the
HYP traps and would treat the native thread like a guest thread.
aarch64 hyp mode only has support for 8 bit hardware ASIDs. We use the
same strategy used in aarch32 for hardware asids where we maintain a
pool of hwasids that seL4 ASIDs are allocated. The allocation is stored
in the last entry of top level paging structure. This commit
encapsulates this into the bitfield specification in the same way as
aarch32.
- seL4_UserTop is a new constant which represents the top of virtual
memory available to user level
- this commit also rationalises several constants (USER_TOP, kernelBase)
and moves them to the arch level, such that ports only need to define
seL4_UserTop.
GrantReply is a new access right added to endpoint capabilities, which
allows seL4_Call to be used on those capabilities (specifically, it
allows reply caps *only* to be granted across endpoints).
Prior to the addition of GrantReply, endpoint capabilities required the
Grant access right, which allowed any arbitrary capabilitiy to be
transferred over an endpoint. Using GrantReply, systems can now be
constructed where threads using seL4_Call over an endpoint do not need to be in the same
security subsystem.
The registers a7, s2-11, and t3-6 were missing from seL4_UserContext.
We also add these to frameRegisters and gpRegisters, which are used
to implement the TCB invocations for reading and writing these
registers.
Zero-length arrays aren't valid expressions or types in ISO C, so
to keep the c parser happy we need to either remove gpRegisters or
provide some contents for it.
In the past, frameRegisters and gpRegisters distinguished between
those registers preserved across a syscall and those that weren't.
TCB_CopyRegisters allows the caller to choose which set to copy.
Since we preserve all non-return registers, this distinction isn't
relevant anymore and there's no easy way to justify the members of
frameRegisters and gpRegisters.
We arbitrarily choose to put the 'last' register t6 in gpRegisters,
for consistency with the register list in registerset.h and with the
order that registers are restored.
Braced groups in expressions like
int x = 0;
x = ({x++; x;});
aren't supported by the C parser (or ISO C), so we replace the SBI_CALL
macro with an equivalent function.
The TLS_BASE stored in the globals frame needs to refer to the TLS_BASE
of the current thread and so must be maintained across all context
switches. (This was only being maintained on the slow path).
So far this is only implemented for the GIC, which most of our platforms
use. Error if this invocation is made on another platform, and guard
calls to the trigger function if it is not supported.
- renamed an architecture label so that it begins with ARM.
- changed setIRQTrigger so that it takes a boolean value instead of an int.
- Arch_decodeIRQControlInvocation converts the second argument (trigger)
to a boolean immediately.
Add a new invocation which allows an irq handler capability to be
obtained with a specific trigger method (edge or level). Obtaining
this capability modifies the GIC state.
While the RISC-V ISA says to that a VMFENCE before a write to the
satp may be necessary, vm faults occur with this ordering when
running on the Rocket Chip. Placing the VMFENCE after the satp write
resolves these faults.
This is also the ordering used in the RISC-V port of Linux when
switching MMU contexts.
Change-Id: I1ec794651d080a5e7a987fa8b2062dc01daeb683
This patch moves the 'outer' chunk of lockTLBEntry into C rather
than handwritten assembly. The outer chunk accesses a global
counter and does arithmetic. The inner chunk (lockTLBEntryCritical)
writes to the registers, must be specially aligned, and is generally
special.
The change reduces unnecessary handwritten assembly, and also avoids
a special case that was problematic for binary verification.
Leaves the last entry in the top level page table free so that it can be used for mapping
devices in the future. This moves the kernel image down to the second last entry in the
top level page table. Leaving the last entry in the top level page table also matches the
rv64 design.
Only a single level 2 page table is now used for mapping the kernel image so this simplifies
the state data to only allocate a single PT and removes the now out of date description.
This instruction is required when more than one thread exists with
different ASIDs. The system will lock up after the first context
switch when running on hardware.
Issue first noticed and fixed by Hesham Almatary
<Hesham.Almatary@cl.cam.ac.uk>
Change-Id: I6eb64df6b584ff7de79c8af30b28bbc7bb234643
This uses a one dimensional page table for the first level
and a two dimensional array for the second level such that
in a worst case scenario, the entire kernel region could
be mapped using second level tables.
Co-authored-by: Chris Guikema <chris.guikema@dornerworks.com>
Change-Id: Iad62303a0d7c2321d6038ca718888100614f91db
This change is required because the zedboard rocket-chip only has
256MiB of memory. Therefore the load address needs to be lowered
to fit in the available range.
This change will also require the kernel to be mapped with 2MiB
granularity so everything is properly page aligned.
Change-Id: I75ddec0be1bb2fd05d0a947ea19bce46e2cd9f96
These registers are part of the 'regular' TCB state and are saved and restored as part
of normal thread switching. As such it is conflicting to have a duplicate idea of the value
of these registers, especially as it is not kept in sync with the version in the TCB,
which is what is actually being loaded into the hardware.
Threads that have a VCPU, and hence might be running in supervisor mode, probably don't
care about the IPC buffer and would rather their registers contain the values they expect.
This register can be modified by the supervisor mode thread attached to a VCPU and we
should be saving and restoring it. The necessity of doing this has been revealed due to
the kernel now allowing TPIDRURO to be used for TLS_BASE, causing the register to be
overriden if we switch away from a VCPU and then back to it.
Defines TLS_BASE to the be the TP register. Currently the TP register is already used to
place the location of the IPC buffer into it and so a user thread should not set a value
for TLS_BASE unless they have their own way to find their IPC buffer.
This commit provides a universal TLS_BASE virtual register on ARM, similar to as exists
on x86. Depending on the precise configuration this virtual register maps to a different
register
* aarch64: TPIDRURW is used for the TLS_BASE and is already declared and being saved
and restored on context switches, so this just adds TLS_BASE as an alias of it
* armv6: Has no hardware register for use for a TLS_BASE, and so the virtual register
gets stored into the globals frame
* armv7+: TPIDURO is used for TLS_BASE and so the restore paths are modified to load
TLS_BASE into it