/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 *
 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
 * Copyright 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
 * Copyright 1999 Hewlett Packard Co.
 *
 */

#include <linux/mm.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/interrupt.h>
#include <linux/extable.h>
#include <linux/uaccess.h>
#include <linux/hugetlb.h>
#include <linux/perf_event.h>

#include <asm/traps.h>

#define DEBUG_NATLB 0

/* Various important other fields */
#define bit22set(x)		(x & 0x00000200)
#define bits23_25set(x)		(x & 0x000001c0)
#define isGraphicsFlushRead(x)	((x & 0xfc003fdf) == 0x04001a80)
				/* extended opcode is 0x6a */

#define BITSSET		0x1c0	/* for identifying LDCW */


int show_unhandled_signals = 1;

/*
 * parisc_acctyp(unsigned int inst) --
 *    Given a PA-RISC memory access instruction, determine if the
 *    instruction would perform a memory read or memory write
 *    operation.
 *
 *    This function assumes that the given instruction is a memory access
 *    instruction (i.e. you should really only call it if you know that
 *    the instruction has generated some sort of a memory access fault).
 *
 * Returns:
 *   VM_READ  if read operation
 *   VM_WRITE if write operation
 *   VM_EXEC  if execute operation
 */
unsigned long
parisc_acctyp(unsigned long code, unsigned int inst)
{
	if (code == 6 || code == 16)
	    return VM_EXEC;

	switch (inst & 0xf0000000) {
	case 0x40000000: /* load */
	case 0x50000000: /* new load */
		return VM_READ;

	case 0x60000000: /* store */
	case 0x70000000: /* new store */
		return VM_WRITE;

	case 0x20000000: /* coproc */
	case 0x30000000: /* coproc2 */
		if (bit22set(inst))
			return VM_WRITE;
		fallthrough;

	case 0x0: /* indexed/memory management */
		if (bit22set(inst)) {
			/*
			 * Check for the 'Graphics Flush Read' instruction.
			 * It resembles an FDC instruction, except for bits
			 * 20 and 21. Any combination other than zero will
			 * utilize the block mover functionality on some
			 * older PA-RISC platforms.  The case where a block
			 * move is performed from VM to graphics IO space
			 * should be treated as a READ.
			 *
			 * The significance of bits 20,21 in the FDC
			 * instruction is:
			 *
			 *   00  Flush data cache (normal instruction behavior)
			 *   01  Graphics flush write  (IO space -> VM)
			 *   10  Graphics flush read   (VM -> IO space)
			 *   11  Graphics flush read/write (VM <-> IO space)
			 */
			if (isGraphicsFlushRead(inst))
				return VM_READ;
			return VM_WRITE;
		} else {
			/*
			 * Check for LDCWX and LDCWS (semaphore instructions).
			 * If bits 23 through 25 are all 1's it is one of
			 * the above two instructions and is a write.
			 *
			 * Note: With the limited bits we are looking at,
			 * this will also catch PROBEW and PROBEWI. However,
			 * these should never get in here because they don't
			 * generate exceptions of the type:
			 *   Data TLB miss fault/data page fault
			 *   Data memory protection trap
			 */
			if (bits23_25set(inst) == BITSSET)
				return VM_WRITE;
		}
		return VM_READ; /* Default */
	}
	return VM_READ; /* Default */
}

#undef bit22set
#undef bits23_25set
#undef isGraphicsFlushRead
#undef BITSSET


#if 0
/* This is the treewalk to find a vma which is the highest that has
 * a start < addr.  We're using find_vma_prev instead right now, but
 * we might want to use this at some point in the future.  Probably
 * not, but I want it committed to CVS so I don't lose it :-)
 */
			while (tree != vm_avl_empty) {
				if (tree->vm_start > addr) {
					tree = tree->vm_avl_left;
				} else {
					prev = tree;
					if (prev->vm_next == NULL)
						break;
					if (prev->vm_next->vm_start > addr)
						break;
					tree = tree->vm_avl_right;
				}
			}
