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

Commit d0303d71 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'linus' into perf/core



Conflicts:
	arch/sparc/kernel/perf_event.c

Merge reason: Resolve the conflict.

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents 90edf27f c79bd892
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
			ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}
		regs->trap = 0;
		return 0;               /* no signals delivered */
	}

@@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
		ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
	}

	regs->trap = 0;
	if (ret) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked, &current->blocked,
+1 −2
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs,
	if (!sig)
		save_r2 = (unsigned int)regs->gpr[2];
	err = restore_general_regs(regs, sr);
	regs->trap = 0;
	err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
	if (!sig)
		regs->gpr[2] = (unsigned long) save_r2;
@@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
	regs->nip = (unsigned long) ka->sa.sa_handler;
	/* enter the signal handler in big-endian mode */
	regs->msr &= ~MSR_LE;
	regs->trap = 0;
	return 1;

badframe:
@@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
	regs->nip = (unsigned long) ka->sa.sa_handler;
	/* enter the signal handler in big-endian mode */
	regs->msr &= ~MSR_LE;
	regs->trap = 0;

	return 1;

+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
	err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
	err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
	/* skip SOFTE */
	err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
	regs->trap = 0;
	err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
	err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
	err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
+12 −3
Original line number Diff line number Diff line
@@ -1076,13 +1076,24 @@ static int sparc_pmu_event_init(struct perf_event *event)
		break;

	case PERF_TYPE_RAW:
		return -EOPNOTSUPP;
		pmap = NULL;
		break;

	default:
		return -ENOENT;

	}

	if (pmap) {
		hwc->event_base = perf_event_encode(pmap);
	} else {
		/*
		 * User gives us "(encoding << 16) | pic_mask" for
		 * PERF_TYPE_RAW events.
		 */
		hwc->event_base = attr->config;
	}

	/* We save the enable bits in the config_base.  */
	hwc->config_base = sparc_pmu->irq_bit;
	if (!attr->exclude_user)
@@ -1092,8 +1103,6 @@ static int sparc_pmu_event_init(struct perf_event *event)
	if (!attr->exclude_hv)
		hwc->config_base |= sparc_pmu->hv_bit;

	hwc->event_base = perf_event_encode(pmap);

	n = 0;
	if (event->group_leader != event) {
		n = collect_events(event->group_leader,
+97 −64
Original line number Diff line number Diff line
@@ -453,7 +453,65 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
	return err;
}

static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
/* The I-cache flush instruction only works in the primary ASI, which
 * right now is the nucleus, aka. kernel space.
 *
 * Therefore we have to kick the instructions out using the kernel
 * side linear mapping of the physical address backing the user
 * instructions.
 */
static void flush_signal_insns(unsigned long address)
{
	unsigned long pstate, paddr;
	pte_t *ptep, pte;
	pgd_t *pgdp;
	pud_t *pudp;
	pmd_t *pmdp;

	/* Commit all stores of the instructions we are about to flush.  */
	wmb();

	/* Disable cross-call reception.  In this way even a very wide
	 * munmap() on another cpu can't tear down the page table
	 * hierarchy from underneath us, since that can't complete
	 * until the IPI tlb flush returns.
	 */

	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
	__asm__ __volatile__("wrpr %0, %1, %%pstate"
				: : "r" (pstate), "i" (PSTATE_IE));

	pgdp = pgd_offset(current->mm, address);
	if (pgd_none(*pgdp))
		goto out_irqs_on;
	pudp = pud_offset(pgdp, address);
	if (pud_none(*pudp))
		goto out_irqs_on;
	pmdp = pmd_offset(pudp, address);
	if (pmd_none(*pmdp))
		goto out_irqs_on;

	ptep = pte_offset_map(pmdp, address);
	pte = *ptep;
	if (!pte_present(pte))
		goto out_unmap;

	paddr = (unsigned long) page_address(pte_page(pte));

	__asm__ __volatile__("flush	%0 + %1"
			     : /* no outputs */
			     : "r" (paddr),
			       "r" (address & (PAGE_SIZE - 1))
			     : "memory");

out_unmap:
	pte_unmap(ptep);
out_irqs_on:
	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));

}

