Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fbdefcf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull parisc fixes from Helge Deller:

 - a patch to change the ordering of cache and TLB flushes to hopefully
   fix the random segfaults we very rarely face (by Dave Anglin).

 - a patch to hide the virtual kernel memory layout due to security
   reasons.

 - two small patches to make the kernel run more smoothly under qemu.

* 'parisc-4.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Reduce irq overhead when run in qemu
  parisc: Use cr16 interval timers unconditionally on qemu
  parisc: Check if secondary CPUs want own PDC calls
  parisc: Hide virtual kernel memory layout
  parisc: Fix ordering of cache and TLB flushes
parents 0573fed9 636a415b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ void flush_user_icache_range_asm(unsigned long, unsigned long);
void flush_kernel_icache_range_asm(unsigned long, unsigned long);
void flush_user_dcache_range_asm(unsigned long, unsigned long);
void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
void purge_kernel_dcache_range_asm(unsigned long, unsigned long);
void flush_kernel_dcache_page_asm(void *);
void flush_kernel_icache_page(void *);

+2 −0
Original line number Diff line number Diff line
@@ -316,6 +316,8 @@ extern int _parisc_requires_coherency;
#define parisc_requires_coherency()	(0)
#endif

extern int running_on_qemu;

#endif /* __ASSEMBLY__ */

#endif /* __ASM_PARISC_PROCESSOR_H */
+31 −26
Original line number Diff line number Diff line
@@ -465,10 +465,10 @@ EXPORT_SYMBOL(copy_user_page);
int __flush_tlb_range(unsigned long sid, unsigned long start,
		      unsigned long end)
{
	unsigned long flags, size;
	unsigned long flags;

	size = (end - start);
	if (size >= parisc_tlb_flush_threshold) {
	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
	    end - start >= parisc_tlb_flush_threshold) {
		flush_tlb_all();
		return 1;
	}
@@ -539,13 +539,11 @@ void flush_cache_mm(struct mm_struct *mm)
	struct vm_area_struct *vma;
	pgd_t *pgd;

	/* Flush the TLB to avoid speculation if coherency is required. */
	if (parisc_requires_coherency())
		flush_tlb_all();

	/* Flushing the whole cache on each cpu takes forever on
	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
	if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
	    mm_total_size(mm) >= parisc_cache_flush_threshold) {
		flush_tlb_all();
		flush_cache_all();
		return;
	}
@@ -553,9 +551,9 @@ void flush_cache_mm(struct mm_struct *mm)
	if (mm->context == mfsp(3)) {
		for (vma = mm->mmap; vma; vma = vma->vm_next) {
			flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
			if ((vma->vm_flags & VM_EXEC) == 0)
				continue;
			if (vma->vm_flags & VM_EXEC)
				flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
			flush_tlb_range(vma, vma->vm_start, vma->vm_end);
		}
		return;
	}
@@ -581,14 +579,9 @@ void flush_cache_mm(struct mm_struct *mm)
void flush_cache_range(struct vm_area_struct *vma,
		unsigned long start, unsigned long end)
{
	BUG_ON(!vma->vm_mm->context);

	/* Flush the TLB to avoid speculation if coherency is required. */
	if (parisc_requires_coherency())
	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
	    end - start >= parisc_cache_flush_threshold) {
		flush_tlb_range(vma, start, end);

	if ((end - start) >= parisc_cache_flush_threshold
	    || vma->vm_mm->context != mfsp(3)) {
		flush_cache_all();
		return;
	}
@@ -596,6 +589,7 @@ void flush_cache_range(struct vm_area_struct *vma,
	flush_user_dcache_range_asm(start, end);
	if (vma->vm_flags & VM_EXEC)
		flush_user_icache_range_asm(start, end);
	flush_tlb_range(vma, start, end);
}

void
@@ -604,7 +598,6 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
	BUG_ON(!vma->vm_mm->context);

	if (pfn_valid(pfn)) {
		if (parisc_requires_coherency())
		flush_tlb_page(vma, vmaddr);
		__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
	}
@@ -613,21 +606,33 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
void flush_kernel_vmap_range(void *vaddr, int size)
{
	unsigned long start = (unsigned long)vaddr;
	unsigned long end = start + size;

	if ((unsigned long)size > parisc_cache_flush_threshold)
	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
	    (unsigned long)size >= parisc_cache_flush_threshold) {
		flush_tlb_kernel_range(start, end);
		flush_data_cache();
	else
		flush_kernel_dcache_range_asm(start, start + size);
		return;
	}

	flush_kernel_dcache_range_asm(start, end);
	flush_tlb_kernel_range(start, end);
}
EXPORT_SYMBOL(flush_kernel_vmap_range);

