Merge branch master into fix-makefile

This commit is contained in:
Adrian Danis 2017-04-24 11:51:47 +10:00
commit 468c7654ce
77 changed files with 599 additions and 461 deletions

10
Kconfig
View file

@ -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

View file

@ -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
############################################################

View file

@ -1 +1 @@
5.0.0
5.0.0-dev

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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:

View file

@ -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);
}
}

View file

@ -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
}

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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 "

View 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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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;

View file

@ -274,7 +274,7 @@ struct vcpu {
#endif
/* TCB associated with this VCPU. */
struct tcb *tcb;
struct tcb *vcpuTCB;
bool_t launched;
/* Currently assigned VPID */

View file

@ -13,7 +13,7 @@
#include <util.h>
#ifdef DEBUG
#ifdef CONFIG_DEBUG_BUILD
void _fail(
const char* str,

View file

@ -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

View file

@ -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 */

View file

@ -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
}

View file

@ -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

View file

@ -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)

View file

@ -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))

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -28,7 +28,7 @@
#include <kernel/traps.h>
#include <arch/machine.h>
#ifdef DEBUG
#ifdef CONFIG_DEBUG_BUILD
#include <arch/machine/capdl.h>
#endif

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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. */

View file

@ -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;

View file

@ -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 */

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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) {

View file

@ -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) {

View file

@ -11,7 +11,7 @@
#include <assert.h>
#include <machine/io.h>
#ifdef DEBUG
#ifdef CONFIG_DEBUG_BUILD
void _fail(
const char* s,

View file

@ -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 */

View file

@ -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 */

View file

@ -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;