From ae5cfd54d9d8cba805801248910a38fe7d7fbd29 Mon Sep 17 00:00:00 2001 From: Merlin Scholz Date: Wed, 1 Mar 2023 20:24:39 +0100 Subject: Implement stubbed out lockdoc functions; update lockdoc_event.h --- sys/arch/x86/include/cpufunc.h | 4 +- sys/kern/tty.c | 2 +- sys/lockdoc/log.c | 120 ++++++++++++++++++++++++++++++++++++++--- sys/sys/lockdoc.h | 38 +++++++++++++ sys/sys/lockdoc_event.h | 5 +- 5 files changed, 157 insertions(+), 12 deletions(-) diff --git a/sys/arch/x86/include/cpufunc.h b/sys/arch/x86/include/cpufunc.h index 5fe30d0b48a..6daa7565b1e 100644 --- a/sys/arch/x86/include/cpufunc.h +++ b/sys/arch/x86/include/cpufunc.h @@ -379,7 +379,7 @@ void x86_enable_intr(void); #define x86_disable_intr() __x86_disable_intr(__FILE__, __LINE__, __func__) void __x86_disable_intr(const char *file, int line, const char *func); -void lockdoc_x86_disable_intr(void); +u_long lockdoc_x86_disable_intr(void); #else @@ -393,7 +393,7 @@ x86_disable_intr(void) #ifdef LOCKDOC #define x86_enable_intr() __x86_enable_intr(__FILE__, __LINE__, __func__) void __x86_enable_intr(const char *file, int line, const char *func); -void lockdoc_x86_enable_intr(void); +u_long lockdoc_x86_enable_intr(void); #else static inline void diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 6ef0b3243b0..a926a65caac 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -131,7 +131,7 @@ const char ttyout[] = "ttyout"; #define CONNECTED(tp) (ISSET(tp->t_state, TS_CARR_ON) || \ ISSET(tp->t_cflag, CLOCAL | MDMBUF)) #else -/* Circumvent Bochs' interesting com* implementation */ +/* Circumvent Bochs' interesting com* implementation that basically has CD stubbed out */ #define CONNECTED(tp) true #endif diff --git a/sys/lockdoc/log.c b/sys/lockdoc/log.c index 28c99ad8bdf..4fbe3d4a7fd 100644 --- a/sys/lockdoc/log.c +++ b/sys/lockdoc/log.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,15 +7,105 @@ struct log_action la_buffer; +int32_t lockdoc_get_ctx(void) { + if (curlwp == NULL) { + return 0; + } else if (curlwp->l_pflag & LP_INTR) { + return -1; + } else { + return curlwp->l_lid; + } +} + +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)PCPU_PTR(curlwp); TODO Implement + 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) { + u_long cur_eflags; + cur_eflags = x86_read_flags(); + if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { +#ifdef DEBUG_TRAPS + log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, frame->tf_trapno); +#else + log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, LOCK_NONE); +#endif + } +} + +void trace_irqs_off(struct trapframe *frame) { + u_long cur_eflags; + cur_eflags = x86_read_flags(); + if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { +#ifdef DEBUG_TRAPS + log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, frame->tf_trapno); +#else + log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, LOCK_NONE); +#endif + } +} + void lockdoc_alloc(const char *func, const char *file, size_t line, volatile void *lock, lockops_t *lo, uintptr_t initaddr){ - // TODO Actually log things } + void lockdoc_free(const char *func, const char *file, size_t line, volatile void *lock){ - // TODO Actually log things } + void lockdoc_wantlock(const char *func, const char *file, size_t line, const volatile void *lock, uintptr_t where, int shared){ - // TODO Actually log things } + void lockdoc_locked(const char *func, const char *file, size_t line, volatile void *lock, void *cvlock, uintptr_t where, int shared){ // shared == 0 means exclusive (write) lock; shared > 0 means shared (read) lock if(shared > 0) { @@ -34,13 +125,12 @@ void lockdoc_unlocked(const char *func, const char *file, size_t line, volatile } } void lockdoc_barrier(const char *func, const char *file, size_t line, volatile void *spinlock, int slplocks){ - // TODO Actually log things } + void lockdoc_mem_check(const char *func, const char *file, size_t line, void *base, size_t sz){ - // TODO Actually log things } + void lockdoc_wakeup(const char *func, const char *file, size_t line, volatile void *lock, uintptr_t where){ - // TODO Actually log things } void __x86_disable_intr(const char *file, int line, const char *func){ @@ -53,8 +143,13 @@ void __x86_disable_intr(const char *file, int line, const char *func){ lockdoc_x86_disable_intr(); } -void lockdoc_x86_disable_intr(void){ +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){ @@ -67,7 +162,16 @@ void __x86_enable_intr(const char *file, int line, const char *func){ lockdoc_x86_enable_intr(); } -void lockdoc_x86_enable_intr(void){ +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 9f8b2ef387a..e2d3a20f1c1 100644 --- a/sys/sys/lockdoc.h +++ b/sys/sys/lockdoc.h @@ -16,6 +16,12 @@ #ifdef LOCKDOC +int32_t lockdoc_get_ctx(void); +void lockdoc_x86_restore_intr(u_long eflags); + +void trace_irqs_on(struct trapframe *frame); +void trace_irqs_off(struct trapframe *frame); + extern struct log_action la_buffer; @@ -37,7 +43,30 @@ static inline void outb_(u_int8_t v, u_int16_t port) } static inline void log_memory(int alloc, const char *datatype, const void *ptr, size_t size) { + register_t flags; + + flags = lockdoc_x86_disable_intr(); + + memset(&la_buffer,0,sizeof(la_buffer)); + + la_buffer.action = (alloc == 1 ? LOCKDOC_ALLOC : LOCKDOC_FREE); + la_buffer.ptr = (unsigned long)ptr; + la_buffer.size = size; + la_buffer.ctx = lockdoc_get_ctx(); + + /* + * One could use a more safe string function, e.g., strlcpy. + * However, we want these *log* functions to be fast. + * We therefore skip all sanity checks, and all that stuff. + * To ensure any string buffer contains a valid string, we + * always write a NULL byte at its end. + */ + strncpy(la_buffer.type,datatype,LOG_CHAR_BUFFER_LEN); + la_buffer.type[LOG_CHAR_BUFFER_LEN - 1] = '\0'; + + outb_(PING_CHAR,IO_PORT_LOG); + lockdoc_x86_restore_intr(flags); } static inline void log_lock(int lock_op, const volatile void* ptr, const char *file, int line, int irq_sync) { @@ -53,6 +82,9 @@ static inline void log_lock(int lock_op, const volatile void* ptr, const char *f // operation la_buffer.lock_op = lock_op; + // context + la_buffer.ctx = lockdoc_get_ctx(); + // pointer la_buffer.ptr = (unsigned long)ptr; @@ -85,6 +117,12 @@ static inline void log_lock(int lock_op, const volatile void* ptr, const char *f 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 log_memory(a, b, c, d) #define log_lock(a, b, c, d, e) diff --git a/sys/sys/lockdoc_event.h b/sys/sys/lockdoc_event.h index c1672345b3c..af5ad08435d 100644 --- a/sys/sys/lockdoc_event.h +++ b/sys/sys/lockdoc_event.h @@ -35,7 +35,9 @@ enum LOCKDOC_OP { LOCKDOC_PID_OFFSET = 'o', LOCKDOC_KERNEL_VERSION = 'v', LOCKDOC_READ = 'r', - LOCKDOC_WRITE = 'w' + LOCKDOC_WRITE = 'w', + LOCKDOC_IRQ_NEST_OFFSET = 'n', + LOCKDOC_LWP_FLAG_OFFSET = 'g' }; enum LOCK_OP { @@ -54,6 +56,7 @@ enum IRQ_SYNC { struct log_action { enum LOCKDOC_OP action; + int32_t ctx; uint32_t lock_op; uint32_t ptr; uint32_t size; -- cgit