static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
			 int signo, sigset_t *oldset)
{
	struct signal_frame32 __user *sf;
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
	if (ka->ka_restorer) {
		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
	} else {
		/* Flush instruction space. */
		unsigned long address = ((unsigned long)&(sf->insns[0]));
		pgd_t *pgdp = pgd_offset(current->mm, address);
		pud_t *pudp = pud_offset(pgdp, address);
		pmd_t *pmdp = pmd_offset(pudp, address);
		pte_t *ptep;
		pte_t pte;

		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
	
@@ -562,32 +614,20 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
		if (err)
			goto sigsegv;

		preempt_disable();
		ptep = pte_offset_map(pmdp, address);
		pte = *ptep;
		if (pte_present(pte)) {
			unsigned long page = (unsigned long)
				page_address(pte_page(pte));

			wmb();
			__asm__ __volatile__("flush	%0 + %1"
					     : /* no outputs */
					     : "r" (page),
					       "r" (address & (PAGE_SIZE - 1))
					     : "memory");
		flush_signal_insns(address);
	}
		pte_unmap(ptep);
		preempt_enable();
	}
	return;
	return 0;

sigill:
	do_exit(SIGILL);
	return -EINVAL;

sigsegv:
	force_sigsegv(signo, current);
	return -EFAULT;
}

static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
			    unsigned long signr, sigset_t *oldset,
			    siginfo_t *info)
{
@@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
	if (ka->ka_restorer)
		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
	else {
		/* Flush instruction space. */
		unsigned long address = ((unsigned long)&(sf->insns[0]));
		pgd_t *pgdp = pgd_offset(current->mm, address);
		pud_t *pudp = pud_offset(pgdp, address);
		pmd_t *pmdp = pmd_offset(pudp, address);
		pte_t *ptep;

		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
	
@@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
		if (err)
			goto sigsegv;

		preempt_disable();
		ptep = pte_offset_map(pmdp, address);
		if (pte_present(*ptep)) {
			unsigned long page = (unsigned long)
				page_address(pte_page(*ptep));

			wmb();
			__asm__ __volatile__("flush	%0 + %1"
					     : /* no outputs */
					     : "r" (page),
					       "r" (address & (PAGE_SIZE - 1))
					     : "memory");
		flush_signal_insns(address);
	}
		pte_unmap(ptep);
		preempt_enable();
	}
	return;
	return 0;

sigill:
	do_exit(SIGILL);
	return -EINVAL;

sigsegv:
	force_sigsegv(signr, current);
	return -EFAULT;
}

static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
				  siginfo_t *info,
				  sigset_t *oldset, struct pt_regs *regs)
{
	int err;

	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame32(ka, regs, signr, oldset, info);
		err = setup_rt_frame32(ka, regs, signr, oldset, info);
	else
		setup_frame32(ka, regs, signr, oldset);
		err = setup_frame32(ka, regs, signr, oldset);

	if (err)
		return err;

	spin_lock_irq(&current->sighand->siglock);
	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
		sigaddset(&current->blocked,signr);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	tracehook_signal_handler(signr, info, ka, regs, 0);

	return 0;
}

static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
	if (signr > 0) {
		if (restart_syscall)
			syscall_restart32(orig_i0, regs, &ka.sa);
		handle_signal32(signr, &ka, &info, oldset, regs);

		if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
			/* A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TS_RESTORE_SIGMASK flag.
			 */
			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;

		tracehook_signal_handler(signr, &info, &ka, regs, 0);
		}
		return;
	}
	if (restart_syscall &&
@@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
		regs->u_regs[UREG_I0] = orig_i0;
		regs->tpc -= 4;
		regs->tnpc -= 4;
		pt_regs_clear_syscall(regs);
	}
	if (restart_syscall &&
	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
		regs->u_regs[UREG_G1] = __NR_restart_syscall;
		regs->tpc -= 4;
		regs->tnpc -= 4;
		pt_regs_clear_syscall(regs);
	}

	/* If there's no signal to deliver, we just put the saved sigmask
Loading