mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-02 04:37:44 +08:00
Merge branch 'linus' into sched/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/acct.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "audit.h"
|
||||
#include <linux/fsnotify_backend.h>
|
||||
#include <linux/namei.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generate definitions needed by the preprocessor.
|
||||
* This code generates raw asm output which is post-processed
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y := core.o
|
||||
|
||||
obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o
|
||||
|
||||
@@ -98,7 +98,7 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
|
||||
array_size += (u64) attr->max_entries * elem_size * num_possible_cpus();
|
||||
|
||||
if (array_size >= U32_MAX - PAGE_SIZE ||
|
||||
elem_size > PCPU_MIN_UNIT_SIZE || bpf_array_alloc_percpu(array)) {
|
||||
bpf_array_alloc_percpu(array)) {
|
||||
bpf_map_area_free(array);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static LIST_HEAD(dev_map_list);
|
||||
|
||||
static u64 dev_map_bitmap_size(const union bpf_attr *attr)
|
||||
{
|
||||
return BITS_TO_LONGS(attr->max_entries) * sizeof(unsigned long);
|
||||
return BITS_TO_LONGS((u64) attr->max_entries) * sizeof(unsigned long);
|
||||
}
|
||||
|
||||
static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
|
||||
@@ -78,6 +78,9 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
|
||||
int err = -EINVAL;
|
||||
u64 cost;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
/* check sanity of attributes */
|
||||
if (attr->max_entries == 0 || attr->key_size != 4 ||
|
||||
attr->value_size != 4 || attr->map_flags & ~BPF_F_NUMA_NODE)
|
||||
@@ -111,8 +114,9 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
|
||||
err = -ENOMEM;
|
||||
|
||||
/* A per cpu bitfield with a bit per possible net device */
|
||||
dtab->flush_needed = __alloc_percpu(dev_map_bitmap_size(attr),
|
||||
__alignof__(unsigned long));
|
||||
dtab->flush_needed = __alloc_percpu_gfp(dev_map_bitmap_size(attr),
|
||||
__alignof__(unsigned long),
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!dtab->flush_needed)
|
||||
goto free_dtab;
|
||||
|
||||
|
||||
@@ -317,10 +317,6 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
|
||||
*/
|
||||
goto free_htab;
|
||||
|
||||
if (percpu && round_up(htab->map.value_size, 8) > PCPU_MIN_UNIT_SIZE)
|
||||
/* make sure the size for pcpu_alloc() is reasonable */
|
||||
goto free_htab;
|
||||
|
||||
htab->elem_size = sizeof(struct htab_elem) +
|
||||
round_up(htab->map.key_size, 8);
|
||||
if (percpu)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/list.h>
|
||||
#include <net/strparser.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
struct bpf_stab {
|
||||
struct bpf_map map;
|
||||
@@ -92,21 +93,45 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
|
||||
return rcu_dereference_sk_user_data(sk);
|
||||
}
|
||||
|
||||
/* compute the linear packet data range [data, data_end) for skb when
|
||||
* sk_skb type programs are in use.
|
||||
*/
|
||||
static inline void bpf_compute_data_end_sk_skb(struct sk_buff *skb)
|
||||
{
|
||||
TCP_SKB_CB(skb)->bpf.data_end = skb->data + skb_headlen(skb);
|
||||
}
|
||||
|
||||
enum __sk_action {
|
||||
__SK_DROP = 0,
|
||||
__SK_PASS,
|
||||
__SK_REDIRECT,
|
||||
};
|
||||
|
||||
static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
|
||||
{
|
||||
struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict);
|
||||
int rc;
|
||||
|
||||
if (unlikely(!prog))
|
||||
return SK_DROP;
|
||||
return __SK_DROP;
|
||||
|
||||
skb_orphan(skb);
|
||||
/* We need to ensure that BPF metadata for maps is also cleared
|
||||
* when we orphan the skb so that we don't have the possibility
|
||||
* to reference a stale map.
|
||||
*/
|
||||
TCP_SKB_CB(skb)->bpf.map = NULL;
|
||||
skb->sk = psock->sock;
|
||||
bpf_compute_data_end(skb);
|
||||
bpf_compute_data_end_sk_skb(skb);
|
||||
preempt_disable();
|
||||
rc = (*prog->bpf_func)(skb, prog->insnsi);
|
||||
preempt_enable();
|
||||
skb->sk = NULL;
|
||||
|
||||
return rc;
|
||||
/* Moving return codes from UAPI namespace into internal namespace */
|
||||
return rc == SK_PASS ?
|
||||
(TCP_SKB_CB(skb)->bpf.map ? __SK_REDIRECT : __SK_PASS) :
|
||||
__SK_DROP;
|
||||
}
|
||||
|
||||
static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
|
||||
@@ -114,17 +139,10 @@ static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
|
||||
struct sock *sk;
|
||||
int rc;
|
||||
|
||||
/* Because we use per cpu values to feed input from sock redirect
|
||||
* in BPF program to do_sk_redirect_map() call we need to ensure we
|
||||
* are not preempted. RCU read lock is not sufficient in this case
|
||||
* with CONFIG_PREEMPT_RCU enabled so we must be explicit here.
|
||||
*/
|
||||
preempt_disable();
|
||||
rc = smap_verdict_func(psock, skb);
|
||||
switch (rc) {
|
||||
case SK_REDIRECT:
|
||||
sk = do_sk_redirect_map();
|
||||
preempt_enable();
|
||||
case __SK_REDIRECT:
|
||||
sk = do_sk_redirect_map(skb);
|
||||
if (likely(sk)) {
|
||||
struct smap_psock *peer = smap_psock_sk(sk);
|
||||
|
||||
@@ -139,10 +157,8 @@ static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
/* Fall through and free skb otherwise */
|
||||
case SK_DROP:
|
||||
case __SK_DROP:
|
||||
default:
|
||||
if (rc != SK_REDIRECT)
|
||||
preempt_enable();
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
@@ -369,7 +385,7 @@ static int smap_parse_func_strparser(struct strparser *strp,
|
||||
* any socket yet.
|
||||
*/
|
||||
skb->sk = psock->sock;
|
||||
bpf_compute_data_end(skb);
|
||||
bpf_compute_data_end_sk_skb(skb);
|
||||
rc = (*prog->bpf_func)(skb, prog->insnsi);
|
||||
skb->sk = NULL;
|
||||
rcu_read_unlock();
|
||||
@@ -487,6 +503,9 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
|
||||
int err = -EINVAL;
|
||||
u64 cost;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
/* check sanity of attributes */
|
||||
if (attr->max_entries == 0 || attr->key_size != 4 ||
|
||||
attr->value_size != 4 || attr->map_flags & ~BPF_F_NUMA_NODE)
|
||||
@@ -840,6 +859,12 @@ static int sock_map_update_elem(struct bpf_map *map,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (skops.sk->sk_type != SOCK_STREAM ||
|
||||
skops.sk->sk_protocol != IPPROTO_TCP) {
|
||||
fput(socket->file);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = sock_map_ctx_update_elem(&skops, map, key, flags);
|
||||
fput(socket->file);
|
||||
return err;
|
||||
|
||||
@@ -1116,7 +1116,12 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
||||
/* ctx accesses must be at a fixed offset, so that we can
|
||||
* determine what type of data were returned.
|
||||
*/
|
||||
if (!tnum_is_const(reg->var_off)) {
|
||||
if (reg->off) {
|
||||
verbose("dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
|
||||
regno, reg->off, off - reg->off);
|
||||
return -EACCES;
|
||||
}
|
||||
if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
|
||||
char tn_buf[48];
|
||||
|
||||
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
|
||||
@@ -1124,7 +1129,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
||||
tn_buf, off, size);
|
||||
return -EACCES;
|
||||
}
|
||||
off += reg->var_off.value;
|
||||
err = check_ctx_access(env, insn_idx, off, size, t, ®_type);
|
||||
if (!err && t == BPF_READ && value_regno >= 0) {
|
||||
/* ctx access returns either a scalar, or a
|
||||
@@ -2426,12 +2430,15 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
}
|
||||
|
||||
static void find_good_pkt_pointers(struct bpf_verifier_state *state,
|
||||
struct bpf_reg_state *dst_reg)
|
||||
struct bpf_reg_state *dst_reg,
|
||||
bool range_right_open)
|
||||
{
|
||||
struct bpf_reg_state *regs = state->regs, *reg;
|
||||
u16 new_range;
|
||||
int i;
|
||||
|
||||
if (dst_reg->off < 0)
|
||||
if (dst_reg->off < 0 ||
|
||||
(dst_reg->off == 0 && range_right_open))
|
||||
/* This doesn't give us any range */
|
||||
return;
|
||||
|
||||
@@ -2442,9 +2449,13 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state,
|
||||
*/
|
||||
return;
|
||||
|
||||
/* LLVM can generate four kind of checks:
|
||||
new_range = dst_reg->off;
|
||||
if (range_right_open)
|
||||
new_range--;
|
||||
|
||||
/* Examples for register markings:
|
||||
*
|
||||
* Type 1/2:
|
||||
* pkt_data in dst register:
|
||||
*
|
||||
* r2 = r3;
|
||||
* r2 += 8;
|
||||
@@ -2461,7 +2472,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state,
|
||||
* r2=pkt(id=n,off=8,r=0)
|
||||
* r3=pkt(id=n,off=0,r=0)
|
||||
*
|
||||
* Type 3/4:
|
||||
* pkt_data in src register:
|
||||
*
|
||||
* r2 = r3;
|
||||
* r2 += 8;
|
||||
@@ -2479,7 +2490,9 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state,
|
||||
* r3=pkt(id=n,off=0,r=0)
|
||||
*
|
||||
* Find register r3 and mark its range as r3=pkt(id=n,off=0,r=8)
|
||||
* so that range of bytes [r3, r3 + 8) is safe to access.
|
||||
* or r3=pkt(id=n,off=0,r=8-1), so that range of bytes [r3, r3 + 8)
|
||||
* and [r3, r3 + 8-1) respectively is safe to access depending on
|
||||
* the check.
|
||||
*/
|
||||
|
||||
/* If our ids match, then we must have the same max_value. And we
|
||||
@@ -2490,14 +2503,14 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state,
|
||||
for (i = 0; i < MAX_BPF_REG; i++)
|
||||
if (regs[i].type == PTR_TO_PACKET && regs[i].id == dst_reg->id)
|
||||
/* keep the maximum range already checked */
|
||||
regs[i].range = max_t(u16, regs[i].range, dst_reg->off);
|
||||
regs[i].range = max(regs[i].range, new_range);
|
||||
|
||||
for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) {
|
||||
if (state->stack_slot_type[i] != STACK_SPILL)
|
||||
continue;
|
||||
reg = &state->spilled_regs[i / BPF_REG_SIZE];
|
||||
if (reg->type == PTR_TO_PACKET && reg->id == dst_reg->id)
|
||||
reg->range = max_t(u16, reg->range, dst_reg->off);
|
||||
reg->range = max(reg->range, new_range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2861,19 +2874,43 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT &&
|
||||
dst_reg->type == PTR_TO_PACKET &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET_END) {
|
||||
find_good_pkt_pointers(this_branch, dst_reg);
|
||||
/* pkt_data' > pkt_end */
|
||||
find_good_pkt_pointers(this_branch, dst_reg, false);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT &&
|
||||
dst_reg->type == PTR_TO_PACKET_END &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET) {
|
||||
/* pkt_end > pkt_data' */
|
||||
find_good_pkt_pointers(other_branch, ®s[insn->src_reg], true);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLT &&
|
||||
dst_reg->type == PTR_TO_PACKET &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET_END) {
|
||||
find_good_pkt_pointers(other_branch, dst_reg);
|
||||
/* pkt_data' < pkt_end */
|
||||
find_good_pkt_pointers(other_branch, dst_reg, true);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLT &&
|
||||
dst_reg->type == PTR_TO_PACKET_END &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET) {
|
||||
/* pkt_end < pkt_data' */
|
||||
find_good_pkt_pointers(this_branch, ®s[insn->src_reg], false);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGE &&
|
||||
dst_reg->type == PTR_TO_PACKET &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET_END) {
|
||||
/* pkt_data' >= pkt_end */
|
||||
find_good_pkt_pointers(this_branch, dst_reg, true);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGE &&
|
||||
dst_reg->type == PTR_TO_PACKET_END &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET) {
|
||||
find_good_pkt_pointers(other_branch, ®s[insn->src_reg]);
|
||||
/* pkt_end >= pkt_data' */
|
||||
find_good_pkt_pointers(other_branch, ®s[insn->src_reg], false);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLE &&
|
||||
dst_reg->type == PTR_TO_PACKET &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET_END) {
|
||||
/* pkt_data' <= pkt_end */
|
||||
find_good_pkt_pointers(other_branch, dst_reg, false);
|
||||
} else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLE &&
|
||||
dst_reg->type == PTR_TO_PACKET_END &&
|
||||
regs[insn->src_reg].type == PTR_TO_PACKET) {
|
||||
find_good_pkt_pointers(this_branch, ®s[insn->src_reg]);
|
||||
/* pkt_end <= pkt_data' */
|
||||
find_good_pkt_pointers(this_branch, ®s[insn->src_reg], true);
|
||||
} else if (is_pointer_value(env, insn->dst_reg)) {
|
||||
verbose("R%d pointer comparison prohibited\n", insn->dst_reg);
|
||||
return -EACCES;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/capability.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y := cgroup.o namespace.o cgroup-v1.o
|
||||
|
||||
obj-$(CONFIG_CGROUP_FREEZER) += freezer.o
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __CGROUP_INTERNAL_H
|
||||
#define __CGROUP_INTERNAL_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Debug controller
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "cgroup-internal.h"
|
||||
|
||||
#include <linux/sched/task.h>
|
||||
|
||||
@@ -632,6 +632,11 @@ cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup,
|
||||
__cpuhp_kick_ap(st);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the leftovers so the next hotplug operation wont use stale
|
||||
* data.
|
||||
*/
|
||||
st->node = st->last = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/dma.c: A DMA channel allocator. Inspired by linux/kernel/irq.c.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/elf.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_core.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
|
||||
@@ -662,7 +662,7 @@ static inline void update_cgrp_time_from_event(struct perf_event *event)
|
||||
/*
|
||||
* Do not update time when cgroup is not active
|
||||
*/
|
||||
if (cgrp == event->cgrp)
|
||||
if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))
|
||||
__update_cgrp_time(event->cgrp);
|
||||
}
|
||||
|
||||
@@ -901,9 +901,11 @@ list_update_cgroup_event(struct perf_event *event,
|
||||
cpuctx_entry = &cpuctx->cgrp_cpuctx_entry;
|
||||
/* cpuctx->cgrp is NULL unless a cgroup event is active in this CPU .*/
|
||||
if (add) {
|
||||
struct perf_cgroup *cgrp = perf_cgroup_from_task(current, ctx);
|
||||
|
||||
list_add(cpuctx_entry, this_cpu_ptr(&cgrp_cpuctx_list));
|
||||
if (perf_cgroup_from_task(current, ctx) == event->cgrp)
|
||||
cpuctx->cgrp = event->cgrp;
|
||||
if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))
|
||||
cpuctx->cgrp = cgrp;
|
||||
} else {
|
||||
list_del(cpuctx_entry);
|
||||
cpuctx->cgrp = NULL;
|
||||
@@ -8955,6 +8957,14 @@ static struct perf_cpu_context __percpu *find_pmu_context(int ctxn)
|
||||
|
||||
static void free_pmu_context(struct pmu *pmu)
|
||||
{
|
||||
/*
|
||||
* Static contexts such as perf_sw_context have a global lifetime
|
||||
* and may be shared between different PMUs. Avoid freeing them
|
||||
* when a single PMU is going away.
|
||||
*/
|
||||
if (pmu->task_ctx_nr > perf_invalid_context)
|
||||
return;
|
||||
|
||||
mutex_lock(&pmus_lock);
|
||||
free_percpu(pmu->pmu_cpu_context);
|
||||
mutex_unlock(&pmus_lock);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _KERNEL_EVENTS_INTERNAL_H
|
||||
#define _KERNEL_EVENTS_INTERNAL_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Handling of different ABIs (personalities).
|
||||
*
|
||||
|
||||
@@ -1610,6 +1610,9 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
|
||||
if (!infop)
|
||||
return err;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
unsafe_put_user(signo, &infop->si_signo, Efault);
|
||||
unsafe_put_user(0, &infop->si_errno, Efault);
|
||||
@@ -1735,6 +1738,9 @@ COMPAT_SYSCALL_DEFINE5(waitid,
|
||||
if (!infop)
|
||||
return err;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
unsafe_put_user(signo, &infop->si_signo, Efault);
|
||||
unsafe_put_user(0, &infop->si_errno, Efault);
|
||||
|
||||
@@ -215,6 +215,10 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
|
||||
if (!s)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_DEBUG_KMEMLEAK
|
||||
/* Clear stale pointers from reused stack. */
|
||||
memset(s->addr, 0, THREAD_SIZE);
|
||||
#endif
|
||||
tsk->stack_vm_area = s;
|
||||
return s->addr;
|
||||
}
|
||||
|
||||
@@ -903,11 +903,27 @@ void exit_pi_state_list(struct task_struct *curr)
|
||||
*/
|
||||
raw_spin_lock_irq(&curr->pi_lock);
|
||||
while (!list_empty(head)) {
|
||||
|
||||
next = head->next;
|
||||
pi_state = list_entry(next, struct futex_pi_state, list);
|
||||
key = pi_state->key;
|
||||
hb = hash_futex(&key);
|
||||
|
||||
/*
|
||||
* We can race against put_pi_state() removing itself from the
|
||||
* list (a waiter going away). put_pi_state() will first
|
||||
* decrement the reference count and then modify the list, so
|
||||
* its possible to see the list entry but fail this reference
|
||||
* acquire.
|
||||
*
|
||||
* In that case; drop the locks to let put_pi_state() make
|
||||
* progress and retry the loop.
|
||||
*/
|
||||
if (!atomic_inc_not_zero(&pi_state->refcount)) {
|
||||
raw_spin_unlock_irq(&curr->pi_lock);
|
||||
cpu_relax();
|
||||
raw_spin_lock_irq(&curr->pi_lock);
|
||||
continue;
|
||||
}
|
||||
raw_spin_unlock_irq(&curr->pi_lock);
|
||||
|
||||
spin_lock(&hb->lock);
|
||||
@@ -918,8 +934,10 @@ void exit_pi_state_list(struct task_struct *curr)
|
||||
* task still owns the PI-state:
|
||||
*/
|
||||
if (head->next != next) {
|
||||
/* retain curr->pi_lock for the loop invariant */
|
||||
raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
|
||||
spin_unlock(&hb->lock);
|
||||
put_pi_state(pi_state);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -927,9 +945,8 @@ void exit_pi_state_list(struct task_struct *curr)
|
||||
WARN_ON(list_empty(&pi_state->list));
|
||||
list_del_init(&pi_state->list);
|
||||
pi_state->owner = NULL;
|
||||
raw_spin_unlock(&curr->pi_lock);
|
||||
|
||||
get_pi_state(pi_state);
|
||||
raw_spin_unlock(&curr->pi_lock);
|
||||
raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
|
||||
spin_unlock(&hb->lock);
|
||||
|
||||
@@ -1570,8 +1587,16 @@ static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
|
||||
int oldval, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) {
|
||||
if (oparg < 0 || oparg > 31)
|
||||
return -EINVAL;
|
||||
if (oparg < 0 || oparg > 31) {
|
||||
char comm[sizeof(current->comm)];
|
||||
/*
|
||||
* kill this print and return -EINVAL when userspace
|
||||
* is sane again
|
||||
*/
|
||||
pr_info_ratelimited("futex_wake_op: %s tries to shift op by %d; fix this program\n",
|
||||
get_task_comm(comm, current), oparg);
|
||||
oparg &= 31;
|
||||
}
|
||||
oparg = 1 << oparg;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/futex_compat.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
ccflags-y := -DSRCTREE='"$(srctree)"' -DOBJTREE='"$(objtree)"'
|
||||
|
||||
obj-y := base.o fs.o
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This code maintains a list of active profiling data structures.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This code exports profiling data as debugfs files to userspace.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This code provides functions to handle gcc's profiling data format
|
||||
* introduced with gcc 3.4. Future versions of gcc may change the gcov
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This code provides functions to handle gcc's profiling data format
|
||||
* introduced with gcc 4.7.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Profiling infrastructure declarations.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Supplementary group IDs
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
|
||||
obj-$(CONFIG_IRQ_TIMINGS) += timings.o
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2016 Thomas Gleixner.
|
||||
* Copyright (C) 2016-2017 Christoph Hellwig.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/irq/autoprobe.c
|
||||
*
|
||||
|
||||
@@ -265,8 +265,8 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
|
||||
irq_setup_affinity(desc);
|
||||
break;
|
||||
case IRQ_STARTUP_MANAGED:
|
||||
irq_do_set_affinity(d, aff, false);
|
||||
ret = __irq_startup(desc);
|
||||
irq_set_affinity_locked(d, aff, false);
|
||||
break;
|
||||
case IRQ_STARTUP_ABORT:
|
||||
return 0;
|
||||
|
||||
@@ -18,8 +18,34 @@
|
||||
static inline bool irq_needs_fixup(struct irq_data *d)
|
||||
{
|
||||
const struct cpumask *m = irq_data_get_effective_affinity_mask(d);
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
return cpumask_test_cpu(smp_processor_id(), m);
|
||||
#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
|
||||
/*
|
||||
* The cpumask_empty() check is a workaround for interrupt chips,
|
||||
* which do not implement effective affinity, but the architecture has
|
||||
* enabled the config switch. Use the general affinity mask instead.
|
||||
*/
|
||||
if (cpumask_empty(m))
|
||||
m = irq_data_get_affinity_mask(d);
|
||||
|
||||
/*
|
||||
* Sanity check. If the mask is not empty when excluding the outgoing
|
||||
* CPU then it must contain at least one online CPU. The outgoing CPU
|
||||
* has been removed from the online mask already.
|
||||
*/
|
||||
if (cpumask_any_but(m, cpu) < nr_cpu_ids &&
|
||||
cpumask_any_and(m, cpu_online_mask) >= nr_cpu_ids) {
|
||||
/*
|
||||
* If this happens then there was a missed IRQ fixup at some
|
||||
* point. Warn about it and enforce fixup.
|
||||
*/
|
||||
pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
|
||||
cpumask_pr_args(m), d->irq, cpu);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return cpumask_test_cpu(cpu, m);
|
||||
}
|
||||
|
||||
static bool migrate_one_irq(struct irq_desc *desc)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Debugging printout:
|
||||
*/
|
||||
|
||||
@@ -135,17 +135,26 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_gc_mask_disable_reg_and_ack - Mask and ack pending interrupt
|
||||
* irq_gc_mask_disable_and_ack_set - Mask and ack pending interrupt
|
||||
* @d: irq_data
|
||||
*
|
||||
* This generic implementation of the irq_mask_ack method is for chips
|
||||
* with separate enable/disable registers instead of a single mask
|
||||
* register and where a pending interrupt is acknowledged by setting a
|
||||
* bit.
|
||||
*
|
||||
* Note: This is the only permutation currently used. Similar generic
|
||||
* functions should be added here if other permutations are required.
|
||||
*/
|
||||
void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
|
||||
void irq_gc_mask_disable_and_ack_set(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_type *ct = irq_data_get_chip_type(d);
|
||||
u32 mask = d->mask;
|
||||
|
||||
irq_gc_lock(gc);
|
||||
irq_reg_writel(gc, mask, ct->regs.mask);
|
||||
irq_reg_writel(gc, mask, ct->regs.disable);
|
||||
*ct->mask_cache &= ~mask;
|
||||
irq_reg_writel(gc, mask, ct->regs.ack);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* IRQ subsystem internal functions and variables:
|
||||
*
|
||||
|
||||
@@ -168,6 +168,19 @@ void irq_set_thread_affinity(struct irq_desc *desc)
|
||||
set_bit(IRQTF_AFFINITY, &action->thread_flags);
|
||||
}
|
||||
|
||||
static void irq_validate_effective_affinity(struct irq_data *data)
|
||||
{
|
||||
#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
|
||||
const struct cpumask *m = irq_data_get_effective_affinity_mask(data);
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
|
||||
if (!cpumask_empty(m))
|
||||
return;
|
||||
pr_warn_once("irq_chip %s did not update eff. affinity mask of irq %u\n",
|
||||
chip->name, data->irq);
|
||||
#endif
|
||||
}
|
||||
|
||||
int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
bool force)
|
||||
{
|
||||
@@ -175,12 +188,16 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
int ret;
|
||||
|
||||
if (!chip || !chip->irq_set_affinity)
|
||||
return -EINVAL;
|
||||
|
||||
ret = chip->irq_set_affinity(data, mask, force);
|
||||
switch (ret) {
|
||||
case IRQ_SET_MASK_OK:
|
||||
case IRQ_SET_MASK_OK_DONE:
|
||||
cpumask_copy(desc->irq_common_data.affinity, mask);
|
||||
case IRQ_SET_MASK_OK_NOCOPY:
|
||||
irq_validate_effective_affinity(data);
|
||||
irq_set_thread_affinity(desc);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/irq/proc.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/irq/resend.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Internal header to deal with irq_desc->status which will be renamed
|
||||
* to irq_desc->settings.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/irq/spurious.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/fdtable.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define pr_fmt(fmt) "kcov: " fmt
|
||||
|
||||
#define DISABLE_BRANCH_PROFILING
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LINUX_KEXEC_INTERNAL_H
|
||||
#define LINUX_KEXEC_INTERNAL_H
|
||||
|
||||
|
||||
@@ -830,6 +830,41 @@ int klp_register_patch(struct klp_patch *patch)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(klp_register_patch);
|
||||
|
||||
/*
|
||||
* Remove parts of patches that touch a given kernel module. The list of
|
||||
* patches processed might be limited. When limit is NULL, all patches
|
||||
* will be handled.
|
||||
*/
|
||||
static void klp_cleanup_module_patches_limited(struct module *mod,
|
||||
struct klp_patch *limit)
|
||||
{
|
||||
struct klp_patch *patch;
|
||||
struct klp_object *obj;
|
||||
|
||||
list_for_each_entry(patch, &klp_patches, list) {
|
||||
if (patch == limit)
|
||||
break;
|
||||
|
||||
klp_for_each_object(patch, obj) {
|
||||
if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Only unpatch the module if the patch is enabled or
|
||||
* is in transition.
|
||||
*/
|
||||
if (patch->enabled || patch == klp_transition_patch) {
|
||||
pr_notice("reverting patch '%s' on unloading module '%s'\n",
|
||||
patch->mod->name, obj->mod->name);
|
||||
klp_unpatch_object(obj);
|
||||
}
|
||||
|
||||
klp_free_object_loaded(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int klp_module_coming(struct module *mod)
|
||||
{
|
||||
int ret;
|
||||
@@ -894,7 +929,7 @@ err:
|
||||
pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n",
|
||||
patch->mod->name, obj->mod->name, obj->mod->name);
|
||||
mod->klp_alive = false;
|
||||
klp_free_object_loaded(obj);
|
||||
klp_cleanup_module_patches_limited(mod, patch);
|
||||
mutex_unlock(&klp_mutex);
|
||||
|
||||
return ret;
|
||||
@@ -902,9 +937,6 @@ err:
|
||||
|
||||
void klp_module_going(struct module *mod)
|
||||
{
|
||||
struct klp_patch *patch;
|
||||
struct klp_object *obj;
|
||||
|
||||
if (WARN_ON(mod->state != MODULE_STATE_GOING &&
|
||||
mod->state != MODULE_STATE_COMING))
|
||||
return;
|
||||
@@ -917,25 +949,7 @@ void klp_module_going(struct module *mod)
|
||||
*/
|
||||
mod->klp_alive = false;
|
||||
|
||||
list_for_each_entry(patch, &klp_patches, list) {
|
||||
klp_for_each_object(patch, obj) {
|
||||
if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Only unpatch the module if the patch is enabled or
|
||||
* is in transition.
|
||||
*/
|
||||
if (patch->enabled || patch == klp_transition_patch) {
|
||||
pr_notice("reverting patch '%s' on unloading module '%s'\n",
|
||||
patch->mod->name, obj->mod->name);
|
||||
klp_unpatch_object(obj);
|
||||
}
|
||||
|
||||
klp_free_object_loaded(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
klp_cleanup_module_patches_limited(mod, NULL);
|
||||
|
||||
mutex_unlock(&klp_mutex);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LIVEPATCH_CORE_H
|
||||
#define _LIVEPATCH_CORE_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LIVEPATCH_PATCH_H
|
||||
#define _LIVEPATCH_PATCH_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LIVEPATCH_TRANSITION_H
|
||||
#define _LIVEPATCH_TRANSITION_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Any varying coverage in these files is non-deterministic
|
||||
# and is generally not a function of system call inputs.
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
@@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
|
||||
struct held_lock *next, int distance, struct stack_trace *trace,
|
||||
int (*save)(struct stack_trace *trace))
|
||||
{
|
||||
struct lock_list *entry;
|
||||
int ret;
|
||||
struct lock_list this;
|
||||
struct lock_list *uninitialized_var(target_entry);
|
||||
struct lock_list *entry;
|
||||
struct lock_list this;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Prove that the new <prev> -> <next> dependency would not
|
||||
@@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
|
||||
this.class = hlock_class(next);
|
||||
this.parent = NULL;
|
||||
ret = check_noncircular(&this, hlock_class(prev), &target_entry);
|
||||
if (unlikely(!ret))
|
||||
if (unlikely(!ret)) {
|
||||
if (!trace->entries) {
|
||||
/*
|
||||
* If @save fails here, the printing might trigger
|
||||
* a WARN but because of the !nr_entries it should
|
||||
* not do bad things.
|
||||
*/
|
||||
save(trace);
|
||||
}
|
||||
return print_circular_bug(&this, target_entry, next, prev, trace);
|
||||
}
|
||||
else if (unlikely(ret < 0))
|
||||
return print_bfs_bug(ret);
|
||||
|
||||
@@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
|
||||
return print_bfs_bug(ret);
|
||||
|
||||
|
||||
if (save && !save(trace))
|
||||
if (!trace->entries && !save(trace))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Debugging printouts:
|
||||
*/
|
||||
if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
|
||||
graph_unlock();
|
||||
printk("\n new dependency: ");
|
||||
print_lock_name(hlock_class(prev));
|
||||
printk(KERN_CONT " => ");
|
||||
print_lock_name(hlock_class(next));
|
||||
printk(KERN_CONT "\n");
|
||||
dump_stack();
|
||||
if (!graph_lock())
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
|
||||
{
|
||||
int depth = curr->lockdep_depth;
|
||||
struct held_lock *hlock;
|
||||
struct stack_trace trace;
|
||||
int (*save)(struct stack_trace *trace) = save_trace;
|
||||
struct stack_trace trace = {
|
||||
.nr_entries = 0,
|
||||
.max_entries = 0,
|
||||
.entries = NULL,
|
||||
.skip = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Debugging checks.
|
||||
@@ -2018,17 +2017,10 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
|
||||
*/
|
||||
if (hlock->read != 2 && hlock->check) {
|
||||
int ret = check_prev_add(curr, hlock, next,
|
||||
distance, &trace, save);
|
||||
distance, &trace, save_trace);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Stop saving stack_trace if save_trace() was
|
||||
* called at least once:
|
||||
*/
|
||||
if (save && ret == 2)
|
||||
save = NULL;
|
||||
|
||||
/*
|
||||
* Stop after the first non-trylock entry,
|
||||
* as non-trylock entries have added their
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* kernel/lockdep_internals.h
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* kernel/lockdep_proc.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* MCS lock defines
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Mutexes: blocking mutual exclusion locks
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Mutexes: blocking mutual exclusion locks
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/osq_lock.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _GEN_PV_LOCK_SLOWPATH
|
||||
#error "do not include this file"
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* RT-Mutexes: blocking mutual exclusion locks with PI support
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* RT-Mutexes: blocking mutual exclusion locks with PI support
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* RT-Mutexes: blocking mutual exclusion locks with PI support
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* RT Mutexes: blocking mutual exclusion locks with PI support
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* rwsem-spinlock.c: R/W semaphores: contention handling functions for
|
||||
* generic spinlock implementation
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* rwsem.c: R/W semaphores: contention handling functions
|
||||
*
|
||||
* Written by David Howells (dhowells@redhat.com).
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* kernel/rwsem.c: R/W semaphores, public implementation
|
||||
*
|
||||
* Written by David Howells (dhowells@redhat.com).
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* The owner field of the rw_semaphore structure will be set to
|
||||
* RWSEM_READ_OWNED when a reader grabs the lock. A writer will clear
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (2004) Linus Torvalds
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* kernel/power/autosleep.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Functions for saving/restoring console.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/suspend_ioctls.h>
|
||||
#include <linux/utsname.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* drivers/power/process.c - Functions for starting/stopping processes on
|
||||
* suspend transitions.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* kernel/power/wakelock.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _PRINTK_BRAILLE_H
|
||||
#define _PRINTK_BRAILLE_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _CONSOLE_CMDLINE_H
|
||||
#define _CONSOLE_CMDLINE_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Range add and subtract
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Any varying coverage in these files is non-deterministic
|
||||
# and is generally not a function of system call inputs.
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
@@ -854,7 +854,7 @@ void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp,
|
||||
/**
|
||||
* call_srcu() - Queue a callback for invocation after an SRCU grace period
|
||||
* @sp: srcu_struct in queue the callback
|
||||
* @head: structure to be used for queueing the SRCU callback.
|
||||
* @rhp: structure to be used for queueing the SRCU callback.
|
||||
* @func: function to be invoked after the SRCU grace period
|
||||
*
|
||||
* The callback function will be invoked some time after a full SRCU
|
||||
|
||||
@@ -85,6 +85,9 @@ void rcu_sync_init(struct rcu_sync *rsp, enum rcu_sync_type type)
|
||||
}
|
||||
|
||||
/**
|
||||
* rcu_sync_enter_start - Force readers onto slow path for multiple updates
|
||||
* @rsp: Pointer to rcu_sync structure to use for synchronization
|
||||
*
|
||||
* Must be called after rcu_sync_init() and before first use.
|
||||
*
|
||||
* Ensures rcu_sync_is_idle() returns false and rcu_sync_{enter,exit}()
|
||||
@@ -142,7 +145,7 @@ void rcu_sync_enter(struct rcu_sync *rsp)
|
||||
|
||||
/**
|
||||
* rcu_sync_func() - Callback function managing reader access to fastpath
|
||||
* @rsp: Pointer to rcu_sync structure to use for synchronization
|
||||
* @rhp: Pointer to rcu_head in rcu_sync structure to use for synchronization
|
||||
*
|
||||
* This function is passed to one of the call_rcu() functions by
|
||||
* rcu_sync_exit(), so that it is invoked after a grace period following the
|
||||
@@ -158,9 +161,9 @@ void rcu_sync_enter(struct rcu_sync *rsp)
|
||||
* rcu_sync_exit(). Otherwise, set all state back to idle so that readers
|
||||
* can again use their fastpaths.
|
||||
*/
|
||||
static void rcu_sync_func(struct rcu_head *rcu)
|
||||
static void rcu_sync_func(struct rcu_head *rhp)
|
||||
{
|
||||
struct rcu_sync *rsp = container_of(rcu, struct rcu_sync, cb_head);
|
||||
struct rcu_sync *rsp = container_of(rhp, struct rcu_sync, cb_head);
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(rsp->gp_state != GP_PASSED);
|
||||
|
||||
@@ -3097,9 +3097,10 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func,
|
||||
* read-side critical sections have completed. call_rcu_sched() assumes
|
||||
* that the read-side critical sections end on enabling of preemption
|
||||
* or on voluntary preemption.
|
||||
* RCU read-side critical sections are delimited by :
|
||||
* - rcu_read_lock_sched() and rcu_read_unlock_sched(), OR
|
||||
* - anything that disables preemption.
|
||||
* RCU read-side critical sections are delimited by:
|
||||
*
|
||||
* - rcu_read_lock_sched() and rcu_read_unlock_sched(), OR
|
||||
* - anything that disables preemption.
|
||||
*
|
||||
* These may be nested.
|
||||
*
|
||||
@@ -3124,11 +3125,12 @@ EXPORT_SYMBOL_GPL(call_rcu_sched);
|
||||
* handler. This means that read-side critical sections in process
|
||||
* context must not be interrupted by softirqs. This interface is to be
|
||||
* used when most of the read-side critical sections are in softirq context.
|
||||
* RCU read-side critical sections are delimited by :
|
||||
* - rcu_read_lock() and rcu_read_unlock(), if in interrupt context.
|
||||
* OR
|
||||
* - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
|
||||
* These may be nested.
|
||||
* RCU read-side critical sections are delimited by:
|
||||
*
|
||||
* - rcu_read_lock() and rcu_read_unlock(), if in interrupt context, OR
|
||||
* - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
|
||||
*
|
||||
* These may be nested.
|
||||
*
|
||||
* See the description of call_rcu() for more detailed information on
|
||||
* memory ordering guarantees.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_clock.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "sched.h"
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifdef CONFIG_SCHED_AUTOGROUP
|
||||
|
||||
#include <linux/kref.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generic wait-for-completion handler;
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifdef CONFIG_CGROUP_CPUACCT
|
||||
|
||||
extern void cpuacct_charge(struct task_struct *tsk, u64 cputime);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_CPUDL_H
|
||||
#define _LINUX_CPUDL_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_CPUPRI_H
|
||||
#define _LINUX_CPUPRI_H
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Deadline Scheduling Class (SCHED_DEADLINE)
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Completely Fair Scheduling (CFS) Class (SCHED_NORMAL/SCHED_BATCH)
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Only give sleepers 50% of their service deficit. This allows
|
||||
* them to run sooner, but does not allow tons of sleepers to
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "sched.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* kernel/sched/loadavg.c
|
||||
*
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/membarrier.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "sched.h" /* for cpu_rq(). */
|
||||
|
||||
@@ -26,21 +27,26 @@
|
||||
* except MEMBARRIER_CMD_QUERY.
|
||||
*/
|
||||
#define MEMBARRIER_CMD_BITMASK \
|
||||
(MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED)
|
||||
(MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED \
|
||||
| MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)
|
||||
|
||||
static void ipi_mb(void *info)
|
||||
{
|
||||
smp_mb(); /* IPIs should be serializing but paranoid. */
|
||||
}
|
||||
|
||||
static void membarrier_private_expedited(void)
|
||||
static int membarrier_private_expedited(void)
|
||||
{
|
||||
int cpu;
|
||||
bool fallback = false;
|
||||
cpumask_var_t tmpmask;
|
||||
|
||||
if (!(atomic_read(¤t->mm->membarrier_state)
|
||||
& MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
|
||||
return -EPERM;
|
||||
|
||||
if (num_online_cpus() == 1)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Matches memory barriers around rq->curr modification in
|
||||
@@ -94,6 +100,24 @@ static void membarrier_private_expedited(void)
|
||||
* rq->curr modification in scheduler.
|
||||
*/
|
||||
smp_mb(); /* exit from system call is not a mb */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void membarrier_register_private_expedited(void)
|
||||
{
|
||||
struct task_struct *p = current;
|
||||
struct mm_struct *mm = p->mm;
|
||||
|
||||
/*
|
||||
* We need to consider threads belonging to different thread
|
||||
* groups, which use the same mm. (CLONE_VM but not
|
||||
* CLONE_THREAD).
|
||||
*/
|
||||
if (atomic_read(&mm->membarrier_state)
|
||||
& MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)
|
||||
return;
|
||||
atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY,
|
||||
&mm->membarrier_state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +168,9 @@ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
|
||||
synchronize_sched();
|
||||
return 0;
|
||||
case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
|
||||
membarrier_private_expedited();
|
||||
return membarrier_private_expedited();
|
||||
case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
|
||||
membarrier_register_private_expedited();
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user