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

Commit 73d2fb75 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt
Browse files

powerpc: Emulate non privileged DSCR read and write

POWER8 allows read and write of the DSCR in userspace. We added
kernel emulation so applications could always use the instructions
regardless of the CPU type.

Unfortunately there are two SPRs for the DSCR and we only added
emulation for the privileged one. Add code to match the non
privileged one.

A simple test was created to verify the fix:

http://ozlabs.org/~anton/junkcode/user_dscr_test.c



Without the patch we get a SIGILL and it passes with the patch.

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Cc: <stable@kernel.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 01227a88
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -115,6 +115,10 @@
#define PPC_INST_MFSPR_DSCR_MASK	0xfc1fffff
#define PPC_INST_MFSPR_DSCR_MASK	0xfc1fffff
#define PPC_INST_MTSPR_DSCR		0x7c1103a6
#define PPC_INST_MTSPR_DSCR		0x7c1103a6
#define PPC_INST_MTSPR_DSCR_MASK	0xfc1fffff
#define PPC_INST_MTSPR_DSCR_MASK	0xfc1fffff
#define PPC_INST_MFSPR_DSCR_USER	0x7c0302a6
#define PPC_INST_MFSPR_DSCR_USER_MASK	0xfc1fffff
#define PPC_INST_MTSPR_DSCR_USER	0x7c0303a6
#define PPC_INST_MTSPR_DSCR_USER_MASK	0xfc1fffff
#define PPC_INST_SLBFEE			0x7c0007a7
#define PPC_INST_SLBFEE			0x7c0007a7


#define PPC_INST_STRING			0x7c00042a
#define PPC_INST_STRING			0x7c00042a
+8 −2
Original line number Original line Diff line number Diff line
@@ -970,7 +970,10 @@ static int emulate_instruction(struct pt_regs *regs)


#ifdef CONFIG_PPC64
#ifdef CONFIG_PPC64
	/* Emulate the mfspr rD, DSCR. */
	/* Emulate the mfspr rD, DSCR. */
	if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
	if ((((instword & PPC_INST_MFSPR_DSCR_USER_MASK) ==
		PPC_INST_MFSPR_DSCR_USER) ||
	     ((instword & PPC_INST_MFSPR_DSCR_MASK) ==
		PPC_INST_MFSPR_DSCR)) &&
			cpu_has_feature(CPU_FTR_DSCR)) {
			cpu_has_feature(CPU_FTR_DSCR)) {
		PPC_WARN_EMULATED(mfdscr, regs);
		PPC_WARN_EMULATED(mfdscr, regs);
		rd = (instword >> 21) & 0x1f;
		rd = (instword >> 21) & 0x1f;
@@ -978,7 +981,10 @@ static int emulate_instruction(struct pt_regs *regs)
		return 0;
		return 0;
	}
	}
	/* Emulate the mtspr DSCR, rD. */
	/* Emulate the mtspr DSCR, rD. */
	if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
	if ((((instword & PPC_INST_MTSPR_DSCR_USER_MASK) ==
		PPC_INST_MTSPR_DSCR_USER) ||
	     ((instword & PPC_INST_MTSPR_DSCR_MASK) ==
		PPC_INST_MTSPR_DSCR)) &&
			cpu_has_feature(CPU_FTR_DSCR)) {
			cpu_has_feature(CPU_FTR_DSCR)) {
		PPC_WARN_EMULATED(mtdscr, regs);
		PPC_WARN_EMULATED(mtdscr, regs);
		rd = (instword >> 21) & 0x1f;
		rd = (instword >> 21) & 0x1f;