#endif

int fixup_exception(struct pt_regs *regs)
{
	const struct exception_table_entry *fix;

	fix = search_exception_tables(regs->iaoq[0]);
	if (fix) {
		/*
		 * Fix up get_user() and put_user().
		 * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant
		 * bit in the relative address of the fixup routine to indicate
		 * that the register encoded in the "or %r0,%r0,register"
		 * opcode should be loaded with -EFAULT to report a userspace
		 * access error.
		 */
		if (fix->fixup & 1) {
			int fault_error_reg = fix->err_opcode & 0x1f;
			if (!WARN_ON(!fault_error_reg))
				regs->gr[fault_error_reg] = -EFAULT;
			pr_debug("Unalignment fixup of register %d at %pS\n",
				fault_error_reg, (void*)regs->iaoq[0]);

			/* zero target register for get_user() */
			if (parisc_acctyp(0, regs->iir) == VM_READ) {
				int treg = regs->iir & 0x1f;
				BUG_ON(treg == 0);
				regs->gr[treg] = 0;
			}
		}

		regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup;
		regs->iaoq[0] &= ~3;
		/*
		 * NOTE: In some cases the faulting instruction
		 * may be in the delay slot of a branch. We
		 * don't want to take the branch, so we don't
		 * increment iaoq[1], instead we set it to be
		 * iaoq[0]+4, and clear the B bit in the PSW
		 */
		regs->iaoq[1] = regs->iaoq[0] + 4;
		regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */

		return 1;
	}

	return 0;
}

/*
 * parisc hardware trap list
 *
 * Documented in section 3 "Addressing and Access Control" of the
 * "PA-RISC 1.1 Architecture and Instruction Set Reference Manual"
 * https://parisc.wiki.kernel.org/index.php/File:Pa11_acd.pdf
 *
 * For implementation see handle_interruption() in traps.c
 */
static const char * const trap_description[] = {
	[1] =	"High-priority machine check (HPMC)",
	[2] =	"Power failure interrupt",
	[3] =	"Recovery counter trap",
	[5] =	"Low-priority machine check",
	[6] =	"Instruction TLB miss fault",
	[7] =	"Instruction access rights / protection trap",
	[8] =	"Illegal instruction trap",
	[9] =	"Break instruction trap",
	[10] =	"Privileged operation trap",
	[11] =	"Privileged register trap",
	[12] =	"Overflow trap",
	[13] =	"Conditional trap",
	[14] =	"FP Assist Exception trap",
	[15] =	"Data TLB miss fault",
	[16] =	"Non-access ITLB miss fault",
	[17] =	"Non-access DTLB miss fault",
	[18] =	"Data memory protection/unaligned access trap",
	[19] =	"Data memory break trap",
	[20] =	"TLB dirty bit trap",
	[21] =	"Page reference trap",
	[22] =	"Assist emulation trap",
	[25] =	"Taken branch trap",
	[26] =	"Data memory access rights trap",
	[27] =	"Data memory protection ID trap",
	[28] =	"Unaligned data reference trap",
};

const char *trap_name(unsigned long code)
{
	const char *t = NULL;

	if (code < ARRAY_SIZE(trap_description))
		t = trap_description[code];

	return t ? t : "Unknown trap";
}

/*
 * Print out info about fatal segfaults, if the show_unhandled_signals
 * sysctl is set:
 */
static inline void
show_signal_msg(struct pt_regs *regs, unsigned long code,
		unsigned long address, struct task_struct *tsk,
		struct vm_area_struct *vma)
{
	if (!unhandled_signal(tsk, SIGSEGV))
		return;

	if (!printk_ratelimit())
		return;

	pr_warn("\n");
	pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx",
	    tsk->comm, code, address);
	print_vma_addr(KERN_CONT " in ", regs->iaoq[0]);

	pr_cont("\ntrap #%lu: %s%c", code, trap_name(code),
		vma ? ',':'\n');

	if (vma)
		pr_cont(" vm_start = 0x%08lx, vm_end = 0x%08lx\n",
			vma->vm_start, vma->vm_end);

	show_regs(regs);
}