void invalidate_kernel_vmap_range(void *vaddr, int size)
{
	unsigned long start = (unsigned long)vaddr;
	unsigned long end = start + size;

	if ((unsigned long)size > parisc_cache_flush_threshold)
	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
	    (unsigned long)size >= parisc_cache_flush_threshold) {
		flush_tlb_kernel_range(start, end);
		flush_data_cache();
	else
		flush_kernel_dcache_range_asm(start, start + size);
		return;
	}

	purge_kernel_dcache_range_asm(start, end);
	flush_tlb_kernel_range(start, end);
}
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
+12 −6
Original line number Diff line number Diff line
@@ -138,6 +138,16 @@ $pgt_fill_loop:
	std		%dp,0x18(%r10)
#endif

#ifdef CONFIG_64BIT
	/* Get PDCE_PROC for monarch CPU. */
#define MEM_PDC_LO 0x388
#define MEM_PDC_HI 0x35C
	ldw             MEM_PDC_LO(%r0),%r3
	ldw             MEM_PDC_HI(%r0),%r10
	depd            %r10, 31, 32, %r3        /* move to upper word */
#endif


#ifdef CONFIG_SMP
	/* Set the smp rendezvous address into page zero.
	** It would be safer to do this in init_smp_config() but
@@ -196,12 +206,6 @@ common_stext:
        ** Someday, palo might not do this for the Monarch either.
        */
2:
#define MEM_PDC_LO 0x388
#define MEM_PDC_HI 0x35C
	ldw             MEM_PDC_LO(%r0),%r3
	ldw             MEM_PDC_HI(%r0),%r6
	depd            %r6, 31, 32, %r3        /* move to upper word */

	mfctl		%cr30,%r6		/* PCX-W2 firmware bug */

	ldo             PDC_PSW(%r0),%arg0              /* 21 */
@@ -268,6 +272,8 @@ $install_iva:
aligned_rfi:
	pcxt_ssm_bug

	copy		%r3, %arg0	/* PDCE_PROC for smp_callin() */

	rsm		PSW_SM_QUIET,%r0	/* off troublesome PSW bits */
	/* Don't need NOPs, have 8 compliant insn before rfi */

+22 −0
Original line number Diff line number Diff line
@@ -1110,6 +1110,28 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
	.procend
ENDPROC_CFI(flush_kernel_dcache_range_asm)

ENTRY_CFI(purge_kernel_dcache_range_asm)
	.proc
	.callinfo NO_CALLS
	.entry

	ldil		L%dcache_stride, %r1
	ldw		R%dcache_stride(%r1), %r23
	ldo		-1(%r23), %r21
	ANDCM		%r26, %r21, %r26

1:      cmpb,COND(<<),n	%r26, %r25,1b
	pdc,m		%r23(%r26)

	sync
	syncdma
	bv		%r0(%r2)
	nop
	.exit

	.procend
ENDPROC_CFI(purge_kernel_dcache_range_asm)

ENTRY_CFI(flush_user_icache_range_asm)
	.proc
	.callinfo NO_CALLS
Loading