{
void *free_slot;
struct fixed_alloc *fa;
- struct hlist_node *pos;
+ DECLARE_NODE_PTR_FOR_HLIST(pos);
swap_hlist_for_each_entry_rcu(fa, pos, &sm->page_list, hlist) {
free_slot = chunk_allocate(&fa->chunk, sm->slot_size);
void free_insn_slot(struct slot_manager *sm, void *slot)
{
struct fixed_alloc *fa;
- struct hlist_node *pos;
+ DECLARE_NODE_PTR_FOR_HLIST(pos);
swap_hlist_for_each_entry_rcu(fa, pos, &sm->page_list, hlist) {
if (!chunk_check_ptr(&fa->chunk, slot, PAGE_SIZE))
struct kprobe *get_kprobe(void *addr)
{
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
head = &kprobe_table[hash_ptr (addr, KPROBE_HASH_BITS)];
swap_hlist_for_each_entry_rcu(p, node, head, hlist) {
/* Called with kretprobe_lock held */
struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
{
- struct hlist_node *node;
struct kretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
return ri;
/* Called with kretprobe_lock held */
struct kretprobe_instance *get_free_rp_inst_no_alloc(struct kretprobe *rp)
{
- struct hlist_node *node;
struct kretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
return ri;
/* Called with kretprobe_lock held */
struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
{
- struct hlist_node *node;
struct kretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->used_instances, uflist) {
return ri;
{
struct kretprobe_instance *ri = NULL;
struct hlist_head *head;
- struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
struct kprobe_ctlblk *kcb;
+ struct hlist_node *tmp;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
+
preempt_disable();
kcb = get_kprobe_ctlblk();
{
unsigned long flags;
struct kretprobe_instance *ri;
- struct hlist_node *node;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
dbi_unregister_kprobe(&rp->kp);
#include <ksyms/ksyms.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+#define DECLARE_NODE_PTR_FOR_HLIST(var_name)
#define swap_hlist_for_each_entry_rcu(tpos, pos, head, member) hlist_for_each_entry_rcu(tpos, head, member)
#define swap_hlist_for_each_entry_safe(tpos, pos, n, head, member) hlist_for_each_entry_safe(tpos, n, head, member)
#define swap_hlist_for_each_entry(tpos, pos, head, member) hlist_for_each_entry(tpos, head, member)
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */
+#define DECLARE_NODE_PTR_FOR_HLIST(var_name) struct hlist_node *var_name
#define swap_hlist_for_each_entry_rcu(tpos, pos, head, member) hlist_for_each_entry_rcu(tpos, pos, head, member)
#define swap_hlist_for_each_entry_safe(tpos, pos, n, head, member) hlist_for_each_entry_safe(tpos, pos, n, head, member)
#define swap_hlist_for_each_entry(tpos, pos, head, member) hlist_for_each_entry(tpos, pos, head, member)
static struct probe *find_probe(unsigned long addr)
{
struct probe *p;
- struct hlist_node *node;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
/* check if such probe does exist */
swap_hlist_for_each_entry(p, node, &list_probes, hlist)
int ksm_unregister_probe_all(void)
{
struct probe *p;
- struct hlist_node *node, *n;
+ struct hlist_node *n;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry_safe(p, node, n, &list_probes, hlist) {
do_ksm_unregister_probe(p);
{
int i;
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
// print uprobe table
for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
{
int i;
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
// print uprobe table
for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
{
int i;
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
// print uprobe table
for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
struct kprobe *get_ukprobe(void *addr, pid_t tgid)
{
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
head = &uprobe_table[hash_ptr(addr, UPROBE_HASH_BITS)];
swap_hlist_for_each_entry_rcu(p, node, head, hlist) {
static struct kprobe *get_ukprobe_bis_arm(void *addr, pid_t tgid)
{
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
/* TODO: test - two processes invokes instrumented function */
head = &uprobe_insn_slot_table[hash_ptr(addr, UPROBE_HASH_BITS)];
static struct kprobe *get_ukprobe_bis_thumb(void *addr, pid_t tgid)
{
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
/* TODO: test - two processes invokes instrumented function */
head = &uprobe_insn_slot_table[hash_ptr(addr, UPROBE_HASH_BITS)];
struct kprobe *get_ukprobe_by_insn_slot(void *addr, pid_t tgid, struct pt_regs *regs)
{
struct hlist_head *head;
- struct hlist_node *node;
struct kprobe *p;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
addr -= UPROBES_TRAMP_RET_BREAK_IDX;
/* Called with uretprobe_lock held */
static struct uretprobe_instance *get_used_urp_inst(struct uretprobe *rp)
{
- struct hlist_node *node;
struct uretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->used_instances, uflist) {
return ri;
/* Called with uretprobe_lock held */
struct uretprobe_instance *get_free_urp_inst_no_alloc(struct uretprobe *rp)
{
- struct hlist_node *node;
struct uretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
return ri;
/* Called with uretprobe_lock held */
static struct uretprobe_instance *get_free_urp_inst(struct uretprobe *rp)
{
- struct hlist_node *node;
struct uretprobe_instance *ri;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) {
return ri;
{
struct uretprobe_instance *ri = NULL;
struct hlist_head *head;
- struct hlist_node *node, *tmp;
unsigned long flags, tramp_addr, orig_ret_addr = 0;
+ struct hlist_node *tmp;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
tramp_addr = arch_get_trampoline_addr(p, regs);
spin_lock_irqsave(&uretprobe_lock, flags);
int dbi_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct *task)
{
struct uretprobe_instance *ri;
- struct hlist_node *node, *tmp;
struct hlist_head *head = uretprobe_inst_table_head(parent->mm);
+ struct hlist_node *tmp;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
if (parent == ri->task) {
void dbi_unregister_all_uprobes(struct task_struct *task)
{
struct hlist_head *head;
- struct hlist_node *node, *tnode;
struct kprobe *p;
int i;
+ struct hlist_node *tnode;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
head = &uprobe_table[i];
int i;
unsigned long table_size;
struct sspt_page *page = NULL;
- struct hlist_node *node = NULL;
struct hlist_head *head = NULL;
static unsigned char *NA = "N/A";
unsigned char *name;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
if (file == NULL) {
printk("### file_p == NULL\n");
void sspt_file_free(struct sspt_file *file)
{
- struct hlist_node *p, *n;
struct hlist_head *head;
struct sspt_page *page;
int i, table_size = (1 << file->page_probes_hash_bits);
+ struct hlist_node *n;
+ DECLARE_NODE_PTR_FOR_HLIST(p);
for (i = 0; i < table_size; ++i) {
head = &file->page_probes_table[i];
static struct sspt_page *sspt_find_page(struct sspt_file *file, unsigned long offset)
{
- struct hlist_node *node;
struct hlist_head *head;
struct sspt_page *page;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
head = &file->page_probes_table[hash_ptr((void *)offset, file->page_probes_hash_bits)];
swap_hlist_for_each_entry(page, node, head, hlist) {
{
int i, table_size;
struct sspt_page *page;
- struct hlist_node *node, *tmp;
struct hlist_head *head;
+ struct hlist_node *tmp;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
table_size = (1 << file->page_probes_hash_bits);
for (i = 0; i < table_size; ++i) {
void sspt_file_install(struct sspt_file *file)
{
struct sspt_page *page = NULL;
- struct hlist_node *node = NULL;
struct hlist_head *head = NULL;
int i, table_size = (1 << file->page_probes_hash_bits);
unsigned long page_addr;
struct mm_struct *mm;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
for (i = 0; i < table_size; ++i) {
head = &file->page_probes_table[i];
int i, err = 0;
int table_size = (1 << file->page_probes_hash_bits);
struct sspt_page *page;
- struct hlist_node *node, *tmp;
struct hlist_head *head;
+ struct hlist_node *tmp;
+ DECLARE_NODE_PTR_FOR_HLIST(node);
for (i = 0; i < table_size; ++i) {
head = &file->page_probes_table[i];
--- /dev/null
+/*
+ * SWAP uprobe manager
+ * modules/us_manager/us_slot_manager.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2013
+ *
+ * 2013 Alexander Aksenov: SWAP us_manager implement
+ *
+ */
+
+
+#include <linux/mm.h>
+#include <linux/version.h>
+
+
+static inline unsigned long swap_do_mmap(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flag,
+ unsigned long offset)
+{
+#if LINUX_VERSION_CODE == KERNEL_VERSION(3, 10, 0)
+ unsigned long populate;
+
+ return do_mmap_pgoff(filp, addr, len, prot, flag, offset, &populate);
+#else /* LINUX_VERSION_CODE == KERNEL_VERSION(3, 10, 0) */
+ return do_mmap(filp, addr, len, prot, flag, offset);
+#endif
+}
#include <linux/list.h>
#include <kprobe/dbi_insn_slots.h>
#include <kprobe/arch/asm/dbi_kprobes.h>
+#include "us_manager_common.h"
static unsigned long alloc_user_pages(struct task_struct *task, unsigned long len, unsigned long prot, unsigned long flags)
{
}
// FIXME: its seems to be bad decision to replace 'current' pointer temporarily
current_thread_info()->task = task;
- ret = do_mmap(NULL, 0, len, prot, flags, 0);
+ ret = swap_do_mmap(NULL, 0, len, prot, flags, 0);
current_thread_info()->task = otask;
if (!atomic) {
downgrade_write (&mm->mmap_sem);