The Arch_hasVCPU function instead of cheaking for whether a thread has a VCPU was
specifically checking for whether a thread on aarch32 had a VCPU, as that was the
condition needed to be passed into sanitiseRegister. This made the implementation
on x86 extremely confusing as Arch_hasVCPU was implemented to return false due to
there being no need for sanitiseRegister on x86 to know whether there was a vcpu.
This commit changes hasVCPU variables to be an abstract archInfo boolean that can
be used arbitrarily by an architecture. Arch_hasVCPU function was also changed to
become Arch_getSanitiseRegisterInfo whose result only passed to sanitiseRegister.
In the original slow path, armv_contextSwitch_HWASID shoots first.
Verification can't reorder machine operations on hardware state we don't
model. This puts the fastpath into the same order as the slow path.
invokeVCPUReadReg should not be setting message registers for the return message unless
the user performed a call. In doing so we must refactor the call to readVCPUReg to
outside the introduced `if` condition since, as it performs machine operations, it
should always happen
The fields in the multiboot_info structure have precise sizes and should not use pointers
types as these sizes change between ia32 and x86_64 builds. This commit changes such
fields to be the correct fixed size uint32_t
Provides a configuration option for enabling HDCR.TD* traps, or saving and loading debug
state on VCPU switches. Currently verification only plans to support the trap setting.
As this option complicates all of the #ifdef's related to debug registers even further,
abstractions for enabling/disabling each individual piece of the debug code for different
configuration options are also implemented.
Part of these refactored #ifdef guards was to remove the guards completely from libsel4
around the definitions of the number of breakpoints and watchpoints.
We were previously using UNPREDICTABLE behaviour, because we were setting
HDCR.TDE without setting the other debug-related bits in HDCR.
Also, don't duplicate code: just call setHDCRTrapDebugExceptionState
within initHDCR().
A more efficient way of setting up threads' initial context is implemented
by this patch: essentially instead of reading the debug coprocessor everytime
we create a thread, we read the coprocessor once at boot and then assign
those pre-read values when initializing threads.
Previous implementation read a 64-bit value from two registers in one go
and implicitly cast down to paddr_t.
C Parser cannot handle an asm register read into anything other than a
word.
Workaround: perform two 32-bit reads instead, returning one of them.
struct vcpu { struct tcb* tcb; ...
struct arch_tcb { struct vcpu* vcpu; ...
and
struct tcb { struct arch_tcb tcbArch; ...
These conspire to generate a type error on verification side due to
assumptions about non-colliding names.
This removes some duplicated constants and moves some constants into debug.h such that
they are visible without the user debugging API enabled. These constants are useful
for configuring other debugging/performance monitoring features.
This patch disables the debug register state save and restore on ARM-hyp,
such that Guest VMs can now interfere with one another and trigger
one another for certain limited scenarios. This will be undone later on.
This patch enables the hype-mode kernel to intercept non-secure PL0
debug exceptions. Since it uses the HDCR register to do this (and not the SDCR),
it consequentially has no effect on any secure-monitor that may be executing
alongside the hypmode kernel.
For native seL4-hyp user threads, when the CPU sees a need to raise a debug
exception that was taken from PL0 (user), it will naturally try to raise that
exception to PL1 (supervisor).
But since seL4 is in PL2 and not PL1, seL4 has not set up an exception vector
table (VBAR) for PL1. So when the CPU attempts to vector into the PL1 VBAR,
it just gets a data abort, which it then delivers to PL2.
This patch causes the PL2 seL4 hypervisor to directly catch the debug exception
straight from PL0 and process the debug exception directly, for native threads.
Guest VM VCPUs are unaffected by this change. Their debug exceptions are delivered
to the Guest VM's PL1 VBAR as per usual.
As things are now, the Guest VMs can modify the debug registers at will
from non-secure PL1, and the kernel does nothing to ensure that guest VM
debug coprocessor registers are preserved.
This is a preliminary patch that simply hooks into vcpu_save and saves the
CPU's debug coprocessor registers when saving VCPU state.
For restoring the debug registers on switching to a VCPU, we just re-use
restore_user_debug_context, which is already called in restore_user_context.
(Restore_user_context is called by c_handle_vcpu_fault()). Specifically,
we modify the used_breakpoints_bf so that restore_user_debug_context()
will always pop all the debug context.
This patch only covers the breakpoint and watchpoint registers,
and it doesn't cover the entire debug coprocessor, which is another
conversation.
* commit '5253dca8b1e6a5cda3b6c7adce55f398ee3274fe':
SELFOUR-746: ARM/SMP - Reserve the first two SGI IDs for seL4 IPI
SELFOUR-746: ARM/GIC - Provide IPI support
SELFOUR-746: ARM/GIC - bank active_irq for each core
Similar to initIRQController(), cpu_initLocalIRQController() has to
be implemented for each platform. For those that are gonna support
SMP, it should be implemented proprely (if required), otherwise
it can be stubbed for single core implementations.
On 64-bit platforms physical address could be >2^32 offset from a virtual address. This
changes offsets to match the word size of the target architecture
In SMP context, init_cpu is meant to be called for each CPU, where
initialising private timer, user access and benchmarks (basically CCNT)
are per-CPU operations and involve per-CPU hardware
resources/interrupts.