Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
"The main changes are relating to our handling of access/dirty bits,
where our low-level page-table helpers could lead to stale young
mappings and loss of the dirty bit in some cases (the latter has not
been observed in practice, but could happen when clearing "soft-dirty"
if we enabled that). These were posted as part of a larger series, but
the rest of that is less urgent and needs a v2 which I'll get to
shortly.

In other news, we've now got a set of fixes to resolve the
lockdep/tracing problems that have been plaguing us for a while, but
they're still a bit "fresh" and I plan to send them to you next week
after we've got some more confidence in them (although initial CI
results look good).

Summary:

- Fix kerneldoc warnings generated by ACPI IORT code

- Fix pte_accessible() so that access flag is ignored

- Fix missing header #include

- Fix loss of software dirty bit across pte_wrprotect() when HW DBM
is enabled"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: pgtable: Ensure dirty bit is preserved across pte_wrprotect()
arm64: pgtable: Fix pte_accessible()
ACPI/IORT: Fix doc warnings in iort.c
arm64/fpsimd: add <asm/insn.h> to <asm/kprobes.h> to fix fpsimd build

+25 -19
+18 -16
arch/arm64/include/asm/pgtable.h
··· 115 115 #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) 116 116 #define pte_valid_not_user(pte) \ 117 117 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) 118 - #define pte_valid_young(pte) \ 119 - ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) 120 118 #define pte_valid_user(pte) \ 121 119 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) 122 120 ··· 122 124 * Could the pte be present in the TLB? We must check mm_tlb_flush_pending 123 125 * so that we don't erroneously return false for pages that have been 124 126 * remapped as PROT_NONE but are yet to be flushed from the TLB. 127 + * Note that we can't make any assumptions based on the state of the access 128 + * flag, since ptep_clear_flush_young() elides a DSB when invalidating the 129 + * TLB. 125 130 */ 126 131 #define pte_accessible(mm, pte) \ 127 - (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte)) 132 + (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte)) 128 133 129 134 /* 130 135 * p??_access_permitted() is true for valid user mappings (subject to the ··· 165 164 return pmd; 166 165 } 167 166 168 - static inline pte_t pte_wrprotect(pte_t pte) 169 - { 170 - pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); 171 - pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); 172 - return pte; 173 - } 174 - 175 167 static inline pte_t pte_mkwrite(pte_t pte) 176 168 { 177 169 pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); ··· 187 193 if (pte_write(pte)) 188 194 pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); 189 195 196 + return pte; 197 + } 198 + 199 + static inline pte_t pte_wrprotect(pte_t pte) 200 + { 201 + /* 202 + * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY 203 + * clear), set the PTE_DIRTY bit. 204 + */ 205 + if (pte_hw_dirty(pte)) 206 + pte = pte_mkdirty(pte); 207 + 208 + pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); 209 + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); 190 210 return pte; 191 211 } 192 212 ··· 853 845 pte = READ_ONCE(*ptep); 854 846 do { 855 847 old_pte = pte; 856 - /* 857 - * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY 858 - * clear), set the PTE_DIRTY bit. 859 - */ 860 - if (pte_hw_dirty(pte)) 861 - pte = pte_mkdirty(pte); 862 848 pte = pte_wrprotect(pte); 863 849 pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), 864 850 pte_val(old_pte), pte_val(pte));
+2
arch/arm64/include/asm/probes.h
··· 7 7 #ifndef _ARM_PROBES_H 8 8 #define _ARM_PROBES_H 9 9 10 + #include <asm/insn.h> 11 + 10 12 typedef u32 probe_opcode_t; 11 13 typedef void (probes_handler_t) (u32 opcode, long addr, struct pt_regs *); 12 14
+5 -3
drivers/acpi/arm64/iort.c
··· 44 44 * iort_set_fwnode() - Create iort_fwnode and use it to register 45 45 * iommu data in the iort_fwnode_list 46 46 * 47 - * @node: IORT table node associated with the IOMMU 47 + * @iort_node: IORT table node associated with the IOMMU 48 48 * @fwnode: fwnode associated with the IORT node 49 49 * 50 50 * Returns: 0 on success ··· 673 673 /** 674 674 * iort_get_device_domain() - Find MSI domain related to a device 675 675 * @dev: The device. 676 - * @req_id: Requester ID for the device. 676 + * @id: Requester ID for the device. 677 + * @bus_token: irq domain bus token. 677 678 * 678 679 * Returns: the MSI domain for this device, NULL otherwise 679 680 */ ··· 1137 1136 * 1138 1137 * @dev: device to configure 1139 1138 * @dma_addr: device DMA address result pointer 1140 - * @size: DMA range size result pointer 1139 + * @dma_size: DMA range size result pointer 1141 1140 */ 1142 1141 void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) 1143 1142 { ··· 1527 1526 /** 1528 1527 * iort_add_platform_device() - Allocate a platform device for IORT node 1529 1528 * @node: Pointer to device ACPI IORT node 1529 + * @ops: Pointer to IORT device config struct 1530 1530 * 1531 1531 * Returns: 0 on success, <0 failure 1532 1532 */