Смекни!
smekni.com

Мониторинг виртуальной памяти в ОС Linux (стр. 6 из 6)

*/

#ifndef MEMMON_MM_FAULT_H

#define MEMMON_MM_FAULT_H

/*

* Install pagefault handler

*/

void capture_mmfault(void);

/*

* Uninstall handler

*/

void release_mmfault(void);

#endif // MEMMON_MM_FAULT_H

mm-fault.c

/*

* Pagefault interception.

*/

#include <linux/module.h>

#include <linux/moduleparam.h>

#include <linux/kernel.h>

#include <linux/mm.h>

#include «common.h»

#include «mm-fault.h»

#include «events.h»

#include «watch-pids.h»

/*

* Dirty kernel hack: PF hook that is called every time

* some process PF's for some page that BELONGS to his VMA space.

*/

extern void (*mm_handle_fault_hook) (struct mm_struct *mm, struct vm_area_struct *vma,

void __user *address, pte_t *pte,

pmd_t *pmd, int write_access);

/*

* Pagefault handler

*/

void mm_handle_fault (struct mm_struct *mm, struct vm_area_struct *vma,

void __user *address, pte_t *pte,

pmd_t *pmd, int write_access)

{

struct memmon_event ev = {.pid = current->pid};

pte_t entry = *pte;

/*

* If PF happened due to R/W or U/S access violation, ignore it

*/

if (! pid_present (current->pid) || pte_present(entry))

return;

/*

* Faulted page is either backed by swapfile, some shared executable file

* or no file yet at all (anonymous page)

*/

if (pte_none(entry))

ev.type = ANON_PF;

else if (pte_file(entry))

ev.type = FILE_PF;

else

ev.type = SWAP_PF;

ev.pagefault.addr = address;

ev.pagefault.write = write_access;

put_event(&ev);

}

/*** Exported entries ***/

/*

* Install pagefault handler

*/

void capture_mmfault(void)

{

mm_handle_fault_hook = mm_handle_fault;

}

/*

* Uninstall handler

*/

void release_mmfault(void)

{

mm_handle_fault_hook = NULL;

}

common.h

/*

* Common defines and global data

*/

#ifndef MEMMON_COMMON_H

#define MEMMON_COMMON_H

/* procfs directory name */

#define PROCDIR «memmon»

/*

* procfs directory entry

*/

extern struct proc_dir_entry *procdir;

#endif // MEMMON_COMMON_H

Makefile

#

ifneq ($(KERNELRELEASE),)

obj-m:= memmon.o

memmon-objs:= mmon.o events.o watch-pids.o syscalls.o syscalls-entry.o mm-fault.o

else

KERNELDIR?= /lib/modules/$(shell uname – r)/build

PWD:= $(shell pwd)

all: offsets.h modules

offsets.h: $(KERNELDIR)/include/asm/thread_info.h

$(MAKE) gen-offsets

gen-offsets > offsets.h

$(RM) gen-offsets

clean modules:

$(MAKE) – C $(KERNELDIR) M=$(PWD) $(MAKECMDGOALS)

PHONY: modules.DEFAULT all

endif

Испрвлениедлядляядра (2.6.20.1)

diff – arNC 3 linux‑2.6.20.1‑j/kernel/kallsyms.c linux‑2.6.20.1‑a/kernel/kallsyms.c

*** linux‑2.6.20.1‑j/kernel/kallsyms.c 2007–02–20 09:34:32.000000000 +0300

– linux‑2.6.20.1‑a/kernel/kallsyms.c 2007–05–26 22:27:23.000000000 +0400

***************

*** 452,454 ****

– 452,460 –

__initcall (kallsyms_init);

EXPORT_SYMBOL (__print_symbol);

+

+ /* HACK */

+

+ extern void *sys_call_table[];

+

+ EXPORT_SYMBOL_GPL (sys_call_table);

diff – arNC 3 linux‑2.6.20.1‑j/mm/memory.c linux‑2.6.20.1‑a/mm/memory.c

*** linux‑2.6.20.1‑j/mm/memory.c 2007–02–20 09:34:32.000000000 +0300

– linux‑2.6.20.1‑a/mm/memory.c 2007–05–28 22:08:41.000000000 +0400

***************

*** 2369,2374 ****

– 2378,2390 –

return VM_FAULT_MAJOR;

}

+ /* DIRTY HACK */

+ void (*mm_handle_fault_hook) (struct mm_struct *mm,

+ struct vm_area_struct *vma, unsigned long address,

+ pte_t *pte, pmd_t *pmd, int write_access) = NULL;

+

+ EXPORT_SYMBOL_GPL (mm_handle_fault_hook);

+

/*

* These routines also need to handle stuff like marking pages dirty

* and/or accessed for architectures that don't do it in hardware (most

***************

*** 2390,2395 ****

– 2406,2414 –

pte_t old_entry;

spinlock_t *ptl;

+ if (mm_handle_fault_hook)

+ mm_handle_fault_hook (mm, vma, address, pte, pmd, write_access);

+

old_entry = entry = *pte;

if (! pte_present(entry)) {

if (pte_none(entry)) {