Merge 38a9d7dac3 ("pstore/ram: Add check for kstrdup") into android13-5.15-lts
Steps on the way to 5.15.121 Change-Id: I9714647fff52ec446455ad9d71297594d6451269 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -326,6 +326,23 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Raw SMP data memory barrier
|
||||
*/
|
||||
.macro __smp_dmb mode
|
||||
#if __LINUX_ARM_ARCH__ >= 7
|
||||
.ifeqs "\mode","arm"
|
||||
dmb ish
|
||||
.else
|
||||
W(dmb) ish
|
||||
.endif
|
||||
#elif __LINUX_ARM_ARCH__ == 6
|
||||
mcr p15, 0, r0, c7, c10, 5 @ dmb
|
||||
#else
|
||||
.error "Incompatible SMP platform"
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#if defined(CONFIG_CPU_V7M)
|
||||
/*
|
||||
* setmode is used to assert to be in svc mode during boot. For v7-M
|
||||
|
||||
@@ -14,14 +14,35 @@
|
||||
* ops which are SMP safe even on a UP kernel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unordered
|
||||
*/
|
||||
|
||||
#define sync_set_bit(nr, p) _set_bit(nr, p)
|
||||
#define sync_clear_bit(nr, p) _clear_bit(nr, p)
|
||||
#define sync_change_bit(nr, p) _change_bit(nr, p)
|
||||
#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p)
|
||||
#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p)
|
||||
#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p)
|
||||
#define sync_test_bit(nr, addr) test_bit(nr, addr)
|
||||
#define arch_sync_cmpxchg arch_cmpxchg
|
||||
|
||||
/*
|
||||
* Fully ordered
|
||||
*/
|
||||
|
||||
int _sync_test_and_set_bit(int nr, volatile unsigned long * p);
|
||||
#define sync_test_and_set_bit(nr, p) _sync_test_and_set_bit(nr, p)
|
||||
|
||||
int _sync_test_and_clear_bit(int nr, volatile unsigned long * p);
|
||||
#define sync_test_and_clear_bit(nr, p) _sync_test_and_clear_bit(nr, p)
|
||||
|
||||
int _sync_test_and_change_bit(int nr, volatile unsigned long * p);
|
||||
#define sync_test_and_change_bit(nr, p) _sync_test_and_change_bit(nr, p)
|
||||
|
||||
#define arch_sync_cmpxchg(ptr, old, new) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__smp_mb__before_atomic(); \
|
||||
__ret = arch_cmpxchg_relaxed((ptr), (old), (new)); \
|
||||
__smp_mb__after_atomic(); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ UNWIND( .fnend )
|
||||
ENDPROC(\name )
|
||||
.endm
|
||||
|
||||
.macro testop, name, instr, store
|
||||
.macro __testop, name, instr, store, barrier
|
||||
ENTRY( \name )
|
||||
UNWIND( .fnstart )
|
||||
ands ip, r1, #3
|
||||
@@ -38,7 +38,7 @@ UNWIND( .fnstart )
|
||||
mov r0, r0, lsr #5
|
||||
add r1, r1, r0, lsl #2 @ Get word offset
|
||||
mov r3, r2, lsl r3 @ create mask
|
||||
smp_dmb
|
||||
\barrier
|
||||
#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
|
||||
.arch_extension mp
|
||||
ALT_SMP(W(pldw) [r1])
|
||||
@@ -50,13 +50,21 @@ UNWIND( .fnstart )
|
||||
strex ip, r2, [r1]
|
||||
cmp ip, #0
|
||||
bne 1b
|
||||
smp_dmb
|
||||
\barrier
|
||||
cmp r0, #0
|
||||
movne r0, #1
|
||||
2: bx lr
|
||||
UNWIND( .fnend )
|
||||
ENDPROC(\name )
|
||||
.endm
|
||||
|
||||
.macro testop, name, instr, store
|
||||
__testop \name, \instr, \store, smp_dmb
|
||||
.endm
|
||||
|
||||
.macro sync_testop, name, instr, store
|
||||
__testop \name, \instr, \store, __smp_dmb
|
||||
.endm
|
||||
#else
|
||||
.macro bitop, name, instr
|
||||
ENTRY( \name )
|
||||
|
||||
@@ -10,3 +10,7 @@
|
||||
.text
|
||||
|
||||
testop _test_and_change_bit, eor, str
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
sync_testop _sync_test_and_change_bit, eor, str
|
||||
#endif
|
||||
|
||||
@@ -10,3 +10,7 @@
|
||||
.text
|
||||
|
||||
testop _test_and_clear_bit, bicne, strne
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
sync_testop _sync_test_and_clear_bit, bicne, strne
|
||||
#endif
|
||||
|
||||
@@ -10,3 +10,7 @@
|
||||
.text
|
||||
|
||||
testop _test_and_set_bit, orreq, streq
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
sync_testop _sync_test_and_set_bit, orreq, streq
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
|
||||
* Different from other insn uses imm8, the real addressing offset of
|
||||
* STRD in T32 encoding should be imm8 * 4. See ARMARM description.
|
||||
*/
|
||||
enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
|
||||
static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
|
||||
struct arch_probes_insn *asi,
|
||||
const struct decode_header *h)
|
||||
{
|
||||
|
||||
@@ -233,7 +233,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
|
||||
* kprobe, and that level is reserved for user kprobe handlers, so we can't
|
||||
* risk encountering a new kprobe in an interrupt handler.
|
||||
*/
|
||||
void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
static void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe *p, *cur;
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
@@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
|
||||
}
|
||||
}
|
||||
|
||||
extern void kprobe_handler(struct pt_regs *regs);
|
||||
|
||||
static void
|
||||
optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
||||
{
|
||||
|
||||
@@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = {
|
||||
[REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP,
|
||||
};
|
||||
|
||||
unsigned coverage_start_registers(const struct decode_header *h)
|
||||
static unsigned coverage_start_registers(const struct decode_header *h)
|
||||
{
|
||||
unsigned regs = 0;
|
||||
int i;
|
||||
|
||||
@@ -454,3 +454,7 @@ void kprobe_thumb32_test_cases(void);
|
||||
#else
|
||||
void kprobe_arm_test_cases(void);
|
||||
#endif
|
||||
|
||||
void __kprobes_test_case_start(void);
|
||||
void __kprobes_test_case_end_16(void);
|
||||
void __kprobes_test_case_end_32(void);
|
||||
|
||||
@@ -364,7 +364,7 @@ static int amd_pmu_hw_config(struct perf_event *event)
|
||||
|
||||
/* pass precise event sampling to ibs: */
|
||||
if (event->attr.precise_ip && get_ibs_caps())
|
||||
return -ENOENT;
|
||||
return forward_event_to_ibs(event);
|
||||
|
||||
if (has_branch_stack(event))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -194,7 +194,7 @@ static struct perf_ibs *get_ibs_pmu(int type)
|
||||
}
|
||||
|
||||
/*
|
||||
* Use IBS for precise event sampling:
|
||||
* core pmu config -> IBS config
|
||||
*
|
||||
* perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count
|
||||
* perf record -a -e r076:p ... # same as -e cpu-cycles:p
|
||||
@@ -203,25 +203,9 @@ static struct perf_ibs *get_ibs_pmu(int type)
|
||||
* IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
|
||||
* MSRC001_1033) is used to select either cycle or micro-ops counting
|
||||
* mode.
|
||||
*
|
||||
* The rip of IBS samples has skid 0. Thus, IBS supports precise
|
||||
* levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
|
||||
* rip is invalid when IBS was not able to record the rip correctly.
|
||||
* We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
|
||||
*
|
||||
*/
|
||||
static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
|
||||
static int core_pmu_ibs_config(struct perf_event *event, u64 *config)
|
||||
{
|
||||
switch (event->attr.precise_ip) {
|
||||
case 0:
|
||||
return -ENOENT;
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (event->attr.type) {
|
||||
case PERF_TYPE_HARDWARE:
|
||||
switch (event->attr.config) {
|
||||
@@ -247,22 +231,37 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* The rip of IBS samples has skid 0. Thus, IBS supports precise
|
||||
* levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
|
||||
* rip is invalid when IBS was not able to record the rip correctly.
|
||||
* We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
|
||||
*/
|
||||
int forward_event_to_ibs(struct perf_event *event)
|
||||
{
|
||||
u64 config = 0;
|
||||
|
||||
if (!event->attr.precise_ip || event->attr.precise_ip > 2)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!core_pmu_ibs_config(event, &config)) {
|
||||
event->attr.type = perf_ibs_op.pmu.type;
|
||||
event->attr.config = config;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int perf_ibs_init(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
struct perf_ibs *perf_ibs;
|
||||
u64 max_cnt, config;
|
||||
int ret;
|
||||
|
||||
perf_ibs = get_ibs_pmu(event->attr.type);
|
||||
if (perf_ibs) {
|
||||
config = event->attr.config;
|
||||
} else {
|
||||
perf_ibs = &perf_ibs_op;
|
||||
ret = perf_ibs_precise_event(event, &config);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (!perf_ibs)
|
||||
return -ENOENT;
|
||||
|
||||
config = event->attr.config;
|
||||
|
||||
if (event->pmu != &perf_ibs->pmu)
|
||||
return -ENOENT;
|
||||
|
||||
@@ -427,8 +427,10 @@ struct pebs_xmm {
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
extern u32 get_ibs_caps(void);
|
||||
extern int forward_event_to_ibs(struct perf_event *event);
|
||||
#else
|
||||
static inline u32 get_ibs_caps(void) { return 0; }
|
||||
static inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
|
||||
@@ -235,8 +235,8 @@ static inline void native_pgd_clear(pgd_t *pgd)
|
||||
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
|
||||
#define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
|
||||
#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val })
|
||||
#define __swp_entry_to_pte(x) (__pte((x).val))
|
||||
#define __swp_entry_to_pmd(x) (__pmd((x).val))
|
||||
|
||||
extern int kern_addr_valid(unsigned long addr);
|
||||
extern void cleanup_highmap(void);
|
||||
|
||||
@@ -731,11 +731,15 @@ unlock:
|
||||
static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
|
||||
{
|
||||
struct task_struct *p, *t;
|
||||
pid_t pid;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_process_thread(p, t) {
|
||||
if (is_closid_match(t, r) || is_rmid_match(t, r))
|
||||
seq_printf(s, "%d\n", t->pid);
|
||||
if (is_closid_match(t, r) || is_rmid_match(t, r)) {
|
||||
pid = task_pid_vnr(t);
|
||||
if (pid)
|
||||
seq_printf(s, "%d\n", pid);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -2448,6 +2448,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
|
||||
u32 hwi, adj_step;
|
||||
s64 margin;
|
||||
u64 cost, new_inuse;
|
||||
unsigned long flags;
|
||||
|
||||
current_hweight(iocg, NULL, &hwi);
|
||||
old_hwi = hwi;
|
||||
@@ -2466,11 +2467,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
|
||||
iocg->inuse == iocg->active)
|
||||
return cost;
|
||||
|
||||
spin_lock_irq(&ioc->lock);
|
||||
spin_lock_irqsave(&ioc->lock, flags);
|
||||
|
||||
/* we own inuse only when @iocg is in the normal active state */
|
||||
if (iocg->abs_vdebt || list_empty(&iocg->active_list)) {
|
||||
spin_unlock_irq(&ioc->lock);
|
||||
spin_unlock_irqrestore(&ioc->lock, flags);
|
||||
return cost;
|
||||
}
|
||||
|
||||
@@ -2491,7 +2492,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
|
||||
} while (time_after64(vtime + cost, now->vnow) &&
|
||||
iocg->inuse != iocg->active);
|
||||
|
||||
spin_unlock_irq(&ioc->lock);
|
||||
spin_unlock_irqrestore(&ioc->lock, flags);
|
||||
|
||||
TRACE_IOCG_PATH(inuse_adjust, iocg, now,
|
||||
old_inuse, iocg->inuse, old_hwi, hwi);
|
||||
|
||||
@@ -2860,10 +2860,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
|
||||
|
||||
err = of_property_read_u32(state_node, "min-residency-us", &residency);
|
||||
if (!err)
|
||||
genpd_state->residency_ns = 1000 * residency;
|
||||
genpd_state->residency_ns = 1000LL * residency;
|
||||
|
||||
genpd_state->power_on_latency_ns = 1000 * exit_latency;
|
||||
genpd_state->power_off_latency_ns = 1000 * entry_latency;
|
||||
genpd_state->power_on_latency_ns = 1000LL * exit_latency;
|
||||
genpd_state->power_off_latency_ns = 1000LL * entry_latency;
|
||||
genpd_state->fwnode = &state_node->fwnode;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -486,10 +486,10 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
|
||||
* and use it. Note that the event timer uses the interrupt and it's the
|
||||
* 2nd TTC hence the irq_of_parse_and_map(,1)
|
||||
*/
|
||||
timer_baseaddr = of_iomap(timer, 0);
|
||||
if (!timer_baseaddr) {
|
||||
timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL);
|
||||
if (IS_ERR(timer_baseaddr)) {
|
||||
pr_err("ERROR: invalid timer base address\n");
|
||||
return -ENXIO;
|
||||
return PTR_ERR(timer_baseaddr);
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(timer, 1);
|
||||
@@ -513,20 +513,27 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
|
||||
clk_ce = of_clk_get(timer, clksel);
|
||||
if (IS_ERR(clk_ce)) {
|
||||
pr_err("ERROR: timer input clock not found\n");
|
||||
return PTR_ERR(clk_ce);
|
||||
ret = PTR_ERR(clk_ce);
|
||||
goto put_clk_cs;
|
||||
}
|
||||
|
||||
ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_clk_ce;
|
||||
|
||||
ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_clk_ce;
|
||||
|
||||
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
|
||||
|
||||
return 0;
|
||||
|
||||
put_clk_ce:
|
||||
clk_put(clk_ce);
|
||||
put_clk_cs:
|
||||
clk_put(clk_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ttc_timer_of_match[] = {
|
||||
|
||||
@@ -824,6 +824,8 @@ static ssize_t store_energy_performance_preference(
|
||||
err = cpufreq_start_governor(policy);
|
||||
if (!ret)
|
||||
ret = err;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ static int __init aic_irq_of_init(struct device_node *node,
|
||||
unsigned min_irq = JCORE_AIC2_MIN_HWIRQ;
|
||||
unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1;
|
||||
struct irq_domain *domain;
|
||||
int ret;
|
||||
|
||||
pr_info("Initializing J-Core AIC\n");
|
||||
|
||||
@@ -100,6 +101,12 @@ static int __init aic_irq_of_init(struct device_node *node,
|
||||
jcore_aic.irq_unmask = noop;
|
||||
jcore_aic.name = "AIC";
|
||||
|
||||
ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq,
|
||||
of_node_to_nid(node));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
|
||||
&jcore_aic_irqdomain_ops,
|
||||
&jcore_aic);
|
||||
|
||||
@@ -54,14 +54,7 @@ __acquires(bitmap->lock)
|
||||
{
|
||||
unsigned char *mappage;
|
||||
|
||||
if (page >= bitmap->pages) {
|
||||
/* This can happen if bitmap_start_sync goes beyond
|
||||
* End-of-device while looking for a whole page.
|
||||
* It is harmless.
|
||||
*/
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(page >= bitmap->pages);
|
||||
if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
|
||||
return 0;
|
||||
|
||||
@@ -1365,6 +1358,14 @@ __acquires(bitmap->lock)
|
||||
sector_t csize;
|
||||
int err;
|
||||
|
||||
if (page >= bitmap->pages) {
|
||||
/*
|
||||
* This can happen if bitmap_start_sync goes beyond
|
||||
* End-of-device while looking for a whole page or
|
||||
* user set a huge number to sysfs bitmap_set_bits.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
err = md_bitmap_checkpage(bitmap, page, create, 0);
|
||||
|
||||
if (bitmap->bp[page].hijacked ||
|
||||
|
||||
@@ -3872,8 +3872,9 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale)
|
||||
static ssize_t
|
||||
safe_delay_show(struct mddev *mddev, char *page)
|
||||
{
|
||||
int msec = (mddev->safemode_delay*1000)/HZ;
|
||||
return sprintf(page, "%d.%03d\n", msec/1000, msec%1000);
|
||||
unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ;
|
||||
|
||||
return sprintf(page, "%u.%03u\n", msec/1000, msec%1000);
|
||||
}
|
||||
static ssize_t
|
||||
safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len)
|
||||
@@ -3885,7 +3886,7 @@ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (strict_strtoul_scaled(cbuf, &msec, 3) < 0)
|
||||
if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ)
|
||||
return -EINVAL;
|
||||
if (msec == 0)
|
||||
mddev->safemode_delay = 0;
|
||||
@@ -4555,6 +4556,8 @@ max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len
|
||||
rv = kstrtouint(buf, 10, &n);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
if (n > INT_MAX)
|
||||
return -EINVAL;
|
||||
atomic_set(&mddev->max_corr_read_errors, n);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -752,8 +752,16 @@ static struct md_rdev *read_balance(struct r10conf *conf,
|
||||
disk = r10_bio->devs[slot].devnum;
|
||||
rdev = rcu_dereference(conf->mirrors[disk].replacement);
|
||||
if (rdev == NULL || test_bit(Faulty, &rdev->flags) ||
|
||||
r10_bio->devs[slot].addr + sectors > rdev->recovery_offset)
|
||||
r10_bio->devs[slot].addr + sectors >
|
||||
rdev->recovery_offset) {
|
||||
/*
|
||||
* Read replacement first to prevent reading both rdev
|
||||
* and replacement as NULL during replacement replace
|
||||
* rdev.
|
||||
*/
|
||||
smp_mb();
|
||||
rdev = rcu_dereference(conf->mirrors[disk].rdev);
|
||||
}
|
||||
if (rdev == NULL ||
|
||||
test_bit(Faulty, &rdev->flags))
|
||||
continue;
|
||||
@@ -1449,9 +1457,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
|
||||
|
||||
for (i = 0; i < conf->copies; i++) {
|
||||
int d = r10_bio->devs[i].devnum;
|
||||
struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev);
|
||||
struct md_rdev *rrdev = rcu_dereference(
|
||||
conf->mirrors[d].replacement);
|
||||
struct md_rdev *rdev, *rrdev;
|
||||
|
||||
rrdev = rcu_dereference(conf->mirrors[d].replacement);
|
||||
/*
|
||||
* Read replacement first to prevent reading both rdev and
|
||||
* replacement as NULL during replacement replace rdev.
|
||||
*/
|
||||
smp_mb();
|
||||
rdev = rcu_dereference(conf->mirrors[d].rdev);
|
||||
if (rdev == rrdev)
|
||||
rrdev = NULL;
|
||||
if (rdev && (test_bit(Faulty, &rdev->flags)))
|
||||
@@ -3412,7 +3426,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
int must_sync;
|
||||
int any_working;
|
||||
int need_recover = 0;
|
||||
int need_replace = 0;
|
||||
struct raid10_info *mirror = &conf->mirrors[i];
|
||||
struct md_rdev *mrdev, *mreplace;
|
||||
|
||||
@@ -3424,11 +3437,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
!test_bit(Faulty, &mrdev->flags) &&
|
||||
!test_bit(In_sync, &mrdev->flags))
|
||||
need_recover = 1;
|
||||
if (mreplace != NULL &&
|
||||
!test_bit(Faulty, &mreplace->flags))
|
||||
need_replace = 1;
|
||||
if (mreplace && test_bit(Faulty, &mreplace->flags))
|
||||
mreplace = NULL;
|
||||
|
||||
if (!need_recover && !need_replace) {
|
||||
if (!need_recover && !mreplace) {
|
||||
rcu_read_unlock();
|
||||
continue;
|
||||
}
|
||||
@@ -3444,8 +3456,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
rcu_read_unlock();
|
||||
continue;
|
||||
}
|
||||
if (mreplace && test_bit(Faulty, &mreplace->flags))
|
||||
mreplace = NULL;
|
||||
/* Unless we are doing a full sync, or a replacement
|
||||
* we only need to recover the block if it is set in
|
||||
* the bitmap
|
||||
@@ -3568,11 +3578,11 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
bio = r10_bio->devs[1].repl_bio;
|
||||
if (bio)
|
||||
bio->bi_end_io = NULL;
|
||||
/* Note: if need_replace, then bio
|
||||
/* Note: if replace is not NULL, then bio
|
||||
* cannot be NULL as r10buf_pool_alloc will
|
||||
* have allocated it.
|
||||
*/
|
||||
if (!need_replace)
|
||||
if (!mreplace)
|
||||
break;
|
||||
bio->bi_next = biolist;
|
||||
biolist = bio;
|
||||
|
||||
@@ -1571,9 +1571,10 @@ static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int id
|
||||
if (dtc->irq < 0)
|
||||
return dtc->irq;
|
||||
|
||||
writel_relaxed(0, dtc->base + CMN_DT_PMCR);
|
||||
writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL);
|
||||
writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
|
||||
writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR);
|
||||
writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR);
|
||||
writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1629,7 +1630,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
|
||||
dn->type = CMN_TYPE_RNI;
|
||||
}
|
||||
|
||||
writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL);
|
||||
arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,12 @@ if POWERCAP
|
||||
# Client driver configurations go here.
|
||||
config INTEL_RAPL_CORE
|
||||
tristate
|
||||
depends on PCI
|
||||
select IOSF_MBI
|
||||
|
||||
config INTEL_RAPL
|
||||
tristate "Intel RAPL Support via MSR Interface"
|
||||
depends on X86 && IOSF_MBI
|
||||
depends on X86 && PCI
|
||||
select INTEL_RAPL_CORE
|
||||
help
|
||||
This enables support for the Intel Running Average Power Limit (RAPL)
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <linux/processor.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/iosf_mbi.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/intel-family.h>
|
||||
|
||||
|
||||
@@ -319,6 +319,11 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sun8i_ths_reset_control_assert(void *data)
|
||||
{
|
||||
reset_control_assert(data);
|
||||
}
|
||||
|
||||
static int sun8i_ths_resource_init(struct ths_device *tmdev)
|
||||
{
|
||||
struct device *dev = tmdev->dev;
|
||||
@@ -339,47 +344,35 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
|
||||
if (IS_ERR(tmdev->reset))
|
||||
return PTR_ERR(tmdev->reset);
|
||||
|
||||
tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus");
|
||||
ret = reset_control_deassert(tmdev->reset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
|
||||
tmdev->reset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
|
||||
if (IS_ERR(tmdev->bus_clk))
|
||||
return PTR_ERR(tmdev->bus_clk);
|
||||
}
|
||||
|
||||
if (tmdev->chip->has_mod_clk) {
|
||||
tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod");
|
||||
tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod");
|
||||
if (IS_ERR(tmdev->mod_clk))
|
||||
return PTR_ERR(tmdev->mod_clk);
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(tmdev->reset);
|
||||
ret = clk_set_rate(tmdev->mod_clk, 24000000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(tmdev->bus_clk);
|
||||
if (ret)
|
||||
goto assert_reset;
|
||||
|
||||
ret = clk_set_rate(tmdev->mod_clk, 24000000);
|
||||
if (ret)
|
||||
goto bus_disable;
|
||||
|
||||
ret = clk_prepare_enable(tmdev->mod_clk);
|
||||
if (ret)
|
||||
goto bus_disable;
|
||||
|
||||
ret = sun8i_ths_calibrate(tmdev);
|
||||
if (ret)
|
||||
goto mod_disable;
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
mod_disable:
|
||||
clk_disable_unprepare(tmdev->mod_clk);
|
||||
bus_disable:
|
||||
clk_disable_unprepare(tmdev->bus_clk);
|
||||
assert_reset:
|
||||
reset_control_assert(tmdev->reset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun8i_h3_thermal_init(struct ths_device *tmdev)
|
||||
@@ -530,17 +523,6 @@ static int sun8i_ths_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun8i_ths_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ths_device *tmdev = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(tmdev->mod_clk);
|
||||
clk_disable_unprepare(tmdev->bus_clk);
|
||||
reset_control_assert(tmdev->reset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ths_thermal_chip sun8i_a83t_ths = {
|
||||
.sensor_num = 3,
|
||||
.scale = 705,
|
||||
@@ -642,7 +624,6 @@ MODULE_DEVICE_TABLE(of, of_ths_match);
|
||||
|
||||
static struct platform_driver ths_driver = {
|
||||
.probe = sun8i_ths_probe,
|
||||
.remove = sun8i_ths_remove,
|
||||
.driver = {
|
||||
.name = "sun8i-thermal",
|
||||
.of_match_table = of_ths_match,
|
||||
|
||||
@@ -591,6 +591,8 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
||||
raw_spin_lock_init(&prz->buffer_lock);
|
||||
prz->flags = flags;
|
||||
prz->label = kstrdup(label, GFP_KERNEL);
|
||||
if (!prz->label)
|
||||
goto err;
|
||||
|
||||
ret = persistent_ram_buffer_map(start, size, prz, memtype);
|
||||
if (ret)
|
||||
|
||||
@@ -265,18 +265,14 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
|
||||
extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
|
||||
|
||||
#ifdef CONFIG_WATCH_QUEUE
|
||||
unsigned long account_pipe_buffers(struct user_struct *user,
|
||||
unsigned long old, unsigned long new);
|
||||
bool too_many_pipe_buffers_soft(unsigned long user_bufs);
|
||||
bool too_many_pipe_buffers_hard(unsigned long user_bufs);
|
||||
bool pipe_is_unprivileged_user(void);
|
||||
#endif
|
||||
|
||||
/* for F_SETPIPE_SZ and F_GETPIPE_SZ */
|
||||
#ifdef CONFIG_WATCH_QUEUE
|
||||
int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots);
|
||||
#endif
|
||||
long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
|
||||
struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
|
||||
|
||||
|
||||
@@ -437,7 +437,8 @@ struct nft_set_ops {
|
||||
int (*init)(const struct nft_set *set,
|
||||
const struct nft_set_desc *desc,
|
||||
const struct nlattr * const nla[]);
|
||||
void (*destroy)(const struct nft_set *set);
|
||||
void (*destroy)(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set);
|
||||
void (*gc_init)(const struct nft_set *set);
|
||||
|
||||
unsigned int elemsize;
|
||||
@@ -772,6 +773,8 @@ int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_expr *expr_array[]);
|
||||
void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
||||
bool destroy_expr);
|
||||
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set, void *elem);
|
||||
|
||||
/**
|
||||
* struct nft_set_gc_batch_head - nf_tables set garbage collection batch
|
||||
|
||||
@@ -156,7 +156,11 @@ DEFINE_EVENT(timer_class, timer_cancel,
|
||||
{ HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \
|
||||
{ HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \
|
||||
{ HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \
|
||||
{ HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" })
|
||||
{ HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \
|
||||
{ HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \
|
||||
{ HRTIMER_MODE_REL_HARD, "REL|HARD" }, \
|
||||
{ HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \
|
||||
{ HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" })
|
||||
|
||||
/**
|
||||
* hrtimer_init - called when the hrtimer is initialized
|
||||
|
||||
@@ -50,8 +50,8 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>");
|
||||
pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s)
|
||||
#define VERBOSE_SCALEOUT_STRING(s) \
|
||||
do { if (verbose) pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s); } while (0)
|
||||
#define VERBOSE_SCALEOUT_ERRSTRING(s) \
|
||||
do { if (verbose) pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s); } while (0)
|
||||
#define SCALEOUT_ERRSTRING(s) \
|
||||
pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s)
|
||||
|
||||
/*
|
||||
* The intended use cases for the nreaders and nwriters module parameters
|
||||
@@ -500,89 +500,6 @@ rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag)
|
||||
scale_type, tag, nrealreaders, nrealwriters, verbose, shutdown);
|
||||
}
|
||||
|
||||
static void
|
||||
rcu_scale_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int ngps = 0;
|
||||
u64 *wdp;
|
||||
u64 *wdpp;
|
||||
|
||||
/*
|
||||
* Would like warning at start, but everything is expedited
|
||||
* during the mid-boot phase, so have to wait till the end.
|
||||
*/
|
||||
if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
|
||||
VERBOSE_SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
|
||||
if (rcu_gp_is_normal() && gp_exp)
|
||||
VERBOSE_SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
|
||||
if (gp_exp && gp_async)
|
||||
VERBOSE_SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
|
||||
|
||||
if (torture_cleanup_begin())
|
||||
return;
|
||||
if (!cur_ops) {
|
||||
torture_cleanup_end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader_tasks) {
|
||||
for (i = 0; i < nrealreaders; i++)
|
||||
torture_stop_kthread(rcu_scale_reader,
|
||||
reader_tasks[i]);
|
||||
kfree(reader_tasks);
|
||||
}
|
||||
|
||||
if (writer_tasks) {
|
||||
for (i = 0; i < nrealwriters; i++) {
|
||||
torture_stop_kthread(rcu_scale_writer,
|
||||
writer_tasks[i]);
|
||||
if (!writer_n_durations)
|
||||
continue;
|
||||
j = writer_n_durations[i];
|
||||
pr_alert("%s%s writer %d gps: %d\n",
|
||||
scale_type, SCALE_FLAG, i, j);
|
||||
ngps += j;
|
||||
}
|
||||
pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
|
||||
scale_type, SCALE_FLAG,
|
||||
t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
|
||||
t_rcu_scale_writer_finished -
|
||||
t_rcu_scale_writer_started,
|
||||
ngps,
|
||||
rcuscale_seq_diff(b_rcu_gp_test_finished,
|
||||
b_rcu_gp_test_started));
|
||||
for (i = 0; i < nrealwriters; i++) {
|
||||
if (!writer_durations)
|
||||
break;
|
||||
if (!writer_n_durations)
|
||||
continue;
|
||||
wdpp = writer_durations[i];
|
||||
if (!wdpp)
|
||||
continue;
|
||||
for (j = 0; j < writer_n_durations[i]; j++) {
|
||||
wdp = &wdpp[j];
|
||||
pr_alert("%s%s %4d writer-duration: %5d %llu\n",
|
||||
scale_type, SCALE_FLAG,
|
||||
i, j, *wdp);
|
||||
if (j % 100 == 0)
|
||||
schedule_timeout_uninterruptible(1);
|
||||
}
|
||||
kfree(writer_durations[i]);
|
||||
}
|
||||
kfree(writer_tasks);
|
||||
kfree(writer_durations);
|
||||
kfree(writer_n_durations);
|
||||
}
|
||||
|
||||
/* Do torture-type-specific cleanup operations. */
|
||||
if (cur_ops->cleanup != NULL)
|
||||
cur_ops->cleanup();
|
||||
|
||||
torture_cleanup_end();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number if non-negative. If -1, the number of CPUs.
|
||||
* If less than -1, that much less than the number of CPUs, but
|
||||
@@ -602,21 +519,6 @@ static int compute_real(int n)
|
||||
return nr;
|
||||
}
|
||||
|
||||
/*
|
||||
* RCU scalability shutdown kthread. Just waits to be awakened, then shuts
|
||||
* down system.
|
||||
*/
|
||||
static int
|
||||
rcu_scale_shutdown(void *arg)
|
||||
{
|
||||
wait_event(shutdown_wq,
|
||||
atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
|
||||
smp_mb(); /* Wake before output. */
|
||||
rcu_scale_cleanup();
|
||||
kernel_power_off();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* kfree_rcu() scalability tests: Start a kfree_rcu() loop on all CPUs for number
|
||||
* of iterations and measure total time and number of GP for all iterations to complete.
|
||||
@@ -736,8 +638,8 @@ kfree_scale_cleanup(void)
|
||||
static int
|
||||
kfree_scale_shutdown(void *arg)
|
||||
{
|
||||
wait_event(shutdown_wq,
|
||||
atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
|
||||
wait_event_idle(shutdown_wq,
|
||||
atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
|
||||
|
||||
smp_mb(); /* Wake before output. */
|
||||
|
||||
@@ -791,6 +693,108 @@ unwind:
|
||||
return firsterr;
|
||||
}
|
||||
|
||||
static void
|
||||
rcu_scale_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int ngps = 0;
|
||||
u64 *wdp;
|
||||
u64 *wdpp;
|
||||
|
||||
/*
|
||||
* Would like warning at start, but everything is expedited
|
||||
* during the mid-boot phase, so have to wait till the end.
|
||||
*/
|
||||
if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
|
||||
SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
|
||||
if (rcu_gp_is_normal() && gp_exp)
|
||||
SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
|
||||
if (gp_exp && gp_async)
|
||||
SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
|
||||
|
||||
if (kfree_rcu_test) {
|
||||
kfree_scale_cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (torture_cleanup_begin())
|
||||
return;
|
||||
if (!cur_ops) {
|
||||
torture_cleanup_end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader_tasks) {
|
||||
for (i = 0; i < nrealreaders; i++)
|
||||
torture_stop_kthread(rcu_scale_reader,
|
||||
reader_tasks[i]);
|
||||
kfree(reader_tasks);
|
||||
}
|
||||
|
||||
if (writer_tasks) {
|
||||
for (i = 0; i < nrealwriters; i++) {
|
||||
torture_stop_kthread(rcu_scale_writer,
|
||||
writer_tasks[i]);
|
||||
if (!writer_n_durations)
|
||||
continue;
|
||||
j = writer_n_durations[i];
|
||||
pr_alert("%s%s writer %d gps: %d\n",
|
||||
scale_type, SCALE_FLAG, i, j);
|
||||
ngps += j;
|
||||
}
|
||||
pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
|
||||
scale_type, SCALE_FLAG,
|
||||
t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
|
||||
t_rcu_scale_writer_finished -
|
||||
t_rcu_scale_writer_started,
|
||||
ngps,
|
||||
rcuscale_seq_diff(b_rcu_gp_test_finished,
|
||||
b_rcu_gp_test_started));
|
||||
for (i = 0; i < nrealwriters; i++) {
|
||||
if (!writer_durations)
|
||||
break;
|
||||
if (!writer_n_durations)
|
||||
continue;
|
||||
wdpp = writer_durations[i];
|
||||
if (!wdpp)
|
||||
continue;
|
||||
for (j = 0; j < writer_n_durations[i]; j++) {
|
||||
wdp = &wdpp[j];
|
||||
pr_alert("%s%s %4d writer-duration: %5d %llu\n",
|
||||
scale_type, SCALE_FLAG,
|
||||
i, j, *wdp);
|
||||
if (j % 100 == 0)
|
||||
schedule_timeout_uninterruptible(1);
|
||||
}
|
||||
kfree(writer_durations[i]);
|
||||
}
|
||||
kfree(writer_tasks);
|
||||
kfree(writer_durations);
|
||||
kfree(writer_n_durations);
|
||||
}
|
||||
|
||||
/* Do torture-type-specific cleanup operations. */
|
||||
if (cur_ops->cleanup != NULL)
|
||||
cur_ops->cleanup();
|
||||
|
||||
torture_cleanup_end();
|
||||
}
|
||||
|
||||
/*
|
||||
* RCU scalability shutdown kthread. Just waits to be awakened, then shuts
|
||||
* down system.
|
||||
*/
|
||||
static int
|
||||
rcu_scale_shutdown(void *arg)
|
||||
{
|
||||
wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
|
||||
smp_mb(); /* Wake before output. */
|
||||
rcu_scale_cleanup();
|
||||
kernel_power_off();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int __init
|
||||
rcu_scale_init(void)
|
||||
{
|
||||
@@ -845,7 +849,7 @@ rcu_scale_init(void)
|
||||
reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
|
||||
GFP_KERNEL);
|
||||
if (reader_tasks == NULL) {
|
||||
VERBOSE_SCALEOUT_ERRSTRING("out of memory");
|
||||
SCALEOUT_ERRSTRING("out of memory");
|
||||
firsterr = -ENOMEM;
|
||||
goto unwind;
|
||||
}
|
||||
@@ -865,7 +869,7 @@ rcu_scale_init(void)
|
||||
kcalloc(nrealwriters, sizeof(*writer_n_durations),
|
||||
GFP_KERNEL);
|
||||
if (!writer_tasks || !writer_durations || !writer_n_durations) {
|
||||
VERBOSE_SCALEOUT_ERRSTRING("out of memory");
|
||||
SCALEOUT_ERRSTRING("out of memory");
|
||||
firsterr = -ENOMEM;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
@@ -1037,27 +1037,52 @@ retry_delete:
|
||||
}
|
||||
|
||||
/*
|
||||
* return timer owned by the process, used by exit_itimers
|
||||
* Delete a timer if it is armed, remove it from the hash and schedule it
|
||||
* for RCU freeing.
|
||||
*/
|
||||
static void itimer_delete(struct k_itimer *timer)
|
||||
{
|
||||
retry_delete:
|
||||
spin_lock_irq(&timer->it_lock);
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* irqsave is required to make timer_wait_running() work.
|
||||
*/
|
||||
spin_lock_irqsave(&timer->it_lock, flags);
|
||||
|
||||
retry_delete:
|
||||
/*
|
||||
* Even if the timer is not longer accessible from other tasks
|
||||
* it still might be armed and queued in the underlying timer
|
||||
* mechanism. Worse, that timer mechanism might run the expiry
|
||||
* function concurrently.
|
||||
*/
|
||||
if (timer_delete_hook(timer) == TIMER_RETRY) {
|
||||
spin_unlock_irq(&timer->it_lock);
|
||||
/*
|
||||
* Timer is expired concurrently, prevent livelocks
|
||||
* and pointless spinning on RT.
|
||||
*
|
||||
* timer_wait_running() drops timer::it_lock, which opens
|
||||
* the possibility for another task to delete the timer.
|
||||
*
|
||||
* That's not possible here because this is invoked from
|
||||
* do_exit() only for the last thread of the thread group.
|
||||
* So no other task can access and delete that timer.
|
||||
*/
|
||||
if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer))
|
||||
return;
|
||||
|
||||
goto retry_delete;
|
||||
}
|
||||
list_del(&timer->list);
|
||||
|
||||
spin_unlock_irq(&timer->it_lock);
|
||||
spin_unlock_irqrestore(&timer->it_lock, flags);
|
||||
release_posix_timer(timer, IT_ID_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by do_exit or de_thread, only when nobody else can
|
||||
* modify the signal->posix_timers list. Yet we need sighand->siglock
|
||||
* to prevent the race with /proc/pid/timers.
|
||||
* Invoked from do_exit() when the last thread of a thread group exits.
|
||||
* At that point no other task can access the timers of the dying
|
||||
* task anymore.
|
||||
*/
|
||||
void exit_itimers(struct task_struct *tsk)
|
||||
{
|
||||
@@ -1067,10 +1092,12 @@ void exit_itimers(struct task_struct *tsk)
|
||||
if (list_empty(&tsk->signal->posix_timers))
|
||||
return;
|
||||
|
||||
/* Protect against concurrent read via /proc/$PID/timers */
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
list_replace_init(&tsk->signal->posix_timers, &timers);
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
|
||||
/* The timers are not longer accessible via tsk::signal */
|
||||
while (!list_empty(&timers)) {
|
||||
tmr = list_first_entry(&timers, struct k_itimer, list);
|
||||
itimer_delete(tmr);
|
||||
|
||||
@@ -581,6 +581,58 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
|
||||
return __nft_trans_set_add(ctx, msg_type, set, NULL);
|
||||
}
|
||||
|
||||
static void nft_setelem_data_deactivate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem);
|
||||
|
||||
static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
nft_setelem_data_deactivate(ctx->net, set, elem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nft_set_elem_catchall {
|
||||
struct list_head list;
|
||||
struct rcu_head rcu;
|
||||
void *elem;
|
||||
};
|
||||
|
||||
static void nft_map_catchall_deactivate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set)
|
||||
{
|
||||
u8 genmask = nft_genmask_next(ctx->net);
|
||||
struct nft_set_elem_catchall *catchall;
|
||||
struct nft_set_elem elem;
|
||||
struct nft_set_ext *ext;
|
||||
|
||||
list_for_each_entry(catchall, &set->catchall_list, list) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_set_elem_active(ext, genmask))
|
||||
continue;
|
||||
|
||||
elem.priv = catchall->elem;
|
||||
nft_setelem_data_deactivate(ctx->net, set, &elem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
struct nft_set_iter iter = {
|
||||
.genmask = nft_genmask_next(ctx->net),
|
||||
.fn = nft_mapelem_deactivate,
|
||||
};
|
||||
|
||||
set->ops->walk(ctx, set, &iter);
|
||||
WARN_ON_ONCE(iter.err);
|
||||
|
||||
nft_map_catchall_deactivate(ctx, set);
|
||||
}
|
||||
|
||||
static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
int err;
|
||||
@@ -589,6 +641,9 @@ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
ctx->table->use--;
|
||||
|
||||
@@ -3407,12 +3462,6 @@ int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nft_set_elem_catchall {
|
||||
struct list_head list;
|
||||
struct rcu_head rcu;
|
||||
void *elem;
|
||||
};
|
||||
|
||||
int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
u8 genmask = nft_genmask_next(ctx->net);
|
||||
@@ -4734,7 +4783,7 @@ err_set_expr_alloc:
|
||||
for (i = 0; i < set->num_exprs; i++)
|
||||
nft_expr_destroy(&ctx, set->exprs[i]);
|
||||
err_set_destroy:
|
||||
ops->destroy(set);
|
||||
ops->destroy(&ctx, set);
|
||||
err_set_init:
|
||||
kfree(set->name);
|
||||
err_set_name:
|
||||
@@ -4749,7 +4798,7 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
|
||||
|
||||
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
|
||||
list_del_rcu(&catchall->list);
|
||||
nft_set_elem_destroy(set, catchall->elem, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, catchall->elem);
|
||||
kfree_rcu(catchall, rcu);
|
||||
}
|
||||
}
|
||||
@@ -4764,7 +4813,7 @@ static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
for (i = 0; i < set->num_exprs; i++)
|
||||
nft_expr_destroy(ctx, set->exprs[i]);
|
||||
|
||||
set->ops->destroy(set);
|
||||
set->ops->destroy(ctx, set);
|
||||
nft_set_catchall_destroy(ctx, set);
|
||||
kfree(set->name);
|
||||
kvfree(set);
|
||||
@@ -4925,10 +4974,60 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
}
|
||||
}
|
||||
|
||||
static void nft_setelem_data_activate(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
struct nft_set_elem *elem);
|
||||
|
||||
static int nft_mapelem_activate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
struct nft_set_elem *elem)
|
||||
{
|
||||
nft_setelem_data_activate(ctx->net, set, elem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_map_catchall_activate(const struct nft_ctx *ctx,
|
||||
struct nft_set *set)
|
||||
{
|
||||
u8 genmask = nft_genmask_next(ctx->net);
|
||||
struct nft_set_elem_catchall *catchall;
|
||||
struct nft_set_elem elem;
|
||||
struct nft_set_ext *ext;
|
||||
|
||||
list_for_each_entry(catchall, &set->catchall_list, list) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_set_elem_active(ext, genmask))
|
||||
continue;
|
||||
|
||||
elem.priv = catchall->elem;
|
||||
nft_setelem_data_activate(ctx->net, set, &elem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
struct nft_set_iter iter = {
|
||||
.genmask = nft_genmask_next(ctx->net),
|
||||
.fn = nft_mapelem_activate,
|
||||
};
|
||||
|
||||
set->ops->walk(ctx, set, &iter);
|
||||
WARN_ON_ONCE(iter.err);
|
||||
|
||||
nft_map_catchall_activate(ctx, set);
|
||||
}
|
||||
|
||||
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
{
|
||||
if (nft_set_is_anonymous(set))
|
||||
if (nft_set_is_anonymous(set)) {
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_activate(ctx, set);
|
||||
|
||||
nft_clear(ctx->net, set);
|
||||
}
|
||||
|
||||
set->use++;
|
||||
}
|
||||
@@ -4947,13 +5046,20 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
set->use--;
|
||||
break;
|
||||
case NFT_TRANS_PREPARE:
|
||||
if (nft_set_is_anonymous(set))
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
if (nft_set_is_anonymous(set)) {
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
}
|
||||
set->use--;
|
||||
return;
|
||||
case NFT_TRANS_ABORT:
|
||||
case NFT_TRANS_RELEASE:
|
||||
if (nft_set_is_anonymous(set) &&
|
||||
set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(ctx, set);
|
||||
|
||||
set->use--;
|
||||
fallthrough;
|
||||
default:
|
||||
@@ -5669,6 +5775,7 @@ static void nft_set_elem_expr_destroy(const struct nft_ctx *ctx,
|
||||
__nft_set_elem_expr_destroy(ctx, expr);
|
||||
}
|
||||
|
||||
/* Drop references and destroy. Called from gc, dynset and abort path. */
|
||||
void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
||||
bool destroy_expr)
|
||||
{
|
||||
@@ -5690,11 +5797,11 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
|
||||
|
||||
/* Only called from commit path, nft_setelem_data_deactivate() already deals
|
||||
* with the refcounting from the preparation phase.
|
||||
/* Destroy element. References have been already dropped in the preparation
|
||||
* path via nft_setelem_data_deactivate().
|
||||
*/
|
||||
static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set, void *elem)
|
||||
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set, void *elem)
|
||||
{
|
||||
struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
|
||||
|
||||
@@ -9323,6 +9430,9 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
case NFT_MSG_DELSET:
|
||||
trans->ctx.table->use++;
|
||||
nft_clear(trans->ctx.net, nft_trans_set(trans));
|
||||
if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_activate(&trans->ctx, nft_trans_set(trans));
|
||||
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_NEWSETELEM:
|
||||
@@ -10089,6 +10199,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
|
||||
list_for_each_entry_safe(set, ns, &table->sets, list) {
|
||||
list_del(&set->list);
|
||||
table->use--;
|
||||
if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
|
||||
nft_map_deactivate(&ctx, set);
|
||||
|
||||
nft_set_destroy(&ctx, set);
|
||||
}
|
||||
list_for_each_entry_safe(obj, ne, &table->objects, list) {
|
||||
|
||||
@@ -271,13 +271,14 @@ static int nft_bitmap_init(const struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_bitmap_destroy(const struct nft_set *set)
|
||||
static void nft_bitmap_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_bitmap *priv = nft_set_priv(set);
|
||||
struct nft_bitmap_elem *be, *n;
|
||||
|
||||
list_for_each_entry_safe(be, n, &priv->list, head)
|
||||
nft_set_elem_destroy(set, be, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, be);
|
||||
}
|
||||
|
||||
static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
|
||||
|
||||
@@ -400,19 +400,31 @@ static int nft_rhash_init(const struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nft_rhash_ctx {
|
||||
const struct nft_ctx ctx;
|
||||
const struct nft_set *set;
|
||||
};
|
||||
|
||||
static void nft_rhash_elem_destroy(void *ptr, void *arg)
|
||||
{
|
||||
nft_set_elem_destroy(arg, ptr, true);
|
||||
struct nft_rhash_ctx *rhash_ctx = arg;
|
||||
|
||||
nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, ptr);
|
||||
}
|
||||
|
||||
static void nft_rhash_destroy(const struct nft_set *set)
|
||||
static void nft_rhash_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_rhash *priv = nft_set_priv(set);
|
||||
struct nft_rhash_ctx rhash_ctx = {
|
||||
.ctx = *ctx,
|
||||
.set = set,
|
||||
};
|
||||
|
||||
cancel_delayed_work_sync(&priv->gc_work);
|
||||
rcu_barrier();
|
||||
rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
|
||||
(void *)set);
|
||||
(void *)&rhash_ctx);
|
||||
}
|
||||
|
||||
/* Number of buckets is stored in u32, so cap our result to 1U<<31 */
|
||||
@@ -643,7 +655,8 @@ static int nft_hash_init(const struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_hash_destroy(const struct nft_set *set)
|
||||
static void nft_hash_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_hash *priv = nft_set_priv(set);
|
||||
struct nft_hash_elem *he;
|
||||
@@ -653,7 +666,7 @@ static void nft_hash_destroy(const struct nft_set *set)
|
||||
for (i = 0; i < priv->buckets; i++) {
|
||||
hlist_for_each_entry_safe(he, next, &priv->table[i], node) {
|
||||
hlist_del_rcu(&he->node);
|
||||
nft_set_elem_destroy(set, he, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, he);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2152,10 +2152,12 @@ out_scratch:
|
||||
|
||||
/**
|
||||
* nft_set_pipapo_match_destroy() - Destroy elements from key mapping array
|
||||
* @ctx: context
|
||||
* @set: nftables API set representation
|
||||
* @m: matching data pointing to key mapping array
|
||||
*/
|
||||
static void nft_set_pipapo_match_destroy(const struct nft_set *set,
|
||||
static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set,
|
||||
struct nft_pipapo_match *m)
|
||||
{
|
||||
struct nft_pipapo_field *f;
|
||||
@@ -2172,15 +2174,17 @@ static void nft_set_pipapo_match_destroy(const struct nft_set *set,
|
||||
|
||||
e = f->mt[r].e;
|
||||
|
||||
nft_set_elem_destroy(set, e, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nft_pipapo_destroy() - Free private data for set and all committed elements
|
||||
* @ctx: context
|
||||
* @set: nftables API set representation
|
||||
*/
|
||||
static void nft_pipapo_destroy(const struct nft_set *set)
|
||||
static void nft_pipapo_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_pipapo *priv = nft_set_priv(set);
|
||||
struct nft_pipapo_match *m;
|
||||
@@ -2190,7 +2194,7 @@ static void nft_pipapo_destroy(const struct nft_set *set)
|
||||
if (m) {
|
||||
rcu_barrier();
|
||||
|
||||
nft_set_pipapo_match_destroy(set, m);
|
||||
nft_set_pipapo_match_destroy(ctx, set, m);
|
||||
|
||||
#ifdef NFT_PIPAPO_ALIGN
|
||||
free_percpu(m->scratch_aligned);
|
||||
@@ -2207,7 +2211,7 @@ static void nft_pipapo_destroy(const struct nft_set *set)
|
||||
m = priv->clone;
|
||||
|
||||
if (priv->dirty)
|
||||
nft_set_pipapo_match_destroy(set, m);
|
||||
nft_set_pipapo_match_destroy(ctx, set, m);
|
||||
|
||||
#ifdef NFT_PIPAPO_ALIGN
|
||||
free_percpu(priv->clone->scratch_aligned);
|
||||
|
||||
@@ -664,7 +664,8 @@ static int nft_rbtree_init(const struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nft_rbtree_destroy(const struct nft_set *set)
|
||||
static void nft_rbtree_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_set *set)
|
||||
{
|
||||
struct nft_rbtree *priv = nft_set_priv(set);
|
||||
struct nft_rbtree_elem *rbe;
|
||||
@@ -675,7 +676,7 @@ static void nft_rbtree_destroy(const struct nft_set *set)
|
||||
while ((node = priv->root.rb_node) != NULL) {
|
||||
rb_erase(node, &priv->root);
|
||||
rbe = rb_entry(node, struct nft_rbtree_elem, node);
|
||||
nft_set_elem_destroy(set, rbe, true);
|
||||
nf_tables_set_elem_destroy(ctx, set, rbe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -791,6 +791,12 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
|
||||
struct svc_rdma_recv_ctxt *ctxt;
|
||||
int ret;
|
||||
|
||||
/* Prevent svc_xprt_release() from releasing pages in rq_pages
|
||||
* when returning 0 or an error.
|
||||
*/
|
||||
rqstp->rq_respages = rqstp->rq_pages;
|
||||
rqstp->rq_next_page = rqstp->rq_respages;
|
||||
|
||||
rqstp->rq_xprt_ctxt = NULL;
|
||||
|
||||
ctxt = NULL;
|
||||
@@ -814,12 +820,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
|
||||
DMA_FROM_DEVICE);
|
||||
svc_rdma_build_arg_xdr(rqstp, ctxt);
|
||||
|
||||
/* Prevent svc_xprt_release from releasing pages in rq_pages
|
||||
* if we return 0 or an error.
|
||||
*/
|
||||
rqstp->rq_respages = rqstp->rq_pages;
|
||||
rqstp->rq_next_page = rqstp->rq_respages;
|
||||
|
||||
ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg, ctxt);
|
||||
if (ret < 0)
|
||||
goto out_err;
|
||||
|
||||
@@ -40,7 +40,7 @@ static const char evm_hmac[] = "hmac(sha1)";
|
||||
/**
|
||||
* evm_set_key() - set EVM HMAC key from the kernel
|
||||
* @key: pointer to a buffer with the key data
|
||||
* @size: length of the key data
|
||||
* @keylen: length of the key data
|
||||
*
|
||||
* This function allows setting the EVM HMAC key from the kernel
|
||||
* without using the "encrypted" key subsystem keys. It can be used
|
||||
|
||||
@@ -324,7 +324,6 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name)
|
||||
/**
|
||||
* evm_read_protected_xattrs - read EVM protected xattr names, lengths, values
|
||||
* @dentry: dentry of the read xattrs
|
||||
* @inode: inode of the read xattrs
|
||||
* @buffer: buffer xattr names, lengths or values are copied to
|
||||
* @buffer_size: size of buffer
|
||||
* @type: n: names, l: lengths, v: values
|
||||
@@ -396,6 +395,7 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
|
||||
* @xattr_name: requested xattr
|
||||
* @xattr_value: requested xattr value
|
||||
* @xattr_value_len: requested xattr value length
|
||||
* @iint: inode integrity metadata
|
||||
*
|
||||
* Calculate the HMAC for the given dentry and verify it against the stored
|
||||
* security.evm xattr. For performance, use the xattr value and length
|
||||
@@ -770,7 +770,9 @@ static int evm_attr_change(struct dentry *dentry, struct iattr *attr)
|
||||
|
||||
/**
|
||||
* evm_inode_setattr - prevent updating an invalid EVM extended attribute
|
||||
* @idmap: idmap of the mount
|
||||
* @dentry: pointer to the affected dentry
|
||||
* @attr: iattr structure containing the new file attributes
|
||||
*
|
||||
* Permit update of file attributes when files have a valid EVM signature,
|
||||
* except in the case of them having an immutable portable signature.
|
||||
|
||||
@@ -89,6 +89,9 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
|
||||
|
||||
/**
|
||||
* ima_collect_modsig - Calculate the file hash without the appended signature.
|
||||
* @modsig: parsed module signature
|
||||
* @buf: data to verify the signature on
|
||||
* @size: data size
|
||||
*
|
||||
* Since the modsig is part of the file contents, the hash used in its signature
|
||||
* isn't the same one ordinarily calculated by IMA. Therefore PKCS7 code
|
||||
|
||||
@@ -674,6 +674,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
|
||||
* @secid: LSM secid of the task to be validated
|
||||
* @func: IMA hook identifier
|
||||
* @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
|
||||
* @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE)
|
||||
* @pcr: set the pcr to extend
|
||||
* @template_desc: the template that should be used for this rule
|
||||
* @func_data: func specific data, may be NULL
|
||||
@@ -1709,7 +1710,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
|
||||
/**
|
||||
* ima_parse_add_rule - add a rule to ima_policy_rules
|
||||
* @rule - ima measurement policy rule
|
||||
* @rule: ima measurement policy rule
|
||||
*
|
||||
* Avoid locking by allowing just one writer at a time in ima_write_policy()
|
||||
* Returns the length of the rule parsed, an error code on failure
|
||||
|
||||
@@ -5,4 +5,4 @@ rcutree.gp_init_delay=3
|
||||
rcutree.gp_cleanup_delay=3
|
||||
rcutree.kthread_prio=2
|
||||
threadirqs
|
||||
tree.use_softirq=0
|
||||
rcutree.use_softirq=0
|
||||
|
||||
@@ -4,4 +4,4 @@ rcutree.gp_init_delay=3
|
||||
rcutree.gp_cleanup_delay=3
|
||||
rcutree.kthread_prio=2
|
||||
threadirqs
|
||||
tree.use_softirq=0
|
||||
rcutree.use_softirq=0
|
||||
|
||||
@@ -84,12 +84,12 @@ static inline int vdso_test_clock(unsigned int clock_id)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
#if _POSIX_TIMERS > 0
|
||||
|
||||
#ifdef CLOCK_REALTIME
|
||||
ret = vdso_test_clock(CLOCK_REALTIME);
|
||||
ret += vdso_test_clock(CLOCK_REALTIME);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
|
||||
Reference in New Issue
Block a user