#include <linux/lockdoc.h>
#include <linux/preempt.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/utsname.h>
#include <linux/sched.h>
#include <linux/string.h>
#include "kernelversion.gen.h"
//#define DBG_ASM_IRQ_TRACE
/* Since we run our experiment in a single-core environment,
* we can safely use *only* one buffer.
* If someone wants to run the experiment on a multi-core system some day,
* he or she has to allocate #cores vars.
*/
struct log_action la_buffer;
int32_t lockdoc_get_ctx(void) {
if (in_irq()) {
return -2;
} else if (in_softirq() || in_serving_softirq()) {
return -1;
} else {
return current->pid;
}
}
#ifdef [31mCONFIG_LOCKDOC[0m
__visible void trace_hardirqs_on_caller(unsigned long ip) {
#ifdef DBG_ASM_IRQ_TRACE
__log_lock(V_WRITE, PSEUDOLOCK_VAR_HARDIRQ, (void*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, __func__, PSEUDOLOCK_NAME_HARDIRQ, ip, 0);
#else
log_lock(V_WRITE, PSEUDOLOCK_VAR_HARDIRQ, (void*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, __func__,0);
#endif
}
EXPORT_SYMBOL(trace_hardirqs_on_caller)
__visible void trace_hardirqs_off_caller(unsigned long ip) {
#ifdef DBG_ASM_IRQ_TRACE
__log_lock(P_WRITE, PSEUDOLOCK_VAR_HARDIRQ, (void*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, __func__, PSEUDOLOCK_NAME_HARDIRQ, ip, 0);
#else
log_lock(P_WRITE, PSEUDOLOCK_VAR_HARDIRQ, (void*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, __func__,0);
#endif
}
EXPORT_SYMBOL(trace_hardirqs_off_caller)
#endif
int log_preempt_count(void) {
return preempt_count();
}
EXPORT_SYMBOL(log_preempt_count);
void lockdoc_send_current_task_addr(void) {
unsigned long eflags;
raw_local_irq_save(eflags);
memset(&la_buffer,0,sizeof(la_buffer));
la_buffer.action = LOCKDOC_CURRENT_TASK;
la_buffer.ptr = (unsigned long)per_cpu_ptr(¤t_task,0);
outb_(PING_CHAR,IO_PORT_LOG);
raw_local_irq_restore(eflags);
}
void lockdoc_send_preempt_count_addr(void) {
unsigned long eflags;
raw_local_irq_save(eflags);
memset(&la_buffer,0,sizeof(la_buffer));
la_buffer.action = LOCKDOC_PREEMPT_COUNT;
la_buffer.ptr = (unsigned long)per_cpu_ptr(&__preempt_count,0);
outb_(PING_CHAR,IO_PORT_LOG);
raw_local_irq_restore(eflags);
}
void lockdoc_send_pid_offset(void) {
unsigned long eflags;
raw_local_irq_save(eflags);
memset(&la_buffer,0,sizeof(la_buffer));
la_buffer.action = LOCKDOC_PID_OFFSET;
la_buffer.ptr = offsetof(struct task_struct, pid);
outb_(PING_CHAR,IO_PORT_LOG);
raw_local_irq_restore(eflags);
}
void lockdoc_send_kernel_version(void) {
unsigned long eflags;
raw_local_irq_save(eflags);
memset(&la_buffer,0,sizeof(la_buffer));
strncat((char*)&la_buffer.type, utsname()->release, LOG_CHAR_BUFFER_LEN);
strncat((char*)&la_buffer.type, KERNEL_VERSION_EXTENDED, LOG_CHAR_BUFFER_LEN);
la_buffer.action = LOCKDOC_KERNEL_VERSION;
outb_(PING_CHAR,IO_PORT_LOG);
raw_local_irq_restore(eflags);
}