void do_page_fault(struct pt_regs *regs, unsigned long code,
			      unsigned long address)
{
	struct vm_area_struct *vma, *prev_vma;
	struct task_struct *tsk;
	struct mm_struct *mm;
	unsigned long acc_type;
	vm_fault_t fault = 0;
	unsigned int flags;
	char *msg;

	tsk = current;
	mm = tsk->mm;
	if (!mm) {
		msg = "Page fault: no context";
		goto no_context;
	}

	flags = FAULT_FLAG_DEFAULT;
	if (user_mode(regs))
		flags |= FAULT_FLAG_USER;

	acc_type = parisc_acctyp(code, regs->iir);
	if (acc_type & VM_WRITE)
		flags |= FAULT_FLAG_WRITE;
	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
retry:
	mmap_read_lock(mm);
	vma = find_vma_prev(mm, address, &prev_vma);
	if (!vma || address < vma->vm_start) {
		if (!prev_vma || !(prev_vma->vm_flags & VM_GROWSUP))
			goto bad_area;
		vma = expand_stack(mm, address);
		if (!vma)
			goto bad_area_nosemaphore;
	}

/*
 * Ok, we have a good vm_area for this memory access. We still need to
 * check the access permissions.
 */

	if ((vma->vm_flags & acc_type) != acc_type)
		goto bad_area;

	/*
	 * If for any reason at all we couldn't handle the fault, make
	 * sure we exit gracefully rather than endlessly redo the
	 * fault.
	 */

	fault = handle_mm_fault(vma, address, flags, regs);

	if (fault_signal_pending(fault, regs)) {
		if (!user_mode(regs)) {
			msg = "Page fault: fault signal on kernel memory";
			goto no_context;
		}
		return;
	}

	/* The fault is fully completed (including releasing mmap lock) */
	if (fault & VM_FAULT_COMPLETED)
		return;

	if (unlikely(fault & VM_FAULT_ERROR)) {
		/*
		 * We hit a shared mapping outside of the file, or some
		 * other thing happened to us that made us unable to
		 * handle the page fault gracefully.
		 */
		if (fault & VM_FAULT_OOM)
			goto out_of_memory;
		else if (fault & VM_FAULT_SIGSEGV)
			goto bad_area;
		else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
				  VM_FAULT_HWPOISON_LARGE))
			goto bad_area;
		BUG();
	}
	if (fault & VM_FAULT_RETRY) {
		/*
		 * No need to mmap_read_unlock(mm) as we would
		 * have already released it in __lock_page_or_retry
		 * in mm/filemap.c.
		 */
		flags |= FAULT_FLAG_TRIED;
		goto retry;
	}
	mmap_read_unlock(mm);
	return;

/*
 * Something tried to access memory that isn't in our memory map..
 */
bad_area:
	mmap_read_unlock(mm);

