aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/mm/mmu.c23
-rw-r--r--arch/arm64/Kconfig21
-rw-r--r--arch/arm64/include/asm/debug-monitors.h7
-rw-r--r--arch/mips/include/uapi/asm/unistd.h6
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c132
-rw-r--r--drivers/cpufreq/cpufreq_stats.c224
-rw-r--r--drivers/misc/uid_cputime.c14
-rw-r--r--drivers/mmc/core/core.c23
-rw-r--r--drivers/mmc/core/host.c3
-rw-r--r--drivers/usb/gadget/f_accessory.c3
-rw-r--r--drivers/usb/gadget/u_ether.c22
-rw-r--r--fs/ext4/super.c2
-rw-r--r--include/linux/cpufreq.h8
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/net/bluetooth/hci.h3
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--include/net/netfilter/ipv4/nf_reject.h8
-rw-r--r--include/net/netfilter/ipv6/nf_reject.h9
-rw-r--r--include/uapi/asm-generic/unistd.h5
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/irq/pm.c1
-rw-r--r--kernel/power/suspend.c3
-rw-r--r--kernel/power/wakelock.c7
-rw-r--r--kernel/sched/cputime.c11
-rw-r--r--kernel/sys.c20
-rw-r--r--net/bluetooth/hci_conn.c18
-rw-r--r--net/bluetooth/hci_event.c1
-rw-r--r--net/bluetooth/rfcomm/core.c1
-rw-r--r--net/caif/caif_socket.c8
-rw-r--r--net/ipv4/netfilter/Kconfig12
-rw-r--r--net/ipv6/netfilter/Kconfig12
-rw-r--r--net/unix/af_unix.c8
-rw-r--r--net/wireless/Kconfig11
-rw-r--r--net/wireless/sme.c7
-rw-r--r--security/selinux/hooks.c45
-rw-r--r--security/selinux/include/security.h1
38 files changed, 345 insertions, 347 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0c2b55e9242a..924ea5bec5bf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -28,7 +28,7 @@ config ARM
select HARDIRQS_SW_RESEND
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
- select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_TRACEHOOK
select HAVE_BPF_JIT
select HAVE_CONTEXT_TRACKING
@@ -1763,6 +1763,11 @@ config OABI_COMPAT
in memory differs between the legacy ABI and the new ARM EABI
(only for non "thumb" binaries). This option adds a tiny
overhead to all syscalls and produces a slightly larger kernel.
+
+ The seccomp filter system will not be available when this is
+ selected, since there is no way yet to sensibly distinguish
+ between calling conventions during filtering.
+
If you know you'll be using only pure EABI user space then you
can say N here. If this option is not selected and you attempt
to execute a legacy ABI binary then the result will be
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4bd2f2c38f56..f15c22e8bcd5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1069,29 +1069,6 @@ void __init sanity_check_meminfo(void)
phys_addr_t size_limit;
*bank = meminfo.bank[i];
-
-#ifdef CONFIG_SPARSEMEM
- if (pfn_to_section_nr(bank_pfn_start(bank)) !=
- pfn_to_section_nr(bank_pfn_end(bank) - 1)) {
- phys_addr_t sz;
- unsigned long start_pfn = bank_pfn_start(bank);
- unsigned long end_pfn = SECTION_ALIGN_UP(start_pfn + 1);
- sz = ((phys_addr_t)(end_pfn - start_pfn) << PAGE_SHIFT);
-
- if (meminfo.nr_banks >= NR_BANKS) {
- pr_crit("NR_BANKS too low, ignoring %lld bytes of memory\n",
- (unsigned long long)(bank->size - sz));
- } else {
- memmove(bank + 1, bank,
- (meminfo.nr_banks - i) * sizeof(*bank));
- meminfo.nr_banks++;
- bank[1].size -= sz;
- bank[1].start = __pfn_to_phys(end_pfn);
- }
- bank->size = sz;
- }
-#endif
-
size_limit = bank->size;
if (bank->start >= vmalloc_limit)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c10c8b3e3959..0c9e4d1086f7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -371,27 +371,6 @@ config ARCH_WANT_HUGE_PMD_SHARE
config HAVE_ARCH_TRANSPARENT_HUGEPAGE
def_bool y
-config ARMV7_COMPAT
- bool "Kernel support for ARMv7 applications"
- depends on COMPAT
- select SWP_EMULATE
- help
- This option enables features that allow that ran on an ARMv7 or older
- processor to continue functioning.
-
- If you want to execute ARMv7 applications, say Y
-
-config ARMV7_COMPAT_CPUINFO
- bool "Report backwards compatible cpu features in /proc/cpuinfo"
- depends on ARMV7_COMPAT
- default y
- help
- This option makes /proc/cpuinfo list CPU features that an ARMv7 or
- earlier kernel would report, but are not optional on an ARMv8 or later
- processor.
-
- If you want to execute ARMv7 applications, say Y
-
source "mm/Kconfig"
config XEN_DOM0
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index aab72ce22348..7fb343779498 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -143,14 +143,7 @@ static inline int reinstall_suspended_bps(struct pt_regs *regs)
}
#endif
-#ifdef CONFIG_COMPAT
int aarch32_break_handler(struct pt_regs *regs);
-#else
-static int aarch32_break_handler(struct pt_regs *regs)
-{
- return -EFAULT;
-}
-#endif
#endif /* __ASSEMBLY */
#endif /* __KERNEL__ */
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h
index 19244e913837..d6e154a9e6a5 100644
--- a/arch/mips/include/uapi/asm/unistd.h
+++ b/arch/mips/include/uapi/asm/unistd.h
@@ -1029,15 +1029,17 @@
#define __NR_process_vm_writev (__NR_Linux + 310)
#define __NR_kcmp (__NR_Linux + 311)
#define __NR_finit_module (__NR_Linux + 312)
+#define __NR_sched_setattr (__NR_Linux + 313)
+#define __NR_sched_getattr (__NR_Linux + 314)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 312
+#define __NR_Linux_syscalls 314
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 312
+#define __NR_N32_Linux_syscalls 314
#endif /* _UAPI_ASM_UNISTD_H */
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index b84f709c760e..39e62187cdbc 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -47,9 +47,10 @@ struct cpufreq_interactive_cpuinfo {
spinlock_t target_freq_lock; /*protects target freq */
unsigned int target_freq;
unsigned int floor_freq;
- unsigned int max_freq;
- u64 floor_validate_time;
- u64 hispeed_validate_time;
+ u64 pol_floor_val_time; /* policy floor_validate_time */
+ u64 loc_floor_val_time; /* per-cpu floor_validate_time */
+ u64 pol_hispeed_val_time; /* policy hispeed_validate_time */
+ u64 loc_hispeed_val_time; /* per-cpu hispeed_validate_time */
struct rw_semaphore enable_sem;
int governor_enabled;
};
@@ -345,6 +346,7 @@ static void cpufreq_interactive_timer(unsigned long data)
unsigned int loadadjfreq;
unsigned int index;
unsigned long flags;
+ u64 max_fvtime;
if (!down_read_trylock(&pcpu->enable_sem))
return;
@@ -367,7 +369,7 @@ static void cpufreq_interactive_timer(unsigned long data)
tunables->boosted = tunables->boost_val || now < tunables->boostpulse_endtime;
if (cpu_load >= tunables->go_hispeed_load || tunables->boosted) {
- if (pcpu->target_freq < tunables->hispeed_freq) {
+ if (pcpu->policy->cur < tunables->hispeed_freq) {
new_freq = tunables->hispeed_freq;
} else {
new_freq = choose_freq(pcpu, loadadjfreq);
@@ -378,14 +380,14 @@ static void cpufreq_interactive_timer(unsigned long data)
} else {
new_freq = choose_freq(pcpu, loadadjfreq);
if (new_freq > tunables->hispeed_freq &&
- pcpu->target_freq < tunables->hispeed_freq)
+ pcpu->policy->cur < tunables->hispeed_freq)
new_freq = tunables->hispeed_freq;
}
- if (pcpu->target_freq >= tunables->hispeed_freq &&
- new_freq > pcpu->target_freq &&
- now - pcpu->hispeed_validate_time <
- freq_to_above_hispeed_delay(tunables, pcpu->target_freq)) {
+ if (pcpu->policy->cur >= tunables->hispeed_freq &&
+ new_freq > pcpu->policy->cur &&
+ now - pcpu->pol_hispeed_val_time <
+ freq_to_above_hispeed_delay(tunables, pcpu->policy->cur)) {
trace_cpufreq_interactive_notyet(
data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
@@ -393,7 +395,7 @@ static void cpufreq_interactive_timer(unsigned long data)
goto rearm;
}
- pcpu->hispeed_validate_time = now;
+ pcpu->loc_hispeed_val_time = now;
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
new_freq, CPUFREQ_RELATION_L,
@@ -408,9 +410,10 @@ static void cpufreq_interactive_timer(unsigned long data)
* Do not scale below floor_freq unless we have been at or above the
* floor frequency for the minimum sample time since last validated.
*/
- if (new_freq < pcpu->floor_freq) {
- if (now - pcpu->floor_validate_time <
- tunables->min_sample_time) {
+ max_fvtime = max(pcpu->pol_floor_val_time, pcpu->loc_floor_val_time);
+ if (new_freq < pcpu->floor_freq &&
+ pcpu->target_freq >= pcpu->policy->cur) {
+ if (now - max_fvtime < tunables->min_sample_time) {
trace_cpufreq_interactive_notyet(
data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
@@ -429,7 +432,9 @@ static void cpufreq_interactive_timer(unsigned long data)
if (!tunables->boosted || new_freq > tunables->hispeed_freq) {
pcpu->floor_freq = new_freq;
- pcpu->floor_validate_time = now;
+ if (pcpu->target_freq >= pcpu->policy->cur ||
+ new_freq >= pcpu->policy->cur)
+ pcpu->loc_floor_val_time = now;
}
if (pcpu->target_freq == new_freq &&
@@ -438,7 +443,7 @@ static void cpufreq_interactive_timer(unsigned long data)
data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
- goto rearm_if_notmax;
+ goto rearm;
}
trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
@@ -451,14 +456,6 @@ static void cpufreq_interactive_timer(unsigned long data)
spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
wake_up_process(speedchange_task);
-rearm_if_notmax:
- /*
- * Already set max speed and don't see a need to change that,
- * wait until next idle to re-evaluate, don't need timer.
- */
- if (pcpu->target_freq == pcpu->policy->max)
- goto exit;
-
rearm:
if (!timer_pending(&pcpu->cpu_timer))
cpufreq_interactive_timer_resched(pcpu);
@@ -468,37 +465,6 @@ exit:
return;
}
-static void cpufreq_interactive_idle_start(void)
-{
- struct cpufreq_interactive_cpuinfo *pcpu =
- &per_cpu(cpuinfo, smp_processor_id());
- int pending;
-
- if (!down_read_trylock(&pcpu->enable_sem))
- return;
- if (!pcpu->governor_enabled) {
- up_read(&pcpu->enable_sem);
- return;
- }
-
- pending = timer_pending(&pcpu->cpu_timer);
-
- if (pcpu->target_freq != pcpu->policy->min) {
- /*
- * Entering idle while not at lowest speed. On some
- * platforms this can hold the other CPU(s) at that speed
- * even though the CPU is idle. Set a timer to re-evaluate
- * speed so this idle CPU doesn't hold the other CPUs above
- * min indefinitely. This should probably be a quirk of
- * the CPUFreq driver.
- */
- if (!pending)
- cpufreq_interactive_timer_resched(pcpu);
- }
-
- up_read(&pcpu->enable_sem);
-}
-
static void cpufreq_interactive_idle_end(void)
{
struct cpufreq_interactive_cpuinfo *pcpu =
@@ -553,6 +519,8 @@ static int cpufreq_interactive_speedchange_task(void *data)
for_each_cpu(cpu, &tmp_mask) {
unsigned int j;
unsigned int max_freq = 0;
+ struct cpufreq_interactive_cpuinfo *pjcpu;
+ u64 hvt = ~0ULL, fvt = 0;
pcpu = &per_cpu(cpuinfo, cpu);
if (!down_read_trylock(&pcpu->enable_sem))
@@ -563,17 +531,30 @@ static int cpufreq_interactive_speedchange_task(void *data)
}
for_each_cpu(j, pcpu->policy->cpus) {
- struct cpufreq_interactive_cpuinfo *pjcpu =
- &per_cpu(cpuinfo, j);
+ pjcpu = &per_cpu(cpuinfo, j);
- if (pjcpu->target_freq > max_freq)
+ fvt = max(fvt, pjcpu->loc_floor_val_time);
+ if (pjcpu->target_freq > max_freq) {
max_freq = pjcpu->target_freq;
+ hvt = pjcpu->loc_hispeed_val_time;
+ } else if (pjcpu->target_freq == max_freq) {
+ hvt = min(hvt, pjcpu->loc_hispeed_val_time);
+ }
+ }
+ for_each_cpu(j, pcpu->policy->cpus) {
+ pjcpu = &per_cpu(cpuinfo, j);
+ pjcpu->pol_floor_val_time = fvt;
}
- if (max_freq != pcpu->policy->cur)
+ if (max_freq != pcpu->policy->cur) {
__cpufreq_driver_target(pcpu->policy,
max_freq,
CPUFREQ_RELATION_H);
+ for_each_cpu(j, pcpu->policy->cpus) {
+ pjcpu = &per_cpu(cpuinfo, j);
+ pjcpu->pol_hispeed_val_time = hvt;
+ }
+ }
trace_cpufreq_interactive_setspeed(cpu,
pcpu->target_freq,
pcpu->policy->cur);
@@ -605,7 +586,7 @@ static void cpufreq_interactive_boost(struct cpufreq_interactive_tunables *tunab
if (pcpu->target_freq < tunables->hispeed_freq) {
pcpu->target_freq = tunables->hispeed_freq;
cpumask_set_cpu(i, &speedchange_cpumask);
- pcpu->hispeed_validate_time =
+ pcpu->pol_hispeed_val_time =
ktime_to_us(ktime_get());
anyboost = 1;
}
@@ -1108,14 +1089,8 @@ static int cpufreq_interactive_idle_notifier(struct notifier_block *nb,
unsigned long val,
void *data)
{
- switch (val) {
- case IDLE_START:
- cpufreq_interactive_idle_start();
- break;
- case IDLE_END:
+ if (val == IDLE_END)
cpufreq_interactive_idle_end();
- break;
- }
return 0;
}
@@ -1232,11 +1207,11 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->target_freq = policy->cur;
pcpu->freq_table = freq_table;
pcpu->floor_freq = pcpu->target_freq;
- pcpu->floor_validate_time =
+ pcpu->pol_floor_val_time =
ktime_to_us(ktime_get());
- pcpu->hispeed_validate_time =
- pcpu->floor_validate_time;
- pcpu->max_freq = policy->max;
+ pcpu->loc_floor_val_time = pcpu->pol_floor_val_time;
+ pcpu->pol_hispeed_val_time = pcpu->pol_floor_val_time;
+ pcpu->loc_hispeed_val_time = pcpu->pol_floor_val_time;
down_write(&pcpu->enable_sem);
del_timer_sync(&pcpu->cpu_timer);
del_timer_sync(&pcpu->cpu_slack_timer);
@@ -1286,23 +1261,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
up_read(&pcpu->enable_sem);
-
- /* Reschedule timer only if policy->max is raised.
- * Delete the timers, else the timer callback may
- * return without re-arm the timer when failed
- * acquire the semaphore. This race may cause timer
- * stopped unexpectedly.
- */
-
- if (policy->max > pcpu->max_freq) {
- down_write(&pcpu->enable_sem);
- del_timer_sync(&pcpu->cpu_timer);
- del_timer_sync(&pcpu->cpu_slack_timer);
- cpufreq_interactive_timer_start(tunables, j);
- up_write(&pcpu->enable_sem);
- }
-
- pcpu->max_freq = policy->max;
}
break;
}
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 1337d99f0c83..3811168bf28d 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -14,7 +14,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sort.h>
-#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/sched.h>
#include <asm/cputime.h>
static spinlock_t cpufreq_stats_lock;
@@ -39,6 +40,12 @@ struct all_cpufreq_stats {
unsigned int *freq_table;
};
+struct cpufreq_power_stats {
+ unsigned int state_num;
+ unsigned int *curr;
+ unsigned int *freq_table;
+};
+
struct all_freq_table {
unsigned int *freq_table;
unsigned int table_size;
@@ -48,6 +55,7 @@ static struct all_freq_table *all_freq_table;
static DEFINE_PER_CPU(struct all_cpufreq_stats *, all_cpufreq_stats);
static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table);
+static DEFINE_PER_CPU(struct cpufreq_power_stats *, cpufreq_power_stats);
struct cpufreq_stats_attribute {
struct attribute attr;
@@ -118,6 +126,47 @@ static int get_index_all_cpufreq_stat(struct all_cpufreq_stats *all_stat,
return -1;
}
+void acct_update_power(struct task_struct *task, cputime_t cputime) {
+ struct cpufreq_power_stats *powerstats;
+ struct cpufreq_stats *stats;
+ unsigned int cpu_num, curr;
+
+ if (!task)
+ return;
+ cpu_num = task_cpu(task);
+ powerstats = per_cpu(cpufreq_power_stats, cpu_num);
+ stats = per_cpu(cpufreq_stats_table, cpu_num);
+ if (!powerstats || !stats)
+ return;
+
+ curr = powerstats->curr[stats->last_index];
+ task->cpu_power += curr * cputime_to_usecs(cputime);
+}
+EXPORT_SYMBOL_GPL(acct_update_power);
+
+static ssize_t show_current_in_state(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ unsigned int i, cpu;
+ struct cpufreq_power_stats *powerstats;
+
+ spin_lock(&cpufreq_stats_lock);
+ for_each_possible_cpu(cpu) {
+ powerstats = per_cpu(cpufreq_power_stats, cpu);
+ if (!powerstats)
+ continue;
+ len += scnprintf(buf + len, PAGE_SIZE - len, "CPU%d:", cpu);
+ for (i = 0; i < powerstats->state_num; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d=%d ", powerstats->freq_table[i],
+ powerstats->curr[i]);
+ len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
+ }
+ spin_unlock(&cpufreq_stats_lock);
+ return len;
+}
+
static ssize_t show_all_time_in_state(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -227,6 +276,9 @@ static struct attribute_group stats_attr_group = {
static struct kobj_attribute _attr_all_time_in_state = __ATTR(all_time_in_state,
0444, show_all_time_in_state, NULL);
+static struct kobj_attribute _attr_current_in_state = __ATTR(current_in_state,
+ 0444, show_current_in_state, NULL);
+
static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
{
int index;
@@ -288,10 +340,27 @@ static void cpufreq_allstats_free(void)
}
}
+static void cpufreq_powerstats_free(void)
+{
+ int cpu;
+ struct cpufreq_power_stats *powerstats;
+
+ sysfs_remove_file(cpufreq_global_kobject, &_attr_current_in_state.attr);
+
+ for_each_possible_cpu(cpu) {
+ powerstats = per_cpu(cpufreq_power_stats, cpu);
+ if (!powerstats)
+ continue;
+ kfree(powerstats->curr);
+ kfree(powerstats);
+ per_cpu(cpufreq_power_stats, cpu) = NULL;
+ }
+}
+
static int __cpufreq_stats_create_table(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table)
+ struct cpufreq_frequency_table *table, int count)
{
- unsigned int i, j, count = 0, ret = 0;
+ unsigned int i, j, ret = 0;
struct cpufreq_stats *stat;
struct cpufreq_policy *current_policy;
unsigned int alloc_size;
@@ -315,12 +384,6 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy,
stat->cpu = cpu;
per_cpu(cpufreq_stats_table, cpu) = stat;
- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- count++;
- }
alloc_size = count * sizeof(int) + count * sizeof(u64);
@@ -361,26 +424,6 @@ error_get_fail:
return ret;
}
-static void cpufreq_stats_create_table(unsigned int cpu)
-{
- struct cpufreq_policy *policy;
- struct cpufreq_frequency_table *table;
-
- /*
- * "likely(!policy)" because normally cpufreq_stats will be registered
- * before cpufreq driver
- */
- policy = cpufreq_cpu_get(cpu);
- if (likely(!policy))
- return;
-
- table = cpufreq_frequency_get_table(policy->cpu);
- if (likely(table))
- __cpufreq_stats_create_table(policy, table);
-
- cpufreq_cpu_put(policy);
-}
-
static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy)
{
struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table,
@@ -394,6 +437,54 @@ static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy)
stat->cpu = policy->cpu;
}
+static void cpufreq_powerstats_create(unsigned int cpu,
+ struct cpufreq_frequency_table *table, int count) {
+ unsigned int alloc_size, i = 0, j = 0, ret = 0;
+ struct cpufreq_power_stats *powerstats;
+ struct device_node *cpu_node;
+ char device_path[16];
+
+ powerstats = kzalloc(sizeof(struct cpufreq_power_stats),
+ GFP_KERNEL);
+ if (!powerstats)
+ return;
+
+ /* Allocate memory for freq table per cpu as well as clockticks per
+ * freq*/
+ alloc_size = count * sizeof(unsigned int) +
+ count * sizeof(unsigned int);
+ powerstats->curr = kzalloc(alloc_size, GFP_KERNEL);
+ if (!powerstats->curr) {
+ kfree(powerstats);
+ return;
+ }
+ powerstats->freq_table = powerstats->curr + count;
+
+ spin_lock(&cpufreq_stats_lock);
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END && j < count; i++) {
+ unsigned int freq = table[i].frequency;
+
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ powerstats->freq_table[j++] = freq;
+ }
+ powerstats->state_num = j;
+
+ snprintf(device_path, sizeof(device_path), "/cpus/cpu@%d", cpu);
+ cpu_node = of_find_node_by_path(device_path);
+ if (cpu_node) {
+ ret = of_property_read_u32_array(cpu_node, "current",
+ powerstats->curr, count);
+ if (ret) {
+ kfree(powerstats->curr);
+ kfree(powerstats);
+ powerstats = NULL;
+ }
+ }
+ per_cpu(cpufreq_power_stats, cpu) = powerstats;
+ spin_unlock(&cpufreq_stats_lock);
+}
+
static int compare_for_sort(const void *lhs_ptr, const void *rhs_ptr)
{
unsigned int lhs = *(const unsigned int *)(lhs_ptr);
@@ -438,24 +529,14 @@ static void add_all_freq_table(unsigned int freq)
all_freq_table->freq_table[all_freq_table->table_size++] = freq;
}
-static void cpufreq_allstats_create(unsigned int cpu)
+static void cpufreq_allstats_create(unsigned int cpu,
+ struct cpufreq_frequency_table *table, int count)
{
int i , j = 0;
- unsigned int alloc_size, count = 0;
- struct cpufreq_frequency_table *table = cpufreq_frequency_get_table(cpu);
+ unsigned int alloc_size;
struct all_cpufreq_stats *all_stat;
bool sort_needed = false;
- if (!table)
- return;
-
- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- count++;
- }
-
all_stat = kzalloc(sizeof(struct all_cpufreq_stats),
GFP_KERNEL);
if (!all_stat) {
@@ -494,10 +575,44 @@ static void cpufreq_allstats_create(unsigned int cpu)
spin_unlock(&cpufreq_stats_lock);
}
+static void cpufreq_stats_create_table(unsigned int cpu)
+{
+ struct cpufreq_policy *policy;
+ struct cpufreq_frequency_table *table;
+ int i, count = 0;
+ /*
+ * "likely(!policy)" because normally cpufreq_stats will be registered
+ * before cpufreq driver
+ */
+ policy = cpufreq_cpu_get(cpu);
+ if (likely(!policy))
+ return;
+
+ table = cpufreq_frequency_get_table(policy->cpu);
+ if (likely(table)) {
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ unsigned int freq = table[i].frequency;
+
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ count++;
+ }
+
+ if (!per_cpu(all_cpufreq_stats, cpu))
+ cpufreq_allstats_create(cpu, table, count);
+
+ if (!per_cpu(cpufreq_power_stats, cpu))
+ cpufreq_powerstats_create(cpu, table, count);
+
+ __cpufreq_stats_create_table(policy, table, count);
+ }
+ cpufreq_cpu_put(policy);
+}
+
static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
unsigned long val, void *data)
{
- int ret = 0;
+ int ret = 0, count = 0, i;
struct cpufreq_policy *policy = data;
struct cpufreq_frequency_table *table;
unsigned int cpu = policy->cpu;
@@ -511,11 +626,22 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
if (!table)
return 0;
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ unsigned int freq = table[i].frequency;
+
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ count++;
+ }
+
if (!per_cpu(all_cpufreq_stats, cpu))
- cpufreq_allstats_create(cpu);
+ cpufreq_allstats_create(cpu, table, count);
+
+ if (!per_cpu(cpufreq_power_stats, cpu))
+ cpufreq_powerstats_create(cpu, table, count);
if (val == CPUFREQ_CREATE_POLICY)
- ret = __cpufreq_stats_create_table(policy, table);
+ ret = __cpufreq_stats_create_table(policy, table, count);
else if (val == CPUFREQ_REMOVE_POLICY)
__cpufreq_stats_free_table(policy);
@@ -595,7 +721,12 @@ static int __init cpufreq_stats_init(void)
ret = sysfs_create_file(cpufreq_global_kobject,
&_attr_all_time_in_state.attr);
if (ret)
- pr_warn("Error creating sysfs file for cpufreq stats\n");
+ pr_warn("Cannot create sysfs file for cpufreq stats\n");
+
+ ret = sysfs_create_file(cpufreq_global_kobject,
+ &_attr_current_in_state.attr);
+ if (ret)
+ pr_warn("Cannot create sysfs file for cpufreq current stats\n");
return 0;
}
@@ -610,6 +741,7 @@ static void __exit cpufreq_stats_exit(void)
for_each_online_cpu(cpu)
cpufreq_stats_free_table(cpu);
cpufreq_allstats_free();
+ cpufreq_powerstats_free();
cpufreq_put_global_kobject();
}
diff --git a/drivers/misc/uid_cputime.c b/drivers/misc/uid_cputime.c
index acd7046ce497..89bfba6c5b6a 100644
--- a/drivers/misc/uid_cputime.c
+++ b/drivers/misc/uid_cputime.c
@@ -38,6 +38,8 @@ struct uid_entry {
cputime_t stime;
cputime_t active_utime;
cputime_t active_stime;
+ unsigned long long active_power;
+ unsigned long long power;
struct hlist_node hash;
};
@@ -83,6 +85,7 @@ static int uid_stat_show(struct seq_file *m, void *v)
hash_for_each(hash_table, bkt, uid_entry, hash) {
uid_entry->active_stime = 0;
uid_entry->active_utime = 0;
+ uid_entry->active_power = 0;
}
read_lock(&tasklist_lock);
@@ -100,6 +103,7 @@ static int uid_stat_show(struct seq_file *m, void *v)
task_cputime_adjusted(task, &utime, &stime);
uid_entry->active_utime += utime;
uid_entry->active_stime += stime;
+ uid_entry->active_power += task->cpu_power;
}
read_unlock(&tasklist_lock);
@@ -108,9 +112,12 @@ static int uid_stat_show(struct seq_file *m, void *v)
uid_entry->active_utime;
cputime_t total_stime = uid_entry->stime +
uid_entry->active_stime;
- seq_printf(m, "%d: %u %u\n", uid_entry->uid,
+ unsigned long long total_power = uid_entry->power +
+ uid_entry->active_power;
+ seq_printf(m, "%d: %u %u %llu\n", uid_entry->uid,
cputime_to_usecs(total_utime),
- cputime_to_usecs(total_stime));
+ cputime_to_usecs(total_stime),
+ total_power);
}
mutex_unlock(&uid_lock);
@@ -203,6 +210,7 @@ static int process_notifier(struct notifier_block *self,
task_cputime_adjusted(task, &utime, &stime);
uid_entry->utime += utime;
uid_entry->stime += stime;
+ uid_entry->power += task->cpu_power;
exit:
mutex_unlock(&uid_lock);
@@ -226,7 +234,7 @@ static int __init proc_uid_cputime_init(void)
proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops,
NULL);
- proc_create_data("show_uid_stat", S_IWUGO, parent, &uid_stat_fops,
+ proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops,
NULL);
profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 2a1cc36b3ace..11655e90be53 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -63,6 +63,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(mmc_blk_rw_end);
#define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */
static struct workqueue_struct *workqueue;
+static struct wake_lock mmc_delayed_work_wake_lock;
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
/*
@@ -96,6 +97,7 @@ MODULE_PARM_DESC(
static int mmc_schedule_delayed_work(struct delayed_work *work,
unsigned long delay)
{
+ wake_lock(&mmc_delayed_work_wake_lock);
return queue_delayed_work(workqueue, work, delay);
}
@@ -1726,8 +1728,6 @@ static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
pm_wakeup_event(mmc_dev(host), 5000);
host->detect_change = 1;
-
- wake_lock(&host->detect_wake_lock);
mmc_schedule_delayed_work(&host->detect, delay);
}
@@ -2511,13 +2511,11 @@ void mmc_rescan(struct work_struct *work)
out:
if (extend_wakelock)
- wake_lock_timeout(&host->detect_wake_lock, HZ / 2);
+ wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
else
- wake_unlock(&host->detect_wake_lock);
- if (host->caps & MMC_CAP_NEEDS_POLL) {
- wake_lock(&host->detect_wake_lock);
+ wake_unlock(&mmc_delayed_work_wake_lock);
+ if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
- }
}
void mmc_start_host(struct mmc_host *host)
@@ -2541,8 +2539,7 @@ void mmc_stop_host(struct mmc_host *host)
#endif
host->rescan_disable = 1;
- if (cancel_delayed_work_sync(&host->detect))
- wake_unlock(&host->detect_wake_lock);
+ cancel_delayed_work_sync(&host->detect);
mmc_flush_scheduled_work();
/* clear pm flags now and let card drivers set them as needed */
@@ -2699,8 +2696,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 1;
spin_unlock_irqrestore(&host->lock, flags);
- if (cancel_delayed_work_sync(&host->detect))
- wake_unlock(&host->detect_wake_lock);
+ cancel_delayed_work_sync(&host->detect);
if (!host->bus_ops)
break;
@@ -2776,6 +2772,9 @@ static int __init mmc_init(void)
if (!workqueue)
return -ENOMEM;
+ wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND,
+ "mmc_delayed_work");
+
ret = mmc_register_bus();
if (ret)
goto destroy_workqueue;
@@ -2796,6 +2795,7 @@ unregister_bus:
mmc_unregister_bus();
destroy_workqueue:
destroy_workqueue(workqueue);
+ wake_lock_destroy(&mmc_delayed_work_wake_lock);
return ret;
}
@@ -2806,6 +2806,7 @@ static void __exit mmc_exit(void)
mmc_unregister_host_class();
mmc_unregister_bus();
destroy_workqueue(workqueue);
+ wake_lock_destroy(&mmc_delayed_work_wake_lock);
}
subsys_initcall(mmc_init);
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 2c886ae34198..cc3164a939eb 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -481,8 +481,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
spin_lock_init(&host->lock);
init_waitqueue_head(&host->wq);
- wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
- kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
#ifdef CONFIG_PM
host->pm_notify.notifier_call = mmc_pm_notify;
@@ -582,7 +580,6 @@ void mmc_free_host(struct mmc_host *host)
spin_lock(&mmc_host_lock);
idr_remove(&mmc_host_idr, host->index);
spin_unlock(&mmc_host_lock);
- wake_lock_destroy(&host->detect_wake_lock);
put_device(&host->class_dev);
}
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index dcedeb4b2fef..0237f1e059b4 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -1204,8 +1204,7 @@ err:
static void acc_disconnect(void)
{
/* unregister all HID devices if USB is disconnected */
- if (_acc_dev)
- kill_all_hid_devices(_acc_dev);
+ kill_all_hid_devices(_acc_dev);
}
static void acc_cleanup(void)
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index bf6589eb7cb5..28b291a4e0e5 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -875,17 +875,6 @@ static int get_ether_addr(const char *str, u8 *dev_addr)
return 1;
}
-static int get_host_ether_addr(u8 *str, u8 *dev_addr)
-{
- memcpy(dev_addr, str, ETH_ALEN);
- if (is_valid_ether_addr(dev_addr))
- return 0;
-
- random_ether_addr(dev_addr);
- memcpy(str, dev_addr, ETH_ALEN);
- return 1;
-}
-
static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len)
{
if (len < 18)
@@ -897,6 +886,17 @@ static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len)
return 18;
}
+static int get_host_ether_addr(u8 *str, u8 *dev_addr)
+{
+ memcpy(dev_addr, str, ETH_ALEN);
+ if (is_valid_ether_addr(dev_addr))
+ return 0;
+
+ random_ether_addr(dev_addr);
+ memcpy(str, dev_addr, ETH_ALEN);
+ return 1;
+}
+
static const struct net_device_ops eth_netdev_ops = {
.ndo_open = eth_open,
.ndo_stop = eth_stop,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9fb3e6c0c578..e0cb26f74842 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -304,6 +304,8 @@ static void __save_error_info(struct super_block *sb, const char *func,
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+ if (bdev_read_only(sb->s_bdev))
+ return;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
es->s_last_error_time = cpu_to_le32(get_seconds());
strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index b0d360c87602..a15944d5a06f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -17,6 +17,8 @@
#include <linux/kobject.h>
#include <linux/notifier.h>
#include <linux/sysfs.h>
+#include <asm/cputime.h>
+
/*********************************************************************
* CPUFREQ INTERFACE *
@@ -509,4 +511,10 @@ static inline int cpufreq_generic_exit(struct cpufreq_policy *policy)
return 0;
}
+/*********************************************************************
+ * CPUFREQ STATS *
+ *********************************************************************/
+
+void acct_update_power(struct task_struct *p, cputime_t cputime);
+
#endif /* _LINUX_CPUFREQ_H */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 1c923ab2dd73..9b92af47577f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/fault-inject.h>
-#include <linux/wakelock.h>
#include <linux/mmc/core.h>
#include <linux/mmc/pm.h>
@@ -330,7 +329,6 @@ struct mmc_host {
int claim_cnt; /* "claim" nesting count */
struct delayed_work detect;
- struct wake_lock detect_wake_lock;
int detect_change; /* card detect flag */
struct mmc_slot slot;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 22913f78b829..67f59c1e0c7b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1297,6 +1297,7 @@ struct task_struct {
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
+ unsigned long long cpu_power;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
struct cputime prev_cputime;
#endif
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 73a22fd1fd66..66c1cd87bfe7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1762,9 +1762,6 @@ struct hci_conn_info {
__u8 out;
__u16 state;
__u32 link_mode;
- __u32 mtu;
- __u32 cnt;
- __u32 pkts;
};
struct hci_dev_req {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6e17a54ac302..f2f0cf5865c4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -659,7 +659,7 @@ static inline void hci_conn_drop(struct hci_conn *conn)
if (conn->state == BT_CONNECTED) {
timeo = conn->disc_timeout;
if (!conn->out)
- timeo *= 20;
+ timeo *= 2;
} else {
timeo = msecs_to_jiffies(10);
}
diff --git a/include/net/netfilter/ipv4/nf_reject.h b/include/net/netfilter/ipv4/nf_reject.h
index 99fdd82a1306..931fbf812171 100644
--- a/include/net/netfilter/ipv4/nf_reject.h
+++ b/include/net/netfilter/ipv4/nf_reject.h
@@ -9,14 +9,6 @@
static inline void nf_send_unreach(struct sk_buff *skb_in, int code)
{
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
-#ifdef CONFIG_IP_NF_TARGET_REJECT_SKERR
- if (skb_in->sk) {
- skb_in->sk->sk_err = icmp_err_convert[code].errno;
- skb_in->sk->sk_error_report(skb_in->sk);
- pr_debug("ipt_REJECT: sk_err=%d for skb=%p sk=%p\n",
- skb_in->sk->sk_err, skb_in, skb_in->sk);
- }
-#endif
}
/* Send RST reply */
diff --git a/include/net/netfilter/ipv6/nf_reject.h b/include/net/netfilter/ipv6/nf_reject.h
index 5f9795c8feb6..710d17ed70b4 100644
--- a/include/net/netfilter/ipv6/nf_reject.h
+++ b/include/net/netfilter/ipv6/nf_reject.h
@@ -15,15 +15,6 @@ nf_send_unreach6(struct net *net, struct sk_buff *skb_in, unsigned char code,
skb_in->dev = net->loopback_dev;
icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
-#ifdef CONFIG_IP6_NF_TARGET_REJECT_SKERR
- if (skb_in->sk) {
- icmpv6_err_convert(ICMPV6_DEST_UNREACH, code,
- &skb_in->sk->sk_err);
- skb_in->sk->sk_error_report(skb_in->sk);
- pr_debug("ip6t_REJECT: sk_err=%d for skb=%p sk=%p\n",
- skb_in->sk->sk_err, skb_in, skb_in->sk);
- }
-#endif
}
/* Send RST reply */
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 0f74c7bdff3c..f2011a9b37d7 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -696,11 +696,12 @@ __SYSCALL(__NR_finit_module, sys_finit_module)
__SYSCALL(__NR_sched_setattr, sys_sched_setattr)
#define __NR_sched_getattr 275
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
-#define __NR_seccomp 276
+
+#define __NR_seccomp 277
__SYSCALL(__NR_seccomp, sys_seccomp)
#undef __NR_syscalls
-#define __NR_syscalls 277
+#define __NR_syscalls 278
/*
* All syscalls below here should go away really,
diff --git a/kernel/fork.c b/kernel/fork.c
index 20eaa23152eb..e5d0ede99339 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1301,6 +1301,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->utime = p->stime = p->gtime = 0;
p->utimescaled = p->stimescaled = 0;
+ p->cpu_power = 0;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
p->prev_cputime.utime = p->prev_cputime.stime = 0;
#endif
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index f94d703c9f55..da5f2ffa7106 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -100,7 +100,6 @@ EXPORT_SYMBOL_GPL(resume_device_irqs);
int check_wakeup_irqs(void)
{
struct irq_desc *desc;
- char __maybe_unused suspend_abort[MAX_SUSPEND_ABORT_LEN];
int irq;
for_each_irq_desc(irq, desc) {
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 2d98d52a8700..2932a43a5659 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -225,10 +225,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
if (!(suspend_test(TEST_CORE) || *wakeup)) {
error = suspend_ops->enter(state);
events_check_enabled = false;
- } else {
+ } else if (*wakeup) {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
+ error = -EBUSY;
}
syscore_resume();
}
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index c8fba3380076..8f50de394d22 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -9,6 +9,7 @@
* manipulate wakelocks on Android.
*/
+#include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -188,6 +189,9 @@ int pm_wake_lock(const char *buf)
size_t len;
int ret = 0;
+ if (!capable(CAP_BLOCK_SUSPEND))
+ return -EPERM;
+
while (*str && !isspace(*str))
str++;
@@ -231,6 +235,9 @@ int pm_wake_unlock(const char *buf)
size_t len;
int ret = 0;
+ if (!capable(CAP_BLOCK_SUSPEND))
+ return -EPERM;
+
len = strlen(buf);
if (!len)
return -EINVAL;
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index cfe2f268afaa..23c4f2e3bafd 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -1,3 +1,4 @@
+#include <linux/cpufreq.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/tsacct_kern.h>
@@ -149,6 +150,11 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
/* Account for user time used */
acct_account_cputime(p);
+
+#ifdef CONFIG_CPU_FREQ_STAT
+ /* Account power usage for user time */
+ acct_update_power(p, cputime);
+#endif
}
/*
@@ -199,6 +205,11 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
/* Account for system time used */
acct_account_cputime(p);
+
+#ifdef CONFIG_CPU_FREQ_STAT
+ /* Account power usage for system time */
+ acct_update_power(p, cputime);
+#endif
}
/*
diff --git a/kernel/sys.c b/kernel/sys.c
index 8ba889e31bea..4bf3cb0f337c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2111,26 +2111,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
else
return -EINVAL;
break;
- case PR_SET_TIMERSLACK_PID:
- if (current->pid != (pid_t)arg3 &&
- !capable(CAP_SYS_NICE))
- return -EPERM;
- rcu_read_lock();
- tsk = find_task_by_pid_ns((pid_t)arg3, &init_pid_ns);
- if (tsk == NULL) {
- rcu_read_unlock();
- return -EINVAL;
- }
- get_task_struct(tsk);
- rcu_read_unlock();
- if (arg2 <= 0)
- tsk->timer_slack_ns =
- tsk->default_timer_slack_ns;
- else
- tsk->timer_slack_ns = arg2;
- put_task_struct(tsk);
- error = 0;
- break;
default:
return -EINVAL;
}
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3cc58beeff21..1c6e950b9ae7 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -983,15 +983,6 @@ int hci_get_conn_list(void __user *arg)
(ci + n)->out = c->out;
(ci + n)->state = c->state;
(ci + n)->link_mode = c->link_mode;
- if (c->type == SCO_LINK) {
- (ci + n)->mtu = hdev->sco_mtu;
- (ci + n)->cnt = hdev->sco_cnt;
- (ci + n)->pkts = hdev->sco_pkts;
- } else {
- (ci + n)->mtu = hdev->acl_mtu;
- (ci + n)->cnt = hdev->acl_cnt;
- (ci + n)->pkts = hdev->acl_pkts;
- }
if (++n >= req.conn_num)
break;
}
@@ -1028,15 +1019,6 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
ci.out = conn->out;
ci.state = conn->state;
ci.link_mode = conn->link_mode;
- if (req.type == SCO_LINK) {
- ci.mtu = hdev->sco_mtu;
- ci.cnt = hdev->sco_cnt;
- ci.pkts = hdev->sco_pkts;
- } else {
- ci.mtu = hdev->acl_mtu;
- ci.cnt = hdev->acl_cnt;
- ci.pkts = hdev->acl_pkts;
- }
}
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3204004a0b91..2e8c5765e5ea 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2905,7 +2905,6 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
break;
case 0x0d: /* Connection Rejected due to Limited Resources */
- case 0x10: /* Connection Accept Timeout */
case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index eb8864095898..b08865111024 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -436,6 +436,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
switch (d->state) {
case BT_CONNECT:
+ case BT_CONFIG:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
rfcomm_schedule();
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 526bf56f4d31..afeb8e07ee41 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -332,6 +332,10 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD))
+ break;
+
clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
}
@@ -376,6 +380,10 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb;
lock_sock(sk);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ err = -ECONNRESET;
+ goto unlock;
+ }
skb = skb_dequeue(&sk->sk_receive_queue);
caif_check_flow_release(sk);
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 34d630d35cc7..a26ce035e3fa 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -159,18 +159,6 @@ config IP_NF_TARGET_SYNPROXY
To compile it as a module, choose M here. If unsure, say N.
-config IP_NF_TARGET_REJECT_SKERR
- bool "Force socket error when rejecting with icmp*"
- depends on IP_NF_TARGET_REJECT
- default n
- help
- This option enables turning a "--reject-with icmp*" into a matching
- socket error also.
- The REJECT target normally allows sending an ICMP message. But it
- leaves the local socket unaware of any ingress rejects.
-
- If unsure, say N.
-
config IP_NF_TARGET_ULOG
tristate "ULOG target support (obsolete)"
default m if NETFILTER_ADVANCED=n
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index c842cd3059c7..4bff1f297e39 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -196,18 +196,6 @@ config IP6_NF_TARGET_SYNPROXY
To compile it as a module, choose M here. If unsure, say N.
-config IP6_NF_TARGET_REJECT_SKERR
- bool "Force socket error when rejecting with icmp*"
- depends on IP6_NF_TARGET_REJECT
- default n
- help
- This option enables turning a "--reject-with icmp*" into a matching
- socket error also.
- The REJECT target normally allows sending an ICMP message. But it
- leaves the local socket unaware of any ingress rejects.
-
- If unsure, say N.
-
config IP6_NF_MANGLE
tristate "Packet mangling"
default m if NETFILTER_ADVANCED=n
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 94404f19f9de..4757f1cf6237 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1893,6 +1893,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
unix_state_unlock(sk);
timeo = freezable_schedule_timeout(timeo);
unix_state_lock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD))
+ break;
+
clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
}
@@ -1957,6 +1961,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb, *last;
unix_state_lock(sk);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ err = -ECONNRESET;
+ goto unlock;
+ }
last = skb = skb_peek(&sk->sk_receive_queue);
again:
if (skb == NULL) {
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 4c602d100480..16d08b399210 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -166,14 +166,3 @@ config LIB80211_DEBUG
from lib80211.
If unsure, say N.
-
-config CFG80211_ALLOW_RECONNECT
- bool "Allow reconnect while already connected"
- depends on CFG80211
- default n
- help
- cfg80211 stack doesn't allow to connect if you are already
- connected. This option allows to make a connection in this case.
-
- Select this option ONLY for wlan drivers that are specifically
- built for such purposes.
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index efe76c6a320a..760722f9126b 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -428,18 +428,11 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
if (!rdev->ops->auth || !rdev->ops->assoc)
return -EOPNOTSUPP;
-#ifndef CONFIG_CFG80211_ALLOW_RECONNECT
if (wdev->current_bss)
return -EALREADY;
if (WARN_ON(wdev->conn))
return -EINPROGRESS;
-#else
- if (wdev->conn) {
- kfree(wdev->conn);
- wdev->conn = NULL;
- }
-#endif
wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
if (!wdev->conn)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a10e0c772fed..6ce2734bcb37 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -731,7 +731,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
}
if (strcmp(sb->s_type->name, "proc") == 0)
- sbsec->flags |= SE_SBPROC;
+ sbsec->flags |= SE_SBPROC | SE_SBGENFS;
+
+ if (!strcmp(sb->s_type->name, "debugfs") ||
+ !strcmp(sb->s_type->name, "sysfs") ||
+ !strcmp(sb->s_type->name, "pstore"))
+ sbsec->flags |= SE_SBGENFS;
if (!sbsec->behavior) {
/*
@@ -1227,12 +1232,13 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
return SECCLASS_SOCKET;
}
-#ifdef CONFIG_PROC_FS
-static int selinux_proc_get_sid(struct dentry *dentry,
- u16 tclass,
- u32 *sid)
+static int selinux_genfs_get_sid(struct dentry *dentry,
+ u16 tclass,
+ u16 flags,
+ u32 *sid)
{
int rc;
+ struct super_block *sb = dentry->d_inode->i_sb;
char *buffer, *path;
buffer = (char *)__get_free_page(GFP_KERNEL);
@@ -1243,26 +1249,20 @@ static int selinux_proc_get_sid(struct dentry *dentry,
if (IS_ERR(path))
rc = PTR_ERR(path);
else {
- /* each process gets a /proc/PID/ entry. Strip off the
- * PID part to get a valid selinux labeling.
- * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
- while (path[1] >= '0' && path[1] <= '9') {
- path[1] = '/';
- path++;
+ if (flags & SE_SBPROC) {
+ /* each process gets a /proc/PID/ entry. Strip off the
+ * PID part to get a valid selinux labeling.
+ * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
+ while (path[1] >= '0' && path[1] <= '9') {
+ path[1] = '/';
+ path++;
+ }
}
- rc = security_genfs_sid("proc", path, tclass, sid);
+ rc = security_genfs_sid(sb->s_type->name, path, tclass, sid);
}
free_page((unsigned long)buffer);
return rc;
}
-#else
-static int selinux_proc_get_sid(struct dentry *dentry,
- u16 tclass,
- u32 *sid)
-{
- return -EINVAL;
-}
-#endif
/* The inode's security attributes must be initialized before first use. */
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
@@ -1419,7 +1419,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
/* Default to the fs superblock SID. */
isec->sid = sbsec->sid;
- if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
+ if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
/* We must have a dentry to determine the label on
* procfs inodes */
if (opt_dentry)
@@ -1442,7 +1442,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
if (!dentry)
goto out_unlock;
isec->sclass = inode_mode_to_security_class(inode->i_mode);
- rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
+ rc = selinux_genfs_get_sid(dentry, isec->sclass,
+ sbsec->flags, &sid);
dput(dentry);
if (rc)
goto out_unlock;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index c8bf6735c6f9..be99667c2a21 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -56,6 +56,7 @@
/* Non-mount related flags */
#define SE_SBINITIALIZED 0x0100
#define SE_SBPROC 0x0200
+#define SE_SBGENFS 0x0400
#define CONTEXT_STR "context="
#define FSCONTEXT_STR "fscontext="