diff options
Diffstat (limited to 'arch')
111 files changed, 869 insertions, 322 deletions
diff --git a/arch/alpha/include/asm/syscall.h b/arch/alpha/include/asm/syscall.h new file mode 100644 index 0000000..88d28eb --- /dev/null +++ b/arch/alpha/include/asm/syscall.h @@ -0,0 +1,11 @@ +#ifndef _ASM_ALPHA_SYSCALL_H +#define _ASM_ALPHA_SYSCALL_H + +#include <uapi/linux/audit.h> + +static inline int syscall_get_arch(void) +{ + return AUDIT_ARCH_ALPHA; +} + +#endif /* _ASM_ALPHA_SYSCALL_H */ diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 86d8351..d9ee817 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -321,7 +321,7 @@ asmlinkage unsigned long syscall_trace_enter(void) if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(current_pt_regs())) ret = -1UL; - audit_syscall_entry(AUDIT_ARCH_ALPHA, regs->r0, regs->r16, regs->r17, regs->r18, regs->r19); + audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19); return ret ?: current_pt_regs()->r0; } diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 3f688b4..acb0d57 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -37,6 +37,11 @@ */ #define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) +/* + * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels. + */ +#define KVM_MMU_CACHE_MIN_PAGES 2 + #ifndef __ASSEMBLY__ #include <asm/cacheflush.h> @@ -50,7 +55,7 @@ void free_hyp_pgds(void); int kvm_alloc_stage2_pgd(struct kvm *kvm); void kvm_free_stage2_pgd(struct kvm *kvm); int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, - phys_addr_t pa, unsigned long size); + phys_addr_t pa, unsigned long size, bool writable); int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); @@ -83,6 +88,11 @@ static inline void kvm_clean_pgd(pgd_t *pgd) clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); } +static inline void kvm_clean_pmd(pmd_t *pmd) +{ + clean_dcache_area(pmd, PTRS_PER_PMD * sizeof(pmd_t)); +} + static inline void kvm_clean_pmd_entry(pmd_t *pmd) { clean_pmd_entry(pmd); @@ -123,10 +133,23 @@ static inline bool kvm_page_empty(void *ptr) } -#define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) -#define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) -#define kvm_pud_table_empty(pudp) (0) +#define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) +#define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) +#define kvm_pud_table_empty(kvm, pudp) (0) + +#define KVM_PREALLOC_LEVEL 0 +static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) +{ + return 0; +} + +static inline void kvm_free_hwpgd(struct kvm *kvm) { } + +static inline void *kvm_get_hwpgd(struct kvm *kvm) +{ + return kvm->arch.pgd; +} struct kvm; diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 90aa4583..3b30062 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -100,7 +100,7 @@ extern pgprot_t pgprot_s2_device; #define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) #define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) #define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) -#define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDWR) +#define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDONLY) #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 5e772a2..ef9119f 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -949,8 +949,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, scno); - audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, - regs->ARM_r2, regs->ARM_r3); + audit_syscall_entry(scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, + regs->ARM_r3); return scno; } diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 7796051..9e193c8 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -409,7 +409,7 @@ static void update_vttbr(struct kvm *kvm) kvm_next_vmid++; /* update vttbr to be used with the new vmid */ - pgd_phys = virt_to_phys(kvm->arch.pgd); + pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm)); BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; kvm->arch.vttbr = pgd_phys | vmid; @@ -808,7 +808,8 @@ static int hyp_init_cpu_notify(struct notifier_block *self, switch (action) { case CPU_STARTING: case CPU_STARTING_FROZEN: - cpu_init_hyp_mode(NULL); + if (__hyp_get_vectors() == hyp_default_vectors) + cpu_init_hyp_mode(NULL); break; } diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 98c8c5b..14d4883 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -433,10 +433,17 @@ ARM_BE8(rev r10, r10 ) str r3, [r11, #VGIC_V2_CPU_HCR] str r4, [r11, #VGIC_V2_CPU_VMCR] str r5, [r11, #VGIC_V2_CPU_MISR] +#ifdef CONFIG_CPU_ENDIAN_BE8 + str r6, [r11, #(VGIC_V2_CPU_EISR + 4)] + str r7, [r11, #VGIC_V2_CPU_EISR] + str r8, [r11, #(VGIC_V2_CPU_ELRSR + 4)] + str r9, [r11, #VGIC_V2_CPU_ELRSR] +#else str r6, [r11, #VGIC_V2_CPU_EISR] str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] str r8, [r11, #VGIC_V2_CPU_ELRSR] str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] +#endif str r10, [r11, #VGIC_V2_CPU_APR] /* Clear GICH_HCR */ diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index eea0306..57a403a 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -42,7 +42,7 @@ static unsigned long hyp_idmap_start; static unsigned long hyp_idmap_end; static phys_addr_t hyp_idmap_vector; -#define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) +#define hyp_pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) @@ -134,7 +134,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, } } while (pte++, addr += PAGE_SIZE, addr != end); - if (kvm_pte_table_empty(start_pte)) + if (kvm_pte_table_empty(kvm, start_pte)) clear_pmd_entry(kvm, pmd, start_addr); } @@ -158,7 +158,7 @@ static void unmap_pmds(struct kvm *kvm, pud_t *pud, } } while (pmd++, addr = next, addr != end); - if (kvm_pmd_table_empty(start_pmd)) + if (kvm_pmd_table_empty(kvm, start_pmd)) clear_pud_entry(kvm, pud, start_addr); } @@ -182,7 +182,7 @@ static void unmap_puds(struct kvm *kvm, pgd_t *pgd, } } while (pud++, addr = next, addr != end); - if (kvm_pud_table_empty(start_pud)) + if (kvm_pud_table_empty(kvm, start_pud)) clear_pgd_entry(kvm, pgd, start_addr); } @@ -306,7 +306,7 @@ void free_boot_hyp_pgd(void) if (boot_hyp_pgd) { unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); - free_pages((unsigned long)boot_hyp_pgd, pgd_order); + free_pages((unsigned long)boot_hyp_pgd, hyp_pgd_order); boot_hyp_pgd = NULL; } @@ -343,7 +343,7 @@ void free_hyp_pgds(void) for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); - free_pages((unsigned long)hyp_pgd, pgd_order); + free_pages((unsigned long)hyp_pgd, hyp_pgd_order); hyp_pgd = NULL; } @@ -401,13 +401,46 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start, return 0; } +static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start, + unsigned long end, unsigned long pfn, + pgprot_t prot) +{ + pud_t *pud; + pmd_t *pmd; + unsigned long addr, next; + int ret; + + addr = start; + do { + pud = pud_offset(pgd, addr); + + if (pud_none_or_clear_bad(pud)) { + pmd = pmd_alloc_one(NULL, addr); + if (!pmd) { + kvm_err("Cannot allocate Hyp pmd\n"); + return -ENOMEM; + } + pud_populate(NULL, pud, pmd); + get_page(virt_to_page(pud)); + kvm_flush_dcache_to_poc(pud, sizeof(*pud)); + } + + next = pud_addr_end(addr, end); + ret = create_hyp_pmd_mappings(pud, addr, next, pfn, prot); + if (ret) + return ret; + pfn += (next - addr) >> PAGE_SHIFT; + } while (addr = next, addr != end); + + return 0; +} + static int __create_hyp_mappings(pgd_t *pgdp, unsigned long start, unsigned long end, unsigned long pfn, pgprot_t prot) { pgd_t *pgd; pud_t *pud; - pmd_t *pmd; unsigned long addr, next; int err = 0; @@ -416,22 +449,21 @@ static int __create_hyp_mappings(pgd_t *pgdp, end = PAGE_ALIGN(end); do { pgd = pgdp + pgd_index(addr); - pud = pud_offset(pgd, addr); - if (pud_none_or_clear_bad(pud)) { - pmd = pmd_alloc_one(NULL, addr); - if (!pmd) { - kvm_err("Cannot allocate Hyp pmd\n"); + if (pgd_none(*pgd)) { + pud = pud_alloc_one(NULL, addr); + if (!pud) { + kvm_err("Cannot allocate Hyp pud\n"); err = -ENOMEM; goto out; } - pud_populate(NULL, pud, pmd); - get_page(virt_to_page(pud)); - kvm_flush_dcache_to_poc(pud, sizeof(*pud)); + pgd_populate(NULL, pgd, pud); + get_page(virt_to_page(pgd)); + kvm_flush_dcache_to_poc(pgd, sizeof(*pgd)); } next = pgd_addr_end(addr, end); - err = create_hyp_pmd_mappings(pud, addr, next, pfn, prot); + err = create_hyp_pud_mappings(pgd, addr, next, pfn, prot); if (err) goto out; pfn += (next - addr) >> PAGE_SHIFT; @@ -521,6 +553,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) */ int kvm_alloc_stage2_pgd(struct kvm *kvm) { + int ret; pgd_t *pgd; if (kvm->arch.pgd != NULL) { @@ -528,15 +561,38 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) return -EINVAL; } - pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, S2_PGD_ORDER); + if (KVM_PREALLOC_LEVEL > 0) { + /* + * Allocate fake pgd for the page table manipulation macros to + * work. This is not used by the hardware and we have no + * alignment requirement for this allocation. + */ + pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), + GFP_KERNEL | __GFP_ZERO); + } else { + /* + * Allocate actual first-level Stage-2 page table used by the + * hardware for Stage-2 page table walks. + */ + pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, S2_PGD_ORDER); + } + if (!pgd) return -ENOMEM; - memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t)); + ret = kvm_prealloc_hwpgd(kvm, pgd); + if (ret) + goto out_err; + kvm_clean_pgd(pgd); kvm->arch.pgd = pgd; - return 0; +out_err: + if (KVM_PREALLOC_LEVEL > 0) + kfree(pgd); + else + free_pages((unsigned long)pgd, S2_PGD_ORDER); + return ret; } /** @@ -572,19 +628,39 @@ void kvm_free_stage2_pgd(struct kvm *kvm) return; unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); - free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); + kvm_free_hwpgd(kvm); + if (KVM_PREALLOC_LEVEL > 0) + kfree(kvm->arch.pgd); + else + free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); kvm->arch.pgd = NULL; } -static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, +static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, phys_addr_t addr) { pgd_t *pgd; pud_t *pud; - pmd_t *pmd; pgd = kvm->arch.pgd + pgd_index(addr); - pud = pud_offset(pgd, addr); + if (WARN_ON(pgd_none(*pgd))) { + if (!cache) + return NULL; + pud = mmu_memory_cache_alloc(cache); + pgd_populate(NULL, pgd, pud); + get_page(virt_to_page(pgd)); + } + + return pud_offset(pgd, addr); +} + +static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, + phys_addr_t addr) +{ + pud_t *pud; + pmd_t *pmd; + + pud = stage2_get_pud(kvm, cache, addr); if (pud_none(*pud)) { if (!cache) return NULL; @@ -630,7 +706,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, pmd_t *pmd; pte_t *pte, old_pte; - /* Create stage-2 page table mapping - Level 1 */ + /* Create stage-2 page table mapping - Levels 0 and 1 */ pmd = stage2_get_pmd(kvm, cache, addr); if (!pmd) { /* @@ -675,7 +751,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, * @size: The size of the mapping */ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, - phys_addr_t pa, unsigned long size) + phys_addr_t pa, unsigned long size, bool writable) { phys_addr_t addr, end; int ret = 0; @@ -688,7 +764,11 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); - ret = mmu_topup_memory_cache(&cache, 2, 2); + if (writable) + kvm_set_s2pte_writable(&pte); + + ret = mmu_topup_memory_cache(&cache, KVM_MMU_CACHE_MIN_PAGES, + KVM_NR_MEM_OBJS); if (ret) goto out; spin_lock(&kvm->mmu_lock); @@ -777,6 +857,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, /* Let's check if we will get back a huge page backed by hugetlbfs */ down_read(¤t->mm->mmap_sem); vma = find_vma_intersection(current->mm, hva, hva + 1); + if (unlikely(!vma)) { + kvm_err("Failed to find VMA for hva 0x%lx\n", hva); + up_read(¤t->mm->mmap_sem); + return -EFAULT; + } + if (is_vm_hugetlb_page(vma)) { hugetlb = true; gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; @@ -797,7 +883,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, up_read(¤t->mm->mmap_sem); /* We need minimum second+third level pages */ - ret = mmu_topup_memory_cache(memcache, 2, KVM_NR_MEM_OBJS); + ret = mmu_topup_memory_cache(memcache, KVM_MMU_CACHE_MIN_PAGES, + KVM_NR_MEM_OBJS); if (ret) return ret; @@ -843,7 +930,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, } coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, - mem_type == PAGE_S2_DEVICE); + pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); } @@ -916,6 +1003,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) goto out_unlock; } + /* Userspace should not be able to register out-of-bounds IPAs */ + VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); + ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); if (ret == 0) ret = 1; @@ -1072,8 +1162,8 @@ int kvm_mmu_init(void) (unsigned long)phys_base); } - hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); - boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); + hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order); + boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order); if (!hyp_pgd || !boot_hyp_pgd) { kvm_err("Hyp mode PGD not allocated\n"); @@ -1126,13 +1216,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, const struct kvm_memory_slot *old, enum kvm_mr_change change) { - gpa_t gpa = old->base_gfn << PAGE_SHIFT; - phys_addr_t size = old->npages << PAGE_SHIFT; - if (change == KVM_MR_DELETE || change == KVM_MR_MOVE) { - spin_lock(&kvm->mmu_lock); - unmap_stage2_range(kvm, gpa, size); - spin_unlock(&kvm->mmu_lock); - } } int kvm_arch_prepare_memory_region(struct kvm *kvm, @@ -1140,7 +1223,77 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, enum kvm_mr_change change) { - return 0; + hva_t hva = mem->userspace_addr; + hva_t reg_end = hva + mem->memory_size; + bool writable = !(mem->flags & KVM_MEM_READONLY); + int ret = 0; + + if (change != KVM_MR_CREATE && change != KVM_MR_MOVE) + return 0; + + /* + * Prevent userspace from creating a memory region outside of the IPA + * space addressable by the KVM guest IPA space. + */ + if (memslot->base_gfn + memslot->npages >= + (KVM_PHYS_SIZE >> PAGE_SHIFT)) + return -EFAULT; + + /* + * A memory region could potentially cover multiple VMAs, and any holes + * between them, so iterate over all of them to find out if we can map + * any of them right now. + * + * +--------------------------------------------+ + * +---------------+----------------+ +----------------+ + * | : VMA 1 | VMA 2 | | VMA 3 : | + * +---------------+----------------+ +----------------+ + * | memory region | + * +--------------------------------------------+ + */ + do { + struct vm_area_struct *vma = find_vma(current->mm, hva); + hva_t vm_start, vm_end; + + if (!vma || vma->vm_start >= reg_end) + break; + + /* + * Mapping a read-only VMA is only allowed if the + * memory region is configured as read-only. + */ + if (writable && !(vma->vm_flags & VM_WRITE)) { + ret = -EPERM; + break; + } + + /* + * Take the intersection of this VMA with the memory region + */ + vm_start = max(hva, vma->vm_start); + vm_end = min(reg_end, vma->vm_end); + + if (vma->vm_flags & VM_PFNMAP) { + gpa_t gpa = mem->guest_phys_addr + + (vm_start - mem->userspace_addr); + phys_addr_t pa = (vma->vm_pgoff << PAGE_SHIFT) + + vm_start - vma->vm_start; + + ret = kvm_phys_addr_ioremap(kvm, gpa, pa, + vm_end - vm_start, + writable); + if (ret) + break; + } + hva = vm_end; + } while (hva < reg_end); + + if (ret) { + spin_lock(&kvm->mmu_lock); + unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); + spin_unlock(&kvm->mmu_lock); + } + return ret; } void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, @@ -1165,4 +1318,10 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) void kvm_arch_flush_shadow_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) { + gpa_t gpa = slot->base_gfn << PAGE_SHIFT; + phys_addr_t size = slot->npages << PAGE_SHIFT; + + spin_lock(&kvm->mmu_lock); + unmap_stage2_range(kvm, gpa, size); + spin_unlock(&kvm->mmu_lock); } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index a4d52c4..5fa3755 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1440,6 +1440,8 @@ static int gpmc_probe_nand_child(struct platform_device *pdev, break; } + gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child); + val = of_get_nand_bus_width(child); if (val == 16) gpmc_nand_data->devsize = NAND_BUSWIDTH_16; diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts index 8eb6d94..2e25de08 100644 --- a/arch/arm64/boot/dts/apm-mustang.dts +++ b/arch/arm64/boot/dts/apm-mustang.dts @@ -41,6 +41,10 @@ status = "ok"; }; +&sgenet0 { + status = "ok"; +}; + &xgenet { status = "ok"; }; diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index 87d3205..295c72d 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -176,6 +176,16 @@ clock-output-names = "menetclk"; }; + sge0clk: sge0clk@1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + csr-mask = <0x3>; + clock-output-names = "sge0clk"; + }; + xge0clk: xge0clk@1f61c000 { compatible = "apm,xgene-device-clock"; #clock-cells = <1>; @@ -611,6 +621,20 @@ }; }; + sgenet0: ethernet@1f210000 { + compatible = "apm,xgene-enet"; + status = "disabled"; + reg = <0x0 0x1f210000 0x0 0x10000>, + <0x0 0x1f200000 0x0 0X10000>, + <0x0 0x1B000000 0x0 0X20000>; + reg-names = "enet_csr", "ring_csr", "ring_cmd"; + interrupts = <0x0 0xA0 0x4>; + dma-coherent; + clocks = <&sge0clk 0>; + local-mac-address = [00 00 00 00 00 00]; + phy-connection-type = "sgmii"; + }; + xgenet: ethernet@1f610000 { compatible = "apm,xgene-enet"; status = "disabled"; diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 774a7c8..dc770bd 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -9,6 +9,7 @@ generic-y += current.h generic-y += delay.h generic-y += div64.h generic-y += dma.h +generic-y += dma-contiguous.h generic-y += early_ioremap.h generic-y += emergency-restart.h generic-y += errno.h diff --git a/arch/arm64/include/asm/dma-contiguous.h b/arch/arm64/include/asm/dma-contiguous.h deleted file mode 100644 index 14c4c0c..0000000 --- a/arch/arm64/include/asm/dma-contiguous.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _ASM_DMA_CONTIGUOUS_H -#define _ASM_DMA_CONTIGUOUS_H - -#ifdef __KERNEL__ -#ifdef CONFIG_DMA_CMA - -#include <linux/types.h> - -static inline void -dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { } - -#endif -#endif - -#endif diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index a030d16..0caf7a5 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -41,6 +41,18 @@ */ #define TRAMPOLINE_VA (HYP_PAGE_OFFSET_MASK & PAGE_MASK) +/* + * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation + * levels in addition to the PGD and potentially the PUD which are + * pre-allocated (we pre-allocate the fake PGD and the PUD when the Stage-2 + * tables use one level of tables less than the kernel. + */ +#ifdef CONFIG_ARM64_64K_PAGES +#define KVM_MMU_CACHE_MIN_PAGES 1 +#else +#define KVM_MMU_CACHE_MIN_PAGES 2 +#endif + #ifdef __ASSEMBLY__ /* @@ -53,6 +65,7 @@ #else +#include <asm/pgalloc.h> #include <asm/cachetype.h> #include <asm/cacheflush.h> @@ -65,10 +78,6 @@ #define KVM_PHYS_SIZE (1UL << KVM_PHYS_SHIFT) #define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1UL) -/* Make sure we get the right size, and thus the right alignment */ -#define PTRS_PER_S2_PGD (1 << (KVM_PHYS_SHIFT - PGDIR_SHIFT)) -#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) - int create_hyp_mappings(void *from, void *to); int create_hyp_io_mappings(void *from, void *to, phys_addr_t); void free_boot_hyp_pgd(void); @@ -77,7 +86,7 @@ void free_hyp_pgds(void); int kvm_alloc_stage2_pgd(struct kvm *kvm); void kvm_free_stage2_pgd(struct kvm *kvm); int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, - phys_addr_t pa, unsigned long size); + phys_addr_t pa, unsigned long size, bool writable); int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); @@ -93,6 +102,7 @@ void kvm_clear_hyp_idmap(void); #define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd) static inline void kvm_clean_pgd(pgd_t *pgd) {} +static inline void kvm_clean_pmd(pmd_t *pmd) {} static inline void kvm_clean_pmd_entry(pmd_t *pmd) {} static inline void kvm_clean_pte(pte_t *pte) {} static inline void kvm_clean_pte_entry(pte_t *pte) {} @@ -111,19 +121,116 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) +/* + * In the case where PGDIR_SHIFT is larger than KVM_PHYS_SHIFT, we can address + * the entire IPA input range with a single pgd entry, and we would only need + * one pgd entry. Note that in this case, the pgd is actually not used by + * the MMU for Stage-2 translations, but is merely a fake pgd used as a data + * structure for the kernel pgtable macros to work. + */ +#if PGDIR_SHIFT > KVM_PHYS_SHIFT +#define PTRS_PER_S2_PGD_SHIFT 0 +#else +#define PTRS_PER_S2_PGD_SHIFT (KVM_PHYS_SHIFT - PGDIR_SHIFT) +#endif +#define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) +#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) + +/* + * If we are concatenating first level stage-2 page tables, we would have less + * than or equal to 16 pointers in the fake PGD, because that's what the + * architecture allows. In this case, (4 - CONFIG_ARM64_PGTABLE_LEVELS) + * represents the first level for the host, and we add 1 to go to the next + * level (which uses contatenation) for the stage-2 tables. + */ +#if PTRS_PER_S2_PGD <= 16 +#define KVM_PREALLOC_LEVEL (4 - CONFIG_ARM64_PGTABLE_LEVELS + 1) +#else +#define KVM_PREALLOC_LEVEL (0) +#endif + +/** + * kvm_prealloc_hwpgd - allocate inital table for VTTBR + * @kvm: The KVM struct pointer for the VM. + * @pgd: The kernel pseudo pgd + * + * When the kernel uses more levels of page tables than the guest, we allocate + * a fake PGD and pre-populate it to point to the next-level page table, which + * will be the real initial page table pointed to by the VTTBR. + * + * When KVM_PREALLOC_LEVEL==2, we allocate a single page for the PMD and + * the kernel will use folded pud. When KVM_PREALLOC_LEVEL==1, we + * allocate 2 consecutive PUD pages. + */ +static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) +{ + unsigned int i; + unsigned long hwpgd; + + if (KVM_PREALLOC_LEVEL == 0) + return 0; + + hwpgd = __get_free_pages(GFP_KERNEL | __GFP_ZERO, PTRS_PER_S2_PGD_SHIFT); + if (!hwpgd) + return -ENOMEM; + + for (i = 0; i < PTRS_PER_S2_PGD; i++) { + if (KVM_PREALLOC_LEVEL == 1) + pgd_populate(NULL, pgd + i, + (pud_t *)hwpgd + i * PTRS_PER_PUD); + else if (KVM_PREALLOC_LEVEL == 2) + pud_populate(NULL, pud_offset(pgd, 0) + i, + (pmd_t *)hwpgd + i * PTRS_PER_PMD); + } + + return 0; +} + +static inline void *kvm_get_hwpgd(struct kvm *kvm) +{ + pgd_t *pgd = kvm->arch.pgd; + pud_t *pud; + + if (KVM_PREALLOC_LEVEL == 0) + return pgd; + + pud = pud_offset(pgd, 0); + if (KVM_PREALLOC_LEVEL == 1) + return pud; + + BUG_ON(KVM_PREALLOC_LEVEL != 2); + return pmd_offset(pud, 0); +} + +static inline void kvm_free_hwpgd(struct kvm *kvm) +{ + if (KVM_PREALLOC_LEVEL > 0) { + unsigned long hwpgd = (unsigned long)kvm_get_hwpgd(kvm); + free_pages(hwpgd, PTRS_PER_S2_PGD_SHIFT); + } +} + static inline bool kvm_page_empty(void *ptr) { struct page *ptr_page = virt_to_page(ptr); return page_count(ptr_page) == 1; } -#define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) -#ifndef CONFIG_ARM64_64K_PAGES -#define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) +#define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) + +#ifdef __PAGETABLE_PMD_FOLDED +#define kvm_pmd_table_empty(kvm, pmdp) (0) +#else +#define kvm_pmd_table_empty(kvm, pmdp) \ + (kvm_page_empty(pmdp) && (!(kvm) || KVM_PREALLOC_LEVEL < 2)) +#endif + +#ifdef __PAGETABLE_PUD_FOLDED +#define kvm_pud_table_empty(kvm, pudp) (0) #else -#define kvm_pmd_table_empty(pmdp) (0) +#define kvm_pud_table_empty(kvm, pudp) \ + (kvm_page_empty(pudp) && (!(kvm) || KVM_PREALLOC_LEVEL < 1)) #endif -#define kvm_pud_table_empty(pudp) (0) struct kvm; diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index cefd3e8..41a43bf 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -79,7 +79,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) -#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN) +#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index fe63ac5..8a4ae8e 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -1120,8 +1120,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, regs->syscallno); - audit_syscall_entry(syscall_get_arch(), regs->syscallno, - regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]); + audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1], + regs->regs[2], regs->regs[3]); return regs->syscallno; } diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S index ae21177..f002fe1 100644 --- a/arch/arm64/kvm/vgic-v2-switch.S +++ b/arch/arm64/kvm/vgic-v2-switch.S @@ -67,10 +67,14 @@ CPU_BE( rev w11, w11 ) str w4, [x3, #VGIC_V2_CPU_HCR] str w5, [x3, #VGIC_V2_CPU_VMCR] str w6, [x3, #VGIC_V2_CPU_MISR] - str w7, [x3, #VGIC_V2_CPU_EISR] - str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] - str w9, [x3, #VGIC_V2_CPU_ELRSR] - str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] +CPU_LE( str w7, [x3, #VGIC_V2_CPU_EISR] ) +CPU_LE( str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] ) +CPU_LE( str w9, [x3, #VGIC_V2_CPU_ELRSR] ) +CPU_LE( str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] ) +CPU_BE( str w7, [x3, #(VGIC_V2_CPU_EISR + 4)] ) +CPU_BE( str w8, [x3, #VGIC_V2_CPU_EISR] ) +CPU_BE( str w9, [x3, #(VGIC_V2_CPU_ELRSR + 4)] ) +CPU_BE( str w10, [x3, #VGIC_V2_CPU_ELRSR] ) str w11, [x3, #VGIC_V2_CPU_APR] /* Clear GICH_HCR */ diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index db85b5e..37b7560 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -7,7 +7,7 @@ */ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> #include <linux/fb.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -1356,10 +1356,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) goto fail; slave->sdata.dma_dev = &dw_dmac0_device.dev; - slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0) - | DWC_CFGH_DST_PER(1)); - slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL - | DWC_CFGL_HS_SRC_POL); + slave->sdata.src_id = 0; + slave->sdata.dst_id = 1; + slave->sdata.src_master = 1; + slave->sdata.dst_master = 0; data->dma_slave = slave; @@ -2052,8 +2052,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for capture should be configured. */ if (flags & AC97C_CAPTURE) { rx_dws->dma_dev = &dw_dmac0_device.dev; - rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); - rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + rx_dws->src_id = 3; rx_dws->src_master = 0; rx_dws->dst_master = 1; } @@ -2061,8 +2060,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for playback should be configured. */ if (flags & AC97C_PLAYBACK) { tx_dws->dma_dev = &dw_dmac0_device.dev; - tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); - tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + tx_dws->dst_id = 4; tx_dws->src_master = 0; tx_dws->dst_master = 1; } @@ -2134,8 +2132,7 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) dws = &data->dws; dws->dma_dev = &dw_dmac0_device.dev; - dws->cfg_hi = DWC_CFGH_DST_PER(2); - dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + dws->dst_id = 2; dws->src_master = 0; dws->dst_master = 1; diff --git a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h index 4bba585..11d7f4b 100644 --- a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h +++ b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h @@ -1,7 +1,7 @@ #ifndef __MACH_ATMEL_MCI_H #define __MACH_ATMEL_MCI_H -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> /** * struct mci_dma_data - DMA data for MCI interface diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h index a7ff1c6..1d0b875 100644 --- a/arch/ia64/include/asm/syscall.h +++ b/arch/ia64/include/asm/syscall.h @@ -13,6 +13,7 @@ #ifndef _ASM_SYSCALL_H #define _ASM_SYSCALL_H 1 +#include <uapi/linux/audit.h> #include <linux/sched.h> #include <linux/err.h> @@ -79,4 +80,9 @@ static inline void syscall_set_arguments(struct task_struct *task, ia64_syscall_get_set_arguments(task, regs, i, n, args, 1); } + +static inline int syscall_get_arch(void) +{ + return AUDIT_ARCH_IA64; +} #endif /* _ASM_SYSCALL_H */ diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index b7a5fff..6f54d51 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -1219,7 +1219,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, ia64_sync_krbs(); - audit_syscall_entry(AUDIT_ARCH_IA64, regs.r15, arg0, arg1, arg2, arg3); + audit_syscall_entry(regs.r15, arg0, arg1, arg2, arg3); return 0; } diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h index 9bc4317..53cfaf3 100644 --- a/arch/microblaze/include/asm/syscall.h +++ b/arch/microblaze/include/asm/syscall.h @@ -1,6 +1,7 @@ #ifndef __ASM_MICROBLAZE_SYSCALL_H #define __ASM_MICROBLAZE_SYSCALL_H +#include <uapi/linux/audit.h> #include <linux/kernel.h> #include <linux/sched.h> #include <asm/ptrace.h> @@ -99,4 +100,8 @@ static inline void syscall_set_arguments(struct task_struct *task, asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); +static inline int syscall_get_arch(void) +{ + return AUDIT_ARCH_MICROBLAZE; +} #endif /* __ASM_MICROBLAZE_SYSCALL_H */ diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index 39cf508..bb10637 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c @@ -147,8 +147,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) */ ret = -1L; - audit_syscall_entry(EM_MICROBLAZE, regs->r12, regs->r5, regs->r6, - regs->r7, regs->r8); + audit_syscall_entry(regs->r12, regs->r5, regs->r6, regs->r7, regs->r8); return ret ?: regs->r12; } diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 574c430..ad6badb 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -29,6 +29,7 @@ config MIPS select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_DMA_ATTRS + select HAVE_DMA_CONTIGUOUS select HAVE_DMA_API_DEBUG select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -353,6 +354,7 @@ config MIPS_SEAD3 bool "MIPS SEAD3 board" select BOOT_ELF32 select BOOT_RAW + select BUILTIN_DTB select CEVT_R4K select CSRC_R4K select CSRC_GIC @@ -742,6 +744,7 @@ config CAVIUM_OCTEON_SOC select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_SMP select NR_CPUS_DEFAULT_16 + select BUILTIN_DTB help This option supports all of the Octeon reference boards from Cavium Networks. It builds a kernel that dynamically determines the Octeon @@ -2482,6 +2485,9 @@ config USE_OF select OF_EARLY_FLATTREE select IRQ_DOMAIN +config BUILTIN_DTB + bool + endmenu config LOCKDEP_SUPPORT diff --git a/arch/mips/Makefile b/arch/mips/Makefile index bbac51e1..23cb948 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -333,6 +333,16 @@ endif CLEAN_FILES += vmlinux.32 vmlinux.64 +# device-trees +core-$(CONFIG_BUILTIN_DTB) += arch/mips/boot/dts/ + +%.dtb %.dtb.S %.dtb.o: | scripts + $(Q)$(MAKE) $(build)=arch/mips/boot/dts arch/mips/boot/dts/$@ + +PHONY += dtbs +dtbs: scripts + $(Q)$(MAKE) $(build)=arch/mips/boot/dts dtbs + archprepare: ifdef CONFIG_MIPS32_N32 @echo ' Checking missing-syscalls for N32' @@ -367,6 +377,7 @@ define archhelp echo ' vmlinuz.srec - SREC zboot image' echo ' uImage - U-Boot image' echo ' uImage.gz - U-Boot image (gzip)' + echo ' dtbs - Device-tree blobs for enabled boards' echo echo ' These will be default as appropriate for a configured platform.' endef diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index ef93ee3..1c64fdb 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -21,6 +21,7 @@ #include <linux/mtd/partitions.h> #include <linux/platform_device.h> #include <linux/smsc911x.h> +#include <linux/wm97xx.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1100_mmc.h> @@ -711,6 +712,46 @@ static struct platform_device db1300_lcd_dev = { /**********************************************************************/ +static void db1300_wm97xx_irqen(struct wm97xx *wm, int enable) +{ + if (enable) + enable_irq(DB1300_AC97_PEN_INT); + else + disable_irq_nosync(DB1300_AC97_PEN_INT); +} + +static struct wm97xx_mach_ops db1300_wm97xx_ops = { + .irq_enable = db1300_wm97xx_irqen, + .irq_gpio = WM97XX_GPIO_3, +}; + +static int db1300_wm97xx_probe(struct platform_device *pdev) +{ + struct wm97xx *wm = platform_get_drvdata(pdev); + + /* external pendown indicator */ + wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, + WM97XX_GPIO_POL_LOW, WM97XX_GPIO_STICKY, + WM97XX_GPIO_WAKE); + + /* internal "virtual" pendown gpio */ + wm97xx_config_gpio(wm, WM97XX_GPIO_3, WM97XX_GPIO_OUT, + WM97XX_GPIO_POL_LOW, WM97XX_GPIO_NOTSTICKY, + WM97XX_GPIO_NOWAKE); + + wm->pen_irq = DB1300_AC97_PEN_INT; + + return wm97xx_register_mach_ops(wm, &db1300_wm97xx_ops); +} + +static struct platform_driver db1300_wm97xx_driver = { + .driver.name = "wm97xx-touch", + .driver.owner = THIS_MODULE, + .probe = db1300_wm97xx_probe, +}; + +/**********************************************************************/ + static struct platform_device *db1300_dev[] __initdata = { &db1300_eth_dev, &db1300_i2c_dev, @@ -755,6 +796,9 @@ int __init db1300_dev_setup(void) i2c_register_board_info(0, db1300_i2c_devs, ARRAY_SIZE(db1300_i2c_devs)); + if (platform_driver_register(&db1300_wm97xx_driver)) + pr_warn("DB1300: failed to init touch pen irq support!\n"); + /* Audio PSC clock is supplied by codecs (PSC1, 2) */ __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); @@ -762,9 +806,10 @@ int __init db1300_dev_setup(void) __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); - /* I2C uses internal 48MHz EXTCLK1 */ + /* I2C driver wants 50MHz, get as close as possible */ c = clk_get(NULL, "psc3_intclk"); if (!IS_ERR(c)) { + clk_set_rate(c, 50000000); clk_prepare_enable(c); clk_put(c); } diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 7e89936..0fd5177 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -34,12 +34,9 @@ static void __init db1550_hw_setup(void) void __iomem *base; unsigned long v; - /* complete SPI setup: link psc0_intclk to a 48MHz source, - * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC - * for AC97 on PB1550. + /* complete pin setup: assign GPIO16 to PSC0_SYNC1 (SPI cs# line) + * as well as PSC1_SYNC for AC97 on PB1550. */ - v = alchemy_rdsys(AU1000_SYS_CLKSRC); - alchemy_wrsys(v | 0x000001e0, AU1000_SYS_CLKSRC); v = alchemy_rdsys(AU1000_SYS_PINFUNC); alchemy_wrsys(v | 1 | SYS_PF_PSC1_S1, AU1000_SYS_PINFUNC); @@ -586,11 +583,13 @@ int __init db1550_dev_setup(void) c = clk_get(NULL, "psc0_intclk"); if (!IS_ERR(c)) { + clk_set_rate(c, 50000000); clk_prepare_enable(c); clk_put(c); } c = clk_get(NULL, "psc2_intclk"); if (!IS_ERR(c)) { + clk_set_rate(c, db1550_spi_platdata.mainclk_hz); clk_prepare_enable(c); clk_put(c); } diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 8df86eb..be139a0 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -11,6 +11,7 @@ #include <linux/pm.h> #include <asm/bootinfo.h> +#include <asm/idle.h> #include <asm/reboot.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-db1x00/bcsr.h> @@ -53,6 +54,8 @@ static void db1x_power_off(void) { bcsr_write(BCSR_RESETS, 0); bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET); + while (1) /* sit and spin */ + cpu_wait(); } static void db1x_reset(char *c) diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore index a73d6e2..d3962cd 100644 --- a/arch/mips/boot/.gitignore +++ b/arch/mips/boot/.gitignore @@ -5,3 +5,4 @@ zImage zImage.tmp calc_vmlinuz_load_addr uImage +*.dtb diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile new file mode 100644 index 0000000..ca9c90e --- /dev/null +++ b/arch/mips/boot/dts/Makefile @@ -0,0 +1,20 @@ +dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb +dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb +dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb +dtb-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb +dtb-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb +dtb-$(CONFIG_DT_XLP_GVP) += xlp_gvp.dtb +dtb-$(CONFIG_DTB_RT2880_EVAL) += rt2880_eval.dtb +dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb +dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb +dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb +dtb-$(CONFIG_MIPS_SEAD3) += sead3.dtb + +obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) + +targets += dtbs +targets += $(dtb-y) + +dtbs: $(addprefix $(obj)/, $(dtb-y)) + +clean-files += *.dtb *.dtb.S diff --git a/arch/mips/lantiq/dts/danube.dtsi b/arch/mips/boot/dts/danube.dtsi index d4c59e0..d4c59e0 100644 --- a/arch/mips/lantiq/dts/danube.dtsi +++ b/arch/mips/boot/dts/danube.dtsi diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/boot/dts/easy50712.dts index 143b8a3..143b8a3 100644 --- a/arch/mips/lantiq/dts/easy50712.dts +++ b/arch/mips/boot/dts/easy50712.dts diff --git a/arch/mips/ralink/dts/mt7620a.dtsi b/arch/mips/boot/dts/mt7620a.dtsi index 08bf24f..08bf24f 100644 --- a/arch/mips/ralink/dts/mt7620a.dtsi +++ b/arch/mips/boot/dts/mt7620a.dtsi diff --git a/arch/mips/ralink/dts/mt7620a_eval.dts b/arch/mips/boot/dts/mt7620a_eval.dts index 709f581..709f581 100644 --- a/arch/mips/ralink/dts/mt7620a_eval.dts +++ b/arch/mips/boot/dts/mt7620a_eval.dts diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/boot/dts/octeon_3xxx.dts index fa33115..fa33115 100644 --- a/arch/mips/cavium-octeon/octeon_3xxx.dts +++ b/arch/mips/boot/dts/octeon_3xxx.dts diff --git a/arch/mips/cavium-octeon/octeon_68xx.dts b/arch/mips/boot/dts/octeon_68xx.dts index 79b46fc..79b46fc 100644 --- a/arch/mips/cavium-octeon/octeon_68xx.dts +++ b/arch/mips/boot/dts/octeon_68xx.dts diff --git a/arch/mips/ralink/dts/rt2880.dtsi b/arch/mips/boot/dts/rt2880.dtsi index 182afde..182afde 100644 --- a/arch/mips/ralink/dts/rt2880.dtsi +++ b/arch/mips/boot/dts/rt2880.dtsi diff --git a/arch/mips/ralink/dts/rt2880_eval.dts b/arch/mips/boot/dts/rt2880_eval.dts index 0a685db..0a685db 100644 --- a/arch/mips/ralink/dts/rt2880_eval.dts +++ b/arch/mips/boot/dts/rt2880_eval.dts diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/boot/dts/rt3050.dtsi index e3203d4..e3203d4 100644 --- a/arch/mips/ralink/dts/rt3050.dtsi +++ b/arch/mips/boot/dts/rt3050.dtsi diff --git a/arch/mips/ralink/dts/rt3052_eval.dts b/arch/mips/boot/dts/rt3052_eval.dts index ec9e9a0..ec9e9a0 100644 --- a/arch/mips/ralink/dts/rt3052_eval.dts +++ b/arch/mips/boot/dts/rt3052_eval.dts diff --git a/arch/mips/ralink/dts/rt3883.dtsi b/arch/mips/boot/dts/rt3883.dtsi index 3b131dd..3b131dd 100644 --- a/arch/mips/ralink/dts/rt3883.dtsi +++ b/arch/mips/boot/dts/rt3883.dtsi diff --git a/arch/mips/ralink/dts/rt3883_eval.dts b/arch/mips/boot/dts/rt3883_eval.dts index e8df21a..e8df21a 100644 --- a/arch/mips/ralink/dts/rt3883_eval.dts +++ b/arch/mips/boot/dts/rt3883_eval.dts diff --git a/arch/mips/mti-sead3/sead3.dts b/arch/mips/boot/dts/sead3.dts index e4b317d..e4b317d 100644 --- a/arch/mips/mti-sead3/sead3.dts +++ b/arch/mips/boot/dts/sead3.dts diff --git a/arch/mips/netlogic/dts/xlp_evp.dts b/arch/mips/boot/dts/xlp_evp.dts index 89ad048..89ad048 100644 --- a/arch/mips/netlogic/dts/xlp_evp.dts +++ b/arch/mips/boot/dts/xlp_evp.dts diff --git a/arch/mips/netlogic/dts/xlp_fvp.dts b/arch/mips/boot/dts/xlp_fvp.dts index 63e62b7..63e62b7 100644 --- a/arch/mips/netlogic/dts/xlp_fvp.dts +++ b/arch/mips/boot/dts/xlp_fvp.dts diff --git a/arch/mips/netlogic/dts/xlp_gvp.dts b/arch/mips/boot/dts/xlp_gvp.dts index bb4ecd1..bb4ecd1 100644 --- a/arch/mips/netlogic/dts/xlp_gvp.dts +++ b/arch/mips/boot/dts/xlp_gvp.dts diff --git a/arch/mips/netlogic/dts/xlp_svp.dts b/arch/mips/boot/dts/xlp_svp.dts index 1ebd00ed..1ebd00ed 100644 --- a/arch/mips/netlogic/dts/xlp_svp.dts +++ b/arch/mips/boot/dts/xlp_svp.dts diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore deleted file mode 100644 index 39c96860..0000000 --- a/arch/mips/cavium-octeon/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.dtb.S -*.dtb diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index 4e95204..42f5f1a 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile @@ -20,13 +20,3 @@ obj-y += executive/ obj-$(CONFIG_MTD) += flash_setup.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o - -DTS_FILES = octeon_3xxx.dts octeon_68xx.dts -DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES)) - -obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES)) - -# Let's keep the .dtb files around in case we want to look at them. -.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES)) - -clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES)) diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index 0abe681..dae9354 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -31,8 +31,8 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y CONFIG_MTD=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y diff --git a/arch/mips/configs/sead3micro_defconfig b/arch/mips/configs/sead3micro_defconfig index 2a0da5b..cd91a77 100644 --- a/arch/mips/configs/sead3micro_defconfig +++ b/arch/mips/configs/sead3micro_defconfig @@ -32,8 +32,8 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y CONFIG_MTD=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 57012ef..72e1cf1 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -1,6 +1,7 @@ # MIPS headers generic-y += cputime.h generic-y += current.h +generic-y += dma-contiguous.h generic-y += emergency-restart.h generic-y += hash.h generic-y += irq_work.h diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index e079598..3325f3e 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -231,6 +231,16 @@ #define cpu_has_clo_clz cpu_has_mips_r #endif +/* + * MIPS32 R2, MIPS64 R2, Loongson 3A and Octeon have WSBH. + * MIPS64 R2, Loongson 3A and Octeon have WSBH, DSBH and DSHD. + * This indicates the availability of WSBH and in case of 64 bit CPUs also + * DSBH and DSHD. + */ +#ifndef cpu_has_wsbh +#define cpu_has_wsbh cpu_has_mips_r2 +#endif + #ifndef cpu_has_dsp #define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP) #endif diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index d5f42c1..a6c9ccb 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -79,6 +79,11 @@ struct cpuinfo_mips { #define NUM_WATCH_REGS 4 u16 watch_reg_masks[NUM_WATCH_REGS]; unsigned int kscratch_mask; /* Usable KScratch mask. */ + /* + * Cache Coherency attribute for write-combine memory writes. + * (shifted by _CACHE_SHIFT) + */ + unsigned int writecombine; } __attribute__((aligned(SMP_CACHE_BYTES))); extern struct cpuinfo_mips cpu_data[]; diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h index 09f45e6..c5b6eef 100644 --- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h @@ -8,6 +8,12 @@ #define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H #define cpu_has_tlb 1 +#define cpu_has_tlbinv 0 +#define cpu_has_segments 0 +#define cpu_has_eva 0 +#define cpu_has_htw 0 +#define cpu_has_rixiex 0 +#define cpu_has_maar 0 #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 @@ -28,6 +34,8 @@ #define cpu_has_mdmx 0 #define cpu_has_mips3d 0 #define cpu_has_smartmips 0 +#define cpu_has_rixi 0 +#define cpu_has_mmips 0 #define cpu_has_vtag_icache 0 #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 1 @@ -50,4 +58,8 @@ #define cpu_dcache_line_size() 32 #define cpu_icache_line_size() 32 +#define cpu_has_perf_cntr_intr_bit 0 +#define cpu_has_vz 0 +#define cpu_has_msa 0 + #endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index cf80228..fa1f3cf 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -57,6 +57,7 @@ #define cpu_has_vint 0 #define cpu_has_veic 0 #define cpu_hwrena_impl_bits 0xc0000000 +#define cpu_has_wsbh 1 #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h index c0f3ef4..7d28f95 100644 --- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h @@ -59,4 +59,6 @@ #define cpu_has_watch 1 #define cpu_has_local_ebase 0 +#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) + #endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index e592f36..e747bfa 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -224,38 +224,52 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define _CACHE_CACHABLE_NONCOHERENT 0 +#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED #elif defined(CONFIG_CPU_SB1) /* No penalty for being coherent on the SB1, so just use it for "noncoherent" spaces, too. Shouldn't hurt. */ -#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) -#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT) #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) -#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) #elif defined(CONFIG_CPU_LOONGSON3) /* Using COHERENT flag for NONCOHERENT doesn't hurt. */ -#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) /* LOONGSON */ #define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */ #define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */ -#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) /* LOONGSON */ -#else +#elif defined(CONFIG_MACH_JZ4740) + +/* Ingenic uses the WA bit to achieve write-combine memory writes */ +#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT) -#define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT) /* R4600 only */ -#define _CACHE_CACHABLE_WA (1<<_CACHE_SHIFT) /* R4600 only */ -#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) /* R4[0246]00 */ -#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* R4[0246]00 */ -#define _CACHE_CACHABLE_CE (4<<_CACHE_SHIFT) /* R4[04]00MC only */ -#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT) /* R4[04]00MC only */ -#define _CACHE_CACHABLE_COHERENT (5<<_CACHE_SHIFT) /* MIPS32R2 CMP */ -#define _CACHE_CACHABLE_CUW (6<<_CACHE_SHIFT) /* R4[04]00MC only */ -#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) /* R10000 only */ +#endif +#ifndef _CACHE_CACHABLE_NO_WA +#define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_CACHABLE_WA +#define _CACHE_CACHABLE_WA (1<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_UNCACHED +#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_CACHABLE_NONCOHERENT +#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_CACHABLE_CE +#define _CACHE_CACHABLE_CE (4<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_CACHABLE_COW +#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_CACHABLE_CUW +#define _CACHE_CACHABLE_CUW (6<<_CACHE_SHIFT) +#endif +#ifndef _CACHE_UNCACHED_ACCELERATED +#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) #endif #define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ)) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index df49a30..d6d1928 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -366,6 +366,16 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) return __pgprot(prot); } +static inline pgprot_t pgprot_writecombine(pgprot_t _prot) +{ + unsigned long prot = pgprot_val(_prot); + + /* cpu_data[0].writecombine is already shifted by _CACHE_SHIFT */ + prot = (prot & ~_CACHE_MASK) | cpu_data[0].writecombine; + + return __pgprot(prot); +} + /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index cdf68b3..bb79637 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -129,7 +129,7 @@ extern const unsigned long sysn32_call_table[]; static inline int syscall_get_arch(void) { - int arch = EM_MIPS; + int arch = AUDIT_ARCH_MIPS; #ifdef CONFIG_64BIT if (!test_thread_flag(TIF_32BIT_REGS)) { arch |= __AUDIT_ARCH_64BIT; diff --git a/arch/mips/include/uapi/asm/swab.h b/arch/mips/include/uapi/asm/swab.h index ac9a8f9..8f2d184 100644 --- a/arch/mips/include/uapi/asm/swab.h +++ b/arch/mips/include/uapi/asm/swab.h @@ -13,12 +13,16 @@ #define __SWAB_64_THRU_32__ -#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2) +#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \ + defined(_MIPS_ARCH_LOONGSON3A) static inline __attribute_const__ __u16 __arch_swab16(__u16 x) { __asm__( + " .set push \n" + " .set arch=mips32r2 \n" " wsbh %0, %1 \n" + " .set pop \n" : "=r" (x) : "r" (x)); @@ -29,8 +33,11 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x) static inline __attribute_const__ __u32 __arch_swab32(__u32 x) { __asm__( + " .set push \n" + " .set arch=mips32r2 \n" " wsbh %0, %1 \n" " rotr %0, %0, 16 \n" + " .set pop \n" : "=r" (x) : "r" (x)); @@ -46,8 +53,11 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) static inline __attribute_const__ __u64 __arch_swab64(__u64 x) { __asm__( - " dsbh %0, %1\n" - " dshd %0, %0" + " .set push \n" + " .set arch=mips64r2 \n" + " dsbh %0, %1 \n" + " dshd %0, %0 \n" + " .set pop \n" : "=r" (x) : "r" (x)); @@ -55,5 +65,5 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x) } #define __arch_swab64 __arch_swab64 #endif /* __mips64 */ -#endif /* MIPS R2 or newer */ +#endif /* MIPS R2 or newer or Loongson 3A */ #endif /* _ASM_SWAB_H */ diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e34b10b..94c4a0c 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -27,6 +27,7 @@ #include <asm/msa.h> #include <asm/watch.h> #include <asm/elf.h> +#include <asm/pgtable-bits.h> #include <asm/spram.h> #include <asm/uaccess.h> @@ -764,6 +765,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) break; case PRID_REV_LOONGSON3A: c->cputype = CPU_LOONGSON3; + c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); break; @@ -798,67 +800,83 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) { + c->writecombine = _CACHE_UNCACHED_ACCELERATED; switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_4KC: c->cputype = CPU_4KC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 4Kc"; break; case PRID_IMP_4KEC: case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 4KEc"; break; case PRID_IMP_4KSC: case PRID_IMP_4KSD: c->cputype = CPU_4KSC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 4KSc"; break; case PRID_IMP_5KC: c->cputype = CPU_5KC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 5Kc"; break; case PRID_IMP_5KE: c->cputype = CPU_5KE; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 5KE"; break; case PRID_IMP_20KC: c->cputype = CPU_20KC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 20Kc"; break; case PRID_IMP_24K: c->cputype = CPU_24K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 24Kc"; break; case PRID_IMP_24KE: c->cputype = CPU_24K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 24KEc"; break; case PRID_IMP_25KF: c->cputype = CPU_25KF; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 25Kc"; break; case PRID_IMP_34K: c->cputype = CPU_34K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 34Kc"; break; case PRID_IMP_74K: c->cputype = CPU_74K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 74Kc"; break; case PRID_IMP_M14KC: c->cputype = CPU_M14KC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS M14Kc"; break; case PRID_IMP_M14KEC: c->cputype = CPU_M14KEC; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS M14KEc"; break; case PRID_IMP_1004K: c->cputype = CPU_1004K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 1004Kc"; break; case PRID_IMP_1074K: c->cputype = CPU_1074K; + c->writecombine = _CACHE_UNCACHED; __cpu_name[cpu] = "MIPS 1074Kc"; break; case PRID_IMP_INTERAPTIV_UP: @@ -932,6 +950,7 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); + c->writecombine = _CACHE_UNCACHED_ACCELERATED; switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_SB1: c->cputype = CPU_SB1; @@ -1063,6 +1082,7 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) switch (c->processor_id & PRID_IMP_MASK) { case PRID_IMP_JZRISC: c->cputype = CPU_JZRISC; + c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] = "Ingenic JZRISC"; break; default: @@ -1169,6 +1189,7 @@ void cpu_probe(void) c->processor_id = PRID_IMP_UNKNOWN; c->fpu_id = FPIR_IMP_NONE; c->cputype = CPU_UNKNOWN; + c->writecombine = _CACHE_UNCACHED; c->processor_id = read_c0_prid(); switch (c->processor_id & PRID_COMP_MASK) { diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index f7aac5b..9d1487d 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -780,9 +780,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[2]); - audit_syscall_entry(syscall_get_arch(), - syscall, - regs->regs[4], regs->regs[5], + audit_syscall_entry(syscall, regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); return syscall; } diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 7c1fe2b..b3b8f0d 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -24,6 +24,8 @@ #include <linux/debugfs.h> #include <linux/kexec.h> #include <linux/sizes.h> +#include <linux/device.h> +#include <linux/dma-contiguous.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> @@ -476,6 +478,7 @@ static void __init bootmem_init(void) * o bootmem_init() * o sparse_init() * o paging_init() + * o dma_continguous_reserve() * * At this stage the bootmem allocator is ready to use. * @@ -609,6 +612,7 @@ static void __init request_crashkernel(struct resource *res) static void __init arch_mem_init(char **cmdline_p) { + struct memblock_region *reg; extern void plat_mem_setup(void); /* call board setup routine */ @@ -675,6 +679,11 @@ static void __init arch_mem_init(char **cmdline_p) sparse_init(); plat_swiotlb_setup(); paging_init(); + + dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); + /* Tell bootmem about cma reserved memblock section */ + for_each_memblock(reserved, reg) + reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); } static void __init resource_init(void) diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index c002191..e10d333 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -30,6 +30,7 @@ choice config DT_EASY50712 bool "Easy50712" depends on SOC_XWAY + select BUILTIN_DTB endchoice config PCI_LANTIQ diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index d6bdc57..690257a 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile @@ -6,8 +6,6 @@ obj-y := irq.o clk.o prom.o -obj-y += dts/ - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile deleted file mode 100644 index 6fa72dd..0000000 --- a/arch/mips/lantiq/dts/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 9901237..4c721e2 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -277,9 +277,12 @@ LEAF(csum_partial) #endif /* odd buffer alignment? */ -#ifdef CONFIG_CPU_MIPSR2 +#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3) + .set push + .set arch=mips32r2 wsbh v1, sum movn sum, v1, t7 + .set pop #else beqz t7, 1f /* odd buffer alignment? */ lui v1, 0x00ff @@ -726,9 +729,12 @@ LEAF(csum_partial) addu sum, v1 #endif -#ifdef CONFIG_CPU_MIPSR2 +#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3) + .set push + .set arch=mips32r2 wsbh v1, sum movn sum, v1, odd + .set pop #else beqz odd, 1f /* odd buffer alignment? */ lui v1, 0x00ff diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 44b6dff..33ba3c5 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -16,6 +16,7 @@ #include <linux/string.h> #include <linux/gfp.h> #include <linux/highmem.h> +#include <linux/dma-contiguous.h> #include <asm/cache.h> #include <asm/cpu-type.h> @@ -128,23 +129,30 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) { void *ret; + struct page *page = NULL; + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) return ret; gfp = massage_gfp_flags(dev, gfp); - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret) { - memset(ret, 0, size); - *dma_handle = plat_map_dma_mem(dev, ret, size); - - if (!plat_device_is_coherent(dev)) { - dma_cache_wback_inv((unsigned long) ret, size); - if (!hw_coherentio) - ret = UNCAC_ADDR(ret); - } + if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC)) + page = dma_alloc_from_contiguous(dev, + count, get_order(size)); + if (!page) + page = alloc_pages(gfp, get_order(size)); + + if (!page) + return NULL; + + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = plat_map_dma_mem(dev, ret, size); + if (!plat_device_is_coherent(dev)) { + dma_cache_wback_inv((unsigned long) ret, size); + if (!hw_coherentio) + ret = UNCAC_ADDR(ret); } return ret; @@ -164,6 +172,8 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, { unsigned long addr = (unsigned long) vaddr; int order = get_order(size); + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct page *page = NULL; if (dma_release_from_coherent(dev, order, vaddr)) return; @@ -173,7 +183,10 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, if (!plat_device_is_coherent(dev) && !hw_coherentio) addr = CAC_ADDR(addr); - free_pages(addr, get_order(size)); + page = virt_to_page((void *) addr); + + if (!dma_release_from_contiguous(dev, page, count)) + __free_pages(page, get_order(size)); } static inline void __dma_sync_virtual(void *addr, size_t size, diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index 071786f..febf433 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -19,9 +19,5 @@ obj-y += sead3-i2c-dev.o sead3-i2c.o \ obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o obj-$(CONFIG_USB_EHCI_HCD) += sead3-ehci.o -obj-$(CONFIG_OF) += sead3.dtb.o CFLAGS_sead3-setup.o = -I$(src)/../../../scripts/dtc/libfdt - -$(obj)/%.dtb: $(obj)/%.dts - $(call if_changed,dtc) diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 7edc083..9b55143 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c @@ -163,6 +163,19 @@ do { \ (ctx)->idx++; \ } while (0) +/* + * Similar to emit_instr but it must be used when we need to emit + * 32-bit or 64-bit instructions + */ +#define emit_long_instr(ctx, func, ...) \ +do { \ + if ((ctx)->target != NULL) { \ + u32 *p = &(ctx)->target[ctx->idx]; \ + UASM_i_##func(&p, ##__VA_ARGS__); \ + } \ + (ctx)->idx++; \ +} while (0) + /* Determine if immediate is within the 16-bit signed range */ static inline bool is_range16(s32 imm) { @@ -218,13 +231,6 @@ static inline void emit_ori(unsigned int dst, unsigned src, u32 imm, } } - -static inline void emit_daddu(unsigned int dst, unsigned int src1, - unsigned int src2, struct jit_ctx *ctx) -{ - emit_instr(ctx, daddu, dst, src1, src2); -} - static inline void emit_daddiu(unsigned int dst, unsigned int src, int imm, struct jit_ctx *ctx) { @@ -283,11 +289,7 @@ static inline void emit_xori(ptr dst, ptr src, u32 imm, struct jit_ctx *ctx) static inline void emit_stack_offset(int offset, struct jit_ctx *ctx) { - if (config_enabled(CONFIG_64BIT)) - emit_instr(ctx, daddiu, r_sp, r_sp, offset); - else - emit_instr(ctx, addiu, r_sp, r_sp, offset); - + emit_long_instr(ctx, ADDIU, r_sp, r_sp, offset); } static inline void emit_subu(unsigned int dst, unsigned int src1, @@ -365,10 +367,7 @@ static inline void emit_store_stack_reg(ptr reg, ptr base, unsigned int offset, struct jit_ctx *ctx) { - if (config_enabled(CONFIG_64BIT)) - emit_instr(ctx, sd, reg, offset, base); - else - emit_instr(ctx, sw, reg, offset, base); + emit_long_instr(ctx, SW, reg, offset, base); } static inline void emit_store(ptr reg, ptr base, unsigned int offset, @@ -381,10 +380,7 @@ static inline void emit_load_stack_reg(ptr reg, ptr base, unsigned int offset, struct jit_ctx *ctx) { - if (config_enabled(CONFIG_64BIT)) - emit_instr(ctx, ld, reg, offset, base); - else - emit_instr(ctx, lw, reg, offset, base); + emit_long_instr(ctx, LW, reg, offset, base); } static inline void emit_load(unsigned int reg, unsigned int base, @@ -458,10 +454,7 @@ static inline void emit_load_ptr(unsigned int dst, unsigned int src, int imm, struct jit_ctx *ctx) { /* src contains the base addr of the 32/64-pointer */ - if (config_enabled(CONFIG_64BIT)) - emit_instr(ctx, ld, dst, imm, src); - else - emit_instr(ctx, lw, dst, imm, src); + emit_long_instr(ctx, LW, dst, imm, src); } /* load a function pointer to register */ @@ -483,10 +476,7 @@ static inline void emit_load_func(unsigned int reg, ptr imm, /* Move to real MIPS register */ static inline void emit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx) { - if (config_enabled(CONFIG_64BIT)) - emit_daddu(dst, src, r_zero, ctx); - else - emit_addu(dst, src, r_zero, ctx); + emit_long_instr(ctx, ADDU, dst, src, r_zero); } /* Move to JIT (32-bit) register */ @@ -623,10 +613,7 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) if (ctx->flags & SEEN_MEM) { if (real_off % (RSIZE * 2)) real_off += RSIZE; - if (config_enabled(CONFIG_64BIT)) - emit_daddiu(r_M, r_sp, real_off, ctx); - else - emit_addiu(r_M, r_sp, real_off, ctx); + emit_long_instr(ctx, ADDIU, r_M, r_sp, real_off); } } @@ -1241,7 +1228,7 @@ jmp_cmp: emit_half_load(r_A, r_skb, off, ctx); #ifdef CONFIG_CPU_LITTLE_ENDIAN /* This needs little endian fixup */ - if (cpu_has_mips_r2) { + if (cpu_has_wsbh) { /* R2 and later have the wsbh instruction */ emit_wsbh(r_A, r_A, ctx); } else { diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig index 4eb683a..0823321 100644 --- a/arch/mips/netlogic/Kconfig +++ b/arch/mips/netlogic/Kconfig @@ -4,6 +4,7 @@ if NLM_XLP_BOARD config DT_XLP_EVP bool "Built-in device tree for XLP EVP boards" default y + select BUILTIN_DTB help Add an FDT blob for XLP EVP boards into the kernel. This DTB will be used if the firmware does not pass in a DTB @@ -13,6 +14,7 @@ config DT_XLP_EVP config DT_XLP_SVP bool "Built-in device tree for XLP SVP boards" default y + select BUILTIN_DTB help Add an FDT blob for XLP VP boards into the kernel. This DTB will be used if the firmware does not pass in a DTB @@ -22,6 +24,7 @@ config DT_XLP_SVP config DT_XLP_FVP bool "Built-in device tree for XLP FVP boards" default y + select BUILTIN_DTB help Add an FDT blob for XLP FVP board into the kernel. This DTB will be used if the firmware does not pass in a DTB @@ -31,6 +34,7 @@ config DT_XLP_FVP config DT_XLP_GVP bool "Built-in device tree for XLP GVP boards" default y + select BUILTIN_DTB help Add an FDT blob for XLP GVP board into the kernel. This DTB will be used if the firmware does not pass in a DTB diff --git a/arch/mips/netlogic/Makefile b/arch/mips/netlogic/Makefile index 7602d13..36d169b 100644 --- a/arch/mips/netlogic/Makefile +++ b/arch/mips/netlogic/Makefile @@ -1,4 +1,3 @@ obj-$(CONFIG_NLM_COMMON) += common/ obj-$(CONFIG_CPU_XLR) += xlr/ obj-$(CONFIG_CPU_XLP) += xlp/ -obj-$(CONFIG_CPU_XLP) += dts/ diff --git a/arch/mips/netlogic/dts/Makefile b/arch/mips/netlogic/dts/Makefile deleted file mode 100644 index 25c8e87..0000000 --- a/arch/mips/netlogic/dts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o -obj-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb.o -obj-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb.o -obj-$(CONFIG_DT_XLP_GVP) += xlp_gvp.dtb.o diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 4a29665..77e8a96 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -42,18 +42,22 @@ choice config DTB_RT2880_EVAL bool "RT2880 eval kit" depends on SOC_RT288X + select BUILTIN_DTB config DTB_RT305X_EVAL bool "RT305x eval kit" depends on SOC_RT305X + select BUILTIN_DTB config DTB_RT3883_EVAL bool "RT3883 eval kit" depends on SOC_RT3883 + select BUILTIN_DTB config DTB_MT7620A_EVAL bool "MT7620A eval kit" depends on SOC_MT7620 + select BUILTIN_DTB endchoice diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 98ae349..2c09c8a 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile @@ -16,5 +16,3 @@ obj-$(CONFIG_SOC_RT3883) += rt3883.o obj-$(CONFIG_SOC_MT7620) += mt7620.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - -obj-y += dts/ diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile deleted file mode 100644 index 18194fa..0000000 --- a/arch/mips/ralink/dts/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o -obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o -obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o -obj-$(CONFIG_DTB_MT7620A_EVAL) := mt7620a_eval.dtb.o diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index e38692a..5bb29b3 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -58,7 +58,7 @@ static irqreturn_t rt_timer_irq(int irq, void *_rt) static int rt_timer_request(struct rt_timer *rt) { - int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED, + int err = request_irq(rt->irq, rt_timer_irq, 0, dev_name(rt->dev), rt); if (err) { dev_err(rt->dev, "failed to request irq\n"); diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h index b752bb6..2db9f1c 100644 --- a/arch/openrisc/include/asm/syscall.h +++ b/arch/openrisc/include/asm/syscall.h @@ -19,6 +19,7 @@ #ifndef __ASM_OPENRISC_SYSCALL_H__ #define __ASM_OPENRISC_SYSCALL_H__ +#include <uapi/linux/audit.h> #include <linux/err.h> #include <linux/sched.h> @@ -71,4 +72,8 @@ syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, memcpy(®s->gpr[3 + i], args, n * sizeof(args[0])); } +static inline int syscall_get_arch(void) +{ + return AUDIT_ARCH_OPENRISC; +} #endif diff --git a/arch/openrisc/include/uapi/asm/elf.h b/arch/openrisc/include/uapi/asm/elf.h index f02ea58..8884276 100644 --- a/arch/openrisc/include/uapi/asm/elf.h +++ b/arch/openrisc/include/uapi/asm/elf.h @@ -55,9 +55,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; /* A placeholder; OR32 does not have fp support yes, so no fp regs for now. */ typedef unsigned long elf_fpregset_t; -/* This should be moved to include/linux/elf.h */ +/* EM_OPENRISC is defined in linux/elf-em.h */ #define EM_OR32 0x8472 -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ /* * These are used to set parameters in the core dumps. diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c index 71a2a0c..4f59fa4 100644 --- a/arch/openrisc/kernel/ptrace.c +++ b/arch/openrisc/kernel/ptrace.c @@ -187,8 +187,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) */ ret = -1L; - audit_syscall_entry(AUDIT_ARCH_OPENRISC, regs->gpr[11], - regs->gpr[3], regs->gpr[4], + audit_syscall_entry(regs->gpr[11], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]); return ret ? : regs->gpr[11]; diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index 8bdfd2c..a5eba95 100644 --- a/arch/parisc/include/asm/syscall.h +++ b/arch/parisc/include/asm/syscall.h @@ -3,6 +3,8 @@ #ifndef _ASM_PARISC_SYSCALL_H_ #define _ASM_PARISC_SYSCALL_H_ +#include <uapi/linux/audit.h> +#include <linux/compat.h> #include <linux/err.h> #include <asm/ptrace.h> @@ -37,4 +39,13 @@ static inline void syscall_get_arguments(struct task_struct *tsk, } } +static inline int syscall_get_arch(void) +{ + int arch = AUDIT_ARCH_PARISC; +#ifdef CONFIG_64BIT + if (!is_compat_task()) + arch = AUDIT_ARCH_PARISC64; +#endif + return arch; +} #endif /*_ASM_PARISC_SYSCALL_H_*/ diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 92438c2..9585c81 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -280,14 +280,11 @@ long do_syscall_trace_enter(struct pt_regs *regs) #ifdef CONFIG_64BIT if (!is_compat_task()) - audit_syscall_entry(AUDIT_ARCH_PARISC64, - regs->gr[20], - regs->gr[26], regs->gr[25], - regs->gr[24], regs->gr[23]); + audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25], + regs->gr[24], regs->gr[23]); else #endif - audit_syscall_entry(AUDIT_ARCH_PARISC, - regs->gr[20] & 0xffffffff, + audit_syscall_entry(regs->gr[20] & 0xffffffff, regs->gr[26] & 0xffffffff, regs->gr[25] & 0xffffffff, regs->gr[24] & 0xffffffff, diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h index b54b2ad..6fa2708 100644 --- a/arch/powerpc/include/asm/syscall.h +++ b/arch/powerpc/include/asm/syscall.h @@ -13,7 +13,9 @@ #ifndef _ASM_SYSCALL_H #define _ASM_SYSCALL_H 1 +#include <uapi/linux/audit.h> #include <linux/sched.h> +#include <linux/thread_info.h> /* ftrace syscalls requires exporting the sys_call_table */ #ifdef CONFIG_FTRACE_SYSCALLS @@ -86,4 +88,8 @@ static inline void syscall_set_arguments(struct task_struct *task, memcpy(®s->gpr[3 + i], args, n * sizeof(args[0])); } +static inline int syscall_get_arch(void) +{ + return is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64; +} #endif /* _ASM_SYSCALL_H */ diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index bd70a51..e5dad9a 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -747,7 +747,11 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, break; } if (res != NULL) { - of_pci_range_to_resource(&range, dev, res); + res->name = dev->full_name; + res->flags = range.flags; + res->start = range.cpu_addr; + res->end = range.cpu_addr + range.size - 1; + res->parent = res->child = res->sibling = NULL; } } } diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index cdb404e..f21897b 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1788,14 +1788,11 @@ long do_syscall_trace_enter(struct pt_regs *regs) #ifdef CONFIG_PPC64 if (!is_32bit_task()) - audit_syscall_entry(AUDIT_ARCH_PPC64, - regs->gpr[0], - regs->gpr[3], regs->gpr[4], + audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]); else #endif - audit_syscall_entry(AUDIT_ARCH_PPC, - regs->gpr[0], + audit_syscall_entry(regs->gpr[0], regs->gpr[3] & 0xffffffff, regs->gpr[4] & 0xffffffff, regs->gpr[5] & 0xffffffff, diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f537e93..99a567b 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -834,9 +834,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->gprs[2]); - audit_syscall_entry(is_compat_task() ? - AUDIT_ARCH_S390 : AUDIT_ARCH_S390X, - regs->gprs[2], regs->orig_gpr2, + audit_syscall_entry(regs->gprs[2], regs->orig_gpr2, regs->gprs[3], regs->gprs[4], regs->gprs[5]); out: diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h index 7d80df4..95be3b0 100644 --- a/arch/sh/include/asm/syscall_32.h +++ b/arch/sh/include/asm/syscall_32.h @@ -1,6 +1,7 @@ #ifndef __ASM_SH_SYSCALL_32_H #define __ASM_SH_SYSCALL_32_H +#include <uapi/linux/audit.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/err.h> @@ -93,4 +94,13 @@ static inline void syscall_set_arguments(struct task_struct *task, } } +static inline int syscall_get_arch(void) +{ + int arch = AUDIT_ARCH_SH; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + arch |= __AUDIT_ARCH_LE; +#endif + return arch; +} #endif /* __ASM_SH_SYSCALL_32_H */ diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h index c3561ca..c6a797b 100644 --- a/arch/sh/include/asm/syscall_64.h +++ b/arch/sh/include/asm/syscall_64.h @@ -1,6 +1,7 @@ #ifndef __ASM_SH_SYSCALL_64_H #define __ASM_SH_SYSCALL_64_H +#include <uapi/linux/audit.h> #include <linux/kernel.h> #include <linux/sched.h> #include <asm/ptrace.h> @@ -61,4 +62,17 @@ static inline void syscall_set_arguments(struct task_struct *task, memcpy(®s->regs[2 + i], args, n * sizeof(args[0])); } +static inline int syscall_get_arch(void) +{ + int arch = AUDIT_ARCH_SH; + +#ifdef CONFIG_64BIT + arch |= __AUDIT_ARCH_64BIT; +#endif +#ifdef CONFIG_CPU_LITTLE_ENDIAN + arch |= __AUDIT_ARCH_LE; +#endif + + return arch; +} #endif /* __ASM_SH_SYSCALL_64_H */ diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 668c816..c1a6b89 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -484,17 +484,6 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -static inline int audit_arch(void) -{ - int arch = EM_SH; - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - arch |= __AUDIT_ARCH_LE; -#endif - - return arch; -} - asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; @@ -513,8 +502,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[0]); - audit_syscall_entry(audit_arch(), regs->regs[3], - regs->regs[4], regs->regs[5], + audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); return ret ?: regs->regs[0]; diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index af90339..5cea973 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -504,20 +504,6 @@ asmlinkage int sh64_ptrace(long request, long pid, return sys_ptrace(request, pid, addr, data); } -static inline int audit_arch(void) -{ - int arch = EM_SH; - -#ifdef CONFIG_64BIT - arch |= __AUDIT_ARCH_64BIT; -#endif -#ifdef CONFIG_CPU_LITTLE_ENDIAN - arch |= __AUDIT_ARCH_LE; -#endif - - return arch; -} - asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) { long long ret = 0; @@ -536,8 +522,7 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[9]); - audit_syscall_entry(audit_arch(), regs->regs[1], - regs->regs[2], regs->regs[3], + audit_syscall_entry(regs->regs[1], regs->regs[2], regs->regs[3], regs->regs[4], regs->regs[5]); return ret ?: regs->regs[9]; diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h index 025a02a..49f71fd 100644 --- a/arch/sparc/include/asm/syscall.h +++ b/arch/sparc/include/asm/syscall.h @@ -1,9 +1,11 @@ #ifndef __ASM_SPARC_SYSCALL_H #define __ASM_SPARC_SYSCALL_H +#include <uapi/linux/audit.h> #include <linux/kernel.h> #include <linux/sched.h> #include <asm/ptrace.h> +#include <asm/thread_info.h> /* * The syscall table always contains 32 bit pointers since we know that the @@ -124,4 +126,9 @@ static inline void syscall_set_arguments(struct task_struct *task, regs->u_regs[UREG_I0 + i + j] = args[j]; } +static inline int syscall_get_arch(void) +{ + return is_32bit_task() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64; +} + #endif /* __ASM_SPARC_SYSCALL_H */ diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index 96efa7a..025c984 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h @@ -130,6 +130,8 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ _TIF_SIGPENDING) +#define is_32bit_task() (1) + #endif /* __KERNEL__ */ #endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index f85dc85..798f027 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -63,7 +63,8 @@ struct thread_info { struct pt_regs *kern_una_regs; unsigned int kern_una_insn; - unsigned long fpregs[0] __attribute__ ((aligned(64))); + unsigned long fpregs[(7 * 256) / sizeof(unsigned long)] + __attribute__ ((aligned(64))); }; #endif /* !(__ASSEMBLY__) */ @@ -220,6 +221,8 @@ register struct thread_info *current_thread_info_reg asm("g6"); _TIF_NEED_RESCHED) #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING) +#define is_32bit_task() (test_thread_flag(TIF_32BIT)) + /* * Thread-synchronous status. * diff --git a/arch/sparc/include/asm/visasm.h b/arch/sparc/include/asm/visasm.h index b266737..1f0aa20 100644 --- a/arch/sparc/include/asm/visasm.h +++ b/arch/sparc/include/asm/visasm.h @@ -39,6 +39,14 @@ 297: wr %o5, FPRS_FEF, %fprs; \ 298: +#define VISEntryHalfFast(fail_label) \ + rd %fprs, %o5; \ + andcc %o5, FPRS_FEF, %g0; \ + be,pt %icc, 297f; \ + nop; \ + ba,a,pt %xcc, fail_label; \ +297: wr %o5, FPRS_FEF, %fprs; + #define VISExitHalf \ wr %o5, 0, %fprs; diff --git a/arch/sparc/kernel/dtlb_prot.S b/arch/sparc/kernel/dtlb_prot.S index b2c2c5b..d668ca14 100644 --- a/arch/sparc/kernel/dtlb_prot.S +++ b/arch/sparc/kernel/dtlb_prot.S @@ -24,11 +24,11 @@ mov TLB_TAG_ACCESS, %g4 ! For reload of vaddr /* PROT ** ICACHE line 2: More real fault processing */ + ldxa [%g4] ASI_DMMU, %g5 ! Put tagaccess in %g5 bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup - ldxa [%g4] ASI_DMMU, %g5 ! Put tagaccess in %g5 - ba,pt %xcc, sparc64_realfault_common ! Nope, normal fault mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 - nop + ba,pt %xcc, sparc64_realfault_common ! Nope, normal fault + nop nop nop nop diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index c13c9f2..9ddc492 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -1076,13 +1076,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->u_regs[UREG_G1]); - audit_syscall_entry((test_thread_flag(TIF_32BIT) ? - AUDIT_ARCH_SPARC : - AUDIT_ARCH_SPARC64), - regs->u_regs[UREG_G1], - regs->u_regs[UREG_I0], - regs->u_regs[UREG_I1], - regs->u_regs[UREG_I2], + audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0], + regs->u_regs[UREG_I1], regs->u_regs[UREG_I2], regs->u_regs[UREG_I3]); return ret; diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index 14158d4..be98685 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -162,10 +162,10 @@ tsb_miss_page_table_walk_sun4v_fastpath: nop .previous - rdpr %tl, %g3 - cmp %g3, 1 + rdpr %tl, %g7 + cmp %g7, 1 bne,pn %xcc, winfix_trampoline - nop + mov %g3, %g4 ba,pt %xcc, etrap rd %pc, %g7 call hugetlb_setup diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S index 9cf2ee0..140527a 100644 --- a/arch/sparc/lib/NG4memcpy.S +++ b/arch/sparc/lib/NG4memcpy.S @@ -41,6 +41,10 @@ #endif #endif +#if !defined(EX_LD) && !defined(EX_ST) +#define NON_USER_COPY +#endif + #ifndef EX_LD #define EX_LD(x) x #endif @@ -197,9 +201,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ mov EX_RETVAL(%o3), %o0 .Llarge_src_unaligned: +#ifdef NON_USER_COPY + VISEntryHalfFast(.Lmedium_vis_entry_fail) +#else + VISEntryHalf +#endif andn %o2, 0x3f, %o4 sub %o2, %o4, %o2 - VISEntryHalf alignaddr %o1, %g0, %g1 add %o1, %o4, %o1 EX_LD(LOAD(ldd, %g1 + 0x00, %f0)) @@ -240,6 +248,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ nop ba,a,pt %icc, .Lmedium_unaligned +#ifdef NON_USER_COPY +.Lmedium_vis_entry_fail: + or %o0, %o1, %g2 +#endif .Lmedium: LOAD(prefetch, %o1 + 0x40, #n_reads_strong) andcc %g2, 0x7, %g0 diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 694d551..62435ef 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -165,8 +165,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, */ void syscall_trace_enter(struct pt_regs *regs) { - audit_syscall_entry(HOST_AUDIT_ARCH, - UPT_SYSCALL_NR(®s->regs), + audit_syscall_entry(UPT_SYSCALL_NR(®s->regs), UPT_SYSCALL_ARG1(®s->regs), UPT_SYSCALL_ARG2(®s->regs), UPT_SYSCALL_ARG3(®s->regs), diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 711de08..8ffba18 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -198,12 +198,12 @@ sysexit_from_sys_call: #ifdef CONFIG_AUDITSYSCALL .macro auditsys_entry_common - movl %esi,%r9d /* 6th arg: 4th syscall arg */ - movl %edx,%r8d /* 5th arg: 3rd syscall arg */ - /* (already in %ecx) 4th arg: 2nd syscall arg */ - movl %ebx,%edx /* 3rd arg: 1st syscall arg */ - movl %eax,%esi /* 2nd arg: syscall number */ - movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ + movl %esi,%r8d /* 5th arg: 4th syscall arg */ + movl %ecx,%r9d /*swap with edx*/ + movl %edx,%ecx /* 4th arg: 3rd syscall arg */ + movl %r9d,%edx /* 3rd arg: 2nd syscall arg */ + movl %ebx,%esi /* 2nd arg: 1st syscall arg */ + movl %eax,%edi /* 1st arg: syscall number */ call __audit_syscall_entry movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ cmpq $(IA32_NR_syscalls-1),%rax diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 3bf000f..d55a210 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -6,6 +6,7 @@ genhdr-y += unistd_x32.h generic-y += clkdev.h generic-y += cputime.h +generic-y += dma-contiguous.h generic-y += early_ioremap.h generic-y += mcs_spinlock.h generic-y += scatterlist.h diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h deleted file mode 100644 index b4b38ba..0000000 --- a/arch/x86/include/asm/dma-contiguous.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ASMX86_DMA_CONTIGUOUS_H -#define ASMX86_DMA_CONTIGUOUS_H - -#ifdef __KERNEL__ - -#include <linux/types.h> - -static inline void -dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { } - -#endif -#endif diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 53cdfb2..4421b5d 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -27,7 +27,6 @@ #include <asm/insn.h> #define __ARCH_WANT_KPROBES_INSN_SLOT -#define ARCH_SUPPORTS_KPROBES_ON_FTRACE struct pt_regs; struct kprobe; diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 4b0e1df..b553ed8 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -449,12 +449,11 @@ sysenter_audit: jnz syscall_trace_entry addl $4,%esp CFI_ADJUST_CFA_OFFSET -4 - /* %esi already in 8(%esp) 6th arg: 4th syscall arg */ - /* %edx already in 4(%esp) 5th arg: 3rd syscall arg */ - /* %ecx already in 0(%esp) 4th arg: 2nd syscall arg */ - movl %ebx,%ecx /* 3rd arg: 1st syscall arg */ - movl %eax,%edx /* 2nd arg: syscall number */ - movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */ + movl %esi,4(%esp) /* 5th arg: 4th syscall arg */ + movl %edx,(%esp) /* 4th arg: 3rd syscall arg */ + /* %ecx already in %ecx 3rd arg: 2nd syscall arg */ + movl %ebx,%edx /* 2nd arg: 1st syscall arg */ + /* %eax already in %eax 1st arg: syscall number */ call __audit_syscall_entry pushl_cfi %ebx movl PT_EAX(%esp),%eax /* reload syscall number */ diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 29576c2..749b0e4 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1445,12 +1445,12 @@ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch) { #ifdef CONFIG_X86_64 if (arch == AUDIT_ARCH_X86_64) { - audit_syscall_entry(arch, regs->orig_ax, regs->di, + audit_syscall_entry(regs->orig_ax, regs->di, regs->si, regs->dx, regs->r10); } else #endif { - audit_syscall_entry(arch, regs->orig_ax, regs->bx, + audit_syscall_entry(regs->orig_ax, regs->bx, regs->cx, regs->dx, regs->si); } } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d9dcfa2..0acac81 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -472,6 +472,7 @@ struct vcpu_vmx { int gs_ldt_reload_needed; int fs_reload_needed; u64 msr_host_bndcfgs; + unsigned long vmcs_host_cr4; /* May not match real cr4 */ } host_state; struct { int vm86_active; @@ -4267,11 +4268,16 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) u32 low32, high32; unsigned long tmpl; struct desc_ptr dt; + unsigned long cr4; vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */ - vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ + /* Save the most likely value for this task's CR4 in the VMCS. */ + cr4 = read_cr4(); + vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */ + vmx->host_state.vmcs_host_cr4 = cr4; + vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ #ifdef CONFIG_X86_64 /* @@ -7514,7 +7520,7 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx) static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned long debugctlmsr; + unsigned long debugctlmsr, cr4; /* Record the guest's net vcpu time for enforced NMI injections. */ if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) @@ -7540,6 +7546,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); + cr4 = read_cr4(); + if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) { + vmcs_writel(HOST_CR4, cr4); + vmx->host_state.vmcs_host_cr4 = cr4; + } + /* When single-stepping over STI and MOV SS, we must clear the * corresponding interruptibility bits in the guest state. Otherwise * vmentry fails as it then expects bit 14 (BS) in pending debug diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index d56cd1f..3f62734 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -182,12 +182,17 @@ struct jit_context { bool seen_ld_abs; }; +/* maximum number of bytes emitted while JITing one eBPF insn */ +#define BPF_MAX_INSN_SIZE 128 +#define BPF_INSN_SAFETY 64 + static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, int oldproglen, struct jit_context *ctx) { struct bpf_insn *insn = bpf_prog->insnsi; int insn_cnt = bpf_prog->len; - u8 temp[64]; + bool seen_ld_abs = ctx->seen_ld_abs | (oldproglen == 0); + u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY]; int i; int proglen = 0; u8 *prog = temp; @@ -225,7 +230,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, EMIT2(0x31, 0xc0); /* xor eax, eax */ EMIT3(0x4D, 0x31, 0xED); /* xor r13, r13 */ - if (ctx->seen_ld_abs) { + if (seen_ld_abs) { /* r9d : skb->len - skb->data_len (headlen) * r10 : skb->data */ @@ -685,7 +690,7 @@ xadd: if (is_imm8(insn->off)) case BPF_JMP | BPF_CALL: func = (u8 *) __bpf_call_base + imm32; jmp_offset = func - (image + addrs[i]); - if (ctx->seen_ld_abs) { + if (seen_ld_abs) { EMIT2(0x41, 0x52); /* push %r10 */ EMIT2(0x41, 0x51); /* push %r9 */ /* need to adjust jmp offset, since @@ -699,7 +704,7 @@ xadd: if (is_imm8(insn->off)) return -EINVAL; } EMIT1_off32(0xE8, jmp_offset); - if (ctx->seen_ld_abs) { + if (seen_ld_abs) { EMIT2(0x41, 0x59); /* pop %r9 */ EMIT2(0x41, 0x5A); /* pop %r10 */ } @@ -804,7 +809,8 @@ emit_jmp: goto common_load; case BPF_LD | BPF_ABS | BPF_W: func = CHOOSE_LOAD_FUNC(imm32, sk_load_word); -common_load: ctx->seen_ld_abs = true; +common_load: + ctx->seen_ld_abs = seen_ld_abs = true; jmp_offset = func - (image + addrs[i]); if (!func || !is_simm32(jmp_offset)) { pr_err("unsupported bpf func %d addr %p image %p\n", @@ -878,6 +884,11 @@ common_load: ctx->seen_ld_abs = true; } ilen = prog - temp; + if (ilen > BPF_MAX_INSN_SIZE) { + pr_err("bpf_jit_compile fatal insn size error\n"); + return -EFAULT; + } + if (image) { if (unlikely(proglen + ilen > oldproglen)) { pr_err("bpf_jit_compile fatal error\n"); @@ -934,9 +945,11 @@ void bpf_int_jit_compile(struct bpf_prog *prog) goto out; } if (image) { - if (proglen != oldproglen) + if (proglen != oldproglen) { pr_err("bpf_jit: proglen=%d != oldproglen=%d\n", proglen, oldproglen); + goto out; + } break; } if (proglen == oldproglen) { diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h index 54f8102..e59eef2 100644 --- a/arch/x86/um/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace.h @@ -47,8 +47,6 @@ struct user_desc; #ifdef CONFIG_X86_32 -#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 - extern int ptrace_get_thread_area(struct task_struct *child, int idx, struct user_desc __user *user_desc); @@ -57,8 +55,6 @@ extern int ptrace_set_thread_area(struct task_struct *child, int idx, #else -#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64 - #define PT_REGS_R8(r) UPT_R8(&(r)->regs) #define PT_REGS_R9(r) UPT_R9(&(r)->regs) #define PT_REGS_R10(r) UPT_R10(&(r)->regs) diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h new file mode 100644 index 0000000..9fe77b7 --- /dev/null +++ b/arch/x86/um/asm/syscall.h @@ -0,0 +1,15 @@ +#ifndef __UM_ASM_SYSCALL_H +#define __UM_ASM_SYSCALL_H + +#include <uapi/linux/audit.h> + +static inline int syscall_get_arch(void) +{ +#ifdef CONFIG_X86_32 + return AUDIT_ARCH_I386; +#else + return AUDIT_ARCH_X86_64; +#endif +} + +#endif /* __UM_ASM_SYSCALL_H */ diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 562fac6..4d54b48 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -342,7 +342,7 @@ void do_syscall_trace_enter(struct pt_regs *regs) do_syscall_trace(); #if 0 - audit_syscall_entry(current, AUDIT_ARCH_XTENSA..); + audit_syscall_entry(...); #endif } |