bad_area_nosemaphore:
	if (!user_mode(regs) && fixup_exception(regs)) {
		return;
	}

	if (user_mode(regs)) {
		int signo, si_code;

		switch (code) {
		case 15:	/* Data TLB miss fault/Data page fault */
			/* send SIGSEGV when outside of vma */
			if (!vma ||
			    address < vma->vm_start || address >= vma->vm_end) {
				signo = SIGSEGV;
				si_code = SEGV_MAPERR;
				break;
			}

			/* send SIGSEGV for wrong permissions */
			if ((vma->vm_flags & acc_type) != acc_type) {
				signo = SIGSEGV;
				si_code = SEGV_ACCERR;
				break;
			}

			/* probably address is outside of mapped file */
			fallthrough;
		case 17:	/* NA data TLB miss / page fault */
		case 18:	/* Unaligned access - PCXS only */
			signo = SIGBUS;
			si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
			break;
		case 16:	/* Non-access instruction TLB miss fault */
		case 26:	/* PCXL: Data memory access rights trap */
		default:
			signo = SIGSEGV;
			si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
			break;
		}
#ifdef CONFIG_MEMORY_FAILURE
		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
			unsigned int lsb = 0;
			printk(KERN_ERR
	"MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n",
			tsk->comm, tsk->pid, address);
			/*
			 * Either small page or large page may be poisoned.
			 * In other words, VM_FAULT_HWPOISON_LARGE and
			 * VM_FAULT_HWPOISON are mutually exclusive.
			 */
			if (fault & VM_FAULT_HWPOISON_LARGE)
				lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
			else if (fault & VM_FAULT_HWPOISON)
				lsb = PAGE_SHIFT;

			force_sig_mceerr(BUS_MCEERR_AR, (void __user *) address,
					 lsb);
			return;
		}
#endif
		show_signal_msg(regs, code, address, tsk, vma);

		force_sig_fault(signo, si_code, (void __user *) address);
		return;
	}
	msg = "Page fault: bad address";

no_context:

	if (!user_mode(regs) && fixup_exception(regs)) {
		return;
	}

	parisc_terminate(msg, regs, code, address);

out_of_memory:
	mmap_read_unlock(mm);
	if (!user_mode(regs)) {
		msg = "Page fault: out of memory";
		goto no_context;
	}
	pagefault_out_of_memory();
}

/* Handle non-access data TLB miss faults.
 *
 * For probe instructions, accesses to userspace are considered allowed
 * if they lie in a valid VMA and the access type matches. We are not
 * allowed to handle MM faults here so there may be situations where an
 * actual access would fail even though a probe was successful.
 */
int
handle_nadtlb_fault(struct pt_regs *regs)
{
	unsigned long insn = regs->iir;
	int breg, treg, xreg, val = 0;
	struct vm_area_struct *vma;
	struct task_struct *tsk;
	struct mm_struct *mm;
	unsigned long address;
	unsigned long acc_type;

	switch (insn & 0x380) {
	case 0x280:
		/* FDC instruction */
		fallthrough;
	case 0x380:
		/* PDC and FIC instructions */
		if (DEBUG_NATLB && printk_ratelimit()) {
			pr_warn("WARNING: nullifying cache flush/purge instruction\n");
			show_regs(regs);
		}
		if (insn & 0x20) {
			/* Base modification */
			breg = (insn >> 21) & 0x1f;
			xreg = (insn >> 16) & 0x1f;
			if (breg && xreg)
				regs->gr[breg] += regs->gr[xreg];
		}
		regs->gr[0] |= PSW_N;
		return 1;

	case 0x180:
		/* PROBE instruction */
		treg = insn & 0x1f;
		if (regs->isr) {
			tsk = current;
			mm = tsk->mm;
			if (mm) {
				/* Search for VMA */
				address = regs->ior;
				mmap_read_lock(mm);
				vma = vma_lookup(mm, address);
				mmap_read_unlock(mm);

				/*
				 * Check if access to the VMA is okay.
				 * We don't allow for stack expansion.
				 */
				acc_type = (insn & 0x40) ? VM_WRITE : VM_READ;
				if (vma
				    && (vma->vm_flags & acc_type) == acc_type)
					val = 1;
			}
		}
		if (treg)
			regs->gr[treg] = val;
		regs->gr[0] |= PSW_N;
		return 1;

	case 0x300:
		/* LPA instruction */
		if (insn & 0x20) {
			/* Base modification */
			breg = (insn >> 21) & 0x1f;
			xreg = (insn >> 16) & 0x1f;
			if (breg && xreg)
				regs->gr[breg] += regs->gr[xreg];
		}
		treg = insn & 0x1f;
		if (treg)
			regs->gr[treg] = 0;
		regs->gr[0] |= PSW_N;
		return 1;

	default:
		break;
	}

	return 0;
}
