Merge branch master into fix-makefile
This commit is contained in:
commit
468c7654ce
77 changed files with 599 additions and 461 deletions
10
Kconfig
10
Kconfig
|
|
@ -446,6 +446,16 @@ menu "Build Options"
|
|||
allows userspace processes to set breakpoints, watchpoints and to
|
||||
single-step through thread execution.
|
||||
|
||||
config ARM_HYP_ENABLE_VCPU_CP14_SAVE_AND_RESTORE
|
||||
bool "Trap, but don't save/restore VCPUs' CP14 accesses"
|
||||
depends on ARM_HYPERVISOR_SUPPORT && !VERIFICATION_BUILD
|
||||
default y
|
||||
help
|
||||
This allows us to turn off the save and restore of VCPU threads' CP14
|
||||
context for performance (or other) reasons, we can just turn them off
|
||||
and trap them instead, and have the VCPUs' accesses to CP14
|
||||
intercepted and delivered to the VM Monitor as fault messages.
|
||||
|
||||
config IRQ_REPORTING
|
||||
bool "Report spurious or undelivered IRQs"
|
||||
depends on PRINTING
|
||||
|
|
|
|||
10
Makefile
10
Makefile
|
|
@ -186,6 +186,8 @@ endif
|
|||
|
||||
ifeq (${PYTHON},)
|
||||
PYTHON = python
|
||||
# Suppress python bytecode (pyc) files for build thread safety
|
||||
export PYTHONDONTWRITEBYTECODE = true
|
||||
endif
|
||||
|
||||
# Allow manually appending CPP flags.
|
||||
|
|
@ -284,10 +286,9 @@ endif
|
|||
|
||||
# Only set CFLAGS if we're building standalone.
|
||||
# common/Makefile.Flags sets NK_CFLAGS in Kbuild environments.
|
||||
#
|
||||
# This entire block is not executed if building a stand alone kernel!
|
||||
ifndef NK_CFLAGS
|
||||
STATICHEADERS += autoconf.h
|
||||
STATICHEADERS += ${SOURCE_ROOT}/configs/$(PLAT)/autoconf.h
|
||||
INCLUDES += "-I${SOURCE_ROOT}/configs/$(PLAT)"
|
||||
DEFINES += -DHAVE_AUTOCONF
|
||||
ifdef DEBUG
|
||||
DEFINES += -DCONFIG_DEBUG_BUILD
|
||||
|
|
@ -640,9 +641,6 @@ kernel.elf: ${OBJECTS} linker.lds_pp
|
|||
$(Q)${CHANGED} $@ ${CC} ${LDFLAGS} -T linker.lds_pp -Wl,-n \
|
||||
-o $@ ${OBJECTS}
|
||||
|
||||
autoconf.h: include/plat/${PLAT}/autoconf.h
|
||||
${Q}cp $< $@
|
||||
|
||||
############################################################
|
||||
### Pattern rules
|
||||
############################################################
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
5.0.0
|
||||
5.0.0-dev
|
||||
|
|
@ -31,10 +31,9 @@
|
|||
#define CONFIG_CROSS_COMPILER_PREFIX "arm-linux-gnueabi-"
|
||||
#define CONFIG_MAX_NUM_WORK_UNITS_PER_PREEMPTION 100
|
||||
#define CONFIG_ARCH_ARM_V7A 1
|
||||
#define CONFIG_ARM_SMMU 1
|
||||
#define CONFIG_OPTIMISATION_O2 1
|
||||
#define CONFIG_ARCH_ARM 1
|
||||
#define CONFIG_NUM_DOMAINS 1
|
||||
#define CONFIG_NUM_DOMAINS 16
|
||||
#define CONFIG_RETYPE_FAN_OUT_LIMIT 256
|
||||
#define CONFIG_ROOT_CNODE_SIZE_BITS 19
|
||||
#define CONFIG_NUM_PRIORITIES 256
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <benchmark/benchmark_track.h>
|
||||
#include <arch/api/syscall.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
#include <model/statedata.h>
|
||||
|
||||
#ifdef CONFIG_PRINTING
|
||||
|
|
@ -53,6 +54,17 @@ debug_printKernelEntryReason(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Prints the user context and stack trace of the current thread */
|
||||
static inline void
|
||||
debug_printUserState(void)
|
||||
{
|
||||
tcb_t *tptr = NODE_STATE(ksCurThread);
|
||||
printf("Current thread: %s\n", tptr->tcbName);
|
||||
printf("Next instruction adress: %lx\n", getRestartPC(tptr));
|
||||
printf("Stack:\n");
|
||||
Arch_userStackTrace(tptr);
|
||||
}
|
||||
#endif /* CONFIG_PRINTING */
|
||||
#endif /* __API_DEBUG_H */
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <api/types.h>
|
||||
#include <api/syscall.h>
|
||||
#include <armv/context_switch.h>
|
||||
#include <arch/machine/debug.h>
|
||||
#include <smp/lock.h>
|
||||
|
||||
/* When building the fastpath the assembler in traps.S makes these
|
||||
|
|
@ -50,7 +51,7 @@ switchToThread_fp(tcb_t *thread, pde_t *cap_pd, pde_t stored_hw_asid)
|
|||
|
||||
hw_asid = pde_pde_invalid_get_stored_hw_asid(stored_hw_asid);
|
||||
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
|
||||
vcpu_switch(thread->tcbArch.vcpu);
|
||||
vcpu_switch(thread->tcbArch.tcbVCPU);
|
||||
}
|
||||
armv_contextSwitch_HWASID(cap_pd, hw_asid);
|
||||
|
||||
|
|
@ -130,7 +131,7 @@ fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread)
|
|||
|
||||
c_exit_hook();
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#ifdef CONFIG_ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS
|
||||
restore_user_debug_context(NODE_STATE(ksCurThread));
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ sanitiseRegister(register_t reg, word_t v, tcb_t *thread)
|
|||
{
|
||||
if (reg == CPSR) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (thread->tcbArch.vcpu) {
|
||||
if (thread->tcbArch.tcbVCPU) {
|
||||
switch (v & 0x1f) {
|
||||
case PMODE_USER:
|
||||
case PMODE_FIQ:
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
#include <mode/machine.h>
|
||||
#include <arch/machine/registerset.h>
|
||||
|
||||
void debug_init(void) VISIBLE;
|
||||
|
|
@ -186,18 +185,18 @@ seL4_Fault_t handleUserLevelDebugException(word_t fault_vaddr);
|
|||
* bitfield.
|
||||
*/
|
||||
static inline void
|
||||
setBreakpointUsedFlag(arch_tcb_t *uds, uint16_t bp_num)
|
||||
setBreakpointUsedFlag(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
if (uds != NULL) {
|
||||
uds->tcbContext.breakpointState.used_breakpoints_bf |= BIT(bp_num);
|
||||
if (t != NULL) {
|
||||
t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf |= BIT(bp_num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
unsetBreakpointUsedFlag(arch_tcb_t *uds, uint16_t bp_num)
|
||||
unsetBreakpointUsedFlag(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
if (uds != NULL) {
|
||||
uds->tcbContext.breakpointState.used_breakpoints_bf &= ~BIT(bp_num);
|
||||
if (t != NULL) {
|
||||
t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf &= ~BIT(bp_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <assert.h>
|
||||
#include <util.h>
|
||||
#include <arch/types.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <plat/api/constants.h>
|
||||
|
||||
/* These are the indices of the registers in the
|
||||
|
|
@ -149,7 +150,7 @@ extern const register_t msgRegisters[];
|
|||
extern const register_t frameRegisters[];
|
||||
extern const register_t gpRegisters[];
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
typedef struct debug_register_pair {
|
||||
word_t cr, vr;
|
||||
} debug_register_pair_t;
|
||||
|
|
@ -163,8 +164,6 @@ typedef struct user_breakpoint_state {
|
|||
bool_t single_step_enabled;
|
||||
uint16_t single_step_hw_bp_num;
|
||||
} user_breakpoint_state_t;
|
||||
|
||||
void Arch_initBreakpointContext(user_breakpoint_state_t *context);
|
||||
#endif
|
||||
|
||||
/* ARM user-code context: size = 72 bytes
|
||||
|
|
@ -177,7 +176,7 @@ void Arch_initBreakpointContext(user_breakpoint_state_t *context);
|
|||
*/
|
||||
struct user_context {
|
||||
word_t registers[n_contextRegisters];
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
user_breakpoint_state_t breakpointState;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -188,12 +187,15 @@ compile_assert(registers_are_first_member_of_user_context,
|
|||
__builtin_offsetof(user_context_t, registers) == 0)
|
||||
#endif
|
||||
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
void Arch_initBreakpointContext(user_context_t *context);
|
||||
#endif
|
||||
|
||||
static inline void Arch_initContext(user_context_t* context)
|
||||
{
|
||||
context->registers[CPSR] = CPSR_USER;
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
Arch_initBreakpointContext(&context->breakpointState);
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
Arch_initBreakpointContext(context);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,12 +86,12 @@ static inline void invalidateHypTLB(void)
|
|||
|
||||
static inline paddr_t PURE addressTranslateS1CPR(vptr_t vaddr)
|
||||
{
|
||||
uint64_t ipa;
|
||||
uint32_t ipa0, ipa1;
|
||||
asm volatile ("mcr p15, 0, %0, c7, c8, 0" :: "r"(vaddr));
|
||||
isb();
|
||||
asm volatile ("mrrc p15, 0, %Q0, %R0, c7" : "=r"(ipa));
|
||||
asm volatile ("mrrc p15, 0, %0, %1, c7" : "=r"(ipa0), "=r"(ipa1));
|
||||
|
||||
return ipa;
|
||||
return ipa0;
|
||||
}
|
||||
|
||||
static inline word_t PURE getHSR(void)
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ typedef struct arch_tcb {
|
|||
user_context_t tcbContext;
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/* Pointer to associated VCPU. NULL if not associated.
|
||||
* tcb->vcpu->tcb == tcb. */
|
||||
struct vcpu* vcpu;
|
||||
* tcb->tcbVCPU->vcpuTCB == tcb. */
|
||||
struct vcpu* tcbVCPU;
|
||||
#endif
|
||||
} arch_tcb_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
* We cannot allow async aborts in the verified kernel, but they are useful
|
||||
* in identifying invalid memory access bugs so we enable them in debug mode.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
#define PSTATE_EXTRA_FLAGS 0
|
||||
#else
|
||||
#define PSTATE_EXTRA_FLAGS PMODE_SERROR
|
||||
|
|
|
|||
|
|
@ -13,18 +13,22 @@
|
|||
#define __ARCH_MACHINE_DEBUG_H
|
||||
|
||||
#include <util.h>
|
||||
#include <api/types.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <plat/api/constants.h>
|
||||
#include <armv/debug.h>
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
void restore_user_debug_context(tcb_t *target_thread);
|
||||
void Arch_debugAssociateVCPUTCB(tcb_t *t);
|
||||
void Arch_debugDissociateVCPUTCB(tcb_t *t);
|
||||
void saveAllBreakpointState(arch_tcb_t *at);
|
||||
void saveAllBreakpointState(tcb_t *t);
|
||||
void loadAllDisabledBreakpointState(void);
|
||||
#endif
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
void Arch_debugAssociateVCPUTCB(tcb_t *t);
|
||||
void Arch_debugDissociateVCPUTCB(tcb_t *t);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HARDWARE_DEBUG_API) && defined(CONFIG_ARM_HYPERVISOR_SUPPORT)
|
||||
#ifdef ARM_HYP_TRAP_CP14
|
||||
/* Those of these that trap NS accesses trap all NS accesses; we can't cause the
|
||||
* processor to only trap NS-PL0 or NS-PL1, but if we want to trap the accesses,
|
||||
* we get both (PL0 and PL1) non-secure modes' accesses.
|
||||
|
|
@ -38,21 +42,6 @@ void loadAllDisabledBreakpointState(void);
|
|||
#define HDCR_PERFMON_TPM_SHIFT (6) /* Trap NS PM accesses */
|
||||
#define HDCR_PERFMON_TPMCR_SHIFT (5) /* Trap NS PMCR reg access */
|
||||
|
||||
static inline void
|
||||
initHDCR(void)
|
||||
{
|
||||
word_t hdcr;
|
||||
|
||||
MRC(ARM_CP15_HDCR, hdcr);
|
||||
/* By default at boot, we SET HDCR.TDE to catch and redirect native threads'
|
||||
* PL0 debug exceptions.
|
||||
*
|
||||
* Subsequently on calls to vcpu_enable/disable, we will modify HDCR.TDE
|
||||
* as needed.
|
||||
*/
|
||||
MCR(ARM_CP15_HDCR, hdcr | BIT(HDCR_DEBUG_TDE_SHIFT));
|
||||
}
|
||||
|
||||
/** When running seL4 as a hypervisor, if we're building with support for the
|
||||
* hardware debug API, we have a case of indirection that we need to handle.
|
||||
*
|
||||
|
|
@ -87,15 +76,39 @@ setHDCRTrapDebugExceptionState(bool_t enable_trapping)
|
|||
/* Trap and redirect debug faults that occur in PL0 native threads by
|
||||
* setting HDCR.TDE (trap debug exceptions).
|
||||
*/
|
||||
hdcr |= BIT(HDCR_DEBUG_TDE_SHIFT);
|
||||
hdcr |= (BIT(HDCR_DEBUG_TDE_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDA_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDRA_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDOSA_SHIFT));
|
||||
} else {
|
||||
/* Let the PL1 Guest VM handle debug events on its own */
|
||||
hdcr &= ~BIT(HDCR_DEBUG_TDE_SHIFT);
|
||||
hdcr &= ~(BIT(HDCR_DEBUG_TDE_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDA_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDRA_SHIFT)
|
||||
| BIT(HDCR_DEBUG_TDOSA_SHIFT));
|
||||
}
|
||||
|
||||
MCR(ARM_CP15_HDCR, hdcr);
|
||||
}
|
||||
#endif /* defined(CONFIG_HARDWARE_DEBUG_API) && defined(CONFIG_ARM_HYPERVISOR_SUPPORT) */
|
||||
|
||||
static inline void
|
||||
initHDCR(void)
|
||||
{
|
||||
/* By default at boot, we SET HDCR.TDE to catch and redirect native threads'
|
||||
* PL0 debug exceptions.
|
||||
*
|
||||
* Unfortunately, this is complicated a bit by ARM's strange requirement that
|
||||
* if you set HDCR.TDE, you must also set TDA, TDOSA, and TDRA:
|
||||
* ARMv7 archref manual: section B1.8.9:
|
||||
* "When HDCR.TDE is set to 1, the HDCR.{TDRA, TDOSA, TDA} bits must all
|
||||
* be set to 1, otherwise behavior is UNPREDICTABLE"
|
||||
*
|
||||
* Subsequently on calls to vcpu_enable/disable, we will modify HDCR.TDE
|
||||
* as needed.
|
||||
*/
|
||||
setHDCRTrapDebugExceptionState(true);
|
||||
}
|
||||
#endif /* ARM_HYP_TRAP_CP14 */
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
|
||||
|
|
@ -117,7 +130,7 @@ getTypeFromBpNum(uint16_t bp_num)
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeConfigureSingleStepping(arch_tcb_t *at,
|
||||
Arch_decodeConfigureSingleStepping(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t n_instr,
|
||||
bool_t is_reply)
|
||||
|
|
@ -132,7 +145,7 @@ Arch_decodeConfigureSingleStepping(arch_tcb_t *at,
|
|||
* configured bp_num. Of course, this assumes that a register had
|
||||
* already previously been configured for single-stepping.
|
||||
*/
|
||||
if (!at->tcbContext.breakpointState.single_step_enabled) {
|
||||
if (!t->tcbArch.tcbContext.breakpointState.single_step_enabled) {
|
||||
userError("Debug: Single-step reply when single-stepping not "
|
||||
"enabled.");
|
||||
ret.type = seL4_IllegalOperation;
|
||||
|
|
@ -140,7 +153,7 @@ Arch_decodeConfigureSingleStepping(arch_tcb_t *at,
|
|||
}
|
||||
|
||||
type = seL4_InstructionBreakpoint;
|
||||
bp_num = at->tcbContext.breakpointState.single_step_hw_bp_num;
|
||||
bp_num = t->tcbArch.tcbContext.breakpointState.single_step_hw_bp_num;
|
||||
} else {
|
||||
type = getTypeFromBpNum(bp_num);
|
||||
bp_num = convertBpNumToArch(bp_num);
|
||||
|
|
@ -154,8 +167,8 @@ Arch_decodeConfigureSingleStepping(arch_tcb_t *at,
|
|||
ret.invalidArgumentNumber = 0;
|
||||
return ret;
|
||||
}
|
||||
if (at->tcbContext.breakpointState.single_step_enabled == true) {
|
||||
if (bp_num != at->tcbContext.breakpointState.single_step_hw_bp_num) {
|
||||
if (t->tcbArch.tcbContext.breakpointState.single_step_enabled == true) {
|
||||
if (bp_num != t->tcbArch.tcbContext.breakpointState.single_step_hw_bp_num) {
|
||||
/* Can't configure more than one register for stepping. */
|
||||
userError("Debug: Only one register can be configured for "
|
||||
"single-stepping at a time.");
|
||||
|
|
@ -171,7 +184,7 @@ Arch_decodeConfigureSingleStepping(arch_tcb_t *at,
|
|||
bool_t byte8WatchpointsSupported(void);
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeSetBreakpoint(arch_tcb_t *uds,
|
||||
Arch_decodeSetBreakpoint(tcb_t *t,
|
||||
uint16_t bp_num, word_t vaddr, word_t type,
|
||||
word_t size, word_t rw)
|
||||
{
|
||||
|
|
@ -216,7 +229,7 @@ Arch_decodeSetBreakpoint(arch_tcb_t *uds,
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeGetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
Arch_decodeGetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
syscall_error_t ret = {
|
||||
.type = seL4_NoError
|
||||
|
|
@ -231,7 +244,7 @@ Arch_decodeGetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeUnsetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
Arch_decodeUnsetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
syscall_error_t ret = {
|
||||
.type = seL4_NoError
|
||||
|
|
@ -249,7 +262,7 @@ Arch_decodeUnsetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
type = getTypeFromBpNum(bp_num);
|
||||
bp_num = convertBpNumToArch(bp_num);
|
||||
|
||||
bcr.words[0] = uds->tcbContext.breakpointState.breakpoint[bp_num].cr;
|
||||
bcr.words[0] = t->tcbArch.tcbContext.breakpointState.breakpoint[bp_num].cr;
|
||||
if (type == seL4_InstructionBreakpoint) {
|
||||
if (Arch_breakpointIsMismatch(bcr) == true && dbg_bcr_get_enabled(bcr)) {
|
||||
userError("Rejecting call to unsetBreakpoint on breakpoint configured "
|
||||
|
|
|
|||
57
include/arch/arm/arch/machine/debug_conf.h
Normal file
57
include/arch/arm/arch/machine/debug_conf.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2017, Data61
|
||||
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
||||
* ABN 41 687 119 230.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(DATA61_GPL)
|
||||
*/
|
||||
|
||||
#ifndef ARCH_MACHINE_DEBUG_CONF_H
|
||||
#define ARCH_MACHINE_DEBUG_CONF_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* These are used to force specific outcomes for various combinations of
|
||||
* settings for the state of CONFIG_ARM_HYPERVISOR_SUPPORT,
|
||||
* CONFIG_ARM_HYP_ENABLE_VCPU_CP14_SAVE_AND_RESTORE and
|
||||
* CONFIG_HARDWARE_DEBUG_API.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
/* With the debug-API on, the ARM-hyp kernel will enable HDCR CP14-related
|
||||
* traps whenever it is running a native thread and not a VCPU thread.
|
||||
*/
|
||||
#define ARM_HYP_TRAP_CP14_IN_NATIVE_USER_THREADS
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_HYP_ENABLE_VCPU_CP14_SAVE_AND_RESTORE
|
||||
/* When this is enabled, the ARM-hyp kernel will enable
|
||||
* CP14 save and restore whenever it is running a VCPU thread. When it's
|
||||
* disabled, the hyp kernel will intercept accesses to the CP14
|
||||
* coprocessor and deliver them as fault messages to the VCPU's fault
|
||||
* handler.
|
||||
*/
|
||||
#define ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
#else
|
||||
#define ARM_HYP_TRAP_CP14_IN_VCPU_THREADS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
/* If HARDWARE_DEBUG_API is set, then we must save/retore native threads. */
|
||||
#define ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS
|
||||
#endif
|
||||
|
||||
#if defined(ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS) || defined(ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS)
|
||||
#define ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
#endif
|
||||
#if defined(ARM_HYP_TRAP_CP14_IN_NATIVE_USER_THREADS) || defined(ARM_HYP_TRAP_CP14_IN_VCPU_THREADS)
|
||||
#define ARM_HYP_TRAP_CP14
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_MACHINE_DEBUG_CONF_H */
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <model/statedata.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <mode/machine/registerset.h>
|
||||
|
||||
NODE_STATE_BEGIN(archNodeState)
|
||||
/* TODO: add ARM-dependent fields here */
|
||||
|
|
@ -21,6 +23,10 @@ NODE_STATE_BEGIN(archNodeState)
|
|||
NODE_STATE_DECLARE(word_t, ipiReschedulePending);
|
||||
NODE_STATE_END(archNodeState);
|
||||
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
extern user_breakpoint_state_t armKSNullBreakpointState VISIBLE;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
extern pdeS1_t armHSGlobalPGD[BIT(PGD_INDEX_BITS)] VISIBLE;
|
||||
extern pdeS1_t armHSGlobalPD[BIT(PT_INDEX_BITS)] VISIBLE;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct gicVCpuIface {
|
|||
|
||||
struct vcpu {
|
||||
/* TCB associated with this VCPU. */
|
||||
struct tcb *tcb;
|
||||
struct tcb *vcpuTCB;
|
||||
struct cpXRegs cpx;
|
||||
struct gicVCpuIface vgic;
|
||||
/* Banked registers */
|
||||
|
|
@ -82,7 +82,7 @@ exception_t decodeVCPUSetTCB(cap_t cap, extra_caps_t extraCaps);
|
|||
|
||||
exception_t invokeVCPUWriteReg(vcpu_t *vcpu, uint32_t field, uint32_t value);
|
||||
exception_t invokeVCPUReadReg(vcpu_t *vcpu, uint32_t field);
|
||||
exception_t invokeVCPUInjectIRQ(vcpu_t *vcpu, int index, virq_t virq);
|
||||
exception_t invokeVCPUInjectIRQ(vcpu_t *vcpu, unsigned long index, virq_t virq);
|
||||
exception_t invokeVCPUSetTCB(vcpu_t *vcpu, tcb_t *tcb);
|
||||
|
||||
#else /* end of CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
|
|
|
|||
|
|
@ -82,18 +82,6 @@ static inline void invalidateLocalTranslationAll(void)
|
|||
invalidateLocalPageStructureCache();
|
||||
}
|
||||
|
||||
/* Flushes entire CPU Cache */
|
||||
static inline void ia32_wbinvd(void)
|
||||
{
|
||||
asm volatile("wbinvd" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
arch_clean_invalidate_caches(void)
|
||||
{
|
||||
ia32_wbinvd();
|
||||
}
|
||||
|
||||
static inline rdmsr_safe_result_t x86_rdmsr_safe(const uint32_t reg)
|
||||
{
|
||||
uint32_t low;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ writeDrReg(uint8_t reg, word_t val)
|
|||
*@param source The memory block from which to load the register values.
|
||||
*/
|
||||
static inline void
|
||||
loadBreakpointState(arch_tcb_t *source)
|
||||
loadBreakpointState(tcb_t *source)
|
||||
{
|
||||
/* Order does matter when restoring the registers: we want to restore the
|
||||
* breakpoint control register (DR7) last since it is what "activates" the
|
||||
|
|
@ -132,7 +132,7 @@ loadBreakpointState(arch_tcb_t *source)
|
|||
"movl (%%edx), %%ecx \n\t"
|
||||
"movl %%ecx, %%dr7 \n\t"
|
||||
:
|
||||
: "r" (source->tcbContext.breakpointState.dr)
|
||||
: "r" (source->tcbArch.tcbContext.breakpointState.dr)
|
||||
: "edx", "ecx");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ writeDrReg(uint8_t reg, word_t val)
|
|||
*@param source The memory block from which to load the register values.
|
||||
*/
|
||||
static inline void
|
||||
loadBreakpointState(arch_tcb_t *source)
|
||||
loadBreakpointState(tcb_t *source)
|
||||
{
|
||||
/* Order does matter when restoring the registers: we want to restore the
|
||||
* breakpoint control register (DR7) last since it is what "activates" the
|
||||
|
|
@ -132,7 +132,7 @@ loadBreakpointState(arch_tcb_t *source)
|
|||
"movq (%%rdx), %%rcx \n\t"
|
||||
"movq %%rcx, %%dr7 \n\t"
|
||||
:
|
||||
: "r" (source->tcbContext.breakpointState.dr)
|
||||
: "r" (source->tcbArch.tcbContext.breakpointState.dr)
|
||||
: "rdx", "rcx");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,14 +48,12 @@ typedef struct multiboot_info {
|
|||
uint32_t mmap_length;
|
||||
uint32_t mmap_addr;
|
||||
uint32_t drives_length;
|
||||
void *drives_addr;
|
||||
void *config_table;
|
||||
void *boot_loader_name;
|
||||
void *apm_table;
|
||||
/* The bootinfo types are declared to be precisely the VBE layout, so
|
||||
* we can reuse those types here */
|
||||
seL4_VBEInfoBlock_t *vbe_control_info;
|
||||
seL4_VBEModeInfoBlock_t *vbe_mode_info;
|
||||
uint32_t drives_addr;
|
||||
uint32_t config_table;
|
||||
uint32_t boot_loader_name;
|
||||
uint32_t apm_table;
|
||||
uint32_t vbe_control_info;
|
||||
uint32_t vbe_mode_info;
|
||||
uint16_t vbe_mode;
|
||||
uint16_t vbe_interface_seg;
|
||||
uint16_t vbe_interface_off;
|
||||
|
|
|
|||
|
|
@ -58,18 +58,18 @@ exception_t handleUserLevelDebugException(int int_vector);
|
|||
* bitfield.
|
||||
*/
|
||||
static inline void
|
||||
setBreakpointUsedFlag(arch_tcb_t *uds, uint16_t bp_num)
|
||||
setBreakpointUsedFlag(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
if (uds != NULL) {
|
||||
uds->tcbContext.breakpointState.used_breakpoints_bf |= BIT(bp_num);
|
||||
if (t != NULL) {
|
||||
t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf |= BIT(bp_num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
unsetBreakpointUsedFlag(arch_tcb_t *uds, uint16_t bp_num)
|
||||
unsetBreakpointUsedFlag(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
if (uds != NULL) {
|
||||
uds->tcbContext.breakpointState.used_breakpoints_bf &= ~BIT(bp_num);
|
||||
if (t != NULL) {
|
||||
t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf &= ~BIT(bp_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,11 +82,11 @@ unsetBreakpointUsedFlag(arch_tcb_t *uds, uint16_t bp_num)
|
|||
* setting the disable bits.
|
||||
*/
|
||||
static void
|
||||
loadAllDisabledBreakpointState(arch_tcb_t *at)
|
||||
loadAllDisabledBreakpointState(tcb_t *t)
|
||||
{
|
||||
word_t disable_value;
|
||||
|
||||
disable_value = at->tcbContext.breakpointState.dr[5];
|
||||
disable_value = t->tcbArch.tcbContext.breakpointState.dr[5];
|
||||
disable_value &= ~(X86_DEBUG_BP0_ENABLE_BIT | X86_DEBUG_BP1_ENABLE_BIT
|
||||
| X86_DEBUG_BP2_ENABLE_BIT | X86_DEBUG_BP3_ENABLE_BIT);
|
||||
|
||||
|
|
@ -98,9 +98,9 @@ restore_user_debug_context(tcb_t *target_thread)
|
|||
{
|
||||
arch_tcb_t *uds = &target_thread->tcbArch;
|
||||
if (uds->tcbContext.breakpointState.used_breakpoints_bf != 0) {
|
||||
loadBreakpointState(uds);
|
||||
loadBreakpointState(target_thread);
|
||||
} else {
|
||||
loadAllDisabledBreakpointState(uds);
|
||||
loadAllDisabledBreakpointState(target_thread);
|
||||
}
|
||||
|
||||
/* If single-stepping was enabled, we need to re-set the TF flag as well. */
|
||||
|
|
@ -126,7 +126,7 @@ restore_user_debug_context(tcb_t *target_thread)
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeConfigureSingleStepping(arch_tcb_t *uc,
|
||||
Arch_decodeConfigureSingleStepping(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t n_instr,
|
||||
bool_t is_reply)
|
||||
|
|
@ -140,7 +140,7 @@ Arch_decodeConfigureSingleStepping(arch_tcb_t *uc,
|
|||
bool_t byte8BreakpointsSupported(void);
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeSetBreakpoint(arch_tcb_t *uds,
|
||||
Arch_decodeSetBreakpoint(tcb_t *t,
|
||||
uint16_t bp_num, word_t vaddr, word_t types,
|
||||
word_t size, word_t rw)
|
||||
{
|
||||
|
|
@ -165,7 +165,7 @@ Arch_decodeSetBreakpoint(arch_tcb_t *uds,
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeGetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
Arch_decodeGetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
syscall_error_t ret = {
|
||||
.type = seL4_NoError
|
||||
|
|
@ -181,7 +181,7 @@ Arch_decodeGetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
}
|
||||
|
||||
static inline syscall_error_t
|
||||
Arch_decodeUnsetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
Arch_decodeUnsetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
syscall_error_t ret = {
|
||||
.type = seL4_NoError
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ static inline void disableFpu(void)
|
|||
#ifdef CONFIG_VTX
|
||||
static inline bool_t vcpuThreadUsingFPU(tcb_t *thread)
|
||||
{
|
||||
return thread->tcbArch.vcpu && &thread->tcbArch.vcpu->fpuState == NODE_STATE(ksActiveFPUState);
|
||||
return thread->tcbArch.tcbVCPU && &thread->tcbArch.tcbVCPU->fpuState == NODE_STATE(ksActiveFPUState);
|
||||
}
|
||||
#endif /* CONFIG_VTX */
|
||||
#endif /* __ARCH_MACHINE_FPU_H */
|
||||
|
|
|
|||
|
|
@ -97,4 +97,16 @@ void flushCacheRange(void* vaddr, uint32_t size_bits);
|
|||
/* Disables a variety of prefetchers */
|
||||
bool_t disablePrefetchers(void);
|
||||
|
||||
/* Flushes entire CPU Cache */
|
||||
static inline void x86_wbinvd(void)
|
||||
{
|
||||
asm volatile("wbinvd" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
arch_clean_invalidate_caches(void)
|
||||
{
|
||||
x86_wbinvd();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ typedef struct arch_tcb {
|
|||
user_context_t tcbContext;
|
||||
#ifdef CONFIG_VTX
|
||||
/* Pointer to associated VCPU. NULL if not associated.
|
||||
* tcb->vcpu->tcb == tcb. */
|
||||
struct vcpu *vcpu;
|
||||
* tcb->tcbVCPU->vcpuTCB == tcb. */
|
||||
struct vcpu *tcbVCPU;
|
||||
#endif /* CONFIG_VTX */
|
||||
} arch_tcb_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ struct vcpu {
|
|||
#endif
|
||||
|
||||
/* TCB associated with this VCPU. */
|
||||
struct tcb *tcb;
|
||||
struct tcb *vcpuTCB;
|
||||
bool_t launched;
|
||||
|
||||
/* Currently assigned VPID */
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <util.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
void _fail(
|
||||
const char* str,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <model/statedata.h>
|
||||
#include <mode/machine.h>
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#define TRACK_KERNEL_ENTRIES 1
|
||||
extern kernel_entry_t ksKernelEntry;
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ void Arch_breakpointThreadDelete(tcb_t *thread);
|
|||
* context-saving memory block, and this function will write to that
|
||||
* context-saving memory block instead.
|
||||
*/
|
||||
void setBreakpoint(arch_tcb_t *uds,
|
||||
void setBreakpoint(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t vaddr, word_t type, word_t size, word_t rw);
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ typedef struct getBreakpointRet {
|
|||
bool_t is_enabled;
|
||||
} getBreakpoint_t;
|
||||
|
||||
getBreakpoint_t getBreakpoint(arch_tcb_t *uds, uint16_t bp_num);
|
||||
getBreakpoint_t getBreakpoint(tcb_t *t, uint16_t bp_num);
|
||||
|
||||
/** Clears a breakpoint's configuration and disables it.
|
||||
* @param bp_num Hardware breakpoint ID. Usually an integer from 0..N.
|
||||
|
|
@ -71,15 +71,15 @@ getBreakpoint_t getBreakpoint(arch_tcb_t *uds, uint16_t bp_num);
|
|||
* context-saving memory block, and this function will write to that
|
||||
* context-saving memory block instead.
|
||||
*/
|
||||
void unsetBreakpoint(arch_tcb_t *uds, uint16_t bp_num);
|
||||
void unsetBreakpoint(tcb_t *t, uint16_t bp_num);
|
||||
|
||||
bool_t configureSingleStepping(arch_tcb_t *uc,
|
||||
bool_t configureSingleStepping(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t n_instr,
|
||||
bool_t is_reply);
|
||||
|
||||
static inline bool_t
|
||||
singleStepFaultCounterReady(arch_tcb_t *uc)
|
||||
singleStepFaultCounterReady(tcb_t *t)
|
||||
{
|
||||
/* For a single-step exception, the user may have specified a certain
|
||||
* number of instructions to skip over before the next stop-point, so
|
||||
|
|
@ -88,10 +88,10 @@ singleStepFaultCounterReady(arch_tcb_t *uc)
|
|||
* We will check the counter's value when deciding whether or not to
|
||||
* actually send a fault message to userspace.
|
||||
*/
|
||||
if (uc->tcbContext.breakpointState.n_instructions > 0) {
|
||||
uc->tcbContext.breakpointState.n_instructions--;
|
||||
if (t->tcbArch.tcbContext.breakpointState.n_instructions > 0) {
|
||||
t->tcbArch.tcbContext.breakpointState.n_instructions--;
|
||||
}
|
||||
return uc->tcbContext.breakpointState.n_instructions == 0;
|
||||
return t->tcbArch.tcbContext.breakpointState.n_instructions == 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARDWARE_DEBUG_API */
|
||||
|
|
|
|||
|
|
@ -138,8 +138,7 @@ block notification {
|
|||
field_high ntfnQueue_head 49
|
||||
|
||||
field_high ntfnQueue_tail 49
|
||||
padding 12
|
||||
field bound 1
|
||||
padding 13
|
||||
field state 2
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ enum IRQConstants {
|
|||
INTERRUPT_GPU = 189,
|
||||
INTERRUPT_GPU_NONSTALL = 190,
|
||||
ARDPAUX = 191,
|
||||
maxIRQ = 192
|
||||
maxIRQ = 191
|
||||
} platform_interrupt_t;
|
||||
|
||||
#define IRQ_CNODE_BITS 12
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ CHANGED_PATH := ${SOURCE_DIR}/tools/changed.sh
|
|||
|
||||
ifeq (${PYTHON},)
|
||||
PYTHON = python
|
||||
# Suppress python bytecode (pyc) files for build thread safety
|
||||
export PYTHONDONTWRITEBYTECODE = true
|
||||
endif
|
||||
|
||||
ifeq (${KERNEL_32}, y)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#define LIBSEL4_INLINE static inline
|
||||
#define LIBSEL4_INLINE_FUNC static inline
|
||||
|
||||
#elif CONFIG_LIB_SEL4_PUBLIC_SYMBOLS
|
||||
#elif defined(CONFIG_LIB_SEL4_PUBLIC_SYMBOLS)
|
||||
#define LIBSEL4_INLINE __attribute__((unused)) __attribute__((weak))
|
||||
#define LIBSEL4_INLINE_FUNC __attribute__((unused)) __attribute__((weak))
|
||||
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ seL4_BenchmarkSetLogBuffer(seL4_Word frame_cptr)
|
|||
seL4_Word unused3 = 0;
|
||||
seL4_Word unused4 = 0;
|
||||
|
||||
x64_sys_send_recv(seL4_SysBenchmarkSetLogBuffer, frame_cptr, &frame_cptr, 0, &unused0, &unused1, &unused2, &unused4, &unused4);
|
||||
x64_sys_send_recv(seL4_SysBenchmarkSetLogBuffer, frame_cptr, &frame_cptr, 0, &unused0, &unused1, &unused2, &unused3, &unused4);
|
||||
|
||||
return (seL4_Error) frame_cptr;
|
||||
}
|
||||
|
|
@ -454,6 +454,13 @@ seL4_BenchmarkNullSyscall(void)
|
|||
asm volatile("" ::: "memory");
|
||||
}
|
||||
|
||||
LIBSEL4_INLINE_FUNC void
|
||||
seL4_BenchmarkFlushCaches(void)
|
||||
{
|
||||
x64_sys_null(seL4_SysBenchmarkFlushCaches);
|
||||
asm volatile("" ::: "memory");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
LIBSEL4_INLINE_FUNC void
|
||||
seL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr)
|
||||
|
|
|
|||
|
|
@ -18,13 +18,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex A7 manual, table 10-2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a8 manual, table 12-11 */
|
||||
#define seL4_NumHWBreakpoints (8)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (2)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a15 manual, section 10.2.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex A57 manual, section 10.6.1 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a9 manual, section 10.1.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a15 manual, section 10.2.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex A57 manual, section 10.6.1 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* ARM1136-JF-S manual, table 13-3 */
|
||||
#define seL4_NumHWBreakpoints (8)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (2)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a9 manual, section 10.1.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex A7 manual, table 10-2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a8 manual, table 12-11 */
|
||||
#define seL4_NumHWBreakpoints (8)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (2)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a15 manual, section 10.2.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,10 @@
|
|||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
/* Cortex a9 manual, section 10.1.2 */
|
||||
#define seL4_NumHWBreakpoints (10)
|
||||
#define seL4_NumExclusiveBreakpoints (6)
|
||||
#define seL4_NumExclusiveWatchpoints (4)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#define seL4_FirstWatchpoint (6)
|
||||
#define seL4_NumDualFunctionMonitors (0)
|
||||
|
|
|
|||
|
|
@ -164,12 +164,12 @@ handleFaultReply(tcb_t *receiver, tcb_t *sender)
|
|||
|
||||
syscall_error_t res;
|
||||
|
||||
res = Arch_decodeConfigureSingleStepping(&receiver->tcbArch, 0, n_instrs, true);
|
||||
res = Arch_decodeConfigureSingleStepping(receiver, 0, n_instrs, true);
|
||||
if (res.type != seL4_NoError) {
|
||||
return false;
|
||||
};
|
||||
|
||||
configureSingleStepping(&receiver->tcbArch, 0, n_instrs, true);
|
||||
configureSingleStepping(receiver, 0, n_instrs, true);
|
||||
|
||||
/* Replying will always resume the thread: the only variant behaviour
|
||||
* is whether or not the thread will be resumed with stepping still
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include <kernel/traps.h>
|
||||
#include <arch/machine.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
#include <arch/machine/capdl.h>
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <model/statedata.h>
|
||||
#include <arch/fastpath/fastpath.h>
|
||||
#include <arch/kernel/traps.h>
|
||||
#include <arch/machine/debug.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <api/syscall.h>
|
||||
#include <arch/linker.h>
|
||||
|
||||
|
|
@ -27,7 +29,7 @@ void VISIBLE NORETURN restore_user_context(void)
|
|||
|
||||
c_exit_hook();
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
#ifdef ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS
|
||||
restore_user_debug_context(NODE_STATE(ksCurThread));
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -839,31 +839,32 @@ resolveVAddr(pde_t *pd, vptr_t vaddr)
|
|||
case pde_pde_coarse: {
|
||||
pte_t *pt = ptrFromPAddr(pde_pde_coarse_ptr_get_address(pde));
|
||||
pte_t *pte = lookupPTSlot_nofail(pt, vaddr);
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
switch (pte_ptr_get_pteType(pte)) {
|
||||
case pte_pte_small:
|
||||
ret.frameBase = pte_pte_small_ptr_get_address(pte);
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (pte_pte_small_ptr_get_contiguous_hint(pte)) {
|
||||
/* Entries are represented as 16 contiguous small frames. We need to mask
|
||||
to get the large frame base */
|
||||
ret.frameBase &= ~MASK(pageBitsForSize(ARMLargePage));
|
||||
ret.frameSize = ARMLargePage;
|
||||
} else {
|
||||
ret.frameSize = ARMSmallPage;
|
||||
}
|
||||
#else
|
||||
ret.frameSize = ARMSmallPage;
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case pte_pte_large:
|
||||
ret.frameBase = pte_pte_large_ptr_get_address(pte);
|
||||
ret.frameSize = ARMLargePage;
|
||||
return ret;
|
||||
|
||||
case pte_pte_small:
|
||||
ret.frameBase = pte_pte_small_ptr_get_address(pte);
|
||||
ret.frameSize = ARMSmallPage;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
if (pte_pte_small_ptr_get_contiguous_hint(pte)) {
|
||||
ret.frameBase = pte_pte_small_ptr_get_address(pte);
|
||||
/* Entries are represented as 16 contiguous small frames. We need to mask to get the large frame base */
|
||||
ret.frameBase &= ~MASK(pageBitsForSize(ARMLargePage));
|
||||
ret.frameSize = ARMLargePage;
|
||||
return ret;
|
||||
} else {
|
||||
ret.frameBase = pte_pte_small_ptr_get_address(pte);
|
||||
ret.frameSize = ARMSmallPage;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1116,7 +1117,7 @@ setVMRoot(tcb_t *tcb)
|
|||
|
||||
armv_contextSwitch(pd, asid);
|
||||
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
|
||||
vcpu_switch(tcb->tcbArch.vcpu);
|
||||
vcpu_switch(tcb->tcbArch.tcbVCPU);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1364,7 +1365,7 @@ handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType)
|
|||
current_fault = handleUserLevelDebugException(pc);
|
||||
|
||||
if (seL4_Fault_DebugException_get_exceptionReason(current_fault) == seL4_SingleStep
|
||||
&& !singleStepFaultCounterReady(&thread->tcbArch)) {
|
||||
&& !singleStepFaultCounterReady(thread)) {
|
||||
/* Don't send a fault message to the thread yet if we were asked
|
||||
* to step through N instructions and the counter isn't depleted
|
||||
* yet.
|
||||
|
|
@ -1751,13 +1752,12 @@ createSafeMappingEntries_PTE
|
|||
ret.pte_entries.base = lu_ret.ptSlot;
|
||||
|
||||
for (i = 0; i < PAGES_PER_LARGE_PAGE; i++) {
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (unlikely(pte_get_pteType(ret.pte_entries.base[i]) ==
|
||||
pte_pte_small)) {
|
||||
#else
|
||||
if (unlikely(pte_ptr_get_pteType(lu_ret.ptSlot) == pte_pte_small
|
||||
&& !pte_pte_small_get_contiguous_hint(ret.pte_entries.base[i]))) {
|
||||
pte_pte_small)
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
&& !pte_pte_small_get_contiguous_hint(ret.pte_entries.base[i])
|
||||
#endif
|
||||
) {
|
||||
current_syscall_error.type =
|
||||
seL4_DeleteFirst;
|
||||
|
||||
|
|
@ -1984,7 +1984,13 @@ performPageInvocationMapPTE(asid_t asid, cap_t cap, cte_t *ctSlot, pte_t pte,
|
|||
j = pte_entries.length;
|
||||
/** GHOSTUPD: "(\<acute>j <= 16, id)" */
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
word_t base_address = pte_pte_small_get_address(pte);
|
||||
#endif
|
||||
for (i = 0; i < pte_entries.length; i++) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
pte = pte_pte_small_set_address(pte, base_address + i * BIT(pageBitsForSize(ARMSmallPage)));
|
||||
#endif
|
||||
pte_entries.base[i] = pte;
|
||||
}
|
||||
cleanCacheRange_PoU((word_t)pte_entries.base,
|
||||
|
|
@ -2013,7 +2019,13 @@ performPageInvocationMapPDE(asid_t asid, cap_t cap, cte_t *ctSlot, pde_t pde,
|
|||
j = pde_entries.length;
|
||||
/** GHOSTUPD: "(\<acute>j <= 16, id)" */
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
word_t base_address = pde_pde_section_get_address(pde);
|
||||
#endif
|
||||
for (i = 0; i < pde_entries.length; i++) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
pde = pde_pde_section_set_address(pde, base_address + i * BIT(pageBitsForSize(ARMSection)));
|
||||
#endif
|
||||
pde_entries.base[i] = pde;
|
||||
}
|
||||
cleanCacheRange_PoU((word_t)pde_entries.base,
|
||||
|
|
@ -2039,11 +2051,14 @@ performPageInvocationRemapPTE(asid_t asid, pte_t pte, pte_range_t pte_entries)
|
|||
j = pte_entries.length;
|
||||
/** GHOSTUPD: "(\<acute>j <= 16, id)" */
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
word_t base_address = pte_pte_small_get_address(pte);
|
||||
#endif
|
||||
for (i = 0; i < pte_entries.length; i++) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
pte = pte_pte_small_set_address(pte, base_address + i * BIT(pageBitsForSize(ARMSmallPage)));
|
||||
#endif
|
||||
pte_entries.base[i] = pte;
|
||||
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
|
||||
pte.words[0] += BIT(pageBitsForSize(ARMLargePage));
|
||||
}
|
||||
}
|
||||
cleanCacheRange_PoU((word_t)pte_entries.base,
|
||||
LAST_BYTE_PTE(pte_entries.base, pte_entries.length),
|
||||
|
|
@ -2068,11 +2083,14 @@ performPageInvocationRemapPDE(asid_t asid, pde_t pde, pde_range_t pde_entries)
|
|||
j = pde_entries.length;
|
||||
/** GHOSTUPD: "(\<acute>j <= 16, id)" */
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
word_t base_address = pde_pde_section_get_address(pde);
|
||||
#endif
|
||||
for (i = 0; i < pde_entries.length; i++) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
pde = pde_pde_section_set_address(pde, base_address + i * BIT(pageBitsForSize(ARMSection)));
|
||||
#endif
|
||||
pde_entries.base[i] = pde;
|
||||
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
|
||||
pde.words[0] += BIT(pageBitsForSize(ARMSection));
|
||||
}
|
||||
}
|
||||
cleanCacheRange_PoU((word_t)pde_entries.base,
|
||||
LAST_BYTE_PDE(pde_entries.base, pde_entries.length),
|
||||
|
|
@ -2972,7 +2990,7 @@ exception_t benchmark_arch_map_logBuffer(word_t frame_cptr)
|
|||
}
|
||||
#endif /* CONFIG_BENCHMARK_USE_KERNEL_LOG_BUFFER */
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
void kernelPrefetchAbort(word_t pc) VISIBLE;
|
||||
void kernelDataAbort(word_t pc) VISIBLE;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <arch/types.h>
|
||||
#include <arch/model/statedata.h>
|
||||
#include <arch/object/structures.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <arch/linker.h>
|
||||
#include <plat/machine/hardware.h>
|
||||
|
||||
|
|
@ -59,3 +60,8 @@ vcpu_t *armHSCurVCPU;
|
|||
/* Whether the current loaded VCPU is enabled in the hardware or not */
|
||||
bool_t armHSVCPUActive;
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
/* Null state for the Debug coprocessor's break/watchpoint registers */
|
||||
user_breakpoint_state_t armKSNullBreakpointState;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -431,14 +431,24 @@ Arch_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
|
||||
case seL4_ARM_SectionObject:
|
||||
if (deviceMemory) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 512
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_device_C ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 256
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_device_C ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** GHOSTUPD: "(True, gs_new_frames vmpage_size.ARMSection
|
||||
(ptr_val \<acute>regionBase)
|
||||
(unat ARMSectionBits))" */
|
||||
} else {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 512
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_C ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 256
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_C ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** GHOSTUPD: "(True, gs_new_frames vmpage_size.ARMSection
|
||||
(ptr_val \<acute>regionBase)
|
||||
(unat ARMSectionBits))" */
|
||||
|
|
@ -450,14 +460,24 @@ Arch_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
|
||||
case seL4_ARM_SuperSectionObject:
|
||||
if (deviceMemory) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 8192
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_device_C ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 4096
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_device_C ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** GHOSTUPD: "(True, gs_new_frames vmpage_size.ARMSuperSection
|
||||
(ptr_val \<acute>regionBase)
|
||||
(unat ARMSuperSectionBits))" */
|
||||
} else {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 8192
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_C ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 4096
|
||||
(Ptr (ptr_val \<acute>regionBase) :: user_data_C ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** GHOSTUPD: "(True, gs_new_frames vmpage_size.ARMSuperSection
|
||||
(ptr_val \<acute>regionBase)
|
||||
(unat ARMSuperSectionBits))" */
|
||||
|
|
@ -468,15 +488,25 @@ Arch_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
(word_t)regionBase);
|
||||
|
||||
case seL4_ARM_PageTableObject:
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 1
|
||||
(Ptr (ptr_val \<acute>regionBase) :: (pte_C[512]) ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 1
|
||||
(Ptr (ptr_val \<acute>regionBase) :: (pte_C[256]) ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
|
||||
return cap_page_table_cap_new(false, asidInvalid, 0,
|
||||
(word_t)regionBase);
|
||||
|
||||
case seL4_ARM_PageDirectoryObject:
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** AUXUPD: "(True, ptr_retyps 1
|
||||
(Ptr (ptr_val \<acute>regionBase) :: (pde_C[2048]) ptr))" */
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/** AUXUPD: "(True, ptr_retyps 1
|
||||
(Ptr (ptr_val \<acute>regionBase) :: (pde_C[4096]) ptr))" */
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
copyGlobalMappings((pde_t *)regionBase);
|
||||
cleanCacheRange_PoU((word_t)regionBase,
|
||||
(word_t)regionBase + (1 << (PD_INDEX_BITS + PDE_SIZE_BITS)) - 1,
|
||||
|
|
@ -486,14 +516,16 @@ Arch_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
(word_t)regionBase);
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case seL4_ARM_VCPUObject:
|
||||
memzero(regionBase, 1 << VCPU_SIZE_BITS);
|
||||
/** AUXUPD: "(True, ptr_retyp
|
||||
(Ptr (ptr_val \<acute>regionBase) :: vcpu_C ptr))" */
|
||||
vcpu_init(VCPU_PTR(regionBase));
|
||||
return cap_vcpu_cap_new(VCPU_REF(regionBase));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
case seL4_ARM_IOPageTableObject:
|
||||
memzero(regionBase, 1 << seL4_IOPageTableBits);
|
||||
/* When the untyped was zeroed it was cleaned to the PoU, but the SMMUs
|
||||
* typically pull directly from RAM, so we do a futher clean to RAM here */
|
||||
cleanCacheRange_RAM((word_t)regionBase,
|
||||
(word_t)regionBase + (1 << seL4_IOPageTableBits) - 1,
|
||||
addrFromPPtr(regionBase));
|
||||
|
|
@ -540,8 +572,8 @@ Arch_decodeInvocation(word_t invLabel, word_t length, cptr_t cptr,
|
|||
void
|
||||
Arch_prepareThreadDelete(tcb_t * thread) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (thread->tcbArch.vcpu) {
|
||||
dissociateVCPUTCB(thread->tcbArch.vcpu, thread);
|
||||
if (thread->tcbArch.tcbVCPU) {
|
||||
dissociateVCPUTCB(thread->tcbArch.tcbVCPU, thread);
|
||||
}
|
||||
#else /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
/* No action required on ARM. */
|
||||
|
|
|
|||
|
|
@ -2185,7 +2185,7 @@ decodeARMMMUInvocation(word_t invLabel, word_t length, cptr_t cptr,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
void kernelPrefetchAbort(word_t pc) VISIBLE;
|
||||
void kernelDataAbort(word_t pc) VISIBLE;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <util.h>
|
||||
#include <arch/model/statedata.h>
|
||||
#include <arch/machine/debug.h>
|
||||
#include <arch/machine/debug_conf.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
#include <arch/machine/registerset.h>
|
||||
#include <armv/debug.h>
|
||||
|
|
@ -160,7 +161,7 @@ byte8WatchpointsSupported(void)
|
|||
|
||||
#endif /* CONFIG_HARDWARE_DEBUG_API */
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
|
||||
#define DBGBCR_ENABLE (BIT(0))
|
||||
|
||||
|
|
@ -306,62 +307,62 @@ DEBUG_GENERATE_WRITE_FN(writeWvrCp, DBGWVR)
|
|||
* context and not from the hardware registers.
|
||||
*/
|
||||
static word_t
|
||||
readBcrContext(arch_tcb_t *at, uint16_t index)
|
||||
readBcrContext(tcb_t *t, uint16_t index)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveBreakpoints);
|
||||
return at->tcbContext.breakpointState.breakpoint[index].cr;
|
||||
return t->tcbArch.tcbContext.breakpointState.breakpoint[index].cr;
|
||||
}
|
||||
|
||||
static word_t
|
||||
readBvrContext(arch_tcb_t *at, uint16_t index)
|
||||
readBvrContext(tcb_t *t, uint16_t index)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveBreakpoints);
|
||||
return at->tcbContext.breakpointState.breakpoint[index].vr;
|
||||
return t->tcbArch.tcbContext.breakpointState.breakpoint[index].vr;
|
||||
}
|
||||
|
||||
static word_t
|
||||
readWcrContext(arch_tcb_t *at, uint16_t index)
|
||||
readWcrContext(tcb_t *t, uint16_t index)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveWatchpoints);
|
||||
return at->tcbContext.breakpointState.watchpoint[index].cr;
|
||||
return t->tcbArch.tcbContext.breakpointState.watchpoint[index].cr;
|
||||
}
|
||||
|
||||
static word_t
|
||||
readWvrContext(arch_tcb_t *at, uint16_t index)
|
||||
readWvrContext(tcb_t *t, uint16_t index)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveWatchpoints);
|
||||
return at->tcbContext.breakpointState.watchpoint[index].vr;
|
||||
return t->tcbArch.tcbContext.breakpointState.watchpoint[index].vr;
|
||||
}
|
||||
|
||||
static void
|
||||
writeBcrContext(arch_tcb_t *at, uint16_t index, word_t val)
|
||||
writeBcrContext(tcb_t *t, uint16_t index, word_t val)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveBreakpoints);
|
||||
at->tcbContext.breakpointState.breakpoint[index].cr = val;
|
||||
t->tcbArch.tcbContext.breakpointState.breakpoint[index].cr = val;
|
||||
}
|
||||
|
||||
static void
|
||||
writeBvrContext(arch_tcb_t *at, uint16_t index, word_t val)
|
||||
writeBvrContext(tcb_t *t, uint16_t index, word_t val)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveBreakpoints);
|
||||
at->tcbContext.breakpointState.breakpoint[index].vr = val;
|
||||
t->tcbArch.tcbContext.breakpointState.breakpoint[index].vr = val;
|
||||
}
|
||||
|
||||
static void
|
||||
writeWcrContext(arch_tcb_t *at, uint16_t index, word_t val)
|
||||
writeWcrContext(tcb_t *t, uint16_t index, word_t val)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveWatchpoints);
|
||||
at->tcbContext.breakpointState.watchpoint[index].cr = val;
|
||||
t->tcbArch.tcbContext.breakpointState.watchpoint[index].cr = val;
|
||||
}
|
||||
|
||||
static void
|
||||
writeWvrContext(arch_tcb_t *at, uint16_t index, word_t val)
|
||||
writeWvrContext(tcb_t *t, uint16_t index, word_t val)
|
||||
{
|
||||
assert(index < seL4_NumExclusiveWatchpoints);
|
||||
at->tcbContext.breakpointState.watchpoint[index].vr = val;
|
||||
t->tcbArch.tcbContext.breakpointState.watchpoint[index].vr = val;
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_VERIFICATION_BUILD) && (CONFIG_HARDWARE_DEBUG_API || CONFIG_ARM_HYPERVISOR_SUPPORT) */
|
||||
#endif /* ARM_BASE_CP14_SAVE_AND_RESTORE */
|
||||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
|
||||
|
|
@ -394,16 +395,16 @@ dumpBpsAndWpsCp(int nBp, int nWp)
|
|||
* @param mWp Number of WP regs to print, beginning at WP #0.
|
||||
*/
|
||||
UNUSED static void
|
||||
dumpBpsAndWpsContext(arch_tcb_t *at, int nBp, int nWp)
|
||||
dumpBpsAndWpsContext(tcb_t *t, int nBp, int nWp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nBp; i++) {
|
||||
userError("Ctxt BP %d: Bcr %lx, Bvr %lx", i, readBcrContext(at, i), readBvrContext(at, i));
|
||||
userError("Ctxt BP %d: Bcr %lx, Bvr %lx", i, readBcrContext(t, i), readBvrContext(t, i));
|
||||
}
|
||||
|
||||
for (i = 0; i < nWp; i++) {
|
||||
userError("Ctxt WP %d: Wcr %lx, Wvr %lx", i, readWcrContext(at, i), readWvrContext(at, i));
|
||||
userError("Ctxt WP %d: Wcr %lx, Wvr %lx", i, readWcrContext(t, i), readWvrContext(t, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +548,7 @@ getMethodOfEntry(void)
|
|||
* All documented in the seL4 API Manuals.
|
||||
*/
|
||||
void
|
||||
setBreakpoint(arch_tcb_t *at,
|
||||
setBreakpoint(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t vaddr, word_t type, word_t size, word_t rw)
|
||||
{
|
||||
|
|
@ -576,23 +577,23 @@ setBreakpoint(arch_tcb_t *at,
|
|||
if (type == seL4_InstructionBreakpoint) {
|
||||
dbg_bcr_t bcr;
|
||||
|
||||
writeBvrContext(at, bp_num, vaddr);
|
||||
writeBvrContext(t, bp_num, vaddr);
|
||||
|
||||
/* Preserve reserved bits. */
|
||||
bcr.words[0] = readBcrContext(at, bp_num);
|
||||
bcr.words[0] = readBcrContext(t, bp_num);
|
||||
bcr = dbg_bcr_set_enabled(bcr, 1);
|
||||
bcr = dbg_bcr_set_linkedBrp(bcr, 0);
|
||||
bcr = dbg_bcr_set_supervisorAccess(bcr, DBGBCR_PRIV_USER);
|
||||
bcr = dbg_bcr_set_byteAddressSelect(bcr, convertSizeToArch(4));
|
||||
bcr = Arch_setupBcr(bcr, true);
|
||||
writeBcrContext(at, bp_num, bcr.words[0]);
|
||||
writeBcrContext(t, bp_num, bcr.words[0]);
|
||||
} else {
|
||||
dbg_wcr_t wcr;
|
||||
|
||||
writeWvrContext(at, bp_num, vaddr);
|
||||
writeWvrContext(t, bp_num, vaddr);
|
||||
|
||||
/* Preserve reserved bits */
|
||||
wcr.words[0] = readWcrContext(at, bp_num);
|
||||
wcr.words[0] = readWcrContext(t, bp_num);
|
||||
wcr = dbg_wcr_set_enabled(wcr, 1);
|
||||
wcr = dbg_wcr_set_supervisorAccess(wcr, DBGWCR_PRIV_USER);
|
||||
wcr = dbg_wcr_set_byteAddressSelect(wcr, convertSizeToArch(size));
|
||||
|
|
@ -600,7 +601,7 @@ setBreakpoint(arch_tcb_t *at,
|
|||
wcr = dbg_wcr_set_enableLinking(wcr, 0);
|
||||
wcr = dbg_wcr_set_linkedBrp(wcr, 0);
|
||||
wcr = Arch_setupWcr(wcr);
|
||||
writeWcrContext(at, bp_num, wcr.words[0]);
|
||||
writeWcrContext(t, bp_num, wcr.words[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -616,7 +617,7 @@ setBreakpoint(arch_tcb_t *at,
|
|||
* breakpoint.
|
||||
*/
|
||||
getBreakpoint_t
|
||||
getBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
||||
getBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
getBreakpoint_t ret;
|
||||
|
||||
|
|
@ -626,21 +627,21 @@ getBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
|||
if (ret.type == seL4_InstructionBreakpoint) {
|
||||
dbg_bcr_t bcr;
|
||||
|
||||
bcr.words[0] = readBcrContext(at, bp_num);
|
||||
bcr.words[0] = readBcrContext(t, bp_num);
|
||||
if (Arch_breakpointIsMismatch(bcr) == true) {
|
||||
ret.type = seL4_SingleStep;
|
||||
};
|
||||
ret.size = 0;
|
||||
ret.rw = seL4_BreakOnRead;
|
||||
ret.vaddr = readBvrContext(at, bp_num);
|
||||
ret.vaddr = readBvrContext(t, bp_num);
|
||||
ret.is_enabled = dbg_bcr_get_enabled(bcr);
|
||||
} else {
|
||||
dbg_wcr_t wcr;
|
||||
|
||||
wcr.words[0] = readWcrContext(at, bp_num);
|
||||
wcr.words[0] = readWcrContext(t, bp_num);
|
||||
ret.size = convertArchToSize(dbg_wcr_get_byteAddressSelect(wcr));
|
||||
ret.rw = convertArchToAccess(dbg_wcr_get_loadStore(wcr));
|
||||
ret.vaddr = readWvrContext(at, bp_num);
|
||||
ret.vaddr = readWvrContext(t, bp_num);
|
||||
ret.is_enabled = dbg_wcr_get_enabled(wcr);
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -652,7 +653,7 @@ getBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
|||
* @param bp_num The hardware breakpoint you want to disable+clear.
|
||||
*/
|
||||
void
|
||||
unsetBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
||||
unsetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t type;
|
||||
|
||||
|
|
@ -662,17 +663,17 @@ unsetBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
|||
if (type == seL4_InstructionBreakpoint) {
|
||||
dbg_bcr_t bcr;
|
||||
|
||||
bcr.words[0] = readBcrContext(at, bp_num);
|
||||
bcr.words[0] = readBcrContext(t, bp_num);
|
||||
bcr = dbg_bcr_set_enabled(bcr, 0);
|
||||
writeBcrContext(at, bp_num, bcr.words[0]);
|
||||
writeBvrContext(at, bp_num, 0);
|
||||
writeBcrContext(t, bp_num, bcr.words[0]);
|
||||
writeBvrContext(t, bp_num, 0);
|
||||
} else {
|
||||
dbg_wcr_t wcr;
|
||||
|
||||
wcr.words[0] = readWcrContext(at, bp_num);
|
||||
wcr.words[0] = readWcrContext(t, bp_num);
|
||||
wcr = dbg_wcr_set_enabled(wcr, 0);
|
||||
writeWcrContext(at, bp_num, wcr.words[0]);
|
||||
writeWvrContext(at, bp_num, 0);
|
||||
writeWcrContext(t, bp_num, wcr.words[0]);
|
||||
writeWvrContext(t, bp_num, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -683,7 +684,7 @@ unsetBreakpoint(arch_tcb_t *at, uint16_t bp_num)
|
|||
* @param n_instr The number of instructions to step over.
|
||||
*/
|
||||
bool_t
|
||||
configureSingleStepping(arch_tcb_t *at,
|
||||
configureSingleStepping(tcb_t *t,
|
||||
uint16_t bp_num,
|
||||
word_t n_instr,
|
||||
bool_t is_reply)
|
||||
|
|
@ -697,7 +698,7 @@ configureSingleStepping(arch_tcb_t *at,
|
|||
*/
|
||||
|
||||
if (is_reply) {
|
||||
bp_num = at->tcbContext.breakpointState.single_step_hw_bp_num;
|
||||
bp_num = t->tcbArch.tcbContext.breakpointState.single_step_hw_bp_num;
|
||||
} else {
|
||||
bp_num = convertBpNumToArch(bp_num);
|
||||
}
|
||||
|
|
@ -714,17 +715,17 @@ configureSingleStepping(arch_tcb_t *at,
|
|||
*/
|
||||
dbg_bcr_t bcr;
|
||||
|
||||
bcr.words[0] = readBcrContext(at, bp_num);
|
||||
bcr.words[0] = readBcrContext(t, bp_num);
|
||||
|
||||
/* If the user calls us with n_instr == 0, allow them to configure, but
|
||||
* leave it disabled.
|
||||
*/
|
||||
if (n_instr > 0) {
|
||||
bcr = dbg_bcr_set_enabled(bcr, 1);
|
||||
at->tcbContext.breakpointState.single_step_enabled = true;
|
||||
t->tcbArch.tcbContext.breakpointState.single_step_enabled = true;
|
||||
} else {
|
||||
bcr = dbg_bcr_set_enabled(bcr, 0);
|
||||
at->tcbContext.breakpointState.single_step_enabled = false;
|
||||
t->tcbArch.tcbContext.breakpointState.single_step_enabled = false;
|
||||
}
|
||||
|
||||
bcr = dbg_bcr_set_linkedBrp(bcr, 0);
|
||||
|
|
@ -732,11 +733,11 @@ configureSingleStepping(arch_tcb_t *at,
|
|||
bcr = dbg_bcr_set_byteAddressSelect(bcr, convertSizeToArch(1));
|
||||
bcr = Arch_setupBcr(bcr, false);
|
||||
|
||||
writeBvrContext(at, bp_num, 0);
|
||||
writeBcrContext(at, bp_num, bcr.words[0]);
|
||||
writeBvrContext(t, bp_num, 0);
|
||||
writeBcrContext(t, bp_num, bcr.words[0]);
|
||||
|
||||
at->tcbContext.breakpointState.n_instructions = n_instr;
|
||||
at->tcbContext.breakpointState.single_step_hw_bp_num = bp_num;
|
||||
t->tcbArch.tcbContext.breakpointState.n_instructions = n_instr;
|
||||
t->tcbArch.tcbContext.breakpointState.single_step_hw_bp_num = bp_num;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -926,6 +927,17 @@ Arch_initHardwareBreakpoints(void)
|
|||
disableAllBpsAndWps();
|
||||
}
|
||||
|
||||
/* Finally, also pre-load some initial register state that can be used
|
||||
* for all new threads so that their initial saved debug register state
|
||||
* is valid when it's first loaded onto the CPU.
|
||||
*/
|
||||
for (int i = 0; i < seL4_NumExclusiveBreakpoints; i++) {
|
||||
armKSNullBreakpointState.breakpoint[i].cr = readBcrCp(i) & ~DBGBCR_ENABLE;
|
||||
}
|
||||
for (int i = 0; i < seL4_NumExclusiveWatchpoints; i++) {
|
||||
armKSNullBreakpointState.watchpoint[i].cr = readWcrCp(i) & ~DBGWCR_ENABLE;
|
||||
}
|
||||
|
||||
dbg.watchpoint_8b_supported = watchpoint8bSupported();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1174,7 +1186,7 @@ handleUserLevelDebugException(word_t fault_vaddr)
|
|||
|
||||
#endif /* CONFIG_HARDWARE_DEBUG_API */
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && (defined(CONFIG_HARDWARE_DEBUG_API) || defined(CONFIG_ARM_HYPERVISOR_SUPPORT))
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
|
||||
/** Mirrors Arch_initFpuContext.
|
||||
*
|
||||
|
|
@ -1184,17 +1196,9 @@ handleUserLevelDebugException(word_t fault_vaddr)
|
|||
* coprocessor.
|
||||
*/
|
||||
void
|
||||
Arch_initBreakpointContext(user_breakpoint_state_t *uds)
|
||||
Arch_initBreakpointContext(user_context_t *uc)
|
||||
{
|
||||
memset(uds, 0, sizeof(*uds));
|
||||
|
||||
/* Preload SBZ/reserved values into thread context. */
|
||||
for (int i = 0; i < seL4_NumExclusiveBreakpoints; i++) {
|
||||
uds->breakpoint[i].cr = readBcrCp(i) & ~DBGBCR_ENABLE;
|
||||
}
|
||||
for (int i = 0; i < seL4_NumExclusiveWatchpoints; i++) {
|
||||
uds->watchpoint[i].cr = readWcrCp(i) & ~DBGWCR_ENABLE;
|
||||
}
|
||||
uc->breakpointState = armKSNullBreakpointState;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1239,23 +1243,24 @@ loadAllDisabledBreakpointState(void)
|
|||
* associateVcpu.
|
||||
*/
|
||||
void
|
||||
saveAllBreakpointState(arch_tcb_t *at)
|
||||
saveAllBreakpointState(tcb_t *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(at != NULL);
|
||||
assert(t != NULL);
|
||||
|
||||
for (i = 0; i < seL4_NumExclusiveBreakpoints; i++) {
|
||||
writeBvrContext(at, i, readBvrCp(i));
|
||||
writeBcrContext(at, i, readBcrCp(i));
|
||||
writeBvrContext(t, i, readBvrCp(i));
|
||||
writeBcrContext(t, i, readBcrCp(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < seL4_NumExclusiveWatchpoints; i++) {
|
||||
writeWvrContext(at, i, readWvrCp(i));
|
||||
writeWcrContext(at, i, readWcrCp(i));
|
||||
writeWvrContext(t, i, readWvrCp(i));
|
||||
writeWcrContext(t, i, readWcrCp(i));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
void
|
||||
Arch_debugAssociateVCPUTCB(tcb_t *t)
|
||||
{
|
||||
|
|
@ -1273,18 +1278,19 @@ Arch_debugDissociateVCPUTCB(tcb_t *t)
|
|||
{
|
||||
t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
loadBreakpointState(arch_tcb_t *at)
|
||||
loadBreakpointState(tcb_t *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(at != NULL);
|
||||
assert(t != NULL);
|
||||
|
||||
for (i = 0; i < seL4_NumExclusiveBreakpoints; i++) {
|
||||
if (at->tcbContext.breakpointState.used_breakpoints_bf & BIT(i)) {
|
||||
writeBvrCp(i, readBvrContext(at, i));
|
||||
writeBcrCp(i, readBcrContext(at, i));
|
||||
if (t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf & BIT(i)) {
|
||||
writeBvrCp(i, readBvrContext(t, i));
|
||||
writeBcrCp(i, readBcrContext(t, i));
|
||||
} else {
|
||||
/* If the thread isn't using the BP, then just load
|
||||
* a default "disabled" state.
|
||||
|
|
@ -1294,10 +1300,10 @@ loadBreakpointState(arch_tcb_t *at)
|
|||
}
|
||||
|
||||
for (i = 0; i < seL4_NumExclusiveWatchpoints; i++) {
|
||||
if (at->tcbContext.breakpointState.used_breakpoints_bf &
|
||||
if (t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf &
|
||||
BIT(i + seL4_NumExclusiveBreakpoints)) {
|
||||
writeWvrCp(i, readWvrContext(at, i));
|
||||
writeWcrCp(i, readWcrContext(at, i));
|
||||
writeWvrCp(i, readWvrContext(t, i));
|
||||
writeWcrCp(i, readWcrContext(t, i));
|
||||
} else {
|
||||
writeWcrCp(i, readWcrCp(i) & ~DBGWCR_ENABLE);
|
||||
}
|
||||
|
|
@ -1316,7 +1322,7 @@ restore_user_debug_context(tcb_t *target_thread)
|
|||
if (target_thread->tcbArch.tcbContext.breakpointState.used_breakpoints_bf == 0) {
|
||||
loadAllDisabledBreakpointState();
|
||||
} else {
|
||||
loadBreakpointState(&target_thread->tcbArch);
|
||||
loadBreakpointState(target_thread);
|
||||
}
|
||||
|
||||
/* ARMv6 manual, sec D3.3.7:
|
||||
|
|
@ -1328,4 +1334,4 @@ restore_user_debug_context(tcb_t *target_thread)
|
|||
*/
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_VERIFICATION_BUILD) && (CONFIG_HARDWARE_DEBUG_API || CONFIG_ARM_HYPERVISOR_SUPPORT) */
|
||||
#endif /* ARM_BASE_CP14_SAVE_AND_RESTORE */
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <arch/object/vcpu.h>
|
||||
#include <plat/machine/devices.h>
|
||||
#include <arch/machine/debug.h> /* Arch_debug[A/Di]ssociateVCPUTCB() */
|
||||
#include <arch/machine/debug_conf.h>
|
||||
|
||||
#define HCR_TGE BIT(27) /* Trap general exceptions */
|
||||
#define HCR_TVM BIT(26) /* Trap MMU access */
|
||||
|
|
@ -407,10 +408,11 @@ vcpu_enable(vcpu_t *vcpu)
|
|||
/* Turn on the VGIC */
|
||||
set_gic_vcpu_ctrl_hcr(vcpu->vgic.hcr);
|
||||
|
||||
#if !defined(CONFIG_VERIFICATION_BUILD) && !defined(CONFIG_HARDWARE_DEBUG_API)
|
||||
/* This is guarded by an #ifNdef (negation) because if it wasn't, we'd be
|
||||
* calling restore_user_debug_context twice on a debug-API build; recall
|
||||
* that restore_user_debug_context is called in restore_user_context.
|
||||
#if !defined(ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS) && defined(ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS)
|
||||
/* This is guarded by an #ifNdef (negation) ARM_CP14_SAVE_AND_RESTORE_NATIVE_THREADS
|
||||
* because if it wasn't, we'd be calling restore_user_debug_context twice
|
||||
* on a debug-API build; recall that restore_user_debug_context is called
|
||||
* in restore_user_context.
|
||||
*
|
||||
* We call restore_user_debug_context here, because vcpu_restore calls this
|
||||
* function (vcpu_enable). It's better to embed the
|
||||
|
|
@ -420,9 +422,9 @@ vcpu_enable(vcpu_t *vcpu)
|
|||
* the code will be able to omit the debug register context restore, if
|
||||
* it's done here.
|
||||
*/
|
||||
restore_user_debug_context(vcpu->tcb);
|
||||
restore_user_debug_context(vcpu->vcpuTCB);
|
||||
#endif
|
||||
#if defined(CONFIG_HARDWARE_DEBUG_API) && defined(CONFIG_ARM_HYPERVISOR_SUPPORT)
|
||||
#if defined(ARM_HYP_TRAP_CP14_IN_NATIVE_USER_THREADS)
|
||||
/* Disable debug exception trapping and let the PL1 Guest VM handle all
|
||||
* of its own debug faults.
|
||||
*/
|
||||
|
|
@ -433,10 +435,14 @@ vcpu_enable(vcpu_t *vcpu)
|
|||
static void
|
||||
vcpu_disable(vcpu_t *vcpu)
|
||||
{
|
||||
uint32_t hcr;
|
||||
word_t SCTLR;
|
||||
dsb();
|
||||
if (likely(vcpu)) {
|
||||
vcpu->vgic.hcr = get_gic_vcpu_ctrl_hcr();
|
||||
vcpu->cpx.sctlr = getSCTLR();
|
||||
hcr = get_gic_vcpu_ctrl_hcr();
|
||||
SCTLR = getSCTLR();
|
||||
vcpu->vgic.hcr = hcr;
|
||||
vcpu->cpx.sctlr = SCTLR;
|
||||
isb();
|
||||
}
|
||||
/* Turn off the VGIC */
|
||||
|
|
@ -447,7 +453,7 @@ vcpu_disable(vcpu_t *vcpu)
|
|||
setSCTLR(SCTLR_DEFAULT);
|
||||
setHCR(HCR_NATIVE);
|
||||
|
||||
#ifndef CONFIG_VERIFICATION_BUILD
|
||||
#if defined(ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS)
|
||||
/* Disable all breakpoint registers from triggering their
|
||||
* respective events, so that when we switch from a guest VM
|
||||
* to a native thread, the native thread won't trigger events
|
||||
|
|
@ -455,7 +461,7 @@ vcpu_disable(vcpu_t *vcpu)
|
|||
*/
|
||||
loadAllDisabledBreakpointState();
|
||||
#endif
|
||||
#if defined(CONFIG_HARDWARE_DEBUG_API) && defined(CONFIG_ARM_HYPERVISOR_SUPPORT)
|
||||
#if defined(ARM_HYP_TRAP_CP14_IN_NATIVE_USER_THREADS)
|
||||
/* Enable debug exception trapping and let seL4 trap all PL0 (user) native
|
||||
* seL4 threads' debug exceptions, so it can deliver them as fault messages.
|
||||
*/
|
||||
|
|
@ -476,7 +482,23 @@ vcpu_boot_init(void)
|
|||
armHSCurVCPU = NULL;
|
||||
armHSVCPUActive = false;
|
||||
|
||||
#if defined(CONFIG_HARDWARE_DEBUG_API) && defined(CONFIG_ARM_HYPERVISOR_SUPPORT)
|
||||
#if defined(ARM_HYP_TRAP_CP14_IN_VCPU_THREADS) || defined(ARM_HYP_TRAP_CP14_IN_NATIVE_USER_THREADS)
|
||||
/* On the verified build, we have implemented a workaround that ensures
|
||||
* that we don't need to save and restore the debug coprocessor's state
|
||||
* (and therefore don't have to expose the CP14 registers to verification).
|
||||
*
|
||||
* This workaround is simple: we just trap and intercept all Guest VM
|
||||
* accesses to the debug coprocessor, and deliver them as VMFault
|
||||
* messages to the VM Monitor. To that end, the VM Monitor can then
|
||||
* choose to either kill the Guest VM, or it can also choose to silently
|
||||
* step over the Guest VM's accesses to the debug coprocessor, thereby
|
||||
* silently eliminating the communication channel between the Guest VMs
|
||||
* (because the debug coprocessor acted as a communication channel
|
||||
* unless we saved/restored its state between VM switches).
|
||||
*
|
||||
* This workaround delegates the communication channel responsibility
|
||||
* from the kernel to the VM Monitor, essentially.
|
||||
*/
|
||||
initHDCR();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -484,7 +506,7 @@ vcpu_boot_init(void)
|
|||
static void
|
||||
vcpu_save(vcpu_t *vcpu, bool_t active)
|
||||
{
|
||||
int i;
|
||||
word_t i;
|
||||
|
||||
assert(vcpu);
|
||||
dsb();
|
||||
|
|
@ -521,18 +543,11 @@ vcpu_save(vcpu_t *vcpu, bool_t active)
|
|||
vcpu->r11_fiq = get_r11_fiq();
|
||||
vcpu->r12_fiq = get_r12_fiq();
|
||||
|
||||
#ifndef CONFIG_VERIFICATION_BUILD
|
||||
/* This is unconditionally done even when the hypervisor is
|
||||
* not exporting the debug API. The Guest VMs should be able
|
||||
* make changes to the debug regs, and see their changes
|
||||
* preserved across guest VM context switches.
|
||||
*
|
||||
* The hypervisor build doesn't have to worry about saving
|
||||
* and restoring native threads' debug register state when
|
||||
* not exporting the debug API, because in that case, native
|
||||
* threads can't modify the debug registers (i.e, without the API).
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
/* This is done when we are asked to save and restore the CP14 debug context
|
||||
* of VCPU threads; the register context is saved into the underlying TCB.
|
||||
*/
|
||||
saveAllBreakpointState(&vcpu->tcb->tcbArch);
|
||||
saveAllBreakpointState(vcpu->vcpuTCB);
|
||||
#endif
|
||||
isb();
|
||||
}
|
||||
|
|
@ -744,7 +759,7 @@ void
|
|||
vcpu_restore(vcpu_t *vcpu)
|
||||
{
|
||||
assert(vcpu);
|
||||
int i;
|
||||
word_t i;
|
||||
/* Turn off the VGIC */
|
||||
set_gic_vcpu_ctrl_hcr(0);
|
||||
isb();
|
||||
|
|
@ -850,8 +865,8 @@ vcpu_switch(vcpu_t *new)
|
|||
armHSVCPUActive = true;
|
||||
} else if (unlikely(armHSVCPUActive)) {
|
||||
/* leave the current VCPU state loaded, but disable vgic and mmu */
|
||||
#ifndef CONFIG_VERIFICATION_BUILD
|
||||
saveAllBreakpointState(&armHSCurVCPU->tcb->tcbArch);
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
saveAllBreakpointState(armHSCurVCPU->vcpuTCB);
|
||||
#endif
|
||||
vcpu_disable(armHSCurVCPU);
|
||||
armHSVCPUActive = false;
|
||||
|
|
@ -876,36 +891,36 @@ vcpu_invalidate_active(void)
|
|||
void
|
||||
vcpu_finalise(vcpu_t *vcpu)
|
||||
{
|
||||
if (vcpu->tcb) {
|
||||
dissociateVCPUTCB(vcpu, vcpu->tcb);
|
||||
if (vcpu->vcpuTCB) {
|
||||
dissociateVCPUTCB(vcpu, vcpu->vcpuTCB);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
associateVCPUTCB(vcpu_t *vcpu, tcb_t *tcb)
|
||||
{
|
||||
if (tcb->tcbArch.vcpu) {
|
||||
dissociateVCPUTCB(tcb->tcbArch.vcpu, tcb);
|
||||
if (tcb->tcbArch.tcbVCPU) {
|
||||
dissociateVCPUTCB(tcb->tcbArch.tcbVCPU, tcb);
|
||||
}
|
||||
if (vcpu->tcb) {
|
||||
dissociateVCPUTCB(vcpu, vcpu->tcb);
|
||||
if (vcpu->vcpuTCB) {
|
||||
dissociateVCPUTCB(vcpu, vcpu->vcpuTCB);
|
||||
}
|
||||
vcpu->tcb = tcb;
|
||||
tcb->tcbArch.vcpu = vcpu;
|
||||
tcb->tcbArch.tcbVCPU = vcpu;
|
||||
vcpu->vcpuTCB = tcb;
|
||||
}
|
||||
|
||||
void
|
||||
dissociateVCPUTCB(vcpu_t *vcpu, tcb_t *tcb)
|
||||
{
|
||||
if (tcb->tcbArch.vcpu != vcpu || vcpu->tcb != tcb) {
|
||||
if (tcb->tcbArch.tcbVCPU != vcpu || vcpu->vcpuTCB != tcb) {
|
||||
fail("TCB and VCPU not associated.");
|
||||
}
|
||||
if (vcpu == armHSCurVCPU) {
|
||||
vcpu_invalidate_active();
|
||||
}
|
||||
tcb->tcbArch.vcpu = NULL;
|
||||
vcpu->tcb = NULL;
|
||||
#ifndef CONFIG_VERIFICATION_BUILD
|
||||
tcb->tcbArch.tcbVCPU = NULL;
|
||||
vcpu->vcpuTCB = NULL;
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
Arch_debugDissociateVCPUTCB(tcb);
|
||||
#endif
|
||||
|
||||
|
|
@ -978,7 +993,7 @@ decodeVCPUReadReg(cap_t cap, unsigned int length, word_t* buffer)
|
|||
}
|
||||
|
||||
exception_t
|
||||
invokeVCPUInjectIRQ(vcpu_t* vcpu, int index, virq_t virq)
|
||||
invokeVCPUInjectIRQ(vcpu_t* vcpu, unsigned long index, virq_t virq)
|
||||
{
|
||||
if (likely(armHSCurVCPU == vcpu)) {
|
||||
set_gic_vcpu_ctrl_lr(index, virq);
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ static void NORETURN restore_vmx(void)
|
|||
loadAllDisabledBreakpointState(&NODE_STATE(ksCurThread)->tcbArch);
|
||||
#endif
|
||||
#if CONFIG_MAX_NUM_NODES > 1
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->kernelSP = ((word_t)kernel_stack_alloc[getCurrentCPUIndex()]) + BIT(CONFIG_KERNEL_STACK_BITS) - 4;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->kernelSP = ((word_t)kernel_stack_alloc[getCurrentCPUIndex()]) + BIT(CONFIG_KERNEL_STACK_BITS) - 4;
|
||||
#endif
|
||||
if (NODE_STATE(ksCurThread)->tcbArch.vcpu->launched) {
|
||||
if (NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->launched) {
|
||||
/* attempt to do a vmresume */
|
||||
asm volatile(
|
||||
// Set our stack pointer to the top of the tcb so we can efficiently pop
|
||||
|
|
@ -65,7 +65,7 @@ static void NORETURN restore_vmx(void)
|
|||
#endif
|
||||
"call %1\n"
|
||||
:
|
||||
: "r"(&NODE_STATE(ksCurThread)->tcbArch.vcpu->gp_registers[VCPU_EAX]),
|
||||
: "r"(&NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->gp_registers[VCPU_EAX]),
|
||||
"m"(vmlaunch_failed),
|
||||
"i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
// Clobber memory so the compiler is forced to complete all stores
|
||||
|
|
@ -94,7 +94,7 @@ static void NORETURN restore_vmx(void)
|
|||
#endif
|
||||
"call %1\n"
|
||||
:
|
||||
: "r"(&NODE_STATE(ksCurThread)->tcbArch.vcpu->gp_registers[VCPU_EAX]),
|
||||
: "r"(&NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->gp_registers[VCPU_EAX]),
|
||||
"m"(vmlaunch_failed),
|
||||
"i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
// Clobber memory so the compiler is forced to complete all stores
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static void NORETURN restore_vmx(void)
|
|||
/* Do not support breakpoints in VMs, so just disable all breakpoints */
|
||||
loadAllDisabledBreakpointState(&cur_thread->tcbArch);
|
||||
#endif
|
||||
if (cur_thread->tcbArch.vcpu->launched) {
|
||||
if (cur_thread->tcbArch.tcbVCPU->launched) {
|
||||
/* attempt to do a vmresume */
|
||||
asm volatile(
|
||||
// Set our stack pointer to the top of the tcb so we can efficiently pop
|
||||
|
|
@ -75,7 +75,7 @@ static void NORETURN restore_vmx(void)
|
|||
"leaq %[failed], %%rax\n"
|
||||
"jmp *%%rax\n"
|
||||
:
|
||||
: [reg]"r"(&cur_thread->tcbArch.vcpu->gp_registers[VCPU_EAX]),
|
||||
: [reg]"r"(&cur_thread->tcbArch.tcbVCPU->gp_registers[VCPU_EAX]),
|
||||
[failed]"m"(vmlaunch_failed),
|
||||
[stack_size]"i"(BIT(CONFIG_KERNEL_STACK_BITS))
|
||||
#if CONFIG_MAX_NUM_NODES > 1
|
||||
|
|
@ -116,7 +116,7 @@ static void NORETURN restore_vmx(void)
|
|||
"leaq %[failed], %%rax\n"
|
||||
"jmp *%%rax\n"
|
||||
:
|
||||
: [reg]"r"(&cur_thread->tcbArch.vcpu->gp_registers[VCPU_EAX]),
|
||||
: [reg]"r"(&cur_thread->tcbArch.tcbVCPU->gp_registers[VCPU_EAX]),
|
||||
[failed]"m"(vmlaunch_failed),
|
||||
[stack_size]"i"(BIT(CONFIG_KERNEL_STACK_BITS))
|
||||
#if CONFIG_MAX_NUM_NODES > 1
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ slowpath(syscall_t syscall)
|
|||
|
||||
#ifdef CONFIG_VTX
|
||||
if (syscall == SysVMEnter) {
|
||||
vcpu_update_state_sysvmenter(NODE_STATE(ksCurThread)->tcbArch.vcpu);
|
||||
vcpu_update_state_sysvmenter(NODE_STATE(ksCurThread)->tcbArch.tcbVCPU);
|
||||
if (NODE_STATE(ksCurThread)->tcbBoundNotification && notification_ptr_get_state(NODE_STATE(ksCurThread)->tcbBoundNotification) == NtfnState_Active) {
|
||||
completeSignal(NODE_STATE(ksCurThread)->tcbBoundNotification, NODE_STATE(ksCurThread));
|
||||
setRegister(NODE_STATE(ksCurThread), msgInfoRegister, SEL4_VMENTER_RESULT_NOTIF);
|
||||
|
|
|
|||
|
|
@ -450,8 +450,8 @@ try_boot_sys(
|
|||
boot_state.vbe_info.vbeMode = -1;
|
||||
printf("Multiboot gave us no video information\n");
|
||||
} else {
|
||||
boot_state.vbe_info.vbeInfoBlock = *mbi->vbe_control_info;
|
||||
boot_state.vbe_info.vbeModeInfoBlock = *mbi->vbe_mode_info;
|
||||
boot_state.vbe_info.vbeInfoBlock = *(seL4_VBEInfoBlock_t*)(seL4_Word)mbi->vbe_control_info;
|
||||
boot_state.vbe_info.vbeModeInfoBlock = *(seL4_VBEModeInfoBlock_t*)(seL4_Word)mbi->vbe_mode_info;
|
||||
boot_state.vbe_info.vbeMode = mbi->vbe_mode;
|
||||
printf("Got VBE info in multiboot. Current video mode is %d\n", mbi->vbe_mode);
|
||||
boot_state.vbe_info.vbeInterfaceSeg = mbi->vbe_interface_seg;
|
||||
|
|
|
|||
|
|
@ -72,25 +72,25 @@ bitwiseAndDr6Reg(word_t mask)
|
|||
}
|
||||
|
||||
static inline word_t
|
||||
readDr7Context(arch_tcb_t *uds)
|
||||
readDr7Context(tcb_t *t)
|
||||
{
|
||||
return uds->tcbContext.breakpointState.dr[5];
|
||||
return t->tcbArch.tcbContext.breakpointState.dr[5];
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitwiseOrDr7Context(arch_tcb_t *uds, word_t val)
|
||||
bitwiseOrDr7Context(tcb_t *t, word_t val)
|
||||
{
|
||||
uds->tcbContext.breakpointState.dr[5] |= val;
|
||||
t->tcbArch.tcbContext.breakpointState.dr[5] |= val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
bitwiseAndDr7Context(arch_tcb_t *uds, word_t mask)
|
||||
bitwiseAndDr7Context(tcb_t *t, word_t mask)
|
||||
{
|
||||
uds->tcbContext.breakpointState.dr[5] &= mask;
|
||||
t->tcbArch.tcbContext.breakpointState.dr[5] &= mask;
|
||||
}
|
||||
|
||||
static void
|
||||
unsetDr7BitsFor(arch_tcb_t *uds, uint16_t bp_num)
|
||||
unsetDr7BitsFor(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t mask;
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ unsetDr7BitsFor(arch_tcb_t *uds, uint16_t bp_num)
|
|||
}
|
||||
|
||||
mask = ~mask;
|
||||
bitwiseAndDr7Context(uds, mask);
|
||||
bitwiseAndDr7Context(t, mask);
|
||||
}
|
||||
|
||||
/** Converts an seL4_BreakpointType value into the underlying hardware
|
||||
|
|
@ -121,7 +121,7 @@ unsetDr7BitsFor(arch_tcb_t *uds, uint16_t bp_num)
|
|||
* @param rw Access trigger condition (read/write).
|
||||
* @return Hardware specific register value representing the inputs.
|
||||
*/
|
||||
static inline word_t
|
||||
PURE static inline word_t
|
||||
convertTypeAndAccessToArch(uint16_t bp_num, word_t type, word_t rw)
|
||||
{
|
||||
switch (type) {
|
||||
|
|
@ -159,7 +159,7 @@ typedef struct {
|
|||
word_t type, rw;
|
||||
} convertedTypeAndAccess_t;
|
||||
|
||||
static inline convertedTypeAndAccess_t
|
||||
PURE static inline convertedTypeAndAccess_t
|
||||
convertArchToTypeAndAccess(word_t dr7, uint16_t bp_num)
|
||||
{
|
||||
convertedTypeAndAccess_t ret;
|
||||
|
|
@ -207,7 +207,7 @@ convertArchToTypeAndAccess(word_t dr7, uint16_t bp_num)
|
|||
* @param size An integer for the operand size of the breakpoint.
|
||||
* @return Converted, hardware-specific value.
|
||||
*/
|
||||
static inline word_t
|
||||
PURE static inline word_t
|
||||
convertSizeToArch(uint16_t bp_num, word_t type, word_t size)
|
||||
{
|
||||
if (type == seL4_InstructionBreakpoint) {
|
||||
|
|
@ -252,7 +252,7 @@ convertSizeToArch(uint16_t bp_num, word_t type, word_t size)
|
|||
* @param n Breakpoint number.
|
||||
* @return Converted size value.
|
||||
*/
|
||||
static inline word_t
|
||||
PURE static inline word_t
|
||||
convertArchToSize(word_t dr7, uint16_t bp_num)
|
||||
{
|
||||
word_t type;
|
||||
|
|
@ -306,11 +306,11 @@ convertArchToSize(word_t dr7, uint16_t bp_num)
|
|||
* @param bp_num Hardware breakpoint ID. Usually an integer from 0..N.
|
||||
*/
|
||||
static void
|
||||
enableBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
enableBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t enable_bit;
|
||||
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
assert(bp_num < X86_DEBUG_BP_N_REGS);
|
||||
|
||||
switch (bp_num) {
|
||||
|
|
@ -328,18 +328,18 @@ enableBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
break;
|
||||
}
|
||||
|
||||
bitwiseOrDr7Context(uds, enable_bit);
|
||||
bitwiseOrDr7Context(t, enable_bit);
|
||||
}
|
||||
|
||||
/** Disables a breakpoint without clearing its configuration.
|
||||
* @param bp_num Hardware breakpoint ID. Usually an integer from 0..N.
|
||||
*/
|
||||
static void
|
||||
disableBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
disableBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t disable_mask;
|
||||
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
assert(bp_num < X86_DEBUG_BP_N_REGS);
|
||||
|
||||
switch (bp_num) {
|
||||
|
|
@ -357,21 +357,21 @@ disableBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
break;
|
||||
}
|
||||
|
||||
bitwiseAndDr7Context(uds, disable_mask);
|
||||
bitwiseAndDr7Context(t, disable_mask);
|
||||
}
|
||||
|
||||
/** Returns a boolean for whether or not a breakpoint is enabled.
|
||||
* @param bp_num Hardware breakpoint ID. Usually an integer from 0..N.
|
||||
*/
|
||||
static bool_t
|
||||
breakpointIsEnabled(arch_tcb_t *uds, uint16_t bp_num)
|
||||
breakpointIsEnabled(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t dr7;
|
||||
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
assert(bp_num < X86_DEBUG_BP_N_REGS);
|
||||
|
||||
dr7 = readDr7Context(uds);
|
||||
dr7 = readDr7Context(t);
|
||||
switch (bp_num) {
|
||||
case 0:
|
||||
return !!(dr7 & X86_DEBUG_BP0_ENABLE_BIT);
|
||||
|
|
@ -385,22 +385,24 @@ breakpointIsEnabled(arch_tcb_t *uds, uint16_t bp_num)
|
|||
}
|
||||
|
||||
static void
|
||||
setBpVaddrContext(user_breakpoint_state_t *uds, uint16_t bp_num, word_t vaddr)
|
||||
setBpVaddrContext(tcb_t *t, uint16_t bp_num, word_t vaddr)
|
||||
{
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
user_breakpoint_state_t *ubs = &t->tcbArch.tcbContext.breakpointState;
|
||||
|
||||
switch (bp_num) {
|
||||
case 0:
|
||||
uds->dr[0] = vaddr;
|
||||
ubs->dr[0] = vaddr;
|
||||
break;
|
||||
case 1:
|
||||
uds->dr[1] = vaddr;
|
||||
ubs->dr[1] = vaddr;
|
||||
break;
|
||||
case 2:
|
||||
uds->dr[2] = vaddr;
|
||||
ubs->dr[2] = vaddr;
|
||||
break;
|
||||
default:
|
||||
assert(bp_num == 3);
|
||||
uds->dr[3] = vaddr;
|
||||
ubs->dr[3] = vaddr;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
|
@ -418,36 +420,38 @@ setBpVaddrContext(user_breakpoint_state_t *uds, uint16_t bp_num, word_t vaddr)
|
|||
* @param rw Access type that should trigger the BP (read/write).
|
||||
*/
|
||||
void
|
||||
setBreakpoint(arch_tcb_t *uds,
|
||||
setBreakpoint(tcb_t *t,
|
||||
uint16_t bp_num, word_t vaddr, word_t types, word_t size, word_t rw)
|
||||
{
|
||||
word_t dr7val;
|
||||
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
|
||||
dr7val = convertTypeAndAccessToArch(bp_num, types, rw);
|
||||
dr7val |= convertSizeToArch(bp_num, types, size);
|
||||
|
||||
setBpVaddrContext(&uds->tcbContext.breakpointState, bp_num, vaddr);
|
||||
unsetDr7BitsFor(uds, bp_num);
|
||||
bitwiseOrDr7Context(uds, dr7val);
|
||||
enableBreakpoint(uds, bp_num);
|
||||
setBpVaddrContext(t, bp_num, vaddr);
|
||||
unsetDr7BitsFor(t, bp_num);
|
||||
bitwiseOrDr7Context(t, dr7val);
|
||||
enableBreakpoint(t, bp_num);
|
||||
}
|
||||
|
||||
static word_t
|
||||
getBpVaddrContext(user_breakpoint_state_t *uds, uint16_t bp_num)
|
||||
getBpVaddrContext(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
assert(uds != NULL);
|
||||
assert(t != NULL);
|
||||
user_breakpoint_state_t *ubs = &t->tcbArch.tcbContext.breakpointState;
|
||||
|
||||
switch (bp_num) {
|
||||
case 0:
|
||||
return uds->dr[0];
|
||||
return ubs->dr[0];
|
||||
case 1:
|
||||
return uds->dr[1];
|
||||
return ubs->dr[1];
|
||||
case 2:
|
||||
return uds->dr[2];
|
||||
return ubs->dr[2];
|
||||
default:
|
||||
assert(bp_num == 3);
|
||||
return uds->dr[3];
|
||||
return ubs->dr[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,19 +465,19 @@ getBpVaddrContext(user_breakpoint_state_t *uds, uint16_t bp_num)
|
|||
* @return Structure containing information about the status of the breakpoint.
|
||||
*/
|
||||
getBreakpoint_t
|
||||
getBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
getBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
word_t dr7val;
|
||||
getBreakpoint_t ret;
|
||||
convertedTypeAndAccess_t res;
|
||||
|
||||
dr7val = readDr7Context(uds);
|
||||
ret.vaddr = getBpVaddrContext(&uds->tcbContext.breakpointState, bp_num);
|
||||
dr7val = readDr7Context(t);
|
||||
ret.vaddr = getBpVaddrContext(t, bp_num);
|
||||
ret.size = convertArchToSize(dr7val, bp_num);
|
||||
res = convertArchToTypeAndAccess(dr7val, bp_num);
|
||||
ret.type = res.type;
|
||||
ret.rw = res.rw;
|
||||
ret.is_enabled = breakpointIsEnabled(uds, bp_num);
|
||||
ret.is_enabled = breakpointIsEnabled(t, bp_num);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -484,11 +488,11 @@ getBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
|||
* @param bp_num The hardware breakpoint ID you'd like to clear.
|
||||
*/
|
||||
void
|
||||
unsetBreakpoint(arch_tcb_t *uds, uint16_t bp_num)
|
||||
unsetBreakpoint(tcb_t *t, uint16_t bp_num)
|
||||
{
|
||||
disableBreakpoint(uds, bp_num);
|
||||
unsetDr7BitsFor(uds, bp_num);
|
||||
setBpVaddrContext(&uds->tcbContext.breakpointState, bp_num, 0);
|
||||
disableBreakpoint(t, bp_num);
|
||||
unsetDr7BitsFor(t, bp_num);
|
||||
setBpVaddrContext(t, bp_num, 0);
|
||||
}
|
||||
|
||||
/** Used in the exception path to determine if an exception was caused by
|
||||
|
|
@ -504,7 +508,7 @@ typedef struct {
|
|||
} testAndResetSingleStepException_t;
|
||||
|
||||
static testAndResetSingleStepException_t
|
||||
testAndResetSingleStepException(arch_tcb_t *uc)
|
||||
testAndResetSingleStepException(tcb_t *t)
|
||||
{
|
||||
testAndResetSingleStepException_t ret;
|
||||
word_t dr6;
|
||||
|
|
@ -516,7 +520,7 @@ testAndResetSingleStepException(arch_tcb_t *uc)
|
|||
}
|
||||
|
||||
ret.ret = true;
|
||||
ret.instr_vaddr = uc->tcbContext.registers[FaultIP];
|
||||
ret.instr_vaddr = t->tcbArch.tcbContext.registers[FaultIP];
|
||||
bitwiseAndDr6Reg(~X86_DEBUG_DR6_SINGLE_STEP_FLAG);
|
||||
|
||||
/* And that's not all: if the breakpoint is an instruction breakpoint, we
|
||||
|
|
@ -531,12 +535,12 @@ testAndResetSingleStepException(arch_tcb_t *uc)
|
|||
* Intel manuals, vol3, section 17.3.1.1.
|
||||
*/
|
||||
/* This will automatically be popped by restore_user_context() */
|
||||
uc->tcbContext.registers[FLAGS] |= X86_DEBUG_EFLAGS_RESUME_FLAG;
|
||||
t->tcbArch.tcbContext.registers[FLAGS] |= X86_DEBUG_EFLAGS_RESUME_FLAG;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t
|
||||
configureSingleStepping(arch_tcb_t *uc, uint16_t bp_num, word_t n_instr,
|
||||
configureSingleStepping(tcb_t *t, uint16_t bp_num, word_t n_instr,
|
||||
UNUSED bool_t is_reply)
|
||||
{
|
||||
/* On x86 no hardware breakpoints are needed for single stepping. */
|
||||
|
|
@ -544,13 +548,13 @@ configureSingleStepping(arch_tcb_t *uc, uint16_t bp_num, word_t n_instr,
|
|||
/* If n_instr (number of instructions to single-step) is 0, that is the
|
||||
* same as requesting that single-stepping be disabled.
|
||||
*/
|
||||
uc->tcbContext.breakpointState.single_step_enabled = false;
|
||||
uc->tcbContext.registers[FLAGS] &= ~X86_DEBUG_EFLAGS_TRAP_FLAG;
|
||||
t->tcbArch.tcbContext.breakpointState.single_step_enabled = false;
|
||||
t->tcbArch.tcbContext.registers[FLAGS] &= ~X86_DEBUG_EFLAGS_TRAP_FLAG;
|
||||
} else {
|
||||
uc->tcbContext.breakpointState.single_step_enabled = true;
|
||||
t->tcbArch.tcbContext.breakpointState.single_step_enabled = true;
|
||||
}
|
||||
|
||||
uc->tcbContext.breakpointState.n_instructions = n_instr;
|
||||
t->tcbArch.tcbContext.breakpointState.n_instructions = n_instr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +580,7 @@ typedef struct {
|
|||
} getAndResetActiveBreakpoint_t;
|
||||
|
||||
static getAndResetActiveBreakpoint_t
|
||||
getAndResetActiveBreakpoint(arch_tcb_t *at)
|
||||
getAndResetActiveBreakpoint(tcb_t *t)
|
||||
{
|
||||
convertedTypeAndAccess_t tmp;
|
||||
getAndResetActiveBreakpoint_t ret;
|
||||
|
|
@ -596,8 +600,8 @@ getAndResetActiveBreakpoint(arch_tcb_t *at)
|
|||
return ret;
|
||||
}
|
||||
|
||||
tmp = convertArchToTypeAndAccess(readDr7Context(at), ret.bp_num);
|
||||
ret.vaddr = getBpVaddrContext(&at->tcbContext.breakpointState, ret.bp_num);
|
||||
tmp = convertArchToTypeAndAccess(readDr7Context(t), ret.bp_num);
|
||||
ret.vaddr = getBpVaddrContext(t, ret.bp_num);
|
||||
ret.reason = tmp.type;
|
||||
|
||||
bitwiseAndDr6Reg(~BIT(ret.bp_num));
|
||||
|
|
@ -607,11 +611,11 @@ getAndResetActiveBreakpoint(arch_tcb_t *at)
|
|||
exception_t
|
||||
handleUserLevelDebugException(int int_vector)
|
||||
{
|
||||
arch_tcb_t *context;
|
||||
tcb_t *ct;
|
||||
getAndResetActiveBreakpoint_t active_bp;
|
||||
testAndResetSingleStepException_t single_step_info;
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
ksKernelEntry.path = Entry_UserLevelFault;
|
||||
ksKernelEntry.word = int_vector;
|
||||
#else
|
||||
|
|
@ -622,7 +626,7 @@ handleUserLevelDebugException(int int_vector)
|
|||
benchmark_track_start();
|
||||
#endif
|
||||
|
||||
context = &NODE_STATE(ksCurThread)->tcbArch;
|
||||
ct = NODE_STATE(ksCurThread);
|
||||
|
||||
/* Software break request (INT3) is detected by the vector number */
|
||||
if (int_vector == int_software_break_request) {
|
||||
|
|
@ -630,20 +634,20 @@ handleUserLevelDebugException(int int_vector)
|
|||
0, seL4_SoftwareBreakRequest);
|
||||
} else {
|
||||
/* Hardware breakpoint trigger is detected using DR6 */
|
||||
active_bp = getAndResetActiveBreakpoint(context);
|
||||
active_bp = getAndResetActiveBreakpoint(ct);
|
||||
if (active_bp.bp_num >= 0) {
|
||||
current_fault = seL4_Fault_DebugException_new(active_bp.vaddr,
|
||||
active_bp.bp_num,
|
||||
active_bp.reason);
|
||||
} else {
|
||||
single_step_info = testAndResetSingleStepException(context);
|
||||
single_step_info = testAndResetSingleStepException(ct);
|
||||
if (single_step_info.ret == true) {
|
||||
/* If the caller asked us to skip over N instructions before
|
||||
* generating the next single-step breakpoint, we shouldn't
|
||||
* bother to construct a fault message until we've skipped N
|
||||
* instructions.
|
||||
*/
|
||||
if (singleStepFaultCounterReady(context) == false) {
|
||||
if (singleStepFaultCounterReady(ct) == false) {
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
current_fault = seL4_Fault_DebugException_new(single_step_info.instr_vaddr,
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ static void sendIOPT(unsigned long address, unsigned int level)
|
|||
if (vtd_pte_get_addr(vtd_pte) != 0) {
|
||||
sendWord(i);
|
||||
sendWord(vtd_pte.words[0]);
|
||||
#if CONFIG_ARCH_IA32
|
||||
#ifdef CONFIG_ARCH_IA32
|
||||
sendWord(vtd_pte.words[1]);
|
||||
#endif
|
||||
if (level == x86KSnumIOPTLevels) {
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ applyFixedBits(uint32_t original, uint32_t high, uint32_t low)
|
|||
void
|
||||
vcpu_init(vcpu_t *vcpu)
|
||||
{
|
||||
vcpu->tcb = NULL;
|
||||
vcpu->vcpuTCB = NULL;
|
||||
vcpu->launched = false;
|
||||
|
||||
memcpy(vcpu->vmcs, &vmcs_revision, 4);
|
||||
|
|
@ -481,17 +481,17 @@ vcpu_init(vcpu_t *vcpu)
|
|||
static void
|
||||
dissociateVcpuTcb(tcb_t *tcb, vcpu_t *vcpu)
|
||||
{
|
||||
assert(tcb->tcbArch.vcpu == vcpu);
|
||||
assert(vcpu->tcb == tcb);
|
||||
tcb->tcbArch.vcpu = NULL;
|
||||
vcpu->tcb = NULL;
|
||||
assert(tcb->tcbArch.tcbVCPU == vcpu);
|
||||
assert(vcpu->vcpuTCB == tcb);
|
||||
tcb->tcbArch.tcbVCPU = NULL;
|
||||
vcpu->vcpuTCB = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
vcpu_finalise(vcpu_t *vcpu)
|
||||
{
|
||||
if (vcpu->tcb) {
|
||||
dissociateVcpuTcb(vcpu->tcb, vcpu);
|
||||
if (vcpu->vcpuTCB) {
|
||||
dissociateVcpuTcb(vcpu->vcpuTCB, vcpu);
|
||||
}
|
||||
if (ARCH_NODE_STATE_ON_CORE(x86KSCurrentVCPU, vcpu->last_cpu) == vcpu) {
|
||||
#if CONFIG_MAX_NUM_NODES > 1
|
||||
|
|
@ -508,14 +508,14 @@ vcpu_finalise(vcpu_t *vcpu)
|
|||
static void
|
||||
associateVcpuTcb(tcb_t *tcb, vcpu_t *vcpu)
|
||||
{
|
||||
if (tcb->tcbArch.vcpu) {
|
||||
dissociateVcpuTcb(tcb, tcb->tcbArch.vcpu);
|
||||
if (tcb->tcbArch.tcbVCPU) {
|
||||
dissociateVcpuTcb(tcb, tcb->tcbArch.tcbVCPU);
|
||||
}
|
||||
if (vcpu->tcb) {
|
||||
dissociateVcpuTcb(vcpu->tcb, vcpu);
|
||||
if (vcpu->vcpuTCB) {
|
||||
dissociateVcpuTcb(vcpu->vcpuTCB, vcpu);
|
||||
}
|
||||
vcpu->tcb = tcb;
|
||||
tcb->tcbArch.vcpu = vcpu;
|
||||
vcpu->vcpuTCB = tcb;
|
||||
tcb->tcbArch.tcbVCPU = vcpu;
|
||||
}
|
||||
|
||||
static exception_t
|
||||
|
|
@ -966,7 +966,7 @@ vcpu_sysvmenter_reply_to_user(tcb_t *tcb)
|
|||
vcpu_t *vcpu;
|
||||
|
||||
buffer = lookupIPCBuffer(true, tcb);
|
||||
vcpu = tcb->tcbArch.vcpu;
|
||||
vcpu = tcb->tcbArch.tcbVCPU;
|
||||
|
||||
assert(vcpu);
|
||||
|
||||
|
|
@ -1128,7 +1128,7 @@ setMRs_vmexit(uint32_t reason, word_t qualification)
|
|||
setMR(NODE_STATE(ksCurThread), buffer, SEL4_VMENTER_FAULT_CR3_MR, vmread(VMX_GUEST_CR3));
|
||||
|
||||
for (i = 0; i < n_vcpu_gp_register; i++) {
|
||||
setMR(NODE_STATE(ksCurThread), buffer, SEL4_VMENTER_FAULT_EAX + i, NODE_STATE(ksCurThread)->tcbArch.vcpu->gp_registers[i]);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, SEL4_VMENTER_FAULT_EAX + i, NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->gp_registers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1152,7 +1152,7 @@ static inline void
|
|||
finishVmexitSaving(void)
|
||||
{
|
||||
vcpu_t *vcpu = ARCH_NODE_STATE(x86KSCurrentVCPU);
|
||||
assert(vcpu == NODE_STATE(ksCurThread)->tcbArch.vcpu);
|
||||
assert(vcpu == NODE_STATE(ksCurThread)->tcbArch.tcbVCPU);
|
||||
vcpu->launched = true;
|
||||
/* Update our cache of what is in the vmcs. This is the only value
|
||||
* that we cache that can be modified by the guest during execution */
|
||||
|
|
@ -1170,7 +1170,7 @@ finishVmexitSaving(void)
|
|||
* value from the vmcs (thus pulling in any modifications the guest made) but removing
|
||||
* the task switched flag that we set and then adding back in the task switched flag
|
||||
* that may be in the desired current cr0 */
|
||||
vcpu->cr0 = (vcpu->cached_cr0 & ~CR0_TASK_SWITCH) | (NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 & CR0_TASK_SWITCH);
|
||||
vcpu->cr0 = (vcpu->cached_cr0 & ~CR0_TASK_SWITCH) | (NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 & CR0_TASK_SWITCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1206,14 +1206,14 @@ handleVmexit(void)
|
|||
* exception AND the owner of this vcpu has not requested that these exceptions be forwarded
|
||||
* to them (i.e. if they have not explicitly set the unimplemented device exception in the
|
||||
* exception_bitmap) */
|
||||
if (reason == EXCEPTION_OR_NMI && !(NODE_STATE(ksCurThread)->tcbArch.vcpu->exception_bitmap & BIT(int_unimpl_dev))) {
|
||||
if (reason == EXCEPTION_OR_NMI && !(NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->exception_bitmap & BIT(int_unimpl_dev))) {
|
||||
interrupt = vmread(VMX_DATA_EXIT_INTERRUPT_INFO);
|
||||
/* The exception number is the bottom 8 bits of the interrupt info */
|
||||
if ((interrupt & 0xff) == int_unimpl_dev) {
|
||||
switchLocalFpuOwner(&NODE_STATE(ksCurThread)->tcbArch.vcpu->fpuState);
|
||||
switchLocalFpuOwner(&NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->fpuState);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
} else if (reason == CONTROL_REGISTER && !(NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0_mask & CR0_TASK_SWITCH)) {
|
||||
} else if (reason == CONTROL_REGISTER && !(NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0_mask & CR0_TASK_SWITCH)) {
|
||||
/* we get here if the guest is attempting to write to a control register that is set (by
|
||||
* a 1 bit in the cr0 mask) as being owned by the host. If we got here then the previous check
|
||||
* on cr0_mask meant that the VCPU owner did not claim ownership of the the task switch bit
|
||||
|
|
@ -1238,19 +1238,19 @@ handleVmexit(void)
|
|||
* get this one from the vmcs */
|
||||
value = vmread(VMX_GUEST_RSP);
|
||||
} else {
|
||||
value = NODE_STATE(ksCurThread)->tcbArch.vcpu->gp_registers[source];
|
||||
value = NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->gp_registers[source];
|
||||
}
|
||||
/* First unset the task switch bit in cr0 */
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 &= ~CR0_TASK_SWITCH;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 &= ~CR0_TASK_SWITCH;
|
||||
/* now set it to the value we were given */
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 |= value & CR0_TASK_SWITCH;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 |= value & CR0_TASK_SWITCH;
|
||||
/* check if there are any parts of the write remaining to forward. we only need
|
||||
* to consider bits that the hardware will not have handled without faulting, which
|
||||
* is writing any bit such that it is different to the shadow, but only considering
|
||||
* bits that the VCPU owner has declared that they want to own (via the cr0_shadow)
|
||||
*/
|
||||
if (!((value ^ NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0_shadow) &
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0_mask)) {
|
||||
if (!((value ^ NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0_shadow) &
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0_mask)) {
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1258,15 +1258,15 @@ handleVmexit(void)
|
|||
}
|
||||
case VMX_EXIT_QUAL_TYPE_CLTS: {
|
||||
/* Easy case. Just remove the task switch bit out of cr0 */
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 &= ~CR0_TASK_SWITCH;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 &= ~CR0_TASK_SWITCH;
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
case VMX_EXIT_QUAL_TYPE_LMSW: {
|
||||
uint16_t value = vmx_data_exit_qualification_control_regster_get_data(qual);
|
||||
/* First unset the task switch bit in cr0 */
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 &= ~CR0_TASK_SWITCH;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 &= ~CR0_TASK_SWITCH;
|
||||
/* now set it to the value we were given */
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0 |= value & CR0_TASK_SWITCH;
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0 |= value & CR0_TASK_SWITCH;
|
||||
/* check if there are any parts of the write remaining to forward. we only need
|
||||
* to consider bits that the hardware will not have handled without faulting, which
|
||||
* is writing any bit such that it is different to the shadow, but only considering
|
||||
|
|
@ -1274,8 +1274,8 @@ handleVmexit(void)
|
|||
* Additionally since LMSW only loads the bottom 4 bits of CR0 we only consider
|
||||
* the low 4 bits
|
||||
*/
|
||||
if (!((value ^ NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0_shadow) &
|
||||
NODE_STATE(ksCurThread)->tcbArch.vcpu->cr0_mask & MASK(4))) {
|
||||
if (!((value ^ NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0_shadow) &
|
||||
NODE_STATE(ksCurThread)->tcbArch.tcbVCPU->cr0_mask & MASK(4))) {
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1404,7 +1404,7 @@ setEPTRoot(cap_t vmxSpace, vcpu_t* vcpu)
|
|||
static void
|
||||
handleLazyFpu(void)
|
||||
{
|
||||
vcpu_t *vcpu = NODE_STATE(ksCurThread)->tcbArch.vcpu;
|
||||
vcpu_t *vcpu = NODE_STATE(ksCurThread)->tcbArch.tcbVCPU;
|
||||
word_t cr0 = vcpu->cr0;
|
||||
word_t exception_bitmap = vcpu->exception_bitmap;
|
||||
word_t cr0_mask = vcpu->cr0_mask;
|
||||
|
|
@ -1527,7 +1527,7 @@ storeVPID(vcpu_t *vcpu, vpid_t vpid)
|
|||
void
|
||||
restoreVMCS(void)
|
||||
{
|
||||
vcpu_t *expected_vmcs = NODE_STATE(ksCurThread)->tcbArch.vcpu;
|
||||
vcpu_t *expected_vmcs = NODE_STATE(ksCurThread)->tcbArch.tcbVCPU;
|
||||
|
||||
/* Check that the right VMCS is active and current. */
|
||||
if (ARCH_NODE_STATE(x86KSCurrentVCPU) != expected_vmcs) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <assert.h>
|
||||
#include <machine/io.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
void _fail(
|
||||
const char* s,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ word_t ksDomScheduleIdx;
|
|||
/* Only used by lockTLBEntry */
|
||||
word_t tlbLockCount = 0;
|
||||
|
||||
#if (defined DEBUG || defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#if (defined CONFIG_DEBUG_BUILD || defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
kernel_entry_t ksKernelEntry;
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
|
|
|||
|
|
@ -389,17 +389,17 @@ decodeSetAffinity(cap_t cap, word_t length, word_t *buffer)
|
|||
|
||||
#ifdef CONFIG_HARDWARE_DEBUG_API
|
||||
static exception_t
|
||||
invokeConfigureSingleStepping(word_t *buffer, arch_tcb_t *context,
|
||||
invokeConfigureSingleStepping(word_t *buffer, tcb_t *t,
|
||||
uint16_t bp_num, word_t n_instrs)
|
||||
{
|
||||
bool_t bp_was_consumed;
|
||||
|
||||
bp_was_consumed = configureSingleStepping(context, bp_num, n_instrs, false);
|
||||
bp_was_consumed = configureSingleStepping(t, bp_num, n_instrs, false);
|
||||
if (n_instrs == 0) {
|
||||
unsetBreakpointUsedFlag(context, bp_num);
|
||||
unsetBreakpointUsedFlag(t, bp_num);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, 0, false);
|
||||
} else {
|
||||
setBreakpointUsedFlag(context, bp_num);
|
||||
setBreakpointUsedFlag(t, bp_num);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, 0, bp_was_consumed);
|
||||
}
|
||||
return EXCEPTION_NONE;
|
||||
|
|
@ -411,32 +411,30 @@ decodeConfigureSingleStepping(cap_t cap, word_t *buffer)
|
|||
uint16_t bp_num;
|
||||
word_t n_instrs;
|
||||
tcb_t *tcb;
|
||||
arch_tcb_t *context;
|
||||
syscall_error_t syserr;
|
||||
|
||||
tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||
context = &tcb->tcbArch;
|
||||
|
||||
bp_num = getSyscallArg(0, buffer);
|
||||
n_instrs = getSyscallArg(1, buffer);
|
||||
|
||||
syserr = Arch_decodeConfigureSingleStepping(context, bp_num, n_instrs, false);
|
||||
syserr = Arch_decodeConfigureSingleStepping(tcb, bp_num, n_instrs, false);
|
||||
if (syserr.type != seL4_NoError) {
|
||||
current_syscall_error = syserr;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
return invokeConfigureSingleStepping(buffer, context, bp_num, n_instrs);
|
||||
return invokeConfigureSingleStepping(buffer, tcb, bp_num, n_instrs);
|
||||
}
|
||||
|
||||
static exception_t
|
||||
invokeSetBreakpoint(arch_tcb_t *context, uint16_t bp_num,
|
||||
invokeSetBreakpoint(tcb_t *tcb, uint16_t bp_num,
|
||||
word_t vaddr, word_t type, word_t size, word_t rw)
|
||||
{
|
||||
setBreakpoint(context, bp_num, vaddr, type, size, rw);
|
||||
setBreakpoint(tcb, bp_num, vaddr, type, size, rw);
|
||||
/* Signal restore_user_context() to pop the breakpoint context on return. */
|
||||
setBreakpointUsedFlag(context, bp_num);
|
||||
setBreakpointUsedFlag(tcb, bp_num);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +444,6 @@ decodeSetBreakpoint(cap_t cap, word_t *buffer)
|
|||
uint16_t bp_num;
|
||||
word_t vaddr, type, size, rw;
|
||||
tcb_t *tcb;
|
||||
arch_tcb_t *context;
|
||||
syscall_error_t error;
|
||||
|
||||
tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||
|
|
@ -548,25 +545,23 @@ decodeSetBreakpoint(cap_t cap, word_t *buffer)
|
|||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
context = &tcb->tcbArch;
|
||||
|
||||
error = Arch_decodeSetBreakpoint(context, bp_num, vaddr, type, size, rw);
|
||||
error = Arch_decodeSetBreakpoint(tcb, bp_num, vaddr, type, size, rw);
|
||||
if (error.type != seL4_NoError) {
|
||||
current_syscall_error = error;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
return invokeSetBreakpoint(context, bp_num,
|
||||
return invokeSetBreakpoint(tcb, bp_num,
|
||||
vaddr, type, size, rw);
|
||||
}
|
||||
|
||||
static exception_t
|
||||
invokeGetBreakpoint(word_t *buffer, arch_tcb_t *context, uint16_t bp_num)
|
||||
invokeGetBreakpoint(word_t *buffer, tcb_t *tcb, uint16_t bp_num)
|
||||
{
|
||||
getBreakpoint_t res;
|
||||
|
||||
res = getBreakpoint(context, bp_num);
|
||||
res = getBreakpoint(tcb, bp_num);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, 0, res.vaddr);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, 1, res.type);
|
||||
setMR(NODE_STATE(ksCurThread), buffer, 2, res.size);
|
||||
|
|
@ -580,30 +575,27 @@ decodeGetBreakpoint(cap_t cap, word_t *buffer)
|
|||
{
|
||||
tcb_t *tcb;
|
||||
uint16_t bp_num;
|
||||
arch_tcb_t *context;
|
||||
syscall_error_t error;
|
||||
|
||||
tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||
bp_num = getSyscallArg(0, buffer);
|
||||
|
||||
context = &tcb->tcbArch;
|
||||
|
||||
error = Arch_decodeGetBreakpoint(context, bp_num);
|
||||
error = Arch_decodeGetBreakpoint(tcb, bp_num);
|
||||
if (error.type != seL4_NoError) {
|
||||
current_syscall_error = error;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
return invokeGetBreakpoint(buffer, context, bp_num);
|
||||
return invokeGetBreakpoint(buffer, tcb, bp_num);
|
||||
}
|
||||
|
||||
static exception_t
|
||||
invokeUnsetBreakpoint(arch_tcb_t *context, uint16_t bp_num)
|
||||
invokeUnsetBreakpoint(tcb_t *tcb, uint16_t bp_num)
|
||||
{
|
||||
/* Maintain the bitfield of in-use breakpoints. */
|
||||
unsetBreakpoint(context, bp_num);
|
||||
unsetBreakpointUsedFlag(context, bp_num);
|
||||
unsetBreakpoint(tcb, bp_num);
|
||||
unsetBreakpointUsedFlag(tcb, bp_num);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -612,22 +604,19 @@ decodeUnsetBreakpoint(cap_t cap, word_t *buffer)
|
|||
{
|
||||
tcb_t *tcb;
|
||||
uint16_t bp_num;
|
||||
arch_tcb_t *context;
|
||||
syscall_error_t error;
|
||||
|
||||
tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||
bp_num = getSyscallArg(0, buffer);
|
||||
|
||||
context = &tcb->tcbArch;
|
||||
|
||||
error = Arch_decodeUnsetBreakpoint(context, bp_num);
|
||||
error = Arch_decodeUnsetBreakpoint(tcb, bp_num);
|
||||
if (error.type != seL4_NoError) {
|
||||
current_syscall_error = error;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
return invokeUnsetBreakpoint(context, bp_num);
|
||||
return invokeUnsetBreakpoint(tcb, bp_num);
|
||||
}
|
||||
#endif /* CONFIG_HARDWARE_DEBUG_API */
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,12 @@ enum IPGConstants {
|
|||
|
||||
#define TIMER_INTERVAL_MS (CONFIG_TIMER_TICK_MS)
|
||||
#define TIMER_CLOCK_SRC IPG_CLK_32K
|
||||
#define TIMER_CLOCK_HZ 32768
|
||||
#define TIMER_CLOCK_HZ 32768u
|
||||
|
||||
#if (TIMER_INTERVAL_MS >= (0xFFFFFFFF / TIMER_CLOCK_HZ))
|
||||
#error "Timer reload val out of range"
|
||||
#else
|
||||
#define TIMER_RELOAD_VAL (TIMER_CLOCK_HZ * TIMER_INTERVAL_MS / 1000)
|
||||
#if TIMER_RELOAD_VAL <= 0 || TIMER_RELOAD_VAL > 0xffffffff
|
||||
#error TIMER_RELOAD_VAL out of range
|
||||
#endif
|
||||
|
||||
interrupt_t active_irq = irqInvalid;
|
||||
|
|
|
|||
Loading…
Reference in a new issue