diff options
298 files changed, 3464 insertions, 2348 deletions
diff --git a/Documentation/networking/segmentation-offloads.txt b/Documentation/networking/segmentation-offloads.txt index 2f09455a993a..d47480b61ac6 100644 --- a/Documentation/networking/segmentation-offloads.txt +++ b/Documentation/networking/segmentation-offloads.txt | |||
| @@ -13,6 +13,7 @@ The following technologies are described: | |||
| 13 | * Generic Segmentation Offload - GSO | 13 | * Generic Segmentation Offload - GSO |
| 14 | * Generic Receive Offload - GRO | 14 | * Generic Receive Offload - GRO |
| 15 | * Partial Generic Segmentation Offload - GSO_PARTIAL | 15 | * Partial Generic Segmentation Offload - GSO_PARTIAL |
| 16 | * SCTP accelleration with GSO - GSO_BY_FRAGS | ||
| 16 | 17 | ||
| 17 | TCP Segmentation Offload | 18 | TCP Segmentation Offload |
| 18 | ======================== | 19 | ======================== |
| @@ -49,6 +50,10 @@ datagram into multiple IPv4 fragments. Many of the requirements for UDP | |||
| 49 | fragmentation offload are the same as TSO. However the IPv4 ID for | 50 | fragmentation offload are the same as TSO. However the IPv4 ID for |
| 50 | fragments should not increment as a single IPv4 datagram is fragmented. | 51 | fragments should not increment as a single IPv4 datagram is fragmented. |
| 51 | 52 | ||
| 53 | UFO is deprecated: modern kernels will no longer generate UFO skbs, but can | ||
| 54 | still receive them from tuntap and similar devices. Offload of UDP-based | ||
| 55 | tunnel protocols is still supported. | ||
| 56 | |||
| 52 | IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads | 57 | IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads |
| 53 | ======================================================== | 58 | ======================================================== |
| 54 | 59 | ||
| @@ -83,10 +88,10 @@ SKB_GSO_UDP_TUNNEL_CSUM. These two additional tunnel types reflect the | |||
| 83 | fact that the outer header also requests to have a non-zero checksum | 88 | fact that the outer header also requests to have a non-zero checksum |
| 84 | included in the outer header. | 89 | included in the outer header. |
| 85 | 90 | ||
| 86 | Finally there is SKB_GSO_REMCSUM which indicates that a given tunnel header | 91 | Finally there is SKB_GSO_TUNNEL_REMCSUM which indicates that a given tunnel |
| 87 | has requested a remote checksum offload. In this case the inner headers | 92 | header has requested a remote checksum offload. In this case the inner |
| 88 | will be left with a partial checksum and only the outer header checksum | 93 | headers will be left with a partial checksum and only the outer header |
| 89 | will be computed. | 94 | checksum will be computed. |
| 90 | 95 | ||
| 91 | Generic Segmentation Offload | 96 | Generic Segmentation Offload |
| 92 | ============================ | 97 | ============================ |
| @@ -128,3 +133,28 @@ values for if the header was simply duplicated. The one exception to this | |||
| 128 | is the outer IPv4 ID field. It is up to the device drivers to guarantee | 133 | is the outer IPv4 ID field. It is up to the device drivers to guarantee |
| 129 | that the IPv4 ID field is incremented in the case that a given header does | 134 | that the IPv4 ID field is incremented in the case that a given header does |
| 130 | not have the DF bit set. | 135 | not have the DF bit set. |
| 136 | |||
| 137 | SCTP accelleration with GSO | ||
| 138 | =========================== | ||
| 139 | |||
| 140 | SCTP - despite the lack of hardware support - can still take advantage of | ||
| 141 | GSO to pass one large packet through the network stack, rather than | ||
| 142 | multiple small packets. | ||
| 143 | |||
| 144 | This requires a different approach to other offloads, as SCTP packets | ||
| 145 | cannot be just segmented to (P)MTU. Rather, the chunks must be contained in | ||
| 146 | IP segments, padding respected. So unlike regular GSO, SCTP can't just | ||
| 147 | generate a big skb, set gso_size to the fragmentation point and deliver it | ||
| 148 | to IP layer. | ||
| 149 | |||
| 150 | Instead, the SCTP protocol layer builds an skb with the segments correctly | ||
| 151 | padded and stored as chained skbs, and skb_segment() splits based on those. | ||
| 152 | To signal this, gso_size is set to the special value GSO_BY_FRAGS. | ||
| 153 | |||
| 154 | Therefore, any code in the core networking stack must be aware of the | ||
| 155 | possibility that gso_size will be GSO_BY_FRAGS and handle that case | ||
| 156 | appropriately. (For size checks, the skb_gso_validate_*_len family of | ||
| 157 | helpers do this automatically.) | ||
| 158 | |||
| 159 | This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits | ||
| 160 | set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 9a7f76eadae9..93a12af4f180 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7909,7 +7909,6 @@ S: Maintained | |||
| 7909 | F: scripts/leaking_addresses.pl | 7909 | F: scripts/leaking_addresses.pl |
| 7910 | 7910 | ||
| 7911 | LED SUBSYSTEM | 7911 | LED SUBSYSTEM |
| 7912 | M: Richard Purdie <rpurdie@rpsys.net> | ||
| 7913 | M: Jacek Anaszewski <jacek.anaszewski@gmail.com> | 7912 | M: Jacek Anaszewski <jacek.anaszewski@gmail.com> |
| 7914 | M: Pavel Machek <pavel@ucw.cz> | 7913 | M: Pavel Machek <pavel@ucw.cz> |
| 7915 | L: linux-leds@vger.kernel.org | 7914 | L: linux-leds@vger.kernel.org |
| @@ -2,7 +2,7 @@ | |||
| 2 | VERSION = 4 | 2 | VERSION = 4 |
| 3 | PATCHLEVEL = 16 | 3 | PATCHLEVEL = 16 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = -rc2 |
| 6 | NAME = Fearless Coyote | 6 | NAME = Fearless Coyote |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
diff --git a/arch/arc/include/asm/bug.h b/arch/arc/include/asm/bug.h index ea022d47896c..21ec82466d62 100644 --- a/arch/arc/include/asm/bug.h +++ b/arch/arc/include/asm/bug.h | |||
| @@ -23,7 +23,8 @@ void die(const char *str, struct pt_regs *regs, unsigned long address); | |||
| 23 | 23 | ||
| 24 | #define BUG() do { \ | 24 | #define BUG() do { \ |
| 25 | pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ | 25 | pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ |
| 26 | dump_stack(); \ | 26 | barrier_before_unreachable(); \ |
| 27 | __builtin_trap(); \ | ||
| 27 | } while (0) | 28 | } while (0) |
| 28 | 29 | ||
| 29 | #define HAVE_ARCH_BUG | 30 | #define HAVE_ARCH_BUG |
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index be7bd19c87ec..eda8c5f629fc 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #define MPIDR_UP_BITMASK (0x1 << 30) | 21 | #define MPIDR_UP_BITMASK (0x1 << 30) |
| 22 | #define MPIDR_MT_BITMASK (0x1 << 24) | 22 | #define MPIDR_MT_BITMASK (0x1 << 24) |
| 23 | #define MPIDR_HWID_BITMASK 0xff00ffffff | 23 | #define MPIDR_HWID_BITMASK 0xff00ffffffUL |
| 24 | 24 | ||
| 25 | #define MPIDR_LEVEL_BITS_SHIFT 3 | 25 | #define MPIDR_LEVEL_BITS_SHIFT 3 |
| 26 | #define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) | 26 | #define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) |
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h index 1dca41bea16a..e73f68569624 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | static inline pte_t huge_ptep_get(pte_t *ptep) | 23 | static inline pte_t huge_ptep_get(pte_t *ptep) |
| 24 | { | 24 | { |
| 25 | return *ptep; | 25 | return READ_ONCE(*ptep); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | 28 | ||
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 9679067a1574..7faed6e48b46 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
| @@ -185,42 +185,42 @@ static inline pmd_t kvm_s2pmd_mkexec(pmd_t pmd) | |||
| 185 | return pmd; | 185 | return pmd; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static inline void kvm_set_s2pte_readonly(pte_t *pte) | 188 | static inline void kvm_set_s2pte_readonly(pte_t *ptep) |
| 189 | { | 189 | { |
| 190 | pteval_t old_pteval, pteval; | 190 | pteval_t old_pteval, pteval; |
| 191 | 191 | ||
| 192 | pteval = READ_ONCE(pte_val(*pte)); | 192 | pteval = READ_ONCE(pte_val(*ptep)); |
| 193 | do { | 193 | do { |
| 194 | old_pteval = pteval; | 194 | old_pteval = pteval; |
| 195 | pteval &= ~PTE_S2_RDWR; | 195 | pteval &= ~PTE_S2_RDWR; |
| 196 | pteval |= PTE_S2_RDONLY; | 196 | pteval |= PTE_S2_RDONLY; |
| 197 | pteval = cmpxchg_relaxed(&pte_val(*pte), old_pteval, pteval); | 197 | pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); |
| 198 | } while (pteval != old_pteval); | 198 | } while (pteval != old_pteval); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | static inline bool kvm_s2pte_readonly(pte_t *pte) | 201 | static inline bool kvm_s2pte_readonly(pte_t *ptep) |
| 202 | { | 202 | { |
| 203 | return (pte_val(*pte) & PTE_S2_RDWR) == PTE_S2_RDONLY; | 203 | return (READ_ONCE(pte_val(*ptep)) & PTE_S2_RDWR) == PTE_S2_RDONLY; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | static inline bool kvm_s2pte_exec(pte_t *pte) | 206 | static inline bool kvm_s2pte_exec(pte_t *ptep) |
| 207 | { | 207 | { |
| 208 | return !(pte_val(*pte) & PTE_S2_XN); | 208 | return !(READ_ONCE(pte_val(*ptep)) & PTE_S2_XN); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static inline void kvm_set_s2pmd_readonly(pmd_t *pmd) | 211 | static inline void kvm_set_s2pmd_readonly(pmd_t *pmdp) |
| 212 | { | 212 | { |
| 213 | kvm_set_s2pte_readonly((pte_t *)pmd); | 213 | kvm_set_s2pte_readonly((pte_t *)pmdp); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static inline bool kvm_s2pmd_readonly(pmd_t *pmd) | 216 | static inline bool kvm_s2pmd_readonly(pmd_t *pmdp) |
| 217 | { | 217 | { |
| 218 | return kvm_s2pte_readonly((pte_t *)pmd); | 218 | return kvm_s2pte_readonly((pte_t *)pmdp); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static inline bool kvm_s2pmd_exec(pmd_t *pmd) | 221 | static inline bool kvm_s2pmd_exec(pmd_t *pmdp) |
| 222 | { | 222 | { |
| 223 | return !(pmd_val(*pmd) & PMD_S2_XN); | 223 | return !(READ_ONCE(pmd_val(*pmdp)) & PMD_S2_XN); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | static inline bool kvm_page_empty(void *ptr) | 226 | static inline bool kvm_page_empty(void *ptr) |
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 8d3331985d2e..39ec0b8a689e 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h | |||
| @@ -141,13 +141,13 @@ static inline void cpu_install_idmap(void) | |||
| 141 | * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD, | 141 | * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD, |
| 142 | * avoiding the possibility of conflicting TLB entries being allocated. | 142 | * avoiding the possibility of conflicting TLB entries being allocated. |
| 143 | */ | 143 | */ |
| 144 | static inline void cpu_replace_ttbr1(pgd_t *pgd) | 144 | static inline void cpu_replace_ttbr1(pgd_t *pgdp) |
| 145 | { | 145 | { |
| 146 | typedef void (ttbr_replace_func)(phys_addr_t); | 146 | typedef void (ttbr_replace_func)(phys_addr_t); |
| 147 | extern ttbr_replace_func idmap_cpu_replace_ttbr1; | 147 | extern ttbr_replace_func idmap_cpu_replace_ttbr1; |
| 148 | ttbr_replace_func *replace_phys; | 148 | ttbr_replace_func *replace_phys; |
| 149 | 149 | ||
| 150 | phys_addr_t pgd_phys = virt_to_phys(pgd); | 150 | phys_addr_t pgd_phys = virt_to_phys(pgdp); |
| 151 | 151 | ||
| 152 | replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1); | 152 | replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1); |
| 153 | 153 | ||
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h index e9d9f1b006ef..2e05bcd944c8 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h | |||
| @@ -36,23 +36,23 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | |||
| 36 | return (pmd_t *)__get_free_page(PGALLOC_GFP); | 36 | return (pmd_t *)__get_free_page(PGALLOC_GFP); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | 39 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp) |
| 40 | { | 40 | { |
| 41 | BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); | 41 | BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1)); |
| 42 | free_page((unsigned long)pmd); | 42 | free_page((unsigned long)pmdp); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot) | 45 | static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) |
| 46 | { | 46 | { |
| 47 | set_pud(pud, __pud(__phys_to_pud_val(pmd) | prot)); | 47 | set_pud(pudp, __pud(__phys_to_pud_val(pmdp) | prot)); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | 50 | static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp) |
| 51 | { | 51 | { |
| 52 | __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE); | 52 | __pud_populate(pudp, __pa(pmdp), PMD_TYPE_TABLE); |
| 53 | } | 53 | } |
| 54 | #else | 54 | #else |
| 55 | static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot) | 55 | static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot) |
| 56 | { | 56 | { |
| 57 | BUILD_BUG(); | 57 | BUILD_BUG(); |
| 58 | } | 58 | } |
| @@ -65,30 +65,30 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | |||
| 65 | return (pud_t *)__get_free_page(PGALLOC_GFP); | 65 | return (pud_t *)__get_free_page(PGALLOC_GFP); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static inline void pud_free(struct mm_struct *mm, pud_t *pud) | 68 | static inline void pud_free(struct mm_struct *mm, pud_t *pudp) |
| 69 | { | 69 | { |
| 70 | BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); | 70 | BUG_ON((unsigned long)pudp & (PAGE_SIZE-1)); |
| 71 | free_page((unsigned long)pud); | 71 | free_page((unsigned long)pudp); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot) | 74 | static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pudp, pgdval_t prot) |
| 75 | { | 75 | { |
| 76 | set_pgd(pgdp, __pgd(__phys_to_pgd_val(pud) | prot)); | 76 | set_pgd(pgdp, __pgd(__phys_to_pgd_val(pudp) | prot)); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | 79 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, pud_t *pudp) |
| 80 | { | 80 | { |
| 81 | __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE); | 81 | __pgd_populate(pgdp, __pa(pudp), PUD_TYPE_TABLE); |
| 82 | } | 82 | } |
| 83 | #else | 83 | #else |
| 84 | static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot) | 84 | static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pudp, pgdval_t prot) |
| 85 | { | 85 | { |
| 86 | BUILD_BUG(); | 86 | BUILD_BUG(); |
| 87 | } | 87 | } |
| 88 | #endif /* CONFIG_PGTABLE_LEVELS > 3 */ | 88 | #endif /* CONFIG_PGTABLE_LEVELS > 3 */ |
| 89 | 89 | ||
| 90 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 90 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |
| 91 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | 91 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgdp); |
| 92 | 92 | ||
| 93 | static inline pte_t * | 93 | static inline pte_t * |
| 94 | pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) | 94 | pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) |
| @@ -114,10 +114,10 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr) | |||
| 114 | /* | 114 | /* |
| 115 | * Free a PTE table. | 115 | * Free a PTE table. |
| 116 | */ | 116 | */ |
| 117 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | 117 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *ptep) |
| 118 | { | 118 | { |
| 119 | if (pte) | 119 | if (ptep) |
| 120 | free_page((unsigned long)pte); | 120 | free_page((unsigned long)ptep); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static inline void pte_free(struct mm_struct *mm, pgtable_t pte) | 123 | static inline void pte_free(struct mm_struct *mm, pgtable_t pte) |
| @@ -126,10 +126,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) | |||
| 126 | __free_page(pte); | 126 | __free_page(pte); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, | 129 | static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep, |
| 130 | pmdval_t prot) | 130 | pmdval_t prot) |
| 131 | { | 131 | { |
| 132 | set_pmd(pmdp, __pmd(__phys_to_pmd_val(pte) | prot)); | 132 | set_pmd(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot)); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | /* | 135 | /* |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 094374c82db0..7e2c27e63cd8 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
| @@ -218,7 +218,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd) | |||
| 218 | 218 | ||
| 219 | static inline void set_pte(pte_t *ptep, pte_t pte) | 219 | static inline void set_pte(pte_t *ptep, pte_t pte) |
| 220 | { | 220 | { |
| 221 | *ptep = pte; | 221 | WRITE_ONCE(*ptep, pte); |
| 222 | 222 | ||
| 223 | /* | 223 | /* |
| 224 | * Only if the new pte is valid and kernel, otherwise TLB maintenance | 224 | * Only if the new pte is valid and kernel, otherwise TLB maintenance |
| @@ -250,6 +250,8 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); | |||
| 250 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 250 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
| 251 | pte_t *ptep, pte_t pte) | 251 | pte_t *ptep, pte_t pte) |
| 252 | { | 252 | { |
| 253 | pte_t old_pte; | ||
| 254 | |||
| 253 | if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) | 255 | if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) |
| 254 | __sync_icache_dcache(pte, addr); | 256 | __sync_icache_dcache(pte, addr); |
| 255 | 257 | ||
| @@ -258,14 +260,15 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 258 | * hardware updates of the pte (ptep_set_access_flags safely changes | 260 | * hardware updates of the pte (ptep_set_access_flags safely changes |
| 259 | * valid ptes without going through an invalid entry). | 261 | * valid ptes without going through an invalid entry). |
| 260 | */ | 262 | */ |
| 261 | if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(*ptep) && pte_valid(pte) && | 263 | old_pte = READ_ONCE(*ptep); |
| 264 | if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(old_pte) && pte_valid(pte) && | ||
| 262 | (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) { | 265 | (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) { |
| 263 | VM_WARN_ONCE(!pte_young(pte), | 266 | VM_WARN_ONCE(!pte_young(pte), |
| 264 | "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", | 267 | "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", |
| 265 | __func__, pte_val(*ptep), pte_val(pte)); | 268 | __func__, pte_val(old_pte), pte_val(pte)); |
| 266 | VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(pte), | 269 | VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte), |
| 267 | "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx", | 270 | "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx", |
| 268 | __func__, pte_val(*ptep), pte_val(pte)); | 271 | __func__, pte_val(old_pte), pte_val(pte)); |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | set_pte(ptep, pte); | 274 | set_pte(ptep, pte); |
| @@ -431,7 +434,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |||
| 431 | 434 | ||
| 432 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 435 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) |
| 433 | { | 436 | { |
| 434 | *pmdp = pmd; | 437 | WRITE_ONCE(*pmdp, pmd); |
| 435 | dsb(ishst); | 438 | dsb(ishst); |
| 436 | isb(); | 439 | isb(); |
| 437 | } | 440 | } |
| @@ -482,7 +485,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd) | |||
| 482 | 485 | ||
| 483 | static inline void set_pud(pud_t *pudp, pud_t pud) | 486 | static inline void set_pud(pud_t *pudp, pud_t pud) |
| 484 | { | 487 | { |
| 485 | *pudp = pud; | 488 | WRITE_ONCE(*pudp, pud); |
| 486 | dsb(ishst); | 489 | dsb(ishst); |
| 487 | isb(); | 490 | isb(); |
| 488 | } | 491 | } |
| @@ -500,7 +503,7 @@ static inline phys_addr_t pud_page_paddr(pud_t pud) | |||
| 500 | /* Find an entry in the second-level page table. */ | 503 | /* Find an entry in the second-level page table. */ |
| 501 | #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) | 504 | #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) |
| 502 | 505 | ||
| 503 | #define pmd_offset_phys(dir, addr) (pud_page_paddr(*(dir)) + pmd_index(addr) * sizeof(pmd_t)) | 506 | #define pmd_offset_phys(dir, addr) (pud_page_paddr(READ_ONCE(*(dir))) + pmd_index(addr) * sizeof(pmd_t)) |
| 504 | #define pmd_offset(dir, addr) ((pmd_t *)__va(pmd_offset_phys((dir), (addr)))) | 507 | #define pmd_offset(dir, addr) ((pmd_t *)__va(pmd_offset_phys((dir), (addr)))) |
| 505 | 508 | ||
| 506 | #define pmd_set_fixmap(addr) ((pmd_t *)set_fixmap_offset(FIX_PMD, addr)) | 509 | #define pmd_set_fixmap(addr) ((pmd_t *)set_fixmap_offset(FIX_PMD, addr)) |
| @@ -535,7 +538,7 @@ static inline phys_addr_t pud_page_paddr(pud_t pud) | |||
| 535 | 538 | ||
| 536 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) | 539 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) |
| 537 | { | 540 | { |
| 538 | *pgdp = pgd; | 541 | WRITE_ONCE(*pgdp, pgd); |
| 539 | dsb(ishst); | 542 | dsb(ishst); |
| 540 | } | 543 | } |
| 541 | 544 | ||
| @@ -552,7 +555,7 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd) | |||
| 552 | /* Find an entry in the frst-level page table. */ | 555 | /* Find an entry in the frst-level page table. */ |
| 553 | #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) | 556 | #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) |
| 554 | 557 | ||
| 555 | #define pud_offset_phys(dir, addr) (pgd_page_paddr(*(dir)) + pud_index(addr) * sizeof(pud_t)) | 558 | #define pud_offset_phys(dir, addr) (pgd_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t)) |
| 556 | #define pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr)))) | 559 | #define pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr)))) |
| 557 | 560 | ||
| 558 | #define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr)) | 561 | #define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr)) |
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 07823595b7f0..52f15cd896e1 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c | |||
| @@ -408,6 +408,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = { | |||
| 408 | }, | 408 | }, |
| 409 | { | 409 | { |
| 410 | .capability = ARM64_HARDEN_BRANCH_PREDICTOR, | 410 | .capability = ARM64_HARDEN_BRANCH_PREDICTOR, |
| 411 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), | ||
| 412 | .enable = qcom_enable_link_stack_sanitization, | ||
| 413 | }, | ||
| 414 | { | ||
| 415 | .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT, | ||
| 416 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), | ||
| 417 | }, | ||
| 418 | { | ||
| 419 | .capability = ARM64_HARDEN_BRANCH_PREDICTOR, | ||
| 411 | MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), | 420 | MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), |
| 412 | .enable = enable_smccc_arch_workaround_1, | 421 | .enable = enable_smccc_arch_workaround_1, |
| 413 | }, | 422 | }, |
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index f85ac58d08a3..a8bf1c892b90 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
| @@ -90,7 +90,7 @@ static int __init set_permissions(pte_t *ptep, pgtable_t token, | |||
| 90 | unsigned long addr, void *data) | 90 | unsigned long addr, void *data) |
| 91 | { | 91 | { |
| 92 | efi_memory_desc_t *md = data; | 92 | efi_memory_desc_t *md = data; |
| 93 | pte_t pte = *ptep; | 93 | pte_t pte = READ_ONCE(*ptep); |
| 94 | 94 | ||
| 95 | if (md->attribute & EFI_MEMORY_RO) | 95 | if (md->attribute & EFI_MEMORY_RO) |
| 96 | pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); | 96 | pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); |
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index f20cf7e99249..1ec5f28c39fc 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c | |||
| @@ -202,10 +202,10 @@ static int create_safe_exec_page(void *src_start, size_t length, | |||
| 202 | gfp_t mask) | 202 | gfp_t mask) |
| 203 | { | 203 | { |
| 204 | int rc = 0; | 204 | int rc = 0; |
| 205 | pgd_t *pgd; | 205 | pgd_t *pgdp; |
| 206 | pud_t *pud; | 206 | pud_t *pudp; |
| 207 | pmd_t *pmd; | 207 | pmd_t *pmdp; |
| 208 | pte_t *pte; | 208 | pte_t *ptep; |
| 209 | unsigned long dst = (unsigned long)allocator(mask); | 209 | unsigned long dst = (unsigned long)allocator(mask); |
| 210 | 210 | ||
| 211 | if (!dst) { | 211 | if (!dst) { |
| @@ -216,38 +216,38 @@ static int create_safe_exec_page(void *src_start, size_t length, | |||
| 216 | memcpy((void *)dst, src_start, length); | 216 | memcpy((void *)dst, src_start, length); |
| 217 | flush_icache_range(dst, dst + length); | 217 | flush_icache_range(dst, dst + length); |
| 218 | 218 | ||
| 219 | pgd = pgd_offset_raw(allocator(mask), dst_addr); | 219 | pgdp = pgd_offset_raw(allocator(mask), dst_addr); |
| 220 | if (pgd_none(*pgd)) { | 220 | if (pgd_none(READ_ONCE(*pgdp))) { |
| 221 | pud = allocator(mask); | 221 | pudp = allocator(mask); |
| 222 | if (!pud) { | 222 | if (!pudp) { |
| 223 | rc = -ENOMEM; | 223 | rc = -ENOMEM; |
| 224 | goto out; | 224 | goto out; |
| 225 | } | 225 | } |
| 226 | pgd_populate(&init_mm, pgd, pud); | 226 | pgd_populate(&init_mm, pgdp, pudp); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | pud = pud_offset(pgd, dst_addr); | 229 | pudp = pud_offset(pgdp, dst_addr); |
| 230 | if (pud_none(*pud)) { | 230 | if (pud_none(READ_ONCE(*pudp))) { |
| 231 | pmd = allocator(mask); | 231 | pmdp = allocator(mask); |
| 232 | if (!pmd) { | 232 | if (!pmdp) { |
| 233 | rc = -ENOMEM; | 233 | rc = -ENOMEM; |
| 234 | goto out; | 234 | goto out; |
| 235 | } | 235 | } |
| 236 | pud_populate(&init_mm, pud, pmd); | 236 | pud_populate(&init_mm, pudp, pmdp); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | pmd = pmd_offset(pud, dst_addr); | 239 | pmdp = pmd_offset(pudp, dst_addr); |
| 240 | if (pmd_none(*pmd)) { | 240 | if (pmd_none(READ_ONCE(*pmdp))) { |
| 241 | pte = allocator(mask); | 241 | ptep = allocator(mask); |
| 242 | if (!pte) { | 242 | if (!ptep) { |
| 243 | rc = -ENOMEM; | 243 | rc = -ENOMEM; |
| 244 | goto out; | 244 | goto out; |
| 245 | } | 245 | } |
| 246 | pmd_populate_kernel(&init_mm, pmd, pte); | 246 | pmd_populate_kernel(&init_mm, pmdp, ptep); |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | pte = pte_offset_kernel(pmd, dst_addr); | 249 | ptep = pte_offset_kernel(pmdp, dst_addr); |
| 250 | set_pte(pte, pfn_pte(virt_to_pfn(dst), PAGE_KERNEL_EXEC)); | 250 | set_pte(ptep, pfn_pte(virt_to_pfn(dst), PAGE_KERNEL_EXEC)); |
| 251 | 251 | ||
| 252 | /* | 252 | /* |
| 253 | * Load our new page tables. A strict BBM approach requires that we | 253 | * Load our new page tables. A strict BBM approach requires that we |
| @@ -263,7 +263,7 @@ static int create_safe_exec_page(void *src_start, size_t length, | |||
| 263 | */ | 263 | */ |
| 264 | cpu_set_reserved_ttbr0(); | 264 | cpu_set_reserved_ttbr0(); |
| 265 | local_flush_tlb_all(); | 265 | local_flush_tlb_all(); |
| 266 | write_sysreg(phys_to_ttbr(virt_to_phys(pgd)), ttbr0_el1); | 266 | write_sysreg(phys_to_ttbr(virt_to_phys(pgdp)), ttbr0_el1); |
| 267 | isb(); | 267 | isb(); |
| 268 | 268 | ||
| 269 | *phys_dst_addr = virt_to_phys((void *)dst); | 269 | *phys_dst_addr = virt_to_phys((void *)dst); |
| @@ -320,9 +320,9 @@ int swsusp_arch_suspend(void) | |||
| 320 | return ret; | 320 | return ret; |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) | 323 | static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr) |
| 324 | { | 324 | { |
| 325 | pte_t pte = *src_pte; | 325 | pte_t pte = READ_ONCE(*src_ptep); |
| 326 | 326 | ||
| 327 | if (pte_valid(pte)) { | 327 | if (pte_valid(pte)) { |
| 328 | /* | 328 | /* |
| @@ -330,7 +330,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) | |||
| 330 | * read only (code, rodata). Clear the RDONLY bit from | 330 | * read only (code, rodata). Clear the RDONLY bit from |
| 331 | * the temporary mappings we use during restore. | 331 | * the temporary mappings we use during restore. |
| 332 | */ | 332 | */ |
| 333 | set_pte(dst_pte, pte_mkwrite(pte)); | 333 | set_pte(dst_ptep, pte_mkwrite(pte)); |
| 334 | } else if (debug_pagealloc_enabled() && !pte_none(pte)) { | 334 | } else if (debug_pagealloc_enabled() && !pte_none(pte)) { |
| 335 | /* | 335 | /* |
| 336 | * debug_pagealloc will removed the PTE_VALID bit if | 336 | * debug_pagealloc will removed the PTE_VALID bit if |
| @@ -343,112 +343,116 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) | |||
| 343 | */ | 343 | */ |
| 344 | BUG_ON(!pfn_valid(pte_pfn(pte))); | 344 | BUG_ON(!pfn_valid(pte_pfn(pte))); |
| 345 | 345 | ||
| 346 | set_pte(dst_pte, pte_mkpresent(pte_mkwrite(pte))); | 346 | set_pte(dst_ptep, pte_mkpresent(pte_mkwrite(pte))); |
| 347 | } | 347 | } |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start, | 350 | static int copy_pte(pmd_t *dst_pmdp, pmd_t *src_pmdp, unsigned long start, |
| 351 | unsigned long end) | 351 | unsigned long end) |
| 352 | { | 352 | { |
| 353 | pte_t *src_pte; | 353 | pte_t *src_ptep; |
| 354 | pte_t *dst_pte; | 354 | pte_t *dst_ptep; |
| 355 | unsigned long addr = start; | 355 | unsigned long addr = start; |
| 356 | 356 | ||
| 357 | dst_pte = (pte_t *)get_safe_page(GFP_ATOMIC); | 357 | dst_ptep = (pte_t *)get_safe_page(GFP_ATOMIC); |
| 358 | if (!dst_pte) | 358 | if (!dst_ptep) |
| 359 | return -ENOMEM; | 359 | return -ENOMEM; |
| 360 | pmd_populate_kernel(&init_mm, dst_pmd, dst_pte); | 360 | pmd_populate_kernel(&init_mm, dst_pmdp, dst_ptep); |
| 361 | dst_pte = pte_offset_kernel(dst_pmd, start); | 361 | dst_ptep = pte_offset_kernel(dst_pmdp, start); |
| 362 | 362 | ||
| 363 | src_pte = pte_offset_kernel(src_pmd, start); | 363 | src_ptep = pte_offset_kernel(src_pmdp, start); |
| 364 | do { | 364 | do { |
| 365 | _copy_pte(dst_pte, src_pte, addr); | 365 | _copy_pte(dst_ptep, src_ptep, addr); |
| 366 | } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end); | 366 | } while (dst_ptep++, src_ptep++, addr += PAGE_SIZE, addr != end); |
| 367 | 367 | ||
| 368 | return 0; | 368 | return 0; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | static int copy_pmd(pud_t *dst_pud, pud_t *src_pud, unsigned long start, | 371 | static int copy_pmd(pud_t *dst_pudp, pud_t *src_pudp, unsigned long start, |
| 372 | unsigned long end) | 372 | unsigned long end) |
| 373 | { | 373 | { |
| 374 | pmd_t *src_pmd; | 374 | pmd_t *src_pmdp; |
| 375 | pmd_t *dst_pmd; | 375 | pmd_t *dst_pmdp; |
| 376 | unsigned long next; | 376 | unsigned long next; |
| 377 | unsigned long addr = start; | 377 | unsigned long addr = start; |
| 378 | 378 | ||
| 379 | if (pud_none(*dst_pud)) { | 379 | if (pud_none(READ_ONCE(*dst_pudp))) { |
| 380 | dst_pmd = (pmd_t *)get_safe_page(GFP_ATOMIC); | 380 | dst_pmdp = (pmd_t *)get_safe_page(GFP_ATOMIC); |
| 381 | if (!dst_pmd) | 381 | if (!dst_pmdp) |
| 382 | return -ENOMEM; | 382 | return -ENOMEM; |
| 383 | pud_populate(&init_mm, dst_pud, dst_pmd); | 383 | pud_populate(&init_mm, dst_pudp, dst_pmdp); |
| 384 | } | 384 | } |
| 385 | dst_pmd = pmd_offset(dst_pud, start); | 385 | dst_pmdp = pmd_offset(dst_pudp, start); |
| 386 | 386 | ||
| 387 | src_pmd = pmd_offset(src_pud, start); | 387 | src_pmdp = pmd_offset(src_pudp, start); |
| 388 | do { | 388 | do { |
| 389 | pmd_t pmd = READ_ONCE(*src_pmdp); | ||
| 390 | |||
| 389 | next = pmd_addr_end(addr, end); | 391 | next = pmd_addr_end(addr, end); |
| 390 | if (pmd_none(*src_pmd)) | 392 | if (pmd_none(pmd)) |
| 391 | continue; | 393 | continue; |
| 392 | if (pmd_table(*src_pmd)) { | 394 | if (pmd_table(pmd)) { |
| 393 | if (copy_pte(dst_pmd, src_pmd, addr, next)) | 395 | if (copy_pte(dst_pmdp, src_pmdp, addr, next)) |
| 394 | return -ENOMEM; | 396 | return -ENOMEM; |
| 395 | } else { | 397 | } else { |
| 396 | set_pmd(dst_pmd, | 398 | set_pmd(dst_pmdp, |
| 397 | __pmd(pmd_val(*src_pmd) & ~PMD_SECT_RDONLY)); | 399 | __pmd(pmd_val(pmd) & ~PMD_SECT_RDONLY)); |
| 398 | } | 400 | } |
| 399 | } while (dst_pmd++, src_pmd++, addr = next, addr != end); | 401 | } while (dst_pmdp++, src_pmdp++, addr = next, addr != end); |
| 400 | 402 | ||
| 401 | return 0; | 403 | return 0; |
| 402 | } | 404 | } |
| 403 | 405 | ||
| 404 | static int copy_pud(pgd_t *dst_pgd, pgd_t *src_pgd, unsigned long start, | 406 | static int copy_pud(pgd_t *dst_pgdp, pgd_t *src_pgdp, unsigned long start, |
| 405 | unsigned long end) | 407 | unsigned long end) |
| 406 | { | 408 | { |
| 407 | pud_t *dst_pud; | 409 | pud_t *dst_pudp; |
| 408 | pud_t *src_pud; | 410 | pud_t *src_pudp; |
| 409 | unsigned long next; | 411 | unsigned long next; |
| 410 | unsigned long addr = start; | 412 | unsigned long addr = start; |
| 411 | 413 | ||
| 412 | if (pgd_none(*dst_pgd)) { | 414 | if (pgd_none(READ_ONCE(*dst_pgdp))) { |
| 413 | dst_pud = (pud_t *)get_safe_page(GFP_ATOMIC); | 415 | dst_pudp = (pud_t *)get_safe_page(GFP_ATOMIC); |
| 414 | if (!dst_pud) | 416 | if (!dst_pudp) |
| 415 | return -ENOMEM; | 417 | return -ENOMEM; |
| 416 | pgd_populate(&init_mm, dst_pgd, dst_pud); | 418 | pgd_populate(&init_mm, dst_pgdp, dst_pudp); |
| 417 | } | 419 | } |
| 418 | dst_pud = pud_offset(dst_pgd, start); | 420 | dst_pudp = pud_offset(dst_pgdp, start); |
| 419 | 421 | ||
| 420 | src_pud = pud_offset(src_pgd, start); | 422 | src_pudp = pud_offset(src_pgdp, start); |
| 421 | do { | 423 | do { |
| 424 | pud_t pud = READ_ONCE(*src_pudp); | ||
| 425 | |||
| 422 | next = pud_addr_end(addr, end); | 426 | next = pud_addr_end(addr, end); |
| 423 | if (pud_none(*src_pud)) | 427 | if (pud_none(pud)) |
| 424 | continue; | 428 | continue; |
| 425 | if (pud_table(*(src_pud))) { | 429 | if (pud_table(pud)) { |
| 426 | if (copy_pmd(dst_pud, src_pud, addr, next)) | 430 | if (copy_pmd(dst_pudp, src_pudp, addr, next)) |
| 427 | return -ENOMEM; | 431 | return -ENOMEM; |
| 428 | } else { | 432 | } else { |
| 429 | set_pud(dst_pud, | 433 | set_pud(dst_pudp, |
| 430 | __pud(pud_val(*src_pud) & ~PMD_SECT_RDONLY)); | 434 | __pud(pud_val(pud) & ~PMD_SECT_RDONLY)); |
| 431 | } | 435 | } |
| 432 | } while (dst_pud++, src_pud++, addr = next, addr != end); | 436 | } while (dst_pudp++, src_pudp++, addr = next, addr != end); |
| 433 | 437 | ||
| 434 | return 0; | 438 | return 0; |
| 435 | } | 439 | } |
| 436 | 440 | ||
| 437 | static int copy_page_tables(pgd_t *dst_pgd, unsigned long start, | 441 | static int copy_page_tables(pgd_t *dst_pgdp, unsigned long start, |
| 438 | unsigned long end) | 442 | unsigned long end) |
| 439 | { | 443 | { |
| 440 | unsigned long next; | 444 | unsigned long next; |
| 441 | unsigned long addr = start; | 445 | unsigned long addr = start; |
| 442 | pgd_t *src_pgd = pgd_offset_k(start); | 446 | pgd_t *src_pgdp = pgd_offset_k(start); |
| 443 | 447 | ||
| 444 | dst_pgd = pgd_offset_raw(dst_pgd, start); | 448 | dst_pgdp = pgd_offset_raw(dst_pgdp, start); |
| 445 | do { | 449 | do { |
| 446 | next = pgd_addr_end(addr, end); | 450 | next = pgd_addr_end(addr, end); |
| 447 | if (pgd_none(*src_pgd)) | 451 | if (pgd_none(READ_ONCE(*src_pgdp))) |
| 448 | continue; | 452 | continue; |
| 449 | if (copy_pud(dst_pgd, src_pgd, addr, next)) | 453 | if (copy_pud(dst_pgdp, src_pgdp, addr, next)) |
| 450 | return -ENOMEM; | 454 | return -ENOMEM; |
| 451 | } while (dst_pgd++, src_pgd++, addr = next, addr != end); | 455 | } while (dst_pgdp++, src_pgdp++, addr = next, addr != end); |
| 452 | 456 | ||
| 453 | return 0; | 457 | return 0; |
| 454 | } | 458 | } |
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 116252a8d3a5..870f4b1587f9 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c | |||
| @@ -407,8 +407,10 @@ again: | |||
| 407 | u32 midr = read_cpuid_id(); | 407 | u32 midr = read_cpuid_id(); |
| 408 | 408 | ||
| 409 | /* Apply BTAC predictors mitigation to all Falkor chips */ | 409 | /* Apply BTAC predictors mitigation to all Falkor chips */ |
| 410 | if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1) | 410 | if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) || |
| 411 | ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) { | ||
| 411 | __qcom_hyp_sanitize_btac_predictors(); | 412 | __qcom_hyp_sanitize_btac_predictors(); |
| 413 | } | ||
| 412 | } | 414 | } |
| 413 | 415 | ||
| 414 | fp_enabled = __fpsimd_enabled(); | 416 | fp_enabled = __fpsimd_enabled(); |
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index 7b60d62ac593..65dfc8571bf8 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c | |||
| @@ -286,48 +286,52 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, | |||
| 286 | 286 | ||
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start) | 289 | static void walk_pte(struct pg_state *st, pmd_t *pmdp, unsigned long start) |
| 290 | { | 290 | { |
| 291 | pte_t *pte = pte_offset_kernel(pmd, 0UL); | 291 | pte_t *ptep = pte_offset_kernel(pmdp, 0UL); |
| 292 | unsigned long addr; | 292 | unsigned long addr; |
| 293 | unsigned i; | 293 | unsigned i; |
| 294 | 294 | ||
| 295 | for (i = 0; i < PTRS_PER_PTE; i++, pte++) { | 295 | for (i = 0; i < PTRS_PER_PTE; i++, ptep++) { |
| 296 | addr = start + i * PAGE_SIZE; | 296 | addr = start + i * PAGE_SIZE; |
| 297 | note_page(st, addr, 4, pte_val(*pte)); | 297 | note_page(st, addr, 4, READ_ONCE(pte_val(*ptep))); |
| 298 | } | 298 | } |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) | 301 | static void walk_pmd(struct pg_state *st, pud_t *pudp, unsigned long start) |
| 302 | { | 302 | { |
| 303 | pmd_t *pmd = pmd_offset(pud, 0UL); | 303 | pmd_t *pmdp = pmd_offset(pudp, 0UL); |
| 304 | unsigned long addr; | 304 | unsigned long addr; |
| 305 | unsigned i; | 305 | unsigned i; |
| 306 | 306 | ||
| 307 | for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { | 307 | for (i = 0; i < PTRS_PER_PMD; i++, pmdp++) { |
| 308 | pmd_t pmd = READ_ONCE(*pmdp); | ||
| 309 | |||
| 308 | addr = start + i * PMD_SIZE; | 310 | addr = start + i * PMD_SIZE; |
| 309 | if (pmd_none(*pmd) || pmd_sect(*pmd)) { | 311 | if (pmd_none(pmd) || pmd_sect(pmd)) { |
| 310 | note_page(st, addr, 3, pmd_val(*pmd)); | 312 | note_page(st, addr, 3, pmd_val(pmd)); |
| 311 | } else { | 313 | } else { |
| 312 | BUG_ON(pmd_bad(*pmd)); | 314 | BUG_ON(pmd_bad(pmd)); |
| 313 | walk_pte(st, pmd, addr); | 315 | walk_pte(st, pmdp, addr); |
| 314 | } | 316 | } |
| 315 | } | 317 | } |
| 316 | } | 318 | } |
| 317 | 319 | ||
| 318 | static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) | 320 | static void walk_pud(struct pg_state *st, pgd_t *pgdp, unsigned long start) |
| 319 | { | 321 | { |
| 320 | pud_t *pud = pud_offset(pgd, 0UL); | 322 | pud_t *pudp = pud_offset(pgdp, 0UL); |
| 321 | unsigned long addr; | 323 | unsigned long addr; |
| 322 | unsigned i; | 324 | unsigned i; |
| 323 | 325 | ||
| 324 | for (i = 0; i < PTRS_PER_PUD; i++, pud++) { | 326 | for (i = 0; i < PTRS_PER_PUD; i++, pudp++) { |
| 327 | pud_t pud = READ_ONCE(*pudp); | ||
| 328 | |||
| 325 | addr = start + i * PUD_SIZE; | 329 | addr = start + i * PUD_SIZE; |
| 326 | if (pud_none(*pud) || pud_sect(*pud)) { | 330 | if (pud_none(pud) || pud_sect(pud)) { |
| 327 | note_page(st, addr, 2, pud_val(*pud)); | 331 | note_page(st, addr, 2, pud_val(pud)); |
| 328 | } else { | 332 | } else { |
| 329 | BUG_ON(pud_bad(*pud)); | 333 | BUG_ON(pud_bad(pud)); |
| 330 | walk_pmd(st, pud, addr); | 334 | walk_pmd(st, pudp, addr); |
| 331 | } | 335 | } |
| 332 | } | 336 | } |
| 333 | } | 337 | } |
| @@ -335,17 +339,19 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) | |||
| 335 | static void walk_pgd(struct pg_state *st, struct mm_struct *mm, | 339 | static void walk_pgd(struct pg_state *st, struct mm_struct *mm, |
| 336 | unsigned long start) | 340 | unsigned long start) |
| 337 | { | 341 | { |
| 338 | pgd_t *pgd = pgd_offset(mm, 0UL); | 342 | pgd_t *pgdp = pgd_offset(mm, 0UL); |
| 339 | unsigned i; | 343 | unsigned i; |
| 340 | unsigned long addr; | 344 | unsigned long addr; |
| 341 | 345 | ||
| 342 | for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { | 346 | for (i = 0; i < PTRS_PER_PGD; i++, pgdp++) { |
| 347 | pgd_t pgd = READ_ONCE(*pgdp); | ||
| 348 | |||
| 343 | addr = start + i * PGDIR_SIZE; | 349 | addr = start + i * PGDIR_SIZE; |
| 344 | if (pgd_none(*pgd)) { | 350 | if (pgd_none(pgd)) { |
| 345 | note_page(st, addr, 1, pgd_val(*pgd)); | 351 | note_page(st, addr, 1, pgd_val(pgd)); |
| 346 | } else { | 352 | } else { |
| 347 | BUG_ON(pgd_bad(*pgd)); | 353 | BUG_ON(pgd_bad(pgd)); |
| 348 | walk_pud(st, pgd, addr); | 354 | walk_pud(st, pgdp, addr); |
| 349 | } | 355 | } |
| 350 | } | 356 | } |
| 351 | } | 357 | } |
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index f76bb2c3c943..bff11553eb05 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
| @@ -130,7 +130,8 @@ static void mem_abort_decode(unsigned int esr) | |||
| 130 | void show_pte(unsigned long addr) | 130 | void show_pte(unsigned long addr) |
| 131 | { | 131 | { |
| 132 | struct mm_struct *mm; | 132 | struct mm_struct *mm; |
| 133 | pgd_t *pgd; | 133 | pgd_t *pgdp; |
| 134 | pgd_t pgd; | ||
| 134 | 135 | ||
| 135 | if (addr < TASK_SIZE) { | 136 | if (addr < TASK_SIZE) { |
| 136 | /* TTBR0 */ | 137 | /* TTBR0 */ |
| @@ -149,33 +150,37 @@ void show_pte(unsigned long addr) | |||
| 149 | return; | 150 | return; |
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgd = %p\n", | 153 | pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n", |
| 153 | mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, | 154 | mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, |
| 154 | VA_BITS, mm->pgd); | 155 | VA_BITS, mm->pgd); |
| 155 | pgd = pgd_offset(mm, addr); | 156 | pgdp = pgd_offset(mm, addr); |
| 156 | pr_alert("[%016lx] *pgd=%016llx", addr, pgd_val(*pgd)); | 157 | pgd = READ_ONCE(*pgdp); |
| 158 | pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd)); | ||
| 157 | 159 | ||
| 158 | do { | 160 | do { |
| 159 | pud_t *pud; | 161 | pud_t *pudp, pud; |
| 160 | pmd_t *pmd; | 162 | pmd_t *pmdp, pmd; |
| 161 | pte_t *pte; | 163 | pte_t *ptep, pte; |
| 162 | 164 | ||
| 163 | if (pgd_none(*pgd) || pgd_bad(*pgd)) | 165 | if (pgd_none(pgd) || pgd_bad(pgd)) |
| 164 | break; | 166 | break; |
| 165 | 167 | ||
| 166 | pud = pud_offset(pgd, addr); | 168 | pudp = pud_offset(pgdp, addr); |
| 167 | pr_cont(", *pud=%016llx", pud_val(*pud)); | 169 | pud = READ_ONCE(*pudp); |
| 168 | if (pud_none(*pud) || pud_bad(*pud)) | 170 | pr_cont(", pud=%016llx", pud_val(pud)); |
| 171 | if (pud_none(pud) || pud_bad(pud)) | ||
| 169 | break; | 172 | break; |
| 170 | 173 | ||
| 171 | pmd = pmd_offset(pud, addr); | 174 | pmdp = pmd_offset(pudp, addr); |
| 172 | pr_cont(", *pmd=%016llx", pmd_val(*pmd)); | 175 | pmd = READ_ONCE(*pmdp); |
| 173 | if (pmd_none(*pmd) || pmd_bad(*pmd)) | 176 | pr_cont(", pmd=%016llx", pmd_val(pmd)); |
| 177 | if (pmd_none(pmd) || pmd_bad(pmd)) | ||
| 174 | break; | 178 | break; |
| 175 | 179 | ||
| 176 | pte = pte_offset_map(pmd, addr); | 180 | ptep = pte_offset_map(pmdp, addr); |
| 177 | pr_cont(", *pte=%016llx", pte_val(*pte)); | 181 | pte = READ_ONCE(*ptep); |
| 178 | pte_unmap(pte); | 182 | pr_cont(", pte=%016llx", pte_val(pte)); |
| 183 | pte_unmap(ptep); | ||
| 179 | } while(0); | 184 | } while(0); |
| 180 | 185 | ||
| 181 | pr_cont("\n"); | 186 | pr_cont("\n"); |
| @@ -196,8 +201,9 @@ int ptep_set_access_flags(struct vm_area_struct *vma, | |||
| 196 | pte_t entry, int dirty) | 201 | pte_t entry, int dirty) |
| 197 | { | 202 | { |
| 198 | pteval_t old_pteval, pteval; | 203 | pteval_t old_pteval, pteval; |
| 204 | pte_t pte = READ_ONCE(*ptep); | ||
| 199 | 205 | ||
| 200 | if (pte_same(*ptep, entry)) | 206 | if (pte_same(pte, entry)) |
| 201 | return 0; | 207 | return 0; |
| 202 | 208 | ||
| 203 | /* only preserve the access flags and write permission */ | 209 | /* only preserve the access flags and write permission */ |
| @@ -210,7 +216,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, | |||
| 210 | * (calculated as: a & b == ~(~a | ~b)). | 216 | * (calculated as: a & b == ~(~a | ~b)). |
| 211 | */ | 217 | */ |
| 212 | pte_val(entry) ^= PTE_RDONLY; | 218 | pte_val(entry) ^= PTE_RDONLY; |
| 213 | pteval = READ_ONCE(pte_val(*ptep)); | 219 | pteval = pte_val(pte); |
| 214 | do { | 220 | do { |
| 215 | old_pteval = pteval; | 221 | old_pteval = pteval; |
| 216 | pteval ^= PTE_RDONLY; | 222 | pteval ^= PTE_RDONLY; |
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 6cb0fa92a651..ecc6818191df 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c | |||
| @@ -54,14 +54,14 @@ static inline pgprot_t pte_pgprot(pte_t pte) | |||
| 54 | static int find_num_contig(struct mm_struct *mm, unsigned long addr, | 54 | static int find_num_contig(struct mm_struct *mm, unsigned long addr, |
| 55 | pte_t *ptep, size_t *pgsize) | 55 | pte_t *ptep, size_t *pgsize) |
| 56 | { | 56 | { |
| 57 | pgd_t *pgd = pgd_offset(mm, addr); | 57 | pgd_t *pgdp = pgd_offset(mm, addr); |
| 58 | pud_t *pud; | 58 | pud_t *pudp; |
| 59 | pmd_t *pmd; | 59 | pmd_t *pmdp; |
| 60 | 60 | ||
| 61 | *pgsize = PAGE_SIZE; | 61 | *pgsize = PAGE_SIZE; |
| 62 | pud = pud_offset(pgd, addr); | 62 | pudp = pud_offset(pgdp, addr); |
| 63 | pmd = pmd_offset(pud, addr); | 63 | pmdp = pmd_offset(pudp, addr); |
| 64 | if ((pte_t *)pmd == ptep) { | 64 | if ((pte_t *)pmdp == ptep) { |
| 65 | *pgsize = PMD_SIZE; | 65 | *pgsize = PMD_SIZE; |
| 66 | return CONT_PMDS; | 66 | return CONT_PMDS; |
| 67 | } | 67 | } |
| @@ -181,11 +181,8 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 181 | 181 | ||
| 182 | clear_flush(mm, addr, ptep, pgsize, ncontig); | 182 | clear_flush(mm, addr, ptep, pgsize, ncontig); |
| 183 | 183 | ||
| 184 | for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) { | 184 | for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) |
| 185 | pr_debug("%s: set pte %p to 0x%llx\n", __func__, ptep, | ||
| 186 | pte_val(pfn_pte(pfn, hugeprot))); | ||
| 187 | set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); | 185 | set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); |
| 188 | } | ||
| 189 | } | 186 | } |
| 190 | 187 | ||
| 191 | void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, | 188 | void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, |
| @@ -203,20 +200,20 @@ void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 203 | pte_t *huge_pte_alloc(struct mm_struct *mm, | 200 | pte_t *huge_pte_alloc(struct mm_struct *mm, |
| 204 | unsigned long addr, unsigned long sz) | 201 | unsigned long addr, unsigned long sz) |
| 205 | { | 202 | { |
| 206 | pgd_t *pgd; | 203 | pgd_t *pgdp; |
| 207 | pud_t *pud; | 204 | pud_t *pudp; |
| 208 | pte_t *pte = NULL; | 205 | pmd_t *pmdp; |
| 209 | 206 | pte_t *ptep = NULL; | |
| 210 | pr_debug("%s: addr:0x%lx sz:0x%lx\n", __func__, addr, sz); | 207 | |
| 211 | pgd = pgd_offset(mm, addr); | 208 | pgdp = pgd_offset(mm, addr); |
| 212 | pud = pud_alloc(mm, pgd, addr); | 209 | pudp = pud_alloc(mm, pgdp, addr); |
| 213 | if (!pud) | 210 | if (!pudp) |
| 214 | return NULL; | 211 | return NULL; |
| 215 | 212 | ||
| 216 | if (sz == PUD_SIZE) { | 213 | if (sz == PUD_SIZE) { |
| 217 | pte = (pte_t *)pud; | 214 | ptep = (pte_t *)pudp; |
| 218 | } else if (sz == (PAGE_SIZE * CONT_PTES)) { | 215 | } else if (sz == (PAGE_SIZE * CONT_PTES)) { |
| 219 | pmd_t *pmd = pmd_alloc(mm, pud, addr); | 216 | pmdp = pmd_alloc(mm, pudp, addr); |
| 220 | 217 | ||
| 221 | WARN_ON(addr & (sz - 1)); | 218 | WARN_ON(addr & (sz - 1)); |
| 222 | /* | 219 | /* |
| @@ -226,60 +223,55 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, | |||
| 226 | * will be no pte_unmap() to correspond with this | 223 | * will be no pte_unmap() to correspond with this |
| 227 | * pte_alloc_map(). | 224 | * pte_alloc_map(). |
| 228 | */ | 225 | */ |
| 229 | pte = pte_alloc_map(mm, pmd, addr); | 226 | ptep = pte_alloc_map(mm, pmdp, addr); |
| 230 | } else if (sz == PMD_SIZE) { | 227 | } else if (sz == PMD_SIZE) { |
| 231 | if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && | 228 | if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && |
| 232 | pud_none(*pud)) | 229 | pud_none(READ_ONCE(*pudp))) |
| 233 | pte = huge_pmd_share(mm, addr, pud); | 230 | ptep = huge_pmd_share(mm, addr, pudp); |
| 234 | else | 231 | else |
| 235 | pte = (pte_t *)pmd_alloc(mm, pud, addr); | 232 | ptep = (pte_t *)pmd_alloc(mm, pudp, addr); |
| 236 | } else if (sz == (PMD_SIZE * CONT_PMDS)) { | 233 | } else if (sz == (PMD_SIZE * CONT_PMDS)) { |
| 237 | pmd_t *pmd; | 234 | pmdp = pmd_alloc(mm, pudp, addr); |
| 238 | |||
| 239 | pmd = pmd_alloc(mm, pud, addr); | ||
| 240 | WARN_ON(addr & (sz - 1)); | 235 | WARN_ON(addr & (sz - 1)); |
| 241 | return (pte_t *)pmd; | 236 | return (pte_t *)pmdp; |
| 242 | } | 237 | } |
| 243 | 238 | ||
| 244 | pr_debug("%s: addr:0x%lx sz:0x%lx ret pte=%p/0x%llx\n", __func__, addr, | 239 | return ptep; |
| 245 | sz, pte, pte_val(*pte)); | ||
| 246 | return pte; | ||
| 247 | } | 240 | } |
| 248 | 241 | ||
| 249 | pte_t *huge_pte_offset(struct mm_struct *mm, | 242 | pte_t *huge_pte_offset(struct mm_struct *mm, |
| 250 | unsigned long addr, unsigned long sz) | 243 | unsigned long addr, unsigned long sz) |
| 251 | { | 244 | { |
| 252 | pgd_t *pgd; | 245 | pgd_t *pgdp; |
| 253 | pud_t *pud; | 246 | pud_t *pudp, pud; |
| 254 | pmd_t *pmd; | 247 | pmd_t *pmdp, pmd; |
| 255 | 248 | ||
| 256 | pgd = pgd_offset(mm, addr); | 249 | pgdp = pgd_offset(mm, addr); |
| 257 | pr_debug("%s: addr:0x%lx pgd:%p\n", __func__, addr, pgd); | 250 | if (!pgd_present(READ_ONCE(*pgdp))) |
| 258 | if (!pgd_present(*pgd)) | ||
| 259 | return NULL; | 251 | return NULL; |
| 260 | 252 | ||
| 261 | pud = pud_offset(pgd, addr); | 253 | pudp = pud_offset(pgdp, addr); |
| 262 | if (sz != PUD_SIZE && pud_none(*pud)) | 254 | pud = READ_ONCE(*pudp); |
| 255 | if (sz != PUD_SIZE && pud_none(pud)) | ||
| 263 | return NULL; | 256 | return NULL; |
| 264 | /* hugepage or swap? */ | 257 | /* hugepage or swap? */ |
| 265 | if (pud_huge(*pud) || !pud_present(*pud)) | 258 | if (pud_huge(pud) || !pud_present(pud)) |
| 266 | return (pte_t *)pud; | 259 | return (pte_t *)pudp; |
| 267 | /* table; check the next level */ | 260 | /* table; check the next level */ |
| 268 | 261 | ||
| 269 | if (sz == CONT_PMD_SIZE) | 262 | if (sz == CONT_PMD_SIZE) |
| 270 | addr &= CONT_PMD_MASK; | 263 | addr &= CONT_PMD_MASK; |
| 271 | 264 | ||
| 272 | pmd = pmd_offset(pud, addr); | 265 | pmdp = pmd_offset(pudp, addr); |
| 266 | pmd = READ_ONCE(*pmdp); | ||
| 273 | if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) && | 267 | if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) && |
| 274 | pmd_none(*pmd)) | 268 | pmd_none(pmd)) |
| 275 | return NULL; | 269 | return NULL; |
| 276 | if (pmd_huge(*pmd) || !pmd_present(*pmd)) | 270 | if (pmd_huge(pmd) || !pmd_present(pmd)) |
| 277 | return (pte_t *)pmd; | 271 | return (pte_t *)pmdp; |
| 278 | 272 | ||
| 279 | if (sz == CONT_PTE_SIZE) { | 273 | if (sz == CONT_PTE_SIZE) |
| 280 | pte_t *pte = pte_offset_kernel(pmd, (addr & CONT_PTE_MASK)); | 274 | return pte_offset_kernel(pmdp, (addr & CONT_PTE_MASK)); |
| 281 | return pte; | ||
| 282 | } | ||
| 283 | 275 | ||
| 284 | return NULL; | 276 | return NULL; |
| 285 | } | 277 | } |
| @@ -367,7 +359,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, | |||
| 367 | size_t pgsize; | 359 | size_t pgsize; |
| 368 | pte_t pte; | 360 | pte_t pte; |
| 369 | 361 | ||
| 370 | if (!pte_cont(*ptep)) { | 362 | if (!pte_cont(READ_ONCE(*ptep))) { |
| 371 | ptep_set_wrprotect(mm, addr, ptep); | 363 | ptep_set_wrprotect(mm, addr, ptep); |
| 372 | return; | 364 | return; |
| 373 | } | 365 | } |
| @@ -391,7 +383,7 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma, | |||
| 391 | size_t pgsize; | 383 | size_t pgsize; |
| 392 | int ncontig; | 384 | int ncontig; |
| 393 | 385 | ||
| 394 | if (!pte_cont(*ptep)) { | 386 | if (!pte_cont(READ_ONCE(*ptep))) { |
| 395 | ptep_clear_flush(vma, addr, ptep); | 387 | ptep_clear_flush(vma, addr, ptep); |
| 396 | return; | 388 | return; |
| 397 | } | 389 | } |
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 6e02e6fb4c7b..dabfc1ecda3d 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c | |||
| @@ -44,92 +44,92 @@ static phys_addr_t __init kasan_alloc_zeroed_page(int node) | |||
| 44 | return __pa(p); | 44 | return __pa(p); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | static pte_t *__init kasan_pte_offset(pmd_t *pmd, unsigned long addr, int node, | 47 | static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node, |
| 48 | bool early) | 48 | bool early) |
| 49 | { | 49 | { |
| 50 | if (pmd_none(*pmd)) { | 50 | if (pmd_none(READ_ONCE(*pmdp))) { |
| 51 | phys_addr_t pte_phys = early ? __pa_symbol(kasan_zero_pte) | 51 | phys_addr_t pte_phys = early ? __pa_symbol(kasan_zero_pte) |
| 52 | : kasan_alloc_zeroed_page(node); | 52 | : kasan_alloc_zeroed_page(node); |
| 53 | __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); | 53 | __pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | return early ? pte_offset_kimg(pmd, addr) | 56 | return early ? pte_offset_kimg(pmdp, addr) |
| 57 | : pte_offset_kernel(pmd, addr); | 57 | : pte_offset_kernel(pmdp, addr); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static pmd_t *__init kasan_pmd_offset(pud_t *pud, unsigned long addr, int node, | 60 | static pmd_t *__init kasan_pmd_offset(pud_t *pudp, unsigned long addr, int node, |
| 61 | bool early) | 61 | bool early) |
| 62 | { | 62 | { |
| 63 | if (pud_none(*pud)) { | 63 | if (pud_none(READ_ONCE(*pudp))) { |
| 64 | phys_addr_t pmd_phys = early ? __pa_symbol(kasan_zero_pmd) | 64 | phys_addr_t pmd_phys = early ? __pa_symbol(kasan_zero_pmd) |
| 65 | : kasan_alloc_zeroed_page(node); | 65 | : kasan_alloc_zeroed_page(node); |
| 66 | __pud_populate(pud, pmd_phys, PMD_TYPE_TABLE); | 66 | __pud_populate(pudp, pmd_phys, PMD_TYPE_TABLE); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | return early ? pmd_offset_kimg(pud, addr) : pmd_offset(pud, addr); | 69 | return early ? pmd_offset_kimg(pudp, addr) : pmd_offset(pudp, addr); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static pud_t *__init kasan_pud_offset(pgd_t *pgd, unsigned long addr, int node, | 72 | static pud_t *__init kasan_pud_offset(pgd_t *pgdp, unsigned long addr, int node, |
| 73 | bool early) | 73 | bool early) |
| 74 | { | 74 | { |
| 75 | if (pgd_none(*pgd)) { | 75 | if (pgd_none(READ_ONCE(*pgdp))) { |
| 76 | phys_addr_t pud_phys = early ? __pa_symbol(kasan_zero_pud) | 76 | phys_addr_t pud_phys = early ? __pa_symbol(kasan_zero_pud) |
| 77 | : kasan_alloc_zeroed_page(node); | 77 | : kasan_alloc_zeroed_page(node); |
| 78 | __pgd_populate(pgd, pud_phys, PMD_TYPE_TABLE); | 78 | __pgd_populate(pgdp, pud_phys, PMD_TYPE_TABLE); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | return early ? pud_offset_kimg(pgd, addr) : pud_offset(pgd, addr); | 81 | return early ? pud_offset_kimg(pgdp, addr) : pud_offset(pgdp, addr); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static void __init kasan_pte_populate(pmd_t *pmd, unsigned long addr, | 84 | static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr, |
| 85 | unsigned long end, int node, bool early) | 85 | unsigned long end, int node, bool early) |
| 86 | { | 86 | { |
| 87 | unsigned long next; | 87 | unsigned long next; |
| 88 | pte_t *pte = kasan_pte_offset(pmd, addr, node, early); | 88 | pte_t *ptep = kasan_pte_offset(pmdp, addr, node, early); |
| 89 | 89 | ||
| 90 | do { | 90 | do { |
| 91 | phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page) | 91 | phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page) |
| 92 | : kasan_alloc_zeroed_page(node); | 92 | : kasan_alloc_zeroed_page(node); |
| 93 | next = addr + PAGE_SIZE; | 93 | next = addr + PAGE_SIZE; |
| 94 | set_pte(pte, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL)); | 94 | set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL)); |
| 95 | } while (pte++, addr = next, addr != end && pte_none(*pte)); | 95 | } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep))); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static void __init kasan_pmd_populate(pud_t *pud, unsigned long addr, | 98 | static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr, |
| 99 | unsigned long end, int node, bool early) | 99 | unsigned long end, int node, bool early) |
| 100 | { | 100 | { |
| 101 | unsigned long next; | 101 | unsigned long next; |
| 102 | pmd_t *pmd = kasan_pmd_offset(pud, addr, node, early); | 102 | pmd_t *pmdp = kasan_pmd_offset(pudp, addr, node, early); |
| 103 | 103 | ||
| 104 | do { | 104 | do { |
| 105 | next = pmd_addr_end(addr, end); | 105 | next = pmd_addr_end(addr, end); |
| 106 | kasan_pte_populate(pmd, addr, next, node, early); | 106 | kasan_pte_populate(pmdp, addr, next, node, early); |
| 107 | } while (pmd++, addr = next, addr != end && pmd_none(*pmd)); | 107 | } while (pmdp++, addr = next, addr != end && pmd_none(READ_ONCE(*pmdp))); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void __init kasan_pud_populate(pgd_t *pgd, unsigned long addr, | 110 | static void __init kasan_pud_populate(pgd_t *pgdp, unsigned long addr, |
| 111 | unsigned long end, int node, bool early) | 111 | unsigned long end, int node, bool early) |
| 112 | { | 112 | { |
| 113 | unsigned long next; | 113 | unsigned long next; |
| 114 | pud_t *pud = kasan_pud_offset(pgd, addr, node, early); | 114 | pud_t *pudp = kasan_pud_offset(pgdp, addr, node, early); |
| 115 | 115 | ||
| 116 | do { | 116 | do { |
| 117 | next = pud_addr_end(addr, end); | 117 | next = pud_addr_end(addr, end); |
| 118 | kasan_pmd_populate(pud, addr, next, node, early); | 118 | kasan_pmd_populate(pudp, addr, next, node, early); |
| 119 | } while (pud++, addr = next, addr != end && pud_none(*pud)); | 119 | } while (pudp++, addr = next, addr != end && pud_none(READ_ONCE(*pudp))); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | static void __init kasan_pgd_populate(unsigned long addr, unsigned long end, | 122 | static void __init kasan_pgd_populate(unsigned long addr, unsigned long end, |
| 123 | int node, bool early) | 123 | int node, bool early) |
| 124 | { | 124 | { |
| 125 | unsigned long next; | 125 | unsigned long next; |
| 126 | pgd_t *pgd; | 126 | pgd_t *pgdp; |
| 127 | 127 | ||
| 128 | pgd = pgd_offset_k(addr); | 128 | pgdp = pgd_offset_k(addr); |
| 129 | do { | 129 | do { |
| 130 | next = pgd_addr_end(addr, end); | 130 | next = pgd_addr_end(addr, end); |
| 131 | kasan_pud_populate(pgd, addr, next, node, early); | 131 | kasan_pud_populate(pgdp, addr, next, node, early); |
| 132 | } while (pgd++, addr = next, addr != end); | 132 | } while (pgdp++, addr = next, addr != end); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | /* The early shadow maps everything to a single page of zeroes */ | 135 | /* The early shadow maps everything to a single page of zeroes */ |
| @@ -155,14 +155,14 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end, | |||
| 155 | */ | 155 | */ |
| 156 | void __init kasan_copy_shadow(pgd_t *pgdir) | 156 | void __init kasan_copy_shadow(pgd_t *pgdir) |
| 157 | { | 157 | { |
| 158 | pgd_t *pgd, *pgd_new, *pgd_end; | 158 | pgd_t *pgdp, *pgdp_new, *pgdp_end; |
| 159 | 159 | ||
| 160 | pgd = pgd_offset_k(KASAN_SHADOW_START); | 160 | pgdp = pgd_offset_k(KASAN_SHADOW_START); |
| 161 | pgd_end = pgd_offset_k(KASAN_SHADOW_END); | 161 | pgdp_end = pgd_offset_k(KASAN_SHADOW_END); |
| 162 | pgd_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START); | 162 | pgdp_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START); |
| 163 | do { | 163 | do { |
| 164 | set_pgd(pgd_new, *pgd); | 164 | set_pgd(pgdp_new, READ_ONCE(*pgdp)); |
| 165 | } while (pgd++, pgd_new++, pgd != pgd_end); | 165 | } while (pgdp++, pgdp_new++, pgdp != pgdp_end); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static void __init clear_pgds(unsigned long start, | 168 | static void __init clear_pgds(unsigned long start, |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 4694cda823c9..3161b853f29e 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
| @@ -125,45 +125,48 @@ static bool pgattr_change_is_safe(u64 old, u64 new) | |||
| 125 | return ((old ^ new) & ~mask) == 0; | 125 | return ((old ^ new) & ~mask) == 0; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static void init_pte(pmd_t *pmd, unsigned long addr, unsigned long end, | 128 | static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, |
| 129 | phys_addr_t phys, pgprot_t prot) | 129 | phys_addr_t phys, pgprot_t prot) |
| 130 | { | 130 | { |
| 131 | pte_t *pte; | 131 | pte_t *ptep; |
| 132 | 132 | ||
| 133 | pte = pte_set_fixmap_offset(pmd, addr); | 133 | ptep = pte_set_fixmap_offset(pmdp, addr); |
| 134 | do { | 134 | do { |
| 135 | pte_t old_pte = *pte; | 135 | pte_t old_pte = READ_ONCE(*ptep); |
| 136 | 136 | ||
| 137 | set_pte(pte, pfn_pte(__phys_to_pfn(phys), prot)); | 137 | set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot)); |
| 138 | 138 | ||
| 139 | /* | 139 | /* |
| 140 | * After the PTE entry has been populated once, we | 140 | * After the PTE entry has been populated once, we |
| 141 | * only allow updates to the permission attributes. | 141 | * only allow updates to the permission attributes. |
| 142 | */ | 142 | */ |
| 143 | BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), pte_val(*pte))); | 143 | BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), |
| 144 | READ_ONCE(pte_val(*ptep)))); | ||
| 144 | 145 | ||
| 145 | phys += PAGE_SIZE; | 146 | phys += PAGE_SIZE; |
| 146 | } while (pte++, addr += PAGE_SIZE, addr != end); | 147 | } while (ptep++, addr += PAGE_SIZE, addr != end); |
| 147 | 148 | ||
| 148 | pte_clear_fixmap(); | 149 | pte_clear_fixmap(); |
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | static void alloc_init_cont_pte(pmd_t *pmd, unsigned long addr, | 152 | static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, |
| 152 | unsigned long end, phys_addr_t phys, | 153 | unsigned long end, phys_addr_t phys, |
| 153 | pgprot_t prot, | 154 | pgprot_t prot, |
| 154 | phys_addr_t (*pgtable_alloc)(void), | 155 | phys_addr_t (*pgtable_alloc)(void), |
| 155 | int flags) | 156 | int flags) |
| 156 | { | 157 | { |
| 157 | unsigned long next; | 158 | unsigned long next; |
| 159 | pmd_t pmd = READ_ONCE(*pmdp); | ||
| 158 | 160 | ||
| 159 | BUG_ON(pmd_sect(*pmd)); | 161 | BUG_ON(pmd_sect(pmd)); |
| 160 | if (pmd_none(*pmd)) { | 162 | if (pmd_none(pmd)) { |
| 161 | phys_addr_t pte_phys; | 163 | phys_addr_t pte_phys; |
| 162 | BUG_ON(!pgtable_alloc); | 164 | BUG_ON(!pgtable_alloc); |
| 163 | pte_phys = pgtable_alloc(); | 165 | pte_phys = pgtable_alloc(); |
| 164 | __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); | 166 | __pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE); |
| 167 | pmd = READ_ONCE(*pmdp); | ||
| 165 | } | 168 | } |
| 166 | BUG_ON(pmd_bad(*pmd)); | 169 | BUG_ON(pmd_bad(pmd)); |
| 167 | 170 | ||
| 168 | do { | 171 | do { |
| 169 | pgprot_t __prot = prot; | 172 | pgprot_t __prot = prot; |
| @@ -175,67 +178,69 @@ static void alloc_init_cont_pte(pmd_t *pmd, unsigned long addr, | |||
| 175 | (flags & NO_CONT_MAPPINGS) == 0) | 178 | (flags & NO_CONT_MAPPINGS) == 0) |
| 176 | __prot = __pgprot(pgprot_val(prot) | PTE_CONT); | 179 | __prot = __pgprot(pgprot_val(prot) | PTE_CONT); |
| 177 | 180 | ||
| 178 | init_pte(pmd, addr, next, phys, __prot); | 181 | init_pte(pmdp, addr, next, phys, __prot); |
| 179 | 182 | ||
| 180 | phys += next - addr; | 183 | phys += next - addr; |
| 181 | } while (addr = next, addr != end); | 184 | } while (addr = next, addr != end); |
| 182 | } | 185 | } |
| 183 | 186 | ||
| 184 | static void init_pmd(pud_t *pud, unsigned long addr, unsigned long end, | 187 | static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, |
| 185 | phys_addr_t phys, pgprot_t prot, | 188 | phys_addr_t phys, pgprot_t prot, |
| 186 | phys_addr_t (*pgtable_alloc)(void), int flags) | 189 | phys_addr_t (*pgtable_alloc)(void), int flags) |
| 187 | { | 190 | { |
| 188 | unsigned long next; | 191 | unsigned long next; |
| 189 | pmd_t *pmd; | 192 | pmd_t *pmdp; |
| 190 | 193 | ||
| 191 | pmd = pmd_set_fixmap_offset(pud, addr); | 194 | pmdp = pmd_set_fixmap_offset(pudp, addr); |
| 192 | do { | 195 | do { |
| 193 | pmd_t old_pmd = *pmd; | 196 | pmd_t old_pmd = READ_ONCE(*pmdp); |
| 194 | 197 | ||
| 195 | next = pmd_addr_end(addr, end); | 198 | next = pmd_addr_end(addr, end); |
| 196 | 199 | ||
| 197 | /* try section mapping first */ | 200 | /* try section mapping first */ |
| 198 | if (((addr | next | phys) & ~SECTION_MASK) == 0 && | 201 | if (((addr | next | phys) & ~SECTION_MASK) == 0 && |
| 199 | (flags & NO_BLOCK_MAPPINGS) == 0) { | 202 | (flags & NO_BLOCK_MAPPINGS) == 0) { |
| 200 | pmd_set_huge(pmd, phys, prot); | 203 | pmd_set_huge(pmdp, phys, prot); |
| 201 | 204 | ||
| 202 | /* | 205 | /* |
| 203 | * After the PMD entry has been populated once, we | 206 | * After the PMD entry has been populated once, we |
| 204 | * only allow updates to the permission attributes. | 207 | * only allow updates to the permission attributes. |
| 205 | */ | 208 | */ |
| 206 | BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd), | 209 | BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd), |
| 207 | pmd_val(*pmd))); | 210 | READ_ONCE(pmd_val(*pmdp)))); |
| 208 | } else { | 211 | } else { |
| 209 | alloc_init_cont_pte(pmd, addr, next, phys, prot, | 212 | alloc_init_cont_pte(pmdp, addr, next, phys, prot, |
| 210 | pgtable_alloc, flags); | 213 | pgtable_alloc, flags); |
| 211 | 214 | ||
| 212 | BUG_ON(pmd_val(old_pmd) != 0 && | 215 | BUG_ON(pmd_val(old_pmd) != 0 && |
| 213 | pmd_val(old_pmd) != pmd_val(*pmd)); | 216 | pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); |
| 214 | } | 217 | } |
| 215 | phys += next - addr; | 218 | phys += next - addr; |
| 216 | } while (pmd++, addr = next, addr != end); | 219 | } while (pmdp++, addr = next, addr != end); |
| 217 | 220 | ||
| 218 | pmd_clear_fixmap(); | 221 | pmd_clear_fixmap(); |
| 219 | } | 222 | } |
| 220 | 223 | ||
| 221 | static void alloc_init_cont_pmd(pud_t *pud, unsigned long addr, | 224 | static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, |
| 222 | unsigned long end, phys_addr_t phys, | 225 | unsigned long end, phys_addr_t phys, |
| 223 | pgprot_t prot, | 226 | pgprot_t prot, |
| 224 | phys_addr_t (*pgtable_alloc)(void), int flags) | 227 | phys_addr_t (*pgtable_alloc)(void), int flags) |
| 225 | { | 228 | { |
| 226 | unsigned long next; | 229 | unsigned long next; |
| 230 | pud_t pud = READ_ONCE(*pudp); | ||
| 227 | 231 | ||
| 228 | /* | 232 | /* |
| 229 | * Check for initial section mappings in the pgd/pud. | 233 | * Check for initial section mappings in the pgd/pud. |
| 230 | */ | 234 | */ |
| 231 | BUG_ON(pud_sect(*pud)); | 235 | BUG_ON(pud_sect(pud)); |
| 232 | if (pud_none(*pud)) { | 236 | if (pud_none(pud)) { |
| 233 | phys_addr_t pmd_phys; | 237 | phys_addr_t pmd_phys; |
| 234 | BUG_ON(!pgtable_alloc); | 238 | BUG_ON(!pgtable_alloc); |
| 235 | pmd_phys = pgtable_alloc(); | 239 | pmd_phys = pgtable_alloc(); |
| 236 | __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE); | 240 | __pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE); |
| 241 | pud = READ_ONCE(*pudp); | ||
| 237 | } | 242 | } |
| 238 | BUG_ON(pud_bad(*pud)); | 243 | BUG_ON(pud_bad(pud)); |
| 239 | 244 | ||
| 240 | do { | 245 | do { |
| 241 | pgprot_t __prot = prot; | 246 | pgprot_t __prot = prot; |
| @@ -247,7 +252,7 @@ static void alloc_init_cont_pmd(pud_t *pud, unsigned long addr, | |||
| 247 | (flags & NO_CONT_MAPPINGS) == 0) | 252 | (flags & NO_CONT_MAPPINGS) == 0) |
| 248 | __prot = __pgprot(pgprot_val(prot) | PTE_CONT); | 253 | __prot = __pgprot(pgprot_val(prot) | PTE_CONT); |
| 249 | 254 | ||
| 250 | init_pmd(pud, addr, next, phys, __prot, pgtable_alloc, flags); | 255 | init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags); |
| 251 | 256 | ||
| 252 | phys += next - addr; | 257 | phys += next - addr; |
| 253 | } while (addr = next, addr != end); | 258 | } while (addr = next, addr != end); |
| @@ -265,25 +270,27 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next, | |||
| 265 | return true; | 270 | return true; |
| 266 | } | 271 | } |
| 267 | 272 | ||
| 268 | static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | 273 | static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, |
| 269 | phys_addr_t phys, pgprot_t prot, | 274 | phys_addr_t phys, pgprot_t prot, |
| 270 | phys_addr_t (*pgtable_alloc)(void), | 275 | phys_addr_t (*pgtable_alloc)(void), |
| 271 | int flags) | 276 | int flags) |
| 272 | { | 277 | { |
| 273 | pud_t *pud; | ||
| 274 | unsigned long next; | 278 | unsigned long next; |
| 279 | pud_t *pudp; | ||
| 280 | pgd_t pgd = READ_ONCE(*pgdp); | ||
| 275 | 281 | ||
| 276 | if (pgd_none(*pgd)) { | 282 | if (pgd_none(pgd)) { |
| 277 | phys_addr_t pud_phys; | 283 | phys_addr_t pud_phys; |
| 278 | BUG_ON(!pgtable_alloc); | 284 | BUG_ON(!pgtable_alloc); |
| 279 | pud_phys = pgtable_alloc(); | 285 | pud_phys = pgtable_alloc(); |
| 280 | __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE); | 286 | __pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE); |
| 287 | pgd = READ_ONCE(*pgdp); | ||
| 281 | } | 288 | } |
| 282 | BUG_ON(pgd_bad(*pgd)); | 289 | BUG_ON(pgd_bad(pgd)); |
| 283 | 290 | ||
| 284 | pud = pud_set_fixmap_offset(pgd, addr); | 291 | pudp = pud_set_fixmap_offset(pgdp, addr); |
| 285 | do { | 292 | do { |
| 286 | pud_t old_pud = *pud; | 293 | pud_t old_pud = READ_ONCE(*pudp); |
| 287 | 294 | ||
| 288 | next = pud_addr_end(addr, end); | 295 | next = pud_addr_end(addr, end); |
| 289 | 296 | ||
| @@ -292,23 +299,23 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
| 292 | */ | 299 | */ |
| 293 | if (use_1G_block(addr, next, phys) && | 300 | if (use_1G_block(addr, next, phys) && |
| 294 | (flags & NO_BLOCK_MAPPINGS) == 0) { | 301 | (flags & NO_BLOCK_MAPPINGS) == 0) { |
| 295 | pud_set_huge(pud, phys, prot); | 302 | pud_set_huge(pudp, phys, prot); |
| 296 | 303 | ||
| 297 | /* | 304 | /* |
| 298 | * After the PUD entry has been populated once, we | 305 | * After the PUD entry has been populated once, we |
| 299 | * only allow updates to the permission attributes. | 306 | * only allow updates to the permission attributes. |
| 300 | */ | 307 | */ |
| 301 | BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), | 308 | BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), |
| 302 | pud_val(*pud))); | 309 | READ_ONCE(pud_val(*pudp)))); |
| 303 | } else { | 310 | } else { |
| 304 | alloc_init_cont_pmd(pud, addr, next, phys, prot, | 311 | alloc_init_cont_pmd(pudp, addr, next, phys, prot, |
| 305 | pgtable_alloc, flags); | 312 | pgtable_alloc, flags); |
| 306 | 313 | ||
| 307 | BUG_ON(pud_val(old_pud) != 0 && | 314 | BUG_ON(pud_val(old_pud) != 0 && |
| 308 | pud_val(old_pud) != pud_val(*pud)); | 315 | pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); |
| 309 | } | 316 | } |
| 310 | phys += next - addr; | 317 | phys += next - addr; |
| 311 | } while (pud++, addr = next, addr != end); | 318 | } while (pudp++, addr = next, addr != end); |
| 312 | 319 | ||
| 313 | pud_clear_fixmap(); | 320 | pud_clear_fixmap(); |
| 314 | } | 321 | } |
| @@ -320,7 +327,7 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, | |||
| 320 | int flags) | 327 | int flags) |
| 321 | { | 328 | { |
| 322 | unsigned long addr, length, end, next; | 329 | unsigned long addr, length, end, next; |
| 323 | pgd_t *pgd = pgd_offset_raw(pgdir, virt); | 330 | pgd_t *pgdp = pgd_offset_raw(pgdir, virt); |
| 324 | 331 | ||
| 325 | /* | 332 | /* |
| 326 | * If the virtual and physical address don't have the same offset | 333 | * If the virtual and physical address don't have the same offset |
| @@ -336,10 +343,10 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, | |||
| 336 | end = addr + length; | 343 | end = addr + length; |
| 337 | do { | 344 | do { |
| 338 | next = pgd_addr_end(addr, end); | 345 | next = pgd_addr_end(addr, end); |
| 339 | alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc, | 346 | alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc, |
| 340 | flags); | 347 | flags); |
| 341 | phys += next - addr; | 348 | phys += next - addr; |
| 342 | } while (pgd++, addr = next, addr != end); | 349 | } while (pgdp++, addr = next, addr != end); |
| 343 | } | 350 | } |
| 344 | 351 | ||
| 345 | static phys_addr_t pgd_pgtable_alloc(void) | 352 | static phys_addr_t pgd_pgtable_alloc(void) |
| @@ -401,10 +408,10 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt, | |||
| 401 | flush_tlb_kernel_range(virt, virt + size); | 408 | flush_tlb_kernel_range(virt, virt + size); |
| 402 | } | 409 | } |
| 403 | 410 | ||
| 404 | static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, | 411 | static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, |
| 405 | phys_addr_t end, pgprot_t prot, int flags) | 412 | phys_addr_t end, pgprot_t prot, int flags) |
| 406 | { | 413 | { |
| 407 | __create_pgd_mapping(pgd, start, __phys_to_virt(start), end - start, | 414 | __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, |
| 408 | prot, early_pgtable_alloc, flags); | 415 | prot, early_pgtable_alloc, flags); |
| 409 | } | 416 | } |
| 410 | 417 | ||
| @@ -418,7 +425,7 @@ void __init mark_linear_text_alias_ro(void) | |||
| 418 | PAGE_KERNEL_RO); | 425 | PAGE_KERNEL_RO); |
| 419 | } | 426 | } |
| 420 | 427 | ||
| 421 | static void __init map_mem(pgd_t *pgd) | 428 | static void __init map_mem(pgd_t *pgdp) |
| 422 | { | 429 | { |
| 423 | phys_addr_t kernel_start = __pa_symbol(_text); | 430 | phys_addr_t kernel_start = __pa_symbol(_text); |
| 424 | phys_addr_t kernel_end = __pa_symbol(__init_begin); | 431 | phys_addr_t kernel_end = __pa_symbol(__init_begin); |
| @@ -451,7 +458,7 @@ static void __init map_mem(pgd_t *pgd) | |||
| 451 | if (memblock_is_nomap(reg)) | 458 | if (memblock_is_nomap(reg)) |
| 452 | continue; | 459 | continue; |
| 453 | 460 | ||
| 454 | __map_memblock(pgd, start, end, PAGE_KERNEL, flags); | 461 | __map_memblock(pgdp, start, end, PAGE_KERNEL, flags); |
| 455 | } | 462 | } |
| 456 | 463 | ||
| 457 | /* | 464 | /* |
| @@ -464,7 +471,7 @@ static void __init map_mem(pgd_t *pgd) | |||
| 464 | * Note that contiguous mappings cannot be remapped in this way, | 471 | * Note that contiguous mappings cannot be remapped in this way, |
| 465 | * so we should avoid them here. | 472 | * so we should avoid them here. |
| 466 | */ | 473 | */ |
| 467 | __map_memblock(pgd, kernel_start, kernel_end, | 474 | __map_memblock(pgdp, kernel_start, kernel_end, |
| 468 | PAGE_KERNEL, NO_CONT_MAPPINGS); | 475 | PAGE_KERNEL, NO_CONT_MAPPINGS); |
| 469 | memblock_clear_nomap(kernel_start, kernel_end - kernel_start); | 476 | memblock_clear_nomap(kernel_start, kernel_end - kernel_start); |
| 470 | 477 | ||
| @@ -475,7 +482,7 @@ static void __init map_mem(pgd_t *pgd) | |||
| 475 | * through /sys/kernel/kexec_crash_size interface. | 482 | * through /sys/kernel/kexec_crash_size interface. |
| 476 | */ | 483 | */ |
| 477 | if (crashk_res.end) { | 484 | if (crashk_res.end) { |
| 478 | __map_memblock(pgd, crashk_res.start, crashk_res.end + 1, | 485 | __map_memblock(pgdp, crashk_res.start, crashk_res.end + 1, |
| 479 | PAGE_KERNEL, | 486 | PAGE_KERNEL, |
| 480 | NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); | 487 | NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); |
| 481 | memblock_clear_nomap(crashk_res.start, | 488 | memblock_clear_nomap(crashk_res.start, |
| @@ -499,7 +506,7 @@ void mark_rodata_ro(void) | |||
| 499 | debug_checkwx(); | 506 | debug_checkwx(); |
| 500 | } | 507 | } |
| 501 | 508 | ||
| 502 | static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end, | 509 | static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end, |
| 503 | pgprot_t prot, struct vm_struct *vma, | 510 | pgprot_t prot, struct vm_struct *vma, |
| 504 | int flags, unsigned long vm_flags) | 511 | int flags, unsigned long vm_flags) |
| 505 | { | 512 | { |
| @@ -509,7 +516,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end, | |||
| 509 | BUG_ON(!PAGE_ALIGNED(pa_start)); | 516 | BUG_ON(!PAGE_ALIGNED(pa_start)); |
| 510 | BUG_ON(!PAGE_ALIGNED(size)); | 517 | BUG_ON(!PAGE_ALIGNED(size)); |
| 511 | 518 | ||
| 512 | __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot, | 519 | __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot, |
| 513 | early_pgtable_alloc, flags); | 520 | early_pgtable_alloc, flags); |
| 514 | 521 | ||
| 515 | if (!(vm_flags & VM_NO_GUARD)) | 522 | if (!(vm_flags & VM_NO_GUARD)) |
| @@ -562,7 +569,7 @@ core_initcall(map_entry_trampoline); | |||
| 562 | /* | 569 | /* |
| 563 | * Create fine-grained mappings for the kernel. | 570 | * Create fine-grained mappings for the kernel. |
| 564 | */ | 571 | */ |
| 565 | static void __init map_kernel(pgd_t *pgd) | 572 | static void __init map_kernel(pgd_t *pgdp) |
| 566 | { | 573 | { |
| 567 | static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, | 574 | static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, |
| 568 | vmlinux_initdata, vmlinux_data; | 575 | vmlinux_initdata, vmlinux_data; |
| @@ -578,24 +585,24 @@ static void __init map_kernel(pgd_t *pgd) | |||
| 578 | * Only rodata will be remapped with different permissions later on, | 585 | * Only rodata will be remapped with different permissions later on, |
| 579 | * all other segments are allowed to use contiguous mappings. | 586 | * all other segments are allowed to use contiguous mappings. |
| 580 | */ | 587 | */ |
| 581 | map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0, | 588 | map_kernel_segment(pgdp, _text, _etext, text_prot, &vmlinux_text, 0, |
| 582 | VM_NO_GUARD); | 589 | VM_NO_GUARD); |
| 583 | map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL, | 590 | map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL, |
| 584 | &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); | 591 | &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); |
| 585 | map_kernel_segment(pgd, __inittext_begin, __inittext_end, text_prot, | 592 | map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot, |
| 586 | &vmlinux_inittext, 0, VM_NO_GUARD); | 593 | &vmlinux_inittext, 0, VM_NO_GUARD); |
| 587 | map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL, | 594 | map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL, |
| 588 | &vmlinux_initdata, 0, VM_NO_GUARD); | 595 | &vmlinux_initdata, 0, VM_NO_GUARD); |
| 589 | map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); | 596 | map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); |
| 590 | 597 | ||
| 591 | if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) { | 598 | if (!READ_ONCE(pgd_val(*pgd_offset_raw(pgdp, FIXADDR_START)))) { |
| 592 | /* | 599 | /* |
| 593 | * The fixmap falls in a separate pgd to the kernel, and doesn't | 600 | * The fixmap falls in a separate pgd to the kernel, and doesn't |
| 594 | * live in the carveout for the swapper_pg_dir. We can simply | 601 | * live in the carveout for the swapper_pg_dir. We can simply |
| 595 | * re-use the existing dir for the fixmap. | 602 | * re-use the existing dir for the fixmap. |
| 596 | */ | 603 | */ |
| 597 | set_pgd(pgd_offset_raw(pgd, FIXADDR_START), | 604 | set_pgd(pgd_offset_raw(pgdp, FIXADDR_START), |
| 598 | *pgd_offset_k(FIXADDR_START)); | 605 | READ_ONCE(*pgd_offset_k(FIXADDR_START))); |
| 599 | } else if (CONFIG_PGTABLE_LEVELS > 3) { | 606 | } else if (CONFIG_PGTABLE_LEVELS > 3) { |
| 600 | /* | 607 | /* |
| 601 | * The fixmap shares its top level pgd entry with the kernel | 608 | * The fixmap shares its top level pgd entry with the kernel |
| @@ -604,14 +611,15 @@ static void __init map_kernel(pgd_t *pgd) | |||
| 604 | * entry instead. | 611 | * entry instead. |
| 605 | */ | 612 | */ |
| 606 | BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); | 613 | BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); |
| 607 | pud_populate(&init_mm, pud_set_fixmap_offset(pgd, FIXADDR_START), | 614 | pud_populate(&init_mm, |
| 615 | pud_set_fixmap_offset(pgdp, FIXADDR_START), | ||
| 608 | lm_alias(bm_pmd)); | 616 | lm_alias(bm_pmd)); |
| 609 | pud_clear_fixmap(); | 617 | pud_clear_fixmap(); |
| 610 | } else { | 618 | } else { |
| 611 | BUG(); | 619 | BUG(); |
| 612 | } | 620 | } |
| 613 | 621 | ||
| 614 | kasan_copy_shadow(pgd); | 622 | kasan_copy_shadow(pgdp); |
| 615 | } | 623 | } |
| 616 | 624 | ||
| 617 | /* | 625 | /* |
| @@ -621,10 +629,10 @@ static void __init map_kernel(pgd_t *pgd) | |||
| 621 | void __init paging_init(void) | 629 | void __init paging_init(void) |
| 622 | { | 630 | { |
| 623 | phys_addr_t pgd_phys = early_pgtable_alloc(); | 631 | phys_addr_t pgd_phys = early_pgtable_alloc(); |
| 624 | pgd_t *pgd = pgd_set_fixmap(pgd_phys); | 632 | pgd_t *pgdp = pgd_set_fixmap(pgd_phys); |
| 625 | 633 | ||
| 626 | map_kernel(pgd); | 634 | map_kernel(pgdp); |
| 627 | map_mem(pgd); | 635 | map_mem(pgdp); |
| 628 | 636 | ||
| 629 | /* | 637 | /* |
| 630 | * We want to reuse the original swapper_pg_dir so we don't have to | 638 | * We want to reuse the original swapper_pg_dir so we don't have to |
| @@ -635,7 +643,7 @@ void __init paging_init(void) | |||
| 635 | * To do this we need to go via a temporary pgd. | 643 | * To do this we need to go via a temporary pgd. |
| 636 | */ | 644 | */ |
| 637 | cpu_replace_ttbr1(__va(pgd_phys)); | 645 | cpu_replace_ttbr1(__va(pgd_phys)); |
| 638 | memcpy(swapper_pg_dir, pgd, PGD_SIZE); | 646 | memcpy(swapper_pg_dir, pgdp, PGD_SIZE); |
| 639 | cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); | 647 | cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); |
| 640 | 648 | ||
| 641 | pgd_clear_fixmap(); | 649 | pgd_clear_fixmap(); |
| @@ -655,37 +663,40 @@ void __init paging_init(void) | |||
| 655 | */ | 663 | */ |
| 656 | int kern_addr_valid(unsigned long addr) | 664 | int kern_addr_valid(unsigned long addr) |
| 657 | { | 665 | { |
| 658 | pgd_t *pgd; | 666 | pgd_t *pgdp; |
| 659 | pud_t *pud; | 667 | pud_t *pudp, pud; |
| 660 | pmd_t *pmd; | 668 | pmd_t *pmdp, pmd; |
| 661 | pte_t *pte; | 669 | pte_t *ptep, pte; |
| 662 | 670 | ||
| 663 | if ((((long)addr) >> VA_BITS) != -1UL) | 671 | if ((((long)addr) >> VA_BITS) != -1UL) |
| 664 | return 0; | 672 | return 0; |
| 665 | 673 | ||
| 666 | pgd = pgd_offset_k(addr); | 674 | pgdp = pgd_offset_k(addr); |
| 667 | if (pgd_none(*pgd)) | 675 | if (pgd_none(READ_ONCE(*pgdp))) |
| 668 | return 0; | 676 | return 0; |
| 669 | 677 | ||
| 670 | pud = pud_offset(pgd, addr); | 678 | pudp = pud_offset(pgdp, addr); |
| 671 | if (pud_none(*pud)) | 679 | pud = READ_ONCE(*pudp); |
| 680 | if (pud_none(pud)) | ||
| 672 | return 0; | 681 | return 0; |
| 673 | 682 | ||
| 674 | if (pud_sect(*pud)) | 683 | if (pud_sect(pud)) |
| 675 | return pfn_valid(pud_pfn(*pud)); | 684 | return pfn_valid(pud_pfn(pud)); |
| 676 | 685 | ||
| 677 | pmd = pmd_offset(pud, addr); | 686 | pmdp = pmd_offset(pudp, addr); |
| 678 | if (pmd_none(*pmd)) | 687 | pmd = READ_ONCE(*pmdp); |
| 688 | if (pmd_none(pmd)) | ||
| 679 | return 0; | 689 | return 0; |
| 680 | 690 | ||
| 681 | if (pmd_sect(*pmd)) | 691 | if (pmd_sect(pmd)) |
| 682 | return pfn_valid(pmd_pfn(*pmd)); | 692 | return pfn_valid(pmd_pfn(pmd)); |
| 683 | 693 | ||
| 684 | pte = pte_offset_kernel(pmd, addr); | 694 | ptep = pte_offset_kernel(pmdp, addr); |
| 685 | if (pte_none(*pte)) | 695 | pte = READ_ONCE(*ptep); |
| 696 | if (pte_none(pte)) | ||
| 686 | return 0; | 697 | return 0; |
| 687 | 698 | ||
| 688 | return pfn_valid(pte_pfn(*pte)); | 699 | return pfn_valid(pte_pfn(pte)); |
| 689 | } | 700 | } |
| 690 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 701 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
| 691 | #if !ARM64_SWAPPER_USES_SECTION_MAPS | 702 | #if !ARM64_SWAPPER_USES_SECTION_MAPS |
| @@ -700,32 +711,32 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, | |||
| 700 | { | 711 | { |
| 701 | unsigned long addr = start; | 712 | unsigned long addr = start; |
| 702 | unsigned long next; | 713 | unsigned long next; |
| 703 | pgd_t *pgd; | 714 | pgd_t *pgdp; |
| 704 | pud_t *pud; | 715 | pud_t *pudp; |
| 705 | pmd_t *pmd; | 716 | pmd_t *pmdp; |
| 706 | 717 | ||
| 707 | do { | 718 | do { |
| 708 | next = pmd_addr_end(addr, end); | 719 | next = pmd_addr_end(addr, end); |
| 709 | 720 | ||
| 710 | pgd = vmemmap_pgd_populate(addr, node); | 721 | pgdp = vmemmap_pgd_populate(addr, node); |
| 711 | if (!pgd) | 722 | if (!pgdp) |
| 712 | return -ENOMEM; | 723 | return -ENOMEM; |
| 713 | 724 | ||
| 714 | pud = vmemmap_pud_populate(pgd, addr, node); | 725 | pudp = vmemmap_pud_populate(pgdp, addr, node); |
| 715 | if (!pud) | 726 | if (!pudp) |
| 716 | return -ENOMEM; | 727 | return -ENOMEM; |
| 717 | 728 | ||
| 718 | pmd = pmd_offset(pud, addr); | 729 | pmdp = pmd_offset(pudp, addr); |
| 719 | if (pmd_none(*pmd)) { | 730 | if (pmd_none(READ_ONCE(*pmdp))) { |
| 720 | void *p = NULL; | 731 | void *p = NULL; |
| 721 | 732 | ||
| 722 | p = vmemmap_alloc_block_buf(PMD_SIZE, node); | 733 | p = vmemmap_alloc_block_buf(PMD_SIZE, node); |
| 723 | if (!p) | 734 | if (!p) |
| 724 | return -ENOMEM; | 735 | return -ENOMEM; |
| 725 | 736 | ||
| 726 | pmd_set_huge(pmd, __pa(p), __pgprot(PROT_SECT_NORMAL)); | 737 | pmd_set_huge(pmdp, __pa(p), __pgprot(PROT_SECT_NORMAL)); |
| 727 | } else | 738 | } else |
| 728 | vmemmap_verify((pte_t *)pmd, node, addr, next); | 739 | vmemmap_verify((pte_t *)pmdp, node, addr, next); |
| 729 | } while (addr = next, addr != end); | 740 | } while (addr = next, addr != end); |
| 730 | 741 | ||
| 731 | return 0; | 742 | return 0; |
| @@ -739,20 +750,22 @@ void vmemmap_free(unsigned long start, unsigned long end, | |||
| 739 | 750 | ||
| 740 | static inline pud_t * fixmap_pud(unsigned long addr) | 751 | static inline pud_t * fixmap_pud(unsigned long addr) |
| 741 | { | 752 | { |
| 742 | pgd_t *pgd = pgd_offset_k(addr); | 753 | pgd_t *pgdp = pgd_offset_k(addr); |
| 754 | pgd_t pgd = READ_ONCE(*pgdp); | ||
| 743 | 755 | ||
| 744 | BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd)); | 756 | BUG_ON(pgd_none(pgd) || pgd_bad(pgd)); |
| 745 | 757 | ||
| 746 | return pud_offset_kimg(pgd, addr); | 758 | return pud_offset_kimg(pgdp, addr); |
| 747 | } | 759 | } |
| 748 | 760 | ||
| 749 | static inline pmd_t * fixmap_pmd(unsigned long addr) | 761 | static inline pmd_t * fixmap_pmd(unsigned long addr) |
| 750 | { | 762 | { |
| 751 | pud_t *pud = fixmap_pud(addr); | 763 | pud_t *pudp = fixmap_pud(addr); |
| 764 | pud_t pud = READ_ONCE(*pudp); | ||
| 752 | 765 | ||
| 753 | BUG_ON(pud_none(*pud) || pud_bad(*pud)); | 766 | BUG_ON(pud_none(pud) || pud_bad(pud)); |
| 754 | 767 | ||
| 755 | return pmd_offset_kimg(pud, addr); | 768 | return pmd_offset_kimg(pudp, addr); |
| 756 | } | 769 | } |
| 757 | 770 | ||
| 758 | static inline pte_t * fixmap_pte(unsigned long addr) | 771 | static inline pte_t * fixmap_pte(unsigned long addr) |
| @@ -768,30 +781,31 @@ static inline pte_t * fixmap_pte(unsigned long addr) | |||
| 768 | */ | 781 | */ |
| 769 | void __init early_fixmap_init(void) | 782 | void __init early_fixmap_init(void) |
| 770 | { | 783 | { |
| 771 | pgd_t *pgd; | 784 | pgd_t *pgdp, pgd; |
| 772 | pud_t *pud; | 785 | pud_t *pudp; |
| 773 | pmd_t *pmd; | 786 | pmd_t *pmdp; |
| 774 | unsigned long addr = FIXADDR_START; | 787 | unsigned long addr = FIXADDR_START; |
| 775 | 788 | ||
| 776 | pgd = pgd_offset_k(addr); | 789 | pgdp = pgd_offset_k(addr); |
| 790 | pgd = READ_ONCE(*pgdp); | ||
| 777 | if (CONFIG_PGTABLE_LEVELS > 3 && | 791 | if (CONFIG_PGTABLE_LEVELS > 3 && |
| 778 | !(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa_symbol(bm_pud))) { | 792 | !(pgd_none(pgd) || pgd_page_paddr(pgd) == __pa_symbol(bm_pud))) { |
| 779 | /* | 793 | /* |
| 780 | * We only end up here if the kernel mapping and the fixmap | 794 | * We only end up here if the kernel mapping and the fixmap |
| 781 | * share the top level pgd entry, which should only happen on | 795 | * share the top level pgd entry, which should only happen on |
| 782 | * 16k/4 levels configurations. | 796 | * 16k/4 levels configurations. |
| 783 | */ | 797 | */ |
| 784 | BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); | 798 | BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); |
| 785 | pud = pud_offset_kimg(pgd, addr); | 799 | pudp = pud_offset_kimg(pgdp, addr); |
| 786 | } else { | 800 | } else { |
| 787 | if (pgd_none(*pgd)) | 801 | if (pgd_none(pgd)) |
| 788 | __pgd_populate(pgd, __pa_symbol(bm_pud), PUD_TYPE_TABLE); | 802 | __pgd_populate(pgdp, __pa_symbol(bm_pud), PUD_TYPE_TABLE); |
| 789 | pud = fixmap_pud(addr); | 803 | pudp = fixmap_pud(addr); |
| 790 | } | 804 | } |
| 791 | if (pud_none(*pud)) | 805 | if (pud_none(READ_ONCE(*pudp))) |
| 792 | __pud_populate(pud, __pa_symbol(bm_pmd), PMD_TYPE_TABLE); | 806 | __pud_populate(pudp, __pa_symbol(bm_pmd), PMD_TYPE_TABLE); |
| 793 | pmd = fixmap_pmd(addr); | 807 | pmdp = fixmap_pmd(addr); |
| 794 | __pmd_populate(pmd, __pa_symbol(bm_pte), PMD_TYPE_TABLE); | 808 | __pmd_populate(pmdp, __pa_symbol(bm_pte), PMD_TYPE_TABLE); |
| 795 | 809 | ||
| 796 | /* | 810 | /* |
| 797 | * The boot-ioremap range spans multiple pmds, for which | 811 | * The boot-ioremap range spans multiple pmds, for which |
| @@ -800,11 +814,11 @@ void __init early_fixmap_init(void) | |||
| 800 | BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT) | 814 | BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT) |
| 801 | != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT)); | 815 | != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT)); |
| 802 | 816 | ||
| 803 | if ((pmd != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN))) | 817 | if ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN))) |
| 804 | || pmd != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) { | 818 | || pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) { |
| 805 | WARN_ON(1); | 819 | WARN_ON(1); |
| 806 | pr_warn("pmd %p != %p, %p\n", | 820 | pr_warn("pmdp %p != %p, %p\n", |
| 807 | pmd, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)), | 821 | pmdp, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)), |
| 808 | fixmap_pmd(fix_to_virt(FIX_BTMAP_END))); | 822 | fixmap_pmd(fix_to_virt(FIX_BTMAP_END))); |
| 809 | pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", | 823 | pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", |
| 810 | fix_to_virt(FIX_BTMAP_BEGIN)); | 824 | fix_to_virt(FIX_BTMAP_BEGIN)); |
| @@ -824,16 +838,16 @@ void __set_fixmap(enum fixed_addresses idx, | |||
| 824 | phys_addr_t phys, pgprot_t flags) | 838 | phys_addr_t phys, pgprot_t flags) |
| 825 | { | 839 | { |
| 826 | unsigned long addr = __fix_to_virt(idx); | 840 | unsigned long addr = __fix_to_virt(idx); |
| 827 | pte_t *pte; | 841 | pte_t *ptep; |
| 828 | 842 | ||
| 829 | BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); | 843 | BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); |
| 830 | 844 | ||
| 831 | pte = fixmap_pte(addr); | 845 | ptep = fixmap_pte(addr); |
| 832 | 846 | ||
| 833 | if (pgprot_val(flags)) { | 847 | if (pgprot_val(flags)) { |
| 834 | set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); | 848 | set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); |
| 835 | } else { | 849 | } else { |
| 836 | pte_clear(&init_mm, addr, pte); | 850 | pte_clear(&init_mm, addr, ptep); |
| 837 | flush_tlb_kernel_range(addr, addr+PAGE_SIZE); | 851 | flush_tlb_kernel_range(addr, addr+PAGE_SIZE); |
| 838 | } | 852 | } |
| 839 | } | 853 | } |
| @@ -915,36 +929,36 @@ int __init arch_ioremap_pmd_supported(void) | |||
| 915 | return 1; | 929 | return 1; |
| 916 | } | 930 | } |
| 917 | 931 | ||
| 918 | int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot) | 932 | int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) |
| 919 | { | 933 | { |
| 920 | pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT | | 934 | pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT | |
| 921 | pgprot_val(mk_sect_prot(prot))); | 935 | pgprot_val(mk_sect_prot(prot))); |
| 922 | BUG_ON(phys & ~PUD_MASK); | 936 | BUG_ON(phys & ~PUD_MASK); |
| 923 | set_pud(pud, pfn_pud(__phys_to_pfn(phys), sect_prot)); | 937 | set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot)); |
| 924 | return 1; | 938 | return 1; |
| 925 | } | 939 | } |
| 926 | 940 | ||
| 927 | int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot) | 941 | int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) |
| 928 | { | 942 | { |
| 929 | pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT | | 943 | pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT | |
| 930 | pgprot_val(mk_sect_prot(prot))); | 944 | pgprot_val(mk_sect_prot(prot))); |
| 931 | BUG_ON(phys & ~PMD_MASK); | 945 | BUG_ON(phys & ~PMD_MASK); |
| 932 | set_pmd(pmd, pfn_pmd(__phys_to_pfn(phys), sect_prot)); | 946 | set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot)); |
| 933 | return 1; | 947 | return 1; |
| 934 | } | 948 | } |
| 935 | 949 | ||
| 936 | int pud_clear_huge(pud_t *pud) | 950 | int pud_clear_huge(pud_t *pudp) |
| 937 | { | 951 | { |
| 938 | if (!pud_sect(*pud)) | 952 | if (!pud_sect(READ_ONCE(*pudp))) |
| 939 | return 0; | 953 | return 0; |
| 940 | pud_clear(pud); | 954 | pud_clear(pudp); |
| 941 | return 1; | 955 | return 1; |
| 942 | } | 956 | } |
| 943 | 957 | ||
| 944 | int pmd_clear_huge(pmd_t *pmd) | 958 | int pmd_clear_huge(pmd_t *pmdp) |
| 945 | { | 959 | { |
| 946 | if (!pmd_sect(*pmd)) | 960 | if (!pmd_sect(READ_ONCE(*pmdp))) |
| 947 | return 0; | 961 | return 0; |
| 948 | pmd_clear(pmd); | 962 | pmd_clear(pmdp); |
| 949 | return 1; | 963 | return 1; |
| 950 | } | 964 | } |
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index a682a0a2a0fa..a56359373d8b 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c | |||
| @@ -29,7 +29,7 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr, | |||
| 29 | void *data) | 29 | void *data) |
| 30 | { | 30 | { |
| 31 | struct page_change_data *cdata = data; | 31 | struct page_change_data *cdata = data; |
| 32 | pte_t pte = *ptep; | 32 | pte_t pte = READ_ONCE(*ptep); |
| 33 | 33 | ||
| 34 | pte = clear_pte_bit(pte, cdata->clear_mask); | 34 | pte = clear_pte_bit(pte, cdata->clear_mask); |
| 35 | pte = set_pte_bit(pte, cdata->set_mask); | 35 | pte = set_pte_bit(pte, cdata->set_mask); |
| @@ -156,30 +156,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) | |||
| 156 | */ | 156 | */ |
| 157 | bool kernel_page_present(struct page *page) | 157 | bool kernel_page_present(struct page *page) |
| 158 | { | 158 | { |
| 159 | pgd_t *pgd; | 159 | pgd_t *pgdp; |
| 160 | pud_t *pud; | 160 | pud_t *pudp, pud; |
| 161 | pmd_t *pmd; | 161 | pmd_t *pmdp, pmd; |
| 162 | pte_t *pte; | 162 | pte_t *ptep; |
| 163 | unsigned long addr = (unsigned long)page_address(page); | 163 | unsigned long addr = (unsigned long)page_address(page); |
| 164 | 164 | ||
| 165 | pgd = pgd_offset_k(addr); | 165 | pgdp = pgd_offset_k(addr); |
| 166 | if (pgd_none(*pgd)) | 166 | if (pgd_none(READ_ONCE(*pgdp))) |
| 167 | return false; | 167 | return false; |
| 168 | 168 | ||
| 169 | pud = pud_offset(pgd, addr); | 169 | pudp = pud_offset(pgdp, addr); |
| 170 | if (pud_none(*pud)) | 170 | pud = READ_ONCE(*pudp); |
| 171 | if (pud_none(pud)) | ||
| 171 | return false; | 172 | return false; |
| 172 | if (pud_sect(*pud)) | 173 | if (pud_sect(pud)) |
| 173 | return true; | 174 | return true; |
| 174 | 175 | ||
| 175 | pmd = pmd_offset(pud, addr); | 176 | pmdp = pmd_offset(pudp, addr); |
| 176 | if (pmd_none(*pmd)) | 177 | pmd = READ_ONCE(*pmdp); |
| 178 | if (pmd_none(pmd)) | ||
| 177 | return false; | 179 | return false; |
| 178 | if (pmd_sect(*pmd)) | 180 | if (pmd_sect(pmd)) |
| 179 | return true; | 181 | return true; |
| 180 | 182 | ||
| 181 | pte = pte_offset_kernel(pmd, addr); | 183 | ptep = pte_offset_kernel(pmdp, addr); |
| 182 | return pte_valid(*pte); | 184 | return pte_valid(READ_ONCE(*ptep)); |
| 183 | } | 185 | } |
| 184 | #endif /* CONFIG_HIBERNATION */ | 186 | #endif /* CONFIG_HIBERNATION */ |
| 185 | #endif /* CONFIG_DEBUG_PAGEALLOC */ | 187 | #endif /* CONFIG_DEBUG_PAGEALLOC */ |
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 71baed7e592a..c0af47617299 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S | |||
| @@ -205,7 +205,8 @@ ENDPROC(idmap_cpu_replace_ttbr1) | |||
| 205 | dc cvac, cur_\()\type\()p // Ensure any existing dirty | 205 | dc cvac, cur_\()\type\()p // Ensure any existing dirty |
| 206 | dmb sy // lines are written back before | 206 | dmb sy // lines are written back before |
| 207 | ldr \type, [cur_\()\type\()p] // loading the entry | 207 | ldr \type, [cur_\()\type\()p] // loading the entry |
| 208 | tbz \type, #0, next_\()\type // Skip invalid entries | 208 | tbz \type, #0, skip_\()\type // Skip invalid and |
| 209 | tbnz \type, #11, skip_\()\type // non-global entries | ||
| 209 | .endm | 210 | .endm |
| 210 | 211 | ||
| 211 | .macro __idmap_kpti_put_pgtable_ent_ng, type | 212 | .macro __idmap_kpti_put_pgtable_ent_ng, type |
| @@ -265,8 +266,9 @@ ENTRY(idmap_kpti_install_ng_mappings) | |||
| 265 | add end_pgdp, cur_pgdp, #(PTRS_PER_PGD * 8) | 266 | add end_pgdp, cur_pgdp, #(PTRS_PER_PGD * 8) |
| 266 | do_pgd: __idmap_kpti_get_pgtable_ent pgd | 267 | do_pgd: __idmap_kpti_get_pgtable_ent pgd |
| 267 | tbnz pgd, #1, walk_puds | 268 | tbnz pgd, #1, walk_puds |
| 268 | __idmap_kpti_put_pgtable_ent_ng pgd | ||
| 269 | next_pgd: | 269 | next_pgd: |
| 270 | __idmap_kpti_put_pgtable_ent_ng pgd | ||
| 271 | skip_pgd: | ||
| 270 | add cur_pgdp, cur_pgdp, #8 | 272 | add cur_pgdp, cur_pgdp, #8 |
| 271 | cmp cur_pgdp, end_pgdp | 273 | cmp cur_pgdp, end_pgdp |
| 272 | b.ne do_pgd | 274 | b.ne do_pgd |
| @@ -294,8 +296,9 @@ walk_puds: | |||
| 294 | add end_pudp, cur_pudp, #(PTRS_PER_PUD * 8) | 296 | add end_pudp, cur_pudp, #(PTRS_PER_PUD * 8) |
| 295 | do_pud: __idmap_kpti_get_pgtable_ent pud | 297 | do_pud: __idmap_kpti_get_pgtable_ent pud |
| 296 | tbnz pud, #1, walk_pmds | 298 | tbnz pud, #1, walk_pmds |
| 297 | __idmap_kpti_put_pgtable_ent_ng pud | ||
| 298 | next_pud: | 299 | next_pud: |
| 300 | __idmap_kpti_put_pgtable_ent_ng pud | ||
| 301 | skip_pud: | ||
| 299 | add cur_pudp, cur_pudp, 8 | 302 | add cur_pudp, cur_pudp, 8 |
| 300 | cmp cur_pudp, end_pudp | 303 | cmp cur_pudp, end_pudp |
| 301 | b.ne do_pud | 304 | b.ne do_pud |
| @@ -314,8 +317,9 @@ walk_pmds: | |||
| 314 | add end_pmdp, cur_pmdp, #(PTRS_PER_PMD * 8) | 317 | add end_pmdp, cur_pmdp, #(PTRS_PER_PMD * 8) |
| 315 | do_pmd: __idmap_kpti_get_pgtable_ent pmd | 318 | do_pmd: __idmap_kpti_get_pgtable_ent pmd |
| 316 | tbnz pmd, #1, walk_ptes | 319 | tbnz pmd, #1, walk_ptes |
| 317 | __idmap_kpti_put_pgtable_ent_ng pmd | ||
| 318 | next_pmd: | 320 | next_pmd: |
| 321 | __idmap_kpti_put_pgtable_ent_ng pmd | ||
| 322 | skip_pmd: | ||
| 319 | add cur_pmdp, cur_pmdp, #8 | 323 | add cur_pmdp, cur_pmdp, #8 |
| 320 | cmp cur_pmdp, end_pmdp | 324 | cmp cur_pmdp, end_pmdp |
| 321 | b.ne do_pmd | 325 | b.ne do_pmd |
| @@ -333,7 +337,7 @@ walk_ptes: | |||
| 333 | add end_ptep, cur_ptep, #(PTRS_PER_PTE * 8) | 337 | add end_ptep, cur_ptep, #(PTRS_PER_PTE * 8) |
| 334 | do_pte: __idmap_kpti_get_pgtable_ent pte | 338 | do_pte: __idmap_kpti_get_pgtable_ent pte |
| 335 | __idmap_kpti_put_pgtable_ent_ng pte | 339 | __idmap_kpti_put_pgtable_ent_ng pte |
| 336 | next_pte: | 340 | skip_pte: |
| 337 | add cur_ptep, cur_ptep, #8 | 341 | add cur_ptep, cur_ptep, #8 |
| 338 | cmp cur_ptep, end_ptep | 342 | cmp cur_ptep, end_ptep |
| 339 | b.ne do_pte | 343 | b.ne do_pte |
diff --git a/arch/cris/include/arch-v10/arch/bug.h b/arch/cris/include/arch-v10/arch/bug.h index 905afeacfedf..06da9d49152a 100644 --- a/arch/cris/include/arch-v10/arch/bug.h +++ b/arch/cris/include/arch-v10/arch/bug.h | |||
| @@ -44,18 +44,25 @@ struct bug_frame { | |||
| 44 | * not be used like this with newer versions of gcc. | 44 | * not be used like this with newer versions of gcc. |
| 45 | */ | 45 | */ |
| 46 | #define BUG() \ | 46 | #define BUG() \ |
| 47 | do { \ | ||
| 47 | __asm__ __volatile__ ("clear.d [" __stringify(BUG_MAGIC) "]\n\t"\ | 48 | __asm__ __volatile__ ("clear.d [" __stringify(BUG_MAGIC) "]\n\t"\ |
| 48 | "movu.w " __stringify(__LINE__) ",$r0\n\t"\ | 49 | "movu.w " __stringify(__LINE__) ",$r0\n\t"\ |
| 49 | "jump 0f\n\t" \ | 50 | "jump 0f\n\t" \ |
| 50 | ".section .rodata\n" \ | 51 | ".section .rodata\n" \ |
| 51 | "0:\t.string \"" __FILE__ "\"\n\t" \ | 52 | "0:\t.string \"" __FILE__ "\"\n\t" \ |
| 52 | ".previous") | 53 | ".previous"); \ |
| 54 | unreachable(); \ | ||
| 55 | } while (0) | ||
| 53 | #endif | 56 | #endif |
| 54 | 57 | ||
| 55 | #else | 58 | #else |
| 56 | 59 | ||
| 57 | /* This just causes an oops. */ | 60 | /* This just causes an oops. */ |
| 58 | #define BUG() (*(int *)0 = 0) | 61 | #define BUG() \ |
| 62 | do { \ | ||
| 63 | barrier_before_unreachable(); \ | ||
| 64 | __builtin_trap(); \ | ||
| 65 | } while (0) | ||
| 59 | 66 | ||
| 60 | #endif | 67 | #endif |
| 61 | 68 | ||
diff --git a/arch/ia64/include/asm/bug.h b/arch/ia64/include/asm/bug.h index bd3eeb8d1cfa..66b37a532765 100644 --- a/arch/ia64/include/asm/bug.h +++ b/arch/ia64/include/asm/bug.h | |||
| @@ -4,7 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #ifdef CONFIG_BUG | 5 | #ifdef CONFIG_BUG |
| 6 | #define ia64_abort() __builtin_trap() | 6 | #define ia64_abort() __builtin_trap() |
| 7 | #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) | 7 | #define BUG() do { \ |
| 8 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | ||
| 9 | barrier_before_unreachable(); \ | ||
| 10 | ia64_abort(); \ | ||
| 11 | } while (0) | ||
| 8 | 12 | ||
| 9 | /* should this BUG be made generic? */ | 13 | /* should this BUG be made generic? */ |
| 10 | #define HAVE_ARCH_BUG | 14 | #define HAVE_ARCH_BUG |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 0b4c65a1af25..498f3da3f225 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
| @@ -41,7 +41,6 @@ ifneq ($(CONFIG_IA64_ESI),) | |||
| 41 | obj-y += esi_stub.o # must be in kernel proper | 41 | obj-y += esi_stub.o # must be in kernel proper |
| 42 | endif | 42 | endif |
| 43 | obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o | 43 | obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o |
| 44 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | ||
| 45 | 44 | ||
| 46 | obj-$(CONFIG_BINFMT_ELF) += elfcore.o | 45 | obj-$(CONFIG_BINFMT_ELF) += elfcore.o |
| 47 | 46 | ||
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h index b7e2bf1ba4a6..275dca1435bf 100644 --- a/arch/m68k/include/asm/bug.h +++ b/arch/m68k/include/asm/bug.h | |||
| @@ -8,16 +8,19 @@ | |||
| 8 | #ifndef CONFIG_SUN3 | 8 | #ifndef CONFIG_SUN3 |
| 9 | #define BUG() do { \ | 9 | #define BUG() do { \ |
| 10 | pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 10 | pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
| 11 | barrier_before_unreachable(); \ | ||
| 11 | __builtin_trap(); \ | 12 | __builtin_trap(); \ |
| 12 | } while (0) | 13 | } while (0) |
| 13 | #else | 14 | #else |
| 14 | #define BUG() do { \ | 15 | #define BUG() do { \ |
| 15 | pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 16 | pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
| 17 | barrier_before_unreachable(); \ | ||
| 16 | panic("BUG!"); \ | 18 | panic("BUG!"); \ |
| 17 | } while (0) | 19 | } while (0) |
| 18 | #endif | 20 | #endif |
| 19 | #else | 21 | #else |
| 20 | #define BUG() do { \ | 22 | #define BUG() do { \ |
| 23 | barrier_before_unreachable(); \ | ||
| 21 | __builtin_trap(); \ | 24 | __builtin_trap(); \ |
| 22 | } while (0) | 25 | } while (0) |
| 23 | #endif | 26 | #endif |
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 1bd5c4f00d19..c22da16d67b8 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile | |||
| @@ -126,6 +126,7 @@ $(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS | |||
| 126 | 126 | ||
| 127 | quiet_cmd_cpp_its_S = ITS $@ | 127 | quiet_cmd_cpp_its_S = ITS $@ |
| 128 | cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ | 128 | cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ |
| 129 | -D__ASSEMBLY__ \ | ||
| 129 | -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ | 130 | -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ |
| 130 | -DVMLINUX_BINARY="\"$(3)\"" \ | 131 | -DVMLINUX_BINARY="\"$(3)\"" \ |
| 131 | -DVMLINUX_COMPRESSION="\"$(2)\"" \ | 132 | -DVMLINUX_COMPRESSION="\"$(2)\"" \ |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 593248110902..9f421641a35c 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
| @@ -81,6 +81,9 @@ static inline int numa_update_cpu_topology(bool cpus_locked) | |||
| 81 | { | 81 | { |
| 82 | return 0; | 82 | return 0; |
| 83 | } | 83 | } |
| 84 | |||
| 85 | static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {} | ||
| 86 | |||
| 84 | #endif /* CONFIG_NUMA */ | 87 | #endif /* CONFIG_NUMA */ |
| 85 | 88 | ||
| 86 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) | 89 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 5a8bfee6e187..04d0bbd7a1dd 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
| @@ -788,7 +788,8 @@ static int register_cpu_online(unsigned int cpu) | |||
| 788 | if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) | 788 | if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) |
| 789 | device_create_file(s, &dev_attr_pir); | 789 | device_create_file(s, &dev_attr_pir); |
| 790 | 790 | ||
| 791 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | 791 | if (cpu_has_feature(CPU_FTR_ARCH_206) && |
| 792 | !firmware_has_feature(FW_FEATURE_LPAR)) | ||
| 792 | device_create_file(s, &dev_attr_tscr); | 793 | device_create_file(s, &dev_attr_tscr); |
| 793 | #endif /* CONFIG_PPC64 */ | 794 | #endif /* CONFIG_PPC64 */ |
| 794 | 795 | ||
| @@ -873,7 +874,8 @@ static int unregister_cpu_online(unsigned int cpu) | |||
| 873 | if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) | 874 | if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2)) |
| 874 | device_remove_file(s, &dev_attr_pir); | 875 | device_remove_file(s, &dev_attr_pir); |
| 875 | 876 | ||
| 876 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | 877 | if (cpu_has_feature(CPU_FTR_ARCH_206) && |
| 878 | !firmware_has_feature(FW_FEATURE_LPAR)) | ||
| 877 | device_remove_file(s, &dev_attr_tscr); | 879 | device_remove_file(s, &dev_attr_tscr); |
| 878 | #endif /* CONFIG_PPC64 */ | 880 | #endif /* CONFIG_PPC64 */ |
| 879 | 881 | ||
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index 1604110c4238..916844f99c64 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c | |||
| @@ -216,6 +216,8 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, | |||
| 216 | u32 i, n_lmbs; | 216 | u32 i, n_lmbs; |
| 217 | 217 | ||
| 218 | n_lmbs = of_read_number(prop++, 1); | 218 | n_lmbs = of_read_number(prop++, 1); |
| 219 | if (n_lmbs == 0) | ||
| 220 | return; | ||
| 219 | 221 | ||
| 220 | for (i = 0; i < n_lmbs; i++) { | 222 | for (i = 0; i < n_lmbs; i++) { |
| 221 | read_drconf_v1_cell(&lmb, &prop); | 223 | read_drconf_v1_cell(&lmb, &prop); |
| @@ -245,6 +247,8 @@ static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, | |||
| 245 | u32 i, j, lmb_sets; | 247 | u32 i, j, lmb_sets; |
| 246 | 248 | ||
| 247 | lmb_sets = of_read_number(prop++, 1); | 249 | lmb_sets = of_read_number(prop++, 1); |
| 250 | if (lmb_sets == 0) | ||
| 251 | return; | ||
| 248 | 252 | ||
| 249 | for (i = 0; i < lmb_sets; i++) { | 253 | for (i = 0; i < lmb_sets; i++) { |
| 250 | read_drconf_v2_cell(&dr_cell, &prop); | 254 | read_drconf_v2_cell(&dr_cell, &prop); |
| @@ -354,6 +358,8 @@ static void __init init_drmem_v1_lmbs(const __be32 *prop) | |||
| 354 | struct drmem_lmb *lmb; | 358 | struct drmem_lmb *lmb; |
| 355 | 359 | ||
| 356 | drmem_info->n_lmbs = of_read_number(prop++, 1); | 360 | drmem_info->n_lmbs = of_read_number(prop++, 1); |
| 361 | if (drmem_info->n_lmbs == 0) | ||
| 362 | return; | ||
| 357 | 363 | ||
| 358 | drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb), | 364 | drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb), |
| 359 | GFP_KERNEL); | 365 | GFP_KERNEL); |
| @@ -373,6 +379,8 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop) | |||
| 373 | int lmb_index; | 379 | int lmb_index; |
| 374 | 380 | ||
| 375 | lmb_sets = of_read_number(prop++, 1); | 381 | lmb_sets = of_read_number(prop++, 1); |
| 382 | if (lmb_sets == 0) | ||
| 383 | return; | ||
| 376 | 384 | ||
| 377 | /* first pass, calculate the number of LMBs */ | 385 | /* first pass, calculate the number of LMBs */ |
| 378 | p = prop; | 386 | p = prop; |
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index dd4c9b8b8a81..f6f55ab4980e 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c | |||
| @@ -199,9 +199,11 @@ static void disable_nest_pmu_counters(void) | |||
| 199 | const struct cpumask *l_cpumask; | 199 | const struct cpumask *l_cpumask; |
| 200 | 200 | ||
| 201 | get_online_cpus(); | 201 | get_online_cpus(); |
| 202 | for_each_online_node(nid) { | 202 | for_each_node_with_cpus(nid) { |
| 203 | l_cpumask = cpumask_of_node(nid); | 203 | l_cpumask = cpumask_of_node(nid); |
| 204 | cpu = cpumask_first(l_cpumask); | 204 | cpu = cpumask_first_and(l_cpumask, cpu_online_mask); |
| 205 | if (cpu >= nr_cpu_ids) | ||
| 206 | continue; | ||
| 205 | opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, | 207 | opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, |
| 206 | get_hard_smp_processor_id(cpu)); | 208 | get_hard_smp_processor_id(cpu)); |
| 207 | } | 209 | } |
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index d9c4c9366049..091f1d0d0af1 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c | |||
| @@ -356,7 +356,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, | |||
| 356 | 356 | ||
| 357 | rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); | 357 | rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); |
| 358 | if (rc) { | 358 | if (rc) { |
| 359 | pr_err("Error %lld getting queue info prio %d\n", rc, prio); | 359 | pr_err("Error %lld getting queue info CPU %d prio %d\n", rc, |
| 360 | target, prio); | ||
| 360 | rc = -EIO; | 361 | rc = -EIO; |
| 361 | goto fail; | 362 | goto fail; |
| 362 | } | 363 | } |
| @@ -370,7 +371,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, | |||
| 370 | /* Configure and enable the queue in HW */ | 371 | /* Configure and enable the queue in HW */ |
| 371 | rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); | 372 | rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); |
| 372 | if (rc) { | 373 | if (rc) { |
| 373 | pr_err("Error %lld setting queue for prio %d\n", rc, prio); | 374 | pr_err("Error %lld setting queue for CPU %d prio %d\n", rc, |
| 375 | target, prio); | ||
| 374 | rc = -EIO; | 376 | rc = -EIO; |
| 375 | } else { | 377 | } else { |
| 376 | q->qpage = qpage; | 378 | q->qpage = qpage; |
| @@ -389,8 +391,8 @@ static int xive_spapr_setup_queue(unsigned int cpu, struct xive_cpu *xc, | |||
| 389 | if (IS_ERR(qpage)) | 391 | if (IS_ERR(qpage)) |
| 390 | return PTR_ERR(qpage); | 392 | return PTR_ERR(qpage); |
| 391 | 393 | ||
| 392 | return xive_spapr_configure_queue(cpu, q, prio, qpage, | 394 | return xive_spapr_configure_queue(get_hard_smp_processor_id(cpu), |
| 393 | xive_queue_shift); | 395 | q, prio, qpage, xive_queue_shift); |
| 394 | } | 396 | } |
| 395 | 397 | ||
| 396 | static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, | 398 | static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, |
| @@ -399,10 +401,12 @@ static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, | |||
| 399 | struct xive_q *q = &xc->queue[prio]; | 401 | struct xive_q *q = &xc->queue[prio]; |
| 400 | unsigned int alloc_order; | 402 | unsigned int alloc_order; |
| 401 | long rc; | 403 | long rc; |
| 404 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
| 402 | 405 | ||
| 403 | rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0); | 406 | rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0); |
| 404 | if (rc) | 407 | if (rc) |
| 405 | pr_err("Error %ld setting queue for prio %d\n", rc, prio); | 408 | pr_err("Error %ld setting queue for CPU %d prio %d\n", rc, |
| 409 | hw_cpu, prio); | ||
| 406 | 410 | ||
| 407 | alloc_order = xive_alloc_order(xive_queue_shift); | 411 | alloc_order = xive_alloc_order(xive_queue_shift); |
| 408 | free_pages((unsigned long)q->qpage, alloc_order); | 412 | free_pages((unsigned long)q->qpage, alloc_order); |
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b6722c246d9c..04807c7f64cc 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig | |||
| @@ -8,7 +8,6 @@ config RISCV | |||
| 8 | select OF | 8 | select OF |
| 9 | select OF_EARLY_FLATTREE | 9 | select OF_EARLY_FLATTREE |
| 10 | select OF_IRQ | 10 | select OF_IRQ |
| 11 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 12 | select ARCH_WANT_FRAME_POINTERS | 11 | select ARCH_WANT_FRAME_POINTERS |
| 13 | select CLONE_BACKWARDS | 12 | select CLONE_BACKWARDS |
| 14 | select COMMON_CLK | 13 | select COMMON_CLK |
| @@ -20,7 +19,6 @@ config RISCV | |||
| 20 | select GENERIC_STRNLEN_USER | 19 | select GENERIC_STRNLEN_USER |
| 21 | select GENERIC_SMP_IDLE_THREAD | 20 | select GENERIC_SMP_IDLE_THREAD |
| 22 | select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A | 21 | select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A |
| 23 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
| 24 | select HAVE_MEMBLOCK | 22 | select HAVE_MEMBLOCK |
| 25 | select HAVE_MEMBLOCK_NODE_MAP | 23 | select HAVE_MEMBLOCK_NODE_MAP |
| 26 | select HAVE_DMA_API_DEBUG | 24 | select HAVE_DMA_API_DEBUG |
| @@ -34,7 +32,6 @@ config RISCV | |||
| 34 | select HAVE_ARCH_TRACEHOOK | 32 | select HAVE_ARCH_TRACEHOOK |
| 35 | select MODULES_USE_ELF_RELA if MODULES | 33 | select MODULES_USE_ELF_RELA if MODULES |
| 36 | select THREAD_INFO_IN_TASK | 34 | select THREAD_INFO_IN_TASK |
| 37 | select RISCV_IRQ_INTC | ||
| 38 | select RISCV_TIMER | 35 | select RISCV_TIMER |
| 39 | 36 | ||
| 40 | config MMU | 37 | config MMU |
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 87fc045be51f..56fa592cfa34 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S | |||
| @@ -172,6 +172,9 @@ ENTRY(handle_exception) | |||
| 172 | move a1, sp /* pt_regs */ | 172 | move a1, sp /* pt_regs */ |
| 173 | tail do_IRQ | 173 | tail do_IRQ |
| 174 | 1: | 174 | 1: |
| 175 | /* Exceptions run with interrupts enabled */ | ||
| 176 | csrs sstatus, SR_SIE | ||
| 177 | |||
| 175 | /* Handle syscalls */ | 178 | /* Handle syscalls */ |
| 176 | li t0, EXC_SYSCALL | 179 | li t0, EXC_SYSCALL |
| 177 | beq s4, t0, handle_syscall | 180 | beq s4, t0, handle_syscall |
| @@ -198,8 +201,6 @@ handle_syscall: | |||
| 198 | */ | 201 | */ |
| 199 | addi s2, s2, 0x4 | 202 | addi s2, s2, 0x4 |
| 200 | REG_S s2, PT_SEPC(sp) | 203 | REG_S s2, PT_SEPC(sp) |
| 201 | /* System calls run with interrupts enabled */ | ||
| 202 | csrs sstatus, SR_SIE | ||
| 203 | /* Trace syscalls, but only if requested by the user. */ | 204 | /* Trace syscalls, but only if requested by the user. */ |
| 204 | REG_L t0, TASK_TI_FLAGS(tp) | 205 | REG_L t0, TASK_TI_FLAGS(tp) |
| 205 | andi t0, t0, _TIF_SYSCALL_TRACE | 206 | andi t0, t0, _TIF_SYSCALL_TRACE |
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 226eeb190f90..6e07ed37bbff 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S | |||
| @@ -64,7 +64,7 @@ ENTRY(_start) | |||
| 64 | /* Start the kernel */ | 64 | /* Start the kernel */ |
| 65 | mv a0, s0 | 65 | mv a0, s0 |
| 66 | mv a1, s1 | 66 | mv a1, s1 |
| 67 | call sbi_save | 67 | call parse_dtb |
| 68 | tail start_kernel | 68 | tail start_kernel |
| 69 | 69 | ||
| 70 | relocate: | 70 | relocate: |
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 09f7064e898c..c11f40c1b2a8 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c | |||
| @@ -144,7 +144,7 @@ asmlinkage void __init setup_vm(void) | |||
| 144 | #endif | 144 | #endif |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void __init sbi_save(unsigned int hartid, void *dtb) | 147 | void __init parse_dtb(unsigned int hartid, void *dtb) |
| 148 | { | 148 | { |
| 149 | early_init_dt_scan(__va(dtb)); | 149 | early_init_dt_scan(__va(dtb)); |
| 150 | } | 150 | } |
diff --git a/arch/sparc/include/asm/bug.h b/arch/sparc/include/asm/bug.h index 6f17528356b2..ea53e418f6c0 100644 --- a/arch/sparc/include/asm/bug.h +++ b/arch/sparc/include/asm/bug.h | |||
| @@ -9,10 +9,14 @@ | |||
| 9 | void do_BUG(const char *file, int line); | 9 | void do_BUG(const char *file, int line); |
| 10 | #define BUG() do { \ | 10 | #define BUG() do { \ |
| 11 | do_BUG(__FILE__, __LINE__); \ | 11 | do_BUG(__FILE__, __LINE__); \ |
| 12 | barrier_before_unreachable(); \ | ||
| 12 | __builtin_trap(); \ | 13 | __builtin_trap(); \ |
| 13 | } while (0) | 14 | } while (0) |
| 14 | #else | 15 | #else |
| 15 | #define BUG() __builtin_trap() | 16 | #define BUG() do { \ |
| 17 | barrier_before_unreachable(); \ | ||
| 18 | __builtin_trap(); \ | ||
| 19 | } while (0) | ||
| 16 | #endif | 20 | #endif |
| 17 | 21 | ||
| 18 | #define HAVE_ARCH_BUG | 22 | #define HAVE_ARCH_BUG |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a528c14d45a5..c1236b187824 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -1404,7 +1404,7 @@ config HIGHMEM4G | |||
| 1404 | 1404 | ||
| 1405 | config HIGHMEM64G | 1405 | config HIGHMEM64G |
| 1406 | bool "64GB" | 1406 | bool "64GB" |
| 1407 | depends on !M486 | 1407 | depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 |
| 1408 | select X86_PAE | 1408 | select X86_PAE |
| 1409 | ---help--- | 1409 | ---help--- |
| 1410 | Select this if you have a 32-bit processor and more than 4 | 1410 | Select this if you have a 32-bit processor and more than 4 |
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 65a9a4716e34..8b8d2297d486 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
| @@ -374,7 +374,7 @@ config X86_TSC | |||
| 374 | 374 | ||
| 375 | config X86_CMPXCHG64 | 375 | config X86_CMPXCHG64 |
| 376 | def_bool y | 376 | def_bool y |
| 377 | depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM | 377 | depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 |
| 378 | 378 | ||
| 379 | # this should be set for all -march=.. options where the compiler | 379 | # this should be set for all -march=.. options where the compiler |
| 380 | # generates cmov. | 380 | # generates cmov. |
| @@ -385,7 +385,7 @@ config X86_CMOV | |||
| 385 | config X86_MINIMUM_CPU_FAMILY | 385 | config X86_MINIMUM_CPU_FAMILY |
| 386 | int | 386 | int |
| 387 | default "64" if X86_64 | 387 | default "64" if X86_64 |
| 388 | default "6" if X86_32 && X86_P6_NOP | 388 | default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8) |
| 389 | default "5" if X86_32 && X86_CMPXCHG64 | 389 | default "5" if X86_32 && X86_CMPXCHG64 |
| 390 | default "4" | 390 | default "4" |
| 391 | 391 | ||
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 461f53d27708..a4189762b266 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
| @@ -129,6 +129,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) | |||
| 129 | void cpu_disable_common(void); | 129 | void cpu_disable_common(void); |
| 130 | void native_smp_prepare_boot_cpu(void); | 130 | void native_smp_prepare_boot_cpu(void); |
| 131 | void native_smp_prepare_cpus(unsigned int max_cpus); | 131 | void native_smp_prepare_cpus(unsigned int max_cpus); |
| 132 | void calculate_max_logical_packages(void); | ||
| 132 | void native_smp_cpus_done(unsigned int max_cpus); | 133 | void native_smp_cpus_done(unsigned int max_cpus); |
| 133 | void common_cpu_up(unsigned int cpunum, struct task_struct *tidle); | 134 | void common_cpu_up(unsigned int cpunum, struct task_struct *tidle); |
| 134 | int native_cpu_up(unsigned int cpunum, struct task_struct *tidle); | 135 | int native_cpu_up(unsigned int cpunum, struct task_struct *tidle); |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 1f790cf9d38f..3b7427aa7d85 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
| @@ -542,6 +542,7 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr, | |||
| 542 | goto overflow; | 542 | goto overflow; |
| 543 | break; | 543 | break; |
| 544 | case R_X86_64_PC32: | 544 | case R_X86_64_PC32: |
| 545 | case R_X86_64_PLT32: | ||
| 545 | value -= (u64)address; | 546 | value -= (u64)address; |
| 546 | *(u32 *)location = value; | 547 | *(u32 *)location = value; |
| 547 | break; | 548 | break; |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index da0c160e5589..f58336af095c 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
| @@ -191,6 +191,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
| 191 | goto overflow; | 191 | goto overflow; |
| 192 | break; | 192 | break; |
| 193 | case R_X86_64_PC32: | 193 | case R_X86_64_PC32: |
| 194 | case R_X86_64_PLT32: | ||
| 194 | if (*(u32 *)loc != 0) | 195 | if (*(u32 *)loc != 0) |
| 195 | goto invalid_relocation; | 196 | goto invalid_relocation; |
| 196 | val -= (u64)loc; | 197 | val -= (u64)loc; |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index cfc61e1d45e2..9eee25d07586 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -1281,11 +1281,10 @@ void __init native_smp_prepare_boot_cpu(void) | |||
| 1281 | cpu_set_state_online(me); | 1281 | cpu_set_state_online(me); |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | void __init native_smp_cpus_done(unsigned int max_cpus) | 1284 | void __init calculate_max_logical_packages(void) |
| 1285 | { | 1285 | { |
| 1286 | int ncpus; | 1286 | int ncpus; |
| 1287 | 1287 | ||
| 1288 | pr_debug("Boot done\n"); | ||
| 1289 | /* | 1288 | /* |
| 1290 | * Today neither Intel nor AMD support heterogenous systems so | 1289 | * Today neither Intel nor AMD support heterogenous systems so |
| 1291 | * extrapolate the boot cpu's data to all packages. | 1290 | * extrapolate the boot cpu's data to all packages. |
| @@ -1293,6 +1292,13 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | |||
| 1293 | ncpus = cpu_data(0).booted_cores * topology_max_smt_threads(); | 1292 | ncpus = cpu_data(0).booted_cores * topology_max_smt_threads(); |
| 1294 | __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); | 1293 | __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); |
| 1295 | pr_info("Max logical packages: %u\n", __max_logical_packages); | 1294 | pr_info("Max logical packages: %u\n", __max_logical_packages); |
| 1295 | } | ||
| 1296 | |||
| 1297 | void __init native_smp_cpus_done(unsigned int max_cpus) | ||
| 1298 | { | ||
| 1299 | pr_debug("Boot done\n"); | ||
| 1300 | |||
| 1301 | calculate_max_logical_packages(); | ||
| 1296 | 1302 | ||
| 1297 | if (x86_has_numa_in_package) | 1303 | if (x86_has_numa_in_package) |
| 1298 | set_sched_topology(x86_numa_in_package_topology); | 1304 | set_sched_topology(x86_numa_in_package_topology); |
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 5d73c443e778..220e97841e49 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c | |||
| @@ -770,9 +770,12 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, | |||
| 770 | break; | 770 | break; |
| 771 | 771 | ||
| 772 | case R_X86_64_PC32: | 772 | case R_X86_64_PC32: |
| 773 | case R_X86_64_PLT32: | ||
| 773 | /* | 774 | /* |
| 774 | * PC relative relocations don't need to be adjusted unless | 775 | * PC relative relocations don't need to be adjusted unless |
| 775 | * referencing a percpu symbol. | 776 | * referencing a percpu symbol. |
| 777 | * | ||
| 778 | * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32. | ||
| 776 | */ | 779 | */ |
| 777 | if (is_percpu_sym(sym, symname)) | 780 | if (is_percpu_sym(sym, symname)) |
| 778 | add_reloc(&relocs32neg, offset); | 781 | add_reloc(&relocs32neg, offset); |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 77c959cf81e7..7a43b2ae19f1 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
| @@ -122,6 +122,8 @@ void __init xen_smp_cpus_done(unsigned int max_cpus) | |||
| 122 | 122 | ||
| 123 | if (xen_hvm_domain()) | 123 | if (xen_hvm_domain()) |
| 124 | native_smp_cpus_done(max_cpus); | 124 | native_smp_cpus_done(max_cpus); |
| 125 | else | ||
| 126 | calculate_max_logical_packages(); | ||
| 125 | 127 | ||
| 126 | if (xen_have_vcpu_info_placement) | 128 | if (xen_have_vcpu_info_placement) |
| 127 | return; | 129 | return; |
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 4117524ca45b..c2033a232a44 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
| @@ -812,7 +812,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, | |||
| 812 | struct gendisk *disk; | 812 | struct gendisk *disk; |
| 813 | struct request_queue *q; | 813 | struct request_queue *q; |
| 814 | struct blkcg_gq *blkg; | 814 | struct blkcg_gq *blkg; |
| 815 | struct module *owner; | ||
| 816 | unsigned int major, minor; | 815 | unsigned int major, minor; |
| 817 | int key_len, part, ret; | 816 | int key_len, part, ret; |
| 818 | char *body; | 817 | char *body; |
| @@ -904,9 +903,7 @@ fail_unlock: | |||
| 904 | spin_unlock_irq(q->queue_lock); | 903 | spin_unlock_irq(q->queue_lock); |
| 905 | rcu_read_unlock(); | 904 | rcu_read_unlock(); |
| 906 | fail: | 905 | fail: |
| 907 | owner = disk->fops->owner; | 906 | put_disk_and_module(disk); |
| 908 | put_disk(disk); | ||
| 909 | module_put(owner); | ||
| 910 | /* | 907 | /* |
| 911 | * If queue was bypassing, we should retry. Do so after a | 908 | * If queue was bypassing, we should retry. Do so after a |
| 912 | * short msleep(). It isn't strictly necessary but queue | 909 | * short msleep(). It isn't strictly necessary but queue |
| @@ -931,13 +928,9 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep); | |||
| 931 | void blkg_conf_finish(struct blkg_conf_ctx *ctx) | 928 | void blkg_conf_finish(struct blkg_conf_ctx *ctx) |
| 932 | __releases(ctx->disk->queue->queue_lock) __releases(rcu) | 929 | __releases(ctx->disk->queue->queue_lock) __releases(rcu) |
| 933 | { | 930 | { |
| 934 | struct module *owner; | ||
| 935 | |||
| 936 | spin_unlock_irq(ctx->disk->queue->queue_lock); | 931 | spin_unlock_irq(ctx->disk->queue->queue_lock); |
| 937 | rcu_read_unlock(); | 932 | rcu_read_unlock(); |
| 938 | owner = ctx->disk->fops->owner; | 933 | put_disk_and_module(ctx->disk); |
| 939 | put_disk(ctx->disk); | ||
| 940 | module_put(owner); | ||
| 941 | } | 934 | } |
| 942 | EXPORT_SYMBOL_GPL(blkg_conf_finish); | 935 | EXPORT_SYMBOL_GPL(blkg_conf_finish); |
| 943 | 936 | ||
diff --git a/block/blk-mq.c b/block/blk-mq.c index df93102e2149..16e83e6df404 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -712,7 +712,6 @@ static void __blk_mq_requeue_request(struct request *rq) | |||
| 712 | 712 | ||
| 713 | trace_block_rq_requeue(q, rq); | 713 | trace_block_rq_requeue(q, rq); |
| 714 | wbt_requeue(q->rq_wb, &rq->issue_stat); | 714 | wbt_requeue(q->rq_wb, &rq->issue_stat); |
| 715 | blk_mq_sched_requeue_request(rq); | ||
| 716 | 715 | ||
| 717 | if (blk_mq_rq_state(rq) != MQ_RQ_IDLE) { | 716 | if (blk_mq_rq_state(rq) != MQ_RQ_IDLE) { |
| 718 | blk_mq_rq_update_state(rq, MQ_RQ_IDLE); | 717 | blk_mq_rq_update_state(rq, MQ_RQ_IDLE); |
| @@ -725,6 +724,9 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list) | |||
| 725 | { | 724 | { |
| 726 | __blk_mq_requeue_request(rq); | 725 | __blk_mq_requeue_request(rq); |
| 727 | 726 | ||
| 727 | /* this request will be re-inserted to io scheduler queue */ | ||
| 728 | blk_mq_sched_requeue_request(rq); | ||
| 729 | |||
| 728 | BUG_ON(blk_queued_rq(rq)); | 730 | BUG_ON(blk_queued_rq(rq)); |
| 729 | blk_mq_add_to_requeue_list(rq, true, kick_requeue_list); | 731 | blk_mq_add_to_requeue_list(rq, true, kick_requeue_list); |
| 730 | } | 732 | } |
| @@ -3164,6 +3166,7 @@ static bool __blk_mq_poll(struct blk_mq_hw_ctx *hctx, struct request *rq) | |||
| 3164 | cpu_relax(); | 3166 | cpu_relax(); |
| 3165 | } | 3167 | } |
| 3166 | 3168 | ||
| 3169 | __set_current_state(TASK_RUNNING); | ||
| 3167 | return false; | 3170 | return false; |
| 3168 | } | 3171 | } |
| 3169 | 3172 | ||
diff --git a/block/genhd.c b/block/genhd.c index 88a53c188cb7..9656f9e9f99e 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -547,7 +547,7 @@ static int exact_lock(dev_t devt, void *data) | |||
| 547 | { | 547 | { |
| 548 | struct gendisk *p = data; | 548 | struct gendisk *p = data; |
| 549 | 549 | ||
| 550 | if (!get_disk(p)) | 550 | if (!get_disk_and_module(p)) |
| 551 | return -1; | 551 | return -1; |
| 552 | return 0; | 552 | return 0; |
| 553 | } | 553 | } |
| @@ -717,6 +717,11 @@ void del_gendisk(struct gendisk *disk) | |||
| 717 | blk_integrity_del(disk); | 717 | blk_integrity_del(disk); |
| 718 | disk_del_events(disk); | 718 | disk_del_events(disk); |
| 719 | 719 | ||
| 720 | /* | ||
| 721 | * Block lookups of the disk until all bdevs are unhashed and the | ||
| 722 | * disk is marked as dead (GENHD_FL_UP cleared). | ||
| 723 | */ | ||
| 724 | down_write(&disk->lookup_sem); | ||
| 720 | /* invalidate stuff */ | 725 | /* invalidate stuff */ |
| 721 | disk_part_iter_init(&piter, disk, | 726 | disk_part_iter_init(&piter, disk, |
| 722 | DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); | 727 | DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); |
| @@ -731,6 +736,7 @@ void del_gendisk(struct gendisk *disk) | |||
| 731 | bdev_unhash_inode(disk_devt(disk)); | 736 | bdev_unhash_inode(disk_devt(disk)); |
| 732 | set_capacity(disk, 0); | 737 | set_capacity(disk, 0); |
| 733 | disk->flags &= ~GENHD_FL_UP; | 738 | disk->flags &= ~GENHD_FL_UP; |
| 739 | up_write(&disk->lookup_sem); | ||
| 734 | 740 | ||
| 735 | if (!(disk->flags & GENHD_FL_HIDDEN)) | 741 | if (!(disk->flags & GENHD_FL_HIDDEN)) |
| 736 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); | 742 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); |
| @@ -809,16 +815,28 @@ struct gendisk *get_gendisk(dev_t devt, int *partno) | |||
| 809 | 815 | ||
| 810 | spin_lock_bh(&ext_devt_lock); | 816 | spin_lock_bh(&ext_devt_lock); |
| 811 | part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); | 817 | part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
| 812 | if (part && get_disk(part_to_disk(part))) { | 818 | if (part && get_disk_and_module(part_to_disk(part))) { |
| 813 | *partno = part->partno; | 819 | *partno = part->partno; |
| 814 | disk = part_to_disk(part); | 820 | disk = part_to_disk(part); |
| 815 | } | 821 | } |
| 816 | spin_unlock_bh(&ext_devt_lock); | 822 | spin_unlock_bh(&ext_devt_lock); |
| 817 | } | 823 | } |
| 818 | 824 | ||
| 819 | if (disk && unlikely(disk->flags & GENHD_FL_HIDDEN)) { | 825 | if (!disk) |
| 820 | put_disk(disk); | 826 | return NULL; |
| 827 | |||
| 828 | /* | ||
| 829 | * Synchronize with del_gendisk() to not return disk that is being | ||
| 830 | * destroyed. | ||
| 831 | */ | ||
| 832 | down_read(&disk->lookup_sem); | ||
| 833 | if (unlikely((disk->flags & GENHD_FL_HIDDEN) || | ||
| 834 | !(disk->flags & GENHD_FL_UP))) { | ||
| 835 | up_read(&disk->lookup_sem); | ||
| 836 | put_disk_and_module(disk); | ||
| 821 | disk = NULL; | 837 | disk = NULL; |
| 838 | } else { | ||
| 839 | up_read(&disk->lookup_sem); | ||
| 822 | } | 840 | } |
| 823 | return disk; | 841 | return disk; |
| 824 | } | 842 | } |
| @@ -1418,6 +1436,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id) | |||
| 1418 | kfree(disk); | 1436 | kfree(disk); |
| 1419 | return NULL; | 1437 | return NULL; |
| 1420 | } | 1438 | } |
| 1439 | init_rwsem(&disk->lookup_sem); | ||
| 1421 | disk->node_id = node_id; | 1440 | disk->node_id = node_id; |
| 1422 | if (disk_expand_part_tbl(disk, 0)) { | 1441 | if (disk_expand_part_tbl(disk, 0)) { |
| 1423 | free_part_stats(&disk->part0); | 1442 | free_part_stats(&disk->part0); |
| @@ -1453,7 +1472,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id) | |||
| 1453 | } | 1472 | } |
| 1454 | EXPORT_SYMBOL(__alloc_disk_node); | 1473 | EXPORT_SYMBOL(__alloc_disk_node); |
| 1455 | 1474 | ||
| 1456 | struct kobject *get_disk(struct gendisk *disk) | 1475 | struct kobject *get_disk_and_module(struct gendisk *disk) |
| 1457 | { | 1476 | { |
| 1458 | struct module *owner; | 1477 | struct module *owner; |
| 1459 | struct kobject *kobj; | 1478 | struct kobject *kobj; |
| @@ -1471,17 +1490,30 @@ struct kobject *get_disk(struct gendisk *disk) | |||
| 1471 | return kobj; | 1490 | return kobj; |
| 1472 | 1491 | ||
| 1473 | } | 1492 | } |
| 1474 | 1493 | EXPORT_SYMBOL(get_disk_and_module); | |
| 1475 | EXPORT_SYMBOL(get_disk); | ||
| 1476 | 1494 | ||
| 1477 | void put_disk(struct gendisk *disk) | 1495 | void put_disk(struct gendisk *disk) |
| 1478 | { | 1496 | { |
| 1479 | if (disk) | 1497 | if (disk) |
| 1480 | kobject_put(&disk_to_dev(disk)->kobj); | 1498 | kobject_put(&disk_to_dev(disk)->kobj); |
| 1481 | } | 1499 | } |
| 1482 | |||
| 1483 | EXPORT_SYMBOL(put_disk); | 1500 | EXPORT_SYMBOL(put_disk); |
| 1484 | 1501 | ||
| 1502 | /* | ||
| 1503 | * This is a counterpart of get_disk_and_module() and thus also of | ||
| 1504 | * get_gendisk(). | ||
| 1505 | */ | ||
| 1506 | void put_disk_and_module(struct gendisk *disk) | ||
| 1507 | { | ||
| 1508 | if (disk) { | ||
| 1509 | struct module *owner = disk->fops->owner; | ||
| 1510 | |||
| 1511 | put_disk(disk); | ||
| 1512 | module_put(owner); | ||
| 1513 | } | ||
| 1514 | } | ||
| 1515 | EXPORT_SYMBOL(put_disk_and_module); | ||
| 1516 | |||
| 1485 | static void set_disk_ro_uevent(struct gendisk *gd, int ro) | 1517 | static void set_disk_ro_uevent(struct gendisk *gd, int ro) |
| 1486 | { | 1518 | { |
| 1487 | char event[] = "DISK_RO=1"; | 1519 | char event[] = "DISK_RO=1"; |
diff --git a/block/ioctl.c b/block/ioctl.c index 1668506d8ed8..3884d810efd2 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
| @@ -225,7 +225,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, | |||
| 225 | 225 | ||
| 226 | if (start + len > i_size_read(bdev->bd_inode)) | 226 | if (start + len > i_size_read(bdev->bd_inode)) |
| 227 | return -EINVAL; | 227 | return -EINVAL; |
| 228 | truncate_inode_pages_range(mapping, start, start + len); | 228 | truncate_inode_pages_range(mapping, start, start + len - 1); |
| 229 | return blkdev_issue_discard(bdev, start >> 9, len >> 9, | 229 | return blkdev_issue_discard(bdev, start >> 9, len >> 9, |
| 230 | GFP_KERNEL, flags); | 230 | GFP_KERNEL, flags); |
| 231 | } | 231 | } |
diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index f95c60774ce8..0d6d25e32e1f 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c | |||
| @@ -833,6 +833,7 @@ static struct elevator_type kyber_sched = { | |||
| 833 | .limit_depth = kyber_limit_depth, | 833 | .limit_depth = kyber_limit_depth, |
| 834 | .prepare_request = kyber_prepare_request, | 834 | .prepare_request = kyber_prepare_request, |
| 835 | .finish_request = kyber_finish_request, | 835 | .finish_request = kyber_finish_request, |
| 836 | .requeue_request = kyber_finish_request, | ||
| 836 | .completed_request = kyber_completed_request, | 837 | .completed_request = kyber_completed_request, |
| 837 | .dispatch_request = kyber_dispatch_request, | 838 | .dispatch_request = kyber_dispatch_request, |
| 838 | .has_work = kyber_has_work, | 839 | .has_work = kyber_has_work, |
diff --git a/certs/blacklist_nohashes.c b/certs/blacklist_nohashes.c index 73fd99098ad7..753b703ef0ef 100644 --- a/certs/blacklist_nohashes.c +++ b/certs/blacklist_nohashes.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include "blacklist.h" | 2 | #include "blacklist.h" |
| 3 | 3 | ||
| 4 | const char __initdata *const blacklist_hashes[] = { | 4 | const char __initconst *const blacklist_hashes[] = { |
| 5 | NULL | 5 | NULL |
| 6 | }; | 6 | }; |
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 15e3d3c2260d..764b63a5aade 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
| @@ -1991,8 +1991,14 @@ static void binder_send_failed_reply(struct binder_transaction *t, | |||
| 1991 | &target_thread->reply_error.work); | 1991 | &target_thread->reply_error.work); |
| 1992 | wake_up_interruptible(&target_thread->wait); | 1992 | wake_up_interruptible(&target_thread->wait); |
| 1993 | } else { | 1993 | } else { |
| 1994 | WARN(1, "Unexpected reply error: %u\n", | 1994 | /* |
| 1995 | target_thread->reply_error.cmd); | 1995 | * Cannot get here for normal operation, but |
| 1996 | * we can if multiple synchronous transactions | ||
| 1997 | * are sent without blocking for responses. | ||
| 1998 | * Just ignore the 2nd error in this case. | ||
| 1999 | */ | ||
| 2000 | pr_warn("Unexpected reply error: %u\n", | ||
| 2001 | target_thread->reply_error.cmd); | ||
| 1996 | } | 2002 | } |
| 1997 | binder_inner_proc_unlock(target_thread->proc); | 2003 | binder_inner_proc_unlock(target_thread->proc); |
| 1998 | binder_thread_dec_tmpref(target_thread); | 2004 | binder_thread_dec_tmpref(target_thread); |
| @@ -2193,7 +2199,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, | |||
| 2193 | int debug_id = buffer->debug_id; | 2199 | int debug_id = buffer->debug_id; |
| 2194 | 2200 | ||
| 2195 | binder_debug(BINDER_DEBUG_TRANSACTION, | 2201 | binder_debug(BINDER_DEBUG_TRANSACTION, |
| 2196 | "%d buffer release %d, size %zd-%zd, failed at %p\n", | 2202 | "%d buffer release %d, size %zd-%zd, failed at %pK\n", |
| 2197 | proc->pid, buffer->debug_id, | 2203 | proc->pid, buffer->debug_id, |
| 2198 | buffer->data_size, buffer->offsets_size, failed_at); | 2204 | buffer->data_size, buffer->offsets_size, failed_at); |
| 2199 | 2205 | ||
| @@ -3705,7 +3711,7 @@ static int binder_thread_write(struct binder_proc *proc, | |||
| 3705 | } | 3711 | } |
| 3706 | } | 3712 | } |
| 3707 | binder_debug(BINDER_DEBUG_DEAD_BINDER, | 3713 | binder_debug(BINDER_DEBUG_DEAD_BINDER, |
| 3708 | "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", | 3714 | "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n", |
| 3709 | proc->pid, thread->pid, (u64)cookie, | 3715 | proc->pid, thread->pid, (u64)cookie, |
| 3710 | death); | 3716 | death); |
| 3711 | if (death == NULL) { | 3717 | if (death == NULL) { |
| @@ -4376,6 +4382,15 @@ static int binder_thread_release(struct binder_proc *proc, | |||
| 4376 | 4382 | ||
| 4377 | binder_inner_proc_unlock(thread->proc); | 4383 | binder_inner_proc_unlock(thread->proc); |
| 4378 | 4384 | ||
| 4385 | /* | ||
| 4386 | * This is needed to avoid races between wake_up_poll() above and | ||
| 4387 | * and ep_remove_waitqueue() called for other reasons (eg the epoll file | ||
| 4388 | * descriptor being closed); ep_remove_waitqueue() holds an RCU read | ||
| 4389 | * lock, so we can be sure it's done after calling synchronize_rcu(). | ||
| 4390 | */ | ||
| 4391 | if (thread->looper & BINDER_LOOPER_STATE_POLL) | ||
| 4392 | synchronize_rcu(); | ||
| 4393 | |||
| 4379 | if (send_reply) | 4394 | if (send_reply) |
| 4380 | binder_send_failed_reply(send_reply, BR_DEAD_REPLY); | 4395 | binder_send_failed_reply(send_reply, BR_DEAD_REPLY); |
| 4381 | binder_release_work(proc, &thread->todo); | 4396 | binder_release_work(proc, &thread->todo); |
| @@ -4391,6 +4406,8 @@ static __poll_t binder_poll(struct file *filp, | |||
| 4391 | bool wait_for_proc_work; | 4406 | bool wait_for_proc_work; |
| 4392 | 4407 | ||
| 4393 | thread = binder_get_thread(proc); | 4408 | thread = binder_get_thread(proc); |
| 4409 | if (!thread) | ||
| 4410 | return POLLERR; | ||
| 4394 | 4411 | ||
| 4395 | binder_inner_proc_lock(thread->proc); | 4412 | binder_inner_proc_lock(thread->proc); |
| 4396 | thread->looper |= BINDER_LOOPER_STATE_POLL; | 4413 | thread->looper |= BINDER_LOOPER_STATE_POLL; |
| @@ -5034,7 +5051,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, | |||
| 5034 | spin_lock(&t->lock); | 5051 | spin_lock(&t->lock); |
| 5035 | to_proc = t->to_proc; | 5052 | to_proc = t->to_proc; |
| 5036 | seq_printf(m, | 5053 | seq_printf(m, |
| 5037 | "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d", | 5054 | "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d", |
| 5038 | prefix, t->debug_id, t, | 5055 | prefix, t->debug_id, t, |
| 5039 | t->from ? t->from->proc->pid : 0, | 5056 | t->from ? t->from->proc->pid : 0, |
| 5040 | t->from ? t->from->pid : 0, | 5057 | t->from ? t->from->pid : 0, |
| @@ -5058,7 +5075,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, | |||
| 5058 | } | 5075 | } |
| 5059 | if (buffer->target_node) | 5076 | if (buffer->target_node) |
| 5060 | seq_printf(m, " node %d", buffer->target_node->debug_id); | 5077 | seq_printf(m, " node %d", buffer->target_node->debug_id); |
| 5061 | seq_printf(m, " size %zd:%zd data %p\n", | 5078 | seq_printf(m, " size %zd:%zd data %pK\n", |
| 5062 | buffer->data_size, buffer->offsets_size, | 5079 | buffer->data_size, buffer->offsets_size, |
| 5063 | buffer->data); | 5080 | buffer->data); |
| 5064 | } | 5081 | } |
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index e5aa62fcf5a8..3aaf6af3ec23 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
| @@ -1758,7 +1758,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
| 1758 | if (unit[drive].type->code == FD_NODRIVE) | 1758 | if (unit[drive].type->code == FD_NODRIVE) |
| 1759 | return NULL; | 1759 | return NULL; |
| 1760 | *part = 0; | 1760 | *part = 0; |
| 1761 | return get_disk(unit[drive].gendisk); | 1761 | return get_disk_and_module(unit[drive].gendisk); |
| 1762 | } | 1762 | } |
| 1763 | 1763 | ||
| 1764 | static int __init amiga_floppy_probe(struct platform_device *pdev) | 1764 | static int __init amiga_floppy_probe(struct platform_device *pdev) |
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 8bc3b9fd8dd2..dfb2c2622e5a 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c | |||
| @@ -1917,7 +1917,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
| 1917 | if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS) | 1917 | if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS) |
| 1918 | return NULL; | 1918 | return NULL; |
| 1919 | *part = 0; | 1919 | *part = 0; |
| 1920 | return get_disk(unit[drive].disk); | 1920 | return get_disk_and_module(unit[drive].disk); |
| 1921 | } | 1921 | } |
| 1922 | 1922 | ||
| 1923 | static int __init atari_floppy_init (void) | 1923 | static int __init atari_floppy_init (void) |
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 8028a3a7e7fd..deea78e485da 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
| @@ -456,7 +456,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data) | |||
| 456 | 456 | ||
| 457 | mutex_lock(&brd_devices_mutex); | 457 | mutex_lock(&brd_devices_mutex); |
| 458 | brd = brd_init_one(MINOR(dev) / max_part, &new); | 458 | brd = brd_init_one(MINOR(dev) / max_part, &new); |
| 459 | kobj = brd ? get_disk(brd->brd_disk) : NULL; | 459 | kobj = brd ? get_disk_and_module(brd->brd_disk) : NULL; |
| 460 | mutex_unlock(&brd_devices_mutex); | 460 | mutex_unlock(&brd_devices_mutex); |
| 461 | 461 | ||
| 462 | if (new) | 462 | if (new) |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index eae484acfbbc..8ec7235fc93b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
| @@ -4505,7 +4505,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
| 4505 | if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) | 4505 | if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) |
| 4506 | return NULL; | 4506 | return NULL; |
| 4507 | *part = 0; | 4507 | *part = 0; |
| 4508 | return get_disk(disks[drive]); | 4508 | return get_disk_and_module(disks[drive]); |
| 4509 | } | 4509 | } |
| 4510 | 4510 | ||
| 4511 | static int __init do_floppy_init(void) | 4511 | static int __init do_floppy_init(void) |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d5fe720cf149..87855b5123a6 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -1922,7 +1922,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) | |||
| 1922 | if (err < 0) | 1922 | if (err < 0) |
| 1923 | kobj = NULL; | 1923 | kobj = NULL; |
| 1924 | else | 1924 | else |
| 1925 | kobj = get_disk(lo->lo_disk); | 1925 | kobj = get_disk_and_module(lo->lo_disk); |
| 1926 | mutex_unlock(&loop_index_mutex); | 1926 | mutex_unlock(&loop_index_mutex); |
| 1927 | 1927 | ||
| 1928 | *part = 0; | 1928 | *part = 0; |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 5f2a4240a204..86258b00a1d4 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
| @@ -1591,7 +1591,7 @@ again: | |||
| 1591 | if (new_index < 0) { | 1591 | if (new_index < 0) { |
| 1592 | mutex_unlock(&nbd_index_mutex); | 1592 | mutex_unlock(&nbd_index_mutex); |
| 1593 | printk(KERN_ERR "nbd: failed to add new device\n"); | 1593 | printk(KERN_ERR "nbd: failed to add new device\n"); |
| 1594 | return ret; | 1594 | return new_index; |
| 1595 | } | 1595 | } |
| 1596 | nbd = idr_find(&nbd_index_idr, new_index); | 1596 | nbd = idr_find(&nbd_index_idr, new_index); |
| 1597 | } | 1597 | } |
diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 84434d3ea19b..64e066eba72e 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c | |||
| @@ -799,7 +799,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
| 799 | return NULL; | 799 | return NULL; |
| 800 | 800 | ||
| 801 | *part = 0; | 801 | *part = 0; |
| 802 | return get_disk(swd->unit[drive].disk); | 802 | return get_disk_and_module(swd->unit[drive].disk); |
| 803 | } | 803 | } |
| 804 | 804 | ||
| 805 | static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) | 805 | static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) |
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 41c95c9b2ab4..8f9130ab5887 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c | |||
| @@ -332,7 +332,7 @@ static const struct block_device_operations z2_fops = | |||
| 332 | static struct kobject *z2_find(dev_t dev, int *part, void *data) | 332 | static struct kobject *z2_find(dev_t dev, int *part, void *data) |
| 333 | { | 333 | { |
| 334 | *part = 0; | 334 | *part = 0; |
| 335 | return get_disk(z2ram_gendisk); | 335 | return get_disk_and_module(z2ram_gendisk); |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | static struct request_queue *z2_queue; | 338 | static struct request_queue *z2_queue; |
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index 188f44b7eb27..5d64c08b7f47 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c | |||
| @@ -1922,15 +1922,21 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) | |||
| 1922 | uint32_t aes_control; | 1922 | uint32_t aes_control; |
| 1923 | unsigned long flags; | 1923 | unsigned long flags; |
| 1924 | int err; | 1924 | int err; |
| 1925 | u8 *iv; | ||
| 1925 | 1926 | ||
| 1926 | aes_control = SSS_AES_KEY_CHANGE_MODE; | 1927 | aes_control = SSS_AES_KEY_CHANGE_MODE; |
| 1927 | if (mode & FLAGS_AES_DECRYPT) | 1928 | if (mode & FLAGS_AES_DECRYPT) |
| 1928 | aes_control |= SSS_AES_MODE_DECRYPT; | 1929 | aes_control |= SSS_AES_MODE_DECRYPT; |
| 1929 | 1930 | ||
| 1930 | if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) | 1931 | if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) { |
| 1931 | aes_control |= SSS_AES_CHAIN_MODE_CBC; | 1932 | aes_control |= SSS_AES_CHAIN_MODE_CBC; |
| 1932 | else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) | 1933 | iv = req->info; |
| 1934 | } else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) { | ||
| 1933 | aes_control |= SSS_AES_CHAIN_MODE_CTR; | 1935 | aes_control |= SSS_AES_CHAIN_MODE_CTR; |
| 1936 | iv = req->info; | ||
| 1937 | } else { | ||
| 1938 | iv = NULL; /* AES_ECB */ | ||
| 1939 | } | ||
| 1934 | 1940 | ||
| 1935 | if (dev->ctx->keylen == AES_KEYSIZE_192) | 1941 | if (dev->ctx->keylen == AES_KEYSIZE_192) |
| 1936 | aes_control |= SSS_AES_KEY_SIZE_192; | 1942 | aes_control |= SSS_AES_KEY_SIZE_192; |
| @@ -1961,7 +1967,7 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) | |||
| 1961 | goto outdata_error; | 1967 | goto outdata_error; |
| 1962 | 1968 | ||
| 1963 | SSS_AES_WRITE(dev, AES_CONTROL, aes_control); | 1969 | SSS_AES_WRITE(dev, AES_CONTROL, aes_control); |
| 1964 | s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen); | 1970 | s5p_set_aes(dev, dev->ctx->aes_key, iv, dev->ctx->keylen); |
| 1965 | 1971 | ||
| 1966 | s5p_set_dma_indata(dev, dev->sg_src); | 1972 | s5p_set_dma_indata(dev, dev->sg_src); |
| 1967 | s5p_set_dma_outdata(dev, dev->sg_dst); | 1973 | s5p_set_dma_outdata(dev, dev->sg_dst); |
diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c index 0a44d43802fe..3ec4c715e240 100644 --- a/drivers/extcon/extcon-axp288.c +++ b/drivers/extcon/extcon-axp288.c | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver | 2 | * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2016-2017 Hans de Goede <hdegoede@redhat.com> | ||
| 5 | * Copyright (C) 2015 Intel Corporation | 4 | * Copyright (C) 2015 Intel Corporation |
| 6 | * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com> | 5 | * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com> |
| 7 | * | 6 | * |
| @@ -98,15 +97,13 @@ struct axp288_extcon_info { | |||
| 98 | struct device *dev; | 97 | struct device *dev; |
| 99 | struct regmap *regmap; | 98 | struct regmap *regmap; |
| 100 | struct regmap_irq_chip_data *regmap_irqc; | 99 | struct regmap_irq_chip_data *regmap_irqc; |
| 101 | struct delayed_work det_work; | ||
| 102 | int irq[EXTCON_IRQ_END]; | 100 | int irq[EXTCON_IRQ_END]; |
| 103 | struct extcon_dev *edev; | 101 | struct extcon_dev *edev; |
| 104 | unsigned int previous_cable; | 102 | unsigned int previous_cable; |
| 105 | bool first_detect_done; | ||
| 106 | }; | 103 | }; |
| 107 | 104 | ||
| 108 | /* Power up/down reason string array */ | 105 | /* Power up/down reason string array */ |
| 109 | static char *axp288_pwr_up_down_info[] = { | 106 | static const char * const axp288_pwr_up_down_info[] = { |
| 110 | "Last wake caused by user pressing the power button", | 107 | "Last wake caused by user pressing the power button", |
| 111 | "Last wake caused by a charger insertion", | 108 | "Last wake caused by a charger insertion", |
| 112 | "Last wake caused by a battery insertion", | 109 | "Last wake caused by a battery insertion", |
| @@ -124,7 +121,7 @@ static char *axp288_pwr_up_down_info[] = { | |||
| 124 | */ | 121 | */ |
| 125 | static void axp288_extcon_log_rsi(struct axp288_extcon_info *info) | 122 | static void axp288_extcon_log_rsi(struct axp288_extcon_info *info) |
| 126 | { | 123 | { |
| 127 | char **rsi; | 124 | const char * const *rsi; |
| 128 | unsigned int val, i, clear_mask = 0; | 125 | unsigned int val, i, clear_mask = 0; |
| 129 | int ret; | 126 | int ret; |
| 130 | 127 | ||
| @@ -140,25 +137,6 @@ static void axp288_extcon_log_rsi(struct axp288_extcon_info *info) | |||
| 140 | regmap_write(info->regmap, AXP288_PS_BOOT_REASON_REG, clear_mask); | 137 | regmap_write(info->regmap, AXP288_PS_BOOT_REASON_REG, clear_mask); |
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | static void axp288_chrg_detect_complete(struct axp288_extcon_info *info) | ||
| 144 | { | ||
| 145 | /* | ||
| 146 | * We depend on other drivers to do things like mux the data lines, | ||
| 147 | * enable/disable vbus based on the id-pin, etc. Sometimes the BIOS has | ||
| 148 | * not set these things up correctly resulting in the initial charger | ||
| 149 | * cable type detection giving a wrong result and we end up not charging | ||
| 150 | * or charging at only 0.5A. | ||
| 151 | * | ||
| 152 | * So we schedule a second cable type detection after 2 seconds to | ||
| 153 | * give the other drivers time to load and do their thing. | ||
| 154 | */ | ||
| 155 | if (!info->first_detect_done) { | ||
| 156 | queue_delayed_work(system_wq, &info->det_work, | ||
| 157 | msecs_to_jiffies(2000)); | ||
| 158 | info->first_detect_done = true; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) | 140 | static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) |
| 163 | { | 141 | { |
| 164 | int ret, stat, cfg, pwr_stat; | 142 | int ret, stat, cfg, pwr_stat; |
| @@ -223,8 +201,6 @@ no_vbus: | |||
| 223 | info->previous_cable = cable; | 201 | info->previous_cable = cable; |
| 224 | } | 202 | } |
| 225 | 203 | ||
| 226 | axp288_chrg_detect_complete(info); | ||
| 227 | |||
| 228 | return 0; | 204 | return 0; |
| 229 | 205 | ||
| 230 | dev_det_ret: | 206 | dev_det_ret: |
| @@ -246,11 +222,8 @@ static irqreturn_t axp288_extcon_isr(int irq, void *data) | |||
| 246 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
| 247 | } | 223 | } |
| 248 | 224 | ||
| 249 | static void axp288_extcon_det_work(struct work_struct *work) | 225 | static void axp288_extcon_enable(struct axp288_extcon_info *info) |
| 250 | { | 226 | { |
| 251 | struct axp288_extcon_info *info = | ||
| 252 | container_of(work, struct axp288_extcon_info, det_work.work); | ||
| 253 | |||
| 254 | regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, | 227 | regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, |
| 255 | BC_GLOBAL_RUN, 0); | 228 | BC_GLOBAL_RUN, 0); |
| 256 | /* Enable the charger detection logic */ | 229 | /* Enable the charger detection logic */ |
| @@ -272,7 +245,6 @@ static int axp288_extcon_probe(struct platform_device *pdev) | |||
| 272 | info->regmap = axp20x->regmap; | 245 | info->regmap = axp20x->regmap; |
| 273 | info->regmap_irqc = axp20x->regmap_irqc; | 246 | info->regmap_irqc = axp20x->regmap_irqc; |
| 274 | info->previous_cable = EXTCON_NONE; | 247 | info->previous_cable = EXTCON_NONE; |
| 275 | INIT_DELAYED_WORK(&info->det_work, axp288_extcon_det_work); | ||
| 276 | 248 | ||
| 277 | platform_set_drvdata(pdev, info); | 249 | platform_set_drvdata(pdev, info); |
| 278 | 250 | ||
| @@ -318,7 +290,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) | |||
| 318 | } | 290 | } |
| 319 | 291 | ||
| 320 | /* Start charger cable type detection */ | 292 | /* Start charger cable type detection */ |
| 321 | queue_delayed_work(system_wq, &info->det_work, 0); | 293 | axp288_extcon_enable(info); |
| 322 | 294 | ||
| 323 | return 0; | 295 | return 0; |
| 324 | } | 296 | } |
diff --git a/drivers/extcon/extcon-intel-int3496.c b/drivers/extcon/extcon-intel-int3496.c index c8691b5a9cb0..191e99f06a9a 100644 --- a/drivers/extcon/extcon-intel-int3496.c +++ b/drivers/extcon/extcon-intel-int3496.c | |||
| @@ -153,8 +153,9 @@ static int int3496_probe(struct platform_device *pdev) | |||
| 153 | return ret; | 153 | return ret; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /* queue initial processing of id-pin */ | 156 | /* process id-pin so that we start with the right status */ |
| 157 | queue_delayed_work(system_wq, &data->work, 0); | 157 | queue_delayed_work(system_wq, &data->work, 0); |
| 158 | flush_delayed_work(&data->work); | ||
| 158 | 159 | ||
| 159 | platform_set_drvdata(pdev, data); | 160 | platform_set_drvdata(pdev, data); |
| 160 | 161 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 43ddcdfbd0da..9454ac134ce2 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -645,6 +645,9 @@ | |||
| 645 | #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 | 645 | #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 |
| 646 | #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 | 646 | #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 |
| 647 | #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 | 647 | #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 |
| 648 | #define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040 | ||
| 649 | #define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042 | ||
| 650 | #define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043 | ||
| 648 | #define USB_DEVICE_ID_LD_JWM 0x1080 | 651 | #define USB_DEVICE_ID_LD_JWM 0x1080 |
| 649 | #define USB_DEVICE_ID_LD_DMMP 0x1081 | 652 | #define USB_DEVICE_ID_LD_DMMP 0x1081 |
| 650 | #define USB_DEVICE_ID_LD_UMIP 0x1090 | 653 | #define USB_DEVICE_ID_LD_UMIP 0x1090 |
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 5f6035a5ce36..e92b77fa574a 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c | |||
| @@ -809,6 +809,9 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 809 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, | 809 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, |
| 810 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, | 810 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, |
| 811 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, | 811 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, |
| 812 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) }, | ||
| 813 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) }, | ||
| 814 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) }, | ||
| 812 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, | 815 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, |
| 813 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, | 816 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, |
| 814 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, | 817 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 17fd55af4d92..caa20eb5f26b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -928,7 +928,7 @@ static int exact_lock(dev_t dev, void *data) | |||
| 928 | { | 928 | { |
| 929 | struct gendisk *p = data; | 929 | struct gendisk *p = data; |
| 930 | 930 | ||
| 931 | if (!get_disk(p)) | 931 | if (!get_disk_and_module(p)) |
| 932 | return -1; | 932 | return -1; |
| 933 | return 0; | 933 | return 0; |
| 934 | } | 934 | } |
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 327a49ba1991..9515ca165dfd 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c | |||
| @@ -243,7 +243,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) | |||
| 243 | ASPEED_ADC_INIT_POLLING_TIME, | 243 | ASPEED_ADC_INIT_POLLING_TIME, |
| 244 | ASPEED_ADC_INIT_TIMEOUT); | 244 | ASPEED_ADC_INIT_TIMEOUT); |
| 245 | if (ret) | 245 | if (ret) |
| 246 | goto scaler_error; | 246 | goto poll_timeout_error; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | /* Start all channels in normal mode. */ | 249 | /* Start all channels in normal mode. */ |
| @@ -274,9 +274,10 @@ iio_register_error: | |||
| 274 | writel(ASPEED_OPERATION_MODE_POWER_DOWN, | 274 | writel(ASPEED_OPERATION_MODE_POWER_DOWN, |
| 275 | data->base + ASPEED_REG_ENGINE_CONTROL); | 275 | data->base + ASPEED_REG_ENGINE_CONTROL); |
| 276 | clk_disable_unprepare(data->clk_scaler->clk); | 276 | clk_disable_unprepare(data->clk_scaler->clk); |
| 277 | reset_error: | ||
| 278 | reset_control_assert(data->rst); | ||
| 279 | clk_enable_error: | 277 | clk_enable_error: |
| 278 | poll_timeout_error: | ||
| 279 | reset_control_assert(data->rst); | ||
| 280 | reset_error: | ||
| 280 | clk_hw_unregister_divider(data->clk_scaler); | 281 | clk_hw_unregister_divider(data->clk_scaler); |
| 281 | scaler_error: | 282 | scaler_error: |
| 282 | clk_hw_unregister_divider(data->clk_prescaler); | 283 | clk_hw_unregister_divider(data->clk_prescaler); |
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 7f5def465340..9a2583caedaa 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c | |||
| @@ -722,8 +722,6 @@ static int stm32h7_adc_enable(struct stm32_adc *adc) | |||
| 722 | int ret; | 722 | int ret; |
| 723 | u32 val; | 723 | u32 val; |
| 724 | 724 | ||
| 725 | /* Clear ADRDY by writing one, then enable ADC */ | ||
| 726 | stm32_adc_set_bits(adc, STM32H7_ADC_ISR, STM32H7_ADRDY); | ||
| 727 | stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN); | 725 | stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN); |
| 728 | 726 | ||
| 729 | /* Poll for ADRDY to be set (after adc startup time) */ | 727 | /* Poll for ADRDY to be set (after adc startup time) */ |
| @@ -731,8 +729,11 @@ static int stm32h7_adc_enable(struct stm32_adc *adc) | |||
| 731 | val & STM32H7_ADRDY, | 729 | val & STM32H7_ADRDY, |
| 732 | 100, STM32_ADC_TIMEOUT_US); | 730 | 100, STM32_ADC_TIMEOUT_US); |
| 733 | if (ret) { | 731 | if (ret) { |
| 734 | stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN); | 732 | stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADDIS); |
| 735 | dev_err(&indio_dev->dev, "Failed to enable ADC\n"); | 733 | dev_err(&indio_dev->dev, "Failed to enable ADC\n"); |
| 734 | } else { | ||
| 735 | /* Clear ADRDY by writing one */ | ||
| 736 | stm32_adc_set_bits(adc, STM32H7_ADC_ISR, STM32H7_ADRDY); | ||
| 736 | } | 737 | } |
| 737 | 738 | ||
| 738 | return ret; | 739 | return ret; |
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index 0dd5a381be64..457372f36791 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c | |||
| @@ -46,6 +46,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) | |||
| 46 | if (adis->trig == NULL) | 46 | if (adis->trig == NULL) |
| 47 | return -ENOMEM; | 47 | return -ENOMEM; |
| 48 | 48 | ||
| 49 | adis->trig->dev.parent = &adis->spi->dev; | ||
| 50 | adis->trig->ops = &adis_trigger_ops; | ||
| 51 | iio_trigger_set_drvdata(adis->trig, adis); | ||
| 52 | |||
| 49 | ret = request_irq(adis->spi->irq, | 53 | ret = request_irq(adis->spi->irq, |
| 50 | &iio_trigger_generic_data_rdy_poll, | 54 | &iio_trigger_generic_data_rdy_poll, |
| 51 | IRQF_TRIGGER_RISING, | 55 | IRQF_TRIGGER_RISING, |
| @@ -54,9 +58,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) | |||
| 54 | if (ret) | 58 | if (ret) |
| 55 | goto error_free_trig; | 59 | goto error_free_trig; |
| 56 | 60 | ||
| 57 | adis->trig->dev.parent = &adis->spi->dev; | ||
| 58 | adis->trig->ops = &adis_trigger_ops; | ||
| 59 | iio_trigger_set_drvdata(adis->trig, adis); | ||
| 60 | ret = iio_trigger_register(adis->trig); | 61 | ret = iio_trigger_register(adis->trig); |
| 61 | 62 | ||
| 62 | indio_dev->trig = iio_trigger_get(adis->trig); | 63 | indio_dev->trig = iio_trigger_get(adis->trig); |
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 79abf70a126d..cd5bfe39591b 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c | |||
| @@ -175,7 +175,7 @@ __poll_t iio_buffer_poll(struct file *filp, | |||
| 175 | struct iio_dev *indio_dev = filp->private_data; | 175 | struct iio_dev *indio_dev = filp->private_data; |
| 176 | struct iio_buffer *rb = indio_dev->buffer; | 176 | struct iio_buffer *rb = indio_dev->buffer; |
| 177 | 177 | ||
| 178 | if (!indio_dev->info) | 178 | if (!indio_dev->info || rb == NULL) |
| 179 | return 0; | 179 | return 0; |
| 180 | 180 | ||
| 181 | poll_wait(filp, &rb->pollq, wait); | 181 | poll_wait(filp, &rb->pollq, wait); |
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index fcb1c4ba5e41..f726f9427602 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig | |||
| @@ -68,6 +68,8 @@ config SX9500 | |||
| 68 | 68 | ||
| 69 | config SRF08 | 69 | config SRF08 |
| 70 | tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor" | 70 | tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor" |
| 71 | select IIO_BUFFER | ||
| 72 | select IIO_TRIGGERED_BUFFER | ||
| 71 | depends on I2C | 73 | depends on I2C |
| 72 | help | 74 | help |
| 73 | Say Y here to build a driver for Devantech SRF02/SRF08/SRF10 | 75 | Say Y here to build a driver for Devantech SRF02/SRF08/SRF10 |
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index c4560d84dfae..25bb178f6074 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h | |||
| @@ -305,16 +305,21 @@ void nldev_exit(void); | |||
| 305 | static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, | 305 | static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, |
| 306 | struct ib_pd *pd, | 306 | struct ib_pd *pd, |
| 307 | struct ib_qp_init_attr *attr, | 307 | struct ib_qp_init_attr *attr, |
| 308 | struct ib_udata *udata) | 308 | struct ib_udata *udata, |
| 309 | struct ib_uobject *uobj) | ||
| 309 | { | 310 | { |
| 310 | struct ib_qp *qp; | 311 | struct ib_qp *qp; |
| 311 | 312 | ||
| 313 | if (!dev->create_qp) | ||
| 314 | return ERR_PTR(-EOPNOTSUPP); | ||
| 315 | |||
| 312 | qp = dev->create_qp(pd, attr, udata); | 316 | qp = dev->create_qp(pd, attr, udata); |
| 313 | if (IS_ERR(qp)) | 317 | if (IS_ERR(qp)) |
| 314 | return qp; | 318 | return qp; |
| 315 | 319 | ||
| 316 | qp->device = dev; | 320 | qp->device = dev; |
| 317 | qp->pd = pd; | 321 | qp->pd = pd; |
| 322 | qp->uobject = uobj; | ||
| 318 | /* | 323 | /* |
| 319 | * We don't track XRC QPs for now, because they don't have PD | 324 | * We don't track XRC QPs for now, because they don't have PD |
| 320 | * and more importantly they are created internaly by driver, | 325 | * and more importantly they are created internaly by driver, |
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c index 85b5ee4defa4..d8eead5d106d 100644 --- a/drivers/infiniband/core/rdma_core.c +++ b/drivers/infiniband/core/rdma_core.c | |||
| @@ -141,7 +141,12 @@ static struct ib_uobject *alloc_uobj(struct ib_ucontext *context, | |||
| 141 | */ | 141 | */ |
| 142 | uobj->context = context; | 142 | uobj->context = context; |
| 143 | uobj->type = type; | 143 | uobj->type = type; |
| 144 | atomic_set(&uobj->usecnt, 0); | 144 | /* |
| 145 | * Allocated objects start out as write locked to deny any other | ||
| 146 | * syscalls from accessing them until they are committed. See | ||
| 147 | * rdma_alloc_commit_uobject | ||
| 148 | */ | ||
| 149 | atomic_set(&uobj->usecnt, -1); | ||
| 145 | kref_init(&uobj->ref); | 150 | kref_init(&uobj->ref); |
| 146 | 151 | ||
| 147 | return uobj; | 152 | return uobj; |
| @@ -196,7 +201,15 @@ static struct ib_uobject *lookup_get_idr_uobject(const struct uverbs_obj_type *t | |||
| 196 | goto free; | 201 | goto free; |
| 197 | } | 202 | } |
| 198 | 203 | ||
| 199 | uverbs_uobject_get(uobj); | 204 | /* |
| 205 | * The idr_find is guaranteed to return a pointer to something that | ||
| 206 | * isn't freed yet, or NULL, as the free after idr_remove goes through | ||
| 207 | * kfree_rcu(). However the object may still have been released and | ||
| 208 | * kfree() could be called at any time. | ||
| 209 | */ | ||
| 210 | if (!kref_get_unless_zero(&uobj->ref)) | ||
| 211 | uobj = ERR_PTR(-ENOENT); | ||
| 212 | |||
| 200 | free: | 213 | free: |
| 201 | rcu_read_unlock(); | 214 | rcu_read_unlock(); |
| 202 | return uobj; | 215 | return uobj; |
| @@ -399,13 +412,13 @@ static int __must_check remove_commit_fd_uobject(struct ib_uobject *uobj, | |||
| 399 | return ret; | 412 | return ret; |
| 400 | } | 413 | } |
| 401 | 414 | ||
| 402 | static void lockdep_check(struct ib_uobject *uobj, bool exclusive) | 415 | static void assert_uverbs_usecnt(struct ib_uobject *uobj, bool exclusive) |
| 403 | { | 416 | { |
| 404 | #ifdef CONFIG_LOCKDEP | 417 | #ifdef CONFIG_LOCKDEP |
| 405 | if (exclusive) | 418 | if (exclusive) |
| 406 | WARN_ON(atomic_read(&uobj->usecnt) > 0); | 419 | WARN_ON(atomic_read(&uobj->usecnt) != -1); |
| 407 | else | 420 | else |
| 408 | WARN_ON(atomic_read(&uobj->usecnt) == -1); | 421 | WARN_ON(atomic_read(&uobj->usecnt) <= 0); |
| 409 | #endif | 422 | #endif |
| 410 | } | 423 | } |
| 411 | 424 | ||
| @@ -444,7 +457,7 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj) | |||
| 444 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); | 457 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); |
| 445 | return 0; | 458 | return 0; |
| 446 | } | 459 | } |
| 447 | lockdep_check(uobj, true); | 460 | assert_uverbs_usecnt(uobj, true); |
| 448 | ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY); | 461 | ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY); |
| 449 | 462 | ||
| 450 | up_read(&ucontext->cleanup_rwsem); | 463 | up_read(&ucontext->cleanup_rwsem); |
| @@ -474,16 +487,17 @@ int rdma_explicit_destroy(struct ib_uobject *uobject) | |||
| 474 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); | 487 | WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); |
| 475 | return 0; | 488 | return 0; |
| 476 | } | 489 | } |
| 477 | lockdep_check(uobject, true); | 490 | assert_uverbs_usecnt(uobject, true); |
| 478 | ret = uobject->type->type_class->remove_commit(uobject, | 491 | ret = uobject->type->type_class->remove_commit(uobject, |
| 479 | RDMA_REMOVE_DESTROY); | 492 | RDMA_REMOVE_DESTROY); |
| 480 | if (ret) | 493 | if (ret) |
| 481 | return ret; | 494 | goto out; |
| 482 | 495 | ||
| 483 | uobject->type = &null_obj_type; | 496 | uobject->type = &null_obj_type; |
| 484 | 497 | ||
| 498 | out: | ||
| 485 | up_read(&ucontext->cleanup_rwsem); | 499 | up_read(&ucontext->cleanup_rwsem); |
| 486 | return 0; | 500 | return ret; |
| 487 | } | 501 | } |
| 488 | 502 | ||
| 489 | static void alloc_commit_idr_uobject(struct ib_uobject *uobj) | 503 | static void alloc_commit_idr_uobject(struct ib_uobject *uobj) |
| @@ -527,6 +541,10 @@ int rdma_alloc_commit_uobject(struct ib_uobject *uobj) | |||
| 527 | return ret; | 541 | return ret; |
| 528 | } | 542 | } |
| 529 | 543 | ||
| 544 | /* matches atomic_set(-1) in alloc_uobj */ | ||
| 545 | assert_uverbs_usecnt(uobj, true); | ||
| 546 | atomic_set(&uobj->usecnt, 0); | ||
| 547 | |||
| 530 | uobj->type->type_class->alloc_commit(uobj); | 548 | uobj->type->type_class->alloc_commit(uobj); |
| 531 | up_read(&uobj->context->cleanup_rwsem); | 549 | up_read(&uobj->context->cleanup_rwsem); |
| 532 | 550 | ||
| @@ -561,7 +579,7 @@ static void lookup_put_fd_uobject(struct ib_uobject *uobj, bool exclusive) | |||
| 561 | 579 | ||
| 562 | void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive) | 580 | void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive) |
| 563 | { | 581 | { |
| 564 | lockdep_check(uobj, exclusive); | 582 | assert_uverbs_usecnt(uobj, exclusive); |
| 565 | uobj->type->type_class->lookup_put(uobj, exclusive); | 583 | uobj->type->type_class->lookup_put(uobj, exclusive); |
| 566 | /* | 584 | /* |
| 567 | * In order to unlock an object, either decrease its usecnt for | 585 | * In order to unlock an object, either decrease its usecnt for |
diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c index 857637bf46da..3dbc4e4cca41 100644 --- a/drivers/infiniband/core/restrack.c +++ b/drivers/infiniband/core/restrack.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include <rdma/restrack.h> | 7 | #include <rdma/restrack.h> |
| 8 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
| 9 | #include <linux/sched/task.h> | 9 | #include <linux/sched/task.h> |
| 10 | #include <linux/uaccess.h> | ||
| 11 | #include <linux/pid_namespace.h> | 10 | #include <linux/pid_namespace.h> |
| 12 | 11 | ||
| 13 | void rdma_restrack_init(struct rdma_restrack_root *res) | 12 | void rdma_restrack_init(struct rdma_restrack_root *res) |
| @@ -63,7 +62,6 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res) | |||
| 63 | { | 62 | { |
| 64 | enum rdma_restrack_type type = res->type; | 63 | enum rdma_restrack_type type = res->type; |
| 65 | struct ib_device *dev; | 64 | struct ib_device *dev; |
| 66 | struct ib_xrcd *xrcd; | ||
| 67 | struct ib_pd *pd; | 65 | struct ib_pd *pd; |
| 68 | struct ib_cq *cq; | 66 | struct ib_cq *cq; |
| 69 | struct ib_qp *qp; | 67 | struct ib_qp *qp; |
| @@ -81,10 +79,6 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res) | |||
| 81 | qp = container_of(res, struct ib_qp, res); | 79 | qp = container_of(res, struct ib_qp, res); |
| 82 | dev = qp->device; | 80 | dev = qp->device; |
| 83 | break; | 81 | break; |
| 84 | case RDMA_RESTRACK_XRCD: | ||
| 85 | xrcd = container_of(res, struct ib_xrcd, res); | ||
| 86 | dev = xrcd->device; | ||
| 87 | break; | ||
| 88 | default: | 82 | default: |
| 89 | WARN_ONCE(true, "Wrong resource tracking type %u\n", type); | 83 | WARN_ONCE(true, "Wrong resource tracking type %u\n", type); |
| 90 | return NULL; | 84 | return NULL; |
| @@ -93,6 +87,21 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res) | |||
| 93 | return dev; | 87 | return dev; |
| 94 | } | 88 | } |
| 95 | 89 | ||
| 90 | static bool res_is_user(struct rdma_restrack_entry *res) | ||
| 91 | { | ||
| 92 | switch (res->type) { | ||
| 93 | case RDMA_RESTRACK_PD: | ||
| 94 | return container_of(res, struct ib_pd, res)->uobject; | ||
| 95 | case RDMA_RESTRACK_CQ: | ||
| 96 | return container_of(res, struct ib_cq, res)->uobject; | ||
| 97 | case RDMA_RESTRACK_QP: | ||
| 98 | return container_of(res, struct ib_qp, res)->uobject; | ||
| 99 | default: | ||
| 100 | WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type); | ||
| 101 | return false; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 96 | void rdma_restrack_add(struct rdma_restrack_entry *res) | 105 | void rdma_restrack_add(struct rdma_restrack_entry *res) |
| 97 | { | 106 | { |
| 98 | struct ib_device *dev = res_to_dev(res); | 107 | struct ib_device *dev = res_to_dev(res); |
| @@ -100,7 +109,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res) | |||
| 100 | if (!dev) | 109 | if (!dev) |
| 101 | return; | 110 | return; |
| 102 | 111 | ||
| 103 | if (!uaccess_kernel()) { | 112 | if (res_is_user(res)) { |
| 104 | get_task_struct(current); | 113 | get_task_struct(current); |
| 105 | res->task = current; | 114 | res->task = current; |
| 106 | res->kern_name = NULL; | 115 | res->kern_name = NULL; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 256934d1f64f..a148de35df8d 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -562,9 +562,10 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file, | |||
| 562 | if (f.file) | 562 | if (f.file) |
| 563 | fdput(f); | 563 | fdput(f); |
| 564 | 564 | ||
| 565 | mutex_unlock(&file->device->xrcd_tree_mutex); | ||
| 566 | |||
| 565 | uobj_alloc_commit(&obj->uobject); | 567 | uobj_alloc_commit(&obj->uobject); |
| 566 | 568 | ||
| 567 | mutex_unlock(&file->device->xrcd_tree_mutex); | ||
| 568 | return in_len; | 569 | return in_len; |
| 569 | 570 | ||
| 570 | err_copy: | 571 | err_copy: |
| @@ -603,10 +604,8 @@ ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file, | |||
| 603 | 604 | ||
| 604 | uobj = uobj_get_write(uobj_get_type(xrcd), cmd.xrcd_handle, | 605 | uobj = uobj_get_write(uobj_get_type(xrcd), cmd.xrcd_handle, |
| 605 | file->ucontext); | 606 | file->ucontext); |
| 606 | if (IS_ERR(uobj)) { | 607 | if (IS_ERR(uobj)) |
| 607 | mutex_unlock(&file->device->xrcd_tree_mutex); | ||
| 608 | return PTR_ERR(uobj); | 608 | return PTR_ERR(uobj); |
| 609 | } | ||
| 610 | 609 | ||
| 611 | ret = uobj_remove_commit(uobj); | 610 | ret = uobj_remove_commit(uobj); |
| 612 | return ret ?: in_len; | 611 | return ret ?: in_len; |
| @@ -979,6 +978,9 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file, | |||
| 979 | struct ib_uverbs_ex_create_cq_resp resp; | 978 | struct ib_uverbs_ex_create_cq_resp resp; |
| 980 | struct ib_cq_init_attr attr = {}; | 979 | struct ib_cq_init_attr attr = {}; |
| 981 | 980 | ||
| 981 | if (!ib_dev->create_cq) | ||
| 982 | return ERR_PTR(-EOPNOTSUPP); | ||
| 983 | |||
| 982 | if (cmd->comp_vector >= file->device->num_comp_vectors) | 984 | if (cmd->comp_vector >= file->device->num_comp_vectors) |
| 983 | return ERR_PTR(-EINVAL); | 985 | return ERR_PTR(-EINVAL); |
| 984 | 986 | ||
| @@ -1030,14 +1032,14 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file, | |||
| 1030 | resp.response_length = offsetof(typeof(resp), response_length) + | 1032 | resp.response_length = offsetof(typeof(resp), response_length) + |
| 1031 | sizeof(resp.response_length); | 1033 | sizeof(resp.response_length); |
| 1032 | 1034 | ||
| 1035 | cq->res.type = RDMA_RESTRACK_CQ; | ||
| 1036 | rdma_restrack_add(&cq->res); | ||
| 1037 | |||
| 1033 | ret = cb(file, obj, &resp, ucore, context); | 1038 | ret = cb(file, obj, &resp, ucore, context); |
| 1034 | if (ret) | 1039 | if (ret) |
| 1035 | goto err_cb; | 1040 | goto err_cb; |
| 1036 | 1041 | ||
| 1037 | uobj_alloc_commit(&obj->uobject); | 1042 | uobj_alloc_commit(&obj->uobject); |
| 1038 | cq->res.type = RDMA_RESTRACK_CQ; | ||
| 1039 | rdma_restrack_add(&cq->res); | ||
| 1040 | |||
| 1041 | return obj; | 1043 | return obj; |
| 1042 | 1044 | ||
| 1043 | err_cb: | 1045 | err_cb: |
| @@ -1518,7 +1520,8 @@ static int create_qp(struct ib_uverbs_file *file, | |||
| 1518 | if (cmd->qp_type == IB_QPT_XRC_TGT) | 1520 | if (cmd->qp_type == IB_QPT_XRC_TGT) |
| 1519 | qp = ib_create_qp(pd, &attr); | 1521 | qp = ib_create_qp(pd, &attr); |
| 1520 | else | 1522 | else |
| 1521 | qp = _ib_create_qp(device, pd, &attr, uhw); | 1523 | qp = _ib_create_qp(device, pd, &attr, uhw, |
| 1524 | &obj->uevent.uobject); | ||
| 1522 | 1525 | ||
| 1523 | if (IS_ERR(qp)) { | 1526 | if (IS_ERR(qp)) { |
| 1524 | ret = PTR_ERR(qp); | 1527 | ret = PTR_ERR(qp); |
| @@ -1550,8 +1553,10 @@ static int create_qp(struct ib_uverbs_file *file, | |||
| 1550 | atomic_inc(&attr.srq->usecnt); | 1553 | atomic_inc(&attr.srq->usecnt); |
| 1551 | if (ind_tbl) | 1554 | if (ind_tbl) |
| 1552 | atomic_inc(&ind_tbl->usecnt); | 1555 | atomic_inc(&ind_tbl->usecnt); |
| 1556 | } else { | ||
| 1557 | /* It is done in _ib_create_qp for other QP types */ | ||
| 1558 | qp->uobject = &obj->uevent.uobject; | ||
| 1553 | } | 1559 | } |
| 1554 | qp->uobject = &obj->uevent.uobject; | ||
| 1555 | 1560 | ||
| 1556 | obj->uevent.uobject.object = qp; | 1561 | obj->uevent.uobject.object = qp; |
| 1557 | 1562 | ||
| @@ -1971,8 +1976,15 @@ static int modify_qp(struct ib_uverbs_file *file, | |||
| 1971 | goto release_qp; | 1976 | goto release_qp; |
| 1972 | } | 1977 | } |
| 1973 | 1978 | ||
| 1979 | if ((cmd->base.attr_mask & IB_QP_AV) && | ||
| 1980 | !rdma_is_port_valid(qp->device, cmd->base.dest.port_num)) { | ||
| 1981 | ret = -EINVAL; | ||
| 1982 | goto release_qp; | ||
| 1983 | } | ||
| 1984 | |||
| 1974 | if ((cmd->base.attr_mask & IB_QP_ALT_PATH) && | 1985 | if ((cmd->base.attr_mask & IB_QP_ALT_PATH) && |
| 1975 | !rdma_is_port_valid(qp->device, cmd->base.alt_port_num)) { | 1986 | (!rdma_is_port_valid(qp->device, cmd->base.alt_port_num) || |
| 1987 | !rdma_is_port_valid(qp->device, cmd->base.alt_dest.port_num))) { | ||
| 1976 | ret = -EINVAL; | 1988 | ret = -EINVAL; |
| 1977 | goto release_qp; | 1989 | goto release_qp; |
| 1978 | } | 1990 | } |
| @@ -2941,6 +2953,11 @@ int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file, | |||
| 2941 | wq_init_attr.create_flags = cmd.create_flags; | 2953 | wq_init_attr.create_flags = cmd.create_flags; |
| 2942 | obj->uevent.events_reported = 0; | 2954 | obj->uevent.events_reported = 0; |
| 2943 | INIT_LIST_HEAD(&obj->uevent.event_list); | 2955 | INIT_LIST_HEAD(&obj->uevent.event_list); |
| 2956 | |||
| 2957 | if (!pd->device->create_wq) { | ||
| 2958 | err = -EOPNOTSUPP; | ||
| 2959 | goto err_put_cq; | ||
| 2960 | } | ||
| 2944 | wq = pd->device->create_wq(pd, &wq_init_attr, uhw); | 2961 | wq = pd->device->create_wq(pd, &wq_init_attr, uhw); |
| 2945 | if (IS_ERR(wq)) { | 2962 | if (IS_ERR(wq)) { |
| 2946 | err = PTR_ERR(wq); | 2963 | err = PTR_ERR(wq); |
| @@ -3084,7 +3101,12 @@ int ib_uverbs_ex_modify_wq(struct ib_uverbs_file *file, | |||
| 3084 | wq_attr.flags = cmd.flags; | 3101 | wq_attr.flags = cmd.flags; |
| 3085 | wq_attr.flags_mask = cmd.flags_mask; | 3102 | wq_attr.flags_mask = cmd.flags_mask; |
| 3086 | } | 3103 | } |
| 3104 | if (!wq->device->modify_wq) { | ||
| 3105 | ret = -EOPNOTSUPP; | ||
| 3106 | goto out; | ||
| 3107 | } | ||
| 3087 | ret = wq->device->modify_wq(wq, &wq_attr, cmd.attr_mask, uhw); | 3108 | ret = wq->device->modify_wq(wq, &wq_attr, cmd.attr_mask, uhw); |
| 3109 | out: | ||
| 3088 | uobj_put_obj_read(wq); | 3110 | uobj_put_obj_read(wq); |
| 3089 | return ret; | 3111 | return ret; |
| 3090 | } | 3112 | } |
| @@ -3181,6 +3203,11 @@ int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file, | |||
| 3181 | 3203 | ||
| 3182 | init_attr.log_ind_tbl_size = cmd.log_ind_tbl_size; | 3204 | init_attr.log_ind_tbl_size = cmd.log_ind_tbl_size; |
| 3183 | init_attr.ind_tbl = wqs; | 3205 | init_attr.ind_tbl = wqs; |
| 3206 | |||
| 3207 | if (!ib_dev->create_rwq_ind_table) { | ||
| 3208 | err = -EOPNOTSUPP; | ||
| 3209 | goto err_uobj; | ||
| 3210 | } | ||
| 3184 | rwq_ind_tbl = ib_dev->create_rwq_ind_table(ib_dev, &init_attr, uhw); | 3211 | rwq_ind_tbl = ib_dev->create_rwq_ind_table(ib_dev, &init_attr, uhw); |
| 3185 | 3212 | ||
| 3186 | if (IS_ERR(rwq_ind_tbl)) { | 3213 | if (IS_ERR(rwq_ind_tbl)) { |
| @@ -3770,6 +3797,9 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file, | |||
| 3770 | struct ib_device_attr attr = {0}; | 3797 | struct ib_device_attr attr = {0}; |
| 3771 | int err; | 3798 | int err; |
| 3772 | 3799 | ||
| 3800 | if (!ib_dev->query_device) | ||
| 3801 | return -EOPNOTSUPP; | ||
| 3802 | |||
| 3773 | if (ucore->inlen < sizeof(cmd)) | 3803 | if (ucore->inlen < sizeof(cmd)) |
| 3774 | return -EINVAL; | 3804 | return -EINVAL; |
| 3775 | 3805 | ||
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c index d96dc1d17be1..339b85145044 100644 --- a/drivers/infiniband/core/uverbs_ioctl.c +++ b/drivers/infiniband/core/uverbs_ioctl.c | |||
| @@ -59,6 +59,9 @@ static int uverbs_process_attr(struct ib_device *ibdev, | |||
| 59 | return 0; | 59 | return 0; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | if (test_bit(attr_id, attr_bundle_h->valid_bitmap)) | ||
| 63 | return -EINVAL; | ||
| 64 | |||
| 62 | spec = &attr_spec_bucket->attrs[attr_id]; | 65 | spec = &attr_spec_bucket->attrs[attr_id]; |
| 63 | e = &elements[attr_id]; | 66 | e = &elements[attr_id]; |
| 64 | e->uattr = uattr_ptr; | 67 | e->uattr = uattr_ptr; |
diff --git a/drivers/infiniband/core/uverbs_ioctl_merge.c b/drivers/infiniband/core/uverbs_ioctl_merge.c index 062485f9300d..62e1eb1d2a28 100644 --- a/drivers/infiniband/core/uverbs_ioctl_merge.c +++ b/drivers/infiniband/core/uverbs_ioctl_merge.c | |||
| @@ -114,6 +114,7 @@ static size_t get_elements_above_id(const void **iters, | |||
| 114 | short min = SHRT_MAX; | 114 | short min = SHRT_MAX; |
| 115 | const void *elem; | 115 | const void *elem; |
| 116 | int i, j, last_stored = -1; | 116 | int i, j, last_stored = -1; |
| 117 | unsigned int equal_min = 0; | ||
| 117 | 118 | ||
| 118 | for_each_element(elem, i, j, elements, num_elements, num_offset, | 119 | for_each_element(elem, i, j, elements, num_elements, num_offset, |
| 119 | data_offset) { | 120 | data_offset) { |
| @@ -136,6 +137,10 @@ static size_t get_elements_above_id(const void **iters, | |||
| 136 | */ | 137 | */ |
| 137 | iters[last_stored == i ? num_iters - 1 : num_iters++] = elem; | 138 | iters[last_stored == i ? num_iters - 1 : num_iters++] = elem; |
| 138 | last_stored = i; | 139 | last_stored = i; |
| 140 | if (min == GET_ID(id)) | ||
| 141 | equal_min++; | ||
| 142 | else | ||
| 143 | equal_min = 1; | ||
| 139 | min = GET_ID(id); | 144 | min = GET_ID(id); |
| 140 | } | 145 | } |
| 141 | 146 | ||
| @@ -146,15 +151,10 @@ static size_t get_elements_above_id(const void **iters, | |||
| 146 | * Therefore, we need to clean the beginning of the array to make sure | 151 | * Therefore, we need to clean the beginning of the array to make sure |
| 147 | * all ids of final elements are equal to min. | 152 | * all ids of final elements are equal to min. |
| 148 | */ | 153 | */ |
| 149 | for (i = num_iters - 1; i >= 0 && | 154 | memmove(iters, iters + num_iters - equal_min, sizeof(*iters) * equal_min); |
| 150 | GET_ID(*(u16 *)(iters[i] + id_offset)) == min; i--) | ||
| 151 | ; | ||
| 152 | |||
| 153 | num_iters -= i + 1; | ||
| 154 | memmove(iters, iters + i + 1, sizeof(*iters) * num_iters); | ||
| 155 | 155 | ||
| 156 | *min_id = min; | 156 | *min_id = min; |
| 157 | return num_iters; | 157 | return equal_min; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | #define find_max_element_entry_id(num_elements, elements, num_objects_fld, \ | 160 | #define find_max_element_entry_id(num_elements, elements, num_objects_fld, \ |
| @@ -322,7 +322,7 @@ static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_me | |||
| 322 | hash = kzalloc(sizeof(*hash) + | 322 | hash = kzalloc(sizeof(*hash) + |
| 323 | ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1), | 323 | ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1), |
| 324 | sizeof(long)) + | 324 | sizeof(long)) + |
| 325 | BITS_TO_LONGS(attr_max_bucket) * sizeof(long), | 325 | BITS_TO_LONGS(attr_max_bucket + 1) * sizeof(long), |
| 326 | GFP_KERNEL); | 326 | GFP_KERNEL); |
| 327 | if (!hash) { | 327 | if (!hash) { |
| 328 | res = -ENOMEM; | 328 | res = -ENOMEM; |
| @@ -509,7 +509,7 @@ static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_ | |||
| 509 | * first handler which != NULL. This also defines the | 509 | * first handler which != NULL. This also defines the |
| 510 | * set of flags used for this handler. | 510 | * set of flags used for this handler. |
| 511 | */ | 511 | */ |
| 512 | for (i = num_object_defs - 1; | 512 | for (i = num_method_defs - 1; |
| 513 | i >= 0 && !method_defs[i]->handler; i--) | 513 | i >= 0 && !method_defs[i]->handler; i--) |
| 514 | ; | 514 | ; |
| 515 | hash->methods[min_id++] = method; | 515 | hash->methods[min_id++] = method; |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 395a3b091229..b1ca223aa380 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -650,12 +650,21 @@ static int verify_command_mask(struct ib_device *ib_dev, __u32 command) | |||
| 650 | return -1; | 650 | return -1; |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | static bool verify_command_idx(u32 command, bool extended) | ||
| 654 | { | ||
| 655 | if (extended) | ||
| 656 | return command < ARRAY_SIZE(uverbs_ex_cmd_table); | ||
| 657 | |||
| 658 | return command < ARRAY_SIZE(uverbs_cmd_table); | ||
| 659 | } | ||
| 660 | |||
| 653 | static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | 661 | static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, |
| 654 | size_t count, loff_t *pos) | 662 | size_t count, loff_t *pos) |
| 655 | { | 663 | { |
| 656 | struct ib_uverbs_file *file = filp->private_data; | 664 | struct ib_uverbs_file *file = filp->private_data; |
| 657 | struct ib_device *ib_dev; | 665 | struct ib_device *ib_dev; |
| 658 | struct ib_uverbs_cmd_hdr hdr; | 666 | struct ib_uverbs_cmd_hdr hdr; |
| 667 | bool extended_command; | ||
| 659 | __u32 command; | 668 | __u32 command; |
| 660 | __u32 flags; | 669 | __u32 flags; |
| 661 | int srcu_key; | 670 | int srcu_key; |
| @@ -688,6 +697,15 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
| 688 | } | 697 | } |
| 689 | 698 | ||
| 690 | command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; | 699 | command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; |
| 700 | flags = (hdr.command & | ||
| 701 | IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; | ||
| 702 | |||
| 703 | extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED; | ||
| 704 | if (!verify_command_idx(command, extended_command)) { | ||
| 705 | ret = -EINVAL; | ||
| 706 | goto out; | ||
| 707 | } | ||
| 708 | |||
| 691 | if (verify_command_mask(ib_dev, command)) { | 709 | if (verify_command_mask(ib_dev, command)) { |
| 692 | ret = -EOPNOTSUPP; | 710 | ret = -EOPNOTSUPP; |
| 693 | goto out; | 711 | goto out; |
| @@ -699,12 +717,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
| 699 | goto out; | 717 | goto out; |
| 700 | } | 718 | } |
| 701 | 719 | ||
| 702 | flags = (hdr.command & | ||
| 703 | IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; | ||
| 704 | |||
| 705 | if (!flags) { | 720 | if (!flags) { |
| 706 | if (command >= ARRAY_SIZE(uverbs_cmd_table) || | 721 | if (!uverbs_cmd_table[command]) { |
| 707 | !uverbs_cmd_table[command]) { | ||
| 708 | ret = -EINVAL; | 722 | ret = -EINVAL; |
| 709 | goto out; | 723 | goto out; |
| 710 | } | 724 | } |
| @@ -725,8 +739,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
| 725 | struct ib_udata uhw; | 739 | struct ib_udata uhw; |
| 726 | size_t written_count = count; | 740 | size_t written_count = count; |
| 727 | 741 | ||
| 728 | if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) || | 742 | if (!uverbs_ex_cmd_table[command]) { |
| 729 | !uverbs_ex_cmd_table[command]) { | ||
| 730 | ret = -ENOSYS; | 743 | ret = -ENOSYS; |
| 731 | goto out; | 744 | goto out; |
| 732 | } | 745 | } |
| @@ -942,6 +955,7 @@ static const struct file_operations uverbs_fops = { | |||
| 942 | .llseek = no_llseek, | 955 | .llseek = no_llseek, |
| 943 | #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS) | 956 | #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS) |
| 944 | .unlocked_ioctl = ib_uverbs_ioctl, | 957 | .unlocked_ioctl = ib_uverbs_ioctl, |
| 958 | .compat_ioctl = ib_uverbs_ioctl, | ||
| 945 | #endif | 959 | #endif |
| 946 | }; | 960 | }; |
| 947 | 961 | ||
| @@ -954,6 +968,7 @@ static const struct file_operations uverbs_mmap_fops = { | |||
| 954 | .llseek = no_llseek, | 968 | .llseek = no_llseek, |
| 955 | #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS) | 969 | #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS) |
| 956 | .unlocked_ioctl = ib_uverbs_ioctl, | 970 | .unlocked_ioctl = ib_uverbs_ioctl, |
| 971 | .compat_ioctl = ib_uverbs_ioctl, | ||
| 957 | #endif | 972 | #endif |
| 958 | }; | 973 | }; |
| 959 | 974 | ||
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c index cab0ac3556eb..df1360e6774f 100644 --- a/drivers/infiniband/core/uverbs_std_types.c +++ b/drivers/infiniband/core/uverbs_std_types.c | |||
| @@ -234,15 +234,18 @@ static void create_udata(struct uverbs_attr_bundle *ctx, | |||
| 234 | uverbs_attr_get(ctx, UVERBS_UHW_OUT); | 234 | uverbs_attr_get(ctx, UVERBS_UHW_OUT); |
| 235 | 235 | ||
| 236 | if (!IS_ERR(uhw_in)) { | 236 | if (!IS_ERR(uhw_in)) { |
| 237 | udata->inbuf = uhw_in->ptr_attr.ptr; | ||
| 238 | udata->inlen = uhw_in->ptr_attr.len; | 237 | udata->inlen = uhw_in->ptr_attr.len; |
| 238 | if (uverbs_attr_ptr_is_inline(uhw_in)) | ||
| 239 | udata->inbuf = &uhw_in->uattr->data; | ||
| 240 | else | ||
| 241 | udata->inbuf = u64_to_user_ptr(uhw_in->ptr_attr.data); | ||
| 239 | } else { | 242 | } else { |
| 240 | udata->inbuf = NULL; | 243 | udata->inbuf = NULL; |
| 241 | udata->inlen = 0; | 244 | udata->inlen = 0; |
| 242 | } | 245 | } |
| 243 | 246 | ||
| 244 | if (!IS_ERR(uhw_out)) { | 247 | if (!IS_ERR(uhw_out)) { |
| 245 | udata->outbuf = uhw_out->ptr_attr.ptr; | 248 | udata->outbuf = u64_to_user_ptr(uhw_out->ptr_attr.data); |
| 246 | udata->outlen = uhw_out->ptr_attr.len; | 249 | udata->outlen = uhw_out->ptr_attr.len; |
| 247 | } else { | 250 | } else { |
| 248 | udata->outbuf = NULL; | 251 | udata->outbuf = NULL; |
| @@ -323,7 +326,8 @@ static int uverbs_create_cq_handler(struct ib_device *ib_dev, | |||
| 323 | cq->res.type = RDMA_RESTRACK_CQ; | 326 | cq->res.type = RDMA_RESTRACK_CQ; |
| 324 | rdma_restrack_add(&cq->res); | 327 | rdma_restrack_add(&cq->res); |
| 325 | 328 | ||
| 326 | ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe); | 329 | ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe, |
| 330 | sizeof(cq->cqe)); | ||
| 327 | if (ret) | 331 | if (ret) |
| 328 | goto err_cq; | 332 | goto err_cq; |
| 329 | 333 | ||
| @@ -375,7 +379,7 @@ static int uverbs_destroy_cq_handler(struct ib_device *ib_dev, | |||
| 375 | resp.comp_events_reported = obj->comp_events_reported; | 379 | resp.comp_events_reported = obj->comp_events_reported; |
| 376 | resp.async_events_reported = obj->async_events_reported; | 380 | resp.async_events_reported = obj->async_events_reported; |
| 377 | 381 | ||
| 378 | return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp); | 382 | return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp, sizeof(resp)); |
| 379 | } | 383 | } |
| 380 | 384 | ||
| 381 | static DECLARE_UVERBS_METHOD( | 385 | static DECLARE_UVERBS_METHOD( |
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 16ebc6372c31..93025d2009b8 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
| @@ -887,7 +887,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, | |||
| 887 | if (qp_init_attr->cap.max_rdma_ctxs) | 887 | if (qp_init_attr->cap.max_rdma_ctxs) |
| 888 | rdma_rw_init_qp(device, qp_init_attr); | 888 | rdma_rw_init_qp(device, qp_init_attr); |
| 889 | 889 | ||
| 890 | qp = _ib_create_qp(device, pd, qp_init_attr, NULL); | 890 | qp = _ib_create_qp(device, pd, qp_init_attr, NULL, NULL); |
| 891 | if (IS_ERR(qp)) | 891 | if (IS_ERR(qp)) |
| 892 | return qp; | 892 | return qp; |
| 893 | 893 | ||
| @@ -898,7 +898,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, | |||
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | qp->real_qp = qp; | 900 | qp->real_qp = qp; |
| 901 | qp->uobject = NULL; | ||
| 902 | qp->qp_type = qp_init_attr->qp_type; | 901 | qp->qp_type = qp_init_attr->qp_type; |
| 903 | qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; | 902 | qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; |
| 904 | 903 | ||
diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h index ca32057e886f..3eb7a8387116 100644 --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h | |||
| @@ -120,7 +120,6 @@ struct bnxt_re_dev { | |||
| 120 | #define BNXT_RE_FLAG_HAVE_L2_REF 3 | 120 | #define BNXT_RE_FLAG_HAVE_L2_REF 3 |
| 121 | #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4 | 121 | #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4 |
| 122 | #define BNXT_RE_FLAG_QOS_WORK_REG 5 | 122 | #define BNXT_RE_FLAG_QOS_WORK_REG 5 |
| 123 | #define BNXT_RE_FLAG_TASK_IN_PROG 6 | ||
| 124 | #define BNXT_RE_FLAG_ISSUE_ROCE_STATS 29 | 123 | #define BNXT_RE_FLAG_ISSUE_ROCE_STATS 29 |
| 125 | struct net_device *netdev; | 124 | struct net_device *netdev; |
| 126 | unsigned int version, major, minor; | 125 | unsigned int version, major, minor; |
| @@ -158,6 +157,7 @@ struct bnxt_re_dev { | |||
| 158 | atomic_t srq_count; | 157 | atomic_t srq_count; |
| 159 | atomic_t mr_count; | 158 | atomic_t mr_count; |
| 160 | atomic_t mw_count; | 159 | atomic_t mw_count; |
| 160 | atomic_t sched_count; | ||
| 161 | /* Max of 2 lossless traffic class supported per port */ | 161 | /* Max of 2 lossless traffic class supported per port */ |
| 162 | u16 cosq[2]; | 162 | u16 cosq[2]; |
| 163 | 163 | ||
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index ae9e9ff54826..643174d949a8 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c | |||
| @@ -174,10 +174,8 @@ int bnxt_re_query_device(struct ib_device *ibdev, | |||
| 174 | ib_attr->max_pd = dev_attr->max_pd; | 174 | ib_attr->max_pd = dev_attr->max_pd; |
| 175 | ib_attr->max_qp_rd_atom = dev_attr->max_qp_rd_atom; | 175 | ib_attr->max_qp_rd_atom = dev_attr->max_qp_rd_atom; |
| 176 | ib_attr->max_qp_init_rd_atom = dev_attr->max_qp_init_rd_atom; | 176 | ib_attr->max_qp_init_rd_atom = dev_attr->max_qp_init_rd_atom; |
| 177 | if (dev_attr->is_atomic) { | 177 | ib_attr->atomic_cap = IB_ATOMIC_NONE; |
| 178 | ib_attr->atomic_cap = IB_ATOMIC_HCA; | 178 | ib_attr->masked_atomic_cap = IB_ATOMIC_NONE; |
| 179 | ib_attr->masked_atomic_cap = IB_ATOMIC_HCA; | ||
| 180 | } | ||
| 181 | 179 | ||
| 182 | ib_attr->max_ee_rd_atom = 0; | 180 | ib_attr->max_ee_rd_atom = 0; |
| 183 | ib_attr->max_res_rd_atom = 0; | 181 | ib_attr->max_res_rd_atom = 0; |
| @@ -787,20 +785,51 @@ int bnxt_re_query_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr) | |||
| 787 | return 0; | 785 | return 0; |
| 788 | } | 786 | } |
| 789 | 787 | ||
| 788 | static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp) | ||
| 789 | __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock) | ||
| 790 | { | ||
| 791 | unsigned long flags; | ||
| 792 | |||
| 793 | spin_lock_irqsave(&qp->scq->cq_lock, flags); | ||
| 794 | if (qp->rcq != qp->scq) | ||
| 795 | spin_lock(&qp->rcq->cq_lock); | ||
| 796 | else | ||
| 797 | __acquire(&qp->rcq->cq_lock); | ||
| 798 | |||
| 799 | return flags; | ||
| 800 | } | ||
| 801 | |||
| 802 | static void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, | ||
| 803 | unsigned long flags) | ||
| 804 | __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock) | ||
| 805 | { | ||
| 806 | if (qp->rcq != qp->scq) | ||
| 807 | spin_unlock(&qp->rcq->cq_lock); | ||
| 808 | else | ||
| 809 | __release(&qp->rcq->cq_lock); | ||
| 810 | spin_unlock_irqrestore(&qp->scq->cq_lock, flags); | ||
| 811 | } | ||
| 812 | |||
| 790 | /* Queue Pairs */ | 813 | /* Queue Pairs */ |
| 791 | int bnxt_re_destroy_qp(struct ib_qp *ib_qp) | 814 | int bnxt_re_destroy_qp(struct ib_qp *ib_qp) |
| 792 | { | 815 | { |
| 793 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); | 816 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); |
| 794 | struct bnxt_re_dev *rdev = qp->rdev; | 817 | struct bnxt_re_dev *rdev = qp->rdev; |
| 795 | int rc; | 818 | int rc; |
| 819 | unsigned int flags; | ||
| 796 | 820 | ||
| 797 | bnxt_qplib_flush_cqn_wq(&qp->qplib_qp); | 821 | bnxt_qplib_flush_cqn_wq(&qp->qplib_qp); |
| 798 | bnxt_qplib_del_flush_qp(&qp->qplib_qp); | ||
| 799 | rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); | 822 | rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); |
| 800 | if (rc) { | 823 | if (rc) { |
| 801 | dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); | 824 | dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); |
| 802 | return rc; | 825 | return rc; |
| 803 | } | 826 | } |
| 827 | |||
| 828 | flags = bnxt_re_lock_cqs(qp); | ||
| 829 | bnxt_qplib_clean_qp(&qp->qplib_qp); | ||
| 830 | bnxt_re_unlock_cqs(qp, flags); | ||
| 831 | bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp); | ||
| 832 | |||
| 804 | if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { | 833 | if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { |
| 805 | rc = bnxt_qplib_destroy_ah(&rdev->qplib_res, | 834 | rc = bnxt_qplib_destroy_ah(&rdev->qplib_res, |
| 806 | &rdev->sqp_ah->qplib_ah); | 835 | &rdev->sqp_ah->qplib_ah); |
| @@ -810,7 +839,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp) | |||
| 810 | return rc; | 839 | return rc; |
| 811 | } | 840 | } |
| 812 | 841 | ||
| 813 | bnxt_qplib_del_flush_qp(&qp->qplib_qp); | 842 | bnxt_qplib_clean_qp(&qp->qplib_qp); |
| 814 | rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, | 843 | rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, |
| 815 | &rdev->qp1_sqp->qplib_qp); | 844 | &rdev->qp1_sqp->qplib_qp); |
| 816 | if (rc) { | 845 | if (rc) { |
| @@ -1069,6 +1098,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, | |||
| 1069 | goto fail; | 1098 | goto fail; |
| 1070 | } | 1099 | } |
| 1071 | qp->qplib_qp.scq = &cq->qplib_cq; | 1100 | qp->qplib_qp.scq = &cq->qplib_cq; |
| 1101 | qp->scq = cq; | ||
| 1072 | } | 1102 | } |
| 1073 | 1103 | ||
| 1074 | if (qp_init_attr->recv_cq) { | 1104 | if (qp_init_attr->recv_cq) { |
| @@ -1080,6 +1110,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, | |||
| 1080 | goto fail; | 1110 | goto fail; |
| 1081 | } | 1111 | } |
| 1082 | qp->qplib_qp.rcq = &cq->qplib_cq; | 1112 | qp->qplib_qp.rcq = &cq->qplib_cq; |
| 1113 | qp->rcq = cq; | ||
| 1083 | } | 1114 | } |
| 1084 | 1115 | ||
| 1085 | if (qp_init_attr->srq) { | 1116 | if (qp_init_attr->srq) { |
| @@ -1185,7 +1216,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, | |||
| 1185 | rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); | 1216 | rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); |
| 1186 | if (rc) { | 1217 | if (rc) { |
| 1187 | dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); | 1218 | dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); |
| 1188 | goto fail; | 1219 | goto free_umem; |
| 1189 | } | 1220 | } |
| 1190 | } | 1221 | } |
| 1191 | 1222 | ||
| @@ -1213,6 +1244,13 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, | |||
| 1213 | return &qp->ib_qp; | 1244 | return &qp->ib_qp; |
| 1214 | qp_destroy: | 1245 | qp_destroy: |
| 1215 | bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); | 1246 | bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); |
| 1247 | free_umem: | ||
| 1248 | if (udata) { | ||
| 1249 | if (qp->rumem) | ||
| 1250 | ib_umem_release(qp->rumem); | ||
| 1251 | if (qp->sumem) | ||
| 1252 | ib_umem_release(qp->sumem); | ||
| 1253 | } | ||
| 1216 | fail: | 1254 | fail: |
| 1217 | kfree(qp); | 1255 | kfree(qp); |
| 1218 | return ERR_PTR(rc); | 1256 | return ERR_PTR(rc); |
| @@ -1603,7 +1641,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, | |||
| 1603 | dev_dbg(rdev_to_dev(rdev), | 1641 | dev_dbg(rdev_to_dev(rdev), |
| 1604 | "Move QP = %p out of flush list\n", | 1642 | "Move QP = %p out of flush list\n", |
| 1605 | qp); | 1643 | qp); |
| 1606 | bnxt_qplib_del_flush_qp(&qp->qplib_qp); | 1644 | bnxt_qplib_clean_qp(&qp->qplib_qp); |
| 1607 | } | 1645 | } |
| 1608 | } | 1646 | } |
| 1609 | if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) { | 1647 | if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) { |
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h index 423ebe012f95..b88a48d43a9d 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h | |||
| @@ -89,6 +89,8 @@ struct bnxt_re_qp { | |||
| 89 | /* QP1 */ | 89 | /* QP1 */ |
| 90 | u32 send_psn; | 90 | u32 send_psn; |
| 91 | struct ib_ud_header qp1_hdr; | 91 | struct ib_ud_header qp1_hdr; |
| 92 | struct bnxt_re_cq *scq; | ||
| 93 | struct bnxt_re_cq *rcq; | ||
| 92 | }; | 94 | }; |
| 93 | 95 | ||
| 94 | struct bnxt_re_cq { | 96 | struct bnxt_re_cq { |
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 508d00a5a106..33a448036c2e 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c | |||
| @@ -656,7 +656,6 @@ static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev) | |||
| 656 | mutex_unlock(&bnxt_re_dev_lock); | 656 | mutex_unlock(&bnxt_re_dev_lock); |
| 657 | 657 | ||
| 658 | synchronize_rcu(); | 658 | synchronize_rcu(); |
| 659 | flush_workqueue(bnxt_re_wq); | ||
| 660 | 659 | ||
| 661 | ib_dealloc_device(&rdev->ibdev); | 660 | ib_dealloc_device(&rdev->ibdev); |
| 662 | /* rdev is gone */ | 661 | /* rdev is gone */ |
| @@ -1441,7 +1440,7 @@ static void bnxt_re_task(struct work_struct *work) | |||
| 1441 | break; | 1440 | break; |
| 1442 | } | 1441 | } |
| 1443 | smp_mb__before_atomic(); | 1442 | smp_mb__before_atomic(); |
| 1444 | clear_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | 1443 | atomic_dec(&rdev->sched_count); |
| 1445 | kfree(re_work); | 1444 | kfree(re_work); |
| 1446 | } | 1445 | } |
| 1447 | 1446 | ||
| @@ -1503,7 +1502,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, | |||
| 1503 | /* netdev notifier will call NETDEV_UNREGISTER again later since | 1502 | /* netdev notifier will call NETDEV_UNREGISTER again later since |
| 1504 | * we are still holding the reference to the netdev | 1503 | * we are still holding the reference to the netdev |
| 1505 | */ | 1504 | */ |
| 1506 | if (test_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags)) | 1505 | if (atomic_read(&rdev->sched_count) > 0) |
| 1507 | goto exit; | 1506 | goto exit; |
| 1508 | bnxt_re_ib_unreg(rdev, false); | 1507 | bnxt_re_ib_unreg(rdev, false); |
| 1509 | bnxt_re_remove_one(rdev); | 1508 | bnxt_re_remove_one(rdev); |
| @@ -1523,7 +1522,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, | |||
| 1523 | re_work->vlan_dev = (real_dev == netdev ? | 1522 | re_work->vlan_dev = (real_dev == netdev ? |
| 1524 | NULL : netdev); | 1523 | NULL : netdev); |
| 1525 | INIT_WORK(&re_work->work, bnxt_re_task); | 1524 | INIT_WORK(&re_work->work, bnxt_re_task); |
| 1526 | set_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | 1525 | atomic_inc(&rdev->sched_count); |
| 1527 | queue_work(bnxt_re_wq, &re_work->work); | 1526 | queue_work(bnxt_re_wq, &re_work->work); |
| 1528 | } | 1527 | } |
| 1529 | } | 1528 | } |
| @@ -1578,6 +1577,11 @@ static void __exit bnxt_re_mod_exit(void) | |||
| 1578 | */ | 1577 | */ |
| 1579 | list_for_each_entry_safe_reverse(rdev, next, &to_be_deleted, list) { | 1578 | list_for_each_entry_safe_reverse(rdev, next, &to_be_deleted, list) { |
| 1580 | dev_info(rdev_to_dev(rdev), "Unregistering Device"); | 1579 | dev_info(rdev_to_dev(rdev), "Unregistering Device"); |
| 1580 | /* | ||
| 1581 | * Flush out any scheduled tasks before destroying the | ||
| 1582 | * resources | ||
| 1583 | */ | ||
| 1584 | flush_workqueue(bnxt_re_wq); | ||
| 1581 | bnxt_re_dev_stop(rdev); | 1585 | bnxt_re_dev_stop(rdev); |
| 1582 | bnxt_re_ib_unreg(rdev, true); | 1586 | bnxt_re_ib_unreg(rdev, true); |
| 1583 | bnxt_re_remove_one(rdev); | 1587 | bnxt_re_remove_one(rdev); |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 1b0e94697fe3..3ea5b9624f6b 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c | |||
| @@ -173,7 +173,7 @@ static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) | |||
| 173 | } | 173 | } |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp) | 176 | void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp) |
| 177 | { | 177 | { |
| 178 | unsigned long flags; | 178 | unsigned long flags; |
| 179 | 179 | ||
| @@ -1419,7 +1419,6 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, | |||
| 1419 | struct bnxt_qplib_rcfw *rcfw = res->rcfw; | 1419 | struct bnxt_qplib_rcfw *rcfw = res->rcfw; |
| 1420 | struct cmdq_destroy_qp req; | 1420 | struct cmdq_destroy_qp req; |
| 1421 | struct creq_destroy_qp_resp resp; | 1421 | struct creq_destroy_qp_resp resp; |
| 1422 | unsigned long flags; | ||
| 1423 | u16 cmd_flags = 0; | 1422 | u16 cmd_flags = 0; |
| 1424 | int rc; | 1423 | int rc; |
| 1425 | 1424 | ||
| @@ -1437,19 +1436,12 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, | |||
| 1437 | return rc; | 1436 | return rc; |
| 1438 | } | 1437 | } |
| 1439 | 1438 | ||
| 1440 | /* Must walk the associated CQs to nullified the QP ptr */ | 1439 | return 0; |
| 1441 | spin_lock_irqsave(&qp->scq->hwq.lock, flags); | 1440 | } |
| 1442 | |||
| 1443 | __clean_cq(qp->scq, (u64)(unsigned long)qp); | ||
| 1444 | |||
| 1445 | if (qp->rcq && qp->rcq != qp->scq) { | ||
| 1446 | spin_lock(&qp->rcq->hwq.lock); | ||
| 1447 | __clean_cq(qp->rcq, (u64)(unsigned long)qp); | ||
| 1448 | spin_unlock(&qp->rcq->hwq.lock); | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | spin_unlock_irqrestore(&qp->scq->hwq.lock, flags); | ||
| 1452 | 1441 | ||
| 1442 | void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res, | ||
| 1443 | struct bnxt_qplib_qp *qp) | ||
| 1444 | { | ||
| 1453 | bnxt_qplib_free_qp_hdr_buf(res, qp); | 1445 | bnxt_qplib_free_qp_hdr_buf(res, qp); |
| 1454 | bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq); | 1446 | bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq); |
| 1455 | kfree(qp->sq.swq); | 1447 | kfree(qp->sq.swq); |
| @@ -1462,7 +1454,6 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, | |||
| 1462 | if (qp->orrq.max_elements) | 1454 | if (qp->orrq.max_elements) |
| 1463 | bnxt_qplib_free_hwq(res->pdev, &qp->orrq); | 1455 | bnxt_qplib_free_hwq(res->pdev, &qp->orrq); |
| 1464 | 1456 | ||
| 1465 | return 0; | ||
| 1466 | } | 1457 | } |
| 1467 | 1458 | ||
| 1468 | void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp, | 1459 | void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp, |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h index 211b27a8f9e2..ca0a2ffa3509 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h | |||
| @@ -478,6 +478,9 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); | |||
| 478 | int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); | 478 | int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); |
| 479 | int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); | 479 | int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); |
| 480 | int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); | 480 | int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp); |
| 481 | void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp); | ||
| 482 | void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res, | ||
| 483 | struct bnxt_qplib_qp *qp); | ||
| 481 | void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp, | 484 | void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp, |
| 482 | struct bnxt_qplib_sge *sge); | 485 | struct bnxt_qplib_sge *sge); |
| 483 | void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp, | 486 | void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp, |
| @@ -500,7 +503,6 @@ void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type); | |||
| 500 | void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq); | 503 | void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq); |
| 501 | int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq); | 504 | int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq); |
| 502 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp); | 505 | void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp); |
| 503 | void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp); | ||
| 504 | void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, | 506 | void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp, |
| 505 | unsigned long *flags); | 507 | unsigned long *flags); |
| 506 | void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp, | 508 | void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp, |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c index c015c1861351..03057983341f 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c | |||
| @@ -52,18 +52,6 @@ const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 52 | 52 | ||
| 53 | /* Device */ | 53 | /* Device */ |
| 54 | 54 | ||
| 55 | static bool bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw *rcfw) | ||
| 56 | { | ||
| 57 | int rc; | ||
| 58 | u16 pcie_ctl2; | ||
| 59 | |||
| 60 | rc = pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2, | ||
| 61 | &pcie_ctl2); | ||
| 62 | if (rc) | ||
| 63 | return false; | ||
| 64 | return !!(pcie_ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw, | 55 | static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw, |
| 68 | char *fw_ver) | 56 | char *fw_ver) |
| 69 | { | 57 | { |
| @@ -165,7 +153,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, | |||
| 165 | attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc); | 153 | attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc); |
| 166 | } | 154 | } |
| 167 | 155 | ||
| 168 | attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw); | 156 | attr->is_atomic = 0; |
| 169 | bail: | 157 | bail: |
| 170 | bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf); | 158 | bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf); |
| 171 | return rc; | 159 | return rc; |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c index faa9478c14a6..f95b97646c25 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | |||
| @@ -114,6 +114,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, | |||
| 114 | union pvrdma_cmd_resp rsp; | 114 | union pvrdma_cmd_resp rsp; |
| 115 | struct pvrdma_cmd_create_cq *cmd = &req.create_cq; | 115 | struct pvrdma_cmd_create_cq *cmd = &req.create_cq; |
| 116 | struct pvrdma_cmd_create_cq_resp *resp = &rsp.create_cq_resp; | 116 | struct pvrdma_cmd_create_cq_resp *resp = &rsp.create_cq_resp; |
| 117 | struct pvrdma_create_cq_resp cq_resp = {0}; | ||
| 117 | struct pvrdma_create_cq ucmd; | 118 | struct pvrdma_create_cq ucmd; |
| 118 | 119 | ||
| 119 | BUILD_BUG_ON(sizeof(struct pvrdma_cqe) != 64); | 120 | BUILD_BUG_ON(sizeof(struct pvrdma_cqe) != 64); |
| @@ -197,6 +198,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, | |||
| 197 | 198 | ||
| 198 | cq->ibcq.cqe = resp->cqe; | 199 | cq->ibcq.cqe = resp->cqe; |
| 199 | cq->cq_handle = resp->cq_handle; | 200 | cq->cq_handle = resp->cq_handle; |
| 201 | cq_resp.cqn = resp->cq_handle; | ||
| 200 | spin_lock_irqsave(&dev->cq_tbl_lock, flags); | 202 | spin_lock_irqsave(&dev->cq_tbl_lock, flags); |
| 201 | dev->cq_tbl[cq->cq_handle % dev->dsr->caps.max_cq] = cq; | 203 | dev->cq_tbl[cq->cq_handle % dev->dsr->caps.max_cq] = cq; |
| 202 | spin_unlock_irqrestore(&dev->cq_tbl_lock, flags); | 204 | spin_unlock_irqrestore(&dev->cq_tbl_lock, flags); |
| @@ -205,7 +207,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, | |||
| 205 | cq->uar = &(to_vucontext(context)->uar); | 207 | cq->uar = &(to_vucontext(context)->uar); |
| 206 | 208 | ||
| 207 | /* Copy udata back. */ | 209 | /* Copy udata back. */ |
| 208 | if (ib_copy_to_udata(udata, &cq->cq_handle, sizeof(__u32))) { | 210 | if (ib_copy_to_udata(udata, &cq_resp, sizeof(cq_resp))) { |
| 209 | dev_warn(&dev->pdev->dev, | 211 | dev_warn(&dev->pdev->dev, |
| 210 | "failed to copy back udata\n"); | 212 | "failed to copy back udata\n"); |
| 211 | pvrdma_destroy_cq(&cq->ibcq); | 213 | pvrdma_destroy_cq(&cq->ibcq); |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c index 5acebb1ef631..af235967a9c2 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | |||
| @@ -113,6 +113,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, | |||
| 113 | union pvrdma_cmd_resp rsp; | 113 | union pvrdma_cmd_resp rsp; |
| 114 | struct pvrdma_cmd_create_srq *cmd = &req.create_srq; | 114 | struct pvrdma_cmd_create_srq *cmd = &req.create_srq; |
| 115 | struct pvrdma_cmd_create_srq_resp *resp = &rsp.create_srq_resp; | 115 | struct pvrdma_cmd_create_srq_resp *resp = &rsp.create_srq_resp; |
| 116 | struct pvrdma_create_srq_resp srq_resp = {0}; | ||
| 116 | struct pvrdma_create_srq ucmd; | 117 | struct pvrdma_create_srq ucmd; |
| 117 | unsigned long flags; | 118 | unsigned long flags; |
| 118 | int ret; | 119 | int ret; |
| @@ -204,12 +205,13 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, | |||
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | srq->srq_handle = resp->srqn; | 207 | srq->srq_handle = resp->srqn; |
| 208 | srq_resp.srqn = resp->srqn; | ||
| 207 | spin_lock_irqsave(&dev->srq_tbl_lock, flags); | 209 | spin_lock_irqsave(&dev->srq_tbl_lock, flags); |
| 208 | dev->srq_tbl[srq->srq_handle % dev->dsr->caps.max_srq] = srq; | 210 | dev->srq_tbl[srq->srq_handle % dev->dsr->caps.max_srq] = srq; |
| 209 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); | 211 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); |
| 210 | 212 | ||
| 211 | /* Copy udata back. */ | 213 | /* Copy udata back. */ |
| 212 | if (ib_copy_to_udata(udata, &srq->srq_handle, sizeof(__u32))) { | 214 | if (ib_copy_to_udata(udata, &srq_resp, sizeof(srq_resp))) { |
| 213 | dev_warn(&dev->pdev->dev, "failed to copy back udata\n"); | 215 | dev_warn(&dev->pdev->dev, "failed to copy back udata\n"); |
| 214 | pvrdma_destroy_srq(&srq->ibsrq); | 216 | pvrdma_destroy_srq(&srq->ibsrq); |
| 215 | return ERR_PTR(-EINVAL); | 217 | return ERR_PTR(-EINVAL); |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c index 16b96616ef7e..a51463cd2f37 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | |||
| @@ -447,6 +447,7 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev, | |||
| 447 | union pvrdma_cmd_resp rsp; | 447 | union pvrdma_cmd_resp rsp; |
| 448 | struct pvrdma_cmd_create_pd *cmd = &req.create_pd; | 448 | struct pvrdma_cmd_create_pd *cmd = &req.create_pd; |
| 449 | struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp; | 449 | struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp; |
| 450 | struct pvrdma_alloc_pd_resp pd_resp = {0}; | ||
| 450 | int ret; | 451 | int ret; |
| 451 | void *ptr; | 452 | void *ptr; |
| 452 | 453 | ||
| @@ -475,9 +476,10 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev, | |||
| 475 | pd->privileged = !context; | 476 | pd->privileged = !context; |
| 476 | pd->pd_handle = resp->pd_handle; | 477 | pd->pd_handle = resp->pd_handle; |
| 477 | pd->pdn = resp->pd_handle; | 478 | pd->pdn = resp->pd_handle; |
| 479 | pd_resp.pdn = resp->pd_handle; | ||
| 478 | 480 | ||
| 479 | if (context) { | 481 | if (context) { |
| 480 | if (ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) { | 482 | if (ib_copy_to_udata(udata, &pd_resp, sizeof(pd_resp))) { |
| 481 | dev_warn(&dev->pdev->dev, | 483 | dev_warn(&dev->pdev->dev, |
| 482 | "failed to copy back protection domain\n"); | 484 | "failed to copy back protection domain\n"); |
| 483 | pvrdma_dealloc_pd(&pd->ibpd); | 485 | pvrdma_dealloc_pd(&pd->ibpd); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 11f74cbe6660..ea302b054601 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
| @@ -281,8 +281,6 @@ void ipoib_delete_debug_files(struct net_device *dev) | |||
| 281 | { | 281 | { |
| 282 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 282 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
| 283 | 283 | ||
| 284 | WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n"); | ||
| 285 | WARN_ONCE(!priv->path_dentry, "null path debug file\n"); | ||
| 286 | debugfs_remove(priv->mcg_dentry); | 284 | debugfs_remove(priv->mcg_dentry); |
| 287 | debugfs_remove(priv->path_dentry); | 285 | debugfs_remove(priv->path_dentry); |
| 288 | priv->mcg_dentry = priv->path_dentry = NULL; | 286 | priv->mcg_dentry = priv->path_dentry = NULL; |
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index 55cfb986225b..faf734ff4cf3 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c | |||
| @@ -339,9 +339,6 @@ int __init bcm7038_l1_of_init(struct device_node *dn, | |||
| 339 | goto out_unmap; | 339 | goto out_unmap; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | pr_info("registered BCM7038 L1 intc (mem: 0x%p, IRQs: %d)\n", | ||
| 343 | intc->cpus[0]->map_base, IRQS_PER_WORD * intc->n_words); | ||
| 344 | |||
| 345 | return 0; | 342 | return 0; |
| 346 | 343 | ||
| 347 | out_unmap: | 344 | out_unmap: |
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 983640eba418..8968e5e93fcb 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c | |||
| @@ -318,9 +318,6 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
| 318 | } | 318 | } |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | pr_info("registered %s intc (mem: 0x%p, parent IRQ(s): %d)\n", | ||
| 322 | intc_name, data->map_base[0], data->num_parent_irqs); | ||
| 323 | |||
| 324 | return 0; | 321 | return 0; |
| 325 | 322 | ||
| 326 | out_free_domain: | 323 | out_free_domain: |
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index 691d20eb0bec..0e65f609352e 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c | |||
| @@ -262,9 +262,6 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
| 262 | ct->chip.irq_set_wake = irq_gc_set_wake; | 262 | ct->chip.irq_set_wake = irq_gc_set_wake; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | pr_info("registered L2 intc (mem: 0x%p, parent irq: %d)\n", | ||
| 266 | base, parent_irq); | ||
| 267 | |||
| 268 | return 0; | 265 | return 0; |
| 269 | 266 | ||
| 270 | out_free_domain: | 267 | out_free_domain: |
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 993a8426a453..1ff38aff9f29 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c | |||
| @@ -94,7 +94,7 @@ static struct irq_chip gicv2m_msi_irq_chip = { | |||
| 94 | 94 | ||
| 95 | static struct msi_domain_info gicv2m_msi_domain_info = { | 95 | static struct msi_domain_info gicv2m_msi_domain_info = { |
| 96 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | 96 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | |
| 97 | MSI_FLAG_PCI_MSIX), | 97 | MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), |
| 98 | .chip = &gicv2m_msi_irq_chip, | 98 | .chip = &gicv2m_msi_irq_chip, |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| @@ -155,18 +155,12 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain, | |||
| 155 | return 0; | 155 | return 0; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq) | 158 | static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq, |
| 159 | int nr_irqs) | ||
| 159 | { | 160 | { |
| 160 | int pos; | ||
| 161 | |||
| 162 | pos = hwirq - v2m->spi_start; | ||
| 163 | if (pos < 0 || pos >= v2m->nr_spis) { | ||
| 164 | pr_err("Failed to teardown msi. Invalid hwirq %d\n", hwirq); | ||
| 165 | return; | ||
| 166 | } | ||
| 167 | |||
| 168 | spin_lock(&v2m_lock); | 161 | spin_lock(&v2m_lock); |
| 169 | __clear_bit(pos, v2m->bm); | 162 | bitmap_release_region(v2m->bm, hwirq - v2m->spi_start, |
| 163 | get_count_order(nr_irqs)); | ||
| 170 | spin_unlock(&v2m_lock); | 164 | spin_unlock(&v2m_lock); |
| 171 | } | 165 | } |
| 172 | 166 | ||
| @@ -174,13 +168,13 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
| 174 | unsigned int nr_irqs, void *args) | 168 | unsigned int nr_irqs, void *args) |
| 175 | { | 169 | { |
| 176 | struct v2m_data *v2m = NULL, *tmp; | 170 | struct v2m_data *v2m = NULL, *tmp; |
| 177 | int hwirq, offset, err = 0; | 171 | int hwirq, offset, i, err = 0; |
| 178 | 172 | ||
| 179 | spin_lock(&v2m_lock); | 173 | spin_lock(&v2m_lock); |
| 180 | list_for_each_entry(tmp, &v2m_nodes, entry) { | 174 | list_for_each_entry(tmp, &v2m_nodes, entry) { |
| 181 | offset = find_first_zero_bit(tmp->bm, tmp->nr_spis); | 175 | offset = bitmap_find_free_region(tmp->bm, tmp->nr_spis, |
| 182 | if (offset < tmp->nr_spis) { | 176 | get_count_order(nr_irqs)); |
| 183 | __set_bit(offset, tmp->bm); | 177 | if (offset >= 0) { |
| 184 | v2m = tmp; | 178 | v2m = tmp; |
| 185 | break; | 179 | break; |
| 186 | } | 180 | } |
| @@ -192,16 +186,21 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
| 192 | 186 | ||
| 193 | hwirq = v2m->spi_start + offset; | 187 | hwirq = v2m->spi_start + offset; |
| 194 | 188 | ||
| 195 | err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq); | 189 | for (i = 0; i < nr_irqs; i++) { |
| 196 | if (err) { | 190 | err = gicv2m_irq_gic_domain_alloc(domain, virq + i, hwirq + i); |
| 197 | gicv2m_unalloc_msi(v2m, hwirq); | 191 | if (err) |
| 198 | return err; | 192 | goto fail; |
| 199 | } | ||
| 200 | 193 | ||
| 201 | irq_domain_set_hwirq_and_chip(domain, virq, hwirq, | 194 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
| 202 | &gicv2m_irq_chip, v2m); | 195 | &gicv2m_irq_chip, v2m); |
| 196 | } | ||
| 203 | 197 | ||
| 204 | return 0; | 198 | return 0; |
| 199 | |||
| 200 | fail: | ||
| 201 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); | ||
| 202 | gicv2m_unalloc_msi(v2m, hwirq, get_count_order(nr_irqs)); | ||
| 203 | return err; | ||
| 205 | } | 204 | } |
| 206 | 205 | ||
| 207 | static void gicv2m_irq_domain_free(struct irq_domain *domain, | 206 | static void gicv2m_irq_domain_free(struct irq_domain *domain, |
| @@ -210,8 +209,7 @@ static void gicv2m_irq_domain_free(struct irq_domain *domain, | |||
| 210 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); | 209 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
| 211 | struct v2m_data *v2m = irq_data_get_irq_chip_data(d); | 210 | struct v2m_data *v2m = irq_data_get_irq_chip_data(d); |
| 212 | 211 | ||
| 213 | BUG_ON(nr_irqs != 1); | 212 | gicv2m_unalloc_msi(v2m, d->hwirq, nr_irqs); |
| 214 | gicv2m_unalloc_msi(v2m, d->hwirq); | ||
| 215 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); | 213 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); |
| 216 | } | 214 | } |
| 217 | 215 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c index 14a8c0a7e095..25a98de5cfb2 100644 --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c | |||
| @@ -132,6 +132,8 @@ static int __init its_pci_of_msi_init(void) | |||
| 132 | 132 | ||
| 133 | for (np = of_find_matching_node(NULL, its_device_id); np; | 133 | for (np = of_find_matching_node(NULL, its_device_id); np; |
| 134 | np = of_find_matching_node(np, its_device_id)) { | 134 | np = of_find_matching_node(np, its_device_id)) { |
| 135 | if (!of_device_is_available(np)) | ||
| 136 | continue; | ||
| 135 | if (!of_property_read_bool(np, "msi-controller")) | 137 | if (!of_property_read_bool(np, "msi-controller")) |
| 136 | continue; | 138 | continue; |
| 137 | 139 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c index 833a90fe33ae..8881a053c173 100644 --- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c | |||
| @@ -154,6 +154,8 @@ static void __init its_pmsi_of_init(void) | |||
| 154 | 154 | ||
| 155 | for (np = of_find_matching_node(NULL, its_device_id); np; | 155 | for (np = of_find_matching_node(NULL, its_device_id); np; |
| 156 | np = of_find_matching_node(np, its_device_id)) { | 156 | np = of_find_matching_node(np, its_device_id)) { |
| 157 | if (!of_device_is_available(np)) | ||
| 158 | continue; | ||
| 157 | if (!of_property_read_bool(np, "msi-controller")) | 159 | if (!of_property_read_bool(np, "msi-controller")) |
| 158 | continue; | 160 | continue; |
| 159 | 161 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 06f025fd5726..1d3056f53747 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
| @@ -3314,6 +3314,8 @@ static int __init its_of_probe(struct device_node *node) | |||
| 3314 | 3314 | ||
| 3315 | for (np = of_find_matching_node(node, its_device_id); np; | 3315 | for (np = of_find_matching_node(node, its_device_id); np; |
| 3316 | np = of_find_matching_node(np, its_device_id)) { | 3316 | np = of_find_matching_node(np, its_device_id)) { |
| 3317 | if (!of_device_is_available(np)) | ||
| 3318 | continue; | ||
| 3317 | if (!of_property_read_bool(np, "msi-controller")) { | 3319 | if (!of_property_read_bool(np, "msi-controller")) { |
| 3318 | pr_warn("%pOF: no msi-controller property, ITS ignored\n", | 3320 | pr_warn("%pOF: no msi-controller property, ITS ignored\n", |
| 3319 | np); | 3321 | np); |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index a57c0fbbd34a..d99cc07903ec 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
| @@ -673,7 +673,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) | |||
| 673 | MPIDR_TO_SGI_RS(cluster_id) | | 673 | MPIDR_TO_SGI_RS(cluster_id) | |
| 674 | tlist << ICC_SGI1R_TARGET_LIST_SHIFT); | 674 | tlist << ICC_SGI1R_TARGET_LIST_SHIFT); |
| 675 | 675 | ||
| 676 | pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); | 676 | pr_devel("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); |
| 677 | gic_write_sgi1r(val); | 677 | gic_write_sgi1r(val); |
| 678 | } | 678 | } |
| 679 | 679 | ||
| @@ -688,7 +688,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
| 688 | * Ensure that stores to Normal memory are visible to the | 688 | * Ensure that stores to Normal memory are visible to the |
| 689 | * other CPUs before issuing the IPI. | 689 | * other CPUs before issuing the IPI. |
| 690 | */ | 690 | */ |
| 691 | smp_wmb(); | 691 | wmb(); |
| 692 | 692 | ||
| 693 | for_each_cpu(cpu, mask) { | 693 | for_each_cpu(cpu, mask) { |
| 694 | u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID(cpu_logical_map(cpu)); | 694 | u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID(cpu_logical_map(cpu)); |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index ef92a4d2038e..d32268cc1174 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
| @@ -424,8 +424,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
| 424 | spin_lock_irqsave(&gic_lock, flags); | 424 | spin_lock_irqsave(&gic_lock, flags); |
| 425 | write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); | 425 | write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); |
| 426 | write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); | 426 | write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); |
| 427 | gic_clear_pcpu_masks(intr); | ||
| 428 | set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); | ||
| 429 | irq_data_update_effective_affinity(data, cpumask_of(cpu)); | 427 | irq_data_update_effective_affinity(data, cpumask_of(cpu)); |
| 430 | spin_unlock_irqrestore(&gic_lock, flags); | 428 | spin_unlock_irqrestore(&gic_lock, flags); |
| 431 | 429 | ||
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 62f541f968f6..07074820a167 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
| @@ -375,6 +375,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
| 375 | dev->ofdev.dev.of_node = np; | 375 | dev->ofdev.dev.of_node = np; |
| 376 | dev->ofdev.archdata.dma_mask = 0xffffffffUL; | 376 | dev->ofdev.archdata.dma_mask = 0xffffffffUL; |
| 377 | dev->ofdev.dev.dma_mask = &dev->ofdev.archdata.dma_mask; | 377 | dev->ofdev.dev.dma_mask = &dev->ofdev.archdata.dma_mask; |
| 378 | dev->ofdev.dev.coherent_dma_mask = dev->ofdev.archdata.dma_mask; | ||
| 378 | dev->ofdev.dev.parent = parent; | 379 | dev->ofdev.dev.parent = parent; |
| 379 | dev->ofdev.dev.bus = &macio_bus_type; | 380 | dev->ofdev.dev.bus = &macio_bus_type; |
| 380 | dev->ofdev.dev.release = macio_release_dev; | 381 | dev->ofdev.dev.release = macio_release_dev; |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 1a46b41dac70..6422846b546e 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
| @@ -659,11 +659,11 @@ static void do_bio_hook(struct search *s, struct bio *orig_bio) | |||
| 659 | static void search_free(struct closure *cl) | 659 | static void search_free(struct closure *cl) |
| 660 | { | 660 | { |
| 661 | struct search *s = container_of(cl, struct search, cl); | 661 | struct search *s = container_of(cl, struct search, cl); |
| 662 | bio_complete(s); | ||
| 663 | 662 | ||
| 664 | if (s->iop.bio) | 663 | if (s->iop.bio) |
| 665 | bio_put(s->iop.bio); | 664 | bio_put(s->iop.bio); |
| 666 | 665 | ||
| 666 | bio_complete(s); | ||
| 667 | closure_debug_destroy(cl); | 667 | closure_debug_destroy(cl); |
| 668 | mempool_free(s, s->d->c->search); | 668 | mempool_free(s, s->d->c->search); |
| 669 | } | 669 | } |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 312895788036..4d1d8dfb2d2a 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
| @@ -1274,7 +1274,7 @@ static int flash_devs_run(struct cache_set *c) | |||
| 1274 | struct uuid_entry *u; | 1274 | struct uuid_entry *u; |
| 1275 | 1275 | ||
| 1276 | for (u = c->uuids; | 1276 | for (u = c->uuids; |
| 1277 | u < c->uuids + c->devices_max_used && !ret; | 1277 | u < c->uuids + c->nr_uuids && !ret; |
| 1278 | u++) | 1278 | u++) |
| 1279 | if (UUID_FLASH_ONLY(u)) | 1279 | if (UUID_FLASH_ONLY(u)) |
| 1280 | ret = flash_dev_run(c, u); | 1280 | ret = flash_dev_run(c, u); |
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 3e5eabdae8d9..772d02922529 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
| @@ -548,12 +548,6 @@ int mei_cldev_disable(struct mei_cl_device *cldev) | |||
| 548 | goto out; | 548 | goto out; |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | if (bus->dev_state == MEI_DEV_POWER_DOWN) { | ||
| 552 | dev_dbg(bus->dev, "Device is powering down, don't bother with disconnection\n"); | ||
| 553 | err = 0; | ||
| 554 | goto out; | ||
| 555 | } | ||
| 556 | |||
| 557 | err = mei_cl_disconnect(cl); | 551 | err = mei_cl_disconnect(cl); |
| 558 | if (err < 0) | 552 | if (err < 0) |
| 559 | dev_err(bus->dev, "Could not disconnect from the ME client\n"); | 553 | dev_err(bus->dev, "Could not disconnect from the ME client\n"); |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index be64969d986a..7e60c1817c31 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
| @@ -945,6 +945,12 @@ int mei_cl_disconnect(struct mei_cl *cl) | |||
| 945 | return 0; | 945 | return 0; |
| 946 | } | 946 | } |
| 947 | 947 | ||
| 948 | if (dev->dev_state == MEI_DEV_POWER_DOWN) { | ||
| 949 | cl_dbg(dev, cl, "Device is powering down, don't bother with disconnection\n"); | ||
| 950 | mei_cl_set_disconnected(cl); | ||
| 951 | return 0; | ||
| 952 | } | ||
| 953 | |||
| 948 | rets = pm_runtime_get(dev->dev); | 954 | rets = pm_runtime_get(dev->dev); |
| 949 | if (rets < 0 && rets != -EINPROGRESS) { | 955 | if (rets < 0 && rets != -EINPROGRESS) { |
| 950 | pm_runtime_put_noidle(dev->dev); | 956 | pm_runtime_put_noidle(dev->dev); |
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 0ccccbaf530d..e4b10b2d1a08 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h | |||
| @@ -132,6 +132,11 @@ | |||
| 132 | #define MEI_DEV_ID_KBP 0xA2BA /* Kaby Point */ | 132 | #define MEI_DEV_ID_KBP 0xA2BA /* Kaby Point */ |
| 133 | #define MEI_DEV_ID_KBP_2 0xA2BB /* Kaby Point 2 */ | 133 | #define MEI_DEV_ID_KBP_2 0xA2BB /* Kaby Point 2 */ |
| 134 | 134 | ||
| 135 | #define MEI_DEV_ID_CNP_LP 0x9DE0 /* Cannon Point LP */ | ||
| 136 | #define MEI_DEV_ID_CNP_LP_4 0x9DE4 /* Cannon Point LP 4 (iTouch) */ | ||
| 137 | #define MEI_DEV_ID_CNP_H 0xA360 /* Cannon Point H */ | ||
| 138 | #define MEI_DEV_ID_CNP_H_4 0xA364 /* Cannon Point H 4 (iTouch) */ | ||
| 139 | |||
| 135 | /* | 140 | /* |
| 136 | * MEI HW Section | 141 | * MEI HW Section |
| 137 | */ | 142 | */ |
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 4a0ccda4d04b..ea4e152270a3 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c | |||
| @@ -98,6 +98,11 @@ static const struct pci_device_id mei_me_pci_tbl[] = { | |||
| 98 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)}, | 98 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)}, |
| 99 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)}, | 99 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)}, |
| 100 | 100 | ||
| 101 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH8_CFG)}, | ||
| 102 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_4, MEI_ME_PCH8_CFG)}, | ||
| 103 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH8_CFG)}, | ||
| 104 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)}, | ||
| 105 | |||
| 101 | /* required last entry */ | 106 | /* required last entry */ |
| 102 | {0, } | 107 | {0, } |
| 103 | }; | 108 | }; |
diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c index 229dc18f0581..768972af8b85 100644 --- a/drivers/mmc/host/bcm2835.c +++ b/drivers/mmc/host/bcm2835.c | |||
| @@ -1265,7 +1265,8 @@ static int bcm2835_add_host(struct bcm2835_host *host) | |||
| 1265 | char pio_limit_string[20]; | 1265 | char pio_limit_string[20]; |
| 1266 | int ret; | 1266 | int ret; |
| 1267 | 1267 | ||
| 1268 | mmc->f_max = host->max_clk; | 1268 | if (!mmc->f_max || mmc->f_max > host->max_clk) |
| 1269 | mmc->f_max = host->max_clk; | ||
| 1269 | mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; | 1270 | mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; |
| 1270 | 1271 | ||
| 1271 | mmc->max_busy_timeout = ~0 / (mmc->f_max / 1000); | 1272 | mmc->max_busy_timeout = ~0 / (mmc->f_max / 1000); |
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 22438ebfe4e6..4f972b879fe6 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
| @@ -717,22 +717,6 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, | |||
| 717 | static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) | 717 | static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) |
| 718 | { | 718 | { |
| 719 | struct meson_host *host = mmc_priv(mmc); | 719 | struct meson_host *host = mmc_priv(mmc); |
| 720 | int ret; | ||
| 721 | |||
| 722 | /* | ||
| 723 | * If this is the initial tuning, try to get a sane Rx starting | ||
| 724 | * phase before doing the actual tuning. | ||
| 725 | */ | ||
| 726 | if (!mmc->doing_retune) { | ||
| 727 | ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); | ||
| 728 | |||
| 729 | if (ret) | ||
| 730 | return ret; | ||
| 731 | } | ||
| 732 | |||
| 733 | ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); | ||
| 734 | if (ret) | ||
| 735 | return ret; | ||
| 736 | 720 | ||
| 737 | return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); | 721 | return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); |
| 738 | } | 722 | } |
| @@ -763,9 +747,8 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 763 | if (!IS_ERR(mmc->supply.vmmc)) | 747 | if (!IS_ERR(mmc->supply.vmmc)) |
| 764 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); | 748 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); |
| 765 | 749 | ||
| 766 | /* Reset phases */ | 750 | /* Reset rx phase */ |
| 767 | clk_set_phase(host->rx_clk, 0); | 751 | clk_set_phase(host->rx_clk, 0); |
| 768 | clk_set_phase(host->tx_clk, 270); | ||
| 769 | 752 | ||
| 770 | break; | 753 | break; |
| 771 | 754 | ||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index e6b8c59f2c0d..736ac887303c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
| @@ -328,7 +328,7 @@ config MTD_NAND_MARVELL | |||
| 328 | tristate "NAND controller support on Marvell boards" | 328 | tristate "NAND controller support on Marvell boards" |
| 329 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ | 329 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ |
| 330 | COMPILE_TEST | 330 | COMPILE_TEST |
| 331 | depends on HAS_IOMEM | 331 | depends on HAS_IOMEM && HAS_DMA |
| 332 | help | 332 | help |
| 333 | This enables the NAND flash controller driver for Marvell boards, | 333 | This enables the NAND flash controller driver for Marvell boards, |
| 334 | including: | 334 | including: |
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 80d31a58e558..f367144f3c6f 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c | |||
| @@ -752,10 +752,8 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
| 752 | if (mtd->oobsize > 64) | 752 | if (mtd->oobsize > 64) |
| 753 | mtd->oobsize = 64; | 753 | mtd->oobsize = 64; |
| 754 | 754 | ||
| 755 | /* | 755 | /* Use default large page ECC layout defined in NAND core */ |
| 756 | * mtd->ecclayout is not specified here because we're using the | 756 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); |
| 757 | * default large page ECC layout defined in NAND core. | ||
| 758 | */ | ||
| 759 | if (chip->ecc.strength == 32) { | 757 | if (chip->ecc.strength == 32) { |
| 760 | nfc->ecc_mode = ECC_60_BYTE; | 758 | nfc->ecc_mode = ECC_60_BYTE; |
| 761 | chip->ecc.bytes = 60; | 759 | chip->ecc.bytes = 60; |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a77ee2f8fb8d..c1841db1b500 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -820,7 +820,7 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) | |||
| 820 | 820 | ||
| 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); | 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); |
| 822 | 822 | ||
| 823 | udelay(10); | 823 | usleep_range(10, 20); |
| 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; | 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; |
| 825 | } | 825 | } |
| 826 | 826 | ||
| @@ -922,8 +922,8 @@ static int tg3_ape_send_event(struct tg3 *tp, u32 event) | |||
| 922 | if (!(apedata & APE_FW_STATUS_READY)) | 922 | if (!(apedata & APE_FW_STATUS_READY)) |
| 923 | return -EAGAIN; | 923 | return -EAGAIN; |
| 924 | 924 | ||
| 925 | /* Wait for up to 1 millisecond for APE to service previous event. */ | 925 | /* Wait for up to 20 millisecond for APE to service previous event. */ |
| 926 | err = tg3_ape_event_lock(tp, 1000); | 926 | err = tg3_ape_event_lock(tp, 20000); |
| 927 | if (err) | 927 | if (err) |
| 928 | return err; | 928 | return err; |
| 929 | 929 | ||
| @@ -946,6 +946,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 946 | 946 | ||
| 947 | switch (kind) { | 947 | switch (kind) { |
| 948 | case RESET_KIND_INIT: | 948 | case RESET_KIND_INIT: |
| 949 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); | ||
| 949 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, | 950 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, |
| 950 | APE_HOST_SEG_SIG_MAGIC); | 951 | APE_HOST_SEG_SIG_MAGIC); |
| 951 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, | 952 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, |
| @@ -962,13 +963,6 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 962 | event = APE_EVENT_STATUS_STATE_START; | 963 | event = APE_EVENT_STATUS_STATE_START; |
| 963 | break; | 964 | break; |
| 964 | case RESET_KIND_SHUTDOWN: | 965 | case RESET_KIND_SHUTDOWN: |
| 965 | /* With the interface we are currently using, | ||
| 966 | * APE does not track driver state. Wiping | ||
| 967 | * out the HOST SEGMENT SIGNATURE forces | ||
| 968 | * the APE to assume OS absent status. | ||
| 969 | */ | ||
| 970 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); | ||
| 971 | |||
| 972 | if (device_may_wakeup(&tp->pdev->dev) && | 966 | if (device_may_wakeup(&tp->pdev->dev) && |
| 973 | tg3_flag(tp, WOL_ENABLE)) { | 967 | tg3_flag(tp, WOL_ENABLE)) { |
| 974 | tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, | 968 | tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, |
| @@ -990,6 +984,18 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 990 | tg3_ape_send_event(tp, event); | 984 | tg3_ape_send_event(tp, event); |
| 991 | } | 985 | } |
| 992 | 986 | ||
| 987 | static void tg3_send_ape_heartbeat(struct tg3 *tp, | ||
| 988 | unsigned long interval) | ||
| 989 | { | ||
| 990 | /* Check if hb interval has exceeded */ | ||
| 991 | if (!tg3_flag(tp, ENABLE_APE) || | ||
| 992 | time_before(jiffies, tp->ape_hb_jiffies + interval)) | ||
| 993 | return; | ||
| 994 | |||
| 995 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); | ||
| 996 | tp->ape_hb_jiffies = jiffies; | ||
| 997 | } | ||
| 998 | |||
| 993 | static void tg3_disable_ints(struct tg3 *tp) | 999 | static void tg3_disable_ints(struct tg3 *tp) |
| 994 | { | 1000 | { |
| 995 | int i; | 1001 | int i; |
| @@ -7262,6 +7268,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) | |||
| 7262 | } | 7268 | } |
| 7263 | } | 7269 | } |
| 7264 | 7270 | ||
| 7271 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); | ||
| 7265 | return work_done; | 7272 | return work_done; |
| 7266 | 7273 | ||
| 7267 | tx_recovery: | 7274 | tx_recovery: |
| @@ -7344,6 +7351,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
| 7344 | } | 7351 | } |
| 7345 | } | 7352 | } |
| 7346 | 7353 | ||
| 7354 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); | ||
| 7347 | return work_done; | 7355 | return work_done; |
| 7348 | 7356 | ||
| 7349 | tx_recovery: | 7357 | tx_recovery: |
| @@ -10732,7 +10740,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) | |||
| 10732 | if (tg3_flag(tp, ENABLE_APE)) | 10740 | if (tg3_flag(tp, ENABLE_APE)) |
| 10733 | /* Write our heartbeat update interval to APE. */ | 10741 | /* Write our heartbeat update interval to APE. */ |
| 10734 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, | 10742 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, |
| 10735 | APE_HOST_HEARTBEAT_INT_DISABLE); | 10743 | APE_HOST_HEARTBEAT_INT_5SEC); |
| 10736 | 10744 | ||
| 10737 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); | 10745 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); |
| 10738 | 10746 | ||
| @@ -11077,6 +11085,9 @@ static void tg3_timer(struct timer_list *t) | |||
| 11077 | tp->asf_counter = tp->asf_multiplier; | 11085 | tp->asf_counter = tp->asf_multiplier; |
| 11078 | } | 11086 | } |
| 11079 | 11087 | ||
| 11088 | /* Update the APE heartbeat every 5 seconds.*/ | ||
| 11089 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL); | ||
| 11090 | |||
| 11080 | spin_unlock(&tp->lock); | 11091 | spin_unlock(&tp->lock); |
| 11081 | 11092 | ||
| 11082 | restart_timer: | 11093 | restart_timer: |
| @@ -16653,6 +16664,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) | |||
| 16653 | pci_state_reg); | 16664 | pci_state_reg); |
| 16654 | 16665 | ||
| 16655 | tg3_ape_lock_init(tp); | 16666 | tg3_ape_lock_init(tp); |
| 16667 | tp->ape_hb_interval = | ||
| 16668 | msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC); | ||
| 16656 | } | 16669 | } |
| 16657 | 16670 | ||
| 16658 | /* Set up tp->grc_local_ctrl before calling | 16671 | /* Set up tp->grc_local_ctrl before calling |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 47f51cc0566d..1d61aa3efda1 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -2508,6 +2508,7 @@ | |||
| 2508 | #define TG3_APE_LOCK_PHY3 5 | 2508 | #define TG3_APE_LOCK_PHY3 5 |
| 2509 | #define TG3_APE_LOCK_GPIO 7 | 2509 | #define TG3_APE_LOCK_GPIO 7 |
| 2510 | 2510 | ||
| 2511 | #define TG3_APE_HB_INTERVAL (tp->ape_hb_interval) | ||
| 2511 | #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 | 2512 | #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 |
| 2512 | 2513 | ||
| 2513 | 2514 | ||
| @@ -3423,6 +3424,10 @@ struct tg3 { | |||
| 3423 | struct device *hwmon_dev; | 3424 | struct device *hwmon_dev; |
| 3424 | bool link_up; | 3425 | bool link_up; |
| 3425 | bool pcierr_recovery; | 3426 | bool pcierr_recovery; |
| 3427 | |||
| 3428 | u32 ape_hb; | ||
| 3429 | unsigned long ape_hb_interval; | ||
| 3430 | unsigned long ape_hb_jiffies; | ||
| 3426 | }; | 3431 | }; |
| 3427 | 3432 | ||
| 3428 | /* Accessor macros for chip and asic attributes | 3433 | /* Accessor macros for chip and asic attributes |
diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.c b/drivers/net/ethernet/cavium/common/cavium_ptp.c index c87c9c684a33..d59497a7bdce 100644 --- a/drivers/net/ethernet/cavium/common/cavium_ptp.c +++ b/drivers/net/ethernet/cavium/common/cavium_ptp.c | |||
| @@ -75,6 +75,8 @@ EXPORT_SYMBOL(cavium_ptp_get); | |||
| 75 | 75 | ||
| 76 | void cavium_ptp_put(struct cavium_ptp *ptp) | 76 | void cavium_ptp_put(struct cavium_ptp *ptp) |
| 77 | { | 77 | { |
| 78 | if (!ptp) | ||
| 79 | return; | ||
| 78 | pci_dev_put(ptp->pdev); | 80 | pci_dev_put(ptp->pdev); |
| 79 | } | 81 | } |
| 80 | EXPORT_SYMBOL(cavium_ptp_put); | 82 | EXPORT_SYMBOL(cavium_ptp_put); |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index b68cde9f17d2..7d9c5ffbd041 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
| @@ -67,11 +67,6 @@ module_param(cpi_alg, int, S_IRUGO); | |||
| 67 | MODULE_PARM_DESC(cpi_alg, | 67 | MODULE_PARM_DESC(cpi_alg, |
| 68 | "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)"); | 68 | "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)"); |
| 69 | 69 | ||
| 70 | struct nicvf_xdp_tx { | ||
| 71 | u64 dma_addr; | ||
| 72 | u8 qidx; | ||
| 73 | }; | ||
| 74 | |||
| 75 | static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx) | 70 | static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx) |
| 76 | { | 71 | { |
| 77 | if (nic->sqs_mode) | 72 | if (nic->sqs_mode) |
| @@ -507,29 +502,14 @@ static int nicvf_init_resources(struct nicvf *nic) | |||
| 507 | return 0; | 502 | return 0; |
| 508 | } | 503 | } |
| 509 | 504 | ||
| 510 | static void nicvf_unmap_page(struct nicvf *nic, struct page *page, u64 dma_addr) | ||
| 511 | { | ||
| 512 | /* Check if it's a recycled page, if not unmap the DMA mapping. | ||
| 513 | * Recycled page holds an extra reference. | ||
| 514 | */ | ||
| 515 | if (page_ref_count(page) == 1) { | ||
| 516 | dma_addr &= PAGE_MASK; | ||
| 517 | dma_unmap_page_attrs(&nic->pdev->dev, dma_addr, | ||
| 518 | RCV_FRAG_LEN + XDP_HEADROOM, | ||
| 519 | DMA_FROM_DEVICE, | ||
| 520 | DMA_ATTR_SKIP_CPU_SYNC); | ||
| 521 | } | ||
| 522 | } | ||
| 523 | |||
| 524 | static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | 505 | static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, |
| 525 | struct cqe_rx_t *cqe_rx, struct snd_queue *sq, | 506 | struct cqe_rx_t *cqe_rx, struct snd_queue *sq, |
| 526 | struct rcv_queue *rq, struct sk_buff **skb) | 507 | struct rcv_queue *rq, struct sk_buff **skb) |
| 527 | { | 508 | { |
| 528 | struct xdp_buff xdp; | 509 | struct xdp_buff xdp; |
| 529 | struct page *page; | 510 | struct page *page; |
| 530 | struct nicvf_xdp_tx *xdp_tx = NULL; | ||
| 531 | u32 action; | 511 | u32 action; |
| 532 | u16 len, err, offset = 0; | 512 | u16 len, offset = 0; |
| 533 | u64 dma_addr, cpu_addr; | 513 | u64 dma_addr, cpu_addr; |
| 534 | void *orig_data; | 514 | void *orig_data; |
| 535 | 515 | ||
| @@ -543,7 +523,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | |||
| 543 | cpu_addr = (u64)phys_to_virt(cpu_addr); | 523 | cpu_addr = (u64)phys_to_virt(cpu_addr); |
| 544 | page = virt_to_page((void *)cpu_addr); | 524 | page = virt_to_page((void *)cpu_addr); |
| 545 | 525 | ||
| 546 | xdp.data_hard_start = page_address(page) + RCV_BUF_HEADROOM; | 526 | xdp.data_hard_start = page_address(page); |
| 547 | xdp.data = (void *)cpu_addr; | 527 | xdp.data = (void *)cpu_addr; |
| 548 | xdp_set_data_meta_invalid(&xdp); | 528 | xdp_set_data_meta_invalid(&xdp); |
| 549 | xdp.data_end = xdp.data + len; | 529 | xdp.data_end = xdp.data + len; |
| @@ -563,7 +543,18 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | |||
| 563 | 543 | ||
| 564 | switch (action) { | 544 | switch (action) { |
| 565 | case XDP_PASS: | 545 | case XDP_PASS: |
| 566 | nicvf_unmap_page(nic, page, dma_addr); | 546 | /* Check if it's a recycled page, if not |
| 547 | * unmap the DMA mapping. | ||
| 548 | * | ||
| 549 | * Recycled page holds an extra reference. | ||
| 550 | */ | ||
| 551 | if (page_ref_count(page) == 1) { | ||
| 552 | dma_addr &= PAGE_MASK; | ||
| 553 | dma_unmap_page_attrs(&nic->pdev->dev, dma_addr, | ||
| 554 | RCV_FRAG_LEN + XDP_PACKET_HEADROOM, | ||
| 555 | DMA_FROM_DEVICE, | ||
| 556 | DMA_ATTR_SKIP_CPU_SYNC); | ||
| 557 | } | ||
| 567 | 558 | ||
| 568 | /* Build SKB and pass on packet to network stack */ | 559 | /* Build SKB and pass on packet to network stack */ |
| 569 | *skb = build_skb(xdp.data, | 560 | *skb = build_skb(xdp.data, |
| @@ -576,20 +567,6 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | |||
| 576 | case XDP_TX: | 567 | case XDP_TX: |
| 577 | nicvf_xdp_sq_append_pkt(nic, sq, (u64)xdp.data, dma_addr, len); | 568 | nicvf_xdp_sq_append_pkt(nic, sq, (u64)xdp.data, dma_addr, len); |
| 578 | return true; | 569 | return true; |
| 579 | case XDP_REDIRECT: | ||
| 580 | /* Save DMA address for use while transmitting */ | ||
| 581 | xdp_tx = (struct nicvf_xdp_tx *)page_address(page); | ||
| 582 | xdp_tx->dma_addr = dma_addr; | ||
| 583 | xdp_tx->qidx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx); | ||
| 584 | |||
| 585 | err = xdp_do_redirect(nic->pnicvf->netdev, &xdp, prog); | ||
| 586 | if (!err) | ||
| 587 | return true; | ||
| 588 | |||
| 589 | /* Free the page on error */ | ||
| 590 | nicvf_unmap_page(nic, page, dma_addr); | ||
| 591 | put_page(page); | ||
| 592 | break; | ||
| 593 | default: | 570 | default: |
| 594 | bpf_warn_invalid_xdp_action(action); | 571 | bpf_warn_invalid_xdp_action(action); |
| 595 | /* fall through */ | 572 | /* fall through */ |
| @@ -597,7 +574,18 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | |||
| 597 | trace_xdp_exception(nic->netdev, prog, action); | 574 | trace_xdp_exception(nic->netdev, prog, action); |
| 598 | /* fall through */ | 575 | /* fall through */ |
| 599 | case XDP_DROP: | 576 | case XDP_DROP: |
| 600 | nicvf_unmap_page(nic, page, dma_addr); | 577 | /* Check if it's a recycled page, if not |
| 578 | * unmap the DMA mapping. | ||
| 579 | * | ||
| 580 | * Recycled page holds an extra reference. | ||
| 581 | */ | ||
| 582 | if (page_ref_count(page) == 1) { | ||
| 583 | dma_addr &= PAGE_MASK; | ||
| 584 | dma_unmap_page_attrs(&nic->pdev->dev, dma_addr, | ||
| 585 | RCV_FRAG_LEN + XDP_PACKET_HEADROOM, | ||
| 586 | DMA_FROM_DEVICE, | ||
| 587 | DMA_ATTR_SKIP_CPU_SYNC); | ||
| 588 | } | ||
| 601 | put_page(page); | 589 | put_page(page); |
| 602 | return true; | 590 | return true; |
| 603 | } | 591 | } |
| @@ -1864,50 +1852,6 @@ static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) | |||
| 1864 | } | 1852 | } |
| 1865 | } | 1853 | } |
| 1866 | 1854 | ||
| 1867 | static int nicvf_xdp_xmit(struct net_device *netdev, struct xdp_buff *xdp) | ||
| 1868 | { | ||
| 1869 | struct nicvf *nic = netdev_priv(netdev); | ||
| 1870 | struct nicvf *snic = nic; | ||
| 1871 | struct nicvf_xdp_tx *xdp_tx; | ||
| 1872 | struct snd_queue *sq; | ||
| 1873 | struct page *page; | ||
| 1874 | int err, qidx; | ||
| 1875 | |||
| 1876 | if (!netif_running(netdev) || !nic->xdp_prog) | ||
| 1877 | return -EINVAL; | ||
| 1878 | |||
| 1879 | page = virt_to_page(xdp->data); | ||
| 1880 | xdp_tx = (struct nicvf_xdp_tx *)page_address(page); | ||
| 1881 | qidx = xdp_tx->qidx; | ||
| 1882 | |||
| 1883 | if (xdp_tx->qidx >= nic->xdp_tx_queues) | ||
| 1884 | return -EINVAL; | ||
| 1885 | |||
| 1886 | /* Get secondary Qset's info */ | ||
| 1887 | if (xdp_tx->qidx >= MAX_SND_QUEUES_PER_QS) { | ||
| 1888 | qidx = xdp_tx->qidx / MAX_SND_QUEUES_PER_QS; | ||
| 1889 | snic = (struct nicvf *)nic->snicvf[qidx - 1]; | ||
| 1890 | if (!snic) | ||
| 1891 | return -EINVAL; | ||
| 1892 | qidx = xdp_tx->qidx % MAX_SND_QUEUES_PER_QS; | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | sq = &snic->qs->sq[qidx]; | ||
| 1896 | err = nicvf_xdp_sq_append_pkt(snic, sq, (u64)xdp->data, | ||
| 1897 | xdp_tx->dma_addr, | ||
| 1898 | xdp->data_end - xdp->data); | ||
| 1899 | if (err) | ||
| 1900 | return -ENOMEM; | ||
| 1901 | |||
| 1902 | nicvf_xdp_sq_doorbell(snic, sq, qidx); | ||
| 1903 | return 0; | ||
| 1904 | } | ||
| 1905 | |||
| 1906 | static void nicvf_xdp_flush(struct net_device *dev) | ||
| 1907 | { | ||
| 1908 | return; | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) | 1855 | static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) |
| 1912 | { | 1856 | { |
| 1913 | struct hwtstamp_config config; | 1857 | struct hwtstamp_config config; |
| @@ -1986,8 +1930,6 @@ static const struct net_device_ops nicvf_netdev_ops = { | |||
| 1986 | .ndo_fix_features = nicvf_fix_features, | 1930 | .ndo_fix_features = nicvf_fix_features, |
| 1987 | .ndo_set_features = nicvf_set_features, | 1931 | .ndo_set_features = nicvf_set_features, |
| 1988 | .ndo_bpf = nicvf_xdp, | 1932 | .ndo_bpf = nicvf_xdp, |
| 1989 | .ndo_xdp_xmit = nicvf_xdp_xmit, | ||
| 1990 | .ndo_xdp_flush = nicvf_xdp_flush, | ||
| 1991 | .ndo_do_ioctl = nicvf_ioctl, | 1933 | .ndo_do_ioctl = nicvf_ioctl, |
| 1992 | }; | 1934 | }; |
| 1993 | 1935 | ||
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 3eae9ff9b53a..d42704d07484 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
| @@ -204,7 +204,7 @@ static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, struct rbdr *rbdr, | |||
| 204 | 204 | ||
| 205 | /* Reserve space for header modifications by BPF program */ | 205 | /* Reserve space for header modifications by BPF program */ |
| 206 | if (rbdr->is_xdp) | 206 | if (rbdr->is_xdp) |
| 207 | buf_len += XDP_HEADROOM; | 207 | buf_len += XDP_PACKET_HEADROOM; |
| 208 | 208 | ||
| 209 | /* Check if it's recycled */ | 209 | /* Check if it's recycled */ |
| 210 | if (pgcache) | 210 | if (pgcache) |
| @@ -224,9 +224,8 @@ ret: | |||
| 224 | nic->rb_page = NULL; | 224 | nic->rb_page = NULL; |
| 225 | return -ENOMEM; | 225 | return -ENOMEM; |
| 226 | } | 226 | } |
| 227 | |||
| 228 | if (pgcache) | 227 | if (pgcache) |
| 229 | pgcache->dma_addr = *rbuf + XDP_HEADROOM; | 228 | pgcache->dma_addr = *rbuf + XDP_PACKET_HEADROOM; |
| 230 | nic->rb_page_offset += buf_len; | 229 | nic->rb_page_offset += buf_len; |
| 231 | } | 230 | } |
| 232 | 231 | ||
| @@ -1244,7 +1243,7 @@ int nicvf_xdp_sq_append_pkt(struct nicvf *nic, struct snd_queue *sq, | |||
| 1244 | int qentry; | 1243 | int qentry; |
| 1245 | 1244 | ||
| 1246 | if (subdesc_cnt > sq->xdp_free_cnt) | 1245 | if (subdesc_cnt > sq->xdp_free_cnt) |
| 1247 | return -1; | 1246 | return 0; |
| 1248 | 1247 | ||
| 1249 | qentry = nicvf_get_sq_desc(sq, subdesc_cnt); | 1248 | qentry = nicvf_get_sq_desc(sq, subdesc_cnt); |
| 1250 | 1249 | ||
| @@ -1255,7 +1254,7 @@ int nicvf_xdp_sq_append_pkt(struct nicvf *nic, struct snd_queue *sq, | |||
| 1255 | 1254 | ||
| 1256 | sq->xdp_desc_cnt += subdesc_cnt; | 1255 | sq->xdp_desc_cnt += subdesc_cnt; |
| 1257 | 1256 | ||
| 1258 | return 0; | 1257 | return 1; |
| 1259 | } | 1258 | } |
| 1260 | 1259 | ||
| 1261 | /* Calculate no of SQ subdescriptors needed to transmit all | 1260 | /* Calculate no of SQ subdescriptors needed to transmit all |
| @@ -1656,7 +1655,7 @@ static void nicvf_unmap_rcv_buffer(struct nicvf *nic, u64 dma_addr, | |||
| 1656 | if (page_ref_count(page) != 1) | 1655 | if (page_ref_count(page) != 1) |
| 1657 | return; | 1656 | return; |
| 1658 | 1657 | ||
| 1659 | len += XDP_HEADROOM; | 1658 | len += XDP_PACKET_HEADROOM; |
| 1660 | /* Receive buffers in XDP mode are mapped from page start */ | 1659 | /* Receive buffers in XDP mode are mapped from page start */ |
| 1661 | dma_addr &= PAGE_MASK; | 1660 | dma_addr &= PAGE_MASK; |
| 1662 | } | 1661 | } |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h index ce1eed7a6d63..5e9a03cf1b4d 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
| 13 | #include <linux/iommu.h> | 13 | #include <linux/iommu.h> |
| 14 | #include <linux/bpf.h> | ||
| 15 | #include <net/xdp.h> | 14 | #include <net/xdp.h> |
| 16 | #include "q_struct.h" | 15 | #include "q_struct.h" |
| 17 | 16 | ||
| @@ -94,9 +93,6 @@ | |||
| 94 | #define RCV_FRAG_LEN (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \ | 93 | #define RCV_FRAG_LEN (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \ |
| 95 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | 94 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) |
| 96 | 95 | ||
| 97 | #define RCV_BUF_HEADROOM 128 /* To store dma address for XDP redirect */ | ||
| 98 | #define XDP_HEADROOM (XDP_PACKET_HEADROOM + RCV_BUF_HEADROOM) | ||
| 99 | |||
| 100 | #define MAX_CQES_FOR_TX ((SND_QUEUE_LEN / MIN_SQ_DESC_PER_PKT_XMIT) * \ | 96 | #define MAX_CQES_FOR_TX ((SND_QUEUE_LEN / MIN_SQ_DESC_PER_PKT_XMIT) * \ |
| 101 | MAX_CQE_PER_PKT_XMIT) | 97 | MAX_CQE_PER_PKT_XMIT) |
| 102 | 98 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c index 557fd8bfd54e..00a1d2d13169 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c | |||
| @@ -472,7 +472,7 @@ int cudbg_collect_cim_la(struct cudbg_init *pdbg_init, | |||
| 472 | 472 | ||
| 473 | if (is_t6(padap->params.chip)) { | 473 | if (is_t6(padap->params.chip)) { |
| 474 | size = padap->params.cim_la_size / 10 + 1; | 474 | size = padap->params.cim_la_size / 10 + 1; |
| 475 | size *= 11 * sizeof(u32); | 475 | size *= 10 * sizeof(u32); |
| 476 | } else { | 476 | } else { |
| 477 | size = padap->params.cim_la_size / 8; | 477 | size = padap->params.cim_la_size / 8; |
| 478 | size *= 8 * sizeof(u32); | 478 | size *= 8 * sizeof(u32); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c index 30485f9a598f..143686c60234 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c | |||
| @@ -102,7 +102,7 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity) | |||
| 102 | case CUDBG_CIM_LA: | 102 | case CUDBG_CIM_LA: |
| 103 | if (is_t6(adap->params.chip)) { | 103 | if (is_t6(adap->params.chip)) { |
| 104 | len = adap->params.cim_la_size / 10 + 1; | 104 | len = adap->params.cim_la_size / 10 + 1; |
| 105 | len *= 11 * sizeof(u32); | 105 | len *= 10 * sizeof(u32); |
| 106 | } else { | 106 | } else { |
| 107 | len = adap->params.cim_la_size / 8; | 107 | len = adap->params.cim_la_size / 8; |
| 108 | len *= 8 * sizeof(u32); | 108 | len *= 8 * sizeof(u32); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 56bc626ef006..7b452e85de2a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -4982,9 +4982,10 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) | |||
| 4982 | 4982 | ||
| 4983 | pcie_fw = readl(adap->regs + PCIE_FW_A); | 4983 | pcie_fw = readl(adap->regs + PCIE_FW_A); |
| 4984 | /* Check if cxgb4 is the MASTER and fw is initialized */ | 4984 | /* Check if cxgb4 is the MASTER and fw is initialized */ |
| 4985 | if (!(pcie_fw & PCIE_FW_INIT_F) || | 4985 | if (num_vfs && |
| 4986 | (!(pcie_fw & PCIE_FW_INIT_F) || | ||
| 4986 | !(pcie_fw & PCIE_FW_MASTER_VLD_F) || | 4987 | !(pcie_fw & PCIE_FW_MASTER_VLD_F) || |
| 4987 | PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF) { | 4988 | PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF)) { |
| 4988 | dev_warn(&pdev->dev, | 4989 | dev_warn(&pdev->dev, |
| 4989 | "cxgb4 driver needs to be MASTER to support SRIOV\n"); | 4990 | "cxgb4 driver needs to be MASTER to support SRIOV\n"); |
| 4990 | return -EOPNOTSUPP; | 4991 | return -EOPNOTSUPP; |
| @@ -5599,24 +5600,24 @@ static void remove_one(struct pci_dev *pdev) | |||
| 5599 | #if IS_ENABLED(CONFIG_IPV6) | 5600 | #if IS_ENABLED(CONFIG_IPV6) |
| 5600 | t4_cleanup_clip_tbl(adapter); | 5601 | t4_cleanup_clip_tbl(adapter); |
| 5601 | #endif | 5602 | #endif |
| 5602 | iounmap(adapter->regs); | ||
| 5603 | if (!is_t4(adapter->params.chip)) | 5603 | if (!is_t4(adapter->params.chip)) |
| 5604 | iounmap(adapter->bar2); | 5604 | iounmap(adapter->bar2); |
| 5605 | pci_disable_pcie_error_reporting(pdev); | ||
| 5606 | if ((adapter->flags & DEV_ENABLED)) { | ||
| 5607 | pci_disable_device(pdev); | ||
| 5608 | adapter->flags &= ~DEV_ENABLED; | ||
| 5609 | } | ||
| 5610 | pci_release_regions(pdev); | ||
| 5611 | kfree(adapter->mbox_log); | ||
| 5612 | synchronize_rcu(); | ||
| 5613 | kfree(adapter); | ||
| 5614 | } | 5605 | } |
| 5615 | #ifdef CONFIG_PCI_IOV | 5606 | #ifdef CONFIG_PCI_IOV |
| 5616 | else { | 5607 | else { |
| 5617 | cxgb4_iov_configure(adapter->pdev, 0); | 5608 | cxgb4_iov_configure(adapter->pdev, 0); |
| 5618 | } | 5609 | } |
| 5619 | #endif | 5610 | #endif |
| 5611 | iounmap(adapter->regs); | ||
| 5612 | pci_disable_pcie_error_reporting(pdev); | ||
| 5613 | if ((adapter->flags & DEV_ENABLED)) { | ||
| 5614 | pci_disable_device(pdev); | ||
| 5615 | adapter->flags &= ~DEV_ENABLED; | ||
| 5616 | } | ||
| 5617 | pci_release_regions(pdev); | ||
| 5618 | kfree(adapter->mbox_log); | ||
| 5619 | synchronize_rcu(); | ||
| 5620 | kfree(adapter); | ||
| 5620 | } | 5621 | } |
| 5621 | 5622 | ||
| 5622 | /* "Shutdown" quiesces the device, stopping Ingress Packet and Interrupt | 5623 | /* "Shutdown" quiesces the device, stopping Ingress Packet and Interrupt |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 047609ef0515..920bccd6bc40 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
| @@ -2637,7 +2637,6 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) | |||
| 2637 | } | 2637 | } |
| 2638 | 2638 | ||
| 2639 | #define EEPROM_STAT_ADDR 0x7bfc | 2639 | #define EEPROM_STAT_ADDR 0x7bfc |
| 2640 | #define VPD_SIZE 0x800 | ||
| 2641 | #define VPD_BASE 0x400 | 2640 | #define VPD_BASE 0x400 |
| 2642 | #define VPD_BASE_OLD 0 | 2641 | #define VPD_BASE_OLD 0 |
| 2643 | #define VPD_LEN 1024 | 2642 | #define VPD_LEN 1024 |
| @@ -2704,15 +2703,6 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
| 2704 | if (!vpd) | 2703 | if (!vpd) |
| 2705 | return -ENOMEM; | 2704 | return -ENOMEM; |
| 2706 | 2705 | ||
| 2707 | /* We have two VPD data structures stored in the adapter VPD area. | ||
| 2708 | * By default, Linux calculates the size of the VPD area by traversing | ||
| 2709 | * the first VPD area at offset 0x0, so we need to tell the OS what | ||
| 2710 | * our real VPD size is. | ||
| 2711 | */ | ||
| 2712 | ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE); | ||
| 2713 | if (ret < 0) | ||
| 2714 | goto out; | ||
| 2715 | |||
| 2716 | /* Card information normally starts at VPD_BASE but early cards had | 2706 | /* Card information normally starts at VPD_BASE but early cards had |
| 2717 | * it at 0. | 2707 | * it at 0. |
| 2718 | */ | 2708 | */ |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 27447260215d..996f47568f9e 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c | |||
| @@ -791,6 +791,18 @@ static int ibmvnic_login(struct net_device *netdev) | |||
| 791 | return 0; | 791 | return 0; |
| 792 | } | 792 | } |
| 793 | 793 | ||
| 794 | static void release_login_buffer(struct ibmvnic_adapter *adapter) | ||
| 795 | { | ||
| 796 | kfree(adapter->login_buf); | ||
| 797 | adapter->login_buf = NULL; | ||
| 798 | } | ||
| 799 | |||
| 800 | static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) | ||
| 801 | { | ||
| 802 | kfree(adapter->login_rsp_buf); | ||
| 803 | adapter->login_rsp_buf = NULL; | ||
| 804 | } | ||
| 805 | |||
| 794 | static void release_resources(struct ibmvnic_adapter *adapter) | 806 | static void release_resources(struct ibmvnic_adapter *adapter) |
| 795 | { | 807 | { |
| 796 | int i; | 808 | int i; |
| @@ -813,6 +825,10 @@ static void release_resources(struct ibmvnic_adapter *adapter) | |||
| 813 | } | 825 | } |
| 814 | } | 826 | } |
| 815 | } | 827 | } |
| 828 | kfree(adapter->napi); | ||
| 829 | adapter->napi = NULL; | ||
| 830 | |||
| 831 | release_login_rsp_buffer(adapter); | ||
| 816 | } | 832 | } |
| 817 | 833 | ||
| 818 | static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state) | 834 | static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state) |
| @@ -1057,6 +1073,35 @@ static int ibmvnic_open(struct net_device *netdev) | |||
| 1057 | return rc; | 1073 | return rc; |
| 1058 | } | 1074 | } |
| 1059 | 1075 | ||
| 1076 | static void clean_rx_pools(struct ibmvnic_adapter *adapter) | ||
| 1077 | { | ||
| 1078 | struct ibmvnic_rx_pool *rx_pool; | ||
| 1079 | u64 rx_entries; | ||
| 1080 | int rx_scrqs; | ||
| 1081 | int i, j; | ||
| 1082 | |||
| 1083 | if (!adapter->rx_pool) | ||
| 1084 | return; | ||
| 1085 | |||
| 1086 | rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); | ||
| 1087 | rx_entries = adapter->req_rx_add_entries_per_subcrq; | ||
| 1088 | |||
| 1089 | /* Free any remaining skbs in the rx buffer pools */ | ||
| 1090 | for (i = 0; i < rx_scrqs; i++) { | ||
| 1091 | rx_pool = &adapter->rx_pool[i]; | ||
| 1092 | if (!rx_pool) | ||
| 1093 | continue; | ||
| 1094 | |||
| 1095 | netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i); | ||
| 1096 | for (j = 0; j < rx_entries; j++) { | ||
| 1097 | if (rx_pool->rx_buff[j].skb) { | ||
| 1098 | dev_kfree_skb_any(rx_pool->rx_buff[j].skb); | ||
| 1099 | rx_pool->rx_buff[j].skb = NULL; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1060 | static void clean_tx_pools(struct ibmvnic_adapter *adapter) | 1105 | static void clean_tx_pools(struct ibmvnic_adapter *adapter) |
| 1061 | { | 1106 | { |
| 1062 | struct ibmvnic_tx_pool *tx_pool; | 1107 | struct ibmvnic_tx_pool *tx_pool; |
| @@ -1134,7 +1179,7 @@ static int __ibmvnic_close(struct net_device *netdev) | |||
| 1134 | } | 1179 | } |
| 1135 | } | 1180 | } |
| 1136 | } | 1181 | } |
| 1137 | 1182 | clean_rx_pools(adapter); | |
| 1138 | clean_tx_pools(adapter); | 1183 | clean_tx_pools(adapter); |
| 1139 | adapter->state = VNIC_CLOSED; | 1184 | adapter->state = VNIC_CLOSED; |
| 1140 | return rc; | 1185 | return rc; |
| @@ -1670,8 +1715,6 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
| 1670 | return 0; | 1715 | return 0; |
| 1671 | } | 1716 | } |
| 1672 | 1717 | ||
| 1673 | netif_carrier_on(netdev); | ||
| 1674 | |||
| 1675 | /* kick napi */ | 1718 | /* kick napi */ |
| 1676 | for (i = 0; i < adapter->req_rx_queues; i++) | 1719 | for (i = 0; i < adapter->req_rx_queues; i++) |
| 1677 | napi_schedule(&adapter->napi[i]); | 1720 | napi_schedule(&adapter->napi[i]); |
| @@ -1679,6 +1722,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
| 1679 | if (adapter->reset_reason != VNIC_RESET_FAILOVER) | 1722 | if (adapter->reset_reason != VNIC_RESET_FAILOVER) |
| 1680 | netdev_notify_peers(netdev); | 1723 | netdev_notify_peers(netdev); |
| 1681 | 1724 | ||
| 1725 | netif_carrier_on(netdev); | ||
| 1726 | |||
| 1682 | return 0; | 1727 | return 0; |
| 1683 | } | 1728 | } |
| 1684 | 1729 | ||
| @@ -1853,6 +1898,7 @@ restart_poll: | |||
| 1853 | be16_to_cpu(next->rx_comp.rc)); | 1898 | be16_to_cpu(next->rx_comp.rc)); |
| 1854 | /* free the entry */ | 1899 | /* free the entry */ |
| 1855 | next->rx_comp.first = 0; | 1900 | next->rx_comp.first = 0; |
| 1901 | dev_kfree_skb_any(rx_buff->skb); | ||
| 1856 | remove_buff_from_pool(adapter, rx_buff); | 1902 | remove_buff_from_pool(adapter, rx_buff); |
| 1857 | continue; | 1903 | continue; |
| 1858 | } | 1904 | } |
| @@ -3013,6 +3059,7 @@ static void send_login(struct ibmvnic_adapter *adapter) | |||
| 3013 | struct vnic_login_client_data *vlcd; | 3059 | struct vnic_login_client_data *vlcd; |
| 3014 | int i; | 3060 | int i; |
| 3015 | 3061 | ||
| 3062 | release_login_rsp_buffer(adapter); | ||
| 3016 | client_data_len = vnic_client_data_len(adapter); | 3063 | client_data_len = vnic_client_data_len(adapter); |
| 3017 | 3064 | ||
| 3018 | buffer_size = | 3065 | buffer_size = |
| @@ -3708,6 +3755,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, | |||
| 3708 | 3755 | ||
| 3709 | dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, | 3756 | dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, |
| 3710 | DMA_BIDIRECTIONAL); | 3757 | DMA_BIDIRECTIONAL); |
| 3758 | release_login_buffer(adapter); | ||
| 3711 | dma_unmap_single(dev, adapter->login_rsp_buf_token, | 3759 | dma_unmap_single(dev, adapter->login_rsp_buf_token, |
| 3712 | adapter->login_rsp_buf_sz, DMA_BIDIRECTIONAL); | 3760 | adapter->login_rsp_buf_sz, DMA_BIDIRECTIONAL); |
| 3713 | 3761 | ||
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index a1d7b88cf083..5a1668cdb461 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c | |||
| @@ -7137,6 +7137,7 @@ static void mvpp2_set_rx_mode(struct net_device *dev) | |||
| 7137 | int id = port->id; | 7137 | int id = port->id; |
| 7138 | bool allmulti = dev->flags & IFF_ALLMULTI; | 7138 | bool allmulti = dev->flags & IFF_ALLMULTI; |
| 7139 | 7139 | ||
| 7140 | retry: | ||
| 7140 | mvpp2_prs_mac_promisc_set(priv, id, dev->flags & IFF_PROMISC); | 7141 | mvpp2_prs_mac_promisc_set(priv, id, dev->flags & IFF_PROMISC); |
| 7141 | mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_ALL, allmulti); | 7142 | mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_ALL, allmulti); |
| 7142 | mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_IP6, allmulti); | 7143 | mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_IP6, allmulti); |
| @@ -7144,9 +7145,13 @@ static void mvpp2_set_rx_mode(struct net_device *dev) | |||
| 7144 | /* Remove all port->id's mcast enries */ | 7145 | /* Remove all port->id's mcast enries */ |
| 7145 | mvpp2_prs_mcast_del_all(priv, id); | 7146 | mvpp2_prs_mcast_del_all(priv, id); |
| 7146 | 7147 | ||
| 7147 | if (allmulti && !netdev_mc_empty(dev)) { | 7148 | if (!allmulti) { |
| 7148 | netdev_for_each_mc_addr(ha, dev) | 7149 | netdev_for_each_mc_addr(ha, dev) { |
| 7149 | mvpp2_prs_mac_da_accept(priv, id, ha->addr, true); | 7150 | if (mvpp2_prs_mac_da_accept(priv, id, ha->addr, true)) { |
| 7151 | allmulti = true; | ||
| 7152 | goto retry; | ||
| 7153 | } | ||
| 7154 | } | ||
| 7150 | } | 7155 | } |
| 7151 | } | 7156 | } |
| 7152 | 7157 | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index f0b25baba09a..f7948e983637 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
| @@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, | |||
| 788 | u32 tb_id, | 788 | u32 tb_id, |
| 789 | struct netlink_ext_ack *extack) | 789 | struct netlink_ext_ack *extack) |
| 790 | { | 790 | { |
| 791 | struct mlxsw_sp_mr_table *mr4_table; | ||
| 792 | struct mlxsw_sp_fib *fib4; | ||
| 793 | struct mlxsw_sp_fib *fib6; | ||
| 791 | struct mlxsw_sp_vr *vr; | 794 | struct mlxsw_sp_vr *vr; |
| 792 | int err; | 795 | int err; |
| 793 | 796 | ||
| @@ -796,29 +799,30 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, | |||
| 796 | NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers"); | 799 | NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers"); |
| 797 | return ERR_PTR(-EBUSY); | 800 | return ERR_PTR(-EBUSY); |
| 798 | } | 801 | } |
| 799 | vr->fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); | 802 | fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); |
| 800 | if (IS_ERR(vr->fib4)) | 803 | if (IS_ERR(fib4)) |
| 801 | return ERR_CAST(vr->fib4); | 804 | return ERR_CAST(fib4); |
| 802 | vr->fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); | 805 | fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); |
| 803 | if (IS_ERR(vr->fib6)) { | 806 | if (IS_ERR(fib6)) { |
| 804 | err = PTR_ERR(vr->fib6); | 807 | err = PTR_ERR(fib6); |
| 805 | goto err_fib6_create; | 808 | goto err_fib6_create; |
| 806 | } | 809 | } |
| 807 | vr->mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id, | 810 | mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id, |
| 808 | MLXSW_SP_L3_PROTO_IPV4); | 811 | MLXSW_SP_L3_PROTO_IPV4); |
| 809 | if (IS_ERR(vr->mr4_table)) { | 812 | if (IS_ERR(mr4_table)) { |
| 810 | err = PTR_ERR(vr->mr4_table); | 813 | err = PTR_ERR(mr4_table); |
| 811 | goto err_mr_table_create; | 814 | goto err_mr_table_create; |
| 812 | } | 815 | } |
| 816 | vr->fib4 = fib4; | ||
| 817 | vr->fib6 = fib6; | ||
| 818 | vr->mr4_table = mr4_table; | ||
| 813 | vr->tb_id = tb_id; | 819 | vr->tb_id = tb_id; |
| 814 | return vr; | 820 | return vr; |
| 815 | 821 | ||
| 816 | err_mr_table_create: | 822 | err_mr_table_create: |
| 817 | mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6); | 823 | mlxsw_sp_fib_destroy(mlxsw_sp, fib6); |
| 818 | vr->fib6 = NULL; | ||
| 819 | err_fib6_create: | 824 | err_fib6_create: |
| 820 | mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4); | 825 | mlxsw_sp_fib_destroy(mlxsw_sp, fib4); |
| 821 | vr->fib4 = NULL; | ||
| 822 | return ERR_PTR(err); | 826 | return ERR_PTR(err); |
| 823 | } | 827 | } |
| 824 | 828 | ||
| @@ -3790,6 +3794,9 @@ mlxsw_sp_fib4_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry) | |||
| 3790 | struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; | 3794 | struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; |
| 3791 | int i; | 3795 | int i; |
| 3792 | 3796 | ||
| 3797 | if (!list_is_singular(&nh_grp->fib_list)) | ||
| 3798 | return; | ||
| 3799 | |||
| 3793 | for (i = 0; i < nh_grp->count; i++) { | 3800 | for (i = 0; i < nh_grp->count; i++) { |
| 3794 | struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; | 3801 | struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; |
| 3795 | 3802 | ||
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 7e7704daf5f1..c4949183eef3 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | |||
| @@ -43,12 +43,6 @@ | |||
| 43 | 43 | ||
| 44 | /* Local Definitions and Declarations */ | 44 | /* Local Definitions and Declarations */ |
| 45 | 45 | ||
| 46 | struct rmnet_walk_data { | ||
| 47 | struct net_device *real_dev; | ||
| 48 | struct list_head *head; | ||
| 49 | struct rmnet_port *port; | ||
| 50 | }; | ||
| 51 | |||
| 52 | static int rmnet_is_real_dev_registered(const struct net_device *real_dev) | 46 | static int rmnet_is_real_dev_registered(const struct net_device *real_dev) |
| 53 | { | 47 | { |
| 54 | return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler; | 48 | return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler; |
| @@ -112,17 +106,14 @@ static int rmnet_register_real_device(struct net_device *real_dev) | |||
| 112 | static void rmnet_unregister_bridge(struct net_device *dev, | 106 | static void rmnet_unregister_bridge(struct net_device *dev, |
| 113 | struct rmnet_port *port) | 107 | struct rmnet_port *port) |
| 114 | { | 108 | { |
| 115 | struct net_device *rmnet_dev, *bridge_dev; | ||
| 116 | struct rmnet_port *bridge_port; | 109 | struct rmnet_port *bridge_port; |
| 110 | struct net_device *bridge_dev; | ||
| 117 | 111 | ||
| 118 | if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) | 112 | if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) |
| 119 | return; | 113 | return; |
| 120 | 114 | ||
| 121 | /* bridge slave handling */ | 115 | /* bridge slave handling */ |
| 122 | if (!port->nr_rmnet_devs) { | 116 | if (!port->nr_rmnet_devs) { |
| 123 | rmnet_dev = netdev_master_upper_dev_get_rcu(dev); | ||
| 124 | netdev_upper_dev_unlink(dev, rmnet_dev); | ||
| 125 | |||
| 126 | bridge_dev = port->bridge_ep; | 117 | bridge_dev = port->bridge_ep; |
| 127 | 118 | ||
| 128 | bridge_port = rmnet_get_port_rtnl(bridge_dev); | 119 | bridge_port = rmnet_get_port_rtnl(bridge_dev); |
| @@ -132,9 +123,6 @@ static void rmnet_unregister_bridge(struct net_device *dev, | |||
| 132 | bridge_dev = port->bridge_ep; | 123 | bridge_dev = port->bridge_ep; |
| 133 | 124 | ||
| 134 | bridge_port = rmnet_get_port_rtnl(bridge_dev); | 125 | bridge_port = rmnet_get_port_rtnl(bridge_dev); |
| 135 | rmnet_dev = netdev_master_upper_dev_get_rcu(bridge_dev); | ||
| 136 | netdev_upper_dev_unlink(bridge_dev, rmnet_dev); | ||
| 137 | |||
| 138 | rmnet_unregister_real_device(bridge_dev, bridge_port); | 126 | rmnet_unregister_real_device(bridge_dev, bridge_port); |
| 139 | } | 127 | } |
| 140 | } | 128 | } |
| @@ -173,10 +161,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, | |||
| 173 | if (err) | 161 | if (err) |
| 174 | goto err1; | 162 | goto err1; |
| 175 | 163 | ||
| 176 | err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL, extack); | ||
| 177 | if (err) | ||
| 178 | goto err2; | ||
| 179 | |||
| 180 | port->rmnet_mode = mode; | 164 | port->rmnet_mode = mode; |
| 181 | 165 | ||
| 182 | hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); | 166 | hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); |
| @@ -193,8 +177,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, | |||
| 193 | 177 | ||
| 194 | return 0; | 178 | return 0; |
| 195 | 179 | ||
| 196 | err2: | ||
| 197 | rmnet_vnd_dellink(mux_id, port, ep); | ||
| 198 | err1: | 180 | err1: |
| 199 | rmnet_unregister_real_device(real_dev, port); | 181 | rmnet_unregister_real_device(real_dev, port); |
| 200 | err0: | 182 | err0: |
| @@ -204,14 +186,13 @@ err0: | |||
| 204 | 186 | ||
| 205 | static void rmnet_dellink(struct net_device *dev, struct list_head *head) | 187 | static void rmnet_dellink(struct net_device *dev, struct list_head *head) |
| 206 | { | 188 | { |
| 189 | struct rmnet_priv *priv = netdev_priv(dev); | ||
| 207 | struct net_device *real_dev; | 190 | struct net_device *real_dev; |
| 208 | struct rmnet_endpoint *ep; | 191 | struct rmnet_endpoint *ep; |
| 209 | struct rmnet_port *port; | 192 | struct rmnet_port *port; |
| 210 | u8 mux_id; | 193 | u8 mux_id; |
| 211 | 194 | ||
| 212 | rcu_read_lock(); | 195 | real_dev = priv->real_dev; |
| 213 | real_dev = netdev_master_upper_dev_get_rcu(dev); | ||
| 214 | rcu_read_unlock(); | ||
| 215 | 196 | ||
| 216 | if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) | 197 | if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) |
| 217 | return; | 198 | return; |
| @@ -219,7 +200,6 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head) | |||
| 219 | port = rmnet_get_port_rtnl(real_dev); | 200 | port = rmnet_get_port_rtnl(real_dev); |
| 220 | 201 | ||
| 221 | mux_id = rmnet_vnd_get_mux(dev); | 202 | mux_id = rmnet_vnd_get_mux(dev); |
| 222 | netdev_upper_dev_unlink(dev, real_dev); | ||
| 223 | 203 | ||
| 224 | ep = rmnet_get_endpoint(port, mux_id); | 204 | ep = rmnet_get_endpoint(port, mux_id); |
| 225 | if (ep) { | 205 | if (ep) { |
| @@ -233,30 +213,13 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head) | |||
| 233 | unregister_netdevice_queue(dev, head); | 213 | unregister_netdevice_queue(dev, head); |
| 234 | } | 214 | } |
| 235 | 215 | ||
| 236 | static int rmnet_dev_walk_unreg(struct net_device *rmnet_dev, void *data) | ||
| 237 | { | ||
| 238 | struct rmnet_walk_data *d = data; | ||
| 239 | struct rmnet_endpoint *ep; | ||
| 240 | u8 mux_id; | ||
| 241 | |||
| 242 | mux_id = rmnet_vnd_get_mux(rmnet_dev); | ||
| 243 | ep = rmnet_get_endpoint(d->port, mux_id); | ||
| 244 | if (ep) { | ||
| 245 | hlist_del_init_rcu(&ep->hlnode); | ||
| 246 | rmnet_vnd_dellink(mux_id, d->port, ep); | ||
| 247 | kfree(ep); | ||
| 248 | } | ||
| 249 | netdev_upper_dev_unlink(rmnet_dev, d->real_dev); | ||
| 250 | unregister_netdevice_queue(rmnet_dev, d->head); | ||
| 251 | |||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | static void rmnet_force_unassociate_device(struct net_device *dev) | 216 | static void rmnet_force_unassociate_device(struct net_device *dev) |
| 256 | { | 217 | { |
| 257 | struct net_device *real_dev = dev; | 218 | struct net_device *real_dev = dev; |
| 258 | struct rmnet_walk_data d; | 219 | struct hlist_node *tmp_ep; |
| 220 | struct rmnet_endpoint *ep; | ||
| 259 | struct rmnet_port *port; | 221 | struct rmnet_port *port; |
| 222 | unsigned long bkt_ep; | ||
| 260 | LIST_HEAD(list); | 223 | LIST_HEAD(list); |
| 261 | 224 | ||
| 262 | if (!rmnet_is_real_dev_registered(real_dev)) | 225 | if (!rmnet_is_real_dev_registered(real_dev)) |
| @@ -264,16 +227,19 @@ static void rmnet_force_unassociate_device(struct net_device *dev) | |||
| 264 | 227 | ||
| 265 | ASSERT_RTNL(); | 228 | ASSERT_RTNL(); |
| 266 | 229 | ||
| 267 | d.real_dev = real_dev; | ||
| 268 | d.head = &list; | ||
| 269 | |||
| 270 | port = rmnet_get_port_rtnl(dev); | 230 | port = rmnet_get_port_rtnl(dev); |
| 271 | d.port = port; | ||
| 272 | 231 | ||
| 273 | rcu_read_lock(); | 232 | rcu_read_lock(); |
| 274 | rmnet_unregister_bridge(dev, port); | 233 | rmnet_unregister_bridge(dev, port); |
| 275 | 234 | ||
| 276 | netdev_walk_all_lower_dev_rcu(real_dev, rmnet_dev_walk_unreg, &d); | 235 | hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { |
| 236 | unregister_netdevice_queue(ep->egress_dev, &list); | ||
| 237 | rmnet_vnd_dellink(ep->mux_id, port, ep); | ||
| 238 | |||
| 239 | hlist_del_init_rcu(&ep->hlnode); | ||
| 240 | kfree(ep); | ||
| 241 | } | ||
| 242 | |||
| 277 | rcu_read_unlock(); | 243 | rcu_read_unlock(); |
| 278 | unregister_netdevice_many(&list); | 244 | unregister_netdevice_many(&list); |
| 279 | 245 | ||
| @@ -422,11 +388,6 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, | |||
| 422 | if (err) | 388 | if (err) |
| 423 | return -EBUSY; | 389 | return -EBUSY; |
| 424 | 390 | ||
| 425 | err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL, | ||
| 426 | extack); | ||
| 427 | if (err) | ||
| 428 | return -EINVAL; | ||
| 429 | |||
| 430 | slave_port = rmnet_get_port(slave_dev); | 391 | slave_port = rmnet_get_port(slave_dev); |
| 431 | slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; | 392 | slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; |
| 432 | slave_port->bridge_ep = real_dev; | 393 | slave_port->bridge_ep = real_dev; |
| @@ -449,7 +410,6 @@ int rmnet_del_bridge(struct net_device *rmnet_dev, | |||
| 449 | port->rmnet_mode = RMNET_EPMODE_VND; | 410 | port->rmnet_mode = RMNET_EPMODE_VND; |
| 450 | port->bridge_ep = NULL; | 411 | port->bridge_ep = NULL; |
| 451 | 412 | ||
| 452 | netdev_upper_dev_unlink(slave_dev, rmnet_dev); | ||
| 453 | slave_port = rmnet_get_port(slave_dev); | 413 | slave_port = rmnet_get_port(slave_dev); |
| 454 | rmnet_unregister_real_device(slave_dev, slave_port); | 414 | rmnet_unregister_real_device(slave_dev, slave_port); |
| 455 | 415 | ||
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c index 6bc328fb88e1..b0dbca070c00 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c | |||
| @@ -38,6 +38,11 @@ static u8 rmnet_map_do_flow_control(struct sk_buff *skb, | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | ep = rmnet_get_endpoint(port, mux_id); | 40 | ep = rmnet_get_endpoint(port, mux_id); |
| 41 | if (!ep) { | ||
| 42 | kfree_skb(skb); | ||
| 43 | return RX_HANDLER_CONSUMED; | ||
| 44 | } | ||
| 45 | |||
| 41 | vnd = ep->egress_dev; | 46 | vnd = ep->egress_dev; |
| 42 | 47 | ||
| 43 | ip_family = cmd->flow_control.ip_family; | 48 | ip_family = cmd->flow_control.ip_family; |
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index 570a227acdd8..346d310914df 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c | |||
| @@ -121,7 +121,7 @@ static void rmnet_get_stats64(struct net_device *dev, | |||
| 121 | memset(&total_stats, 0, sizeof(struct rmnet_vnd_stats)); | 121 | memset(&total_stats, 0, sizeof(struct rmnet_vnd_stats)); |
| 122 | 122 | ||
| 123 | for_each_possible_cpu(cpu) { | 123 | for_each_possible_cpu(cpu) { |
| 124 | pcpu_ptr = this_cpu_ptr(priv->pcpu_stats); | 124 | pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu); |
| 125 | 125 | ||
| 126 | do { | 126 | do { |
| 127 | start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp); | 127 | start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp); |
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index c87f57ca4437..a95fbd5510d9 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c | |||
| @@ -2255,9 +2255,6 @@ static int ravb_wol_setup(struct net_device *ndev) | |||
| 2255 | /* Enable MagicPacket */ | 2255 | /* Enable MagicPacket */ |
| 2256 | ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE); | 2256 | ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE); |
| 2257 | 2257 | ||
| 2258 | /* Increased clock usage so device won't be suspended */ | ||
| 2259 | clk_enable(priv->clk); | ||
| 2260 | |||
| 2261 | return enable_irq_wake(priv->emac_irq); | 2258 | return enable_irq_wake(priv->emac_irq); |
| 2262 | } | 2259 | } |
| 2263 | 2260 | ||
| @@ -2276,9 +2273,6 @@ static int ravb_wol_restore(struct net_device *ndev) | |||
| 2276 | if (ret < 0) | 2273 | if (ret < 0) |
| 2277 | return ret; | 2274 | return ret; |
| 2278 | 2275 | ||
| 2279 | /* Restore clock usage count */ | ||
| 2280 | clk_disable(priv->clk); | ||
| 2281 | |||
| 2282 | return disable_irq_wake(priv->emac_irq); | 2276 | return disable_irq_wake(priv->emac_irq); |
| 2283 | } | 2277 | } |
| 2284 | 2278 | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index a197e11f3a56..92dcf8717fc6 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
| 41 | #include <linux/ethtool.h> | 41 | #include <linux/ethtool.h> |
| 42 | #include <linux/if_vlan.h> | 42 | #include <linux/if_vlan.h> |
| 43 | #include <linux/clk.h> | ||
| 44 | #include <linux/sh_eth.h> | 43 | #include <linux/sh_eth.h> |
| 45 | #include <linux/of_mdio.h> | 44 | #include <linux/of_mdio.h> |
| 46 | 45 | ||
| @@ -2304,7 +2303,7 @@ static void sh_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) | |||
| 2304 | wol->supported = 0; | 2303 | wol->supported = 0; |
| 2305 | wol->wolopts = 0; | 2304 | wol->wolopts = 0; |
| 2306 | 2305 | ||
| 2307 | if (mdp->cd->magic && mdp->clk) { | 2306 | if (mdp->cd->magic) { |
| 2308 | wol->supported = WAKE_MAGIC; | 2307 | wol->supported = WAKE_MAGIC; |
| 2309 | wol->wolopts = mdp->wol_enabled ? WAKE_MAGIC : 0; | 2308 | wol->wolopts = mdp->wol_enabled ? WAKE_MAGIC : 0; |
| 2310 | } | 2309 | } |
| @@ -2314,7 +2313,7 @@ static int sh_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) | |||
| 2314 | { | 2313 | { |
| 2315 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2314 | struct sh_eth_private *mdp = netdev_priv(ndev); |
| 2316 | 2315 | ||
| 2317 | if (!mdp->cd->magic || !mdp->clk || wol->wolopts & ~WAKE_MAGIC) | 2316 | if (!mdp->cd->magic || wol->wolopts & ~WAKE_MAGIC) |
| 2318 | return -EOPNOTSUPP; | 2317 | return -EOPNOTSUPP; |
| 2319 | 2318 | ||
| 2320 | mdp->wol_enabled = !!(wol->wolopts & WAKE_MAGIC); | 2319 | mdp->wol_enabled = !!(wol->wolopts & WAKE_MAGIC); |
| @@ -3153,11 +3152,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
| 3153 | goto out_release; | 3152 | goto out_release; |
| 3154 | } | 3153 | } |
| 3155 | 3154 | ||
| 3156 | /* Get clock, if not found that's OK but Wake-On-Lan is unavailable */ | ||
| 3157 | mdp->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 3158 | if (IS_ERR(mdp->clk)) | ||
| 3159 | mdp->clk = NULL; | ||
| 3160 | |||
| 3161 | ndev->base_addr = res->start; | 3155 | ndev->base_addr = res->start; |
| 3162 | 3156 | ||
| 3163 | spin_lock_init(&mdp->lock); | 3157 | spin_lock_init(&mdp->lock); |
| @@ -3278,7 +3272,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
| 3278 | if (ret) | 3272 | if (ret) |
| 3279 | goto out_napi_del; | 3273 | goto out_napi_del; |
| 3280 | 3274 | ||
| 3281 | if (mdp->cd->magic && mdp->clk) | 3275 | if (mdp->cd->magic) |
| 3282 | device_set_wakeup_capable(&pdev->dev, 1); | 3276 | device_set_wakeup_capable(&pdev->dev, 1); |
| 3283 | 3277 | ||
| 3284 | /* print device information */ | 3278 | /* print device information */ |
| @@ -3331,9 +3325,6 @@ static int sh_eth_wol_setup(struct net_device *ndev) | |||
| 3331 | /* Enable MagicPacket */ | 3325 | /* Enable MagicPacket */ |
| 3332 | sh_eth_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE); | 3326 | sh_eth_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE); |
| 3333 | 3327 | ||
| 3334 | /* Increased clock usage so device won't be suspended */ | ||
| 3335 | clk_enable(mdp->clk); | ||
| 3336 | |||
| 3337 | return enable_irq_wake(ndev->irq); | 3328 | return enable_irq_wake(ndev->irq); |
| 3338 | } | 3329 | } |
| 3339 | 3330 | ||
| @@ -3359,9 +3350,6 @@ static int sh_eth_wol_restore(struct net_device *ndev) | |||
| 3359 | if (ret < 0) | 3350 | if (ret < 0) |
| 3360 | return ret; | 3351 | return ret; |
| 3361 | 3352 | ||
| 3362 | /* Restore clock usage count */ | ||
| 3363 | clk_disable(mdp->clk); | ||
| 3364 | |||
| 3365 | return disable_irq_wake(ndev->irq); | 3353 | return disable_irq_wake(ndev->irq); |
| 3366 | } | 3354 | } |
| 3367 | 3355 | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b13eed21c87d..d39ae77707ef 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -1382,7 +1382,7 @@ int genphy_setup_forced(struct phy_device *phydev) | |||
| 1382 | ctl |= BMCR_FULLDPLX; | 1382 | ctl |= BMCR_FULLDPLX; |
| 1383 | 1383 | ||
| 1384 | return phy_modify(phydev, MII_BMCR, | 1384 | return phy_modify(phydev, MII_BMCR, |
| 1385 | BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN, ctl); | 1385 | ~(BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN), ctl); |
| 1386 | } | 1386 | } |
| 1387 | EXPORT_SYMBOL(genphy_setup_forced); | 1387 | EXPORT_SYMBOL(genphy_setup_forced); |
| 1388 | 1388 | ||
diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c index ca5e375de27c..e0d6760f3219 100644 --- a/drivers/net/thunderbolt.c +++ b/drivers/net/thunderbolt.c | |||
| @@ -166,6 +166,8 @@ struct tbnet_ring { | |||
| 166 | * @connected_work: Worker that finalizes the ThunderboltIP connection | 166 | * @connected_work: Worker that finalizes the ThunderboltIP connection |
| 167 | * setup and enables DMA paths for high speed data | 167 | * setup and enables DMA paths for high speed data |
| 168 | * transfers | 168 | * transfers |
| 169 | * @disconnect_work: Worker that handles tearing down the ThunderboltIP | ||
| 170 | * connection | ||
| 169 | * @rx_hdr: Copy of the currently processed Rx frame. Used when a | 171 | * @rx_hdr: Copy of the currently processed Rx frame. Used when a |
| 170 | * network packet consists of multiple Thunderbolt frames. | 172 | * network packet consists of multiple Thunderbolt frames. |
| 171 | * In host byte order. | 173 | * In host byte order. |
| @@ -190,6 +192,7 @@ struct tbnet { | |||
| 190 | int login_retries; | 192 | int login_retries; |
| 191 | struct delayed_work login_work; | 193 | struct delayed_work login_work; |
| 192 | struct work_struct connected_work; | 194 | struct work_struct connected_work; |
| 195 | struct work_struct disconnect_work; | ||
| 193 | struct thunderbolt_ip_frame_header rx_hdr; | 196 | struct thunderbolt_ip_frame_header rx_hdr; |
| 194 | struct tbnet_ring rx_ring; | 197 | struct tbnet_ring rx_ring; |
| 195 | atomic_t frame_id; | 198 | atomic_t frame_id; |
| @@ -445,7 +448,7 @@ static int tbnet_handle_packet(const void *buf, size_t size, void *data) | |||
| 445 | case TBIP_LOGOUT: | 448 | case TBIP_LOGOUT: |
| 446 | ret = tbnet_logout_response(net, route, sequence, command_id); | 449 | ret = tbnet_logout_response(net, route, sequence, command_id); |
| 447 | if (!ret) | 450 | if (!ret) |
| 448 | tbnet_tear_down(net, false); | 451 | queue_work(system_long_wq, &net->disconnect_work); |
| 449 | break; | 452 | break; |
| 450 | 453 | ||
| 451 | default: | 454 | default: |
| @@ -659,6 +662,13 @@ static void tbnet_login_work(struct work_struct *work) | |||
| 659 | } | 662 | } |
| 660 | } | 663 | } |
| 661 | 664 | ||
| 665 | static void tbnet_disconnect_work(struct work_struct *work) | ||
| 666 | { | ||
| 667 | struct tbnet *net = container_of(work, typeof(*net), disconnect_work); | ||
| 668 | |||
| 669 | tbnet_tear_down(net, false); | ||
| 670 | } | ||
| 671 | |||
| 662 | static bool tbnet_check_frame(struct tbnet *net, const struct tbnet_frame *tf, | 672 | static bool tbnet_check_frame(struct tbnet *net, const struct tbnet_frame *tf, |
| 663 | const struct thunderbolt_ip_frame_header *hdr) | 673 | const struct thunderbolt_ip_frame_header *hdr) |
| 664 | { | 674 | { |
| @@ -881,6 +891,7 @@ static int tbnet_stop(struct net_device *dev) | |||
| 881 | 891 | ||
| 882 | napi_disable(&net->napi); | 892 | napi_disable(&net->napi); |
| 883 | 893 | ||
| 894 | cancel_work_sync(&net->disconnect_work); | ||
| 884 | tbnet_tear_down(net, true); | 895 | tbnet_tear_down(net, true); |
| 885 | 896 | ||
| 886 | tb_ring_free(net->rx_ring.ring); | 897 | tb_ring_free(net->rx_ring.ring); |
| @@ -1195,6 +1206,7 @@ static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id) | |||
| 1195 | net = netdev_priv(dev); | 1206 | net = netdev_priv(dev); |
| 1196 | INIT_DELAYED_WORK(&net->login_work, tbnet_login_work); | 1207 | INIT_DELAYED_WORK(&net->login_work, tbnet_login_work); |
| 1197 | INIT_WORK(&net->connected_work, tbnet_connected_work); | 1208 | INIT_WORK(&net->connected_work, tbnet_connected_work); |
| 1209 | INIT_WORK(&net->disconnect_work, tbnet_disconnect_work); | ||
| 1198 | mutex_init(&net->connection_lock); | 1210 | mutex_init(&net->connection_lock); |
| 1199 | atomic_set(&net->command_id, 0); | 1211 | atomic_set(&net->command_id, 0); |
| 1200 | atomic_set(&net->frame_id, 0); | 1212 | atomic_set(&net->frame_id, 0); |
| @@ -1270,10 +1282,7 @@ static int __maybe_unused tbnet_suspend(struct device *dev) | |||
| 1270 | stop_login(net); | 1282 | stop_login(net); |
| 1271 | if (netif_running(net->dev)) { | 1283 | if (netif_running(net->dev)) { |
| 1272 | netif_device_detach(net->dev); | 1284 | netif_device_detach(net->dev); |
| 1273 | tb_ring_stop(net->rx_ring.ring); | 1285 | tbnet_tear_down(net, true); |
| 1274 | tb_ring_stop(net->tx_ring.ring); | ||
| 1275 | tbnet_free_buffers(&net->rx_ring); | ||
| 1276 | tbnet_free_buffers(&net->tx_ring); | ||
| 1277 | } | 1286 | } |
| 1278 | 1287 | ||
| 1279 | return 0; | 1288 | return 0; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 81e6cc951e7f..b52258c327d2 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1489,27 +1489,23 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, | |||
| 1489 | skb->truesize += skb->data_len; | 1489 | skb->truesize += skb->data_len; |
| 1490 | 1490 | ||
| 1491 | for (i = 1; i < it->nr_segs; i++) { | 1491 | for (i = 1; i < it->nr_segs; i++) { |
| 1492 | struct page_frag *pfrag = ¤t->task_frag; | ||
| 1492 | size_t fragsz = it->iov[i].iov_len; | 1493 | size_t fragsz = it->iov[i].iov_len; |
| 1493 | unsigned long offset; | ||
| 1494 | struct page *page; | ||
| 1495 | void *data; | ||
| 1496 | 1494 | ||
| 1497 | if (fragsz == 0 || fragsz > PAGE_SIZE) { | 1495 | if (fragsz == 0 || fragsz > PAGE_SIZE) { |
| 1498 | err = -EINVAL; | 1496 | err = -EINVAL; |
| 1499 | goto free; | 1497 | goto free; |
| 1500 | } | 1498 | } |
| 1501 | 1499 | ||
| 1502 | local_bh_disable(); | 1500 | if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { |
| 1503 | data = napi_alloc_frag(fragsz); | ||
| 1504 | local_bh_enable(); | ||
| 1505 | if (!data) { | ||
| 1506 | err = -ENOMEM; | 1501 | err = -ENOMEM; |
| 1507 | goto free; | 1502 | goto free; |
| 1508 | } | 1503 | } |
| 1509 | 1504 | ||
| 1510 | page = virt_to_head_page(data); | 1505 | skb_fill_page_desc(skb, i - 1, pfrag->page, |
| 1511 | offset = data - page_address(page); | 1506 | pfrag->offset, fragsz); |
| 1512 | skb_fill_page_desc(skb, i - 1, page, offset, fragsz); | 1507 | page_ref_inc(pfrag->page); |
| 1508 | pfrag->offset += fragsz; | ||
| 1513 | } | 1509 | } |
| 1514 | 1510 | ||
| 1515 | return skb; | 1511 | return skb; |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 6088ea13a6bf..817e5e2766da 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -120,8 +120,12 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) | |||
| 120 | int ret; | 120 | int ret; |
| 121 | 121 | ||
| 122 | ret = nvme_reset_ctrl(ctrl); | 122 | ret = nvme_reset_ctrl(ctrl); |
| 123 | if (!ret) | 123 | if (!ret) { |
| 124 | flush_work(&ctrl->reset_work); | 124 | flush_work(&ctrl->reset_work); |
| 125 | if (ctrl->state != NVME_CTRL_LIVE) | ||
| 126 | ret = -ENETRESET; | ||
| 127 | } | ||
| 128 | |||
| 125 | return ret; | 129 | return ret; |
| 126 | } | 130 | } |
| 127 | EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync); | 131 | EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync); |
| @@ -265,7 +269,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | |||
| 265 | switch (new_state) { | 269 | switch (new_state) { |
| 266 | case NVME_CTRL_ADMIN_ONLY: | 270 | case NVME_CTRL_ADMIN_ONLY: |
| 267 | switch (old_state) { | 271 | switch (old_state) { |
| 268 | case NVME_CTRL_RECONNECTING: | 272 | case NVME_CTRL_CONNECTING: |
| 269 | changed = true; | 273 | changed = true; |
| 270 | /* FALLTHRU */ | 274 | /* FALLTHRU */ |
| 271 | default: | 275 | default: |
| @@ -276,7 +280,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | |||
| 276 | switch (old_state) { | 280 | switch (old_state) { |
| 277 | case NVME_CTRL_NEW: | 281 | case NVME_CTRL_NEW: |
| 278 | case NVME_CTRL_RESETTING: | 282 | case NVME_CTRL_RESETTING: |
| 279 | case NVME_CTRL_RECONNECTING: | 283 | case NVME_CTRL_CONNECTING: |
| 280 | changed = true; | 284 | changed = true; |
| 281 | /* FALLTHRU */ | 285 | /* FALLTHRU */ |
| 282 | default: | 286 | default: |
| @@ -294,9 +298,9 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | |||
| 294 | break; | 298 | break; |
| 295 | } | 299 | } |
| 296 | break; | 300 | break; |
| 297 | case NVME_CTRL_RECONNECTING: | 301 | case NVME_CTRL_CONNECTING: |
| 298 | switch (old_state) { | 302 | switch (old_state) { |
| 299 | case NVME_CTRL_LIVE: | 303 | case NVME_CTRL_NEW: |
| 300 | case NVME_CTRL_RESETTING: | 304 | case NVME_CTRL_RESETTING: |
| 301 | changed = true; | 305 | changed = true; |
| 302 | /* FALLTHRU */ | 306 | /* FALLTHRU */ |
| @@ -309,7 +313,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | |||
| 309 | case NVME_CTRL_LIVE: | 313 | case NVME_CTRL_LIVE: |
| 310 | case NVME_CTRL_ADMIN_ONLY: | 314 | case NVME_CTRL_ADMIN_ONLY: |
| 311 | case NVME_CTRL_RESETTING: | 315 | case NVME_CTRL_RESETTING: |
| 312 | case NVME_CTRL_RECONNECTING: | 316 | case NVME_CTRL_CONNECTING: |
| 313 | changed = true; | 317 | changed = true; |
| 314 | /* FALLTHRU */ | 318 | /* FALLTHRU */ |
| 315 | default: | 319 | default: |
| @@ -518,9 +522,11 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, | |||
| 518 | u64 slba = nvme_block_nr(ns, bio->bi_iter.bi_sector); | 522 | u64 slba = nvme_block_nr(ns, bio->bi_iter.bi_sector); |
| 519 | u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; | 523 | u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; |
| 520 | 524 | ||
| 521 | range[n].cattr = cpu_to_le32(0); | 525 | if (n < segments) { |
| 522 | range[n].nlb = cpu_to_le32(nlb); | 526 | range[n].cattr = cpu_to_le32(0); |
| 523 | range[n].slba = cpu_to_le64(slba); | 527 | range[n].nlb = cpu_to_le32(nlb); |
| 528 | range[n].slba = cpu_to_le64(slba); | ||
| 529 | } | ||
| 524 | n++; | 530 | n++; |
| 525 | } | 531 | } |
| 526 | 532 | ||
| @@ -794,13 +800,9 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) | |||
| 794 | 800 | ||
| 795 | static int nvme_keep_alive(struct nvme_ctrl *ctrl) | 801 | static int nvme_keep_alive(struct nvme_ctrl *ctrl) |
| 796 | { | 802 | { |
| 797 | struct nvme_command c; | ||
| 798 | struct request *rq; | 803 | struct request *rq; |
| 799 | 804 | ||
| 800 | memset(&c, 0, sizeof(c)); | 805 | rq = nvme_alloc_request(ctrl->admin_q, &ctrl->ka_cmd, BLK_MQ_REQ_RESERVED, |
| 801 | c.common.opcode = nvme_admin_keep_alive; | ||
| 802 | |||
| 803 | rq = nvme_alloc_request(ctrl->admin_q, &c, BLK_MQ_REQ_RESERVED, | ||
| 804 | NVME_QID_ANY); | 806 | NVME_QID_ANY); |
| 805 | if (IS_ERR(rq)) | 807 | if (IS_ERR(rq)) |
| 806 | return PTR_ERR(rq); | 808 | return PTR_ERR(rq); |
| @@ -832,6 +834,8 @@ void nvme_start_keep_alive(struct nvme_ctrl *ctrl) | |||
| 832 | return; | 834 | return; |
| 833 | 835 | ||
| 834 | INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work); | 836 | INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work); |
| 837 | memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd)); | ||
| 838 | ctrl->ka_cmd.common.opcode = nvme_admin_keep_alive; | ||
| 835 | schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); | 839 | schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); |
| 836 | } | 840 | } |
| 837 | EXPORT_SYMBOL_GPL(nvme_start_keep_alive); | 841 | EXPORT_SYMBOL_GPL(nvme_start_keep_alive); |
| @@ -1117,14 +1121,19 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, | |||
| 1117 | 1121 | ||
| 1118 | static void nvme_update_formats(struct nvme_ctrl *ctrl) | 1122 | static void nvme_update_formats(struct nvme_ctrl *ctrl) |
| 1119 | { | 1123 | { |
| 1120 | struct nvme_ns *ns; | 1124 | struct nvme_ns *ns, *next; |
| 1125 | LIST_HEAD(rm_list); | ||
| 1121 | 1126 | ||
| 1122 | mutex_lock(&ctrl->namespaces_mutex); | 1127 | mutex_lock(&ctrl->namespaces_mutex); |
| 1123 | list_for_each_entry(ns, &ctrl->namespaces, list) { | 1128 | list_for_each_entry(ns, &ctrl->namespaces, list) { |
| 1124 | if (ns->disk && nvme_revalidate_disk(ns->disk)) | 1129 | if (ns->disk && nvme_revalidate_disk(ns->disk)) { |
| 1125 | nvme_ns_remove(ns); | 1130 | list_move_tail(&ns->list, &rm_list); |
| 1131 | } | ||
| 1126 | } | 1132 | } |
| 1127 | mutex_unlock(&ctrl->namespaces_mutex); | 1133 | mutex_unlock(&ctrl->namespaces_mutex); |
| 1134 | |||
| 1135 | list_for_each_entry_safe(ns, next, &rm_list, list) | ||
| 1136 | nvme_ns_remove(ns); | ||
| 1128 | } | 1137 | } |
| 1129 | 1138 | ||
| 1130 | static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) | 1139 | static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) |
| @@ -2687,7 +2696,7 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, | |||
| 2687 | [NVME_CTRL_LIVE] = "live", | 2696 | [NVME_CTRL_LIVE] = "live", |
| 2688 | [NVME_CTRL_ADMIN_ONLY] = "only-admin", | 2697 | [NVME_CTRL_ADMIN_ONLY] = "only-admin", |
| 2689 | [NVME_CTRL_RESETTING] = "resetting", | 2698 | [NVME_CTRL_RESETTING] = "resetting", |
| 2690 | [NVME_CTRL_RECONNECTING]= "reconnecting", | 2699 | [NVME_CTRL_CONNECTING] = "connecting", |
| 2691 | [NVME_CTRL_DELETING] = "deleting", | 2700 | [NVME_CTRL_DELETING] = "deleting", |
| 2692 | [NVME_CTRL_DEAD] = "dead", | 2701 | [NVME_CTRL_DEAD] = "dead", |
| 2693 | }; | 2702 | }; |
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index 25b19f722f5b..a3145d90c1d2 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h | |||
| @@ -171,13 +171,14 @@ static inline blk_status_t nvmf_check_init_req(struct nvme_ctrl *ctrl, | |||
| 171 | cmd->common.opcode != nvme_fabrics_command || | 171 | cmd->common.opcode != nvme_fabrics_command || |
| 172 | cmd->fabrics.fctype != nvme_fabrics_type_connect) { | 172 | cmd->fabrics.fctype != nvme_fabrics_type_connect) { |
| 173 | /* | 173 | /* |
| 174 | * Reconnecting state means transport disruption, which can take | 174 | * Connecting state means transport disruption or initial |
| 175 | * a long time and even might fail permanently, fail fast to | 175 | * establishment, which can take a long time and even might |
| 176 | * give upper layers a chance to failover. | 176 | * fail permanently, fail fast to give upper layers a chance |
| 177 | * to failover. | ||
| 177 | * Deleting state means that the ctrl will never accept commands | 178 | * Deleting state means that the ctrl will never accept commands |
| 178 | * again, fail it permanently. | 179 | * again, fail it permanently. |
| 179 | */ | 180 | */ |
| 180 | if (ctrl->state == NVME_CTRL_RECONNECTING || | 181 | if (ctrl->state == NVME_CTRL_CONNECTING || |
| 181 | ctrl->state == NVME_CTRL_DELETING) { | 182 | ctrl->state == NVME_CTRL_DELETING) { |
| 182 | nvme_req(rq)->status = NVME_SC_ABORT_REQ; | 183 | nvme_req(rq)->status = NVME_SC_ABORT_REQ; |
| 183 | return BLK_STS_IOERR; | 184 | return BLK_STS_IOERR; |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index b856d7c919d2..7f51f8414b97 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
| @@ -55,9 +55,7 @@ struct nvme_fc_queue { | |||
| 55 | 55 | ||
| 56 | enum nvme_fcop_flags { | 56 | enum nvme_fcop_flags { |
| 57 | FCOP_FLAGS_TERMIO = (1 << 0), | 57 | FCOP_FLAGS_TERMIO = (1 << 0), |
| 58 | FCOP_FLAGS_RELEASED = (1 << 1), | 58 | FCOP_FLAGS_AEN = (1 << 1), |
| 59 | FCOP_FLAGS_COMPLETE = (1 << 2), | ||
| 60 | FCOP_FLAGS_AEN = (1 << 3), | ||
| 61 | }; | 59 | }; |
| 62 | 60 | ||
| 63 | struct nvmefc_ls_req_op { | 61 | struct nvmefc_ls_req_op { |
| @@ -532,7 +530,7 @@ nvme_fc_resume_controller(struct nvme_fc_ctrl *ctrl) | |||
| 532 | { | 530 | { |
| 533 | switch (ctrl->ctrl.state) { | 531 | switch (ctrl->ctrl.state) { |
| 534 | case NVME_CTRL_NEW: | 532 | case NVME_CTRL_NEW: |
| 535 | case NVME_CTRL_RECONNECTING: | 533 | case NVME_CTRL_CONNECTING: |
| 536 | /* | 534 | /* |
| 537 | * As all reconnects were suppressed, schedule a | 535 | * As all reconnects were suppressed, schedule a |
| 538 | * connect. | 536 | * connect. |
| @@ -777,7 +775,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl) | |||
| 777 | } | 775 | } |
| 778 | break; | 776 | break; |
| 779 | 777 | ||
| 780 | case NVME_CTRL_RECONNECTING: | 778 | case NVME_CTRL_CONNECTING: |
| 781 | /* | 779 | /* |
| 782 | * The association has already been terminated and the | 780 | * The association has already been terminated and the |
| 783 | * controller is attempting reconnects. No need to do anything | 781 | * controller is attempting reconnects. No need to do anything |
| @@ -1470,7 +1468,6 @@ nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl) | |||
| 1470 | 1468 | ||
| 1471 | /* *********************** NVME Ctrl Routines **************************** */ | 1469 | /* *********************** NVME Ctrl Routines **************************** */ |
| 1472 | 1470 | ||
| 1473 | static void __nvme_fc_final_op_cleanup(struct request *rq); | ||
| 1474 | static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg); | 1471 | static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg); |
| 1475 | 1472 | ||
| 1476 | static int | 1473 | static int |
| @@ -1512,13 +1509,19 @@ nvme_fc_exit_request(struct blk_mq_tag_set *set, struct request *rq, | |||
| 1512 | static int | 1509 | static int |
| 1513 | __nvme_fc_abort_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_fcp_op *op) | 1510 | __nvme_fc_abort_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_fcp_op *op) |
| 1514 | { | 1511 | { |
| 1515 | int state; | 1512 | unsigned long flags; |
| 1513 | int opstate; | ||
| 1514 | |||
| 1515 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 1516 | opstate = atomic_xchg(&op->state, FCPOP_STATE_ABORTED); | ||
| 1517 | if (opstate != FCPOP_STATE_ACTIVE) | ||
| 1518 | atomic_set(&op->state, opstate); | ||
| 1519 | else if (ctrl->flags & FCCTRL_TERMIO) | ||
| 1520 | ctrl->iocnt++; | ||
| 1521 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 1516 | 1522 | ||
| 1517 | state = atomic_xchg(&op->state, FCPOP_STATE_ABORTED); | 1523 | if (opstate != FCPOP_STATE_ACTIVE) |
| 1518 | if (state != FCPOP_STATE_ACTIVE) { | ||
| 1519 | atomic_set(&op->state, state); | ||
| 1520 | return -ECANCELED; | 1524 | return -ECANCELED; |
| 1521 | } | ||
| 1522 | 1525 | ||
| 1523 | ctrl->lport->ops->fcp_abort(&ctrl->lport->localport, | 1526 | ctrl->lport->ops->fcp_abort(&ctrl->lport->localport, |
| 1524 | &ctrl->rport->remoteport, | 1527 | &ctrl->rport->remoteport, |
| @@ -1532,60 +1535,26 @@ static void | |||
| 1532 | nvme_fc_abort_aen_ops(struct nvme_fc_ctrl *ctrl) | 1535 | nvme_fc_abort_aen_ops(struct nvme_fc_ctrl *ctrl) |
| 1533 | { | 1536 | { |
| 1534 | struct nvme_fc_fcp_op *aen_op = ctrl->aen_ops; | 1537 | struct nvme_fc_fcp_op *aen_op = ctrl->aen_ops; |
| 1535 | unsigned long flags; | 1538 | int i; |
| 1536 | int i, ret; | ||
| 1537 | |||
| 1538 | for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) { | ||
| 1539 | if (atomic_read(&aen_op->state) != FCPOP_STATE_ACTIVE) | ||
| 1540 | continue; | ||
| 1541 | |||
| 1542 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 1543 | if (ctrl->flags & FCCTRL_TERMIO) { | ||
| 1544 | ctrl->iocnt++; | ||
| 1545 | aen_op->flags |= FCOP_FLAGS_TERMIO; | ||
| 1546 | } | ||
| 1547 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 1548 | |||
| 1549 | ret = __nvme_fc_abort_op(ctrl, aen_op); | ||
| 1550 | if (ret) { | ||
| 1551 | /* | ||
| 1552 | * if __nvme_fc_abort_op failed the io wasn't | ||
| 1553 | * active. Thus this call path is running in | ||
| 1554 | * parallel to the io complete. Treat as non-error. | ||
| 1555 | */ | ||
| 1556 | 1539 | ||
| 1557 | /* back out the flags/counters */ | 1540 | for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) |
| 1558 | spin_lock_irqsave(&ctrl->lock, flags); | 1541 | __nvme_fc_abort_op(ctrl, aen_op); |
| 1559 | if (ctrl->flags & FCCTRL_TERMIO) | ||
| 1560 | ctrl->iocnt--; | ||
| 1561 | aen_op->flags &= ~FCOP_FLAGS_TERMIO; | ||
| 1562 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 1563 | return; | ||
| 1564 | } | ||
| 1565 | } | ||
| 1566 | } | 1542 | } |
| 1567 | 1543 | ||
| 1568 | static inline int | 1544 | static inline void |
| 1569 | __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *ctrl, | 1545 | __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *ctrl, |
| 1570 | struct nvme_fc_fcp_op *op) | 1546 | struct nvme_fc_fcp_op *op, int opstate) |
| 1571 | { | 1547 | { |
| 1572 | unsigned long flags; | 1548 | unsigned long flags; |
| 1573 | bool complete_rq = false; | ||
| 1574 | 1549 | ||
| 1575 | spin_lock_irqsave(&ctrl->lock, flags); | 1550 | if (opstate == FCPOP_STATE_ABORTED) { |
| 1576 | if (unlikely(op->flags & FCOP_FLAGS_TERMIO)) { | 1551 | spin_lock_irqsave(&ctrl->lock, flags); |
| 1577 | if (ctrl->flags & FCCTRL_TERMIO) { | 1552 | if (ctrl->flags & FCCTRL_TERMIO) { |
| 1578 | if (!--ctrl->iocnt) | 1553 | if (!--ctrl->iocnt) |
| 1579 | wake_up(&ctrl->ioabort_wait); | 1554 | wake_up(&ctrl->ioabort_wait); |
| 1580 | } | 1555 | } |
| 1556 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 1581 | } | 1557 | } |
| 1582 | if (op->flags & FCOP_FLAGS_RELEASED) | ||
| 1583 | complete_rq = true; | ||
| 1584 | else | ||
| 1585 | op->flags |= FCOP_FLAGS_COMPLETE; | ||
| 1586 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 1587 | |||
| 1588 | return complete_rq; | ||
| 1589 | } | 1558 | } |
| 1590 | 1559 | ||
| 1591 | static void | 1560 | static void |
| @@ -1601,6 +1570,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) | |||
| 1601 | __le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1); | 1570 | __le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1); |
| 1602 | union nvme_result result; | 1571 | union nvme_result result; |
| 1603 | bool terminate_assoc = true; | 1572 | bool terminate_assoc = true; |
| 1573 | int opstate; | ||
| 1604 | 1574 | ||
| 1605 | /* | 1575 | /* |
| 1606 | * WARNING: | 1576 | * WARNING: |
| @@ -1639,11 +1609,12 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) | |||
| 1639 | * association to be terminated. | 1609 | * association to be terminated. |
| 1640 | */ | 1610 | */ |
| 1641 | 1611 | ||
| 1612 | opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE); | ||
| 1613 | |||
| 1642 | fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma, | 1614 | fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma, |
| 1643 | sizeof(op->rsp_iu), DMA_FROM_DEVICE); | 1615 | sizeof(op->rsp_iu), DMA_FROM_DEVICE); |
| 1644 | 1616 | ||
| 1645 | if (atomic_read(&op->state) == FCPOP_STATE_ABORTED || | 1617 | if (opstate == FCPOP_STATE_ABORTED) |
| 1646 | op->flags & FCOP_FLAGS_TERMIO) | ||
| 1647 | status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); | 1618 | status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); |
| 1648 | else if (freq->status) | 1619 | else if (freq->status) |
| 1649 | status = cpu_to_le16(NVME_SC_INTERNAL << 1); | 1620 | status = cpu_to_le16(NVME_SC_INTERNAL << 1); |
| @@ -1708,7 +1679,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) | |||
| 1708 | done: | 1679 | done: |
| 1709 | if (op->flags & FCOP_FLAGS_AEN) { | 1680 | if (op->flags & FCOP_FLAGS_AEN) { |
| 1710 | nvme_complete_async_event(&queue->ctrl->ctrl, status, &result); | 1681 | nvme_complete_async_event(&queue->ctrl->ctrl, status, &result); |
| 1711 | __nvme_fc_fcpop_chk_teardowns(ctrl, op); | 1682 | __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); |
| 1712 | atomic_set(&op->state, FCPOP_STATE_IDLE); | 1683 | atomic_set(&op->state, FCPOP_STATE_IDLE); |
| 1713 | op->flags = FCOP_FLAGS_AEN; /* clear other flags */ | 1684 | op->flags = FCOP_FLAGS_AEN; /* clear other flags */ |
| 1714 | nvme_fc_ctrl_put(ctrl); | 1685 | nvme_fc_ctrl_put(ctrl); |
| @@ -1722,13 +1693,11 @@ done: | |||
| 1722 | if (status && | 1693 | if (status && |
| 1723 | (blk_queue_dying(rq->q) || | 1694 | (blk_queue_dying(rq->q) || |
| 1724 | ctrl->ctrl.state == NVME_CTRL_NEW || | 1695 | ctrl->ctrl.state == NVME_CTRL_NEW || |
| 1725 | ctrl->ctrl.state == NVME_CTRL_RECONNECTING)) | 1696 | ctrl->ctrl.state == NVME_CTRL_CONNECTING)) |
| 1726 | status |= cpu_to_le16(NVME_SC_DNR << 1); | 1697 | status |= cpu_to_le16(NVME_SC_DNR << 1); |
| 1727 | 1698 | ||
| 1728 | if (__nvme_fc_fcpop_chk_teardowns(ctrl, op)) | 1699 | __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); |
| 1729 | __nvme_fc_final_op_cleanup(rq); | 1700 | nvme_end_request(rq, status, result); |
| 1730 | else | ||
| 1731 | nvme_end_request(rq, status, result); | ||
| 1732 | 1701 | ||
| 1733 | check_error: | 1702 | check_error: |
| 1734 | if (terminate_assoc) | 1703 | if (terminate_assoc) |
| @@ -2415,46 +2384,16 @@ nvme_fc_submit_async_event(struct nvme_ctrl *arg) | |||
| 2415 | } | 2384 | } |
| 2416 | 2385 | ||
| 2417 | static void | 2386 | static void |
| 2418 | __nvme_fc_final_op_cleanup(struct request *rq) | 2387 | nvme_fc_complete_rq(struct request *rq) |
| 2419 | { | 2388 | { |
| 2420 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq); | 2389 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq); |
| 2421 | struct nvme_fc_ctrl *ctrl = op->ctrl; | 2390 | struct nvme_fc_ctrl *ctrl = op->ctrl; |
| 2422 | 2391 | ||
| 2423 | atomic_set(&op->state, FCPOP_STATE_IDLE); | 2392 | atomic_set(&op->state, FCPOP_STATE_IDLE); |
| 2424 | op->flags &= ~(FCOP_FLAGS_TERMIO | FCOP_FLAGS_RELEASED | | ||
| 2425 | FCOP_FLAGS_COMPLETE); | ||
| 2426 | 2393 | ||
| 2427 | nvme_fc_unmap_data(ctrl, rq, op); | 2394 | nvme_fc_unmap_data(ctrl, rq, op); |
| 2428 | nvme_complete_rq(rq); | 2395 | nvme_complete_rq(rq); |
| 2429 | nvme_fc_ctrl_put(ctrl); | 2396 | nvme_fc_ctrl_put(ctrl); |
| 2430 | |||
| 2431 | } | ||
| 2432 | |||
| 2433 | static void | ||
| 2434 | nvme_fc_complete_rq(struct request *rq) | ||
| 2435 | { | ||
| 2436 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq); | ||
| 2437 | struct nvme_fc_ctrl *ctrl = op->ctrl; | ||
| 2438 | unsigned long flags; | ||
| 2439 | bool completed = false; | ||
| 2440 | |||
| 2441 | /* | ||
| 2442 | * the core layer, on controller resets after calling | ||
| 2443 | * nvme_shutdown_ctrl(), calls complete_rq without our | ||
| 2444 | * calling blk_mq_complete_request(), thus there may still | ||
| 2445 | * be live i/o outstanding with the LLDD. Means transport has | ||
| 2446 | * to track complete calls vs fcpio_done calls to know what | ||
| 2447 | * path to take on completes and dones. | ||
| 2448 | */ | ||
| 2449 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 2450 | if (op->flags & FCOP_FLAGS_COMPLETE) | ||
| 2451 | completed = true; | ||
| 2452 | else | ||
| 2453 | op->flags |= FCOP_FLAGS_RELEASED; | ||
| 2454 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 2455 | |||
| 2456 | if (completed) | ||
| 2457 | __nvme_fc_final_op_cleanup(rq); | ||
| 2458 | } | 2397 | } |
| 2459 | 2398 | ||
| 2460 | /* | 2399 | /* |
| @@ -2476,35 +2415,11 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved) | |||
| 2476 | struct nvme_ctrl *nctrl = data; | 2415 | struct nvme_ctrl *nctrl = data; |
| 2477 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); | 2416 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); |
| 2478 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req); | 2417 | struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req); |
| 2479 | unsigned long flags; | ||
| 2480 | int status; | ||
| 2481 | 2418 | ||
| 2482 | if (!blk_mq_request_started(req)) | 2419 | if (!blk_mq_request_started(req)) |
| 2483 | return; | 2420 | return; |
| 2484 | 2421 | ||
| 2485 | spin_lock_irqsave(&ctrl->lock, flags); | 2422 | __nvme_fc_abort_op(ctrl, op); |
| 2486 | if (ctrl->flags & FCCTRL_TERMIO) { | ||
| 2487 | ctrl->iocnt++; | ||
| 2488 | op->flags |= FCOP_FLAGS_TERMIO; | ||
| 2489 | } | ||
| 2490 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 2491 | |||
| 2492 | status = __nvme_fc_abort_op(ctrl, op); | ||
| 2493 | if (status) { | ||
| 2494 | /* | ||
| 2495 | * if __nvme_fc_abort_op failed the io wasn't | ||
| 2496 | * active. Thus this call path is running in | ||
| 2497 | * parallel to the io complete. Treat as non-error. | ||
| 2498 | */ | ||
| 2499 | |||
| 2500 | /* back out the flags/counters */ | ||
| 2501 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 2502 | if (ctrl->flags & FCCTRL_TERMIO) | ||
| 2503 | ctrl->iocnt--; | ||
| 2504 | op->flags &= ~FCOP_FLAGS_TERMIO; | ||
| 2505 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 2506 | return; | ||
| 2507 | } | ||
| 2508 | } | 2423 | } |
| 2509 | 2424 | ||
| 2510 | 2425 | ||
| @@ -2943,7 +2858,7 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status) | |||
| 2943 | unsigned long recon_delay = ctrl->ctrl.opts->reconnect_delay * HZ; | 2858 | unsigned long recon_delay = ctrl->ctrl.opts->reconnect_delay * HZ; |
| 2944 | bool recon = true; | 2859 | bool recon = true; |
| 2945 | 2860 | ||
| 2946 | if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING) | 2861 | if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) |
| 2947 | return; | 2862 | return; |
| 2948 | 2863 | ||
| 2949 | if (portptr->port_state == FC_OBJSTATE_ONLINE) | 2864 | if (portptr->port_state == FC_OBJSTATE_ONLINE) |
| @@ -2991,10 +2906,10 @@ nvme_fc_reset_ctrl_work(struct work_struct *work) | |||
| 2991 | /* will block will waiting for io to terminate */ | 2906 | /* will block will waiting for io to terminate */ |
| 2992 | nvme_fc_delete_association(ctrl); | 2907 | nvme_fc_delete_association(ctrl); |
| 2993 | 2908 | ||
| 2994 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | 2909 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { |
| 2995 | dev_err(ctrl->ctrl.device, | 2910 | dev_err(ctrl->ctrl.device, |
| 2996 | "NVME-FC{%d}: error_recovery: Couldn't change state " | 2911 | "NVME-FC{%d}: error_recovery: Couldn't change state " |
| 2997 | "to RECONNECTING\n", ctrl->cnum); | 2912 | "to CONNECTING\n", ctrl->cnum); |
| 2998 | return; | 2913 | return; |
| 2999 | } | 2914 | } |
| 3000 | 2915 | ||
| @@ -3195,7 +3110,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3195 | * transport errors (frame drop, LS failure) inherently must kill | 3110 | * transport errors (frame drop, LS failure) inherently must kill |
| 3196 | * the association. The transport is coded so that any command used | 3111 | * the association. The transport is coded so that any command used |
| 3197 | * to create the association (prior to a LIVE state transition | 3112 | * to create the association (prior to a LIVE state transition |
| 3198 | * while NEW or RECONNECTING) will fail if it completes in error or | 3113 | * while NEW or CONNECTING) will fail if it completes in error or |
| 3199 | * times out. | 3114 | * times out. |
| 3200 | * | 3115 | * |
| 3201 | * As such: as the connect request was mostly likely due to a | 3116 | * As such: as the connect request was mostly likely due to a |
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 8e4550fa08f8..0521e4707d1c 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
| @@ -123,7 +123,7 @@ enum nvme_ctrl_state { | |||
| 123 | NVME_CTRL_LIVE, | 123 | NVME_CTRL_LIVE, |
| 124 | NVME_CTRL_ADMIN_ONLY, /* Only admin queue live */ | 124 | NVME_CTRL_ADMIN_ONLY, /* Only admin queue live */ |
| 125 | NVME_CTRL_RESETTING, | 125 | NVME_CTRL_RESETTING, |
| 126 | NVME_CTRL_RECONNECTING, | 126 | NVME_CTRL_CONNECTING, |
| 127 | NVME_CTRL_DELETING, | 127 | NVME_CTRL_DELETING, |
| 128 | NVME_CTRL_DEAD, | 128 | NVME_CTRL_DEAD, |
| 129 | }; | 129 | }; |
| @@ -183,6 +183,7 @@ struct nvme_ctrl { | |||
| 183 | struct work_struct scan_work; | 183 | struct work_struct scan_work; |
| 184 | struct work_struct async_event_work; | 184 | struct work_struct async_event_work; |
| 185 | struct delayed_work ka_work; | 185 | struct delayed_work ka_work; |
| 186 | struct nvme_command ka_cmd; | ||
| 186 | struct work_struct fw_act_work; | 187 | struct work_struct fw_act_work; |
| 187 | 188 | ||
| 188 | /* Power saving configuration */ | 189 | /* Power saving configuration */ |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 022b070e60b7..5933a5c732e8 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -1141,7 +1141,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) | |||
| 1141 | /* If there is a reset/reinit ongoing, we shouldn't reset again. */ | 1141 | /* If there is a reset/reinit ongoing, we shouldn't reset again. */ |
| 1142 | switch (dev->ctrl.state) { | 1142 | switch (dev->ctrl.state) { |
| 1143 | case NVME_CTRL_RESETTING: | 1143 | case NVME_CTRL_RESETTING: |
| 1144 | case NVME_CTRL_RECONNECTING: | 1144 | case NVME_CTRL_CONNECTING: |
| 1145 | return false; | 1145 | return false; |
| 1146 | default: | 1146 | default: |
| 1147 | break; | 1147 | break; |
| @@ -1215,13 +1215,17 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
| 1215 | * cancellation error. All outstanding requests are completed on | 1215 | * cancellation error. All outstanding requests are completed on |
| 1216 | * shutdown, so we return BLK_EH_HANDLED. | 1216 | * shutdown, so we return BLK_EH_HANDLED. |
| 1217 | */ | 1217 | */ |
| 1218 | if (dev->ctrl.state == NVME_CTRL_RESETTING) { | 1218 | switch (dev->ctrl.state) { |
| 1219 | case NVME_CTRL_CONNECTING: | ||
| 1220 | case NVME_CTRL_RESETTING: | ||
| 1219 | dev_warn(dev->ctrl.device, | 1221 | dev_warn(dev->ctrl.device, |
| 1220 | "I/O %d QID %d timeout, disable controller\n", | 1222 | "I/O %d QID %d timeout, disable controller\n", |
| 1221 | req->tag, nvmeq->qid); | 1223 | req->tag, nvmeq->qid); |
| 1222 | nvme_dev_disable(dev, false); | 1224 | nvme_dev_disable(dev, false); |
| 1223 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; | 1225 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; |
| 1224 | return BLK_EH_HANDLED; | 1226 | return BLK_EH_HANDLED; |
| 1227 | default: | ||
| 1228 | break; | ||
| 1225 | } | 1229 | } |
| 1226 | 1230 | ||
| 1227 | /* | 1231 | /* |
| @@ -1364,18 +1368,14 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues, | |||
| 1364 | static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, | 1368 | static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, |
| 1365 | int qid, int depth) | 1369 | int qid, int depth) |
| 1366 | { | 1370 | { |
| 1367 | if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { | 1371 | /* CMB SQEs will be mapped before creation */ |
| 1368 | unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth), | 1372 | if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) |
| 1369 | dev->ctrl.page_size); | 1373 | return 0; |
| 1370 | nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; | ||
| 1371 | nvmeq->sq_cmds_io = dev->cmb + offset; | ||
| 1372 | } else { | ||
| 1373 | nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), | ||
| 1374 | &nvmeq->sq_dma_addr, GFP_KERNEL); | ||
| 1375 | if (!nvmeq->sq_cmds) | ||
| 1376 | return -ENOMEM; | ||
| 1377 | } | ||
| 1378 | 1374 | ||
| 1375 | nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), | ||
| 1376 | &nvmeq->sq_dma_addr, GFP_KERNEL); | ||
| 1377 | if (!nvmeq->sq_cmds) | ||
| 1378 | return -ENOMEM; | ||
| 1379 | return 0; | 1379 | return 0; |
| 1380 | } | 1380 | } |
| 1381 | 1381 | ||
| @@ -1449,6 +1449,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
| 1449 | struct nvme_dev *dev = nvmeq->dev; | 1449 | struct nvme_dev *dev = nvmeq->dev; |
| 1450 | int result; | 1450 | int result; |
| 1451 | 1451 | ||
| 1452 | if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { | ||
| 1453 | unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth), | ||
| 1454 | dev->ctrl.page_size); | ||
| 1455 | nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; | ||
| 1456 | nvmeq->sq_cmds_io = dev->cmb + offset; | ||
| 1457 | } | ||
| 1458 | |||
| 1452 | nvmeq->cq_vector = qid - 1; | 1459 | nvmeq->cq_vector = qid - 1; |
| 1453 | result = adapter_alloc_cq(dev, qid, nvmeq); | 1460 | result = adapter_alloc_cq(dev, qid, nvmeq); |
| 1454 | if (result < 0) | 1461 | if (result < 0) |
| @@ -2291,12 +2298,12 @@ static void nvme_reset_work(struct work_struct *work) | |||
| 2291 | nvme_dev_disable(dev, false); | 2298 | nvme_dev_disable(dev, false); |
| 2292 | 2299 | ||
| 2293 | /* | 2300 | /* |
| 2294 | * Introduce RECONNECTING state from nvme-fc/rdma transports to mark the | 2301 | * Introduce CONNECTING state from nvme-fc/rdma transports to mark the |
| 2295 | * initializing procedure here. | 2302 | * initializing procedure here. |
| 2296 | */ | 2303 | */ |
| 2297 | if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RECONNECTING)) { | 2304 | if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) { |
| 2298 | dev_warn(dev->ctrl.device, | 2305 | dev_warn(dev->ctrl.device, |
| 2299 | "failed to mark controller RECONNECTING\n"); | 2306 | "failed to mark controller CONNECTING\n"); |
| 2300 | goto out; | 2307 | goto out; |
| 2301 | } | 2308 | } |
| 2302 | 2309 | ||
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index acc9eb21c242..4d84a73ee12d 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
| @@ -887,7 +887,7 @@ free_ctrl: | |||
| 887 | static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl) | 887 | static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl) |
| 888 | { | 888 | { |
| 889 | /* If we are resetting/deleting then do nothing */ | 889 | /* If we are resetting/deleting then do nothing */ |
| 890 | if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING) { | 890 | if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) { |
| 891 | WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW || | 891 | WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW || |
| 892 | ctrl->ctrl.state == NVME_CTRL_LIVE); | 892 | ctrl->ctrl.state == NVME_CTRL_LIVE); |
| 893 | return; | 893 | return; |
| @@ -973,7 +973,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) | |||
| 973 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); | 973 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); |
| 974 | nvme_start_queues(&ctrl->ctrl); | 974 | nvme_start_queues(&ctrl->ctrl); |
| 975 | 975 | ||
| 976 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | 976 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { |
| 977 | /* state change failure should never happen */ | 977 | /* state change failure should never happen */ |
| 978 | WARN_ON_ONCE(1); | 978 | WARN_ON_ONCE(1); |
| 979 | return; | 979 | return; |
| @@ -1756,7 +1756,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | |||
| 1756 | nvme_stop_ctrl(&ctrl->ctrl); | 1756 | nvme_stop_ctrl(&ctrl->ctrl); |
| 1757 | nvme_rdma_shutdown_ctrl(ctrl, false); | 1757 | nvme_rdma_shutdown_ctrl(ctrl, false); |
| 1758 | 1758 | ||
| 1759 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | 1759 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { |
| 1760 | /* state change failure should never happen */ | 1760 | /* state change failure should never happen */ |
| 1761 | WARN_ON_ONCE(1); | 1761 | WARN_ON_ONCE(1); |
| 1762 | return; | 1762 | return; |
| @@ -1784,11 +1784,8 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | |||
| 1784 | return; | 1784 | return; |
| 1785 | 1785 | ||
| 1786 | out_fail: | 1786 | out_fail: |
| 1787 | dev_warn(ctrl->ctrl.device, "Removing after reset failure\n"); | 1787 | ++ctrl->ctrl.nr_reconnects; |
| 1788 | nvme_remove_namespaces(&ctrl->ctrl); | 1788 | nvme_rdma_reconnect_or_remove(ctrl); |
| 1789 | nvme_rdma_shutdown_ctrl(ctrl, true); | ||
| 1790 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
| 1791 | nvme_put_ctrl(&ctrl->ctrl); | ||
| 1792 | } | 1789 | } |
| 1793 | 1790 | ||
| 1794 | static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { | 1791 | static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { |
| @@ -1942,6 +1939,9 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, | |||
| 1942 | if (!ctrl->queues) | 1939 | if (!ctrl->queues) |
| 1943 | goto out_uninit_ctrl; | 1940 | goto out_uninit_ctrl; |
| 1944 | 1941 | ||
| 1942 | changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING); | ||
| 1943 | WARN_ON_ONCE(!changed); | ||
| 1944 | |||
| 1945 | ret = nvme_rdma_configure_admin_queue(ctrl, true); | 1945 | ret = nvme_rdma_configure_admin_queue(ctrl, true); |
| 1946 | if (ret) | 1946 | if (ret) |
| 1947 | goto out_kfree_queues; | 1947 | goto out_kfree_queues; |
diff --git a/drivers/nvme/target/io-cmd.c b/drivers/nvme/target/io-cmd.c index 0a4372a016f2..28bbdff4a88b 100644 --- a/drivers/nvme/target/io-cmd.c +++ b/drivers/nvme/target/io-cmd.c | |||
| @@ -105,10 +105,13 @@ static void nvmet_execute_flush(struct nvmet_req *req) | |||
| 105 | static u16 nvmet_discard_range(struct nvmet_ns *ns, | 105 | static u16 nvmet_discard_range(struct nvmet_ns *ns, |
| 106 | struct nvme_dsm_range *range, struct bio **bio) | 106 | struct nvme_dsm_range *range, struct bio **bio) |
| 107 | { | 107 | { |
| 108 | if (__blkdev_issue_discard(ns->bdev, | 108 | int ret; |
| 109 | |||
| 110 | ret = __blkdev_issue_discard(ns->bdev, | ||
| 109 | le64_to_cpu(range->slba) << (ns->blksize_shift - 9), | 111 | le64_to_cpu(range->slba) << (ns->blksize_shift - 9), |
| 110 | le32_to_cpu(range->nlb) << (ns->blksize_shift - 9), | 112 | le32_to_cpu(range->nlb) << (ns->blksize_shift - 9), |
| 111 | GFP_KERNEL, 0, bio)) | 113 | GFP_KERNEL, 0, bio); |
| 114 | if (ret && ret != -EOPNOTSUPP) | ||
| 112 | return NVME_SC_INTERNAL | NVME_SC_DNR; | 115 | return NVME_SC_INTERNAL | NVME_SC_DNR; |
| 113 | return 0; | 116 | return 0; |
| 114 | } | 117 | } |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index fc734014206f..8b14bd326d4a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -3419,22 +3419,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE, | |||
| 3419 | 3419 | ||
| 3420 | static void quirk_chelsio_extend_vpd(struct pci_dev *dev) | 3420 | static void quirk_chelsio_extend_vpd(struct pci_dev *dev) |
| 3421 | { | 3421 | { |
| 3422 | pci_set_vpd_size(dev, 8192); | 3422 | int chip = (dev->device & 0xf000) >> 12; |
| 3423 | } | 3423 | int func = (dev->device & 0x0f00) >> 8; |
| 3424 | 3424 | int prod = (dev->device & 0x00ff) >> 0; | |
| 3425 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd); | 3425 | |
| 3426 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd); | 3426 | /* |
| 3427 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd); | 3427 | * If this is a T3-based adapter, there's a 1KB VPD area at offset |
| 3428 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd); | 3428 | * 0xc00 which contains the preferred VPD values. If this is a T4 or |
| 3429 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd); | 3429 | * later based adapter, the special VPD is at offset 0x400 for the |
| 3430 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd); | 3430 | * Physical Functions (the SR-IOV Virtual Functions have no VPD |
| 3431 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd); | 3431 | * Capabilities). The PCI VPD Access core routines will normally |
| 3432 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd); | 3432 | * compute the size of the VPD by parsing the VPD Data Structure at |
| 3433 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd); | 3433 | * offset 0x000. This will result in silent failures when attempting |
| 3434 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd); | 3434 | * to accesses these other VPD areas which are beyond those computed |
| 3435 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd); | 3435 | * limits. |
| 3436 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd); | 3436 | */ |
| 3437 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd); | 3437 | if (chip == 0x0 && prod >= 0x20) |
| 3438 | pci_set_vpd_size(dev, 8192); | ||
| 3439 | else if (chip >= 0x4 && func < 0x8) | ||
| 3440 | pci_set_vpd_size(dev, 2048); | ||
| 3441 | } | ||
| 3442 | |||
| 3443 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, | ||
| 3444 | quirk_chelsio_extend_vpd); | ||
| 3438 | 3445 | ||
| 3439 | #ifdef CONFIG_ACPI | 3446 | #ifdef CONFIG_ACPI |
| 3440 | /* | 3447 | /* |
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index bbdc53b686dd..6dbba5aff191 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
| @@ -702,30 +702,32 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, | |||
| 702 | size_t pgstart, pgend; | 702 | size_t pgstart, pgend; |
| 703 | int ret = -EINVAL; | 703 | int ret = -EINVAL; |
| 704 | 704 | ||
| 705 | mutex_lock(&ashmem_mutex); | ||
| 706 | |||
| 705 | if (unlikely(!asma->file)) | 707 | if (unlikely(!asma->file)) |
| 706 | return -EINVAL; | 708 | goto out_unlock; |
| 707 | 709 | ||
| 708 | if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) | 710 | if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) { |
| 709 | return -EFAULT; | 711 | ret = -EFAULT; |
| 712 | goto out_unlock; | ||
| 713 | } | ||
| 710 | 714 | ||
| 711 | /* per custom, you can pass zero for len to mean "everything onward" */ | 715 | /* per custom, you can pass zero for len to mean "everything onward" */ |
| 712 | if (!pin.len) | 716 | if (!pin.len) |
| 713 | pin.len = PAGE_ALIGN(asma->size) - pin.offset; | 717 | pin.len = PAGE_ALIGN(asma->size) - pin.offset; |
| 714 | 718 | ||
| 715 | if (unlikely((pin.offset | pin.len) & ~PAGE_MASK)) | 719 | if (unlikely((pin.offset | pin.len) & ~PAGE_MASK)) |
| 716 | return -EINVAL; | 720 | goto out_unlock; |
| 717 | 721 | ||
| 718 | if (unlikely(((__u32)-1) - pin.offset < pin.len)) | 722 | if (unlikely(((__u32)-1) - pin.offset < pin.len)) |
| 719 | return -EINVAL; | 723 | goto out_unlock; |
| 720 | 724 | ||
| 721 | if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len)) | 725 | if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len)) |
| 722 | return -EINVAL; | 726 | goto out_unlock; |
| 723 | 727 | ||
| 724 | pgstart = pin.offset / PAGE_SIZE; | 728 | pgstart = pin.offset / PAGE_SIZE; |
| 725 | pgend = pgstart + (pin.len / PAGE_SIZE) - 1; | 729 | pgend = pgstart + (pin.len / PAGE_SIZE) - 1; |
| 726 | 730 | ||
| 727 | mutex_lock(&ashmem_mutex); | ||
| 728 | |||
| 729 | switch (cmd) { | 731 | switch (cmd) { |
| 730 | case ASHMEM_PIN: | 732 | case ASHMEM_PIN: |
| 731 | ret = ashmem_pin(asma, pgstart, pgend); | 733 | ret = ashmem_pin(asma, pgstart, pgend); |
| @@ -738,6 +740,7 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, | |||
| 738 | break; | 740 | break; |
| 739 | } | 741 | } |
| 740 | 742 | ||
| 743 | out_unlock: | ||
| 741 | mutex_unlock(&ashmem_mutex); | 744 | mutex_unlock(&ashmem_mutex); |
| 742 | 745 | ||
| 743 | return ret; | 746 | return ret; |
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 94e06925c712..49718c96bf9e 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| 13 | #include <linux/cma.h> | 13 | #include <linux/cma.h> |
| 14 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
| 15 | #include <linux/highmem.h> | ||
| 15 | 16 | ||
| 16 | #include "ion.h" | 17 | #include "ion.h" |
| 17 | 18 | ||
| @@ -42,6 +43,22 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, | |||
| 42 | if (!pages) | 43 | if (!pages) |
| 43 | return -ENOMEM; | 44 | return -ENOMEM; |
| 44 | 45 | ||
| 46 | if (PageHighMem(pages)) { | ||
| 47 | unsigned long nr_clear_pages = nr_pages; | ||
| 48 | struct page *page = pages; | ||
| 49 | |||
| 50 | while (nr_clear_pages > 0) { | ||
| 51 | void *vaddr = kmap_atomic(page); | ||
| 52 | |||
| 53 | memset(vaddr, 0, PAGE_SIZE); | ||
| 54 | kunmap_atomic(vaddr); | ||
| 55 | page++; | ||
| 56 | nr_clear_pages--; | ||
| 57 | } | ||
| 58 | } else { | ||
| 59 | memset(page_address(pages), 0, size); | ||
| 60 | } | ||
| 61 | |||
| 45 | table = kmalloc(sizeof(*table), GFP_KERNEL); | 62 | table = kmalloc(sizeof(*table), GFP_KERNEL); |
| 46 | if (!table) | 63 | if (!table) |
| 47 | goto err; | 64 | goto err; |
diff --git a/drivers/staging/fsl-mc/bus/Kconfig b/drivers/staging/fsl-mc/bus/Kconfig index 1f9100049176..b35ef7ee6901 100644 --- a/drivers/staging/fsl-mc/bus/Kconfig +++ b/drivers/staging/fsl-mc/bus/Kconfig | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | config FSL_MC_BUS | 8 | config FSL_MC_BUS |
| 9 | bool "QorIQ DPAA2 fsl-mc bus driver" | 9 | bool "QorIQ DPAA2 fsl-mc bus driver" |
| 10 | depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86 || PPC))) | 10 | depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86_LOCAL_APIC || PPC))) |
| 11 | select GENERIC_MSI_IRQ_DOMAIN | 11 | select GENERIC_MSI_IRQ_DOMAIN |
| 12 | help | 12 | help |
| 13 | Driver to enable the bus infrastructure for the QorIQ DPAA2 | 13 | Driver to enable the bus infrastructure for the QorIQ DPAA2 |
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c index 5064d5ddf581..fc2013aade51 100644 --- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | |||
| @@ -73,6 +73,8 @@ static int __init its_fsl_mc_msi_init(void) | |||
| 73 | 73 | ||
| 74 | for (np = of_find_matching_node(NULL, its_device_id); np; | 74 | for (np = of_find_matching_node(NULL, its_device_id); np; |
| 75 | np = of_find_matching_node(np, its_device_id)) { | 75 | np = of_find_matching_node(np, its_device_id)) { |
| 76 | if (!of_device_is_available(np)) | ||
| 77 | continue; | ||
| 76 | if (!of_property_read_bool(np, "msi-controller")) | 78 | if (!of_property_read_bool(np, "msi-controller")) |
| 77 | continue; | 79 | continue; |
| 78 | 80 | ||
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index f01595593ce2..425e8b82533b 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
| @@ -141,6 +141,8 @@ | |||
| 141 | #define AD7192_GPOCON_P1DAT BIT(1) /* P1 state */ | 141 | #define AD7192_GPOCON_P1DAT BIT(1) /* P1 state */ |
| 142 | #define AD7192_GPOCON_P0DAT BIT(0) /* P0 state */ | 142 | #define AD7192_GPOCON_P0DAT BIT(0) /* P0 state */ |
| 143 | 143 | ||
| 144 | #define AD7192_EXT_FREQ_MHZ_MIN 2457600 | ||
| 145 | #define AD7192_EXT_FREQ_MHZ_MAX 5120000 | ||
| 144 | #define AD7192_INT_FREQ_MHZ 4915200 | 146 | #define AD7192_INT_FREQ_MHZ 4915200 |
| 145 | 147 | ||
| 146 | /* NOTE: | 148 | /* NOTE: |
| @@ -218,6 +220,12 @@ static int ad7192_calibrate_all(struct ad7192_state *st) | |||
| 218 | ARRAY_SIZE(ad7192_calib_arr)); | 220 | ARRAY_SIZE(ad7192_calib_arr)); |
| 219 | } | 221 | } |
| 220 | 222 | ||
| 223 | static inline bool ad7192_valid_external_frequency(u32 freq) | ||
| 224 | { | ||
| 225 | return (freq >= AD7192_EXT_FREQ_MHZ_MIN && | ||
| 226 | freq <= AD7192_EXT_FREQ_MHZ_MAX); | ||
| 227 | } | ||
| 228 | |||
| 221 | static int ad7192_setup(struct ad7192_state *st, | 229 | static int ad7192_setup(struct ad7192_state *st, |
| 222 | const struct ad7192_platform_data *pdata) | 230 | const struct ad7192_platform_data *pdata) |
| 223 | { | 231 | { |
| @@ -243,17 +251,20 @@ static int ad7192_setup(struct ad7192_state *st, | |||
| 243 | id); | 251 | id); |
| 244 | 252 | ||
| 245 | switch (pdata->clock_source_sel) { | 253 | switch (pdata->clock_source_sel) { |
| 246 | case AD7192_CLK_EXT_MCLK1_2: | ||
| 247 | case AD7192_CLK_EXT_MCLK2: | ||
| 248 | st->mclk = AD7192_INT_FREQ_MHZ; | ||
| 249 | break; | ||
| 250 | case AD7192_CLK_INT: | 254 | case AD7192_CLK_INT: |
| 251 | case AD7192_CLK_INT_CO: | 255 | case AD7192_CLK_INT_CO: |
| 252 | if (pdata->ext_clk_hz) | 256 | st->mclk = AD7192_INT_FREQ_MHZ; |
| 253 | st->mclk = pdata->ext_clk_hz; | ||
| 254 | else | ||
| 255 | st->mclk = AD7192_INT_FREQ_MHZ; | ||
| 256 | break; | 257 | break; |
| 258 | case AD7192_CLK_EXT_MCLK1_2: | ||
| 259 | case AD7192_CLK_EXT_MCLK2: | ||
| 260 | if (ad7192_valid_external_frequency(pdata->ext_clk_hz)) { | ||
| 261 | st->mclk = pdata->ext_clk_hz; | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | dev_err(&st->sd.spi->dev, "Invalid frequency setting %u\n", | ||
| 265 | pdata->ext_clk_hz); | ||
| 266 | ret = -EINVAL; | ||
| 267 | goto out; | ||
| 257 | default: | 268 | default: |
| 258 | ret = -EINVAL; | 269 | ret = -EINVAL; |
| 259 | goto out; | 270 | goto out; |
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 2b28fb9c0048..3bcf49466361 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c | |||
| @@ -648,8 +648,6 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) | |||
| 648 | /* Ring buffer functions - here trigger setup related */ | 648 | /* Ring buffer functions - here trigger setup related */ |
| 649 | indio_dev->setup_ops = &ad5933_ring_setup_ops; | 649 | indio_dev->setup_ops = &ad5933_ring_setup_ops; |
| 650 | 650 | ||
| 651 | indio_dev->modes |= INDIO_BUFFER_HARDWARE; | ||
| 652 | |||
| 653 | return 0; | 651 | return 0; |
| 654 | } | 652 | } |
| 655 | 653 | ||
| @@ -762,7 +760,7 @@ static int ad5933_probe(struct i2c_client *client, | |||
| 762 | indio_dev->dev.parent = &client->dev; | 760 | indio_dev->dev.parent = &client->dev; |
| 763 | indio_dev->info = &ad5933_info; | 761 | indio_dev->info = &ad5933_info; |
| 764 | indio_dev->name = id->name; | 762 | indio_dev->name = id->name; |
| 765 | indio_dev->modes = INDIO_DIRECT_MODE; | 763 | indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE); |
| 766 | indio_dev->channels = ad5933_channels; | 764 | indio_dev->channels = ad5933_channels; |
| 767 | indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); | 765 | indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); |
| 768 | 766 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 06b3b54a0e68..7b366a6c0b49 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -174,6 +174,7 @@ static int acm_wb_alloc(struct acm *acm) | |||
| 174 | wb = &acm->wb[wbn]; | 174 | wb = &acm->wb[wbn]; |
| 175 | if (!wb->use) { | 175 | if (!wb->use) { |
| 176 | wb->use = 1; | 176 | wb->use = 1; |
| 177 | wb->len = 0; | ||
| 177 | return wbn; | 178 | return wbn; |
| 178 | } | 179 | } |
| 179 | wbn = (wbn + 1) % ACM_NW; | 180 | wbn = (wbn + 1) % ACM_NW; |
| @@ -805,16 +806,18 @@ static int acm_tty_write(struct tty_struct *tty, | |||
| 805 | static void acm_tty_flush_chars(struct tty_struct *tty) | 806 | static void acm_tty_flush_chars(struct tty_struct *tty) |
| 806 | { | 807 | { |
| 807 | struct acm *acm = tty->driver_data; | 808 | struct acm *acm = tty->driver_data; |
| 808 | struct acm_wb *cur = acm->putbuffer; | 809 | struct acm_wb *cur; |
| 809 | int err; | 810 | int err; |
| 810 | unsigned long flags; | 811 | unsigned long flags; |
| 811 | 812 | ||
| 813 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 814 | |||
| 815 | cur = acm->putbuffer; | ||
| 812 | if (!cur) /* nothing to do */ | 816 | if (!cur) /* nothing to do */ |
| 813 | return; | 817 | goto out; |
| 814 | 818 | ||
| 815 | acm->putbuffer = NULL; | 819 | acm->putbuffer = NULL; |
| 816 | err = usb_autopm_get_interface_async(acm->control); | 820 | err = usb_autopm_get_interface_async(acm->control); |
| 817 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 818 | if (err < 0) { | 821 | if (err < 0) { |
| 819 | cur->use = 0; | 822 | cur->use = 0; |
| 820 | acm->putbuffer = cur; | 823 | acm->putbuffer = cur; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 4024926c1d68..f4a548471f0f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -226,6 +226,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 226 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = | 226 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = |
| 227 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | 227 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, |
| 228 | 228 | ||
| 229 | /* Corsair K70 RGB */ | ||
| 230 | { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
| 231 | |||
| 229 | /* Corsair Strafe RGB */ | 232 | /* Corsair Strafe RGB */ |
| 230 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, | 233 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 231 | 234 | ||
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e4c3ce0de5de..5bcad1d869b5 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -1917,7 +1917,9 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg, | |||
| 1917 | /* Not specific buffer needed for ep0 ZLP */ | 1917 | /* Not specific buffer needed for ep0 ZLP */ |
| 1918 | dma_addr_t dma = hs_ep->desc_list_dma; | 1918 | dma_addr_t dma = hs_ep->desc_list_dma; |
| 1919 | 1919 | ||
| 1920 | dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); | 1920 | if (!index) |
| 1921 | dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); | ||
| 1922 | |||
| 1921 | dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0); | 1923 | dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0); |
| 1922 | } else { | 1924 | } else { |
| 1923 | dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | | 1925 | dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | |
| @@ -2974,9 +2976,13 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | |||
| 2974 | if (ints & DXEPINT_STSPHSERCVD) { | 2976 | if (ints & DXEPINT_STSPHSERCVD) { |
| 2975 | dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__); | 2977 | dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__); |
| 2976 | 2978 | ||
| 2977 | /* Move to STATUS IN for DDMA */ | 2979 | /* Safety check EP0 state when STSPHSERCVD asserted */ |
| 2978 | if (using_desc_dma(hsotg)) | 2980 | if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) { |
| 2979 | dwc2_hsotg_ep0_zlp(hsotg, true); | 2981 | /* Move to STATUS IN for DDMA */ |
| 2982 | if (using_desc_dma(hsotg)) | ||
| 2983 | dwc2_hsotg_ep0_zlp(hsotg, true); | ||
| 2984 | } | ||
| 2985 | |||
| 2980 | } | 2986 | } |
| 2981 | 2987 | ||
| 2982 | if (ints & DXEPINT_BACK2BACKSETUP) | 2988 | if (ints & DXEPINT_BACK2BACKSETUP) |
| @@ -3375,12 +3381,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, | |||
| 3375 | dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | | 3381 | dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | |
| 3376 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); | 3382 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); |
| 3377 | 3383 | ||
| 3378 | dwc2_hsotg_enqueue_setup(hsotg); | ||
| 3379 | |||
| 3380 | dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
| 3381 | dwc2_readl(hsotg->regs + DIEPCTL0), | ||
| 3382 | dwc2_readl(hsotg->regs + DOEPCTL0)); | ||
| 3383 | |||
| 3384 | /* clear global NAKs */ | 3384 | /* clear global NAKs */ |
| 3385 | val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; | 3385 | val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; |
| 3386 | if (!is_usb_reset) | 3386 | if (!is_usb_reset) |
| @@ -3391,6 +3391,12 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, | |||
| 3391 | mdelay(3); | 3391 | mdelay(3); |
| 3392 | 3392 | ||
| 3393 | hsotg->lx_state = DWC2_L0; | 3393 | hsotg->lx_state = DWC2_L0; |
| 3394 | |||
| 3395 | dwc2_hsotg_enqueue_setup(hsotg); | ||
| 3396 | |||
| 3397 | dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
| 3398 | dwc2_readl(hsotg->regs + DIEPCTL0), | ||
| 3399 | dwc2_readl(hsotg->regs + DOEPCTL0)); | ||
| 3394 | } | 3400 | } |
| 3395 | 3401 | ||
| 3396 | static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) | 3402 | static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ade2ab00d37a..f1d838a4acd6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -100,6 +100,8 @@ static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) | |||
| 100 | reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); | 100 | reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); |
| 101 | reg |= DWC3_GCTL_PRTCAPDIR(mode); | 101 | reg |= DWC3_GCTL_PRTCAPDIR(mode); |
| 102 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 102 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
| 103 | |||
| 104 | dwc->current_dr_role = mode; | ||
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | static void __dwc3_set_mode(struct work_struct *work) | 107 | static void __dwc3_set_mode(struct work_struct *work) |
| @@ -133,8 +135,6 @@ static void __dwc3_set_mode(struct work_struct *work) | |||
| 133 | 135 | ||
| 134 | dwc3_set_prtcap(dwc, dwc->desired_dr_role); | 136 | dwc3_set_prtcap(dwc, dwc->desired_dr_role); |
| 135 | 137 | ||
| 136 | dwc->current_dr_role = dwc->desired_dr_role; | ||
| 137 | |||
| 138 | spin_unlock_irqrestore(&dwc->lock, flags); | 138 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 139 | 139 | ||
| 140 | switch (dwc->desired_dr_role) { | 140 | switch (dwc->desired_dr_role) { |
| @@ -219,7 +219,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) | |||
| 219 | * XHCI driver will reset the host block. If dwc3 was configured for | 219 | * XHCI driver will reset the host block. If dwc3 was configured for |
| 220 | * host-only mode, then we can return early. | 220 | * host-only mode, then we can return early. |
| 221 | */ | 221 | */ |
| 222 | if (dwc->dr_mode == USB_DR_MODE_HOST) | 222 | if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) |
| 223 | return 0; | 223 | return 0; |
| 224 | 224 | ||
| 225 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 225 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
| @@ -234,6 +234,9 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) | |||
| 234 | udelay(1); | 234 | udelay(1); |
| 235 | } while (--retries); | 235 | } while (--retries); |
| 236 | 236 | ||
| 237 | phy_exit(dwc->usb3_generic_phy); | ||
| 238 | phy_exit(dwc->usb2_generic_phy); | ||
| 239 | |||
| 237 | return -ETIMEDOUT; | 240 | return -ETIMEDOUT; |
| 238 | } | 241 | } |
| 239 | 242 | ||
| @@ -483,6 +486,22 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) | |||
| 483 | parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); | 486 | parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); |
| 484 | } | 487 | } |
| 485 | 488 | ||
| 489 | static int dwc3_core_ulpi_init(struct dwc3 *dwc) | ||
| 490 | { | ||
| 491 | int intf; | ||
| 492 | int ret = 0; | ||
| 493 | |||
| 494 | intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3); | ||
| 495 | |||
| 496 | if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI || | ||
| 497 | (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI && | ||
| 498 | dwc->hsphy_interface && | ||
| 499 | !strncmp(dwc->hsphy_interface, "ulpi", 4))) | ||
| 500 | ret = dwc3_ulpi_init(dwc); | ||
| 501 | |||
| 502 | return ret; | ||
| 503 | } | ||
| 504 | |||
| 486 | /** | 505 | /** |
| 487 | * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core | 506 | * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core |
| 488 | * @dwc: Pointer to our controller context structure | 507 | * @dwc: Pointer to our controller context structure |
| @@ -494,7 +513,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) | |||
| 494 | static int dwc3_phy_setup(struct dwc3 *dwc) | 513 | static int dwc3_phy_setup(struct dwc3 *dwc) |
| 495 | { | 514 | { |
| 496 | u32 reg; | 515 | u32 reg; |
| 497 | int ret; | ||
| 498 | 516 | ||
| 499 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | 517 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
| 500 | 518 | ||
| @@ -565,9 +583,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
| 565 | } | 583 | } |
| 566 | /* FALLTHROUGH */ | 584 | /* FALLTHROUGH */ |
| 567 | case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: | 585 | case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: |
| 568 | ret = dwc3_ulpi_init(dwc); | ||
| 569 | if (ret) | ||
| 570 | return ret; | ||
| 571 | /* FALLTHROUGH */ | 586 | /* FALLTHROUGH */ |
| 572 | default: | 587 | default: |
| 573 | break; | 588 | break; |
| @@ -724,6 +739,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) | |||
| 724 | } | 739 | } |
| 725 | 740 | ||
| 726 | static int dwc3_core_get_phy(struct dwc3 *dwc); | 741 | static int dwc3_core_get_phy(struct dwc3 *dwc); |
| 742 | static int dwc3_core_ulpi_init(struct dwc3 *dwc); | ||
| 727 | 743 | ||
| 728 | /** | 744 | /** |
| 729 | * dwc3_core_init - Low-level initialization of DWC3 Core | 745 | * dwc3_core_init - Low-level initialization of DWC3 Core |
| @@ -755,17 +771,27 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
| 755 | dwc->maximum_speed = USB_SPEED_HIGH; | 771 | dwc->maximum_speed = USB_SPEED_HIGH; |
| 756 | } | 772 | } |
| 757 | 773 | ||
| 758 | ret = dwc3_core_get_phy(dwc); | 774 | ret = dwc3_phy_setup(dwc); |
| 759 | if (ret) | 775 | if (ret) |
| 760 | goto err0; | 776 | goto err0; |
| 761 | 777 | ||
| 762 | ret = dwc3_core_soft_reset(dwc); | 778 | if (!dwc->ulpi_ready) { |
| 763 | if (ret) | 779 | ret = dwc3_core_ulpi_init(dwc); |
| 764 | goto err0; | 780 | if (ret) |
| 781 | goto err0; | ||
| 782 | dwc->ulpi_ready = true; | ||
| 783 | } | ||
| 765 | 784 | ||
| 766 | ret = dwc3_phy_setup(dwc); | 785 | if (!dwc->phys_ready) { |
| 786 | ret = dwc3_core_get_phy(dwc); | ||
| 787 | if (ret) | ||
| 788 | goto err0a; | ||
| 789 | dwc->phys_ready = true; | ||
| 790 | } | ||
| 791 | |||
| 792 | ret = dwc3_core_soft_reset(dwc); | ||
| 767 | if (ret) | 793 | if (ret) |
| 768 | goto err0; | 794 | goto err0a; |
| 769 | 795 | ||
| 770 | dwc3_core_setup_global_control(dwc); | 796 | dwc3_core_setup_global_control(dwc); |
| 771 | dwc3_core_num_eps(dwc); | 797 | dwc3_core_num_eps(dwc); |
| @@ -838,6 +864,9 @@ err1: | |||
| 838 | phy_exit(dwc->usb2_generic_phy); | 864 | phy_exit(dwc->usb2_generic_phy); |
| 839 | phy_exit(dwc->usb3_generic_phy); | 865 | phy_exit(dwc->usb3_generic_phy); |
| 840 | 866 | ||
| 867 | err0a: | ||
| 868 | dwc3_ulpi_exit(dwc); | ||
| 869 | |||
| 841 | err0: | 870 | err0: |
| 842 | return ret; | 871 | return ret; |
| 843 | } | 872 | } |
| @@ -916,7 +945,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) | |||
| 916 | 945 | ||
| 917 | switch (dwc->dr_mode) { | 946 | switch (dwc->dr_mode) { |
| 918 | case USB_DR_MODE_PERIPHERAL: | 947 | case USB_DR_MODE_PERIPHERAL: |
| 919 | dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE; | ||
| 920 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); | 948 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); |
| 921 | 949 | ||
| 922 | if (dwc->usb2_phy) | 950 | if (dwc->usb2_phy) |
| @@ -932,7 +960,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) | |||
| 932 | } | 960 | } |
| 933 | break; | 961 | break; |
| 934 | case USB_DR_MODE_HOST: | 962 | case USB_DR_MODE_HOST: |
| 935 | dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST; | ||
| 936 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); | 963 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); |
| 937 | 964 | ||
| 938 | if (dwc->usb2_phy) | 965 | if (dwc->usb2_phy) |
| @@ -1234,7 +1261,6 @@ err4: | |||
| 1234 | 1261 | ||
| 1235 | err3: | 1262 | err3: |
| 1236 | dwc3_free_event_buffers(dwc); | 1263 | dwc3_free_event_buffers(dwc); |
| 1237 | dwc3_ulpi_exit(dwc); | ||
| 1238 | 1264 | ||
| 1239 | err2: | 1265 | err2: |
| 1240 | pm_runtime_allow(&pdev->dev); | 1266 | pm_runtime_allow(&pdev->dev); |
| @@ -1284,7 +1310,7 @@ static int dwc3_remove(struct platform_device *pdev) | |||
| 1284 | } | 1310 | } |
| 1285 | 1311 | ||
| 1286 | #ifdef CONFIG_PM | 1312 | #ifdef CONFIG_PM |
| 1287 | static int dwc3_suspend_common(struct dwc3 *dwc) | 1313 | static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) |
| 1288 | { | 1314 | { |
| 1289 | unsigned long flags; | 1315 | unsigned long flags; |
| 1290 | 1316 | ||
| @@ -1296,6 +1322,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc) | |||
| 1296 | dwc3_core_exit(dwc); | 1322 | dwc3_core_exit(dwc); |
| 1297 | break; | 1323 | break; |
| 1298 | case DWC3_GCTL_PRTCAP_HOST: | 1324 | case DWC3_GCTL_PRTCAP_HOST: |
| 1325 | /* do nothing during host runtime_suspend */ | ||
| 1326 | if (!PMSG_IS_AUTO(msg)) | ||
| 1327 | dwc3_core_exit(dwc); | ||
| 1328 | break; | ||
| 1299 | default: | 1329 | default: |
| 1300 | /* do nothing */ | 1330 | /* do nothing */ |
| 1301 | break; | 1331 | break; |
| @@ -1304,7 +1334,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc) | |||
| 1304 | return 0; | 1334 | return 0; |
| 1305 | } | 1335 | } |
| 1306 | 1336 | ||
| 1307 | static int dwc3_resume_common(struct dwc3 *dwc) | 1337 | static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) |
| 1308 | { | 1338 | { |
| 1309 | unsigned long flags; | 1339 | unsigned long flags; |
| 1310 | int ret; | 1340 | int ret; |
| @@ -1320,6 +1350,13 @@ static int dwc3_resume_common(struct dwc3 *dwc) | |||
| 1320 | spin_unlock_irqrestore(&dwc->lock, flags); | 1350 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 1321 | break; | 1351 | break; |
| 1322 | case DWC3_GCTL_PRTCAP_HOST: | 1352 | case DWC3_GCTL_PRTCAP_HOST: |
| 1353 | /* nothing to do on host runtime_resume */ | ||
| 1354 | if (!PMSG_IS_AUTO(msg)) { | ||
| 1355 | ret = dwc3_core_init(dwc); | ||
| 1356 | if (ret) | ||
| 1357 | return ret; | ||
| 1358 | } | ||
| 1359 | break; | ||
| 1323 | default: | 1360 | default: |
| 1324 | /* do nothing */ | 1361 | /* do nothing */ |
| 1325 | break; | 1362 | break; |
| @@ -1331,12 +1368,11 @@ static int dwc3_resume_common(struct dwc3 *dwc) | |||
| 1331 | static int dwc3_runtime_checks(struct dwc3 *dwc) | 1368 | static int dwc3_runtime_checks(struct dwc3 *dwc) |
| 1332 | { | 1369 | { |
| 1333 | switch (dwc->current_dr_role) { | 1370 | switch (dwc->current_dr_role) { |
| 1334 | case USB_DR_MODE_PERIPHERAL: | 1371 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 1335 | case USB_DR_MODE_OTG: | ||
| 1336 | if (dwc->connected) | 1372 | if (dwc->connected) |
| 1337 | return -EBUSY; | 1373 | return -EBUSY; |
| 1338 | break; | 1374 | break; |
| 1339 | case USB_DR_MODE_HOST: | 1375 | case DWC3_GCTL_PRTCAP_HOST: |
| 1340 | default: | 1376 | default: |
| 1341 | /* do nothing */ | 1377 | /* do nothing */ |
| 1342 | break; | 1378 | break; |
| @@ -1353,7 +1389,7 @@ static int dwc3_runtime_suspend(struct device *dev) | |||
| 1353 | if (dwc3_runtime_checks(dwc)) | 1389 | if (dwc3_runtime_checks(dwc)) |
| 1354 | return -EBUSY; | 1390 | return -EBUSY; |
| 1355 | 1391 | ||
| 1356 | ret = dwc3_suspend_common(dwc); | 1392 | ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND); |
| 1357 | if (ret) | 1393 | if (ret) |
| 1358 | return ret; | 1394 | return ret; |
| 1359 | 1395 | ||
| @@ -1369,7 +1405,7 @@ static int dwc3_runtime_resume(struct device *dev) | |||
| 1369 | 1405 | ||
| 1370 | device_init_wakeup(dev, false); | 1406 | device_init_wakeup(dev, false); |
| 1371 | 1407 | ||
| 1372 | ret = dwc3_resume_common(dwc); | 1408 | ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME); |
| 1373 | if (ret) | 1409 | if (ret) |
| 1374 | return ret; | 1410 | return ret; |
| 1375 | 1411 | ||
| @@ -1416,7 +1452,7 @@ static int dwc3_suspend(struct device *dev) | |||
| 1416 | struct dwc3 *dwc = dev_get_drvdata(dev); | 1452 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 1417 | int ret; | 1453 | int ret; |
| 1418 | 1454 | ||
| 1419 | ret = dwc3_suspend_common(dwc); | 1455 | ret = dwc3_suspend_common(dwc, PMSG_SUSPEND); |
| 1420 | if (ret) | 1456 | if (ret) |
| 1421 | return ret; | 1457 | return ret; |
| 1422 | 1458 | ||
| @@ -1432,7 +1468,7 @@ static int dwc3_resume(struct device *dev) | |||
| 1432 | 1468 | ||
| 1433 | pinctrl_pm_select_default_state(dev); | 1469 | pinctrl_pm_select_default_state(dev); |
| 1434 | 1470 | ||
| 1435 | ret = dwc3_resume_common(dwc); | 1471 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
| 1436 | if (ret) | 1472 | if (ret) |
| 1437 | return ret; | 1473 | return ret; |
| 1438 | 1474 | ||
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 03c7aaaac926..860d2bc184d1 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
| @@ -158,13 +158,15 @@ | |||
| 158 | #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) | 158 | #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) |
| 159 | #define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff) | 159 | #define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff) |
| 160 | 160 | ||
| 161 | #define DWC3_TXFIFOQ 1 | 161 | #define DWC3_TXFIFOQ 0 |
| 162 | #define DWC3_RXFIFOQ 3 | 162 | #define DWC3_RXFIFOQ 1 |
| 163 | #define DWC3_TXREQQ 5 | 163 | #define DWC3_TXREQQ 2 |
| 164 | #define DWC3_RXREQQ 7 | 164 | #define DWC3_RXREQQ 3 |
| 165 | #define DWC3_RXINFOQ 9 | 165 | #define DWC3_RXINFOQ 4 |
| 166 | #define DWC3_DESCFETCHQ 13 | 166 | #define DWC3_PSTATQ 5 |
| 167 | #define DWC3_EVENTQ 15 | 167 | #define DWC3_DESCFETCHQ 6 |
| 168 | #define DWC3_EVENTQ 7 | ||
| 169 | #define DWC3_AUXEVENTQ 8 | ||
| 168 | 170 | ||
| 169 | /* Global RX Threshold Configuration Register */ | 171 | /* Global RX Threshold Configuration Register */ |
| 170 | #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19) | 172 | #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19) |
| @@ -795,7 +797,9 @@ struct dwc3_scratchpad_array { | |||
| 795 | * @usb3_phy: pointer to USB3 PHY | 797 | * @usb3_phy: pointer to USB3 PHY |
| 796 | * @usb2_generic_phy: pointer to USB2 PHY | 798 | * @usb2_generic_phy: pointer to USB2 PHY |
| 797 | * @usb3_generic_phy: pointer to USB3 PHY | 799 | * @usb3_generic_phy: pointer to USB3 PHY |
| 800 | * @phys_ready: flag to indicate that PHYs are ready | ||
| 798 | * @ulpi: pointer to ulpi interface | 801 | * @ulpi: pointer to ulpi interface |
| 802 | * @ulpi_ready: flag to indicate that ULPI is initialized | ||
| 799 | * @u2sel: parameter from Set SEL request. | 803 | * @u2sel: parameter from Set SEL request. |
| 800 | * @u2pel: parameter from Set SEL request. | 804 | * @u2pel: parameter from Set SEL request. |
| 801 | * @u1sel: parameter from Set SEL request. | 805 | * @u1sel: parameter from Set SEL request. |
| @@ -893,7 +897,10 @@ struct dwc3 { | |||
| 893 | struct phy *usb2_generic_phy; | 897 | struct phy *usb2_generic_phy; |
| 894 | struct phy *usb3_generic_phy; | 898 | struct phy *usb3_generic_phy; |
| 895 | 899 | ||
| 900 | bool phys_ready; | ||
| 901 | |||
| 896 | struct ulpi *ulpi; | 902 | struct ulpi *ulpi; |
| 903 | bool ulpi_ready; | ||
| 897 | 904 | ||
| 898 | void __iomem *regs; | 905 | void __iomem *regs; |
| 899 | size_t regs_size; | 906 | size_t regs_size; |
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 7ae0eefc7cc7..e54c3622eb28 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c | |||
| @@ -143,6 +143,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev) | |||
| 143 | clk_disable_unprepare(simple->clks[i]); | 143 | clk_disable_unprepare(simple->clks[i]); |
| 144 | clk_put(simple->clks[i]); | 144 | clk_put(simple->clks[i]); |
| 145 | } | 145 | } |
| 146 | simple->num_clocks = 0; | ||
| 146 | 147 | ||
| 147 | reset_control_assert(simple->resets); | 148 | reset_control_assert(simple->resets); |
| 148 | reset_control_put(simple->resets); | 149 | reset_control_put(simple->resets); |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index a4719e853b85..ed8b86517675 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
| @@ -582,9 +582,25 @@ static int dwc3_omap_resume(struct device *dev) | |||
| 582 | return 0; | 582 | return 0; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | static void dwc3_omap_complete(struct device *dev) | ||
| 586 | { | ||
| 587 | struct dwc3_omap *omap = dev_get_drvdata(dev); | ||
| 588 | |||
| 589 | if (extcon_get_state(omap->edev, EXTCON_USB)) | ||
| 590 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
| 591 | else | ||
| 592 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF); | ||
| 593 | |||
| 594 | if (extcon_get_state(omap->edev, EXTCON_USB_HOST)) | ||
| 595 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
| 596 | else | ||
| 597 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT); | ||
| 598 | } | ||
| 599 | |||
| 585 | static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { | 600 | static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { |
| 586 | 601 | ||
| 587 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume) | 602 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume) |
| 603 | .complete = dwc3_omap_complete, | ||
| 588 | }; | 604 | }; |
| 589 | 605 | ||
| 590 | #define DEV_PM_OPS (&dwc3_omap_dev_pm_ops) | 606 | #define DEV_PM_OPS (&dwc3_omap_dev_pm_ops) |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9c2e4a17918e..18be31d5743a 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
| @@ -854,7 +854,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
| 854 | trb++; | 854 | trb++; |
| 855 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | 855 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; |
| 856 | trace_dwc3_complete_trb(ep0, trb); | 856 | trace_dwc3_complete_trb(ep0, trb); |
| 857 | ep0->trb_enqueue = 0; | 857 | |
| 858 | if (r->direction) | ||
| 859 | dwc->eps[1]->trb_enqueue = 0; | ||
| 860 | else | ||
| 861 | dwc->eps[0]->trb_enqueue = 0; | ||
| 862 | |||
| 858 | dwc->ep0_bounced = false; | 863 | dwc->ep0_bounced = false; |
| 859 | } | 864 | } |
| 860 | 865 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 616ef49ccb49..2bda4eb1e9ac 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -2745,6 +2745,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | |||
| 2745 | break; | 2745 | break; |
| 2746 | } | 2746 | } |
| 2747 | 2747 | ||
| 2748 | dwc->eps[1]->endpoint.maxpacket = dwc->gadget.ep0->maxpacket; | ||
| 2749 | |||
| 2748 | /* Enable USB2 LPM Capability */ | 2750 | /* Enable USB2 LPM Capability */ |
| 2749 | 2751 | ||
| 2750 | if ((dwc->revision > DWC3_REVISION_194A) && | 2752 | if ((dwc->revision > DWC3_REVISION_194A) && |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 8f2cf3baa19c..c2592d883f67 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
| @@ -1855,44 +1855,20 @@ static int ffs_func_eps_enable(struct ffs_function *func) | |||
| 1855 | 1855 | ||
| 1856 | spin_lock_irqsave(&func->ffs->eps_lock, flags); | 1856 | spin_lock_irqsave(&func->ffs->eps_lock, flags); |
| 1857 | while(count--) { | 1857 | while(count--) { |
| 1858 | struct usb_endpoint_descriptor *ds; | ||
| 1859 | struct usb_ss_ep_comp_descriptor *comp_desc = NULL; | ||
| 1860 | int needs_comp_desc = false; | ||
| 1861 | int desc_idx; | ||
| 1862 | |||
| 1863 | if (ffs->gadget->speed == USB_SPEED_SUPER) { | ||
| 1864 | desc_idx = 2; | ||
| 1865 | needs_comp_desc = true; | ||
| 1866 | } else if (ffs->gadget->speed == USB_SPEED_HIGH) | ||
| 1867 | desc_idx = 1; | ||
| 1868 | else | ||
| 1869 | desc_idx = 0; | ||
| 1870 | |||
| 1871 | /* fall-back to lower speed if desc missing for current speed */ | ||
| 1872 | do { | ||
| 1873 | ds = ep->descs[desc_idx]; | ||
| 1874 | } while (!ds && --desc_idx >= 0); | ||
| 1875 | |||
| 1876 | if (!ds) { | ||
| 1877 | ret = -EINVAL; | ||
| 1878 | break; | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | ep->ep->driver_data = ep; | 1858 | ep->ep->driver_data = ep; |
| 1882 | ep->ep->desc = ds; | ||
| 1883 | 1859 | ||
| 1884 | if (needs_comp_desc) { | 1860 | ret = config_ep_by_speed(func->gadget, &func->function, ep->ep); |
| 1885 | comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + | 1861 | if (ret) { |
| 1886 | USB_DT_ENDPOINT_SIZE); | 1862 | pr_err("%s: config_ep_by_speed(%s) returned %d\n", |
| 1887 | ep->ep->maxburst = comp_desc->bMaxBurst + 1; | 1863 | __func__, ep->ep->name, ret); |
| 1888 | ep->ep->comp_desc = comp_desc; | 1864 | break; |
| 1889 | } | 1865 | } |
| 1890 | 1866 | ||
| 1891 | ret = usb_ep_enable(ep->ep); | 1867 | ret = usb_ep_enable(ep->ep); |
| 1892 | if (likely(!ret)) { | 1868 | if (likely(!ret)) { |
| 1893 | epfile->ep = ep; | 1869 | epfile->ep = ep; |
| 1894 | epfile->in = usb_endpoint_dir_in(ds); | 1870 | epfile->in = usb_endpoint_dir_in(ep->ep->desc); |
| 1895 | epfile->isoc = usb_endpoint_xfer_isoc(ds); | 1871 | epfile->isoc = usb_endpoint_xfer_isoc(ep->ep->desc); |
| 1896 | } else { | 1872 | } else { |
| 1897 | break; | 1873 | break; |
| 1898 | } | 1874 | } |
| @@ -2979,10 +2955,8 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2979 | struct ffs_data *ffs = func->ffs; | 2955 | struct ffs_data *ffs = func->ffs; |
| 2980 | 2956 | ||
| 2981 | const int full = !!func->ffs->fs_descs_count; | 2957 | const int full = !!func->ffs->fs_descs_count; |
| 2982 | const int high = gadget_is_dualspeed(func->gadget) && | 2958 | const int high = !!func->ffs->hs_descs_count; |
| 2983 | func->ffs->hs_descs_count; | 2959 | const int super = !!func->ffs->ss_descs_count; |
| 2984 | const int super = gadget_is_superspeed(func->gadget) && | ||
| 2985 | func->ffs->ss_descs_count; | ||
| 2986 | 2960 | ||
| 2987 | int fs_len, hs_len, ss_len, ret, i; | 2961 | int fs_len, hs_len, ss_len, ret, i; |
| 2988 | struct ffs_ep *eps_ptr; | 2962 | struct ffs_ep *eps_ptr; |
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 11fe788b4308..d2dc1f00180b 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c | |||
| @@ -524,6 +524,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
| 524 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | 524 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); |
| 525 | return ret; | 525 | return ret; |
| 526 | } | 526 | } |
| 527 | iad_desc.bFirstInterface = ret; | ||
| 528 | |||
| 527 | std_ac_if_desc.bInterfaceNumber = ret; | 529 | std_ac_if_desc.bInterfaceNumber = ret; |
| 528 | uac2->ac_intf = ret; | 530 | uac2->ac_intf = ret; |
| 529 | uac2->ac_alt = 0; | 531 | uac2->ac_alt = 0; |
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 1e9567091d86..0875d38476ee 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig | |||
| @@ -274,7 +274,6 @@ config USB_SNP_UDC_PLAT | |||
| 274 | tristate "Synopsys USB 2.0 Device controller" | 274 | tristate "Synopsys USB 2.0 Device controller" |
| 275 | depends on USB_GADGET && OF && HAS_DMA | 275 | depends on USB_GADGET && OF && HAS_DMA |
| 276 | depends on EXTCON || EXTCON=n | 276 | depends on EXTCON || EXTCON=n |
| 277 | select USB_GADGET_DUALSPEED | ||
| 278 | select USB_SNP_CORE | 277 | select USB_SNP_CORE |
| 279 | default ARCH_BCM_IPROC | 278 | default ARCH_BCM_IPROC |
| 280 | help | 279 | help |
diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c index 1e940f054cb8..6dbc489513cd 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_pci.c +++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c | |||
| @@ -77,6 +77,7 @@ static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) | |||
| 77 | if (ret) { | 77 | if (ret) { |
| 78 | dev_err(&pci->dev, | 78 | dev_err(&pci->dev, |
| 79 | "couldn't add resources to bdc device\n"); | 79 | "couldn't add resources to bdc device\n"); |
| 80 | platform_device_put(bdc); | ||
| 80 | return ret; | 81 | return ret; |
| 81 | } | 82 | } |
| 82 | 83 | ||
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 859d5b11ba4c..1f8b19d9cf97 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c | |||
| @@ -180,8 +180,8 @@ EXPORT_SYMBOL_GPL(usb_ep_alloc_request); | |||
| 180 | void usb_ep_free_request(struct usb_ep *ep, | 180 | void usb_ep_free_request(struct usb_ep *ep, |
| 181 | struct usb_request *req) | 181 | struct usb_request *req) |
| 182 | { | 182 | { |
| 183 | ep->ops->free_request(ep, req); | ||
| 184 | trace_usb_ep_free_request(ep, req, 0); | 183 | trace_usb_ep_free_request(ep, req, 0); |
| 184 | ep->ops->free_request(ep, req); | ||
| 185 | } | 185 | } |
| 186 | EXPORT_SYMBOL_GPL(usb_ep_free_request); | 186 | EXPORT_SYMBOL_GPL(usb_ep_free_request); |
| 187 | 187 | ||
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index e5b4ee96c4bf..56b517a38865 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c | |||
| @@ -1305,7 +1305,7 @@ static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) | |||
| 1305 | { | 1305 | { |
| 1306 | struct fsl_ep *ep = get_ep_by_pipe(udc, pipe); | 1306 | struct fsl_ep *ep = get_ep_by_pipe(udc, pipe); |
| 1307 | 1307 | ||
| 1308 | if (ep->name) | 1308 | if (ep->ep.name) |
| 1309 | nuke(ep, -ESHUTDOWN); | 1309 | nuke(ep, -ESHUTDOWN); |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| @@ -1693,7 +1693,7 @@ static void dtd_complete_irq(struct fsl_udc *udc) | |||
| 1693 | curr_ep = get_ep_by_pipe(udc, i); | 1693 | curr_ep = get_ep_by_pipe(udc, i); |
| 1694 | 1694 | ||
| 1695 | /* If the ep is configured */ | 1695 | /* If the ep is configured */ |
| 1696 | if (curr_ep->name == NULL) { | 1696 | if (!curr_ep->ep.name) { |
| 1697 | WARNING("Invalid EP?"); | 1697 | WARNING("Invalid EP?"); |
| 1698 | continue; | 1698 | continue; |
| 1699 | } | 1699 | } |
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 6e87af248367..409cde4e6a51 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c | |||
| @@ -2410,7 +2410,7 @@ static int renesas_usb3_remove(struct platform_device *pdev) | |||
| 2410 | __renesas_usb3_ep_free_request(usb3->ep0_req); | 2410 | __renesas_usb3_ep_free_request(usb3->ep0_req); |
| 2411 | if (usb3->phy) | 2411 | if (usb3->phy) |
| 2412 | phy_put(usb3->phy); | 2412 | phy_put(usb3->phy); |
| 2413 | pm_runtime_disable(usb3_to_dev(usb3)); | 2413 | pm_runtime_disable(&pdev->dev); |
| 2414 | 2414 | ||
| 2415 | return 0; | 2415 | return 0; |
| 2416 | } | 2416 | } |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index facafdf8fb95..d7641cbdee43 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -774,12 +774,12 @@ static struct urb *request_single_step_set_feature_urb( | |||
| 774 | atomic_inc(&urb->use_count); | 774 | atomic_inc(&urb->use_count); |
| 775 | atomic_inc(&urb->dev->urbnum); | 775 | atomic_inc(&urb->dev->urbnum); |
| 776 | urb->setup_dma = dma_map_single( | 776 | urb->setup_dma = dma_map_single( |
| 777 | hcd->self.controller, | 777 | hcd->self.sysdev, |
| 778 | urb->setup_packet, | 778 | urb->setup_packet, |
| 779 | sizeof(struct usb_ctrlrequest), | 779 | sizeof(struct usb_ctrlrequest), |
| 780 | DMA_TO_DEVICE); | 780 | DMA_TO_DEVICE); |
| 781 | urb->transfer_dma = dma_map_single( | 781 | urb->transfer_dma = dma_map_single( |
| 782 | hcd->self.controller, | 782 | hcd->self.sysdev, |
| 783 | urb->transfer_buffer, | 783 | urb->transfer_buffer, |
| 784 | urb->transfer_buffer_length, | 784 | urb->transfer_buffer_length, |
| 785 | DMA_FROM_DEVICE); | 785 | DMA_FROM_DEVICE); |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 88158324dcae..327630405695 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -1188,10 +1188,10 @@ static int submit_single_step_set_feature( | |||
| 1188 | * 15 secs after the setup | 1188 | * 15 secs after the setup |
| 1189 | */ | 1189 | */ |
| 1190 | if (is_setup) { | 1190 | if (is_setup) { |
| 1191 | /* SETUP pid */ | 1191 | /* SETUP pid, and interrupt after SETUP completion */ |
| 1192 | qtd_fill(ehci, qtd, urb->setup_dma, | 1192 | qtd_fill(ehci, qtd, urb->setup_dma, |
| 1193 | sizeof(struct usb_ctrlrequest), | 1193 | sizeof(struct usb_ctrlrequest), |
| 1194 | token | (2 /* "setup" */ << 8), 8); | 1194 | QTD_IOC | token | (2 /* "setup" */ << 8), 8); |
| 1195 | 1195 | ||
| 1196 | submit_async(ehci, urb, &qtd_list, GFP_ATOMIC); | 1196 | submit_async(ehci, urb, &qtd_list, GFP_ATOMIC); |
| 1197 | return 0; /*Return now; we shall come back after 15 seconds*/ | 1197 | return 0; /*Return now; we shall come back after 15 seconds*/ |
| @@ -1228,12 +1228,8 @@ static int submit_single_step_set_feature( | |||
| 1228 | qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma); | 1228 | qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma); |
| 1229 | list_add_tail(&qtd->qtd_list, head); | 1229 | list_add_tail(&qtd->qtd_list, head); |
| 1230 | 1230 | ||
| 1231 | /* dont fill any data in such packets */ | 1231 | /* Interrupt after STATUS completion */ |
| 1232 | qtd_fill(ehci, qtd, 0, 0, token, 0); | 1232 | qtd_fill(ehci, qtd, 0, 0, token | QTD_IOC, 0); |
| 1233 | |||
| 1234 | /* by default, enable interrupt on urb completion */ | ||
| 1235 | if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT))) | ||
| 1236 | qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC); | ||
| 1237 | 1233 | ||
| 1238 | submit_async(ehci, urb, &qtd_list, GFP_KERNEL); | 1234 | submit_async(ehci, urb, &qtd_list, GFP_KERNEL); |
| 1239 | 1235 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ee9676349333..84f88fa411cd 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -74,6 +74,7 @@ static const char hcd_name [] = "ohci_hcd"; | |||
| 74 | 74 | ||
| 75 | #define STATECHANGE_DELAY msecs_to_jiffies(300) | 75 | #define STATECHANGE_DELAY msecs_to_jiffies(300) |
| 76 | #define IO_WATCHDOG_DELAY msecs_to_jiffies(275) | 76 | #define IO_WATCHDOG_DELAY msecs_to_jiffies(275) |
| 77 | #define IO_WATCHDOG_OFF 0xffffff00 | ||
| 77 | 78 | ||
| 78 | #include "ohci.h" | 79 | #include "ohci.h" |
| 79 | #include "pci-quirks.h" | 80 | #include "pci-quirks.h" |
| @@ -231,7 +232,7 @@ static int ohci_urb_enqueue ( | |||
| 231 | } | 232 | } |
| 232 | 233 | ||
| 233 | /* Start up the I/O watchdog timer, if it's not running */ | 234 | /* Start up the I/O watchdog timer, if it's not running */ |
| 234 | if (!timer_pending(&ohci->io_watchdog) && | 235 | if (ohci->prev_frame_no == IO_WATCHDOG_OFF && |
| 235 | list_empty(&ohci->eds_in_use) && | 236 | list_empty(&ohci->eds_in_use) && |
| 236 | !(ohci->flags & OHCI_QUIRK_QEMU)) { | 237 | !(ohci->flags & OHCI_QUIRK_QEMU)) { |
| 237 | ohci->prev_frame_no = ohci_frame_no(ohci); | 238 | ohci->prev_frame_no = ohci_frame_no(ohci); |
| @@ -501,6 +502,7 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
| 501 | return 0; | 502 | return 0; |
| 502 | 503 | ||
| 503 | timer_setup(&ohci->io_watchdog, io_watchdog_func, 0); | 504 | timer_setup(&ohci->io_watchdog, io_watchdog_func, 0); |
| 505 | ohci->prev_frame_no = IO_WATCHDOG_OFF; | ||
| 504 | 506 | ||
| 505 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, | 507 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, |
| 506 | sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); | 508 | sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); |
| @@ -730,7 +732,7 @@ static void io_watchdog_func(struct timer_list *t) | |||
| 730 | u32 head; | 732 | u32 head; |
| 731 | struct ed *ed; | 733 | struct ed *ed; |
| 732 | struct td *td, *td_start, *td_next; | 734 | struct td *td, *td_start, *td_next; |
| 733 | unsigned frame_no; | 735 | unsigned frame_no, prev_frame_no = IO_WATCHDOG_OFF; |
| 734 | unsigned long flags; | 736 | unsigned long flags; |
| 735 | 737 | ||
| 736 | spin_lock_irqsave(&ohci->lock, flags); | 738 | spin_lock_irqsave(&ohci->lock, flags); |
| @@ -835,7 +837,7 @@ static void io_watchdog_func(struct timer_list *t) | |||
| 835 | } | 837 | } |
| 836 | } | 838 | } |
| 837 | if (!list_empty(&ohci->eds_in_use)) { | 839 | if (!list_empty(&ohci->eds_in_use)) { |
| 838 | ohci->prev_frame_no = frame_no; | 840 | prev_frame_no = frame_no; |
| 839 | ohci->prev_wdh_cnt = ohci->wdh_cnt; | 841 | ohci->prev_wdh_cnt = ohci->wdh_cnt; |
| 840 | ohci->prev_donehead = ohci_readl(ohci, | 842 | ohci->prev_donehead = ohci_readl(ohci, |
| 841 | &ohci->regs->donehead); | 843 | &ohci->regs->donehead); |
| @@ -845,6 +847,7 @@ static void io_watchdog_func(struct timer_list *t) | |||
| 845 | } | 847 | } |
| 846 | 848 | ||
| 847 | done: | 849 | done: |
| 850 | ohci->prev_frame_no = prev_frame_no; | ||
| 848 | spin_unlock_irqrestore(&ohci->lock, flags); | 851 | spin_unlock_irqrestore(&ohci->lock, flags); |
| 849 | } | 852 | } |
| 850 | 853 | ||
| @@ -973,6 +976,7 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
| 973 | if (quirk_nec(ohci)) | 976 | if (quirk_nec(ohci)) |
| 974 | flush_work(&ohci->nec_work); | 977 | flush_work(&ohci->nec_work); |
| 975 | del_timer_sync(&ohci->io_watchdog); | 978 | del_timer_sync(&ohci->io_watchdog); |
| 979 | ohci->prev_frame_no = IO_WATCHDOG_OFF; | ||
| 976 | 980 | ||
| 977 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 981 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
| 978 | ohci_usb_reset(ohci); | 982 | ohci_usb_reset(ohci); |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index fb7aaa3b9d06..634f3c7bf774 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
| @@ -311,8 +311,10 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) | |||
| 311 | rc = ohci_rh_suspend (ohci, 0); | 311 | rc = ohci_rh_suspend (ohci, 0); |
| 312 | spin_unlock_irq (&ohci->lock); | 312 | spin_unlock_irq (&ohci->lock); |
| 313 | 313 | ||
| 314 | if (rc == 0) | 314 | if (rc == 0) { |
| 315 | del_timer_sync(&ohci->io_watchdog); | 315 | del_timer_sync(&ohci->io_watchdog); |
| 316 | ohci->prev_frame_no = IO_WATCHDOG_OFF; | ||
| 317 | } | ||
| 316 | return rc; | 318 | return rc; |
| 317 | } | 319 | } |
| 318 | 320 | ||
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index b2ec8c399363..4ccb85a67bb3 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
| @@ -1019,6 +1019,8 @@ skip_ed: | |||
| 1019 | * have modified this list. normally it's just prepending | 1019 | * have modified this list. normally it's just prepending |
| 1020 | * entries (which we'd ignore), but paranoia won't hurt. | 1020 | * entries (which we'd ignore), but paranoia won't hurt. |
| 1021 | */ | 1021 | */ |
| 1022 | *last = ed->ed_next; | ||
| 1023 | ed->ed_next = NULL; | ||
| 1022 | modified = 0; | 1024 | modified = 0; |
| 1023 | 1025 | ||
| 1024 | /* unlink urbs as requested, but rescan the list after | 1026 | /* unlink urbs as requested, but rescan the list after |
| @@ -1077,21 +1079,22 @@ rescan_this: | |||
| 1077 | goto rescan_this; | 1079 | goto rescan_this; |
| 1078 | 1080 | ||
| 1079 | /* | 1081 | /* |
| 1080 | * If no TDs are queued, take ED off the ed_rm_list. | 1082 | * If no TDs are queued, ED is now idle. |
| 1081 | * Otherwise, if the HC is running, reschedule. | 1083 | * Otherwise, if the HC is running, reschedule. |
| 1082 | * If not, leave it on the list for further dequeues. | 1084 | * If the HC isn't running, add ED back to the |
| 1085 | * start of the list for later processing. | ||
| 1083 | */ | 1086 | */ |
| 1084 | if (list_empty(&ed->td_list)) { | 1087 | if (list_empty(&ed->td_list)) { |
| 1085 | *last = ed->ed_next; | ||
| 1086 | ed->ed_next = NULL; | ||
| 1087 | ed->state = ED_IDLE; | 1088 | ed->state = ED_IDLE; |
| 1088 | list_del(&ed->in_use_list); | 1089 | list_del(&ed->in_use_list); |
| 1089 | } else if (ohci->rh_state == OHCI_RH_RUNNING) { | 1090 | } else if (ohci->rh_state == OHCI_RH_RUNNING) { |
| 1090 | *last = ed->ed_next; | ||
| 1091 | ed->ed_next = NULL; | ||
| 1092 | ed_schedule(ohci, ed); | 1091 | ed_schedule(ohci, ed); |
| 1093 | } else { | 1092 | } else { |
| 1094 | last = &ed->ed_next; | 1093 | ed->ed_next = ohci->ed_rm_list; |
| 1094 | ohci->ed_rm_list = ed; | ||
| 1095 | /* Don't loop on the same ED */ | ||
| 1096 | if (last == &ohci->ed_rm_list) | ||
| 1097 | last = &ed->ed_next; | ||
| 1095 | } | 1098 | } |
| 1096 | 1099 | ||
| 1097 | if (modified) | 1100 | if (modified) |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 161536717025..67ad4bb6919a 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -66,6 +66,23 @@ | |||
| 66 | #define AX_INDXC 0x30 | 66 | #define AX_INDXC 0x30 |
| 67 | #define AX_DATAC 0x34 | 67 | #define AX_DATAC 0x34 |
| 68 | 68 | ||
| 69 | #define PT_ADDR_INDX 0xE8 | ||
| 70 | #define PT_READ_INDX 0xE4 | ||
| 71 | #define PT_SIG_1_ADDR 0xA520 | ||
| 72 | #define PT_SIG_2_ADDR 0xA521 | ||
| 73 | #define PT_SIG_3_ADDR 0xA522 | ||
| 74 | #define PT_SIG_4_ADDR 0xA523 | ||
| 75 | #define PT_SIG_1_DATA 0x78 | ||
| 76 | #define PT_SIG_2_DATA 0x56 | ||
| 77 | #define PT_SIG_3_DATA 0x34 | ||
| 78 | #define PT_SIG_4_DATA 0x12 | ||
| 79 | #define PT4_P1_REG 0xB521 | ||
| 80 | #define PT4_P2_REG 0xB522 | ||
| 81 | #define PT2_P1_REG 0xD520 | ||
| 82 | #define PT2_P2_REG 0xD521 | ||
| 83 | #define PT1_P1_REG 0xD522 | ||
| 84 | #define PT1_P2_REG 0xD523 | ||
| 85 | |||
| 69 | #define NB_PCIE_INDX_ADDR 0xe0 | 86 | #define NB_PCIE_INDX_ADDR 0xe0 |
| 70 | #define NB_PCIE_INDX_DATA 0xe4 | 87 | #define NB_PCIE_INDX_DATA 0xe4 |
| 71 | #define PCIE_P_CNTL 0x10040 | 88 | #define PCIE_P_CNTL 0x10040 |
| @@ -513,6 +530,98 @@ void usb_amd_dev_put(void) | |||
| 513 | EXPORT_SYMBOL_GPL(usb_amd_dev_put); | 530 | EXPORT_SYMBOL_GPL(usb_amd_dev_put); |
| 514 | 531 | ||
| 515 | /* | 532 | /* |
| 533 | * Check if port is disabled in BIOS on AMD Promontory host. | ||
| 534 | * BIOS Disabled ports may wake on connect/disconnect and need | ||
| 535 | * driver workaround to keep them disabled. | ||
| 536 | * Returns true if port is marked disabled. | ||
| 537 | */ | ||
| 538 | bool usb_amd_pt_check_port(struct device *device, int port) | ||
| 539 | { | ||
| 540 | unsigned char value, port_shift; | ||
| 541 | struct pci_dev *pdev; | ||
| 542 | u16 reg; | ||
| 543 | |||
| 544 | pdev = to_pci_dev(device); | ||
| 545 | pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_1_ADDR); | ||
| 546 | |||
| 547 | pci_read_config_byte(pdev, PT_READ_INDX, &value); | ||
| 548 | if (value != PT_SIG_1_DATA) | ||
| 549 | return false; | ||
| 550 | |||
| 551 | pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_2_ADDR); | ||
| 552 | |||
| 553 | pci_read_config_byte(pdev, PT_READ_INDX, &value); | ||
| 554 | if (value != PT_SIG_2_DATA) | ||
| 555 | return false; | ||
| 556 | |||
| 557 | pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_3_ADDR); | ||
| 558 | |||
| 559 | pci_read_config_byte(pdev, PT_READ_INDX, &value); | ||
| 560 | if (value != PT_SIG_3_DATA) | ||
| 561 | return false; | ||
| 562 | |||
| 563 | pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_4_ADDR); | ||
| 564 | |||
| 565 | pci_read_config_byte(pdev, PT_READ_INDX, &value); | ||
| 566 | if (value != PT_SIG_4_DATA) | ||
| 567 | return false; | ||
| 568 | |||
| 569 | /* Check disabled port setting, if bit is set port is enabled */ | ||
| 570 | switch (pdev->device) { | ||
| 571 | case 0x43b9: | ||
| 572 | case 0x43ba: | ||
| 573 | /* | ||
| 574 | * device is AMD_PROMONTORYA_4(0x43b9) or PROMONTORYA_3(0x43ba) | ||
| 575 | * PT4_P1_REG bits[7..1] represents USB2.0 ports 6 to 0 | ||
| 576 | * PT4_P2_REG bits[6..0] represents ports 13 to 7 | ||
| 577 | */ | ||
| 578 | if (port > 6) { | ||
| 579 | reg = PT4_P2_REG; | ||
| 580 | port_shift = port - 7; | ||
| 581 | } else { | ||
| 582 | reg = PT4_P1_REG; | ||
| 583 | port_shift = port + 1; | ||
| 584 | } | ||
| 585 | break; | ||
| 586 | case 0x43bb: | ||
| 587 | /* | ||
| 588 | * device is AMD_PROMONTORYA_2(0x43bb) | ||
| 589 | * PT2_P1_REG bits[7..5] represents USB2.0 ports 2 to 0 | ||
| 590 | * PT2_P2_REG bits[5..0] represents ports 9 to 3 | ||
| 591 | */ | ||
| 592 | if (port > 2) { | ||
| 593 | reg = PT2_P2_REG; | ||
| 594 | port_shift = port - 3; | ||
| 595 | } else { | ||
| 596 | reg = PT2_P1_REG; | ||
| 597 | port_shift = port + 5; | ||
| 598 | } | ||
| 599 | break; | ||
| 600 | case 0x43bc: | ||
| 601 | /* | ||
| 602 | * device is AMD_PROMONTORYA_1(0x43bc) | ||
| 603 | * PT1_P1_REG[7..4] represents USB2.0 ports 3 to 0 | ||
| 604 | * PT1_P2_REG[5..0] represents ports 9 to 4 | ||
| 605 | */ | ||
| 606 | if (port > 3) { | ||
| 607 | reg = PT1_P2_REG; | ||
| 608 | port_shift = port - 4; | ||
| 609 | } else { | ||
| 610 | reg = PT1_P1_REG; | ||
| 611 | port_shift = port + 4; | ||
| 612 | } | ||
| 613 | break; | ||
| 614 | default: | ||
| 615 | return false; | ||
| 616 | } | ||
| 617 | pci_write_config_word(pdev, PT_ADDR_INDX, reg); | ||
| 618 | pci_read_config_byte(pdev, PT_READ_INDX, &value); | ||
| 619 | |||
| 620 | return !(value & BIT(port_shift)); | ||
| 621 | } | ||
| 622 | EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); | ||
| 623 | |||
| 624 | /* | ||
| 516 | * Make sure the controller is completely inactive, unable to | 625 | * Make sure the controller is completely inactive, unable to |
| 517 | * generate interrupts or do DMA. | 626 | * generate interrupts or do DMA. |
| 518 | */ | 627 | */ |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index b68dcb5dd0fd..4ca0d9b7e463 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
| @@ -17,6 +17,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); | |||
| 17 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | 17 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); |
| 18 | void sb800_prefetch(struct device *dev, int on); | 18 | void sb800_prefetch(struct device *dev, int on); |
| 19 | bool usb_xhci_needs_pci_reset(struct pci_dev *pdev); | 19 | bool usb_xhci_needs_pci_reset(struct pci_dev *pdev); |
| 20 | bool usb_amd_pt_check_port(struct device *device, int port); | ||
| 20 | #else | 21 | #else |
| 21 | struct pci_dev; | 22 | struct pci_dev; |
| 22 | static inline void usb_amd_quirk_pll_disable(void) {} | 23 | static inline void usb_amd_quirk_pll_disable(void) {} |
| @@ -25,6 +26,10 @@ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} | |||
| 25 | static inline void usb_amd_dev_put(void) {} | 26 | static inline void usb_amd_dev_put(void) {} |
| 26 | static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} | 27 | static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} |
| 27 | static inline void sb800_prefetch(struct device *dev, int on) {} | 28 | static inline void sb800_prefetch(struct device *dev, int on) {} |
| 29 | static inline bool usb_amd_pt_check_port(struct device *device, int port) | ||
| 30 | { | ||
| 31 | return false; | ||
| 32 | } | ||
| 28 | #endif /* CONFIG_USB_PCI */ | 33 | #endif /* CONFIG_USB_PCI */ |
| 29 | 34 | ||
| 30 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ | 35 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ |
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index e26e685d8a57..5851052d4668 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c | |||
| @@ -211,7 +211,7 @@ static void xhci_ring_dump_segment(struct seq_file *s, | |||
| 211 | static int xhci_ring_trb_show(struct seq_file *s, void *unused) | 211 | static int xhci_ring_trb_show(struct seq_file *s, void *unused) |
| 212 | { | 212 | { |
| 213 | int i; | 213 | int i; |
| 214 | struct xhci_ring *ring = s->private; | 214 | struct xhci_ring *ring = *(struct xhci_ring **)s->private; |
| 215 | struct xhci_segment *seg = ring->first_seg; | 215 | struct xhci_segment *seg = ring->first_seg; |
| 216 | 216 | ||
| 217 | for (i = 0; i < ring->num_segs; i++) { | 217 | for (i = 0; i < ring->num_segs; i++) { |
| @@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, | |||
| 387 | 387 | ||
| 388 | snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); | 388 | snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); |
| 389 | epriv->root = xhci_debugfs_create_ring_dir(xhci, | 389 | epriv->root = xhci_debugfs_create_ring_dir(xhci, |
| 390 | &dev->eps[ep_index].new_ring, | 390 | &dev->eps[ep_index].ring, |
| 391 | epriv->name, | 391 | epriv->name, |
| 392 | spriv->root); | 392 | spriv->root); |
| 393 | spriv->eps[ep_index] = epriv; | 393 | spriv->eps[ep_index] = epriv; |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 46d5e08f05f1..72ebbc908e19 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
| @@ -1224,17 +1224,17 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 1224 | temp = readl(port_array[wIndex]); | 1224 | temp = readl(port_array[wIndex]); |
| 1225 | break; | 1225 | break; |
| 1226 | } | 1226 | } |
| 1227 | 1227 | /* Port must be enabled */ | |
| 1228 | /* Software should not attempt to set | 1228 | if (!(temp & PORT_PE)) { |
| 1229 | * port link state above '3' (U3) and the port | 1229 | retval = -ENODEV; |
| 1230 | * must be enabled. | 1230 | break; |
| 1231 | */ | 1231 | } |
| 1232 | if ((temp & PORT_PE) == 0 || | 1232 | /* Can't set port link state above '3' (U3) */ |
| 1233 | (link_state > USB_SS_PORT_LS_U3)) { | 1233 | if (link_state > USB_SS_PORT_LS_U3) { |
| 1234 | xhci_warn(xhci, "Cannot set link state.\n"); | 1234 | xhci_warn(xhci, "Cannot set port %d link state %d\n", |
| 1235 | wIndex, link_state); | ||
| 1235 | goto error; | 1236 | goto error; |
| 1236 | } | 1237 | } |
| 1237 | |||
| 1238 | if (link_state == USB_SS_PORT_LS_U3) { | 1238 | if (link_state == USB_SS_PORT_LS_U3) { |
| 1239 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | 1239 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, |
| 1240 | wIndex + 1); | 1240 | wIndex + 1); |
| @@ -1522,6 +1522,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
| 1522 | t2 |= PORT_WKOC_E | PORT_WKCONN_E; | 1522 | t2 |= PORT_WKOC_E | PORT_WKCONN_E; |
| 1523 | t2 &= ~PORT_WKDISC_E; | 1523 | t2 &= ~PORT_WKDISC_E; |
| 1524 | } | 1524 | } |
| 1525 | |||
| 1526 | if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && | ||
| 1527 | (hcd->speed < HCD_USB3)) { | ||
| 1528 | if (usb_amd_pt_check_port(hcd->self.controller, | ||
| 1529 | port_index)) | ||
| 1530 | t2 &= ~PORT_WAKE_BITS; | ||
| 1531 | } | ||
| 1525 | } else | 1532 | } else |
| 1526 | t2 &= ~PORT_WAKE_BITS; | 1533 | t2 &= ~PORT_WAKE_BITS; |
| 1527 | 1534 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 6c79037876db..5262fa571a5d 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -42,6 +42,10 @@ | |||
| 42 | #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 | 42 | #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 |
| 43 | #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 | 43 | #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 |
| 44 | 44 | ||
| 45 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 | ||
| 46 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba | ||
| 47 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb | ||
| 48 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc | ||
| 45 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 | 49 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 46 | 50 | ||
| 47 | static const char hcd_name[] = "xhci_hcd"; | 51 | static const char hcd_name[] = "xhci_hcd"; |
| @@ -125,6 +129,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 125 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | 129 | if (pdev->vendor == PCI_VENDOR_ID_AMD) |
| 126 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 130 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| 127 | 131 | ||
| 132 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) && | ||
| 133 | ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || | ||
| 134 | (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || | ||
| 135 | (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || | ||
| 136 | (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) | ||
| 137 | xhci->quirks |= XHCI_U2_DISABLE_WAKE; | ||
| 138 | |||
| 128 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | 139 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
| 129 | xhci->quirks |= XHCI_LPM_SUPPORT; | 140 | xhci->quirks |= XHCI_LPM_SUPPORT; |
| 130 | xhci->quirks |= XHCI_INTEL_HOST; | 141 | xhci->quirks |= XHCI_INTEL_HOST; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1eeb3396300f..25d4b748a56f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -646,8 +646,6 @@ static void xhci_stop(struct usb_hcd *hcd) | |||
| 646 | return; | 646 | return; |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | xhci_debugfs_exit(xhci); | ||
| 650 | |||
| 651 | xhci_dbc_exit(xhci); | 649 | xhci_dbc_exit(xhci); |
| 652 | 650 | ||
| 653 | spin_lock_irq(&xhci->lock); | 651 | spin_lock_irq(&xhci->lock); |
| @@ -680,6 +678,7 @@ static void xhci_stop(struct usb_hcd *hcd) | |||
| 680 | 678 | ||
| 681 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory"); | 679 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory"); |
| 682 | xhci_mem_cleanup(xhci); | 680 | xhci_mem_cleanup(xhci); |
| 681 | xhci_debugfs_exit(xhci); | ||
| 683 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 682 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
| 684 | "xhci_stop completed - status = %x", | 683 | "xhci_stop completed - status = %x", |
| 685 | readl(&xhci->op_regs->status)); | 684 | readl(&xhci->op_regs->status)); |
| @@ -1014,6 +1013,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
| 1014 | 1013 | ||
| 1015 | xhci_dbg(xhci, "cleaning up memory\n"); | 1014 | xhci_dbg(xhci, "cleaning up memory\n"); |
| 1016 | xhci_mem_cleanup(xhci); | 1015 | xhci_mem_cleanup(xhci); |
| 1016 | xhci_debugfs_exit(xhci); | ||
| 1017 | xhci_dbg(xhci, "xhci_stop completed - status = %x\n", | 1017 | xhci_dbg(xhci, "xhci_stop completed - status = %x\n", |
| 1018 | readl(&xhci->op_regs->status)); | 1018 | readl(&xhci->op_regs->status)); |
| 1019 | 1019 | ||
| @@ -3544,12 +3544,10 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 3544 | virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING; | 3544 | virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING; |
| 3545 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); | 3545 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); |
| 3546 | } | 3546 | } |
| 3547 | 3547 | xhci_debugfs_remove_slot(xhci, udev->slot_id); | |
| 3548 | ret = xhci_disable_slot(xhci, udev->slot_id); | 3548 | ret = xhci_disable_slot(xhci, udev->slot_id); |
| 3549 | if (ret) { | 3549 | if (ret) |
| 3550 | xhci_debugfs_remove_slot(xhci, udev->slot_id); | ||
| 3551 | xhci_free_virt_device(xhci, udev->slot_id); | 3550 | xhci_free_virt_device(xhci, udev->slot_id); |
| 3552 | } | ||
| 3553 | } | 3551 | } |
| 3554 | 3552 | ||
| 3555 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) | 3553 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 96099a245c69..e4d7d3d06a75 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
| @@ -1822,7 +1822,7 @@ struct xhci_hcd { | |||
| 1822 | /* For controller with a broken Port Disable implementation */ | 1822 | /* For controller with a broken Port Disable implementation */ |
| 1823 | #define XHCI_BROKEN_PORT_PED (1 << 25) | 1823 | #define XHCI_BROKEN_PORT_PED (1 << 25) |
| 1824 | #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) | 1824 | #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) |
| 1825 | /* Reserved. It was XHCI_U2_DISABLE_WAKE */ | 1825 | #define XHCI_U2_DISABLE_WAKE (1 << 27) |
| 1826 | #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) | 1826 | #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) |
| 1827 | #define XHCI_HW_LPM_DISABLE (1 << 29) | 1827 | #define XHCI_HW_LPM_DISABLE (1 << 29) |
| 1828 | 1828 | ||
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 63b9e85dc0e9..236a60f53099 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
| @@ -42,6 +42,9 @@ | |||
| 42 | #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 /* USB Product ID of Micro-CASSY Time (reserved) */ | 42 | #define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 /* USB Product ID of Micro-CASSY Time (reserved) */ |
| 43 | #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 /* USB Product ID of Micro-CASSY Temperature */ | 43 | #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 /* USB Product ID of Micro-CASSY Temperature */ |
| 44 | #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 /* USB Product ID of Micro-CASSY pH */ | 44 | #define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 /* USB Product ID of Micro-CASSY pH */ |
| 45 | #define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040 /* USB Product ID of Power Analyser CASSY */ | ||
| 46 | #define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042 /* USB Product ID of Converter Controller CASSY */ | ||
| 47 | #define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043 /* USB Product ID of Machine Test CASSY */ | ||
| 45 | #define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */ | 48 | #define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */ |
| 46 | #define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */ | 49 | #define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */ |
| 47 | #define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */ | 50 | #define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */ |
| @@ -84,6 +87,9 @@ static const struct usb_device_id ld_usb_table[] = { | |||
| 84 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, | 87 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, |
| 85 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, | 88 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, |
| 86 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, | 89 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, |
| 90 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) }, | ||
| 91 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) }, | ||
| 92 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) }, | ||
| 87 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, | 93 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, |
| 88 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, | 94 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, |
| 89 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, | 95 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 968bf1e8b0fe..eef4ad578b31 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -2708,7 +2708,8 @@ static int musb_resume(struct device *dev) | |||
| 2708 | if ((devctl & mask) != (musb->context.devctl & mask)) | 2708 | if ((devctl & mask) != (musb->context.devctl & mask)) |
| 2709 | musb->port1_status = 0; | 2709 | musb->port1_status = 0; |
| 2710 | 2710 | ||
| 2711 | musb_start(musb); | 2711 | musb_enable_interrupts(musb); |
| 2712 | musb_platform_enable(musb); | ||
| 2712 | 2713 | ||
| 2713 | spin_lock_irqsave(&musb->lock, flags); | 2714 | spin_lock_irqsave(&musb->lock, flags); |
| 2714 | error = musb_run_resume_work(musb); | 2715 | error = musb_run_resume_work(musb); |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 394b4ac86161..45ed32c2cba9 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -391,13 +391,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
| 391 | } | 391 | } |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | /* | 394 | if (qh != NULL && qh->is_ready) { |
| 395 | * The pipe must be broken if current urb->status is set, so don't | ||
| 396 | * start next urb. | ||
| 397 | * TODO: to minimize the risk of regression, only check urb->status | ||
| 398 | * for RX, until we have a test case to understand the behavior of TX. | ||
| 399 | */ | ||
| 400 | if ((!status || !is_in) && qh && qh->is_ready) { | ||
| 401 | musb_dbg(musb, "... next ep%d %cX urb %p", | 395 | musb_dbg(musb, "... next ep%d %cX urb %p", |
| 402 | hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); | 396 | hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); |
| 403 | musb_start_urb(musb, is_in, qh); | 397 | musb_start_urb(musb, is_in, qh); |
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index da031c45395a..fbec863350f6 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
| @@ -602,6 +602,9 @@ static enum usb_charger_type mxs_phy_charger_detect(struct usb_phy *phy) | |||
| 602 | void __iomem *base = phy->io_priv; | 602 | void __iomem *base = phy->io_priv; |
| 603 | enum usb_charger_type chgr_type = UNKNOWN_TYPE; | 603 | enum usb_charger_type chgr_type = UNKNOWN_TYPE; |
| 604 | 604 | ||
| 605 | if (!regmap) | ||
| 606 | return UNKNOWN_TYPE; | ||
| 607 | |||
| 605 | if (mxs_charger_data_contact_detect(mxs_phy)) | 608 | if (mxs_charger_data_contact_detect(mxs_phy)) |
| 606 | return chgr_type; | 609 | return chgr_type; |
| 607 | 610 | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 5925d111bd47..39fa2fc1b8b7 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
| @@ -982,6 +982,10 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt, | |||
| 982 | if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1)) | 982 | if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1)) |
| 983 | goto usbhsf_pio_prepare_pop; | 983 | goto usbhsf_pio_prepare_pop; |
| 984 | 984 | ||
| 985 | /* return at this time if the pipe is running */ | ||
| 986 | if (usbhs_pipe_is_running(pipe)) | ||
| 987 | return 0; | ||
| 988 | |||
| 985 | usbhs_pipe_config_change_bfre(pipe, 1); | 989 | usbhs_pipe_config_change_bfre(pipe, 1); |
| 986 | 990 | ||
| 987 | ret = usbhsf_fifo_select(pipe, fifo, 0); | 991 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
| @@ -1172,6 +1176,7 @@ static int usbhsf_dma_pop_done_with_usb_dmac(struct usbhs_pkt *pkt, | |||
| 1172 | usbhsf_fifo_clear(pipe, fifo); | 1176 | usbhsf_fifo_clear(pipe, fifo); |
| 1173 | pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len); | 1177 | pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len); |
| 1174 | 1178 | ||
| 1179 | usbhs_pipe_running(pipe, 0); | ||
| 1175 | usbhsf_dma_stop(pipe, fifo); | 1180 | usbhsf_dma_stop(pipe, fifo); |
| 1176 | usbhsf_dma_unmap(pkt); | 1181 | usbhsf_dma_unmap(pkt); |
| 1177 | usbhsf_fifo_unselect(pipe, pipe->fifo); | 1182 | usbhsf_fifo_unselect(pipe, pipe->fifo); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5db8ed517e0e..2d8d9150da0c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -241,6 +241,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 241 | #define QUECTEL_PRODUCT_EC21 0x0121 | 241 | #define QUECTEL_PRODUCT_EC21 0x0121 |
| 242 | #define QUECTEL_PRODUCT_EC25 0x0125 | 242 | #define QUECTEL_PRODUCT_EC25 0x0125 |
| 243 | #define QUECTEL_PRODUCT_BG96 0x0296 | 243 | #define QUECTEL_PRODUCT_BG96 0x0296 |
| 244 | #define QUECTEL_PRODUCT_EP06 0x0306 | ||
| 244 | 245 | ||
| 245 | #define CMOTECH_VENDOR_ID 0x16d8 | 246 | #define CMOTECH_VENDOR_ID 0x16d8 |
| 246 | #define CMOTECH_PRODUCT_6001 0x6001 | 247 | #define CMOTECH_PRODUCT_6001 0x6001 |
| @@ -689,6 +690,10 @@ static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { | |||
| 689 | .reserved = BIT(1) | BIT(4), | 690 | .reserved = BIT(1) | BIT(4), |
| 690 | }; | 691 | }; |
| 691 | 692 | ||
| 693 | static const struct option_blacklist_info quectel_ep06_blacklist = { | ||
| 694 | .reserved = BIT(4) | BIT(5), | ||
| 695 | }; | ||
| 696 | |||
| 692 | static const struct usb_device_id option_ids[] = { | 697 | static const struct usb_device_id option_ids[] = { |
| 693 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 698 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 694 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 699 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -1203,6 +1208,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 1203 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1208 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 1204 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), | 1209 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), |
| 1205 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1210 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 1211 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), | ||
| 1212 | .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist }, | ||
| 1206 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 1213 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
| 1207 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, | 1214 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, |
| 1208 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), | 1215 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), |
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 49e552472c3f..dd8ef36ab10e 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c | |||
| @@ -73,6 +73,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a | |||
| 73 | goto err; | 73 | goto err; |
| 74 | 74 | ||
| 75 | sdev->ud.tcp_socket = socket; | 75 | sdev->ud.tcp_socket = socket; |
| 76 | sdev->ud.sockfd = sockfd; | ||
| 76 | 77 | ||
| 77 | spin_unlock_irq(&sdev->ud.lock); | 78 | spin_unlock_irq(&sdev->ud.lock); |
| 78 | 79 | ||
| @@ -172,6 +173,7 @@ static void stub_shutdown_connection(struct usbip_device *ud) | |||
| 172 | if (ud->tcp_socket) { | 173 | if (ud->tcp_socket) { |
| 173 | sockfd_put(ud->tcp_socket); | 174 | sockfd_put(ud->tcp_socket); |
| 174 | ud->tcp_socket = NULL; | 175 | ud->tcp_socket = NULL; |
| 176 | ud->sockfd = -1; | ||
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | /* 3. free used data */ | 179 | /* 3. free used data */ |
| @@ -266,6 +268,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev) | |||
| 266 | sdev->ud.status = SDEV_ST_AVAILABLE; | 268 | sdev->ud.status = SDEV_ST_AVAILABLE; |
| 267 | spin_lock_init(&sdev->ud.lock); | 269 | spin_lock_init(&sdev->ud.lock); |
| 268 | sdev->ud.tcp_socket = NULL; | 270 | sdev->ud.tcp_socket = NULL; |
| 271 | sdev->ud.sockfd = -1; | ||
| 269 | 272 | ||
| 270 | INIT_LIST_HEAD(&sdev->priv_init); | 273 | INIT_LIST_HEAD(&sdev->priv_init); |
| 271 | INIT_LIST_HEAD(&sdev->priv_tx); | 274 | INIT_LIST_HEAD(&sdev->priv_tx); |
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c3e1008aa491..20e3d4609583 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
| @@ -984,6 +984,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) | |||
| 984 | if (vdev->ud.tcp_socket) { | 984 | if (vdev->ud.tcp_socket) { |
| 985 | sockfd_put(vdev->ud.tcp_socket); | 985 | sockfd_put(vdev->ud.tcp_socket); |
| 986 | vdev->ud.tcp_socket = NULL; | 986 | vdev->ud.tcp_socket = NULL; |
| 987 | vdev->ud.sockfd = -1; | ||
| 987 | } | 988 | } |
| 988 | pr_info("release socket\n"); | 989 | pr_info("release socket\n"); |
| 989 | 990 | ||
| @@ -1030,6 +1031,7 @@ static void vhci_device_reset(struct usbip_device *ud) | |||
| 1030 | if (ud->tcp_socket) { | 1031 | if (ud->tcp_socket) { |
| 1031 | sockfd_put(ud->tcp_socket); | 1032 | sockfd_put(ud->tcp_socket); |
| 1032 | ud->tcp_socket = NULL; | 1033 | ud->tcp_socket = NULL; |
| 1034 | ud->sockfd = -1; | ||
| 1033 | } | 1035 | } |
| 1034 | ud->status = VDEV_ST_NULL; | 1036 | ud->status = VDEV_ST_NULL; |
| 1035 | 1037 | ||
diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 753d9cb437d0..aedbee3b2838 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c | |||
| @@ -60,6 +60,7 @@ struct sock_mapping { | |||
| 60 | bool active_socket; | 60 | bool active_socket; |
| 61 | struct list_head list; | 61 | struct list_head list; |
| 62 | struct socket *sock; | 62 | struct socket *sock; |
| 63 | atomic_t refcount; | ||
| 63 | union { | 64 | union { |
| 64 | struct { | 65 | struct { |
| 65 | int irq; | 66 | int irq; |
| @@ -93,6 +94,32 @@ struct sock_mapping { | |||
| 93 | }; | 94 | }; |
| 94 | }; | 95 | }; |
| 95 | 96 | ||
| 97 | static inline struct sock_mapping *pvcalls_enter_sock(struct socket *sock) | ||
| 98 | { | ||
| 99 | struct sock_mapping *map; | ||
| 100 | |||
| 101 | if (!pvcalls_front_dev || | ||
| 102 | dev_get_drvdata(&pvcalls_front_dev->dev) == NULL) | ||
| 103 | return ERR_PTR(-ENOTCONN); | ||
| 104 | |||
| 105 | map = (struct sock_mapping *)sock->sk->sk_send_head; | ||
| 106 | if (map == NULL) | ||
| 107 | return ERR_PTR(-ENOTSOCK); | ||
| 108 | |||
| 109 | pvcalls_enter(); | ||
| 110 | atomic_inc(&map->refcount); | ||
| 111 | return map; | ||
| 112 | } | ||
| 113 | |||
| 114 | static inline void pvcalls_exit_sock(struct socket *sock) | ||
| 115 | { | ||
| 116 | struct sock_mapping *map; | ||
| 117 | |||
| 118 | map = (struct sock_mapping *)sock->sk->sk_send_head; | ||
| 119 | atomic_dec(&map->refcount); | ||
| 120 | pvcalls_exit(); | ||
| 121 | } | ||
| 122 | |||
| 96 | static inline int get_request(struct pvcalls_bedata *bedata, int *req_id) | 123 | static inline int get_request(struct pvcalls_bedata *bedata, int *req_id) |
| 97 | { | 124 | { |
| 98 | *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1); | 125 | *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1); |
| @@ -369,31 +396,23 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, | |||
| 369 | if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) | 396 | if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) |
| 370 | return -EOPNOTSUPP; | 397 | return -EOPNOTSUPP; |
| 371 | 398 | ||
| 372 | pvcalls_enter(); | 399 | map = pvcalls_enter_sock(sock); |
| 373 | if (!pvcalls_front_dev) { | 400 | if (IS_ERR(map)) |
| 374 | pvcalls_exit(); | 401 | return PTR_ERR(map); |
| 375 | return -ENOTCONN; | ||
| 376 | } | ||
| 377 | 402 | ||
| 378 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 403 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 379 | 404 | ||
| 380 | map = (struct sock_mapping *)sock->sk->sk_send_head; | ||
| 381 | if (!map) { | ||
| 382 | pvcalls_exit(); | ||
| 383 | return -ENOTSOCK; | ||
| 384 | } | ||
| 385 | |||
| 386 | spin_lock(&bedata->socket_lock); | 405 | spin_lock(&bedata->socket_lock); |
| 387 | ret = get_request(bedata, &req_id); | 406 | ret = get_request(bedata, &req_id); |
| 388 | if (ret < 0) { | 407 | if (ret < 0) { |
| 389 | spin_unlock(&bedata->socket_lock); | 408 | spin_unlock(&bedata->socket_lock); |
| 390 | pvcalls_exit(); | 409 | pvcalls_exit_sock(sock); |
| 391 | return ret; | 410 | return ret; |
| 392 | } | 411 | } |
| 393 | ret = create_active(map, &evtchn); | 412 | ret = create_active(map, &evtchn); |
| 394 | if (ret < 0) { | 413 | if (ret < 0) { |
| 395 | spin_unlock(&bedata->socket_lock); | 414 | spin_unlock(&bedata->socket_lock); |
| 396 | pvcalls_exit(); | 415 | pvcalls_exit_sock(sock); |
| 397 | return ret; | 416 | return ret; |
| 398 | } | 417 | } |
| 399 | 418 | ||
| @@ -423,7 +442,7 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, | |||
| 423 | smp_rmb(); | 442 | smp_rmb(); |
| 424 | ret = bedata->rsp[req_id].ret; | 443 | ret = bedata->rsp[req_id].ret; |
| 425 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; | 444 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; |
| 426 | pvcalls_exit(); | 445 | pvcalls_exit_sock(sock); |
| 427 | return ret; | 446 | return ret; |
| 428 | } | 447 | } |
| 429 | 448 | ||
| @@ -488,23 +507,15 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 488 | if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB)) | 507 | if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB)) |
| 489 | return -EOPNOTSUPP; | 508 | return -EOPNOTSUPP; |
| 490 | 509 | ||
| 491 | pvcalls_enter(); | 510 | map = pvcalls_enter_sock(sock); |
| 492 | if (!pvcalls_front_dev) { | 511 | if (IS_ERR(map)) |
| 493 | pvcalls_exit(); | 512 | return PTR_ERR(map); |
| 494 | return -ENOTCONN; | ||
| 495 | } | ||
| 496 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 513 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 497 | 514 | ||
| 498 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 499 | if (!map) { | ||
| 500 | pvcalls_exit(); | ||
| 501 | return -ENOTSOCK; | ||
| 502 | } | ||
| 503 | |||
| 504 | mutex_lock(&map->active.out_mutex); | 515 | mutex_lock(&map->active.out_mutex); |
| 505 | if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { | 516 | if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { |
| 506 | mutex_unlock(&map->active.out_mutex); | 517 | mutex_unlock(&map->active.out_mutex); |
| 507 | pvcalls_exit(); | 518 | pvcalls_exit_sock(sock); |
| 508 | return -EAGAIN; | 519 | return -EAGAIN; |
| 509 | } | 520 | } |
| 510 | if (len > INT_MAX) | 521 | if (len > INT_MAX) |
| @@ -526,7 +537,7 @@ again: | |||
| 526 | tot_sent = sent; | 537 | tot_sent = sent; |
| 527 | 538 | ||
| 528 | mutex_unlock(&map->active.out_mutex); | 539 | mutex_unlock(&map->active.out_mutex); |
| 529 | pvcalls_exit(); | 540 | pvcalls_exit_sock(sock); |
| 530 | return tot_sent; | 541 | return tot_sent; |
| 531 | } | 542 | } |
| 532 | 543 | ||
| @@ -591,19 +602,11 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
| 591 | if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC)) | 602 | if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC)) |
| 592 | return -EOPNOTSUPP; | 603 | return -EOPNOTSUPP; |
| 593 | 604 | ||
| 594 | pvcalls_enter(); | 605 | map = pvcalls_enter_sock(sock); |
| 595 | if (!pvcalls_front_dev) { | 606 | if (IS_ERR(map)) |
| 596 | pvcalls_exit(); | 607 | return PTR_ERR(map); |
| 597 | return -ENOTCONN; | ||
| 598 | } | ||
| 599 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 608 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 600 | 609 | ||
| 601 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 602 | if (!map) { | ||
| 603 | pvcalls_exit(); | ||
| 604 | return -ENOTSOCK; | ||
| 605 | } | ||
| 606 | |||
| 607 | mutex_lock(&map->active.in_mutex); | 610 | mutex_lock(&map->active.in_mutex); |
| 608 | if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) | 611 | if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) |
| 609 | len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER); | 612 | len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER); |
| @@ -623,7 +626,7 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
| 623 | ret = 0; | 626 | ret = 0; |
| 624 | 627 | ||
| 625 | mutex_unlock(&map->active.in_mutex); | 628 | mutex_unlock(&map->active.in_mutex); |
| 626 | pvcalls_exit(); | 629 | pvcalls_exit_sock(sock); |
| 627 | return ret; | 630 | return ret; |
| 628 | } | 631 | } |
| 629 | 632 | ||
| @@ -637,24 +640,16 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
| 637 | if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) | 640 | if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) |
| 638 | return -EOPNOTSUPP; | 641 | return -EOPNOTSUPP; |
| 639 | 642 | ||
| 640 | pvcalls_enter(); | 643 | map = pvcalls_enter_sock(sock); |
| 641 | if (!pvcalls_front_dev) { | 644 | if (IS_ERR(map)) |
| 642 | pvcalls_exit(); | 645 | return PTR_ERR(map); |
| 643 | return -ENOTCONN; | ||
| 644 | } | ||
| 645 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 646 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 646 | 647 | ||
| 647 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 648 | if (map == NULL) { | ||
| 649 | pvcalls_exit(); | ||
| 650 | return -ENOTSOCK; | ||
| 651 | } | ||
| 652 | |||
| 653 | spin_lock(&bedata->socket_lock); | 648 | spin_lock(&bedata->socket_lock); |
| 654 | ret = get_request(bedata, &req_id); | 649 | ret = get_request(bedata, &req_id); |
| 655 | if (ret < 0) { | 650 | if (ret < 0) { |
| 656 | spin_unlock(&bedata->socket_lock); | 651 | spin_unlock(&bedata->socket_lock); |
| 657 | pvcalls_exit(); | 652 | pvcalls_exit_sock(sock); |
| 658 | return ret; | 653 | return ret; |
| 659 | } | 654 | } |
| 660 | req = RING_GET_REQUEST(&bedata->ring, req_id); | 655 | req = RING_GET_REQUEST(&bedata->ring, req_id); |
| @@ -684,7 +679,7 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
| 684 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; | 679 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; |
| 685 | 680 | ||
| 686 | map->passive.status = PVCALLS_STATUS_BIND; | 681 | map->passive.status = PVCALLS_STATUS_BIND; |
| 687 | pvcalls_exit(); | 682 | pvcalls_exit_sock(sock); |
| 688 | return 0; | 683 | return 0; |
| 689 | } | 684 | } |
| 690 | 685 | ||
| @@ -695,21 +690,13 @@ int pvcalls_front_listen(struct socket *sock, int backlog) | |||
| 695 | struct xen_pvcalls_request *req; | 690 | struct xen_pvcalls_request *req; |
| 696 | int notify, req_id, ret; | 691 | int notify, req_id, ret; |
| 697 | 692 | ||
| 698 | pvcalls_enter(); | 693 | map = pvcalls_enter_sock(sock); |
| 699 | if (!pvcalls_front_dev) { | 694 | if (IS_ERR(map)) |
| 700 | pvcalls_exit(); | 695 | return PTR_ERR(map); |
| 701 | return -ENOTCONN; | ||
| 702 | } | ||
| 703 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 696 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 704 | 697 | ||
| 705 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 706 | if (!map) { | ||
| 707 | pvcalls_exit(); | ||
| 708 | return -ENOTSOCK; | ||
| 709 | } | ||
| 710 | |||
| 711 | if (map->passive.status != PVCALLS_STATUS_BIND) { | 698 | if (map->passive.status != PVCALLS_STATUS_BIND) { |
| 712 | pvcalls_exit(); | 699 | pvcalls_exit_sock(sock); |
| 713 | return -EOPNOTSUPP; | 700 | return -EOPNOTSUPP; |
| 714 | } | 701 | } |
| 715 | 702 | ||
| @@ -717,7 +704,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) | |||
| 717 | ret = get_request(bedata, &req_id); | 704 | ret = get_request(bedata, &req_id); |
| 718 | if (ret < 0) { | 705 | if (ret < 0) { |
| 719 | spin_unlock(&bedata->socket_lock); | 706 | spin_unlock(&bedata->socket_lock); |
| 720 | pvcalls_exit(); | 707 | pvcalls_exit_sock(sock); |
| 721 | return ret; | 708 | return ret; |
| 722 | } | 709 | } |
| 723 | req = RING_GET_REQUEST(&bedata->ring, req_id); | 710 | req = RING_GET_REQUEST(&bedata->ring, req_id); |
| @@ -741,7 +728,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) | |||
| 741 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; | 728 | bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; |
| 742 | 729 | ||
| 743 | map->passive.status = PVCALLS_STATUS_LISTEN; | 730 | map->passive.status = PVCALLS_STATUS_LISTEN; |
| 744 | pvcalls_exit(); | 731 | pvcalls_exit_sock(sock); |
| 745 | return ret; | 732 | return ret; |
| 746 | } | 733 | } |
| 747 | 734 | ||
| @@ -753,21 +740,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 753 | struct xen_pvcalls_request *req; | 740 | struct xen_pvcalls_request *req; |
| 754 | int notify, req_id, ret, evtchn, nonblock; | 741 | int notify, req_id, ret, evtchn, nonblock; |
| 755 | 742 | ||
| 756 | pvcalls_enter(); | 743 | map = pvcalls_enter_sock(sock); |
| 757 | if (!pvcalls_front_dev) { | 744 | if (IS_ERR(map)) |
| 758 | pvcalls_exit(); | 745 | return PTR_ERR(map); |
| 759 | return -ENOTCONN; | ||
| 760 | } | ||
| 761 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 746 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 762 | 747 | ||
| 763 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 764 | if (!map) { | ||
| 765 | pvcalls_exit(); | ||
| 766 | return -ENOTSOCK; | ||
| 767 | } | ||
| 768 | |||
| 769 | if (map->passive.status != PVCALLS_STATUS_LISTEN) { | 748 | if (map->passive.status != PVCALLS_STATUS_LISTEN) { |
| 770 | pvcalls_exit(); | 749 | pvcalls_exit_sock(sock); |
| 771 | return -EINVAL; | 750 | return -EINVAL; |
| 772 | } | 751 | } |
| 773 | 752 | ||
| @@ -785,13 +764,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 785 | goto received; | 764 | goto received; |
| 786 | } | 765 | } |
| 787 | if (nonblock) { | 766 | if (nonblock) { |
| 788 | pvcalls_exit(); | 767 | pvcalls_exit_sock(sock); |
| 789 | return -EAGAIN; | 768 | return -EAGAIN; |
| 790 | } | 769 | } |
| 791 | if (wait_event_interruptible(map->passive.inflight_accept_req, | 770 | if (wait_event_interruptible(map->passive.inflight_accept_req, |
| 792 | !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, | 771 | !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, |
| 793 | (void *)&map->passive.flags))) { | 772 | (void *)&map->passive.flags))) { |
| 794 | pvcalls_exit(); | 773 | pvcalls_exit_sock(sock); |
| 795 | return -EINTR; | 774 | return -EINTR; |
| 796 | } | 775 | } |
| 797 | } | 776 | } |
| @@ -802,7 +781,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 802 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, | 781 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, |
| 803 | (void *)&map->passive.flags); | 782 | (void *)&map->passive.flags); |
| 804 | spin_unlock(&bedata->socket_lock); | 783 | spin_unlock(&bedata->socket_lock); |
| 805 | pvcalls_exit(); | 784 | pvcalls_exit_sock(sock); |
| 806 | return ret; | 785 | return ret; |
| 807 | } | 786 | } |
| 808 | map2 = kzalloc(sizeof(*map2), GFP_ATOMIC); | 787 | map2 = kzalloc(sizeof(*map2), GFP_ATOMIC); |
| @@ -810,7 +789,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 810 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, | 789 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, |
| 811 | (void *)&map->passive.flags); | 790 | (void *)&map->passive.flags); |
| 812 | spin_unlock(&bedata->socket_lock); | 791 | spin_unlock(&bedata->socket_lock); |
| 813 | pvcalls_exit(); | 792 | pvcalls_exit_sock(sock); |
| 814 | return -ENOMEM; | 793 | return -ENOMEM; |
| 815 | } | 794 | } |
| 816 | ret = create_active(map2, &evtchn); | 795 | ret = create_active(map2, &evtchn); |
| @@ -819,7 +798,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 819 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, | 798 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, |
| 820 | (void *)&map->passive.flags); | 799 | (void *)&map->passive.flags); |
| 821 | spin_unlock(&bedata->socket_lock); | 800 | spin_unlock(&bedata->socket_lock); |
| 822 | pvcalls_exit(); | 801 | pvcalls_exit_sock(sock); |
| 823 | return ret; | 802 | return ret; |
| 824 | } | 803 | } |
| 825 | list_add_tail(&map2->list, &bedata->socket_mappings); | 804 | list_add_tail(&map2->list, &bedata->socket_mappings); |
| @@ -841,13 +820,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 841 | /* We could check if we have received a response before returning. */ | 820 | /* We could check if we have received a response before returning. */ |
| 842 | if (nonblock) { | 821 | if (nonblock) { |
| 843 | WRITE_ONCE(map->passive.inflight_req_id, req_id); | 822 | WRITE_ONCE(map->passive.inflight_req_id, req_id); |
| 844 | pvcalls_exit(); | 823 | pvcalls_exit_sock(sock); |
| 845 | return -EAGAIN; | 824 | return -EAGAIN; |
| 846 | } | 825 | } |
| 847 | 826 | ||
| 848 | if (wait_event_interruptible(bedata->inflight_req, | 827 | if (wait_event_interruptible(bedata->inflight_req, |
| 849 | READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { | 828 | READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { |
| 850 | pvcalls_exit(); | 829 | pvcalls_exit_sock(sock); |
| 851 | return -EINTR; | 830 | return -EINTR; |
| 852 | } | 831 | } |
| 853 | /* read req_id, then the content */ | 832 | /* read req_id, then the content */ |
| @@ -862,7 +841,7 @@ received: | |||
| 862 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, | 841 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, |
| 863 | (void *)&map->passive.flags); | 842 | (void *)&map->passive.flags); |
| 864 | pvcalls_front_free_map(bedata, map2); | 843 | pvcalls_front_free_map(bedata, map2); |
| 865 | pvcalls_exit(); | 844 | pvcalls_exit_sock(sock); |
| 866 | return -ENOMEM; | 845 | return -ENOMEM; |
| 867 | } | 846 | } |
| 868 | newsock->sk->sk_send_head = (void *)map2; | 847 | newsock->sk->sk_send_head = (void *)map2; |
| @@ -874,7 +853,7 @@ received: | |||
| 874 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); | 853 | clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); |
| 875 | wake_up(&map->passive.inflight_accept_req); | 854 | wake_up(&map->passive.inflight_accept_req); |
| 876 | 855 | ||
| 877 | pvcalls_exit(); | 856 | pvcalls_exit_sock(sock); |
| 878 | return ret; | 857 | return ret; |
| 879 | } | 858 | } |
| 880 | 859 | ||
| @@ -965,23 +944,16 @@ __poll_t pvcalls_front_poll(struct file *file, struct socket *sock, | |||
| 965 | struct sock_mapping *map; | 944 | struct sock_mapping *map; |
| 966 | __poll_t ret; | 945 | __poll_t ret; |
| 967 | 946 | ||
| 968 | pvcalls_enter(); | 947 | map = pvcalls_enter_sock(sock); |
| 969 | if (!pvcalls_front_dev) { | 948 | if (IS_ERR(map)) |
| 970 | pvcalls_exit(); | ||
| 971 | return EPOLLNVAL; | 949 | return EPOLLNVAL; |
| 972 | } | ||
| 973 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 950 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 974 | 951 | ||
| 975 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 976 | if (!map) { | ||
| 977 | pvcalls_exit(); | ||
| 978 | return EPOLLNVAL; | ||
| 979 | } | ||
| 980 | if (map->active_socket) | 952 | if (map->active_socket) |
| 981 | ret = pvcalls_front_poll_active(file, bedata, map, wait); | 953 | ret = pvcalls_front_poll_active(file, bedata, map, wait); |
| 982 | else | 954 | else |
| 983 | ret = pvcalls_front_poll_passive(file, bedata, map, wait); | 955 | ret = pvcalls_front_poll_passive(file, bedata, map, wait); |
| 984 | pvcalls_exit(); | 956 | pvcalls_exit_sock(sock); |
| 985 | return ret; | 957 | return ret; |
| 986 | } | 958 | } |
| 987 | 959 | ||
| @@ -995,25 +967,20 @@ int pvcalls_front_release(struct socket *sock) | |||
| 995 | if (sock->sk == NULL) | 967 | if (sock->sk == NULL) |
| 996 | return 0; | 968 | return 0; |
| 997 | 969 | ||
| 998 | pvcalls_enter(); | 970 | map = pvcalls_enter_sock(sock); |
| 999 | if (!pvcalls_front_dev) { | 971 | if (IS_ERR(map)) { |
| 1000 | pvcalls_exit(); | 972 | if (PTR_ERR(map) == -ENOTCONN) |
| 1001 | return -EIO; | 973 | return -EIO; |
| 974 | else | ||
| 975 | return 0; | ||
| 1002 | } | 976 | } |
| 1003 | |||
| 1004 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | 977 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); |
| 1005 | 978 | ||
| 1006 | map = (struct sock_mapping *) sock->sk->sk_send_head; | ||
| 1007 | if (map == NULL) { | ||
| 1008 | pvcalls_exit(); | ||
| 1009 | return 0; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | spin_lock(&bedata->socket_lock); | 979 | spin_lock(&bedata->socket_lock); |
| 1013 | ret = get_request(bedata, &req_id); | 980 | ret = get_request(bedata, &req_id); |
| 1014 | if (ret < 0) { | 981 | if (ret < 0) { |
| 1015 | spin_unlock(&bedata->socket_lock); | 982 | spin_unlock(&bedata->socket_lock); |
| 1016 | pvcalls_exit(); | 983 | pvcalls_exit_sock(sock); |
| 1017 | return ret; | 984 | return ret; |
| 1018 | } | 985 | } |
| 1019 | sock->sk->sk_send_head = NULL; | 986 | sock->sk->sk_send_head = NULL; |
| @@ -1043,14 +1010,20 @@ int pvcalls_front_release(struct socket *sock) | |||
| 1043 | /* | 1010 | /* |
| 1044 | * We need to make sure that sendmsg/recvmsg on this socket have | 1011 | * We need to make sure that sendmsg/recvmsg on this socket have |
| 1045 | * not started before we've cleared sk_send_head here. The | 1012 | * not started before we've cleared sk_send_head here. The |
| 1046 | * easiest (though not optimal) way to guarantee this is to see | 1013 | * easiest way to guarantee this is to see that no pvcalls |
| 1047 | * that no pvcall (other than us) is in progress. | 1014 | * (other than us) is in progress on this socket. |
| 1048 | */ | 1015 | */ |
| 1049 | while (atomic_read(&pvcalls_refcount) > 1) | 1016 | while (atomic_read(&map->refcount) > 1) |
| 1050 | cpu_relax(); | 1017 | cpu_relax(); |
| 1051 | 1018 | ||
| 1052 | pvcalls_front_free_map(bedata, map); | 1019 | pvcalls_front_free_map(bedata, map); |
| 1053 | } else { | 1020 | } else { |
| 1021 | wake_up(&bedata->inflight_req); | ||
| 1022 | wake_up(&map->passive.inflight_accept_req); | ||
| 1023 | |||
| 1024 | while (atomic_read(&map->refcount) > 1) | ||
| 1025 | cpu_relax(); | ||
| 1026 | |||
| 1054 | spin_lock(&bedata->socket_lock); | 1027 | spin_lock(&bedata->socket_lock); |
| 1055 | list_del(&map->list); | 1028 | list_del(&map->list); |
| 1056 | spin_unlock(&bedata->socket_lock); | 1029 | spin_unlock(&bedata->socket_lock); |
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index bf13d1ec51f3..04e7b3b29bac 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c | |||
| @@ -284,6 +284,10 @@ static int tmem_frontswap_store(unsigned type, pgoff_t offset, | |||
| 284 | int pool = tmem_frontswap_poolid; | 284 | int pool = tmem_frontswap_poolid; |
| 285 | int ret; | 285 | int ret; |
| 286 | 286 | ||
| 287 | /* THP isn't supported */ | ||
| 288 | if (PageTransHuge(page)) | ||
| 289 | return -1; | ||
| 290 | |||
| 287 | if (pool < 0) | 291 | if (pool < 0) |
| 288 | return -1; | 292 | return -1; |
| 289 | if (ind64 != ind) | 293 | if (ind64 != ind) |
diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h index 149c5e7efc89..092981171df1 100644 --- a/drivers/xen/xenbus/xenbus.h +++ b/drivers/xen/xenbus/xenbus.h | |||
| @@ -76,6 +76,7 @@ struct xb_req_data { | |||
| 76 | struct list_head list; | 76 | struct list_head list; |
| 77 | wait_queue_head_t wq; | 77 | wait_queue_head_t wq; |
| 78 | struct xsd_sockmsg msg; | 78 | struct xsd_sockmsg msg; |
| 79 | uint32_t caller_req_id; | ||
| 79 | enum xsd_sockmsg_type type; | 80 | enum xsd_sockmsg_type type; |
| 80 | char *body; | 81 | char *body; |
| 81 | const struct kvec *vec; | 82 | const struct kvec *vec; |
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c index 5b081a01779d..d239fc3c5e3d 100644 --- a/drivers/xen/xenbus/xenbus_comms.c +++ b/drivers/xen/xenbus/xenbus_comms.c | |||
| @@ -309,6 +309,7 @@ static int process_msg(void) | |||
| 309 | goto out; | 309 | goto out; |
| 310 | 310 | ||
| 311 | if (req->state == xb_req_state_wait_reply) { | 311 | if (req->state == xb_req_state_wait_reply) { |
| 312 | req->msg.req_id = req->caller_req_id; | ||
| 312 | req->msg.type = state.msg.type; | 313 | req->msg.type = state.msg.type; |
| 313 | req->msg.len = state.msg.len; | 314 | req->msg.len = state.msg.len; |
| 314 | req->body = state.body; | 315 | req->body = state.body; |
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 3e59590c7254..3f3b29398ab8 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
| @@ -227,6 +227,8 @@ static void xs_send(struct xb_req_data *req, struct xsd_sockmsg *msg) | |||
| 227 | req->state = xb_req_state_queued; | 227 | req->state = xb_req_state_queued; |
| 228 | init_waitqueue_head(&req->wq); | 228 | init_waitqueue_head(&req->wq); |
| 229 | 229 | ||
| 230 | /* Save the caller req_id and restore it later in the reply */ | ||
| 231 | req->caller_req_id = req->msg.req_id; | ||
| 230 | req->msg.req_id = xs_request_enter(req); | 232 | req->msg.req_id = xs_request_enter(req); |
| 231 | 233 | ||
| 232 | mutex_lock(&xb_write_mutex); | 234 | mutex_lock(&xb_write_mutex); |
| @@ -310,6 +312,7 @@ static void *xs_talkv(struct xenbus_transaction t, | |||
| 310 | req->num_vecs = num_vecs; | 312 | req->num_vecs = num_vecs; |
| 311 | req->cb = xs_wake_up; | 313 | req->cb = xs_wake_up; |
| 312 | 314 | ||
| 315 | msg.req_id = 0; | ||
| 313 | msg.tx_id = t.id; | 316 | msg.tx_id = t.id; |
| 314 | msg.type = type; | 317 | msg.type = type; |
| 315 | msg.len = 0; | 318 | msg.len = 0; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 4a181fcb5175..fe09ef9c21f3 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -1058,6 +1058,27 @@ retry: | |||
| 1058 | return 0; | 1058 | return 0; |
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| 1061 | static struct gendisk *bdev_get_gendisk(struct block_device *bdev, int *partno) | ||
| 1062 | { | ||
| 1063 | struct gendisk *disk = get_gendisk(bdev->bd_dev, partno); | ||
| 1064 | |||
| 1065 | if (!disk) | ||
| 1066 | return NULL; | ||
| 1067 | /* | ||
| 1068 | * Now that we hold gendisk reference we make sure bdev we looked up is | ||
| 1069 | * not stale. If it is, it means device got removed and created before | ||
| 1070 | * we looked up gendisk and we fail open in such case. Associating | ||
| 1071 | * unhashed bdev with newly created gendisk could lead to two bdevs | ||
| 1072 | * (and thus two independent caches) being associated with one device | ||
| 1073 | * which is bad. | ||
| 1074 | */ | ||
| 1075 | if (inode_unhashed(bdev->bd_inode)) { | ||
| 1076 | put_disk_and_module(disk); | ||
| 1077 | return NULL; | ||
| 1078 | } | ||
| 1079 | return disk; | ||
| 1080 | } | ||
| 1081 | |||
| 1061 | /** | 1082 | /** |
| 1062 | * bd_start_claiming - start claiming a block device | 1083 | * bd_start_claiming - start claiming a block device |
| 1063 | * @bdev: block device of interest | 1084 | * @bdev: block device of interest |
| @@ -1094,7 +1115,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, | |||
| 1094 | * @bdev might not have been initialized properly yet, look up | 1115 | * @bdev might not have been initialized properly yet, look up |
| 1095 | * and grab the outer block device the hard way. | 1116 | * and grab the outer block device the hard way. |
| 1096 | */ | 1117 | */ |
| 1097 | disk = get_gendisk(bdev->bd_dev, &partno); | 1118 | disk = bdev_get_gendisk(bdev, &partno); |
| 1098 | if (!disk) | 1119 | if (!disk) |
| 1099 | return ERR_PTR(-ENXIO); | 1120 | return ERR_PTR(-ENXIO); |
| 1100 | 1121 | ||
| @@ -1111,8 +1132,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, | |||
| 1111 | else | 1132 | else |
| 1112 | whole = bdgrab(bdev); | 1133 | whole = bdgrab(bdev); |
| 1113 | 1134 | ||
| 1114 | module_put(disk->fops->owner); | 1135 | put_disk_and_module(disk); |
| 1115 | put_disk(disk); | ||
| 1116 | if (!whole) | 1136 | if (!whole) |
| 1117 | return ERR_PTR(-ENOMEM); | 1137 | return ERR_PTR(-ENOMEM); |
| 1118 | 1138 | ||
| @@ -1407,10 +1427,10 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); | |||
| 1407 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | 1427 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) |
| 1408 | { | 1428 | { |
| 1409 | struct gendisk *disk; | 1429 | struct gendisk *disk; |
| 1410 | struct module *owner; | ||
| 1411 | int ret; | 1430 | int ret; |
| 1412 | int partno; | 1431 | int partno; |
| 1413 | int perm = 0; | 1432 | int perm = 0; |
| 1433 | bool first_open = false; | ||
| 1414 | 1434 | ||
| 1415 | if (mode & FMODE_READ) | 1435 | if (mode & FMODE_READ) |
| 1416 | perm |= MAY_READ; | 1436 | perm |= MAY_READ; |
| @@ -1430,14 +1450,14 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1430 | restart: | 1450 | restart: |
| 1431 | 1451 | ||
| 1432 | ret = -ENXIO; | 1452 | ret = -ENXIO; |
| 1433 | disk = get_gendisk(bdev->bd_dev, &partno); | 1453 | disk = bdev_get_gendisk(bdev, &partno); |
| 1434 | if (!disk) | 1454 | if (!disk) |
| 1435 | goto out; | 1455 | goto out; |
| 1436 | owner = disk->fops->owner; | ||
| 1437 | 1456 | ||
| 1438 | disk_block_events(disk); | 1457 | disk_block_events(disk); |
| 1439 | mutex_lock_nested(&bdev->bd_mutex, for_part); | 1458 | mutex_lock_nested(&bdev->bd_mutex, for_part); |
| 1440 | if (!bdev->bd_openers) { | 1459 | if (!bdev->bd_openers) { |
| 1460 | first_open = true; | ||
| 1441 | bdev->bd_disk = disk; | 1461 | bdev->bd_disk = disk; |
| 1442 | bdev->bd_queue = disk->queue; | 1462 | bdev->bd_queue = disk->queue; |
| 1443 | bdev->bd_contains = bdev; | 1463 | bdev->bd_contains = bdev; |
| @@ -1463,8 +1483,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1463 | bdev->bd_queue = NULL; | 1483 | bdev->bd_queue = NULL; |
| 1464 | mutex_unlock(&bdev->bd_mutex); | 1484 | mutex_unlock(&bdev->bd_mutex); |
| 1465 | disk_unblock_events(disk); | 1485 | disk_unblock_events(disk); |
| 1466 | put_disk(disk); | 1486 | put_disk_and_module(disk); |
| 1467 | module_put(owner); | ||
| 1468 | goto restart; | 1487 | goto restart; |
| 1469 | } | 1488 | } |
| 1470 | } | 1489 | } |
| @@ -1524,15 +1543,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1524 | if (ret) | 1543 | if (ret) |
| 1525 | goto out_unlock_bdev; | 1544 | goto out_unlock_bdev; |
| 1526 | } | 1545 | } |
| 1527 | /* only one opener holds refs to the module and disk */ | ||
| 1528 | put_disk(disk); | ||
| 1529 | module_put(owner); | ||
| 1530 | } | 1546 | } |
| 1531 | bdev->bd_openers++; | 1547 | bdev->bd_openers++; |
| 1532 | if (for_part) | 1548 | if (for_part) |
| 1533 | bdev->bd_part_count++; | 1549 | bdev->bd_part_count++; |
| 1534 | mutex_unlock(&bdev->bd_mutex); | 1550 | mutex_unlock(&bdev->bd_mutex); |
| 1535 | disk_unblock_events(disk); | 1551 | disk_unblock_events(disk); |
| 1552 | /* only one opener holds refs to the module and disk */ | ||
| 1553 | if (!first_open) | ||
| 1554 | put_disk_and_module(disk); | ||
| 1536 | return 0; | 1555 | return 0; |
| 1537 | 1556 | ||
| 1538 | out_clear: | 1557 | out_clear: |
| @@ -1546,8 +1565,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1546 | out_unlock_bdev: | 1565 | out_unlock_bdev: |
| 1547 | mutex_unlock(&bdev->bd_mutex); | 1566 | mutex_unlock(&bdev->bd_mutex); |
| 1548 | disk_unblock_events(disk); | 1567 | disk_unblock_events(disk); |
| 1549 | put_disk(disk); | 1568 | put_disk_and_module(disk); |
| 1550 | module_put(owner); | ||
| 1551 | out: | 1569 | out: |
| 1552 | bdput(bdev); | 1570 | bdput(bdev); |
| 1553 | 1571 | ||
| @@ -1770,8 +1788,6 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1770 | disk->fops->release(disk, mode); | 1788 | disk->fops->release(disk, mode); |
| 1771 | } | 1789 | } |
| 1772 | if (!bdev->bd_openers) { | 1790 | if (!bdev->bd_openers) { |
| 1773 | struct module *owner = disk->fops->owner; | ||
| 1774 | |||
| 1775 | disk_put_part(bdev->bd_part); | 1791 | disk_put_part(bdev->bd_part); |
| 1776 | bdev->bd_part = NULL; | 1792 | bdev->bd_part = NULL; |
| 1777 | bdev->bd_disk = NULL; | 1793 | bdev->bd_disk = NULL; |
| @@ -1779,8 +1795,7 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1779 | victim = bdev->bd_contains; | 1795 | victim = bdev->bd_contains; |
| 1780 | bdev->bd_contains = NULL; | 1796 | bdev->bd_contains = NULL; |
| 1781 | 1797 | ||
| 1782 | put_disk(disk); | 1798 | put_disk_and_module(disk); |
| 1783 | module_put(owner); | ||
| 1784 | } | 1799 | } |
| 1785 | mutex_unlock(&bdev->bd_mutex); | 1800 | mutex_unlock(&bdev->bd_mutex); |
| 1786 | bdput(bdev); | 1801 | bdput(bdev); |
diff --git a/fs/direct-io.c b/fs/direct-io.c index a0ca9e48e993..1357ef563893 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
| @@ -1274,8 +1274,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | |||
| 1274 | */ | 1274 | */ |
| 1275 | if (dio->is_async && iov_iter_rw(iter) == WRITE) { | 1275 | if (dio->is_async && iov_iter_rw(iter) == WRITE) { |
| 1276 | retval = 0; | 1276 | retval = 0; |
| 1277 | if ((iocb->ki_filp->f_flags & O_DSYNC) || | 1277 | if (iocb->ki_flags & IOCB_DSYNC) |
| 1278 | IS_SYNC(iocb->ki_filp->f_mapping->host)) | ||
| 1279 | retval = dio_set_defer_completion(dio); | 1278 | retval = dio_set_defer_completion(dio); |
| 1280 | else if (!dio->inode->i_sb->s_dio_done_wq) { | 1279 | else if (!dio->inode->i_sb->s_dio_done_wq) { |
| 1281 | /* | 1280 | /* |
diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index 5f22e74bbade..8e568428c88b 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/efi.h> | 10 | #include <linux/efi.h> |
| 11 | #include <linux/delay.h> | ||
| 11 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
| 12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 13 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
| @@ -74,6 +75,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, | |||
| 74 | ssize_t size = 0; | 75 | ssize_t size = 0; |
| 75 | int err; | 76 | int err; |
| 76 | 77 | ||
| 78 | while (!__ratelimit(&file->f_cred->user->ratelimit)) { | ||
| 79 | if (!msleep_interruptible(50)) | ||
| 80 | return -EINTR; | ||
| 81 | } | ||
| 82 | |||
| 77 | err = efivar_entry_size(var, &datasize); | 83 | err = efivar_entry_size(var, &datasize); |
| 78 | 84 | ||
| 79 | /* | 85 | /* |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 9990957264e3..76bf9cc62074 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
| @@ -118,13 +118,22 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, | |||
| 118 | err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno); | 118 | err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno); |
| 119 | #endif | 119 | #endif |
| 120 | #ifdef BUS_MCEERR_AO | 120 | #ifdef BUS_MCEERR_AO |
| 121 | /* | 121 | /* |
| 122 | * Other callers might not initialize the si_lsb field, | ||
| 123 | * so check explicitly for the right codes here. | ||
| 124 | */ | ||
| 125 | if (kinfo->si_signo == SIGBUS && | ||
| 126 | kinfo->si_code == BUS_MCEERR_AO) | ||
| 127 | err |= __put_user((short) kinfo->si_addr_lsb, | ||
| 128 | &uinfo->ssi_addr_lsb); | ||
| 129 | #endif | ||
| 130 | #ifdef BUS_MCEERR_AR | ||
| 131 | /* | ||
| 122 | * Other callers might not initialize the si_lsb field, | 132 | * Other callers might not initialize the si_lsb field, |
| 123 | * so check explicitly for the right codes here. | 133 | * so check explicitly for the right codes here. |
| 124 | */ | 134 | */ |
| 125 | if (kinfo->si_signo == SIGBUS && | 135 | if (kinfo->si_signo == SIGBUS && |
| 126 | (kinfo->si_code == BUS_MCEERR_AR || | 136 | kinfo->si_code == BUS_MCEERR_AR) |
| 127 | kinfo->si_code == BUS_MCEERR_AO)) | ||
| 128 | err |= __put_user((short) kinfo->si_addr_lsb, | 137 | err |= __put_user((short) kinfo->si_addr_lsb, |
| 129 | &uinfo->ssi_addr_lsb); | 138 | &uinfo->ssi_addr_lsb); |
| 130 | #endif | 139 | #endif |
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 963b755d19b0..a7613e1b0c87 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h | |||
| @@ -52,6 +52,7 @@ struct bug_entry { | |||
| 52 | #ifndef HAVE_ARCH_BUG | 52 | #ifndef HAVE_ARCH_BUG |
| 53 | #define BUG() do { \ | 53 | #define BUG() do { \ |
| 54 | printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ | 54 | printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ |
| 55 | barrier_before_unreachable(); \ | ||
| 55 | panic("BUG!"); \ | 56 | panic("BUG!"); \ |
| 56 | } while (0) | 57 | } while (0) |
| 57 | #endif | 58 | #endif |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4f3df807cf8f..ed63f3b69c12 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -49,7 +49,7 @@ struct blk_stat_callback; | |||
| 49 | #define BLKDEV_MIN_RQ 4 | 49 | #define BLKDEV_MIN_RQ 4 |
| 50 | #define BLKDEV_MAX_RQ 128 /* Default maximum */ | 50 | #define BLKDEV_MAX_RQ 128 /* Default maximum */ |
| 51 | 51 | ||
| 52 | /* Must be consisitent with blk_mq_poll_stats_bkt() */ | 52 | /* Must be consistent with blk_mq_poll_stats_bkt() */ |
| 53 | #define BLK_MQ_POLL_STATS_BKTS 16 | 53 | #define BLK_MQ_POLL_STATS_BKTS 16 |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 73bc63e0a1c4..901c1ccb3374 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
| @@ -208,6 +208,15 @@ | |||
| 208 | #endif | 208 | #endif |
| 209 | 209 | ||
| 210 | /* | 210 | /* |
| 211 | * calling noreturn functions, __builtin_unreachable() and __builtin_trap() | ||
| 212 | * confuse the stack allocation in gcc, leading to overly large stack | ||
| 213 | * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365 | ||
| 214 | * | ||
| 215 | * Adding an empty inline assembly before it works around the problem | ||
| 216 | */ | ||
| 217 | #define barrier_before_unreachable() asm volatile("") | ||
| 218 | |||
| 219 | /* | ||
| 211 | * Mark a position in code as unreachable. This can be used to | 220 | * Mark a position in code as unreachable. This can be used to |
| 212 | * suppress control flow warnings after asm blocks that transfer | 221 | * suppress control flow warnings after asm blocks that transfer |
| 213 | * control elsewhere. | 222 | * control elsewhere. |
| @@ -217,7 +226,11 @@ | |||
| 217 | * unreleased. Really, we need to have autoconf for the kernel. | 226 | * unreleased. Really, we need to have autoconf for the kernel. |
| 218 | */ | 227 | */ |
| 219 | #define unreachable() \ | 228 | #define unreachable() \ |
| 220 | do { annotate_unreachable(); __builtin_unreachable(); } while (0) | 229 | do { \ |
| 230 | annotate_unreachable(); \ | ||
| 231 | barrier_before_unreachable(); \ | ||
| 232 | __builtin_unreachable(); \ | ||
| 233 | } while (0) | ||
| 221 | 234 | ||
| 222 | /* Mark a function definition as prohibited from being cloned. */ | 235 | /* Mark a function definition as prohibited from being cloned. */ |
| 223 | #define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) | 236 | #define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index e835fc0423ec..ab4711c63601 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -86,6 +86,11 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, | |||
| 86 | # define barrier_data(ptr) barrier() | 86 | # define barrier_data(ptr) barrier() |
| 87 | #endif | 87 | #endif |
| 88 | 88 | ||
| 89 | /* workaround for GCC PR82365 if needed */ | ||
| 90 | #ifndef barrier_before_unreachable | ||
| 91 | # define barrier_before_unreachable() do { } while (0) | ||
| 92 | #endif | ||
| 93 | |||
| 89 | /* Unreachable code */ | 94 | /* Unreachable code */ |
| 90 | #ifdef CONFIG_STACK_VALIDATION | 95 | #ifdef CONFIG_STACK_VALIDATION |
| 91 | /* | 96 | /* |
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index d4a2a7dcd72d..bf53d893ad02 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h | |||
| @@ -170,6 +170,8 @@ static inline unsigned int cpumask_local_spread(unsigned int i, int node) | |||
| 170 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) | 170 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) |
| 171 | #define for_each_cpu_not(cpu, mask) \ | 171 | #define for_each_cpu_not(cpu, mask) \ |
| 172 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) | 172 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) |
| 173 | #define for_each_cpu_wrap(cpu, mask, start) \ | ||
| 174 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)(start)) | ||
| 173 | #define for_each_cpu_and(cpu, mask, and) \ | 175 | #define for_each_cpu_and(cpu, mask, and) \ |
| 174 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and) | 176 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and) |
| 175 | #else | 177 | #else |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 34fe8463d10e..eb9eab4ecd6d 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
| @@ -578,7 +578,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
| 578 | 578 | ||
| 579 | /* | 579 | /* |
| 580 | * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please | 580 | * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please |
| 581 | * don't use this is new code. | 581 | * don't use this in new code. |
| 582 | */ | 582 | */ |
| 583 | #ifndef arch_dma_supported | 583 | #ifndef arch_dma_supported |
| 584 | #define arch_dma_supported(dev, mask) (1) | 584 | #define arch_dma_supported(dev, mask) (1) |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 5e3531027b51..c826b0b5232a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
| @@ -198,6 +198,7 @@ struct gendisk { | |||
| 198 | void *private_data; | 198 | void *private_data; |
| 199 | 199 | ||
| 200 | int flags; | 200 | int flags; |
| 201 | struct rw_semaphore lookup_sem; | ||
| 201 | struct kobject *slave_dir; | 202 | struct kobject *slave_dir; |
| 202 | 203 | ||
| 203 | struct timer_rand_state *random; | 204 | struct timer_rand_state *random; |
| @@ -600,8 +601,9 @@ extern void delete_partition(struct gendisk *, int); | |||
| 600 | extern void printk_all_partitions(void); | 601 | extern void printk_all_partitions(void); |
| 601 | 602 | ||
| 602 | extern struct gendisk *__alloc_disk_node(int minors, int node_id); | 603 | extern struct gendisk *__alloc_disk_node(int minors, int node_id); |
| 603 | extern struct kobject *get_disk(struct gendisk *disk); | 604 | extern struct kobject *get_disk_and_module(struct gendisk *disk); |
| 604 | extern void put_disk(struct gendisk *disk); | 605 | extern void put_disk(struct gendisk *disk); |
| 606 | extern void put_disk_and_module(struct gendisk *disk); | ||
| 605 | extern void blk_register_region(dev_t devt, unsigned long range, | 607 | extern void blk_register_region(dev_t devt, unsigned long range, |
| 606 | struct module *module, | 608 | struct module *module, |
| 607 | struct kobject *(*probe)(dev_t, int *, void *), | 609 | struct kobject *(*probe)(dev_t, int *, void *), |
diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index fec5076eda91..dcde9471897d 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h | |||
| @@ -4,6 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include <generated/autoconf.h> | 5 | #include <generated/autoconf.h> |
| 6 | 6 | ||
| 7 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
| 8 | #define __BIG_ENDIAN 4321 | ||
| 9 | #else | ||
| 10 | #define __LITTLE_ENDIAN 1234 | ||
| 11 | #endif | ||
| 12 | |||
| 7 | #define __ARG_PLACEHOLDER_1 0, | 13 | #define __ARG_PLACEHOLDER_1 0, |
| 8 | #define __take_second_arg(__ignored, val, ...) val | 14 | #define __take_second_arg(__ignored, val, ...) val |
| 9 | 15 | ||
| @@ -64,4 +70,7 @@ | |||
| 64 | */ | 70 | */ |
| 65 | #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) | 71 | #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) |
| 66 | 72 | ||
| 73 | /* Make sure we always have all types and struct attributes defined. */ | ||
| 74 | #include <linux/compiler_types.h> | ||
| 75 | |||
| 67 | #endif /* __LINUX_KCONFIG_H */ | 76 | #endif /* __LINUX_KCONFIG_H */ |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 882046863581..c46016bb25eb 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -523,9 +523,11 @@ static inline void __mod_memcg_state(struct mem_cgroup *memcg, | |||
| 523 | static inline void mod_memcg_state(struct mem_cgroup *memcg, | 523 | static inline void mod_memcg_state(struct mem_cgroup *memcg, |
| 524 | int idx, int val) | 524 | int idx, int val) |
| 525 | { | 525 | { |
| 526 | preempt_disable(); | 526 | unsigned long flags; |
| 527 | |||
| 528 | local_irq_save(flags); | ||
| 527 | __mod_memcg_state(memcg, idx, val); | 529 | __mod_memcg_state(memcg, idx, val); |
| 528 | preempt_enable(); | 530 | local_irq_restore(flags); |
| 529 | } | 531 | } |
| 530 | 532 | ||
| 531 | /** | 533 | /** |
| @@ -606,9 +608,11 @@ static inline void __mod_lruvec_state(struct lruvec *lruvec, | |||
| 606 | static inline void mod_lruvec_state(struct lruvec *lruvec, | 608 | static inline void mod_lruvec_state(struct lruvec *lruvec, |
| 607 | enum node_stat_item idx, int val) | 609 | enum node_stat_item idx, int val) |
| 608 | { | 610 | { |
| 609 | preempt_disable(); | 611 | unsigned long flags; |
| 612 | |||
| 613 | local_irq_save(flags); | ||
| 610 | __mod_lruvec_state(lruvec, idx, val); | 614 | __mod_lruvec_state(lruvec, idx, val); |
| 611 | preempt_enable(); | 615 | local_irq_restore(flags); |
| 612 | } | 616 | } |
| 613 | 617 | ||
| 614 | static inline void __mod_lruvec_page_state(struct page *page, | 618 | static inline void __mod_lruvec_page_state(struct page *page, |
| @@ -630,9 +634,11 @@ static inline void __mod_lruvec_page_state(struct page *page, | |||
| 630 | static inline void mod_lruvec_page_state(struct page *page, | 634 | static inline void mod_lruvec_page_state(struct page *page, |
| 631 | enum node_stat_item idx, int val) | 635 | enum node_stat_item idx, int val) |
| 632 | { | 636 | { |
| 633 | preempt_disable(); | 637 | unsigned long flags; |
| 638 | |||
| 639 | local_irq_save(flags); | ||
| 634 | __mod_lruvec_page_state(page, idx, val); | 640 | __mod_lruvec_page_state(page, idx, val); |
| 635 | preempt_enable(); | 641 | local_irq_restore(flags); |
| 636 | } | 642 | } |
| 637 | 643 | ||
| 638 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, | 644 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| @@ -659,9 +665,11 @@ static inline void __count_memcg_events(struct mem_cgroup *memcg, | |||
| 659 | static inline void count_memcg_events(struct mem_cgroup *memcg, | 665 | static inline void count_memcg_events(struct mem_cgroup *memcg, |
| 660 | int idx, unsigned long count) | 666 | int idx, unsigned long count) |
| 661 | { | 667 | { |
| 662 | preempt_disable(); | 668 | unsigned long flags; |
| 669 | |||
| 670 | local_irq_save(flags); | ||
| 663 | __count_memcg_events(memcg, idx, count); | 671 | __count_memcg_events(memcg, idx, count); |
| 664 | preempt_enable(); | 672 | local_irq_restore(flags); |
| 665 | } | 673 | } |
| 666 | 674 | ||
| 667 | /* idx can be of type enum memcg_event_item or vm_event_item */ | 675 | /* idx can be of type enum memcg_event_item or vm_event_item */ |
diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h index b884b7794187..e6335227b844 100644 --- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h | |||
| @@ -469,7 +469,7 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r, | |||
| 469 | */ | 469 | */ |
| 470 | static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) | 470 | static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) |
| 471 | { | 471 | { |
| 472 | if (size * sizeof(void *) > KMALLOC_MAX_SIZE) | 472 | if (size > KMALLOC_MAX_SIZE / sizeof(void *)) |
| 473 | return NULL; | 473 | return NULL; |
| 474 | return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO); | 474 | return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO); |
| 475 | } | 475 | } |
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 1149533aa2fa..9806184bb3d5 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h | |||
| @@ -36,7 +36,18 @@ static inline void mmgrab(struct mm_struct *mm) | |||
| 36 | atomic_inc(&mm->mm_count); | 36 | atomic_inc(&mm->mm_count); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | extern void mmdrop(struct mm_struct *mm); | 39 | extern void __mmdrop(struct mm_struct *mm); |
| 40 | |||
| 41 | static inline void mmdrop(struct mm_struct *mm) | ||
| 42 | { | ||
| 43 | /* | ||
| 44 | * The implicit full barrier implied by atomic_dec_and_test() is | ||
| 45 | * required by the membarrier system call before returning to | ||
| 46 | * user-space, after storing to rq->curr. | ||
| 47 | */ | ||
| 48 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | ||
| 49 | __mmdrop(mm); | ||
| 50 | } | ||
| 40 | 51 | ||
| 41 | /** | 52 | /** |
| 42 | * mmget() - Pin the address space associated with a &struct mm_struct. | 53 | * mmget() - Pin the address space associated with a &struct mm_struct. |
diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h index 0dcf4e480ef7..96fe289c4c6e 100644 --- a/include/linux/sched/user.h +++ b/include/linux/sched/user.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <linux/uidgid.h> | 5 | #include <linux/uidgid.h> |
| 6 | #include <linux/atomic.h> | 6 | #include <linux/atomic.h> |
| 7 | #include <linux/ratelimit.h> | ||
| 7 | 8 | ||
| 8 | struct key; | 9 | struct key; |
| 9 | 10 | ||
| @@ -41,6 +42,9 @@ struct user_struct { | |||
| 41 | defined(CONFIG_NET) | 42 | defined(CONFIG_NET) |
| 42 | atomic_long_t locked_vm; | 43 | atomic_long_t locked_vm; |
| 43 | #endif | 44 | #endif |
| 45 | |||
| 46 | /* Miscellaneous per-user rate limit */ | ||
| 47 | struct ratelimit_state ratelimit; | ||
| 44 | }; | 48 | }; |
| 45 | 49 | ||
| 46 | extern int uids_sysfs_init(void); | 50 | extern int uids_sysfs_init(void); |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5ebc0f869720..c1e66bdcf583 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -3646,7 +3646,7 @@ static inline bool __skb_checksum_validate_needed(struct sk_buff *skb, | |||
| 3646 | return true; | 3646 | return true; |
| 3647 | } | 3647 | } |
| 3648 | 3648 | ||
| 3649 | /* For small packets <= CHECKSUM_BREAK peform checksum complete directly | 3649 | /* For small packets <= CHECKSUM_BREAK perform checksum complete directly |
| 3650 | * in checksum_init. | 3650 | * in checksum_init. |
| 3651 | */ | 3651 | */ |
| 3652 | #define CHECKSUM_BREAK 76 | 3652 | #define CHECKSUM_BREAK 76 |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 7b6a59f722a3..a1a3f4ed94ce 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
| @@ -337,8 +337,6 @@ extern void deactivate_file_page(struct page *page); | |||
| 337 | extern void mark_page_lazyfree(struct page *page); | 337 | extern void mark_page_lazyfree(struct page *page); |
| 338 | extern void swap_setup(void); | 338 | extern void swap_setup(void); |
| 339 | 339 | ||
| 340 | extern void add_page_to_unevictable_list(struct page *page); | ||
| 341 | |||
| 342 | extern void lru_cache_add_active_or_unevictable(struct page *page, | 340 | extern void lru_cache_add_active_or_unevictable(struct page *page, |
| 343 | struct vm_area_struct *vma); | 341 | struct vm_area_struct *vma); |
| 344 | 342 | ||
diff --git a/include/net/udplite.h b/include/net/udplite.h index 81bdbf97319b..9185e45b997f 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h | |||
| @@ -64,6 +64,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) | |||
| 64 | UDP_SKB_CB(skb)->cscov = cscov; | 64 | UDP_SKB_CB(skb)->cscov = cscov; |
| 65 | if (skb->ip_summed == CHECKSUM_COMPLETE) | 65 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
| 66 | skb->ip_summed = CHECKSUM_NONE; | 66 | skb->ip_summed = CHECKSUM_NONE; |
| 67 | skb->csum_valid = 0; | ||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | return 0; | 70 | return 0; |
diff --git a/include/rdma/restrack.h b/include/rdma/restrack.h index c2d81167c858..2cdf8dcf4bdc 100644 --- a/include/rdma/restrack.h +++ b/include/rdma/restrack.h | |||
| @@ -29,10 +29,6 @@ enum rdma_restrack_type { | |||
| 29 | */ | 29 | */ |
| 30 | RDMA_RESTRACK_QP, | 30 | RDMA_RESTRACK_QP, |
| 31 | /** | 31 | /** |
| 32 | * @RDMA_RESTRACK_XRCD: XRC domain (XRCD) | ||
| 33 | */ | ||
| 34 | RDMA_RESTRACK_XRCD, | ||
| 35 | /** | ||
| 36 | * @RDMA_RESTRACK_MAX: Last entry, used for array dclarations | 32 | * @RDMA_RESTRACK_MAX: Last entry, used for array dclarations |
| 37 | */ | 33 | */ |
| 38 | RDMA_RESTRACK_MAX | 34 | RDMA_RESTRACK_MAX |
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h index 6da44079aa58..38287d9d23a1 100644 --- a/include/rdma/uverbs_ioctl.h +++ b/include/rdma/uverbs_ioctl.h | |||
| @@ -276,10 +276,7 @@ struct uverbs_object_tree_def { | |||
| 276 | */ | 276 | */ |
| 277 | 277 | ||
| 278 | struct uverbs_ptr_attr { | 278 | struct uverbs_ptr_attr { |
| 279 | union { | 279 | u64 data; |
| 280 | u64 data; | ||
| 281 | void __user *ptr; | ||
| 282 | }; | ||
| 283 | u16 len; | 280 | u16 len; |
| 284 | /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ | 281 | /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ |
| 285 | u16 flags; | 282 | u16 flags; |
| @@ -351,38 +348,60 @@ static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr | |||
| 351 | } | 348 | } |
| 352 | 349 | ||
| 353 | static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, | 350 | static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, |
| 354 | size_t idx, const void *from) | 351 | size_t idx, const void *from, size_t size) |
| 355 | { | 352 | { |
| 356 | const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); | 353 | const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); |
| 357 | u16 flags; | 354 | u16 flags; |
| 355 | size_t min_size; | ||
| 358 | 356 | ||
| 359 | if (IS_ERR(attr)) | 357 | if (IS_ERR(attr)) |
| 360 | return PTR_ERR(attr); | 358 | return PTR_ERR(attr); |
| 361 | 359 | ||
| 360 | min_size = min_t(size_t, attr->ptr_attr.len, size); | ||
| 361 | if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size)) | ||
| 362 | return -EFAULT; | ||
| 363 | |||
| 362 | flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; | 364 | flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; |
| 363 | return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) && | 365 | if (put_user(flags, &attr->uattr->flags)) |
| 364 | !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT; | 366 | return -EFAULT; |
| 367 | |||
| 368 | return 0; | ||
| 365 | } | 369 | } |
| 366 | 370 | ||
| 367 | static inline int _uverbs_copy_from(void *to, size_t to_size, | 371 | static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr) |
| 372 | { | ||
| 373 | return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data); | ||
| 374 | } | ||
| 375 | |||
| 376 | static inline int _uverbs_copy_from(void *to, | ||
| 368 | const struct uverbs_attr_bundle *attrs_bundle, | 377 | const struct uverbs_attr_bundle *attrs_bundle, |
| 369 | size_t idx) | 378 | size_t idx, |
| 379 | size_t size) | ||
| 370 | { | 380 | { |
| 371 | const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); | 381 | const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); |
| 372 | 382 | ||
| 373 | if (IS_ERR(attr)) | 383 | if (IS_ERR(attr)) |
| 374 | return PTR_ERR(attr); | 384 | return PTR_ERR(attr); |
| 375 | 385 | ||
| 376 | if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data)) | 386 | /* |
| 387 | * Validation ensures attr->ptr_attr.len >= size. If the caller is | ||
| 388 | * using UVERBS_ATTR_SPEC_F_MIN_SZ then it must call copy_from with | ||
| 389 | * the right size. | ||
| 390 | */ | ||
| 391 | if (unlikely(size < attr->ptr_attr.len)) | ||
| 392 | return -EINVAL; | ||
| 393 | |||
| 394 | if (uverbs_attr_ptr_is_inline(attr)) | ||
| 377 | memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); | 395 | memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); |
| 378 | else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len)) | 396 | else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data), |
| 397 | attr->ptr_attr.len)) | ||
| 379 | return -EFAULT; | 398 | return -EFAULT; |
| 380 | 399 | ||
| 381 | return 0; | 400 | return 0; |
| 382 | } | 401 | } |
| 383 | 402 | ||
| 384 | #define uverbs_copy_from(to, attrs_bundle, idx) \ | 403 | #define uverbs_copy_from(to, attrs_bundle, idx) \ |
| 385 | _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx) | 404 | _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to)) |
| 386 | 405 | ||
| 387 | /* ================================================= | 406 | /* ================================================= |
| 388 | * Definitions -> Specs infrastructure | 407 | * Definitions -> Specs infrastructure |
diff --git a/include/uapi/linux/blktrace_api.h b/include/uapi/linux/blktrace_api.h index 20d1490d6377..3c50e07ee833 100644 --- a/include/uapi/linux/blktrace_api.h +++ b/include/uapi/linux/blktrace_api.h | |||
| @@ -131,7 +131,7 @@ enum { | |||
| 131 | #define BLKTRACE_BDEV_SIZE 32 | 131 | #define BLKTRACE_BDEV_SIZE 32 |
| 132 | 132 | ||
| 133 | /* | 133 | /* |
| 134 | * User setup structure passed with BLKTRACESTART | 134 | * User setup structure passed with BLKTRACESETUP |
| 135 | */ | 135 | */ |
| 136 | struct blk_user_trace_setup { | 136 | struct blk_user_trace_setup { |
| 137 | char name[BLKTRACE_BDEV_SIZE]; /* output */ | 137 | char name[BLKTRACE_BDEV_SIZE]; /* output */ |
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index f8cb5760ea4f..8bbbcb5cd94b 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #define _UAPI_LINUX_IF_ETHER_H | 23 | #define _UAPI_LINUX_IF_ETHER_H |
| 24 | 24 | ||
| 25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
| 26 | #include <linux/libc-compat.h> | ||
| 27 | 26 | ||
| 28 | /* | 27 | /* |
| 29 | * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble | 28 | * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble |
| @@ -151,6 +150,11 @@ | |||
| 151 | * This is an Ethernet frame header. | 150 | * This is an Ethernet frame header. |
| 152 | */ | 151 | */ |
| 153 | 152 | ||
| 153 | /* allow libcs like musl to deactivate this, glibc does not implement this. */ | ||
| 154 | #ifndef __UAPI_DEF_ETHHDR | ||
| 155 | #define __UAPI_DEF_ETHHDR 1 | ||
| 156 | #endif | ||
| 157 | |||
| 154 | #if __UAPI_DEF_ETHHDR | 158 | #if __UAPI_DEF_ETHHDR |
| 155 | struct ethhdr { | 159 | struct ethhdr { |
| 156 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ | 160 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ |
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index fc29efaa918c..8254c937c9f4 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h | |||
| @@ -264,10 +264,4 @@ | |||
| 264 | 264 | ||
| 265 | #endif /* __GLIBC__ */ | 265 | #endif /* __GLIBC__ */ |
| 266 | 266 | ||
| 267 | /* Definitions for if_ether.h */ | ||
| 268 | /* allow libcs like musl to deactivate this, glibc does not implement this. */ | ||
| 269 | #ifndef __UAPI_DEF_ETHHDR | ||
| 270 | #define __UAPI_DEF_ETHHDR 1 | ||
| 271 | #endif | ||
| 272 | |||
| 273 | #endif /* _UAPI_LIBC_COMPAT_H */ | 267 | #endif /* _UAPI_LIBC_COMPAT_H */ |
diff --git a/include/uapi/rdma/rdma_user_ioctl.h b/include/uapi/rdma/rdma_user_ioctl.h index 03557b5f9aa6..46de0885e800 100644 --- a/include/uapi/rdma/rdma_user_ioctl.h +++ b/include/uapi/rdma/rdma_user_ioctl.h | |||
| @@ -65,7 +65,7 @@ struct ib_uverbs_attr { | |||
| 65 | __u16 len; /* only for pointers */ | 65 | __u16 len; /* only for pointers */ |
| 66 | __u16 flags; /* combination of UVERBS_ATTR_F_XXXX */ | 66 | __u16 flags; /* combination of UVERBS_ATTR_F_XXXX */ |
| 67 | __u16 reserved; | 67 | __u16 reserved; |
| 68 | __u64 data; /* ptr to command, inline data or idr/fd */ | 68 | __aligned_u64 data; /* ptr to command, inline data or idr/fd */ |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | struct ib_uverbs_ioctl_hdr { | 71 | struct ib_uverbs_ioctl_hdr { |
| @@ -73,7 +73,7 @@ struct ib_uverbs_ioctl_hdr { | |||
| 73 | __u16 object_id; | 73 | __u16 object_id; |
| 74 | __u16 method_id; | 74 | __u16 method_id; |
| 75 | __u16 num_attrs; | 75 | __u16 num_attrs; |
| 76 | __u64 reserved; | 76 | __aligned_u64 reserved; |
| 77 | struct ib_uverbs_attr attrs[0]; | 77 | struct ib_uverbs_attr attrs[0]; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index be8aa5b98666..e5d9d405ae4e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -592,7 +592,7 @@ static void check_mm(struct mm_struct *mm) | |||
| 592 | * is dropped: either by a lazy thread or by | 592 | * is dropped: either by a lazy thread or by |
| 593 | * mmput. Free the page directory and the mm. | 593 | * mmput. Free the page directory and the mm. |
| 594 | */ | 594 | */ |
| 595 | static void __mmdrop(struct mm_struct *mm) | 595 | void __mmdrop(struct mm_struct *mm) |
| 596 | { | 596 | { |
| 597 | BUG_ON(mm == &init_mm); | 597 | BUG_ON(mm == &init_mm); |
| 598 | mm_free_pgd(mm); | 598 | mm_free_pgd(mm); |
| @@ -603,18 +603,7 @@ static void __mmdrop(struct mm_struct *mm) | |||
| 603 | put_user_ns(mm->user_ns); | 603 | put_user_ns(mm->user_ns); |
| 604 | free_mm(mm); | 604 | free_mm(mm); |
| 605 | } | 605 | } |
| 606 | 606 | EXPORT_SYMBOL_GPL(__mmdrop); | |
| 607 | void mmdrop(struct mm_struct *mm) | ||
| 608 | { | ||
| 609 | /* | ||
| 610 | * The implicit full barrier implied by atomic_dec_and_test() is | ||
| 611 | * required by the membarrier system call before returning to | ||
| 612 | * user-space, after storing to rq->curr. | ||
| 613 | */ | ||
| 614 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | ||
| 615 | __mmdrop(mm); | ||
| 616 | } | ||
| 617 | EXPORT_SYMBOL_GPL(mmdrop); | ||
| 618 | 607 | ||
| 619 | static void mmdrop_async_fn(struct work_struct *work) | 608 | static void mmdrop_async_fn(struct work_struct *work) |
| 620 | { | 609 | { |
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e6a9c36470ee..82b8b18ee1eb 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c | |||
| @@ -1726,25 +1726,14 @@ static int irq_domain_debug_show(struct seq_file *m, void *p) | |||
| 1726 | irq_domain_debug_show_one(m, d, 0); | 1726 | irq_domain_debug_show_one(m, d, 0); |
| 1727 | return 0; | 1727 | return 0; |
| 1728 | } | 1728 | } |
| 1729 | 1729 | DEFINE_SHOW_ATTRIBUTE(irq_domain_debug); | |
| 1730 | static int irq_domain_debug_open(struct inode *inode, struct file *file) | ||
| 1731 | { | ||
| 1732 | return single_open(file, irq_domain_debug_show, inode->i_private); | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | static const struct file_operations dfs_domain_ops = { | ||
| 1736 | .open = irq_domain_debug_open, | ||
| 1737 | .read = seq_read, | ||
| 1738 | .llseek = seq_lseek, | ||
| 1739 | .release = single_release, | ||
| 1740 | }; | ||
| 1741 | 1730 | ||
| 1742 | static void debugfs_add_domain_dir(struct irq_domain *d) | 1731 | static void debugfs_add_domain_dir(struct irq_domain *d) |
| 1743 | { | 1732 | { |
| 1744 | if (!d->name || !domain_dir || d->debugfs_file) | 1733 | if (!d->name || !domain_dir || d->debugfs_file) |
| 1745 | return; | 1734 | return; |
| 1746 | d->debugfs_file = debugfs_create_file(d->name, 0444, domain_dir, d, | 1735 | d->debugfs_file = debugfs_create_file(d->name, 0444, domain_dir, d, |
| 1747 | &dfs_domain_ops); | 1736 | &irq_domain_debug_fops); |
| 1748 | } | 1737 | } |
| 1749 | 1738 | ||
| 1750 | static void debugfs_remove_domain_dir(struct irq_domain *d) | 1739 | static void debugfs_remove_domain_dir(struct irq_domain *d) |
| @@ -1760,7 +1749,8 @@ void __init irq_domain_debugfs_init(struct dentry *root) | |||
| 1760 | if (!domain_dir) | 1749 | if (!domain_dir) |
| 1761 | return; | 1750 | return; |
| 1762 | 1751 | ||
| 1763 | debugfs_create_file("default", 0444, domain_dir, NULL, &dfs_domain_ops); | 1752 | debugfs_create_file("default", 0444, domain_dir, NULL, |
| 1753 | &irq_domain_debug_fops); | ||
| 1764 | mutex_lock(&irq_domain_mutex); | 1754 | mutex_lock(&irq_domain_mutex); |
| 1765 | list_for_each_entry(d, &irq_domain_list, link) | 1755 | list_for_each_entry(d, &irq_domain_list, link) |
| 1766 | debugfs_add_domain_dir(d); | 1756 | debugfs_add_domain_dir(d); |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index da2ccf142358..102160ff5c66 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -978,67 +978,90 @@ static int prepare_kprobe(struct kprobe *p) | |||
| 978 | } | 978 | } |
| 979 | 979 | ||
| 980 | /* Caller must lock kprobe_mutex */ | 980 | /* Caller must lock kprobe_mutex */ |
| 981 | static void arm_kprobe_ftrace(struct kprobe *p) | 981 | static int arm_kprobe_ftrace(struct kprobe *p) |
| 982 | { | 982 | { |
| 983 | int ret; | 983 | int ret = 0; |
| 984 | 984 | ||
| 985 | ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, | 985 | ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, |
| 986 | (unsigned long)p->addr, 0, 0); | 986 | (unsigned long)p->addr, 0, 0); |
| 987 | WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret); | 987 | if (ret) { |
| 988 | kprobe_ftrace_enabled++; | 988 | pr_debug("Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret); |
| 989 | if (kprobe_ftrace_enabled == 1) { | 989 | return ret; |
| 990 | } | ||
| 991 | |||
| 992 | if (kprobe_ftrace_enabled == 0) { | ||
| 990 | ret = register_ftrace_function(&kprobe_ftrace_ops); | 993 | ret = register_ftrace_function(&kprobe_ftrace_ops); |
| 991 | WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret); | 994 | if (ret) { |
| 995 | pr_debug("Failed to init kprobe-ftrace (%d)\n", ret); | ||
| 996 | goto err_ftrace; | ||
| 997 | } | ||
| 992 | } | 998 | } |
| 999 | |||
| 1000 | kprobe_ftrace_enabled++; | ||
| 1001 | return ret; | ||
| 1002 | |||
| 1003 | err_ftrace: | ||
| 1004 | /* | ||
| 1005 | * Note: Since kprobe_ftrace_ops has IPMODIFY set, and ftrace requires a | ||
| 1006 | * non-empty filter_hash for IPMODIFY ops, we're safe from an accidental | ||
| 1007 | * empty filter_hash which would undesirably trace all functions. | ||
| 1008 | */ | ||
| 1009 | ftrace_set_filter_ip(&kprobe_ftrace_ops, (unsigned long)p->addr, 1, 0); | ||
| 1010 | return ret; | ||
| 993 | } | 1011 | } |
| 994 | 1012 | ||
| 995 | /* Caller must lock kprobe_mutex */ | 1013 | /* Caller must lock kprobe_mutex */ |
| 996 | static void disarm_kprobe_ftrace(struct kprobe *p) | 1014 | static int disarm_kprobe_ftrace(struct kprobe *p) |
| 997 | { | 1015 | { |
| 998 | int ret; | 1016 | int ret = 0; |
| 999 | 1017 | ||
| 1000 | kprobe_ftrace_enabled--; | 1018 | if (kprobe_ftrace_enabled == 1) { |
| 1001 | if (kprobe_ftrace_enabled == 0) { | ||
| 1002 | ret = unregister_ftrace_function(&kprobe_ftrace_ops); | 1019 | ret = unregister_ftrace_function(&kprobe_ftrace_ops); |
| 1003 | WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret); | 1020 | if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", ret)) |
| 1021 | return ret; | ||
| 1004 | } | 1022 | } |
| 1023 | |||
| 1024 | kprobe_ftrace_enabled--; | ||
| 1025 | |||
| 1005 | ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, | 1026 | ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, |
| 1006 | (unsigned long)p->addr, 1, 0); | 1027 | (unsigned long)p->addr, 1, 0); |
| 1007 | WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret); | 1028 | WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret); |
| 1029 | return ret; | ||
| 1008 | } | 1030 | } |
| 1009 | #else /* !CONFIG_KPROBES_ON_FTRACE */ | 1031 | #else /* !CONFIG_KPROBES_ON_FTRACE */ |
| 1010 | #define prepare_kprobe(p) arch_prepare_kprobe(p) | 1032 | #define prepare_kprobe(p) arch_prepare_kprobe(p) |
| 1011 | #define arm_kprobe_ftrace(p) do {} while (0) | 1033 | #define arm_kprobe_ftrace(p) (-ENODEV) |
| 1012 | #define disarm_kprobe_ftrace(p) do {} while (0) | 1034 | #define disarm_kprobe_ftrace(p) (-ENODEV) |
| 1013 | #endif | 1035 | #endif |
| 1014 | 1036 | ||
| 1015 | /* Arm a kprobe with text_mutex */ | 1037 | /* Arm a kprobe with text_mutex */ |
| 1016 | static void arm_kprobe(struct kprobe *kp) | 1038 | static int arm_kprobe(struct kprobe *kp) |
| 1017 | { | 1039 | { |
| 1018 | if (unlikely(kprobe_ftrace(kp))) { | 1040 | if (unlikely(kprobe_ftrace(kp))) |
| 1019 | arm_kprobe_ftrace(kp); | 1041 | return arm_kprobe_ftrace(kp); |
| 1020 | return; | 1042 | |
| 1021 | } | ||
| 1022 | cpus_read_lock(); | 1043 | cpus_read_lock(); |
| 1023 | mutex_lock(&text_mutex); | 1044 | mutex_lock(&text_mutex); |
| 1024 | __arm_kprobe(kp); | 1045 | __arm_kprobe(kp); |
| 1025 | mutex_unlock(&text_mutex); | 1046 | mutex_unlock(&text_mutex); |
| 1026 | cpus_read_unlock(); | 1047 | cpus_read_unlock(); |
| 1048 | |||
| 1049 | return 0; | ||
| 1027 | } | 1050 | } |
| 1028 | 1051 | ||
| 1029 | /* Disarm a kprobe with text_mutex */ | 1052 | /* Disarm a kprobe with text_mutex */ |
| 1030 | static void disarm_kprobe(struct kprobe *kp, bool reopt) | 1053 | static int disarm_kprobe(struct kprobe *kp, bool reopt) |
| 1031 | { | 1054 | { |
| 1032 | if (unlikely(kprobe_ftrace(kp))) { | 1055 | if (unlikely(kprobe_ftrace(kp))) |
| 1033 | disarm_kprobe_ftrace(kp); | 1056 | return disarm_kprobe_ftrace(kp); |
| 1034 | return; | ||
| 1035 | } | ||
| 1036 | 1057 | ||
| 1037 | cpus_read_lock(); | 1058 | cpus_read_lock(); |
| 1038 | mutex_lock(&text_mutex); | 1059 | mutex_lock(&text_mutex); |
| 1039 | __disarm_kprobe(kp, reopt); | 1060 | __disarm_kprobe(kp, reopt); |
| 1040 | mutex_unlock(&text_mutex); | 1061 | mutex_unlock(&text_mutex); |
| 1041 | cpus_read_unlock(); | 1062 | cpus_read_unlock(); |
| 1063 | |||
| 1064 | return 0; | ||
| 1042 | } | 1065 | } |
| 1043 | 1066 | ||
| 1044 | /* | 1067 | /* |
| @@ -1362,9 +1385,15 @@ out: | |||
| 1362 | 1385 | ||
| 1363 | if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) { | 1386 | if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) { |
| 1364 | ap->flags &= ~KPROBE_FLAG_DISABLED; | 1387 | ap->flags &= ~KPROBE_FLAG_DISABLED; |
| 1365 | if (!kprobes_all_disarmed) | 1388 | if (!kprobes_all_disarmed) { |
| 1366 | /* Arm the breakpoint again. */ | 1389 | /* Arm the breakpoint again. */ |
| 1367 | arm_kprobe(ap); | 1390 | ret = arm_kprobe(ap); |
| 1391 | if (ret) { | ||
| 1392 | ap->flags |= KPROBE_FLAG_DISABLED; | ||
| 1393 | list_del_rcu(&p->list); | ||
| 1394 | synchronize_sched(); | ||
| 1395 | } | ||
| 1396 | } | ||
| 1368 | } | 1397 | } |
| 1369 | return ret; | 1398 | return ret; |
| 1370 | } | 1399 | } |
| @@ -1573,8 +1602,14 @@ int register_kprobe(struct kprobe *p) | |||
| 1573 | hlist_add_head_rcu(&p->hlist, | 1602 | hlist_add_head_rcu(&p->hlist, |
| 1574 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); | 1603 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); |
| 1575 | 1604 | ||
| 1576 | if (!kprobes_all_disarmed && !kprobe_disabled(p)) | 1605 | if (!kprobes_all_disarmed && !kprobe_disabled(p)) { |
| 1577 | arm_kprobe(p); | 1606 | ret = arm_kprobe(p); |
| 1607 | if (ret) { | ||
| 1608 | hlist_del_rcu(&p->hlist); | ||
| 1609 | synchronize_sched(); | ||
| 1610 | goto out; | ||
| 1611 | } | ||
| 1612 | } | ||
| 1578 | 1613 | ||
| 1579 | /* Try to optimize kprobe */ | 1614 | /* Try to optimize kprobe */ |
| 1580 | try_to_optimize_kprobe(p); | 1615 | try_to_optimize_kprobe(p); |
| @@ -1608,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap) | |||
| 1608 | static struct kprobe *__disable_kprobe(struct kprobe *p) | 1643 | static struct kprobe *__disable_kprobe(struct kprobe *p) |
| 1609 | { | 1644 | { |
| 1610 | struct kprobe *orig_p; | 1645 | struct kprobe *orig_p; |
| 1646 | int ret; | ||
| 1611 | 1647 | ||
| 1612 | /* Get an original kprobe for return */ | 1648 | /* Get an original kprobe for return */ |
| 1613 | orig_p = __get_valid_kprobe(p); | 1649 | orig_p = __get_valid_kprobe(p); |
| 1614 | if (unlikely(orig_p == NULL)) | 1650 | if (unlikely(orig_p == NULL)) |
| 1615 | return NULL; | 1651 | return ERR_PTR(-EINVAL); |
| 1616 | 1652 | ||
| 1617 | if (!kprobe_disabled(p)) { | 1653 | if (!kprobe_disabled(p)) { |
| 1618 | /* Disable probe if it is a child probe */ | 1654 | /* Disable probe if it is a child probe */ |
| @@ -1626,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p) | |||
| 1626 | * should have already been disarmed, so | 1662 | * should have already been disarmed, so |
| 1627 | * skip unneed disarming process. | 1663 | * skip unneed disarming process. |
| 1628 | */ | 1664 | */ |
| 1629 | if (!kprobes_all_disarmed) | 1665 | if (!kprobes_all_disarmed) { |
| 1630 | disarm_kprobe(orig_p, true); | 1666 | ret = disarm_kprobe(orig_p, true); |
| 1667 | if (ret) { | ||
| 1668 | p->flags &= ~KPROBE_FLAG_DISABLED; | ||
| 1669 | return ERR_PTR(ret); | ||
| 1670 | } | ||
| 1671 | } | ||
| 1631 | orig_p->flags |= KPROBE_FLAG_DISABLED; | 1672 | orig_p->flags |= KPROBE_FLAG_DISABLED; |
| 1632 | } | 1673 | } |
| 1633 | } | 1674 | } |
| @@ -1644,8 +1685,8 @@ static int __unregister_kprobe_top(struct kprobe *p) | |||
| 1644 | 1685 | ||
| 1645 | /* Disable kprobe. This will disarm it if needed. */ | 1686 | /* Disable kprobe. This will disarm it if needed. */ |
| 1646 | ap = __disable_kprobe(p); | 1687 | ap = __disable_kprobe(p); |
| 1647 | if (ap == NULL) | 1688 | if (IS_ERR(ap)) |
| 1648 | return -EINVAL; | 1689 | return PTR_ERR(ap); |
| 1649 | 1690 | ||
| 1650 | if (ap == p) | 1691 | if (ap == p) |
| 1651 | /* | 1692 | /* |
| @@ -2078,12 +2119,14 @@ static void kill_kprobe(struct kprobe *p) | |||
| 2078 | int disable_kprobe(struct kprobe *kp) | 2119 | int disable_kprobe(struct kprobe *kp) |
| 2079 | { | 2120 | { |
| 2080 | int ret = 0; | 2121 | int ret = 0; |
| 2122 | struct kprobe *p; | ||
| 2081 | 2123 | ||
| 2082 | mutex_lock(&kprobe_mutex); | 2124 | mutex_lock(&kprobe_mutex); |
| 2083 | 2125 | ||
| 2084 | /* Disable this kprobe */ | 2126 | /* Disable this kprobe */ |
| 2085 | if (__disable_kprobe(kp) == NULL) | 2127 | p = __disable_kprobe(kp); |
| 2086 | ret = -EINVAL; | 2128 | if (IS_ERR(p)) |
| 2129 | ret = PTR_ERR(p); | ||
| 2087 | 2130 | ||
| 2088 | mutex_unlock(&kprobe_mutex); | 2131 | mutex_unlock(&kprobe_mutex); |
| 2089 | return ret; | 2132 | return ret; |
| @@ -2116,7 +2159,9 @@ int enable_kprobe(struct kprobe *kp) | |||
| 2116 | 2159 | ||
| 2117 | if (!kprobes_all_disarmed && kprobe_disabled(p)) { | 2160 | if (!kprobes_all_disarmed && kprobe_disabled(p)) { |
| 2118 | p->flags &= ~KPROBE_FLAG_DISABLED; | 2161 | p->flags &= ~KPROBE_FLAG_DISABLED; |
| 2119 | arm_kprobe(p); | 2162 | ret = arm_kprobe(p); |
| 2163 | if (ret) | ||
| 2164 | p->flags |= KPROBE_FLAG_DISABLED; | ||
| 2120 | } | 2165 | } |
| 2121 | out: | 2166 | out: |
| 2122 | mutex_unlock(&kprobe_mutex); | 2167 | mutex_unlock(&kprobe_mutex); |
| @@ -2407,11 +2452,12 @@ static const struct file_operations debugfs_kprobe_blacklist_ops = { | |||
| 2407 | .release = seq_release, | 2452 | .release = seq_release, |
| 2408 | }; | 2453 | }; |
| 2409 | 2454 | ||
| 2410 | static void arm_all_kprobes(void) | 2455 | static int arm_all_kprobes(void) |
| 2411 | { | 2456 | { |
| 2412 | struct hlist_head *head; | 2457 | struct hlist_head *head; |
| 2413 | struct kprobe *p; | 2458 | struct kprobe *p; |
| 2414 | unsigned int i; | 2459 | unsigned int i, total = 0, errors = 0; |
| 2460 | int err, ret = 0; | ||
| 2415 | 2461 | ||
| 2416 | mutex_lock(&kprobe_mutex); | 2462 | mutex_lock(&kprobe_mutex); |
| 2417 | 2463 | ||
| @@ -2428,46 +2474,74 @@ static void arm_all_kprobes(void) | |||
| 2428 | /* Arming kprobes doesn't optimize kprobe itself */ | 2474 | /* Arming kprobes doesn't optimize kprobe itself */ |
| 2429 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 2475 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 2430 | head = &kprobe_table[i]; | 2476 | head = &kprobe_table[i]; |
| 2431 | hlist_for_each_entry_rcu(p, head, hlist) | 2477 | /* Arm all kprobes on a best-effort basis */ |
| 2432 | if (!kprobe_disabled(p)) | 2478 | hlist_for_each_entry_rcu(p, head, hlist) { |
| 2433 | arm_kprobe(p); | 2479 | if (!kprobe_disabled(p)) { |
| 2480 | err = arm_kprobe(p); | ||
| 2481 | if (err) { | ||
| 2482 | errors++; | ||
| 2483 | ret = err; | ||
| 2484 | } | ||
| 2485 | total++; | ||
| 2486 | } | ||
| 2487 | } | ||
| 2434 | } | 2488 | } |
| 2435 | 2489 | ||
| 2436 | printk(KERN_INFO "Kprobes globally enabled\n"); | 2490 | if (errors) |
| 2491 | pr_warn("Kprobes globally enabled, but failed to arm %d out of %d probes\n", | ||
| 2492 | errors, total); | ||
| 2493 | else | ||
| 2494 | pr_info("Kprobes globally enabled\n"); | ||
| 2437 | 2495 | ||
| 2438 | already_enabled: | 2496 | already_enabled: |
| 2439 | mutex_unlock(&kprobe_mutex); | 2497 | mutex_unlock(&kprobe_mutex); |
| 2440 | return; | 2498 | return ret; |
| 2441 | } | 2499 | } |
| 2442 | 2500 | ||
| 2443 | static void disarm_all_kprobes(void) | 2501 | static int disarm_all_kprobes(void) |
| 2444 | { | 2502 | { |
| 2445 | struct hlist_head *head; | 2503 | struct hlist_head *head; |
| 2446 | struct kprobe *p; | 2504 | struct kprobe *p; |
| 2447 | unsigned int i; | 2505 | unsigned int i, total = 0, errors = 0; |
| 2506 | int err, ret = 0; | ||
| 2448 | 2507 | ||
| 2449 | mutex_lock(&kprobe_mutex); | 2508 | mutex_lock(&kprobe_mutex); |
| 2450 | 2509 | ||
| 2451 | /* If kprobes are already disarmed, just return */ | 2510 | /* If kprobes are already disarmed, just return */ |
| 2452 | if (kprobes_all_disarmed) { | 2511 | if (kprobes_all_disarmed) { |
| 2453 | mutex_unlock(&kprobe_mutex); | 2512 | mutex_unlock(&kprobe_mutex); |
| 2454 | return; | 2513 | return 0; |
| 2455 | } | 2514 | } |
| 2456 | 2515 | ||
| 2457 | kprobes_all_disarmed = true; | 2516 | kprobes_all_disarmed = true; |
| 2458 | printk(KERN_INFO "Kprobes globally disabled\n"); | ||
| 2459 | 2517 | ||
| 2460 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 2518 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 2461 | head = &kprobe_table[i]; | 2519 | head = &kprobe_table[i]; |
| 2520 | /* Disarm all kprobes on a best-effort basis */ | ||
| 2462 | hlist_for_each_entry_rcu(p, head, hlist) { | 2521 | hlist_for_each_entry_rcu(p, head, hlist) { |
| 2463 | if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) | 2522 | if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) { |
| 2464 | disarm_kprobe(p, false); | 2523 | err = disarm_kprobe(p, false); |
| 2524 | if (err) { | ||
| 2525 | errors++; | ||
| 2526 | ret = err; | ||
| 2527 | } | ||
| 2528 | total++; | ||
| 2529 | } | ||
| 2465 | } | 2530 | } |
| 2466 | } | 2531 | } |
| 2532 | |||
| 2533 | if (errors) | ||
| 2534 | pr_warn("Kprobes globally disabled, but failed to disarm %d out of %d probes\n", | ||
| 2535 | errors, total); | ||
| 2536 | else | ||
| 2537 | pr_info("Kprobes globally disabled\n"); | ||
| 2538 | |||
| 2467 | mutex_unlock(&kprobe_mutex); | 2539 | mutex_unlock(&kprobe_mutex); |
| 2468 | 2540 | ||
| 2469 | /* Wait for disarming all kprobes by optimizer */ | 2541 | /* Wait for disarming all kprobes by optimizer */ |
| 2470 | wait_for_kprobe_optimizer(); | 2542 | wait_for_kprobe_optimizer(); |
| 2543 | |||
| 2544 | return ret; | ||
| 2471 | } | 2545 | } |
| 2472 | 2546 | ||
| 2473 | /* | 2547 | /* |
| @@ -2494,6 +2568,7 @@ static ssize_t write_enabled_file_bool(struct file *file, | |||
| 2494 | { | 2568 | { |
| 2495 | char buf[32]; | 2569 | char buf[32]; |
| 2496 | size_t buf_size; | 2570 | size_t buf_size; |
| 2571 | int ret = 0; | ||
| 2497 | 2572 | ||
| 2498 | buf_size = min(count, (sizeof(buf)-1)); | 2573 | buf_size = min(count, (sizeof(buf)-1)); |
| 2499 | if (copy_from_user(buf, user_buf, buf_size)) | 2574 | if (copy_from_user(buf, user_buf, buf_size)) |
| @@ -2504,17 +2579,20 @@ static ssize_t write_enabled_file_bool(struct file *file, | |||
| 2504 | case 'y': | 2579 | case 'y': |
| 2505 | case 'Y': | 2580 | case 'Y': |
| 2506 | case '1': | 2581 | case '1': |
| 2507 | arm_all_kprobes(); | 2582 | ret = arm_all_kprobes(); |
| 2508 | break; | 2583 | break; |
| 2509 | case 'n': | 2584 | case 'n': |
| 2510 | case 'N': | 2585 | case 'N': |
| 2511 | case '0': | 2586 | case '0': |
| 2512 | disarm_all_kprobes(); | 2587 | ret = disarm_all_kprobes(); |
| 2513 | break; | 2588 | break; |
| 2514 | default: | 2589 | default: |
| 2515 | return -EINVAL; | 2590 | return -EINVAL; |
| 2516 | } | 2591 | } |
| 2517 | 2592 | ||
| 2593 | if (ret) | ||
| 2594 | return ret; | ||
| 2595 | |||
| 2518 | return count; | 2596 | return count; |
| 2519 | } | 2597 | } |
| 2520 | 2598 | ||
diff --git a/kernel/relay.c b/kernel/relay.c index c3029402f15c..c955b10c973c 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
| @@ -163,7 +163,7 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan) | |||
| 163 | { | 163 | { |
| 164 | struct rchan_buf *buf; | 164 | struct rchan_buf *buf; |
| 165 | 165 | ||
| 166 | if (chan->n_subbufs > UINT_MAX / sizeof(size_t *)) | 166 | if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *)) |
| 167 | return NULL; | 167 | return NULL; |
| 168 | 168 | ||
| 169 | buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL); | 169 | buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL); |
diff --git a/kernel/user.c b/kernel/user.c index 9a20acce460d..36288d840675 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
| @@ -101,6 +101,7 @@ struct user_struct root_user = { | |||
| 101 | .sigpending = ATOMIC_INIT(0), | 101 | .sigpending = ATOMIC_INIT(0), |
| 102 | .locked_shm = 0, | 102 | .locked_shm = 0, |
| 103 | .uid = GLOBAL_ROOT_UID, | 103 | .uid = GLOBAL_ROOT_UID, |
| 104 | .ratelimit = RATELIMIT_STATE_INIT(root_user.ratelimit, 0, 0), | ||
| 104 | }; | 105 | }; |
| 105 | 106 | ||
| 106 | /* | 107 | /* |
| @@ -191,6 +192,8 @@ struct user_struct *alloc_uid(kuid_t uid) | |||
| 191 | 192 | ||
| 192 | new->uid = uid; | 193 | new->uid = uid; |
| 193 | atomic_set(&new->__count, 1); | 194 | atomic_set(&new->__count, 1); |
| 195 | ratelimit_state_init(&new->ratelimit, HZ, 100); | ||
| 196 | ratelimit_set_flags(&new->ratelimit, RATELIMIT_MSG_ON_RELEASE); | ||
| 194 | 197 | ||
| 195 | /* | 198 | /* |
| 196 | * Before adding this, check whether we raced | 199 | * Before adding this, check whether we raced |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6088408ef26c..64155e310a9f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -1642,6 +1642,7 @@ config DMA_API_DEBUG | |||
| 1642 | 1642 | ||
| 1643 | menuconfig RUNTIME_TESTING_MENU | 1643 | menuconfig RUNTIME_TESTING_MENU |
| 1644 | bool "Runtime Testing" | 1644 | bool "Runtime Testing" |
| 1645 | def_bool y | ||
| 1645 | 1646 | ||
| 1646 | if RUNTIME_TESTING_MENU | 1647 | if RUNTIME_TESTING_MENU |
| 1647 | 1648 | ||
diff --git a/lib/dma-direct.c b/lib/dma-direct.c index 40b1f92f2214..c9e8e21cb334 100644 --- a/lib/dma-direct.c +++ b/lib/dma-direct.c | |||
| @@ -84,6 +84,10 @@ again: | |||
| 84 | return page_address(page); | 84 | return page_address(page); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | /* | ||
| 88 | * NOTE: this function must never look at the dma_addr argument, because we want | ||
| 89 | * to be able to use it as a helper for iommu implementations as well. | ||
| 90 | */ | ||
| 87 | void dma_direct_free(struct device *dev, size_t size, void *cpu_addr, | 91 | void dma_direct_free(struct device *dev, size_t size, void *cpu_addr, |
| 88 | dma_addr_t dma_addr, unsigned long attrs) | 92 | dma_addr_t dma_addr, unsigned long attrs) |
| 89 | { | 93 | { |
| @@ -152,5 +156,6 @@ const struct dma_map_ops dma_direct_ops = { | |||
| 152 | .map_sg = dma_direct_map_sg, | 156 | .map_sg = dma_direct_map_sg, |
| 153 | .dma_supported = dma_direct_supported, | 157 | .dma_supported = dma_direct_supported, |
| 154 | .mapping_error = dma_direct_mapping_error, | 158 | .mapping_error = dma_direct_mapping_error, |
| 159 | .is_phys = 1, | ||
| 155 | }; | 160 | }; |
| 156 | EXPORT_SYMBOL(dma_direct_ops); | 161 | EXPORT_SYMBOL(dma_direct_ops); |
| @@ -431,7 +431,6 @@ int ida_get_new_above(struct ida *ida, int start, int *id) | |||
| 431 | bitmap = this_cpu_xchg(ida_bitmap, NULL); | 431 | bitmap = this_cpu_xchg(ida_bitmap, NULL); |
| 432 | if (!bitmap) | 432 | if (!bitmap) |
| 433 | return -EAGAIN; | 433 | return -EAGAIN; |
| 434 | memset(bitmap, 0, sizeof(*bitmap)); | ||
| 435 | bitmap->bitmap[0] = tmp >> RADIX_TREE_EXCEPTIONAL_SHIFT; | 434 | bitmap->bitmap[0] = tmp >> RADIX_TREE_EXCEPTIONAL_SHIFT; |
| 436 | rcu_assign_pointer(*slot, bitmap); | 435 | rcu_assign_pointer(*slot, bitmap); |
| 437 | } | 436 | } |
| @@ -464,7 +463,6 @@ int ida_get_new_above(struct ida *ida, int start, int *id) | |||
| 464 | bitmap = this_cpu_xchg(ida_bitmap, NULL); | 463 | bitmap = this_cpu_xchg(ida_bitmap, NULL); |
| 465 | if (!bitmap) | 464 | if (!bitmap) |
| 466 | return -EAGAIN; | 465 | return -EAGAIN; |
| 467 | memset(bitmap, 0, sizeof(*bitmap)); | ||
| 468 | __set_bit(bit, bitmap->bitmap); | 466 | __set_bit(bit, bitmap->bitmap); |
| 469 | radix_tree_iter_replace(root, &iter, slot, bitmap); | 467 | radix_tree_iter_replace(root, &iter, slot, bitmap); |
| 470 | } | 468 | } |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 0a7ae3288a24..8e00138d593f 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
| @@ -2125,7 +2125,7 @@ int ida_pre_get(struct ida *ida, gfp_t gfp) | |||
| 2125 | preempt_enable(); | 2125 | preempt_enable(); |
| 2126 | 2126 | ||
| 2127 | if (!this_cpu_read(ida_bitmap)) { | 2127 | if (!this_cpu_read(ida_bitmap)) { |
| 2128 | struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); | 2128 | struct ida_bitmap *bitmap = kzalloc(sizeof(*bitmap), gfp); |
| 2129 | if (!bitmap) | 2129 | if (!bitmap) |
| 2130 | return 0; | 2130 | return 0; |
| 2131 | if (this_cpu_cmpxchg(ida_bitmap, NULL, bitmap)) | 2131 | if (this_cpu_cmpxchg(ida_bitmap, NULL, bitmap)) |
diff --git a/mm/mlock.c b/mm/mlock.c index 79398200e423..74e5a6547c3d 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
| @@ -64,6 +64,12 @@ void clear_page_mlock(struct page *page) | |||
| 64 | mod_zone_page_state(page_zone(page), NR_MLOCK, | 64 | mod_zone_page_state(page_zone(page), NR_MLOCK, |
| 65 | -hpage_nr_pages(page)); | 65 | -hpage_nr_pages(page)); |
| 66 | count_vm_event(UNEVICTABLE_PGCLEARED); | 66 | count_vm_event(UNEVICTABLE_PGCLEARED); |
| 67 | /* | ||
| 68 | * The previous TestClearPageMlocked() corresponds to the smp_mb() | ||
| 69 | * in __pagevec_lru_add_fn(). | ||
| 70 | * | ||
| 71 | * See __pagevec_lru_add_fn for more explanation. | ||
| 72 | */ | ||
| 67 | if (!isolate_lru_page(page)) { | 73 | if (!isolate_lru_page(page)) { |
| 68 | putback_lru_page(page); | 74 | putback_lru_page(page); |
| 69 | } else { | 75 | } else { |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 81e18ceef579..cb416723538f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/stop_machine.h> | 46 | #include <linux/stop_machine.h> |
| 47 | #include <linux/sort.h> | 47 | #include <linux/sort.h> |
| 48 | #include <linux/pfn.h> | 48 | #include <linux/pfn.h> |
| 49 | #include <xen/xen.h> | ||
| 49 | #include <linux/backing-dev.h> | 50 | #include <linux/backing-dev.h> |
| 50 | #include <linux/fault-inject.h> | 51 | #include <linux/fault-inject.h> |
| 51 | #include <linux/page-isolation.h> | 52 | #include <linux/page-isolation.h> |
| @@ -347,6 +348,9 @@ static inline bool update_defer_init(pg_data_t *pgdat, | |||
| 347 | /* Always populate low zones for address-constrained allocations */ | 348 | /* Always populate low zones for address-constrained allocations */ |
| 348 | if (zone_end < pgdat_end_pfn(pgdat)) | 349 | if (zone_end < pgdat_end_pfn(pgdat)) |
| 349 | return true; | 350 | return true; |
| 351 | /* Xen PV domains need page structures early */ | ||
| 352 | if (xen_pv_domain()) | ||
| 353 | return true; | ||
| 350 | (*nr_initialised)++; | 354 | (*nr_initialised)++; |
| 351 | if ((*nr_initialised > pgdat->static_init_pgcnt) && | 355 | if ((*nr_initialised > pgdat->static_init_pgcnt) && |
| 352 | (pfn & (PAGES_PER_SECTION - 1)) == 0) { | 356 | (pfn & (PAGES_PER_SECTION - 1)) == 0) { |
| @@ -446,30 +446,6 @@ void lru_cache_add(struct page *page) | |||
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | /** | 448 | /** |
| 449 | * add_page_to_unevictable_list - add a page to the unevictable list | ||
| 450 | * @page: the page to be added to the unevictable list | ||
| 451 | * | ||
| 452 | * Add page directly to its zone's unevictable list. To avoid races with | ||
| 453 | * tasks that might be making the page evictable, through eg. munlock, | ||
| 454 | * munmap or exit, while it's not on the lru, we want to add the page | ||
| 455 | * while it's locked or otherwise "invisible" to other tasks. This is | ||
| 456 | * difficult to do when using the pagevec cache, so bypass that. | ||
| 457 | */ | ||
| 458 | void add_page_to_unevictable_list(struct page *page) | ||
| 459 | { | ||
| 460 | struct pglist_data *pgdat = page_pgdat(page); | ||
| 461 | struct lruvec *lruvec; | ||
| 462 | |||
| 463 | spin_lock_irq(&pgdat->lru_lock); | ||
| 464 | lruvec = mem_cgroup_page_lruvec(page, pgdat); | ||
| 465 | ClearPageActive(page); | ||
| 466 | SetPageUnevictable(page); | ||
| 467 | SetPageLRU(page); | ||
| 468 | add_page_to_lru_list(page, lruvec, LRU_UNEVICTABLE); | ||
| 469 | spin_unlock_irq(&pgdat->lru_lock); | ||
| 470 | } | ||
| 471 | |||
| 472 | /** | ||
| 473 | * lru_cache_add_active_or_unevictable | 449 | * lru_cache_add_active_or_unevictable |
| 474 | * @page: the page to be added to LRU | 450 | * @page: the page to be added to LRU |
| 475 | * @vma: vma in which page is mapped for determining reclaimability | 451 | * @vma: vma in which page is mapped for determining reclaimability |
| @@ -484,13 +460,9 @@ void lru_cache_add_active_or_unevictable(struct page *page, | |||
| 484 | { | 460 | { |
| 485 | VM_BUG_ON_PAGE(PageLRU(page), page); | 461 | VM_BUG_ON_PAGE(PageLRU(page), page); |
| 486 | 462 | ||
| 487 | if (likely((vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) != VM_LOCKED)) { | 463 | if (likely((vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) != VM_LOCKED)) |
| 488 | SetPageActive(page); | 464 | SetPageActive(page); |
| 489 | lru_cache_add(page); | 465 | else if (!TestSetPageMlocked(page)) { |
| 490 | return; | ||
| 491 | } | ||
| 492 | |||
| 493 | if (!TestSetPageMlocked(page)) { | ||
| 494 | /* | 466 | /* |
| 495 | * We use the irq-unsafe __mod_zone_page_stat because this | 467 | * We use the irq-unsafe __mod_zone_page_stat because this |
| 496 | * counter is not modified from interrupt context, and the pte | 468 | * counter is not modified from interrupt context, and the pte |
| @@ -500,7 +472,7 @@ void lru_cache_add_active_or_unevictable(struct page *page, | |||
| 500 | hpage_nr_pages(page)); | 472 | hpage_nr_pages(page)); |
| 501 | count_vm_event(UNEVICTABLE_PGMLOCKED); | 473 | count_vm_event(UNEVICTABLE_PGMLOCKED); |
| 502 | } | 474 | } |
| 503 | add_page_to_unevictable_list(page); | 475 | lru_cache_add(page); |
| 504 | } | 476 | } |
| 505 | 477 | ||
| 506 | /* | 478 | /* |
| @@ -886,15 +858,55 @@ void lru_add_page_tail(struct page *page, struct page *page_tail, | |||
| 886 | static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec, | 858 | static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec, |
| 887 | void *arg) | 859 | void *arg) |
| 888 | { | 860 | { |
| 889 | int file = page_is_file_cache(page); | 861 | enum lru_list lru; |
| 890 | int active = PageActive(page); | 862 | int was_unevictable = TestClearPageUnevictable(page); |
| 891 | enum lru_list lru = page_lru(page); | ||
| 892 | 863 | ||
| 893 | VM_BUG_ON_PAGE(PageLRU(page), page); | 864 | VM_BUG_ON_PAGE(PageLRU(page), page); |
| 894 | 865 | ||
| 895 | SetPageLRU(page); | 866 | SetPageLRU(page); |
| 867 | /* | ||
| 868 | * Page becomes evictable in two ways: | ||
| 869 | * 1) Within LRU lock [munlock_vma_pages() and __munlock_pagevec()]. | ||
| 870 | * 2) Before acquiring LRU lock to put the page to correct LRU and then | ||
| 871 | * a) do PageLRU check with lock [check_move_unevictable_pages] | ||
| 872 | * b) do PageLRU check before lock [clear_page_mlock] | ||
| 873 | * | ||
| 874 | * (1) & (2a) are ok as LRU lock will serialize them. For (2b), we need | ||
| 875 | * following strict ordering: | ||
| 876 | * | ||
| 877 | * #0: __pagevec_lru_add_fn #1: clear_page_mlock | ||
| 878 | * | ||
| 879 | * SetPageLRU() TestClearPageMlocked() | ||
| 880 | * smp_mb() // explicit ordering // above provides strict | ||
| 881 | * // ordering | ||
| 882 | * PageMlocked() PageLRU() | ||
| 883 | * | ||
| 884 | * | ||
| 885 | * if '#1' does not observe setting of PG_lru by '#0' and fails | ||
| 886 | * isolation, the explicit barrier will make sure that page_evictable | ||
| 887 | * check will put the page in correct LRU. Without smp_mb(), SetPageLRU | ||
| 888 | * can be reordered after PageMlocked check and can make '#1' to fail | ||
| 889 | * the isolation of the page whose Mlocked bit is cleared (#0 is also | ||
| 890 | * looking at the same page) and the evictable page will be stranded | ||
| 891 | * in an unevictable LRU. | ||
| 892 | */ | ||
| 893 | smp_mb(); | ||
| 894 | |||
| 895 | if (page_evictable(page)) { | ||
| 896 | lru = page_lru(page); | ||
| 897 | update_page_reclaim_stat(lruvec, page_is_file_cache(page), | ||
| 898 | PageActive(page)); | ||
| 899 | if (was_unevictable) | ||
| 900 | count_vm_event(UNEVICTABLE_PGRESCUED); | ||
| 901 | } else { | ||
| 902 | lru = LRU_UNEVICTABLE; | ||
| 903 | ClearPageActive(page); | ||
| 904 | SetPageUnevictable(page); | ||
| 905 | if (!was_unevictable) | ||
| 906 | count_vm_event(UNEVICTABLE_PGCULLED); | ||
| 907 | } | ||
| 908 | |||
| 896 | add_page_to_lru_list(page, lruvec, lru); | 909 | add_page_to_lru_list(page, lruvec, lru); |
| 897 | update_page_reclaim_stat(lruvec, file, active); | ||
| 898 | trace_mm_lru_insertion(page, lru); | 910 | trace_mm_lru_insertion(page, lru); |
| 899 | } | 911 | } |
| 900 | 912 | ||
| @@ -913,7 +925,7 @@ EXPORT_SYMBOL(__pagevec_lru_add); | |||
| 913 | * @pvec: Where the resulting entries are placed | 925 | * @pvec: Where the resulting entries are placed |
| 914 | * @mapping: The address_space to search | 926 | * @mapping: The address_space to search |
| 915 | * @start: The starting entry index | 927 | * @start: The starting entry index |
| 916 | * @nr_pages: The maximum number of pages | 928 | * @nr_entries: The maximum number of pages |
| 917 | * @indices: The cache indices corresponding to the entries in @pvec | 929 | * @indices: The cache indices corresponding to the entries in @pvec |
| 918 | * | 930 | * |
| 919 | * pagevec_lookup_entries() will search for and return a group of up | 931 | * pagevec_lookup_entries() will search for and return a group of up |
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 673942094328..ebff729cc956 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
| @@ -1943,11 +1943,15 @@ void *vmalloc_exec(unsigned long size) | |||
| 1943 | } | 1943 | } |
| 1944 | 1944 | ||
| 1945 | #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) | 1945 | #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) |
| 1946 | #define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL | 1946 | #define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL) |
| 1947 | #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) | 1947 | #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) |
| 1948 | #define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL | 1948 | #define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL) |
| 1949 | #else | 1949 | #else |
| 1950 | #define GFP_VMALLOC32 GFP_KERNEL | 1950 | /* |
| 1951 | * 64b systems should always have either DMA or DMA32 zones. For others | ||
| 1952 | * GFP_DMA32 should do the right thing and use the normal zone. | ||
| 1953 | */ | ||
| 1954 | #define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL | ||
| 1951 | #endif | 1955 | #endif |
| 1952 | 1956 | ||
| 1953 | /** | 1957 | /** |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 444749669187..bee53495a829 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -769,64 +769,7 @@ int remove_mapping(struct address_space *mapping, struct page *page) | |||
| 769 | */ | 769 | */ |
| 770 | void putback_lru_page(struct page *page) | 770 | void putback_lru_page(struct page *page) |
| 771 | { | 771 | { |
| 772 | bool is_unevictable; | 772 | lru_cache_add(page); |
| 773 | int was_unevictable = PageUnevictable(page); | ||
| 774 | |||
| 775 | VM_BUG_ON_PAGE(PageLRU(page), page); | ||
| 776 | |||
| 777 | redo: | ||
| 778 | ClearPageUnevictable(page); | ||
| 779 | |||
| 780 | if (page_evictable(page)) { | ||
| 781 | /* | ||
| 782 | * For evictable pages, we can use the cache. | ||
| 783 | * In event of a race, worst case is we end up with an | ||
| 784 | * unevictable page on [in]active list. | ||
| 785 | * We know how to handle that. | ||
| 786 | */ | ||
| 787 | is_unevictable = false; | ||
| 788 | lru_cache_add(page); | ||
| 789 | } else { | ||
| 790 | /* | ||
| 791 | * Put unevictable pages directly on zone's unevictable | ||
| 792 | * list. | ||
| 793 | */ | ||
| 794 | is_unevictable = true; | ||
| 795 | add_page_to_unevictable_list(page); | ||
| 796 | /* | ||
| 797 | * When racing with an mlock or AS_UNEVICTABLE clearing | ||
| 798 | * (page is unlocked) make sure that if the other thread | ||
| 799 | * does not observe our setting of PG_lru and fails | ||
| 800 | * isolation/check_move_unevictable_pages, | ||
| 801 | * we see PG_mlocked/AS_UNEVICTABLE cleared below and move | ||
| 802 | * the page back to the evictable list. | ||
| 803 | * | ||
| 804 | * The other side is TestClearPageMlocked() or shmem_lock(). | ||
| 805 | */ | ||
| 806 | smp_mb(); | ||
| 807 | } | ||
| 808 | |||
| 809 | /* | ||
| 810 | * page's status can change while we move it among lru. If an evictable | ||
| 811 | * page is on unevictable list, it never be freed. To avoid that, | ||
| 812 | * check after we added it to the list, again. | ||
| 813 | */ | ||
| 814 | if (is_unevictable && page_evictable(page)) { | ||
| 815 | if (!isolate_lru_page(page)) { | ||
| 816 | put_page(page); | ||
| 817 | goto redo; | ||
| 818 | } | ||
| 819 | /* This means someone else dropped this page from LRU | ||
| 820 | * So, it will be freed or putback to LRU again. There is | ||
| 821 | * nothing to do here. | ||
| 822 | */ | ||
| 823 | } | ||
| 824 | |||
| 825 | if (was_unevictable && !is_unevictable) | ||
| 826 | count_vm_event(UNEVICTABLE_PGRESCUED); | ||
| 827 | else if (!was_unevictable && is_unevictable) | ||
| 828 | count_vm_event(UNEVICTABLE_PGCULLED); | ||
| 829 | |||
| 830 | put_page(page); /* drop ref from isolate */ | 773 | put_page(page); /* drop ref from isolate */ |
| 831 | } | 774 | } |
| 832 | 775 | ||
diff --git a/mm/zpool.c b/mm/zpool.c index f8cb83e7699b..01a771e304fa 100644 --- a/mm/zpool.c +++ b/mm/zpool.c | |||
| @@ -360,7 +360,7 @@ u64 zpool_get_total_size(struct zpool *zpool) | |||
| 360 | 360 | ||
| 361 | /** | 361 | /** |
| 362 | * zpool_evictable() - Test if zpool is potentially evictable | 362 | * zpool_evictable() - Test if zpool is potentially evictable |
| 363 | * @pool The zpool to test | 363 | * @zpool: The zpool to test |
| 364 | * | 364 | * |
| 365 | * Zpool is only potentially evictable when it's created with struct | 365 | * Zpool is only potentially evictable when it's created with struct |
| 366 | * zpool_ops.evict and its driver implements struct zpool_driver.shrink. | 366 | * zpool_ops.evict and its driver implements struct zpool_driver.shrink. |
diff --git a/mm/zswap.c b/mm/zswap.c index c004aa4fd3f4..61a5c41972db 100644 --- a/mm/zswap.c +++ b/mm/zswap.c | |||
| @@ -1007,6 +1007,12 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 1007 | u8 *src, *dst; | 1007 | u8 *src, *dst; |
| 1008 | struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) }; | 1008 | struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) }; |
| 1009 | 1009 | ||
| 1010 | /* THP isn't supported */ | ||
| 1011 | if (PageTransHuge(page)) { | ||
| 1012 | ret = -EINVAL; | ||
| 1013 | goto reject; | ||
| 1014 | } | ||
| 1015 | |||
| 1010 | if (!zswap_enabled || !tree) { | 1016 | if (!zswap_enabled || !tree) { |
| 1011 | ret = -ENODEV; | 1017 | ret = -ENODEV; |
| 1012 | goto reject; | 1018 | goto reject; |
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 0254c35b2bf0..126a8ea73c96 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c | |||
| @@ -255,6 +255,9 @@ static ssize_t brport_show(struct kobject *kobj, | |||
| 255 | struct brport_attribute *brport_attr = to_brport_attr(attr); | 255 | struct brport_attribute *brport_attr = to_brport_attr(attr); |
| 256 | struct net_bridge_port *p = to_brport(kobj); | 256 | struct net_bridge_port *p = to_brport(kobj); |
| 257 | 257 | ||
| 258 | if (!brport_attr->show) | ||
| 259 | return -EINVAL; | ||
| 260 | |||
| 258 | return brport_attr->show(p, buf); | 261 | return brport_attr->show(p, buf); |
| 259 | } | 262 | } |
| 260 | 263 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index dda9d7b9a840..d4362befe7e2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2382,8 +2382,11 @@ EXPORT_SYMBOL(netdev_set_num_tc); | |||
| 2382 | */ | 2382 | */ |
| 2383 | int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) | 2383 | int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) |
| 2384 | { | 2384 | { |
| 2385 | bool disabling; | ||
| 2385 | int rc; | 2386 | int rc; |
| 2386 | 2387 | ||
| 2388 | disabling = txq < dev->real_num_tx_queues; | ||
| 2389 | |||
| 2387 | if (txq < 1 || txq > dev->num_tx_queues) | 2390 | if (txq < 1 || txq > dev->num_tx_queues) |
| 2388 | return -EINVAL; | 2391 | return -EINVAL; |
| 2389 | 2392 | ||
| @@ -2399,15 +2402,19 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) | |||
| 2399 | if (dev->num_tc) | 2402 | if (dev->num_tc) |
| 2400 | netif_setup_tc(dev, txq); | 2403 | netif_setup_tc(dev, txq); |
| 2401 | 2404 | ||
| 2402 | if (txq < dev->real_num_tx_queues) { | 2405 | dev->real_num_tx_queues = txq; |
| 2406 | |||
| 2407 | if (disabling) { | ||
| 2408 | synchronize_net(); | ||
| 2403 | qdisc_reset_all_tx_gt(dev, txq); | 2409 | qdisc_reset_all_tx_gt(dev, txq); |
| 2404 | #ifdef CONFIG_XPS | 2410 | #ifdef CONFIG_XPS |
| 2405 | netif_reset_xps_queues_gt(dev, txq); | 2411 | netif_reset_xps_queues_gt(dev, txq); |
| 2406 | #endif | 2412 | #endif |
| 2407 | } | 2413 | } |
| 2414 | } else { | ||
| 2415 | dev->real_num_tx_queues = txq; | ||
| 2408 | } | 2416 | } |
| 2409 | 2417 | ||
| 2410 | dev->real_num_tx_queues = txq; | ||
| 2411 | return 0; | 2418 | return 0; |
| 2412 | } | 2419 | } |
| 2413 | EXPORT_SYMBOL(netif_set_real_num_tx_queues); | 2420 | EXPORT_SYMBOL(netif_set_real_num_tx_queues); |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 91dd09f79808..791aff68af88 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
| @@ -1338,6 +1338,12 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use | |||
| 1338 | lock_sock(sk); | 1338 | lock_sock(sk); |
| 1339 | err = __dn_setsockopt(sock, level, optname, optval, optlen, 0); | 1339 | err = __dn_setsockopt(sock, level, optname, optval, optlen, 0); |
| 1340 | release_sock(sk); | 1340 | release_sock(sk); |
| 1341 | #ifdef CONFIG_NETFILTER | ||
| 1342 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | ||
| 1343 | if (err == -ENOPROTOOPT && optname != DSO_LINKINFO && | ||
| 1344 | optname != DSO_STREAM && optname != DSO_SEQPACKET) | ||
| 1345 | err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen); | ||
| 1346 | #endif | ||
| 1341 | 1347 | ||
| 1342 | return err; | 1348 | return err; |
| 1343 | } | 1349 | } |
| @@ -1445,15 +1451,6 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us | |||
| 1445 | dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation); | 1451 | dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation); |
| 1446 | break; | 1452 | break; |
| 1447 | 1453 | ||
| 1448 | default: | ||
| 1449 | #ifdef CONFIG_NETFILTER | ||
| 1450 | return nf_setsockopt(sk, PF_DECnet, optname, optval, optlen); | ||
| 1451 | #endif | ||
| 1452 | case DSO_LINKINFO: | ||
| 1453 | case DSO_STREAM: | ||
| 1454 | case DSO_SEQPACKET: | ||
| 1455 | return -ENOPROTOOPT; | ||
| 1456 | |||
| 1457 | case DSO_MAXWINDOW: | 1454 | case DSO_MAXWINDOW: |
| 1458 | if (optlen != sizeof(unsigned long)) | 1455 | if (optlen != sizeof(unsigned long)) |
| 1459 | return -EINVAL; | 1456 | return -EINVAL; |
| @@ -1501,6 +1498,12 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us | |||
| 1501 | return -EINVAL; | 1498 | return -EINVAL; |
| 1502 | scp->info_loc = u.info; | 1499 | scp->info_loc = u.info; |
| 1503 | break; | 1500 | break; |
| 1501 | |||
| 1502 | case DSO_LINKINFO: | ||
| 1503 | case DSO_STREAM: | ||
| 1504 | case DSO_SEQPACKET: | ||
| 1505 | default: | ||
| 1506 | return -ENOPROTOOPT; | ||
| 1504 | } | 1507 | } |
| 1505 | 1508 | ||
| 1506 | return 0; | 1509 | return 0; |
| @@ -1514,6 +1517,20 @@ static int dn_getsockopt(struct socket *sock, int level, int optname, char __use | |||
| 1514 | lock_sock(sk); | 1517 | lock_sock(sk); |
| 1515 | err = __dn_getsockopt(sock, level, optname, optval, optlen, 0); | 1518 | err = __dn_getsockopt(sock, level, optname, optval, optlen, 0); |
| 1516 | release_sock(sk); | 1519 | release_sock(sk); |
| 1520 | #ifdef CONFIG_NETFILTER | ||
| 1521 | if (err == -ENOPROTOOPT && optname != DSO_STREAM && | ||
| 1522 | optname != DSO_SEQPACKET && optname != DSO_CONACCEPT && | ||
| 1523 | optname != DSO_CONREJECT) { | ||
| 1524 | int len; | ||
| 1525 | |||
| 1526 | if (get_user(len, optlen)) | ||
| 1527 | return -EFAULT; | ||
| 1528 | |||
| 1529 | err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len); | ||
| 1530 | if (err >= 0) | ||
| 1531 | err = put_user(len, optlen); | ||
| 1532 | } | ||
| 1533 | #endif | ||
| 1517 | 1534 | ||
| 1518 | return err; | 1535 | return err; |
| 1519 | } | 1536 | } |
| @@ -1579,26 +1596,6 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us | |||
| 1579 | r_data = &link; | 1596 | r_data = &link; |
| 1580 | break; | 1597 | break; |
| 1581 | 1598 | ||
| 1582 | default: | ||
| 1583 | #ifdef CONFIG_NETFILTER | ||
| 1584 | { | ||
| 1585 | int ret, len; | ||
| 1586 | |||
| 1587 | if (get_user(len, optlen)) | ||
| 1588 | return -EFAULT; | ||
| 1589 | |||
| 1590 | ret = nf_getsockopt(sk, PF_DECnet, optname, optval, &len); | ||
| 1591 | if (ret >= 0) | ||
| 1592 | ret = put_user(len, optlen); | ||
| 1593 | return ret; | ||
| 1594 | } | ||
| 1595 | #endif | ||
| 1596 | case DSO_STREAM: | ||
| 1597 | case DSO_SEQPACKET: | ||
| 1598 | case DSO_CONACCEPT: | ||
| 1599 | case DSO_CONREJECT: | ||
| 1600 | return -ENOPROTOOPT; | ||
| 1601 | |||
| 1602 | case DSO_MAXWINDOW: | 1599 | case DSO_MAXWINDOW: |
| 1603 | if (r_len > sizeof(unsigned long)) | 1600 | if (r_len > sizeof(unsigned long)) |
| 1604 | r_len = sizeof(unsigned long); | 1601 | r_len = sizeof(unsigned long); |
| @@ -1630,6 +1627,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us | |||
| 1630 | r_len = sizeof(unsigned char); | 1627 | r_len = sizeof(unsigned char); |
| 1631 | r_data = &scp->info_rem; | 1628 | r_data = &scp->info_rem; |
| 1632 | break; | 1629 | break; |
| 1630 | |||
| 1631 | case DSO_STREAM: | ||
| 1632 | case DSO_SEQPACKET: | ||
| 1633 | case DSO_CONACCEPT: | ||
| 1634 | case DSO_CONREJECT: | ||
| 1635 | default: | ||
| 1636 | return -ENOPROTOOPT; | ||
| 1633 | } | 1637 | } |
| 1634 | 1638 | ||
| 1635 | if (r_data) { | 1639 | if (r_data) { |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index c586597da20d..7d36a950d961 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
| @@ -646,6 +646,11 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, | |||
| 646 | fi->fib_nh, cfg, extack)) | 646 | fi->fib_nh, cfg, extack)) |
| 647 | return 1; | 647 | return 1; |
| 648 | } | 648 | } |
| 649 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
| 650 | if (cfg->fc_flow && | ||
| 651 | cfg->fc_flow != fi->fib_nh->nh_tclassid) | ||
| 652 | return 1; | ||
| 653 | #endif | ||
| 649 | if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) && | 654 | if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) && |
| 650 | (!cfg->fc_gw || cfg->fc_gw == fi->fib_nh->nh_gw)) | 655 | (!cfg->fc_gw || cfg->fc_gw == fi->fib_nh->nh_gw)) |
| 651 | return 0; | 656 | return 0; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e9f985e42405..b2bca373f8be 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -2027,6 +2027,24 @@ static inline void tcp_mtu_check_reprobe(struct sock *sk) | |||
| 2027 | } | 2027 | } |
| 2028 | } | 2028 | } |
| 2029 | 2029 | ||
| 2030 | static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len) | ||
| 2031 | { | ||
| 2032 | struct sk_buff *skb, *next; | ||
| 2033 | |||
| 2034 | skb = tcp_send_head(sk); | ||
| 2035 | tcp_for_write_queue_from_safe(skb, next, sk) { | ||
| 2036 | if (len <= skb->len) | ||
| 2037 | break; | ||
| 2038 | |||
| 2039 | if (unlikely(TCP_SKB_CB(skb)->eor)) | ||
| 2040 | return false; | ||
| 2041 | |||
| 2042 | len -= skb->len; | ||
| 2043 | } | ||
| 2044 | |||
| 2045 | return true; | ||
| 2046 | } | ||
| 2047 | |||
| 2030 | /* Create a new MTU probe if we are ready. | 2048 | /* Create a new MTU probe if we are ready. |
| 2031 | * MTU probe is regularly attempting to increase the path MTU by | 2049 | * MTU probe is regularly attempting to increase the path MTU by |
| 2032 | * deliberately sending larger packets. This discovers routing | 2050 | * deliberately sending larger packets. This discovers routing |
| @@ -2099,6 +2117,9 @@ static int tcp_mtu_probe(struct sock *sk) | |||
| 2099 | return 0; | 2117 | return 0; |
| 2100 | } | 2118 | } |
| 2101 | 2119 | ||
| 2120 | if (!tcp_can_coalesce_send_queue_head(sk, probe_size)) | ||
| 2121 | return -1; | ||
| 2122 | |||
| 2102 | /* We're allowed to probe. Build it now. */ | 2123 | /* We're allowed to probe. Build it now. */ |
| 2103 | nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false); | 2124 | nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false); |
| 2104 | if (!nskb) | 2125 | if (!nskb) |
| @@ -2134,6 +2155,10 @@ static int tcp_mtu_probe(struct sock *sk) | |||
| 2134 | /* We've eaten all the data from this skb. | 2155 | /* We've eaten all the data from this skb. |
| 2135 | * Throw it away. */ | 2156 | * Throw it away. */ |
| 2136 | TCP_SKB_CB(nskb)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; | 2157 | TCP_SKB_CB(nskb)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; |
| 2158 | /* If this is the last SKB we copy and eor is set | ||
| 2159 | * we need to propagate it to the new skb. | ||
| 2160 | */ | ||
| 2161 | TCP_SKB_CB(nskb)->eor = TCP_SKB_CB(skb)->eor; | ||
| 2137 | tcp_unlink_write_queue(skb, sk); | 2162 | tcp_unlink_write_queue(skb, sk); |
| 2138 | sk_wmem_free_skb(sk, skb); | 2163 | sk_wmem_free_skb(sk, skb); |
| 2139 | } else { | 2164 | } else { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index bfaefe560b5c..e5ef7c38c934 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -2024,6 +2024,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh, | |||
| 2024 | err = udplite_checksum_init(skb, uh); | 2024 | err = udplite_checksum_init(skb, uh); |
| 2025 | if (err) | 2025 | if (err) |
| 2026 | return err; | 2026 | return err; |
| 2027 | |||
| 2028 | if (UDP_SKB_CB(skb)->partial_cov) { | ||
| 2029 | skb->csum = inet_compute_pseudo(skb, proto); | ||
| 2030 | return 0; | ||
| 2031 | } | ||
| 2027 | } | 2032 | } |
| 2028 | 2033 | ||
| 2029 | /* Note, we are only interested in != 0 or == 0, thus the | 2034 | /* Note, we are only interested in != 0 or == 0, thus the |
diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c index ec43d18b5ff9..547515e8450a 100644 --- a/net/ipv6/ip6_checksum.c +++ b/net/ipv6/ip6_checksum.c | |||
| @@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto) | |||
| 73 | err = udplite_checksum_init(skb, uh); | 73 | err = udplite_checksum_init(skb, uh); |
| 74 | if (err) | 74 | if (err) |
| 75 | return err; | 75 | return err; |
| 76 | |||
| 77 | if (UDP_SKB_CB(skb)->partial_cov) { | ||
| 78 | skb->csum = ip6_compute_pseudo(skb, proto); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 76 | } | 81 | } |
| 77 | 82 | ||
| 78 | /* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels) | 83 | /* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels) |
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index 367d8c027101..2ceefa183cee 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c | |||
| @@ -149,6 +149,10 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri, | |||
| 149 | 149 | ||
| 150 | pr_debug("uri: %s, len: %zu\n", uri, uri_len); | 150 | pr_debug("uri: %s, len: %zu\n", uri, uri_len); |
| 151 | 151 | ||
| 152 | /* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */ | ||
| 153 | if (WARN_ON_ONCE(uri_len > U8_MAX - 4)) | ||
| 154 | return NULL; | ||
| 155 | |||
| 152 | sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL); | 156 | sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL); |
| 153 | if (sdreq == NULL) | 157 | if (sdreq == NULL) |
| 154 | return NULL; | 158 | return NULL; |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index c0b83dc9d993..f018eafc2a0d 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
| @@ -61,7 +61,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = { | 63 | static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = { |
| 64 | [NFC_SDP_ATTR_URI] = { .type = NLA_STRING }, | 64 | [NFC_SDP_ATTR_URI] = { .type = NLA_STRING, |
| 65 | .len = U8_MAX - 4 }, | ||
| 65 | [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 }, | 66 | [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 }, |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
diff --git a/net/rds/connection.c b/net/rds/connection.c index 94e190febfdd..2da3176bf792 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
| @@ -224,7 +224,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, | |||
| 224 | if (rds_destroy_pending(conn)) | 224 | if (rds_destroy_pending(conn)) |
| 225 | ret = -ENETDOWN; | 225 | ret = -ENETDOWN; |
| 226 | else | 226 | else |
| 227 | ret = trans->conn_alloc(conn, gfp); | 227 | ret = trans->conn_alloc(conn, GFP_ATOMIC); |
| 228 | if (ret) { | 228 | if (ret) { |
| 229 | rcu_read_unlock(); | 229 | rcu_read_unlock(); |
| 230 | kfree(conn->c_path); | 230 | kfree(conn->c_path); |
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index cc21e8db25b0..9d45d8b56744 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
| @@ -517,9 +517,10 @@ try_again: | |||
| 517 | ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, | 517 | ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, |
| 518 | sizeof(unsigned int), &id32); | 518 | sizeof(unsigned int), &id32); |
| 519 | } else { | 519 | } else { |
| 520 | unsigned long idl = call->user_call_ID; | ||
| 521 | |||
| 520 | ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, | 522 | ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID, |
| 521 | sizeof(unsigned long), | 523 | sizeof(unsigned long), &idl); |
| 522 | &call->user_call_ID); | ||
| 523 | } | 524 | } |
| 524 | if (ret < 0) | 525 | if (ret < 0) |
| 525 | goto error_unlock_call; | 526 | goto error_unlock_call; |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 2bc1bc23d42e..a7dc7271042a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
| @@ -376,17 +376,12 @@ struct tcf_net { | |||
| 376 | static unsigned int tcf_net_id; | 376 | static unsigned int tcf_net_id; |
| 377 | 377 | ||
| 378 | static int tcf_block_insert(struct tcf_block *block, struct net *net, | 378 | static int tcf_block_insert(struct tcf_block *block, struct net *net, |
| 379 | u32 block_index, struct netlink_ext_ack *extack) | 379 | struct netlink_ext_ack *extack) |
| 380 | { | 380 | { |
| 381 | struct tcf_net *tn = net_generic(net, tcf_net_id); | 381 | struct tcf_net *tn = net_generic(net, tcf_net_id); |
| 382 | int err; | ||
| 383 | 382 | ||
| 384 | err = idr_alloc_u32(&tn->idr, block, &block_index, block_index, | 383 | return idr_alloc_u32(&tn->idr, block, &block->index, block->index, |
| 385 | GFP_KERNEL); | 384 | GFP_KERNEL); |
| 386 | if (err) | ||
| 387 | return err; | ||
| 388 | block->index = block_index; | ||
| 389 | return 0; | ||
| 390 | } | 385 | } |
| 391 | 386 | ||
| 392 | static void tcf_block_remove(struct tcf_block *block, struct net *net) | 387 | static void tcf_block_remove(struct tcf_block *block, struct net *net) |
| @@ -397,6 +392,7 @@ static void tcf_block_remove(struct tcf_block *block, struct net *net) | |||
| 397 | } | 392 | } |
| 398 | 393 | ||
| 399 | static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, | 394 | static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, |
| 395 | u32 block_index, | ||
| 400 | struct netlink_ext_ack *extack) | 396 | struct netlink_ext_ack *extack) |
| 401 | { | 397 | { |
| 402 | struct tcf_block *block; | 398 | struct tcf_block *block; |
| @@ -419,10 +415,13 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, | |||
| 419 | err = -ENOMEM; | 415 | err = -ENOMEM; |
| 420 | goto err_chain_create; | 416 | goto err_chain_create; |
| 421 | } | 417 | } |
| 422 | block->net = qdisc_net(q); | ||
| 423 | block->refcnt = 1; | 418 | block->refcnt = 1; |
| 424 | block->net = net; | 419 | block->net = net; |
| 425 | block->q = q; | 420 | block->index = block_index; |
| 421 | |||
| 422 | /* Don't store q pointer for blocks which are shared */ | ||
| 423 | if (!tcf_block_shared(block)) | ||
| 424 | block->q = q; | ||
| 426 | return block; | 425 | return block; |
| 427 | 426 | ||
| 428 | err_chain_create: | 427 | err_chain_create: |
| @@ -518,13 +517,12 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, | |||
| 518 | } | 517 | } |
| 519 | 518 | ||
| 520 | if (!block) { | 519 | if (!block) { |
| 521 | block = tcf_block_create(net, q, extack); | 520 | block = tcf_block_create(net, q, ei->block_index, extack); |
| 522 | if (IS_ERR(block)) | 521 | if (IS_ERR(block)) |
| 523 | return PTR_ERR(block); | 522 | return PTR_ERR(block); |
| 524 | created = true; | 523 | created = true; |
| 525 | if (ei->block_index) { | 524 | if (tcf_block_shared(block)) { |
| 526 | err = tcf_block_insert(block, net, | 525 | err = tcf_block_insert(block, net, extack); |
| 527 | ei->block_index, extack); | ||
| 528 | if (err) | 526 | if (err) |
| 529 | goto err_block_insert; | 527 | goto err_block_insert; |
| 530 | } | 528 | } |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 6c7601a530e3..ed8b6a24b9e9 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
| @@ -96,7 +96,7 @@ struct tc_u_hnode { | |||
| 96 | 96 | ||
| 97 | struct tc_u_common { | 97 | struct tc_u_common { |
| 98 | struct tc_u_hnode __rcu *hlist; | 98 | struct tc_u_hnode __rcu *hlist; |
| 99 | struct tcf_block *block; | 99 | void *ptr; |
| 100 | int refcnt; | 100 | int refcnt; |
| 101 | struct idr handle_idr; | 101 | struct idr handle_idr; |
| 102 | struct hlist_node hnode; | 102 | struct hlist_node hnode; |
| @@ -330,9 +330,25 @@ static struct hlist_head *tc_u_common_hash; | |||
| 330 | #define U32_HASH_SHIFT 10 | 330 | #define U32_HASH_SHIFT 10 |
| 331 | #define U32_HASH_SIZE (1 << U32_HASH_SHIFT) | 331 | #define U32_HASH_SIZE (1 << U32_HASH_SHIFT) |
| 332 | 332 | ||
| 333 | static void *tc_u_common_ptr(const struct tcf_proto *tp) | ||
| 334 | { | ||
| 335 | struct tcf_block *block = tp->chain->block; | ||
| 336 | |||
| 337 | /* The block sharing is currently supported only | ||
| 338 | * for classless qdiscs. In that case we use block | ||
| 339 | * for tc_u_common identification. In case the | ||
| 340 | * block is not shared, block->q is a valid pointer | ||
| 341 | * and we can use that. That works for classful qdiscs. | ||
| 342 | */ | ||
| 343 | if (tcf_block_shared(block)) | ||
| 344 | return block; | ||
| 345 | else | ||
| 346 | return block->q; | ||
| 347 | } | ||
| 348 | |||
| 333 | static unsigned int tc_u_hash(const struct tcf_proto *tp) | 349 | static unsigned int tc_u_hash(const struct tcf_proto *tp) |
| 334 | { | 350 | { |
| 335 | return hash_ptr(tp->chain->block, U32_HASH_SHIFT); | 351 | return hash_ptr(tc_u_common_ptr(tp), U32_HASH_SHIFT); |
| 336 | } | 352 | } |
| 337 | 353 | ||
| 338 | static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) | 354 | static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) |
| @@ -342,7 +358,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) | |||
| 342 | 358 | ||
| 343 | h = tc_u_hash(tp); | 359 | h = tc_u_hash(tp); |
| 344 | hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) { | 360 | hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) { |
| 345 | if (tc->block == tp->chain->block) | 361 | if (tc->ptr == tc_u_common_ptr(tp)) |
| 346 | return tc; | 362 | return tc; |
| 347 | } | 363 | } |
| 348 | return NULL; | 364 | return NULL; |
| @@ -371,7 +387,7 @@ static int u32_init(struct tcf_proto *tp) | |||
| 371 | kfree(root_ht); | 387 | kfree(root_ht); |
| 372 | return -ENOBUFS; | 388 | return -ENOBUFS; |
| 373 | } | 389 | } |
| 374 | tp_c->block = tp->chain->block; | 390 | tp_c->ptr = tc_u_common_ptr(tp); |
| 375 | INIT_HLIST_NODE(&tp_c->hnode); | 391 | INIT_HLIST_NODE(&tp_c->hnode); |
| 376 | idr_init(&tp_c->handle_idr); | 392 | idr_init(&tp_c->handle_idr); |
| 377 | 393 | ||
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index 291c97b07058..8f6c2e8c0953 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
| @@ -81,6 +81,12 @@ const char *sctp_cname(const union sctp_subtype cid) | |||
| 81 | case SCTP_CID_RECONF: | 81 | case SCTP_CID_RECONF: |
| 82 | return "RECONF"; | 82 | return "RECONF"; |
| 83 | 83 | ||
| 84 | case SCTP_CID_I_DATA: | ||
| 85 | return "I_DATA"; | ||
| 86 | |||
| 87 | case SCTP_CID_I_FWD_TSN: | ||
| 88 | return "I_FWD_TSN"; | ||
| 89 | |||
| 84 | default: | 90 | default: |
| 85 | break; | 91 | break; |
| 86 | } | 92 | } |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 141c9c466ec1..0247cc432e02 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -897,15 +897,12 @@ int sctp_hash_transport(struct sctp_transport *t) | |||
| 897 | rhl_for_each_entry_rcu(transport, tmp, list, node) | 897 | rhl_for_each_entry_rcu(transport, tmp, list, node) |
| 898 | if (transport->asoc->ep == t->asoc->ep) { | 898 | if (transport->asoc->ep == t->asoc->ep) { |
| 899 | rcu_read_unlock(); | 899 | rcu_read_unlock(); |
| 900 | err = -EEXIST; | 900 | return -EEXIST; |
| 901 | goto out; | ||
| 902 | } | 901 | } |
| 903 | rcu_read_unlock(); | 902 | rcu_read_unlock(); |
| 904 | 903 | ||
| 905 | err = rhltable_insert_key(&sctp_transport_hashtable, &arg, | 904 | err = rhltable_insert_key(&sctp_transport_hashtable, &arg, |
| 906 | &t->node, sctp_hash_params); | 905 | &t->node, sctp_hash_params); |
| 907 | |||
| 908 | out: | ||
| 909 | if (err) | 906 | if (err) |
| 910 | pr_err_once("insert transport fail, errno %d\n", err); | 907 | pr_err_once("insert transport fail, errno %d\n", err); |
| 911 | 908 | ||
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index cedf672487f9..f799043abec9 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * | 6 | * |
| 7 | * This file is part of the SCTP kernel implementation | 7 | * This file is part of the SCTP kernel implementation |
| 8 | * | 8 | * |
| 9 | * These functions manipulate sctp tsn mapping array. | 9 | * This file contains sctp stream maniuplation primitives and helpers. |
| 10 | * | 10 | * |
| 11 | * This SCTP implementation is free software; | 11 | * This SCTP implementation is free software; |
| 12 | * you can redistribute it and/or modify it under the terms of | 12 | * you can redistribute it and/or modify it under the terms of |
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c index 8c7cf8f08711..d3764c181299 100644 --- a/net/sctp/stream_interleave.c +++ b/net/sctp/stream_interleave.c | |||
| @@ -3,7 +3,8 @@ | |||
| 3 | * | 3 | * |
| 4 | * This file is part of the SCTP kernel implementation | 4 | * This file is part of the SCTP kernel implementation |
| 5 | * | 5 | * |
| 6 | * These functions manipulate sctp stream queue/scheduling. | 6 | * These functions implement sctp stream message interleaving, mostly |
| 7 | * including I-DATA and I-FORWARD-TSN chunks process. | ||
| 7 | * | 8 | * |
| 8 | * This SCTP implementation is free software; | 9 | * This SCTP implementation is free software; |
| 9 | * you can redistribute it and/or modify it under the terms of | 10 | * you can redistribute it and/or modify it under the terms of |
| @@ -954,12 +955,8 @@ static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
| 954 | __u32 freed = 0; | 955 | __u32 freed = 0; |
| 955 | __u16 needed; | 956 | __u16 needed; |
| 956 | 957 | ||
| 957 | if (chunk) { | 958 | needed = ntohs(chunk->chunk_hdr->length) - |
| 958 | needed = ntohs(chunk->chunk_hdr->length); | 959 | sizeof(struct sctp_idata_chunk); |
| 959 | needed -= sizeof(struct sctp_idata_chunk); | ||
| 960 | } else { | ||
| 961 | needed = SCTP_DEFAULT_MAXWINDOW; | ||
| 962 | } | ||
| 963 | 960 | ||
| 964 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { | 961 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { |
| 965 | freed = sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed); | 962 | freed = sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed); |
| @@ -971,9 +968,8 @@ static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
| 971 | needed); | 968 | needed); |
| 972 | } | 969 | } |
| 973 | 970 | ||
| 974 | if (chunk && freed >= needed) | 971 | if (freed >= needed && sctp_ulpevent_idata(ulpq, chunk, gfp) <= 0) |
| 975 | if (sctp_ulpevent_idata(ulpq, chunk, gfp) <= 0) | 972 | sctp_intl_start_pd(ulpq, gfp); |
| 976 | sctp_intl_start_pd(ulpq, gfp); | ||
| 977 | 973 | ||
| 978 | sk_mem_reclaim(asoc->base.sk); | 974 | sk_mem_reclaim(asoc->base.sk); |
| 979 | } | 975 | } |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index c8001471da6c..3e3dce3d4c63 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
| @@ -813,7 +813,7 @@ err_out: | |||
| 813 | return err; | 813 | return err; |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) | 816 | int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) |
| 817 | { | 817 | { |
| 818 | int err; | 818 | int err; |
| 819 | char *name; | 819 | char *name; |
| @@ -835,20 +835,27 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) | |||
| 835 | 835 | ||
| 836 | name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); | 836 | name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); |
| 837 | 837 | ||
| 838 | rtnl_lock(); | ||
| 839 | bearer = tipc_bearer_find(net, name); | 838 | bearer = tipc_bearer_find(net, name); |
| 840 | if (!bearer) { | 839 | if (!bearer) |
| 841 | rtnl_unlock(); | ||
| 842 | return -EINVAL; | 840 | return -EINVAL; |
| 843 | } | ||
| 844 | 841 | ||
| 845 | bearer_disable(net, bearer); | 842 | bearer_disable(net, bearer); |
| 846 | rtnl_unlock(); | ||
| 847 | 843 | ||
| 848 | return 0; | 844 | return 0; |
| 849 | } | 845 | } |
| 850 | 846 | ||
| 851 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) | 847 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) |
| 848 | { | ||
| 849 | int err; | ||
| 850 | |||
| 851 | rtnl_lock(); | ||
| 852 | err = __tipc_nl_bearer_disable(skb, info); | ||
| 853 | rtnl_unlock(); | ||
| 854 | |||
| 855 | return err; | ||
| 856 | } | ||
| 857 | |||
| 858 | int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) | ||
| 852 | { | 859 | { |
| 853 | int err; | 860 | int err; |
| 854 | char *bearer; | 861 | char *bearer; |
| @@ -890,15 +897,18 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) | |||
| 890 | prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); | 897 | prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); |
| 891 | } | 898 | } |
| 892 | 899 | ||
| 900 | return tipc_enable_bearer(net, bearer, domain, prio, attrs); | ||
| 901 | } | ||
| 902 | |||
| 903 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) | ||
| 904 | { | ||
| 905 | int err; | ||
| 906 | |||
| 893 | rtnl_lock(); | 907 | rtnl_lock(); |
| 894 | err = tipc_enable_bearer(net, bearer, domain, prio, attrs); | 908 | err = __tipc_nl_bearer_enable(skb, info); |
| 895 | if (err) { | ||
| 896 | rtnl_unlock(); | ||
| 897 | return err; | ||
| 898 | } | ||
| 899 | rtnl_unlock(); | 909 | rtnl_unlock(); |
| 900 | 910 | ||
| 901 | return 0; | 911 | return err; |
| 902 | } | 912 | } |
| 903 | 913 | ||
| 904 | int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) | 914 | int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) |
| @@ -944,7 +954,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) | |||
| 944 | return 0; | 954 | return 0; |
| 945 | } | 955 | } |
| 946 | 956 | ||
| 947 | int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) | 957 | int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) |
| 948 | { | 958 | { |
| 949 | int err; | 959 | int err; |
| 950 | char *name; | 960 | char *name; |
| @@ -965,22 +975,17 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) | |||
| 965 | return -EINVAL; | 975 | return -EINVAL; |
| 966 | name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); | 976 | name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); |
| 967 | 977 | ||
| 968 | rtnl_lock(); | ||
| 969 | b = tipc_bearer_find(net, name); | 978 | b = tipc_bearer_find(net, name); |
| 970 | if (!b) { | 979 | if (!b) |
| 971 | rtnl_unlock(); | ||
| 972 | return -EINVAL; | 980 | return -EINVAL; |
| 973 | } | ||
| 974 | 981 | ||
| 975 | if (attrs[TIPC_NLA_BEARER_PROP]) { | 982 | if (attrs[TIPC_NLA_BEARER_PROP]) { |
| 976 | struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; | 983 | struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; |
| 977 | 984 | ||
| 978 | err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP], | 985 | err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP], |
| 979 | props); | 986 | props); |
| 980 | if (err) { | 987 | if (err) |
| 981 | rtnl_unlock(); | ||
| 982 | return err; | 988 | return err; |
| 983 | } | ||
| 984 | 989 | ||
| 985 | if (props[TIPC_NLA_PROP_TOL]) | 990 | if (props[TIPC_NLA_PROP_TOL]) |
| 986 | b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); | 991 | b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); |
| @@ -989,11 +994,21 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) | |||
| 989 | if (props[TIPC_NLA_PROP_WIN]) | 994 | if (props[TIPC_NLA_PROP_WIN]) |
| 990 | b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); | 995 | b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); |
| 991 | } | 996 | } |
| 992 | rtnl_unlock(); | ||
| 993 | 997 | ||
| 994 | return 0; | 998 | return 0; |
| 995 | } | 999 | } |
| 996 | 1000 | ||
| 1001 | int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) | ||
| 1002 | { | ||
| 1003 | int err; | ||
| 1004 | |||
| 1005 | rtnl_lock(); | ||
| 1006 | err = __tipc_nl_bearer_set(skb, info); | ||
| 1007 | rtnl_unlock(); | ||
| 1008 | |||
| 1009 | return err; | ||
| 1010 | } | ||
| 1011 | |||
| 997 | static int __tipc_nl_add_media(struct tipc_nl_msg *msg, | 1012 | static int __tipc_nl_add_media(struct tipc_nl_msg *msg, |
| 998 | struct tipc_media *media, int nlflags) | 1013 | struct tipc_media *media, int nlflags) |
| 999 | { | 1014 | { |
| @@ -1115,7 +1130,7 @@ err_out: | |||
| 1115 | return err; | 1130 | return err; |
| 1116 | } | 1131 | } |
| 1117 | 1132 | ||
| 1118 | int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) | 1133 | int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) |
| 1119 | { | 1134 | { |
| 1120 | int err; | 1135 | int err; |
| 1121 | char *name; | 1136 | char *name; |
| @@ -1133,22 +1148,17 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) | |||
| 1133 | return -EINVAL; | 1148 | return -EINVAL; |
| 1134 | name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); | 1149 | name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); |
| 1135 | 1150 | ||
| 1136 | rtnl_lock(); | ||
| 1137 | m = tipc_media_find(name); | 1151 | m = tipc_media_find(name); |
| 1138 | if (!m) { | 1152 | if (!m) |
| 1139 | rtnl_unlock(); | ||
| 1140 | return -EINVAL; | 1153 | return -EINVAL; |
| 1141 | } | ||
| 1142 | 1154 | ||
| 1143 | if (attrs[TIPC_NLA_MEDIA_PROP]) { | 1155 | if (attrs[TIPC_NLA_MEDIA_PROP]) { |
| 1144 | struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; | 1156 | struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; |
| 1145 | 1157 | ||
| 1146 | err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP], | 1158 | err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP], |
| 1147 | props); | 1159 | props); |
| 1148 | if (err) { | 1160 | if (err) |
| 1149 | rtnl_unlock(); | ||
| 1150 | return err; | 1161 | return err; |
| 1151 | } | ||
| 1152 | 1162 | ||
| 1153 | if (props[TIPC_NLA_PROP_TOL]) | 1163 | if (props[TIPC_NLA_PROP_TOL]) |
| 1154 | m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); | 1164 | m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); |
| @@ -1157,7 +1167,17 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) | |||
| 1157 | if (props[TIPC_NLA_PROP_WIN]) | 1167 | if (props[TIPC_NLA_PROP_WIN]) |
| 1158 | m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); | 1168 | m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); |
| 1159 | } | 1169 | } |
| 1160 | rtnl_unlock(); | ||
| 1161 | 1170 | ||
| 1162 | return 0; | 1171 | return 0; |
| 1163 | } | 1172 | } |
| 1173 | |||
| 1174 | int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) | ||
| 1175 | { | ||
| 1176 | int err; | ||
| 1177 | |||
| 1178 | rtnl_lock(); | ||
| 1179 | err = __tipc_nl_media_set(skb, info); | ||
| 1180 | rtnl_unlock(); | ||
| 1181 | |||
| 1182 | return err; | ||
| 1183 | } | ||
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 42d6eeeb646d..a53613d95bc9 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
| @@ -188,15 +188,19 @@ extern struct tipc_media udp_media_info; | |||
| 188 | #endif | 188 | #endif |
| 189 | 189 | ||
| 190 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); | 190 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); |
| 191 | int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); | ||
| 191 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); | 192 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); |
| 193 | int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); | ||
| 192 | int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); | 194 | int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 193 | int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); | 195 | int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); |
| 194 | int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); | 196 | int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); |
| 197 | int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); | ||
| 195 | int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info); | 198 | int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info); |
| 196 | 199 | ||
| 197 | int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb); | 200 | int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 198 | int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info); | 201 | int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info); |
| 199 | int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); | 202 | int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); |
| 203 | int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); | ||
| 200 | 204 | ||
| 201 | int tipc_media_set_priority(const char *name, u32 new_value); | 205 | int tipc_media_set_priority(const char *name, u32 new_value); |
| 202 | int tipc_media_set_window(const char *name, u32 new_value); | 206 | int tipc_media_set_window(const char *name, u32 new_value); |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 719c5924b638..1a2fde0d6f61 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
| @@ -200,7 +200,7 @@ out: | |||
| 200 | return skb->len; | 200 | return skb->len; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) | 203 | int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) |
| 204 | { | 204 | { |
| 205 | struct net *net = sock_net(skb->sk); | 205 | struct net *net = sock_net(skb->sk); |
| 206 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 206 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
| @@ -241,10 +241,19 @@ int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) | |||
| 241 | if (!tipc_addr_node_valid(addr)) | 241 | if (!tipc_addr_node_valid(addr)) |
| 242 | return -EINVAL; | 242 | return -EINVAL; |
| 243 | 243 | ||
| 244 | rtnl_lock(); | ||
| 245 | tipc_net_start(net, addr); | 244 | tipc_net_start(net, addr); |
| 246 | rtnl_unlock(); | ||
| 247 | } | 245 | } |
| 248 | 246 | ||
| 249 | return 0; | 247 | return 0; |
| 250 | } | 248 | } |
| 249 | |||
| 250 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) | ||
| 251 | { | ||
| 252 | int err; | ||
| 253 | |||
| 254 | rtnl_lock(); | ||
| 255 | err = __tipc_nl_net_set(skb, info); | ||
| 256 | rtnl_unlock(); | ||
| 257 | |||
| 258 | return err; | ||
| 259 | } | ||
diff --git a/net/tipc/net.h b/net/tipc/net.h index c7c254902873..c0306aa2374b 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
| @@ -47,5 +47,6 @@ void tipc_net_stop(struct net *net); | |||
| 47 | 47 | ||
| 48 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); | 48 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 49 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); | 49 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); |
| 50 | int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); | ||
| 50 | 51 | ||
| 51 | #endif | 52 | #endif |
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index e48f0b2c01b9..4492cda45566 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c | |||
| @@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 285 | if (!trans_buf) | 285 | if (!trans_buf) |
| 286 | return -ENOMEM; | 286 | return -ENOMEM; |
| 287 | 287 | ||
| 288 | err = (*cmd->transcode)(cmd, trans_buf, msg); | ||
| 289 | if (err) | ||
| 290 | goto trans_out; | ||
| 291 | |||
| 292 | attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * | 288 | attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * |
| 293 | sizeof(struct nlattr *), GFP_KERNEL); | 289 | sizeof(struct nlattr *), GFP_KERNEL); |
| 294 | if (!attrbuf) { | 290 | if (!attrbuf) { |
| @@ -296,27 +292,34 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 296 | goto trans_out; | 292 | goto trans_out; |
| 297 | } | 293 | } |
| 298 | 294 | ||
| 299 | err = nla_parse(attrbuf, tipc_genl_family.maxattr, | ||
| 300 | (const struct nlattr *)trans_buf->data, | ||
| 301 | trans_buf->len, NULL, NULL); | ||
| 302 | if (err) | ||
| 303 | goto parse_out; | ||
| 304 | |||
| 305 | doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 295 | doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
| 306 | if (!doit_buf) { | 296 | if (!doit_buf) { |
| 307 | err = -ENOMEM; | 297 | err = -ENOMEM; |
| 308 | goto parse_out; | 298 | goto attrbuf_out; |
| 309 | } | 299 | } |
| 310 | 300 | ||
| 311 | doit_buf->sk = msg->dst_sk; | ||
| 312 | |||
| 313 | memset(&info, 0, sizeof(info)); | 301 | memset(&info, 0, sizeof(info)); |
| 314 | info.attrs = attrbuf; | 302 | info.attrs = attrbuf; |
| 315 | 303 | ||
| 304 | rtnl_lock(); | ||
| 305 | err = (*cmd->transcode)(cmd, trans_buf, msg); | ||
| 306 | if (err) | ||
| 307 | goto doit_out; | ||
| 308 | |||
| 309 | err = nla_parse(attrbuf, tipc_genl_family.maxattr, | ||
| 310 | (const struct nlattr *)trans_buf->data, | ||
| 311 | trans_buf->len, NULL, NULL); | ||
| 312 | if (err) | ||
| 313 | goto doit_out; | ||
| 314 | |||
| 315 | doit_buf->sk = msg->dst_sk; | ||
| 316 | |||
| 316 | err = (*cmd->doit)(doit_buf, &info); | 317 | err = (*cmd->doit)(doit_buf, &info); |
| 318 | doit_out: | ||
| 319 | rtnl_unlock(); | ||
| 317 | 320 | ||
| 318 | kfree_skb(doit_buf); | 321 | kfree_skb(doit_buf); |
| 319 | parse_out: | 322 | attrbuf_out: |
| 320 | kfree(attrbuf); | 323 | kfree(attrbuf); |
| 321 | trans_out: | 324 | trans_out: |
| 322 | kfree_skb(trans_buf); | 325 | kfree_skb(trans_buf); |
| @@ -722,13 +725,13 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd, | |||
| 722 | 725 | ||
| 723 | media = tipc_media_find(lc->name); | 726 | media = tipc_media_find(lc->name); |
| 724 | if (media) { | 727 | if (media) { |
| 725 | cmd->doit = &tipc_nl_media_set; | 728 | cmd->doit = &__tipc_nl_media_set; |
| 726 | return tipc_nl_compat_media_set(skb, msg); | 729 | return tipc_nl_compat_media_set(skb, msg); |
| 727 | } | 730 | } |
| 728 | 731 | ||
| 729 | bearer = tipc_bearer_find(msg->net, lc->name); | 732 | bearer = tipc_bearer_find(msg->net, lc->name); |
| 730 | if (bearer) { | 733 | if (bearer) { |
| 731 | cmd->doit = &tipc_nl_bearer_set; | 734 | cmd->doit = &__tipc_nl_bearer_set; |
| 732 | return tipc_nl_compat_bearer_set(skb, msg); | 735 | return tipc_nl_compat_bearer_set(skb, msg); |
| 733 | } | 736 | } |
| 734 | 737 | ||
| @@ -1089,12 +1092,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | |||
| 1089 | return tipc_nl_compat_dumpit(&dump, msg); | 1092 | return tipc_nl_compat_dumpit(&dump, msg); |
| 1090 | case TIPC_CMD_ENABLE_BEARER: | 1093 | case TIPC_CMD_ENABLE_BEARER: |
| 1091 | msg->req_type = TIPC_TLV_BEARER_CONFIG; | 1094 | msg->req_type = TIPC_TLV_BEARER_CONFIG; |
| 1092 | doit.doit = tipc_nl_bearer_enable; | 1095 | doit.doit = __tipc_nl_bearer_enable; |
| 1093 | doit.transcode = tipc_nl_compat_bearer_enable; | 1096 | doit.transcode = tipc_nl_compat_bearer_enable; |
| 1094 | return tipc_nl_compat_doit(&doit, msg); | 1097 | return tipc_nl_compat_doit(&doit, msg); |
| 1095 | case TIPC_CMD_DISABLE_BEARER: | 1098 | case TIPC_CMD_DISABLE_BEARER: |
| 1096 | msg->req_type = TIPC_TLV_BEARER_NAME; | 1099 | msg->req_type = TIPC_TLV_BEARER_NAME; |
| 1097 | doit.doit = tipc_nl_bearer_disable; | 1100 | doit.doit = __tipc_nl_bearer_disable; |
| 1098 | doit.transcode = tipc_nl_compat_bearer_disable; | 1101 | doit.transcode = tipc_nl_compat_bearer_disable; |
| 1099 | return tipc_nl_compat_doit(&doit, msg); | 1102 | return tipc_nl_compat_doit(&doit, msg); |
| 1100 | case TIPC_CMD_SHOW_LINK_STATS: | 1103 | case TIPC_CMD_SHOW_LINK_STATS: |
| @@ -1148,12 +1151,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | |||
| 1148 | return tipc_nl_compat_dumpit(&dump, msg); | 1151 | return tipc_nl_compat_dumpit(&dump, msg); |
| 1149 | case TIPC_CMD_SET_NODE_ADDR: | 1152 | case TIPC_CMD_SET_NODE_ADDR: |
| 1150 | msg->req_type = TIPC_TLV_NET_ADDR; | 1153 | msg->req_type = TIPC_TLV_NET_ADDR; |
| 1151 | doit.doit = tipc_nl_net_set; | 1154 | doit.doit = __tipc_nl_net_set; |
| 1152 | doit.transcode = tipc_nl_compat_net_set; | 1155 | doit.transcode = tipc_nl_compat_net_set; |
| 1153 | return tipc_nl_compat_doit(&doit, msg); | 1156 | return tipc_nl_compat_doit(&doit, msg); |
| 1154 | case TIPC_CMD_SET_NETID: | 1157 | case TIPC_CMD_SET_NETID: |
| 1155 | msg->req_type = TIPC_TLV_UNSIGNED; | 1158 | msg->req_type = TIPC_TLV_UNSIGNED; |
| 1156 | doit.doit = tipc_nl_net_set; | 1159 | doit.doit = __tipc_nl_net_set; |
| 1157 | doit.transcode = tipc_nl_compat_net_set; | 1160 | doit.transcode = tipc_nl_compat_net_set; |
| 1158 | return tipc_nl_compat_doit(&doit, msg); | 1161 | return tipc_nl_compat_doit(&doit, msg); |
| 1159 | case TIPC_CMD_GET_NETID: | 1162 | case TIPC_CMD_GET_NETID: |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index b0d5fcea47e7..e9b4b53ab53e 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
| @@ -308,8 +308,11 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval, | |||
| 308 | goto out; | 308 | goto out; |
| 309 | } | 309 | } |
| 310 | lock_sock(sk); | 310 | lock_sock(sk); |
| 311 | memcpy(crypto_info_aes_gcm_128->iv, ctx->iv, | 311 | memcpy(crypto_info_aes_gcm_128->iv, |
| 312 | ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | ||
| 312 | TLS_CIPHER_AES_GCM_128_IV_SIZE); | 313 | TLS_CIPHER_AES_GCM_128_IV_SIZE); |
| 314 | memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->rec_seq, | ||
| 315 | TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | ||
| 313 | release_sock(sk); | 316 | release_sock(sk); |
| 314 | if (copy_to_user(optval, | 317 | if (copy_to_user(optval, |
| 315 | crypto_info_aes_gcm_128, | 318 | crypto_info_aes_gcm_128, |
| @@ -375,7 +378,7 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | |||
| 375 | rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info)); | 378 | rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info)); |
| 376 | if (rc) { | 379 | if (rc) { |
| 377 | rc = -EFAULT; | 380 | rc = -EFAULT; |
| 378 | goto out; | 381 | goto err_crypto_info; |
| 379 | } | 382 | } |
| 380 | 383 | ||
| 381 | /* check version */ | 384 | /* check version */ |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d545e1d0dea2..2d465bdeccbc 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1825,7 +1825,7 @@ out: | |||
| 1825 | } | 1825 | } |
| 1826 | 1826 | ||
| 1827 | /* We use paged skbs for stream sockets, and limit occupancy to 32768 | 1827 | /* We use paged skbs for stream sockets, and limit occupancy to 32768 |
| 1828 | * bytes, and a minimun of a full page. | 1828 | * bytes, and a minimum of a full page. |
| 1829 | */ | 1829 | */ |
| 1830 | #define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768)) | 1830 | #define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768)) |
| 1831 | 1831 | ||
diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h index 637b7263cb86..833ed9a16adf 100644 --- a/tools/arch/powerpc/include/uapi/asm/kvm.h +++ b/tools/arch/powerpc/include/uapi/asm/kvm.h | |||
| @@ -632,6 +632,8 @@ struct kvm_ppc_cpu_char { | |||
| 632 | #define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc) | 632 | #define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc) |
| 633 | #define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd) | 633 | #define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd) |
| 634 | 634 | ||
| 635 | #define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe) | ||
| 636 | |||
| 635 | /* Transactional Memory checkpointed state: | 637 | /* Transactional Memory checkpointed state: |
| 636 | * This is all GPRs, all VSX regs and a subset of SPRs | 638 | * This is all GPRs, all VSX regs and a subset of SPRs |
| 637 | */ | 639 | */ |
diff --git a/tools/arch/s390/include/uapi/asm/unistd.h b/tools/arch/s390/include/uapi/asm/unistd.h deleted file mode 100644 index 725120939051..000000000000 --- a/tools/arch/s390/include/uapi/asm/unistd.h +++ /dev/null | |||
| @@ -1,412 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
| 2 | /* | ||
| 3 | * S390 version | ||
| 4 | * | ||
| 5 | * Derived from "include/asm-i386/unistd.h" | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _UAPI_ASM_S390_UNISTD_H_ | ||
| 9 | #define _UAPI_ASM_S390_UNISTD_H_ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * This file contains the system call numbers. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #define __NR_exit 1 | ||
| 16 | #define __NR_fork 2 | ||
| 17 | #define __NR_read 3 | ||
| 18 | #define __NR_write 4 | ||
| 19 | #define __NR_open 5 | ||
| 20 | #define __NR_close 6 | ||
| 21 | #define __NR_restart_syscall 7 | ||
| 22 | #define __NR_creat 8 | ||
| 23 | #define __NR_link 9 | ||
| 24 | #define __NR_unlink 10 | ||
| 25 | #define __NR_execve 11 | ||
| 26 | #define __NR_chdir 12 | ||
| 27 | #define __NR_mknod 14 | ||
| 28 | #define __NR_chmod 15 | ||
| 29 | #define __NR_lseek 19 | ||
| 30 | #define __NR_getpid 20 | ||
| 31 | #define __NR_mount 21 | ||
| 32 | #define __NR_umount 22 | ||
| 33 | #define __NR_ptrace 26 | ||
| 34 | #define __NR_alarm 27 | ||
| 35 | #define __NR_pause 29 | ||
| 36 | #define __NR_utime 30 | ||
| 37 | #define __NR_access 33 | ||
| 38 | #define __NR_nice 34 | ||
| 39 | #define __NR_sync 36 | ||
| 40 | #define __NR_kill 37 | ||
| 41 | #define __NR_rename 38 | ||
| 42 | #define __NR_mkdir 39 | ||
| 43 | #define __NR_rmdir 40 | ||
| 44 | #define __NR_dup 41 | ||
| 45 | #define __NR_pipe 42 | ||
| 46 | #define __NR_times 43 | ||
| 47 | #define __NR_brk 45 | ||
| 48 | #define __NR_signal 48 | ||
| 49 | #define __NR_acct 51 | ||
| 50 | #define __NR_umount2 52 | ||
| 51 | #define __NR_ioctl 54 | ||
| 52 | #define __NR_fcntl 55 | ||
| 53 | #define __NR_setpgid 57 | ||
| 54 | #define __NR_umask 60 | ||
| 55 | #define __NR_chroot 61 | ||
| 56 | #define __NR_ustat 62 | ||
| 57 | #define __NR_dup2 63 | ||
| 58 | #define __NR_getppid 64 | ||
| 59 | #define __NR_getpgrp 65 | ||
| 60 | #define __NR_setsid 66 | ||
| 61 | #define __NR_sigaction 67 | ||
| 62 | #define __NR_sigsuspend 72 | ||
| 63 | #define __NR_sigpending 73 | ||
| 64 | #define __NR_sethostname 74 | ||
| 65 | #define __NR_setrlimit 75 | ||
| 66 | #define __NR_getrusage 77 | ||
| 67 | #define __NR_gettimeofday 78 | ||
| 68 | #define __NR_settimeofday 79 | ||
| 69 | #define __NR_symlink 83 | ||
| 70 | #define __NR_readlink 85 | ||
| 71 | #define __NR_uselib 86 | ||
| 72 | #define __NR_swapon 87 | ||
| 73 | #define __NR_reboot 88 | ||
| 74 | #define __NR_readdir 89 | ||
| 75 | #define __NR_mmap 90 | ||
| 76 | #define __NR_munmap 91 | ||
| 77 | #define __NR_truncate 92 | ||
| 78 | #define __NR_ftruncate 93 | ||
| 79 | #define __NR_fchmod 94 | ||
| 80 | #define __NR_getpriority 96 | ||
| 81 | #define __NR_setpriority 97 | ||
| 82 | #define __NR_statfs 99 | ||
| 83 | #define __NR_fstatfs 100 | ||
| 84 | #define __NR_socketcall 102 | ||
| 85 | #define __NR_syslog 103 | ||
| 86 | #define __NR_setitimer 104 | ||
| 87 | #define __NR_getitimer 105 | ||
| 88 | #define __NR_stat 106 | ||
| 89 | #define __NR_lstat 107 | ||
| 90 | #define __NR_fstat 108 | ||
| 91 | #define __NR_lookup_dcookie 110 | ||
| 92 | #define __NR_vhangup 111 | ||
| 93 | #define __NR_idle 112 | ||
| 94 | #define __NR_wait4 114 | ||
| 95 | #define __NR_swapoff 115 | ||
| 96 | #define __NR_sysinfo 116 | ||
| 97 | #define __NR_ipc 117 | ||
| 98 | #define __NR_fsync 118 | ||
| 99 | #define __NR_sigreturn 119 | ||
| 100 | #define __NR_clone 120 | ||
| 101 | #define __NR_setdomainname 121 | ||
| 102 | #define __NR_uname 122 | ||
| 103 | #define __NR_adjtimex 124 | ||
| 104 | #define __NR_mprotect 125 | ||
| 105 | #define __NR_sigprocmask 126 | ||
| 106 | #define __NR_create_module 127 | ||
| 107 | #define __NR_init_module 128 | ||
| 108 | #define __NR_delete_module 129 | ||
| 109 | #define __NR_get_kernel_syms 130 | ||
| 110 | #define __NR_quotactl 131 | ||
| 111 | #define __NR_getpgid 132 | ||
| 112 | #define __NR_fchdir 133 | ||
| 113 | #define __NR_bdflush 134 | ||
| 114 | #define __NR_sysfs 135 | ||
| 115 | #define __NR_personality 136 | ||
| 116 | #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
| 117 | #define __NR_getdents 141 | ||
| 118 | #define __NR_flock 143 | ||
| 119 | #define __NR_msync 144 | ||
| 120 | #define __NR_readv 145 | ||
| 121 | #define __NR_writev 146 | ||
| 122 | #define __NR_getsid 147 | ||
| 123 | #define __NR_fdatasync 148 | ||
| 124 | #define __NR__sysctl 149 | ||
| 125 | #define __NR_mlock 150 | ||
| 126 | #define __NR_munlock 151 | ||
| 127 | #define __NR_mlockall 152 | ||
| 128 | #define __NR_munlockall 153 | ||
| 129 | #define __NR_sched_setparam 154 | ||
| 130 | #define __NR_sched_getparam 155 | ||
| 131 | #define __NR_sched_setscheduler 156 | ||
| 132 | #define __NR_sched_getscheduler 157 | ||
| 133 | #define __NR_sched_yield 158 | ||
| 134 | #define __NR_sched_get_priority_max 159 | ||
| 135 | #define __NR_sched_get_priority_min 160 | ||
| 136 | #define __NR_sched_rr_get_interval 161 | ||
| 137 | #define __NR_nanosleep 162 | ||
| 138 | #define __NR_mremap 163 | ||
| 139 | #define __NR_query_module 167 | ||
| 140 | #define __NR_poll 168 | ||
| 141 | #define __NR_nfsservctl 169 | ||
| 142 | #define __NR_prctl 172 | ||
| 143 | #define __NR_rt_sigreturn 173 | ||
| 144 | #define __NR_rt_sigaction 174 | ||
| 145 | #define __NR_rt_sigprocmask 175 | ||
| 146 | #define __NR_rt_sigpending 176 | ||
| 147 | #define __NR_rt_sigtimedwait 177 | ||
| 148 | #define __NR_rt_sigqueueinfo 178 | ||
| 149 | #define __NR_rt_sigsuspend 179 | ||
| 150 | #define __NR_pread64 180 | ||
| 151 | #define __NR_pwrite64 181 | ||
| 152 | #define __NR_getcwd 183 | ||
| 153 | #define __NR_capget 184 | ||
| 154 | #define __NR_capset 185 | ||
| 155 | #define __NR_sigaltstack 186 | ||
| 156 | #define __NR_sendfile 187 | ||
| 157 | #define __NR_getpmsg 188 | ||
| 158 | #define __NR_putpmsg 189 | ||
| 159 | #define __NR_vfork 190 | ||
| 160 | #define __NR_pivot_root 217 | ||
| 161 | #define __NR_mincore 218 | ||
| 162 | #define __NR_madvise 219 | ||
| 163 | #define __NR_getdents64 220 | ||
| 164 | #define __NR_readahead 222 | ||
| 165 | #define __NR_setxattr 224 | ||
| 166 | #define __NR_lsetxattr 225 | ||
| 167 | #define __NR_fsetxattr 226 | ||
| 168 | #define __NR_getxattr 227 | ||
| 169 | #define __NR_lgetxattr 228 | ||
| 170 | #define __NR_fgetxattr 229 | ||
| 171 | #define __NR_listxattr 230 | ||
| 172 | #define __NR_llistxattr 231 | ||
| 173 | #define __NR_flistxattr 232 | ||
| 174 | #define __NR_removexattr 233 | ||
| 175 | #define __NR_lremovexattr 234 | ||
| 176 | #define __NR_fremovexattr 235 | ||
| 177 | #define __NR_gettid 236 | ||
| 178 | #define __NR_tkill 237 | ||
| 179 | #define __NR_futex 238 | ||
| 180 | #define __NR_sched_setaffinity 239 | ||
| 181 | #define __NR_sched_getaffinity 240 | ||
| 182 | #define __NR_tgkill 241 | ||
| 183 | /* Number 242 is reserved for tux */ | ||
| 184 | #define __NR_io_setup 243 | ||
| 185 | #define __NR_io_destroy 244 | ||
| 186 | #define __NR_io_getevents 245 | ||
| 187 | #define __NR_io_submit 246 | ||
| 188 | #define __NR_io_cancel 247 | ||
| 189 | #define __NR_exit_group 248 | ||
| 190 | #define __NR_epoll_create 249 | ||
| 191 | #define __NR_epoll_ctl 250 | ||
| 192 | #define __NR_epoll_wait 251 | ||
| 193 | #define __NR_set_tid_address 252 | ||
| 194 | #define __NR_fadvise64 253 | ||
| 195 | #define __NR_timer_create 254 | ||
| 196 | #define __NR_timer_settime 255 | ||
| 197 | #define __NR_timer_gettime 256 | ||
| 198 | #define __NR_timer_getoverrun 257 | ||
| 199 | #define __NR_timer_delete 258 | ||
| 200 | #define __NR_clock_settime 259 | ||
| 201 | #define __NR_clock_gettime 260 | ||
| 202 | #define __NR_clock_getres 261 | ||
| 203 | #define __NR_clock_nanosleep 262 | ||
| 204 | /* Number 263 is reserved for vserver */ | ||
| 205 | #define __NR_statfs64 265 | ||
| 206 | #define __NR_fstatfs64 266 | ||
| 207 | #define __NR_remap_file_pages 267 | ||
| 208 | #define __NR_mbind 268 | ||
| 209 | #define __NR_get_mempolicy 269 | ||
| 210 | #define __NR_set_mempolicy 270 | ||
| 211 | #define __NR_mq_open 271 | ||
| 212 | #define __NR_mq_unlink 272 | ||
| 213 | #define __NR_mq_timedsend 273 | ||
| 214 | #define __NR_mq_timedreceive 274 | ||
| 215 | #define __NR_mq_notify 275 | ||
| 216 | #define __NR_mq_getsetattr 276 | ||
| 217 | #define __NR_kexec_load 277 | ||
| 218 | #define __NR_add_key 278 | ||
| 219 | #define __NR_request_key 279 | ||
| 220 | #define __NR_keyctl 280 | ||
| 221 | #define __NR_waitid 281 | ||
| 222 | #define __NR_ioprio_set 282 | ||
| 223 | #define __NR_ioprio_get 283 | ||
| 224 | #define __NR_inotify_init 284 | ||
| 225 | #define __NR_inotify_add_watch 285 | ||
| 226 | #define __NR_inotify_rm_watch 286 | ||
| 227 | #define __NR_migrate_pages 287 | ||
| 228 | #define __NR_openat 288 | ||
| 229 | #define __NR_mkdirat 289 | ||
| 230 | #define __NR_mknodat 290 | ||
| 231 | #define __NR_fchownat 291 | ||
| 232 | #define __NR_futimesat 292 | ||
| 233 | #define __NR_unlinkat 294 | ||
| 234 | #define __NR_renameat 295 | ||
| 235 | #define __NR_linkat 296 | ||
| 236 | #define __NR_symlinkat 297 | ||
| 237 | #define __NR_readlinkat 298 | ||
| 238 | #define __NR_fchmodat 299 | ||
| 239 | #define __NR_faccessat 300 | ||
| 240 | #define __NR_pselect6 301 | ||
| 241 | #define __NR_ppoll 302 | ||
| 242 | #define __NR_unshare 303 | ||
| 243 | #define __NR_set_robust_list 304 | ||
| 244 | #define __NR_get_robust_list 305 | ||
| 245 | #define __NR_splice 306 | ||
| 246 | #define __NR_sync_file_range 307 | ||
| 247 | #define __NR_tee 308 | ||
| 248 | #define __NR_vmsplice 309 | ||
| 249 | #define __NR_move_pages 310 | ||
| 250 | #define __NR_getcpu 311 | ||
| 251 | #define __NR_epoll_pwait 312 | ||
| 252 | #define __NR_utimes 313 | ||
| 253 | #define __NR_fallocate 314 | ||
| 254 | #define __NR_utimensat 315 | ||
| 255 | #define __NR_signalfd 316 | ||
| 256 | #define __NR_timerfd 317 | ||
| 257 | #define __NR_eventfd 318 | ||
| 258 | #define __NR_timerfd_create 319 | ||
| 259 | #define __NR_timerfd_settime 320 | ||
| 260 | #define __NR_timerfd_gettime 321 | ||
| 261 | #define __NR_signalfd4 322 | ||
| 262 | #define __NR_eventfd2 323 | ||
| 263 | #define __NR_inotify_init1 324 | ||
| 264 | #define __NR_pipe2 325 | ||
| 265 | #define __NR_dup3 326 | ||
| 266 | #define __NR_epoll_create1 327 | ||
| 267 | #define __NR_preadv 328 | ||
| 268 | #define __NR_pwritev 329 | ||
| 269 | #define __NR_rt_tgsigqueueinfo 330 | ||
| 270 | #define __NR_perf_event_open 331 | ||
| 271 | #define __NR_fanotify_init 332 | ||
| 272 | #define __NR_fanotify_mark 333 | ||
| 273 | #define __NR_prlimit64 334 | ||
| 274 | #define __NR_name_to_handle_at 335 | ||
| 275 | #define __NR_open_by_handle_at 336 | ||
| 276 | #define __NR_clock_adjtime 337 | ||
| 277 | #define __NR_syncfs 338 | ||
| 278 | #define __NR_setns 339 | ||
| 279 | #define __NR_process_vm_readv 340 | ||
| 280 | #define __NR_process_vm_writev 341 | ||
| 281 | #define __NR_s390_runtime_instr 342 | ||
| 282 | #define __NR_kcmp 343 | ||
| 283 | #define __NR_finit_module 344 | ||
| 284 | #define __NR_sched_setattr 345 | ||
| 285 | #define __NR_sched_getattr 346 | ||
| 286 | #define __NR_renameat2 347 | ||
| 287 | #define __NR_seccomp 348 | ||
| 288 | #define __NR_getrandom 349 | ||
| 289 | #define __NR_memfd_create 350 | ||
| 290 | #define __NR_bpf 351 | ||
| 291 | #define __NR_s390_pci_mmio_write 352 | ||
| 292 | #define __NR_s390_pci_mmio_read 353 | ||
| 293 | #define __NR_execveat 354 | ||
| 294 | #define __NR_userfaultfd 355 | ||
| 295 | #define __NR_membarrier 356 | ||
| 296 | #define __NR_recvmmsg 357 | ||
| 297 | #define __NR_sendmmsg 358 | ||
| 298 | #define __NR_socket 359 | ||
| 299 | #define __NR_socketpair 360 | ||
| 300 | #define __NR_bind 361 | ||
| 301 | #define __NR_connect 362 | ||
| 302 | #define __NR_listen 363 | ||
| 303 | #define __NR_accept4 364 | ||
| 304 | #define __NR_getsockopt 365 | ||
| 305 | #define __NR_setsockopt 366 | ||
| 306 | #define __NR_getsockname 367 | ||
| 307 | #define __NR_getpeername 368 | ||
| 308 | #define __NR_sendto 369 | ||
| 309 | #define __NR_sendmsg 370 | ||
| 310 | #define __NR_recvfrom 371 | ||
| 311 | #define __NR_recvmsg 372 | ||
| 312 | #define __NR_shutdown 373 | ||
| 313 | #define __NR_mlock2 374 | ||
| 314 | #define __NR_copy_file_range 375 | ||
| 315 | #define __NR_preadv2 376 | ||
| 316 | #define __NR_pwritev2 377 | ||
| 317 | #define __NR_s390_guarded_storage 378 | ||
| 318 | #define __NR_statx 379 | ||
| 319 | #define __NR_s390_sthyi 380 | ||
| 320 | #define NR_syscalls 381 | ||
| 321 | |||
| 322 | /* | ||
| 323 | * There are some system calls that are not present on 64 bit, some | ||
| 324 | * have a different name although they do the same (e.g. __NR_chown32 | ||
| 325 | * is __NR_chown on 64 bit). | ||
| 326 | */ | ||
| 327 | #ifndef __s390x__ | ||
| 328 | |||
| 329 | #define __NR_time 13 | ||
| 330 | #define __NR_lchown 16 | ||
| 331 | #define __NR_setuid 23 | ||
| 332 | #define __NR_getuid 24 | ||
| 333 | #define __NR_stime 25 | ||
| 334 | #define __NR_setgid 46 | ||
| 335 | #define __NR_getgid 47 | ||
| 336 | #define __NR_geteuid 49 | ||
| 337 | #define __NR_getegid 50 | ||
| 338 | #define __NR_setreuid 70 | ||
| 339 | #define __NR_setregid 71 | ||
| 340 | #define __NR_getrlimit 76 | ||
| 341 | #define __NR_getgroups 80 | ||
| 342 | #define __NR_setgroups 81 | ||
| 343 | #define __NR_fchown 95 | ||
| 344 | #define __NR_ioperm 101 | ||
| 345 | #define __NR_setfsuid 138 | ||
| 346 | #define __NR_setfsgid 139 | ||
| 347 | #define __NR__llseek 140 | ||
| 348 | #define __NR__newselect 142 | ||
| 349 | #define __NR_setresuid 164 | ||
| 350 | #define __NR_getresuid 165 | ||
| 351 | #define __NR_setresgid 170 | ||
| 352 | #define __NR_getresgid 171 | ||
| 353 | #define __NR_chown 182 | ||
| 354 | #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ | ||
| 355 | #define __NR_mmap2 192 | ||
| 356 | #define __NR_truncate64 193 | ||
| 357 | #define __NR_ftruncate64 194 | ||
| 358 | #define __NR_stat64 195 | ||
| 359 | #define __NR_lstat64 196 | ||
| 360 | #define __NR_fstat64 197 | ||
| 361 | #define __NR_lchown32 198 | ||
| 362 | #define __NR_getuid32 199 | ||
| 363 | #define __NR_getgid32 200 | ||
| 364 | #define __NR_geteuid32 201 | ||
| 365 | #define __NR_getegid32 202 | ||
| 366 | #define __NR_setreuid32 203 | ||
| 367 | #define __NR_setregid32 204 | ||
| 368 | #define __NR_getgroups32 205 | ||
| 369 | #define __NR_setgroups32 206 | ||
| 370 | #define __NR_fchown32 207 | ||
| 371 | #define __NR_setresuid32 208 | ||
| 372 | #define __NR_getresuid32 209 | ||
| 373 | #define __NR_setresgid32 210 | ||
| 374 | #define __NR_getresgid32 211 | ||
| 375 | #define __NR_chown32 212 | ||
| 376 | #define __NR_setuid32 213 | ||
| 377 | #define __NR_setgid32 214 | ||
| 378 | #define __NR_setfsuid32 215 | ||
| 379 | #define __NR_setfsgid32 216 | ||
| 380 | #define __NR_fcntl64 221 | ||
| 381 | #define __NR_sendfile64 223 | ||
| 382 | #define __NR_fadvise64_64 264 | ||
| 383 | #define __NR_fstatat64 293 | ||
| 384 | |||
| 385 | #else | ||
| 386 | |||
| 387 | #define __NR_select 142 | ||
| 388 | #define __NR_getrlimit 191 /* SuS compliant getrlimit */ | ||
| 389 | #define __NR_lchown 198 | ||
| 390 | #define __NR_getuid 199 | ||
| 391 | #define __NR_getgid 200 | ||
| 392 | #define __NR_geteuid 201 | ||
| 393 | #define __NR_getegid 202 | ||
| 394 | #define __NR_setreuid 203 | ||
| 395 | #define __NR_setregid 204 | ||
| 396 | #define __NR_getgroups 205 | ||
| 397 | #define __NR_setgroups 206 | ||
| 398 | #define __NR_fchown 207 | ||
| 399 | #define __NR_setresuid 208 | ||
| 400 | #define __NR_getresuid 209 | ||
| 401 | #define __NR_setresgid 210 | ||
| 402 | #define __NR_getresgid 211 | ||
| 403 | #define __NR_chown 212 | ||
| 404 | #define __NR_setuid 213 | ||
| 405 | #define __NR_setgid 214 | ||
| 406 | #define __NR_setfsuid 215 | ||
| 407 | #define __NR_setfsgid 216 | ||
| 408 | #define __NR_newfstatat 293 | ||
| 409 | |||
| 410 | #endif | ||
| 411 | |||
| 412 | #endif /* _UAPI_ASM_S390_UNISTD_H_ */ | ||
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 1d9199e1c2ad..0dfe4d3f74e2 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h | |||
| @@ -210,6 +210,7 @@ | |||
| 210 | 210 | ||
| 211 | #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ | 211 | #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ |
| 212 | #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ | 212 | #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ |
| 213 | #define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ | ||
| 213 | 214 | ||
| 214 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ | 215 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ |
| 215 | 216 | ||
diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile index 860fa151640a..ffca068e4a76 100644 --- a/tools/cgroup/Makefile +++ b/tools/cgroup/Makefile | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # Makefile for cgroup tools | 2 | # Makefile for cgroup tools |
| 3 | 3 | ||
| 4 | CC = $(CROSS_COMPILE)gcc | ||
| 5 | CFLAGS = -Wall -Wextra | 4 | CFLAGS = -Wall -Wextra |
| 6 | 5 | ||
| 7 | all: cgroup_event_listener | 6 | all: cgroup_event_listener |
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index 805a2c0cf4cd..240eda014b37 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile | |||
| @@ -12,8 +12,6 @@ endif | |||
| 12 | # (this improves performance and avoids hard-to-debug behaviour); | 12 | # (this improves performance and avoids hard-to-debug behaviour); |
| 13 | MAKEFLAGS += -r | 13 | MAKEFLAGS += -r |
| 14 | 14 | ||
| 15 | CC = $(CROSS_COMPILE)gcc | ||
| 16 | LD = $(CROSS_COMPILE)ld | ||
| 17 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | 15 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
| 18 | 16 | ||
| 19 | ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon | 17 | ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon |
diff --git a/tools/hv/Makefile b/tools/hv/Makefile index 1139d71fa0cf..5db5e62cebda 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # Makefile for Hyper-V tools | 2 | # Makefile for Hyper-V tools |
| 3 | 3 | ||
| 4 | CC = $(CROSS_COMPILE)gcc | ||
| 5 | WARNINGS = -Wall -Wextra | 4 | WARNINGS = -Wall -Wextra |
| 6 | CFLAGS = $(WARNINGS) -g $(shell getconf LFS_CFLAGS) | 5 | CFLAGS = $(WARNINGS) -g $(shell getconf LFS_CFLAGS) |
| 7 | 6 | ||
diff --git a/tools/iio/Makefile b/tools/iio/Makefile index a08e7a47d6a3..332ed2f6c2c2 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile | |||
| @@ -12,8 +12,6 @@ endif | |||
| 12 | # (this improves performance and avoids hard-to-debug behaviour); | 12 | # (this improves performance and avoids hard-to-debug behaviour); |
| 13 | MAKEFLAGS += -r | 13 | MAKEFLAGS += -r |
| 14 | 14 | ||
| 15 | CC = $(CROSS_COMPILE)gcc | ||
| 16 | LD = $(CROSS_COMPILE)ld | ||
| 17 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | 15 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
| 18 | 16 | ||
| 19 | ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer | 17 | ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer |
diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h index ac3c6503ca27..536ee4febd74 100644 --- a/tools/include/uapi/drm/i915_drm.h +++ b/tools/include/uapi/drm/i915_drm.h | |||
| @@ -86,6 +86,62 @@ enum i915_mocs_table_index { | |||
| 86 | I915_MOCS_CACHED, | 86 | I915_MOCS_CACHED, |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | /* | ||
| 90 | * Different engines serve different roles, and there may be more than one | ||
| 91 | * engine serving each role. enum drm_i915_gem_engine_class provides a | ||
| 92 | * classification of the role of the engine, which may be used when requesting | ||
| 93 | * operations to be performed on a certain subset of engines, or for providing | ||
| 94 | * information about that group. | ||
| 95 | */ | ||
| 96 | enum drm_i915_gem_engine_class { | ||
| 97 | I915_ENGINE_CLASS_RENDER = 0, | ||
| 98 | I915_ENGINE_CLASS_COPY = 1, | ||
| 99 | I915_ENGINE_CLASS_VIDEO = 2, | ||
| 100 | I915_ENGINE_CLASS_VIDEO_ENHANCE = 3, | ||
| 101 | |||
| 102 | I915_ENGINE_CLASS_INVALID = -1 | ||
| 103 | }; | ||
| 104 | |||
| 105 | /** | ||
| 106 | * DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915 | ||
| 107 | * | ||
| 108 | */ | ||
| 109 | |||
| 110 | enum drm_i915_pmu_engine_sample { | ||
| 111 | I915_SAMPLE_BUSY = 0, | ||
| 112 | I915_SAMPLE_WAIT = 1, | ||
| 113 | I915_SAMPLE_SEMA = 2 | ||
| 114 | }; | ||
| 115 | |||
| 116 | #define I915_PMU_SAMPLE_BITS (4) | ||
| 117 | #define I915_PMU_SAMPLE_MASK (0xf) | ||
| 118 | #define I915_PMU_SAMPLE_INSTANCE_BITS (8) | ||
| 119 | #define I915_PMU_CLASS_SHIFT \ | ||
| 120 | (I915_PMU_SAMPLE_BITS + I915_PMU_SAMPLE_INSTANCE_BITS) | ||
| 121 | |||
| 122 | #define __I915_PMU_ENGINE(class, instance, sample) \ | ||
| 123 | ((class) << I915_PMU_CLASS_SHIFT | \ | ||
| 124 | (instance) << I915_PMU_SAMPLE_BITS | \ | ||
| 125 | (sample)) | ||
| 126 | |||
| 127 | #define I915_PMU_ENGINE_BUSY(class, instance) \ | ||
| 128 | __I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY) | ||
| 129 | |||
| 130 | #define I915_PMU_ENGINE_WAIT(class, instance) \ | ||
| 131 | __I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT) | ||
| 132 | |||
| 133 | #define I915_PMU_ENGINE_SEMA(class, instance) \ | ||
| 134 | __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA) | ||
| 135 | |||
| 136 | #define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x)) | ||
| 137 | |||
| 138 | #define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0) | ||
| 139 | #define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1) | ||
| 140 | #define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2) | ||
| 141 | #define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3) | ||
| 142 | |||
| 143 | #define I915_PMU_LAST I915_PMU_RC6_RESIDENCY | ||
| 144 | |||
| 89 | /* Each region is a minimum of 16k, and there are at most 255 of them. | 145 | /* Each region is a minimum of 16k, and there are at most 255 of them. |
| 90 | */ | 146 | */ |
| 91 | #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use | 147 | #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use |
| @@ -450,6 +506,27 @@ typedef struct drm_i915_irq_wait { | |||
| 450 | */ | 506 | */ |
| 451 | #define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 | 507 | #define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 |
| 452 | 508 | ||
| 509 | /* | ||
| 510 | * Query whether every context (both per-file default and user created) is | ||
| 511 | * isolated (insofar as HW supports). If this parameter is not true, then | ||
| 512 | * freshly created contexts may inherit values from an existing context, | ||
| 513 | * rather than default HW values. If true, it also ensures (insofar as HW | ||
| 514 | * supports) that all state set by this context will not leak to any other | ||
| 515 | * context. | ||
| 516 | * | ||
| 517 | * As not every engine across every gen support contexts, the returned | ||
| 518 | * value reports the support of context isolation for individual engines by | ||
| 519 | * returning a bitmask of each engine class set to true if that class supports | ||
| 520 | * isolation. | ||
| 521 | */ | ||
| 522 | #define I915_PARAM_HAS_CONTEXT_ISOLATION 50 | ||
| 523 | |||
| 524 | /* Frequency of the command streamer timestamps given by the *_TIMESTAMP | ||
| 525 | * registers. This used to be fixed per platform but from CNL onwards, this | ||
| 526 | * might vary depending on the parts. | ||
| 527 | */ | ||
| 528 | #define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51 | ||
| 529 | |||
| 453 | typedef struct drm_i915_getparam { | 530 | typedef struct drm_i915_getparam { |
| 454 | __s32 param; | 531 | __s32 param; |
| 455 | /* | 532 | /* |
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index 8616131e2c61..6d9447700e18 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h | |||
| @@ -163,6 +163,7 @@ enum { | |||
| 163 | IFLA_IF_NETNSID, | 163 | IFLA_IF_NETNSID, |
| 164 | IFLA_CARRIER_UP_COUNT, | 164 | IFLA_CARRIER_UP_COUNT, |
| 165 | IFLA_CARRIER_DOWN_COUNT, | 165 | IFLA_CARRIER_DOWN_COUNT, |
| 166 | IFLA_NEW_IFINDEX, | ||
| 166 | __IFLA_MAX | 167 | __IFLA_MAX |
| 167 | }; | 168 | }; |
| 168 | 169 | ||
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 8fb90a0819c3..0fb5ef939732 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h | |||
| @@ -1362,6 +1362,96 @@ struct kvm_s390_ucas_mapping { | |||
| 1362 | /* Available with KVM_CAP_S390_CMMA_MIGRATION */ | 1362 | /* Available with KVM_CAP_S390_CMMA_MIGRATION */ |
| 1363 | #define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log) | 1363 | #define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log) |
| 1364 | #define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log) | 1364 | #define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log) |
| 1365 | /* Memory Encryption Commands */ | ||
| 1366 | #define KVM_MEMORY_ENCRYPT_OP _IOWR(KVMIO, 0xba, unsigned long) | ||
| 1367 | |||
| 1368 | struct kvm_enc_region { | ||
| 1369 | __u64 addr; | ||
| 1370 | __u64 size; | ||
| 1371 | }; | ||
| 1372 | |||
| 1373 | #define KVM_MEMORY_ENCRYPT_REG_REGION _IOR(KVMIO, 0xbb, struct kvm_enc_region) | ||
| 1374 | #define KVM_MEMORY_ENCRYPT_UNREG_REGION _IOR(KVMIO, 0xbc, struct kvm_enc_region) | ||
| 1375 | |||
| 1376 | /* Secure Encrypted Virtualization command */ | ||
| 1377 | enum sev_cmd_id { | ||
| 1378 | /* Guest initialization commands */ | ||
| 1379 | KVM_SEV_INIT = 0, | ||
| 1380 | KVM_SEV_ES_INIT, | ||
| 1381 | /* Guest launch commands */ | ||
| 1382 | KVM_SEV_LAUNCH_START, | ||
| 1383 | KVM_SEV_LAUNCH_UPDATE_DATA, | ||
| 1384 | KVM_SEV_LAUNCH_UPDATE_VMSA, | ||
| 1385 | KVM_SEV_LAUNCH_SECRET, | ||
| 1386 | KVM_SEV_LAUNCH_MEASURE, | ||
| 1387 | KVM_SEV_LAUNCH_FINISH, | ||
| 1388 | /* Guest migration commands (outgoing) */ | ||
| 1389 | KVM_SEV_SEND_START, | ||
| 1390 | KVM_SEV_SEND_UPDATE_DATA, | ||
| 1391 | KVM_SEV_SEND_UPDATE_VMSA, | ||
| 1392 | KVM_SEV_SEND_FINISH, | ||
| 1393 | /* Guest migration commands (incoming) */ | ||
| 1394 | KVM_SEV_RECEIVE_START, | ||
| 1395 | KVM_SEV_RECEIVE_UPDATE_DATA, | ||
| 1396 | KVM_SEV_RECEIVE_UPDATE_VMSA, | ||
| 1397 | KVM_SEV_RECEIVE_FINISH, | ||
| 1398 | /* Guest status and debug commands */ | ||
| 1399 | KVM_SEV_GUEST_STATUS, | ||
| 1400 | KVM_SEV_DBG_DECRYPT, | ||
| 1401 | KVM_SEV_DBG_ENCRYPT, | ||
| 1402 | /* Guest certificates commands */ | ||
| 1403 | KVM_SEV_CERT_EXPORT, | ||
| 1404 | |||
| 1405 | KVM_SEV_NR_MAX, | ||
| 1406 | }; | ||
| 1407 | |||
| 1408 | struct kvm_sev_cmd { | ||
| 1409 | __u32 id; | ||
| 1410 | __u64 data; | ||
| 1411 | __u32 error; | ||
| 1412 | __u32 sev_fd; | ||
| 1413 | }; | ||
| 1414 | |||
| 1415 | struct kvm_sev_launch_start { | ||
| 1416 | __u32 handle; | ||
| 1417 | __u32 policy; | ||
| 1418 | __u64 dh_uaddr; | ||
| 1419 | __u32 dh_len; | ||
| 1420 | __u64 session_uaddr; | ||
| 1421 | __u32 session_len; | ||
| 1422 | }; | ||
| 1423 | |||
| 1424 | struct kvm_sev_launch_update_data { | ||
| 1425 | __u64 uaddr; | ||
| 1426 | __u32 len; | ||
| 1427 | }; | ||
| 1428 | |||
| 1429 | |||
| 1430 | struct kvm_sev_launch_secret { | ||
| 1431 | __u64 hdr_uaddr; | ||
| 1432 | __u32 hdr_len; | ||
| 1433 | __u64 guest_uaddr; | ||
| 1434 | __u32 guest_len; | ||
| 1435 | __u64 trans_uaddr; | ||
| 1436 | __u32 trans_len; | ||
| 1437 | }; | ||
| 1438 | |||
| 1439 | struct kvm_sev_launch_measure { | ||
| 1440 | __u64 uaddr; | ||
| 1441 | __u32 len; | ||
| 1442 | }; | ||
| 1443 | |||
| 1444 | struct kvm_sev_guest_status { | ||
| 1445 | __u32 handle; | ||
| 1446 | __u32 policy; | ||
| 1447 | __u32 state; | ||
| 1448 | }; | ||
| 1449 | |||
| 1450 | struct kvm_sev_dbg { | ||
| 1451 | __u64 src_uaddr; | ||
| 1452 | __u64 dst_uaddr; | ||
| 1453 | __u32 len; | ||
| 1454 | }; | ||
| 1365 | 1455 | ||
| 1366 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) | 1456 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) |
| 1367 | #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) | 1457 | #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) |
diff --git a/tools/laptop/freefall/Makefile b/tools/laptop/freefall/Makefile index 5f758c489a20..b572d94255f6 100644 --- a/tools/laptop/freefall/Makefile +++ b/tools/laptop/freefall/Makefile | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | PREFIX ?= /usr | 2 | PREFIX ?= /usr |
| 3 | SBINDIR ?= sbin | 3 | SBINDIR ?= sbin |
| 4 | INSTALL ?= install | 4 | INSTALL ?= install |
| 5 | CC = $(CROSS_COMPILE)gcc | ||
| 6 | 5 | ||
| 7 | TARGET = freefall | 6 | TARGET = freefall |
| 8 | 7 | ||
diff --git a/tools/leds/Makefile b/tools/leds/Makefile index c379af003807..7b6bed13daaa 100644 --- a/tools/leds/Makefile +++ b/tools/leds/Makefile | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # Makefile for LEDs tools | 2 | # Makefile for LEDs tools |
| 3 | 3 | ||
| 4 | CC = $(CROSS_COMPILE)gcc | ||
| 5 | CFLAGS = -Wall -Wextra -g -I../../include/uapi | 4 | CFLAGS = -Wall -Wextra -g -I../../include/uapi |
| 6 | 5 | ||
| 7 | all: uledmon led_hw_brightness_mon | 6 | all: uledmon led_hw_brightness_mon |
diff --git a/tools/perf/Documentation/perf-data.txt b/tools/perf/Documentation/perf-data.txt index f0796a47dfa3..90bb4aabe4f8 100644 --- a/tools/perf/Documentation/perf-data.txt +++ b/tools/perf/Documentation/perf-data.txt | |||
| @@ -30,6 +30,10 @@ OPTIONS for 'convert' | |||
| 30 | -i:: | 30 | -i:: |
| 31 | Specify input perf data file path. | 31 | Specify input perf data file path. |
| 32 | 32 | ||
| 33 | -f:: | ||
| 34 | --force:: | ||
| 35 | Don't complain, do it. | ||
| 36 | |||
| 33 | -v:: | 37 | -v:: |
| 34 | --verbose:: | 38 | --verbose:: |
| 35 | Be more verbose (show counter open errors, etc). | 39 | Be more verbose (show counter open errors, etc). |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 9b0351d3ce34..012328038594 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -146,12 +146,6 @@ define allow-override | |||
| 146 | $(eval $(1) = $(2))) | 146 | $(eval $(1) = $(2))) |
| 147 | endef | 147 | endef |
| 148 | 148 | ||
| 149 | # Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix. | ||
| 150 | $(call allow-override,CC,$(CROSS_COMPILE)gcc) | ||
| 151 | $(call allow-override,AR,$(CROSS_COMPILE)ar) | ||
| 152 | $(call allow-override,LD,$(CROSS_COMPILE)ld) | ||
| 153 | $(call allow-override,CXX,$(CROSS_COMPILE)g++) | ||
| 154 | |||
| 155 | LD += $(EXTRA_LDFLAGS) | 149 | LD += $(EXTRA_LDFLAGS) |
| 156 | 150 | ||
| 157 | HOSTCC ?= gcc | 151 | HOSTCC ?= gcc |
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile index 48228de415d0..dfa6e3103437 100644 --- a/tools/perf/arch/s390/Makefile +++ b/tools/perf/arch/s390/Makefile | |||
| @@ -10,15 +10,19 @@ PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 | |||
| 10 | 10 | ||
| 11 | out := $(OUTPUT)arch/s390/include/generated/asm | 11 | out := $(OUTPUT)arch/s390/include/generated/asm |
| 12 | header := $(out)/syscalls_64.c | 12 | header := $(out)/syscalls_64.c |
| 13 | sysdef := $(srctree)/tools/arch/s390/include/uapi/asm/unistd.h | 13 | syskrn := $(srctree)/arch/s390/kernel/syscalls/syscall.tbl |
| 14 | sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls/ | 14 | sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls |
| 15 | sysdef := $(sysprf)/syscall.tbl | ||
| 15 | systbl := $(sysprf)/mksyscalltbl | 16 | systbl := $(sysprf)/mksyscalltbl |
| 16 | 17 | ||
| 17 | # Create output directory if not already present | 18 | # Create output directory if not already present |
| 18 | _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') | 19 | _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') |
| 19 | 20 | ||
| 20 | $(header): $(sysdef) $(systbl) | 21 | $(header): $(sysdef) $(systbl) |
| 21 | $(Q)$(SHELL) '$(systbl)' '$(CC)' $(sysdef) > $@ | 22 | @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ |
| 23 | (diff -B $(sysdef) $(syskrn) >/dev/null) \ | ||
| 24 | || echo "Warning: Kernel ABI header at '$(sysdef)' differs from latest version at '$(syskrn)'" >&2 )) || true | ||
| 25 | $(Q)$(SHELL) '$(systbl)' $(sysdef) > $@ | ||
| 22 | 26 | ||
| 23 | clean:: | 27 | clean:: |
| 24 | $(call QUIET_CLEAN, s390) $(RM) $(header) | 28 | $(call QUIET_CLEAN, s390) $(RM) $(header) |
diff --git a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl index 7fa0d0abd419..72ecbb676370 100755 --- a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl +++ b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl | |||
| @@ -3,25 +3,23 @@ | |||
| 3 | # | 3 | # |
| 4 | # Generate system call table for perf | 4 | # Generate system call table for perf |
| 5 | # | 5 | # |
| 6 | # | 6 | # Copyright IBM Corp. 2017, 2018 |
| 7 | # Copyright IBM Corp. 2017 | ||
| 8 | # Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 7 | # Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> |
| 9 | # | 8 | # |
| 10 | 9 | ||
| 11 | gcc=$1 | 10 | SYSCALL_TBL=$1 |
| 12 | input=$2 | ||
| 13 | 11 | ||
| 14 | if ! test -r $input; then | 12 | if ! test -r $SYSCALL_TBL; then |
| 15 | echo "Could not read input file" >&2 | 13 | echo "Could not read input file" >&2 |
| 16 | exit 1 | 14 | exit 1 |
| 17 | fi | 15 | fi |
| 18 | 16 | ||
| 19 | create_table() | 17 | create_table() |
| 20 | { | 18 | { |
| 21 | local max_nr | 19 | local max_nr nr abi sc discard |
| 22 | 20 | ||
| 23 | echo 'static const char *syscalltbl_s390_64[] = {' | 21 | echo 'static const char *syscalltbl_s390_64[] = {' |
| 24 | while read sc nr; do | 22 | while read nr abi sc discard; do |
| 25 | printf '\t[%d] = "%s",\n' $nr $sc | 23 | printf '\t[%d] = "%s",\n' $nr $sc |
| 26 | max_nr=$nr | 24 | max_nr=$nr |
| 27 | done | 25 | done |
| @@ -29,8 +27,6 @@ create_table() | |||
| 29 | echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr" | 27 | echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr" |
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | 30 | grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL \ | |
| 33 | $gcc -m64 -E -dM -x c $input \ | 31 | |sort -k1 -n \ |
| 34 | |sed -ne 's/^#define __NR_//p' \ | ||
| 35 | |sort -t' ' -k2 -nu \ | ||
| 36 | |create_table | 32 | |create_table |
diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl new file mode 100644 index 000000000000..b38d48464368 --- /dev/null +++ b/tools/perf/arch/s390/entry/syscalls/syscall.tbl | |||
| @@ -0,0 +1,390 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note | ||
| 2 | # | ||
| 3 | # System call table for s390 | ||
| 4 | # | ||
| 5 | # Format: | ||
| 6 | # | ||
| 7 | # <nr> <abi> <syscall> <entry-64bit> <compat-entry> | ||
| 8 | # | ||
| 9 | # where <abi> can be common, 64, or 32 | ||
| 10 | |||
| 11 | 1 common exit sys_exit sys_exit | ||
| 12 | 2 common fork sys_fork sys_fork | ||
| 13 | 3 common read sys_read compat_sys_s390_read | ||
| 14 | 4 common write sys_write compat_sys_s390_write | ||
| 15 | 5 common open sys_open compat_sys_open | ||
| 16 | 6 common close sys_close sys_close | ||
| 17 | 7 common restart_syscall sys_restart_syscall sys_restart_syscall | ||
| 18 | 8 common creat sys_creat compat_sys_creat | ||
| 19 | 9 common link sys_link compat_sys_link | ||
| 20 | 10 common unlink sys_unlink compat_sys_unlink | ||
| 21 | 11 common execve sys_execve compat_sys_execve | ||
| 22 | 12 common chdir sys_chdir compat_sys_chdir | ||
| 23 | 13 32 time - compat_sys_time | ||
| 24 | 14 common mknod sys_mknod compat_sys_mknod | ||
| 25 | 15 common chmod sys_chmod compat_sys_chmod | ||
| 26 | 16 32 lchown - compat_sys_s390_lchown16 | ||
| 27 | 19 common lseek sys_lseek compat_sys_lseek | ||
| 28 | 20 common getpid sys_getpid sys_getpid | ||
| 29 | 21 common mount sys_mount compat_sys_mount | ||
| 30 | 22 common umount sys_oldumount compat_sys_oldumount | ||
| 31 | 23 32 setuid - compat_sys_s390_setuid16 | ||
| 32 | 24 32 getuid - compat_sys_s390_getuid16 | ||
| 33 | 25 32 stime - compat_sys_stime | ||
| 34 | 26 common ptrace sys_ptrace compat_sys_ptrace | ||
| 35 | 27 common alarm sys_alarm sys_alarm | ||
| 36 | 29 common pause sys_pause sys_pause | ||
| 37 | 30 common utime sys_utime compat_sys_utime | ||
| 38 | 33 common access sys_access compat_sys_access | ||
| 39 | 34 common nice sys_nice sys_nice | ||
| 40 | 36 common sync sys_sync sys_sync | ||
| 41 | 37 common kill sys_kill sys_kill | ||
| 42 | 38 common rename sys_rename compat_sys_rename | ||
| 43 | 39 common mkdir sys_mkdir compat_sys_mkdir | ||
| 44 | 40 common rmdir sys_rmdir compat_sys_rmdir | ||
| 45 | 41 common dup sys_dup sys_dup | ||
| 46 | 42 common pipe sys_pipe compat_sys_pipe | ||
| 47 | 43 common times sys_times compat_sys_times | ||
| 48 | 45 common brk sys_brk compat_sys_brk | ||
| 49 | 46 32 setgid - compat_sys_s390_setgid16 | ||
| 50 | 47 32 getgid - compat_sys_s390_getgid16 | ||
| 51 | 48 common signal sys_signal compat_sys_signal | ||
| 52 | 49 32 geteuid - compat_sys_s390_geteuid16 | ||
| 53 | 50 32 getegid - compat_sys_s390_getegid16 | ||
| 54 | 51 common acct sys_acct compat_sys_acct | ||
| 55 | 52 common umount2 sys_umount compat_sys_umount | ||
| 56 | 54 common ioctl sys_ioctl compat_sys_ioctl | ||
| 57 | 55 common fcntl sys_fcntl compat_sys_fcntl | ||
| 58 | 57 common setpgid sys_setpgid sys_setpgid | ||
| 59 | 60 common umask sys_umask sys_umask | ||
| 60 | 61 common chroot sys_chroot compat_sys_chroot | ||
| 61 | 62 common ustat sys_ustat compat_sys_ustat | ||
| 62 | 63 common dup2 sys_dup2 sys_dup2 | ||
| 63 | 64 common getppid sys_getppid sys_getppid | ||
| 64 | 65 common getpgrp sys_getpgrp sys_getpgrp | ||
| 65 | 66 common setsid sys_setsid sys_setsid | ||
| 66 | 67 common sigaction sys_sigaction compat_sys_sigaction | ||
| 67 | 70 32 setreuid - compat_sys_s390_setreuid16 | ||
| 68 | 71 32 setregid - compat_sys_s390_setregid16 | ||
| 69 | 72 common sigsuspend sys_sigsuspend compat_sys_sigsuspend | ||
| 70 | 73 common sigpending sys_sigpending compat_sys_sigpending | ||
| 71 | 74 common sethostname sys_sethostname compat_sys_sethostname | ||
| 72 | 75 common setrlimit sys_setrlimit compat_sys_setrlimit | ||
| 73 | 76 32 getrlimit - compat_sys_old_getrlimit | ||
| 74 | 77 common getrusage sys_getrusage compat_sys_getrusage | ||
| 75 | 78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday | ||
| 76 | 79 common settimeofday sys_settimeofday compat_sys_settimeofday | ||
| 77 | 80 32 getgroups - compat_sys_s390_getgroups16 | ||
| 78 | 81 32 setgroups - compat_sys_s390_setgroups16 | ||
| 79 | 83 common symlink sys_symlink compat_sys_symlink | ||
| 80 | 85 common readlink sys_readlink compat_sys_readlink | ||
| 81 | 86 common uselib sys_uselib compat_sys_uselib | ||
| 82 | 87 common swapon sys_swapon compat_sys_swapon | ||
| 83 | 88 common reboot sys_reboot compat_sys_reboot | ||
| 84 | 89 common readdir - compat_sys_old_readdir | ||
| 85 | 90 common mmap sys_old_mmap compat_sys_s390_old_mmap | ||
| 86 | 91 common munmap sys_munmap compat_sys_munmap | ||
| 87 | 92 common truncate sys_truncate compat_sys_truncate | ||
| 88 | 93 common ftruncate sys_ftruncate compat_sys_ftruncate | ||
| 89 | 94 common fchmod sys_fchmod sys_fchmod | ||
| 90 | 95 32 fchown - compat_sys_s390_fchown16 | ||
| 91 | 96 common getpriority sys_getpriority sys_getpriority | ||
| 92 | 97 common setpriority sys_setpriority sys_setpriority | ||
| 93 | 99 common statfs sys_statfs compat_sys_statfs | ||
| 94 | 100 common fstatfs sys_fstatfs compat_sys_fstatfs | ||
| 95 | 101 32 ioperm - - | ||
| 96 | 102 common socketcall sys_socketcall compat_sys_socketcall | ||
| 97 | 103 common syslog sys_syslog compat_sys_syslog | ||
| 98 | 104 common setitimer sys_setitimer compat_sys_setitimer | ||
| 99 | 105 common getitimer sys_getitimer compat_sys_getitimer | ||
| 100 | 106 common stat sys_newstat compat_sys_newstat | ||
| 101 | 107 common lstat sys_newlstat compat_sys_newlstat | ||
| 102 | 108 common fstat sys_newfstat compat_sys_newfstat | ||
| 103 | 110 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie | ||
| 104 | 111 common vhangup sys_vhangup sys_vhangup | ||
| 105 | 112 common idle - - | ||
| 106 | 114 common wait4 sys_wait4 compat_sys_wait4 | ||
| 107 | 115 common swapoff sys_swapoff compat_sys_swapoff | ||
| 108 | 116 common sysinfo sys_sysinfo compat_sys_sysinfo | ||
| 109 | 117 common ipc sys_s390_ipc compat_sys_s390_ipc | ||
| 110 | 118 common fsync sys_fsync sys_fsync | ||
| 111 | 119 common sigreturn sys_sigreturn compat_sys_sigreturn | ||
| 112 | 120 common clone sys_clone compat_sys_clone | ||
| 113 | 121 common setdomainname sys_setdomainname compat_sys_setdomainname | ||
| 114 | 122 common uname sys_newuname compat_sys_newuname | ||
| 115 | 124 common adjtimex sys_adjtimex compat_sys_adjtimex | ||
| 116 | 125 common mprotect sys_mprotect compat_sys_mprotect | ||
| 117 | 126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask | ||
| 118 | 127 common create_module - - | ||
| 119 | 128 common init_module sys_init_module compat_sys_init_module | ||
| 120 | 129 common delete_module sys_delete_module compat_sys_delete_module | ||
| 121 | 130 common get_kernel_syms - - | ||
| 122 | 131 common quotactl sys_quotactl compat_sys_quotactl | ||
| 123 | 132 common getpgid sys_getpgid sys_getpgid | ||
| 124 | 133 common fchdir sys_fchdir sys_fchdir | ||
| 125 | 134 common bdflush sys_bdflush compat_sys_bdflush | ||
| 126 | 135 common sysfs sys_sysfs compat_sys_sysfs | ||
| 127 | 136 common personality sys_s390_personality sys_s390_personality | ||
| 128 | 137 common afs_syscall - - | ||
| 129 | 138 32 setfsuid - compat_sys_s390_setfsuid16 | ||
| 130 | 139 32 setfsgid - compat_sys_s390_setfsgid16 | ||
| 131 | 140 32 _llseek - compat_sys_llseek | ||
| 132 | 141 common getdents sys_getdents compat_sys_getdents | ||
| 133 | 142 32 _newselect - compat_sys_select | ||
| 134 | 142 64 select sys_select - | ||
| 135 | 143 common flock sys_flock sys_flock | ||
| 136 | 144 common msync sys_msync compat_sys_msync | ||
| 137 | 145 common readv sys_readv compat_sys_readv | ||
| 138 | 146 common writev sys_writev compat_sys_writev | ||
| 139 | 147 common getsid sys_getsid sys_getsid | ||
| 140 | 148 common fdatasync sys_fdatasync sys_fdatasync | ||
| 141 | 149 common _sysctl sys_sysctl compat_sys_sysctl | ||
| 142 | 150 common mlock sys_mlock compat_sys_mlock | ||
| 143 | 151 common munlock sys_munlock compat_sys_munlock | ||
| 144 | 152 common mlockall sys_mlockall sys_mlockall | ||
| 145 | 153 common munlockall sys_munlockall sys_munlockall | ||
| 146 | 154 common sched_setparam sys_sched_setparam compat_sys_sched_setparam | ||
| 147 | 155 common sched_getparam sys_sched_getparam compat_sys_sched_getparam | ||
| 148 | 156 common sched_setscheduler sys_sched_setscheduler compat_sys_sched_setscheduler | ||
| 149 | 157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler | ||
| 150 | 158 common sched_yield sys_sched_yield sys_sched_yield | ||
| 151 | 159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max | ||
| 152 | 160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min | ||
| 153 | 161 common sched_rr_get_interval sys_sched_rr_get_interval compat_sys_sched_rr_get_interval | ||
| 154 | 162 common nanosleep sys_nanosleep compat_sys_nanosleep | ||
| 155 | 163 common mremap sys_mremap compat_sys_mremap | ||
| 156 | 164 32 setresuid - compat_sys_s390_setresuid16 | ||
| 157 | 165 32 getresuid - compat_sys_s390_getresuid16 | ||
| 158 | 167 common query_module - - | ||
| 159 | 168 common poll sys_poll compat_sys_poll | ||
| 160 | 169 common nfsservctl - - | ||
| 161 | 170 32 setresgid - compat_sys_s390_setresgid16 | ||
| 162 | 171 32 getresgid - compat_sys_s390_getresgid16 | ||
| 163 | 172 common prctl sys_prctl compat_sys_prctl | ||
| 164 | 173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn | ||
| 165 | 174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction | ||
| 166 | 175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask | ||
| 167 | 176 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending | ||
| 168 | 177 common rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait | ||
| 169 | 178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo | ||
| 170 | 179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend | ||
| 171 | 180 common pread64 sys_pread64 compat_sys_s390_pread64 | ||
| 172 | 181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64 | ||
| 173 | 182 32 chown - compat_sys_s390_chown16 | ||
| 174 | 183 common getcwd sys_getcwd compat_sys_getcwd | ||
| 175 | 184 common capget sys_capget compat_sys_capget | ||
| 176 | 185 common capset sys_capset compat_sys_capset | ||
| 177 | 186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack | ||
| 178 | 187 common sendfile sys_sendfile64 compat_sys_sendfile | ||
| 179 | 188 common getpmsg - - | ||
| 180 | 189 common putpmsg - - | ||
| 181 | 190 common vfork sys_vfork sys_vfork | ||
| 182 | 191 32 ugetrlimit - compat_sys_getrlimit | ||
| 183 | 191 64 getrlimit sys_getrlimit - | ||
| 184 | 192 32 mmap2 - compat_sys_s390_mmap2 | ||
| 185 | 193 32 truncate64 - compat_sys_s390_truncate64 | ||
| 186 | 194 32 ftruncate64 - compat_sys_s390_ftruncate64 | ||
| 187 | 195 32 stat64 - compat_sys_s390_stat64 | ||
| 188 | 196 32 lstat64 - compat_sys_s390_lstat64 | ||
| 189 | 197 32 fstat64 - compat_sys_s390_fstat64 | ||
| 190 | 198 32 lchown32 - compat_sys_lchown | ||
| 191 | 198 64 lchown sys_lchown - | ||
| 192 | 199 32 getuid32 - sys_getuid | ||
| 193 | 199 64 getuid sys_getuid - | ||
| 194 | 200 32 getgid32 - sys_getgid | ||
| 195 | 200 64 getgid sys_getgid - | ||
| 196 | 201 32 geteuid32 - sys_geteuid | ||
| 197 | 201 64 geteuid sys_geteuid - | ||
| 198 | 202 32 getegid32 - sys_getegid | ||
| 199 | 202 64 getegid sys_getegid - | ||
| 200 | 203 32 setreuid32 - sys_setreuid | ||
| 201 | 203 64 setreuid sys_setreuid - | ||
| 202 | 204 32 setregid32 - sys_setregid | ||
| 203 | 204 64 setregid sys_setregid - | ||
| 204 | 205 32 getgroups32 - compat_sys_getgroups | ||
| 205 | 205 64 getgroups sys_getgroups - | ||
| 206 | 206 32 setgroups32 - compat_sys_setgroups | ||
| 207 | 206 64 setgroups sys_setgroups - | ||
| 208 | 207 32 fchown32 - sys_fchown | ||
| 209 | 207 64 fchown sys_fchown - | ||
| 210 | 208 32 setresuid32 - sys_setresuid | ||
| 211 | 208 64 setresuid sys_setresuid - | ||
| 212 | 209 32 getresuid32 - compat_sys_getresuid | ||
| 213 | 209 64 getresuid sys_getresuid - | ||
| 214 | 210 32 setresgid32 - sys_setresgid | ||
| 215 | 210 64 setresgid sys_setresgid - | ||
| 216 | 211 32 getresgid32 - compat_sys_getresgid | ||
| 217 | 211 64 getresgid sys_getresgid - | ||
| 218 | 212 32 chown32 - compat_sys_chown | ||
| 219 | 212 64 chown sys_chown - | ||
| 220 | 213 32 setuid32 - sys_setuid | ||
| 221 | 213 64 setuid sys_setuid - | ||
| 222 | 214 32 setgid32 - sys_setgid | ||
| 223 | 214 64 setgid sys_setgid - | ||
| 224 | 215 32 setfsuid32 - sys_setfsuid | ||
| 225 | 215 64 setfsuid sys_setfsuid - | ||
| 226 | 216 32 setfsgid32 - sys_setfsgid | ||
| 227 | 216 64 setfsgid sys_setfsgid - | ||
| 228 | 217 common pivot_root sys_pivot_root compat_sys_pivot_root | ||
| 229 | 218 common mincore sys_mincore compat_sys_mincore | ||
| 230 | 219 common madvise sys_madvise compat_sys_madvise | ||
| 231 | 220 common getdents64 sys_getdents64 compat_sys_getdents64 | ||
| 232 | 221 32 fcntl64 - compat_sys_fcntl64 | ||
| 233 | 222 common readahead sys_readahead compat_sys_s390_readahead | ||
| 234 | 223 32 sendfile64 - compat_sys_sendfile64 | ||
| 235 | 224 common setxattr sys_setxattr compat_sys_setxattr | ||
| 236 | 225 common lsetxattr sys_lsetxattr compat_sys_lsetxattr | ||
| 237 | 226 common fsetxattr sys_fsetxattr compat_sys_fsetxattr | ||
| 238 | 227 common getxattr sys_getxattr compat_sys_getxattr | ||
| 239 | 228 common lgetxattr sys_lgetxattr compat_sys_lgetxattr | ||
| 240 | 229 common fgetxattr sys_fgetxattr compat_sys_fgetxattr | ||
| 241 | 230 common listxattr sys_listxattr compat_sys_listxattr | ||
| 242 | 231 common llistxattr sys_llistxattr compat_sys_llistxattr | ||
| 243 | 232 common flistxattr sys_flistxattr compat_sys_flistxattr | ||
| 244 | 233 common removexattr sys_removexattr compat_sys_removexattr | ||
| 245 | 234 common lremovexattr sys_lremovexattr compat_sys_lremovexattr | ||
| 246 | 235 common fremovexattr sys_fremovexattr compat_sys_fremovexattr | ||
| 247 | 236 common gettid sys_gettid sys_gettid | ||
| 248 | 237 common tkill sys_tkill sys_tkill | ||
| 249 | 238 common futex sys_futex compat_sys_futex | ||
| 250 | 239 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity | ||
| 251 | 240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity | ||
| 252 | 241 common tgkill sys_tgkill sys_tgkill | ||
| 253 | 243 common io_setup sys_io_setup compat_sys_io_setup | ||
| 254 | 244 common io_destroy sys_io_destroy compat_sys_io_destroy | ||
| 255 | 245 common io_getevents sys_io_getevents compat_sys_io_getevents | ||
| 256 | 246 common io_submit sys_io_submit compat_sys_io_submit | ||
| 257 | 247 common io_cancel sys_io_cancel compat_sys_io_cancel | ||
| 258 | 248 common exit_group sys_exit_group sys_exit_group | ||
| 259 | 249 common epoll_create sys_epoll_create sys_epoll_create | ||
| 260 | 250 common epoll_ctl sys_epoll_ctl compat_sys_epoll_ctl | ||
| 261 | 251 common epoll_wait sys_epoll_wait compat_sys_epoll_wait | ||
| 262 | 252 common set_tid_address sys_set_tid_address compat_sys_set_tid_address | ||
| 263 | 253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64 | ||
| 264 | 254 common timer_create sys_timer_create compat_sys_timer_create | ||
| 265 | 255 common timer_settime sys_timer_settime compat_sys_timer_settime | ||
| 266 | 256 common timer_gettime sys_timer_gettime compat_sys_timer_gettime | ||
| 267 | 257 common timer_getoverrun sys_timer_getoverrun sys_timer_getoverrun | ||
| 268 | 258 common timer_delete sys_timer_delete sys_timer_delete | ||
| 269 | 259 common clock_settime sys_clock_settime compat_sys_clock_settime | ||
| 270 | 260 common clock_gettime sys_clock_gettime compat_sys_clock_gettime | ||
| 271 | 261 common clock_getres sys_clock_getres compat_sys_clock_getres | ||
| 272 | 262 common clock_nanosleep sys_clock_nanosleep compat_sys_clock_nanosleep | ||
| 273 | 264 32 fadvise64_64 - compat_sys_s390_fadvise64_64 | ||
| 274 | 265 common statfs64 sys_statfs64 compat_sys_statfs64 | ||
| 275 | 266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 | ||
| 276 | 267 common remap_file_pages sys_remap_file_pages compat_sys_remap_file_pages | ||
| 277 | 268 common mbind sys_mbind compat_sys_mbind | ||
| 278 | 269 common get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy | ||
| 279 | 270 common set_mempolicy sys_set_mempolicy compat_sys_set_mempolicy | ||
| 280 | 271 common mq_open sys_mq_open compat_sys_mq_open | ||
| 281 | 272 common mq_unlink sys_mq_unlink compat_sys_mq_unlink | ||
| 282 | 273 common mq_timedsend sys_mq_timedsend compat_sys_mq_timedsend | ||
| 283 | 274 common mq_timedreceive sys_mq_timedreceive compat_sys_mq_timedreceive | ||
| 284 | 275 common mq_notify sys_mq_notify compat_sys_mq_notify | ||
| 285 | 276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr | ||
| 286 | 277 common kexec_load sys_kexec_load compat_sys_kexec_load | ||
| 287 | 278 common add_key sys_add_key compat_sys_add_key | ||
| 288 | 279 common request_key sys_request_key compat_sys_request_key | ||
| 289 | 280 common keyctl sys_keyctl compat_sys_keyctl | ||
| 290 | 281 common waitid sys_waitid compat_sys_waitid | ||
| 291 | 282 common ioprio_set sys_ioprio_set sys_ioprio_set | ||
| 292 | 283 common ioprio_get sys_ioprio_get sys_ioprio_get | ||
| 293 | 284 common inotify_init sys_inotify_init sys_inotify_init | ||
| 294 | 285 common inotify_add_watch sys_inotify_add_watch compat_sys_inotify_add_watch | ||
| 295 | 286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch | ||
| 296 | 287 common migrate_pages sys_migrate_pages compat_sys_migrate_pages | ||
| 297 | 288 common openat sys_openat compat_sys_openat | ||
| 298 | 289 common mkdirat sys_mkdirat compat_sys_mkdirat | ||
| 299 | 290 common mknodat sys_mknodat compat_sys_mknodat | ||
| 300 | 291 common fchownat sys_fchownat compat_sys_fchownat | ||
| 301 | 292 common futimesat sys_futimesat compat_sys_futimesat | ||
| 302 | 293 32 fstatat64 - compat_sys_s390_fstatat64 | ||
| 303 | 293 64 newfstatat sys_newfstatat - | ||
| 304 | 294 common unlinkat sys_unlinkat compat_sys_unlinkat | ||
| 305 | 295 common renameat sys_renameat compat_sys_renameat | ||
| 306 | 296 common linkat sys_linkat compat_sys_linkat | ||
| 307 | 297 common symlinkat sys_symlinkat compat_sys_symlinkat | ||
| 308 | 298 common readlinkat sys_readlinkat compat_sys_readlinkat | ||
| 309 | 299 common fchmodat sys_fchmodat compat_sys_fchmodat | ||
| 310 | 300 common faccessat sys_faccessat compat_sys_faccessat | ||
| 311 | 301 common pselect6 sys_pselect6 compat_sys_pselect6 | ||
| 312 | 302 common ppoll sys_ppoll compat_sys_ppoll | ||
| 313 | 303 common unshare sys_unshare compat_sys_unshare | ||
| 314 | 304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list | ||
| 315 | 305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list | ||
| 316 | 306 common splice sys_splice compat_sys_splice | ||
| 317 | 307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range | ||
| 318 | 308 common tee sys_tee compat_sys_tee | ||
| 319 | 309 common vmsplice sys_vmsplice compat_sys_vmsplice | ||
| 320 | 310 common move_pages sys_move_pages compat_sys_move_pages | ||
| 321 | 311 common getcpu sys_getcpu compat_sys_getcpu | ||
| 322 | 312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait | ||
| 323 | 313 common utimes sys_utimes compat_sys_utimes | ||
| 324 | 314 common fallocate sys_fallocate compat_sys_s390_fallocate | ||
| 325 | 315 common utimensat sys_utimensat compat_sys_utimensat | ||
| 326 | 316 common signalfd sys_signalfd compat_sys_signalfd | ||
| 327 | 317 common timerfd - - | ||
| 328 | 318 common eventfd sys_eventfd sys_eventfd | ||
| 329 | 319 common timerfd_create sys_timerfd_create sys_timerfd_create | ||
| 330 | 320 common timerfd_settime sys_timerfd_settime compat_sys_timerfd_settime | ||
| 331 | 321 common timerfd_gettime sys_timerfd_gettime compat_sys_timerfd_gettime | ||
| 332 | 322 common signalfd4 sys_signalfd4 compat_sys_signalfd4 | ||
| 333 | 323 common eventfd2 sys_eventfd2 sys_eventfd2 | ||
| 334 | 324 common inotify_init1 sys_inotify_init1 sys_inotify_init1 | ||
| 335 | 325 common pipe2 sys_pipe2 compat_sys_pipe2 | ||
| 336 | 326 common dup3 sys_dup3 sys_dup3 | ||
| 337 | 327 common epoll_create1 sys_epoll_create1 sys_epoll_create1 | ||
| 338 | 328 common preadv sys_preadv compat_sys_preadv | ||
| 339 | 329 common pwritev sys_pwritev compat_sys_pwritev | ||
| 340 | 330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo | ||
| 341 | 331 common perf_event_open sys_perf_event_open compat_sys_perf_event_open | ||
| 342 | 332 common fanotify_init sys_fanotify_init sys_fanotify_init | ||
| 343 | 333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark | ||
| 344 | 334 common prlimit64 sys_prlimit64 compat_sys_prlimit64 | ||
| 345 | 335 common name_to_handle_at sys_name_to_handle_at compat_sys_name_to_handle_at | ||
| 346 | 336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at | ||
| 347 | 337 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime | ||
| 348 | 338 common syncfs sys_syncfs sys_syncfs | ||
| 349 | 339 common setns sys_setns sys_setns | ||
| 350 | 340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv | ||
| 351 | 341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev | ||
| 352 | 342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr | ||
| 353 | 343 common kcmp sys_kcmp compat_sys_kcmp | ||
| 354 | 344 common finit_module sys_finit_module compat_sys_finit_module | ||
| 355 | 345 common sched_setattr sys_sched_setattr compat_sys_sched_setattr | ||
| 356 | 346 common sched_getattr sys_sched_getattr compat_sys_sched_getattr | ||
| 357 | 347 common renameat2 sys_renameat2 compat_sys_renameat2 | ||
| 358 | 348 common seccomp sys_seccomp compat_sys_seccomp | ||
| 359 | 349 common getrandom sys_getrandom compat_sys_getrandom | ||
| 360 | 350 common memfd_create sys_memfd_create compat_sys_memfd_create | ||
| 361 | 351 common bpf sys_bpf compat_sys_bpf | ||
| 362 | 352 common s390_pci_mmio_write sys_s390_pci_mmio_write compat_sys_s390_pci_mmio_write | ||
| 363 | 353 common s390_pci_mmio_read sys_s390_pci_mmio_read compat_sys_s390_pci_mmio_read | ||
| 364 | 354 common execveat sys_execveat compat_sys_execveat | ||
| 365 | 355 common userfaultfd sys_userfaultfd sys_userfaultfd | ||
| 366 | 356 common membarrier sys_membarrier sys_membarrier | ||
| 367 | 357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg | ||
| 368 | 358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg | ||
| 369 | 359 common socket sys_socket sys_socket | ||
| 370 | 360 common socketpair sys_socketpair compat_sys_socketpair | ||
| 371 | 361 common bind sys_bind compat_sys_bind | ||
| 372 | 362 common connect sys_connect compat_sys_connect | ||
| 373 | 363 common listen sys_listen sys_listen | ||
| 374 | 364 common accept4 sys_accept4 compat_sys_accept4 | ||
| 375 | 365 common getsockopt sys_getsockopt compat_sys_getsockopt | ||
| 376 | 366 common setsockopt sys_setsockopt compat_sys_setsockopt | ||
| 377 | 367 common getsockname sys_getsockname compat_sys_getsockname | ||
| 378 | 368 common getpeername sys_getpeername compat_sys_getpeername | ||
| 379 | 369 common sendto sys_sendto compat_sys_sendto | ||
| 380 | 370 common sendmsg sys_sendmsg compat_sys_sendmsg | ||
| 381 | 371 common recvfrom sys_recvfrom compat_sys_recvfrom | ||
| 382 | 372 common recvmsg sys_recvmsg compat_sys_recvmsg | ||
| 383 | 373 common shutdown sys_shutdown sys_shutdown | ||
| 384 | 374 common mlock2 sys_mlock2 compat_sys_mlock2 | ||
| 385 | 375 common copy_file_range sys_copy_file_range compat_sys_copy_file_range | ||
| 386 | 376 common preadv2 sys_preadv2 compat_sys_preadv2 | ||
| 387 | 377 common pwritev2 sys_pwritev2 compat_sys_pwritev2 | ||
| 388 | 378 common s390_guarded_storage sys_s390_guarded_storage compat_sys_s390_guarded_storage | ||
| 389 | 379 common statx sys_statx compat_sys_statx | ||
| 390 | 380 common s390_sthyi sys_s390_sthyi compat_sys_s390_sthyi | ||
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index c0815a37fdb5..539c3d460158 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
| @@ -2245,7 +2245,7 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he) | |||
| 2245 | c2c_browser__update_nr_entries(browser); | 2245 | c2c_browser__update_nr_entries(browser); |
| 2246 | 2246 | ||
| 2247 | while (1) { | 2247 | while (1) { |
| 2248 | key = hist_browser__run(browser, "? - help"); | 2248 | key = hist_browser__run(browser, "? - help", true); |
| 2249 | 2249 | ||
| 2250 | switch (key) { | 2250 | switch (key) { |
| 2251 | case 's': | 2251 | case 's': |
| @@ -2314,7 +2314,7 @@ static int perf_c2c__hists_browse(struct hists *hists) | |||
| 2314 | c2c_browser__update_nr_entries(browser); | 2314 | c2c_browser__update_nr_entries(browser); |
| 2315 | 2315 | ||
| 2316 | while (1) { | 2316 | while (1) { |
| 2317 | key = hist_browser__run(browser, "? - help"); | 2317 | key = hist_browser__run(browser, "? - help", true); |
| 2318 | 2318 | ||
| 2319 | switch (key) { | 2319 | switch (key) { |
| 2320 | case 'q': | 2320 | case 'q': |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 42a52dcc41cd..4ad5dc649716 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -530,7 +530,8 @@ static int report__browse_hists(struct report *rep) | |||
| 530 | case 1: | 530 | case 1: |
| 531 | ret = perf_evlist__tui_browse_hists(evlist, help, NULL, | 531 | ret = perf_evlist__tui_browse_hists(evlist, help, NULL, |
| 532 | rep->min_percent, | 532 | rep->min_percent, |
| 533 | &session->header.env); | 533 | &session->header.env, |
| 534 | true); | ||
| 534 | /* | 535 | /* |
| 535 | * Usually "ret" is the last pressed key, and we only | 536 | * Usually "ret" is the last pressed key, and we only |
| 536 | * care if the key notifies us to switch data file. | 537 | * care if the key notifies us to switch data file. |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c6ccda52117d..b7c823ba8374 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -283,8 +283,9 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
| 283 | 283 | ||
| 284 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 284 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
| 285 | 285 | ||
| 286 | if (hists->stats.nr_lost_warned != | 286 | if (!top->record_opts.overwrite && |
| 287 | hists->stats.nr_events[PERF_RECORD_LOST]) { | 287 | (hists->stats.nr_lost_warned != |
| 288 | hists->stats.nr_events[PERF_RECORD_LOST])) { | ||
| 288 | hists->stats.nr_lost_warned = | 289 | hists->stats.nr_lost_warned = |
| 289 | hists->stats.nr_events[PERF_RECORD_LOST]; | 290 | hists->stats.nr_events[PERF_RECORD_LOST]; |
| 290 | color_fprintf(stdout, PERF_COLOR_RED, | 291 | color_fprintf(stdout, PERF_COLOR_RED, |
| @@ -611,7 +612,8 @@ static void *display_thread_tui(void *arg) | |||
| 611 | 612 | ||
| 612 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, | 613 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, |
| 613 | top->min_percent, | 614 | top->min_percent, |
| 614 | &top->session->header.env); | 615 | &top->session->header.env, |
| 616 | !top->record_opts.overwrite); | ||
| 615 | 617 | ||
| 616 | done = 1; | 618 | done = 1; |
| 617 | return NULL; | 619 | return NULL; |
| @@ -807,15 +809,23 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 807 | 809 | ||
| 808 | static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | 810 | static void perf_top__mmap_read_idx(struct perf_top *top, int idx) |
| 809 | { | 811 | { |
| 812 | struct record_opts *opts = &top->record_opts; | ||
| 813 | struct perf_evlist *evlist = top->evlist; | ||
| 810 | struct perf_sample sample; | 814 | struct perf_sample sample; |
| 811 | struct perf_evsel *evsel; | 815 | struct perf_evsel *evsel; |
| 816 | struct perf_mmap *md; | ||
| 812 | struct perf_session *session = top->session; | 817 | struct perf_session *session = top->session; |
| 813 | union perf_event *event; | 818 | union perf_event *event; |
| 814 | struct machine *machine; | 819 | struct machine *machine; |
| 820 | u64 end, start; | ||
| 815 | int ret; | 821 | int ret; |
| 816 | 822 | ||
| 817 | while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { | 823 | md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx]; |
| 818 | ret = perf_evlist__parse_sample(top->evlist, event, &sample); | 824 | if (perf_mmap__read_init(md, opts->overwrite, &start, &end) < 0) |
| 825 | return; | ||
| 826 | |||
| 827 | while ((event = perf_mmap__read_event(md, opts->overwrite, &start, end)) != NULL) { | ||
| 828 | ret = perf_evlist__parse_sample(evlist, event, &sample); | ||
| 819 | if (ret) { | 829 | if (ret) { |
| 820 | pr_err("Can't parse sample, err = %d\n", ret); | 830 | pr_err("Can't parse sample, err = %d\n", ret); |
| 821 | goto next_event; | 831 | goto next_event; |
| @@ -869,16 +879,120 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 869 | } else | 879 | } else |
| 870 | ++session->evlist->stats.nr_unknown_events; | 880 | ++session->evlist->stats.nr_unknown_events; |
| 871 | next_event: | 881 | next_event: |
| 872 | perf_evlist__mmap_consume(top->evlist, idx); | 882 | perf_mmap__consume(md, opts->overwrite); |
| 873 | } | 883 | } |
| 884 | |||
| 885 | perf_mmap__read_done(md); | ||
| 874 | } | 886 | } |
| 875 | 887 | ||
| 876 | static void perf_top__mmap_read(struct perf_top *top) | 888 | static void perf_top__mmap_read(struct perf_top *top) |
| 877 | { | 889 | { |
| 890 | bool overwrite = top->record_opts.overwrite; | ||
| 891 | struct perf_evlist *evlist = top->evlist; | ||
| 892 | unsigned long long start, end; | ||
| 878 | int i; | 893 | int i; |
| 879 | 894 | ||
| 895 | start = rdclock(); | ||
| 896 | if (overwrite) | ||
| 897 | perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING); | ||
| 898 | |||
| 880 | for (i = 0; i < top->evlist->nr_mmaps; i++) | 899 | for (i = 0; i < top->evlist->nr_mmaps; i++) |
| 881 | perf_top__mmap_read_idx(top, i); | 900 | perf_top__mmap_read_idx(top, i); |
| 901 | |||
| 902 | if (overwrite) { | ||
| 903 | perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); | ||
| 904 | perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); | ||
| 905 | } | ||
| 906 | end = rdclock(); | ||
| 907 | |||
| 908 | if ((end - start) > (unsigned long long)top->delay_secs * NSEC_PER_SEC) | ||
| 909 | ui__warning("Too slow to read ring buffer.\n" | ||
| 910 | "Please try increasing the period (-c) or\n" | ||
| 911 | "decreasing the freq (-F) or\n" | ||
| 912 | "limiting the number of CPUs (-C)\n"); | ||
| 913 | } | ||
| 914 | |||
| 915 | /* | ||
| 916 | * Check per-event overwrite term. | ||
| 917 | * perf top should support consistent term for all events. | ||
| 918 | * - All events don't have per-event term | ||
| 919 | * E.g. "cpu/cpu-cycles/,cpu/instructions/" | ||
| 920 | * Nothing change, return 0. | ||
| 921 | * - All events have same per-event term | ||
| 922 | * E.g. "cpu/cpu-cycles,no-overwrite/,cpu/instructions,no-overwrite/ | ||
| 923 | * Using the per-event setting to replace the opts->overwrite if | ||
| 924 | * they are different, then return 0. | ||
| 925 | * - Events have different per-event term | ||
| 926 | * E.g. "cpu/cpu-cycles,overwrite/,cpu/instructions,no-overwrite/" | ||
| 927 | * Return -1 | ||
| 928 | * - Some of the event set per-event term, but some not. | ||
| 929 | * E.g. "cpu/cpu-cycles/,cpu/instructions,no-overwrite/" | ||
| 930 | * Return -1 | ||
| 931 | */ | ||
| 932 | static int perf_top__overwrite_check(struct perf_top *top) | ||
| 933 | { | ||
| 934 | struct record_opts *opts = &top->record_opts; | ||
| 935 | struct perf_evlist *evlist = top->evlist; | ||
| 936 | struct perf_evsel_config_term *term; | ||
| 937 | struct list_head *config_terms; | ||
| 938 | struct perf_evsel *evsel; | ||
| 939 | int set, overwrite = -1; | ||
| 940 | |||
| 941 | evlist__for_each_entry(evlist, evsel) { | ||
| 942 | set = -1; | ||
| 943 | config_terms = &evsel->config_terms; | ||
| 944 | list_for_each_entry(term, config_terms, list) { | ||
| 945 | if (term->type == PERF_EVSEL__CONFIG_TERM_OVERWRITE) | ||
| 946 | set = term->val.overwrite ? 1 : 0; | ||
| 947 | } | ||
| 948 | |||
| 949 | /* no term for current and previous event (likely) */ | ||
| 950 | if ((overwrite < 0) && (set < 0)) | ||
| 951 | continue; | ||
| 952 | |||
| 953 | /* has term for both current and previous event, compare */ | ||
| 954 | if ((overwrite >= 0) && (set >= 0) && (overwrite != set)) | ||
| 955 | return -1; | ||
| 956 | |||
| 957 | /* no term for current event but has term for previous one */ | ||
| 958 | if ((overwrite >= 0) && (set < 0)) | ||
| 959 | return -1; | ||
| 960 | |||
| 961 | /* has term for current event */ | ||
| 962 | if ((overwrite < 0) && (set >= 0)) { | ||
| 963 | /* if it's first event, set overwrite */ | ||
| 964 | if (evsel == perf_evlist__first(evlist)) | ||
| 965 | overwrite = set; | ||
| 966 | else | ||
| 967 | return -1; | ||
| 968 | } | ||
| 969 | } | ||
| 970 | |||
| 971 | if ((overwrite >= 0) && (opts->overwrite != overwrite)) | ||
| 972 | opts->overwrite = overwrite; | ||
| 973 | |||
| 974 | return 0; | ||
| 975 | } | ||
| 976 | |||
| 977 | static int perf_top_overwrite_fallback(struct perf_top *top, | ||
| 978 | struct perf_evsel *evsel) | ||
| 979 | { | ||
| 980 | struct record_opts *opts = &top->record_opts; | ||
| 981 | struct perf_evlist *evlist = top->evlist; | ||
| 982 | struct perf_evsel *counter; | ||
| 983 | |||
| 984 | if (!opts->overwrite) | ||
| 985 | return 0; | ||
| 986 | |||
| 987 | /* only fall back when first event fails */ | ||
| 988 | if (evsel != perf_evlist__first(evlist)) | ||
| 989 | return 0; | ||
| 990 | |||
| 991 | evlist__for_each_entry(evlist, counter) | ||
| 992 | counter->attr.write_backward = false; | ||
| 993 | opts->overwrite = false; | ||
| 994 | ui__warning("fall back to non-overwrite mode\n"); | ||
| 995 | return 1; | ||
| 882 | } | 996 | } |
| 883 | 997 | ||
| 884 | static int perf_top__start_counters(struct perf_top *top) | 998 | static int perf_top__start_counters(struct perf_top *top) |
| @@ -888,12 +1002,33 @@ static int perf_top__start_counters(struct perf_top *top) | |||
| 888 | struct perf_evlist *evlist = top->evlist; | 1002 | struct perf_evlist *evlist = top->evlist; |
| 889 | struct record_opts *opts = &top->record_opts; | 1003 | struct record_opts *opts = &top->record_opts; |
| 890 | 1004 | ||
| 1005 | if (perf_top__overwrite_check(top)) { | ||
| 1006 | ui__error("perf top only support consistent per-event " | ||
| 1007 | "overwrite setting for all events\n"); | ||
| 1008 | goto out_err; | ||
| 1009 | } | ||
| 1010 | |||
| 891 | perf_evlist__config(evlist, opts, &callchain_param); | 1011 | perf_evlist__config(evlist, opts, &callchain_param); |
| 892 | 1012 | ||
| 893 | evlist__for_each_entry(evlist, counter) { | 1013 | evlist__for_each_entry(evlist, counter) { |
| 894 | try_again: | 1014 | try_again: |
| 895 | if (perf_evsel__open(counter, top->evlist->cpus, | 1015 | if (perf_evsel__open(counter, top->evlist->cpus, |
| 896 | top->evlist->threads) < 0) { | 1016 | top->evlist->threads) < 0) { |
| 1017 | |||
| 1018 | /* | ||
| 1019 | * Specially handle overwrite fall back. | ||
| 1020 | * Because perf top is the only tool which has | ||
| 1021 | * overwrite mode by default, support | ||
| 1022 | * both overwrite and non-overwrite mode, and | ||
| 1023 | * require consistent mode for all events. | ||
| 1024 | * | ||
| 1025 | * May move it to generic code with more tools | ||
| 1026 | * have similar attribute. | ||
| 1027 | */ | ||
| 1028 | if (perf_missing_features.write_backward && | ||
| 1029 | perf_top_overwrite_fallback(top, counter)) | ||
| 1030 | goto try_again; | ||
| 1031 | |||
| 897 | if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { | 1032 | if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { |
| 898 | if (verbose > 0) | 1033 | if (verbose > 0) |
| 899 | ui__warning("%s\n", msg); | 1034 | ui__warning("%s\n", msg); |
| @@ -1033,7 +1168,7 @@ static int __cmd_top(struct perf_top *top) | |||
| 1033 | 1168 | ||
| 1034 | perf_top__mmap_read(top); | 1169 | perf_top__mmap_read(top); |
| 1035 | 1170 | ||
| 1036 | if (hits == top->samples) | 1171 | if (opts->overwrite || (hits == top->samples)) |
| 1037 | ret = perf_evlist__poll(top->evlist, 100); | 1172 | ret = perf_evlist__poll(top->evlist, 100); |
| 1038 | 1173 | ||
| 1039 | if (resize) { | 1174 | if (resize) { |
| @@ -1127,6 +1262,7 @@ int cmd_top(int argc, const char **argv) | |||
| 1127 | .uses_mmap = true, | 1262 | .uses_mmap = true, |
| 1128 | }, | 1263 | }, |
| 1129 | .proc_map_timeout = 500, | 1264 | .proc_map_timeout = 500, |
| 1265 | .overwrite = 1, | ||
| 1130 | }, | 1266 | }, |
| 1131 | .max_stack = sysctl_perf_event_max_stack, | 1267 | .max_stack = sysctl_perf_event_max_stack, |
| 1132 | .sym_pcnt_filter = 5, | 1268 | .sym_pcnt_filter = 5, |
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 51abdb0a4047..790ec25919a0 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh | |||
| @@ -33,7 +33,6 @@ arch/s390/include/uapi/asm/kvm.h | |||
| 33 | arch/s390/include/uapi/asm/kvm_perf.h | 33 | arch/s390/include/uapi/asm/kvm_perf.h |
| 34 | arch/s390/include/uapi/asm/ptrace.h | 34 | arch/s390/include/uapi/asm/ptrace.h |
| 35 | arch/s390/include/uapi/asm/sie.h | 35 | arch/s390/include/uapi/asm/sie.h |
| 36 | arch/s390/include/uapi/asm/unistd.h | ||
| 37 | arch/arm/include/uapi/asm/kvm.h | 36 | arch/arm/include/uapi/asm/kvm.h |
| 38 | arch/arm64/include/uapi/asm/kvm.h | 37 | arch/arm64/include/uapi/asm/kvm.h |
| 39 | arch/alpha/include/uapi/asm/errno.h | 38 | arch/alpha/include/uapi/asm/errno.h |
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json new file mode 100644 index 000000000000..3b6208763e50 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0x7A", | ||
| 4 | "EventName": "BR_INDIRECT_SPEC", | ||
| 5 | "BriefDescription": "Branch speculatively executed - Indirect branch" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0xC9", | ||
| 9 | "EventName": "BR_COND", | ||
| 10 | "BriefDescription": "Conditional branch executed" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xCA", | ||
| 14 | "EventName": "BR_INDIRECT_MISPRED", | ||
| 15 | "BriefDescription": "Indirect branch mispredicted" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xCB", | ||
| 19 | "EventName": "BR_INDIRECT_MISPRED_ADDR", | ||
| 20 | "BriefDescription": "Indirect branch mispredicted because of address miscompare" | ||
| 21 | }, | ||
| 22 | {, | ||
| 23 | "EventCode": "0xCC", | ||
| 24 | "EventName": "BR_COND_MISPRED", | ||
| 25 | "BriefDescription": "Conditional branch mispredicted" | ||
| 26 | } | ||
| 27 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json new file mode 100644 index 000000000000..480d9f7460ab --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0x60", | ||
| 4 | "EventName": "BUS_ACCESS_LD", | ||
| 5 | "BriefDescription": "Bus access - Read" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0x61", | ||
| 9 | "EventName": "BUS_ACCESS_ST", | ||
| 10 | "BriefDescription": "Bus access - Write" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xC0", | ||
| 14 | "EventName": "EXT_MEM_REQ", | ||
| 15 | "BriefDescription": "External memory request" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xC1", | ||
| 19 | "EventName": "EXT_MEM_REQ_NC", | ||
| 20 | "BriefDescription": "Non-cacheable external memory request" | ||
| 21 | } | ||
| 22 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json new file mode 100644 index 000000000000..11baad6344b9 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0xC2", | ||
| 4 | "EventName": "PREFETCH_LINEFILL", | ||
| 5 | "BriefDescription": "Linefill because of prefetch" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0xC3", | ||
| 9 | "EventName": "PREFETCH_LINEFILL_DROP", | ||
| 10 | "BriefDescription": "Instruction Cache Throttle occurred" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xC4", | ||
| 14 | "EventName": "READ_ALLOC_ENTER", | ||
| 15 | "BriefDescription": "Entering read allocate mode" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xC5", | ||
| 19 | "EventName": "READ_ALLOC", | ||
| 20 | "BriefDescription": "Read allocate mode" | ||
| 21 | }, | ||
| 22 | {, | ||
| 23 | "EventCode": "0xC8", | ||
| 24 | "EventName": "EXT_SNOOP", | ||
| 25 | "BriefDescription": "SCU Snooped data from another CPU for this CPU" | ||
| 26 | } | ||
| 27 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json new file mode 100644 index 000000000000..480d9f7460ab --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0x60", | ||
| 4 | "EventName": "BUS_ACCESS_LD", | ||
| 5 | "BriefDescription": "Bus access - Read" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0x61", | ||
| 9 | "EventName": "BUS_ACCESS_ST", | ||
| 10 | "BriefDescription": "Bus access - Write" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xC0", | ||
| 14 | "EventName": "EXT_MEM_REQ", | ||
| 15 | "BriefDescription": "External memory request" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xC1", | ||
| 19 | "EventName": "EXT_MEM_REQ_NC", | ||
| 20 | "BriefDescription": "Non-cacheable external memory request" | ||
| 21 | } | ||
| 22 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json new file mode 100644 index 000000000000..73a22402d003 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0x86", | ||
| 4 | "EventName": "EXC_IRQ", | ||
| 5 | "BriefDescription": "Exception taken, IRQ" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0x87", | ||
| 9 | "EventName": "EXC_FIQ", | ||
| 10 | "BriefDescription": "Exception taken, FIQ" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xC6", | ||
| 14 | "EventName": "PRE_DECODE_ERR", | ||
| 15 | "BriefDescription": "Pre-decode error" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xD0", | ||
| 19 | "EventName": "L1I_CACHE_ERR", | ||
| 20 | "BriefDescription": "L1 Instruction Cache (data or tag) memory error" | ||
| 21 | }, | ||
| 22 | {, | ||
| 23 | "EventCode": "0xD1", | ||
| 24 | "EventName": "L1D_CACHE_ERR", | ||
| 25 | "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable" | ||
| 26 | }, | ||
| 27 | {, | ||
| 28 | "EventCode": "0xD2", | ||
| 29 | "EventName": "TLB_ERR", | ||
| 30 | "BriefDescription": "TLB memory error" | ||
| 31 | } | ||
| 32 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json new file mode 100644 index 000000000000..3149fb90555a --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | [ | ||
| 2 | {, | ||
| 3 | "EventCode": "0xC7", | ||
| 4 | "EventName": "STALL_SB_FULL", | ||
| 5 | "BriefDescription": "Data Write operation that stalls the pipeline because the store buffer is full" | ||
| 6 | }, | ||
| 7 | {, | ||
| 8 | "EventCode": "0xE0", | ||
| 9 | "EventName": "OTHER_IQ_DEP_STALL", | ||
| 10 | "BriefDescription": "Cycles that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error" | ||
| 11 | }, | ||
| 12 | {, | ||
| 13 | "EventCode": "0xE1", | ||
| 14 | "EventName": "IC_DEP_STALL", | ||
| 15 | "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction cache miss being processed" | ||
| 16 | }, | ||
| 17 | {, | ||
| 18 | "EventCode": "0xE2", | ||
| 19 | "EventName": "IUTLB_DEP_STALL", | ||
| 20 | "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction micro-TLB miss being processed" | ||
| 21 | }, | ||
| 22 | {, | ||
| 23 | "EventCode": "0xE3", | ||
| 24 | "EventName": "DECODE_DEP_STALL", | ||
| 25 | "BriefDescription": "Cycles the DPU IQ is empty and there is a pre-decode error being processed" | ||
| 26 | }, | ||
| 27 | {, | ||
| 28 | "EventCode": "0xE4", | ||
| 29 | "EventName": "OTHER_INTERLOCK_STALL", | ||
| 30 | "BriefDescription": "Cycles there is an interlock other than Advanced SIMD/Floating-point instructions or load/store instruction" | ||
| 31 | }, | ||
| 32 | {, | ||
| 33 | "EventCode": "0xE5", | ||
| 34 | "EventName": "AGU_DEP_STALL", | ||
| 35 | "BriefDescription": "Cycles there is an interlock for a load/store instruction waiting for data to calculate the address in the AGU" | ||
| 36 | }, | ||
| 37 | {, | ||
| 38 | "EventCode": "0xE6", | ||
| 39 | "EventName": "SIMD_DEP_STALL", | ||
| 40 | "BriefDescription": "Cycles there is an interlock for an Advanced SIMD/Floating-point operation." | ||
| 41 | }, | ||
| 42 | {, | ||
| 43 | "EventCode": "0xE7", | ||
| 44 | "EventName": "LD_DEP_STALL", | ||
| 45 | "BriefDescription": "Cycles there is a stall in the Wr stage because of a load miss" | ||
| 46 | }, | ||
| 47 | {, | ||
| 48 | "EventCode": "0xE8", | ||
| 49 | "EventName": "ST_DEP_STALL", | ||
| 50 | "BriefDescription": "Cycles there is a stall in the Wr stage because of a store" | ||
| 51 | } | ||
| 52 | ] | ||
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv index 219d6756134e..e61c9ca6cf9e 100644 --- a/tools/perf/pmu-events/arch/arm64/mapfile.csv +++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv | |||
| @@ -13,3 +13,4 @@ | |||
| 13 | # | 13 | # |
| 14 | #Family-model,Version,Filename,EventType | 14 | #Family-model,Version,Filename,EventType |
| 15 | 0x00000000420f5160,v1,cavium,core | 15 | 0x00000000420f5160,v1,cavium,core |
| 16 | 0x00000000410fd03[[:xdigit:]],v1,cortex-a53,core | ||
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 4035d43523c3..e0b1b414d466 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c | |||
| @@ -31,10 +31,12 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, | |||
| 31 | int i; | 31 | int i; |
| 32 | 32 | ||
| 33 | for (i = 0; i < evlist->nr_mmaps; i++) { | 33 | for (i = 0; i < evlist->nr_mmaps; i++) { |
| 34 | struct perf_mmap *map = &evlist->overwrite_mmap[i]; | ||
| 34 | union perf_event *event; | 35 | union perf_event *event; |
| 36 | u64 start, end; | ||
| 35 | 37 | ||
| 36 | perf_mmap__read_catchup(&evlist->overwrite_mmap[i]); | 38 | perf_mmap__read_init(map, true, &start, &end); |
| 37 | while ((event = perf_mmap__read_backward(&evlist->overwrite_mmap[i])) != NULL) { | 39 | while ((event = perf_mmap__read_event(map, true, &start, end)) != NULL) { |
| 38 | const u32 type = event->header.type; | 40 | const u32 type = event->header.type; |
| 39 | 41 | ||
| 40 | switch (type) { | 42 | switch (type) { |
| @@ -49,6 +51,7 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, | |||
| 49 | return TEST_FAIL; | 51 | return TEST_FAIL; |
| 50 | } | 52 | } |
| 51 | } | 53 | } |
| 54 | perf_mmap__read_done(map); | ||
| 52 | } | 55 | } |
| 53 | return TEST_OK; | 56 | return TEST_OK; |
| 54 | } | 57 | } |
diff --git a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh index 8b3da21a08f1..c446c894b297 100755 --- a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh | |||
| @@ -22,10 +22,23 @@ trace_libc_inet_pton_backtrace() { | |||
| 22 | expected[4]="rtt min.*" | 22 | expected[4]="rtt min.*" |
| 23 | expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" | 23 | expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" |
| 24 | expected[6]=".*inet_pton[[:space:]]\($libc\)$" | 24 | expected[6]=".*inet_pton[[:space:]]\($libc\)$" |
| 25 | expected[7]="getaddrinfo[[:space:]]\($libc\)$" | 25 | case "$(uname -m)" in |
| 26 | expected[8]=".*\(.*/bin/ping.*\)$" | 26 | s390x) |
| 27 | 27 | eventattr='call-graph=dwarf' | |
| 28 | perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do | 28 | expected[7]="gaih_inet[[:space:]]\(inlined\)$" |
| 29 | expected[8]="__GI_getaddrinfo[[:space:]]\(inlined\)$" | ||
| 30 | expected[9]="main[[:space:]]\(.*/bin/ping.*\)$" | ||
| 31 | expected[10]="__libc_start_main[[:space:]]\($libc\)$" | ||
| 32 | expected[11]="_start[[:space:]]\(.*/bin/ping.*\)$" | ||
| 33 | ;; | ||
| 34 | *) | ||
| 35 | eventattr='max-stack=3' | ||
| 36 | expected[7]="getaddrinfo[[:space:]]\($libc\)$" | ||
| 37 | expected[8]=".*\(.*/bin/ping.*\)$" | ||
| 38 | ;; | ||
| 39 | esac | ||
| 40 | |||
| 41 | perf trace --no-syscalls -e probe_libc:inet_pton/$eventattr/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do | ||
| 29 | echo $line | 42 | echo $line |
| 30 | echo "$line" | egrep -q "${expected[$idx]}" | 43 | echo "$line" | egrep -q "${expected[$idx]}" |
| 31 | if [ $? -ne 0 ] ; then | 44 | if [ $? -ne 0 ] ; then |
| @@ -33,7 +46,7 @@ trace_libc_inet_pton_backtrace() { | |||
| 33 | exit 1 | 46 | exit 1 |
| 34 | fi | 47 | fi |
| 35 | let idx+=1 | 48 | let idx+=1 |
| 36 | [ $idx -eq 9 ] && break | 49 | [ -z "${expected[$idx]}" ] && break |
| 37 | done | 50 | done |
| 38 | } | 51 | } |
| 39 | 52 | ||
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 68146f4620a5..6495ee55d9c3 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
| @@ -608,7 +608,8 @@ static int hist_browser__title(struct hist_browser *browser, char *bf, size_t si | |||
| 608 | return browser->title ? browser->title(browser, bf, size) : 0; | 608 | return browser->title ? browser->title(browser, bf, size) : 0; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | int hist_browser__run(struct hist_browser *browser, const char *help) | 611 | int hist_browser__run(struct hist_browser *browser, const char *help, |
| 612 | bool warn_lost_event) | ||
| 612 | { | 613 | { |
| 613 | int key; | 614 | int key; |
| 614 | char title[160]; | 615 | char title[160]; |
| @@ -638,8 +639,9 @@ int hist_browser__run(struct hist_browser *browser, const char *help) | |||
| 638 | nr_entries = hist_browser__nr_entries(browser); | 639 | nr_entries = hist_browser__nr_entries(browser); |
| 639 | ui_browser__update_nr_entries(&browser->b, nr_entries); | 640 | ui_browser__update_nr_entries(&browser->b, nr_entries); |
| 640 | 641 | ||
| 641 | if (browser->hists->stats.nr_lost_warned != | 642 | if (warn_lost_event && |
| 642 | browser->hists->stats.nr_events[PERF_RECORD_LOST]) { | 643 | (browser->hists->stats.nr_lost_warned != |
| 644 | browser->hists->stats.nr_events[PERF_RECORD_LOST])) { | ||
| 643 | browser->hists->stats.nr_lost_warned = | 645 | browser->hists->stats.nr_lost_warned = |
| 644 | browser->hists->stats.nr_events[PERF_RECORD_LOST]; | 646 | browser->hists->stats.nr_events[PERF_RECORD_LOST]; |
| 645 | ui_browser__warn_lost_events(&browser->b); | 647 | ui_browser__warn_lost_events(&browser->b); |
| @@ -2763,7 +2765,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 2763 | bool left_exits, | 2765 | bool left_exits, |
| 2764 | struct hist_browser_timer *hbt, | 2766 | struct hist_browser_timer *hbt, |
| 2765 | float min_pcnt, | 2767 | float min_pcnt, |
| 2766 | struct perf_env *env) | 2768 | struct perf_env *env, |
| 2769 | bool warn_lost_event) | ||
| 2767 | { | 2770 | { |
| 2768 | struct hists *hists = evsel__hists(evsel); | 2771 | struct hists *hists = evsel__hists(evsel); |
| 2769 | struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env); | 2772 | struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env); |
| @@ -2844,7 +2847,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 2844 | 2847 | ||
| 2845 | nr_options = 0; | 2848 | nr_options = 0; |
| 2846 | 2849 | ||
| 2847 | key = hist_browser__run(browser, helpline); | 2850 | key = hist_browser__run(browser, helpline, |
| 2851 | warn_lost_event); | ||
| 2848 | 2852 | ||
| 2849 | if (browser->he_selection != NULL) { | 2853 | if (browser->he_selection != NULL) { |
| 2850 | thread = hist_browser__selected_thread(browser); | 2854 | thread = hist_browser__selected_thread(browser); |
| @@ -3184,7 +3188,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
| 3184 | 3188 | ||
| 3185 | static int perf_evsel_menu__run(struct perf_evsel_menu *menu, | 3189 | static int perf_evsel_menu__run(struct perf_evsel_menu *menu, |
| 3186 | int nr_events, const char *help, | 3190 | int nr_events, const char *help, |
| 3187 | struct hist_browser_timer *hbt) | 3191 | struct hist_browser_timer *hbt, |
| 3192 | bool warn_lost_event) | ||
| 3188 | { | 3193 | { |
| 3189 | struct perf_evlist *evlist = menu->b.priv; | 3194 | struct perf_evlist *evlist = menu->b.priv; |
| 3190 | struct perf_evsel *pos; | 3195 | struct perf_evsel *pos; |
| @@ -3203,7 +3208,9 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, | |||
| 3203 | case K_TIMER: | 3208 | case K_TIMER: |
| 3204 | hbt->timer(hbt->arg); | 3209 | hbt->timer(hbt->arg); |
| 3205 | 3210 | ||
| 3206 | if (!menu->lost_events_warned && menu->lost_events) { | 3211 | if (!menu->lost_events_warned && |
| 3212 | menu->lost_events && | ||
| 3213 | warn_lost_event) { | ||
| 3207 | ui_browser__warn_lost_events(&menu->b); | 3214 | ui_browser__warn_lost_events(&menu->b); |
| 3208 | menu->lost_events_warned = true; | 3215 | menu->lost_events_warned = true; |
| 3209 | } | 3216 | } |
| @@ -3224,7 +3231,8 @@ browse_hists: | |||
| 3224 | key = perf_evsel__hists_browse(pos, nr_events, help, | 3231 | key = perf_evsel__hists_browse(pos, nr_events, help, |
| 3225 | true, hbt, | 3232 | true, hbt, |
| 3226 | menu->min_pcnt, | 3233 | menu->min_pcnt, |
| 3227 | menu->env); | 3234 | menu->env, |
| 3235 | warn_lost_event); | ||
| 3228 | ui_browser__show_title(&menu->b, title); | 3236 | ui_browser__show_title(&menu->b, title); |
| 3229 | switch (key) { | 3237 | switch (key) { |
| 3230 | case K_TAB: | 3238 | case K_TAB: |
| @@ -3282,7 +3290,8 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, | |||
| 3282 | int nr_entries, const char *help, | 3290 | int nr_entries, const char *help, |
| 3283 | struct hist_browser_timer *hbt, | 3291 | struct hist_browser_timer *hbt, |
| 3284 | float min_pcnt, | 3292 | float min_pcnt, |
| 3285 | struct perf_env *env) | 3293 | struct perf_env *env, |
| 3294 | bool warn_lost_event) | ||
| 3286 | { | 3295 | { |
| 3287 | struct perf_evsel *pos; | 3296 | struct perf_evsel *pos; |
| 3288 | struct perf_evsel_menu menu = { | 3297 | struct perf_evsel_menu menu = { |
| @@ -3309,13 +3318,15 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, | |||
| 3309 | menu.b.width = line_len; | 3318 | menu.b.width = line_len; |
| 3310 | } | 3319 | } |
| 3311 | 3320 | ||
| 3312 | return perf_evsel_menu__run(&menu, nr_entries, help, hbt); | 3321 | return perf_evsel_menu__run(&menu, nr_entries, help, |
| 3322 | hbt, warn_lost_event); | ||
| 3313 | } | 3323 | } |
| 3314 | 3324 | ||
| 3315 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | 3325 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, |
| 3316 | struct hist_browser_timer *hbt, | 3326 | struct hist_browser_timer *hbt, |
| 3317 | float min_pcnt, | 3327 | float min_pcnt, |
| 3318 | struct perf_env *env) | 3328 | struct perf_env *env, |
| 3329 | bool warn_lost_event) | ||
| 3319 | { | 3330 | { |
| 3320 | int nr_entries = evlist->nr_entries; | 3331 | int nr_entries = evlist->nr_entries; |
| 3321 | 3332 | ||
| @@ -3325,7 +3336,7 @@ single_entry: | |||
| 3325 | 3336 | ||
| 3326 | return perf_evsel__hists_browse(first, nr_entries, help, | 3337 | return perf_evsel__hists_browse(first, nr_entries, help, |
| 3327 | false, hbt, min_pcnt, | 3338 | false, hbt, min_pcnt, |
| 3328 | env); | 3339 | env, warn_lost_event); |
| 3329 | } | 3340 | } |
| 3330 | 3341 | ||
| 3331 | if (symbol_conf.event_group) { | 3342 | if (symbol_conf.event_group) { |
| @@ -3342,5 +3353,6 @@ single_entry: | |||
| 3342 | } | 3353 | } |
| 3343 | 3354 | ||
| 3344 | return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, | 3355 | return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, |
| 3345 | hbt, min_pcnt, env); | 3356 | hbt, min_pcnt, env, |
| 3357 | warn_lost_event); | ||
| 3346 | } | 3358 | } |
diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h index ba431777f559..9428bee076f2 100644 --- a/tools/perf/ui/browsers/hists.h +++ b/tools/perf/ui/browsers/hists.h | |||
| @@ -28,7 +28,8 @@ struct hist_browser { | |||
| 28 | 28 | ||
| 29 | struct hist_browser *hist_browser__new(struct hists *hists); | 29 | struct hist_browser *hist_browser__new(struct hists *hists); |
| 30 | void hist_browser__delete(struct hist_browser *browser); | 30 | void hist_browser__delete(struct hist_browser *browser); |
| 31 | int hist_browser__run(struct hist_browser *browser, const char *help); | 31 | int hist_browser__run(struct hist_browser *browser, const char *help, |
| 32 | bool warn_lost_event); | ||
| 32 | void hist_browser__init(struct hist_browser *browser, | 33 | void hist_browser__init(struct hist_browser *browser, |
| 33 | struct hists *hists); | 34 | struct hists *hists); |
| 34 | #endif /* _PERF_UI_BROWSER_HISTS_H_ */ | 35 | #endif /* _PERF_UI_BROWSER_HISTS_H_ */ |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ac35cd214feb..e5fc14e53c05 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -715,28 +715,11 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int | |||
| 715 | return perf_mmap__read_forward(md); | 715 | return perf_mmap__read_forward(md); |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) | ||
| 719 | { | ||
| 720 | struct perf_mmap *md = &evlist->mmap[idx]; | ||
| 721 | |||
| 722 | /* | ||
| 723 | * No need to check messup for backward ring buffer: | ||
| 724 | * We can always read arbitrary long data from a backward | ||
| 725 | * ring buffer unless we forget to pause it before reading. | ||
| 726 | */ | ||
| 727 | return perf_mmap__read_backward(md); | ||
| 728 | } | ||
| 729 | |||
| 730 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) | 718 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) |
| 731 | { | 719 | { |
| 732 | return perf_evlist__mmap_read_forward(evlist, idx); | 720 | return perf_evlist__mmap_read_forward(evlist, idx); |
| 733 | } | 721 | } |
| 734 | 722 | ||
| 735 | void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) | ||
| 736 | { | ||
| 737 | perf_mmap__read_catchup(&evlist->mmap[idx]); | ||
| 738 | } | ||
| 739 | |||
| 740 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) | 723 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) |
| 741 | { | 724 | { |
| 742 | perf_mmap__consume(&evlist->mmap[idx], false); | 725 | perf_mmap__consume(&evlist->mmap[idx], false); |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 75f8e0ad5d76..336b838e6957 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -133,10 +133,6 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx); | |||
| 133 | 133 | ||
| 134 | union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, | 134 | union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, |
| 135 | int idx); | 135 | int idx); |
| 136 | union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, | ||
| 137 | int idx); | ||
| 138 | void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx); | ||
| 139 | |||
| 140 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); | 136 | void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); |
| 141 | 137 | ||
| 142 | int perf_evlist__open(struct perf_evlist *evlist); | 138 | int perf_evlist__open(struct perf_evlist *evlist); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ff359c9ece2e..ef351688b797 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -41,17 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | #include "sane_ctype.h" | 42 | #include "sane_ctype.h" |
| 43 | 43 | ||
| 44 | static struct { | 44 | struct perf_missing_features perf_missing_features; |
| 45 | bool sample_id_all; | ||
| 46 | bool exclude_guest; | ||
| 47 | bool mmap2; | ||
| 48 | bool cloexec; | ||
| 49 | bool clockid; | ||
| 50 | bool clockid_wrong; | ||
| 51 | bool lbr_flags; | ||
| 52 | bool write_backward; | ||
| 53 | bool group_read; | ||
| 54 | } perf_missing_features; | ||
| 55 | 45 | ||
| 56 | static clockid_t clockid; | 46 | static clockid_t clockid; |
| 57 | 47 | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 846e41644525..a7487c6d1866 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -149,6 +149,20 @@ union u64_swap { | |||
| 149 | u32 val32[2]; | 149 | u32 val32[2]; |
| 150 | }; | 150 | }; |
| 151 | 151 | ||
| 152 | struct perf_missing_features { | ||
| 153 | bool sample_id_all; | ||
| 154 | bool exclude_guest; | ||
| 155 | bool mmap2; | ||
| 156 | bool cloexec; | ||
| 157 | bool clockid; | ||
| 158 | bool clockid_wrong; | ||
| 159 | bool lbr_flags; | ||
| 160 | bool write_backward; | ||
| 161 | bool group_read; | ||
| 162 | }; | ||
| 163 | |||
| 164 | extern struct perf_missing_features perf_missing_features; | ||
| 165 | |||
| 152 | struct cpu_map; | 166 | struct cpu_map; |
| 153 | struct target; | 167 | struct target; |
| 154 | struct thread_map; | 168 | struct thread_map; |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index f6630cb95eff..02721b579746 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -430,7 +430,8 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, | |||
| 430 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | 430 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, |
| 431 | struct hist_browser_timer *hbt, | 431 | struct hist_browser_timer *hbt, |
| 432 | float min_pcnt, | 432 | float min_pcnt, |
| 433 | struct perf_env *env); | 433 | struct perf_env *env, |
| 434 | bool warn_lost_event); | ||
| 434 | int script_browse(const char *script_opt); | 435 | int script_browse(const char *script_opt); |
| 435 | #else | 436 | #else |
| 436 | static inline | 437 | static inline |
| @@ -438,7 +439,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, | |||
| 438 | const char *help __maybe_unused, | 439 | const char *help __maybe_unused, |
| 439 | struct hist_browser_timer *hbt __maybe_unused, | 440 | struct hist_browser_timer *hbt __maybe_unused, |
| 440 | float min_pcnt __maybe_unused, | 441 | float min_pcnt __maybe_unused, |
| 441 | struct perf_env *env __maybe_unused) | 442 | struct perf_env *env __maybe_unused, |
| 443 | bool warn_lost_event __maybe_unused) | ||
| 442 | { | 444 | { |
| 443 | return 0; | 445 | return 0; |
| 444 | } | 446 | } |
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 05076e683938..91531a7c8fbf 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c | |||
| @@ -22,29 +22,27 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map) | |||
| 22 | 22 | ||
| 23 | /* When check_messup is true, 'end' must points to a good entry */ | 23 | /* When check_messup is true, 'end' must points to a good entry */ |
| 24 | static union perf_event *perf_mmap__read(struct perf_mmap *map, | 24 | static union perf_event *perf_mmap__read(struct perf_mmap *map, |
| 25 | u64 start, u64 end, u64 *prev) | 25 | u64 *startp, u64 end) |
| 26 | { | 26 | { |
| 27 | unsigned char *data = map->base + page_size; | 27 | unsigned char *data = map->base + page_size; |
| 28 | union perf_event *event = NULL; | 28 | union perf_event *event = NULL; |
| 29 | int diff = end - start; | 29 | int diff = end - *startp; |
| 30 | 30 | ||
| 31 | if (diff >= (int)sizeof(event->header)) { | 31 | if (diff >= (int)sizeof(event->header)) { |
| 32 | size_t size; | 32 | size_t size; |
| 33 | 33 | ||
| 34 | event = (union perf_event *)&data[start & map->mask]; | 34 | event = (union perf_event *)&data[*startp & map->mask]; |
| 35 | size = event->header.size; | 35 | size = event->header.size; |
| 36 | 36 | ||
| 37 | if (size < sizeof(event->header) || diff < (int)size) { | 37 | if (size < sizeof(event->header) || diff < (int)size) |
| 38 | event = NULL; | 38 | return NULL; |
| 39 | goto broken_event; | ||
| 40 | } | ||
| 41 | 39 | ||
| 42 | /* | 40 | /* |
| 43 | * Event straddles the mmap boundary -- header should always | 41 | * Event straddles the mmap boundary -- header should always |
| 44 | * be inside due to u64 alignment of output. | 42 | * be inside due to u64 alignment of output. |
| 45 | */ | 43 | */ |
| 46 | if ((start & map->mask) + size != ((start + size) & map->mask)) { | 44 | if ((*startp & map->mask) + size != ((*startp + size) & map->mask)) { |
| 47 | unsigned int offset = start; | 45 | unsigned int offset = *startp; |
| 48 | unsigned int len = min(sizeof(*event), size), cpy; | 46 | unsigned int len = min(sizeof(*event), size), cpy; |
| 49 | void *dst = map->event_copy; | 47 | void *dst = map->event_copy; |
| 50 | 48 | ||
| @@ -59,20 +57,19 @@ static union perf_event *perf_mmap__read(struct perf_mmap *map, | |||
| 59 | event = (union perf_event *)map->event_copy; | 57 | event = (union perf_event *)map->event_copy; |
| 60 | } | 58 | } |
| 61 | 59 | ||
| 62 | start += size; | 60 | *startp += size; |
| 63 | } | 61 | } |
| 64 | 62 | ||
| 65 | broken_event: | ||
| 66 | if (prev) | ||
| 67 | *prev = start; | ||
| 68 | |||
| 69 | return event; | 63 | return event; |
| 70 | } | 64 | } |
| 71 | 65 | ||
| 66 | /* | ||
| 67 | * legacy interface for mmap read. | ||
| 68 | * Don't use it. Use perf_mmap__read_event(). | ||
| 69 | */ | ||
| 72 | union perf_event *perf_mmap__read_forward(struct perf_mmap *map) | 70 | union perf_event *perf_mmap__read_forward(struct perf_mmap *map) |
| 73 | { | 71 | { |
| 74 | u64 head; | 72 | u64 head; |
| 75 | u64 old = map->prev; | ||
| 76 | 73 | ||
| 77 | /* | 74 | /* |
| 78 | * Check if event was unmapped due to a POLLHUP/POLLERR. | 75 | * Check if event was unmapped due to a POLLHUP/POLLERR. |
| @@ -82,13 +79,26 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map) | |||
| 82 | 79 | ||
| 83 | head = perf_mmap__read_head(map); | 80 | head = perf_mmap__read_head(map); |
| 84 | 81 | ||
| 85 | return perf_mmap__read(map, old, head, &map->prev); | 82 | return perf_mmap__read(map, &map->prev, head); |
| 86 | } | 83 | } |
| 87 | 84 | ||
| 88 | union perf_event *perf_mmap__read_backward(struct perf_mmap *map) | 85 | /* |
| 86 | * Read event from ring buffer one by one. | ||
| 87 | * Return one event for each call. | ||
| 88 | * | ||
| 89 | * Usage: | ||
| 90 | * perf_mmap__read_init() | ||
| 91 | * while(event = perf_mmap__read_event()) { | ||
| 92 | * //process the event | ||
| 93 | * perf_mmap__consume() | ||
| 94 | * } | ||
| 95 | * perf_mmap__read_done() | ||
| 96 | */ | ||
| 97 | union perf_event *perf_mmap__read_event(struct perf_mmap *map, | ||
| 98 | bool overwrite, | ||
| 99 | u64 *startp, u64 end) | ||
| 89 | { | 100 | { |
| 90 | u64 head, end; | 101 | union perf_event *event; |
| 91 | u64 start = map->prev; | ||
| 92 | 102 | ||
| 93 | /* | 103 | /* |
| 94 | * Check if event was unmapped due to a POLLHUP/POLLERR. | 104 | * Check if event was unmapped due to a POLLHUP/POLLERR. |
| @@ -96,40 +106,19 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map) | |||
| 96 | if (!refcount_read(&map->refcnt)) | 106 | if (!refcount_read(&map->refcnt)) |
| 97 | return NULL; | 107 | return NULL; |
| 98 | 108 | ||
| 99 | head = perf_mmap__read_head(map); | 109 | if (startp == NULL) |
| 100 | if (!head) | ||
| 101 | return NULL; | 110 | return NULL; |
| 102 | 111 | ||
| 103 | /* | 112 | /* non-overwirte doesn't pause the ringbuffer */ |
| 104 | * 'head' pointer starts from 0. Kernel minus sizeof(record) form | 113 | if (!overwrite) |
| 105 | * it each time when kernel writes to it, so in fact 'head' is | 114 | end = perf_mmap__read_head(map); |
| 106 | * negative. 'end' pointer is made manually by adding the size of | ||
| 107 | * the ring buffer to 'head' pointer, means the validate data can | ||
| 108 | * read is the whole ring buffer. If 'end' is positive, the ring | ||
| 109 | * buffer has not fully filled, so we must adjust 'end' to 0. | ||
| 110 | * | ||
| 111 | * However, since both 'head' and 'end' is unsigned, we can't | ||
| 112 | * simply compare 'end' against 0. Here we compare '-head' and | ||
| 113 | * the size of the ring buffer, where -head is the number of bytes | ||
| 114 | * kernel write to the ring buffer. | ||
| 115 | */ | ||
| 116 | if (-head < (u64)(map->mask + 1)) | ||
| 117 | end = 0; | ||
| 118 | else | ||
| 119 | end = head + map->mask + 1; | ||
| 120 | |||
| 121 | return perf_mmap__read(map, start, end, &map->prev); | ||
| 122 | } | ||
| 123 | 115 | ||
| 124 | void perf_mmap__read_catchup(struct perf_mmap *map) | 116 | event = perf_mmap__read(map, startp, end); |
| 125 | { | ||
| 126 | u64 head; | ||
| 127 | 117 | ||
| 128 | if (!refcount_read(&map->refcnt)) | 118 | if (!overwrite) |
| 129 | return; | 119 | map->prev = *startp; |
| 130 | 120 | ||
| 131 | head = perf_mmap__read_head(map); | 121 | return event; |
| 132 | map->prev = head; | ||
| 133 | } | 122 | } |
| 134 | 123 | ||
| 135 | static bool perf_mmap__empty(struct perf_mmap *map) | 124 | static bool perf_mmap__empty(struct perf_mmap *map) |
| @@ -267,41 +256,60 @@ static int overwrite_rb_find_range(void *buf, int mask, u64 head, u64 *start, u6 | |||
| 267 | return -1; | 256 | return -1; |
| 268 | } | 257 | } |
| 269 | 258 | ||
| 270 | int perf_mmap__push(struct perf_mmap *md, bool overwrite, | 259 | /* |
| 271 | void *to, int push(void *to, void *buf, size_t size)) | 260 | * Report the start and end of the available data in ringbuffer |
| 261 | */ | ||
| 262 | int perf_mmap__read_init(struct perf_mmap *md, bool overwrite, | ||
| 263 | u64 *startp, u64 *endp) | ||
| 272 | { | 264 | { |
| 273 | u64 head = perf_mmap__read_head(md); | 265 | u64 head = perf_mmap__read_head(md); |
| 274 | u64 old = md->prev; | 266 | u64 old = md->prev; |
| 275 | u64 end = head, start = old; | ||
| 276 | unsigned char *data = md->base + page_size; | 267 | unsigned char *data = md->base + page_size; |
| 277 | unsigned long size; | 268 | unsigned long size; |
| 278 | void *buf; | ||
| 279 | int rc = 0; | ||
| 280 | 269 | ||
| 281 | start = overwrite ? head : old; | 270 | *startp = overwrite ? head : old; |
| 282 | end = overwrite ? old : head; | 271 | *endp = overwrite ? old : head; |
| 283 | 272 | ||
| 284 | if (start == end) | 273 | if (*startp == *endp) |
| 285 | return 0; | 274 | return -EAGAIN; |
| 286 | 275 | ||
| 287 | size = end - start; | 276 | size = *endp - *startp; |
| 288 | if (size > (unsigned long)(md->mask) + 1) { | 277 | if (size > (unsigned long)(md->mask) + 1) { |
| 289 | if (!overwrite) { | 278 | if (!overwrite) { |
| 290 | WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); | 279 | WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); |
| 291 | 280 | ||
| 292 | md->prev = head; | 281 | md->prev = head; |
| 293 | perf_mmap__consume(md, overwrite); | 282 | perf_mmap__consume(md, overwrite); |
| 294 | return 0; | 283 | return -EAGAIN; |
| 295 | } | 284 | } |
| 296 | 285 | ||
| 297 | /* | 286 | /* |
| 298 | * Backward ring buffer is full. We still have a chance to read | 287 | * Backward ring buffer is full. We still have a chance to read |
| 299 | * most of data from it. | 288 | * most of data from it. |
| 300 | */ | 289 | */ |
| 301 | if (overwrite_rb_find_range(data, md->mask, head, &start, &end)) | 290 | if (overwrite_rb_find_range(data, md->mask, head, startp, endp)) |
| 302 | return -1; | 291 | return -EINVAL; |
| 303 | } | 292 | } |
| 304 | 293 | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | int perf_mmap__push(struct perf_mmap *md, bool overwrite, | ||
| 298 | void *to, int push(void *to, void *buf, size_t size)) | ||
| 299 | { | ||
| 300 | u64 head = perf_mmap__read_head(md); | ||
| 301 | u64 end, start; | ||
| 302 | unsigned char *data = md->base + page_size; | ||
| 303 | unsigned long size; | ||
| 304 | void *buf; | ||
| 305 | int rc = 0; | ||
| 306 | |||
| 307 | rc = perf_mmap__read_init(md, overwrite, &start, &end); | ||
| 308 | if (rc < 0) | ||
| 309 | return (rc == -EAGAIN) ? 0 : -1; | ||
| 310 | |||
| 311 | size = end - start; | ||
| 312 | |||
| 305 | if ((start & md->mask) + size != (end & md->mask)) { | 313 | if ((start & md->mask) + size != (end & md->mask)) { |
| 306 | buf = &data[start & md->mask]; | 314 | buf = &data[start & md->mask]; |
| 307 | size = md->mask + 1 - (start & md->mask); | 315 | size = md->mask + 1 - (start & md->mask); |
| @@ -327,3 +335,14 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, | |||
| 327 | out: | 335 | out: |
| 328 | return rc; | 336 | return rc; |
| 329 | } | 337 | } |
| 338 | |||
| 339 | /* | ||
| 340 | * Mandatory for overwrite mode | ||
| 341 | * The direction of overwrite mode is backward. | ||
| 342 | * The last perf_mmap__read() will set tail to map->prev. | ||
| 343 | * Need to correct the map->prev to head which is the end of next read. | ||
| 344 | */ | ||
| 345 | void perf_mmap__read_done(struct perf_mmap *map) | ||
| 346 | { | ||
| 347 | map->prev = perf_mmap__read_head(map); | ||
| 348 | } | ||
diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index e43d7b55a55f..ec7d3a24e276 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h | |||
| @@ -65,8 +65,6 @@ void perf_mmap__put(struct perf_mmap *map); | |||
| 65 | 65 | ||
| 66 | void perf_mmap__consume(struct perf_mmap *map, bool overwrite); | 66 | void perf_mmap__consume(struct perf_mmap *map, bool overwrite); |
| 67 | 67 | ||
| 68 | void perf_mmap__read_catchup(struct perf_mmap *md); | ||
| 69 | |||
| 70 | static inline u64 perf_mmap__read_head(struct perf_mmap *mm) | 68 | static inline u64 perf_mmap__read_head(struct perf_mmap *mm) |
| 71 | { | 69 | { |
| 72 | struct perf_event_mmap_page *pc = mm->base; | 70 | struct perf_event_mmap_page *pc = mm->base; |
| @@ -87,11 +85,17 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) | |||
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | union perf_event *perf_mmap__read_forward(struct perf_mmap *map); | 87 | union perf_event *perf_mmap__read_forward(struct perf_mmap *map); |
| 90 | union perf_event *perf_mmap__read_backward(struct perf_mmap *map); | 88 | |
| 89 | union perf_event *perf_mmap__read_event(struct perf_mmap *map, | ||
| 90 | bool overwrite, | ||
| 91 | u64 *startp, u64 end); | ||
| 91 | 92 | ||
| 92 | int perf_mmap__push(struct perf_mmap *md, bool backward, | 93 | int perf_mmap__push(struct perf_mmap *md, bool backward, |
| 93 | void *to, int push(void *to, void *buf, size_t size)); | 94 | void *to, int push(void *to, void *buf, size_t size)); |
| 94 | 95 | ||
| 95 | size_t perf_mmap__mmap_len(struct perf_mmap *map); | 96 | size_t perf_mmap__mmap_len(struct perf_mmap *map); |
| 96 | 97 | ||
| 98 | int perf_mmap__read_init(struct perf_mmap *md, bool overwrite, | ||
| 99 | u64 *startp, u64 *endp); | ||
| 100 | void perf_mmap__read_done(struct perf_mmap *map); | ||
| 97 | #endif /*__PERF_MMAP_H */ | 101 | #endif /*__PERF_MMAP_H */ |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 443892dabedb..1019bbc5dbd8 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
| @@ -340,35 +340,15 @@ size_t hex_width(u64 v) | |||
| 340 | return n; | 340 | return n; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | static int hex(char ch) | ||
| 344 | { | ||
| 345 | if ((ch >= '0') && (ch <= '9')) | ||
| 346 | return ch - '0'; | ||
| 347 | if ((ch >= 'a') && (ch <= 'f')) | ||
| 348 | return ch - 'a' + 10; | ||
| 349 | if ((ch >= 'A') && (ch <= 'F')) | ||
| 350 | return ch - 'A' + 10; | ||
| 351 | return -1; | ||
| 352 | } | ||
| 353 | |||
| 354 | /* | 343 | /* |
| 355 | * While we find nice hex chars, build a long_val. | 344 | * While we find nice hex chars, build a long_val. |
| 356 | * Return number of chars processed. | 345 | * Return number of chars processed. |
| 357 | */ | 346 | */ |
| 358 | int hex2u64(const char *ptr, u64 *long_val) | 347 | int hex2u64(const char *ptr, u64 *long_val) |
| 359 | { | 348 | { |
| 360 | const char *p = ptr; | 349 | char *p; |
| 361 | *long_val = 0; | ||
| 362 | |||
| 363 | while (*p) { | ||
| 364 | const int hex_val = hex(*p); | ||
| 365 | 350 | ||
| 366 | if (hex_val < 0) | 351 | *long_val = strtoull(ptr, &p, 16); |
| 367 | break; | ||
| 368 | |||
| 369 | *long_val = (*long_val << 4) | hex_val; | ||
| 370 | p++; | ||
| 371 | } | ||
| 372 | 352 | ||
| 373 | return p - ptr; | 353 | return p - ptr; |
| 374 | } | 354 | } |
diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config index a1883bbb0144..2cccbba64418 100644 --- a/tools/power/acpi/Makefile.config +++ b/tools/power/acpi/Makefile.config | |||
| @@ -56,9 +56,6 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} | |||
| 56 | # to compile vs uClibc, that can be done here as well. | 56 | # to compile vs uClibc, that can be done here as well. |
| 57 | CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- | 57 | CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- |
| 58 | CROSS_COMPILE ?= $(CROSS) | 58 | CROSS_COMPILE ?= $(CROSS) |
| 59 | CC = $(CROSS_COMPILE)gcc | ||
| 60 | LD = $(CROSS_COMPILE)gcc | ||
| 61 | STRIP = $(CROSS_COMPILE)strip | ||
| 62 | HOSTCC = gcc | 59 | HOSTCC = gcc |
| 63 | 60 | ||
| 64 | # check if compiler option is supported | 61 | # check if compiler option is supported |
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index fcb3ed0be5f8..dd614463d4d6 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include | |||
| @@ -42,6 +42,24 @@ EXTRA_WARNINGS += -Wformat | |||
| 42 | 42 | ||
| 43 | CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?) | 43 | CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?) |
| 44 | 44 | ||
| 45 | # Makefiles suck: This macro sets a default value of $(2) for the | ||
| 46 | # variable named by $(1), unless the variable has been set by | ||
| 47 | # environment or command line. This is necessary for CC and AR | ||
| 48 | # because make sets default values, so the simpler ?= approach | ||
| 49 | # won't work as expected. | ||
| 50 | define allow-override | ||
| 51 | $(if $(or $(findstring environment,$(origin $(1))),\ | ||
| 52 | $(findstring command line,$(origin $(1)))),,\ | ||
| 53 | $(eval $(1) = $(2))) | ||
| 54 | endef | ||
| 55 | |||
| 56 | # Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix. | ||
| 57 | $(call allow-override,CC,$(CROSS_COMPILE)gcc) | ||
| 58 | $(call allow-override,AR,$(CROSS_COMPILE)ar) | ||
| 59 | $(call allow-override,LD,$(CROSS_COMPILE)ld) | ||
| 60 | $(call allow-override,CXX,$(CROSS_COMPILE)g++) | ||
| 61 | $(call allow-override,STRIP,$(CROSS_COMPILE)strip) | ||
| 62 | |||
| 45 | ifeq ($(CC_NO_CLANG), 1) | 63 | ifeq ($(CC_NO_CLANG), 1) |
| 46 | EXTRA_WARNINGS += -Wstrict-aliasing=3 | 64 | EXTRA_WARNINGS += -Wstrict-aliasing=3 |
| 47 | endif | 65 | endif |
diff --git a/tools/spi/Makefile b/tools/spi/Makefile index 90615e10c79a..815d15589177 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile | |||
| @@ -11,8 +11,6 @@ endif | |||
| 11 | # (this improves performance and avoids hard-to-debug behaviour); | 11 | # (this improves performance and avoids hard-to-debug behaviour); |
| 12 | MAKEFLAGS += -r | 12 | MAKEFLAGS += -r |
| 13 | 13 | ||
| 14 | CC = $(CROSS_COMPILE)gcc | ||
| 15 | LD = $(CROSS_COMPILE)ld | ||
| 16 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | 14 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
| 17 | 15 | ||
| 18 | ALL_TARGETS := spidev_test spidev_fdx | 16 | ALL_TARGETS := spidev_test spidev_fdx |
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index a5276a91dfbf..0862e6f47a38 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile | |||
| @@ -5,6 +5,7 @@ CFLAGS += -I../../../../include/ | |||
| 5 | CFLAGS += -I../../../../usr/include/ | 5 | CFLAGS += -I../../../../usr/include/ |
| 6 | 6 | ||
| 7 | TEST_PROGS := run_tests.sh | 7 | TEST_PROGS := run_tests.sh |
| 8 | TEST_FILES := run_fuse_test.sh | ||
| 8 | TEST_GEN_FILES := memfd_test fuse_mnt fuse_test | 9 | TEST_GEN_FILES := memfd_test fuse_mnt fuse_test |
| 9 | 10 | ||
| 10 | fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | 11 | fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) |
diff --git a/tools/usb/Makefile b/tools/usb/Makefile index 4e6506078494..01d758d73b6d 100644 --- a/tools/usb/Makefile +++ b/tools/usb/Makefile | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # Makefile for USB tools | 2 | # Makefile for USB tools |
| 3 | 3 | ||
| 4 | CC = $(CROSS_COMPILE)gcc | ||
| 5 | PTHREAD_LIBS = -lpthread | 4 | PTHREAD_LIBS = -lpthread |
| 6 | WARNINGS = -Wall -Wextra | 5 | WARNINGS = -Wall -Wextra |
| 7 | CFLAGS = $(WARNINGS) -g -I../include | 6 | CFLAGS = $(WARNINGS) -g -I../include |
diff --git a/tools/vm/Makefile b/tools/vm/Makefile index be320b905ea7..20f6cf04377f 100644 --- a/tools/vm/Makefile +++ b/tools/vm/Makefile | |||
| @@ -6,7 +6,6 @@ TARGETS=page-types slabinfo page_owner_sort | |||
| 6 | LIB_DIR = ../lib/api | 6 | LIB_DIR = ../lib/api |
| 7 | LIBS = $(LIB_DIR)/libapi.a | 7 | LIBS = $(LIB_DIR)/libapi.a |
| 8 | 8 | ||
| 9 | CC = $(CROSS_COMPILE)gcc | ||
| 10 | CFLAGS = -Wall -Wextra -I../lib/ | 9 | CFLAGS = -Wall -Wextra -I../lib/ |
| 11 | LDFLAGS = $(LIBS) | 10 | LDFLAGS = $(LIBS) |
| 12 | 11 | ||
diff --git a/tools/wmi/Makefile b/tools/wmi/Makefile index e664f1167388..e0e87239126b 100644 --- a/tools/wmi/Makefile +++ b/tools/wmi/Makefile | |||
| @@ -2,7 +2,6 @@ PREFIX ?= /usr | |||
| 2 | SBINDIR ?= sbin | 2 | SBINDIR ?= sbin |
| 3 | INSTALL ?= install | 3 | INSTALL ?= install |
| 4 | CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include | 4 | CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include |
| 5 | CC = $(CROSS_COMPILE)gcc | ||
| 6 | 5 | ||
| 7 | TARGET = dell-smbios-example | 6 | TARGET = dell-smbios-example |
| 8 | 7 | ||
