diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/kernel/profile.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c index 4cfcae620507..aad0a9e5991a 100644 --- a/arch/cris/kernel/profile.c +++ b/arch/cris/kernel/profile.c | |||
@@ -15,39 +15,47 @@ static int prof_running = 0; | |||
15 | void | 15 | void |
16 | cris_profile_sample(struct pt_regs* regs) | 16 | cris_profile_sample(struct pt_regs* regs) |
17 | { | 17 | { |
18 | if (!prof_running) | 18 | if (!prof_running) |
19 | return; | 19 | return; |
20 | if (user_mode(regs)) | 20 | |
21 | *(unsigned int*)sample_buffer_pos = current->pid; | 21 | if (user_mode(regs)) |
22 | else | 22 | *(unsigned int*)sample_buffer_pos = current->pid; |
23 | *(unsigned int*)sample_buffer_pos = 0; | 23 | else |
24 | *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); | 24 | *(unsigned int*)sample_buffer_pos = 0; |
25 | sample_buffer_pos += 8; | 25 | |
26 | if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) | 26 | *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); |
27 | sample_buffer_pos = sample_buffer; | 27 | sample_buffer_pos += 8; |
28 | |||
29 | if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) | ||
30 | sample_buffer_pos = sample_buffer; | ||
28 | } | 31 | } |
29 | 32 | ||
30 | static ssize_t | 33 | static ssize_t |
31 | read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 34 | read_cris_profile(struct file *file, char __user *buf, |
35 | size_t count, loff_t *ppos) | ||
32 | { | 36 | { |
33 | unsigned long p = *ppos; | 37 | unsigned long p = *ppos; |
34 | if (p > SAMPLE_BUFFER_SIZE) | 38 | |
35 | return 0; | 39 | if (p > SAMPLE_BUFFER_SIZE) |
36 | if (p + count > SAMPLE_BUFFER_SIZE) | 40 | return 0; |
37 | count = SAMPLE_BUFFER_SIZE - p; | 41 | |
38 | if (copy_to_user(buf, sample_buffer + p,count)) | 42 | if (p + count > SAMPLE_BUFFER_SIZE) |
43 | count = SAMPLE_BUFFER_SIZE - p; | ||
44 | if (copy_to_user(buf, sample_buffer + p,count)) | ||
39 | return -EFAULT; | 45 | return -EFAULT; |
40 | memset(sample_buffer + p, 0, count); | 46 | |
41 | *ppos += count; | 47 | memset(sample_buffer + p, 0, count); |
42 | return count; | 48 | *ppos += count; |
49 | |||
50 | return count; | ||
43 | } | 51 | } |
44 | 52 | ||
45 | static ssize_t | 53 | static ssize_t |
46 | write_cris_profile(struct file *file, const char __user *buf, | 54 | write_cris_profile(struct file *file, const char __user *buf, |
47 | size_t count, loff_t *ppos) | 55 | size_t count, loff_t *ppos) |
48 | { | 56 | { |
49 | sample_buffer_pos = sample_buffer; | 57 | sample_buffer_pos = sample_buffer; |
50 | memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); | 58 | memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); |
51 | } | 59 | } |
52 | 60 | ||
53 | static const struct file_operations cris_proc_profile_operations = { | 61 | static const struct file_operations cris_proc_profile_operations = { |
@@ -58,16 +66,23 @@ static const struct file_operations cris_proc_profile_operations = { | |||
58 | static int | 66 | static int |
59 | __init init_cris_profile(void) | 67 | __init init_cris_profile(void) |
60 | { | 68 | { |
61 | struct proc_dir_entry *entry; | 69 | struct proc_dir_entry *entry; |
62 | sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); | 70 | |
63 | sample_buffer_pos = sample_buffer; | 71 | sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); |
64 | entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); | 72 | if (!sample_buffer) { |
65 | if (entry) { | 73 | return -ENOMEM; |
66 | entry->proc_fops = &cris_proc_profile_operations; | 74 | } |
67 | entry->size = SAMPLE_BUFFER_SIZE; | 75 | |
68 | } | 76 | sample_buffer_pos = sample_buffer; |
69 | prof_running = 1; | 77 | |
70 | return 0; | 78 | entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); |
79 | if (entry) { | ||
80 | entry->proc_fops = &cris_proc_profile_operations; | ||
81 | entry->size = SAMPLE_BUFFER_SIZE; | ||
82 | } | ||
83 | prof_running = 1; | ||
84 | |||
85 | return 0; | ||
71 | } | 86 | } |
72 | 87 | ||
73 | __initcall(init_cris_profile); | 88 | __initcall(init_cris_profile); |