diff options
| -rw-r--r-- | sys/arch/i386/conf/files.i386 | 1 | ||||
| -rw-r--r-- | sys/arch/i386/i386/i386_trap.S | 6 | ||||
| -rw-r--r-- | sys/arch/x86/include/cpufunc.h | 32 | ||||
| -rw-r--r-- | sys/lockdoc/init_data.c | 68 | ||||
| -rw-r--r-- | sys/lockdoc/log.c | 134 | ||||
| -rw-r--r-- | sys/sys/lockdoc.h | 64 |
6 files changed, 160 insertions, 145 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 17c115a8c7c..f527b0ab9b2 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -48,6 +48,7 @@ defparam opt_beep.h BEEP_ONHALT_PITCH=1500 defparam opt_beep.h BEEP_ONHALT_PERIOD=250 +file lockdoc/init_data.c lockdoc file lockdoc/log.c lockdoc file lockdoc/test.c lockdoc diff --git a/sys/arch/i386/i386/i386_trap.S b/sys/arch/i386/i386/i386_trap.S index 22bf694f7dc..70e8f118ef6 100644 --- a/sys/arch/i386/i386/i386_trap.S +++ b/sys/arch/i386/i386/i386_trap.S @@ -408,13 +408,7 @@ calltrap: addl $1,CPUVAR(NTRAP) /* statistical info */ adcl $0,CPUVAR(NTRAP)+4 pushl %esp -#ifdef LOCKDOC - call _C_LABEL(trace_irqs_off) -#endif call _C_LABEL(trap) -#ifdef LOCKDOC - call _C_LABEL(trace_irqs_on) -#endif addl $4,%esp _C_LABEL(trapreturn): .globl trapreturn testb $CHK_UPL,TF_CS(%esp) diff --git a/sys/arch/x86/include/cpufunc.h b/sys/arch/x86/include/cpufunc.h index 6daa7565b1e..c2615991036 100644 --- a/sys/arch/x86/include/cpufunc.h +++ b/sys/arch/x86/include/cpufunc.h @@ -376,32 +376,27 @@ void x86_enable_intr(void); #else #ifdef LOCKDOC - -#define x86_disable_intr() __x86_disable_intr(__FILE__, __LINE__, __func__) -void __x86_disable_intr(const char *file, int line, const char *func); -u_long lockdoc_x86_disable_intr(void); - +static inline void +_x86_disable_intr(void) #else - static inline void x86_disable_intr(void) +#endif { __asm volatile ("cli" ::: "memory"); } -#endif /* LOCKDOC */ #ifdef LOCKDOC -#define x86_enable_intr() __x86_enable_intr(__FILE__, __LINE__, __func__) -void __x86_enable_intr(const char *file, int line, const char *func); -u_long lockdoc_x86_enable_intr(void); - +static inline void +_x86_enable_intr(void) #else static inline void x86_enable_intr(void) +#endif { __asm volatile ("sti" ::: "memory"); } -#endif /* LOCKDOC */ + #endif /* XENPV */ @@ -415,6 +410,19 @@ void x86_write_flags(u_long); void x86_reset(void); +/* + * This import is needed so that the interrupt functions are being redefined + * without having to add the lockdoc.h import to every single + * file those functions are being called. + * + * We have to include it this late into the file to avoid circular + * dependencies with the calls to x86_read_flags and x86_write_flags + * in lockdoc.h. + */ +#ifdef LOCKDOC +#include <sys/lockdoc.h> +#endif + /* -------------------------------------------------------------------------- */ /* diff --git a/sys/lockdoc/init_data.c b/sys/lockdoc/init_data.c new file mode 100644 index 00000000000..bce4ea7a20f --- /dev/null +++ b/sys/lockdoc/init_data.c @@ -0,0 +1,68 @@ +#include <arch/x86/include/cpufunc.h> +#include <sys/lwp.h> +#include <sys/lockdoc.h> + +#ifdef LOCKDOC + +void lockdoc_send_current_task_addr(void) { + u_long flags; + + flags = x86_read_flags(); + _x86_disable_intr(); + + memset(&la_buffer,0,sizeof(la_buffer)); + + la_buffer.action = LOCKDOC_CURRENT_TASK; + la_buffer.ptr = (uint32_t)((uint32_t)curcpu()->ci_self + offsetof(struct cpu_info, ci_curlwp)); + + outb_(PING_CHAR,IO_PORT_LOG); + + x86_write_flags(flags); +} + +void lockdoc_send_lwp_flag_offset(void) { + u_long flags; + + flags = x86_read_flags(); + _x86_disable_intr(); + + memset(&la_buffer,0,sizeof(la_buffer)); + + la_buffer.action = LOCKDOC_LWP_FLAG_OFFSET; + la_buffer.ptr = offsetof(struct lwp, l_pflag); + outb_(PING_CHAR,IO_PORT_LOG); + + x86_write_flags(flags); +} + +void lockdoc_send_pid_offset(void) { + u_long flags; + + flags = x86_read_flags(); + _x86_disable_intr(); + + memset(&la_buffer,0,sizeof(la_buffer)); + + la_buffer.action = LOCKDOC_PID_OFFSET; + la_buffer.ptr = offsetof(struct lwp, l_lid); + outb_(PING_CHAR,IO_PORT_LOG); + + x86_write_flags(flags); +} + +void lockdoc_send_kernel_version(void) { + u_long flags; + + flags = x86_read_flags(); + _x86_disable_intr(); + + memset(&la_buffer,0,sizeof(la_buffer)); + + snprintf((char*)&la_buffer.type, LOG_CHAR_BUFFER_LEN, "%s", "notimplemented"); // TODO Implement + la_buffer.action = LOCKDOC_KERNEL_VERSION; + outb_(PING_CHAR,IO_PORT_LOG); + + x86_write_flags(flags); +} + +#endif
\ No newline at end of file diff --git a/sys/lockdoc/log.c b/sys/lockdoc/log.c index 9f63e336958..b8207e54d46 100644 --- a/sys/lockdoc/log.c +++ b/sys/lockdoc/log.c @@ -88,9 +88,27 @@ inline void __rw_exit(krwlock_t * lock, const char* file, int line, const char* } #undef LOCK_TYPE -/* - * Yet to be implemented: Check https://man.netbsd.org/locking.9 (esp. IRQ, CVlock and BKL, check issue tracker) - */ +inline void __x86_disable_intr(const char* file, int line, const char* func) { + u_long eflags; + + eflags = x86_read_flags(); + if (eflags & (1 << 9)){ // Check if interrupts were enabled in the first place + lockdoc_log_lock(P_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); + } + + _x86_disable_intr(); +} + +inline void __x86_enable_intr(const char* file, int line, const char* func) { + u_long eflags; + + eflags = x86_read_flags(); + if (!(eflags & (1 << 9))){ // Check if interrupts were disabled in the first place + lockdoc_log_lock(V_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); + } + + _x86_enable_intr(); +} int32_t lockdoc_get_ctx(void) { if (curlwp == NULL) { @@ -102,118 +120,28 @@ int32_t lockdoc_get_ctx(void) { } } -void lockdoc_send_current_task_addr(void) { - u_long flags; - - flags = lockdoc_x86_disable_intr(); - - memset(&la_buffer,0,sizeof(la_buffer)); - - la_buffer.action = LOCKDOC_CURRENT_TASK; - la_buffer.ptr = (uint32_t)((uint32_t)curcpu()->ci_self + offsetof(struct cpu_info, ci_curlwp)); - - outb_(PING_CHAR,IO_PORT_LOG); - - lockdoc_x86_restore_intr(flags); -} - -void lockdoc_send_lwp_flag_offset(void) { - u_long flags; - - flags = lockdoc_x86_disable_intr(); - - memset(&la_buffer,0,sizeof(la_buffer)); - - la_buffer.action = LOCKDOC_LWP_FLAG_OFFSET; - la_buffer.ptr = offsetof(struct lwp, l_pflag); - outb_(PING_CHAR,IO_PORT_LOG); - - lockdoc_x86_restore_intr(flags); -} - -void lockdoc_send_pid_offset(void) { - u_long flags; - - flags = lockdoc_x86_disable_intr(); - - memset(&la_buffer,0,sizeof(la_buffer)); - - la_buffer.action = LOCKDOC_PID_OFFSET; - la_buffer.ptr = offsetof(struct lwp, l_lid); - outb_(PING_CHAR,IO_PORT_LOG); - - lockdoc_x86_restore_intr(flags); -} - -void lockdoc_send_kernel_version(void) { - u_long flags; - - flags = lockdoc_x86_disable_intr(); - - memset(&la_buffer,0,sizeof(la_buffer)); - - snprintf((char*)&la_buffer.type, LOG_CHAR_BUFFER_LEN, "%s", "notimplemented"); // TODO Implement - la_buffer.action = LOCKDOC_KERNEL_VERSION; - outb_(PING_CHAR,IO_PORT_LOG); - - lockdoc_x86_restore_intr(flags); +void __trace_irqs_on(struct trapframe *frame, const char *file, int line) { + lockdoc_log_lock(V_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); } -void trace_irqs_on(struct trapframe *frame) { +void __trace_irqs_on_check(struct trapframe *frame, const char *file, int line) { u_long cur_eflags; cur_eflags = x86_read_flags(); if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { - lockdoc_log_lock(V_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", "dummy", LOCK_NONE); + lockdoc_log_lock(V_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); } } -void trace_irqs_off(struct trapframe *frame) { +void __trace_irqs_off(struct trapframe *frame, const char *file, int line) { + lockdoc_log_lock(P_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", frame->tf_trapno); +} + +void __trace_irqs_off_check(struct trapframe *frame, const char *file, int line) { u_long cur_eflags; cur_eflags = x86_read_flags(); if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { - lockdoc_log_lock(P_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", "dummy", frame->tf_trapno); + lockdoc_log_lock(P_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", frame->tf_trapno); } } -void __x86_disable_intr(const char *file, int line, const char *func){ - u_long eflags; - - eflags = x86_read_flags(); - if (eflags & (1 << 9)){ // Check if interrupts were enabled in the first place - lockdoc_log_lock(P_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); - } - lockdoc_x86_disable_intr(); -} - -u_long lockdoc_x86_disable_intr(void){ - u_long eflags; - - eflags = x86_read_flags(); - __asm volatile ("cli" ::: "memory"); - return eflags; - -} - -void __x86_enable_intr(const char *file, int line, const char *func){ - u_long eflags; - - eflags = x86_read_flags(); - if (!(eflags & (1 << 9))){ // Check if interrupts were disabled in the first place - lockdoc_log_lock(V_WRITE, (void *)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", "dummy", LOCK_NONE); - } - lockdoc_x86_enable_intr(); -} - -u_long lockdoc_x86_enable_intr(void){ - u_long eflags; - - eflags = x86_read_flags(); - __asm volatile ("sti" ::: "memory"); - return eflags; -} - -void lockdoc_x86_restore_intr(u_long eflags){ - x86_write_flags(eflags); -} - #endif /* LOCKDOC */
\ No newline at end of file diff --git a/sys/sys/lockdoc.h b/sys/sys/lockdoc.h index 8e96d7cf719..6d8ed6ef4ff 100644 --- a/sys/sys/lockdoc.h +++ b/sys/sys/lockdoc.h @@ -18,27 +18,48 @@ #ifdef LOCKDOC +/* + * The struct we will use to transfer data between VM and host + */ +extern struct log_action la_buffer; + +/* + * Prototypes + */ + +void lockdoc_send_current_task_addr(void); +void lockdoc_send_lwp_flag_offset(void); +void lockdoc_send_pid_offset(void); +void lockdoc_send_kernel_version(void); int32_t lockdoc_get_ctx(void); -void lockdoc_x86_restore_intr(u_long eflags); void __mutex_enter(kmutex_t *, const char*, int, const char*); void __mutex_exit(kmutex_t *, const char*, int, const char*); void __mutex_spin_enter(kmutex_t *, const char*, int, const char*); void __mutex_spin_exit(kmutex_t *, const char*, int, const char*); int __mutex_tryenter(kmutex_t *, const char*, int, const char*); + int __rw_tryupgrade(krwlock_t *, const char*, int, const char*); void __rw_downgrade(krwlock_t *, const char*, int, const char*); void __rw_enter(krwlock_t *, const krw_t, const char*, int, const char*); int __rw_tryenter(krwlock_t *, const krw_t, const char*, int, const char*); void __rw_exit(krwlock_t *, const char*, int, const char*); -void trace_irqs_on(struct trapframe *frame); -void trace_irqs_off(struct trapframe *frame); +void __x86_disable_intr(const char*, int, const char*); +void __x86_enable_intr(const char*, int, const char*); + +void __trace_irqs_on(struct trapframe *, const char *, int); +void __trace_irqs_on_check(struct trapframe *, const char *, int); +void __trace_irqs_off(struct trapframe *, const char *, int); +void __trace_irqs_off_check(struct trapframe *, const char *, int); + +/* Helper function to get a lock type (backported from NetBSD 10.0-STABLE) */ +krw_t rw_lock_op(krwlock_t *rw); -extern struct log_action la_buffer; /* - * Redefine lock function as macros instead of normal functions, so that __FILE__ etc. will work properly + * Redefine lock/interrupt function as macros instead of normal functions, + * so that __FILE__ etc. will work properly */ #define mutex_enter(lock) __mutex_enter(lock, __FILE__, __LINE__, __func__) #define mutex_exit(lock) __mutex_exit(lock, __FILE__, __LINE__, __func__) @@ -52,10 +73,14 @@ extern struct log_action la_buffer; #define rw_tryenter(lock, type) __rw_tryenter(lock, type, __FILE__, __LINE__, __func__) #define rw_exit(lock) __rw_exit(lock, __FILE__, __LINE__, __func__) -/* - * Helper function to get a lock type (backported from NetBSD 10.0-STABLE) - */ -krw_t rw_lock_op(krwlock_t *rw); +#define x86_disable_intr() __x86_disable_intr(__FILE__, __LINE__, __func__) +#define x86_enable_intr() __x86_enable_intr(__FILE__, __LINE__, __func__) + +#define trace_irqs_on(frame) __trace_irqs_on(frame, __FILE__, __LINE__) +#define trace_irqs_on_check(frame) __trace_irqs_on_check(frame, __FILE__, __LINE__) +#define trace_irqs_off(frame) __trace_irqs_off(frame, __FILE__, __LINE__) +#define trace_irqs_off_check(frame) __trace_irqs_off_check(frame, __FILE__, __LINE__) + /* Basic port I/O */ static inline void outb_(u_int8_t v, u_int16_t port) @@ -64,9 +89,9 @@ static inline void outb_(u_int8_t v, u_int16_t port) } static inline void lockdoc_log_memory(int alloc, const char *datatype, const void *ptr, size_t size) { - u_long flags; - - flags = lockdoc_x86_disable_intr(); + u_long eflags; + eflags = x86_read_flags(); + _x86_disable_intr(); memset(&la_buffer,0,sizeof(la_buffer)); @@ -87,13 +112,13 @@ static inline void lockdoc_log_memory(int alloc, const char *datatype, const voi outb_(PING_CHAR,IO_PORT_LOG); - lockdoc_x86_restore_intr(flags); + x86_write_flags(eflags); } static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const char *file, int line, const char* func, const char* lock_type, int irq_sync) { u_long eflags; - eflags = x86_read_psl(); - lockdoc_x86_disable_intr(); + eflags = x86_read_flags(); + _x86_disable_intr(); memset(&la_buffer,0,sizeof(la_buffer)); @@ -141,15 +166,6 @@ static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const x86_write_flags(eflags); } -void lockdoc_send_current_task_addr(void); -void lockdoc_send_lwp_flag_offset(void); -void lockdoc_send_pid_offset(void); -void lockdoc_send_kernel_version(void); - -#else -#define lockdoc_log_memory(a, b, c, d) -#define lockdoc_log_lock(a, b, c, d, e) - #endif /* LOCKDOC */ #endif /* __LOCKDOC_H__ */ |
