mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 22:23:14 -04:00
Merge "Merge android11-5.4.233+ (4716ccc) into msm-5.4"
This commit is contained in:
commit
3d70718402
996 changed files with 10163 additions and 4608 deletions
|
|
@ -331,6 +331,8 @@ static comp_t encode_comp_t(unsigned long value)
|
|||
exp++;
|
||||
}
|
||||
|
||||
if (exp > (((comp_t) ~0U) >> MANTSIZE))
|
||||
return (comp_t) ~0U;
|
||||
/*
|
||||
* Clean it up and polish it off.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2849,6 +2849,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
|
|||
break;
|
||||
}
|
||||
|
||||
if (btf_type_is_resolve_source_only(arg_type)) {
|
||||
btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args[i].name_off &&
|
||||
(!btf_name_offset_valid(btf, args[i].name_off) ||
|
||||
!btf_name_valid_identifier(btf, args[i].name_off))) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/kallsyms.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
|
@ -1576,9 +1577,7 @@ out:
|
|||
* reuse preexisting logic from Spectre v1 mitigation that
|
||||
* happens to produce the required code on x86 for v4 as well.
|
||||
*/
|
||||
#ifdef CONFIG_X86
|
||||
barrier_nospec();
|
||||
#endif
|
||||
CONT;
|
||||
#define LDST(SIZEOP, SIZE) \
|
||||
STX_MEM_##SIZEOP: \
|
||||
|
|
|
|||
|
|
@ -1924,7 +1924,9 @@ static int check_stack_write(struct bpf_verifier_env *env,
|
|||
bool sanitize = reg && is_spillable_regtype(reg->type);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (state->stack[spi].slot_type[i] == STACK_INVALID) {
|
||||
u8 type = state->stack[spi].slot_type[i];
|
||||
|
||||
if (type != STACK_MISC && type != STACK_ZERO) {
|
||||
sanitize = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -5140,6 +5142,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
|
|||
return err;
|
||||
return adjust_ptr_min_max_vals(env, insn,
|
||||
dst_reg, src_reg);
|
||||
} else if (dst_reg->precise) {
|
||||
/* if dst_reg is precise, src_reg should be precise as well */
|
||||
err = mark_chain_precision(env, insn->src_reg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* Pretend the src is a reg with a known value, since we only
|
||||
|
|
|
|||
|
|
@ -169,7 +169,6 @@ extern struct mutex cgroup_mutex;
|
|||
extern spinlock_t css_set_lock;
|
||||
extern struct cgroup_subsys *cgroup_subsys[];
|
||||
extern struct list_head cgroup_roots;
|
||||
extern struct file_system_type cgroup_fs_type;
|
||||
|
||||
/* iterate across the hierarchies */
|
||||
#define for_each_root(root) \
|
||||
|
|
|
|||
|
|
@ -10119,13 +10119,15 @@ static int pmu_dev_alloc(struct pmu *pmu)
|
|||
|
||||
pmu->dev->groups = pmu->attr_groups;
|
||||
device_initialize(pmu->dev);
|
||||
ret = dev_set_name(pmu->dev, "%s", pmu->name);
|
||||
if (ret)
|
||||
goto free_dev;
|
||||
|
||||
dev_set_drvdata(pmu->dev, pmu);
|
||||
pmu->dev->bus = &pmu_bus;
|
||||
pmu->dev->release = pmu_dev_release;
|
||||
|
||||
ret = dev_set_name(pmu->dev, "%s", pmu->name);
|
||||
if (ret)
|
||||
goto free_dev;
|
||||
|
||||
ret = device_add(pmu->dev);
|
||||
if (ret)
|
||||
goto free_dev;
|
||||
|
|
|
|||
|
|
@ -63,12 +63,59 @@
|
|||
#include <linux/random.h>
|
||||
#include <linux/rcuwait.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
/*
|
||||
* The default value should be high enough to not crash a system that randomly
|
||||
* crashes its kernel from time to time, but low enough to at least not permit
|
||||
* overflowing 32-bit refcounts or the ldsem writer count.
|
||||
*/
|
||||
static unsigned int oops_limit = 10000;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table kern_exit_table[] = {
|
||||
{
|
||||
.procname = "oops_limit",
|
||||
.data = &oops_limit,
|
||||
.maxlen = sizeof(oops_limit),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_douintvec,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static __init int kernel_exit_sysctls_init(void)
|
||||
{
|
||||
register_sysctl_init("kernel", kern_exit_table);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(kernel_exit_sysctls_init);
|
||||
#endif
|
||||
|
||||
static atomic_t oops_count = ATOMIC_INIT(0);
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
return sysfs_emit(page, "%d\n", atomic_read(&oops_count));
|
||||
}
|
||||
|
||||
static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count);
|
||||
|
||||
static __init int kernel_exit_sysfs_init(void)
|
||||
{
|
||||
sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(kernel_exit_sysfs_init);
|
||||
#endif
|
||||
|
||||
static void __unhash_process(struct task_struct *p, bool group_dead)
|
||||
{
|
||||
nr_threads--;
|
||||
|
|
@ -864,6 +911,31 @@ void __noreturn do_exit(long code)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(do_exit);
|
||||
|
||||
void __noreturn make_task_dead(int signr)
|
||||
{
|
||||
/*
|
||||
* Take the task off the cpu after something catastrophic has
|
||||
* happened.
|
||||
*/
|
||||
unsigned int limit;
|
||||
|
||||
/*
|
||||
* Every time the system oopses, if the oops happens while a reference
|
||||
* to an object was held, the reference leaks.
|
||||
* If the oops doesn't also leak memory, repeated oopsing can cause
|
||||
* reference counters to wrap around (if they're not using refcount_t).
|
||||
* This means that repeated oopsing can make unexploitable-looking bugs
|
||||
* exploitable through repeated oopsing.
|
||||
* To make sure this can't happen, place an upper bound on how often the
|
||||
* kernel may oops without panic().
|
||||
*/
|
||||
limit = READ_ONCE(oops_limit);
|
||||
if (atomic_inc_return(&oops_count) >= limit && limit)
|
||||
panic("Oopsed too often (kernel.oops_limit is %d)", limit);
|
||||
|
||||
do_exit(signr);
|
||||
}
|
||||
|
||||
void complete_and_exit(struct completion *comp, long code)
|
||||
{
|
||||
if (comp)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct gcov_fn_info {
|
|||
* @version: gcov version magic indicating the gcc version used for compilation
|
||||
* @next: list head for a singly-linked list
|
||||
* @stamp: uniquifying time stamp
|
||||
* @checksum: unique object checksum
|
||||
* @filename: name of the associated gcov data file
|
||||
* @merge: merge functions (null for unused counter type)
|
||||
* @n_functions: number of instrumented functions
|
||||
|
|
@ -97,6 +98,10 @@ struct gcov_info {
|
|||
unsigned int version;
|
||||
struct gcov_info *next;
|
||||
unsigned int stamp;
|
||||
/* Since GCC 12.1 a checksum field is added. */
|
||||
#if (__GNUC__ >= 12)
|
||||
unsigned int checksum;
|
||||
#endif
|
||||
const char *filename;
|
||||
void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
|
||||
unsigned int n_functions;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ enum {
|
|||
* IRQS_PENDING - irq is pending and replayed later
|
||||
* IRQS_SUSPENDED - irq is suspended
|
||||
* IRQS_NMI - irq line is used to deliver NMIs
|
||||
* IRQS_SYSFS - descriptor has been added to sysfs
|
||||
*/
|
||||
enum {
|
||||
IRQS_AUTODETECT = 0x00000001,
|
||||
|
|
@ -64,6 +65,7 @@ enum {
|
|||
IRQS_SUSPENDED = 0x00000800,
|
||||
IRQS_TIMINGS = 0x00001000,
|
||||
IRQS_NMI = 0x00002000,
|
||||
IRQS_SYSFS = 0x00004000,
|
||||
};
|
||||
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -288,22 +288,25 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc)
|
|||
if (irq_kobj_base) {
|
||||
/*
|
||||
* Continue even in case of failure as this is nothing
|
||||
* crucial.
|
||||
* crucial and failures in the late irq_sysfs_init()
|
||||
* cannot be rolled back.
|
||||
*/
|
||||
if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
|
||||
pr_warn("Failed to add kobject for irq %d\n", irq);
|
||||
else
|
||||
desc->istate |= IRQS_SYSFS;
|
||||
}
|
||||
}
|
||||
|
||||
static void irq_sysfs_del(struct irq_desc *desc)
|
||||
{
|
||||
/*
|
||||
* If irq_sysfs_init() has not yet been invoked (early boot), then
|
||||
* irq_kobj_base is NULL and the descriptor was never added.
|
||||
* kobject_del() complains about a object with no parent, so make
|
||||
* it conditional.
|
||||
* Only invoke kobject_del() when kobject_add() was successfully
|
||||
* invoked for the descriptor. This covers both early boot, where
|
||||
* sysfs is not initialized yet, and the case of a failed
|
||||
* kobject_add() invocation.
|
||||
*/
|
||||
if (irq_kobj_base)
|
||||
if (desc->istate & IRQS_SYSFS)
|
||||
kobject_del(&desc->kobj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3666,7 +3666,8 @@ static bool finished_loading(const char *name)
|
|||
sched_annotate_sleep();
|
||||
mutex_lock(&module_mutex);
|
||||
mod = find_module_all(name, strlen(name), true);
|
||||
ret = !mod || mod->state == MODULE_STATE_LIVE;
|
||||
ret = !mod || mod->state == MODULE_STATE_LIVE
|
||||
|| mod->state == MODULE_STATE_GOING;
|
||||
mutex_unlock(&module_mutex);
|
||||
|
||||
return ret;
|
||||
|
|
@ -3832,20 +3833,35 @@ static int add_unformed_module(struct module *mod)
|
|||
|
||||
mod->state = MODULE_STATE_UNFORMED;
|
||||
|
||||
again:
|
||||
mutex_lock(&module_mutex);
|
||||
old = find_module_all(mod->name, strlen(mod->name), true);
|
||||
if (old != NULL) {
|
||||
if (old->state != MODULE_STATE_LIVE) {
|
||||
if (old->state == MODULE_STATE_COMING
|
||||
|| old->state == MODULE_STATE_UNFORMED) {
|
||||
/* Wait in case it fails to load. */
|
||||
mutex_unlock(&module_mutex);
|
||||
err = wait_event_interruptible(module_wq,
|
||||
finished_loading(mod->name));
|
||||
if (err)
|
||||
goto out_unlocked;
|
||||
goto again;
|
||||
|
||||
/* The module might have gone in the meantime. */
|
||||
mutex_lock(&module_mutex);
|
||||
old = find_module_all(mod->name, strlen(mod->name),
|
||||
true);
|
||||
}
|
||||
err = -EEXIST;
|
||||
|
||||
/*
|
||||
* We are here only when the same module was being loaded. Do
|
||||
* not try to load it again right now. It prevents long delays
|
||||
* caused by serialized module load failures. It might happen
|
||||
* when more devices of the same type trigger load of
|
||||
* a particular module.
|
||||
*/
|
||||
if (old && old->state == MODULE_STATE_LIVE)
|
||||
err = -EEXIST;
|
||||
else
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
mod_update_bounds(mod);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#define PANIC_TIMER_STEP 100
|
||||
|
|
@ -44,6 +45,7 @@ static int pause_on_oops_flag;
|
|||
static DEFINE_SPINLOCK(pause_on_oops_lock);
|
||||
bool crash_kexec_post_notifiers;
|
||||
int panic_on_warn __read_mostly;
|
||||
static unsigned int warn_limit __read_mostly;
|
||||
|
||||
int panic_timeout = CONFIG_PANIC_TIMEOUT;
|
||||
EXPORT_SYMBOL_GPL(panic_timeout);
|
||||
|
|
@ -60,6 +62,45 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
|
|||
|
||||
EXPORT_SYMBOL(panic_notifier_list);
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table kern_panic_table[] = {
|
||||
{
|
||||
.procname = "warn_limit",
|
||||
.data = &warn_limit,
|
||||
.maxlen = sizeof(warn_limit),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_douintvec,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static __init int kernel_panic_sysctls_init(void)
|
||||
{
|
||||
register_sysctl_init("kernel", kern_panic_table);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(kernel_panic_sysctls_init);
|
||||
#endif
|
||||
|
||||
static atomic_t warn_count = ATOMIC_INIT(0);
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
static ssize_t warn_count_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
return sysfs_emit(page, "%d\n", atomic_read(&warn_count));
|
||||
}
|
||||
|
||||
static struct kobj_attribute warn_count_attr = __ATTR_RO(warn_count);
|
||||
|
||||
static __init int kernel_panic_sysfs_init(void)
|
||||
{
|
||||
sysfs_add_file_to_group(kernel_kobj, &warn_count_attr.attr, NULL);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(kernel_panic_sysfs_init);
|
||||
#endif
|
||||
|
||||
static long no_blink(int state)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -156,6 +197,19 @@ static void panic_print_sys_info(void)
|
|||
ftrace_dump(DUMP_ALL);
|
||||
}
|
||||
|
||||
void check_panic_on_warn(const char *origin)
|
||||
{
|
||||
unsigned int limit;
|
||||
|
||||
if (panic_on_warn)
|
||||
panic("%s: panic_on_warn set ...\n", origin);
|
||||
|
||||
limit = READ_ONCE(warn_limit);
|
||||
if (atomic_inc_return(&warn_count) >= limit && limit)
|
||||
panic("%s: system warned too often (kernel.warn_limit is %d)",
|
||||
origin, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* panic - halt the system
|
||||
* @fmt: The text string to print
|
||||
|
|
@ -173,6 +227,16 @@ void panic(const char *fmt, ...)
|
|||
int old_cpu, this_cpu;
|
||||
bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
|
||||
|
||||
if (panic_on_warn) {
|
||||
/*
|
||||
* This thread may hit another WARN() in the panic path.
|
||||
* Resetting this prevents additional WARN() from panicking the
|
||||
* system on this thread. Other threads are blocked by the
|
||||
* panic_mutex in panic().
|
||||
*/
|
||||
panic_on_warn = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable local interrupts. This will prevent panic_smp_self_stop
|
||||
* from deadlocking the first cpu that invokes the panic, since
|
||||
|
|
@ -571,16 +635,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
|
|||
if (args)
|
||||
vprintk(args->fmt, args->args);
|
||||
|
||||
if (panic_on_warn) {
|
||||
/*
|
||||
* This thread may hit another WARN() in the panic path.
|
||||
* Resetting this prevents additional WARN() from panicking the
|
||||
* system on this thread. Other threads are blocked by the
|
||||
* panic_mutex in panic().
|
||||
*/
|
||||
panic_on_warn = 0;
|
||||
panic("panic_on_warn set ...\n");
|
||||
}
|
||||
check_panic_on_warn("kernel");
|
||||
|
||||
print_modules();
|
||||
|
||||
|
|
|
|||
|
|
@ -1680,8 +1680,8 @@ static unsigned long minimum_image_size(unsigned long saveable)
|
|||
* /sys/power/reserved_size, respectively). To make this happen, we compute the
|
||||
* total number of available page frames and allocate at least
|
||||
*
|
||||
* ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
|
||||
* + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
|
||||
* ([page frames total] - PAGES_FOR_IO - [metadata pages]) / 2
|
||||
* - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
|
||||
*
|
||||
* of them, which corresponds to the maximum size of a hibernation image.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2319,7 +2319,7 @@ void rcu_force_quiescent_state(void)
|
|||
struct rcu_node *rnp_old = NULL;
|
||||
|
||||
/* Funnel through hierarchy to reduce memory contention. */
|
||||
rnp = __this_cpu_read(rcu_data.mynode);
|
||||
rnp = raw_cpu_read(rcu_data.mynode);
|
||||
for (; rnp != NULL; rnp = rnp->parent) {
|
||||
ret = (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) ||
|
||||
!raw_spin_trylock(&rnp->fqslock);
|
||||
|
|
|
|||
|
|
@ -163,13 +163,13 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan)
|
|||
{
|
||||
struct rchan_buf *buf;
|
||||
|
||||
if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
|
||||
if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t))
|
||||
return NULL;
|
||||
|
||||
buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *),
|
||||
buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t),
|
||||
GFP_KERNEL);
|
||||
if (!buf->padding)
|
||||
goto free_buf;
|
||||
|
|
|
|||
|
|
@ -4148,8 +4148,7 @@ static noinline void __schedule_bug(struct task_struct *prev)
|
|||
print_ip_sym(preempt_disable_ip);
|
||||
pr_cont("\n");
|
||||
}
|
||||
if (panic_on_warn)
|
||||
panic("scheduling while atomic\n");
|
||||
check_panic_on_warn("scheduling while atomic");
|
||||
|
||||
#ifdef CONFIG_PANIC_ON_SCHED_BUG
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -1137,10 +1137,11 @@ void psi_trigger_destroy(struct psi_trigger *t)
|
|||
|
||||
group = t->group;
|
||||
/*
|
||||
* Wakeup waiters to stop polling. Can happen if cgroup is deleted
|
||||
* from under a polling process.
|
||||
* Wakeup waiters to stop polling and clear the queue to prevent it from
|
||||
* being accessed later. Can happen if cgroup is deleted from under a
|
||||
* polling process.
|
||||
*/
|
||||
wake_up_interruptible(&t->event_wait);
|
||||
wake_up_pollfree(&t->event_wait);
|
||||
|
||||
mutex_lock(&group->trigger_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -1538,6 +1538,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
|
|||
|
||||
if (resource >= RLIM_NLIMITS)
|
||||
return -EINVAL;
|
||||
resource = array_index_nospec(resource, RLIM_NLIMITS);
|
||||
|
||||
if (new_rlim) {
|
||||
if (new_rlim->rlim_cur > new_rlim->rlim_max)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -479,11 +479,35 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(alarm_forward);
|
||||
|
||||
u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
|
||||
static u64 __alarm_forward_now(struct alarm *alarm, ktime_t interval, bool throttle)
|
||||
{
|
||||
struct alarm_base *base = &alarm_bases[alarm->type];
|
||||
ktime_t now = base->gettime();
|
||||
|
||||
return alarm_forward(alarm, base->gettime(), interval);
|
||||
if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && throttle) {
|
||||
/*
|
||||
* Same issue as with posix_timer_fn(). Timers which are
|
||||
* periodic but the signal is ignored can starve the system
|
||||
* with a very small interval. The real fix which was
|
||||
* promised in the context of posix_timer_fn() never
|
||||
* materialized, but someone should really work on it.
|
||||
*
|
||||
* To prevent DOS fake @now to be 1 jiffie out which keeps
|
||||
* the overrun accounting correct but creates an
|
||||
* inconsistency vs. timer_gettime(2).
|
||||
*/
|
||||
ktime_t kj = NSEC_PER_SEC / HZ;
|
||||
|
||||
if (interval < kj)
|
||||
now = ktime_add(now, kj);
|
||||
}
|
||||
|
||||
return alarm_forward(alarm, now, interval);
|
||||
}
|
||||
|
||||
u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
|
||||
{
|
||||
return __alarm_forward_now(alarm, interval, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alarm_forward_now);
|
||||
|
||||
|
|
@ -557,9 +581,10 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
|
|||
if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
|
||||
/*
|
||||
* Handle ignored signals and rearm the timer. This will go
|
||||
* away once we handle ignored signals proper.
|
||||
* away once we handle ignored signals proper. Ensure that
|
||||
* small intervals cannot starve the system.
|
||||
*/
|
||||
ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
|
||||
ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true);
|
||||
++ptr->it_requeue_pending;
|
||||
ptr->it_active = 1;
|
||||
result = ALARMTIMER_RESTART;
|
||||
|
|
|
|||
|
|
@ -1589,7 +1589,8 @@ blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
|
|||
|
||||
static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
|
||||
{
|
||||
if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
|
||||
if ((iter->ent->type != TRACE_BLK) ||
|
||||
!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
|
||||
return TRACE_TYPE_UNHANDLED;
|
||||
|
||||
return print_one_line(iter, true);
|
||||
|
|
|
|||
|
|
@ -649,6 +649,9 @@ BPF_CALL_1(bpf_send_signal, u32, sig)
|
|||
return -EPERM;
|
||||
if (unlikely(!nmi_uaccess_okay()))
|
||||
return -EPERM;
|
||||
/* Task should not be pid=1 to avoid kernel panic. */
|
||||
if (unlikely(is_global_init(current)))
|
||||
return -EPERM;
|
||||
|
||||
if (irqs_disabled()) {
|
||||
/* Do an early check on signal validity. Otherwise,
|
||||
|
|
|
|||
|
|
@ -6123,7 +6123,20 @@ waitagain:
|
|||
|
||||
ret = print_trace_line(iter);
|
||||
if (ret == TRACE_TYPE_PARTIAL_LINE) {
|
||||
/* don't print partial lines */
|
||||
/*
|
||||
* If one print_trace_line() fills entire trace_seq in one shot,
|
||||
* trace_seq_to_user() will returns -EBUSY because save_len == 0,
|
||||
* In this case, we need to consume it, otherwise, loop will peek
|
||||
* this event next time, resulting in an infinite loop.
|
||||
*/
|
||||
if (save_len == 0) {
|
||||
iter->seq.full = 0;
|
||||
trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
|
||||
trace_consume(iter);
|
||||
break;
|
||||
}
|
||||
|
||||
/* In other cases, don't print partial lines */
|
||||
iter->seq.seq.len = save_len;
|
||||
break;
|
||||
}
|
||||
|
|
@ -8310,9 +8323,6 @@ buffer_percent_write(struct file *filp, const char __user *ubuf,
|
|||
if (val > 100)
|
||||
return -EINVAL;
|
||||
|
||||
if (!val)
|
||||
val = 1;
|
||||
|
||||
tr->buffer_percent = val;
|
||||
|
||||
(*ppos)++;
|
||||
|
|
@ -9398,6 +9408,8 @@ void __init early_trace_init(void)
|
|||
static_key_enable(&tracepoint_printk_key.key);
|
||||
}
|
||||
tracer_alloc_buffers();
|
||||
|
||||
init_events();
|
||||
}
|
||||
|
||||
void __init trace_init(void)
|
||||
|
|
|
|||
|
|
@ -1613,6 +1613,7 @@ extern void trace_event_enable_cmd_record(bool enable);
|
|||
extern void trace_event_enable_tgid_record(bool enable);
|
||||
|
||||
extern int event_trace_init(void);
|
||||
extern int init_events(void);
|
||||
extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
|
||||
extern int event_trace_del_tracer(struct trace_array *tr);
|
||||
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ struct action_data {
|
|||
* event param, and is passed to the synthetic event
|
||||
* invocation.
|
||||
*/
|
||||
unsigned int var_ref_idx[TRACING_MAP_VARS_MAX];
|
||||
unsigned int var_ref_idx[SYNTH_FIELDS_MAX];
|
||||
struct synth_event *synth_event;
|
||||
bool use_trace_keyword;
|
||||
char *synth_event_name;
|
||||
|
|
@ -2564,6 +2564,8 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
|
|||
unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
|
||||
hist_field->fn = hist_field_log2;
|
||||
hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
|
||||
if (!hist_field->operands[0])
|
||||
goto free;
|
||||
hist_field->size = hist_field->operands[0]->size;
|
||||
hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL);
|
||||
if (!hist_field->type)
|
||||
|
|
@ -2764,7 +2766,9 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
|
|||
return ref_field;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
|
||||
if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
|
||||
return NULL;
|
||||
ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
|
||||
if (ref_field) {
|
||||
if (init_var_ref(ref_field, var_field, system, event_name)) {
|
||||
|
|
@ -4026,6 +4030,7 @@ static int parse_action_params(struct trace_array *tr, char *params,
|
|||
while (params) {
|
||||
if (data->n_params >= SYNTH_FIELDS_MAX) {
|
||||
hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -4350,6 +4355,10 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
|
|||
|
||||
lockdep_assert_held(&event_mutex);
|
||||
|
||||
/* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
|
||||
if (data->n_params > SYNTH_FIELDS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (data->use_trace_keyword)
|
||||
synth_event_name = data->synth_event_name;
|
||||
else
|
||||
|
|
@ -6445,7 +6454,7 @@ enable:
|
|||
/* Just return zero, not the number of registered triggers */
|
||||
ret = 0;
|
||||
out:
|
||||
if (ret == 0)
|
||||
if (ret == 0 && glob[0])
|
||||
hist_err_clear();
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1366,7 +1366,7 @@ static struct trace_event *events[] __initdata = {
|
|||
NULL
|
||||
};
|
||||
|
||||
__init static int init_events(void)
|
||||
__init int init_events(void)
|
||||
{
|
||||
struct trace_event *event;
|
||||
int i, ret;
|
||||
|
|
@ -1384,4 +1384,3 @@ __init static int init_events(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
early_initcall(init_events);
|
||||
|
|
|
|||
Loading…
Reference in a new issue