endif
-## FB_SCX30G
-ifeq ($(CONFIG_FB_SCX30G), y)
- swap_energy-y += lcd/sprdfb_panel.o
- LCD_FUNC_LIST += sprdfb_panel
-endif
-
-
# MARU:
ifeq ($(CONFIG_MARU_BACKLIGHT), y)
swap_energy-y += lcd/maru.o
static DEFINE_RATIONAL(cpu0_running_coef); /* boot core uses distinct coeff */
static DEFINE_RATIONAL(cpuN_running_coef);
-static u64 __energy_cpu0(enum parameter_energy pe)
+static u64 __energy_cpu(enum parameter_energy pe)
{
u64 times[NR_CPUS] = { 0 };
u64 val = 0;
+ int i;
- /* TODO: make for only cpu0 */
if (get_parameter_energy(pe, times, sizeof(times)) == 0) {
val = div_u64(times[0] * cpu0_running_coef.num,
cpu0_running_coef.denom);
- }
-
- return val;
-}
-
-static u64 __energy_cpuN(enum parameter_energy pe)
-{
- u64 times[NR_CPUS] = { 0 };
- u64 val = 0;
-
- if (get_parameter_energy(pe, times, sizeof(times)) == 0) {
- int i;
-
for (i = 1; i < NR_CPUS; i++)
val += div_u64(times[i] * cpuN_running_coef.num,
cpuN_running_coef.denom);
return val;
}
-static u64 cpu0_system(void)
-{
- return __energy_cpu0(PE_TIME_SYSTEM);
-}
-
-static u64 cpuN_system(void)
-{
- return __energy_cpuN(PE_TIME_SYSTEM);
-}
-
-static u64 cpu0_apps(void)
+static u64 cpu_system(void)
{
- return __energy_cpu0(PE_TIME_APPS);
+ return __energy_cpu(PE_TIME_SYSTEM);
}
-static u64 cpuN_apps(void)
+static u64 cpu_apps(void)
{
- return __energy_cpuN(PE_TIME_APPS);
+ return __energy_cpu(PE_TIME_APPS);
}
}
-/* wifi recv */
-static DEFINE_RATIONAL(wf_recv_coef);
-
-static u64 wf_recv_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_WF_RECV_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom);
-}
-
-static u64 wf_recv_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_WF_RECV_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom);
-}
-
-/* wifi send */
-static DEFINE_RATIONAL(wf_send_coef);
-
-static u64 wf_send_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_WF_SEND_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * wf_send_coef.num, wf_send_coef.denom);
-}
-
-static u64 wf_send_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_WF_SEND_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * wf_send_coef.num, wf_send_coef.denom);
-}
-
-/* l2cap_recv_acldata */
-static DEFINE_RATIONAL(l2cap_recv_acldata_coef);
-
-static u64 l2cap_recv_acldata_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_L2CAP_RECV_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * l2cap_recv_acldata_coef.num,
- l2cap_recv_acldata_coef.denom);
-}
-
-static u64 l2cap_recv_acldata_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_L2CAP_RECV_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * l2cap_recv_acldata_coef.num,
- l2cap_recv_acldata_coef.denom);
-}
-
-/* sco_recv_scodata */
-static DEFINE_RATIONAL(sco_recv_scodata_coef);
-
-static u64 sco_recv_scodata_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_SCO_RECV_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * sco_recv_scodata_coef.num,
- sco_recv_scodata_coef.denom);
-}
-
-static u64 sco_recv_scodata_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PE_SCO_RECV_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * sco_recv_scodata_coef.num,
- sco_recv_scodata_coef.denom);
-}
-
-/* hci_send_acl */
-static DEFINE_RATIONAL(hci_send_acl_coef);
-
-static u64 hci_send_acl_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PT_SEND_ACL_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom);
-}
-
-static u64 hci_send_acl_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PT_SEND_ACL_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom);
-}
-
-/* hci_send_sco */
-static DEFINE_RATIONAL(hci_send_sco_coef);
-
-static u64 hci_send_sco_system(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PT_SEND_SCO_SYSTEM, &byte, sizeof(byte));
-
- return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom);
-}
-
-static u64 hci_send_sco_apps(void)
-{
- u64 byte = 0;
-
- get_parameter_energy(PT_SEND_SCO_APPS, &byte, sizeof(byte));
-
- return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom);
-}
-
-
{
.name = "cpu_running",
.coef = &cpu0_running_coef,
- .system = cpu0_system,
- .apps = cpu0_apps
+ .system = cpu_system,
+ .apps = cpu_apps
},
{
.name = "cpuN_running",
.coef = &cpuN_running_coef,
- .system = cpuN_system,
- .apps = cpuN_apps
+ .system = cpu_system,
+ .apps = cpu_apps
},
{
.name = "cpu_idle",
.coef = &fw_coef,
.system = fw_system,
.apps = fw_apps
- },
- {
- .name = "wf_recv",
- .coef = &wf_recv_coef,
- .system = wf_recv_system,
- .apps = wf_recv_apps
- },
- {
- .name = "wf_send",
- .coef = &wf_send_coef,
- .system = wf_send_system,
- .apps = wf_send_apps
- },
- {
- .name = "sco_recv_scodata",
- .coef = &sco_recv_scodata_coef,
- .system = sco_recv_scodata_system,
- .apps = sco_recv_scodata_apps
- },
- {
- .name = "l2cap_recv_acldata",
- .coef = &l2cap_recv_acldata_coef,
- .system = l2cap_recv_acldata_system,
- .apps = l2cap_recv_acldata_apps
- },
- {
- .name = "hci_send_acl",
- .coef = &hci_send_acl_coef,
- .system = hci_send_acl_system,
- .apps = hci_send_acl_apps
- },
- {
- .name = "hci_send_sco",
- .coef = &hci_send_sco_coef,
- .system = hci_send_sco_system,
- .apps = hci_send_sco_apps
}
};
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/net.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include <linux/fdtable.h>
-#include <net/sock.h>
#include <kprobe/swap_kprobes.h>
#include <ksyms/ksyms.h>
-#include <master/swap_deps.h>
#include <us_manager/sspt/sspt_proc.h>
#include <us_manager/sspt/sspt_feature.h>
#include <linux/atomic.h>
/* ============================================================================
- * = ENERGY_XXX =
- * ============================================================================
- */
-struct kern_probe {
- const char *name;
- struct kretprobe *rp;
-};
-
-static int energy_xxx_once(struct kern_probe p[], int size)
-{
- int i;
- const char *sym;
-
- for (i = 0; i < size; ++i) {
- struct kretprobe *rp = p[i].rp;
-
- sym = p[i].name;
- rp->kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
- if (rp->kp.addr == NULL)
- goto not_found;
- }
-
- return 0;
-
-not_found:
- printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym);
- return -ESRCH;
-}
-
-static int energy_xxx_set(struct kern_probe p[], int size, int *flag)
-{
- int i, ret;
-
- for (i = 0; i < size; ++i) {
- ret = swap_register_kretprobe(p[i].rp);
- if (ret)
- goto fail;
- }
-
- *flag = 1;
- return 0;
-
-fail:
- pr_err("swap_register_kretprobe(%s) ret=%d\n", p[i].name, ret);
-
- for (--i; i != -1; --i)
- swap_unregister_kretprobe(p[i].rp);
-
- return ret;
-}
-
-static void energy_xxx_unset(struct kern_probe p[], int size, int *flag)
-{
- int i;
-
- if (*flag == 0)
- return;
-
- for (i = size - 1; i != -1; --i)
- swap_unregister_kretprobe(p[i].rp);
-
- *flag = 0;
-}
-
-
-
-
-
-/* ============================================================================
* = CPUS_TIME =
* ============================================================================
*/
/*for sys_write */
atomic64_t bytes_written;
- /*for recvmsg*/
- atomic64_t bytes_recv;
-
- /* for sock_send */
- atomic64_t bytes_send;
-
- /* for l2cap_recv */
- atomic64_t bytes_l2cap_recv_acldata;
-
- /* for sco_recv_scodata */
- atomic64_t bytes_sco_recv_scodata;
-
- /* for hci_send_acl */
- atomic64_t bytes_hci_send_acl;
-
- /* for hci_send_sco */
- atomic64_t bytes_hci_send_sco;
};
static sspt_feature_id_t feature_id = SSPT_FEATURE_ID_BAD;
cpus_time_init(&ed->ct, 0);
atomic64_set(&ed->bytes_read, 0);
atomic64_set(&ed->bytes_written, 0);
- atomic64_set(&ed->bytes_recv, 0);
- atomic64_set(&ed->bytes_send, 0);
- atomic64_set(&ed->bytes_l2cap_recv_acldata, 0);
- atomic64_set(&ed->bytes_sco_recv_scodata, 0);
- atomic64_set(&ed->bytes_hci_send_acl, 0);
- atomic64_set(&ed->bytes_hci_send_sco, 0);
}
static void uninit_ed(struct energy_data *ed)
cpus_time_init(&ed->ct, 0);
atomic64_set(&ed->bytes_read, 0);
atomic64_set(&ed->bytes_written, 0);
- atomic64_set(&ed->bytes_recv, 0);
- atomic64_set(&ed->bytes_send, 0);
- atomic64_set(&ed->bytes_l2cap_recv_acldata, 0);
- atomic64_set(&ed->bytes_sco_recv_scodata, 0);
- atomic64_set(&ed->bytes_hci_send_acl, 0);
- atomic64_set(&ed->bytes_hci_send_sco, 0);
}
static void *create_ed(void)
-/* ============================================================================
- * = wifi =
- * ============================================================================
- */
-static bool check_wlan0(struct socket *sock)
-{
- /* FIXME: hardcode interface */
- const char *name_intrf = "wlan0";
-
- if (sock->sk->sk_dst_cache &&
- sock->sk->sk_dst_cache->dev &&
- !strcmp(sock->sk->sk_dst_cache->dev->name, name_intrf))
- return true;
-
- return false;
-}
-
-static bool check_socket(struct task_struct *task, struct socket *socket)
-{
- bool ret = false;
- unsigned int fd;
- struct files_struct *files;
-
- files = swap_get_files_struct(task);
- if (files == NULL)
- return false;
-
- rcu_read_lock();
- for (fd = 0; fd < files_fdtable(files)->max_fds; ++fd) {
- if (fcheck_files(files, fd) == socket->file) {
- ret = true;
- goto unlock;
- }
- }
-
-unlock:
- rcu_read_unlock();
- swap_put_files_struct(files);
- return ret;
-}
-
-static struct energy_data *get_energy_data_by_socket(struct task_struct *task,
- struct socket *socket)
-{
- struct energy_data *ed;
-
- ed = get_energy_data(task);
- if (ed)
- ed = check_socket(task, socket) ? ed : NULL;
-
- return ed;
-}
-
-static int wf_sock_eh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- struct socket *socket = (struct socket *)swap_get_karg(regs, 0);
-
- *(struct socket **)ri->data = check_wlan0(socket) ? socket : NULL;
-
- return 0;
-}
-
-static int wf_sock_aio_eh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- struct kiocb *iocb = (struct kiocb *)swap_get_karg(regs, 0);
- struct socket *socket = iocb->ki_filp->private_data;
-
- *(struct socket **)ri->data = check_wlan0(socket) ? socket : NULL;
-
- return 0;
-}
-
-static int wf_sock_recv_rh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
-
- if (ret > 0) {
- struct socket *socket = *(struct socket **)ri->data;
-
- if (socket) {
- struct energy_data *ed;
-
- ed = get_energy_data_by_socket(current, socket);
- if (ed)
- atomic64_add(ret, &ed->bytes_recv);
- atomic64_add(ret, &ed_system.bytes_recv);
- }
- }
-
- return 0;
-}
-
-static int wf_sock_send_rh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
-
- if (ret > 0) {
- struct socket *socket = *(struct socket **)ri->data;
-
- if (socket) {
- struct energy_data *ed;
-
- ed = get_energy_data_by_socket(current, socket);
- if (ed)
- atomic64_add(ret, &ed->bytes_send);
- atomic64_add(ret, &ed_system.bytes_send);
- }
- }
-
- return 0;
-}
-
-static struct kretprobe sock_recv_krp = {
- .entry_handler = wf_sock_eh,
- .handler = wf_sock_recv_rh,
- .data_size = sizeof(struct socket *)
-};
-
-static struct kretprobe sock_send_krp = {
- .entry_handler = wf_sock_eh,
- .handler = wf_sock_send_rh,
- .data_size = sizeof(struct socket *)
-};
-
-static struct kretprobe sock_aio_read_krp = {
- .entry_handler = wf_sock_aio_eh,
- .handler = wf_sock_recv_rh,
- .data_size = sizeof(struct socket *)
-};
-
-static struct kretprobe sock_aio_write_krp = {
- .entry_handler = wf_sock_aio_eh,
- .handler = wf_sock_send_rh,
- .data_size = sizeof(struct socket *)
-};
-
-static struct kern_probe wifi_probes[] = {
- {
- .name = "sock_recvmsg",
- .rp = &sock_recv_krp,
- },
- {
- .name = "sock_sendmsg",
- .rp = &sock_send_krp,
- },
- {
- .name = "sock_aio_read",
- .rp = &sock_aio_read_krp,
- },
- {
- .name = "sock_aio_write",
- .rp = &sock_aio_write_krp,
- }
-};
-
-enum { wifi_probes_cnt = ARRAY_SIZE(wifi_probes) };
-static int wifi_flag = 0;
-
-
-
-
-
-/* ============================================================================
- * = bluetooth =
- * ============================================================================
- */
-
-struct swap_bt_data {
- struct socket *socket;
-};
-
-static int bt_entry_handler(struct kretprobe_instance *ri,
- struct pt_regs *regs)
-{
- struct swap_bt_data *data = (struct swap_bt_data *)ri->data;
- struct socket *sock = (struct socket *)swap_get_sarg(regs, 1);
-
- data->socket = sock ? sock : NULL;
-
- return 0;
-}
-
-static int bt_recvmsg_handler(struct kretprobe_instance *ri,
- struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
- struct swap_bt_data *data = (struct swap_bt_data *)ri->data;
-
- if (ret > 0) {
- struct socket *socket = data->socket;
-
- if (socket) {
- struct energy_data *ed;
-
- ed = get_energy_data_by_socket(current, socket);
- if (ed)
- atomic64_add(ret, &ed->bytes_l2cap_recv_acldata);
- }
- atomic64_add(ret, &ed_system.bytes_l2cap_recv_acldata);
- }
-
- return 0;
-}
-
-static int bt_sendmsg_handler(struct kretprobe_instance *ri,
- struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
- struct swap_bt_data *data = (struct swap_bt_data *)ri->data;
-
- if (ret > 0) {
- struct socket *socket = data->socket;
-
- if (socket) {
- struct energy_data *ed;
-
- ed = get_energy_data_by_socket(current, socket);
- if (ed)
- atomic64_add(ret, &ed->bytes_hci_send_sco);
- }
- atomic64_add(ret, &ed_system.bytes_hci_send_sco);
- }
-
- return 0;
-}
-
-static struct kretprobe rfcomm_sock_recvmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_recvmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe l2cap_sock_recvmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_recvmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe hci_sock_recvmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_recvmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe sco_sock_recvmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_recvmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-static struct kretprobe rfcomm_sock_sendmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_sendmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe l2cap_sock_sendmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_sendmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe hci_sock_sendmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_sendmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kretprobe sco_sock_sendmsg_krp = {
- .entry_handler = bt_entry_handler,
- .handler = bt_sendmsg_handler,
- .data_size = sizeof(struct swap_bt_data)
-};
-
-static struct kern_probe bt_probes[] = {
- {
- .name = "rfcomm_sock_recvmsg",
- .rp = &rfcomm_sock_recvmsg_krp,
- },
- {
- .name = "l2cap_sock_recvmsg",
- .rp = &l2cap_sock_recvmsg_krp,
- },
- {
- .name = "hci_sock_recvmsg",
- .rp = &hci_sock_recvmsg_krp,
- },
- {
- .name = "sco_sock_recvmsg",
- .rp = &sco_sock_recvmsg_krp,
- },
- {
- .name = "rfcomm_sock_sendmsg",
- .rp = &rfcomm_sock_sendmsg_krp,
- },
- {
- .name = "l2cap_sock_sendmsg",
- .rp = &l2cap_sock_sendmsg_krp,
- },
- {
- .name = "hci_sock_sendmsg",
- .rp = &hci_sock_sendmsg_krp,
- },
- {
- .name = "sco_sock_sendmsg",
- .rp = &sco_sock_sendmsg_krp,
- }
-};
-
-enum { bt_probes_cnt = ARRAY_SIZE(bt_probes) };
-static int energy_bt_flag = 0;
-
enum parameter_type {
PT_CPU,
PT_READ,
- PT_WRITE,
- PT_WF_RECV,
- PT_WF_SEND,
- PT_L2CAP_RECV,
- PT_SCO_RECV,
- PT_SEND_ACL,
- PT_SEND_SCO
+ PT_WRITE
};
struct cmd_pt {
case PT_WRITE:
*val += atomic64_read(&ed->bytes_written);
break;
- case PT_WF_RECV:
- *val += atomic64_read(&ed->bytes_recv);
- break;
- case PT_WF_SEND:
- *val += atomic64_read(&ed->bytes_send);
- break;
- case PT_L2CAP_RECV:
- *val += atomic64_read(&ed->bytes_l2cap_recv_acldata);
- break;
- case PT_SCO_RECV:
- *val += atomic64_read(&ed->bytes_sco_recv_scodata);
- break;
- case PT_SEND_ACL:
- *val += atomic64_read(&ed->bytes_hci_send_acl);
- break;
- case PT_SEND_SCO:
- *val += atomic64_read(&ed->bytes_hci_send_sco);
- break;
default:
break;
}
case PE_WRITE_SYSTEM:
*val = atomic64_read(&ed_system.bytes_written);
break;
- case PE_WF_RECV_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_recv);
- break;
- case PE_WF_SEND_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_send);
- break;
- case PE_L2CAP_RECV_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_l2cap_recv_acldata);
- break;
- case PE_SCO_RECV_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_sco_recv_scodata);
- break;
- case PT_SEND_ACL_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_hci_send_acl);
- break;
- case PT_SEND_SCO_SYSTEM:
- *val = atomic64_read(&ed_system.bytes_hci_send_sco);
- break;
case PE_READ_APPS:
current_parameter_apps(PT_READ, buf, sz);
break;
case PE_WRITE_APPS:
current_parameter_apps(PT_WRITE, buf, sz);
break;
- case PE_WF_RECV_APPS:
- current_parameter_apps(PT_WF_RECV, buf, sz);
- break;
- case PE_WF_SEND_APPS:
- current_parameter_apps(PT_WF_SEND, buf, sz);
- break;
- case PE_L2CAP_RECV_APPS:
- current_parameter_apps(PT_L2CAP_RECV, buf, sz);
- break;
- case PE_SCO_RECV_APPS:
- current_parameter_apps(PT_SCO_RECV, buf, sz);
- break;
- case PT_SEND_ACL_APPS:
- current_parameter_apps(PT_SEND_ACL, buf, sz);
- break;
- case PT_SEND_SCO_APPS:
- current_parameter_apps(PT_SEND_SCO, buf, sz);
- break;
default:
ret = -EINVAL;
break;
goto unregister_sys_write;
}
- energy_xxx_set(bt_probes, bt_probes_cnt, &energy_bt_flag);
- energy_xxx_set(wifi_probes, wifi_probes_cnt, &wifi_flag);
-
/* TODO: check return value */
lcd_set_energy();
void do_unset_energy(void)
{
lcd_unset_energy();
- energy_xxx_unset(wifi_probes, wifi_probes_cnt, &wifi_flag);
- energy_xxx_unset(bt_probes, bt_probes_cnt, &energy_bt_flag);
swap_unregister_kretprobe(&switch_to_krp);
swap_unregister_kretprobe(&sys_write_krp);
if (sys_write_krp.kp.addr == NULL)
goto not_found;
- energy_xxx_once(bt_probes, bt_probes_cnt);
- energy_xxx_once(wifi_probes, wifi_probes_cnt);
-
return 0;
not_found:
PE_READ_SYSTEM, /**< number of bytes are read by system */
PE_WRITE_SYSTEM, /**< number of bytes are write by system */
PE_READ_APPS, /**< number of bytes are read by apps */
- PE_WRITE_APPS, /**< number of bytes are write by apps */
- PE_WF_RECV_SYSTEM, /**< number of bytes are receive by system through wifi */
- PE_WF_SEND_SYSTEM, /**< number of bytes are send by system through wifi */
- PE_WF_RECV_APPS, /**< number of bytes are receive by apps through wifi */
- PE_WF_SEND_APPS, /**< number of bytes are send by apps through wifi */
- PE_L2CAP_RECV_SYSTEM, /**< number of bytes(ACL packets) are recv by system through bluetooth */
- PE_L2CAP_RECV_APPS, /**< number of bytes(ACL packets) are recv by apps through bluetooth */
- PE_SCO_RECV_SYSTEM, /**< number of bytes(SCO packets) are recv by system through bluetooth */
- PE_SCO_RECV_APPS, /**< number of bytes(SCO packets) are recv by apps through bluetooth */
- PT_SEND_ACL_SYSTEM, /**< number of bytes(ACL packets) are send by system through bluetooth */
- PT_SEND_ACL_APPS, /**< number of bytes(ACL packets) are send by apps through bluetooth */
- PT_SEND_SCO_SYSTEM, /**< number of bytes(SCO packets) are send by system through bluetooth */
- PT_SEND_SCO_APPS, /**< number of bytes(SCO packets) are send by apps through bluetooth */
+ PE_WRITE_APPS /**< number of bytes are write by apps*/
};
+++ /dev/null
-/*
- * 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, 2015
- *
- * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
- *
- */
-
-
-#include <linux/backlight.h>
-#include <kprobe/swap_kprobes.h>
-#include "lcd_base.h"
-
-
-static const char path_backlight[] = "/sys/class/backlight/panel/brightness";
-static const char path_backlight_max[] = "/sys/class/backlight/panel/max_brightness";
-static const char path_power[] = "/sys/class/lcd/panel/lcd_power";
-
-static const char * const all_path[] = {
- path_backlight,
- path_backlight_max,
- path_power
-};
-
-
-static int sprdfb_panel_check(struct lcd_ops *ops)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(all_path); ++i) {
- int ret = read_val(all_path[i]);
-
- if (IS_ERR_VALUE(ret))
- return 0;
- }
-
- return 1;
-}
-
-static unsigned long sprdfb_panel_get_parameter(struct lcd_ops *ops,
- enum lcd_parameter_type type)
-{
- switch (type) {
- case LPD_MIN_BRIGHTNESS:
- return 0;
- case LPD_MAX_BRIGHTNESS:
- return read_val(path_backlight_max);
- case LPD_BRIGHTNESS:
- return read_val(path_backlight);
- case LPD_POWER:
- return read_val(path_power);
- }
-
- return -EINVAL;
-}
-
-static int set_power_eh(struct kretprobe_instance *ri, struct pt_regs *regs);
-static int set_power_rh(struct kretprobe_instance *ri, struct pt_regs *regs);
-
-static struct kretprobe set_power_krp = {
- .kp.symbol_name = "sprdfb_set_power",
- .entry_handler = set_power_eh,
- .handler = set_power_rh,
- .data_size = sizeof(int)
-};
-
-
-static int set_backlight_eh(struct kretprobe_instance *ri, struct pt_regs *regs);
-static int set_backlight_rh(struct kretprobe_instance *ri, struct pt_regs *regs);
-
-static struct kretprobe set_backlight_krp = {
- .kp.symbol_name = "panel_update_brightness",
- .entry_handler = set_backlight_eh,
- .handler = set_backlight_rh,
- .data_size = sizeof(int)
-};
-
-
-int sprdfb_panel_set(struct lcd_ops *ops)
-{
- int ret;
-
- ret = swap_register_kretprobe(&set_power_krp);
- if (ret)
- return ret;
-
- ret = swap_register_kretprobe(&set_backlight_krp);
- if (ret)
- swap_unregister_kretprobe(&set_power_krp);
-
- return ret;
-}
-
-int sprdfb_panel_unset(struct lcd_ops *ops)
-{
- swap_unregister_kretprobe(&set_backlight_krp);
- swap_unregister_kretprobe(&set_power_krp);
-
- return 0;
-}
-
-
-static struct lcd_ops sprdfb_panel_ops = {
- .name = "sprdfb_panel",
- .check = sprdfb_panel_check,
- .set = sprdfb_panel_set,
- .unset = sprdfb_panel_unset,
- .get = sprdfb_panel_get_parameter
-};
-
-struct lcd_ops *LCD_MAKE_FNAME(sprdfb_panel)(void)
-{
- return &sprdfb_panel_ops;
-}
-
-
-
-
-
-/* ============================================================================
- * === POWER ===
- * ============================================================================
- */
-static int set_power_eh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int *power = (int *)ri->data;
-
- *power = (int)swap_get_karg(regs, 1);
-
- return 0;
-}
-
-static int set_power_rh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
- int *power = (int *)ri->data;
-
- if (!ret && sprdfb_panel_ops.notifier)
- sprdfb_panel_ops.notifier(&sprdfb_panel_ops, LAT_POWER,
- (void *)*power);
- return 0;
-}
-
-
-
-
-
-/* ============================================================================
- * === BACKLIGHT ===
- * ============================================================================
- */
-static int set_backlight_eh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int *brightness = (int *)ri->data;
- struct backlight_device *bd;
-
- bd = (struct backlight_device *)swap_get_karg(regs, 0);
- *brightness = bd->props.brightness;
-
- return 0;
-}
-
-static int set_backlight_rh(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int ret = regs_return_value(regs);
- int *brightness = (int *)ri->data;
-
- if (!ret && sprdfb_panel_ops.notifier)
- sprdfb_panel_ops.notifier(&sprdfb_panel_ops, LAT_BRIGHTNESS,
- (void *)*brightness);
-
- return 0;
-}
(p->list.next == &old_p->list) && (p->list.prev == &old_p->list))) {
/* Only probe on the hash list */
swap_arch_disarm_kprobe(p);
-
- /* FIXME: move sync out from atomic context */
- if (!in_atomic())
- synchronize_sched();
-
hlist_del_rcu(&old_p->hlist);
remove_kprobe(old_p);
unsigned long flags;
const size_t end = ((size_t) 0) - 1;
+ spin_lock_irqsave(&kretprobe_lock, flags);
for (--size; size != end; --size) {
swap_unregister_kprobe(&rps[size]->kp);
- if (rp_disarm) {
- spin_lock_irqsave(&kretprobe_lock, flags);
+ if (rp_disarm)
swap_disarm_krp(rps[size]);
- spin_unlock_irqrestore(&kretprobe_lock, flags);
- }
}
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;
}
static char *fops_fpath(struct file *file, char *buf, int buflen)
{
- char *filename;
-
- path_get(&file->f_path);
- filename = d_path(&file->f_path, buf, buflen);
- path_put(&file->f_path);
+ char *filename = d_path(&file->f_path, buf, buflen);
if (IS_ERR_OR_NULL(filename)) {
printk(FOPS_PREFIX "d_path FAILED: %ld\n", PTR_ERR(filename));
n = strncpy_from_user(p, ofile, size);
if (n < 0) {
printk(KSF_PREFIX "cannot copy ofile\n");
- goto put_msg;
+ swap_msg_put(m);
}
swap_msg_flush(m, ret + n + 1);
obj-m := swap_master.o
swap_master-y := master_module.o \
swap_debugfs.o \
- swap_initializer.o \
- swap_deps.o
+ swap_initializer.o
+++ /dev/null
-/*
- * 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, 2015
- *
- * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
- *
- */
-
-
-#include <linux/module.h>
-#include <ksyms/ksyms.h>
-#include "swap_deps.h"
-
-
-static struct files_struct *(*__get_files_struct)(struct task_struct *);
-static void (*__put_files_struct)(struct files_struct *fs);
-
-struct files_struct *swap_get_files_struct(struct task_struct *task)
-{
- return __get_files_struct(task);
-}
-EXPORT_SYMBOL_GPL(swap_get_files_struct);
-
-void swap_put_files_struct(struct files_struct *fs)
-{
- __put_files_struct(fs);
-}
-EXPORT_SYMBOL_GPL(swap_put_files_struct);
-
-
-int chef_once(void)
-{
- const char *sym;
- static unsigned once_flag = 0;
-
- if (once_flag)
- return 0;
-
- sym = "get_files_struct";
- __get_files_struct = (void *)swap_ksyms(sym);
- if (__get_files_struct == NULL)
- goto not_found;
-
- sym = "put_files_struct";
- __put_files_struct = (void *)swap_ksyms(sym);
- if (__put_files_struct == NULL)
- goto not_found;
-
- once_flag = 1;
- return 0;
-
-not_found:
- printk("ERROR: symbol '%s' not found\n", sym);
- return -ESRCH;
-}
-
+++ /dev/null
-/*
- * 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, 2015
- *
- * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
- *
- */
-
-
-#ifndef _SWAP_DEPS_H
-#define _SWAP_DEPS_H
-
-
-struct task_struct;
-struct files_struct;
-
-
-struct files_struct *swap_get_files_struct(struct task_struct *task);
-void swap_put_files_struct(struct files_struct *fs);
-
-
-int chef_once(void);
-
-
-#endif /* _SWAP_DEPS_H */
#include <linux/types.h>
#include <linux/spinlock.h>
#include "swap_initializer.h"
-#include "swap_deps.h"
enum init_level {
int ret;
struct swap_init_struct *init;
- ret = chef_once();
- if (ret)
- return ret;
-
list_for_each_entry(init, &init_list, list) {
ret = sis_once(init);
if (ret)
}
pi->probe_type = SWAP_PRELOAD_PROBE;
- pi->size = 0;
+ pi->size = sizeof(pi->pl_i) + sizeof(pi->probe_type) + sizeof(pi->size);
pi->pl_i.handler = handler;
pi->pl_i.flags = flags;
int get_get_caller_probe(struct msg_buf *mb, struct probe_info *pi)
{
pi->probe_type = SWAP_GET_CALLER;
- pi->size = 0;
+ pi->size = sizeof(pi->gc_i);
return 0;
}
int get_get_call_type_probe(struct msg_buf *mb, struct probe_info *pi)
{
pi->probe_type = SWAP_GET_CALL_TYPE;
- pi->size = 0;
+ pi->size = sizeof(pi->gct_i);
return 0;
}
int get_write_msg_probe(struct msg_buf *mb, struct probe_info *pi)
{
pi->probe_type = SWAP_WRITE_MSG;
- pi->size = 0;
+ pi->size = sizeof(pi->wm_i);
return 0;
}
return ret;
ret = init_cpu_deps();
+ if (ret)
+ return ret;
+
+ ret = usm_msg_once();
return ret;
}
#include <linux/dcache.h>
#include <linux/fdtable.h>
#include <writer/swap_msg.h>
-#include <master/swap_deps.h>
#include <us_manager/sspt/sspt.h> /* ... check_vma() */
#define USM_PREFIX KERN_INFO "[USM] "
+static struct files_struct *(*swap_get_files_struct)(struct task_struct *);
+static void (*swap_put_files_struct)(struct files_struct *fs);
+
+int usm_msg_once(void)
+{
+ const char *sym;
+
+ sym = "get_files_struct";
+ swap_get_files_struct = (void *)swap_ksyms(sym);
+ if (swap_get_files_struct == NULL)
+ goto not_found;
+
+ sym = "put_files_struct";
+ swap_put_files_struct = (void *)swap_ksyms(sym);
+ if (swap_put_files_struct == NULL)
+ goto not_found;
+
+ return 0;
+
+not_found:
+ printk("ERROR: symbol '%s' not found\n", sym);
+ return -ESRCH;
+}
+
+
+
+
+
struct kmem_info {
const char *name;
unsigned long start;
goto cp2buf;
}
- path_get(&file->f_path);
filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
- path_put(&file->f_path);
-
if (IS_ERR_OR_NULL(filename)) {
filename = NA;
goto cp2buf;
struct task_struct;
struct vm_area_struct;
+int usm_msg_once(void);
void usm_msg_info(struct task_struct *task, struct dentry *dentry);
void usm_msg_term(struct task_struct *task);
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/limits.h>
-#include <linux/list.h>
#include <us_manager/sspt/ip.h>
#include "preload_probe.h"
#include "preload_module.h"
+
+#define DEFAULT_SLOTS_COUNT 5
+#define DEFAULT_SLOTS_STEP 2
+
struct bin_desc {
- struct list_head list;
struct dentry *dentry;
char *filename;
};
-static LIST_HEAD(target_binaries_list);
-static DEFINE_RWLOCK(target_binaries_lock);
-static int target_binaries_cnt = 0;
+static struct bin_desc *target_binaries = NULL;
+static unsigned int target_binaries_cnt = 0;
+static unsigned int target_binaries_slots = 0;
+
+static DEFINE_MUTEX(__target_binaries_mutex);
+
+
+static inline void __target_binaries_lock(void)
+{
+ mutex_lock(&__target_binaries_mutex);
+}
+
+static inline void __target_binaries_unlock(void)
+{
+ mutex_unlock(&__target_binaries_mutex);
+}
static inline struct task_struct *__get_task_struct(void)
{
return current;
}
-static struct bin_desc *__alloc_target_binary(struct dentry *dentry,
- char *name, int namelen)
+static int __alloc_target_binaries_no_lock(unsigned int cnt)
{
- struct bin_desc *p = NULL;
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return NULL;
+ target_binaries = kmalloc(sizeof(*target_binaries) * cnt, GFP_KERNEL);
+ if (target_binaries == NULL)
+ return -ENOMEM;
- INIT_LIST_HEAD(&p->list);
- p->filename = kmalloc(namelen + 1, GFP_KERNEL);
- if (!p->filename)
- goto fail;
- memcpy(p->filename, name, namelen);
- p->filename[namelen] = '\0';
- p->dentry = dentry;
+ target_binaries_slots = cnt;
- return p;
-fail:
- kfree(p);
- return NULL;
+ return 0;
}
-static void __free_target_binary(struct bin_desc *p)
+static int __alloc_target_binaries(unsigned int cnt)
{
- kfree(p->filename);
- kfree(p);
+ int ret;
+
+ __target_binaries_lock();
+ ret = __alloc_target_binaries_no_lock(cnt);
+ __target_binaries_unlock();
+
+ return ret;
}
static void __free_target_binaries(void)
{
- struct bin_desc *p, *n;
- struct list_head rm_head;
+ int i;
+
+ __target_binaries_lock();
- INIT_LIST_HEAD(&rm_head);
- write_lock(&target_binaries_lock);
- list_for_each_entry_safe(p, n, &target_binaries_list, list) {
- list_move(&p->list, &rm_head);
+ for (i = 0; i < target_binaries_cnt; i++) {
+ put_dentry(target_binaries[i].dentry);
+ kfree(target_binaries[i].filename);
}
+
+ kfree(target_binaries);
target_binaries_cnt = 0;
- write_unlock(&target_binaries_lock);
+ target_binaries_slots = 0;
+
+ __target_binaries_unlock();
+}
+
+static int __grow_target_binaries(void)
+{
+ struct bin_desc *tmp = target_binaries;
+ int i, ret;
+
+ __target_binaries_lock();
+
+ ret = __alloc_target_binaries_no_lock(target_binaries_slots + DEFAULT_SLOTS_STEP);
+ if (ret != 0)
+ return ret;
- list_for_each_entry_safe(p, n, &rm_head, list) {
- list_del(&p->list);
- put_dentry(p->dentry);
- __free_target_binary(p);
+ target_binaries_slots += DEFAULT_SLOTS_STEP;
+
+ for (i = 0; i < target_binaries_cnt; i++) {
+ target_binaries[i].dentry = tmp[i].dentry;
+ target_binaries[i].filename = tmp[i].filename;
}
+
+ __target_binaries_unlock();
+
+ kfree(tmp);
+
+ return 0;
}
static bool __check_dentry_already_exist(struct dentry *dentry)
{
- struct bin_desc *p;
+ int i;
bool ret = false;
- read_lock(&target_binaries_lock);
- list_for_each_entry(p, &target_binaries_list, list) {
- if (p->dentry == dentry) {
+ __target_binaries_lock();
+
+ for (i = 0; i < target_binaries_cnt; i++) {
+ if (target_binaries[i].dentry == dentry) {
ret = true;
- goto out;
+ goto check_dentry_unlock;
}
}
-out:
- read_unlock(&target_binaries_lock);
+
+check_dentry_unlock:
+ __target_binaries_unlock();
return ret;
}
static int __add_target_binary(struct dentry *dentry, char *filename)
{
- struct bin_desc *p;
+ int ret;
size_t len;
if (__check_dentry_already_exist(dentry)) {
return EALREADY;
}
+
+ if (target_binaries_slots == target_binaries_cnt) {
+ ret = __grow_target_binaries();
+ if (ret != 0)
+ return ret;
+ }
+
/* Filename should be < PATH_MAX */
len = strnlen(filename, PATH_MAX);
if (len == PATH_MAX)
return -EINVAL;
- p = __alloc_target_binary(dentry, filename, len);
- if (!p)
- return -ENOMEM;
+ __target_binaries_lock();
+
+ target_binaries[target_binaries_cnt].dentry = dentry;
+ target_binaries[target_binaries_cnt].filename = kmalloc(len + 1, GFP_KERNEL);
+ memcpy(target_binaries[target_binaries_cnt].filename, filename, len + 1);
+ ++target_binaries_cnt;
- write_lock(&target_binaries_lock);
- list_add_tail(&p->list, &target_binaries_list);
- target_binaries_cnt++;
- write_unlock(&target_binaries_lock);
+ __target_binaries_unlock();
return 0;
}
+static char *__get_binary_name(struct bin_desc *bin)
+{
+ return bin->filename;
+}
+
static struct dentry *__get_caller_dentry(struct task_struct *task,
unsigned long caller)
{
static bool __check_if_instrumented(struct task_struct *task,
struct dentry *dentry)
{
- return __check_dentry_already_exist(dentry);
+ int i;
+
+ for (i = 0; i < target_binaries_cnt; i++)
+ if (target_binaries[i].dentry == dentry)
+ return true;
+
+ return false;
}
static bool __is_instrumented(void *caller)
int preload_control_clean_instrumented_bins(void)
{
__free_target_binaries();
-
- return 0;
+ return __alloc_target_binaries(DEFAULT_SLOTS_COUNT);
}
unsigned int preload_control_get_bin_names(char ***filenames_p)
{
- unsigned int i, ret = 0;
- struct bin_desc *p;
- char **a = NULL;
+ int i;
+ unsigned int ret = 0;
- read_lock(&target_binaries_lock);
if (target_binaries_cnt == 0)
- goto out;
+ return 0;
- a = kmalloc(sizeof(*a) * target_binaries_cnt, GFP_KERNEL);
- if (!a)
- goto out;
+ __target_binaries_lock();
- i = 0;
- list_for_each_entry(p, &target_binaries_list, list) {
- if (i >= target_binaries_cnt)
- break;
- a[i++] = p->filename;
- }
+ *filenames_p = kmalloc(sizeof(**filenames_p) * target_binaries_cnt,
+ GFP_KERNEL);
+ if (*filenames_p == NULL)
+ goto get_binaries_names_out;
+
+ for (i = 0; i < target_binaries_cnt; i++)
+ (*filenames_p)[i] = __get_binary_name(&target_binaries[i]);
+
+ ret = target_binaries_cnt;
+
+get_binaries_names_out:
+ __target_binaries_unlock();
- *filenames_p = a;
- ret = i;
-out:
- read_unlock(&target_binaries_lock);
return ret;
}
int preload_control_init(void)
{
- return 0;
+ return __alloc_target_binaries(DEFAULT_SLOTS_COUNT);
}
void preload_control_exit(void)
__free_target_binaries();
}
+#undef DEFAULT_SLOTS_STEP
+#undef DEFAULT_SLOTS_COUNT
static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
static const char PRELOAD_CALLER[] = "caller";
static const char PRELOAD_HANDLERS_PATH[] = "handlers_path";
-static const char PRELOAD_UI_VIEWER_PATH[] = "ui_viewer_path";
-static const char PRELOAD_UI_VIEWER_APP_INFO[] = "ui_viewer_app_info";
static const char PRELOAD_LINKER_DATA[] = "linker";
static const char PRELOAD_LINKER_PATH[] = "linker_path";
static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
};
-/* ===========================================================================
- * = UI VIEWER PATH =
- * ===========================================================================
- */
-
-
-static ssize_t ui_viewer_path_write(struct file *file, const char __user *buf,
- size_t len, loff_t *ppos)
-{
- ssize_t ret;
- char *path;
-
- path = kmalloc(len, GFP_KERNEL);
- if (path == NULL) {
- ret = -ENOMEM;
- goto ui_viewer_path_write_out;
- }
-
- if (copy_from_user(path, buf, len)) {
- ret = -EINVAL;
- goto ui_viewer_path_write_out;
- }
-
- path[len - 1] = '\0';
-
- if (preload_storage_set_ui_viewer_info(path) != 0) {
- printk(PRELOAD_PREFIX "Cannot set ui viewer path %s\n", path);
- ret = -EINVAL;
- goto ui_viewer_path_write_out;
- }
-
- ret = len;
-
- printk(PRELOAD_PREFIX "Set ui viewer path %s\n", path);
-
-ui_viewer_path_write_out:
- kfree(path);
-
- return ret;
-}
-
-static const struct file_operations ui_viewer_path_file_ops = {
- .owner = THIS_MODULE,
- .write = ui_viewer_path_write,
-};
-
-
-/*
- * format:
- * main:app_path
- *
- * sample:
- * 0x00000d60:/bin/app_sample
- */
-static int ui_viewer_add_app_info(const char *buf, size_t len)
-{
- int n, ret;
- char *app_path;
- unsigned long main_addr;
- const char fmt[] = "%%lx:/%%%ds";
- char fmt_buf[64];
-
- n = snprintf(fmt_buf, sizeof(fmt_buf), fmt, PATH_MAX - 2);
- if (n <= 0)
- return -EINVAL;
-
- app_path = kmalloc(PATH_MAX, GFP_KERNEL);
- if (app_path == NULL)
- return -ENOMEM;
-
- n = sscanf(buf, fmt_buf, &main_addr, app_path + 1);
- if (n != 2) {
- ret = -EINVAL;
- goto free_app_path;
- }
- app_path[0] = '/';
-
- printk(PRELOAD_PREFIX "Set ui viewer app path %s, main offset 0x%lx\n", app_path, main_addr);
-
- ret = preload_ui_viewer_data_set(app_path, main_addr);
-
-free_app_path:
- kfree(app_path);
- return ret;
-}
-
-static ssize_t write_ui_viewer_app_info(struct file *file,
- const char __user *user_buf,
- size_t len, loff_t *ppos)
-{
- ssize_t ret;
- char *buf;
-
- buf = kmalloc(len, GFP_KERNEL);
- if (buf == NULL) {
- ret = -ENOMEM;
- goto free_buf;
- }
-
- if (copy_from_user(buf, user_buf, len)) {
- ret = -EINVAL;
- goto free_buf;
- }
-
- buf[len - 1] = '\0';
-
- if (ui_viewer_add_app_info(buf, len))
- ret = -EINVAL;
-
- ret = len;
-
-free_buf:
- kfree(buf);
-
- return ret;
-}
-
-static const struct file_operations ui_viewer_app_info_file_ops = {
- .owner = THIS_MODULE,
- .write = write_ui_viewer_app_info,
-};
-
unsigned long preload_debugfs_r_debug_offset(void)
{
struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
*bin_path, *bin_list, *bin_add, *bin_remove,
- *linker_dir, *linker_path, *linker_offset, *handlers_path,
- *ui_viewer_path, *ui_viewer_app_info;
+ *linker_dir, *linker_path, *linker_offset, *handlers_path;
int ret;
ret = -ENODEV;
goto remove;
}
- ui_viewer_path = debugfs_create_file(PRELOAD_UI_VIEWER_PATH,
- PRELOAD_DEFAULT_PERMS, root, NULL,
- &ui_viewer_path_file_ops);
- if (IS_ERR_OR_NULL(ui_viewer_path)) {
- ret = -ENOMEM;
- goto remove;
- }
-
- ui_viewer_app_info = debugfs_create_file(PRELOAD_UI_VIEWER_APP_INFO,
- PRELOAD_DEFAULT_PERMS, root, NULL,
- &ui_viewer_app_info_file_ops);
- if (IS_ERR_OR_NULL(ui_viewer_app_info)) {
- ret = -ENOMEM;
- goto remove;
- }
-
return 0;
remove:
#include <kprobe/swap_kprobes.h>
#include <kprobe/swap_kprobes_deps.h>
#include <us_manager/us_manager_common.h>
-#include <us_manager/pf/pf_group.h>
#include <us_manager/sspt/sspt_page.h>
#include <us_manager/sspt/sspt_file.h>
#include <us_manager/sspt/sspt_proc.h>
#include <us_manager/sspt/ip.h>
#include <us_manager/callbacks.h>
-#include <us_manager/probes/probe_info_new.h>
#include <writer/kernel_operations.h>
#include <master/swap_initializer.h>
#include <writer/swap_msg.h>
+#include <task_data/task_data.h>
#include "preload.h"
#include "preload_probe.h"
#include "preload_debugfs.h"
enum mmap_type_t {
MMAP_LOADER,
MMAP_HANDLERS,
- MMAP_UI_VIEWER,
MMAP_SKIP
};
unsigned long prot = swap_get_karg(regs, 3);
struct mmap_priv *priv = (struct mmap_priv *)ri->data;
struct dentry *dentry, *loader_dentry;
- struct bin_info *hi, *vi;
+ struct bin_info *hi;
priv->type = MMAP_SKIP;
if (!check_prot(prot))
return 0;
}
- vi = preload_storage_get_ui_viewer_info();
- if (vi == NULL) {
- printk(PRELOAD_PREFIX "Cannot get ui viewer info [%u %u %s]\n",
- current->tgid, current->pid, current->comm);
- goto put_hi;
- }
-
loader_dentry = preload_debugfs_get_loader_dentry();
if (dentry == loader_dentry)
priv->type = MMAP_LOADER;
else if (hi->dentry != NULL && dentry == hi->dentry)
priv->type = MMAP_HANDLERS;
- else if (vi->dentry != NULL && dentry == vi->dentry)
- priv->type = MMAP_UI_VIEWER;
- preload_storage_put_handlers_info(vi);
-put_hi:
preload_storage_put_handlers_info(hi);
return 0;
case MMAP_HANDLERS:
preload_pd_set_handlers_base(pd, vaddr);
break;
- case MMAP_UI_VIEWER:
- preload_pd_set_ui_viewer_base(proc->private_data, vaddr);
- break;
case MMAP_SKIP:
default:
break;
if (vaddr) {
/* save original regs state */
__save_uregs(ri, regs);
- print_regs("PROBE ORIG", regs, ri);
+ print_regs("ORIG", regs, ri);
path = preload_pd_get_path(pd);
/* restore original regs state */
__restore_uregs(ri, regs);
- print_regs("PROBE REST", regs, ri);
+ print_regs("REST", regs, ri);
/* check if preloading done */
if (preload_pd_get_handle(pd)) {
preload_pd_set_state(pd, LOADED);
+ preload_pd_put_path(pd);
} else {
preload_pd_dec_attempts(pd);
preload_pd_set_state(pd, FAILED);
+ preload_pd_put_path(pd);
}
}
break;
case FAILED:
if (preload_pd_get_attempts(pd)) {
preload_pd_set_state(pd, NOT_LOADED);
+ preload_pd_put_path(pd);
}
break;
case ERROR:
}
-
-/* ============================================================================
- * = ui_viewer =
- * ============================================================================
- */
-
-/* main handler for ui viewer */
-static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri,
- struct pt_regs *regs);
-static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri,
- struct pt_regs *regs);
-static struct probe_info_new pin_main = MAKE_URPROBE(preload_ui_viewer_main_eh,
- preload_ui_viewer_main_rh,
- 0);
-
-struct ui_viewer_data {
- struct dentry *app_dentry;
- struct probe_new p_main;
- struct pf_group *pfg;
-};
-
-static struct ui_viewer_data __ui_data;
-
-static int preload_ui_viewer_data_inst(void)
-{
- int ret;
- struct pf_group *pfg;
-
- pfg = get_pf_group_by_dentry(__ui_data.app_dentry,
- (void *)__ui_data.app_dentry);
- if (pfg == NULL)
- return -ENOMEM;
-
- ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry);
- if (ret)
- goto put_g;
-
- __ui_data.pfg = pfg;
-
- return 0;
-put_g:
- put_pf_group(pfg);
- return ret;
-}
-
-/*
-static void preload_ui_viewer_data_uninst(void)
-{
- struct pf_group *pfg = __ui_data.pfg;
-
- pin_unregister(&__ui_data.p_main, pfg, __ui_data.app_dentry);
-
- put_pf_group(pfg);
-
- __ui_data.pfg = NULL;
-}
-*/
-
-static int preload_ui_viewer_init(struct us_ip *ip)
-{
- return 0;
-}
-
-static void preload_ui_viewer_exit(struct us_ip *ip)
-{
- return;
-}
-
-int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr)
-{
- struct dentry *dentry;
-
- dentry = dentry_by_path(app_path);
- if (dentry == NULL)
- return -ENOENT;
-
- __ui_data.app_dentry = dentry;
- __ui_data.p_main.info = &pin_main;
- __ui_data.p_main.offset = main_addr;
- __ui_data.pfg = NULL;
-
- preload_ui_viewer_data_inst();
-
- return 0;
-}
-
-/* ============================================================================
- * = ui viewer handlers =
- * ============================================================================
- */
-static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri,
- struct pt_regs *regs)
-{
- struct process_data *pd;
- struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
- unsigned long vaddr = 0;
- char __user *path = NULL;
-
- preload_ui_viewer_init(ip);
-
- pd = __get_process_data(ri->rp);
-
- switch (preload_pd_get_ui_viewer_state(pd)) {
- case NOT_LOADED:
- /* jump to loader code if ready */
- vaddr = preload_pd_get_loader_base(pd) +
- preload_debugfs_get_loader_offset();
- if (vaddr) {
- /* save original regs state */
- __save_uregs(ri, regs);
- print_regs("UI VIEWER ORIG", regs, ri);
-
- path = preload_pd_get_ui_viewer_path(pd);
-
- /* set dlopen args: filename, flags */
- swap_set_arg(regs, 0, (unsigned long)path);
- swap_set_arg(regs, 1, 2 /* RTLD_NOW */);
-
- /* do the jump to dlopen */
- __prepare_ujump(ri, regs, vaddr);
- /* set new state */
- preload_pd_set_ui_viewer_state(pd, LOADING);
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
- struct process_data *pd = __get_process_data(ri->rp);
- struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
- unsigned long vaddr = 0;
-
- switch (preload_pd_get_ui_viewer_state(pd)) {
- case LOADING:
- vaddr = preload_pd_get_loader_base(pd) +
- preload_debugfs_get_loader_offset();
- if (vaddr) {
- preload_pd_set_handle(pd,
- (void __user *)regs_return_value(regs));
- /* restore original regs state */
- __restore_uregs(ri, regs);
- print_regs("UI VIEWER REST", regs, ri);
-
- /* check if preloading is done */
- if (preload_pd_get_handle(pd)) {
- preload_pd_set_ui_viewer_state(pd, LOADED);
- } else {
- preload_pd_set_ui_viewer_state(pd, FAILED);
- }
- }
- default:
- break;
- }
-
- preload_ui_viewer_exit(ip);
-
- return 0;
-}
-
-
static int preload_module_init(void)
{
int ret;
struct dentry *get_dentry(const char *filepath);
void put_dentry(struct dentry *dentry);
-int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr);
-
#endif /* __PRELOAD_MODULE_H__ */
#include "preload_storage.h"
#include "preload.h"
-
struct process_data {
enum preload_state_t state;
- enum preload_state_t ui_viewer_state;
unsigned long loader_base;
unsigned long handlers_base;
- unsigned long ui_viewer_base;
unsigned long data_page;
- unsigned long ui_viewer_offset;
void __user *handle;
long attempts;
long refcount;
};
static struct bin_info *handlers_info;
-static struct bin_info *ui_viewer_info;
pd->refcount = refcount;
}
-static inline enum preload_state_t __get_ui_viewer_state(struct process_data *pd)
-{
- return pd->ui_viewer_state;
-}
-
-static inline void __set_ui_viewer_state(struct process_data *pd,
- enum preload_state_t state)
-{
- pd->ui_viewer_state = state;
-}
-
-static inline void __set_ui_viewer_base(struct process_data *pd,
- unsigned long addr)
-{
- pd->ui_viewer_base = addr;
-}
-
-static inline unsigned long __get_ui_viewer_base(struct process_data *pd)
-{
- return pd->ui_viewer_base;
-}
-
-static inline void __set_ui_viewer_offset(struct process_data *pd,
- unsigned long offset)
-{
- pd->ui_viewer_offset = offset;
-}
-
-static inline char __user *__get_ui_viewer_path(struct process_data *pd)
-{
- return (char *)(pd->data_page + pd->ui_viewer_offset);
-}
return -EINVAL;
}
- if (ui_viewer_info == NULL) {
- ui_viewer_info = preload_storage_get_ui_viewer_info();
- if (ui_viewer_info == NULL)
- return -EINVAL;
- }
-
return 0;
}
{
if (pd == NULL) {
printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
- current->tgid, current->comm);
+ current->tgid, current->comm);
return;
}
__set_state(pd, state);
}
-enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd)
-{
- if (pd == NULL)
- return 0;
-
- return __get_ui_viewer_state(pd);
-}
-
-void preload_pd_set_ui_viewer_state(struct process_data *pd,
- enum preload_state_t state)
-{
- if (pd == NULL) {
- printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
- current->tgid, current->comm);
- return;
- }
-
- __set_ui_viewer_state(pd, state);
-}
-
-char __user *preload_pd_get_path(struct process_data *pd)
-{
- char __user *path = __get_path(pd);
-
- return path;
-}
-
-char __user *preload_pd_get_ui_viewer_path(struct process_data *pd)
-{
- char __user *path = __get_ui_viewer_path(pd);
-
- return path;
-}
-
unsigned long preload_pd_get_loader_base(struct process_data *pd)
{
if (pd == NULL)
__set_handlers_base(pd, vaddr);
}
-unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd)
-{
- if (pd == NULL)
- return 0;
-
- return __get_ui_viewer_base(pd);
-}
-
-void preload_pd_set_ui_viewer_base(struct process_data *pd, unsigned long vaddr)
-{
- if (pd == NULL) {
- printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
- current->tgid, current->comm);
- return;
- }
-
- __set_ui_viewer_base(pd, vaddr);
-}
-
void preload_pd_put_path(struct process_data *pd)
{
if (pd == NULL) {
printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
- current->tgid, current->comm);
+ current->tgid, current->comm);
return;
}
__set_data_page(pd, 0);
}
+char __user *preload_pd_get_path(struct process_data *pd)
+{
+ char __user *path = __get_path(pd);
+
+ return path;
+}
+
+
+
void *preload_pd_get_handle(struct process_data *pd)
{
if (pd == NULL)
return (struct process_data *)proc->private_data;
}
-static unsigned long make_preload_path(unsigned long *offset)
+static unsigned long make_preload_path(void)
{
unsigned long page = -EINVAL;
- if (handlers_info && ui_viewer_info) {
- const char *probe_path = handlers_info->path;
- size_t probe_len = strnlen(probe_path, PATH_MAX);
- const char *ui_viewer_path = ui_viewer_info->path;
- size_t ui_viewer_len = strnlen(ui_viewer_path, PATH_MAX);
+ if (handlers_info) {
+ const char *path = handlers_info->path;
+ size_t len = strnlen(path, PATH_MAX);
down_write(¤t->mm->mmap_sem);
page = swap_do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
goto out;
}
- /* set preload_libraries paths */
- if (copy_to_user((void __user *)page, probe_path,
- probe_len) != 0)
- printk(KERN_ERR PRELOAD_PREFIX
- "Cannot copy string to user!\n");
-
- /* split paths with 0 value */
- *offset = probe_len + 1;
-
- if (copy_to_user((void __user *)(page + *offset),
- ui_viewer_path, ui_viewer_len) != 0)
+ /* set preload_library path */
+ if (copy_to_user((void __user *)page, path, len) != 0)
printk(KERN_ERR PRELOAD_PREFIX
"Cannot copy string to user!\n");
}
static struct process_data *do_create_pd(struct task_struct *task)
{
struct process_data *pd;
- unsigned long page, offset = 0;
+ unsigned long page;
int ret;
ret = __pd_create_on_demand();
goto create_pd_exit;
}
- page = make_preload_path(&offset);
+ page = make_preload_path();
if (IS_ERR_VALUE(page)) {
ret = (long)page;
goto free_pd;
}
__set_data_page(pd, page);
- __set_ui_viewer_offset(pd, offset);
__set_attempts(pd, PRELOAD_MAX_ATTEMPTS);
set_already_mapp(pd, task->mm);
if (handlers_info)
preload_storage_put_handlers_info(handlers_info);
handlers_info = NULL;
-
- if (ui_viewer_info)
- preload_storage_put_ui_viewer_info(ui_viewer_info);
- ui_viewer_info = NULL;
}
enum preload_state_t preload_pd_get_state(struct process_data *pd);
void preload_pd_set_state(struct process_data *pd, enum preload_state_t state);
-enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd);
-void preload_pd_set_ui_viewer_state(struct process_data *pd,
- enum preload_state_t state);
unsigned long preload_pd_get_loader_base(struct process_data *pd);
void preload_pd_set_loader_base(struct process_data *pd, unsigned long vaddr);
unsigned long preload_pd_get_handlers_base(struct process_data *pd);
void preload_pd_set_handlers_base(struct process_data *pd, unsigned long vaddr);
-unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd);
-void preload_pd_set_ui_viewer_base(struct process_data *pd,
- unsigned long vaddr);
void *preload_pd_get_handle(struct process_data *pd);
void preload_pd_set_handle(struct process_data *pd, void __user *handle);
long preload_pd_get_refs(struct process_data *pd);
char __user *preload_pd_get_path(struct process_data *pd);
-char __user *preload_pd_get_ui_viewer_path(struct process_data *pd);
void preload_pd_put_path(struct process_data *pd);
int preload_pd_init(void);
preload_module_write_msg_init(ip);
}
-static int write_msg_reg(struct us_ip *ip)
-{
- ip->uprobe.atomic_ctx = false;
-
- return get_caller_register_probe(ip);
-}
-
static void write_msg_uninit(struct us_ip *ip)
{
preload_module_write_msg_exit(ip);
static struct probe_iface write_msg_iface = {
.init = write_msg_init,
.uninit = write_msg_uninit,
- .reg = write_msg_reg,
+ .reg = get_caller_register_probe,
.unreg = get_caller_unregister_probe,
.get_uprobe = get_caller_get_uprobe,
.copy = get_caller_info_copy,
return ret;
ret = swap_register_probe_type(SWAP_WRITE_MSG, &write_msg_iface);
-
return ret;
}
#include "preload_storage.h"
static struct bin_info __handlers_info = { NULL, NULL };
-static struct bin_info __ui_viewer_info = { NULL, NULL };
static struct bin_info __linker_info = { NULL, NULL };
static struct bin_info __libc_info;
static struct bin_info __libpthread_info;
__handlers_info.dentry = NULL;
}
-static inline struct bin_info *__get_ui_viewer_info(void)
-{
- return &__ui_viewer_info;
-}
-
-static inline bool __check_ui_viewer_info(void)
-{
- return (__ui_viewer_info.dentry != NULL); /* TODO */
-}
-
-static inline int __init_ui_viewer_info(char *path)
-{
- struct dentry *dentry;
- size_t len = strnlen(path, PATH_MAX);
- int ret = 0;
-
- __ui_viewer_info.path = kmalloc(len + 1, GFP_KERNEL);
- if (__ui_viewer_info.path == NULL) {
- ret = -ENOMEM;
- goto init_ui_viewer_fail;
- }
-
- dentry = get_dentry(path);
- if (!dentry) {
- ret = -ENOENT;
- goto init_ui_viewer_fail_free;
- }
-
- strncpy(__ui_viewer_info.path, path, len);
- __ui_viewer_info.path[len] = '\0';
- __ui_viewer_info.dentry = dentry;
-
- return ret;
-
-init_ui_viewer_fail_free:
- kfree(__ui_viewer_info.path);
-
-init_ui_viewer_fail:
- return ret;
-}
-
-static inline void __drop_ui_viewer_info(void)
-{
- kfree(__ui_viewer_info.path);
- __ui_viewer_info.path = NULL;
-
- if (__ui_viewer_info.dentry)
- put_dentry(__ui_viewer_info.dentry);
- __ui_viewer_info.dentry = NULL;
-}
-
static inline struct bin_info *__get_linker_info(void)
{
return &__linker_info;
{
}
-int preload_storage_set_ui_viewer_info(char *path)
-{
- return __init_ui_viewer_info(path);
-}
-
-struct bin_info *preload_storage_get_ui_viewer_info(void)
-{
- struct bin_info *info = __get_ui_viewer_info();
-
- if (__check_ui_viewer_info())
- return info;
-
- return NULL;
-}
-
-void preload_storage_put_ui_viewer_info(struct bin_info *info)
-{
-}
-
int preload_storage_set_linker_info(char *path)
{
return __init_linker_info(path);
__drop_libpthread_info();
__drop_libc_info();
__drop_handlers_info();
- __drop_ui_viewer_info();
__drop_linker_info();
}
struct bin_info *preload_storage_get_handlers_info(void);
void preload_storage_put_handlers_info(struct bin_info *info);
-int preload_storage_set_ui_viewer_info(char *path);
-struct bin_info *preload_storage_get_ui_viewer_info(void);
-void preload_storage_put_ui_viewer_info(struct bin_info *info);
-
int preload_storage_set_linker_info(char *path);
struct bin_info *preload_storage_get_linker_info(void);
void preload_storage_put_linker_info(struct bin_info *info);
td->data = NULL;
return;
}
+
+ WARN(!ok, TD_PREFIX "td(%p) check failed: %08lx", td, get_magic(td));
}
void *swap_task_data_get(struct task_struct *task, int *ok)
p = get_ukprobe((kprobe_opcode_t *)vaddr, tgid);
if (p) {
- struct uprobe *up = kp2up(p);
- bool prepare = false;
-
- if (up->atomic_ctx) {
- if (!p->pre_handler || !p->pre_handler(p, regs))
- prepare = true;
- } else {
- swap_preempt_enable_no_resched();
- local_irq_restore(flags);
-
- if (!p->pre_handler || !p->pre_handler(p, regs))
- prepare = true;
-
- local_irq_save(flags);
- preempt_disable();
- }
-
- if (prepare)
+ if (!p->pre_handler || !p->pre_handler(p, regs))
prepare_singlestep(p, regs);
} else {
ret = urp_handler(regs, tgid);
return 0;
}
-static bool get_long(struct task_struct *task,
- unsigned long vaddr, unsigned long *val)
-{
- return sizeof(*val) != read_proc_vm_atomic(task, vaddr,
- val, sizeof(*val));
-}
-
-static bool put_long(struct task_struct *task,
- unsigned long vaddr, unsigned long *val)
-{
- return sizeof(*val) != write_proc_vm_atomic(task, vaddr,
- val, sizeof(*val));
-}
-
/**
* @brief Disarms uretprobe on x86 arch.
*
else
tramp_addr = tr; /* ri - invalid */
- if (get_long(task, sp, &ret_addr)) {
+ if (get_user(ret_addr, (unsigned long *)sp)) {
printk(KERN_INFO "---> %s (%d/%d): failed to read stack from %08lx\n",
task->comm, task->tgid, task->pid, sp);
return -EFAULT;
}
if (tramp_addr == ret_addr) {
- if (put_long(task, sp, (unsigned long *)&ri->ret_addr)) {
+ if (put_user((unsigned long)ri->ret_addr, (unsigned long *)sp)) {
printk(KERN_INFO "---> %s (%d/%d): failed to write "
"orig_ret_addr to %08lx",
task->comm, task->tgid, task->pid, sp);
struct uretprobe_instance *ri;
__swap_unregister_uprobe(&rp->up, disarm);
-
spin_lock_irqsave(&uretprobe_lock, flags);
- while ((ri = get_used_urp_inst(rp)) != NULL) {
- bool is_current = ri->task == current;
- if (is_current)
- spin_unlock_irqrestore(&uretprobe_lock, flags);
-
- /* FIXME: arch_disarm_urp_inst() for no current context */
+ while ((ri = get_used_urp_inst(rp)) != NULL) {
if (arch_disarm_urp_inst(ri, ri->task, 0) != 0)
printk(KERN_INFO "%s (%d/%d): "
"cannot disarm urp instance (%08lx)\n",
ri->task->comm, ri->task->tgid, ri->task->pid,
(unsigned long)rp->up.kp.addr);
-
- if (is_current)
- spin_lock_irqsave(&uretprobe_lock, flags);
-
recycle_urp_inst(ri);
}
ri->rp = NULL;
hlist_del(&ri->uflist);
}
- spin_unlock_irqrestore(&uretprobe_lock, flags);
+ spin_unlock_irqrestore(&uretprobe_lock, flags);
free_urp_inst(rp);
}
EXPORT_SYMBOL_GPL(__swap_unregister_uretprobe);
struct task_struct *task; /**< Pointer to the task struct */
struct slot_manager *sm; /**< Pointer to slot manager */
struct arch_specific_tramp atramp; /**< Stores trampoline */
- bool atomic_ctx; /**< Handler context */
};
struct uinst_info {
static int ctx_task_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
- int ret;
struct sspt_proc *proc;
+ unsigned long page_addr;
struct task_struct *task = current;
if (is_kthread(task) || check_task_on_filters(task) == 0)
if (proc && proc->first_install)
return 0;
- ret = set_kjump_cb(regs, cb_check_and_install, NULL, 0);
- if (ret < 0)
- pr_err("ctx_task_pre_handler: ret=%d\n", ret);
+ page_addr = 0;
- return 0;
+ return set_kjump_cb(regs, cb_check_and_install, NULL, 0);
}
static struct kprobe ctx_task_kprobe = {
};
sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(current);
+ proc = sspt_proc_get_by_task(current);
if (proc) {
sspt_proc_on_each_ip(proc, func_uinst_creare, (void *)&cdata.head);
urinst_info_get_current_hlist(&cdata.rhead, false);
/* if the thread is killed we need to discard pending
* uretprobe instances which have not triggered yet */
sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
+ proc = sspt_proc_get_by_task(task);
if (proc) {
urinst_info_get_current_hlist(&head, true);
}
sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
+ proc = sspt_proc_get_by_task(task);
if (proc)
__remove_unmap_probes(proc, umd);
struct sspt_proc *proc;
sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
+ proc = sspt_proc_get_by_task(task);
if (proc)
list_del(&proc->list);
sspt_proc_write_unlock();
ip->retprobe.handler = urp_ret_handler;
ip->retprobe.maxactive = 0;
/* FIXME: make dynamic size field 'data_size' */
- ip->retprobe.data_size = 128;
+ ip->retprobe.data_size = sizeof(void *);
}
static void urp_uninit(struct us_ip *ip)
up->kp.addr = (kprobe_opcode_t *)ip->orig_addr;
up->task = ip->page->file->proc->task;
up->sm = ip->page->file->proc->sm;
- up->atomic_ctx = true;
ret = probe_info_register(ip->info, ip);
if (ret) {
#include <linux/list.h>
#include <us_manager/us_slot_manager.h>
+
static LIST_HEAD(proc_probes_list);
static DEFINE_RWLOCK(sspt_proc_rwlock);
}
}
-struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
-{
- struct sspt_proc *proc;
-
- sspt_proc_read_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
- sspt_proc_read_unlock();
-
- return proc;
-}
-EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
-
/**
* @brief Get sspt_proc by task
*
* @param task Pointer on the task_struct struct
* @return Pointer on the sspt_proc struct
*/
-struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task)
+struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
{
struct sspt_proc *proc, *tmp;
return NULL;
}
-EXPORT_SYMBOL_GPL(sspt_proc_get_by_task_no_lock);
+EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
/**
* @brief Call func() on each proc (no lock)
*/
struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
{
- struct sspt_proc *proc;
-
- sspt_proc_write_lock();
- proc = sspt_proc_get_by_task_no_lock(task);
+ struct sspt_proc *proc = sspt_proc_get_by_task(task);
if (proc == NULL)
proc = sspt_proc_create(task);
- sspt_proc_write_unlock();
return proc;
}
void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data);
struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task);
-struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task);
struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task);
void sspt_proc_free_all(void);
{
struct sspt_proc *proc;
- /* FIXME: add read lock (deadlock in sampler) */
- proc = sspt_proc_get_by_task_no_lock(task);
+ proc = sspt_proc_get_by_task(task);
if (proc)
return sspt_proc_is_send_event(proc);
};
-/* TODO: configure this from outside (using debugfs) */
-static const char webapp_path[] = "/usr/bin/wrt_launchpad_daemon";
+static const char webapp_path[] = "/usr/bin/WebProcess";
static const char ewebkit_path[] = "/usr/lib/libewebkit2.so";