Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0-jb
Conflicts: Makefile drivers/net/tun.c drivers/net/wireless/rt2x00/rt61pci.c drivers/usb/core/hub.c sound/soc/codecs/wm8994.c
This commit is contained in:
commit
109b0ba094
139 changed files with 1756 additions and 763 deletions
|
|
@ -1,4 +1,4 @@
|
|||
Everything you ever wanted to know about Linux 2.6 -stable releases.
|
||||
Everything you ever wanted to know about Linux -stable releases.
|
||||
|
||||
Rules on what kind of patches are accepted, and which ones are not, into the
|
||||
"-stable" tree:
|
||||
|
|
@ -41,10 +41,10 @@ Procedure for submitting patches to the -stable tree:
|
|||
cherry-picked than this can be specified in the following format in
|
||||
the sign-off area:
|
||||
|
||||
Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle
|
||||
Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
|
||||
Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic
|
||||
Cc: <stable@vger.kernel.org> # .32.x
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
|
||||
Cc: <stable@vger.kernel.org> # 3.3.x
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
|
||||
The tag sequence has the meaning of:
|
||||
|
|
@ -78,6 +78,15 @@ Review cycle:
|
|||
security kernel team, and not go through the normal review cycle.
|
||||
Contact the kernel security team for more details on this procedure.
|
||||
|
||||
Trees:
|
||||
|
||||
- The queues of patches, for both completed versions and in progress
|
||||
versions can be found at:
|
||||
http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git
|
||||
- The finalized and tagged releases of all stable kernels can be found
|
||||
in separate branches per version at:
|
||||
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git
|
||||
|
||||
|
||||
Review committee:
|
||||
|
||||
|
|
|
|||
|
|
@ -379,10 +379,10 @@ EVENT_PROCESS:
|
|||
|
||||
# To closer match vmstat scanning statistics, only count isolate_both
|
||||
# and isolate_inactive as scanning. isolate_active is rotation
|
||||
# isolate_inactive == 0
|
||||
# isolate_active == 1
|
||||
# isolate_both == 2
|
||||
if ($isolate_mode != 1) {
|
||||
# isolate_inactive == 1
|
||||
# isolate_active == 2
|
||||
# isolate_both == 3
|
||||
if ($isolate_mode != 2) {
|
||||
$perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
|
||||
}
|
||||
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
|
||||
|
|
|
|||
|
|
@ -5247,7 +5247,7 @@ F: Documentation/blockdev/ramdisk.txt
|
|||
F: drivers/block/brd.c
|
||||
|
||||
RANDOM NUMBER DRIVER
|
||||
M: Matt Mackall <mpm@selenic.com>
|
||||
M: Theodore Ts'o" <tytso@mit.edu>
|
||||
S: Maintained
|
||||
F: drivers/char/random.c
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ CONFIG_NO_HZ=y
|
|||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
|
||||
CONFIG_AUTO_ZRELADDR=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_NET=y
|
||||
|
|
|
|||
|
|
@ -215,7 +215,9 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm)
|
|||
static inline void
|
||||
vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
||||
{
|
||||
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
|
||||
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
|
||||
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
|
||||
vma->vm_flags);
|
||||
}
|
||||
|
|
@ -223,7 +225,9 @@ vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
|
|||
static inline void
|
||||
vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
|
||||
{
|
||||
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
|
||||
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
|
||||
unsigned long addr = user_addr & PAGE_MASK;
|
||||
__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
|
|||
omap_table_init = 1;
|
||||
|
||||
/* Lets now register with OPP library */
|
||||
for (i = 0; i < opp_def_size; i++) {
|
||||
for (i = 0; i < opp_def_size; i++, opp_def++) {
|
||||
struct omap_hwmod *oh;
|
||||
struct device *dev;
|
||||
|
||||
|
|
@ -86,7 +86,6 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
|
|||
__func__, opp_def->freq,
|
||||
opp_def->hwmod_name, i, r);
|
||||
}
|
||||
opp_def++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -38,11 +38,19 @@ ENTRY(v7wbi_flush_user_tlb_range)
|
|||
dsb
|
||||
mov r0, r0, lsr #PAGE_SHIFT @ align address
|
||||
mov r1, r1, lsr #PAGE_SHIFT
|
||||
#ifdef CONFIG_ARM_ERRATA_720789
|
||||
mov r3, #0
|
||||
#else
|
||||
asid r3, r3 @ mask ASID
|
||||
#endif
|
||||
orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
|
||||
mov r1, r1, lsl #PAGE_SHIFT
|
||||
1:
|
||||
#ifdef CONFIG_ARM_ERRATA_720789
|
||||
ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
|
||||
#else
|
||||
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
|
||||
#endif
|
||||
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
|
||||
|
||||
add r0, r0, #PAGE_SZ
|
||||
|
|
@ -70,7 +78,11 @@ ENTRY(v7wbi_flush_kern_tlb_range)
|
|||
mov r0, r0, lsl #PAGE_SHIFT
|
||||
mov r1, r1, lsl #PAGE_SHIFT
|
||||
1:
|
||||
#ifdef CONFIG_ARM_ERRATA_720789
|
||||
ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
|
||||
#else
|
||||
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
|
||||
#endif
|
||||
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
|
||||
add r0, r0, #PAGE_SZ
|
||||
cmp r0, r1
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
#include <asm/system.h>
|
||||
|
||||
|
||||
#define ATOMIC_INIT(i) ((atomic_t) { (i) })
|
||||
#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#define atomic_read(v) (*(volatile int *)&(v)->counter)
|
||||
#define atomic64_read(v) (*(volatile long *)&(v)->counter)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/random.h> /* for rand_initialize_irq() */
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/threads.h>
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
/* the following macro is used when enabling interrupts */
|
||||
#if defined(MACH_ATARI_ONLY)
|
||||
/* block out HSYNC on the atari */
|
||||
#define ALLOWINT (~0x400)
|
||||
/* block out HSYNC = ipl 2 on the atari */
|
||||
#define ALLOWINT (~0x500)
|
||||
#define MAX_NOINT_IPL 3
|
||||
#else
|
||||
/* portable version */
|
||||
|
|
|
|||
|
|
@ -479,9 +479,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
|
|||
goto bad_access;
|
||||
}
|
||||
|
||||
mem_value = *mem;
|
||||
/*
|
||||
* No need to check for EFAULT; we know that the page is
|
||||
* present and writable.
|
||||
*/
|
||||
__get_user(mem_value, mem);
|
||||
if (mem_value == oldval)
|
||||
*mem = newval;
|
||||
__put_user(newval, mem);
|
||||
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
up_read(&mm->mmap_sem);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ struct thread_info {
|
|||
register struct thread_info *__current_thread_info __asm__("$28");
|
||||
#define current_thread_info() __current_thread_info
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/* thread information allocation */
|
||||
#if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT)
|
||||
#define THREAD_SIZE_ORDER (1)
|
||||
|
|
@ -97,8 +99,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
|
|||
|
||||
#define free_thread_info(info) kfree(info)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define PREEMPT_ACTIVE 0x10000000
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
#undef mips
|
||||
|
|
@ -73,7 +74,7 @@ SECTIONS
|
|||
.data : { /* Data */
|
||||
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
|
||||
|
||||
INIT_TASK_DATA(PAGE_SIZE)
|
||||
INIT_TASK_DATA(THREAD_SIZE)
|
||||
NOSAVE_DATA
|
||||
CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
|
||||
READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
|
||||
|
|
|
|||
|
|
@ -126,11 +126,11 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct)
|
|||
/*
|
||||
* Convert cputime <-> microseconds
|
||||
*/
|
||||
extern u64 __cputime_msec_factor;
|
||||
extern u64 __cputime_usec_factor;
|
||||
|
||||
static inline unsigned long cputime_to_usecs(const cputime_t ct)
|
||||
{
|
||||
return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC;
|
||||
return mulhdu(ct, __cputime_usec_factor);
|
||||
}
|
||||
|
||||
static inline cputime_t usecs_to_cputime(const unsigned long us)
|
||||
|
|
@ -143,7 +143,7 @@ static inline cputime_t usecs_to_cputime(const unsigned long us)
|
|||
sec = us / 1000000;
|
||||
if (ct) {
|
||||
ct *= tb_ticks_per_sec;
|
||||
do_div(ct, 1000);
|
||||
do_div(ct, 1000000);
|
||||
}
|
||||
if (sec)
|
||||
ct += (cputime_t) sec * tb_ticks_per_sec;
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,8 @@
|
|||
/* Macros for setting and retrieving special purpose registers */
|
||||
#ifndef __ASSEMBLY__
|
||||
#define mfmsr() ({unsigned long rval; \
|
||||
asm volatile("mfmsr %0" : "=r" (rval)); rval;})
|
||||
asm volatile("mfmsr %0" : "=r" (rval) : \
|
||||
: "memory"); rval;})
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
|
||||
: : "r" (v) : "memory")
|
||||
|
|
|
|||
|
|
@ -245,9 +245,9 @@ __ftrace_make_nop(struct module *mod,
|
|||
|
||||
/*
|
||||
* On PPC32 the trampoline looks like:
|
||||
* 0x3d, 0x60, 0x00, 0x00 lis r11,sym@ha
|
||||
* 0x39, 0x6b, 0x00, 0x00 addi r11,r11,sym@l
|
||||
* 0x7d, 0x69, 0x03, 0xa6 mtctr r11
|
||||
* 0x3d, 0x80, 0x00, 0x00 lis r12,sym@ha
|
||||
* 0x39, 0x8c, 0x00, 0x00 addi r12,r12,sym@l
|
||||
* 0x7d, 0x89, 0x03, 0xa6 mtctr r12
|
||||
* 0x4e, 0x80, 0x04, 0x20 bctr
|
||||
*/
|
||||
|
||||
|
|
@ -262,9 +262,9 @@ __ftrace_make_nop(struct module *mod,
|
|||
pr_devel(" %08x %08x ", jmp[0], jmp[1]);
|
||||
|
||||
/* verify that this is what we expect it to be */
|
||||
if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
|
||||
((jmp[1] & 0xffff0000) != 0x396b0000) ||
|
||||
(jmp[2] != 0x7d6903a6) ||
|
||||
if (((jmp[0] & 0xffff0000) != 0x3d800000) ||
|
||||
((jmp[1] & 0xffff0000) != 0x398c0000) ||
|
||||
(jmp[2] != 0x7d8903a6) ||
|
||||
(jmp[3] != 0x4e800420)) {
|
||||
printk(KERN_ERR "Not a trampoline\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -168,13 +168,13 @@ EXPORT_SYMBOL_GPL(ppc_tb_freq);
|
|||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
/*
|
||||
* Factors for converting from cputime_t (timebase ticks) to
|
||||
* jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds).
|
||||
* jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds).
|
||||
* These are all stored as 0.64 fixed-point binary fractions.
|
||||
*/
|
||||
u64 __cputime_jiffies_factor;
|
||||
EXPORT_SYMBOL(__cputime_jiffies_factor);
|
||||
u64 __cputime_msec_factor;
|
||||
EXPORT_SYMBOL(__cputime_msec_factor);
|
||||
u64 __cputime_usec_factor;
|
||||
EXPORT_SYMBOL(__cputime_usec_factor);
|
||||
u64 __cputime_sec_factor;
|
||||
EXPORT_SYMBOL(__cputime_sec_factor);
|
||||
u64 __cputime_clockt_factor;
|
||||
|
|
@ -192,8 +192,8 @@ static void calc_cputime_factors(void)
|
|||
|
||||
div128_by_32(HZ, 0, tb_ticks_per_sec, &res);
|
||||
__cputime_jiffies_factor = res.result_low;
|
||||
div128_by_32(1000, 0, tb_ticks_per_sec, &res);
|
||||
__cputime_msec_factor = res.result_low;
|
||||
div128_by_32(1000000, 0, tb_ticks_per_sec, &res);
|
||||
__cputime_usec_factor = res.result_low;
|
||||
div128_by_32(1, 0, tb_ticks_per_sec, &res);
|
||||
__cputime_sec_factor = res.result_low;
|
||||
div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ struct cpuinfo_x86 {
|
|||
u16 apicid;
|
||||
u16 initial_apicid;
|
||||
u16 x86_clflush_size;
|
||||
#ifdef CONFIG_SMP
|
||||
/* number of cores as seen by the OS: */
|
||||
u16 booted_cores;
|
||||
/* Physical processor id: */
|
||||
|
|
@ -110,7 +109,6 @@ struct cpuinfo_x86 {
|
|||
u8 compute_unit_id;
|
||||
/* Index into per_cpu list: */
|
||||
u16 cpu_index;
|
||||
#endif
|
||||
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
|
||||
|
||||
#define X86_VENDOR_INTEL 0
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ void __init arch_init_ideal_nops(void)
|
|||
ideal_nops = intel_nops;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
#ifdef CONFIG_X86_64
|
||||
ideal_nops = k8_nops;
|
||||
|
|
|
|||
|
|
@ -154,16 +154,14 @@ int amd_get_subcaches(int cpu)
|
|||
{
|
||||
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
|
||||
unsigned int mask;
|
||||
int cuid = 0;
|
||||
int cuid;
|
||||
|
||||
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||
return 0;
|
||||
|
||||
pci_read_config_dword(link, 0x1d4, &mask);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cuid = cpu_data(cpu).compute_unit_id;
|
||||
#endif
|
||||
return (mask >> (4 * cuid)) & 0xf;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +170,7 @@ int amd_set_subcaches(int cpu, int mask)
|
|||
static unsigned int reset, ban;
|
||||
struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu));
|
||||
unsigned int reg;
|
||||
int cuid = 0;
|
||||
int cuid;
|
||||
|
||||
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
|
||||
return -EINVAL;
|
||||
|
|
@ -190,9 +188,7 @@ int amd_set_subcaches(int cpu, int mask)
|
|||
pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cuid = cpu_data(cpu).compute_unit_id;
|
||||
#endif
|
||||
mask <<= 4 * cuid;
|
||||
mask |= (0xf ^ (1 << cuid)) << 26;
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,6 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
|
|||
|
||||
static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/* calling is from identify_secondary_cpu() ? */
|
||||
if (!c->cpu_index)
|
||||
return;
|
||||
|
|
@ -190,7 +189,6 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
|
|||
|
||||
valid_k7:
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
|
||||
|
|
|
|||
|
|
@ -675,9 +675,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
|
|||
if (this_cpu->c_early_init)
|
||||
this_cpu->c_early_init(c);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
c->cpu_index = 0;
|
||||
#endif
|
||||
filter_cpuid_features(c, false);
|
||||
|
||||
setup_smep(c);
|
||||
|
|
@ -760,10 +758,7 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
|
|||
c->apicid = c->initial_apicid;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_HT
|
||||
c->phys_proc_id = c->initial_apicid;
|
||||
#endif
|
||||
}
|
||||
|
||||
setup_smep(c);
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ static void __cpuinit trap_init_f00f_bug(void)
|
|||
|
||||
static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/* calling is from identify_secondary_cpu() ? */
|
||||
if (!c->cpu_index)
|
||||
return;
|
||||
|
|
@ -196,7 +195,6 @@ static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
|||
WARN_ONCE(1, "WARNING: SMP operation may be unreliable"
|
||||
"with B stepping processors.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
|
||||
|
|
|
|||
|
|
@ -122,9 +122,7 @@ void mce_setup(struct mce *m)
|
|||
m->time = get_seconds();
|
||||
m->cpuvendor = boot_cpu_data.x86_vendor;
|
||||
m->cpuid = cpuid_eax(1);
|
||||
#ifdef CONFIG_SMP
|
||||
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
||||
#endif
|
||||
m->apicid = cpu_data(m->extcpu).initial_apicid;
|
||||
rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,11 +65,9 @@ struct threshold_bank {
|
|||
};
|
||||
static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static unsigned char shared_bank[NR_BANKS] = {
|
||||
0, 0, 0, 0, 1
|
||||
};
|
||||
#endif
|
||||
|
||||
static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
|
||||
|
||||
|
|
@ -227,10 +225,9 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
|
|||
|
||||
if (!block)
|
||||
per_cpu(bank_map, cpu) |= (1 << bank);
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
if (shared_bank[bank] && c->cpu_core_id)
|
||||
break;
|
||||
#endif
|
||||
|
||||
memset(&b, 0, sizeof(b));
|
||||
b.cpu = cpu;
|
||||
|
|
|
|||
|
|
@ -64,12 +64,10 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
|
|||
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
{
|
||||
struct cpuinfo_x86 *c = v;
|
||||
unsigned int cpu = 0;
|
||||
unsigned int cpu;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = c->cpu_index;
|
||||
#endif
|
||||
seq_printf(m, "processor\t: %u\n"
|
||||
"vendor_id\t: %s\n"
|
||||
"cpu family\t: %d\n"
|
||||
|
|
|
|||
|
|
@ -297,20 +297,31 @@ static ssize_t reload_store(struct sys_device *dev,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long val;
|
||||
int cpu = dev->id;
|
||||
int ret = 0;
|
||||
char *end;
|
||||
int cpu;
|
||||
ssize_t ret = 0, tmp_ret;
|
||||
|
||||
val = simple_strtoul(buf, &end, 0);
|
||||
if (end == buf)
|
||||
/* allow reload only from the BSP */
|
||||
if (boot_cpu_data.cpu_index != dev->id)
|
||||
return -EINVAL;
|
||||
|
||||
if (val == 1) {
|
||||
get_online_cpus();
|
||||
if (cpu_online(cpu))
|
||||
ret = reload_for_cpu(cpu);
|
||||
put_online_cpus();
|
||||
ret = kstrtoul(buf, 0, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val != 1)
|
||||
return size;
|
||||
|
||||
get_online_cpus();
|
||||
for_each_online_cpu(cpu) {
|
||||
tmp_ret = reload_for_cpu(cpu);
|
||||
if (tmp_ret != 0)
|
||||
pr_warn("Error reloading microcode on CPU %d\n", cpu);
|
||||
|
||||
/* save retval of the first encountered reload error */
|
||||
if (!ret)
|
||||
ret = tmp_ret;
|
||||
}
|
||||
put_online_cpus();
|
||||
|
||||
if (!ret)
|
||||
ret = size;
|
||||
|
|
|
|||
|
|
@ -292,7 +292,9 @@ static int acpi_ac_add(struct acpi_device *device)
|
|||
ac->charger.properties = ac_props;
|
||||
ac->charger.num_properties = ARRAY_SIZE(ac_props);
|
||||
ac->charger.get_property = get_ac_property;
|
||||
power_supply_register(&ac->device->dev, &ac->charger);
|
||||
result = power_supply_register(&ac->device->dev, &ac->charger);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
|
|
|
|||
|
|
@ -223,6 +223,42 @@ int memory_isolate_notify(unsigned long val, void *v)
|
|||
return atomic_notifier_call_chain(&memory_isolate_chain, val, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* The probe routines leave the pages reserved, just as the bootmem code does.
|
||||
* Make sure they're still that way.
|
||||
*/
|
||||
static bool pages_correctly_reserved(unsigned long start_pfn,
|
||||
unsigned long nr_pages)
|
||||
{
|
||||
int i, j;
|
||||
struct page *page;
|
||||
unsigned long pfn = start_pfn;
|
||||
|
||||
/*
|
||||
* memmap between sections is not contiguous except with
|
||||
* SPARSEMEM_VMEMMAP. We lookup the page once per section
|
||||
* and assume memmap is contiguous within each section
|
||||
*/
|
||||
for (i = 0; i < sections_per_block; i++, pfn += PAGES_PER_SECTION) {
|
||||
if (WARN_ON_ONCE(!pfn_valid(pfn)))
|
||||
return false;
|
||||
page = pfn_to_page(pfn);
|
||||
|
||||
for (j = 0; j < PAGES_PER_SECTION; j++) {
|
||||
if (PageReserved(page + j))
|
||||
continue;
|
||||
|
||||
printk(KERN_WARNING "section number %ld page number %d "
|
||||
"not reserved, was it already online?\n",
|
||||
pfn_to_section_nr(pfn), j);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
|
||||
* OK to have direct references to sparsemem variables in here.
|
||||
|
|
@ -230,7 +266,6 @@ int memory_isolate_notify(unsigned long val, void *v)
|
|||
static int
|
||||
memory_block_action(unsigned long phys_index, unsigned long action)
|
||||
{
|
||||
int i;
|
||||
unsigned long start_pfn, start_paddr;
|
||||
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
|
||||
struct page *first_page;
|
||||
|
|
@ -238,26 +273,13 @@ memory_block_action(unsigned long phys_index, unsigned long action)
|
|||
|
||||
first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
|
||||
|
||||
/*
|
||||
* The probe routines leave the pages reserved, just
|
||||
* as the bootmem code does. Make sure they're still
|
||||
* that way.
|
||||
*/
|
||||
if (action == MEM_ONLINE) {
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
if (PageReserved(first_page+i))
|
||||
continue;
|
||||
|
||||
printk(KERN_WARNING "section number %ld page number %d "
|
||||
"not reserved, was it already online?\n",
|
||||
phys_index, i);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MEM_ONLINE:
|
||||
start_pfn = page_to_pfn(first_page);
|
||||
|
||||
if (!pages_correctly_reserved(start_pfn, nr_pages))
|
||||
return -EBUSY;
|
||||
|
||||
ret = online_pages(start_pfn, nr_pages);
|
||||
break;
|
||||
case MEM_OFFLINE:
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
|
|||
vdata->flags = flags;
|
||||
vdata->type = type;
|
||||
spin_lock_init(&vdata->lock);
|
||||
vdata->refcnt = ATOMIC_INIT(1);
|
||||
atomic_set(&vdata->refcnt, 1);
|
||||
vma->vm_private_data = vdata;
|
||||
|
||||
vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
|
||||
|
|
|
|||
|
|
@ -125,21 +125,26 @@
|
|||
* The current exported interfaces for gathering environmental noise
|
||||
* from the devices are:
|
||||
*
|
||||
* void add_device_randomness(const void *buf, unsigned int size);
|
||||
* void add_input_randomness(unsigned int type, unsigned int code,
|
||||
* unsigned int value);
|
||||
* void add_interrupt_randomness(int irq);
|
||||
* void add_interrupt_randomness(int irq, int irq_flags);
|
||||
* void add_disk_randomness(struct gendisk *disk);
|
||||
*
|
||||
* add_device_randomness() is for adding data to the random pool that
|
||||
* is likely to differ between two devices (or possibly even per boot).
|
||||
* This would be things like MAC addresses or serial numbers, or the
|
||||
* read-out of the RTC. This does *not* add any actual entropy to the
|
||||
* pool, but it initializes the pool to different values for devices
|
||||
* that might otherwise be identical and have very little entropy
|
||||
* available to them (particularly common in the embedded world).
|
||||
*
|
||||
* add_input_randomness() uses the input layer interrupt timing, as well as
|
||||
* the event type information from the hardware.
|
||||
*
|
||||
* add_interrupt_randomness() uses the inter-interrupt timing as random
|
||||
* inputs to the entropy pool. Note that not all interrupts are good
|
||||
* sources of randomness! For example, the timer interrupts is not a
|
||||
* good choice, because the periodicity of the interrupts is too
|
||||
* regular, and hence predictable to an attacker. Network Interface
|
||||
* Controller interrupts are a better measure, since the timing of the
|
||||
* NIC interrupts are more unpredictable.
|
||||
* add_interrupt_randomness() uses the interrupt timing as random
|
||||
* inputs to the entropy pool. Using the cycle counters and the irq source
|
||||
* as inputs, it feeds the randomness roughly once a second.
|
||||
*
|
||||
* add_disk_randomness() uses what amounts to the seek time of block
|
||||
* layer request events, on a per-disk_devt basis, as input to the
|
||||
|
|
@ -248,6 +253,8 @@
|
|||
#include <linux/percpu.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/fips.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/kmemcheck.h>
|
||||
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
# include <linux/irq.h>
|
||||
|
|
@ -256,8 +263,12 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irq_regs.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/random.h>
|
||||
|
||||
/*
|
||||
* Configuration information
|
||||
*/
|
||||
|
|
@ -266,6 +277,8 @@
|
|||
#define SEC_XFER_SIZE 512
|
||||
#define EXTRACT_SIZE 10
|
||||
|
||||
#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
|
||||
|
||||
/*
|
||||
* The minimum number of bits of entropy before we wake up a read on
|
||||
* /dev/random. Should be enough to do a significant reseed.
|
||||
|
|
@ -420,8 +433,10 @@ struct entropy_store {
|
|||
/* read-write data: */
|
||||
spinlock_t lock;
|
||||
unsigned add_ptr;
|
||||
unsigned input_rotate;
|
||||
int entropy_count;
|
||||
int input_rotate;
|
||||
int entropy_total;
|
||||
unsigned int initialized:1;
|
||||
__u8 last_data[EXTRACT_SIZE];
|
||||
};
|
||||
|
||||
|
|
@ -454,6 +469,10 @@ static struct entropy_store nonblocking_pool = {
|
|||
.pool = nonblocking_pool_data
|
||||
};
|
||||
|
||||
static __u32 const twist_table[8] = {
|
||||
0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
|
||||
0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
|
||||
|
||||
/*
|
||||
* This function adds bytes into the entropy "pool". It does not
|
||||
* update the entropy estimate. The caller should call
|
||||
|
|
@ -464,29 +483,24 @@ static struct entropy_store nonblocking_pool = {
|
|||
* it's cheap to do so and helps slightly in the expected case where
|
||||
* the entropy is concentrated in the low-order bits.
|
||||
*/
|
||||
static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
|
||||
int nbytes, __u8 out[64])
|
||||
static void _mix_pool_bytes(struct entropy_store *r, const void *in,
|
||||
int nbytes, __u8 out[64])
|
||||
{
|
||||
static __u32 const twist_table[8] = {
|
||||
0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
|
||||
0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
|
||||
unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
|
||||
int input_rotate;
|
||||
int wordmask = r->poolinfo->poolwords - 1;
|
||||
const char *bytes = in;
|
||||
__u32 w;
|
||||
unsigned long flags;
|
||||
|
||||
/* Taps are constant, so we can load them without holding r->lock. */
|
||||
tap1 = r->poolinfo->tap1;
|
||||
tap2 = r->poolinfo->tap2;
|
||||
tap3 = r->poolinfo->tap3;
|
||||
tap4 = r->poolinfo->tap4;
|
||||
tap5 = r->poolinfo->tap5;
|
||||
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
input_rotate = r->input_rotate;
|
||||
i = r->add_ptr;
|
||||
smp_rmb();
|
||||
input_rotate = ACCESS_ONCE(r->input_rotate);
|
||||
i = ACCESS_ONCE(r->add_ptr);
|
||||
|
||||
/* mix one byte at a time to simplify size handling and churn faster */
|
||||
while (nbytes--) {
|
||||
|
|
@ -513,19 +527,61 @@ static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
|
|||
input_rotate += i ? 7 : 14;
|
||||
}
|
||||
|
||||
r->input_rotate = input_rotate;
|
||||
r->add_ptr = i;
|
||||
ACCESS_ONCE(r->input_rotate) = input_rotate;
|
||||
ACCESS_ONCE(r->add_ptr) = i;
|
||||
smp_wmb();
|
||||
|
||||
if (out)
|
||||
for (j = 0; j < 16; j++)
|
||||
((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
|
||||
}
|
||||
|
||||
static void __mix_pool_bytes(struct entropy_store *r, const void *in,
|
||||
int nbytes, __u8 out[64])
|
||||
{
|
||||
trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_);
|
||||
_mix_pool_bytes(r, in, nbytes, out);
|
||||
}
|
||||
|
||||
static void mix_pool_bytes(struct entropy_store *r, const void *in,
|
||||
int nbytes, __u8 out[64])
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
_mix_pool_bytes(r, in, nbytes, out);
|
||||
spin_unlock_irqrestore(&r->lock, flags);
|
||||
}
|
||||
|
||||
static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes)
|
||||
struct fast_pool {
|
||||
__u32 pool[4];
|
||||
unsigned long last;
|
||||
unsigned short count;
|
||||
unsigned char rotate;
|
||||
unsigned char last_timer_intr;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a fast mixing routine used by the interrupt randomness
|
||||
* collector. It's hardcoded for an 128 bit pool and assumes that any
|
||||
* locks that might be needed are taken by the caller.
|
||||
*/
|
||||
static void fast_mix(struct fast_pool *f, const void *in, int nbytes)
|
||||
{
|
||||
mix_pool_bytes_extract(r, in, bytes, NULL);
|
||||
const char *bytes = in;
|
||||
__u32 w;
|
||||
unsigned i = f->count;
|
||||
unsigned input_rotate = f->rotate;
|
||||
|
||||
while (nbytes--) {
|
||||
w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^
|
||||
f->pool[(i + 1) & 3];
|
||||
f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7];
|
||||
input_rotate += (i++ & 3) ? 7 : 14;
|
||||
}
|
||||
f->count = i;
|
||||
f->rotate = input_rotate;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -533,30 +589,38 @@ static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes)
|
|||
*/
|
||||
static void credit_entropy_bits(struct entropy_store *r, int nbits)
|
||||
{
|
||||
unsigned long flags;
|
||||
int entropy_count;
|
||||
int entropy_count, orig;
|
||||
|
||||
if (!nbits)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
|
||||
DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
|
||||
entropy_count = r->entropy_count;
|
||||
retry:
|
||||
entropy_count = orig = ACCESS_ONCE(r->entropy_count);
|
||||
entropy_count += nbits;
|
||||
|
||||
if (entropy_count < 0) {
|
||||
DEBUG_ENT("negative entropy/overflow\n");
|
||||
entropy_count = 0;
|
||||
} else if (entropy_count > r->poolinfo->POOLBITS)
|
||||
entropy_count = r->poolinfo->POOLBITS;
|
||||
r->entropy_count = entropy_count;
|
||||
if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
|
||||
goto retry;
|
||||
|
||||
if (!r->initialized && nbits > 0) {
|
||||
r->entropy_total += nbits;
|
||||
if (r->entropy_total > 128)
|
||||
r->initialized = 1;
|
||||
}
|
||||
|
||||
trace_credit_entropy_bits(r->name, nbits, entropy_count,
|
||||
r->entropy_total, _RET_IP_);
|
||||
|
||||
/* should we wake readers? */
|
||||
if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
|
||||
wake_up_interruptible(&random_read_wait);
|
||||
kill_fasync(&fasync, SIGIO, POLL_IN);
|
||||
}
|
||||
spin_unlock_irqrestore(&r->lock, flags);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
@ -572,42 +636,24 @@ struct timer_rand_state {
|
|||
unsigned dont_count_entropy:1;
|
||||
};
|
||||
|
||||
#ifndef CONFIG_GENERIC_HARDIRQS
|
||||
|
||||
static struct timer_rand_state *irq_timer_state[NR_IRQS];
|
||||
|
||||
static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
|
||||
/*
|
||||
* Add device- or boot-specific data to the input and nonblocking
|
||||
* pools to help initialize them to unique values.
|
||||
*
|
||||
* None of this adds any entropy, it is meant to avoid the
|
||||
* problem of the nonblocking pool having similar initial state
|
||||
* across largely identical devices.
|
||||
*/
|
||||
void add_device_randomness(const void *buf, unsigned int size)
|
||||
{
|
||||
return irq_timer_state[irq];
|
||||
unsigned long time = get_cycles() ^ jiffies;
|
||||
|
||||
mix_pool_bytes(&input_pool, buf, size, NULL);
|
||||
mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
|
||||
mix_pool_bytes(&nonblocking_pool, buf, size, NULL);
|
||||
mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL);
|
||||
}
|
||||
|
||||
static void set_timer_rand_state(unsigned int irq,
|
||||
struct timer_rand_state *state)
|
||||
{
|
||||
irq_timer_state[irq] = state;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
|
||||
{
|
||||
struct irq_desc *desc;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
|
||||
return desc->timer_rand_state;
|
||||
}
|
||||
|
||||
static void set_timer_rand_state(unsigned int irq,
|
||||
struct timer_rand_state *state)
|
||||
{
|
||||
struct irq_desc *desc;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
|
||||
desc->timer_rand_state = state;
|
||||
}
|
||||
#endif
|
||||
EXPORT_SYMBOL(add_device_randomness);
|
||||
|
||||
static struct timer_rand_state input_timer_state;
|
||||
|
||||
|
|
@ -624,8 +670,8 @@ static struct timer_rand_state input_timer_state;
|
|||
static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
|
||||
{
|
||||
struct {
|
||||
cycles_t cycles;
|
||||
long jiffies;
|
||||
unsigned cycles;
|
||||
unsigned num;
|
||||
} sample;
|
||||
long delta, delta2, delta3;
|
||||
|
|
@ -639,7 +685,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
|
|||
sample.jiffies = jiffies;
|
||||
sample.cycles = get_cycles();
|
||||
sample.num = num;
|
||||
mix_pool_bytes(&input_pool, &sample, sizeof(sample));
|
||||
mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);
|
||||
|
||||
/*
|
||||
* Calculate number of bits of randomness we probably added.
|
||||
|
|
@ -696,17 +742,48 @@ void add_input_randomness(unsigned int type, unsigned int code,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(add_input_randomness);
|
||||
|
||||
void add_interrupt_randomness(int irq)
|
||||
static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
|
||||
|
||||
void add_interrupt_randomness(int irq, int irq_flags)
|
||||
{
|
||||
struct timer_rand_state *state;
|
||||
struct entropy_store *r;
|
||||
struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness);
|
||||
struct pt_regs *regs = get_irq_regs();
|
||||
unsigned long now = jiffies;
|
||||
__u32 input[4], cycles = get_cycles();
|
||||
|
||||
state = get_timer_rand_state(irq);
|
||||
input[0] = cycles ^ jiffies;
|
||||
input[1] = irq;
|
||||
if (regs) {
|
||||
__u64 ip = instruction_pointer(regs);
|
||||
input[2] = ip;
|
||||
input[3] = ip >> 32;
|
||||
}
|
||||
|
||||
if (state == NULL)
|
||||
fast_mix(fast_pool, input, sizeof(input));
|
||||
|
||||
if ((fast_pool->count & 1023) &&
|
||||
!time_after(now, fast_pool->last + HZ))
|
||||
return;
|
||||
|
||||
DEBUG_ENT("irq event %d\n", irq);
|
||||
add_timer_randomness(state, 0x100 + irq);
|
||||
fast_pool->last = now;
|
||||
|
||||
r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
|
||||
__mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
|
||||
/*
|
||||
* If we don't have a valid cycle counter, and we see
|
||||
* back-to-back timer interrupts, then skip giving credit for
|
||||
* any entropy.
|
||||
*/
|
||||
if (cycles == 0) {
|
||||
if (irq_flags & __IRQF_TIMER) {
|
||||
if (fast_pool->last_timer_intr)
|
||||
return;
|
||||
fast_pool->last_timer_intr = 1;
|
||||
} else
|
||||
fast_pool->last_timer_intr = 0;
|
||||
}
|
||||
credit_entropy_bits(r, 1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
|
|
@ -738,7 +815,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|||
*/
|
||||
static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
|
||||
{
|
||||
__u32 tmp[OUTPUT_POOL_WORDS];
|
||||
__u32 tmp[OUTPUT_POOL_WORDS];
|
||||
|
||||
if (r->pull && r->entropy_count < nbytes * 8 &&
|
||||
r->entropy_count < r->poolinfo->POOLBITS) {
|
||||
|
|
@ -757,7 +834,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
|
|||
|
||||
bytes = extract_entropy(r->pull, tmp, bytes,
|
||||
random_read_wakeup_thresh / 8, rsvd);
|
||||
mix_pool_bytes(r, tmp, bytes);
|
||||
mix_pool_bytes(r, tmp, bytes, NULL);
|
||||
credit_entropy_bits(r, bytes*8);
|
||||
}
|
||||
}
|
||||
|
|
@ -816,13 +893,19 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
|
|||
static void extract_buf(struct entropy_store *r, __u8 *out)
|
||||
{
|
||||
int i;
|
||||
__u32 hash[5], workspace[SHA_WORKSPACE_WORDS];
|
||||
union {
|
||||
__u32 w[5];
|
||||
unsigned long l[LONGS(EXTRACT_SIZE)];
|
||||
} hash;
|
||||
__u32 workspace[SHA_WORKSPACE_WORDS];
|
||||
__u8 extract[64];
|
||||
unsigned long flags;
|
||||
|
||||
/* Generate a hash across the pool, 16 words (512 bits) at a time */
|
||||
sha_init(hash);
|
||||
sha_init(hash.w);
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
for (i = 0; i < r->poolinfo->poolwords; i += 16)
|
||||
sha_transform(hash, (__u8 *)(r->pool + i), workspace);
|
||||
sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
|
||||
|
||||
/*
|
||||
* We mix the hash back into the pool to prevent backtracking
|
||||
|
|
@ -833,13 +916,14 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
|
|||
* brute-forcing the feedback as hard as brute-forcing the
|
||||
* hash.
|
||||
*/
|
||||
mix_pool_bytes_extract(r, hash, sizeof(hash), extract);
|
||||
__mix_pool_bytes(r, hash.w, sizeof(hash.w), extract);
|
||||
spin_unlock_irqrestore(&r->lock, flags);
|
||||
|
||||
/*
|
||||
* To avoid duplicates, we atomically extract a portion of the
|
||||
* pool while mixing, and hash one final time.
|
||||
*/
|
||||
sha_transform(hash, extract, workspace);
|
||||
sha_transform(hash.w, extract, workspace);
|
||||
memset(extract, 0, sizeof(extract));
|
||||
memset(workspace, 0, sizeof(workspace));
|
||||
|
||||
|
|
@ -848,20 +932,32 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
|
|||
* pattern, we fold it in half. Thus, we always feed back
|
||||
* twice as much data as we output.
|
||||
*/
|
||||
hash[0] ^= hash[3];
|
||||
hash[1] ^= hash[4];
|
||||
hash[2] ^= rol32(hash[2], 16);
|
||||
memcpy(out, hash, EXTRACT_SIZE);
|
||||
memset(hash, 0, sizeof(hash));
|
||||
hash.w[0] ^= hash.w[3];
|
||||
hash.w[1] ^= hash.w[4];
|
||||
hash.w[2] ^= rol32(hash.w[2], 16);
|
||||
|
||||
/*
|
||||
* If we have a architectural hardware random number
|
||||
* generator, mix that in, too.
|
||||
*/
|
||||
for (i = 0; i < LONGS(EXTRACT_SIZE); i++) {
|
||||
unsigned long v;
|
||||
if (!arch_get_random_long(&v))
|
||||
break;
|
||||
hash.l[i] ^= v;
|
||||
}
|
||||
|
||||
memcpy(out, &hash, EXTRACT_SIZE);
|
||||
memset(&hash, 0, sizeof(hash));
|
||||
}
|
||||
|
||||
static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
||||
size_t nbytes, int min, int reserved)
|
||||
size_t nbytes, int min, int reserved)
|
||||
{
|
||||
ssize_t ret = 0, i;
|
||||
__u8 tmp[EXTRACT_SIZE];
|
||||
unsigned long flags;
|
||||
|
||||
trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
|
||||
xfer_secondary_pool(r, nbytes);
|
||||
nbytes = account(r, nbytes, min, reserved);
|
||||
|
||||
|
|
@ -869,6 +965,8 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|||
extract_buf(r, tmp);
|
||||
|
||||
if (fips_enabled) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
|
||||
panic("Hardware RNG duplicated output!\n");
|
||||
|
|
@ -894,6 +992,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
|
|||
ssize_t ret = 0, i;
|
||||
__u8 tmp[EXTRACT_SIZE];
|
||||
|
||||
trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_);
|
||||
xfer_secondary_pool(r, nbytes);
|
||||
nbytes = account(r, nbytes, 0, 0);
|
||||
|
||||
|
|
@ -927,8 +1026,9 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
|
|||
|
||||
/*
|
||||
* This function is the exported kernel interface. It returns some
|
||||
* number of good random numbers, suitable for seeding TCP sequence
|
||||
* numbers, etc.
|
||||
* number of good random numbers, suitable for key generation, seeding
|
||||
* TCP sequence numbers, etc. It does not use the hw random number
|
||||
* generator, if available; use get_random_bytes_arch() for that.
|
||||
*/
|
||||
void get_random_bytes(void *buf, int nbytes)
|
||||
{
|
||||
|
|
@ -936,6 +1036,39 @@ void get_random_bytes(void *buf, int nbytes)
|
|||
}
|
||||
EXPORT_SYMBOL(get_random_bytes);
|
||||
|
||||
/*
|
||||
* This function will use the architecture-specific hardware random
|
||||
* number generator if it is available. The arch-specific hw RNG will
|
||||
* almost certainly be faster than what we can do in software, but it
|
||||
* is impossible to verify that it is implemented securely (as
|
||||
* opposed, to, say, the AES encryption of a sequence number using a
|
||||
* key known by the NSA). So it's useful if we need the speed, but
|
||||
* only if we're willing to trust the hardware manufacturer not to
|
||||
* have put in a back door.
|
||||
*/
|
||||
void get_random_bytes_arch(void *buf, int nbytes)
|
||||
{
|
||||
char *p = buf;
|
||||
|
||||
trace_get_random_bytes(nbytes, _RET_IP_);
|
||||
while (nbytes) {
|
||||
unsigned long v;
|
||||
int chunk = min(nbytes, (int)sizeof(unsigned long));
|
||||
|
||||
if (!arch_get_random_long(&v))
|
||||
break;
|
||||
|
||||
memcpy(p, &v, chunk);
|
||||
p += chunk;
|
||||
nbytes -= chunk;
|
||||
}
|
||||
|
||||
if (nbytes)
|
||||
extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_bytes_arch);
|
||||
|
||||
|
||||
/*
|
||||
* init_std_data - initialize pool with system data
|
||||
*
|
||||
|
|
@ -947,18 +1080,31 @@ EXPORT_SYMBOL(get_random_bytes);
|
|||
*/
|
||||
static void init_std_data(struct entropy_store *r)
|
||||
{
|
||||
ktime_t now;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
ktime_t now = ktime_get_real();
|
||||
unsigned long rv;
|
||||
|
||||
spin_lock_irqsave(&r->lock, flags);
|
||||
r->entropy_count = 0;
|
||||
spin_unlock_irqrestore(&r->lock, flags);
|
||||
|
||||
now = ktime_get_real();
|
||||
mix_pool_bytes(r, &now, sizeof(now));
|
||||
mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
|
||||
r->entropy_total = 0;
|
||||
mix_pool_bytes(r, &now, sizeof(now), NULL);
|
||||
for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
|
||||
if (!arch_get_random_long(&rv))
|
||||
break;
|
||||
mix_pool_bytes(r, &rv, sizeof(rv), NULL);
|
||||
}
|
||||
mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that setup_arch() may call add_device_randomness()
|
||||
* long before we get here. This allows seeding of the pools
|
||||
* with some platform dependent data very early in the boot
|
||||
* process. But it limits our options here. We must use
|
||||
* statically allocated structures that already have all
|
||||
* initializations complete at compile time. We should also
|
||||
* take care not to overwrite the precious per platform data
|
||||
* we were given.
|
||||
*/
|
||||
static int rand_initialize(void)
|
||||
{
|
||||
init_std_data(&input_pool);
|
||||
|
|
@ -968,24 +1114,6 @@ static int rand_initialize(void)
|
|||
}
|
||||
module_init(rand_initialize);
|
||||
|
||||
void rand_initialize_irq(int irq)
|
||||
{
|
||||
struct timer_rand_state *state;
|
||||
|
||||
state = get_timer_rand_state(irq);
|
||||
|
||||
if (state)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If kzalloc returns null, we just won't use that entropy
|
||||
* source.
|
||||
*/
|
||||
state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
|
||||
if (state)
|
||||
set_timer_rand_state(irq, state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
void rand_initialize_disk(struct gendisk *disk)
|
||||
{
|
||||
|
|
@ -1093,7 +1221,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
|
|||
count -= bytes;
|
||||
p += bytes;
|
||||
|
||||
mix_pool_bytes(r, buf, bytes);
|
||||
mix_pool_bytes(r, buf, bytes, NULL);
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
|
|
@ -1236,10 +1364,15 @@ static int proc_do_uuid(ctl_table *table, int write,
|
|||
uuid = table->data;
|
||||
if (!uuid) {
|
||||
uuid = tmp_uuid;
|
||||
uuid[8] = 0;
|
||||
}
|
||||
if (uuid[8] == 0)
|
||||
generate_random_uuid(uuid);
|
||||
} else {
|
||||
static DEFINE_SPINLOCK(bootid_spinlock);
|
||||
|
||||
spin_lock(&bootid_spinlock);
|
||||
if (!uuid[8])
|
||||
generate_random_uuid(uuid);
|
||||
spin_unlock(&bootid_spinlock);
|
||||
}
|
||||
|
||||
sprintf(buf, "%pU", uuid);
|
||||
|
||||
|
|
@ -1318,9 +1451,14 @@ late_initcall(random_int_secret_init);
|
|||
DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
|
||||
unsigned int get_random_int(void)
|
||||
{
|
||||
__u32 *hash = get_cpu_var(get_random_int_hash);
|
||||
__u32 *hash;
|
||||
unsigned int ret;
|
||||
|
||||
if (arch_get_random_int(&ret))
|
||||
return ret;
|
||||
|
||||
hash = get_cpu_var(get_random_int_hash);
|
||||
|
||||
hash[0] += current->pid + jiffies + get_cycles();
|
||||
md5_transform(hash, random_int_secret);
|
||||
ret = hash[0];
|
||||
|
|
|
|||
|
|
@ -1842,11 +1842,9 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
|
|||
if (mce->bank != 8)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Only handle if it is the right mc controller */
|
||||
if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
smp_rmb();
|
||||
if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <linux/dmi.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/random.h>
|
||||
#include <asm/dmi.h>
|
||||
|
||||
/*
|
||||
|
|
@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
|
|||
|
||||
dmi_table(buf, dmi_len, dmi_num, decode, NULL);
|
||||
|
||||
add_device_randomness(buf, dmi_len);
|
||||
|
||||
dmi_iounmap(buf, dmi_len);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline)
|
|||
if (efi.hcdp == EFI_INVALID_TABLE_ADDR)
|
||||
return -ENODEV;
|
||||
|
||||
pcdp = ioremap(efi.hcdp, 4096);
|
||||
pcdp = early_ioremap(efi.hcdp, 4096);
|
||||
printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp);
|
||||
|
||||
if (strstr(cmdline, "console=hcdp")) {
|
||||
|
|
@ -131,6 +131,6 @@ efi_setup_pcdp_console(char *cmdline)
|
|||
}
|
||||
|
||||
out:
|
||||
iounmap(pcdp);
|
||||
early_iounmap(pcdp, 4096);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
* Jerome Glisse
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
|
|
@ -624,7 +625,6 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector,
|
|||
ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS,
|
||||
link_status, DP_LINK_STATUS_SIZE, 100);
|
||||
if (ret <= 0) {
|
||||
DRM_ERROR("displayport link status failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -797,8 +797,10 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
|
|||
else
|
||||
mdelay(dp_info->rd_interval * 4);
|
||||
|
||||
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
|
||||
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
|
||||
DRM_ERROR("displayport link status failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
|
||||
clock_recovery = true;
|
||||
|
|
@ -860,8 +862,10 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
|
|||
else
|
||||
mdelay(dp_info->rd_interval * 4);
|
||||
|
||||
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
|
||||
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
|
||||
DRM_ERROR("displayport link status failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
|
||||
channel_eq = true;
|
||||
|
|
|
|||
|
|
@ -66,14 +66,33 @@ void radeon_connector_hotplug(struct drm_connector *connector)
|
|||
|
||||
/* just deal with DP (not eDP) here. */
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||
int saved_dpms = connector->dpms;
|
||||
struct radeon_connector_atom_dig *dig_connector =
|
||||
radeon_connector->con_priv;
|
||||
|
||||
/* Only turn off the display it it's physically disconnected */
|
||||
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
else if (radeon_dp_needs_link_train(radeon_connector))
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
connector->dpms = saved_dpms;
|
||||
/* if existing sink type was not DP no need to retrain */
|
||||
if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT)
|
||||
return;
|
||||
|
||||
/* first get sink type as it may be reset after (un)plug */
|
||||
dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
|
||||
/* don't do anything if sink is not display port, i.e.,
|
||||
* passive dp->(dvi|hdmi) adaptor
|
||||
*/
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
||||
int saved_dpms = connector->dpms;
|
||||
/* Only turn off the display if it's physically disconnected */
|
||||
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
} else if (radeon_dp_needs_link_train(radeon_connector)) {
|
||||
/* set it to OFF so that drm_helper_connector_dpms()
|
||||
* won't return immediately since the current state
|
||||
* is ON at this point.
|
||||
*/
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
connector->dpms = saved_dpms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -257,8 +257,14 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
|
|||
if (!(cursor_end & 0x7f))
|
||||
w--;
|
||||
}
|
||||
if (w <= 0)
|
||||
if (w <= 0) {
|
||||
w = 1;
|
||||
cursor_end = x - xorigin + w;
|
||||
if (!(cursor_end & 0x7f)) {
|
||||
x--;
|
||||
WARN_ON_ONCE(x < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,16 +47,15 @@
|
|||
#define MAX_ATTRS 5 /* Maximum no of per-core attrs */
|
||||
#define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id
|
||||
#define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id
|
||||
#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu))
|
||||
#else
|
||||
#define TO_PHYS_ID(cpu) (cpu)
|
||||
#define TO_CORE_ID(cpu) (cpu)
|
||||
#define for_each_sibling(i, cpu) for (i = 0; false; )
|
||||
#endif
|
||||
#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
|
||||
|
||||
/*
|
||||
* Per-Core Temperature Data
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
|
|||
input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
|
||||
input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
|
||||
if (wacom->tool[0] != BTN_TOOL_MOUSE) {
|
||||
input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
|
||||
input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8));
|
||||
input_report_key(input, BTN_TOUCH, data[1] & 0x01);
|
||||
input_report_key(input, BTN_STYLUS, data[1] & 0x02);
|
||||
input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
|
||||
|
|
|
|||
|
|
@ -1210,7 +1210,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
|||
* We need to dec pending if this was a write.
|
||||
*/
|
||||
if (rw == WRITE) {
|
||||
if (!(bio->bi_rw & REQ_FLUSH))
|
||||
if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)))
|
||||
dm_rh_dec(ms->rh, map_context->ll);
|
||||
return error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
|
|||
return;
|
||||
}
|
||||
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
return;
|
||||
|
||||
/* We must inform the log that the sync count has changed. */
|
||||
log->type->set_region_sync(log, region, 0);
|
||||
|
||||
|
|
@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
|
|||
struct bio *bio;
|
||||
|
||||
for (bio = bios->head; bio; bio = bio->bi_next) {
|
||||
if (bio->bi_rw & REQ_FLUSH)
|
||||
if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))
|
||||
continue;
|
||||
rh_inc(rh, dm_rh_bio_to_region(rh, bio));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,8 +408,6 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data)
|
|||
u32 fatevent;
|
||||
int err;
|
||||
|
||||
add_interrupt_randomness(irq);
|
||||
|
||||
err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
|
||||
event_regs, 3);
|
||||
if (err)
|
||||
|
|
@ -938,9 +936,6 @@ static int __devinit ab3100_probe(struct i2c_client *client,
|
|||
|
||||
err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
|
||||
IRQF_ONESHOT, "ab3100-core", ab3100);
|
||||
/* This real unpredictable IRQ is of course sampled for entropy */
|
||||
rand_initialize_irq(client->irq);
|
||||
|
||||
if (err)
|
||||
goto exit_no_irq;
|
||||
|
||||
|
|
|
|||
|
|
@ -1309,8 +1309,6 @@ static int __init ab3550_probe(struct i2c_client *client,
|
|||
|
||||
err = request_threaded_irq(client->irq, NULL, ab3550_irq_handler,
|
||||
IRQF_ONESHOT, "ab3550-core", ab);
|
||||
/* This real unpredictable IRQ is of course sampled for entropy */
|
||||
rand_initialize_irq(client->irq);
|
||||
|
||||
if (err)
|
||||
goto exit_no_irq;
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work)
|
|||
}
|
||||
local_irq_enable();
|
||||
ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
|
||||
} while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
|
||||
} while (gpio_get_value(pdata->gpio));
|
||||
}
|
||||
|
||||
static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/bcd.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <linux/mfd/wm831x/core.h>
|
||||
#include <linux/mfd/wm831x/otp.h>
|
||||
|
|
@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL);
|
|||
|
||||
int wm831x_otp_init(struct wm831x *wm831x)
|
||||
{
|
||||
char uuid[WM831X_UNIQUE_ID_LEN];
|
||||
int ret;
|
||||
|
||||
ret = device_create_file(wm831x->dev, &dev_attr_unique_id);
|
||||
|
|
@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831x)
|
|||
dev_err(wm831x->dev, "Unique ID attribute not created: %d\n",
|
||||
ret);
|
||||
|
||||
ret = wm831x_unique_id_read(wm831x, uuid);
|
||||
if (ret == 0)
|
||||
add_device_randomness(uuid, sizeof(uuid));
|
||||
else
|
||||
dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = {
|
|||
static const struct sdhci_pci_fixes sdhci_cafe = {
|
||||
.quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
|
||||
SDHCI_QUIRK_NO_BUSY_IRQ |
|
||||
SDHCI_QUIRK_BROKEN_CARD_DETECTION |
|
||||
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5310,7 +5310,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
|
|||
int k, last;
|
||||
|
||||
if (skb == NULL) {
|
||||
j++;
|
||||
j = NEXT_TX_BD(j);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -5322,8 +5322,8 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
|
|||
tx_buf->skb = NULL;
|
||||
|
||||
last = tx_buf->nr_frags;
|
||||
j++;
|
||||
for (k = 0; k < last; k++, j++) {
|
||||
j = NEXT_TX_BD(j);
|
||||
for (k = 0; k < last; k++, j = NEXT_TX_BD(j)) {
|
||||
tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)];
|
||||
dma_unmap_page(&bp->pdev->dev,
|
||||
dma_unmap_addr(tx_buf, mapping),
|
||||
|
|
|
|||
|
|
@ -325,6 +325,9 @@ static int ldisc_open(struct tty_struct *tty)
|
|||
|
||||
sprintf(name, "cf%s", tty->name);
|
||||
dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
ser = netdev_priv(dev);
|
||||
ser->tty = tty_kref_get(tty);
|
||||
ser->dev = dev;
|
||||
|
|
|
|||
|
|
@ -1602,10 +1602,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
|||
* auto-negotiation in the TXCW register and disable
|
||||
* forced link in the Device Control register in an
|
||||
* attempt to auto-negotiate with our link partner.
|
||||
* If the partner code word is null, stop forcing
|
||||
* and restart auto negotiation.
|
||||
*/
|
||||
if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) {
|
||||
if (rxcw & E1000_RXCW_C) {
|
||||
/* Enable autoneg, and unforce link up */
|
||||
ew32(TXCW, mac->txcw);
|
||||
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
|
||||
|
|
|
|||
|
|
@ -1245,10 +1245,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
|
||||
if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) {
|
||||
if (copy_from_user(&ifr, argp, ifreq_len))
|
||||
return -EFAULT;
|
||||
|
||||
} else {
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
}
|
||||
if (cmd == TUNGETFEATURES) {
|
||||
/* Currently this just means: "what IFF flags are valid?".
|
||||
* This is needed because we never checked for invalid flags on
|
||||
|
|
|
|||
|
|
@ -1308,7 +1308,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev,
|
|||
int retv;
|
||||
int length = 0; /* shut up GCC */
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_NOIO);
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/mfd/wm831x/core.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
/*
|
||||
* R16416 (0x4020) - RTC Write Counter
|
||||
|
|
@ -96,6 +96,26 @@ struct wm831x_rtc {
|
|||
unsigned int alarm_enabled:1;
|
||||
};
|
||||
|
||||
static void wm831x_rtc_add_randomness(struct wm831x *wm831x)
|
||||
{
|
||||
int ret;
|
||||
u16 reg;
|
||||
|
||||
/*
|
||||
* The write counter contains a pseudo-random number which is
|
||||
* regenerated every time we set the RTC so it should be a
|
||||
* useful per-system source of entropy.
|
||||
*/
|
||||
ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER);
|
||||
if (ret >= 0) {
|
||||
reg = ret;
|
||||
add_device_randomness(®, sizeof(reg));
|
||||
} else {
|
||||
dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read current time and date in RTC
|
||||
*/
|
||||
|
|
@ -469,6 +489,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
|
|||
alm_irq, ret);
|
||||
}
|
||||
|
||||
wm831x_rtc_add_randomness(wm831x);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ static struct domain_device *sas_ex_discover_end_dev(
|
|||
}
|
||||
|
||||
/* See if this phy is part of a wide port */
|
||||
static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
||||
static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
||||
{
|
||||
struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
|
||||
int i;
|
||||
|
|
@ -786,11 +786,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
|
|||
sas_port_add_phy(ephy->port, phy->phy);
|
||||
phy->port = ephy->port;
|
||||
phy->phy_state = PHY_DEVICE_DISCOVERED;
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct domain_device *sas_ex_discover_expander(
|
||||
|
|
@ -928,8 +928,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
|
|||
return res;
|
||||
}
|
||||
|
||||
res = sas_ex_join_wide_port(dev, phy_id);
|
||||
if (!res) {
|
||||
if (sas_ex_join_wide_port(dev, phy_id)) {
|
||||
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
||||
phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
|
||||
return res;
|
||||
|
|
@ -974,8 +973,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
|
|||
if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
|
||||
SAS_ADDR(child->sas_addr)) {
|
||||
ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
|
||||
res = sas_ex_join_wide_port(dev, i);
|
||||
if (!res)
|
||||
if (sas_ex_join_wide_port(dev, i))
|
||||
SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
|
||||
i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
|
||||
|
||||
|
|
@ -1838,32 +1836,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
|
|||
{
|
||||
struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
|
||||
struct domain_device *child;
|
||||
bool found = false;
|
||||
int res, i;
|
||||
int res;
|
||||
|
||||
SAS_DPRINTK("ex %016llx phy%d new device attached\n",
|
||||
SAS_ADDR(dev->sas_addr), phy_id);
|
||||
res = sas_ex_phy_discover(dev, phy_id);
|
||||
if (res)
|
||||
goto out;
|
||||
/* to support the wide port inserted */
|
||||
for (i = 0; i < dev->ex_dev.num_phys; i++) {
|
||||
struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i];
|
||||
if (i == phy_id)
|
||||
continue;
|
||||
if (SAS_ADDR(ex_phy_temp->attached_sas_addr) ==
|
||||
SAS_ADDR(ex_phy->attached_sas_addr)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
sas_ex_join_wide_port(dev, phy_id);
|
||||
return res;
|
||||
|
||||
if (sas_ex_join_wide_port(dev, phy_id))
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = sas_ex_discover_devices(dev, phy_id);
|
||||
if (!res)
|
||||
goto out;
|
||||
if (res)
|
||||
return res;
|
||||
list_for_each_entry(child, &dev->ex_dev.children, siblings) {
|
||||
if (SAS_ADDR(child->sas_addr) ==
|
||||
SAS_ADDR(ex_phy->attached_sas_addr)) {
|
||||
|
|
@ -1873,7 +1859,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id)
|
|||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1972,9 +1957,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev)
|
|||
struct domain_device *dev = NULL;
|
||||
|
||||
res = sas_find_bcast_dev(port_dev, &dev);
|
||||
if (res)
|
||||
goto out;
|
||||
if (dev) {
|
||||
while (res == 0 && dev) {
|
||||
struct expander_device *ex = &dev->ex_dev;
|
||||
int i = 0, phy_id;
|
||||
|
||||
|
|
@ -1986,8 +1969,10 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev)
|
|||
res = sas_rediscover(dev, phy_id);
|
||||
i = phy_id + 1;
|
||||
} while (i < ex->num_phys);
|
||||
|
||||
dev = NULL;
|
||||
res = sas_find_bcast_dev(port_dev, &dev);
|
||||
}
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1665,6 +1665,20 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
|
|||
* requests are started.
|
||||
*/
|
||||
scsi_run_host_queues(shost);
|
||||
|
||||
/*
|
||||
* if eh is active and host_eh_scheduled is pending we need to re-run
|
||||
* recovery. we do this check after scsi_run_host_queues() to allow
|
||||
* everything pent up since the last eh run a chance to make forward
|
||||
* progress before we sync again. Either we'll immediately re-run
|
||||
* recovery or scsi_device_unbusy() will wake us again when these
|
||||
* pending commands complete.
|
||||
*/
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (shost->host_eh_scheduled)
|
||||
if (scsi_host_set_state(shost, SHOST_RECOVERY))
|
||||
WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY));
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -481,15 +481,26 @@ void scsi_requeue_run_queue(struct work_struct *work)
|
|||
*/
|
||||
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
struct request *req = cmd->request;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* We need to hold a reference on the device to avoid the queue being
|
||||
* killed after the unlock and before scsi_run_queue is invoked which
|
||||
* may happen because scsi_unprep_request() puts the command which
|
||||
* releases its reference on the device.
|
||||
*/
|
||||
get_device(&sdev->sdev_gendev);
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
scsi_unprep_request(req);
|
||||
blk_requeue_request(q, req);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
scsi_run_queue(q);
|
||||
|
||||
put_device(&sdev->sdev_gendev);
|
||||
}
|
||||
|
||||
void scsi_next_command(struct scsi_cmnd *cmd)
|
||||
|
|
|
|||
|
|
@ -1710,6 +1710,9 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
|
|||
{
|
||||
struct scsi_device *sdev;
|
||||
shost_for_each_device(sdev, shost) {
|
||||
/* target removed before the device could be added */
|
||||
if (sdev->sdev_state == SDEV_DEL)
|
||||
continue;
|
||||
if (!scsi_host_scan_allowed(shost) ||
|
||||
scsi_sysfs_add_sdev(sdev) != 0)
|
||||
__scsi_remove_device(sdev);
|
||||
|
|
|
|||
|
|
@ -962,7 +962,6 @@ static void __scsi_remove_target(struct scsi_target *starget)
|
|||
struct scsi_device *sdev;
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
starget->reap_ref++;
|
||||
restart:
|
||||
list_for_each_entry(sdev, &shost->__devices, siblings) {
|
||||
if (sdev->channel != starget->channel ||
|
||||
|
|
@ -976,14 +975,6 @@ static void __scsi_remove_target(struct scsi_target *starget)
|
|||
goto restart;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_target_reap(starget);
|
||||
}
|
||||
|
||||
static int __remove_child (struct device * dev, void * data)
|
||||
{
|
||||
if (scsi_is_target_device(dev))
|
||||
__scsi_remove_target(to_scsi_target(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -996,14 +987,34 @@ static int __remove_child (struct device * dev, void * data)
|
|||
*/
|
||||
void scsi_remove_target(struct device *dev)
|
||||
{
|
||||
if (scsi_is_target_device(dev)) {
|
||||
__scsi_remove_target(to_scsi_target(dev));
|
||||
return;
|
||||
}
|
||||
struct Scsi_Host *shost = dev_to_shost(dev->parent);
|
||||
struct scsi_target *starget, *found;
|
||||
unsigned long flags;
|
||||
|
||||
get_device(dev);
|
||||
device_for_each_child(dev, NULL, __remove_child);
|
||||
put_device(dev);
|
||||
restart:
|
||||
found = NULL;
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
list_for_each_entry(starget, &shost->__targets, siblings) {
|
||||
if (starget->state == STARGET_DEL)
|
||||
continue;
|
||||
if (starget->dev.parent == dev || &starget->dev == dev) {
|
||||
found = starget;
|
||||
found->reap_ref++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
if (found) {
|
||||
__scsi_remove_target(found);
|
||||
scsi_target_reap(found);
|
||||
/* in the case where @dev has multiple starget children,
|
||||
* continue removing.
|
||||
*
|
||||
* FIXME: does such a case exist?
|
||||
*/
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_remove_target);
|
||||
|
||||
|
|
|
|||
|
|
@ -1557,10 +1557,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
|
|||
void __user *addr = as->userurb;
|
||||
unsigned int i;
|
||||
|
||||
if (as->userbuffer && urb->actual_length)
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
|
||||
urb->actual_length))
|
||||
if (as->userbuffer && urb->actual_length) {
|
||||
if (urb->number_of_packets > 0) /* Isochronous */
|
||||
i = urb->transfer_buffer_length;
|
||||
else /* Non-Isoc */
|
||||
i = urb->actual_length;
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
|
||||
return -EFAULT;
|
||||
}
|
||||
if (put_user(as->status, &userurb->status))
|
||||
return -EFAULT;
|
||||
if (put_user(urb->actual_length, &userurb->actual_length))
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
|
@ -1905,6 +1906,14 @@ int usb_new_device(struct usb_device *udev)
|
|||
/* Tell the world! */
|
||||
announce_device(udev);
|
||||
|
||||
if (udev->serial)
|
||||
add_device_randomness(udev->serial, strlen(udev->serial));
|
||||
if (udev->product)
|
||||
add_device_randomness(udev->product, strlen(udev->product));
|
||||
if (udev->manufacturer)
|
||||
add_device_randomness(udev->manufacturer,
|
||||
strlen(udev->manufacturer));
|
||||
|
||||
/* kever@rk 20111205
|
||||
* We don't use async suspend in rk29 usb
|
||||
* to make sure usb1.1 host is suspend before usb 2.0 host.
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void)
|
|||
writel(FLAG_CF, &ehci_regs->configured_flag);
|
||||
|
||||
/* Wait until the controller is no longer halted */
|
||||
loop = 10;
|
||||
loop = 1000;
|
||||
do {
|
||||
status = readl(&ehci_regs->status);
|
||||
if (!(status & STS_HALT))
|
||||
|
|
|
|||
|
|
@ -823,12 +823,6 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
|
|||
|
||||
SET_ETHTOOL_OPS(net, &ops);
|
||||
|
||||
/* two kinds of host-initiated state changes:
|
||||
* - iff DATA transfer is active, carrier is "on"
|
||||
* - tx queueing enabled if open *and* carrier is "on"
|
||||
*/
|
||||
netif_carrier_off(net);
|
||||
|
||||
dev->gadget = g;
|
||||
SET_NETDEV_DEV(net, &g->dev);
|
||||
SET_NETDEV_DEVTYPE(net, &gadget_type);
|
||||
|
|
@ -842,6 +836,12 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
|
|||
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
|
||||
|
||||
the_dev = dev;
|
||||
|
||||
/* two kinds of host-initiated state changes:
|
||||
* - iff DATA transfer is active, carrier is "on"
|
||||
* - tx queueing enabled if open *and* carrier is "on"
|
||||
*/
|
||||
netif_carrier_off(net);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -212,10 +212,17 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers,
|
|||
|
||||
work->ordered_func(work);
|
||||
|
||||
/* now take the lock again and call the freeing code */
|
||||
/* now take the lock again and drop our item from the list */
|
||||
spin_lock(&workers->order_lock);
|
||||
list_del(&work->order_list);
|
||||
spin_unlock(&workers->order_lock);
|
||||
|
||||
/*
|
||||
* we don't want to call the ordered free functions
|
||||
* with the lock held though
|
||||
*/
|
||||
work->ordered_free(work);
|
||||
spin_lock(&workers->order_lock);
|
||||
}
|
||||
|
||||
spin_unlock(&workers->order_lock);
|
||||
|
|
|
|||
|
|
@ -801,7 +801,8 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
|
|||
|
||||
#ifdef CONFIG_MIGRATION
|
||||
static int btree_migratepage(struct address_space *mapping,
|
||||
struct page *newpage, struct page *page)
|
||||
struct page *newpage, struct page *page,
|
||||
enum migrate_mode mode)
|
||||
{
|
||||
/*
|
||||
* we can't safely write a btree page from here,
|
||||
|
|
@ -816,7 +817,7 @@ static int btree_migratepage(struct address_space *mapping,
|
|||
if (page_has_private(page) &&
|
||||
!try_to_release_page(page, GFP_KERNEL))
|
||||
return -EAGAIN;
|
||||
return migrate_page(mapping, newpage, page);
|
||||
return migrate_page(mapping, newpage, page, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -85,9 +85,12 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
|
|||
|
||||
dentry = d_lookup(parent, name);
|
||||
if (dentry) {
|
||||
/* FIXME: check for inode number changes? */
|
||||
if (dentry->d_inode != NULL)
|
||||
inode = dentry->d_inode;
|
||||
/* update inode in place if i_ino didn't change */
|
||||
if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
|
||||
cifs_fattr_to_inode(inode, fattr);
|
||||
return dentry;
|
||||
}
|
||||
d_drop(dentry);
|
||||
dput(dentry);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,7 +514,8 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
|
|||
if (bitmap_bh == NULL)
|
||||
continue;
|
||||
|
||||
x = ext4_count_free(bitmap_bh, sb->s_blocksize);
|
||||
x = ext4_count_free(bitmap_bh->b_data,
|
||||
EXT4_BLOCKS_PER_GROUP(sb) / 8);
|
||||
printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n",
|
||||
i, ext4_free_blks_count(sb, gdp), x);
|
||||
bitmap_count += x;
|
||||
|
|
|
|||
|
|
@ -15,15 +15,13 @@
|
|||
|
||||
static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
|
||||
|
||||
unsigned int ext4_count_free(struct buffer_head *map, unsigned int numchars)
|
||||
unsigned int ext4_count_free(char *bitmap, unsigned int numchars)
|
||||
{
|
||||
unsigned int i, sum = 0;
|
||||
|
||||
if (!map)
|
||||
return 0;
|
||||
for (i = 0; i < numchars; i++)
|
||||
sum += nibblemap[map->b_data[i] & 0xf] +
|
||||
nibblemap[(map->b_data[i] >> 4) & 0xf];
|
||||
sum += nibblemap[bitmap[i] & 0xf] +
|
||||
nibblemap[(bitmap[i] >> 4) & 0xf];
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1713,7 +1713,7 @@ struct mmpd_data {
|
|||
# define NORET_AND noreturn,
|
||||
|
||||
/* bitmap.c */
|
||||
extern unsigned int ext4_count_free(struct buffer_head *, unsigned);
|
||||
extern unsigned int ext4_count_free(char *bitmap, unsigned numchars);
|
||||
|
||||
/* balloc.c */
|
||||
extern unsigned int ext4_block_group(struct super_block *sb,
|
||||
|
|
|
|||
|
|
@ -1193,7 +1193,8 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
|
|||
if (!bitmap_bh)
|
||||
continue;
|
||||
|
||||
x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
|
||||
x = ext4_count_free(bitmap_bh->b_data,
|
||||
EXT4_INODES_PER_GROUP(sb) / 8);
|
||||
printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
|
||||
(unsigned long) i, ext4_free_inodes_count(sb, gdp), x);
|
||||
bitmap_count += x;
|
||||
|
|
|
|||
|
|
@ -1134,6 +1134,15 @@ void ext4_da_update_reserve_space(struct inode *inode,
|
|||
used = ei->i_reserved_data_blocks;
|
||||
}
|
||||
|
||||
if (unlikely(ei->i_allocated_meta_blocks > ei->i_reserved_meta_blocks)) {
|
||||
ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, allocated %d "
|
||||
"with only %d reserved metadata blocks\n", __func__,
|
||||
inode->i_ino, ei->i_allocated_meta_blocks,
|
||||
ei->i_reserved_meta_blocks);
|
||||
WARN_ON(1);
|
||||
ei->i_allocated_meta_blocks = ei->i_reserved_meta_blocks;
|
||||
}
|
||||
|
||||
/* Update per-inode reservations */
|
||||
ei->i_reserved_data_blocks -= used;
|
||||
ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks;
|
||||
|
|
|
|||
|
|
@ -568,7 +568,8 @@ static int hugetlbfs_set_page_dirty(struct page *page)
|
|||
}
|
||||
|
||||
static int hugetlbfs_migrate_page(struct address_space *mapping,
|
||||
struct page *newpage, struct page *page)
|
||||
struct page *newpage, struct page *page,
|
||||
enum migrate_mode mode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ static int flock_make_lock(struct file *filp, struct file_lock **lock,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int assign_type(struct file_lock *fl, int type)
|
||||
static int assign_type(struct file_lock *fl, long type)
|
||||
{
|
||||
switch (type) {
|
||||
case F_RDLCK:
|
||||
|
|
@ -452,7 +452,7 @@ static const struct lock_manager_operations lease_manager_ops = {
|
|||
/*
|
||||
* Initialize a lease, use the default lock manager operations
|
||||
*/
|
||||
static int lease_init(struct file *filp, int type, struct file_lock *fl)
|
||||
static int lease_init(struct file *filp, long type, struct file_lock *fl)
|
||||
{
|
||||
if (assign_type(fl, type) != 0)
|
||||
return -EINVAL;
|
||||
|
|
@ -470,7 +470,7 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
|
|||
}
|
||||
|
||||
/* Allocate a file_lock initialised to this type of lease */
|
||||
static struct file_lock *lease_alloc(struct file *filp, int type)
|
||||
static struct file_lock *lease_alloc(struct file *filp, long type)
|
||||
{
|
||||
struct file_lock *fl = locks_alloc_lock();
|
||||
int error = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -493,8 +493,11 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
|
|||
|
||||
dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
|
||||
|
||||
/* Only do I/O if gfp is a superset of GFP_KERNEL */
|
||||
if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) {
|
||||
/* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not
|
||||
* doing this memory reclaim for a fs-related allocation.
|
||||
*/
|
||||
if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL &&
|
||||
!(current->flags & PF_FSTRANS)) {
|
||||
int how = FLUSH_SYNC;
|
||||
|
||||
/* Don't let kswapd deadlock waiting for OOM RPC calls */
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data);
|
|||
|
||||
#ifdef CONFIG_MIGRATION
|
||||
extern int nfs_migrate_page(struct address_space *,
|
||||
struct page *, struct page *);
|
||||
struct page *, struct page *, enum migrate_mode);
|
||||
#else
|
||||
#define nfs_migrate_page NULL
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1662,7 +1662,7 @@ out_error:
|
|||
|
||||
#ifdef CONFIG_MIGRATION
|
||||
int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
|
||||
struct page *page)
|
||||
struct page *page, enum migrate_mode mode)
|
||||
{
|
||||
/*
|
||||
* If PagePrivate is set, then the page is currently associated with
|
||||
|
|
@ -1677,7 +1677,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
|
|||
|
||||
nfs_fscache_release_page(page, GFP_KERNEL);
|
||||
|
||||
return migrate_page(mapping, newpage, page);
|
||||
return migrate_page(mapping, newpage, page, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2010,7 +2010,7 @@ out_acl:
|
|||
if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
|
||||
if ((buflen -= 4) < 0)
|
||||
goto out_resource;
|
||||
WRITE32(1);
|
||||
WRITE32(0);
|
||||
}
|
||||
if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
|
||||
if ((buflen -= 4) < 0)
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
|
|||
if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
|
||||
goto out;
|
||||
|
||||
down_read(&inode->i_sb->s_umount);
|
||||
mutex_lock(&nilfs->ns_snapshot_mount_mutex);
|
||||
|
||||
nilfs_transaction_begin(inode->i_sb, &ti, 0);
|
||||
ret = nilfs_cpfile_change_cpmode(
|
||||
|
|
@ -192,7 +192,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
|
|||
else
|
||||
nilfs_transaction_commit(inode->i_sb); /* never fails */
|
||||
|
||||
up_read(&inode->i_sb->s_umount);
|
||||
mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
|
||||
out:
|
||||
mnt_drop_write(filp->f_path.mnt);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -951,6 +951,8 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
|
|||
struct nilfs_root *root;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&nilfs->ns_snapshot_mount_mutex);
|
||||
|
||||
down_read(&nilfs->ns_segctor_sem);
|
||||
ret = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, cno);
|
||||
up_read(&nilfs->ns_segctor_sem);
|
||||
|
|
@ -975,6 +977,7 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
|
|||
ret = nilfs_get_root_dentry(s, root, root_dentry);
|
||||
nilfs_put_root(root);
|
||||
out:
|
||||
mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
|
|||
nilfs->ns_bdev = bdev;
|
||||
atomic_set(&nilfs->ns_ndirtyblks, 0);
|
||||
init_rwsem(&nilfs->ns_sem);
|
||||
mutex_init(&nilfs->ns_snapshot_mount_mutex);
|
||||
INIT_LIST_HEAD(&nilfs->ns_dirty_files);
|
||||
INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
|
||||
spin_lock_init(&nilfs->ns_inode_lock);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ enum {
|
|||
* @ns_flags: flags
|
||||
* @ns_bdev: block device
|
||||
* @ns_sem: semaphore for shared states
|
||||
* @ns_snapshot_mount_mutex: mutex to protect snapshot mounts
|
||||
* @ns_sbh: buffer heads of on-disk super blocks
|
||||
* @ns_sbp: pointers to super block data
|
||||
* @ns_sbwtime: previous write time of super block
|
||||
|
|
@ -99,6 +100,7 @@ struct the_nilfs {
|
|||
|
||||
struct block_device *ns_bdev;
|
||||
struct rw_semaphore ns_sem;
|
||||
struct mutex ns_snapshot_mount_mutex;
|
||||
|
||||
/*
|
||||
* used for
|
||||
|
|
|
|||
|
|
@ -715,8 +715,12 @@ static int fixup_free_space(struct ubifs_info *c)
|
|||
lnum = ubifs_next_log_lnum(c, lnum);
|
||||
}
|
||||
|
||||
/* Fixup the current log head */
|
||||
err = fixup_leb(c, c->lhead_lnum, c->lhead_offs);
|
||||
/*
|
||||
* Fixup the log head which contains the only a CS node at the
|
||||
* beginning.
|
||||
*/
|
||||
err = fixup_leb(c, c->lhead_lnum,
|
||||
ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size));
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,9 @@ enum {
|
|||
/* migration should happen before other stuff but after perf */
|
||||
CPU_PRI_PERF = 20,
|
||||
CPU_PRI_MIGRATION = 10,
|
||||
/* prepare workqueues for other notifiers */
|
||||
CPU_PRI_WORKQUEUE = 5,
|
||||
/* bring up workqueues before normal notifiers and down after */
|
||||
CPU_PRI_WORKQUEUE_UP = 5,
|
||||
CPU_PRI_WORKQUEUE_DOWN = -5,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
|||
|
|
@ -89,42 +89,33 @@ extern void rebuild_sched_domains(void);
|
|||
extern void cpuset_print_task_mems_allowed(struct task_struct *p);
|
||||
|
||||
/*
|
||||
* reading current mems_allowed and mempolicy in the fastpath must protected
|
||||
* by get_mems_allowed()
|
||||
* get_mems_allowed is required when making decisions involving mems_allowed
|
||||
* such as during page allocation. mems_allowed can be updated in parallel
|
||||
* and depending on the new value an operation can fail potentially causing
|
||||
* process failure. A retry loop with get_mems_allowed and put_mems_allowed
|
||||
* prevents these artificial failures.
|
||||
*/
|
||||
static inline void get_mems_allowed(void)
|
||||
static inline unsigned int get_mems_allowed(void)
|
||||
{
|
||||
current->mems_allowed_change_disable++;
|
||||
|
||||
/*
|
||||
* ensure that reading mems_allowed and mempolicy happens after the
|
||||
* update of ->mems_allowed_change_disable.
|
||||
*
|
||||
* the write-side task finds ->mems_allowed_change_disable is not 0,
|
||||
* and knows the read-side task is reading mems_allowed or mempolicy,
|
||||
* so it will clear old bits lazily.
|
||||
*/
|
||||
smp_mb();
|
||||
return read_seqcount_begin(¤t->mems_allowed_seq);
|
||||
}
|
||||
|
||||
static inline void put_mems_allowed(void)
|
||||
/*
|
||||
* If this returns false, the operation that took place after get_mems_allowed
|
||||
* may have failed. It is up to the caller to retry the operation if
|
||||
* appropriate.
|
||||
*/
|
||||
static inline bool put_mems_allowed(unsigned int seq)
|
||||
{
|
||||
/*
|
||||
* ensure that reading mems_allowed and mempolicy before reducing
|
||||
* mems_allowed_change_disable.
|
||||
*
|
||||
* the write-side task will know that the read-side task is still
|
||||
* reading mems_allowed or mempolicy, don't clears old bits in the
|
||||
* nodemask.
|
||||
*/
|
||||
smp_mb();
|
||||
--ACCESS_ONCE(current->mems_allowed_change_disable);
|
||||
return !read_seqcount_retry(¤t->mems_allowed_seq, seq);
|
||||
}
|
||||
|
||||
static inline void set_mems_allowed(nodemask_t nodemask)
|
||||
{
|
||||
task_lock(current);
|
||||
write_seqcount_begin(¤t->mems_allowed_seq);
|
||||
current->mems_allowed = nodemask;
|
||||
write_seqcount_end(¤t->mems_allowed_seq);
|
||||
task_unlock(current);
|
||||
}
|
||||
|
||||
|
|
@ -234,12 +225,14 @@ static inline void set_mems_allowed(nodemask_t nodemask)
|
|||
{
|
||||
}
|
||||
|
||||
static inline void get_mems_allowed(void)
|
||||
static inline unsigned int get_mems_allowed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void put_mems_allowed(void)
|
||||
static inline bool put_mems_allowed(unsigned int seq)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_CPUSETS */
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ enum positive_aop_returns {
|
|||
struct page;
|
||||
struct address_space;
|
||||
struct writeback_control;
|
||||
enum migrate_mode;
|
||||
|
||||
struct iov_iter {
|
||||
const struct iovec *iov;
|
||||
|
|
@ -607,9 +608,12 @@ struct address_space_operations {
|
|||
loff_t offset, unsigned long nr_segs);
|
||||
int (*get_xip_mem)(struct address_space *, pgoff_t, int,
|
||||
void **, unsigned long *);
|
||||
/* migrate the contents of a page to the specified target */
|
||||
/*
|
||||
* migrate the contents of a page to the specified target. If sync
|
||||
* is false, it must not block.
|
||||
*/
|
||||
int (*migratepage) (struct address_space *,
|
||||
struct page *, struct page *);
|
||||
struct page *, struct page *, enum migrate_mode);
|
||||
int (*launder_page) (struct page *);
|
||||
int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
|
||||
unsigned long);
|
||||
|
|
@ -2478,7 +2482,8 @@ extern int generic_check_addressable(unsigned, u64);
|
|||
|
||||
#ifdef CONFIG_MIGRATION
|
||||
extern int buffer_migrate_page(struct address_space *,
|
||||
struct page *, struct page *);
|
||||
struct page *, struct page *,
|
||||
enum migrate_mode);
|
||||
#else
|
||||
#define buffer_migrate_page NULL
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@ extern struct fs_struct init_fs;
|
|||
#define INIT_THREADGROUP_FORK_LOCK(sig)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPUSETS
|
||||
#define INIT_CPUSET_SEQ \
|
||||
.mems_allowed_seq = SEQCNT_ZERO,
|
||||
#else
|
||||
#define INIT_CPUSET_SEQ
|
||||
#endif
|
||||
|
||||
#define INIT_SIGNALS(sig) { \
|
||||
.nr_threads = 1, \
|
||||
.wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\
|
||||
|
|
@ -193,6 +200,7 @@ extern struct cred init_cred;
|
|||
INIT_FTRACE_GRAPH \
|
||||
INIT_TRACE_RECURSION \
|
||||
INIT_TASK_RCU_PREEMPT(tsk) \
|
||||
INIT_CPUSET_SEQ \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ struct timer_rand_state;
|
|||
*/
|
||||
struct irq_desc {
|
||||
struct irq_data irq_data;
|
||||
struct timer_rand_state *timer_rand_state;
|
||||
unsigned int __percpu *kstat_irqs;
|
||||
irq_flow_handler_t handle_irq;
|
||||
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ enum mem_cgroup_page_stat_item {
|
|||
extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
|
||||
struct list_head *dst,
|
||||
unsigned long *scanned, int order,
|
||||
int mode, struct zone *z,
|
||||
isolate_mode_t mode,
|
||||
struct zone *z,
|
||||
struct mem_cgroup *mem_cont,
|
||||
int active, int file);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ struct pcap_subdev {
|
|||
struct pcap_platform_data {
|
||||
unsigned int irq_base;
|
||||
unsigned int config;
|
||||
int gpio;
|
||||
void (*init) (void *); /* board specific init */
|
||||
int num_subdevs;
|
||||
struct pcap_subdev *subdevs;
|
||||
|
|
|
|||
|
|
@ -6,18 +6,31 @@
|
|||
|
||||
typedef struct page *new_page_t(struct page *, unsigned long private, int **);
|
||||
|
||||
/*
|
||||
* MIGRATE_ASYNC means never block
|
||||
* MIGRATE_SYNC_LIGHT in the current implementation means to allow blocking
|
||||
* on most operations but not ->writepage as the potential stall time
|
||||
* is too significant
|
||||
* MIGRATE_SYNC will block when migrating pages
|
||||
*/
|
||||
enum migrate_mode {
|
||||
MIGRATE_ASYNC,
|
||||
MIGRATE_SYNC_LIGHT,
|
||||
MIGRATE_SYNC,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MIGRATION
|
||||
#define PAGE_MIGRATION 1
|
||||
|
||||
extern void putback_lru_pages(struct list_head *l);
|
||||
extern int migrate_page(struct address_space *,
|
||||
struct page *, struct page *);
|
||||
struct page *, struct page *, enum migrate_mode);
|
||||
extern int migrate_pages(struct list_head *l, new_page_t x,
|
||||
unsigned long private, bool offlining,
|
||||
bool sync);
|
||||
enum migrate_mode mode);
|
||||
extern int migrate_huge_pages(struct list_head *l, new_page_t x,
|
||||
unsigned long private, bool offlining,
|
||||
bool sync);
|
||||
enum migrate_mode mode);
|
||||
|
||||
extern int fail_migrate_page(struct address_space *,
|
||||
struct page *, struct page *);
|
||||
|
|
@ -36,10 +49,10 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping,
|
|||
static inline void putback_lru_pages(struct list_head *l) {}
|
||||
static inline int migrate_pages(struct list_head *l, new_page_t x,
|
||||
unsigned long private, bool offlining,
|
||||
bool sync) { return -ENOSYS; }
|
||||
enum migrate_mode mode) { return -ENOSYS; }
|
||||
static inline int migrate_huge_pages(struct list_head *l, new_page_t x,
|
||||
unsigned long private, bool offlining,
|
||||
bool sync) { return -ENOSYS; }
|
||||
enum migrate_mode mode) { return -ENOSYS; }
|
||||
|
||||
static inline int migrate_prep(void) { return -ENOSYS; }
|
||||
static inline int migrate_prep_local(void) { return -ENOSYS; }
|
||||
|
|
|
|||
|
|
@ -158,6 +158,20 @@ static inline int is_unevictable_lru(enum lru_list l)
|
|||
return (l == LRU_UNEVICTABLE);
|
||||
}
|
||||
|
||||
/* Isolate inactive pages */
|
||||
#define ISOLATE_INACTIVE ((__force isolate_mode_t)0x1)
|
||||
/* Isolate active pages */
|
||||
#define ISOLATE_ACTIVE ((__force isolate_mode_t)0x2)
|
||||
/* Isolate clean file */
|
||||
#define ISOLATE_CLEAN ((__force isolate_mode_t)0x4)
|
||||
/* Isolate unmapped file */
|
||||
#define ISOLATE_UNMAPPED ((__force isolate_mode_t)0x8)
|
||||
/* Isolate for asynchronous migration */
|
||||
#define ISOLATE_ASYNC_MIGRATE ((__force isolate_mode_t)0x10)
|
||||
|
||||
/* LRU Isolation modes. */
|
||||
typedef unsigned __bitwise__ isolate_mode_t;
|
||||
|
||||
enum zone_watermarks {
|
||||
WMARK_MIN,
|
||||
WMARK_LOW,
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ struct rnd_state {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
extern void rand_initialize_irq(int irq);
|
||||
|
||||
extern void add_device_randomness(const void *, unsigned int);
|
||||
extern void add_input_randomness(unsigned int type, unsigned int code,
|
||||
unsigned int value);
|
||||
extern void add_interrupt_randomness(int irq);
|
||||
extern void add_interrupt_randomness(int irq, int irq_flags);
|
||||
|
||||
extern void get_random_bytes(void *buf, int nbytes);
|
||||
extern void get_random_bytes_arch(void *buf, int nbytes);
|
||||
void generate_random_uuid(unsigned char uuid_out[16]);
|
||||
|
||||
#ifndef MODULE
|
||||
|
|
@ -91,6 +91,19 @@ static inline void prandom32_seed(struct rnd_state *state, u64 seed)
|
|||
state->s3 = __seed(i, 15);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_RANDOM
|
||||
# include <asm/archrandom.h>
|
||||
#else
|
||||
static inline int arch_get_random_long(unsigned long *v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int arch_get_random_int(unsigned int *v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL___ */
|
||||
|
||||
#endif /* _LINUX_RANDOM_H */
|
||||
|
|
|
|||
|
|
@ -1484,7 +1484,7 @@ struct task_struct {
|
|||
#endif
|
||||
#ifdef CONFIG_CPUSETS
|
||||
nodemask_t mems_allowed; /* Protected by alloc_lock */
|
||||
int mems_allowed_change_disable;
|
||||
seqcount_t mems_allowed_seq; /* Seqence no to catch updates */
|
||||
int cpuset_mem_spread_rotor;
|
||||
int cpuset_slab_spread_rotor;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -243,11 +243,6 @@ static inline void lru_cache_add_file(struct page *page)
|
|||
__lru_cache_add(page, LRU_INACTIVE_FILE);
|
||||
}
|
||||
|
||||
/* LRU Isolation modes. */
|
||||
#define ISOLATE_INACTIVE 0 /* Isolate inactive pages. */
|
||||
#define ISOLATE_ACTIVE 1 /* Isolate active pages. */
|
||||
#define ISOLATE_BOTH 2 /* Isolate both active and inactive pages. */
|
||||
|
||||
/* linux/mm/vmscan.c */
|
||||
extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
|
||||
gfp_t gfp_mask, nodemask_t *mask);
|
||||
|
|
@ -259,7 +254,7 @@ extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
|
|||
unsigned int swappiness,
|
||||
struct zone *zone,
|
||||
unsigned long *nr_scanned);
|
||||
extern int __isolate_lru_page(struct page *page, int mode, int file);
|
||||
extern int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file);
|
||||
extern unsigned long shrink_all_memory(unsigned long nr_pages);
|
||||
extern int vm_swappiness;
|
||||
extern int remove_mapping(struct address_space *mapping, struct page *page);
|
||||
|
|
|
|||
134
include/trace/events/random.h
Normal file
134
include/trace/events/random.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM random
|
||||
|
||||
#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_RANDOM_H
|
||||
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
DECLARE_EVENT_CLASS(random__mix_pool_bytes,
|
||||
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, bytes, IP),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( const char *, pool_name )
|
||||
__field( int, bytes )
|
||||
__field(unsigned long, IP )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->pool_name = pool_name;
|
||||
__entry->bytes = bytes;
|
||||
__entry->IP = IP;
|
||||
),
|
||||
|
||||
TP_printk("%s pool: bytes %d caller %pF",
|
||||
__entry->pool_name, __entry->bytes, (void *)__entry->IP)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes,
|
||||
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, bytes, IP)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
|
||||
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, bytes, IP)
|
||||
);
|
||||
|
||||
TRACE_EVENT(credit_entropy_bits,
|
||||
TP_PROTO(const char *pool_name, int bits, int entropy_count,
|
||||
int entropy_total, unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( const char *, pool_name )
|
||||
__field( int, bits )
|
||||
__field( int, entropy_count )
|
||||
__field( int, entropy_total )
|
||||
__field(unsigned long, IP )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->pool_name = pool_name;
|
||||
__entry->bits = bits;
|
||||
__entry->entropy_count = entropy_count;
|
||||
__entry->entropy_total = entropy_total;
|
||||
__entry->IP = IP;
|
||||
),
|
||||
|
||||
TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
|
||||
"caller %pF", __entry->pool_name, __entry->bits,
|
||||
__entry->entropy_count, __entry->entropy_total,
|
||||
(void *)__entry->IP)
|
||||
);
|
||||
|
||||
TRACE_EVENT(get_random_bytes,
|
||||
TP_PROTO(int nbytes, unsigned long IP),
|
||||
|
||||
TP_ARGS(nbytes, IP),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( int, nbytes )
|
||||
__field(unsigned long, IP )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->nbytes = nbytes;
|
||||
__entry->IP = IP;
|
||||
),
|
||||
|
||||
TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(random__extract_entropy,
|
||||
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
|
||||
unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, nbytes, entropy_count, IP),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( const char *, pool_name )
|
||||
__field( int, nbytes )
|
||||
__field( int, entropy_count )
|
||||
__field(unsigned long, IP )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->pool_name = pool_name;
|
||||
__entry->nbytes = nbytes;
|
||||
__entry->entropy_count = entropy_count;
|
||||
__entry->IP = IP;
|
||||
),
|
||||
|
||||
TP_printk("%s pool: nbytes %d entropy_count %d caller %pF",
|
||||
__entry->pool_name, __entry->nbytes, __entry->entropy_count,
|
||||
(void *)__entry->IP)
|
||||
);
|
||||
|
||||
|
||||
DEFINE_EVENT(random__extract_entropy, extract_entropy,
|
||||
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
|
||||
unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, nbytes, entropy_count, IP)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(random__extract_entropy, extract_entropy_user,
|
||||
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
|
||||
unsigned long IP),
|
||||
|
||||
TP_ARGS(pool_name, nbytes, entropy_count, IP)
|
||||
);
|
||||
|
||||
|
||||
|
||||
#endif /* _TRACE_RANDOM_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
||||
|
|
@ -179,6 +179,83 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_re
|
|||
TP_ARGS(nr_reclaimed)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mm_shrink_slab_start,
|
||||
TP_PROTO(struct shrinker *shr, struct shrink_control *sc,
|
||||
long nr_objects_to_shrink, unsigned long pgs_scanned,
|
||||
unsigned long lru_pgs, unsigned long cache_items,
|
||||
unsigned long long delta, unsigned long total_scan),
|
||||
|
||||
TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs,
|
||||
cache_items, delta, total_scan),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct shrinker *, shr)
|
||||
__field(void *, shrink)
|
||||
__field(long, nr_objects_to_shrink)
|
||||
__field(gfp_t, gfp_flags)
|
||||
__field(unsigned long, pgs_scanned)
|
||||
__field(unsigned long, lru_pgs)
|
||||
__field(unsigned long, cache_items)
|
||||
__field(unsigned long long, delta)
|
||||
__field(unsigned long, total_scan)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->shr = shr;
|
||||
__entry->shrink = shr->shrink;
|
||||
__entry->nr_objects_to_shrink = nr_objects_to_shrink;
|
||||
__entry->gfp_flags = sc->gfp_mask;
|
||||
__entry->pgs_scanned = pgs_scanned;
|
||||
__entry->lru_pgs = lru_pgs;
|
||||
__entry->cache_items = cache_items;
|
||||
__entry->delta = delta;
|
||||
__entry->total_scan = total_scan;
|
||||
),
|
||||
|
||||
TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld",
|
||||
__entry->shrink,
|
||||
__entry->shr,
|
||||
__entry->nr_objects_to_shrink,
|
||||
show_gfp_flags(__entry->gfp_flags),
|
||||
__entry->pgs_scanned,
|
||||
__entry->lru_pgs,
|
||||
__entry->cache_items,
|
||||
__entry->delta,
|
||||
__entry->total_scan)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mm_shrink_slab_end,
|
||||
TP_PROTO(struct shrinker *shr, int shrinker_retval,
|
||||
long unused_scan_cnt, long new_scan_cnt),
|
||||
|
||||
TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct shrinker *, shr)
|
||||
__field(void *, shrink)
|
||||
__field(long, unused_scan)
|
||||
__field(long, new_scan)
|
||||
__field(int, retval)
|
||||
__field(long, total_scan)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->shr = shr;
|
||||
__entry->shrink = shr->shrink;
|
||||
__entry->unused_scan = unused_scan_cnt;
|
||||
__entry->new_scan = new_scan_cnt;
|
||||
__entry->retval = shrinker_retval;
|
||||
__entry->total_scan = new_scan_cnt - unused_scan_cnt;
|
||||
),
|
||||
|
||||
TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d",
|
||||
__entry->shrink,
|
||||
__entry->shr,
|
||||
__entry->unused_scan,
|
||||
__entry->new_scan,
|
||||
__entry->total_scan,
|
||||
__entry->retval)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
|
||||
|
||||
|
|
@ -189,7 +266,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
|
|||
unsigned long nr_lumpy_taken,
|
||||
unsigned long nr_lumpy_dirty,
|
||||
unsigned long nr_lumpy_failed,
|
||||
int isolate_mode),
|
||||
isolate_mode_t isolate_mode),
|
||||
|
||||
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode),
|
||||
|
||||
|
|
@ -201,7 +278,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
|
|||
__field(unsigned long, nr_lumpy_taken)
|
||||
__field(unsigned long, nr_lumpy_dirty)
|
||||
__field(unsigned long, nr_lumpy_failed)
|
||||
__field(int, isolate_mode)
|
||||
__field(isolate_mode_t, isolate_mode)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
|
|
@ -235,7 +312,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate,
|
|||
unsigned long nr_lumpy_taken,
|
||||
unsigned long nr_lumpy_dirty,
|
||||
unsigned long nr_lumpy_failed,
|
||||
int isolate_mode),
|
||||
isolate_mode_t isolate_mode),
|
||||
|
||||
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)
|
||||
|
||||
|
|
@ -250,7 +327,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate,
|
|||
unsigned long nr_lumpy_taken,
|
||||
unsigned long nr_lumpy_dirty,
|
||||
unsigned long nr_lumpy_failed,
|
||||
int isolate_mode),
|
||||
isolate_mode_t isolate_mode),
|
||||
|
||||
TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,19 @@ static inline struct cpuset *task_cs(struct task_struct *task)
|
|||
struct cpuset, css);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
static inline bool task_has_mempolicy(struct task_struct *task)
|
||||
{
|
||||
return task->mempolicy;
|
||||
}
|
||||
#else
|
||||
static inline bool task_has_mempolicy(struct task_struct *task)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* bits in struct cpuset flags field */
|
||||
typedef enum {
|
||||
CS_CPU_EXCLUSIVE,
|
||||
|
|
@ -949,7 +962,8 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
|
|||
static void cpuset_change_task_nodemask(struct task_struct *tsk,
|
||||
nodemask_t *newmems)
|
||||
{
|
||||
repeat:
|
||||
bool need_loop;
|
||||
|
||||
/*
|
||||
* Allow tasks that have access to memory reserves because they have
|
||||
* been OOM killed to get memory anywhere.
|
||||
|
|
@ -960,46 +974,27 @@ repeat:
|
|||
return;
|
||||
|
||||
task_lock(tsk);
|
||||
/*
|
||||
* Determine if a loop is necessary if another thread is doing
|
||||
* get_mems_allowed(). If at least one node remains unchanged and
|
||||
* tsk does not have a mempolicy, then an empty nodemask will not be
|
||||
* possible when mems_allowed is larger than a word.
|
||||
*/
|
||||
need_loop = task_has_mempolicy(tsk) ||
|
||||
!nodes_intersects(*newmems, tsk->mems_allowed);
|
||||
|
||||
if (need_loop)
|
||||
write_seqcount_begin(&tsk->mems_allowed_seq);
|
||||
|
||||
nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
|
||||
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
|
||||
|
||||
|
||||
/*
|
||||
* ensure checking ->mems_allowed_change_disable after setting all new
|
||||
* allowed nodes.
|
||||
*
|
||||
* the read-side task can see an nodemask with new allowed nodes and
|
||||
* old allowed nodes. and if it allocates page when cpuset clears newly
|
||||
* disallowed ones continuous, it can see the new allowed bits.
|
||||
*
|
||||
* And if setting all new allowed nodes is after the checking, setting
|
||||
* all new allowed nodes and clearing newly disallowed ones will be done
|
||||
* continuous, and the read-side task may find no node to alloc page.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* Allocation of memory is very fast, we needn't sleep when waiting
|
||||
* for the read-side.
|
||||
*/
|
||||
while (ACCESS_ONCE(tsk->mems_allowed_change_disable)) {
|
||||
task_unlock(tsk);
|
||||
if (!task_curr(tsk))
|
||||
yield();
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure checking ->mems_allowed_change_disable before clearing all new
|
||||
* disallowed nodes.
|
||||
*
|
||||
* if clearing newly disallowed bits before the checking, the read-side
|
||||
* task may find no node to alloc page.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2);
|
||||
tsk->mems_allowed = *newmems;
|
||||
|
||||
if (need_loop)
|
||||
write_seqcount_end(&tsk->mems_allowed_seq);
|
||||
|
||||
task_unlock(tsk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
|||
#ifdef CONFIG_CGROUPS
|
||||
init_rwsem(&sig->threadgroup_fork_lock);
|
||||
#endif
|
||||
#ifdef CONFIG_CPUSETS
|
||||
seqcount_init(&tsk->mems_allowed_seq);
|
||||
#endif
|
||||
|
||||
sig->oom_adj = current->signal->oom_adj;
|
||||
sig->oom_score_adj = current->signal->oom_score_adj;
|
||||
|
|
|
|||
|
|
@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
|
|||
* @uaddr2: the pi futex we will take prior to returning to user-space
|
||||
*
|
||||
* The caller will wait on uaddr and will be requeued by futex_requeue() to
|
||||
* uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and
|
||||
* complete the acquisition of the rt_mutex prior to returning to userspace.
|
||||
* This ensures the rt_mutex maintains an owner when it has waiters; without
|
||||
* one, the pi logic wouldn't know which task to boost/deboost, if there was a
|
||||
* need to.
|
||||
* uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake
|
||||
* on uaddr2 and complete the acquisition of the rt_mutex prior to returning to
|
||||
* userspace. This ensures the rt_mutex maintains an owner when it has waiters;
|
||||
* without one, the pi logic would not know which task to boost/deboost, if
|
||||
* there was a need to.
|
||||
*
|
||||
* We call schedule in futex_wait_queue_me() when we enqueue and return there
|
||||
* via the following:
|
||||
|
|
@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
|
|||
struct futex_q q = futex_q_init;
|
||||
int res, ret;
|
||||
|
||||
if (uaddr == uaddr2)
|
||||
return -EINVAL;
|
||||
|
||||
if (!bitset)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
|
|||
* signal. futex_unlock_pi() will not destroy the lock_ptr nor
|
||||
* the pi_state.
|
||||
*/
|
||||
WARN_ON(!&q.pi_state);
|
||||
WARN_ON(!q.pi_state);
|
||||
pi_mutex = &q.pi_state->pi_mutex;
|
||||
ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1);
|
||||
debug_rt_mutex_free_waiter(&rt_waiter);
|
||||
|
|
@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
|
|||
* fault, unlock the rt_mutex and return the fault to userspace.
|
||||
*/
|
||||
if (ret == -EFAULT) {
|
||||
if (rt_mutex_owner(pi_mutex) == current)
|
||||
if (pi_mutex && rt_mutex_owner(pi_mutex) == current)
|
||||
rt_mutex_unlock(pi_mutex);
|
||||
} else if (ret == -EINTR) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ irqreturn_t
|
|||
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
|
||||
{
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
unsigned int random = 0, irq = desc->irq_data.irq;
|
||||
unsigned int flags = 0, irq = desc->irq_data.irq;
|
||||
|
||||
do {
|
||||
irqreturn_t res;
|
||||
|
|
@ -145,7 +145,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
|
|||
|
||||
/* Fall through to add to randomness */
|
||||
case IRQ_HANDLED:
|
||||
random |= action->flags;
|
||||
flags |= action->flags;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -156,8 +156,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
|
|||
action = action->next;
|
||||
} while (action);
|
||||
|
||||
if (random & IRQF_SAMPLE_RANDOM)
|
||||
add_interrupt_randomness(irq);
|
||||
add_interrupt_randomness(irq, flags);
|
||||
|
||||
if (!noirqdebug)
|
||||
note_interrupt(irq, desc, retval);
|
||||
|
|
|
|||
|
|
@ -886,22 +886,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
|
|||
|
||||
if (desc->irq_data.chip == &no_irq_chip)
|
||||
return -ENOSYS;
|
||||
/*
|
||||
* Some drivers like serial.c use request_irq() heavily,
|
||||
* so we have to be careful not to interfere with a
|
||||
* running system.
|
||||
*/
|
||||
if (new->flags & IRQF_SAMPLE_RANDOM) {
|
||||
/*
|
||||
* This function might sleep, we want to call it first,
|
||||
* outside of the atomic block.
|
||||
* Yes, this might clear the entropy pool if the wrong
|
||||
* driver is attempted to be loaded, without actually
|
||||
* installing a new handler, but is this really a problem,
|
||||
* only the sysadmin is able to do this.
|
||||
*/
|
||||
rand_initialize_irq(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the interrupt nests into another interrupt
|
||||
|
|
@ -1325,7 +1309,6 @@ EXPORT_SYMBOL(free_irq);
|
|||
* Flags:
|
||||
*
|
||||
* IRQF_SHARED Interrupt is shared
|
||||
* IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
|
||||
* IRQF_TRIGGER_* Specify active edge(s) or level
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ int hibernation_snapshot(int platform_mode)
|
|||
goto Complete_devices;
|
||||
|
||||
suspend_console();
|
||||
ftrace_stop();
|
||||
pm_restrict_gfp_mask();
|
||||
error = dpm_suspend(PMSG_FREEZE);
|
||||
if (error)
|
||||
|
|
@ -369,6 +370,7 @@ int hibernation_snapshot(int platform_mode)
|
|||
if (error || !in_suspend)
|
||||
pm_restore_gfp_mask();
|
||||
|
||||
ftrace_start();
|
||||
resume_console();
|
||||
|
||||
Complete_devices:
|
||||
|
|
@ -471,6 +473,7 @@ int hibernation_restore(int platform_mode)
|
|||
|
||||
pm_prepare_console();
|
||||
suspend_console();
|
||||
ftrace_stop();
|
||||
pm_restrict_gfp_mask();
|
||||
error = dpm_suspend_start(PMSG_QUIESCE);
|
||||
if (!error) {
|
||||
|
|
@ -478,6 +481,7 @@ int hibernation_restore(int platform_mode)
|
|||
dpm_resume_end(PMSG_RECOVER);
|
||||
}
|
||||
pm_restore_gfp_mask();
|
||||
ftrace_start();
|
||||
resume_console();
|
||||
pm_restore_console();
|
||||
return error;
|
||||
|
|
@ -504,6 +508,7 @@ int hibernation_platform_enter(void)
|
|||
|
||||
entering_platform_hibernation = true;
|
||||
suspend_console();
|
||||
ftrace_stop();
|
||||
error = dpm_suspend_start(PMSG_HIBERNATE);
|
||||
if (error) {
|
||||
if (hibernation_ops->recover)
|
||||
|
|
@ -547,6 +552,7 @@ int hibernation_platform_enter(void)
|
|||
Resume_devices:
|
||||
entering_platform_hibernation = false;
|
||||
dpm_resume_end(PMSG_RESTORE);
|
||||
ftrace_start();
|
||||
resume_console();
|
||||
|
||||
Close:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue