This is the 4.4.2 stable release
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJWxNijAAoJEDjbvchgkmk+VrQP/1GrH46U3OoTil9kCgBF7KON w/tLdpt/u7z79wGJmTYO/7qLe8hwxamRSWPVS3yFUBZroHnichqzcabfKplyps3o RcHQ/okaFmjtbDNN+bnWueicZoUhA3BpMRSYKhY+3JtnJ6Dh3yYwZH/pyP6npbTf Id+gG6zCVXJZGHEM8YOXQxcA75B3Dl7Ofpqn86WgnJYLY/qIr3g0n+UZYZkD5fpS 7HjxjEaOSi8uYvKwHvU3Ym040Gz9DehxztStSo9UMRz8VkrImbVhaoiLurtFLqcJ McuUNHGTPrbWUm6AlQUpxBKBSF3WLXhID9u42pDaXXtv9QUGq6iyr06VQ4mek/g6 4a0RpqjfdRU6EkEMc6ntgugj1x0PvbjRIxVs8Lon0G0OIJpQq9hNrnoM447pF/Q3 oEB//pXYu3tSpktbB0LXFre0drEtLs7Bnnf3ouVCQPlVntuF61+EPAd6REJphV6L m4Bpvj1IY3KOOrJCVPNvpoXcf76AzYtSZjjPz7gLyeRBaUQGQUFD3ARWVIdRlfnk vo9V5YrX2rFgHZPvGHDaEHWtWqxuNV3Cvm1A708/ZUb8YcC/hDydExv7QaWka+vZ JyYICYZq1lxfWhwMQFLnkz/z8akw45i52q60YrEumZRtr+ypGLgXVF4yt8zCIs3j pSeSLzVyPc/S6bQf9GKz =7SZx -----END PGP SIGNATURE----- Merge tag 'v4.4.2' This is the 4.4.2 stable release
This commit is contained in:
commit
fbcc24698c
183 changed files with 2317 additions and 842 deletions
|
|
@ -134,19 +134,21 @@ Description:
|
|||
enabled for the device. Developer can write y/Y/1 or n/N/0 to
|
||||
the file to enable/disable the feature.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/usb3_hardware_lpm
|
||||
Date: June 2015
|
||||
What: /sys/bus/usb/devices/.../power/usb3_hardware_lpm_u1
|
||||
/sys/bus/usb/devices/.../power/usb3_hardware_lpm_u2
|
||||
Date: November 2015
|
||||
Contact: Kevin Strasser <kevin.strasser@linux.intel.com>
|
||||
Lu Baolu <baolu.lu@linux.intel.com>
|
||||
Description:
|
||||
If CONFIG_PM is set and a USB 3.0 lpm-capable device is plugged
|
||||
in to a xHCI host which supports link PM, it will check if U1
|
||||
and U2 exit latencies have been set in the BOS descriptor; if
|
||||
the check is is passed and the host supports USB3 hardware LPM,
|
||||
the check is passed and the host supports USB3 hardware LPM,
|
||||
USB3 hardware LPM will be enabled for the device and the USB
|
||||
device directory will contain a file named
|
||||
power/usb3_hardware_lpm. The file holds a string value (enable
|
||||
or disable) indicating whether or not USB3 hardware LPM is
|
||||
enabled for the device.
|
||||
device directory will contain two files named
|
||||
power/usb3_hardware_lpm_u1 and power/usb3_hardware_lpm_u2. These
|
||||
files hold a string value (enable or disable) indicating whether
|
||||
or not USB3 hardware LPM U1 or U2 is enabled for the device.
|
||||
|
||||
What: /sys/bus/usb/devices/.../removable
|
||||
Date: February 2012
|
||||
|
|
|
|||
|
|
@ -537,17 +537,18 @@ relevant attribute files are usb2_hardware_lpm and usb3_hardware_lpm.
|
|||
can write y/Y/1 or n/N/0 to the file to enable/disable
|
||||
USB2 hardware LPM manually. This is for test purpose mainly.
|
||||
|
||||
power/usb3_hardware_lpm
|
||||
power/usb3_hardware_lpm_u1
|
||||
power/usb3_hardware_lpm_u2
|
||||
|
||||
When a USB 3.0 lpm-capable device is plugged in to a
|
||||
xHCI host which supports link PM, it will check if U1
|
||||
and U2 exit latencies have been set in the BOS
|
||||
descriptor; if the check is is passed and the host
|
||||
supports USB3 hardware LPM, USB3 hardware LPM will be
|
||||
enabled for the device and this file will be created.
|
||||
The file holds a string value (enable or disable)
|
||||
indicating whether or not USB3 hardware LPM is
|
||||
enabled for the device.
|
||||
enabled for the device and these files will be created.
|
||||
The files hold a string value (enable or disable)
|
||||
indicating whether or not USB3 hardware LPM U1 or U2
|
||||
is enabled for the device.
|
||||
|
||||
USB Port Power Control
|
||||
----------------------
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 0
|
||||
SUBLEVEL = 2
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
|||
|
|
@ -512,9 +512,14 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
|
|||
#endif
|
||||
|
||||
/* EL2 debug */
|
||||
mrs x0, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
|
||||
sbfx x0, x0, #8, #4
|
||||
cmp x0, #1
|
||||
b.lt 4f // Skip if no PMU present
|
||||
mrs x0, pmcr_el0 // Disable debug access traps
|
||||
ubfx x0, x0, #11, #5 // to EL2 and allow access to
|
||||
msr mdcr_el2, x0 // all PMU counters from EL1
|
||||
4:
|
||||
|
||||
/* Stage-2 translation */
|
||||
msr vttbr_el2, xzr
|
||||
|
|
|
|||
|
|
@ -574,9 +574,6 @@ static void armv8pmu_reset(void *info)
|
|||
|
||||
/* Initialize & Reset PMNC: C and P bits. */
|
||||
armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C);
|
||||
|
||||
/* Disable access from userspace. */
|
||||
asm volatile("msr pmuserenr_el0, %0" :: "r" (0));
|
||||
}
|
||||
|
||||
static int armv8_pmuv3_map_event(struct perf_event *event)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
*/
|
||||
void ptrace_disable(struct task_struct *child)
|
||||
{
|
||||
/*
|
||||
* This would be better off in core code, but PTRACE_DETACH has
|
||||
* grown its fair share of arch-specific worts and changing it
|
||||
* is likely to cause regressions on obscure architectures.
|
||||
*/
|
||||
user_disable_single_step(child);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||
|
|
|
|||
|
|
@ -456,6 +456,9 @@ void __init paging_init(void)
|
|||
|
||||
empty_zero_page = virt_to_page(zero_page);
|
||||
|
||||
/* Ensure the zero page is visible to the page table walker */
|
||||
dsb(ishst);
|
||||
|
||||
/*
|
||||
* TTBR0 is only used for the identity mapping at this stage. Make it
|
||||
* point to zero page to avoid speculatively fetching new entries.
|
||||
|
|
|
|||
|
|
@ -62,3 +62,15 @@
|
|||
bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
|
||||
*/
|
||||
.macro reset_pmuserenr_el0, tmpreg
|
||||
mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
|
||||
sbfx \tmpreg, \tmpreg, #8, #4
|
||||
cmp \tmpreg, #1 // Skip if no PMU present
|
||||
b.lt 9000f
|
||||
msr pmuserenr_el0, xzr // Disable PMU access from EL0
|
||||
9000:
|
||||
.endm
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ ENTRY(cpu_do_resume)
|
|||
*/
|
||||
ubfx x11, x11, #1, #1
|
||||
msr oslar_el1, x11
|
||||
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
|
||||
mov x0, x12
|
||||
dsb nsh // Make sure local tlb invalidation completed
|
||||
isb
|
||||
|
|
@ -155,6 +156,7 @@ ENTRY(__cpu_setup)
|
|||
msr cpacr_el1, x0 // Enable FP/ASIMD
|
||||
mov x0, #1 << 12 // Reset mdscr_el1 and disable
|
||||
msr mdscr_el1, x0 // access to the DCC from EL0
|
||||
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
|
||||
/*
|
||||
* Memory region attributes for LPAE:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -54,24 +54,12 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
|
|||
return pte_wrprotect(pte);
|
||||
}
|
||||
|
||||
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_t old_pte = *ptep;
|
||||
set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
|
||||
}
|
||||
void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
|
||||
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
int changed = !pte_same(*ptep, pte);
|
||||
if (changed) {
|
||||
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
flush_tlb_page(vma, addr);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
pte_t pte, int dirty);
|
||||
|
||||
static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _PARISC_SIGINFO_H
|
||||
#define _PARISC_SIGINFO_H
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
|
||||
#endif
|
||||
|
||||
#include <asm-generic/siginfo.h>
|
||||
|
||||
#undef NSIGTRAP
|
||||
|
|
|
|||
|
|
@ -105,15 +105,13 @@ static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long ad
|
|||
addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT;
|
||||
|
||||
for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
|
||||
mtsp(mm->context, 1);
|
||||
pdtlb(addr);
|
||||
if (unlikely(split_tlb))
|
||||
pitlb(addr);
|
||||
purge_tlb_entries(mm, addr);
|
||||
addr += (1UL << REAL_HPAGE_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
|
||||
static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
unsigned long addr_start;
|
||||
|
|
@ -123,14 +121,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
|||
addr_start = addr;
|
||||
|
||||
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
|
||||
/* Directly write pte entry. We could call set_pte_at(mm, addr, ptep, entry)
|
||||
* instead, but then we get double locking on pa_tlb_lock. */
|
||||
*ptep = entry;
|
||||
set_pte(ptep, entry);
|
||||
ptep++;
|
||||
|
||||
/* Drop the PAGE_SIZE/non-huge tlb entry */
|
||||
purge_tlb_entries(mm, addr);
|
||||
|
||||
addr += PAGE_SIZE;
|
||||
pte_val(entry) += PAGE_SIZE;
|
||||
}
|
||||
|
|
@ -138,18 +131,61 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
|||
purge_tlb_entries_huge(mm, addr_start);
|
||||
}
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
__set_huge_pte_at(mm, addr, ptep, entry);
|
||||
purge_tlb_end(flags);
|
||||
}
|
||||
|
||||
|
||||
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
{
|
||||
unsigned long flags;
|
||||
pte_t entry;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
entry = *ptep;
|
||||
set_huge_pte_at(mm, addr, ptep, __pte(0));
|
||||
__set_huge_pte_at(mm, addr, ptep, __pte(0));
|
||||
purge_tlb_end(flags);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
unsigned long flags;
|
||||
pte_t old_pte;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
old_pte = *ptep;
|
||||
__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
|
||||
purge_tlb_end(flags);
|
||||
}
|
||||
|
||||
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
unsigned long flags;
|
||||
int changed;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
changed = !pte_same(*ptep, pte);
|
||||
if (changed) {
|
||||
__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
}
|
||||
purge_tlb_end(flags);
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
int pmd_huge(pmd_t pmd)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ __xchg_u32(volatile void *p, unsigned long val)
|
|||
unsigned long prev;
|
||||
|
||||
__asm__ __volatile__(
|
||||
PPC_RELEASE_BARRIER
|
||||
PPC_ATOMIC_ENTRY_BARRIER
|
||||
"1: lwarx %0,0,%2 \n"
|
||||
PPC405_ERR77(0,%2)
|
||||
" stwcx. %3,0,%2 \n\
|
||||
bne- 1b"
|
||||
PPC_ACQUIRE_BARRIER
|
||||
PPC_ATOMIC_EXIT_BARRIER
|
||||
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
|
||||
: "r" (p), "r" (val)
|
||||
: "cc", "memory");
|
||||
|
|
@ -61,12 +61,12 @@ __xchg_u64(volatile void *p, unsigned long val)
|
|||
unsigned long prev;
|
||||
|
||||
__asm__ __volatile__(
|
||||
PPC_RELEASE_BARRIER
|
||||
PPC_ATOMIC_ENTRY_BARRIER
|
||||
"1: ldarx %0,0,%2 \n"
|
||||
PPC405_ERR77(0,%2)
|
||||
" stdcx. %3,0,%2 \n\
|
||||
bne- 1b"
|
||||
PPC_ACQUIRE_BARRIER
|
||||
PPC_ATOMIC_EXIT_BARRIER
|
||||
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
|
||||
: "r" (p), "r" (val)
|
||||
: "cc", "memory");
|
||||
|
|
@ -151,14 +151,14 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
|
|||
unsigned int prev;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
PPC_RELEASE_BARRIER
|
||||
PPC_ATOMIC_ENTRY_BARRIER
|
||||
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
|
||||
cmpw 0,%0,%3\n\
|
||||
bne- 2f\n"
|
||||
PPC405_ERR77(0,%2)
|
||||
" stwcx. %4,0,%2\n\
|
||||
bne- 1b"
|
||||
PPC_ACQUIRE_BARRIER
|
||||
PPC_ATOMIC_EXIT_BARRIER
|
||||
"\n\
|
||||
2:"
|
||||
: "=&r" (prev), "+m" (*p)
|
||||
|
|
@ -197,13 +197,13 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
|
|||
unsigned long prev;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
PPC_RELEASE_BARRIER
|
||||
PPC_ATOMIC_ENTRY_BARRIER
|
||||
"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
|
||||
cmpd 0,%0,%3\n\
|
||||
bne- 2f\n\
|
||||
stdcx. %4,0,%2\n\
|
||||
bne- 1b"
|
||||
PPC_ACQUIRE_BARRIER
|
||||
PPC_ATOMIC_EXIT_BARRIER
|
||||
"\n\
|
||||
2:"
|
||||
: "=&r" (prev), "+m" (*p)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static inline void isync(void)
|
|||
MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
|
||||
#define PPC_ACQUIRE_BARRIER "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
|
||||
#define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n"
|
||||
#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
|
||||
#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n"
|
||||
#define PPC_ATOMIC_EXIT_BARRIER "\n" stringify_in_c(sync) "\n"
|
||||
#else
|
||||
#define PPC_ACQUIRE_BARRIER
|
||||
|
|
|
|||
|
|
@ -295,6 +295,8 @@ do { \
|
|||
#define R_PPC64_TLSLD 108
|
||||
#define R_PPC64_TOCSAVE 109
|
||||
|
||||
#define R_PPC64_ENTRY 118
|
||||
|
||||
#define R_PPC64_REL16 249
|
||||
#define R_PPC64_REL16_LO 250
|
||||
#define R_PPC64_REL16_HI 251
|
||||
|
|
|
|||
|
|
@ -635,6 +635,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|||
*/
|
||||
break;
|
||||
|
||||
case R_PPC64_ENTRY:
|
||||
/*
|
||||
* Optimize ELFv2 large code model entry point if
|
||||
* the TOC is within 2GB range of current location.
|
||||
*/
|
||||
value = my_r2(sechdrs, me) - (unsigned long)location;
|
||||
if (value + 0x80008000 > 0xffffffff)
|
||||
break;
|
||||
/*
|
||||
* Check for the large code model prolog sequence:
|
||||
* ld r2, ...(r12)
|
||||
* add r2, r2, r12
|
||||
*/
|
||||
if ((((uint32_t *)location)[0] & ~0xfffc)
|
||||
!= 0xe84c0000)
|
||||
break;
|
||||
if (((uint32_t *)location)[1] != 0x7c426214)
|
||||
break;
|
||||
/*
|
||||
* If found, replace it with:
|
||||
* addis r2, r12, (.TOC.-func)@ha
|
||||
* addi r2, r12, (.TOC.-func)@l
|
||||
*/
|
||||
((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
|
||||
((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
|
||||
break;
|
||||
|
||||
case R_PPC64_REL16_HA:
|
||||
/* Subtract location pointer */
|
||||
value -= (unsigned long)location;
|
||||
|
|
|
|||
|
|
@ -551,6 +551,24 @@ static void tm_reclaim_thread(struct thread_struct *thr,
|
|||
msr_diff &= MSR_FP | MSR_VEC | MSR_VSX | MSR_FE0 | MSR_FE1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the current MSR TM suspended bit to track if we have
|
||||
* checkpointed state outstanding.
|
||||
* On signal delivery, we'd normally reclaim the checkpointed
|
||||
* state to obtain stack pointer (see:get_tm_stackpointer()).
|
||||
* This will then directly return to userspace without going
|
||||
* through __switch_to(). However, if the stack frame is bad,
|
||||
* we need to exit this thread which calls __switch_to() which
|
||||
* will again attempt to reclaim the already saved tm state.
|
||||
* Hence we need to check that we've not already reclaimed
|
||||
* this state.
|
||||
* We do this using the current MSR, rather tracking it in
|
||||
* some specific thread_struct bit, as it has the additional
|
||||
* benifit of checking for a potential TM bad thing exception.
|
||||
*/
|
||||
if (!MSR_TM_SUSPENDED(mfmsr()))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Use the current MSR TM suspended bit to track if we have
|
||||
* checkpointed state outstanding.
|
||||
|
|
|
|||
|
|
@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3)
|
|||
# done with the slightly better performing SSSE3 byte shuffling,
|
||||
# 7/12-bit word rotation uses traditional shift+OR.
|
||||
|
||||
sub $0x40,%rsp
|
||||
mov %rsp,%r11
|
||||
sub $0x80,%rsp
|
||||
and $~63,%rsp
|
||||
|
||||
# x0..15[0-3] = s0..3[0..3]
|
||||
movq 0x00(%rdi),%xmm1
|
||||
|
|
@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3)
|
|||
pxor %xmm1,%xmm15
|
||||
movdqu %xmm15,0xf0(%rsi)
|
||||
|
||||
add $0x40,%rsp
|
||||
mov %r11,%rsp
|
||||
ret
|
||||
ENDPROC(chacha20_4block_xor_ssse3)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#define BOOT_HEAP_SIZE 0x400000
|
||||
#else /* !CONFIG_KERNEL_BZIP2 */
|
||||
|
||||
#define BOOT_HEAP_SIZE 0x8000
|
||||
#define BOOT_HEAP_SIZE 0x10000
|
||||
|
||||
#endif /* !CONFIG_KERNEL_BZIP2 */
|
||||
|
||||
|
|
|
|||
|
|
@ -116,8 +116,36 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
#endif
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/* Re-load page tables */
|
||||
/*
|
||||
* Re-load page tables.
|
||||
*
|
||||
* This logic has an ordering constraint:
|
||||
*
|
||||
* CPU 0: Write to a PTE for 'next'
|
||||
* CPU 0: load bit 1 in mm_cpumask. if nonzero, send IPI.
|
||||
* CPU 1: set bit 1 in next's mm_cpumask
|
||||
* CPU 1: load from the PTE that CPU 0 writes (implicit)
|
||||
*
|
||||
* We need to prevent an outcome in which CPU 1 observes
|
||||
* the new PTE value and CPU 0 observes bit 1 clear in
|
||||
* mm_cpumask. (If that occurs, then the IPI will never
|
||||
* be sent, and CPU 0's TLB will contain a stale entry.)
|
||||
*
|
||||
* The bad outcome can occur if either CPU's load is
|
||||
* reordered before that CPU's store, so both CPUs must
|
||||
* execute full barriers to prevent this from happening.
|
||||
*
|
||||
* Thus, switch_mm needs a full barrier between the
|
||||
* store to mm_cpumask and any operation that could load
|
||||
* from next->pgd. TLB fills are special and can happen
|
||||
* due to instruction fetches or for no reason at all,
|
||||
* and neither LOCK nor MFENCE orders them.
|
||||
* Fortunately, load_cr3() is serializing and gives the
|
||||
* ordering guarantee we need.
|
||||
*
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
|
||||
/* Stop flush ipis for the previous mm */
|
||||
|
|
@ -156,10 +184,14 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
* schedule, protecting us from simultaneous changes.
|
||||
*/
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/*
|
||||
* We were in lazy tlb mode and leave_mm disabled
|
||||
* tlb flush IPI delivery. We must reload CR3
|
||||
* to make sure to use no freed page tables.
|
||||
*
|
||||
* As above, load_cr3() is serializing and orders TLB
|
||||
* fills with respect to the mm_cpumask write.
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
|
|
|
|||
|
|
@ -182,6 +182,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
|
||||
},
|
||||
},
|
||||
{ /* Handle problems with rebooting on the iMac10,1. */
|
||||
.callback = set_pci_reboot,
|
||||
.ident = "Apple iMac10,1",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"),
|
||||
},
|
||||
},
|
||||
|
||||
/* ASRock */
|
||||
{ /* Handle problems with rebooting on ASRock Q1900DC-ITX */
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ TRACE_EVENT(kvm_inj_virq,
|
|||
#define kvm_trace_sym_exc \
|
||||
EXS(DE), EXS(DB), EXS(BP), EXS(OF), EXS(BR), EXS(UD), EXS(NM), \
|
||||
EXS(DF), EXS(TS), EXS(NP), EXS(SS), EXS(GP), EXS(PF), \
|
||||
EXS(MF), EXS(MC)
|
||||
EXS(MF), EXS(AC), EXS(MC)
|
||||
|
||||
/*
|
||||
* Tracepoint for kvm interrupt injection:
|
||||
|
|
|
|||
|
|
@ -8932,7 +8932,8 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
|||
best->ebx &= ~bit(X86_FEATURE_INVPCID);
|
||||
}
|
||||
|
||||
vmcs_set_secondary_exec_control(secondary_exec_ctl);
|
||||
if (cpu_has_secondary_exec_ctrls())
|
||||
vmcs_set_secondary_exec_control(secondary_exec_ctl);
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_PCOMMIT) && nested) {
|
||||
if (guest_cpuid_has_pcommit(vcpu))
|
||||
|
|
|
|||
|
|
@ -951,7 +951,7 @@ static u32 msrs_to_save[] = {
|
|||
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
|
||||
#endif
|
||||
MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
|
||||
MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS
|
||||
MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
|
||||
};
|
||||
|
||||
static unsigned num_msrs_to_save;
|
||||
|
|
@ -4006,16 +4006,17 @@ static void kvm_init_msr_list(void)
|
|||
|
||||
/*
|
||||
* Even MSRs that are valid in the host may not be exposed
|
||||
* to the guests in some cases. We could work around this
|
||||
* in VMX with the generic MSR save/load machinery, but it
|
||||
* is not really worthwhile since it will really only
|
||||
* happen with nested virtualization.
|
||||
* to the guests in some cases.
|
||||
*/
|
||||
switch (msrs_to_save[i]) {
|
||||
case MSR_IA32_BNDCFGS:
|
||||
if (!kvm_x86_ops->mpx_supported())
|
||||
continue;
|
||||
break;
|
||||
case MSR_TSC_AUX:
|
||||
if (!kvm_x86_ops->rdtscp_supported())
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,10 @@ void flush_tlb_current_task(void)
|
|||
preempt_disable();
|
||||
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
|
||||
/* This is an implicit full barrier that synchronizes with switch_mm. */
|
||||
local_flush_tlb();
|
||||
|
||||
trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL);
|
||||
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
|
||||
flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL);
|
||||
|
|
@ -188,17 +191,29 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
|||
unsigned long base_pages_to_flush = TLB_FLUSH_ALL;
|
||||
|
||||
preempt_disable();
|
||||
if (current->active_mm != mm)
|
||||
if (current->active_mm != mm) {
|
||||
/* Synchronize with switch_mm. */
|
||||
smp_mb();
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!current->mm) {
|
||||
leave_mm(smp_processor_id());
|
||||
|
||||
/* Synchronize with switch_mm. */
|
||||
smp_mb();
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB))
|
||||
base_pages_to_flush = (end - start) >> PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* Both branches below are implicit full barriers (MOV to CR or
|
||||
* INVLPG) that synchronize with switch_mm.
|
||||
*/
|
||||
if (base_pages_to_flush > tlb_single_page_flush_ceiling) {
|
||||
base_pages_to_flush = TLB_FLUSH_ALL;
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
|
|
@ -228,10 +243,18 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long start)
|
|||
preempt_disable();
|
||||
|
||||
if (current->active_mm == mm) {
|
||||
if (current->mm)
|
||||
if (current->mm) {
|
||||
/*
|
||||
* Implicit full barrier (INVLPG) that synchronizes
|
||||
* with switch_mm.
|
||||
*/
|
||||
__flush_tlb_one(start);
|
||||
else
|
||||
} else {
|
||||
leave_mm(smp_processor_id());
|
||||
|
||||
/* Synchronize with switch_mm. */
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ static void xen_hvm_post_suspend(int suspend_cancelled)
|
|||
{
|
||||
#ifdef CONFIG_XEN_PVHVM
|
||||
int cpu;
|
||||
xen_hvm_init_shared_info();
|
||||
if (!suspend_cancelled)
|
||||
xen_hvm_init_shared_info();
|
||||
xen_callback_vector();
|
||||
xen_unplug_emulated_devices();
|
||||
if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q,
|
|||
return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
|
||||
}
|
||||
|
||||
static inline unsigned get_max_io_size(struct request_queue *q,
|
||||
struct bio *bio)
|
||||
{
|
||||
unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector);
|
||||
unsigned mask = queue_logical_block_size(q) - 1;
|
||||
|
||||
/* aligned to logical block size */
|
||||
sectors &= ~(mask >> 9);
|
||||
|
||||
return sectors;
|
||||
}
|
||||
|
||||
static struct bio *blk_bio_segment_split(struct request_queue *q,
|
||||
struct bio *bio,
|
||||
struct bio_set *bs,
|
||||
|
|
@ -79,11 +91,9 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
|
|||
unsigned front_seg_size = bio->bi_seg_front_size;
|
||||
bool do_split = true;
|
||||
struct bio *new = NULL;
|
||||
const unsigned max_sectors = get_max_io_size(q, bio);
|
||||
|
||||
bio_for_each_segment(bv, bio, iter) {
|
||||
if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
|
||||
goto split;
|
||||
|
||||
/*
|
||||
* If the queue doesn't support SG gaps and adding this
|
||||
* offset would create a gap, disallow it.
|
||||
|
|
@ -91,6 +101,21 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
|
|||
if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
|
||||
goto split;
|
||||
|
||||
if (sectors + (bv.bv_len >> 9) > max_sectors) {
|
||||
/*
|
||||
* Consider this a new segment if we're splitting in
|
||||
* the middle of this vector.
|
||||
*/
|
||||
if (nsegs < queue_max_segments(q) &&
|
||||
sectors < max_sectors) {
|
||||
nsegs++;
|
||||
sectors = max_sectors;
|
||||
}
|
||||
if (sectors)
|
||||
goto split;
|
||||
/* Make this single bvec as the 1st segment */
|
||||
}
|
||||
|
||||
if (bvprvp && blk_queue_cluster(q)) {
|
||||
if (seg_size + bv.bv_len > queue_max_segment_size(q))
|
||||
goto new_segment;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type)
|
|||
goto unlock;
|
||||
|
||||
type->ops->owner = THIS_MODULE;
|
||||
if (type->ops_nokey)
|
||||
type->ops_nokey->owner = THIS_MODULE;
|
||||
node->type = type;
|
||||
list_add(&node->list, &alg_types);
|
||||
err = 0;
|
||||
|
|
@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release);
|
||||
|
||||
void af_alg_release_parent(struct sock *sk)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int nokey = ask->nokey_refcnt;
|
||||
bool last = nokey && !ask->refcnt;
|
||||
|
||||
sk = ask->parent;
|
||||
ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
ask->nokey_refcnt -= nokey;
|
||||
if (!last)
|
||||
last = !--ask->refcnt;
|
||||
release_sock(sk);
|
||||
|
||||
if (last)
|
||||
sock_put(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release_parent);
|
||||
|
||||
static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
const u32 forbidden = CRYPTO_ALG_INTERNAL;
|
||||
|
|
@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
struct sockaddr_alg *sa = (void *)uaddr;
|
||||
const struct af_alg_type *type;
|
||||
void *private;
|
||||
int err;
|
||||
|
||||
if (sock->state == SS_CONNECTED)
|
||||
return -EINVAL;
|
||||
|
|
@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
return PTR_ERR(private);
|
||||
}
|
||||
|
||||
err = -EBUSY;
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt | ask->nokey_refcnt)
|
||||
goto unlock;
|
||||
|
||||
swap(ask->type, type);
|
||||
swap(ask->private, private);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(sk);
|
||||
|
||||
alg_do_release(type, private);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int alg_setkey(struct sock *sk, char __user *ukey,
|
||||
|
|
@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
|
|||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
int err = -ENOPROTOOPT;
|
||||
int err = -EBUSY;
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock;
|
||||
|
||||
type = ask->type;
|
||||
|
||||
err = -ENOPROTOOPT;
|
||||
if (level != SOL_ALG || !type)
|
||||
goto unlock;
|
||||
|
||||
|
|
@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
struct sock *sk2;
|
||||
unsigned int nokey;
|
||||
int err;
|
||||
|
||||
lock_sock(sk);
|
||||
|
|
@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
security_sk_clone(sk, sk2);
|
||||
|
||||
err = type->accept(ask->private, sk2);
|
||||
if (err) {
|
||||
sk_free(sk2);
|
||||
|
||||
nokey = err == -ENOKEY;
|
||||
if (nokey && type->accept_nokey)
|
||||
err = type->accept_nokey(ask->private, sk2);
|
||||
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
sk2->sk_family = PF_ALG;
|
||||
|
||||
sock_hold(sk);
|
||||
if (nokey || !ask->refcnt++)
|
||||
sock_hold(sk);
|
||||
ask->nokey_refcnt += nokey;
|
||||
alg_sk(sk2)->parent = sk;
|
||||
alg_sk(sk2)->type = type;
|
||||
alg_sk(sk2)->nokey_refcnt = nokey;
|
||||
|
||||
newsock->ops = type->ops;
|
||||
newsock->state = SS_CONNECTED;
|
||||
|
||||
if (nokey)
|
||||
newsock->ops = type->ops_nokey;
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
struct ahash_alg *alg = crypto_ahash_alg(hash);
|
||||
|
||||
hash->setkey = ahash_nosetkey;
|
||||
hash->has_setkey = false;
|
||||
hash->export = ahash_no_export;
|
||||
hash->import = ahash_no_import;
|
||||
|
||||
|
|
@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
hash->finup = alg->finup ?: ahash_def_finup;
|
||||
hash->digest = alg->digest;
|
||||
|
||||
if (alg->setkey)
|
||||
if (alg->setkey) {
|
||||
hash->setkey = alg->setkey;
|
||||
hash->has_setkey = true;
|
||||
}
|
||||
if (alg->export)
|
||||
hash->export = alg->export;
|
||||
if (alg->import)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ struct hash_ctx {
|
|||
struct ahash_request req;
|
||||
};
|
||||
|
||||
struct algif_hash_tfm {
|
||||
struct crypto_ahash *hash;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored)
|
||||
{
|
||||
|
|
@ -49,7 +54,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
lock_sock(sk);
|
||||
if (!ctx->more) {
|
||||
err = crypto_ahash_init(&ctx->req);
|
||||
err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
|
||||
&ctx->completion);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -120,6 +126,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
|
|||
} else {
|
||||
if (!ctx->more) {
|
||||
err = crypto_ahash_init(&ctx->req);
|
||||
err = af_alg_wait_for_completion(err, &ctx->completion);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -235,19 +242,151 @@ static struct proto_ops algif_hash_ops = {
|
|||
.accept = hash_accept,
|
||||
};
|
||||
|
||||
static int hash_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
|
||||
int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_accept(sock, newsock, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_hash_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
.poll = sock_no_poll,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = hash_sendmsg_nokey,
|
||||
.sendpage = hash_sendpage_nokey,
|
||||
.recvmsg = hash_recvmsg_nokey,
|
||||
.accept = hash_accept_nokey,
|
||||
};
|
||||
|
||||
static void *hash_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_ahash(name, type, mask);
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct crypto_ahash *hash;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hash = crypto_alloc_ahash(name, type, mask);
|
||||
if (IS_ERR(hash)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(hash);
|
||||
}
|
||||
|
||||
tfm->hash = hash;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void hash_release(void *private)
|
||||
{
|
||||
crypto_free_ahash(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
crypto_free_ahash(tfm->hash);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_ahash_setkey(private, key, keylen);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_ahash_setkey(tfm->hash, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void hash_sock_destruct(struct sock *sk)
|
||||
|
|
@ -261,12 +400,14 @@ static void hash_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
static int hash_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct hash_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
|
||||
unsigned ds = crypto_ahash_digestsize(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
struct crypto_ahash *hash = tfm->hash;
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
|
||||
unsigned ds = crypto_ahash_digestsize(hash);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
|
|
@ -286,7 +427,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
ahash_request_set_tfm(&ctx->req, private);
|
||||
ahash_request_set_tfm(&ctx->req, hash);
|
||||
ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
|
|
@ -295,12 +436,24 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
|
||||
return -ENOKEY;
|
||||
|
||||
return hash_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_hash = {
|
||||
.bind = hash_bind,
|
||||
.release = hash_release,
|
||||
.setkey = hash_setkey,
|
||||
.accept = hash_accept_parent,
|
||||
.accept_nokey = hash_accept_parent_nokey,
|
||||
.ops = &algif_hash_ops,
|
||||
.ops_nokey = &algif_hash_ops_nokey,
|
||||
.name = "hash",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ struct skcipher_sg_list {
|
|||
struct scatterlist sg[0];
|
||||
};
|
||||
|
||||
struct skcipher_tfm {
|
||||
struct crypto_skcipher *skcipher;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
struct skcipher_ctx {
|
||||
struct list_head tsgl;
|
||||
struct af_alg_sgl rsgl;
|
||||
|
|
@ -60,18 +65,10 @@ struct skcipher_async_req {
|
|||
struct skcipher_async_rsgl first_sgl;
|
||||
struct list_head list;
|
||||
struct scatterlist *tsg;
|
||||
char iv[];
|
||||
atomic_t *inflight;
|
||||
struct skcipher_request req;
|
||||
};
|
||||
|
||||
#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
|
||||
crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
|
||||
|
||||
#define GET_REQ_SIZE(ctx) \
|
||||
crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
|
||||
|
||||
#define GET_IV_SIZE(ctx) \
|
||||
crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
|
||||
|
||||
#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
|
||||
sizeof(struct scatterlist) - 1)
|
||||
|
||||
|
|
@ -97,15 +94,12 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
|
|||
|
||||
static void skcipher_async_cb(struct crypto_async_request *req, int err)
|
||||
{
|
||||
struct sock *sk = req->data;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
|
||||
struct skcipher_async_req *sreq = req->data;
|
||||
struct kiocb *iocb = sreq->iocb;
|
||||
|
||||
atomic_dec(&ctx->inflight);
|
||||
atomic_dec(sreq->inflight);
|
||||
skcipher_free_async_sgls(sreq);
|
||||
kfree(req);
|
||||
kzfree(sreq);
|
||||
iocb->ki_complete(iocb, err, err);
|
||||
}
|
||||
|
||||
|
|
@ -301,8 +295,11 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
unsigned ivsize = crypto_skcipher_ivsize(tfm);
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct af_alg_control con = {};
|
||||
|
|
@ -387,7 +384,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
sg_unmark_end(sg + sgl->cur);
|
||||
if (sgl->cur)
|
||||
sg_unmark_end(sg + sgl->cur - 1);
|
||||
do {
|
||||
i = sgl->cur;
|
||||
plen = min_t(int, len, PAGE_SIZE);
|
||||
|
|
@ -503,37 +501,43 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct scatterlist *sg;
|
||||
struct skcipher_async_req *sreq;
|
||||
struct skcipher_request *req;
|
||||
struct skcipher_async_rsgl *last_rsgl = NULL;
|
||||
unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
|
||||
unsigned int reqlen = sizeof(struct skcipher_async_req) +
|
||||
GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx);
|
||||
unsigned int txbufs = 0, len = 0, tx_nents;
|
||||
unsigned int reqsize = crypto_skcipher_reqsize(tfm);
|
||||
unsigned int ivsize = crypto_skcipher_ivsize(tfm);
|
||||
int err = -ENOMEM;
|
||||
bool mark = false;
|
||||
char *iv;
|
||||
|
||||
sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL);
|
||||
if (unlikely(!sreq))
|
||||
goto out;
|
||||
|
||||
req = &sreq->req;
|
||||
iv = (char *)(req + 1) + reqsize;
|
||||
sreq->iocb = msg->msg_iocb;
|
||||
INIT_LIST_HEAD(&sreq->list);
|
||||
sreq->inflight = &ctx->inflight;
|
||||
|
||||
lock_sock(sk);
|
||||
req = kmalloc(reqlen, GFP_KERNEL);
|
||||
if (unlikely(!req))
|
||||
goto unlock;
|
||||
|
||||
sreq = GET_SREQ(req, ctx);
|
||||
sreq->iocb = msg->msg_iocb;
|
||||
memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl));
|
||||
INIT_LIST_HEAD(&sreq->list);
|
||||
tx_nents = skcipher_all_sg_nents(ctx);
|
||||
sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
|
||||
if (unlikely(!sreq->tsg)) {
|
||||
kfree(req);
|
||||
if (unlikely(!sreq->tsg))
|
||||
goto unlock;
|
||||
}
|
||||
sg_init_table(sreq->tsg, tx_nents);
|
||||
memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx));
|
||||
skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req));
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
skcipher_async_cb, sk);
|
||||
memcpy(iv, ctx->iv, ivsize);
|
||||
skcipher_request_set_tfm(req, tfm);
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
skcipher_async_cb, sreq);
|
||||
|
||||
while (iov_iter_count(&msg->msg_iter)) {
|
||||
struct skcipher_async_rsgl *rsgl;
|
||||
|
|
@ -609,20 +613,22 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
|||
sg_mark_end(sreq->tsg + txbufs - 1);
|
||||
|
||||
skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
|
||||
len, sreq->iv);
|
||||
len, iv);
|
||||
err = ctx->enc ? crypto_skcipher_encrypt(req) :
|
||||
crypto_skcipher_decrypt(req);
|
||||
if (err == -EINPROGRESS) {
|
||||
atomic_inc(&ctx->inflight);
|
||||
err = -EIOCBQUEUED;
|
||||
sreq = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
free:
|
||||
skcipher_free_async_sgls(sreq);
|
||||
kfree(req);
|
||||
unlock:
|
||||
skcipher_wmem_wakeup(sk);
|
||||
release_sock(sk);
|
||||
kzfree(sreq);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -631,9 +637,12 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm(
|
||||
&ctx->req));
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
unsigned bs = crypto_skcipher_blocksize(tfm);
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct scatterlist *sg;
|
||||
int err = -EAGAIN;
|
||||
|
|
@ -642,13 +651,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
lock_sock(sk);
|
||||
while (msg_data_left(msg)) {
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
if (!ctx->used) {
|
||||
err = skcipher_wait_for_data(sk, flags);
|
||||
if (err)
|
||||
|
|
@ -669,6 +671,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
if (!used)
|
||||
goto free;
|
||||
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
|
||||
ctx->iv);
|
||||
|
||||
|
|
@ -748,19 +757,139 @@ static struct proto_ops algif_skcipher_ops = {
|
|||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static int skcipher_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct skcipher_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_skcipher_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.accept = sock_no_accept,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = skcipher_sendmsg_nokey,
|
||||
.sendpage = skcipher_sendpage_nokey,
|
||||
.recvmsg = skcipher_recvmsg_nokey,
|
||||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static void *skcipher_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_skcipher(name, type, mask);
|
||||
struct skcipher_tfm *tfm;
|
||||
struct crypto_skcipher *skcipher;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
skcipher = crypto_alloc_skcipher(name, type, mask);
|
||||
if (IS_ERR(skcipher)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(skcipher);
|
||||
}
|
||||
|
||||
tfm->skcipher = skcipher;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void skcipher_release(void *private)
|
||||
{
|
||||
crypto_free_skcipher(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
crypto_free_skcipher(tfm->skcipher);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_skcipher_setkey(private, key, keylen);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void skcipher_wait(struct sock *sk)
|
||||
|
|
@ -788,24 +917,26 @@ static void skcipher_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
struct crypto_skcipher *skcipher = tfm->skcipher;
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
|
||||
GFP_KERNEL);
|
||||
if (!ctx->iv) {
|
||||
sock_kfree_s(sk, ctx, len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
|
||||
|
||||
INIT_LIST_HEAD(&ctx->tsgl);
|
||||
ctx->len = len;
|
||||
|
|
@ -818,8 +949,9 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
skcipher_request_set_tfm(&ctx->req, private);
|
||||
skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
skcipher_request_set_tfm(&ctx->req, skcipher);
|
||||
skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP |
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
sk->sk_destruct = skcipher_sock_destruct;
|
||||
|
|
@ -827,12 +959,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
|
||||
return -ENOKEY;
|
||||
|
||||
return skcipher_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_skcipher = {
|
||||
.bind = skcipher_bind,
|
||||
.release = skcipher_release,
|
||||
.setkey = skcipher_setkey,
|
||||
.accept = skcipher_accept_parent,
|
||||
.accept_nokey = skcipher_accept_parent_nokey,
|
||||
.ops = &algif_skcipher_ops,
|
||||
.ops_nokey = &algif_skcipher_ops_nokey,
|
||||
.name = "skcipher",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
|||
|
|
@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
MODULE_ALIAS_CRYPTO("crc32c-generic");
|
||||
MODULE_SOFTDEP("pre: crc32c");
|
||||
|
|
|
|||
|
|
@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (link->dump == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&crypto_alg_sem);
|
||||
list_for_each_entry(alg, &crypto_alg_list, cra_list)
|
||||
dump_alloc += CRYPTO_REPORT_MAXSIZE;
|
||||
|
||||
|
|
@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
.done = link->done,
|
||||
.min_dump_alloc = dump_alloc,
|
||||
};
|
||||
return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
|
||||
err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
|
||||
}
|
||||
up_read(&crypto_alg_sem);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
|
||||
|
|
|
|||
|
|
@ -354,9 +354,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
|
|||
crt->final = shash_async_final;
|
||||
crt->finup = shash_async_finup;
|
||||
crt->digest = shash_async_digest;
|
||||
crt->setkey = shash_async_setkey;
|
||||
|
||||
crt->has_setkey = alg->setkey != shash_no_setkey;
|
||||
|
||||
if (alg->setkey)
|
||||
crt->setkey = shash_async_setkey;
|
||||
if (alg->export)
|
||||
crt->export = shash_async_export;
|
||||
if (alg->import)
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->decrypt = skcipher_decrypt_blkcipher;
|
||||
|
||||
skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
|
||||
skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
|
||||
skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
|
||||
sizeof(struct ablkcipher_request);
|
||||
skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
|
||||
|
|
|
|||
|
|
@ -495,8 +495,8 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
|
|||
}
|
||||
}
|
||||
|
||||
/* fabricate port_map from cap.nr_ports */
|
||||
if (!port_map) {
|
||||
/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
|
||||
if (!port_map && vers < 0x10300) {
|
||||
port_map = (1 << ahci_nr_ports(cap)) - 1;
|
||||
dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map);
|
||||
|
||||
|
|
|
|||
|
|
@ -513,10 +513,15 @@ static int platform_drv_probe(struct device *_dev)
|
|||
return ret;
|
||||
|
||||
ret = dev_pm_domain_attach(_dev, true);
|
||||
if (ret != -EPROBE_DEFER && drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
} else {
|
||||
/* don't fail if just dev_pm_domain_attach failed */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
|
|||
*/
|
||||
static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL);
|
||||
struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO);
|
||||
if (!zstrm)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
|
|||
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
|
||||
* case when compressed size is larger than the original one
|
||||
*/
|
||||
zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
|
||||
zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1);
|
||||
if (!zstrm->private || !zstrm->buffer) {
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
zstrm = NULL;
|
||||
|
|
|
|||
|
|
@ -10,17 +10,36 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lz4.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "zcomp_lz4.h"
|
||||
|
||||
static void *zcomp_lz4_create(void)
|
||||
{
|
||||
return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
|
||||
void *ret;
|
||||
|
||||
/*
|
||||
* This function can be called in swapout/fs write path
|
||||
* so we can't use GFP_FS|IO. And it assumes we already
|
||||
* have at least one stream in zram initialization so we
|
||||
* don't do best effort to allocate more stream in here.
|
||||
* A default stream will work well without further multiple
|
||||
* streams. That's why we use NORETRY | NOWARN.
|
||||
*/
|
||||
ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
|
||||
__GFP_NOWARN);
|
||||
if (!ret)
|
||||
ret = __vmalloc(LZ4_MEM_COMPRESS,
|
||||
GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
|
||||
__GFP_ZERO | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void zcomp_lz4_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
kvfree(private);
|
||||
}
|
||||
|
||||
static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst,
|
||||
|
|
|
|||
|
|
@ -10,17 +10,36 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lzo.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "zcomp_lzo.h"
|
||||
|
||||
static void *lzo_create(void)
|
||||
{
|
||||
return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
|
||||
void *ret;
|
||||
|
||||
/*
|
||||
* This function can be called in swapout/fs write path
|
||||
* so we can't use GFP_FS|IO. And it assumes we already
|
||||
* have at least one stream in zram initialization so we
|
||||
* don't do best effort to allocate more stream in here.
|
||||
* A default stream will work well without further multiple
|
||||
* streams. That's why we use NORETRY | NOWARN.
|
||||
*/
|
||||
ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
|
||||
__GFP_NOWARN);
|
||||
if (!ret)
|
||||
ret = __vmalloc(LZO1X_MEM_COMPRESS,
|
||||
GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
|
||||
__GFP_ZERO | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lzo_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
kvfree(private);
|
||||
}
|
||||
|
||||
static int lzo_compress(const unsigned char *src, unsigned char *dst,
|
||||
|
|
|
|||
|
|
@ -1325,7 +1325,6 @@ static int zram_remove(struct zram *zram)
|
|||
|
||||
pr_info("Removed device: %s\n", zram->disk->disk_name);
|
||||
|
||||
idr_remove(&zram_index_idr, zram->disk->first_minor);
|
||||
blk_cleanup_queue(zram->disk->queue);
|
||||
del_gendisk(zram->disk);
|
||||
put_disk(zram->disk);
|
||||
|
|
@ -1367,10 +1366,12 @@ static ssize_t hot_remove_store(struct class *class,
|
|||
mutex_lock(&zram_index_mutex);
|
||||
|
||||
zram = idr_find(&zram_index_idr, dev_id);
|
||||
if (zram)
|
||||
if (zram) {
|
||||
ret = zram_remove(zram);
|
||||
else
|
||||
idr_remove(&zram_index_idr, dev_id);
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
mutex_unlock(&zram_index_mutex);
|
||||
return ret ? ret : count;
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct ahash_request *req, int err)
|
|||
dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
|
||||
SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY);
|
||||
|
||||
clk_disable_unprepare(dd->iclk);
|
||||
clk_disable(dd->iclk);
|
||||
|
||||
if (req->base.complete)
|
||||
req->base.complete(&req->base, err);
|
||||
|
|
@ -796,7 +796,7 @@ static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(dd->iclk);
|
||||
err = clk_enable(dd->iclk);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -823,7 +823,7 @@ static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
|
|||
dev_info(dd->dev,
|
||||
"version: 0x%x\n", dd->hw_version);
|
||||
|
||||
clk_disable_unprepare(dd->iclk);
|
||||
clk_disable(dd->iclk);
|
||||
}
|
||||
|
||||
static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
|
||||
|
|
@ -1411,6 +1411,10 @@ static int atmel_sha_probe(struct platform_device *pdev)
|
|||
goto res_err;
|
||||
}
|
||||
|
||||
err = clk_prepare(sha_dd->iclk);
|
||||
if (err)
|
||||
goto res_err;
|
||||
|
||||
atmel_sha_hw_version_init(sha_dd);
|
||||
|
||||
atmel_sha_get_cap(sha_dd);
|
||||
|
|
@ -1422,12 +1426,12 @@ static int atmel_sha_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(pdata)) {
|
||||
dev_err(&pdev->dev, "platform data not available\n");
|
||||
err = PTR_ERR(pdata);
|
||||
goto res_err;
|
||||
goto iclk_unprepare;
|
||||
}
|
||||
}
|
||||
if (!pdata->dma_slave) {
|
||||
err = -ENXIO;
|
||||
goto res_err;
|
||||
goto iclk_unprepare;
|
||||
}
|
||||
err = atmel_sha_dma_init(sha_dd, pdata);
|
||||
if (err)
|
||||
|
|
@ -1458,6 +1462,8 @@ err_algs:
|
|||
if (sha_dd->caps.has_dma)
|
||||
atmel_sha_dma_cleanup(sha_dd);
|
||||
err_sha_dma:
|
||||
iclk_unprepare:
|
||||
clk_unprepare(sha_dd->iclk);
|
||||
res_err:
|
||||
tasklet_kill(&sha_dd->done_task);
|
||||
sha_dd_err:
|
||||
|
|
@ -1484,12 +1490,7 @@ static int atmel_sha_remove(struct platform_device *pdev)
|
|||
if (sha_dd->caps.has_dma)
|
||||
atmel_sha_dma_cleanup(sha_dd);
|
||||
|
||||
iounmap(sha_dd->io_base);
|
||||
|
||||
clk_put(sha_dd->iclk);
|
||||
|
||||
if (sha_dd->irq >= 0)
|
||||
free_irq(sha_dd->irq, sha_dd);
|
||||
clk_unprepare(sha_dd->iclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -534,8 +534,8 @@ static int caam_probe(struct platform_device *pdev)
|
|||
* long pointers in master configuration register
|
||||
*/
|
||||
clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
|
||||
MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ?
|
||||
MCFGR_LONG_PTR : 0));
|
||||
MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE |
|
||||
(sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
|
||||
|
||||
/*
|
||||
* Read the Compile Time paramters and SCFGR to determine
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
|
|||
return -ENOMEM;
|
||||
|
||||
dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
|
||||
if (!dma->cache_pool)
|
||||
if (!dma->padding_pool)
|
||||
return -ENOMEM;
|
||||
|
||||
cesa->dma = dma;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ static struct sun4i_ss_alg_template ss_algs[] = {
|
|||
.import = sun4i_hash_import_md5,
|
||||
.halg = {
|
||||
.digestsize = MD5_DIGEST_SIZE,
|
||||
.statesize = sizeof(struct md5_state),
|
||||
.base = {
|
||||
.cra_name = "md5",
|
||||
.cra_driver_name = "md5-sun4i-ss",
|
||||
|
|
@ -66,6 +67,7 @@ static struct sun4i_ss_alg_template ss_algs[] = {
|
|||
.import = sun4i_hash_import_sha1,
|
||||
.halg = {
|
||||
.digestsize = SHA1_DIGEST_SIZE,
|
||||
.statesize = sizeof(struct sha1_state),
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name = "sha1-sun4i-ss",
|
||||
|
|
|
|||
|
|
@ -357,8 +357,19 @@ static void mt_feature_mapping(struct hid_device *hdev,
|
|||
break;
|
||||
}
|
||||
|
||||
td->inputmode = field->report->id;
|
||||
td->inputmode_index = usage->usage_index;
|
||||
if (td->inputmode < 0) {
|
||||
td->inputmode = field->report->id;
|
||||
td->inputmode_index = usage->usage_index;
|
||||
} else {
|
||||
/*
|
||||
* Some elan panels wrongly declare 2 input mode
|
||||
* features, and silently ignore when we set the
|
||||
* value in the second field. Skip the second feature
|
||||
* and hope for the best.
|
||||
*/
|
||||
dev_info(&hdev->dev,
|
||||
"Ignoring the extra HID_DG_INPUTMODE\n");
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_DG_CONTACTMAX:
|
||||
|
|
|
|||
|
|
@ -477,8 +477,6 @@ static void hid_ctrl(struct urb *urb)
|
|||
struct usbhid_device *usbhid = hid->driver_data;
|
||||
int unplug = 0, status = urb->status;
|
||||
|
||||
spin_lock(&usbhid->lock);
|
||||
|
||||
switch (status) {
|
||||
case 0: /* success */
|
||||
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
|
||||
|
|
@ -498,6 +496,8 @@ static void hid_ctrl(struct urb *urb)
|
|||
hid_warn(urb->dev, "ctrl urb status %d received\n", status);
|
||||
}
|
||||
|
||||
spin_lock(&usbhid->lock);
|
||||
|
||||
if (unplug) {
|
||||
usbhid->ctrltail = usbhid->ctrlhead;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
|
|||
int uninitialized_var(index);
|
||||
int uninitialized_var(inlen);
|
||||
int cqe_size;
|
||||
int irqn;
|
||||
unsigned int irqn;
|
||||
int eqn;
|
||||
int err;
|
||||
|
||||
|
|
|
|||
|
|
@ -405,17 +405,18 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
|
|||
arm_lpae_iopte *start, *end;
|
||||
unsigned long table_size;
|
||||
|
||||
/* Only leaf entries at the last level */
|
||||
if (lvl == ARM_LPAE_MAX_LEVELS - 1)
|
||||
return;
|
||||
|
||||
if (lvl == ARM_LPAE_START_LVL(data))
|
||||
table_size = data->pgd_size;
|
||||
else
|
||||
table_size = 1UL << data->pg_shift;
|
||||
|
||||
start = ptep;
|
||||
end = (void *)ptep + table_size;
|
||||
|
||||
/* Only leaf entries at the last level */
|
||||
if (lvl == ARM_LPAE_MAX_LEVELS - 1)
|
||||
end = ptep;
|
||||
else
|
||||
end = (void *)ptep + table_size;
|
||||
|
||||
while (ptep != end) {
|
||||
arm_lpae_iopte pte = *ptep++;
|
||||
|
|
|
|||
|
|
@ -2017,28 +2017,32 @@ int md_integrity_register(struct mddev *mddev)
|
|||
}
|
||||
EXPORT_SYMBOL(md_integrity_register);
|
||||
|
||||
/* Disable data integrity if non-capable/non-matching disk is being added */
|
||||
void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
|
||||
/*
|
||||
* Attempt to add an rdev, but only if it is consistent with the current
|
||||
* integrity profile
|
||||
*/
|
||||
int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
|
||||
{
|
||||
struct blk_integrity *bi_rdev;
|
||||
struct blk_integrity *bi_mddev;
|
||||
char name[BDEVNAME_SIZE];
|
||||
|
||||
if (!mddev->gendisk)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
bi_rdev = bdev_get_integrity(rdev->bdev);
|
||||
bi_mddev = blk_get_integrity(mddev->gendisk);
|
||||
|
||||
if (!bi_mddev) /* nothing to do */
|
||||
return;
|
||||
if (rdev->raid_disk < 0) /* skip spares */
|
||||
return;
|
||||
if (bi_rdev && blk_integrity_compare(mddev->gendisk,
|
||||
rdev->bdev->bd_disk) >= 0)
|
||||
return;
|
||||
WARN_ON_ONCE(!mddev->suspended);
|
||||
printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
|
||||
blk_integrity_unregister(mddev->gendisk);
|
||||
return 0;
|
||||
|
||||
if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) {
|
||||
printk(KERN_NOTICE "%s: incompatible integrity profile for %s\n",
|
||||
mdname(mddev), bdevname(rdev->bdev, name));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(md_integrity_add_rdev);
|
||||
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
|||
extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
|
||||
extern int md_check_no_bitmap(struct mddev *mddev);
|
||||
extern int md_integrity_register(struct mddev *mddev);
|
||||
extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
||||
extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
||||
extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
|
||||
|
||||
extern void mddev_init(struct mddev *mddev);
|
||||
|
|
|
|||
|
|
@ -257,6 +257,9 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
disk_stack_limits(mddev->gendisk, rdev->bdev,
|
||||
rdev->data_offset << 9);
|
||||
|
||||
err = md_integrity_add_rdev(rdev, mddev);
|
||||
if (err)
|
||||
break;
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
mddev->degraded--;
|
||||
rdev->raid_disk = path;
|
||||
|
|
@ -264,9 +267,6 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
spin_unlock_irq(&conf->device_lock);
|
||||
rcu_assign_pointer(p->rdev, rdev);
|
||||
err = 0;
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1589,6 +1589,9 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
if (mddev->recovery_disabled == conf->recovery_disabled)
|
||||
return -EBUSY;
|
||||
|
||||
if (md_integrity_add_rdev(rdev, mddev))
|
||||
return -ENXIO;
|
||||
|
||||
if (rdev->raid_disk >= 0)
|
||||
first = last = rdev->raid_disk;
|
||||
|
||||
|
|
@ -1632,9 +1635,6 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
break;
|
||||
}
|
||||
}
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
|
||||
print_conf(conf);
|
||||
|
|
|
|||
|
|
@ -1698,6 +1698,9 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1))
|
||||
return -EINVAL;
|
||||
|
||||
if (md_integrity_add_rdev(rdev, mddev))
|
||||
return -ENXIO;
|
||||
|
||||
if (rdev->raid_disk >= 0)
|
||||
first = last = rdev->raid_disk;
|
||||
|
||||
|
|
@ -1739,9 +1742,6 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
rcu_assign_pointer(p->rdev, rdev);
|
||||
break;
|
||||
}
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
|
||||
|
||||
|
|
|
|||
|
|
@ -478,7 +478,6 @@ static const struct i2c_device_id ir_kbd_id[] = {
|
|||
{ "ir_rx_z8f0811_hdpvr", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
|
||||
|
||||
static struct i2c_driver ir_kbd_driver = {
|
||||
.driver = {
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,8 @@ static int alsa_device_init(struct saa7134_dev *dev)
|
|||
|
||||
static int alsa_device_exit(struct saa7134_dev *dev)
|
||||
{
|
||||
if (!snd_saa7134_cards[dev->nr])
|
||||
return 1;
|
||||
|
||||
snd_card_free(snd_saa7134_cards[dev->nr]);
|
||||
snd_saa7134_cards[dev->nr] = NULL;
|
||||
|
|
@ -1260,7 +1262,8 @@ static void saa7134_alsa_exit(void)
|
|||
int idx;
|
||||
|
||||
for (idx = 0; idx < SNDRV_CARDS; idx++) {
|
||||
snd_card_free(snd_saa7134_cards[idx]);
|
||||
if (snd_saa7134_cards[idx])
|
||||
snd_card_free(snd_saa7134_cards[idx]);
|
||||
}
|
||||
|
||||
saa7134_dmasound_init = NULL;
|
||||
|
|
|
|||
|
|
@ -3995,6 +3995,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!mtd->name && mtd->dev.parent)
|
||||
mtd->name = dev_name(mtd->dev.parent);
|
||||
|
||||
/* Set the default functions */
|
||||
nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
|
||||
|
||||
|
|
|
|||
|
|
@ -1207,7 +1207,6 @@ static int bond_master_upper_dev_link(struct net_device *bond_dev,
|
|||
err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
|
||||
if (err)
|
||||
return err;
|
||||
slave_dev->flags |= IFF_SLAVE;
|
||||
rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1465,6 +1464,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* set slave flag before open to prevent IPv6 addrconf */
|
||||
slave_dev->flags |= IFF_SLAVE;
|
||||
|
||||
/* open the slave since the application closed it */
|
||||
res = dev_open(slave_dev);
|
||||
if (res) {
|
||||
|
|
@ -1725,6 +1727,7 @@ err_close:
|
|||
dev_close(slave_dev);
|
||||
|
||||
err_restore_mac:
|
||||
slave_dev->flags &= ~IFF_SLAVE;
|
||||
if (!bond->params.fail_over_mac ||
|
||||
BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
|
||||
/* XXX TODO - fom follow mode needs to change master's
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ static int mlx5e_create_cq(struct mlx5e_channel *c,
|
|||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
struct mlx5_core_cq *mcq = &cq->mcq;
|
||||
int eqn_not_used;
|
||||
int irqn;
|
||||
unsigned int irqn;
|
||||
int err;
|
||||
u32 i;
|
||||
|
||||
|
|
@ -800,7 +800,7 @@ static int mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
|
|||
void *in;
|
||||
void *cqc;
|
||||
int inlen;
|
||||
int irqn_not_used;
|
||||
unsigned int irqn_not_used;
|
||||
int eqn;
|
||||
int err;
|
||||
|
||||
|
|
@ -1504,7 +1504,7 @@ static int mlx5e_create_drop_cq(struct mlx5e_priv *priv,
|
|||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
struct mlx5_core_cq *mcq = &cq->mcq;
|
||||
int eqn_not_used;
|
||||
int irqn;
|
||||
unsigned int irqn;
|
||||
int err;
|
||||
|
||||
err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq,
|
||||
|
|
|
|||
|
|
@ -568,7 +568,8 @@ static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
|
|||
mlx5_irq_clear_affinity_hint(mdev, i);
|
||||
}
|
||||
|
||||
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn)
|
||||
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
|
||||
unsigned int *irqn)
|
||||
{
|
||||
struct mlx5_eq_table *table = &dev->priv.eq_table;
|
||||
struct mlx5_eq *eq, *n;
|
||||
|
|
|
|||
|
|
@ -2107,7 +2107,7 @@ static int dwceqos_tx_frags(struct sk_buff *skb, struct net_local *lp,
|
|||
dd = &lp->tx_descs[lp->tx_next];
|
||||
|
||||
/* Set DMA Descriptor fields */
|
||||
dd->des0 = dma_handle;
|
||||
dd->des0 = dma_handle + consumed_size;
|
||||
dd->des1 = 0;
|
||||
dd->des2 = dma_size;
|
||||
|
||||
|
|
|
|||
|
|
@ -1845,10 +1845,10 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
|
|||
struct team *team = netdev_priv(dev);
|
||||
struct team_port *port;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(port, &team->port_list, list)
|
||||
mutex_lock(&team->lock);
|
||||
list_for_each_entry(port, &team->port_list, list)
|
||||
vlan_vid_del(port->dev, proto, vid);
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&team->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2751,7 +2751,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
|
|||
struct vxlan_config *conf)
|
||||
{
|
||||
struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
|
||||
struct vxlan_rdst *dst = &vxlan->default_dst;
|
||||
unsigned short needed_headroom = ETH_HLEN;
|
||||
int err;
|
||||
|
|
@ -2817,9 +2817,15 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
|
|||
if (!vxlan->cfg.age_interval)
|
||||
vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
|
||||
|
||||
if (vxlan_find_vni(src_net, conf->vni, use_ipv6 ? AF_INET6 : AF_INET,
|
||||
vxlan->cfg.dst_port, vxlan->flags))
|
||||
list_for_each_entry(tmp, &vn->vxlan_list, next) {
|
||||
if (tmp->cfg.vni == conf->vni &&
|
||||
(tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
|
||||
tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
|
||||
tmp->cfg.dst_port == vxlan->cfg.dst_port &&
|
||||
(tmp->flags & VXLAN_F_RCV_FLAGS) ==
|
||||
(vxlan->flags & VXLAN_F_RCV_FLAGS))
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
dev->ethtool_ops = &vxlan_ethtool_ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -351,7 +351,6 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
|
|||
case COUNTRY_CODE_SPAIN:
|
||||
case COUNTRY_CODE_FRANCE:
|
||||
case COUNTRY_CODE_ISRAEL:
|
||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||
return &rtl_regdom_12_13;
|
||||
case COUNTRY_CODE_MKK:
|
||||
case COUNTRY_CODE_MKK1:
|
||||
|
|
@ -360,6 +359,7 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
|
|||
return &rtl_regdom_14_60_64;
|
||||
case COUNTRY_CODE_GLOBAL_DOMAIN:
|
||||
return &rtl_regdom_14;
|
||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||
case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
|
||||
return &rtl_regdom_12_13_5g_all;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -95,8 +95,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
|||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
|
||||
rtl8821ae_bt_reg_init(hw);
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
|
||||
|
||||
rtlpriv->dm.dm_initialgain_enable = 1;
|
||||
|
|
@ -168,12 +166,15 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
|||
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
|
||||
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpriv->cfg->mod_params->sw_crypto =
|
||||
rtlpriv->cfg->mod_params->sw_crypto;
|
||||
rtlpriv->cfg->mod_params->disable_watchdog =
|
||||
rtlpriv->cfg->mod_params->disable_watchdog;
|
||||
if (rtlpriv->cfg->mod_params->disable_watchdog)
|
||||
pr_info("watchdog disabled\n");
|
||||
rtlpriv->psc.reg_fwctrl_lps = 3;
|
||||
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
|
||||
/* for ASPM, you can close aspm through
|
||||
* set const_support_pciaspm = 0
|
||||
|
|
|
|||
|
|
@ -531,6 +531,8 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
|
|||
ieee80211_rx(hw, skb);
|
||||
else
|
||||
dev_kfree_skb_any(skb);
|
||||
} else {
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -207,19 +207,23 @@ static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg,
|
|||
|
||||
static inline void wl1271_power_off(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
|
||||
return;
|
||||
|
||||
ret = wl->if_ops->power(wl->dev, false);
|
||||
if (wl->if_ops->power)
|
||||
ret = wl->if_ops->power(wl->dev, false);
|
||||
if (!ret)
|
||||
clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
|
||||
}
|
||||
|
||||
static inline int wl1271_power_on(struct wl1271 *wl)
|
||||
{
|
||||
int ret = wl->if_ops->power(wl->dev, true);
|
||||
int ret = 0;
|
||||
|
||||
if (wl->if_ops->power)
|
||||
ret = wl->if_ops->power(wl->dev, true);
|
||||
if (ret == 0)
|
||||
set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,10 @@
|
|||
*/
|
||||
#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
|
||||
|
||||
#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
|
||||
/* Maximum number of SPI write chunks */
|
||||
#define WSPI_MAX_NUM_OF_CHUNKS \
|
||||
((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
|
||||
|
||||
|
||||
struct wl12xx_spi_glue {
|
||||
struct device *dev;
|
||||
|
|
@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
|
|||
void *buf, size_t len, bool fixed)
|
||||
{
|
||||
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
|
||||
struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
|
||||
/* SPI write buffers - 2 for each chunk */
|
||||
struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
|
||||
struct spi_message m;
|
||||
u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
|
||||
u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
|
||||
u32 *cmd;
|
||||
u32 chunk_len;
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
type_mask |= IORESOURCE_TYPE_BITS;
|
||||
|
||||
pci_bus_for_each_resource(bus, r, i) {
|
||||
resource_size_t min_used = min;
|
||||
|
||||
if (!r)
|
||||
continue;
|
||||
|
||||
|
|
@ -163,12 +165,12 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
* overrides "min".
|
||||
*/
|
||||
if (avail.start)
|
||||
min = avail.start;
|
||||
min_used = avail.start;
|
||||
|
||||
max = avail.end;
|
||||
|
||||
/* Ok, try it out.. */
|
||||
ret = allocate_resource(r, res, size, min, max,
|
||||
ret = allocate_resource(r, res, size, min_used, max,
|
||||
align, alignf, alignf_data);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -302,7 +302,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
|
|||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, pp->irq,
|
||||
dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
|
||||
dra7xx_pcie_msi_irq_handler,
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"dra7-pcie-msi", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request irq\n");
|
||||
|
|
|
|||
|
|
@ -522,7 +522,8 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
|
|||
|
||||
ret = devm_request_irq(&pdev->dev, pp->msi_irq,
|
||||
exynos_pcie_msi_irq_handler,
|
||||
IRQF_SHARED, "exynos-pcie", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"exynos-pcie", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request msi irq\n");
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -537,7 +537,8 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
|
|||
|
||||
ret = devm_request_irq(&pdev->dev, pp->msi_irq,
|
||||
imx6_pcie_msi_handler,
|
||||
IRQF_SHARED, "mx6-pcie-msi", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"mx6-pcie-msi", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request MSI irq\n");
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1288,7 +1288,7 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
|
|||
|
||||
msi->irq = err;
|
||||
|
||||
err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
|
||||
err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
|
||||
tegra_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
|
|
|
|||
|
|
@ -720,14 +720,16 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
|
|||
|
||||
/* Two irqs are for MSI, but they are also used for non-MSI irqs */
|
||||
err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
|
|||
return -ENODEV;
|
||||
}
|
||||
ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
|
||||
IRQF_SHARED, "spear1340-pcie", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"spear1340-pcie", pp);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request irq %d\n", pp->irq);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
|
|||
|
||||
port->irq = irq_of_parse_and_map(node, 0);
|
||||
err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler,
|
||||
IRQF_SHARED, "xilinx-pcie", port);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"xilinx-pcie", port);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to request irq %d\n", port->irq);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -258,16 +258,13 @@ static void n_tty_check_throttle(struct tty_struct *tty)
|
|||
|
||||
static void n_tty_check_unthrottle(struct tty_struct *tty)
|
||||
{
|
||||
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
||||
tty->link->ldisc->ops->write_wakeup == n_tty_write_wakeup) {
|
||||
if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
|
||||
if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
|
||||
return;
|
||||
if (!tty->count)
|
||||
return;
|
||||
n_tty_kick_worker(tty);
|
||||
n_tty_write_wakeup(tty->link);
|
||||
if (waitqueue_active(&tty->link->write_wait))
|
||||
wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT);
|
||||
tty_wakeup(tty->link);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1462,13 +1462,13 @@ static int tty_reopen(struct tty_struct *tty)
|
|||
{
|
||||
struct tty_driver *driver = tty->driver;
|
||||
|
||||
if (!tty->count)
|
||||
return -EIO;
|
||||
|
||||
if (driver->type == TTY_DRIVER_TYPE_PTY &&
|
||||
driver->subtype == PTY_TYPE_MASTER)
|
||||
return -EIO;
|
||||
|
||||
if (!tty->count)
|
||||
return -EAGAIN;
|
||||
|
||||
if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
|
||||
return -EBUSY;
|
||||
|
||||
|
|
@ -2069,7 +2069,12 @@ retry_open:
|
|||
|
||||
if (tty) {
|
||||
mutex_unlock(&tty_mutex);
|
||||
tty_lock(tty);
|
||||
retval = tty_lock_interruptible(tty);
|
||||
if (retval) {
|
||||
if (retval == -EINTR)
|
||||
retval = -ERESTARTSYS;
|
||||
goto err_unref;
|
||||
}
|
||||
/* safe to drop the kref from tty_driver_lookup_tty() */
|
||||
tty_kref_put(tty);
|
||||
retval = tty_reopen(tty);
|
||||
|
|
@ -2087,7 +2092,11 @@ retry_open:
|
|||
|
||||
if (IS_ERR(tty)) {
|
||||
retval = PTR_ERR(tty);
|
||||
goto err_file;
|
||||
if (retval != -EAGAIN || signal_pending(current))
|
||||
goto err_file;
|
||||
tty_free_file(filp);
|
||||
schedule();
|
||||
goto retry_open;
|
||||
}
|
||||
|
||||
tty_add_file(tty, filp);
|
||||
|
|
@ -2156,6 +2165,7 @@ retry_open:
|
|||
return 0;
|
||||
err_unlock:
|
||||
mutex_unlock(&tty_mutex);
|
||||
err_unref:
|
||||
/* after locks to avoid deadlock */
|
||||
if (!IS_ERR_OR_NULL(driver))
|
||||
tty_driver_kref_put(driver);
|
||||
|
|
@ -2652,6 +2662,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* tiocgetd - get line discipline
|
||||
* @tty: tty device
|
||||
* @p: pointer to user data
|
||||
*
|
||||
* Retrieves the line discipline id directly from the ldisc.
|
||||
*
|
||||
* Locking: waits for ldisc reference (in case the line discipline
|
||||
* is changing or the tty is being hungup)
|
||||
*/
|
||||
|
||||
static int tiocgetd(struct tty_struct *tty, int __user *p)
|
||||
{
|
||||
struct tty_ldisc *ld;
|
||||
int ret;
|
||||
|
||||
ld = tty_ldisc_ref_wait(tty);
|
||||
ret = put_user(ld->ops->num, p);
|
||||
tty_ldisc_deref(ld);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* send_break - performed time break
|
||||
* @tty: device to break on
|
||||
|
|
@ -2878,7 +2910,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
case TIOCGSID:
|
||||
return tiocgsid(tty, real_tty, p);
|
||||
case TIOCGETD:
|
||||
return put_user(tty->ldisc->ops->num, (int __user *)p);
|
||||
return tiocgetd(tty, p);
|
||||
case TIOCSETD:
|
||||
return tiocsetd(tty, p);
|
||||
case TIOCVHANGUP:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,14 @@ void __lockfunc tty_lock(struct tty_struct *tty)
|
|||
}
|
||||
EXPORT_SYMBOL(tty_lock);
|
||||
|
||||
int tty_lock_interruptible(struct tty_struct *tty)
|
||||
{
|
||||
if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty))
|
||||
return -EIO;
|
||||
tty_kref_get(tty);
|
||||
return mutex_lock_interruptible(&tty->legacy_mutex);
|
||||
}
|
||||
|
||||
void __lockfunc tty_unlock(struct tty_struct *tty)
|
||||
{
|
||||
if (tty->magic != TTY_MAGIC) {
|
||||
|
|
|
|||
|
|
@ -428,7 +428,8 @@ static void acm_read_bulk_callback(struct urb *urb)
|
|||
set_bit(rb->index, &acm->read_urbs_free);
|
||||
dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
|
||||
__func__, status);
|
||||
return;
|
||||
if ((status != -ENOENT) || (urb->actual_length == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
usb_mark_last_busy(acm->dev);
|
||||
|
|
@ -1404,6 +1405,8 @@ made_compressed_probe:
|
|||
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
NULL, acm->writesize, acm_write_bulk, snd);
|
||||
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
if (quirks & SEND_ZERO_PACKET)
|
||||
snd->urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
snd->instance = acm;
|
||||
}
|
||||
|
||||
|
|
@ -1861,6 +1864,10 @@ static const struct usb_device_id acm_ids[] = {
|
|||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
|
||||
USB_CDC_ACM_PROTO_AT_CDMA) },
|
||||
|
||||
{ USB_DEVICE(0x1519, 0x0452), /* Intel 7260 modem */
|
||||
.driver_info = SEND_ZERO_PACKET,
|
||||
},
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -134,3 +134,4 @@ struct acm {
|
|||
#define IGNORE_DEVICE BIT(5)
|
||||
#define QUIRK_CONTROL_LINE_STATE BIT(6)
|
||||
#define CLEAR_HALT_CONDITIONS BIT(7)
|
||||
#define SEND_ZERO_PACKET BIT(8)
|
||||
|
|
|
|||
|
|
@ -3895,17 +3895,30 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
return;
|
||||
}
|
||||
|
||||
if (usb_set_lpm_timeout(udev, state, timeout))
|
||||
if (usb_set_lpm_timeout(udev, state, timeout)) {
|
||||
/* If we can't set the parent hub U1/U2 timeout,
|
||||
* device-initiated LPM won't be allowed either, so let the xHCI
|
||||
* host know that this link state won't be enabled.
|
||||
*/
|
||||
hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
|
||||
} else {
|
||||
/* Only a configured device will accept the Set Feature
|
||||
* U1/U2_ENABLE
|
||||
*/
|
||||
if (udev->actconfig)
|
||||
usb_set_device_initiated_lpm(udev, state, true);
|
||||
|
||||
/* Only a configured device will accept the Set Feature U1/U2_ENABLE */
|
||||
else if (udev->actconfig)
|
||||
usb_set_device_initiated_lpm(udev, state, true);
|
||||
|
||||
/* As soon as usb_set_lpm_timeout(timeout) returns 0, the
|
||||
* hub-initiated LPM is enabled. Thus, LPM is enabled no
|
||||
* matter the result of usb_set_device_initiated_lpm().
|
||||
* The only difference is whether device is able to initiate
|
||||
* LPM.
|
||||
*/
|
||||
if (state == USB3_LPM_U1)
|
||||
udev->usb3_lpm_u1_enabled = 1;
|
||||
else if (state == USB3_LPM_U2)
|
||||
udev->usb3_lpm_u2_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3945,6 +3958,18 @@ static int usb_disable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
dev_warn(&udev->dev, "Could not disable xHCI %s timeout, "
|
||||
"bus schedule bandwidth may be impacted.\n",
|
||||
usb3_lpm_names[state]);
|
||||
|
||||
/* As soon as usb_set_lpm_timeout(0) return 0, hub initiated LPM
|
||||
* is disabled. Hub will disallows link to enter U1/U2 as well,
|
||||
* even device is initiating LPM. Hence LPM is disabled if hub LPM
|
||||
* timeout set to 0, no matter device-initiated LPM is disabled or
|
||||
* not.
|
||||
*/
|
||||
if (state == USB3_LPM_U1)
|
||||
udev->usb3_lpm_u1_enabled = 0;
|
||||
else if (state == USB3_LPM_U2)
|
||||
udev->usb3_lpm_u2_enabled = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3979,8 +4004,6 @@ int usb_disable_lpm(struct usb_device *udev)
|
|||
if (usb_disable_link_state(hcd, udev, USB3_LPM_U2))
|
||||
goto enable_lpm;
|
||||
|
||||
udev->usb3_lpm_enabled = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
enable_lpm:
|
||||
|
|
@ -4038,8 +4061,6 @@ void usb_enable_lpm(struct usb_device *udev)
|
|||
|
||||
usb_enable_link_state(hcd, udev, USB3_LPM_U1);
|
||||
usb_enable_link_state(hcd, udev, USB3_LPM_U2);
|
||||
|
||||
udev->usb3_lpm_enabled = 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_enable_lpm);
|
||||
|
||||
|
|
@ -5365,7 +5386,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
|||
}
|
||||
|
||||
bos = udev->bos;
|
||||
udev->bos = NULL;
|
||||
|
||||
for (i = 0; i < SET_CONFIG_TRIES; ++i) {
|
||||
|
||||
|
|
@ -5458,8 +5478,11 @@ done:
|
|||
usb_set_usb2_hardware_lpm(udev, 1);
|
||||
usb_unlocked_enable_lpm(udev);
|
||||
usb_enable_ltm(udev);
|
||||
usb_release_bos_descriptor(udev);
|
||||
udev->bos = bos;
|
||||
/* release the new BOS descriptor allocated by hub_port_init() */
|
||||
if (udev->bos != bos) {
|
||||
usb_release_bos_descriptor(udev);
|
||||
udev->bos = bos;
|
||||
}
|
||||
return 0;
|
||||
|
||||
re_enumerate:
|
||||
|
|
|
|||
|
|
@ -531,7 +531,7 @@ static ssize_t usb2_lpm_besl_store(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR_RW(usb2_lpm_besl);
|
||||
|
||||
static ssize_t usb3_hardware_lpm_show(struct device *dev,
|
||||
static ssize_t usb3_hardware_lpm_u1_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
|
|
@ -539,7 +539,7 @@ static ssize_t usb3_hardware_lpm_show(struct device *dev,
|
|||
|
||||
usb_lock_device(udev);
|
||||
|
||||
if (udev->usb3_lpm_enabled)
|
||||
if (udev->usb3_lpm_u1_enabled)
|
||||
p = "enabled";
|
||||
else
|
||||
p = "disabled";
|
||||
|
|
@ -548,7 +548,26 @@ static ssize_t usb3_hardware_lpm_show(struct device *dev,
|
|||
|
||||
return sprintf(buf, "%s\n", p);
|
||||
}
|
||||
static DEVICE_ATTR_RO(usb3_hardware_lpm);
|
||||
static DEVICE_ATTR_RO(usb3_hardware_lpm_u1);
|
||||
|
||||
static ssize_t usb3_hardware_lpm_u2_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
const char *p;
|
||||
|
||||
usb_lock_device(udev);
|
||||
|
||||
if (udev->usb3_lpm_u2_enabled)
|
||||
p = "enabled";
|
||||
else
|
||||
p = "disabled";
|
||||
|
||||
usb_unlock_device(udev);
|
||||
|
||||
return sprintf(buf, "%s\n", p);
|
||||
}
|
||||
static DEVICE_ATTR_RO(usb3_hardware_lpm_u2);
|
||||
|
||||
static struct attribute *usb2_hardware_lpm_attr[] = {
|
||||
&dev_attr_usb2_hardware_lpm.attr,
|
||||
|
|
@ -562,7 +581,8 @@ static struct attribute_group usb2_hardware_lpm_attr_group = {
|
|||
};
|
||||
|
||||
static struct attribute *usb3_hardware_lpm_attr[] = {
|
||||
&dev_attr_usb3_hardware_lpm.attr,
|
||||
&dev_attr_usb3_hardware_lpm_u1.attr,
|
||||
&dev_attr_usb3_hardware_lpm_u2.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group usb3_hardware_lpm_attr_group = {
|
||||
|
|
@ -592,7 +612,8 @@ static int add_power_attributes(struct device *dev)
|
|||
if (udev->usb2_hw_lpm_capable == 1)
|
||||
rc = sysfs_merge_group(&dev->kobj,
|
||||
&usb2_hardware_lpm_attr_group);
|
||||
if (udev->lpm_capable == 1)
|
||||
if (udev->speed == USB_SPEED_SUPER &&
|
||||
udev->lpm_capable == 1)
|
||||
rc = sysfs_merge_group(&dev->kobj,
|
||||
&usb3_hardware_lpm_attr_group);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@
|
|||
#include "xhci.h"
|
||||
#include "xhci-trace.h"
|
||||
|
||||
#define PORT2_SSIC_CONFIG_REG2 0x883c
|
||||
#define SSIC_PORT_NUM 2
|
||||
#define SSIC_PORT_CFG2 0x880c
|
||||
#define SSIC_PORT_CFG2_OFFSET 0x30
|
||||
#define PROG_DONE (1 << 30)
|
||||
#define SSIC_PORT_UNUSED (1 << 31)
|
||||
|
||||
|
|
@ -45,6 +47,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5
|
||||
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f
|
||||
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
|
||||
#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
|
||||
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
|
||||
|
|
@ -152,7 +155,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
|||
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) {
|
||||
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
|
||||
|
|
@ -322,28 +326,36 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend)
|
|||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
u32 val;
|
||||
void __iomem *reg;
|
||||
int i;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
|
||||
|
||||
reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2;
|
||||
for (i = 0; i < SSIC_PORT_NUM; i++) {
|
||||
reg = (void __iomem *) xhci->cap_regs +
|
||||
SSIC_PORT_CFG2 +
|
||||
i * SSIC_PORT_CFG2_OFFSET;
|
||||
|
||||
/* Notify SSIC that SSIC profile programming is not done */
|
||||
val = readl(reg) & ~PROG_DONE;
|
||||
writel(val, reg);
|
||||
/*
|
||||
* Notify SSIC that SSIC profile programming
|
||||
* is not done.
|
||||
*/
|
||||
val = readl(reg) & ~PROG_DONE;
|
||||
writel(val, reg);
|
||||
|
||||
/* Mark SSIC port as unused(suspend) or used(resume) */
|
||||
val = readl(reg);
|
||||
if (suspend)
|
||||
val |= SSIC_PORT_UNUSED;
|
||||
else
|
||||
val &= ~SSIC_PORT_UNUSED;
|
||||
writel(val, reg);
|
||||
/* Mark SSIC port as unused(suspend) or used(resume) */
|
||||
val = readl(reg);
|
||||
if (suspend)
|
||||
val |= SSIC_PORT_UNUSED;
|
||||
else
|
||||
val &= ~SSIC_PORT_UNUSED;
|
||||
writel(val, reg);
|
||||
|
||||
/* Notify SSIC that SSIC profile programming is done */
|
||||
val = readl(reg) | PROG_DONE;
|
||||
writel(val, reg);
|
||||
readl(reg);
|
||||
/* Notify SSIC that SSIC profile programming is done */
|
||||
val = readl(reg) | PROG_DONE;
|
||||
writel(val, reg);
|
||||
readl(reg);
|
||||
}
|
||||
}
|
||||
|
||||
reg = (void __iomem *) xhci->cap_regs + 0x80a4;
|
||||
|
|
|
|||
|
|
@ -5059,6 +5059,10 @@ static int __init xhci_hcd_init(void)
|
|||
BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
|
||||
/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
|
||||
BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1599,6 +1599,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
|
|||
&motg->id.nb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "register ID notifier failed\n");
|
||||
extcon_unregister_notifier(motg->vbus.extcon,
|
||||
EXTCON_USB, &motg->vbus.nb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1660,15 +1662,6 @@ static int msm_otg_probe(struct platform_device *pdev)
|
|||
if (!motg)
|
||||
return -ENOMEM;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
if (!np)
|
||||
return -ENXIO;
|
||||
ret = msm_otg_read_dt(pdev, motg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
|
||||
GFP_KERNEL);
|
||||
if (!motg->phy.otg)
|
||||
|
|
@ -1710,6 +1703,15 @@ static int msm_otg_probe(struct platform_device *pdev)
|
|||
if (!motg->regs)
|
||||
return -ENOMEM;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
if (!np)
|
||||
return -ENXIO;
|
||||
ret = msm_otg_read_dt(pdev, motg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: The PHYs can be multiplexed between the chipidea controller
|
||||
* and the dwc3 controller, using a single bit. It is important that
|
||||
|
|
@ -1717,8 +1719,10 @@ static int msm_otg_probe(struct platform_device *pdev)
|
|||
*/
|
||||
if (motg->phy_number) {
|
||||
phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4);
|
||||
if (!phy_select)
|
||||
return -ENOMEM;
|
||||
if (!phy_select) {
|
||||
ret = -ENOMEM;
|
||||
goto unregister_extcon;
|
||||
}
|
||||
/* Enable second PHY with the OTG port */
|
||||
writel(0x1, phy_select);
|
||||
}
|
||||
|
|
@ -1728,7 +1732,8 @@ static int msm_otg_probe(struct platform_device *pdev)
|
|||
motg->irq = platform_get_irq(pdev, 0);
|
||||
if (motg->irq < 0) {
|
||||
dev_err(&pdev->dev, "platform_get_irq failed\n");
|
||||
return motg->irq;
|
||||
ret = motg->irq;
|
||||
goto unregister_extcon;
|
||||
}
|
||||
|
||||
regs[0].supply = "vddcx";
|
||||
|
|
@ -1737,7 +1742,7 @@ static int msm_otg_probe(struct platform_device *pdev)
|
|||
|
||||
ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto unregister_extcon;
|
||||
|
||||
motg->vddcx = regs[0].consumer;
|
||||
motg->v3p3 = regs[1].consumer;
|
||||
|
|
@ -1834,6 +1839,12 @@ disable_clks:
|
|||
clk_disable_unprepare(motg->clk);
|
||||
if (!IS_ERR(motg->core_clk))
|
||||
clk_disable_unprepare(motg->core_clk);
|
||||
unregister_extcon:
|
||||
extcon_unregister_notifier(motg->id.extcon,
|
||||
EXTCON_USB_HOST, &motg->id.nb);
|
||||
extcon_unregister_notifier(motg->vbus.extcon,
|
||||
EXTCON_USB, &motg->vbus.nb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
|
||||
{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
|
||||
{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
|
||||
{ USB_DEVICE(0x10C4, 0x81D7) }, /* IAI Corp. RCB-CV-USB USB to RS485 Adaptor */
|
||||
{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
|
||||
{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
|
||||
{ USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
|
||||
|
|
@ -160,6 +161,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
|
||||
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
|
||||
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
|
||||
{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
|
||||
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
|
||||
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
|
||||
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
|
||||
|
|
|
|||
|
|
@ -824,6 +824,7 @@ static const struct usb_device_id id_table_combined[] = {
|
|||
{ USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
|
||||
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
|
||||
|
||||
/* Papouch devices based on FTDI chip */
|
||||
|
|
|
|||
|
|
@ -615,6 +615,7 @@
|
|||
*/
|
||||
#define RATOC_VENDOR_ID 0x0584
|
||||
#define RATOC_PRODUCT_ID_USB60F 0xb020
|
||||
#define RATOC_PRODUCT_ID_SCU18 0xb03a
|
||||
|
||||
/*
|
||||
* Infineon Technologies
|
||||
|
|
|
|||
|
|
@ -268,6 +268,8 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define TELIT_PRODUCT_CC864_SINGLE 0x1006
|
||||
#define TELIT_PRODUCT_DE910_DUAL 0x1010
|
||||
#define TELIT_PRODUCT_UE910_V2 0x1012
|
||||
#define TELIT_PRODUCT_LE922_USBCFG0 0x1042
|
||||
#define TELIT_PRODUCT_LE922_USBCFG3 0x1043
|
||||
#define TELIT_PRODUCT_LE920 0x1200
|
||||
#define TELIT_PRODUCT_LE910 0x1201
|
||||
|
||||
|
|
@ -615,6 +617,16 @@ static const struct option_blacklist_info telit_le920_blacklist = {
|
|||
.reserved = BIT(1) | BIT(5),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = {
|
||||
.sendsetup = BIT(2),
|
||||
.reserved = BIT(0) | BIT(1) | BIT(3),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = {
|
||||
.sendsetup = BIT(0),
|
||||
.reserved = BIT(1) | BIT(2) | BIT(3),
|
||||
};
|
||||
|
||||
static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||
|
|
@ -1160,6 +1172,10 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
|
||||
.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
|
||||
.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
|
||||
.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
|
||||
|
|
@ -1679,7 +1695,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
|
||||
|
|
|
|||
|
|
@ -544,6 +544,11 @@ static int treo_attach(struct usb_serial *serial)
|
|||
(serial->num_interrupt_in == 0))
|
||||
return 0;
|
||||
|
||||
if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) {
|
||||
dev_err(&serial->interface->dev, "missing endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* It appears that Treos and Kyoceras want to use the
|
||||
* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
|
||||
|
|
@ -597,8 +602,10 @@ static int clie_5_attach(struct usb_serial *serial)
|
|||
*/
|
||||
|
||||
/* some sanity check */
|
||||
if (serial->num_ports < 2)
|
||||
return -1;
|
||||
if (serial->num_bulk_out < 2) {
|
||||
dev_err(&serial->interface->dev, "missing bulk out endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* port 0 now uses the modified endpoint Address */
|
||||
port = serial->port[0];
|
||||
|
|
|
|||
|
|
@ -213,9 +213,11 @@ retry:
|
|||
res = -ENOKEY;
|
||||
goto out;
|
||||
}
|
||||
down_read(&keyring_key->sem);
|
||||
ukp = user_key_payload(keyring_key);
|
||||
if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
|
||||
res = -EINVAL;
|
||||
up_read(&keyring_key->sem);
|
||||
goto out;
|
||||
}
|
||||
master_key = (struct ext4_encryption_key *)ukp->data;
|
||||
|
|
@ -226,10 +228,12 @@ retry:
|
|||
"ext4: key size incorrect: %d\n",
|
||||
master_key->size);
|
||||
res = -ENOKEY;
|
||||
up_read(&keyring_key->sem);
|
||||
goto out;
|
||||
}
|
||||
res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
|
||||
raw_key);
|
||||
up_read(&keyring_key->sem);
|
||||
if (res)
|
||||
goto out;
|
||||
got_key:
|
||||
|
|
|
|||
|
|
@ -8054,7 +8054,6 @@ static void nfs4_layoutreturn_release(void *calldata)
|
|||
pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
|
||||
pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range);
|
||||
pnfs_clear_layoutreturn_waitbit(lo);
|
||||
lo->plh_block_lgets--;
|
||||
spin_unlock(&lo->plh_inode->i_lock);
|
||||
pnfs_free_lseg_list(&freeme);
|
||||
pnfs_put_layout_hdr(lrp->args.layout);
|
||||
|
|
|
|||
|
|
@ -2519,6 +2519,11 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
|
|||
spin_lock(&dlm->master_lock);
|
||||
ret = dlm_add_migration_mle(dlm, res, mle, &oldmle, name,
|
||||
namelen, target, dlm->node_num);
|
||||
/* get an extra reference on the mle.
|
||||
* otherwise the assert_master from the new
|
||||
* master will destroy this.
|
||||
*/
|
||||
dlm_get_mle_inuse(mle);
|
||||
spin_unlock(&dlm->master_lock);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
|
|
@ -2554,6 +2559,7 @@ fail:
|
|||
if (mle_added) {
|
||||
dlm_mle_detach_hb_events(dlm, mle);
|
||||
dlm_put_mle(mle);
|
||||
dlm_put_mle_inuse(mle);
|
||||
} else if (mle) {
|
||||
kmem_cache_free(dlm_mle_cache, mle);
|
||||
mle = NULL;
|
||||
|
|
@ -2571,17 +2577,6 @@ fail:
|
|||
* ensure that all assert_master work is flushed. */
|
||||
flush_workqueue(dlm->dlm_worker);
|
||||
|
||||
/* get an extra reference on the mle.
|
||||
* otherwise the assert_master from the new
|
||||
* master will destroy this.
|
||||
* also, make sure that all callers of dlm_get_mle
|
||||
* take both dlm->spinlock and dlm->master_lock */
|
||||
spin_lock(&dlm->spinlock);
|
||||
spin_lock(&dlm->master_lock);
|
||||
dlm_get_mle_inuse(mle);
|
||||
spin_unlock(&dlm->master_lock);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
/* notify new node and send all lock state */
|
||||
/* call send_one_lockres with migration flag.
|
||||
* this serves as notice to the target node that a
|
||||
|
|
@ -3312,6 +3307,15 @@ top:
|
|||
mle->new_master != dead_node)
|
||||
continue;
|
||||
|
||||
if (mle->new_master == dead_node && mle->inuse) {
|
||||
mlog(ML_NOTICE, "%s: target %u died during "
|
||||
"migration from %u, the MLE is "
|
||||
"still keep used, ignore it!\n",
|
||||
dlm->name, dead_node,
|
||||
mle->master);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we have reached this point, this mle needs to be
|
||||
* removed from the list and freed. */
|
||||
dlm_clean_migration_mle(dlm, mle);
|
||||
|
|
|
|||
|
|
@ -2360,6 +2360,8 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
|
|||
break;
|
||||
}
|
||||
}
|
||||
dlm_lockres_clear_refmap_bit(dlm, res,
|
||||
dead_node);
|
||||
spin_unlock(&res->spinlock);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1390,6 +1390,7 @@ static int __ocfs2_cluster_lock(struct ocfs2_super *osb,
|
|||
unsigned int gen;
|
||||
int noqueue_attempted = 0;
|
||||
int dlm_locked = 0;
|
||||
int kick_dc = 0;
|
||||
|
||||
if (!(lockres->l_flags & OCFS2_LOCK_INITIALIZED)) {
|
||||
mlog_errno(-EINVAL);
|
||||
|
|
@ -1524,7 +1525,12 @@ update_holders:
|
|||
unlock:
|
||||
lockres_clear_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING);
|
||||
|
||||
/* ocfs2_unblock_lock reques on seeing OCFS2_LOCK_UPCONVERT_FINISHING */
|
||||
kick_dc = (lockres->l_flags & OCFS2_LOCK_BLOCKED);
|
||||
|
||||
spin_unlock_irqrestore(&lockres->l_lock, flags);
|
||||
if (kick_dc)
|
||||
ocfs2_wake_downconvert_thread(osb);
|
||||
out:
|
||||
/*
|
||||
* This is helping work around a lock inversion between the page lock
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ struct crypto_ahash {
|
|||
unsigned int keylen);
|
||||
|
||||
unsigned int reqsize;
|
||||
bool has_setkey;
|
||||
struct crypto_tfm base;
|
||||
};
|
||||
|
||||
|
|
@ -375,6 +376,11 @@ static inline void *ahash_request_ctx(struct ahash_request *req)
|
|||
int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
|
||||
unsigned int keylen);
|
||||
|
||||
static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm)
|
||||
{
|
||||
return tfm->has_setkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypto_ahash_finup() - update and finalize message digest
|
||||
* @req: reference to the ahash_request handle that holds all information
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ struct alg_sock {
|
|||
|
||||
struct sock *parent;
|
||||
|
||||
unsigned int refcnt;
|
||||
unsigned int nokey_refcnt;
|
||||
|
||||
const struct af_alg_type *type;
|
||||
void *private;
|
||||
};
|
||||
|
|
@ -50,9 +53,11 @@ struct af_alg_type {
|
|||
void (*release)(void *private);
|
||||
int (*setkey)(void *private, const u8 *key, unsigned int keylen);
|
||||
int (*accept)(void *private, struct sock *sk);
|
||||
int (*accept_nokey)(void *private, struct sock *sk);
|
||||
int (*setauthsize)(void *private, unsigned int authsize);
|
||||
|
||||
struct proto_ops *ops;
|
||||
struct proto_ops *ops_nokey;
|
||||
struct module *owner;
|
||||
char name[14];
|
||||
};
|
||||
|
|
@ -67,6 +72,7 @@ int af_alg_register_type(const struct af_alg_type *type);
|
|||
int af_alg_unregister_type(const struct af_alg_type *type);
|
||||
|
||||
int af_alg_release(struct socket *sock);
|
||||
void af_alg_release_parent(struct sock *sk);
|
||||
int af_alg_accept(struct sock *sk, struct socket *newsock);
|
||||
|
||||
int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
|
||||
|
|
@ -83,11 +89,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
|
|||
return (struct alg_sock *)sk;
|
||||
}
|
||||
|
||||
static inline void af_alg_release_parent(struct sock *sk)
|
||||
{
|
||||
sock_put(alg_sk(sk)->parent);
|
||||
}
|
||||
|
||||
static inline void af_alg_init_completion(struct af_alg_completion *completion)
|
||||
{
|
||||
init_completion(&completion->completion);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ struct crypto_skcipher {
|
|||
unsigned int ivsize;
|
||||
unsigned int reqsize;
|
||||
|
||||
bool has_setkey;
|
||||
|
||||
struct crypto_tfm base;
|
||||
};
|
||||
|
||||
|
|
@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey(struct crypto_skcipher *tfm,
|
|||
return tfm->setkey(tfm, key, keylen);
|
||||
}
|
||||
|
||||
static inline bool crypto_skcipher_has_setkey(struct crypto_skcipher *tfm)
|
||||
{
|
||||
return tfm->has_setkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypto_skcipher_reqtfm() - obtain cipher handle from request
|
||||
* @req: skcipher_request out of which the cipher handle is to be obtained
|
||||
|
|
|
|||
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