diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2012-09-18 08:09:57 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2012-09-18 08:09:57 -0400 |
commit | e23200f6e64c8febf4f0a37056bc82b1f95f7d47 (patch) | |
tree | 8437f5fb32654b5b8b342d3ac4ffb4375e554bca | |
parent | Grsec/PaX: 2.9.1-{2.6.32.59,3.5.3}-201209131726 (diff) | |
download | hardened-patchset-e23200f6e64c8febf4f0a37056bc82b1f95f7d47.tar.gz hardened-patchset-e23200f6e64c8febf4f0a37056bc82b1f95f7d47.tar.bz2 hardened-patchset-e23200f6e64c8febf4f0a37056bc82b1f95f7d47.zip |
Grsec/PaX: 2.9.1-{2.6.32.59,3.2.28,3.5.4}-20120917182420120917
-rw-r--r-- | 2.6.32/0000_README | 2 | ||||
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209171823.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209131725.patch) | 69 | ||||
-rw-r--r-- | 3.2.29/0000_README (renamed from 3.2.28/0000_README) | 6 | ||||
-rw-r--r-- | 3.2.29/1021_linux-3.2.22.patch (renamed from 3.2.28/1021_linux-3.2.22.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1022_linux-3.2.23.patch (renamed from 3.2.28/1022_linux-3.2.23.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1023_linux-3.2.24.patch (renamed from 3.2.28/1023_linux-3.2.24.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1024_linux-3.2.25.patch (renamed from 3.2.28/1024_linux-3.2.25.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1025_linux-3.2.26.patch (renamed from 3.2.28/1025_linux-3.2.26.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1026_linux-3.2.27.patch (renamed from 3.2.28/1026_linux-3.2.27.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1027_linux-3.2.28.patch (renamed from 3.2.28/1027_linux-3.2.28.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/1028_linux-3.2.29.patch | 4279 | ||||
-rw-r--r-- | 3.2.29/4420_grsecurity-2.9.1-3.2.29-201209171824.patch (renamed from 3.2.28/4420_grsecurity-2.9.1-3.2.29-201209122157.patch) | 348 | ||||
-rw-r--r-- | 3.2.29/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.28/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/4435_grsec-mute-warnings.patch (renamed from 3.2.28/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/4440_grsec-remove-protected-paths.patch (renamed from 3.2.28/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.28/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.28/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.2.29/4470_disable-compat_vdso.patch (renamed from 3.2.28/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/0000_README (renamed from 3.5.3/0000_README) | 2 | ||||
-rw-r--r-- | 3.5.4/4420_grsecurity-2.9.1-3.5.4-201209171824.patch (renamed from 3.5.3/4420_grsecurity-2.9.1-3.5.3-201209131726.patch) | 733 | ||||
-rw-r--r-- | 3.5.4/4430_grsec-remove-localversion-grsec.patch (renamed from 3.5.3/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/4435_grsec-mute-warnings.patch (renamed from 3.5.3/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/4440_grsec-remove-protected-paths.patch (renamed from 3.5.3/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/4450_grsec-kconfig-default-gids.patch (renamed from 3.5.3/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.5.3/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.5.4/4470_disable-compat_vdso.patch (renamed from 3.5.3/4470_disable-compat_vdso.patch) | 0 |
26 files changed, 5139 insertions, 300 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index c9c7d67..0955009 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -30,7 +30,7 @@ Patch: 1058_linux-2.6.32.59.patch From: http://www.kernel.org Desc: Linux 2.6.32.59 -Patch: 4420_grsecurity-2.9.1-2.6.32.59-201209131725.patch +Patch: 4420_grsecurity-2.9.1-2.6.32.59-201209171823.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209131725.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209171823.patch index b281d5e..1bc2c59 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209131725.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201209171823.patch @@ -23574,7 +23574,7 @@ index 7c6e63e..c5d92c1 100644 .disabled_by_bios = is_disabled, .hardware_setup = svm_hardware_setup, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index e6d925f..e7a4af8 100644 +index e6d925f..6bde4d6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -570,7 +570,11 @@ static void reload_tss(void) @@ -23589,7 +23589,18 @@ index e6d925f..e7a4af8 100644 load_TR_desc(); } -@@ -1410,8 +1414,11 @@ static __init int hardware_setup(void) +@@ -746,6 +750,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + kvm_get_gdt(&dt); + vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */ + ++#ifdef CONFIG_PAX_PER_CPU_PGD ++ vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif ++ + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + +@@ -1410,8 +1418,11 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_flexpriority()) flexpriority_enabled = 0; @@ -23603,7 +23614,18 @@ index e6d925f..e7a4af8 100644 if (enable_ept && !cpu_has_vmx_ept_2m_page()) kvm_disable_largepages(); -@@ -2362,7 +2369,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) +@@ -2338,7 +2349,10 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) + + vmcs_writel(HOST_CR0, read_cr0()); /* 22.2.3 */ + vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ ++ ++#ifndef CONFIG_PAX_PER_CPU_PGD + vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif + + vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ + vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ +@@ -2362,7 +2376,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); @@ -23612,7 +23634,7 @@ index e6d925f..e7a4af8 100644 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0); vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0); vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0); -@@ -3718,6 +3725,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +@@ -3718,6 +3732,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) "jmp .Lkvm_vmx_return \n\t" ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" ".Lkvm_vmx_return: " @@ -23625,7 +23647,7 @@ index e6d925f..e7a4af8 100644 /* Save guest registers, load host registers, keep flags */ "xchg %0, (%%"R"sp) \n\t" "mov %%"R"ax, %c[rax](%0) \n\t" -@@ -3764,8 +3777,13 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +@@ -3764,8 +3784,13 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])), #endif [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) @@ -23640,7 +23662,7 @@ index e6d925f..e7a4af8 100644 #ifdef CONFIG_X86_64 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" #endif -@@ -3782,7 +3800,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +@@ -3782,7 +3807,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vmx->rmode.irq.pending) fixup_rmode_irq(vmx); @@ -23658,7 +23680,7 @@ index e6d925f..e7a4af8 100644 vmx->launched = 1; vmx_complete_interrupts(vmx); -@@ -3957,7 +3984,7 @@ static bool vmx_gb_page_enable(void) +@@ -3957,7 +3991,7 @@ static bool vmx_gb_page_enable(void) return false; } @@ -102296,7 +102318,7 @@ index c8d466a..1ff8750 100644 * ksize - get the actual amount of memory allocated for a given object * @objp: Pointer to the object diff --git a/mm/slob.c b/mm/slob.c -index 837ebd6..5cb1310 100644 +index 837ebd6..1f9a479 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -29,7 +29,7 @@ @@ -102505,7 +102527,7 @@ index 837ebd6..5cb1310 100644 + base = (void *)((unsigned long)ptr & PAGE_MASK); + free = sp->free; + -+ while (!slob_last(free) && (void *)free <= ptr) { ++ while ((void *)free <= ptr) { + base = free + slob_units(free); + free = slob_next(free); + } @@ -107467,10 +107489,31 @@ index f2f7c63..bc36b3d 100644 x->km.state = XFRM_STATE_VALID; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index b95a2d6..53a422d 100644 +index b95a2d6..b6081b4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c -@@ -1169,6 +1169,8 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) +@@ -646,6 +646,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + { + struct xfrm_dump_info info; + struct sk_buff *skb; ++ int err; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!skb) +@@ -656,9 +657,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + info.nlmsg_seq = seq; + info.nlmsg_flags = 0; + +- if (dump_one_state(x, 0, &info)) { ++ err = dump_one_state(x, 0, &info); ++ if (err) { + kfree_skb(skb); +- return NULL; ++ return ERR_PTR(err); + } + + return skb; +@@ -1169,6 +1171,8 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) struct xfrm_user_tmpl vec[XFRM_MAX_DEPTH]; int i; @@ -107479,7 +107522,7 @@ index b95a2d6..53a422d 100644 if (xp->xfrm_nr == 0) return 0; -@@ -1176,6 +1178,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) +@@ -1176,6 +1180,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) struct xfrm_user_tmpl *up = &vec[i]; struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; @@ -107487,7 +107530,7 @@ index b95a2d6..53a422d 100644 memcpy(&up->id, &kp->id, sizeof(up->id)); up->family = kp->encap_family; memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); -@@ -1784,6 +1787,8 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, +@@ -1784,6 +1789,8 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, int err; int n = 0; diff --git a/3.2.28/0000_README b/3.2.29/0000_README index d6a4b02..77f70fa 100644 --- a/3.2.28/0000_README +++ b/3.2.29/0000_README @@ -30,7 +30,11 @@ Patch: 1027_linux-3.2.28.patch From: http://www.kernel.org Desc: Linux 3.2.28 -Patch: 4420_grsecurity-2.9.1-3.2.29-201209122157.patch +Patch: 1028_linux-3.2.29.patch +From: http://www.kernel.org +Desc: Linux 3.2.29 + +Patch: 4420_grsecurity-2.9.1-3.2.29-201209171824.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.28/1021_linux-3.2.22.patch b/3.2.29/1021_linux-3.2.22.patch index e6ad93a..e6ad93a 100644 --- a/3.2.28/1021_linux-3.2.22.patch +++ b/3.2.29/1021_linux-3.2.22.patch diff --git a/3.2.28/1022_linux-3.2.23.patch b/3.2.29/1022_linux-3.2.23.patch index 3d796d0..3d796d0 100644 --- a/3.2.28/1022_linux-3.2.23.patch +++ b/3.2.29/1022_linux-3.2.23.patch diff --git a/3.2.28/1023_linux-3.2.24.patch b/3.2.29/1023_linux-3.2.24.patch index 4692eb4..4692eb4 100644 --- a/3.2.28/1023_linux-3.2.24.patch +++ b/3.2.29/1023_linux-3.2.24.patch diff --git a/3.2.28/1024_linux-3.2.25.patch b/3.2.29/1024_linux-3.2.25.patch index e95c213..e95c213 100644 --- a/3.2.28/1024_linux-3.2.25.patch +++ b/3.2.29/1024_linux-3.2.25.patch diff --git a/3.2.28/1025_linux-3.2.26.patch b/3.2.29/1025_linux-3.2.26.patch index 44065b9..44065b9 100644 --- a/3.2.28/1025_linux-3.2.26.patch +++ b/3.2.29/1025_linux-3.2.26.patch diff --git a/3.2.28/1026_linux-3.2.27.patch b/3.2.29/1026_linux-3.2.27.patch index 5878eb4..5878eb4 100644 --- a/3.2.28/1026_linux-3.2.27.patch +++ b/3.2.29/1026_linux-3.2.27.patch diff --git a/3.2.28/1027_linux-3.2.28.patch b/3.2.29/1027_linux-3.2.28.patch index 4dbba4b..4dbba4b 100644 --- a/3.2.28/1027_linux-3.2.28.patch +++ b/3.2.29/1027_linux-3.2.28.patch diff --git a/3.2.29/1028_linux-3.2.29.patch b/3.2.29/1028_linux-3.2.29.patch new file mode 100644 index 0000000..3c65179 --- /dev/null +++ b/3.2.29/1028_linux-3.2.29.patch @@ -0,0 +1,4279 @@ +diff --git a/MAINTAINERS b/MAINTAINERS +index f986e7d..82d7fa6 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -5452,7 +5452,7 @@ F: Documentation/blockdev/ramdisk.txt + F: drivers/block/brd.c + + RANDOM NUMBER DRIVER +-M: Matt Mackall <mpm@selenic.com> ++M: Theodore Ts'o" <tytso@mit.edu> + S: Maintained + F: drivers/char/random.c + +diff --git a/Makefile b/Makefile +index 5368961..d96fc2a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 28 ++SUBLEVEL = 29 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h +index 640f909..6f1aca7 100644 +--- a/arch/alpha/include/asm/atomic.h ++++ b/arch/alpha/include/asm/atomic.h +@@ -14,8 +14,8 @@ + */ + + +-#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) +-#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) ++#define ATOMIC_INIT(i) { (i) } ++#define ATOMIC64_INIT(i) { (i) } + + #define atomic_read(v) (*(volatile int *)&(v)->counter) + #define atomic64_read(v) (*(volatile long *)&(v)->counter) +diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h +index 06edfef..3eeb47c 100644 +--- a/arch/alpha/include/asm/socket.h ++++ b/arch/alpha/include/asm/socket.h +@@ -69,9 +69,11 @@ + + #define SO_RXQ_OVFL 40 + ++#ifdef __KERNEL__ + /* O_NONBLOCK clashes with the bits used for socket types. Therefore we + * have to define SOCK_NONBLOCK to a different value here. + */ + #define SOCK_NONBLOCK 0x40000000 ++#endif /* __KERNEL__ */ + + #endif /* _ASM_SOCKET_H */ +diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h +index 9451dce..8512475 100644 +--- a/arch/arm/include/asm/pgtable.h ++++ b/arch/arm/include/asm/pgtable.h +@@ -288,13 +288,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +- * <--------------- offset --------------------> <- type --> 0 0 0 ++ * <--------------- offset ----------------------> < type -> 0 0 0 + * +- * This gives us up to 63 swap files and 32GB per swap file. Note that ++ * This gives us up to 31 swap files and 64GB per swap file. Note that + * the offset field is always non-zero. + */ + #define __SWP_TYPE_SHIFT 3 +-#define __SWP_TYPE_BITS 6 ++#define __SWP_TYPE_BITS 5 + #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) + #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) + +diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S +index c202113..ea94765 100644 +--- a/arch/arm/mm/tlb-v7.S ++++ b/arch/arm/mm/tlb-v7.S +@@ -38,10 +38,10 @@ ENTRY(v7wbi_flush_user_tlb_range) + dsb + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT +-#ifdef CONFIG_ARM_ERRATA_720789 +- mov r3, #0 +-#else + asid r3, r3 @ mask ASID ++#ifdef CONFIG_ARM_ERRATA_720789 ++ ALT_SMP(W(mov) r3, #0 ) ++ ALT_UP(W(nop) ) + #endif + orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA + mov r1, r1, lsl #PAGE_SHIFT +diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c +index ad83dad..f0702f3 100644 +--- a/arch/arm/vfp/vfpmodule.c ++++ b/arch/arm/vfp/vfpmodule.c +@@ -628,8 +628,10 @@ static int __init vfp_init(void) + if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + elf_hwcap |= HWCAP_NEON; + #endif ++#ifdef CONFIG_VFPv3 + if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) + elf_hwcap |= HWCAP_VFPv4; ++#endif + } + } + return 0; +diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c +index f581a18..df7d12c 100644 +--- a/arch/x86/mm/hugetlbpage.c ++++ b/arch/x86/mm/hugetlbpage.c +@@ -56,9 +56,16 @@ static int vma_shareable(struct vm_area_struct *vma, unsigned long addr) + } + + /* +- * search for a shareable pmd page for hugetlb. ++ * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc() ++ * and returns the corresponding pte. While this is not necessary for the ++ * !shared pmd case because we can allocate the pmd later as well, it makes the ++ * code much cleaner. pmd allocation is essential for the shared case because ++ * pud has to be populated inside the same i_mmap_mutex section - otherwise ++ * racing tasks could either miss the sharing (see huge_pte_offset) or select a ++ * bad pmd for sharing. + */ +-static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) ++static pte_t * ++huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) + { + struct vm_area_struct *vma = find_vma(mm, addr); + struct address_space *mapping = vma->vm_file->f_mapping; +@@ -68,9 +75,10 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) + struct vm_area_struct *svma; + unsigned long saddr; + pte_t *spte = NULL; ++ pte_t *pte; + + if (!vma_shareable(vma, addr)) +- return; ++ return (pte_t *)pmd_alloc(mm, pud, addr); + + mutex_lock(&mapping->i_mmap_mutex); + vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { +@@ -97,7 +105,9 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) + put_page(virt_to_page(spte)); + spin_unlock(&mm->page_table_lock); + out: ++ pte = (pte_t *)pmd_alloc(mm, pud, addr); + mutex_unlock(&mapping->i_mmap_mutex); ++ return pte; + } + + /* +@@ -142,8 +152,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, + } else { + BUG_ON(sz != PMD_SIZE); + if (pud_none(*pud)) +- huge_pmd_share(mm, addr, pud); +- pte = (pte_t *) pmd_alloc(mm, pud, addr); ++ pte = huge_pmd_share(mm, addr, pud); ++ else ++ pte = (pte_t *)pmd_alloc(mm, pud, addr); + } + } + BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); +diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c +index e7d13f5..d05f2fe 100644 +--- a/drivers/acpi/acpica/tbxface.c ++++ b/drivers/acpi/acpica/tbxface.c +@@ -436,6 +436,7 @@ acpi_get_table_with_size(char *signature, + + return (AE_NOT_FOUND); + } ++ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) + + acpi_status + acpi_get_table(char *signature, +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 8c78443..3790c80 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -385,7 +385,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) + goto repeat; + } + +- dev->power.deferred_resume = false; + if (dev->power.no_callbacks) + goto no_callback; /* Assume success. */ + +@@ -446,6 +445,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) + wake_up_all(&dev->power.wait_queue); + + if (dev->power.deferred_resume) { ++ dev->power.deferred_resume = false; + rpm_resume(dev, 0); + retval = -EAGAIN; + goto out; +@@ -568,6 +568,7 @@ static int rpm_resume(struct device *dev, int rpmflags) + || dev->parent->power.runtime_status == RPM_ACTIVE) { + atomic_inc(&dev->parent->power.child_count); + spin_unlock(&dev->parent->power.lock); ++ retval = 1; + goto no_callback; /* Assume success. */ + } + spin_unlock(&dev->parent->power.lock); +@@ -645,7 +646,7 @@ static int rpm_resume(struct device *dev, int rpmflags) + } + wake_up_all(&dev->power.wait_queue); + +- if (!retval) ++ if (retval >= 0) + rpm_idle(dev, RPM_ASYNC); + + out: +diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c +index acda773..38aa6dd 100644 +--- a/drivers/block/cciss_scsi.c ++++ b/drivers/block/cciss_scsi.c +@@ -763,16 +763,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, + { + case CMD_TARGET_STATUS: + /* Pass it up to the upper layers... */ +- if( ei->ScsiStatus) +- { +-#if 0 +- printk(KERN_WARNING "cciss: cmd %p " +- "has SCSI Status = %x\n", +- c, ei->ScsiStatus); +-#endif +- cmd->result |= (ei->ScsiStatus << 1); +- } +- else { /* scsi status is zero??? How??? */ ++ if (!ei->ScsiStatus) { + + /* Ordinarily, this case should never happen, but there is a bug + in some released firmware revisions that allows it to happen +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 650a308..de9c800 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -4,6 +4,7 @@ + #include <linux/blkdev.h> + #include <linux/hdreg.h> + #include <linux/module.h> ++#include <linux/mutex.h> + #include <linux/virtio.h> + #include <linux/virtio_blk.h> + #include <linux/scatterlist.h> +@@ -26,14 +27,17 @@ struct virtio_blk + /* The disk structure for the kernel. */ + struct gendisk *disk; + +- /* Request tracking. */ +- struct list_head reqs; +- + mempool_t *pool; + + /* Process context for config space updates */ + struct work_struct config_work; + ++ /* Lock for config space updates */ ++ struct mutex config_lock; ++ ++ /* enable config space updates */ ++ bool config_enable; ++ + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + +@@ -46,7 +50,6 @@ struct virtio_blk + + struct virtblk_req + { +- struct list_head list; + struct request *req; + struct virtio_blk_outhdr out_hdr; + struct virtio_scsi_inhdr in_hdr; +@@ -90,7 +93,6 @@ static void blk_done(struct virtqueue *vq) + } + + __blk_end_request_all(vbr->req, error); +- list_del(&vbr->list); + mempool_free(vbr, vblk->pool); + } + /* In case queue is stopped waiting for more buffers. */ +@@ -175,7 +177,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, + return false; + } + +- list_add_tail(&vbr->list, &vblk->reqs); + return true; + } + +@@ -316,6 +317,10 @@ static void virtblk_config_changed_work(struct work_struct *work) + char cap_str_2[10], cap_str_10[10]; + u64 capacity, size; + ++ mutex_lock(&vblk->config_lock); ++ if (!vblk->config_enable) ++ goto done; ++ + /* Host must always specify the capacity. */ + vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), + &capacity, sizeof(capacity)); +@@ -338,6 +343,8 @@ static void virtblk_config_changed_work(struct work_struct *work) + cap_str_10, cap_str_2); + + set_capacity(vblk->disk, capacity); ++done: ++ mutex_unlock(&vblk->config_lock); + } + + static void virtblk_config_changed(struct virtio_device *vdev) +@@ -381,11 +388,12 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) + goto out_free_index; + } + +- INIT_LIST_HEAD(&vblk->reqs); + vblk->vdev = vdev; + vblk->sg_elems = sg_elems; + sg_init_table(vblk->sg, vblk->sg_elems); ++ mutex_init(&vblk->config_lock); + INIT_WORK(&vblk->config_work, virtblk_config_changed_work); ++ vblk->config_enable = true; + + /* We expect one virtqueue, for output. */ + vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); +@@ -539,16 +547,19 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) + struct virtio_blk *vblk = vdev->priv; + int index = vblk->index; + +- flush_work(&vblk->config_work); ++ /* Prevent config work handler from accessing the device. */ ++ mutex_lock(&vblk->config_lock); ++ vblk->config_enable = false; ++ mutex_unlock(&vblk->config_lock); + +- /* Nothing should be pending. */ +- BUG_ON(!list_empty(&vblk->reqs)); ++ del_gendisk(vblk->disk); ++ blk_cleanup_queue(vblk->disk->queue); + + /* Stop all the virtqueues. */ + vdev->config->reset(vdev); + +- del_gendisk(vblk->disk); +- blk_cleanup_queue(vblk->disk->queue); ++ flush_work(&vblk->config_work); ++ + put_disk(vblk->disk); + mempool_destroy(vblk->pool); + vdev->config->del_vqs(vdev); +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 631d4f6..8ae9235 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1114,6 +1114,16 @@ static void init_std_data(struct entropy_store *r) + mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); + } + ++/* ++ * Note that setup_arch() may call add_device_randomness() ++ * long before we get here. This allows seeding of the pools ++ * with some platform dependent data very early in the boot ++ * process. But it limits our options here. We must use ++ * statically allocated structures that already have all ++ * initializations complete at compile time. We should also ++ * take care not to overwrite the precious per platform data ++ * we were given. ++ */ + static int rand_initialize(void) + { + init_std_data(&input_pool); +@@ -1391,10 +1401,15 @@ static int proc_do_uuid(ctl_table *table, int write, + uuid = table->data; + if (!uuid) { + uuid = tmp_uuid; +- uuid[8] = 0; +- } +- if (uuid[8] == 0) + generate_random_uuid(uuid); ++ } else { ++ static DEFINE_SPINLOCK(bootid_spinlock); ++ ++ spin_lock(&bootid_spinlock); ++ if (!uuid[8]) ++ generate_random_uuid(uuid); ++ spin_unlock(&bootid_spinlock); ++ } + + sprintf(buf, "%pU", uuid); + +diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c +index 153980b..b298158 100644 +--- a/drivers/firmware/dmi_scan.c ++++ b/drivers/firmware/dmi_scan.c +@@ -6,6 +6,7 @@ + #include <linux/dmi.h> + #include <linux/efi.h> + #include <linux/bootmem.h> ++#include <linux/random.h> + #include <asm/dmi.h> + + /* +@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, + + dmi_table(buf, dmi_len, dmi_num, decode, NULL); + ++ add_device_randomness(buf, dmi_len); ++ + dmi_iounmap(buf, dmi_len); + return 0; + } +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cc75c4b..3eed270 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4748,17 +4748,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, + continue; + } + +- if (intel_encoder->type == INTEL_OUTPUT_EDP) { +- /* Use VBT settings if we have an eDP panel */ +- unsigned int edp_bpc = dev_priv->edp.bpp / 3; +- +- if (edp_bpc < display_bpc) { +- DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); +- display_bpc = edp_bpc; +- } +- continue; +- } +- + /* Not one of the known troublemakers, check the EDID */ + list_for_each_entry(connector, &dev->mode_config.connector_list, + head) { +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index fae2050..c8ecaab 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1152,10 +1152,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) + WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); + + pp = ironlake_get_pp_control(dev_priv); +- pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); ++ /* We need to switch off panel power _and_ force vdd, for otherwise some ++ * panels get very unhappy and cease to work. */ ++ pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); + ++ intel_dp->want_panel_vdd = false; ++ + ironlake_wait_panel_off(intel_dp); + } + +@@ -1265,11 +1269,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder) + * ensure that we have vdd while we switch off the panel. */ + ironlake_edp_panel_vdd_on(intel_dp); + ironlake_edp_backlight_off(intel_dp); +- ironlake_edp_panel_off(intel_dp); +- + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); ++ ironlake_edp_panel_off(intel_dp); + intel_dp_link_down(intel_dp); +- ironlake_edp_panel_vdd_off(intel_dp, false); + } + + static void intel_dp_commit(struct drm_encoder *encoder) +@@ -1304,11 +1306,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) + /* Switching the panel off requires vdd. */ + ironlake_edp_panel_vdd_on(intel_dp); + ironlake_edp_backlight_off(intel_dp); +- ironlake_edp_panel_off(intel_dp); +- + intel_dp_sink_dpms(intel_dp, mode); ++ ironlake_edp_panel_off(intel_dp); + intel_dp_link_down(intel_dp); +- ironlake_edp_panel_vdd_off(intel_dp, false); + + if (is_cpu_edp(intel_dp)) + ironlake_edp_pll_off(encoder); +diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c +index cb006a7..3002d82 100644 +--- a/drivers/gpu/drm/nouveau/nvd0_display.c ++++ b/drivers/gpu/drm/nouveau/nvd0_display.c +@@ -472,7 +472,7 @@ static int + nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) + { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); +- const u32 data = (y << 16) | x; ++ const u32 data = (y << 16) | (x & 0xffff); + + nv_wr32(crtc->dev, 0x64d084 + (nv_crtc->index * 0x1000), data); + nv_wr32(crtc->dev, 0x64d080 + (nv_crtc->index * 0x1000), 0x00000000); +diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h +index 1b50ad8..4760466 100644 +--- a/drivers/gpu/drm/radeon/atombios.h ++++ b/drivers/gpu/drm/radeon/atombios.h +@@ -101,6 +101,7 @@ + #define ATOM_LCD_SELFTEST_START (ATOM_DISABLE+5) + #define ATOM_LCD_SELFTEST_STOP (ATOM_ENABLE+5) + #define ATOM_ENCODER_INIT (ATOM_DISABLE+7) ++#define ATOM_INIT (ATOM_DISABLE+7) + #define ATOM_GET_STATUS (ATOM_DISABLE+8) + + #define ATOM_BLANKING 1 +@@ -251,25 +252,25 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ + USHORT SetEngineClock; //Function Table,directly used by various SW components,latest version 1.1 + USHORT SetMemoryClock; //Function Table,directly used by various SW components,latest version 1.1 + USHORT SetPixelClock; //Function Table,directly used by various SW components,latest version 1.2 +- USHORT DynamicClockGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init ++ USHORT EnableDispPowerGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT ResetMemoryDLL; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT ResetMemoryDevice; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock +- USHORT MemoryPLLInit; +- USHORT AdjustDisplayPll; //only used by Bios ++ USHORT MemoryPLLInit; //Atomic Table, used only by Bios ++ USHORT AdjustDisplayPll; //Atomic Table, used by various SW componentes. + USHORT AdjustMemoryController; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT EnableASIC_StaticPwrMgt; //Atomic Table, only used by Bios + USHORT ASIC_StaticPwrMgtStatusChange; //Obsolete , only used by Bios + USHORT DAC_LoadDetection; //Atomic Table, directly used by various SW components,latest version 1.2 + USHORT LVTMAEncoderControl; //Atomic Table,directly used by various SW components,latest version 1.3 +- USHORT LCD1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 ++ USHORT HW_Misc_Operation; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC1EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC2EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DVOOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT CV1OutputControl; //Atomic Table, Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead +- USHORT GetConditionalGoldenSetting; //only used by Bios ++ USHORT GetConditionalGoldenSetting; //Only used by Bios + USHORT TVEncoderControl; //Function Table,directly used by various SW components,latest version 1.1 +- USHORT TMDSAEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 +- USHORT LVDSEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 ++ USHORT PatchMCSetting; //only used by BIOS ++ USHORT MC_SEQ_Control; //only used by BIOS + USHORT TV1OutputControl; //Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead + USHORT EnableScaler; //Atomic Table, used only by Bios + USHORT BlankCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 +@@ -282,7 +283,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ + USHORT SetCRTC_Replication; //Atomic Table, used only by Bios + USHORT SelectCRTC_Source; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT EnableGraphSurfaces; //Atomic Table, used only by Bios +- USHORT UpdateCRTC_DoubleBufferRegisters; ++ USHORT UpdateCRTC_DoubleBufferRegisters; //Atomic Table, used only by Bios + USHORT LUT_AutoFill; //Atomic Table, only used by Bios + USHORT EnableHW_IconCursor; //Atomic Table, only used by Bios + USHORT GetMemoryClock; //Atomic Table, directly used by various SW components,latest version 1.1 +@@ -308,27 +309,36 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ + USHORT SetVoltage; //Function Table,directly and/or indirectly used by various SW components,latest version 1.1 + USHORT DAC1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC2OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 +- USHORT SetupHWAssistedI2CStatus; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" ++ USHORT ComputeMemoryClockParam; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" + USHORT ClockSource; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT MemoryDeviceInit; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock +- USHORT EnableYUV; //Atomic Table, indirectly used by various SW components,called from EnableVGARender ++ USHORT GetDispObjectInfo; //Atomic Table, indirectly used by various SW components,called from EnableVGARender + USHORT DIG1EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG2EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG1TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG2TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT ProcessAuxChannelTransaction; //Function Table,only used by Bios + USHORT DPEncoderService; //Function Table,only used by Bios ++ USHORT GetVoltageInfo; //Function Table,only used by Bios since SI + }ATOM_MASTER_LIST_OF_COMMAND_TABLES; + + // For backward compatible + #define ReadEDIDFromHWAssistedI2C ProcessI2cChannelTransaction +-#define UNIPHYTransmitterControl DIG1TransmitterControl +-#define LVTMATransmitterControl DIG2TransmitterControl ++#define DPTranslatorControl DIG2EncoderControl ++#define UNIPHYTransmitterControl DIG1TransmitterControl ++#define LVTMATransmitterControl DIG2TransmitterControl + #define SetCRTC_DPM_State GetConditionalGoldenSetting + #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange + #define HPDInterruptService ReadHWAssistedI2CStatus + #define EnableVGA_Access GetSCLKOverMCLKRatio +-#define GetDispObjectInfo EnableYUV ++#define EnableYUV GetDispObjectInfo ++#define DynamicClockGating EnableDispPowerGating ++#define SetupHWAssistedI2CStatus ComputeMemoryClockParam ++ ++#define TMDSAEncoderControl PatchMCSetting ++#define LVDSEncoderControl MC_SEQ_Control ++#define LCD1OutputControl HW_Misc_Operation ++ + + typedef struct _ATOM_MASTER_COMMAND_TABLE + { +@@ -495,6 +505,34 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 + // ucInputFlag + #define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN 1 // 1-StrobeMode, 0-PerformanceMode + ++// use for ComputeMemoryClockParamTable ++typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 ++{ ++ union ++ { ++ ULONG ulClock; ++ ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output:UPPER_WORD=FB_DIV_INTEGER, LOWER_WORD=FB_DIV_FRAC shl (16-FB_FRACTION_BITS) ++ }; ++ UCHAR ucDllSpeed; //Output ++ UCHAR ucPostDiv; //Output ++ union{ ++ UCHAR ucInputFlag; //Input : ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN: 1-StrobeMode, 0-PerformanceMode ++ UCHAR ucPllCntlFlag; //Output: ++ }; ++ UCHAR ucBWCntl; ++}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1; ++ ++// definition of ucInputFlag ++#define MPLL_INPUT_FLAG_STROBE_MODE_EN 0x01 ++// definition of ucPllCntlFlag ++#define MPLL_CNTL_FLAG_VCO_MODE_MASK 0x03 ++#define MPLL_CNTL_FLAG_BYPASS_DQ_PLL 0x04 ++#define MPLL_CNTL_FLAG_QDR_ENABLE 0x08 ++#define MPLL_CNTL_FLAG_AD_HALF_RATE 0x10 ++ ++//MPLL_CNTL_FLAG_BYPASS_AD_PLL has a wrong name, should be BYPASS_DQ_PLL ++#define MPLL_CNTL_FLAG_BYPASS_AD_PLL 0x04 ++ + typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER + { + ATOM_COMPUTE_CLOCK_FREQ ulClock; +@@ -562,6 +600,16 @@ typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS + #define DYNAMIC_CLOCK_GATING_PS_ALLOCATION DYNAMIC_CLOCK_GATING_PARAMETERS + + /****************************************************************************/ ++// Structure used by EnableDispPowerGatingTable.ctb ++/****************************************************************************/ ++typedef struct _ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 ++{ ++ UCHAR ucDispPipeId; // ATOM_CRTC1, ATOM_CRTC2, ... ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucPadding[2]; ++}ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1; ++ ++/****************************************************************************/ + // Structure used by EnableASIC_StaticPwrMgtTable.ctb + /****************************************************************************/ + typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS +@@ -807,6 +855,7 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 + #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ 0x00 + #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ 0x01 + #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ 0x02 ++#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ 0x03 + #define ATOM_ENCODER_CONFIG_V4_ENCODER_SEL 0x70 + #define ATOM_ENCODER_CONFIG_V4_DIG0_ENCODER 0x00 + #define ATOM_ENCODER_CONFIG_V4_DIG1_ENCODER 0x10 +@@ -814,6 +863,7 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 + #define ATOM_ENCODER_CONFIG_V4_DIG3_ENCODER 0x30 + #define ATOM_ENCODER_CONFIG_V4_DIG4_ENCODER 0x40 + #define ATOM_ENCODER_CONFIG_V4_DIG5_ENCODER 0x50 ++#define ATOM_ENCODER_CONFIG_V4_DIG6_ENCODER 0x60 + + typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V4 + { +@@ -1171,6 +1221,106 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 + #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER3 0x80 //EF + + ++typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V5 ++{ ++#if ATOM_BIG_ENDIAN ++ UCHAR ucReservd1:1; ++ UCHAR ucHPDSel:3; ++ UCHAR ucPhyClkSrcId:2; ++ UCHAR ucCoherentMode:1; ++ UCHAR ucReserved:1; ++#else ++ UCHAR ucReserved:1; ++ UCHAR ucCoherentMode:1; ++ UCHAR ucPhyClkSrcId:2; ++ UCHAR ucHPDSel:3; ++ UCHAR ucReservd1:1; ++#endif ++}ATOM_DIG_TRANSMITTER_CONFIG_V5; ++ ++typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 ++{ ++ USHORT usSymClock; // Encoder Clock in 10kHz,(DP mode)= linkclock/10, (TMDS/LVDS/HDMI)= pixel clock, (HDMI deep color), =pixel clock * deep_color_ratio ++ UCHAR ucPhyId; // 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4= UNIPHYE 5=UNIPHYF ++ UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_xxx ++ UCHAR ucLaneNum; // indicate lane number 1-8 ++ UCHAR ucConnObjId; // Connector Object Id defined in ObjectId.h ++ UCHAR ucDigMode; // indicate DIG mode ++ union{ ++ ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig; ++ UCHAR ucConfig; ++ }; ++ UCHAR ucDigEncoderSel; // indicate DIG front end encoder ++ UCHAR ucDPLaneSet; ++ UCHAR ucReserved; ++ UCHAR ucReserved1; ++}DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5; ++ ++//ucPhyId ++#define ATOM_PHY_ID_UNIPHYA 0 ++#define ATOM_PHY_ID_UNIPHYB 1 ++#define ATOM_PHY_ID_UNIPHYC 2 ++#define ATOM_PHY_ID_UNIPHYD 3 ++#define ATOM_PHY_ID_UNIPHYE 4 ++#define ATOM_PHY_ID_UNIPHYF 5 ++#define ATOM_PHY_ID_UNIPHYG 6 ++ ++// ucDigEncoderSel ++#define ATOM_TRANMSITTER_V5__DIGA_SEL 0x01 ++#define ATOM_TRANMSITTER_V5__DIGB_SEL 0x02 ++#define ATOM_TRANMSITTER_V5__DIGC_SEL 0x04 ++#define ATOM_TRANMSITTER_V5__DIGD_SEL 0x08 ++#define ATOM_TRANMSITTER_V5__DIGE_SEL 0x10 ++#define ATOM_TRANMSITTER_V5__DIGF_SEL 0x20 ++#define ATOM_TRANMSITTER_V5__DIGG_SEL 0x40 ++ ++// ucDigMode ++#define ATOM_TRANSMITTER_DIGMODE_V5_DP 0 ++#define ATOM_TRANSMITTER_DIGMODE_V5_LVDS 1 ++#define ATOM_TRANSMITTER_DIGMODE_V5_DVI 2 ++#define ATOM_TRANSMITTER_DIGMODE_V5_HDMI 3 ++#define ATOM_TRANSMITTER_DIGMODE_V5_SDVO 4 ++#define ATOM_TRANSMITTER_DIGMODE_V5_DP_MST 5 ++ ++// ucDPLaneSet ++#define DP_LANE_SET__0DB_0_4V 0x00 ++#define DP_LANE_SET__0DB_0_6V 0x01 ++#define DP_LANE_SET__0DB_0_8V 0x02 ++#define DP_LANE_SET__0DB_1_2V 0x03 ++#define DP_LANE_SET__3_5DB_0_4V 0x08 ++#define DP_LANE_SET__3_5DB_0_6V 0x09 ++#define DP_LANE_SET__3_5DB_0_8V 0x0a ++#define DP_LANE_SET__6DB_0_4V 0x10 ++#define DP_LANE_SET__6DB_0_6V 0x11 ++#define DP_LANE_SET__9_5DB_0_4V 0x18 ++ ++// ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig; ++// Bit1 ++#define ATOM_TRANSMITTER_CONFIG_V5_COHERENT 0x02 ++ ++// Bit3:2 ++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_MASK 0x0c ++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_SHIFT 0x02 ++ ++#define ATOM_TRANSMITTER_CONFIG_V5_P1PLL 0x00 ++#define ATOM_TRANSMITTER_CONFIG_V5_P2PLL 0x04 ++#define ATOM_TRANSMITTER_CONFIG_V5_P0PLL 0x08 ++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT 0x0c ++// Bit6:4 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_MASK 0x70 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_SHIFT 0x04 ++ ++#define ATOM_TRANSMITTER_CONFIG_V5_NO_HPD_SEL 0x00 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL 0x10 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL 0x20 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL 0x30 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL 0x40 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL 0x50 ++#define ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL 0x60 ++ ++#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION_V1_5 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 ++ ++ + /****************************************************************************/ + // Structures used by ExternalEncoderControlTable V1.3 + // ASIC Families: Evergreen, Llano, NI +@@ -1793,6 +1943,7 @@ typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 + #define ATOM_PPLL_SS_TYPE_V3_P1PLL 0x00 + #define ATOM_PPLL_SS_TYPE_V3_P2PLL 0x04 + #define ATOM_PPLL_SS_TYPE_V3_DCPLL 0x08 ++#define ATOM_PPLL_SS_TYPE_V3_P0PLL ATOM_PPLL_SS_TYPE_V3_DCPLL + #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK 0x00FF + #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT 0 + #define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK 0x0F00 +@@ -2030,12 +2181,77 @@ typedef struct _SET_VOLTAGE_PARAMETERS_V2 + USHORT usVoltageLevel; // real voltage level + }SET_VOLTAGE_PARAMETERS_V2; + ++ ++typedef struct _SET_VOLTAGE_PARAMETERS_V1_3 ++{ ++ UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI ++ UCHAR ucVoltageMode; // Indicate action: Set voltage level ++ USHORT usVoltageLevel; // real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) ++}SET_VOLTAGE_PARAMETERS_V1_3; ++ ++//ucVoltageType ++#define VOLTAGE_TYPE_VDDC 1 ++#define VOLTAGE_TYPE_MVDDC 2 ++#define VOLTAGE_TYPE_MVDDQ 3 ++#define VOLTAGE_TYPE_VDDCI 4 ++ ++//SET_VOLTAGE_PARAMETERS_V3.ucVoltageMode ++#define ATOM_SET_VOLTAGE 0 //Set voltage Level ++#define ATOM_INIT_VOLTAGE_REGULATOR 3 //Init Regulator ++#define ATOM_SET_VOLTAGE_PHASE 4 //Set Vregulator Phase ++#define ATOM_GET_MAX_VOLTAGE 6 //Get Max Voltage, not used in SetVoltageTable v1.3 ++#define ATOM_GET_VOLTAGE_LEVEL 6 //Get Voltage level from vitual voltage ID ++ ++// define vitual voltage id in usVoltageLevel ++#define ATOM_VIRTUAL_VOLTAGE_ID0 0xff01 ++#define ATOM_VIRTUAL_VOLTAGE_ID1 0xff02 ++#define ATOM_VIRTUAL_VOLTAGE_ID2 0xff03 ++#define ATOM_VIRTUAL_VOLTAGE_ID3 0xff04 ++ + typedef struct _SET_VOLTAGE_PS_ALLOCATION + { + SET_VOLTAGE_PARAMETERS sASICSetVoltage; + WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; + }SET_VOLTAGE_PS_ALLOCATION; + ++// New Added from SI for GetVoltageInfoTable, input parameter structure ++typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1 ++{ ++ UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI ++ UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info ++ USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id ++ ULONG ulReserved; ++}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1; ++ ++// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_VID ++typedef struct _GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 ++{ ++ ULONG ulVotlageGpioState; ++ ULONG ulVoltageGPioMask; ++}GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1; ++ ++// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_STATEx_LEAKAGE_VID ++typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 ++{ ++ USHORT usVoltageLevel; ++ USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator ++ ULONG ulReseved; ++}GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1; ++ ++ ++// GetVoltageInfo v1.1 ucVoltageMode ++#define ATOM_GET_VOLTAGE_VID 0x00 ++#define ATOM_GET_VOTLAGE_INIT_SEQ 0x03 ++#define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04 ++// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state ++#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 ++ ++// for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state ++#define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11 ++// undefined power state ++#define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12 ++#define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13 ++ + /****************************************************************************/ + // Structures used by TVEncoderControlTable + /****************************************************************************/ +@@ -2065,9 +2281,9 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES + USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios + USHORT StandardVESA_Timing; // Only used by Bios + USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 +- USHORT DAC_Info; // Will be obsolete from R600 ++ USHORT PaletteData; // Only used by BIOS + USHORT LCD_Info; // Shared by various SW components,latest version 1.3, was called LVDS_Info +- USHORT TMDS_Info; // Will be obsolete from R600 ++ USHORT DIGTransmitterInfo; // Internal used by VBIOS only version 3.1 + USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 + USHORT SupportedDevicesInfo; // Will be obsolete from R600 + USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600 +@@ -2096,15 +2312,16 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES + USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 + }ATOM_MASTER_LIST_OF_DATA_TABLES; + +-// For backward compatible +-#define LVDS_Info LCD_Info +- + typedef struct _ATOM_MASTER_DATA_TABLE + { + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; + }ATOM_MASTER_DATA_TABLE; + ++// For backward compatible ++#define LVDS_Info LCD_Info ++#define DAC_Info PaletteData ++#define TMDS_Info DIGTransmitterInfo + + /****************************************************************************/ + // Structure used in MultimediaCapabilityInfoTable +@@ -2171,7 +2388,9 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO + typedef struct _ATOM_FIRMWARE_CAPABILITY + { + #if ATOM_BIG_ENDIAN +- USHORT Reserved:3; ++ USHORT Reserved:1; ++ USHORT SCL2Redefined:1; ++ USHORT PostWithoutModeSet:1; + USHORT HyperMemory_Size:4; + USHORT HyperMemory_Support:1; + USHORT PPMode_Assigned:1; +@@ -2193,7 +2412,9 @@ typedef struct _ATOM_FIRMWARE_CAPABILITY + USHORT PPMode_Assigned:1; + USHORT HyperMemory_Support:1; + USHORT HyperMemory_Size:4; +- USHORT Reserved:3; ++ USHORT PostWithoutModeSet:1; ++ USHORT SCL2Redefined:1; ++ USHORT Reserved:1; + #endif + }ATOM_FIRMWARE_CAPABILITY; + +@@ -2418,7 +2639,8 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2 + USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit + ULONG ulReserved4; //Was ulAsicMaximumVoltage + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit +- ULONG ulReserved5; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input ++ UCHAR ucRemoteDisplayConfig; ++ UCHAR ucReserved5[3]; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input + ULONG ulReserved6; //Was usMinEngineClockPLL_Output and usMinMemoryClockPLL_Input + ULONG ulReserved7; //Was usMaxMemoryClockPLL_Input and usMinMemoryClockPLL_Output + USHORT usReserved11; //Was usMaxPixelClock; //In 10Khz unit, Max. Pclk used only for DAC +@@ -2438,6 +2660,11 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2 + + #define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_2 + ++ ++// definition of ucRemoteDisplayConfig ++#define REMOTE_DISPLAY_DISABLE 0x00 ++#define REMOTE_DISPLAY_ENABLE 0x01 ++ + /****************************************************************************/ + // Structures used in IntegratedSystemInfoTable + /****************************************************************************/ +@@ -2660,8 +2887,9 @@ usMinDownStreamHTLinkWidth: same as above. + #define INTEGRATED_SYSTEM_INFO__AMD_CPU__GREYHOUND 2 + #define INTEGRATED_SYSTEM_INFO__AMD_CPU__K8 3 + #define INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH 4 ++#define INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI 5 + +-#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH // this deff reflects max defined CPU code ++#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI // this deff reflects max defined CPU code + + #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 + #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 +@@ -2753,6 +2981,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 + #define ASIC_INT_DIG4_ENCODER_ID 0x0b + #define ASIC_INT_DIG5_ENCODER_ID 0x0c + #define ASIC_INT_DIG6_ENCODER_ID 0x0d ++#define ASIC_INT_DIG7_ENCODER_ID 0x0e + + //define Encoder attribute + #define ATOM_ANALOG_ENCODER 0 +@@ -3226,15 +3455,23 @@ typedef struct _ATOM_LCD_INFO_V13 + + UCHAR ucPowerSequenceDIGONtoDE_in4Ms; + UCHAR ucPowerSequenceDEtoVARY_BL_in4Ms; +- UCHAR ucPowerSequenceDEtoDIGON_in4Ms; + UCHAR ucPowerSequenceVARY_BLtoDE_in4Ms; ++ UCHAR ucPowerSequenceDEtoDIGON_in4Ms; + + UCHAR ucOffDelay_in4Ms; + UCHAR ucPowerSequenceVARY_BLtoBLON_in4Ms; + UCHAR ucPowerSequenceBLONtoVARY_BL_in4Ms; + UCHAR ucReserved1; + +- ULONG ulReserved[4]; ++ UCHAR ucDPCD_eDP_CONFIGURATION_CAP; // dpcd 0dh ++ UCHAR ucDPCD_MAX_LINK_RATE; // dpcd 01h ++ UCHAR ucDPCD_MAX_LANE_COUNT; // dpcd 02h ++ UCHAR ucDPCD_MAX_DOWNSPREAD; // dpcd 03h ++ ++ USHORT usMaxPclkFreqInSingleLink; // Max PixelClock frequency in single link mode. ++ UCHAR uceDPToLVDSRxId; ++ UCHAR ucLcdReservd; ++ ULONG ulReserved[2]; + }ATOM_LCD_INFO_V13; + + #define ATOM_LCD_INFO_LAST ATOM_LCD_INFO_V13 +@@ -3273,6 +3510,11 @@ typedef struct _ATOM_LCD_INFO_V13 + //Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. + #define LCDPANEL_CAP_V13_eDP 0x4 // = LCDPANEL_CAP_eDP no change comparing to previous version + ++//uceDPToLVDSRxId ++#define eDP_TO_LVDS_RX_DISABLE 0x00 // no eDP->LVDS translator chip ++#define eDP_TO_LVDS_COMMON_ID 0x01 // common eDP->LVDS translator chip without AMD SW init ++#define eDP_TO_LVDS_RT_ID 0x02 // RT tanslator which require AMD SW init ++ + typedef struct _ATOM_PATCH_RECORD_MODE + { + UCHAR ucRecordType; +@@ -3317,6 +3559,7 @@ typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD + #define LCD_CAP_RECORD_TYPE 3 + #define LCD_FAKE_EDID_PATCH_RECORD_TYPE 4 + #define LCD_PANEL_RESOLUTION_RECORD_TYPE 5 ++#define LCD_EDID_OFFSET_PATCH_RECORD_TYPE 6 + #define ATOM_RECORD_END_TYPE 0xFF + + /****************************Spread Spectrum Info Table Definitions **********************/ +@@ -3528,6 +3771,7 @@ else //Non VGA case + + CAIL needs to claim an reserved area defined by FBAccessAreaOffset and usFBUsedbyDrvInKB in non VGA case.*/ + ++/***********************************************************************************/ + #define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO 1 + + typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO +@@ -3818,13 +4062,17 @@ typedef struct _EXT_DISPLAY_PATH + ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping; + ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping; + }; +- UCHAR ucReserved; +- USHORT usReserved[2]; ++ UCHAR ucChPNInvert; // bit vector for up to 8 lanes, =0: P and N is not invert, =1 P and N is inverted ++ USHORT usCaps; ++ USHORT usReserved; + }EXT_DISPLAY_PATH; + + #define NUMBER_OF_UCHAR_FOR_GUID 16 + #define MAX_NUMBER_OF_EXT_DISPLAY_PATH 7 + ++//usCaps ++#define EXT_DISPLAY_PATH_CAPS__HBR2_DISABLE 0x01 ++ + typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO + { + ATOM_COMMON_TABLE_HEADER sHeader; +@@ -3832,7 +4080,9 @@ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO + EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. + UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. + UCHAR uc3DStereoPinId; // use for eDP panel +- UCHAR Reserved [6]; // for potential expansion ++ UCHAR ucRemoteDisplayConfig; ++ UCHAR uceDPToLVDSRxId; ++ UCHAR Reserved[4]; // for potential expansion + }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; + + //Related definitions, all records are different but they have a commond header +@@ -3977,6 +4227,7 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD + #define GPIO_PIN_STATE_ACTIVE_HIGH 0x1 + + // Indexes to GPIO array in GLSync record ++// GLSync record is for Frame Lock/Gen Lock feature. + #define ATOM_GPIO_INDEX_GLSYNC_REFCLK 0 + #define ATOM_GPIO_INDEX_GLSYNC_HSYNC 1 + #define ATOM_GPIO_INDEX_GLSYNC_VSYNC 2 +@@ -3984,7 +4235,9 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD + #define ATOM_GPIO_INDEX_GLSYNC_SWAP_GNT 4 + #define ATOM_GPIO_INDEX_GLSYNC_INTERRUPT 5 + #define ATOM_GPIO_INDEX_GLSYNC_V_RESET 6 +-#define ATOM_GPIO_INDEX_GLSYNC_MAX 7 ++#define ATOM_GPIO_INDEX_GLSYNC_SWAP_CNTL 7 ++#define ATOM_GPIO_INDEX_GLSYNC_SWAP_SEL 8 ++#define ATOM_GPIO_INDEX_GLSYNC_MAX 9 + + typedef struct _ATOM_ENCODER_DVO_CF_RECORD + { +@@ -3994,7 +4247,8 @@ typedef struct _ATOM_ENCODER_DVO_CF_RECORD + }ATOM_ENCODER_DVO_CF_RECORD; + + // Bit maps for ATOM_ENCODER_CAP_RECORD.ucEncoderCap +-#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by this path ++#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by HW encoder ++#define ATOM_ENCODER_CAP_RECORD_HBR2_EN 0x02 // DP1.2 HBR2 setting is qualified and HBR2 can be enabled + + typedef struct _ATOM_ENCODER_CAP_RECORD + { +@@ -4003,11 +4257,13 @@ typedef struct _ATOM_ENCODER_CAP_RECORD + USHORT usEncoderCap; + struct { + #if ATOM_BIG_ENDIAN +- USHORT usReserved:15; // Bit1-15 may be defined for other capability in future ++ USHORT usReserved:14; // Bit1-15 may be defined for other capability in future ++ USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable + USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. + #else + USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. +- USHORT usReserved:15; // Bit1-15 may be defined for other capability in future ++ USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable ++ USHORT usReserved:14; // Bit1-15 may be defined for other capability in future + #endif + }; + }; +@@ -4157,6 +4413,7 @@ typedef struct _ATOM_VOLTAGE_CONTROL + #define VOLTAGE_CONTROL_ID_VT1556M 0x07 + #define VOLTAGE_CONTROL_ID_CHL822x 0x08 + #define VOLTAGE_CONTROL_ID_VT1586M 0x09 ++#define VOLTAGE_CONTROL_ID_UP1637 0x0A + + typedef struct _ATOM_VOLTAGE_OBJECT + { +@@ -4193,6 +4450,69 @@ typedef struct _ATOM_LEAKID_VOLTAGE + USHORT usVoltage; + }ATOM_LEAKID_VOLTAGE; + ++typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{ ++ UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI ++ UCHAR ucVoltageMode; //Indicate voltage control mode: Init/Set/Leakage/Set phase ++ USHORT usSize; //Size of Object ++}ATOM_VOLTAGE_OBJECT_HEADER_V3; ++ ++typedef struct _VOLTAGE_LUT_ENTRY_V2 ++{ ++ ULONG ulVoltageId; // The Voltage ID which is used to program GPIO register ++ USHORT usVoltageValue; // The corresponding Voltage Value, in mV ++}VOLTAGE_LUT_ENTRY_V2; ++ ++typedef struct _LEAKAGE_VOLTAGE_LUT_ENTRY_V2 ++{ ++ USHORT usVoltageLevel; // The Voltage ID which is used to program GPIO register ++ USHORT usVoltageId; ++ USHORT usLeakageId; // The corresponding Voltage Value, in mV ++}LEAKAGE_VOLTAGE_LUT_ENTRY_V2; ++ ++typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3 ++{ ++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; ++ UCHAR ucVoltageRegulatorId; //Indicate Voltage Regulator Id ++ UCHAR ucVoltageControlI2cLine; ++ UCHAR ucVoltageControlAddress; ++ UCHAR ucVoltageControlOffset; ++ ULONG ulReserved; ++ VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff ++}ATOM_I2C_VOLTAGE_OBJECT_V3; ++ ++typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 ++{ ++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; ++ UCHAR ucVoltageGpioCntlId; // default is 0 which indicate control through CG VID mode ++ UCHAR ucGpioEntryNum; // indiate the entry numbers of Votlage/Gpio value Look up table ++ UCHAR ucPhaseDelay; // phase delay in unit of micro second ++ UCHAR ucReserved; ++ ULONG ulGpioMaskVal; // GPIO Mask value ++ VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[1]; ++}ATOM_GPIO_VOLTAGE_OBJECT_V3; ++ ++typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 ++{ ++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; ++ UCHAR ucLeakageCntlId; // default is 0 ++ UCHAR ucLeakageEntryNum; // indicate the entry number of LeakageId/Voltage Lut table ++ UCHAR ucReserved[2]; ++ ULONG ulMaxVoltageLevel; ++ LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1]; ++}ATOM_LEAKAGE_VOLTAGE_OBJECT_V3; ++ ++typedef union _ATOM_VOLTAGE_OBJECT_V3{ ++ ATOM_GPIO_VOLTAGE_OBJECT_V3 asGpioVoltageObj; ++ ATOM_I2C_VOLTAGE_OBJECT_V3 asI2cVoltageObj; ++ ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 asLeakageObj; ++}ATOM_VOLTAGE_OBJECT_V3; ++ ++typedef struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ATOM_VOLTAGE_OBJECT_V3 asVoltageObj[3]; //Info for Voltage control ++}ATOM_VOLTAGE_OBJECT_INFO_V3_1; ++ + typedef struct _ATOM_ASIC_PROFILE_VOLTAGE + { + UCHAR ucProfileId; +@@ -4305,7 +4625,18 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 + USHORT usHDMISSpreadRateIn10Hz; + USHORT usDVISSPercentage; + USHORT usDVISSpreadRateIn10Hz; +- ULONG ulReserved3[21]; ++ ULONG SclkDpmBoostMargin; ++ ULONG SclkDpmThrottleMargin; ++ USHORT SclkDpmTdpLimitPG; ++ USHORT SclkDpmTdpLimitBoost; ++ ULONG ulBoostEngineCLock; ++ UCHAR ulBoostVid_2bit; ++ UCHAR EnableBoost; ++ USHORT GnbTdpLimit; ++ USHORT usMaxLVDSPclkFreqInSingleLink; ++ UCHAR ucLvdsMisc; ++ UCHAR ucLVDSReserved; ++ ULONG ulReserved3[15]; + ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; + }ATOM_INTEGRATED_SYSTEM_INFO_V6; + +@@ -4313,9 +4644,16 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 + #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 + #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__DISABLE_AUX_HW_MODE_DETECTION 0x08 + +-// ulOtherDisplayMisc +-#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01 ++//ucLVDSMisc: ++#define SYS_INFO_LVDSMISC__888_FPDI_MODE 0x01 ++#define SYS_INFO_LVDSMISC__DL_CH_SWAP 0x02 ++#define SYS_INFO_LVDSMISC__888_BPC 0x04 ++#define SYS_INFO_LVDSMISC__OVERRIDE_EN 0x08 ++#define SYS_INFO_LVDSMISC__BLON_ACTIVE_LOW 0x10 + ++// not used any more ++#define SYS_INFO_LVDSMISC__VSYNC_ACTIVE_LOW 0x04 ++#define SYS_INFO_LVDSMISC__HSYNC_ACTIVE_LOW 0x08 + + /********************************************************************************************************************** + ATOM_INTEGRATED_SYSTEM_INFO_V6 Description +@@ -4384,7 +4722,208 @@ ucUMAChannelNumber: System memory channel numbers. + ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default + ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. + ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. +-sAvail_SCLK[5]: Arrays to provide available list of SLCK and corresponding voltage, order from low to high ++sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high ++ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. ++ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. ++ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. ++ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. ++ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. ++usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%. ++usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread. ++usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. ++usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. ++usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. ++usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. ++usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. ++usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. ++usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz ++ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode ++ [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped ++ [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color ++ [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used ++ [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low ) ++**********************************************************************************************************************/ ++ ++// this Table is used for Liano/Ontario APU ++typedef struct _ATOM_FUSION_SYSTEM_INFO_V1 ++{ ++ ATOM_INTEGRATED_SYSTEM_INFO_V6 sIntegratedSysInfo; ++ ULONG ulPowerplayTable[128]; ++}ATOM_FUSION_SYSTEM_INFO_V1; ++/********************************************************************************************************************** ++ ATOM_FUSION_SYSTEM_INFO_V1 Description ++sIntegratedSysInfo: refer to ATOM_INTEGRATED_SYSTEM_INFO_V6 definition. ++ulPowerplayTable[128]: This 512 bytes memory is used to save ATOM_PPLIB_POWERPLAYTABLE3, starting form ulPowerplayTable[0] ++**********************************************************************************************************************/ ++ ++// this IntegrateSystemInfoTable is used for Trinity APU ++typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ ULONG ulBootUpEngineClock; ++ ULONG ulDentistVCOFreq; ++ ULONG ulBootUpUMAClock; ++ ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4]; ++ ULONG ulBootUpReqDisplayVector; ++ ULONG ulOtherDisplayMisc; ++ ULONG ulGPUCapInfo; ++ ULONG ulSB_MMIO_Base_Addr; ++ USHORT usRequestedPWMFreqInHz; ++ UCHAR ucHtcTmpLmt; ++ UCHAR ucHtcHystLmt; ++ ULONG ulMinEngineClock; ++ ULONG ulSystemConfig; ++ ULONG ulCPUCapInfo; ++ USHORT usNBP0Voltage; ++ USHORT usNBP1Voltage; ++ USHORT usBootUpNBVoltage; ++ USHORT usExtDispConnInfoOffset; ++ USHORT usPanelRefreshRateRange; ++ UCHAR ucMemoryType; ++ UCHAR ucUMAChannelNumber; ++ UCHAR strVBIOSMsg[40]; ++ ULONG ulReserved[20]; ++ ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5]; ++ ULONG ulGMCRestoreResetTime; ++ ULONG ulMinimumNClk; ++ ULONG ulIdleNClk; ++ ULONG ulDDR_DLL_PowerUpTime; ++ ULONG ulDDR_PLL_PowerUpTime; ++ USHORT usPCIEClkSSPercentage; ++ USHORT usPCIEClkSSType; ++ USHORT usLvdsSSPercentage; ++ USHORT usLvdsSSpreadRateIn10Hz; ++ USHORT usHDMISSPercentage; ++ USHORT usHDMISSpreadRateIn10Hz; ++ USHORT usDVISSPercentage; ++ USHORT usDVISSpreadRateIn10Hz; ++ ULONG SclkDpmBoostMargin; ++ ULONG SclkDpmThrottleMargin; ++ USHORT SclkDpmTdpLimitPG; ++ USHORT SclkDpmTdpLimitBoost; ++ ULONG ulBoostEngineCLock; ++ UCHAR ulBoostVid_2bit; ++ UCHAR EnableBoost; ++ USHORT GnbTdpLimit; ++ USHORT usMaxLVDSPclkFreqInSingleLink; ++ UCHAR ucLvdsMisc; ++ UCHAR ucLVDSReserved; ++ UCHAR ucLVDSPwrOnSeqDIGONtoDE_in4Ms; ++ UCHAR ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; ++ UCHAR ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; ++ UCHAR ucLVDSPwrOffSeqDEtoDIGON_in4Ms; ++ UCHAR ucLVDSOffToOnDelay_in4Ms; ++ UCHAR ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; ++ UCHAR ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; ++ UCHAR ucLVDSReserved1; ++ ULONG ulLCDBitDepthControlVal; ++ ULONG ulNbpStateMemclkFreq[4]; ++ USHORT usNBP2Voltage; ++ USHORT usNBP3Voltage; ++ ULONG ulNbpStateNClkFreq[4]; ++ UCHAR ucNBDPMEnable; ++ UCHAR ucReserved[3]; ++ UCHAR ucDPMState0VclkFid; ++ UCHAR ucDPMState0DclkFid; ++ UCHAR ucDPMState1VclkFid; ++ UCHAR ucDPMState1DclkFid; ++ UCHAR ucDPMState2VclkFid; ++ UCHAR ucDPMState2DclkFid; ++ UCHAR ucDPMState3VclkFid; ++ UCHAR ucDPMState3DclkFid; ++ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; ++}ATOM_INTEGRATED_SYSTEM_INFO_V1_7; ++ ++// ulOtherDisplayMisc ++#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01 ++#define INTEGRATED_SYSTEM_INFO__GET_BOOTUP_DISPLAY_CALLBACK_FUNC_SUPPORT 0x02 ++#define INTEGRATED_SYSTEM_INFO__GET_EXPANSION_CALLBACK_FUNC_SUPPORT 0x04 ++#define INTEGRATED_SYSTEM_INFO__FAST_BOOT_SUPPORT 0x08 ++ ++// ulGPUCapInfo ++#define SYS_INFO_GPUCAPS__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 ++#define SYS_INFO_GPUCAPS__DP_SINGLEPLL_MODE 0x02 ++#define SYS_INFO_GPUCAPS__DISABLE_AUX_MODE_DETECT 0x08 ++ ++/********************************************************************************************************************** ++ ATOM_INTEGRATED_SYSTEM_INFO_V1_7 Description ++ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock ++ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. ++ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. ++sDISPCLK_Voltage: Report Display clock voltage requirement. ++ ++ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Trinity projects: ++ ATOM_DEVICE_CRT1_SUPPORT 0x0001 ++ ATOM_DEVICE_DFP1_SUPPORT 0x0008 ++ ATOM_DEVICE_DFP6_SUPPORT 0x0040 ++ ATOM_DEVICE_DFP2_SUPPORT 0x0080 ++ ATOM_DEVICE_DFP3_SUPPORT 0x0200 ++ ATOM_DEVICE_DFP4_SUPPORT 0x0400 ++ ATOM_DEVICE_DFP5_SUPPORT 0x0800 ++ ATOM_DEVICE_LCD1_SUPPORT 0x0002 ++ulOtherDisplayMisc: bit[0]=0: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is not supported by SBIOS. ++ =1: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is supported by SBIOS. ++ bit[1]=0: INT15 callback function Get boot display( ax=4e08, bl=01h) is not supported by SBIOS ++ =1: INT15 callback function Get boot display( ax=4e08, bl=01h) is supported by SBIOS ++ bit[2]=0: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is not supported by SBIOS ++ =1: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is supported by SBIOS ++ bit[3]=0: VBIOS fast boot is disable ++ =1: VBIOS fast boot is enable. ( VBIOS skip display device detection in every set mode if LCD panel is connect and LID is open) ++ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode. ++ =1: TMDS/HDMI Coherent Mode use signel PLL mode. ++ bit[1]=0: DP mode use cascade PLL mode ( New for Trinity ) ++ =1: DP mode use single PLL mode ++ bit[3]=0: Enable AUX HW mode detection logic ++ =1: Disable AUX HW mode detection logic ++ ++ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage. ++ ++usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). ++ Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0; ++ ++ When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below: ++ 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use; ++ VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result, ++ Changing BL using VBIOS function is functional in both driver and non-driver present environment; ++ and enabling VariBri under the driver environment from PP table is optional. ++ ++ 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating ++ that BL control from GPU is expected. ++ VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1 ++ Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but ++ it's per platform ++ and enabling VariBri under the driver environment from PP table is optional. ++ ++ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt. ++ Threshold on value to enter HTC_active state. ++ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt. ++ To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt. ++ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings. ++ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled ++ =1: PCIE Power Gating Enabled ++ Bit[1]=0: DDR-DLL shut-down feature disabled. ++ 1: DDR-DLL shut-down feature enabled. ++ Bit[2]=0: DDR-PLL Power down feature disabled. ++ 1: DDR-PLL Power down feature enabled. ++ulCPUCapInfo: TBD ++usNBP0Voltage: VID for voltage on NB P0 State ++usNBP1Voltage: VID for voltage on NB P1 State ++usNBP2Voltage: VID for voltage on NB P2 State ++usNBP3Voltage: VID for voltage on NB P3 State ++usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement. ++usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure ++usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set ++ to indicate a range. ++ SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 ++ SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 ++ SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 ++ SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 ++ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. ++ucUMAChannelNumber: System memory channel numbers. ++ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default ++ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. ++ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. ++sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high + ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. + ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. + ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. +@@ -4398,6 +4937,41 @@ usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; + usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. + usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. + usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. ++usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz ++ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode ++ [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped ++ [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color ++ [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used ++ [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low ) ++ucLVDSPwrOnSeqDIGONtoDE_in4Ms: LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ). ++ =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ucLVDSPwrOnDEtoVARY_BL_in4Ms: LVDS power up sequence time in unit of 4ms., time delay from DE( data enable ) active to Vary Brightness enable signal active( VARY_BL ). ++ =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ucLVDSPwrOffVARY_BLtoDE_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from data enable ( DE ) signal off to LCDVCC (DIGON) off. ++ =0 mean use VBIOS default delay which is 8 ( 32ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ucLVDSPwrOffDEtoDIGON_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from vary brightness enable signal( VARY_BL) off to data enable ( DE ) signal off. ++ =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ucLVDSOffToOnDelay_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from DIGON signal off to DIGON signal active. ++ =0 means to use VBIOS default delay which is 125 ( 500ms ). ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ucLVDSPwrOnVARY_BLtoBLON_in4Ms: LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. ++ =0 means to use VBIOS default delay which is 0 ( 0ms ). ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ucLVDSPwrOffBLONtoVARY_BL_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. ++ =0 means to use VBIOS default delay which is 0 ( 0ms ). ++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. ++ ++ulNbpStateMemclkFreq[4]: system memory clock frequncey in unit of 10Khz in different NB pstate. ++ + **********************************************************************************************************************/ + + /**************************************************************************/ +@@ -4459,6 +5033,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT + #define ASIC_INTERNAL_SS_ON_DP 7 + #define ASIC_INTERNAL_SS_ON_DCPLL 8 + #define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9 ++#define ASIC_INTERNAL_VCE_SS 10 + + typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 + { +@@ -4520,7 +5095,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 + #define ATOM_DOS_MODE_INFO_DEF 7 + #define ATOM_I2C_CHANNEL_STATUS_DEF 8 + #define ATOM_I2C_CHANNEL_STATUS1_DEF 9 +- ++#define ATOM_INTERNAL_TIMER_DEF 10 + + // BIOS_0_SCRATCH Definition + #define ATOM_S0_CRT1_MONO 0x00000001L +@@ -4648,6 +5223,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 + #define ATOM_S2_DEVICE_DPMS_MASKw1 0x3FF + #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3 0x0C + #define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGEb3 0x10 ++#define ATOM_S2_TMDS_COHERENT_MODEb3 0x10 // used by VBIOS code only, use coherent mode for TMDS/HDMI mode + #define ATOM_S2_VRI_BRIGHT_ENABLEb3 0x20 + #define ATOM_S2_ROTATION_STATE_MASKb3 0xC0 + +@@ -5038,6 +5614,23 @@ typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3 + USHORT usDeviceId; // Active Device Id for this surface. If no device, set to 0. + }ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3; + ++typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4 ++{ ++ USHORT usHight; // Image Hight ++ USHORT usWidth; // Image Width ++ USHORT usGraphPitch; ++ UCHAR ucColorDepth; ++ UCHAR ucPixelFormat; ++ UCHAR ucSurface; // Surface 1 or 2 ++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE ++ UCHAR ucModeType; ++ UCHAR ucReserved; ++}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4; ++ ++// ucEnable ++#define ATOM_GRAPH_CONTROL_SET_PITCH 0x0f ++#define ATOM_GRAPH_CONTROL_SET_DISP_START 0x10 ++ + typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION + { + ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface; +@@ -5057,6 +5650,58 @@ typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS + USHORT usY_Size; + }GET_DISPLAY_SURFACE_SIZE_PARAMETERS; + ++typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2 ++{ ++ union{ ++ USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC ++ USHORT usSurface; ++ }; ++ USHORT usY_Size; ++ USHORT usDispXStart; ++ USHORT usDispYStart; ++}GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2; ++ ++ ++typedef struct _PALETTE_DATA_CONTROL_PARAMETERS_V3 ++{ ++ UCHAR ucLutId; ++ UCHAR ucAction; ++ USHORT usLutStartIndex; ++ USHORT usLutLength; ++ USHORT usLutOffsetInVram; ++}PALETTE_DATA_CONTROL_PARAMETERS_V3; ++ ++// ucAction: ++#define PALETTE_DATA_AUTO_FILL 1 ++#define PALETTE_DATA_READ 2 ++#define PALETTE_DATA_WRITE 3 ++ ++ ++typedef struct _INTERRUPT_SERVICE_PARAMETERS_V2 ++{ ++ UCHAR ucInterruptId; ++ UCHAR ucServiceId; ++ UCHAR ucStatus; ++ UCHAR ucReserved; ++}INTERRUPT_SERVICE_PARAMETER_V2; ++ ++// ucInterruptId ++#define HDP1_INTERRUPT_ID 1 ++#define HDP2_INTERRUPT_ID 2 ++#define HDP3_INTERRUPT_ID 3 ++#define HDP4_INTERRUPT_ID 4 ++#define HDP5_INTERRUPT_ID 5 ++#define HDP6_INTERRUPT_ID 6 ++#define SW_INTERRUPT_ID 11 ++ ++// ucAction ++#define INTERRUPT_SERVICE_GEN_SW_INT 1 ++#define INTERRUPT_SERVICE_GET_STATUS 2 ++ ++ // ucStatus ++#define INTERRUPT_STATUS__INT_TRIGGER 1 ++#define INTERRUPT_STATUS__HPD_HIGH 2 ++ + typedef struct _INDIRECT_IO_ACCESS + { + ATOM_COMMON_TABLE_HEADER sHeader; +@@ -5189,7 +5834,7 @@ typedef struct _ATOM_INIT_REG_BLOCK{ + + #define END_OF_REG_INDEX_BLOCK 0x0ffff + #define END_OF_REG_DATA_BLOCK 0x00000000 +-#define ATOM_INIT_REG_MASK_FLAG 0x80 ++#define ATOM_INIT_REG_MASK_FLAG 0x80 //Not used in BIOS + #define CLOCK_RANGE_HIGHEST 0x00ffffff + + #define VALUE_DWORD SIZEOF ULONG +@@ -5229,6 +5874,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE + #define _128Mx8 0x51 + #define _128Mx16 0x52 + #define _256Mx8 0x61 ++#define _256Mx16 0x62 + + #define SAMSUNG 0x1 + #define INFINEON 0x2 +@@ -5585,7 +6231,7 @@ typedef struct _ATOM_VRAM_MODULE_V7 + ULONG ulChannelMapCfg; // mmMC_SHARED_CHREMAP + USHORT usModuleSize; // Size of ATOM_VRAM_MODULE_V7 + USHORT usPrivateReserved; // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) +- USHORT usReserved; ++ USHORT usEnableChannels; // bit vector which indicate which channels are enabled + UCHAR ucExtMemoryID; // Current memory module ID + UCHAR ucMemoryType; // MEM_TYPE_DDR2/DDR3/GDDR3/GDDR5 + UCHAR ucChannelNum; // Number of mem. channels supported in this module +@@ -5597,7 +6243,8 @@ typedef struct _ATOM_VRAM_MODULE_V7 + UCHAR ucNPL_RT; // Round trip delay (MC_SEQ_CAS_TIMING [28:24]:TCL=CL+NPL_RT-2). Always 2. + UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemorySize; // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros +- UCHAR ucReserved[3]; ++ USHORT usSEQSettingOffset; ++ UCHAR ucReserved; + // Memory Module specific values + USHORT usEMRS2Value; // EMRS2/MR2 Value. + USHORT usEMRS3Value; // EMRS3/MR3 Value. +@@ -5633,10 +6280,10 @@ typedef struct _ATOM_VRAM_INFO_V3 + typedef struct _ATOM_VRAM_INFO_V4 + { + ATOM_COMMON_TABLE_HEADER sHeader; +- USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting +- USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting +- USHORT usRerseved; +- UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 ++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting ++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting ++ USHORT usRerseved; ++ UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 + ULONG ulMemDQ7_0BitRemap; // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] + UCHAR ucReservde[4]; + UCHAR ucNumOfVRAMModule; +@@ -5648,9 +6295,10 @@ typedef struct _ATOM_VRAM_INFO_V4 + typedef struct _ATOM_VRAM_INFO_HEADER_V2_1 + { + ATOM_COMMON_TABLE_HEADER sHeader; +- USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting +- USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting +- USHORT usReserved[4]; ++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting ++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting ++ USHORT usPerBytePresetOffset; // offset of ATOM_INIT_REG_BLOCK structure for Per Byte Offset Preset Settings ++ USHORT usReserved[3]; + UCHAR ucNumOfVRAMModule; // indicate number of VRAM module + UCHAR ucMemoryClkPatchTblVer; // version of memory AC timing register list + UCHAR ucVramModuleVer; // indicate ATOM_VRAM_MODUE version +@@ -5935,6 +6583,52 @@ typedef struct _ATOM_DISP_OUT_INFO_V2 + ASIC_ENCODER_INFO asEncoderInfo[1]; + }ATOM_DISP_OUT_INFO_V2; + ++ ++typedef struct _ATOM_DISP_CLOCK_ID { ++ UCHAR ucPpllId; ++ UCHAR ucPpllAttribute; ++}ATOM_DISP_CLOCK_ID; ++ ++// ucPpllAttribute ++#define CLOCK_SOURCE_SHAREABLE 0x01 ++#define CLOCK_SOURCE_DP_MODE 0x02 ++#define CLOCK_SOURCE_NONE_DP_MODE 0x04 ++ ++//DispOutInfoTable ++typedef struct _ASIC_TRANSMITTER_INFO_V2 ++{ ++ USHORT usTransmitterObjId; ++ USHORT usDispClkIdOffset; // point to clock source id list supported by Encoder Object ++ UCHAR ucTransmitterCmdTblId; ++ UCHAR ucConfig; ++ UCHAR ucEncoderID; // available 1st encoder ( default ) ++ UCHAR ucOptionEncoderID; // available 2nd encoder ( optional ) ++ UCHAR uc2ndEncoderID; ++ UCHAR ucReserved; ++}ASIC_TRANSMITTER_INFO_V2; ++ ++typedef struct _ATOM_DISP_OUT_INFO_V3 ++{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT ptrTransmitterInfo; ++ USHORT ptrEncoderInfo; ++ USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary. ++ USHORT usReserved; ++ UCHAR ucDCERevision; ++ UCHAR ucMaxDispEngineNum; ++ UCHAR ucMaxActiveDispEngineNum; ++ UCHAR ucMaxPPLLNum; ++ UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE ++ UCHAR ucReserved[3]; ++ ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only ++}ATOM_DISP_OUT_INFO_V3; ++ ++typedef enum CORE_REF_CLK_SOURCE{ ++ CLOCK_SRC_XTALIN=0, ++ CLOCK_SRC_XO_IN=1, ++ CLOCK_SRC_XO_IN2=2, ++}CORE_REF_CLK_SOURCE; ++ + // DispDevicePriorityInfo + typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO + { +@@ -6070,6 +6764,39 @@ typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS + #define HW_I2C_READ 0 + #define I2C_2BYTE_ADDR 0x02 + ++/****************************************************************************/ ++// Structures used by HW_Misc_OperationTable ++/****************************************************************************/ ++typedef struct _ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1 ++{ ++ UCHAR ucCmd; // Input: To tell which action to take ++ UCHAR ucReserved[3]; ++ ULONG ulReserved; ++}ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1; ++ ++typedef struct _ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1 ++{ ++ UCHAR ucReturnCode; // Output: Return value base on action was taken ++ UCHAR ucReserved[3]; ++ ULONG ulReserved; ++}ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1; ++ ++// Actions code ++#define ATOM_GET_SDI_SUPPORT 0xF0 ++ ++// Return code ++#define ATOM_UNKNOWN_CMD 0 ++#define ATOM_FEATURE_NOT_SUPPORTED 1 ++#define ATOM_FEATURE_SUPPORTED 2 ++ ++typedef struct _ATOM_HW_MISC_OPERATION_PS_ALLOCATION ++{ ++ ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1 sInput_Output; ++ PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS sReserved; ++}ATOM_HW_MISC_OPERATION_PS_ALLOCATION; ++ ++/****************************************************************************/ ++ + typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 + { + UCHAR ucHWBlkInst; // HW block instance, 0, 1, 2, ... +@@ -6090,6 +6817,52 @@ typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 + #define SELECT_CRTC_PIXEL_RATE 7 + #define SELECT_VGA_BLK 8 + ++// DIGTransmitterInfoTable structure used to program UNIPHY settings ++typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_1{ ++ ATOM_COMMON_TABLE_HEADER sHeader; ++ USHORT usDPVsPreEmphSettingOffset; // offset of PHY_ANALOG_SETTING_INFO * with DP Voltage Swing and Pre-Emphasis for each Link clock ++ USHORT usPhyAnalogRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with None-DP mode Analog Setting's register Info ++ USHORT usPhyAnalogSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with None-DP mode Analog Setting for each link clock range ++ USHORT usPhyPllRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy Pll register Info ++ USHORT usPhyPllSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings ++}DIG_TRANSMITTER_INFO_HEADER_V3_1; ++ ++typedef struct _CLOCK_CONDITION_REGESTER_INFO{ ++ USHORT usRegisterIndex; ++ UCHAR ucStartBit; ++ UCHAR ucEndBit; ++}CLOCK_CONDITION_REGESTER_INFO; ++ ++typedef struct _CLOCK_CONDITION_SETTING_ENTRY{ ++ USHORT usMaxClockFreq; ++ UCHAR ucEncodeMode; ++ UCHAR ucPhySel; ++ ULONG ulAnalogSetting[1]; ++}CLOCK_CONDITION_SETTING_ENTRY; ++ ++typedef struct _CLOCK_CONDITION_SETTING_INFO{ ++ USHORT usEntrySize; ++ CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[1]; ++}CLOCK_CONDITION_SETTING_INFO; ++ ++typedef struct _PHY_CONDITION_REG_VAL{ ++ ULONG ulCondition; ++ ULONG ulRegVal; ++}PHY_CONDITION_REG_VAL; ++ ++typedef struct _PHY_CONDITION_REG_INFO{ ++ USHORT usRegIndex; ++ USHORT usSize; ++ PHY_CONDITION_REG_VAL asRegVal[1]; ++}PHY_CONDITION_REG_INFO; ++ ++typedef struct _PHY_ANALOG_SETTING_INFO{ ++ UCHAR ucEncodeMode; ++ UCHAR ucPhySel; ++ USHORT usSize; ++ PHY_CONDITION_REG_INFO asAnalogSetting[1]; ++}PHY_ANALOG_SETTING_INFO; ++ + /****************************************************************************/ + //Portion VI: Definitinos for vbios MC scratch registers that driver used + /****************************************************************************/ +@@ -7020,4 +7793,68 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table + + #pragma pack() // BIOS data must use byte aligment + ++// ++// AMD ACPI Table ++// ++#pragma pack(1) ++ ++typedef struct { ++ ULONG Signature; ++ ULONG TableLength; //Length ++ UCHAR Revision; ++ UCHAR Checksum; ++ UCHAR OemId[6]; ++ UCHAR OemTableId[8]; //UINT64 OemTableId; ++ ULONG OemRevision; ++ ULONG CreatorId; ++ ULONG CreatorRevision; ++} AMD_ACPI_DESCRIPTION_HEADER; ++/* ++//EFI_ACPI_DESCRIPTION_HEADER from AcpiCommon.h ++typedef struct { ++ UINT32 Signature; //0x0 ++ UINT32 Length; //0x4 ++ UINT8 Revision; //0x8 ++ UINT8 Checksum; //0x9 ++ UINT8 OemId[6]; //0xA ++ UINT64 OemTableId; //0x10 ++ UINT32 OemRevision; //0x18 ++ UINT32 CreatorId; //0x1C ++ UINT32 CreatorRevision; //0x20 ++}EFI_ACPI_DESCRIPTION_HEADER; ++*/ ++typedef struct { ++ AMD_ACPI_DESCRIPTION_HEADER SHeader; ++ UCHAR TableUUID[16]; //0x24 ++ ULONG VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture. ++ ULONG Lib1ImageOffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture. ++ ULONG Reserved[4]; //0x3C ++}UEFI_ACPI_VFCT; ++ ++typedef struct { ++ ULONG PCIBus; //0x4C ++ ULONG PCIDevice; //0x50 ++ ULONG PCIFunction; //0x54 ++ USHORT VendorID; //0x58 ++ USHORT DeviceID; //0x5A ++ USHORT SSVID; //0x5C ++ USHORT SSID; //0x5E ++ ULONG Revision; //0x60 ++ ULONG ImageLength; //0x64 ++}VFCT_IMAGE_HEADER; ++ ++ ++typedef struct { ++ VFCT_IMAGE_HEADER VbiosHeader; ++ UCHAR VbiosContent[1]; ++}GOP_VBIOS_CONTENT; ++ ++typedef struct { ++ VFCT_IMAGE_HEADER Lib1Header; ++ UCHAR Lib1Content[1]; ++}GOP_LIB1_CONTENT; ++ ++#pragma pack() ++ ++ + #endif /* _ATOMBIOS_H */ +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 8227e76..28e69e9 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -123,21 +123,6 @@ struct radeon_device; + /* + * BIOS. + */ +-#define ATRM_BIOS_PAGE 4096 +- +-#if defined(CONFIG_VGA_SWITCHEROO) +-bool radeon_atrm_supported(struct pci_dev *pdev); +-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); +-#else +-static inline bool radeon_atrm_supported(struct pci_dev *pdev) +-{ +- return false; +-} +- +-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ +- return -EINVAL; +-} +-#endif + bool radeon_get_bios(struct radeon_device *rdev); + + +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 9d2c369..38585c5 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -446,7 +446,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, + } + + /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ +- if ((dev->pdev->device == 0x9802) && ++ if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && + (dev->pdev->subsystem_vendor == 0x1734) && + (dev->pdev->subsystem_device == 0x11bd)) { + if (*connector_type == DRM_MODE_CONNECTOR_VGA) { +diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +index 9d95792..2a2cf0b 100644 +--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c ++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +@@ -30,56 +30,8 @@ static struct radeon_atpx_priv { + /* handle for device - and atpx */ + acpi_handle dhandle; + acpi_handle atpx_handle; +- acpi_handle atrm_handle; + } radeon_atpx_priv; + +-/* retrieve the ROM in 4k blocks */ +-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, +- int offset, int len) +-{ +- acpi_status status; +- union acpi_object atrm_arg_elements[2], *obj; +- struct acpi_object_list atrm_arg; +- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; +- +- atrm_arg.count = 2; +- atrm_arg.pointer = &atrm_arg_elements[0]; +- +- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; +- atrm_arg_elements[0].integer.value = offset; +- +- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; +- atrm_arg_elements[1].integer.value = len; +- +- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); +- if (ACPI_FAILURE(status)) { +- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); +- return -ENODEV; +- } +- +- obj = (union acpi_object *)buffer.pointer; +- memcpy(bios+offset, obj->buffer.pointer, len); +- kfree(buffer.pointer); +- return len; +-} +- +-bool radeon_atrm_supported(struct pci_dev *pdev) +-{ +- /* get the discrete ROM only via ATRM */ +- if (!radeon_atpx_priv.atpx_detected) +- return false; +- +- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) +- return false; +- return true; +-} +- +- +-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) +-{ +- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); +-} +- + static int radeon_atpx_get_version(acpi_handle handle) + { + acpi_status status; +@@ -197,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, + + static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) + { +- acpi_handle dhandle, atpx_handle, atrm_handle; ++ acpi_handle dhandle, atpx_handle; + acpi_status status; + + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); +@@ -208,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) + if (ACPI_FAILURE(status)) + return false; + +- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); +- if (ACPI_FAILURE(status)) +- return false; +- + radeon_atpx_priv.dhandle = dhandle; + radeon_atpx_priv.atpx_handle = atpx_handle; +- radeon_atpx_priv.atrm_handle = atrm_handle; + return true; + } + +diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c +index 229a20f..d306cc8 100644 +--- a/drivers/gpu/drm/radeon/radeon_bios.c ++++ b/drivers/gpu/drm/radeon/radeon_bios.c +@@ -32,6 +32,7 @@ + + #include <linux/vga_switcheroo.h> + #include <linux/slab.h> ++#include <linux/acpi.h> + /* + * BIOS. + */ +@@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev) + return true; + } + ++#ifdef CONFIG_ACPI + /* ATRM is used to get the BIOS on the discrete cards in + * dual-gpu systems. + */ ++/* retrieve the ROM in 4k blocks */ ++#define ATRM_BIOS_PAGE 4096 ++/** ++ * radeon_atrm_call - fetch a chunk of the vbios ++ * ++ * @atrm_handle: acpi ATRM handle ++ * @bios: vbios image pointer ++ * @offset: offset of vbios image data to fetch ++ * @len: length of vbios image data to fetch ++ * ++ * Executes ATRM to fetch a chunk of the discrete ++ * vbios image on PX systems (all asics). ++ * Returns the length of the buffer fetched. ++ */ ++static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, ++ int offset, int len) ++{ ++ acpi_status status; ++ union acpi_object atrm_arg_elements[2], *obj; ++ struct acpi_object_list atrm_arg; ++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; ++ ++ atrm_arg.count = 2; ++ atrm_arg.pointer = &atrm_arg_elements[0]; ++ ++ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; ++ atrm_arg_elements[0].integer.value = offset; ++ ++ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; ++ atrm_arg_elements[1].integer.value = len; ++ ++ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); ++ if (ACPI_FAILURE(status)) { ++ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); ++ return -ENODEV; ++ } ++ ++ obj = (union acpi_object *)buffer.pointer; ++ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); ++ len = obj->buffer.length; ++ kfree(buffer.pointer); ++ return len; ++} ++ + static bool radeon_atrm_get_bios(struct radeon_device *rdev) + { + int ret; + int size = 256 * 1024; + int i; ++ struct pci_dev *pdev = NULL; ++ acpi_handle dhandle, atrm_handle; ++ acpi_status status; ++ bool found = false; ++ ++ /* ATRM is for the discrete card only */ ++ if (rdev->flags & RADEON_IS_IGP) ++ return false; ++ ++ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { ++ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); ++ if (!dhandle) ++ continue; ++ ++ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); ++ if (!ACPI_FAILURE(status)) { ++ found = true; ++ break; ++ } ++ } + +- if (!radeon_atrm_supported(rdev->pdev)) ++ if (!found) + return false; + + rdev->bios = kmalloc(size, GFP_KERNEL); +@@ -117,10 +183,11 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) + } + + for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { +- ret = radeon_atrm_get_bios_chunk(rdev->bios, +- (i * ATRM_BIOS_PAGE), +- ATRM_BIOS_PAGE); +- if (ret <= 0) ++ ret = radeon_atrm_call(atrm_handle, ++ rdev->bios, ++ (i * ATRM_BIOS_PAGE), ++ ATRM_BIOS_PAGE); ++ if (ret < ATRM_BIOS_PAGE) + break; + } + +@@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) + } + return true; + } ++#else ++static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) ++{ ++ return false; ++} ++#endif + + static bool ni_read_disabled_bios(struct radeon_device *rdev) + { +@@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) + return legacy_read_disabled_bios(rdev); + } + ++#ifdef CONFIG_ACPI ++static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) ++{ ++ bool ret = false; ++ struct acpi_table_header *hdr; ++ acpi_size tbl_size; ++ UEFI_ACPI_VFCT *vfct; ++ GOP_VBIOS_CONTENT *vbios; ++ VFCT_IMAGE_HEADER *vhdr; ++ ++ if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) ++ return false; ++ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { ++ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); ++ goto out_unmap; ++ } ++ ++ vfct = (UEFI_ACPI_VFCT *)hdr; ++ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { ++ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); ++ goto out_unmap; ++ } ++ ++ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); ++ vhdr = &vbios->VbiosHeader; ++ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", ++ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, ++ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); ++ ++ if (vhdr->PCIBus != rdev->pdev->bus->number || ++ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || ++ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) || ++ vhdr->VendorID != rdev->pdev->vendor || ++ vhdr->DeviceID != rdev->pdev->device) { ++ DRM_INFO("ACPI VFCT table is not for this card\n"); ++ goto out_unmap; ++ }; ++ ++ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { ++ DRM_ERROR("ACPI VFCT image truncated\n"); ++ goto out_unmap; ++ } ++ ++ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); ++ ret = !!rdev->bios; ++ ++out_unmap: ++ return ret; ++} ++#else ++static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) ++{ ++ return false; ++} ++#endif + + bool radeon_get_bios(struct radeon_device *rdev) + { +@@ -484,6 +612,8 @@ bool radeon_get_bios(struct radeon_device *rdev) + + r = radeon_atrm_get_bios(rdev); + if (r == false) ++ r = radeon_acpi_vfct_bios(rdev); ++ if (r == false) + r = igp_read_bios_from_vram(rdev); + if (r == false) + r = radeon_read_bios(rdev); +diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c +index 39497c7..f3ae607 100644 +--- a/drivers/gpu/drm/radeon/radeon_object.c ++++ b/drivers/gpu/drm/radeon/radeon_object.c +@@ -117,6 +117,7 @@ int radeon_bo_create(struct radeon_device *rdev, + return -ENOMEM; + } + ++retry: + bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); + if (bo == NULL) + return -ENOMEM; +@@ -129,8 +130,6 @@ int radeon_bo_create(struct radeon_device *rdev, + bo->gem_base.driver_private = NULL; + bo->surface_reg = -1; + INIT_LIST_HEAD(&bo->list); +- +-retry: + radeon_ttm_placement_from_domain(bo, domain); + /* Kernel allocation are uninterruptible */ + mutex_lock(&rdev->vram_mutex); +diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c +index b99af34..a2abb8e 100644 +--- a/drivers/hid/hid-chicony.c ++++ b/drivers/hid/hid-chicony.c +@@ -60,6 +60,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + static const struct hid_device_id ch_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, + { } + }; + MODULE_DEVICE_TABLE(hid, ch_devices); +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 95430a0..5cc029f 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1398,12 +1398,14 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, +diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c +index 2f0be4c..9e43aac 100644 +--- a/drivers/hid/hid-cypress.c ++++ b/drivers/hid/hid-cypress.c +@@ -129,6 +129,8 @@ static const struct hid_device_id cp_devices[] = { + .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3), + .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4), ++ .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), + .driver_data = CP_2WHEEL_MOUSE_HACK }, + { } +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 7db934d..e4317a2 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -196,6 +196,7 @@ + #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d + #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 + #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 ++#define USB_DEVICE_ID_CHICONY_AK1D 0x1125 + + #define USB_VENDOR_ID_CHUNGHWAT 0x2247 + #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 +@@ -225,6 +226,7 @@ + #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 + #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 + #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 ++#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 + #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 + + #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 0bfa545..c76b051 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -568,24 +568,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, + scmnd->sc_data_direction); + } + +-static void srp_remove_req(struct srp_target_port *target, +- struct srp_request *req, s32 req_lim_delta) ++/** ++ * srp_claim_req - Take ownership of the scmnd associated with a request. ++ * @target: SRP target port. ++ * @req: SRP request. ++ * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take ++ * ownership of @req->scmnd if it equals @scmnd. ++ * ++ * Return value: ++ * Either NULL or a pointer to the SCSI command the caller became owner of. ++ */ ++static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, ++ struct srp_request *req, ++ struct scsi_cmnd *scmnd) + { + unsigned long flags; + +- srp_unmap_data(req->scmnd, target, req); ++ spin_lock_irqsave(&target->lock, flags); ++ if (!scmnd) { ++ scmnd = req->scmnd; ++ req->scmnd = NULL; ++ } else if (req->scmnd == scmnd) { ++ req->scmnd = NULL; ++ } else { ++ scmnd = NULL; ++ } ++ spin_unlock_irqrestore(&target->lock, flags); ++ ++ return scmnd; ++} ++ ++/** ++ * srp_free_req() - Unmap data and add request to the free request list. ++ */ ++static void srp_free_req(struct srp_target_port *target, ++ struct srp_request *req, struct scsi_cmnd *scmnd, ++ s32 req_lim_delta) ++{ ++ unsigned long flags; ++ ++ srp_unmap_data(scmnd, target, req); ++ + spin_lock_irqsave(&target->lock, flags); + target->req_lim += req_lim_delta; +- req->scmnd = NULL; + list_add_tail(&req->list, &target->free_reqs); + spin_unlock_irqrestore(&target->lock, flags); + } + + static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) + { +- req->scmnd->result = DID_RESET << 16; +- req->scmnd->scsi_done(req->scmnd); +- srp_remove_req(target, req, 0); ++ struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL); ++ ++ if (scmnd) { ++ scmnd->result = DID_RESET << 16; ++ scmnd->scsi_done(scmnd); ++ srp_free_req(target, req, scmnd, 0); ++ } + } + + static int srp_reconnect_target(struct srp_target_port *target) +@@ -1055,11 +1093,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) + complete(&target->tsk_mgmt_done); + } else { + req = &target->req_ring[rsp->tag]; +- scmnd = req->scmnd; +- if (!scmnd) ++ scmnd = srp_claim_req(target, req, NULL); ++ if (!scmnd) { + shost_printk(KERN_ERR, target->scsi_host, + "Null scmnd for RSP w/tag %016llx\n", + (unsigned long long) rsp->tag); ++ ++ spin_lock_irqsave(&target->lock, flags); ++ target->req_lim += be32_to_cpu(rsp->req_lim_delta); ++ spin_unlock_irqrestore(&target->lock, flags); ++ ++ return; ++ } + scmnd->result = rsp->status; + + if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { +@@ -1074,7 +1119,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) + else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) + scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); + +- srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta)); ++ srp_free_req(target, req, scmnd, ++ be32_to_cpu(rsp->req_lim_delta)); ++ + scmnd->host_scribble = NULL; + scmnd->scsi_done(scmnd); + } +@@ -1613,25 +1660,17 @@ static int srp_abort(struct scsi_cmnd *scmnd) + { + struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_request *req = (struct srp_request *) scmnd->host_scribble; +- int ret = SUCCESS; + + shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); + +- if (!req || target->qp_in_error) +- return FAILED; +- if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, +- SRP_TSK_ABORT_TASK)) ++ if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) + return FAILED; ++ srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, ++ SRP_TSK_ABORT_TASK); ++ srp_free_req(target, req, scmnd, 0); ++ scmnd->result = DID_ABORT << 16; + +- if (req->scmnd) { +- if (!target->tsk_mgmt_status) { +- srp_remove_req(target, req, 0); +- scmnd->result = DID_ABORT << 16; +- } else +- ret = FAILED; +- } +- +- return ret; ++ return SUCCESS; + } + + static int srp_reset_device(struct scsi_cmnd *scmnd) +diff --git a/drivers/md/md.c b/drivers/md/md.c +index d8646d7..2887f22 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1144,8 +1144,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor + ret = 0; + } + rdev->sectors = rdev->sb_start; +- /* Limit to 4TB as metadata cannot record more than that */ +- if (rdev->sectors >= (2ULL << 32)) ++ /* Limit to 4TB as metadata cannot record more than that. ++ * (not needed for Linear and RAID0 as metadata doesn't ++ * record this size) ++ */ ++ if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) + rdev->sectors = (2ULL << 32) - 2; + + if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) +@@ -1427,7 +1430,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) + /* Limit to 4TB as metadata cannot record more than that. + * 4TB == 2^32 KB, or 2*2^32 sectors. + */ +- if (num_sectors >= (2ULL << 32)) ++ if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) + num_sectors = (2ULL << 32) - 2; + md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, + rdev->sb_page); +diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c +index fb68805..027550d 100644 +--- a/drivers/media/dvb/siano/smsusb.c ++++ b/drivers/media/dvb/siano/smsusb.c +@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf) + return 0; + } + +-static const struct usb_device_id smsusb_id_table[] __devinitconst = { ++static const struct usb_device_id smsusb_id_table[] = { + { USB_DEVICE(0x187f, 0x0010), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0100), +diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c +index 89fec4c..731cd16 100644 +--- a/drivers/media/video/gspca/spca506.c ++++ b/drivers/media/video/gspca/spca506.c +@@ -685,7 +685,7 @@ static const struct sd_desc sd_desc = { + }; + + /* -- module initialisation -- */ +-static const struct usb_device_id device_table[] __devinitconst = { ++static const struct usb_device_id device_table[] = { + {USB_DEVICE(0x06e1, 0xa190)}, + /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 + {USB_DEVICE(0x0733, 0x0430)}, */ +diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c +index 17bbacb..cc2ae7e 100644 +--- a/drivers/misc/sgi-xp/xpc_uv.c ++++ b/drivers/misc/sgi-xp/xpc_uv.c +@@ -18,6 +18,8 @@ + #include <linux/interrupt.h> + #include <linux/delay.h> + #include <linux/device.h> ++#include <linux/cpu.h> ++#include <linux/module.h> + #include <linux/err.h> + #include <linux/slab.h> + #include <asm/uv/uv_hub.h> +@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv; + XPC_NOTIFY_MSG_SIZE_UV) + #define XPC_NOTIFY_IRQ_NAME "xpc_notify" + ++static int xpc_mq_node = -1; ++ + static struct xpc_gru_mq_uv *xpc_activate_mq_uv; + static struct xpc_gru_mq_uv *xpc_notify_mq_uv; + +@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) + #if defined CONFIG_X86_64 + mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, + UV_AFFINITY_CPU); +- if (mq->irq < 0) { +- dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", +- -mq->irq); ++ if (mq->irq < 0) + return mq->irq; +- } + + mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); + +@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, + mq->mmr_blade = uv_cpu_to_blade_id(cpu); + + nid = cpu_to_node(cpu); +- page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, +- pg_order); ++ page = alloc_pages_exact_node(nid, ++ GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, ++ pg_order); + if (page == NULL) { + dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " + "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); +@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_arch_ops_uv = { + .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, + }; + ++static int ++xpc_init_mq_node(int nid) ++{ ++ int cpu; ++ ++ get_online_cpus(); ++ ++ for_each_cpu(cpu, cpumask_of_node(nid)) { ++ xpc_activate_mq_uv = ++ xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, ++ XPC_ACTIVATE_IRQ_NAME, ++ xpc_handle_activate_IRQ_uv); ++ if (!IS_ERR(xpc_activate_mq_uv)) ++ break; ++ } ++ if (IS_ERR(xpc_activate_mq_uv)) { ++ put_online_cpus(); ++ return PTR_ERR(xpc_activate_mq_uv); ++ } ++ ++ for_each_cpu(cpu, cpumask_of_node(nid)) { ++ xpc_notify_mq_uv = ++ xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, ++ XPC_NOTIFY_IRQ_NAME, ++ xpc_handle_notify_IRQ_uv); ++ if (!IS_ERR(xpc_notify_mq_uv)) ++ break; ++ } ++ if (IS_ERR(xpc_notify_mq_uv)) { ++ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); ++ put_online_cpus(); ++ return PTR_ERR(xpc_notify_mq_uv); ++ } ++ ++ put_online_cpus(); ++ return 0; ++} ++ + int + xpc_init_uv(void) + { ++ int nid; ++ int ret = 0; ++ + xpc_arch_ops = xpc_arch_ops_uv; + + if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { +@@ -1742,21 +1785,21 @@ xpc_init_uv(void) + return -E2BIG; + } + +- xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, +- XPC_ACTIVATE_IRQ_NAME, +- xpc_handle_activate_IRQ_uv); +- if (IS_ERR(xpc_activate_mq_uv)) +- return PTR_ERR(xpc_activate_mq_uv); ++ if (xpc_mq_node < 0) ++ for_each_online_node(nid) { ++ ret = xpc_init_mq_node(nid); + +- xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, +- XPC_NOTIFY_IRQ_NAME, +- xpc_handle_notify_IRQ_uv); +- if (IS_ERR(xpc_notify_mq_uv)) { +- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); +- return PTR_ERR(xpc_notify_mq_uv); +- } ++ if (!ret) ++ break; ++ } ++ else ++ ret = xpc_init_mq_node(xpc_mq_node); + +- return 0; ++ if (ret < 0) ++ dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", ++ -ret); ++ ++ return ret; + } + + void +@@ -1765,3 +1808,6 @@ xpc_exit_uv(void) + xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); + } ++ ++module_param(xpc_mq_node, int, 0); ++MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); +diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c +index e888202..01b104e 100644 +--- a/drivers/net/netconsole.c ++++ b/drivers/net/netconsole.c +@@ -652,7 +652,6 @@ static int netconsole_netdev_event(struct notifier_block *this, + flags); + dev_put(nt->np.dev); + nt->np.dev = NULL; +- netconsole_target_put(nt); + } + nt->enabled = 0; + stopped = true; +diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c +index e6d791c..b4cbc82 100644 +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -1782,7 +1782,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_hdr *hdr; + int retval; +- bool decrypt_error = false; + struct ath_rx_status rs; + enum ath9k_rx_qtype qtype; + bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); +@@ -1804,6 +1803,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) + tsf_lower = tsf & 0xffffffff; + + do { ++ bool decrypt_error = false; + /* If handling rx interrupt and flush is in progress => exit */ + if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) + break; +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index 9b60968..8a009bc 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb"); + * whenever you add a new device. + */ + +-static struct usb_device_id p54u_table[] __devinitdata = { ++static struct usb_device_id p54u_table[] = { + /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ + {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ +diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c +index 4a78f9e..4e98c39 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c +@@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); + MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); + MODULE_LICENSE("GPL"); + +-static struct usb_device_id rtl8187_table[] __devinitdata = { ++static struct usb_device_id rtl8187_table[] = { + /* Asus */ + {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, + /* Belkin */ +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index d024f83..68af94c 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -952,6 +952,13 @@ static int pci_pm_poweroff_noirq(struct device *dev) + if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) + pci_prepare_to_sleep(pci_dev); + ++ /* ++ * The reason for doing this here is the same as for the analogous code ++ * in pci_pm_suspend_noirq(). ++ */ ++ if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) ++ pci_write_config_word(pci_dev, PCI_COMMAND, 0); ++ + return 0; + } + +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index b0859d4..ec5b17f 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -86,6 +86,10 @@ static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, 0x8A, { KEY_PROG1 } }, + { KE_KEY, 0x95, { KEY_MEDIA } }, + { KE_KEY, 0x99, { KEY_PHONE } }, ++ { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ ++ { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ ++ { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ ++ { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ + { KE_KEY, 0xb5, { KEY_CALC } }, + { KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, + { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, +diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c +index 30d2072..33471e1 100644 +--- a/drivers/rapidio/devices/tsi721.c ++++ b/drivers/rapidio/devices/tsi721.c +@@ -439,6 +439,9 @@ static void tsi721_db_dpc(struct work_struct *work) + " info %4.4x\n", DBELL_SID(idb.bytes), + DBELL_TID(idb.bytes), DBELL_INF(idb.bytes)); + } ++ ++ wr_ptr = ioread32(priv->regs + ++ TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; + } + + iowrite32(rd_ptr & (IDB_QSIZE - 1), +@@ -449,6 +452,10 @@ static void tsi721_db_dpc(struct work_struct *work) + regval |= TSI721_SR_CHINT_IDBQRCV; + iowrite32(regval, + priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); ++ ++ wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; ++ if (wr_ptr != rd_ptr) ++ schedule_work(&priv->idb_work); + } + + /** +@@ -2155,7 +2162,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, + const struct pci_device_id *id) + { + struct tsi721_device *priv; +- int i, cap; ++ int cap; + int err; + u32 regval; + +@@ -2175,12 +2182,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, + priv->pdev = pdev; + + #ifdef DEBUG ++ { ++ int i; + for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { + dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n", + i, (unsigned long long)pci_resource_start(pdev, i), + (unsigned long)pci_resource_len(pdev, i), + pci_resource_flags(pdev, i)); + } ++ } + #endif + /* + * Verify BAR configuration +diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c +index 971bc8e..11bcb20 100644 +--- a/drivers/rtc/rtc-rs5c348.c ++++ b/drivers/rtc/rtc-rs5c348.c +@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) + tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); + tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); + if (!pdata->rtc_24h) { +- tm->tm_hour %= 12; +- if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) ++ if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { ++ tm->tm_hour -= 20; ++ tm->tm_hour %= 12; + tm->tm_hour += 12; ++ } else ++ tm->tm_hour %= 12; + } + tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); + tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); +diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c +index 8be5604..0d70f68 100644 +--- a/drivers/staging/speakup/main.c ++++ b/drivers/staging/speakup/main.c +@@ -1854,7 +1854,7 @@ static void speakup_bits(struct vc_data *vc) + + static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) + { +- static u_char *goto_buf = "\0\0\0\0\0\0"; ++ static u_char goto_buf[8]; + static int num; + int maxlen, go_pos; + char *cp; +diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c +index 27521b6..ae62d57 100644 +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -222,7 +222,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); + // Static vars definitions + // + +-static struct usb_device_id vt6656_table[] __devinitdata = { ++static struct usb_device_id vt6656_table[] = { + {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, + {} + }; +diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c +index f958eb4..3f0ce2b 100644 +--- a/drivers/staging/winbond/wbusb.c ++++ b/drivers/staging/winbond/wbusb.c +@@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); + MODULE_LICENSE("GPL"); + MODULE_VERSION("0.1"); + +-static const struct usb_device_id wb35_table[] __devinitconst = { ++static const struct usb_device_id wb35_table[] = { + { USB_DEVICE(0x0416, 0x0035) }, + { USB_DEVICE(0x18E8, 0x6201) }, + { USB_DEVICE(0x18E8, 0x6206) }, +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index 94c03d2..597fb9b 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -3509,9 +3509,9 @@ transport_generic_get_mem(struct se_cmd *cmd) + return 0; + + out: +- while (i >= 0) { +- __free_page(sg_page(&cmd->t_data_sg[i])); ++ while (i > 0) { + i--; ++ __free_page(sg_page(&cmd->t_data_sg[i])); + } + kfree(cmd->t_data_sg); + cmd->t_data_sg = NULL; +diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c +index 5acd24a..086f7fe 100644 +--- a/drivers/tty/serial/pmac_zilog.c ++++ b/drivers/tty/serial/pmac_zilog.c +@@ -1407,10 +1407,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) + static int pmz_poll_get_char(struct uart_port *port) + { + struct uart_pmac_port *uap = (struct uart_pmac_port *)port; ++ int tries = 2; + +- while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) +- udelay(5); +- return read_zsdata(uap); ++ while (tries) { ++ if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0) ++ return read_zsdata(uap); ++ if (tries--) ++ udelay(5); ++ } ++ ++ return NO_POLL_CHAR; + } + + static void pmz_poll_put_char(struct uart_port *port, unsigned char c) +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 1094469..dbf7d20 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1043,7 +1043,8 @@ skip_normal_probe: + } + + +- if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) ++ if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || ++ control_interface->cur_altsetting->desc.bNumEndpoints == 0) + return -EINVAL; + + epctrl = &control_interface->cur_altsetting->endpoint[0].desc; +diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c +index 4e1f0aa..9a2a1ae 100644 +--- a/drivers/usb/gadget/u_ether.c ++++ b/drivers/usb/gadget/u_ether.c +@@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net) + spin_lock_irqsave(&dev->lock, flags); + if (dev->port_usb) { + struct gether *link = dev->port_usb; ++ const struct usb_endpoint_descriptor *in; ++ const struct usb_endpoint_descriptor *out; + + if (link->close) + link->close(link); +@@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net) + * their own pace; the network stack can handle old packets. + * For the moment we leave this here, since it works. + */ ++ in = link->in_ep->desc; ++ out = link->out_ep->desc; + usb_ep_disable(link->in_ep); + usb_ep_disable(link->out_ep); + if (netif_carrier_ok(net)) { + DBG(dev, "host still using in/out endpoints\n"); ++ link->in_ep->desc = in; ++ link->out_ep->desc = out; + usb_ep_enable(link->in_ep); + usb_ep_enable(link->out_ep); + } +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index daf5754..07c72a4 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -95,6 +95,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + pdev->device == PCI_DEVICE_ID_ASROCK_P67) { + xhci->quirks |= XHCI_RESET_ON_RESUME; + xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); ++ xhci->quirks |= XHCI_TRUST_TX_LENGTH; + } + if (pdev->vendor == PCI_VENDOR_ID_VIA) + xhci->quirks |= XHCI_RESET_ON_RESUME; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 05f82e9..f7c0a2a 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -163,7 +163,7 @@ int xhci_reset(struct xhci_hcd *xhci) + xhci_writel(xhci, command, &xhci->op_regs->command); + + ret = handshake(xhci, &xhci->op_regs->command, +- CMD_RESET, 0, 250 * 1000); ++ CMD_RESET, 0, 10 * 1000 * 1000); + if (ret) + return ret; + +@@ -172,7 +172,8 @@ int xhci_reset(struct xhci_hcd *xhci) + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ +- return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); ++ return handshake(xhci, &xhci->op_regs->status, ++ STS_CNR, 0, 10 * 1000 * 1000); + } + + #ifdef CONFIG_PCI +diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c +index fc15ad4..723e833 100644 +--- a/drivers/usb/misc/emi62.c ++++ b/drivers/usb/misc/emi62.c +@@ -259,7 +259,7 @@ wraperr: + return err; + } + +-static const struct usb_device_id id_table[] __devinitconst = { ++static const struct usb_device_id id_table[] = { + { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, + { } /* Terminating entry */ + }; +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 4045e39..b3182bb 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -811,6 +811,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, + { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, + { USB_DEVICE(PI_VID, PI_E861_PID) }, ++ { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, + { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, + { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index d27d7d7..54b4258 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -795,6 +795,13 @@ + #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ + + /* ++ * Kondo Kagaku Co.Ltd. ++ * http://www.kondo-robot.com/EN ++ */ ++#define KONDO_VID 0x165c ++#define KONDO_USB_SERIAL_PID 0x0002 ++ ++/* + * Bayer Ascensia Contour blood glucose meter USB-converter cable. + * http://winglucofacts.com/cables/ + */ +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index 5c7d654..b150ed9 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -1191,9 +1191,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) + } + + spin_lock_irqsave(&mos7840_port->pool_lock, flags); +- for (i = 0; i < NUM_URBS; ++i) +- if (mos7840_port->busy[i]) +- chars += URB_TRANSFER_BUFFER_SIZE; ++ for (i = 0; i < NUM_URBS; ++i) { ++ if (mos7840_port->busy[i]) { ++ struct urb *urb = mos7840_port->write_urb_pool[i]; ++ chars += urb->transfer_buffer_length; ++ } ++ } + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + dbg("%s - returns %d", __func__, chars); + return chars; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index d89aac1..113560d 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -80,84 +80,9 @@ static void option_instat_callback(struct urb *urb); + #define OPTION_PRODUCT_GTM380_MODEM 0x7201 + + #define HUAWEI_VENDOR_ID 0x12D1 +-#define HUAWEI_PRODUCT_E600 0x1001 +-#define HUAWEI_PRODUCT_E220 0x1003 +-#define HUAWEI_PRODUCT_E220BIS 0x1004 +-#define HUAWEI_PRODUCT_E1401 0x1401 +-#define HUAWEI_PRODUCT_E1402 0x1402 +-#define HUAWEI_PRODUCT_E1403 0x1403 +-#define HUAWEI_PRODUCT_E1404 0x1404 +-#define HUAWEI_PRODUCT_E1405 0x1405 +-#define HUAWEI_PRODUCT_E1406 0x1406 +-#define HUAWEI_PRODUCT_E1407 0x1407 +-#define HUAWEI_PRODUCT_E1408 0x1408 +-#define HUAWEI_PRODUCT_E1409 0x1409 +-#define HUAWEI_PRODUCT_E140A 0x140A +-#define HUAWEI_PRODUCT_E140B 0x140B +-#define HUAWEI_PRODUCT_E140C 0x140C +-#define HUAWEI_PRODUCT_E140D 0x140D +-#define HUAWEI_PRODUCT_E140E 0x140E +-#define HUAWEI_PRODUCT_E140F 0x140F +-#define HUAWEI_PRODUCT_E1410 0x1410 +-#define HUAWEI_PRODUCT_E1411 0x1411 +-#define HUAWEI_PRODUCT_E1412 0x1412 +-#define HUAWEI_PRODUCT_E1413 0x1413 +-#define HUAWEI_PRODUCT_E1414 0x1414 +-#define HUAWEI_PRODUCT_E1415 0x1415 +-#define HUAWEI_PRODUCT_E1416 0x1416 +-#define HUAWEI_PRODUCT_E1417 0x1417 +-#define HUAWEI_PRODUCT_E1418 0x1418 +-#define HUAWEI_PRODUCT_E1419 0x1419 +-#define HUAWEI_PRODUCT_E141A 0x141A +-#define HUAWEI_PRODUCT_E141B 0x141B +-#define HUAWEI_PRODUCT_E141C 0x141C +-#define HUAWEI_PRODUCT_E141D 0x141D +-#define HUAWEI_PRODUCT_E141E 0x141E +-#define HUAWEI_PRODUCT_E141F 0x141F +-#define HUAWEI_PRODUCT_E1420 0x1420 +-#define HUAWEI_PRODUCT_E1421 0x1421 +-#define HUAWEI_PRODUCT_E1422 0x1422 +-#define HUAWEI_PRODUCT_E1423 0x1423 +-#define HUAWEI_PRODUCT_E1424 0x1424 +-#define HUAWEI_PRODUCT_E1425 0x1425 +-#define HUAWEI_PRODUCT_E1426 0x1426 +-#define HUAWEI_PRODUCT_E1427 0x1427 +-#define HUAWEI_PRODUCT_E1428 0x1428 +-#define HUAWEI_PRODUCT_E1429 0x1429 +-#define HUAWEI_PRODUCT_E142A 0x142A +-#define HUAWEI_PRODUCT_E142B 0x142B +-#define HUAWEI_PRODUCT_E142C 0x142C +-#define HUAWEI_PRODUCT_E142D 0x142D +-#define HUAWEI_PRODUCT_E142E 0x142E +-#define HUAWEI_PRODUCT_E142F 0x142F +-#define HUAWEI_PRODUCT_E1430 0x1430 +-#define HUAWEI_PRODUCT_E1431 0x1431 +-#define HUAWEI_PRODUCT_E1432 0x1432 +-#define HUAWEI_PRODUCT_E1433 0x1433 +-#define HUAWEI_PRODUCT_E1434 0x1434 +-#define HUAWEI_PRODUCT_E1435 0x1435 +-#define HUAWEI_PRODUCT_E1436 0x1436 +-#define HUAWEI_PRODUCT_E1437 0x1437 +-#define HUAWEI_PRODUCT_E1438 0x1438 +-#define HUAWEI_PRODUCT_E1439 0x1439 +-#define HUAWEI_PRODUCT_E143A 0x143A +-#define HUAWEI_PRODUCT_E143B 0x143B +-#define HUAWEI_PRODUCT_E143C 0x143C +-#define HUAWEI_PRODUCT_E143D 0x143D +-#define HUAWEI_PRODUCT_E143E 0x143E +-#define HUAWEI_PRODUCT_E143F 0x143F + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 +-#define HUAWEI_PRODUCT_E14AC 0x14AC +-#define HUAWEI_PRODUCT_K3806 0x14AE + #define HUAWEI_PRODUCT_K4605 0x14C6 +-#define HUAWEI_PRODUCT_K3770 0x14C9 +-#define HUAWEI_PRODUCT_K3771 0x14CA +-#define HUAWEI_PRODUCT_K4510 0x14CB +-#define HUAWEI_PRODUCT_K4511 0x14CC +-#define HUAWEI_PRODUCT_ETS1220 0x1803 +-#define HUAWEI_PRODUCT_E353 0x1506 +-#define HUAWEI_PRODUCT_E173S 0x1C05 + + #define QUANTA_VENDOR_ID 0x0408 + #define QUANTA_PRODUCT_Q101 0xEA02 +@@ -614,101 +539,123 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, ++ ++ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index 8745637..bf9a9b7 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -373,8 +373,15 @@ static void fb_flashcursor(struct work_struct *work) + struct vc_data *vc = NULL; + int c; + int mode; ++ int ret; ++ ++ /* FIXME: we should sort out the unbind locking instead */ ++ /* instead we just fail to flash the cursor if we can't get ++ * the lock instead of blocking fbcon deinit */ ++ ret = console_trylock(); ++ if (ret == 0) ++ return; + +- console_lock(); + if (ops && ops->currcon != -1) + vc = vc_cons[ops->currcon].d; + +diff --git a/fs/buffer.c b/fs/buffer.c +index 4115eca..19a4f0b 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -964,7 +964,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head) + /* + * Initialise the state of a blockdev page's buffers. + */ +-static void ++static sector_t + init_page_buffers(struct page *page, struct block_device *bdev, + sector_t block, int size) + { +@@ -986,33 +986,41 @@ init_page_buffers(struct page *page, struct block_device *bdev, + block++; + bh = bh->b_this_page; + } while (bh != head); ++ ++ /* ++ * Caller needs to validate requested block against end of device. ++ */ ++ return end_block; + } + + /* + * Create the page-cache page that contains the requested block. + * +- * This is user purely for blockdev mappings. ++ * This is used purely for blockdev mappings. + */ +-static struct page * ++static int + grow_dev_page(struct block_device *bdev, sector_t block, +- pgoff_t index, int size) ++ pgoff_t index, int size, int sizebits) + { + struct inode *inode = bdev->bd_inode; + struct page *page; + struct buffer_head *bh; ++ sector_t end_block; ++ int ret = 0; /* Will call free_more_memory() */ + + page = find_or_create_page(inode->i_mapping, index, + (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); + if (!page) +- return NULL; ++ return ret; + + BUG_ON(!PageLocked(page)); + + if (page_has_buffers(page)) { + bh = page_buffers(page); + if (bh->b_size == size) { +- init_page_buffers(page, bdev, block, size); +- return page; ++ end_block = init_page_buffers(page, bdev, ++ index << sizebits, size); ++ goto done; + } + if (!try_to_free_buffers(page)) + goto failed; +@@ -1032,15 +1040,14 @@ grow_dev_page(struct block_device *bdev, sector_t block, + */ + spin_lock(&inode->i_mapping->private_lock); + link_dev_buffers(page, bh); +- init_page_buffers(page, bdev, block, size); ++ end_block = init_page_buffers(page, bdev, index << sizebits, size); + spin_unlock(&inode->i_mapping->private_lock); +- return page; +- ++done: ++ ret = (block < end_block) ? 1 : -ENXIO; + failed: +- BUG(); + unlock_page(page); + page_cache_release(page); +- return NULL; ++ return ret; + } + + /* +@@ -1050,7 +1057,6 @@ failed: + static int + grow_buffers(struct block_device *bdev, sector_t block, int size) + { +- struct page *page; + pgoff_t index; + int sizebits; + +@@ -1074,22 +1080,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) + bdevname(bdev, b)); + return -EIO; + } +- block = index << sizebits; ++ + /* Create a page with the proper size buffers.. */ +- page = grow_dev_page(bdev, block, index, size); +- if (!page) +- return 0; +- unlock_page(page); +- page_cache_release(page); +- return 1; ++ return grow_dev_page(bdev, block, index, size, sizebits); + } + + static struct buffer_head * + __getblk_slow(struct block_device *bdev, sector_t block, int size) + { +- int ret; +- struct buffer_head *bh; +- + /* Size must be multiple of hard sectorsize */ + if (unlikely(size & (bdev_logical_block_size(bdev)-1) || + (size < 512 || size > PAGE_SIZE))) { +@@ -1102,21 +1100,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) + return NULL; + } + +-retry: +- bh = __find_get_block(bdev, block, size); +- if (bh) +- return bh; ++ for (;;) { ++ struct buffer_head *bh; ++ int ret; + +- ret = grow_buffers(bdev, block, size); +- if (ret == 0) { +- free_more_memory(); +- goto retry; +- } else if (ret > 0) { + bh = __find_get_block(bdev, block, size); + if (bh) + return bh; ++ ++ ret = grow_buffers(bdev, block, size); ++ if (ret < 0) ++ return NULL; ++ if (ret == 0) ++ free_more_memory(); + } +- return NULL; + } + + /* +@@ -1372,10 +1369,6 @@ EXPORT_SYMBOL(__find_get_block); + * which corresponds to the passed block_device, block and size. The + * returned buffer has its reference count incremented. + * +- * __getblk() cannot fail - it just keeps trying. If you pass it an +- * illegal block number, __getblk() will happily return a buffer_head +- * which represents the non-existent block. Very weird. +- * + * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers() + * attempt is failing. FIXME, perhaps? + */ +diff --git a/fs/compat.c b/fs/compat.c +index c987875..e07a3d3 100644 +--- a/fs/compat.c ++++ b/fs/compat.c +@@ -1174,11 +1174,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, + struct file *file; + int fput_needed; + ssize_t ret; ++ loff_t pos; + + file = fget_light(fd, &fput_needed); + if (!file) + return -EBADF; +- ret = compat_readv(file, vec, vlen, &file->f_pos); ++ pos = file->f_pos; ++ ret = compat_readv(file, vec, vlen, &pos); ++ file->f_pos = pos; + fput_light(file, fput_needed); + return ret; + } +@@ -1233,11 +1236,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, + struct file *file; + int fput_needed; + ssize_t ret; ++ loff_t pos; + + file = fget_light(fd, &fput_needed); + if (!file) + return -EBADF; +- ret = compat_writev(file, vec, vlen, &file->f_pos); ++ pos = file->f_pos; ++ ret = compat_writev(file, vec, vlen, &pos); ++ file->f_pos = pos; + fput_light(file, fput_needed); + return ret; + } +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index a071348..f8d5fce 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -904,6 +904,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) + ei->i_reserved_meta_blocks = 0; + ei->i_allocated_meta_blocks = 0; + ei->i_da_metadata_calc_len = 0; ++ ei->i_da_metadata_calc_last_lblock = 0; + spin_lock_init(&(ei->i_block_reservation_lock)); + #ifdef CONFIG_QUOTA + ei->i_reserved_quota = 0; +@@ -3107,6 +3108,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp, + ext4_group_t i, ngroups = ext4_get_groups_count(sb); + int s, j, count = 0; + ++ if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) ++ return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) + ++ sbi->s_itb_per_group + 2); ++ + first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + + (grp * EXT4_BLOCKS_PER_GROUP(sb)); + last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 0c84100..5242006 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1687,7 +1687,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) + size_t n; + u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; + +- for (n = 0; n < count; n++) { ++ for (n = 0; n < count; n++, iov++) { + if (iov->iov_len > (size_t) max) + return -ENOMEM; + max -= iov->iov_len; +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index 3db6b82..d774309 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -38,6 +38,8 @@ + #include <linux/buffer_head.h> /* various write calls */ + #include <linux/prefetch.h> + ++#include "../pnfs.h" ++#include "../internal.h" + #include "blocklayout.h" + + #define NFSDBG_FACILITY NFSDBG_PNFS_LD +@@ -814,7 +816,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh, + * GETDEVICEINFO's maxcount + */ + max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; +- max_pages = max_resp_sz >> PAGE_SHIFT; ++ max_pages = nfs_page_array_len(0, max_resp_sz); + dprintk("%s max_resp_sz %u max_pages %d\n", + __func__, max_resp_sz, max_pages); + +diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c +index c69682a..4e2ee99 100644 +--- a/fs/nfs/blocklayout/extents.c ++++ b/fs/nfs/blocklayout/extents.c +@@ -153,7 +153,7 @@ static int _preload_range(struct pnfs_inval_markings *marks, + count = (int)(end - start) / (int)tree->mtt_step_size; + + /* Pre-malloc what memory we might need */ +- storage = kmalloc(sizeof(*storage) * count, GFP_NOFS); ++ storage = kcalloc(count, sizeof(*storage), GFP_NOFS); + if (!storage) + return -ENOMEM; + for (i = 0; i < count; i++) { +diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c +index ac28990..756f4df 100644 +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1103,7 +1103,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) + struct nfs_fattr *fattr = NULL; + int error; + +- if (nd->flags & LOOKUP_RCU) ++ if (nd && (nd->flags & LOOKUP_RCU)) + return -ECHILD; + + parent = dget_parent(dentry); +@@ -1508,7 +1508,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) + struct nfs_open_context *ctx; + int openflags, ret = 0; + +- if (nd->flags & LOOKUP_RCU) ++ if (nd && (nd->flags & LOOKUP_RCU)) + return -ECHILD; + + inode = dentry->d_inode; +diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c +index d4bc9ed9..5195fd6 100644 +--- a/fs/nfs/nfs3proc.c ++++ b/fs/nfs/nfs3proc.c +@@ -68,7 +68,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, + nfs_fattr_init(info->fattr); + status = rpc_call_sync(client, &msg, 0); + dprintk("%s: reply fsinfo: %d\n", __func__, status); +- if (!(info->fattr->valid & NFS_ATTR_FATTR)) { ++ if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) { + msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; + msg.rpc_resp = info->fattr; + status = rpc_call_sync(client, &msg, 0); +diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c +index ed388aa..bd5d9cf 100644 +--- a/fs/nfs/nfs4filelayoutdev.c ++++ b/fs/nfs/nfs4filelayoutdev.c +@@ -721,7 +721,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla + * GETDEVICEINFO's maxcount + */ + max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; +- max_pages = max_resp_sz >> PAGE_SHIFT; ++ max_pages = nfs_page_array_len(0, max_resp_sz); + dprintk("%s inode %p max_resp_sz %u max_pages %d\n", + __func__, inode, max_resp_sz, max_pages); + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 8000459..d20221d 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5769,11 +5769,58 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) + dprintk("<-- %s\n", __func__); + } + ++static size_t max_response_pages(struct nfs_server *server) ++{ ++ u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; ++ return nfs_page_array_len(0, max_resp_sz); ++} ++ ++static void nfs4_free_pages(struct page **pages, size_t size) ++{ ++ int i; ++ ++ if (!pages) ++ return; ++ ++ for (i = 0; i < size; i++) { ++ if (!pages[i]) ++ break; ++ __free_page(pages[i]); ++ } ++ kfree(pages); ++} ++ ++static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) ++{ ++ struct page **pages; ++ int i; ++ ++ pages = kcalloc(size, sizeof(struct page *), gfp_flags); ++ if (!pages) { ++ dprintk("%s: can't alloc array of %zu pages\n", __func__, size); ++ return NULL; ++ } ++ ++ for (i = 0; i < size; i++) { ++ pages[i] = alloc_page(gfp_flags); ++ if (!pages[i]) { ++ dprintk("%s: failed to allocate page\n", __func__); ++ nfs4_free_pages(pages, size); ++ return NULL; ++ } ++ } ++ ++ return pages; ++} ++ + static void nfs4_layoutget_release(void *calldata) + { + struct nfs4_layoutget *lgp = calldata; ++ struct nfs_server *server = NFS_SERVER(lgp->args.inode); ++ size_t max_pages = max_response_pages(server); + + dprintk("--> %s\n", __func__); ++ nfs4_free_pages(lgp->args.layout.pages, max_pages); + put_nfs_open_context(lgp->args.ctx); + kfree(calldata); + dprintk("<-- %s\n", __func__); +@@ -5785,9 +5832,10 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = { + .rpc_release = nfs4_layoutget_release, + }; + +-int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) ++int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) + { + struct nfs_server *server = NFS_SERVER(lgp->args.inode); ++ size_t max_pages = max_response_pages(server); + struct rpc_task *task; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], +@@ -5805,6 +5853,13 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) + + dprintk("--> %s\n", __func__); + ++ lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); ++ if (!lgp->args.layout.pages) { ++ nfs4_layoutget_release(lgp); ++ return -ENOMEM; ++ } ++ lgp->args.layout.pglen = max_pages * PAGE_SIZE; ++ + lgp->res.layoutp = &lgp->args.layout; + lgp->res.seq_res.sr_slot = NULL; + task = rpc_run_task(&task_setup_data); +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index f881a63..3ad6595 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -575,9 +575,6 @@ send_layoutget(struct pnfs_layout_hdr *lo, + struct nfs_server *server = NFS_SERVER(ino); + struct nfs4_layoutget *lgp; + struct pnfs_layout_segment *lseg = NULL; +- struct page **pages = NULL; +- int i; +- u32 max_resp_sz, max_pages; + + dprintk("--> %s\n", __func__); + +@@ -586,20 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *lo, + if (lgp == NULL) + return NULL; + +- /* allocate pages for xdr post processing */ +- max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; +- max_pages = max_resp_sz >> PAGE_SHIFT; +- +- pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags); +- if (!pages) +- goto out_err_free; +- +- for (i = 0; i < max_pages; i++) { +- pages[i] = alloc_page(gfp_flags); +- if (!pages[i]) +- goto out_err_free; +- } +- + lgp->args.minlength = PAGE_CACHE_SIZE; + if (lgp->args.minlength > range->length) + lgp->args.minlength = range->length; +@@ -608,39 +591,19 @@ send_layoutget(struct pnfs_layout_hdr *lo, + lgp->args.type = server->pnfs_curr_ld->id; + lgp->args.inode = ino; + lgp->args.ctx = get_nfs_open_context(ctx); +- lgp->args.layout.pages = pages; +- lgp->args.layout.pglen = max_pages * PAGE_SIZE; + lgp->lsegpp = &lseg; + lgp->gfp_flags = gfp_flags; + + /* Synchronously retrieve layout information from server and + * store in lseg. + */ +- nfs4_proc_layoutget(lgp); ++ nfs4_proc_layoutget(lgp, gfp_flags); + if (!lseg) { + /* remember that LAYOUTGET failed and suspend trying */ + set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); + } + +- /* free xdr pages */ +- for (i = 0; i < max_pages; i++) +- __free_page(pages[i]); +- kfree(pages); +- + return lseg; +- +-out_err_free: +- /* free any allocated xdr pages, lgp as it's not used */ +- if (pages) { +- for (i = 0; i < max_pages; i++) { +- if (!pages[i]) +- break; +- __free_page(pages[i]); +- } +- kfree(pages); +- } +- kfree(lgp); +- return NULL; + } + + /* Initiates a LAYOUTRETURN(FILE) */ +diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h +index 53d593a..c946b1b 100644 +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -162,7 +162,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server, + struct pnfs_devicelist *devlist); + extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, + struct pnfs_device *dev); +-extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); ++extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); + extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); + + /* pnfs.c */ +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index 376cd65..6e85ec6 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -3087,4 +3087,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, + return res; + } + ++MODULE_ALIAS("nfs4"); ++ + #endif /* CONFIG_NFS_V4 */ +diff --git a/fs/nfs/write.c b/fs/nfs/write.c +index c6e523a..301391a 100644 +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1742,12 +1742,12 @@ int __init nfs_init_writepagecache(void) + nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, + nfs_wdata_cachep); + if (nfs_wdata_mempool == NULL) +- return -ENOMEM; ++ goto out_destroy_write_cache; + + nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, + nfs_wdata_cachep); + if (nfs_commit_mempool == NULL) +- return -ENOMEM; ++ goto out_destroy_write_mempool; + + /* + * NFS congestion size, scale with available memory. +@@ -1770,6 +1770,12 @@ int __init nfs_init_writepagecache(void) + nfs_congestion_kb = 256*1024; + + return 0; ++ ++out_destroy_write_mempool: ++ mempool_destroy(nfs_wdata_mempool); ++out_destroy_write_cache: ++ kmem_cache_destroy(nfs_wdata_cachep); ++ return -ENOMEM; + } + + void nfs_destroy_writepagecache(void) +diff --git a/fs/open.c b/fs/open.c +index e2b5d51..b8485d3 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -882,9 +882,10 @@ static inline int build_open_flags(int flags, int mode, struct open_flags *op) + int lookup_flags = 0; + int acc_mode; + +- if (!(flags & O_CREAT)) +- mode = 0; +- op->mode = mode; ++ if (flags & O_CREAT) ++ op->mode = (mode & S_IALLUGO) | S_IFREG; ++ else ++ op->mode = 0; + + /* Must never be set by userspace */ + flags &= ~FMODE_NONOTIFY; +diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c +index 2da1715..4619247 100644 +--- a/fs/squashfs/super.c ++++ b/fs/squashfs/super.c +@@ -290,7 +290,7 @@ handle_fragments: + + check_directory_table: + /* Sanity check directory_table */ +- if (msblk->directory_table >= next_table) { ++ if (msblk->directory_table > next_table) { + err = -EINVAL; + goto failed_mount; + } +diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h +index 580a6d3..c04e0db 100644 +--- a/include/asm-generic/mutex-xchg.h ++++ b/include/asm-generic/mutex-xchg.h +@@ -26,7 +26,13 @@ static inline void + __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) + { + if (unlikely(atomic_xchg(count, 0) != 1)) +- fail_fn(count); ++ /* ++ * We failed to acquire the lock, so mark it contended ++ * to ensure that any waiting tasks are woken up by the ++ * unlock slow path. ++ */ ++ if (likely(atomic_xchg(count, -1) != 1)) ++ fail_fn(count); + } + + /** +@@ -43,7 +49,8 @@ static inline int + __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) + { + if (unlikely(atomic_xchg(count, 0) != 1)) +- return fail_fn(count); ++ if (likely(atomic_xchg(count, -1) != 1)) ++ return fail_fn(count); + return 0; + } + +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 4269c3f..93629fc 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -775,6 +775,27 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) + .bInterfaceSubClass = (sc), \ + .bInterfaceProtocol = (pr) + ++/** ++ * USB_VENDOR_AND_INTERFACE_INFO - describe a specific usb vendor with a class of usb interfaces ++ * @vend: the 16 bit USB Vendor ID ++ * @cl: bInterfaceClass value ++ * @sc: bInterfaceSubClass value ++ * @pr: bInterfaceProtocol value ++ * ++ * This macro is used to create a struct usb_device_id that matches a ++ * specific vendor with a specific class of interfaces. ++ * ++ * This is especially useful when explicitly matching devices that have ++ * vendor specific bDeviceClass values, but standards-compliant interfaces. ++ */ ++#define USB_VENDOR_AND_INTERFACE_INFO(vend, cl, sc, pr) \ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ ++ | USB_DEVICE_ID_MATCH_VENDOR, \ ++ .idVendor = (vend), \ ++ .bInterfaceClass = (cl), \ ++ .bInterfaceSubClass = (sc), \ ++ .bInterfaceProtocol = (pr) ++ + /* ----------------------------------------------------------------------- */ + + /* Stuff for dynamic usb ids */ +diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c +index 5bf0790..31fdc48 100644 +--- a/kernel/audit_tree.c ++++ b/kernel/audit_tree.c +@@ -250,7 +250,6 @@ static void untag_chunk(struct node *p) + spin_unlock(&hash_lock); + spin_unlock(&entry->lock); + fsnotify_destroy_mark(entry); +- fsnotify_put_mark(entry); + goto out; + } + +@@ -259,7 +258,7 @@ static void untag_chunk(struct node *p) + + fsnotify_duplicate_mark(&new->mark, entry); + if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { +- free_chunk(new); ++ fsnotify_put_mark(&new->mark); + goto Fallback; + } + +@@ -293,7 +292,6 @@ static void untag_chunk(struct node *p) + spin_unlock(&hash_lock); + spin_unlock(&entry->lock); + fsnotify_destroy_mark(entry); +- fsnotify_put_mark(entry); + goto out; + + Fallback: +@@ -322,7 +320,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) + + entry = &chunk->mark; + if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) { +- free_chunk(chunk); ++ fsnotify_put_mark(entry); + return -ENOSPC; + } + +@@ -332,6 +330,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) + spin_unlock(&hash_lock); + chunk->dead = 1; + spin_unlock(&entry->lock); ++ fsnotify_get_mark(entry); + fsnotify_destroy_mark(entry); + fsnotify_put_mark(entry); + return 0; +@@ -396,7 +395,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) + fsnotify_duplicate_mark(chunk_entry, old_entry); + if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) { + spin_unlock(&old_entry->lock); +- free_chunk(chunk); ++ fsnotify_put_mark(chunk_entry); + fsnotify_put_mark(old_entry); + return -ENOSPC; + } +@@ -412,6 +411,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) + spin_unlock(&chunk_entry->lock); + spin_unlock(&old_entry->lock); + ++ fsnotify_get_mark(chunk_entry); + fsnotify_destroy_mark(chunk_entry); + + fsnotify_put_mark(chunk_entry); +@@ -445,7 +445,6 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) + spin_unlock(&old_entry->lock); + fsnotify_destroy_mark(old_entry); + fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ +- fsnotify_put_mark(old_entry); /* and kill it */ + return 0; + } + +diff --git a/kernel/sched.c b/kernel/sched.c +index e0431c4..910db7d 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -4355,6 +4355,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) + # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) + #endif + ++static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total) ++{ ++ u64 temp = (__force u64) rtime; ++ ++ temp *= (__force u64) utime; ++ ++ if (sizeof(cputime_t) == 4) ++ temp = div_u64(temp, (__force u32) total); ++ else ++ temp = div64_u64(temp, (__force u64) total); ++ ++ return (__force cputime_t) temp; ++} ++ + void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) + { + cputime_t rtime, utime = p->utime, total = cputime_add(utime, p->stime); +@@ -4364,13 +4378,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) + */ + rtime = nsecs_to_cputime(p->se.sum_exec_runtime); + +- if (total) { +- u64 temp = rtime; +- +- temp *= utime; +- do_div(temp, total); +- utime = (cputime_t)temp; +- } else ++ if (total) ++ utime = scale_utime(utime, rtime, total); ++ else + utime = rtime; + + /* +@@ -4397,13 +4407,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) + total = cputime_add(cputime.utime, cputime.stime); + rtime = nsecs_to_cputime(cputime.sum_exec_runtime); + +- if (total) { +- u64 temp = rtime; +- +- temp *= cputime.utime; +- do_div(temp, total); +- utime = (cputime_t)temp; +- } else ++ if (total) ++ utime = scale_utime(cputime.utime, rtime, total); ++ else + utime = rtime; + + sig->prev_utime = max(sig->prev_utime, utime); +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 48febd7..86eb848 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -1977,10 +1977,10 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, + * proportional to the fraction of recently scanned pages on + * each list that were recently referenced and in active use. + */ +- ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1); ++ ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1); + ap /= reclaim_stat->recent_rotated[0] + 1; + +- fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1); ++ fp = file_prio * (reclaim_stat->recent_scanned[1] + 1); + fp /= reclaim_stat->recent_rotated[1] + 1; + spin_unlock_irq(&zone->lru_lock); + +@@ -1993,7 +1993,7 @@ out: + unsigned long scan; + + scan = zone_nr_lru_pages(zone, sc, l); +- if (priority || noswap) { ++ if (priority || noswap || !vmscan_swappiness(sc)) { + scan >>= priority; + if (!scan && force_scan) + scan = SWAP_CLUSTER_MAX; +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 643a41b..6033f02 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -1411,7 +1411,13 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s + if (conn->type == ACL_LINK) { + conn->state = BT_CONFIG; + hci_conn_hold(conn); +- conn->disc_timeout = HCI_DISCONN_TIMEOUT; ++ ++ if (!conn->out && ++ !(conn->ssp_mode && conn->hdev->ssp_mode) && ++ !hci_find_link_key(hdev, &ev->bdaddr)) ++ conn->disc_timeout = HCI_PAIRING_TIMEOUT; ++ else ++ conn->disc_timeout = HCI_DISCONN_TIMEOUT; + mgmt_connected(hdev->id, &ev->bdaddr, conn->type); + } else + conn->state = BT_CONNECTED; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 17b5b1c..dd76177 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -862,6 +862,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) + write_lock_bh(&conn->chan_lock); + + hci_conn_hold(conn->hcon); ++ conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; + + bacpy(&bt_sk(sk)->src, conn->src); + bacpy(&bt_sk(sk)->dst, conn->dst); +@@ -2263,12 +2264,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) + while (len >= L2CAP_CONF_OPT_SIZE) { + len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); + +- switch (type) { +- case L2CAP_CONF_RFC: +- if (olen == sizeof(rfc)) +- memcpy(&rfc, (void *)val, olen); +- goto done; +- } ++ if (type != L2CAP_CONF_RFC) ++ continue; ++ ++ if (olen != sizeof(rfc)) ++ break; ++ ++ memcpy(&rfc, (void *)val, olen); ++ goto done; + } + + /* Use sane default values in case a misbehaving remote device +diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h +index 75c3582..fb85d37 100644 +--- a/net/dccp/ccid.h ++++ b/net/dccp/ccid.h +@@ -246,7 +246,7 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk, + u32 __user *optval, int __user *optlen) + { + int rc = -ENOPROTOOPT; +- if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) ++ if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) + rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len, + optval, optlen); + return rc; +@@ -257,7 +257,7 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk, + u32 __user *optval, int __user *optlen) + { + int rc = -ENOPROTOOPT; +- if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) ++ if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) + rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len, + optval, optlen); + return rc; +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index 9ed2cd0..3282453 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -315,7 +315,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt) + */ + void svc_xprt_enqueue(struct svc_xprt *xprt) + { +- struct svc_serv *serv = xprt->xpt_server; + struct svc_pool *pool; + struct svc_rqst *rqstp; + int cpu; +@@ -361,8 +360,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) + rqstp, rqstp->rq_xprt); + rqstp->rq_xprt = xprt; + svc_xprt_get(xprt); +- rqstp->rq_reserved = serv->sv_max_mesg; +- atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); + pool->sp_stats.threads_woken++; + wake_up(&rqstp->rq_wait); + } else { +@@ -642,8 +639,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) + if (xprt) { + rqstp->rq_xprt = xprt; + svc_xprt_get(xprt); +- rqstp->rq_reserved = serv->sv_max_mesg; +- atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); + + /* As there is a shortage of threads and this request + * had to be queued, don't allow the thread to wait so +@@ -740,6 +735,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) + else + len = xprt->xpt_ops->xpo_recvfrom(rqstp); + dprintk("svc: got len=%d\n", len); ++ rqstp->rq_reserved = serv->sv_max_mesg; ++ atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); + } + svc_xprt_received(xprt); + +@@ -796,7 +793,8 @@ int svc_send(struct svc_rqst *rqstp) + + /* Grab mutex to serialize outgoing data. */ + mutex_lock(&xprt->xpt_mutex); +- if (test_bit(XPT_DEAD, &xprt->xpt_flags)) ++ if (test_bit(XPT_DEAD, &xprt->xpt_flags) ++ || test_bit(XPT_CLOSE, &xprt->xpt_flags)) + len = -ENOTCONN; + else + len = xprt->xpt_ops->xpo_sendto(rqstp); +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index 71bed1c..296192c 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -1136,9 +1136,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) + if (len >= 0) + svsk->sk_tcplen += len; + if (len != want) { ++ svc_tcp_save_pages(svsk, rqstp); + if (len < 0 && len != -EAGAIN) + goto err_other; +- svc_tcp_save_pages(svsk, rqstp); + dprintk("svc: incomplete TCP record (%d of %d)\n", + svsk->sk_tcplen, svsk->sk_reclen); + goto err_noclose; +diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c +index 254ab52..2210b83 100644 +--- a/sound/pci/hda/hda_proc.c ++++ b/sound/pci/hda/hda_proc.c +@@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer, + if (digi1 & AC_DIG1_EMPHASIS) + snd_iprintf(buffer, " Preemphasis"); + if (digi1 & AC_DIG1_COPYRIGHT) +- snd_iprintf(buffer, " Copyright"); ++ snd_iprintf(buffer, " Non-Copyright"); + if (digi1 & AC_DIG1_NONAUDIO) + snd_iprintf(buffer, " Non-Audio"); + if (digi1 & AC_DIG1_PROFESSIONAL) +diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c +index 35abe3c..b22989e 100644 +--- a/sound/pci/hda/patch_ca0132.c ++++ b/sound/pci/hda/patch_ca0132.c +@@ -276,6 +276,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, + int type = dir ? HDA_INPUT : HDA_OUTPUT; + struct snd_kcontrol_new knew = + HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); ++ if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) { ++ snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid); ++ return 0; ++ } + sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); + return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); + } +@@ -287,6 +291,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, + int type = dir ? HDA_INPUT : HDA_OUTPUT; + struct snd_kcontrol_new knew = + HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); ++ if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) { ++ snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid); ++ return 0; ++ } + sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); + return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); + } +diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c +index 90117f8..90e5005 100644 +--- a/sound/soc/codecs/wm9712.c ++++ b/sound/soc/codecs/wm9712.c +@@ -270,7 +270,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]); + + /* Mic select */ + static const struct snd_kcontrol_new wm9712_mic_src_controls = +-SOC_DAPM_ENUM("Route", wm9712_enum[7]); ++SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]); + + /* diff select */ + static const struct snd_kcontrol_new wm9712_diff_sel_controls = +@@ -289,7 +289,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0, + &wm9712_capture_selectl_controls), + SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, + &wm9712_capture_selectr_controls), +-SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0, ++SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0, ++ &wm9712_mic_src_controls), ++SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0, + &wm9712_mic_src_controls), + SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, + &wm9712_diff_sel_controls), +@@ -317,6 +319,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0), + SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), + SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), + SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), ++SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), + SND_SOC_DAPM_OUTPUT("MONOOUT"), + SND_SOC_DAPM_OUTPUT("HPOUTL"), +@@ -377,6 +380,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { + {"Mic PGA", NULL, "MIC1"}, + {"Mic PGA", NULL, "MIC2"}, + ++ /* microphones */ ++ {"Differential Mic", NULL, "MIC1"}, ++ {"Differential Mic", NULL, "MIC2"}, ++ {"Left Mic Select Source", "Mic 1", "MIC1"}, ++ {"Left Mic Select Source", "Mic 2", "MIC2"}, ++ {"Left Mic Select Source", "Stereo", "MIC1"}, ++ {"Left Mic Select Source", "Differential", "Differential Mic"}, ++ {"Right Mic Select Source", "Mic 1", "MIC1"}, ++ {"Right Mic Select Source", "Mic 2", "MIC2"}, ++ {"Right Mic Select Source", "Stereo", "MIC2"}, ++ {"Right Mic Select Source", "Differential", "Differential Mic"}, ++ + /* left capture selector */ + {"Left Capture Select", "Mic", "MIC1"}, + {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, diff --git a/3.2.28/4420_grsecurity-2.9.1-3.2.29-201209122157.patch b/3.2.29/4420_grsecurity-2.9.1-3.2.29-201209171824.patch index 228fc5d..4eebb32 100644 --- a/3.2.28/4420_grsecurity-2.9.1-3.2.29-201209122157.patch +++ b/3.2.29/4420_grsecurity-2.9.1-3.2.29-201209171824.patch @@ -20653,7 +20653,7 @@ index 94a4672..5c6b853 100644 local_irq_disable(); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index 407789b..942f6a6 100644 +index 407789b..5570a86 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1305,7 +1305,11 @@ static void reload_tss(void) @@ -20668,7 +20668,18 @@ index 407789b..942f6a6 100644 load_TR_desc(); } -@@ -2634,8 +2638,11 @@ static __init int hardware_setup(void) +@@ -1504,6 +1508,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ + vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */ + ++#ifdef CONFIG_PAX_PER_CPU_PGD ++ vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif ++ + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + vmx->loaded_vmcs->cpu = cpu; +@@ -2634,8 +2642,11 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_flexpriority()) flexpriority_enabled = 0; @@ -20682,7 +20693,18 @@ index 407789b..942f6a6 100644 if (enable_ept && !cpu_has_vmx_ept_2m_page()) kvm_disable_largepages(); -@@ -3649,7 +3656,7 @@ static void vmx_set_constant_host_state(void) +@@ -3637,7 +3648,10 @@ static void vmx_set_constant_host_state(void) + + vmcs_writel(HOST_CR0, read_cr0() | X86_CR0_TS); /* 22.2.3 */ + vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ ++ ++#ifndef CONFIG_PAX_PER_CPU_PGD + vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif + + vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ + vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ +@@ -3649,7 +3663,7 @@ static void vmx_set_constant_host_state(void) vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(tmpl)); @@ -20691,7 +20713,7 @@ index 407789b..942f6a6 100644 rdmsr(MSR_IA32_SYSENTER_CS, low32, high32); vmcs_write32(HOST_IA32_SYSENTER_CS, low32); -@@ -6172,6 +6179,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6172,6 +6186,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) "jmp .Lkvm_vmx_return \n\t" ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" ".Lkvm_vmx_return: " @@ -20704,7 +20726,7 @@ index 407789b..942f6a6 100644 /* Save guest registers, load host registers, keep flags */ "mov %0, %c[wordsize](%%"R"sp) \n\t" "pop %0 \n\t" -@@ -6220,6 +6233,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6220,6 +6240,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)), [wordsize]"i"(sizeof(ulong)) @@ -20716,7 +20738,7 @@ index 407789b..942f6a6 100644 : "cc", "memory" , R"ax", R"bx", R"di", R"si" #ifdef CONFIG_X86_64 -@@ -6248,7 +6266,16 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6248,7 +6273,16 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) } } @@ -44609,10 +44631,36 @@ index f3a257d..715ac0f 100644 } EXPORT_SYMBOL_GPL(debugfs_create_dir); diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c -index af11098..81e3bbe 100644 +index af11098..4e6f039 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c -@@ -691,7 +691,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, +@@ -640,6 +640,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct dentry *lower_old_dir_dentry; + struct dentry *lower_new_dir_dentry; + struct dentry *trap = NULL; ++ struct inode *target_inode; + + lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); +@@ -647,6 +648,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + dget(lower_new_dentry); + lower_old_dir_dentry = dget_parent(lower_old_dentry); + lower_new_dir_dentry = dget_parent(lower_new_dentry); ++ target_inode = new_dentry->d_inode; + trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); + /* source should not be ancestor of target */ + if (trap == lower_old_dentry) { +@@ -662,6 +664,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + lower_new_dir_dentry->d_inode, lower_new_dentry); + if (rc) + goto out_lock; ++ if (target_inode) ++ fsstack_copy_attr_all(target_inode, ++ ecryptfs_inode_to_lower(target_inode)); + fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); + if (new_dir != old_dir) + fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); +@@ -691,7 +696,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, old_fs = get_fs(); set_fs(get_ds()); rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, @@ -44621,7 +44669,7 @@ index af11098..81e3bbe 100644 lower_bufsiz); set_fs(old_fs); if (rc < 0) -@@ -737,7 +737,7 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) +@@ -737,7 +742,7 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) } old_fs = get_fs(); set_fs(get_ds()); @@ -44630,7 +44678,7 @@ index af11098..81e3bbe 100644 set_fs(old_fs); if (rc < 0) { kfree(buf); -@@ -752,7 +752,7 @@ out: +@@ -752,7 +757,7 @@ out: static void ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) { @@ -63491,6 +63539,19 @@ index b16f653..eb908f4 100644 #define request_module(mod...) __request_module(true, mod) #define request_module_nowait(mod...) __request_module(false, mod) #define try_then_request_module(x, mod...) \ +diff --git a/include/linux/kobject.h b/include/linux/kobject.h +index ad81e1c..445f978 100644 +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -226,7 +226,7 @@ static inline int kobject_uevent_env(struct kobject *kobj, + + static inline __printf(2, 3) + int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) +-{ return 0; } ++{ return -ENOMEM; } + + static inline int kobject_action_type(const char *buf, size_t count, + enum kobject_action *type) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 6136821..b3ba6ba 100644 --- a/include/linux/kvm_host.h @@ -64149,7 +64210,7 @@ index 4633b2f..988bc08 100644 atomic_t refcnt; unsigned int max_seq_nr; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index b1f8912..c955bff 100644 +index b1f8912..8335421 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -748,8 +748,8 @@ struct perf_event { @@ -64163,7 +64224,14 @@ index b1f8912..c955bff 100644 /* * These are the total time in nanoseconds that the event -@@ -800,8 +800,8 @@ struct perf_event { +@@ -794,14 +794,14 @@ struct perf_event { + struct hw_perf_event hw; + + struct perf_event_context *ctx; +- struct file *filp; ++ atomic_long_t refcount; + + /* * These accumulate total time (in nanoseconds) that children * events have been enabled and running, respectively. */ @@ -67520,7 +67588,7 @@ index 63786e7..0780cac 100644 #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/events/core.c b/kernel/events/core.c -index 58690af..d903d75 100644 +index 58690af..66d5a8e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -173,7 +173,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, @@ -67541,7 +67609,38 @@ index 58690af..d903d75 100644 } static u64 perf_event_read(struct perf_event *event) -@@ -3065,9 +3065,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -3011,12 +3011,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel); + /* + * Called when the last reference to the file is gone. + */ +-static int perf_release(struct inode *inode, struct file *file) ++static void put_event(struct perf_event *event) + { +- struct perf_event *event = file->private_data; + struct task_struct *owner; + +- file->private_data = NULL; ++ if (!atomic_long_dec_and_test(&event->refcount)) ++ return; + + rcu_read_lock(); + owner = ACCESS_ONCE(event->owner); +@@ -3051,7 +3051,13 @@ static int perf_release(struct inode *inode, struct file *file) + put_task_struct(owner); + } + +- return perf_event_release_kernel(event); ++ perf_event_release_kernel(event); ++} ++ ++static int perf_release(struct inode *inode, struct file *file) ++{ ++ put_event(file->private_data); ++ return 0; + } + + u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -3065,9 +3071,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) mutex_lock(&event->child_mutex); total += perf_event_read(event); *enabled += event->total_time_enabled + @@ -67553,7 +67652,51 @@ index 58690af..d903d75 100644 list_for_each_entry(child, &event->child_list, child_list) { total += perf_event_read(child); -@@ -3474,10 +3474,10 @@ void perf_event_update_userpage(struct perf_event *event) +@@ -3304,7 +3310,7 @@ unlock: + + static const struct file_operations perf_fops; + +-static struct perf_event *perf_fget_light(int fd, int *fput_needed) ++static struct file *perf_fget_light(int fd, int *fput_needed) + { + struct file *file; + +@@ -3318,7 +3324,7 @@ static struct perf_event *perf_fget_light(int fd, int *fput_needed) + return ERR_PTR(-EBADF); + } + +- return file->private_data; ++ return file; + } + + static int perf_event_set_output(struct perf_event *event, +@@ -3350,19 +3356,21 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + case PERF_EVENT_IOC_SET_OUTPUT: + { ++ struct file *output_file = NULL; + struct perf_event *output_event = NULL; + int fput_needed = 0; + int ret; + + if (arg != -1) { +- output_event = perf_fget_light(arg, &fput_needed); +- if (IS_ERR(output_event)) +- return PTR_ERR(output_event); ++ output_file = perf_fget_light(arg, &fput_needed); ++ if (IS_ERR(output_file)) ++ return PTR_ERR(output_file); ++ output_event = output_file->private_data; + } + + ret = perf_event_set_output(event, output_event); + if (output_event) +- fput_light(output_event->filp, fput_needed); ++ fput_light(output_file, fput_needed); + + return ret; + } +@@ -3474,10 +3482,10 @@ void perf_event_update_userpage(struct perf_event *event) userpg->offset -= local64_read(&event->hw.prev_count); userpg->time_enabled = enabled + @@ -67566,7 +67709,7 @@ index 58690af..d903d75 100644 barrier(); ++userpg->lock; -@@ -3906,11 +3906,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, +@@ -3906,11 +3914,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { values[n++] = enabled + @@ -67580,7 +67723,7 @@ index 58690af..d903d75 100644 } if (read_format & PERF_FORMAT_ID) values[n++] = primary_event_id(event); -@@ -4561,12 +4561,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) +@@ -4561,12 +4569,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) * need to add enough zero bytes after the string to handle * the 64bit alignment we do later. */ @@ -67595,7 +67738,15 @@ index 58690af..d903d75 100644 if (IS_ERR(name)) { name = strncpy(tmp, "//toolong", sizeof(tmp)); goto got_name; -@@ -5921,7 +5921,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, +@@ -5912,6 +5920,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + + mutex_init(&event->mmap_mutex); + ++ atomic_long_set(&event->refcount, 1); + event->cpu = cpu; + event->attr = *attr; + event->group_leader = group_leader; +@@ -5921,7 +5930,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->parent = parent_event; event->ns = get_pid_ns(current->nsproxy->pid_ns); @@ -67604,7 +67755,40 @@ index 58690af..d903d75 100644 event->state = PERF_EVENT_STATE_INACTIVE; -@@ -6443,10 +6443,10 @@ static void sync_child_event(struct perf_event *child_event, +@@ -6182,12 +6191,12 @@ SYSCALL_DEFINE5(perf_event_open, + return event_fd; + + if (group_fd != -1) { +- group_leader = perf_fget_light(group_fd, &fput_needed); +- if (IS_ERR(group_leader)) { +- err = PTR_ERR(group_leader); ++ group_file = perf_fget_light(group_fd, &fput_needed); ++ if (IS_ERR(group_file)) { ++ err = PTR_ERR(group_file); + goto err_fd; + } +- group_file = group_leader->filp; ++ group_leader = group_file->private_data; + if (flags & PERF_FLAG_FD_OUTPUT) + output_event = group_leader; + if (flags & PERF_FLAG_FD_NO_GROUP) +@@ -6322,7 +6331,6 @@ SYSCALL_DEFINE5(perf_event_open, + put_ctx(gctx); + } + +- event->filp = event_file; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + +@@ -6412,7 +6420,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, + goto err_free; + } + +- event->filp = NULL; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + perf_install_in_context(ctx, event, cpu); +@@ -6443,10 +6450,10 @@ static void sync_child_event(struct perf_event *child_event, /* * Add back the child's count to the parent's count: */ @@ -67618,6 +67802,64 @@ index 58690af..d903d75 100644 &parent_event->child_total_time_running); /* +@@ -6461,7 +6468,7 @@ static void sync_child_event(struct perf_event *child_event, + * Release the parent event, if this was the last + * reference to it. + */ +- fput(parent_event->filp); ++ put_event(parent_event); + } + + static void +@@ -6537,9 +6544,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) + * + * __perf_event_exit_task() + * sync_child_event() +- * fput(parent_event->filp) +- * perf_release() +- * mutex_lock(&ctx->mutex) ++ * put_event() ++ * mutex_lock(&ctx->mutex) + * + * But since its the parent context it won't be the same instance. + */ +@@ -6607,7 +6613,7 @@ static void perf_free_event(struct perf_event *event, + list_del_init(&event->child_list); + mutex_unlock(&parent->child_mutex); + +- fput(parent->filp); ++ put_event(parent); + + perf_group_detach(event); + list_del_event(event, ctx); +@@ -6687,6 +6693,12 @@ inherit_event(struct perf_event *parent_event, + NULL, NULL); + if (IS_ERR(child_event)) + return child_event; ++ ++ if (!atomic_long_inc_not_zero(&parent_event->refcount)) { ++ free_event(child_event); ++ return NULL; ++ } ++ + get_ctx(child_ctx); + + /* +@@ -6728,14 +6740,6 @@ inherit_event(struct perf_event *parent_event, + raw_spin_unlock_irqrestore(&child_ctx->lock, flags); + + /* +- * Get a reference to the parent filp - we will fput it +- * when the child event exits. This is safe to do because +- * we are in the parent and we know that the filp still +- * exists and has a nonzero count: +- */ +- atomic_long_inc(&parent_event->filp->f_count); +- +- /* + * Link this into the parent event's child list + */ + WARN_ON_ONCE(parent_event->ctx->parent_ctx); diff --git a/kernel/exit.c b/kernel/exit.c index 5a8a66e..ded4680 100644 --- a/kernel/exit.c @@ -75544,7 +75786,7 @@ index cd3ab93..3ff7a99 100644 * ksize - get the actual amount of memory allocated for a given object * @objp: Pointer to the object diff --git a/mm/slob.c b/mm/slob.c -index 8105be4..3e3e9cd 100644 +index 8105be4..33e52d7 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -29,7 +29,7 @@ @@ -75564,17 +75806,18 @@ index 8105be4..3e3e9cd 100644 #include <linux/slab.h> #include <linux/mm.h> #include <linux/swap.h> /* struct reclaim_state */ -@@ -102,7 +103,8 @@ struct slob_page { +@@ -100,9 +101,8 @@ struct slob_page { + union { + struct { unsigned long flags; /* mandatory */ - atomic_t _count; /* mandatory */ +- atomic_t _count; /* mandatory */ slobidx_t units; /* free units left in page */ - unsigned long pad[2]; -+ unsigned long pad[1]; + unsigned long size; /* size when >=PAGE_SIZE */ slob_t *free; /* first free slob_t in page */ struct list_head list; /* linked list of free pages */ }; -@@ -135,7 +137,7 @@ static LIST_HEAD(free_slob_large); +@@ -135,7 +135,7 @@ static LIST_HEAD(free_slob_large); */ static inline int is_slob_page(struct slob_page *sp) { @@ -75583,7 +75826,7 @@ index 8105be4..3e3e9cd 100644 } static inline void set_slob_page(struct slob_page *sp) -@@ -150,7 +152,7 @@ static inline void clear_slob_page(struct slob_page *sp) +@@ -150,7 +150,7 @@ static inline void clear_slob_page(struct slob_page *sp) static inline struct slob_page *slob_page(const void *addr) { @@ -75592,7 +75835,7 @@ index 8105be4..3e3e9cd 100644 } /* -@@ -210,7 +212,7 @@ static void set_slob(slob_t *s, slobidx_t size, slob_t *next) +@@ -210,7 +210,7 @@ static void set_slob(slob_t *s, slobidx_t size, slob_t *next) /* * Return the size of a slob block. */ @@ -75601,7 +75844,7 @@ index 8105be4..3e3e9cd 100644 { if (s->units > 0) return s->units; -@@ -220,7 +222,7 @@ static slobidx_t slob_units(slob_t *s) +@@ -220,7 +220,7 @@ static slobidx_t slob_units(slob_t *s) /* * Return the next free slob block pointer after this one. */ @@ -75610,7 +75853,7 @@ index 8105be4..3e3e9cd 100644 { slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK); slobidx_t next; -@@ -235,7 +237,7 @@ static slob_t *slob_next(slob_t *s) +@@ -235,7 +235,7 @@ static slob_t *slob_next(slob_t *s) /* * Returns true if s is the last free block in its page. */ @@ -75619,7 +75862,7 @@ index 8105be4..3e3e9cd 100644 { return !((unsigned long)slob_next(s) & ~PAGE_MASK); } -@@ -254,6 +256,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) +@@ -254,6 +254,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) if (!page) return NULL; @@ -75627,7 +75870,7 @@ index 8105be4..3e3e9cd 100644 return page_address(page); } -@@ -370,11 +373,11 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) +@@ -370,11 +371,11 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) if (!b) return NULL; sp = slob_page(b); @@ -75640,7 +75883,7 @@ index 8105be4..3e3e9cd 100644 INIT_LIST_HEAD(&sp->list); set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE)); set_slob_page_free(sp, slob_list); -@@ -476,10 +479,9 @@ out: +@@ -476,10 +477,9 @@ out: * End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend. */ @@ -75653,7 +75896,7 @@ index 8105be4..3e3e9cd 100644 void *ret; gfp &= gfp_allowed_mask; -@@ -494,7 +496,10 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) +@@ -494,7 +494,10 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) if (!m) return NULL; @@ -75665,7 +75908,7 @@ index 8105be4..3e3e9cd 100644 ret = (void *)m + align; trace_kmalloc_node(_RET_IP_, ret, -@@ -506,16 +511,25 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) +@@ -506,16 +509,25 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) gfp |= __GFP_COMP; ret = slob_new_pages(gfp, order, node); if (ret) { @@ -75695,7 +75938,7 @@ index 8105be4..3e3e9cd 100644 return ret; } EXPORT_SYMBOL(__kmalloc_node); -@@ -533,13 +547,88 @@ void kfree(const void *block) +@@ -533,13 +545,88 @@ void kfree(const void *block) sp = slob_page(block); if (is_slob_page(sp)) { int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); @@ -75753,7 +75996,7 @@ index 8105be4..3e3e9cd 100644 + base = (void *)((unsigned long)ptr & PAGE_MASK); + free = sp->free; + -+ while (!slob_last(free) && (void *)free <= ptr) { ++ while ((void *)free <= ptr) { + base = free + slob_units(free); + free = slob_next(free); + } @@ -75787,7 +76030,7 @@ index 8105be4..3e3e9cd 100644 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */ size_t ksize(const void *block) { -@@ -552,10 +641,10 @@ size_t ksize(const void *block) +@@ -552,10 +639,10 @@ size_t ksize(const void *block) sp = slob_page(block); if (is_slob_page(sp)) { int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); @@ -75801,7 +76044,7 @@ index 8105be4..3e3e9cd 100644 } EXPORT_SYMBOL(ksize); -@@ -571,8 +660,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, +@@ -571,8 +658,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, { struct kmem_cache *c; @@ -75815,7 +76058,7 @@ index 8105be4..3e3e9cd 100644 if (c) { c->name = name; -@@ -614,17 +708,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) +@@ -614,17 +706,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) lockdep_trace_alloc(flags); @@ -75841,7 +76084,7 @@ index 8105be4..3e3e9cd 100644 if (c->ctor) c->ctor(b); -@@ -636,10 +738,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); +@@ -636,10 +736,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); static void __kmem_cache_free(void *b, int size) { @@ -75860,7 +76103,7 @@ index 8105be4..3e3e9cd 100644 } static void kmem_rcu_free(struct rcu_head *head) -@@ -652,17 +760,31 @@ static void kmem_rcu_free(struct rcu_head *head) +@@ -652,17 +758,31 @@ static void kmem_rcu_free(struct rcu_head *head) void kmem_cache_free(struct kmem_cache *c, void *b) { @@ -80767,10 +81010,31 @@ index 9414b9c..d14ecb6 100644 if (init_replay) { err = xfrm_init_replay(x); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index 7cae73e..fe80421 100644 +index 7cae73e..ca5c26f 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c -@@ -1401,6 +1401,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) +@@ -862,6 +862,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + { + struct xfrm_dump_info info; + struct sk_buff *skb; ++ int err; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!skb) +@@ -872,9 +873,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + info.nlmsg_seq = seq; + info.nlmsg_flags = 0; + +- if (dump_one_state(x, 0, &info)) { ++ err = dump_one_state(x, 0, &info); ++ if (err) { + kfree_skb(skb); +- return NULL; ++ return ERR_PTR(err); + } + + return skb; +@@ -1401,6 +1403,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) struct xfrm_user_tmpl *up = &vec[i]; struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; diff --git a/3.2.28/4430_grsec-remove-localversion-grsec.patch b/3.2.29/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.2.28/4430_grsec-remove-localversion-grsec.patch +++ b/3.2.29/4430_grsec-remove-localversion-grsec.patch diff --git a/3.2.28/4435_grsec-mute-warnings.patch b/3.2.29/4435_grsec-mute-warnings.patch index e85abd6..e85abd6 100644 --- a/3.2.28/4435_grsec-mute-warnings.patch +++ b/3.2.29/4435_grsec-mute-warnings.patch diff --git a/3.2.28/4440_grsec-remove-protected-paths.patch b/3.2.29/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.2.28/4440_grsec-remove-protected-paths.patch +++ b/3.2.29/4440_grsec-remove-protected-paths.patch diff --git a/3.2.28/4450_grsec-kconfig-default-gids.patch b/3.2.29/4450_grsec-kconfig-default-gids.patch index 0ab1250..0ab1250 100644 --- a/3.2.28/4450_grsec-kconfig-default-gids.patch +++ b/3.2.29/4450_grsec-kconfig-default-gids.patch diff --git a/3.2.28/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.29/4465_selinux-avc_audit-log-curr_ip.patch index 48acad7..48acad7 100644 --- a/3.2.28/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.2.29/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.2.28/4470_disable-compat_vdso.patch b/3.2.29/4470_disable-compat_vdso.patch index 4742d01..4742d01 100644 --- a/3.2.28/4470_disable-compat_vdso.patch +++ b/3.2.29/4470_disable-compat_vdso.patch diff --git a/3.5.3/0000_README b/3.5.4/0000_README index c901840..2253a6b 100644 --- a/3.5.3/0000_README +++ b/3.5.4/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-2.9.1-3.5.3-201209131726.patch +Patch: 4420_grsecurity-2.9.1-3.5.4-201209171824.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.5.3/4420_grsecurity-2.9.1-3.5.3-201209131726.patch b/3.5.4/4420_grsecurity-2.9.1-3.5.4-201209171824.patch index fa219c0..ca159d7 100644 --- a/3.5.3/4420_grsecurity-2.9.1-3.5.3-201209131726.patch +++ b/3.5.4/4420_grsecurity-2.9.1-3.5.4-201209171824.patch @@ -275,7 +275,7 @@ index 13d6166..8c235b6 100644 ============================================================== diff --git a/Makefile b/Makefile -index c901aae..0f96503 100644 +index 6453ead..f5148e2 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -3244,7 +3244,7 @@ index 4ce7a01..449202a 100644 #endif /* __ASM_OPENRISC_CACHE_H */ diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h -index 6c6defc..d30653d 100644 +index af9cf30..2aae9b2 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -229,6 +229,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) @@ -4214,7 +4214,7 @@ index 2e3200c..72095ce 100644 /* Find this entry, or if that fails, the next avail. entry */ while (entry->jump[0]) { diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c -index 710f400..d00ebe6 100644 +index 1a1f2dd..f4d1bb4 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -681,8 +681,8 @@ void show_regs(struct pt_regs * regs) @@ -4228,7 +4228,7 @@ index 710f400..d00ebe6 100644 #endif show_stack(current, (unsigned long *) regs->gpr[1]); if (!user_mode(regs)) -@@ -1189,10 +1189,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) +@@ -1181,10 +1181,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) newsp = stack[0]; ip = stack[STACK_FRAME_LR_SAVE]; if (!firstframe || ip != lr) { @@ -4241,7 +4241,7 @@ index 710f400..d00ebe6 100644 (void *)current->ret_stack[curr_frame].ret); curr_frame--; } -@@ -1212,7 +1212,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) +@@ -1204,7 +1204,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); lr = regs->link; @@ -4250,7 +4250,7 @@ index 710f400..d00ebe6 100644 regs->trap, (void *)regs->nip, (void *)lr); firstframe = 1; } -@@ -1254,58 +1254,3 @@ void __ppc64_runlatch_off(void) +@@ -1246,58 +1246,3 @@ void __ppc64_runlatch_off(void) mtspr(SPRN_CTRLT, ctrl); } #endif /* CONFIG_PPC64 */ @@ -4395,7 +4395,7 @@ index f2496f2..4e3cc47 100644 } #endif diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c -index 1589723..cefe690 100644 +index ae0843f..f16372c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -133,6 +133,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs) @@ -9067,7 +9067,7 @@ index 49331be..9706065 100644 ".previous" diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h -index eaff479..3025a63 100644 +index eaff479..1eff9b5 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -44,7 +44,7 @@ static inline void generic_apic_probe(void) @@ -9079,6 +9079,15 @@ index eaff479..3025a63 100644 extern int local_apic_timer_c2_ok; extern int disable_apic; +@@ -390,7 +390,7 @@ struct apic { + */ + int (*x86_32_numa_cpu_node)(int cpu); + #endif +-}; ++} __do_const; + + /* + * Pointer to the local APIC driver in use on this system (there's diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h index 20370c6..a2eb9b0 100644 --- a/arch/x86/include/asm/apm.h @@ -13940,6 +13949,19 @@ index 5f0ff59..f9e01bc 100644 eoi_ioapic_irq(irq, cfg); } +diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c +index 3fe9866..6abf259 100644 +--- a/arch/x86/kernel/apic/probe_64.c ++++ b/arch/x86/kernel/apic/probe_64.c +@@ -50,7 +50,7 @@ void __init default_setup_apic_routing(void) + + if (is_vsmp_box()) { + /* need to update phys_pkg_id */ +- apic->phys_pkg_id = apicid_phys_pkg_id; ++ *(void **)&apic->phys_pkg_id = apicid_phys_pkg_id; + } + } + diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 07b0c0d..1df6f42 100644 --- a/arch/x86/kernel/apm_32.c @@ -14469,6 +14491,24 @@ index c4706cf..264b0f7 100644 } } +diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c +index 187c294..28a069c 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel.c ++++ b/arch/x86/kernel/cpu/perf_event_intel.c +@@ -1811,10 +1811,10 @@ __init int intel_pmu_init(void) + * v2 and above have a perf capabilities MSR + */ + if (version > 1) { +- u64 capabilities; ++ u64 capabilities = x86_pmu.intel_cap.capabilities; + +- rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); +- x86_pmu.intel_cap.capabilities = capabilities; ++ if (rdmsrl_safe(MSR_IA32_PERF_CAPABILITIES, &x86_pmu.intel_cap.capabilities)) ++ x86_pmu.intel_cap.capabilities = capabilities; + } + + intel_ds_init(); diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 13ad899..f642b9a 100644 --- a/arch/x86/kernel/crash.c @@ -20412,7 +20452,7 @@ index f75af40..285b18f 100644 local_irq_disable(); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index 86c8704..e8ee2ac 100644 +index 86c8704..d9277bb 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1317,7 +1317,11 @@ static void reload_tss(void) @@ -20427,7 +20467,18 @@ index 86c8704..e8ee2ac 100644 load_TR_desc(); } -@@ -2650,8 +2654,11 @@ static __init int hardware_setup(void) +@@ -1527,6 +1531,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ + vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */ + ++#ifdef CONFIG_PAX_PER_CPU_PGD ++ vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif ++ + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + vmx->loaded_vmcs->cpu = cpu; +@@ -2650,8 +2658,11 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_flexpriority()) flexpriority_enabled = 0; @@ -20441,7 +20492,18 @@ index 86c8704..e8ee2ac 100644 if (enable_ept && !cpu_has_vmx_ept_2m_page()) kvm_disable_largepages(); -@@ -3719,7 +3726,7 @@ static void vmx_set_constant_host_state(void) +@@ -3697,7 +3708,10 @@ static void vmx_set_constant_host_state(void) + + vmcs_writel(HOST_CR0, read_cr0() | X86_CR0_TS); /* 22.2.3 */ + vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ ++ ++#ifndef CONFIG_PAX_PER_CPU_PGD + vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ ++#endif + + vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ + #ifdef CONFIG_X86_64 +@@ -3719,7 +3733,7 @@ static void vmx_set_constant_host_state(void) vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(tmpl)); @@ -20450,7 +20512,7 @@ index 86c8704..e8ee2ac 100644 rdmsr(MSR_IA32_SYSENTER_CS, low32, high32); vmcs_write32(HOST_IA32_SYSENTER_CS, low32); -@@ -6257,6 +6264,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6257,6 +6271,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) "jmp .Lkvm_vmx_return \n\t" ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" ".Lkvm_vmx_return: " @@ -20463,7 +20525,7 @@ index 86c8704..e8ee2ac 100644 /* Save guest registers, load host registers, keep flags */ "mov %0, %c[wordsize](%%"R"sp) \n\t" "pop %0 \n\t" -@@ -6305,6 +6318,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6305,6 +6325,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)), [wordsize]"i"(sizeof(ulong)) @@ -20475,7 +20537,7 @@ index 86c8704..e8ee2ac 100644 : "cc", "memory" , R"ax", R"bx", R"di", R"si" #ifdef CONFIG_X86_64 -@@ -6312,7 +6330,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6312,7 +6337,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif ); @@ -20484,7 +20546,7 @@ index 86c8704..e8ee2ac 100644 /* * The sysexit path does not restore ds/es, so we must set them to * a reasonable value ourselves. -@@ -6321,8 +6339,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -6321,8 +6346,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) * may be executed in interrupt context, which saves and restore segments * around it, nullifying its effect. */ @@ -24260,10 +24322,10 @@ index 6f31ee5..8ee4164 100644 return (void *)vaddr; diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c -index f6679a7..8f795a3 100644 +index b91e485..d00e7c9 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c -@@ -266,13 +266,20 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, +@@ -277,13 +277,20 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, struct hstate *h = hstate_file(file); struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -24288,7 +24350,7 @@ index f6679a7..8f795a3 100644 } full_search: -@@ -280,26 +287,27 @@ full_search: +@@ -291,26 +298,27 @@ full_search: for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ @@ -24323,7 +24385,7 @@ index f6679a7..8f795a3 100644 } static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, -@@ -310,9 +318,8 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, +@@ -321,9 +329,8 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long base = mm->mmap_base; @@ -24334,7 +24396,7 @@ index f6679a7..8f795a3 100644 /* don't allow allocations above current base */ if (mm->free_area_cache > base) -@@ -322,16 +329,15 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, +@@ -333,16 +340,15 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, largest_hole = 0; mm->free_area_cache = base; } @@ -24353,7 +24415,7 @@ index f6679a7..8f795a3 100644 /* * Lookup failure means no vma is above this address, * i.e. return with success: -@@ -340,10 +346,10 @@ try_again: +@@ -351,10 +357,10 @@ try_again: if (!vma) return addr; @@ -24367,7 +24429,7 @@ index f6679a7..8f795a3 100644 } else if (mm->free_area_cache == vma->vm_end) { /* pull free_area_cache down to the first hole */ mm->free_area_cache = vma->vm_start; -@@ -352,29 +358,34 @@ try_again: +@@ -363,29 +369,34 @@ try_again: /* remember the largest hole we saw so far */ if (addr + largest_hole < vma->vm_start) @@ -24415,7 +24477,7 @@ index f6679a7..8f795a3 100644 mm->cached_hole_size = ~0UL; addr = hugetlb_get_unmapped_area_bottomup(file, addr0, len, pgoff, flags); -@@ -382,6 +393,7 @@ fail: +@@ -393,6 +404,7 @@ fail: /* * Restore the topdown base: */ @@ -24423,7 +24485,7 @@ index f6679a7..8f795a3 100644 mm->free_area_cache = base; mm->cached_hole_size = ~0UL; -@@ -395,10 +407,19 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, +@@ -406,10 +418,19 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, struct hstate *h = hstate_file(file); struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -24444,7 +24506,7 @@ index f6679a7..8f795a3 100644 return -ENOMEM; if (flags & MAP_FIXED) { -@@ -410,8 +431,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, +@@ -421,8 +442,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (addr) { addr = ALIGN(addr, huge_page_size(h)); vma = find_vma(mm, addr); @@ -34795,7 +34857,7 @@ index 9d71c9c..0e4a0ac 100644 { "100/10M Ethernet PCI Adapter", HAS_CHIP_XCVR }, { "1000/100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h -index 6e6fffb..588f361 100644 +index fa47b85..246edeb 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -181,7 +181,7 @@ struct e1000_info; @@ -37052,10 +37114,10 @@ index bbbc9c9..ce22f77 100644 /* check if the device is still usable */ if (unlikely(cmd->device->sdev_state == SDEV_DEL)) { diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index 495db80..fb37d59 100644 +index dae3873..bb4bee6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c -@@ -1422,7 +1422,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) +@@ -1425,7 +1425,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) shost = sdev->host; scsi_init_cmd_errh(cmd); cmd->result = DID_NO_CONNECT << 16; @@ -37064,7 +37126,7 @@ index 495db80..fb37d59 100644 /* * SCSI request completion path will do scsi_device_unbusy(), -@@ -1448,9 +1448,9 @@ static void scsi_softirq_done(struct request *rq) +@@ -1451,9 +1451,9 @@ static void scsi_softirq_done(struct request *rq) INIT_LIST_HEAD(&cmd->eh_entry); @@ -37511,7 +37573,7 @@ index 0d4aa82..f7832d4 100644 /* core tmem accessor functions */ diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c -index c6c385f..b23c65d 100644 +index df9824c..f699b8a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1233,7 +1233,7 @@ struct se_device *transport_add_device_to_core_hba( @@ -44023,7 +44085,7 @@ index 6901578..d402eb5 100644 return hit; diff --git a/fs/compat.c b/fs/compat.c -index 6161255..9f28287 100644 +index 1bdb350..9f28287 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -490,7 +490,7 @@ compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p) @@ -44133,38 +44195,6 @@ index 6161255..9f28287 100644 if (__put_user_unaligned(d_off, &lastdirent->d_off)) error = -EFAULT; else -@@ -1155,11 +1173,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, - struct file *file; - int fput_needed; - ssize_t ret; -+ loff_t pos; - - file = fget_light(fd, &fput_needed); - if (!file) - return -EBADF; -- ret = compat_readv(file, vec, vlen, &file->f_pos); -+ pos = file->f_pos; -+ ret = compat_readv(file, vec, vlen, &pos); -+ file->f_pos = pos; - fput_light(file, fput_needed); - return ret; - } -@@ -1221,11 +1242,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, - struct file *file; - int fput_needed; - ssize_t ret; -+ loff_t pos; - - file = fget_light(fd, &fput_needed); - if (!file) - return -EBADF; -- ret = compat_writev(file, vec, vlen, &file->f_pos); -+ pos = file->f_pos; -+ ret = compat_writev(file, vec, vlen, &pos); -+ file->f_pos = pos; - fput_light(file, fput_needed); - return ret; - } diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 112e45a..b59845b 100644 --- a/fs/compat_binfmt_elf.c @@ -44283,10 +44313,36 @@ index b80bc84..0d46d1a 100644 } EXPORT_SYMBOL_GPL(debugfs_create_dir); diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c -index a07441a..046fc0d 100644 +index a07441a..5c47fa2 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c -@@ -671,7 +671,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, +@@ -621,6 +621,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct dentry *lower_old_dir_dentry; + struct dentry *lower_new_dir_dentry; + struct dentry *trap = NULL; ++ struct inode *target_inode; + + lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); +@@ -628,6 +629,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + dget(lower_new_dentry); + lower_old_dir_dentry = dget_parent(lower_old_dentry); + lower_new_dir_dentry = dget_parent(lower_new_dentry); ++ target_inode = new_dentry->d_inode; + trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); + /* source should not be ancestor of target */ + if (trap == lower_old_dentry) { +@@ -643,6 +645,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + lower_new_dir_dentry->d_inode, lower_new_dentry); + if (rc) + goto out_lock; ++ if (target_inode) ++ fsstack_copy_attr_all(target_inode, ++ ecryptfs_inode_to_lower(target_inode)); + fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); + if (new_dir != old_dir) + fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); +@@ -671,7 +676,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, old_fs = get_fs(); set_fs(get_ds()); rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, @@ -44295,7 +44351,7 @@ index a07441a..046fc0d 100644 PATH_MAX); set_fs(old_fs); if (rc < 0) -@@ -703,7 +703,7 @@ out: +@@ -703,7 +708,7 @@ out: static void ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) { @@ -47005,7 +47061,7 @@ index 3426521..3b75162 100644 cuse_class = class_create(THIS_MODULE, "cuse"); if (IS_ERR(cuse_class)) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c -index 7df2b5e..5804aa7 100644 +index f4246cf..b4aed1d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1242,7 +1242,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, @@ -48096,7 +48152,7 @@ index 68f4541..89cfe6a 100644 /* Copy the blockcheck stats from the superblock probe */ osb->osb_ecc_stats = *stats; diff --git a/fs/open.c b/fs/open.c -index 1540632..79d7242 100644 +index 5d9c71b..adb5b19 100644 --- a/fs/open.c +++ b/fs/open.c @@ -31,6 +31,8 @@ @@ -48193,7 +48249,7 @@ index 1540632..79d7242 100644 newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { if (!uid_valid(uid)) -@@ -1035,6 +1072,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) +@@ -1036,6 +1073,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) } else { fsnotify_open(f); fd_install(fd, f); @@ -62811,6 +62867,19 @@ index 5398d58..5883a34 100644 #define request_module(mod...) __request_module(true, mod) #define request_module_nowait(mod...) __request_module(false, mod) #define try_then_request_module(x, mod...) \ +diff --git a/include/linux/kobject.h b/include/linux/kobject.h +index fc615a9..1e57449 100644 +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -224,7 +224,7 @@ static inline int kobject_uevent_env(struct kobject *kobj, + + static inline __printf(2, 3) + int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) +-{ return 0; } ++{ return -ENOMEM; } + + static inline int kobject_action_type(const char *buf, size_t count, + enum kobject_action *type) diff --git a/include/linux/kref.h b/include/linux/kref.h index 9c07dce..a92fa71 100644 --- a/include/linux/kref.h @@ -63424,7 +63493,7 @@ index a4c5624..79d6d88 100644 /** create a directory */ struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 45db49f..386788e 100644 +index 45db49f..8795db3 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -879,8 +879,8 @@ struct perf_event { @@ -63438,7 +63507,14 @@ index 45db49f..386788e 100644 /* * These are the total time in nanoseconds that the event -@@ -931,8 +931,8 @@ struct perf_event { +@@ -925,14 +925,14 @@ struct perf_event { + struct hw_perf_event hw; + + struct perf_event_context *ctx; +- struct file *filp; ++ atomic_long_t refcount; + + /* * These accumulate total time (in nanoseconds) that children * events have been enabled and running, respectively. */ @@ -66664,7 +66740,7 @@ index 1f91413..362a0a1 100644 #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/events/core.c b/kernel/events/core.c -index d7d71d6..f54b76f 100644 +index d7d71d6..b6ec863 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -181,7 +181,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, @@ -66685,7 +66761,38 @@ index d7d71d6..f54b76f 100644 } static u64 perf_event_read(struct perf_event *event) -@@ -2987,9 +2987,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -2933,12 +2933,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel); + /* + * Called when the last reference to the file is gone. + */ +-static int perf_release(struct inode *inode, struct file *file) ++static void put_event(struct perf_event *event) + { +- struct perf_event *event = file->private_data; + struct task_struct *owner; + +- file->private_data = NULL; ++ if (!atomic_long_dec_and_test(&event->refcount)) ++ return; + + rcu_read_lock(); + owner = ACCESS_ONCE(event->owner); +@@ -2973,7 +2973,13 @@ static int perf_release(struct inode *inode, struct file *file) + put_task_struct(owner); + } + +- return perf_event_release_kernel(event); ++ perf_event_release_kernel(event); ++} ++ ++static int perf_release(struct inode *inode, struct file *file) ++{ ++ put_event(file->private_data); ++ return 0; + } + + u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -2987,9 +2993,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) mutex_lock(&event->child_mutex); total += perf_event_read(event); *enabled += event->total_time_enabled + @@ -66697,7 +66804,51 @@ index d7d71d6..f54b76f 100644 list_for_each_entry(child, &event->child_list, child_list) { total += perf_event_read(child); -@@ -3396,10 +3396,10 @@ void perf_event_update_userpage(struct perf_event *event) +@@ -3225,7 +3231,7 @@ unlock: + + static const struct file_operations perf_fops; + +-static struct perf_event *perf_fget_light(int fd, int *fput_needed) ++static struct file *perf_fget_light(int fd, int *fput_needed) + { + struct file *file; + +@@ -3239,7 +3245,7 @@ static struct perf_event *perf_fget_light(int fd, int *fput_needed) + return ERR_PTR(-EBADF); + } + +- return file->private_data; ++ return file; + } + + static int perf_event_set_output(struct perf_event *event, +@@ -3271,19 +3277,21 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + case PERF_EVENT_IOC_SET_OUTPUT: + { ++ struct file *output_file = NULL; + struct perf_event *output_event = NULL; + int fput_needed = 0; + int ret; + + if (arg != -1) { +- output_event = perf_fget_light(arg, &fput_needed); +- if (IS_ERR(output_event)) +- return PTR_ERR(output_event); ++ output_file = perf_fget_light(arg, &fput_needed); ++ if (IS_ERR(output_file)) ++ return PTR_ERR(output_file); ++ output_event = output_file->private_data; + } + + ret = perf_event_set_output(event, output_event); + if (output_event) +- fput_light(output_event->filp, fput_needed); ++ fput_light(output_file, fput_needed); + + return ret; + } +@@ -3396,10 +3404,10 @@ void perf_event_update_userpage(struct perf_event *event) userpg->offset -= local64_read(&event->hw.prev_count); userpg->time_enabled = enabled + @@ -66710,7 +66861,7 @@ index d7d71d6..f54b76f 100644 arch_perf_update_userpage(userpg, now); -@@ -3832,11 +3832,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, +@@ -3832,11 +3840,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { values[n++] = enabled + @@ -66724,7 +66875,7 @@ index d7d71d6..f54b76f 100644 } if (read_format & PERF_FORMAT_ID) values[n++] = primary_event_id(event); -@@ -4514,12 +4514,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) +@@ -4514,12 +4522,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) * need to add enough zero bytes after the string to handle * the 64bit alignment we do later. */ @@ -66739,7 +66890,15 @@ index d7d71d6..f54b76f 100644 if (IS_ERR(name)) { name = strncpy(tmp, "//toolong", sizeof(tmp)); goto got_name; -@@ -5931,7 +5931,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, +@@ -5922,6 +5930,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + + mutex_init(&event->mmap_mutex); + ++ atomic_long_set(&event->refcount, 1); + event->cpu = cpu; + event->attr = *attr; + event->group_leader = group_leader; +@@ -5931,7 +5940,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->parent = parent_event; event->ns = get_pid_ns(current->nsproxy->pid_ns); @@ -66748,7 +66907,40 @@ index d7d71d6..f54b76f 100644 event->state = PERF_EVENT_STATE_INACTIVE; -@@ -6493,10 +6493,10 @@ static void sync_child_event(struct perf_event *child_event, +@@ -6232,12 +6241,12 @@ SYSCALL_DEFINE5(perf_event_open, + return event_fd; + + if (group_fd != -1) { +- group_leader = perf_fget_light(group_fd, &fput_needed); +- if (IS_ERR(group_leader)) { +- err = PTR_ERR(group_leader); ++ group_file = perf_fget_light(group_fd, &fput_needed); ++ if (IS_ERR(group_file)) { ++ err = PTR_ERR(group_file); + goto err_fd; + } +- group_file = group_leader->filp; ++ group_leader = group_file->private_data; + if (flags & PERF_FLAG_FD_OUTPUT) + output_event = group_leader; + if (flags & PERF_FLAG_FD_NO_GROUP) +@@ -6372,7 +6381,6 @@ SYSCALL_DEFINE5(perf_event_open, + put_ctx(gctx); + } + +- event->filp = event_file; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + +@@ -6462,7 +6470,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, + goto err_free; + } + +- event->filp = NULL; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + perf_install_in_context(ctx, event, cpu); +@@ -6493,10 +6500,10 @@ static void sync_child_event(struct perf_event *child_event, /* * Add back the child's count to the parent's count: */ @@ -66762,6 +66954,64 @@ index d7d71d6..f54b76f 100644 &parent_event->child_total_time_running); /* +@@ -6511,7 +6518,7 @@ static void sync_child_event(struct perf_event *child_event, + * Release the parent event, if this was the last + * reference to it. + */ +- fput(parent_event->filp); ++ put_event(parent_event); + } + + static void +@@ -6587,9 +6594,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) + * + * __perf_event_exit_task() + * sync_child_event() +- * fput(parent_event->filp) +- * perf_release() +- * mutex_lock(&ctx->mutex) ++ * put_event() ++ * mutex_lock(&ctx->mutex) + * + * But since its the parent context it won't be the same instance. + */ +@@ -6657,7 +6663,7 @@ static void perf_free_event(struct perf_event *event, + list_del_init(&event->child_list); + mutex_unlock(&parent->child_mutex); + +- fput(parent->filp); ++ put_event(parent); + + perf_group_detach(event); + list_del_event(event, ctx); +@@ -6737,6 +6743,12 @@ inherit_event(struct perf_event *parent_event, + NULL, NULL); + if (IS_ERR(child_event)) + return child_event; ++ ++ if (!atomic_long_inc_not_zero(&parent_event->refcount)) { ++ free_event(child_event); ++ return NULL; ++ } ++ + get_ctx(child_ctx); + + /* +@@ -6778,14 +6790,6 @@ inherit_event(struct perf_event *parent_event, + raw_spin_unlock_irqrestore(&child_ctx->lock, flags); + + /* +- * Get a reference to the parent filp - we will fput it +- * when the child event exits. This is safe to do because +- * we are in the parent and we know that the filp still +- * exists and has a nonzero count: +- */ +- atomic_long_inc(&parent_event->filp->f_count); +- +- /* + * Link this into the parent event's child list + */ + WARN_ON_ONCE(parent_event->ctx->parent_ctx); diff --git a/kernel/exit.c b/kernel/exit.c index 46ce8da..c648f3a 100644 --- a/kernel/exit.c @@ -66852,7 +67102,7 @@ index 46ce8da..c648f3a 100644 { struct signal_struct *sig = current->signal; diff --git a/kernel/fork.c b/kernel/fork.c -index f00e319..c212fbc 100644 +index f9d0499..e4f8f44 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -321,7 +321,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) @@ -67028,9 +67278,9 @@ index f00e319..c212fbc 100644 if (retval) goto out; -- if (file && uprobe_mmap(tmp)) -+ if (tmp->vm_file && uprobe_mmap(tmp)) - goto out; +- if (file) ++ if (tmp->vm_file) + uprobe_mmap(tmp); } + +#ifdef CONFIG_PAX_SEGMEXEC @@ -69507,10 +69757,10 @@ index 0984a21..939f183 100644 #ifdef CONFIG_RT_GROUP_SCHED /* diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 468bdd4..b941572 100644 +index 39c44fa..70edb8b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -4097,6 +4097,8 @@ int can_nice(const struct task_struct *p, const int nice) +@@ -4103,6 +4103,8 @@ int can_nice(const struct task_struct *p, const int nice) /* convert nice value [19,-20] to rlimit style value [1,40] */ int nice_rlim = 20 - nice; @@ -69519,7 +69769,7 @@ index 468bdd4..b941572 100644 return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) || capable(CAP_SYS_NICE)); } -@@ -4130,7 +4132,8 @@ SYSCALL_DEFINE1(nice, int, increment) +@@ -4136,7 +4138,8 @@ SYSCALL_DEFINE1(nice, int, increment) if (nice > 19) nice = 19; @@ -69529,7 +69779,7 @@ index 468bdd4..b941572 100644 return -EPERM; retval = security_task_setnice(current, nice); -@@ -4284,6 +4287,7 @@ recheck: +@@ -4290,6 +4293,7 @@ recheck: unsigned long rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO); @@ -70818,6 +71068,24 @@ index 80b9c76..9e32279 100644 } EXPORT_SYMBOL(devm_ioport_unmap); +diff --git a/lib/digsig.c b/lib/digsig.c +index 286d558..8c0e629 100644 +--- a/lib/digsig.c ++++ b/lib/digsig.c +@@ -163,9 +163,11 @@ static int digsig_verify_rsa(struct key *key, + memcpy(out1 + head, p, l); + + err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); ++ if (err) ++ goto err; + +- if (!err && len == hlen) +- err = memcmp(out2, h, hlen); ++ if (len != hlen || memcmp(out2, h, hlen)) ++ err = -EINVAL; + + err: + mpi_free(in); diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 66ce414..6f0a0dd 100644 --- a/lib/dma-debug.c @@ -71440,15 +71708,19 @@ index 6de0d61..da836cf 100644 /* keep elevated page count for bad page */ return ret; diff --git a/mm/memory.c b/mm/memory.c -index 2466d12..08be4f6 100644 +index 2466d12..595ed79 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -434,8 +434,12 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud, - return; +@@ -422,6 +422,7 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud, + free_pte_range(tlb, pmd, addr); + } while (pmd++, addr = next, addr != end); - pmd = pmd_offset(pud, start); -+ +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_PER_CPU_PGD) + start &= PUD_MASK; + if (start < floor) + return; +@@ -436,6 +437,8 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud, + pmd = pmd_offset(pud, start); pud_clear(pud); pmd_free_tlb(tlb, pmd, start); +#endif @@ -71456,11 +71728,15 @@ index 2466d12..08be4f6 100644 } static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, -@@ -466,9 +470,12 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, - if (end - 1 > ceiling - 1) - return; +@@ -455,6 +458,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, + free_pmd_range(tlb, pud, addr, next, floor, ceiling); + } while (pud++, addr = next, addr != end); +#if !defined(CONFIG_X86_64) || !defined(CONFIG_PAX_PER_CPU_PGD) + start &= PGDIR_MASK; + if (start < floor) + return; +@@ -469,6 +473,8 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, pud = pud_offset(pgd, start); pgd_clear(pgd); pud_free_tlb(tlb, pud, start); @@ -71469,7 +71745,7 @@ index 2466d12..08be4f6 100644 } /* -@@ -1602,12 +1609,6 @@ no_page_table: +@@ -1602,12 +1608,6 @@ no_page_table: return page; } @@ -71482,7 +71758,7 @@ index 2466d12..08be4f6 100644 /** * __get_user_pages() - pin user pages in memory * @tsk: task_struct of target task -@@ -1680,10 +1681,10 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1680,10 +1680,10 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); i = 0; @@ -71495,7 +71771,7 @@ index 2466d12..08be4f6 100644 if (!vma && in_gate_area(mm, start)) { unsigned long pg = start & PAGE_MASK; pgd_t *pgd; -@@ -1731,7 +1732,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1731,7 +1731,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, goto next_page; } @@ -71504,7 +71780,7 @@ index 2466d12..08be4f6 100644 (vma->vm_flags & (VM_IO | VM_PFNMAP)) || !(vm_flags & vma->vm_flags)) return i ? : -EFAULT; -@@ -1758,11 +1759,6 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1758,11 +1758,6 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, int ret; unsigned int fault_flags = 0; @@ -71516,7 +71792,7 @@ index 2466d12..08be4f6 100644 if (foll_flags & FOLL_WRITE) fault_flags |= FAULT_FLAG_WRITE; if (nonblocking) -@@ -1836,7 +1832,7 @@ next_page: +@@ -1836,7 +1831,7 @@ next_page: start += PAGE_SIZE; nr_pages--; } while (nr_pages && start < vma->vm_end); @@ -71525,7 +71801,7 @@ index 2466d12..08be4f6 100644 return i; } EXPORT_SYMBOL(__get_user_pages); -@@ -2043,6 +2039,10 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, +@@ -2043,6 +2038,10 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, page_add_file_rmap(page); set_pte_at(mm, addr, pte, mk_pte(page, prot)); @@ -71536,7 +71812,7 @@ index 2466d12..08be4f6 100644 retval = 0; pte_unmap_unlock(pte, ptl); return retval; -@@ -2077,10 +2077,22 @@ out: +@@ -2077,10 +2076,22 @@ out: int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page) { @@ -71559,7 +71835,7 @@ index 2466d12..08be4f6 100644 vma->vm_flags |= VM_INSERTPAGE; return insert_page(vma, addr, page, vma->vm_page_prot); } -@@ -2166,6 +2178,7 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, +@@ -2166,6 +2177,7 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { BUG_ON(!(vma->vm_flags & VM_MIXEDMAP)); @@ -71567,7 +71843,7 @@ index 2466d12..08be4f6 100644 if (addr < vma->vm_start || addr >= vma->vm_end) return -EFAULT; -@@ -2373,7 +2386,9 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, +@@ -2373,7 +2385,9 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, BUG_ON(pud_huge(*pud)); @@ -71578,7 +71854,7 @@ index 2466d12..08be4f6 100644 if (!pmd) return -ENOMEM; do { -@@ -2393,7 +2408,9 @@ static int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd, +@@ -2393,7 +2407,9 @@ static int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd, unsigned long next; int err; @@ -71589,7 +71865,7 @@ index 2466d12..08be4f6 100644 if (!pud) return -ENOMEM; do { -@@ -2481,6 +2498,186 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo +@@ -2481,6 +2497,186 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo copy_user_highpage(dst, src, va, vma); } @@ -71776,7 +72052,7 @@ index 2466d12..08be4f6 100644 /* * This routine handles present pages, when users try to write * to a shared page. It is done by copying the page to a new address -@@ -2692,6 +2889,12 @@ gotten: +@@ -2692,6 +2888,12 @@ gotten: */ page_table = pte_offset_map_lock(mm, pmd, address, &ptl); if (likely(pte_same(*page_table, orig_pte))) { @@ -71789,7 +72065,7 @@ index 2466d12..08be4f6 100644 if (old_page) { if (!PageAnon(old_page)) { dec_mm_counter_fast(mm, MM_FILEPAGES); -@@ -2743,6 +2946,10 @@ gotten: +@@ -2743,6 +2945,10 @@ gotten: page_remove_rmap(old_page); } @@ -71800,7 +72076,7 @@ index 2466d12..08be4f6 100644 /* Free the old page.. */ new_page = old_page; ret |= VM_FAULT_WRITE; -@@ -3022,6 +3229,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3022,6 +3228,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, swap_free(entry); if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) try_to_free_swap(page); @@ -71812,7 +72088,7 @@ index 2466d12..08be4f6 100644 unlock_page(page); if (swapcache) { /* -@@ -3045,6 +3257,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3045,6 +3256,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, address, page_table); @@ -71824,7 +72100,7 @@ index 2466d12..08be4f6 100644 unlock: pte_unmap_unlock(page_table, ptl); out: -@@ -3064,40 +3281,6 @@ out_release: +@@ -3064,40 +3280,6 @@ out_release: } /* @@ -71865,7 +72141,7 @@ index 2466d12..08be4f6 100644 * We enter with non-exclusive mmap_sem (to exclude vma changes, * but allow concurrent faults), and pte mapped but not yet locked. * We return with mmap_sem still held, but pte unmapped and unlocked. -@@ -3106,27 +3289,23 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3106,27 +3288,23 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, unsigned int flags) { @@ -71898,7 +72174,7 @@ index 2466d12..08be4f6 100644 if (unlikely(anon_vma_prepare(vma))) goto oom; page = alloc_zeroed_user_highpage_movable(vma, address); -@@ -3145,6 +3324,11 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3145,6 +3323,11 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, if (!pte_none(*page_table)) goto release; @@ -71910,7 +72186,7 @@ index 2466d12..08be4f6 100644 inc_mm_counter_fast(mm, MM_ANONPAGES); page_add_new_anon_rmap(page, vma, address); setpte: -@@ -3152,6 +3336,12 @@ setpte: +@@ -3152,6 +3335,12 @@ setpte: /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, address, page_table); @@ -71923,7 +72199,7 @@ index 2466d12..08be4f6 100644 unlock: pte_unmap_unlock(page_table, ptl); return 0; -@@ -3295,6 +3485,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3295,6 +3484,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, */ /* Only go through if we didn't race with anybody else... */ if (likely(pte_same(*page_table, orig_pte))) { @@ -71936,7 +72212,7 @@ index 2466d12..08be4f6 100644 flush_icache_page(vma, page); entry = mk_pte(page, vma->vm_page_prot); if (flags & FAULT_FLAG_WRITE) -@@ -3314,6 +3510,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3314,6 +3509,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, /* no need to invalidate: a not-present page won't be cached */ update_mmu_cache(vma, address, page_table); @@ -71951,7 +72227,7 @@ index 2466d12..08be4f6 100644 } else { if (cow_page) mem_cgroup_uncharge_page(cow_page); -@@ -3467,6 +3671,12 @@ int handle_pte_fault(struct mm_struct *mm, +@@ -3467,6 +3670,12 @@ int handle_pte_fault(struct mm_struct *mm, if (flags & FAULT_FLAG_WRITE) flush_tlb_fix_spurious_fault(vma, address); } @@ -71964,7 +72240,7 @@ index 2466d12..08be4f6 100644 unlock: pte_unmap_unlock(pte, ptl); return 0; -@@ -3483,6 +3693,10 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3483,6 +3692,10 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, pmd_t *pmd; pte_t *pte; @@ -71975,7 +72251,7 @@ index 2466d12..08be4f6 100644 __set_current_state(TASK_RUNNING); count_vm_event(PGFAULT); -@@ -3494,6 +3708,34 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -3494,6 +3707,34 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(is_vm_hugetlb_page(vma))) return hugetlb_fault(mm, vma, address, flags); @@ -72010,7 +72286,7 @@ index 2466d12..08be4f6 100644 retry: pgd = pgd_offset(mm, address); pud = pud_alloc(mm, pgd, address); -@@ -3535,7 +3777,7 @@ retry: +@@ -3535,7 +3776,7 @@ retry: * run pte_offset_map on the pmd, if an huge pmd could * materialize from under us from a different thread. */ @@ -72019,7 +72295,7 @@ index 2466d12..08be4f6 100644 return VM_FAULT_OOM; /* if an huge pmd materialized from under us just retry later */ if (unlikely(pmd_trans_huge(*pmd))) -@@ -3572,6 +3814,23 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +@@ -3572,6 +3813,23 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) spin_unlock(&mm->page_table_lock); return 0; } @@ -72043,7 +72319,7 @@ index 2466d12..08be4f6 100644 #endif /* __PAGETABLE_PUD_FOLDED */ #ifndef __PAGETABLE_PMD_FOLDED -@@ -3602,6 +3861,30 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) +@@ -3602,6 +3860,30 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) spin_unlock(&mm->page_table_lock); return 0; } @@ -72074,7 +72350,7 @@ index 2466d12..08be4f6 100644 #endif /* __PAGETABLE_PMD_FOLDED */ int make_pages_present(unsigned long addr, unsigned long end) -@@ -3639,7 +3922,7 @@ static int __init gate_vma_init(void) +@@ -3639,7 +3921,7 @@ static int __init gate_vma_init(void) gate_vma.vm_start = FIXADDR_USER_START; gate_vma.vm_end = FIXADDR_USER_END; gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; @@ -72084,7 +72360,7 @@ index 2466d12..08be4f6 100644 return 0; } diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 1d771e4..64b57d0 100644 +index b12b28a..64b57d0 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -619,6 +619,10 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, @@ -72159,15 +72435,6 @@ index 1d771e4..64b57d0 100644 err = do_migrate_pages(mm, old, new, capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); -@@ -2556,7 +2589,7 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) - break; - - default: -- BUG(); -+ return -EINVAL; - } - - l = strlen(policy_modes[mode]); diff --git a/mm/mlock.c b/mm/mlock.c index ef726e8..cd7f1ec 100644 --- a/mm/mlock.c @@ -72255,7 +72522,7 @@ index ef726e8..cd7f1ec 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index 3edfcdf..4a27ae9 100644 +index fa1f274..86de476 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -47,6 +47,16 @@ @@ -72629,7 +72896,7 @@ index 3edfcdf..4a27ae9 100644 if (vm_flags & VM_LOCKED) { if (!mlock_vma_pages_range(vma, addr, addr + len)) mm->locked_vm += (len >> PAGE_SHIFT); -@@ -1371,6 +1521,12 @@ unmap_and_free_vma: +@@ -1370,6 +1520,12 @@ unmap_and_free_vma: unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); charged = 0; free_vma: @@ -72642,7 +72909,7 @@ index 3edfcdf..4a27ae9 100644 kmem_cache_free(vm_area_cachep, vma); unacct_error: if (charged) -@@ -1378,6 +1534,44 @@ unacct_error: +@@ -1377,6 +1533,44 @@ unacct_error: return error; } @@ -72687,7 +72954,7 @@ index 3edfcdf..4a27ae9 100644 /* Get an address range which is currently unmapped. * For shmat() with addr=0. * -@@ -1404,18 +1598,23 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, +@@ -1403,18 +1597,23 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (flags & MAP_FIXED) return addr; @@ -72718,7 +72985,7 @@ index 3edfcdf..4a27ae9 100644 } full_search: -@@ -1426,34 +1625,40 @@ full_search: +@@ -1425,34 +1624,40 @@ full_search: * Start a new search - just in case we missed * some holes. */ @@ -72770,7 +73037,7 @@ index 3edfcdf..4a27ae9 100644 mm->free_area_cache = addr; } -@@ -1469,7 +1674,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1468,7 +1673,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; @@ -72779,7 +73046,7 @@ index 3edfcdf..4a27ae9 100644 /* requested length too big for entire address space */ if (len > TASK_SIZE) -@@ -1478,13 +1683,18 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1477,13 +1682,18 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, if (flags & MAP_FIXED) return addr; @@ -72802,7 +73069,7 @@ index 3edfcdf..4a27ae9 100644 } /* check if free_area_cache is useful for us */ -@@ -1508,7 +1718,7 @@ try_again: +@@ -1507,7 +1717,7 @@ try_again: * return with success: */ vma = find_vma(mm, addr); @@ -72811,7 +73078,7 @@ index 3edfcdf..4a27ae9 100644 /* remember the address as a hint for next time */ return (mm->free_area_cache = addr); -@@ -1517,8 +1727,8 @@ try_again: +@@ -1516,8 +1726,8 @@ try_again: mm->cached_hole_size = vma->vm_start - addr; /* try just below the current vma->vm_start */ @@ -72822,7 +73089,7 @@ index 3edfcdf..4a27ae9 100644 fail: /* -@@ -1541,13 +1751,21 @@ fail: +@@ -1540,13 +1750,21 @@ fail: * can happen with large stack limits and large mmap() * allocations. */ @@ -72846,7 +73113,7 @@ index 3edfcdf..4a27ae9 100644 mm->cached_hole_size = ~0UL; return addr; -@@ -1556,6 +1774,12 @@ fail: +@@ -1555,6 +1773,12 @@ fail: void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) { @@ -72859,7 +73126,7 @@ index 3edfcdf..4a27ae9 100644 /* * Is this a new hole at the highest possible address? */ -@@ -1563,8 +1787,10 @@ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) +@@ -1562,8 +1786,10 @@ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) mm->free_area_cache = addr; /* dont allow allocations above current base */ @@ -72871,7 +73138,7 @@ index 3edfcdf..4a27ae9 100644 } unsigned long -@@ -1663,6 +1889,28 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, +@@ -1662,6 +1888,28 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, return vma; } @@ -72900,7 +73167,7 @@ index 3edfcdf..4a27ae9 100644 /* * Verify that the stack growth is acceptable and * update accounting. This is shared with both the -@@ -1679,6 +1927,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -1678,6 +1926,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns return -ENOMEM; /* Stack limit test */ @@ -72908,7 +73175,7 @@ index 3edfcdf..4a27ae9 100644 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) return -ENOMEM; -@@ -1689,6 +1938,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -1688,6 +1937,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns locked = mm->locked_vm + grow; limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur); limit >>= PAGE_SHIFT; @@ -72916,7 +73183,7 @@ index 3edfcdf..4a27ae9 100644 if (locked > limit && !capable(CAP_IPC_LOCK)) return -ENOMEM; } -@@ -1719,37 +1969,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -1718,37 +1968,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns * PA-RISC uses this for its stack; IA64 for its Register Backing Store. * vma is the last one with address > vma->vm_end. Have to extend vma. */ @@ -72974,7 +73241,7 @@ index 3edfcdf..4a27ae9 100644 unsigned long size, grow; size = address - vma->vm_start; -@@ -1764,6 +2025,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) +@@ -1763,6 +2024,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) } } } @@ -72983,7 +73250,7 @@ index 3edfcdf..4a27ae9 100644 vma_unlock_anon_vma(vma); khugepaged_enter_vma_merge(vma); return error; -@@ -1777,6 +2040,8 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -1776,6 +2039,8 @@ int expand_downwards(struct vm_area_struct *vma, unsigned long address) { int error; @@ -72992,7 +73259,7 @@ index 3edfcdf..4a27ae9 100644 /* * We must make sure the anon_vma is allocated -@@ -1790,6 +2055,15 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -1789,6 +2054,15 @@ int expand_downwards(struct vm_area_struct *vma, if (error) return error; @@ -73008,7 +73275,7 @@ index 3edfcdf..4a27ae9 100644 vma_lock_anon_vma(vma); /* -@@ -1799,9 +2073,17 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -1798,9 +2072,17 @@ int expand_downwards(struct vm_area_struct *vma, */ /* Somebody else might have raced and expanded it already */ @@ -73027,7 +73294,7 @@ index 3edfcdf..4a27ae9 100644 size = vma->vm_end - address; grow = (vma->vm_start - address) >> PAGE_SHIFT; -@@ -1811,11 +2093,22 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -1810,11 +2092,22 @@ int expand_downwards(struct vm_area_struct *vma, if (!error) { vma->vm_start = address; vma->vm_pgoff -= grow; @@ -73050,7 +73317,7 @@ index 3edfcdf..4a27ae9 100644 khugepaged_enter_vma_merge(vma); return error; } -@@ -1887,6 +2180,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -1886,6 +2179,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); @@ -73064,7 +73331,7 @@ index 3edfcdf..4a27ae9 100644 if (vma->vm_flags & VM_ACCOUNT) nr_accounted += nrpages; mm->total_vm -= nrpages; -@@ -1933,6 +2233,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -1932,6 +2232,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, insertion_point = (prev ? &prev->vm_next : &mm->mmap); vma->vm_prev = NULL; do { @@ -73081,7 +73348,7 @@ index 3edfcdf..4a27ae9 100644 rb_erase(&vma->vm_rb, &mm->mm_rb); mm->map_count--; tail_vma = vma; -@@ -1961,14 +2271,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1960,14 +2270,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct *new; int err = -ENOMEM; @@ -73115,7 +73382,7 @@ index 3edfcdf..4a27ae9 100644 /* most fields are the same, copy all, and then fixup */ *new = *vma; -@@ -1981,6 +2310,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1980,6 +2309,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); } @@ -73138,7 +73405,7 @@ index 3edfcdf..4a27ae9 100644 pol = mpol_dup(vma_policy(vma)); if (IS_ERR(pol)) { err = PTR_ERR(pol); -@@ -2006,6 +2351,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2005,6 +2350,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -73181,7 +73448,7 @@ index 3edfcdf..4a27ae9 100644 /* Success. */ if (!err) return 0; -@@ -2018,10 +2399,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2017,10 +2398,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, removed_exe_file_vma(mm); fput(new->vm_file); } @@ -73201,7 +73468,7 @@ index 3edfcdf..4a27ae9 100644 kmem_cache_free(vm_area_cachep, new); out_err: return err; -@@ -2034,6 +2423,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2033,6 +2422,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, int new_below) { @@ -73217,7 +73484,7 @@ index 3edfcdf..4a27ae9 100644 if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; -@@ -2045,11 +2443,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2044,11 +2442,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, * work. This now handles partial unmappings. * Jeremy Fitzhardinge <jeremy@goop.org> */ @@ -73248,7 +73515,7 @@ index 3edfcdf..4a27ae9 100644 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) return -EINVAL; -@@ -2124,6 +2541,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) +@@ -2123,6 +2540,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) /* Fix up all other VM information */ remove_vma_list(mm, vma); @@ -73257,7 +73524,7 @@ index 3edfcdf..4a27ae9 100644 return 0; } -@@ -2132,6 +2551,13 @@ int vm_munmap(unsigned long start, size_t len) +@@ -2131,6 +2550,13 @@ int vm_munmap(unsigned long start, size_t len) int ret; struct mm_struct *mm = current->mm; @@ -73271,7 +73538,7 @@ index 3edfcdf..4a27ae9 100644 down_write(&mm->mmap_sem); ret = do_munmap(mm, start, len); up_write(&mm->mmap_sem); -@@ -2145,16 +2571,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +@@ -2144,16 +2570,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) return vm_munmap(addr, len); } @@ -73288,7 +73555,7 @@ index 3edfcdf..4a27ae9 100644 /* * this is really a simplified "do_mmap". it only handles * anonymous maps. eventually we may be able to do some -@@ -2168,6 +2584,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2167,6 +2583,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; int error; @@ -73296,7 +73563,7 @@ index 3edfcdf..4a27ae9 100644 len = PAGE_ALIGN(len); if (!len) -@@ -2175,16 +2592,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2174,16 +2591,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -73328,7 +73595,7 @@ index 3edfcdf..4a27ae9 100644 locked += mm->locked_vm; lock_limit = rlimit(RLIMIT_MEMLOCK); lock_limit >>= PAGE_SHIFT; -@@ -2201,22 +2632,22 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2200,22 +2631,22 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) /* * Clear old maps. this also does some error checking for us */ @@ -73356,7 +73623,7 @@ index 3edfcdf..4a27ae9 100644 return -ENOMEM; /* Can we just expand an old private anonymous mapping? */ -@@ -2230,7 +2661,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2229,7 +2660,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) */ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { @@ -73365,7 +73632,7 @@ index 3edfcdf..4a27ae9 100644 return -ENOMEM; } -@@ -2244,11 +2675,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2243,11 +2674,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) vma_link(mm, vma, prev, rb_link, rb_parent); out: perf_event_mmap(vma); @@ -73380,7 +73647,7 @@ index 3edfcdf..4a27ae9 100644 return addr; } -@@ -2306,6 +2738,7 @@ void exit_mmap(struct mm_struct *mm) +@@ -2305,6 +2737,7 @@ void exit_mmap(struct mm_struct *mm) while (vma) { if (vma->vm_flags & VM_ACCOUNT) nr_accounted += vma_pages(vma); @@ -73388,7 +73655,7 @@ index 3edfcdf..4a27ae9 100644 vma = remove_vma(vma); } vm_unacct_memory(nr_accounted); -@@ -2322,6 +2755,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2321,6 +2754,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) struct vm_area_struct * __vma, * prev; struct rb_node ** rb_link, * rb_parent; @@ -73402,7 +73669,7 @@ index 3edfcdf..4a27ae9 100644 /* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index -@@ -2348,7 +2788,21 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2347,7 +2787,21 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) if (vma->vm_file && uprobe_mmap(vma)) return -EINVAL; @@ -73424,7 +73691,7 @@ index 3edfcdf..4a27ae9 100644 return 0; } -@@ -2367,6 +2821,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2366,6 +2820,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, struct mempolicy *pol; bool faulted_in_anon_vma = true; @@ -73433,7 +73700,7 @@ index 3edfcdf..4a27ae9 100644 /* * If anonymous vma has not yet been faulted, update new pgoff * to match new location, to increase its chance of merging. -@@ -2438,6 +2894,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2437,6 +2893,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, return NULL; } @@ -73473,7 +73740,7 @@ index 3edfcdf..4a27ae9 100644 /* * Return true if the calling process may expand its vm space by the passed * number of pages -@@ -2449,6 +2938,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) +@@ -2448,6 +2937,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT; @@ -73486,7 +73753,7 @@ index 3edfcdf..4a27ae9 100644 if (cur + npages > lim) return 0; return 1; -@@ -2519,6 +3014,22 @@ int install_special_mapping(struct mm_struct *mm, +@@ -2518,6 +3013,22 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_start = addr; vma->vm_end = addr + len; @@ -74348,7 +74615,7 @@ index e901a36..9ff3f90 100644 * ksize - get the actual amount of memory allocated for a given object * @objp: Pointer to the object diff --git a/mm/slob.c b/mm/slob.c -index 8105be4..3e3e9cd 100644 +index 8105be4..33e52d7 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -29,7 +29,7 @@ @@ -74368,17 +74635,18 @@ index 8105be4..3e3e9cd 100644 #include <linux/slab.h> #include <linux/mm.h> #include <linux/swap.h> /* struct reclaim_state */ -@@ -102,7 +103,8 @@ struct slob_page { +@@ -100,9 +101,8 @@ struct slob_page { + union { + struct { unsigned long flags; /* mandatory */ - atomic_t _count; /* mandatory */ +- atomic_t _count; /* mandatory */ slobidx_t units; /* free units left in page */ - unsigned long pad[2]; -+ unsigned long pad[1]; + unsigned long size; /* size when >=PAGE_SIZE */ slob_t *free; /* first free slob_t in page */ struct list_head list; /* linked list of free pages */ }; -@@ -135,7 +137,7 @@ static LIST_HEAD(free_slob_large); +@@ -135,7 +135,7 @@ static LIST_HEAD(free_slob_large); */ static inline int is_slob_page(struct slob_page *sp) { @@ -74387,7 +74655,7 @@ index 8105be4..3e3e9cd 100644 } static inline void set_slob_page(struct slob_page *sp) -@@ -150,7 +152,7 @@ static inline void clear_slob_page(struct slob_page *sp) +@@ -150,7 +150,7 @@ static inline void clear_slob_page(struct slob_page *sp) static inline struct slob_page *slob_page(const void *addr) { @@ -74396,7 +74664,7 @@ index 8105be4..3e3e9cd 100644 } /* -@@ -210,7 +212,7 @@ static void set_slob(slob_t *s, slobidx_t size, slob_t *next) +@@ -210,7 +210,7 @@ static void set_slob(slob_t *s, slobidx_t size, slob_t *next) /* * Return the size of a slob block. */ @@ -74405,7 +74673,7 @@ index 8105be4..3e3e9cd 100644 { if (s->units > 0) return s->units; -@@ -220,7 +222,7 @@ static slobidx_t slob_units(slob_t *s) +@@ -220,7 +220,7 @@ static slobidx_t slob_units(slob_t *s) /* * Return the next free slob block pointer after this one. */ @@ -74414,7 +74682,7 @@ index 8105be4..3e3e9cd 100644 { slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK); slobidx_t next; -@@ -235,7 +237,7 @@ static slob_t *slob_next(slob_t *s) +@@ -235,7 +235,7 @@ static slob_t *slob_next(slob_t *s) /* * Returns true if s is the last free block in its page. */ @@ -74423,7 +74691,7 @@ index 8105be4..3e3e9cd 100644 { return !((unsigned long)slob_next(s) & ~PAGE_MASK); } -@@ -254,6 +256,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) +@@ -254,6 +254,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) if (!page) return NULL; @@ -74431,7 +74699,7 @@ index 8105be4..3e3e9cd 100644 return page_address(page); } -@@ -370,11 +373,11 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) +@@ -370,11 +371,11 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) if (!b) return NULL; sp = slob_page(b); @@ -74444,7 +74712,7 @@ index 8105be4..3e3e9cd 100644 INIT_LIST_HEAD(&sp->list); set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE)); set_slob_page_free(sp, slob_list); -@@ -476,10 +479,9 @@ out: +@@ -476,10 +477,9 @@ out: * End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend. */ @@ -74457,7 +74725,7 @@ index 8105be4..3e3e9cd 100644 void *ret; gfp &= gfp_allowed_mask; -@@ -494,7 +496,10 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) +@@ -494,7 +494,10 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) if (!m) return NULL; @@ -74469,7 +74737,7 @@ index 8105be4..3e3e9cd 100644 ret = (void *)m + align; trace_kmalloc_node(_RET_IP_, ret, -@@ -506,16 +511,25 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) +@@ -506,16 +509,25 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node) gfp |= __GFP_COMP; ret = slob_new_pages(gfp, order, node); if (ret) { @@ -74499,7 +74767,7 @@ index 8105be4..3e3e9cd 100644 return ret; } EXPORT_SYMBOL(__kmalloc_node); -@@ -533,13 +547,88 @@ void kfree(const void *block) +@@ -533,13 +545,88 @@ void kfree(const void *block) sp = slob_page(block); if (is_slob_page(sp)) { int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); @@ -74557,7 +74825,7 @@ index 8105be4..3e3e9cd 100644 + base = (void *)((unsigned long)ptr & PAGE_MASK); + free = sp->free; + -+ while (!slob_last(free) && (void *)free <= ptr) { ++ while ((void *)free <= ptr) { + base = free + slob_units(free); + free = slob_next(free); + } @@ -74591,7 +74859,7 @@ index 8105be4..3e3e9cd 100644 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */ size_t ksize(const void *block) { -@@ -552,10 +641,10 @@ size_t ksize(const void *block) +@@ -552,10 +639,10 @@ size_t ksize(const void *block) sp = slob_page(block); if (is_slob_page(sp)) { int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); @@ -74605,7 +74873,7 @@ index 8105be4..3e3e9cd 100644 } EXPORT_SYMBOL(ksize); -@@ -571,8 +660,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, +@@ -571,8 +658,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, { struct kmem_cache *c; @@ -74619,7 +74887,7 @@ index 8105be4..3e3e9cd 100644 if (c) { c->name = name; -@@ -614,17 +708,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) +@@ -614,17 +706,25 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) lockdep_trace_alloc(flags); @@ -74645,7 +74913,7 @@ index 8105be4..3e3e9cd 100644 if (c->ctor) c->ctor(b); -@@ -636,10 +738,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); +@@ -636,10 +736,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); static void __kmem_cache_free(void *b, int size) { @@ -74664,7 +74932,7 @@ index 8105be4..3e3e9cd 100644 } static void kmem_rcu_free(struct rcu_head *head) -@@ -652,17 +760,31 @@ static void kmem_rcu_free(struct rcu_head *head) +@@ -652,17 +758,31 @@ static void kmem_rcu_free(struct rcu_head *head) void kmem_cache_free(struct kmem_cache *c, void *b) { @@ -75651,10 +75919,10 @@ index 5914623..bedc768 100644 uf.opcode = f->opcode; uf.event_mask[0] = *((u32 *) f->event_mask + 0); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c -index 4554e80..b778671 100644 +index 7568a6f..ea3097b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c -@@ -2798,8 +2798,10 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi +@@ -2799,8 +2799,10 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi break; case L2CAP_CONF_RFC: @@ -76311,28 +76579,6 @@ index 5fd1467..8b70900 100644 } EXPORT_SYMBOL_GPL(sock_diag_save_cookie); -diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h -index 75c3582..fb85d37 100644 ---- a/net/dccp/ccid.h -+++ b/net/dccp/ccid.h -@@ -246,7 +246,7 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk, - u32 __user *optval, int __user *optlen) - { - int rc = -ENOPROTOOPT; -- if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) -+ if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) - rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len, - optval, optlen); - return rc; -@@ -257,7 +257,7 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk, - u32 __user *optval, int __user *optlen) - { - int rc = -ENOPROTOOPT; -- if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) -+ if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) - rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len, - optval, optlen); - return rc; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 8c67bed..ce0d140 100644 --- a/net/dccp/ccids/ccid3.c @@ -78608,7 +78854,7 @@ index 31c7bfc..bc380ae 100644 to += addrlen; cnt++; diff --git a/net/socket.c b/net/socket.c -index 0452dca..5af9802 100644 +index a990aa9..5af9802 100644 --- a/net/socket.c +++ b/net/socket.c @@ -88,6 +88,7 @@ @@ -78779,24 +79025,6 @@ index 0452dca..5af9802 100644 uaddr_len = COMPAT_NAMELEN(msg); if (MSG_CMSG_COMPAT & flags) { err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); -@@ -2605,7 +2665,7 @@ static int do_siocgstamp(struct net *net, struct socket *sock, - err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); - set_fs(old_fs); - if (!err) -- err = compat_put_timeval(up, &ktv); -+ err = compat_put_timeval(&ktv, up); - - return err; - } -@@ -2621,7 +2681,7 @@ static int do_siocgstampns(struct net *net, struct socket *sock, - err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); - set_fs(old_fs); - if (!err) -- err = compat_put_timespec(up, &kts); -+ err = compat_put_timespec(&kts, up); - - return err; - } @@ -2658,6 +2718,7 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) return -EFAULT; @@ -79396,10 +79624,31 @@ index 5b228f9..6aca4e3 100644 if (init_replay) { err = xfrm_init_replay(x); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index 44293b3..be1d3e58 100644 +index 44293b3..2c00fd0 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c -@@ -1413,6 +1413,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) +@@ -872,6 +872,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + { + struct xfrm_dump_info info; + struct sk_buff *skb; ++ int err; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!skb) +@@ -882,9 +883,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, + info.nlmsg_seq = seq; + info.nlmsg_flags = 0; + +- if (dump_one_state(x, 0, &info)) { ++ err = dump_one_state(x, 0, &info); ++ if (err) { + kfree_skb(skb); +- return NULL; ++ return ERR_PTR(err); + } + + return skb; +@@ -1413,6 +1415,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) struct xfrm_user_tmpl *up = &vec[i]; struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; diff --git a/3.5.3/4430_grsec-remove-localversion-grsec.patch b/3.5.4/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.5.3/4430_grsec-remove-localversion-grsec.patch +++ b/3.5.4/4430_grsec-remove-localversion-grsec.patch diff --git a/3.5.3/4435_grsec-mute-warnings.patch b/3.5.4/4435_grsec-mute-warnings.patch index e1a7a3c..e1a7a3c 100644 --- a/3.5.3/4435_grsec-mute-warnings.patch +++ b/3.5.4/4435_grsec-mute-warnings.patch diff --git a/3.5.3/4440_grsec-remove-protected-paths.patch b/3.5.4/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.5.3/4440_grsec-remove-protected-paths.patch +++ b/3.5.4/4440_grsec-remove-protected-paths.patch diff --git a/3.5.3/4450_grsec-kconfig-default-gids.patch b/3.5.4/4450_grsec-kconfig-default-gids.patch index eb5154a..eb5154a 100644 --- a/3.5.3/4450_grsec-kconfig-default-gids.patch +++ b/3.5.4/4450_grsec-kconfig-default-gids.patch diff --git a/3.5.3/4465_selinux-avc_audit-log-curr_ip.patch b/3.5.4/4465_selinux-avc_audit-log-curr_ip.patch index fd7ab67..fd7ab67 100644 --- a/3.5.3/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.5.4/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.5.3/4470_disable-compat_vdso.patch b/3.5.4/4470_disable-compat_vdso.patch index 68af025..68af025 100644 --- a/3.5.3/4470_disable-compat_vdso.patch +++ b/3.5.4/4470_disable-compat_vdso.patch |