diff options
| author | David S. Miller <davem@davemloft.net> | 2012-11-10 18:32:51 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-11-10 18:32:51 -0500 |
| commit | d4185bbf62a5d8d777ee445db1581beb17882a07 (patch) | |
| tree | 024b0badbd7c970b1983be6d8c345cc4a290cb31 /kernel | |
| parent | c075b13098b399dc565b4d53f42047a8d40ed3ba (diff) | |
| parent | a375413311b39005ef281bfd71ae8f4e3df22e97 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Minor conflict between the BCM_CNIC define removal in net-next
and a bug fix added to net. Based upon a conflict resolution
patch posted by Stephen Rothwell.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/Makefile | 6 | ||||
| -rw-r--r-- | kernel/cgroup.c | 41 | ||||
| -rw-r--r-- | kernel/events/uprobes.c | 345 | ||||
| -rw-r--r-- | kernel/module-internal.h | 3 | ||||
| -rw-r--r-- | kernel/module.c | 26 | ||||
| -rw-r--r-- | kernel/module_signing.c | 24 | ||||
| -rw-r--r-- | kernel/pid_namespace.c | 33 | ||||
| -rw-r--r-- | kernel/sys.c | 12 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 4 | ||||
| -rw-r--r-- | kernel/workqueue.c | 2 |
10 files changed, 236 insertions, 260 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 0dfeca4324e..86e3285ae7e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
| @@ -174,10 +174,8 @@ signing_key.priv signing_key.x509: x509.genkey | |||
| 174 | @echo "###" | 174 | @echo "###" |
| 175 | @echo "### If this takes a long time, you might wish to run rngd in the" | 175 | @echo "### If this takes a long time, you might wish to run rngd in the" |
| 176 | @echo "### background to keep the supply of entropy topped up. It" | 176 | @echo "### background to keep the supply of entropy topped up. It" |
| 177 | @echo "### needs to be run as root, and should use a hardware random" | 177 | @echo "### needs to be run as root, and uses a hardware random" |
| 178 | @echo "### number generator if one is available, eg:" | 178 | @echo "### number generator if one is available." |
| 179 | @echo "###" | ||
| 180 | @echo "### rngd -r /dev/hwrandom" | ||
| 181 | @echo "###" | 179 | @echo "###" |
| 182 | openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \ | 180 | openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \ |
| 183 | -x509 -config x509.genkey \ | 181 | -x509 -config x509.genkey \ |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 13774b3b39a..f24f724620d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -1962,9 +1962,8 @@ static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp, | |||
| 1962 | * trading it for newcg is protected by cgroup_mutex, we're safe to drop | 1962 | * trading it for newcg is protected by cgroup_mutex, we're safe to drop |
| 1963 | * it here; it will be freed under RCU. | 1963 | * it here; it will be freed under RCU. |
| 1964 | */ | 1964 | */ |
| 1965 | put_css_set(oldcg); | ||
| 1966 | |||
| 1967 | set_bit(CGRP_RELEASABLE, &oldcgrp->flags); | 1965 | set_bit(CGRP_RELEASABLE, &oldcgrp->flags); |
| 1966 | put_css_set(oldcg); | ||
| 1968 | } | 1967 | } |
| 1969 | 1968 | ||
| 1970 | /** | 1969 | /** |
| @@ -4815,31 +4814,20 @@ static const struct file_operations proc_cgroupstats_operations = { | |||
| 4815 | * | 4814 | * |
| 4816 | * A pointer to the shared css_set was automatically copied in | 4815 | * A pointer to the shared css_set was automatically copied in |
| 4817 | * fork.c by dup_task_struct(). However, we ignore that copy, since | 4816 | * fork.c by dup_task_struct(). However, we ignore that copy, since |
| 4818 | * it was not made under the protection of RCU, cgroup_mutex or | 4817 | * it was not made under the protection of RCU or cgroup_mutex, so |
| 4819 | * threadgroup_change_begin(), so it might no longer be a valid | 4818 | * might no longer be a valid cgroup pointer. cgroup_attach_task() might |
| 4820 | * cgroup pointer. cgroup_attach_task() might have already changed | 4819 | * have already changed current->cgroups, allowing the previously |
| 4821 | * current->cgroups, allowing the previously referenced cgroup | 4820 | * referenced cgroup group to be removed and freed. |
| 4822 | * group to be removed and freed. | ||
| 4823 | * | ||
| 4824 | * Outside the pointer validity we also need to process the css_set | ||
| 4825 | * inheritance between threadgoup_change_begin() and | ||
| 4826 | * threadgoup_change_end(), this way there is no leak in any process | ||
| 4827 | * wide migration performed by cgroup_attach_proc() that could otherwise | ||
| 4828 | * miss a thread because it is too early or too late in the fork stage. | ||
| 4829 | * | 4821 | * |
| 4830 | * At the point that cgroup_fork() is called, 'current' is the parent | 4822 | * At the point that cgroup_fork() is called, 'current' is the parent |
| 4831 | * task, and the passed argument 'child' points to the child task. | 4823 | * task, and the passed argument 'child' points to the child task. |
| 4832 | */ | 4824 | */ |
| 4833 | void cgroup_fork(struct task_struct *child) | 4825 | void cgroup_fork(struct task_struct *child) |
| 4834 | { | 4826 | { |
| 4835 | /* | 4827 | task_lock(current); |
| 4836 | * We don't need to task_lock() current because current->cgroups | ||
| 4837 | * can't be changed concurrently here. The parent obviously hasn't | ||
| 4838 | * exited and called cgroup_exit(), and we are synchronized against | ||
| 4839 | * cgroup migration through threadgroup_change_begin(). | ||
| 4840 | */ | ||
| 4841 | child->cgroups = current->cgroups; | 4828 | child->cgroups = current->cgroups; |
| 4842 | get_css_set(child->cgroups); | 4829 | get_css_set(child->cgroups); |
| 4830 | task_unlock(current); | ||
| 4843 | INIT_LIST_HEAD(&child->cg_list); | 4831 | INIT_LIST_HEAD(&child->cg_list); |
| 4844 | } | 4832 | } |
| 4845 | 4833 | ||
| @@ -4895,19 +4883,10 @@ void cgroup_post_fork(struct task_struct *child) | |||
| 4895 | */ | 4883 | */ |
| 4896 | if (use_task_css_set_links) { | 4884 | if (use_task_css_set_links) { |
| 4897 | write_lock(&css_set_lock); | 4885 | write_lock(&css_set_lock); |
| 4898 | if (list_empty(&child->cg_list)) { | 4886 | task_lock(child); |
| 4899 | /* | 4887 | if (list_empty(&child->cg_list)) |
| 4900 | * It's safe to use child->cgroups without task_lock() | ||
| 4901 | * here because we are protected through | ||
| 4902 | * threadgroup_change_begin() against concurrent | ||
| 4903 | * css_set change in cgroup_task_migrate(). Also | ||
| 4904 | * the task can't exit at that point until | ||
| 4905 | * wake_up_new_task() is called, so we are protected | ||
| 4906 | * against cgroup_exit() setting child->cgroup to | ||
| 4907 | * init_css_set. | ||
| 4908 | */ | ||
| 4909 | list_add(&child->cg_list, &child->cgroups->tasks); | 4888 | list_add(&child->cg_list, &child->cgroups->tasks); |
| 4910 | } | 4889 | task_unlock(child); |
| 4911 | write_unlock(&css_set_lock); | 4890 | write_unlock(&css_set_lock); |
| 4912 | } | 4891 | } |
| 4913 | } | 4892 | } |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 98256bc71ee..5cc4e7e42e6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
| @@ -78,15 +78,23 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; | |||
| 78 | */ | 78 | */ |
| 79 | static atomic_t uprobe_events = ATOMIC_INIT(0); | 79 | static atomic_t uprobe_events = ATOMIC_INIT(0); |
| 80 | 80 | ||
| 81 | /* Have a copy of original instruction */ | ||
| 82 | #define UPROBE_COPY_INSN 0 | ||
| 83 | /* Dont run handlers when first register/ last unregister in progress*/ | ||
| 84 | #define UPROBE_RUN_HANDLER 1 | ||
| 85 | /* Can skip singlestep */ | ||
| 86 | #define UPROBE_SKIP_SSTEP 2 | ||
| 87 | |||
| 81 | struct uprobe { | 88 | struct uprobe { |
| 82 | struct rb_node rb_node; /* node in the rb tree */ | 89 | struct rb_node rb_node; /* node in the rb tree */ |
| 83 | atomic_t ref; | 90 | atomic_t ref; |
| 84 | struct rw_semaphore consumer_rwsem; | 91 | struct rw_semaphore consumer_rwsem; |
| 92 | struct mutex copy_mutex; /* TODO: kill me and UPROBE_COPY_INSN */ | ||
| 85 | struct list_head pending_list; | 93 | struct list_head pending_list; |
| 86 | struct uprobe_consumer *consumers; | 94 | struct uprobe_consumer *consumers; |
| 87 | struct inode *inode; /* Also hold a ref to inode */ | 95 | struct inode *inode; /* Also hold a ref to inode */ |
| 88 | loff_t offset; | 96 | loff_t offset; |
| 89 | int flags; | 97 | unsigned long flags; |
| 90 | struct arch_uprobe arch; | 98 | struct arch_uprobe arch; |
| 91 | }; | 99 | }; |
| 92 | 100 | ||
| @@ -100,17 +108,12 @@ struct uprobe { | |||
| 100 | */ | 108 | */ |
| 101 | static bool valid_vma(struct vm_area_struct *vma, bool is_register) | 109 | static bool valid_vma(struct vm_area_struct *vma, bool is_register) |
| 102 | { | 110 | { |
| 103 | if (!vma->vm_file) | 111 | vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED; |
| 104 | return false; | ||
| 105 | |||
| 106 | if (!is_register) | ||
| 107 | return true; | ||
| 108 | 112 | ||
| 109 | if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) | 113 | if (is_register) |
| 110 | == (VM_READ|VM_EXEC)) | 114 | flags |= VM_WRITE; |
| 111 | return true; | ||
| 112 | 115 | ||
| 113 | return false; | 116 | return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC; |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) | 119 | static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) |
| @@ -193,19 +196,44 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn) | |||
| 193 | return *insn == UPROBE_SWBP_INSN; | 196 | return *insn == UPROBE_SWBP_INSN; |
| 194 | } | 197 | } |
| 195 | 198 | ||
| 199 | static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode) | ||
| 200 | { | ||
| 201 | void *kaddr = kmap_atomic(page); | ||
| 202 | memcpy(opcode, kaddr + (vaddr & ~PAGE_MASK), UPROBE_SWBP_INSN_SIZE); | ||
| 203 | kunmap_atomic(kaddr); | ||
| 204 | } | ||
| 205 | |||
| 206 | static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode) | ||
| 207 | { | ||
| 208 | uprobe_opcode_t old_opcode; | ||
| 209 | bool is_swbp; | ||
| 210 | |||
| 211 | copy_opcode(page, vaddr, &old_opcode); | ||
| 212 | is_swbp = is_swbp_insn(&old_opcode); | ||
| 213 | |||
| 214 | if (is_swbp_insn(new_opcode)) { | ||
| 215 | if (is_swbp) /* register: already installed? */ | ||
| 216 | return 0; | ||
| 217 | } else { | ||
| 218 | if (!is_swbp) /* unregister: was it changed by us? */ | ||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | return 1; | ||
| 223 | } | ||
| 224 | |||
| 196 | /* | 225 | /* |
| 197 | * NOTE: | 226 | * NOTE: |
| 198 | * Expect the breakpoint instruction to be the smallest size instruction for | 227 | * Expect the breakpoint instruction to be the smallest size instruction for |
| 199 | * the architecture. If an arch has variable length instruction and the | 228 | * the |
