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

Commit 26ad19d8 authored by Helge Deller's avatar Helge Deller
Browse files

Merge tag 'parisc-fixes' of...

Merge tag 'parisc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6

 into stable-3.8

PARISC fixes on 20130213

This is a couple of patches, one to fix a broken build with HPUX compatibility
and the other to solve a coherency problem we've been seeing in our TLB where
setting a page read only occasionally fails to trigger a COW because of a
stale writeable TLB entry.

Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parents 19f949f5 6c700d71
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -43,8 +43,7 @@ int hpux_execve(struct pt_regs *regs)

	error = do_execve(filename->name,
			  (const char __user *const __user *) regs->gr[25],
			  (const char __user *const __user *) regs->gr[24],
			  regs);
			  (const char __user *const __user *) regs->gr[24]);

	putname(filename);

+10 −3
Original line number Diff line number Diff line
@@ -12,11 +12,10 @@

#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/mm_types.h>
#include <asm/processor.h>
#include <asm/cache.h>

struct vm_area_struct;

/*
 * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
 * memory.  For the return value to be meaningful, ADDR must be >=
@@ -40,7 +39,14 @@ struct vm_area_struct;
        do{                                                     \
                *(pteptr) = (pteval);                           \
        } while(0)
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)

extern void purge_tlb_entries(struct mm_struct *, unsigned long);

#define set_pte_at(mm, addr, ptep, pteval)                      \
	do {                                                    \
		set_pte(ptep, pteval);                          \
		purge_tlb_entries(mm, addr);                    \
	} while (0)

#endif /* !__ASSEMBLY__ */

@@ -466,6 +472,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
		old = pte_val(*ptep);
		new = pte_val(pte_wrprotect(__pte (old)));
	} while (cmpxchg((unsigned long *) ptep, old, new) != old);
	purge_tlb_entries(mm, addr);
#else
	pte_t old_pte = *ptep;
	set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+18 −0
Original line number Diff line number Diff line
@@ -419,6 +419,24 @@ void kunmap_parisc(void *addr)
EXPORT_SYMBOL(kunmap_parisc);
#endif

void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
{
	unsigned long flags;

	/* Note: purge_tlb_entries can be called at startup with
	   no context.  */

	/* Disable preemption while we play with %sr1.  */
	preempt_disable();
	mtsp(mm->context, 1);
	purge_tlb_start(flags);
	pdtlb(addr);
	pitlb(addr);
	purge_tlb_end(flags);
	preempt_enable();
}
EXPORT_SYMBOL(purge_tlb_entries);

void __flush_tlb_range(unsigned long sid, unsigned long start,
		       unsigned long end)
{