stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	"Masami Hiramatsu (Google)" <mhiramat@kernel.org>,
	Nathan Chancellor <nathan@kernel.org>
Subject: [PATCH 6.1 31/46] x86/alternatives: Teach text_poke_bp() to patch Jcc.d32 instructions
Date: Thu, 23 Feb 2023 14:06:38 +0100	[thread overview]
Message-ID: <20230223130433.029351046@linuxfoundation.org> (raw)
In-Reply-To: <20230223130431.553657459@linuxfoundation.org>

From: Peter Zijlstra <peterz@infradead.org>

commit ac0ee0a9560c97fa5fe1409e450c2425d4ebd17a upstream.

In order to re-write Jcc.d32 instructions text_poke_bp() needs to be
taught about them.

The biggest hurdle is that the whole machinery is currently made for 5
byte instructions and extending this would grow struct text_poke_loc
which is currently a nice 16 bytes and used in an array.

However, since text_poke_loc contains a full copy of the (s32)
displacement, it is possible to map the Jcc.d32 2 byte opcodes to
Jcc.d8 1 byte opcode for the int3 emulation.

This then leaves the replacement bytes; fudge that by only storing the
last 5 bytes and adding the rule that 'length == 6' instruction will
be prefixed with a 0x0f byte.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Link: https://lore.kernel.org/r/20230123210607.115718513@infradead.org
[nathan: Introduce is_jcc32() as part of this change; upstream
         introduced it in 3b6c1747da48]
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kernel/alternative.c |   59 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 48 insertions(+), 11 deletions(-)

--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -339,6 +339,12 @@ next:
 	}
 }
 
+static inline bool is_jcc32(struct insn *insn)
+{
+	/* Jcc.d32 second opcode byte is in the range: 0x80-0x8f */
+	return insn->opcode.bytes[0] == 0x0f && (insn->opcode.bytes[1] & 0xf0) == 0x80;
+}
+
 #if defined(CONFIG_RETPOLINE) && defined(CONFIG_OBJTOOL)
 
 /*
@@ -427,8 +433,7 @@ static int patch_retpoline(void *addr, s
 	 *   [ NOP ]
 	 * 1:
 	 */
-	/* Jcc.d32 second opcode byte is in the range: 0x80-0x8f */
-	if (op == 0x0f && (insn->opcode.bytes[1] & 0xf0) == 0x80) {
+	if (is_jcc32(insn)) {
 		cc = insn->opcode.bytes[1] & 0xf;
 		cc ^= 1; /* invert condition */
 
@@ -1311,6 +1316,11 @@ void text_poke_sync(void)
 	on_each_cpu(do_sync_core, NULL, 1);
 }
 
+/*
+ * NOTE: crazy scheme to allow patching Jcc.d32 but not increase the size of
+ * this thing. When len == 6 everything is prefixed with 0x0f and we map
+ * opcode to Jcc.d8, using len to distinguish.
+ */
 struct text_poke_loc {
 	/* addr := _stext + rel_addr */
 	s32 rel_addr;
@@ -1432,6 +1442,10 @@ noinstr int poke_int3_handler(struct pt_
 		int3_emulate_jmp(regs, (long)ip + tp->disp);
 		break;
 
+	case 0x70 ... 0x7f: /* Jcc */
+		int3_emulate_jcc(regs, tp->opcode & 0xf, (long)ip, tp->disp);
+		break;
+
 	default:
 		BUG();
 	}
@@ -1505,16 +1519,26 @@ static void text_poke_bp_batch(struct te
 	 * Second step: update all but the first byte of the patched range.
 	 */
 	for (do_sync = 0, i = 0; i < nr_entries; i++) {
-		u8 old[POKE_MAX_OPCODE_SIZE] = { tp[i].old, };
+		u8 old[POKE_MAX_OPCODE_SIZE+1] = { tp[i].old, };
+		u8 _new[POKE_MAX_OPCODE_SIZE+1];
+		const u8 *new = tp[i].text;
 		int len = tp[i].len;
 
 		if (len - INT3_INSN_SIZE > 0) {
 			memcpy(old + INT3_INSN_SIZE,
 			       text_poke_addr(&tp[i]) + INT3_INSN_SIZE,
 			       len - INT3_INSN_SIZE);
+
+			if (len == 6) {
+				_new[0] = 0x0f;
+				memcpy(_new + 1, new, 5);
+				new = _new;
+			}
+
 			text_poke(text_poke_addr(&tp[i]) + INT3_INSN_SIZE,
-				  (const char *)tp[i].text + INT3_INSN_SIZE,
+				  new + INT3_INSN_SIZE,
 				  len - INT3_INSN_SIZE);
+
 			do_sync++;
 		}
 
@@ -1542,8 +1566,7 @@ static void text_poke_bp_batch(struct te
 		 * The old instruction is recorded so that the event can be
 		 * processed forwards or backwards.
 		 */
-		perf_event_text_poke(text_poke_addr(&tp[i]), old, len,
-				     tp[i].text, len);
+		perf_event_text_poke(text_poke_addr(&tp[i]), old, len, new, len);
 	}
 
 	if (do_sync) {
@@ -1560,10 +1583,15 @@ static void text_poke_bp_batch(struct te
 	 * replacing opcode.
 	 */
 	for (do_sync = 0, i = 0; i < nr_entries; i++) {
-		if (tp[i].text[0] == INT3_INSN_OPCODE)
+		u8 byte = tp[i].text[0];
+
+		if (tp[i].len == 6)
+			byte = 0x0f;
+
+		if (byte == INT3_INSN_OPCODE)
 			continue;
 
-		text_poke(text_poke_addr(&tp[i]), tp[i].text, INT3_INSN_SIZE);
+		text_poke(text_poke_addr(&tp[i]), &byte, INT3_INSN_SIZE);
 		do_sync++;
 	}
 
@@ -1581,9 +1609,11 @@ static void text_poke_loc_init(struct te
 			       const void *opcode, size_t len, const void *emulate)
 {
 	struct insn insn;
-	int ret, i;
+	int ret, i = 0;
 
-	memcpy((void *)tp->text, opcode, len);
+	if (len == 6)
+		i = 1;
+	memcpy((void *)tp->text, opcode+i, len-i);
 	if (!emulate)
 		emulate = opcode;
 
@@ -1594,6 +1624,13 @@ static void text_poke_loc_init(struct te
 	tp->len = len;
 	tp->opcode = insn.opcode.bytes[0];
 
+	if (is_jcc32(&insn)) {
+		/*
+		 * Map Jcc.d32 onto Jcc.d8 and use len to distinguish.
+		 */
+		tp->opcode = insn.opcode.bytes[1] - 0x10;
+	}
+
 	switch (tp->opcode) {
 	case RET_INSN_OPCODE:
 	case JMP32_INSN_OPCODE:
@@ -1610,7 +1647,6 @@ static void text_poke_loc_init(struct te
 		BUG_ON(len != insn.length);
 	};
 
-
 	switch (tp->opcode) {
 	case INT3_INSN_OPCODE:
 	case RET_INSN_OPCODE:
@@ -1619,6 +1655,7 @@ static void text_poke_loc_init(struct te
 	case CALL_INSN_OPCODE:
 	case JMP32_INSN_OPCODE:
 	case JMP8_INSN_OPCODE:
+	case 0x70 ... 0x7f: /* Jcc */
 		tp->disp = insn.immediate.value;
 		break;
 



  parent reply	other threads:[~2023-02-23 13:09 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-23 13:06 [PATCH 6.1 00/46] 6.1.14-rc1 review Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 01/46] drm/etnaviv: dont truncate physical page address Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 02/46] wifi: ath11k: fix warning in dma_free_coherent() of memory chunks while recovery Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 03/46] wifi: rtl8xxxu: gen2: Turn on the rate control Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 04/46] drm/edid: Fix minimum bpc supported with DSC1.2 for HDMI sink Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 05/46] clk: mxl: Switch from direct readl/writel based IO to regmap based IO Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 06/46] clk: mxl: Remove redundant spinlocks Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 07/46] clk: mxl: Add option to override gate clks Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 08/46] clk: mxl: Fix a clk entry by adding relevant flags Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 09/46] powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 10/46] clk: mxl: syscon_node_to_regmap() returns error pointers Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 11/46] sched/psi: Stop relying on timer_pending() for poll_work rescheduling Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 12/46] random: always mix cycle counter in add_latent_entropy() Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 13/46] scsi: libsas: Add smp_ata_check_ready_type() Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 14/46] scsi: hisi_sas: Fix SATA devices missing issue during I_T nexus reset Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 15/46] spi: mediatek: Enable irq when pdata is ready Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 16/46] docs: perf: Fix PMU instance name of hisi-pcie-pmu Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 17/46] KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 18/46] KVM: SVM: Skip WRMSR fastpath on VM-Exit if next RIP isnt valid Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 19/46] KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 20/46] can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 21/46] powerpc: dts: t208x: Disable 10G on MAC1 and MAC2 Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 22/46] spi: mediatek: Enable irq before the spi registration Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 23/46] drm/i915: Remove __maybe_unused from mtl_info Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 24/46] KVM: x86: fix deadlock for KVM_XEN_EVTCHN_RESET Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 25/46] selftests: kvm: move declaration at the beginning of main() Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 26/46] powerpc/64s/radix: Fix RWX mapping with relocated kernel Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 27/46] nfp: ethtool: support reporting link modes Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 28/46] nfp: ethtool: fix the bug of setting unsupported port speed Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 29/46] uaccess: Add speculation barrier to copy_from_user() Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 30/46] x86/alternatives: Introduce int3_emulate_jcc() Greg Kroah-Hartman
2023-02-23 13:06 ` Greg Kroah-Hartman [this message]
2023-02-23 13:06 ` [PATCH 6.1 32/46] x86/static_call: Add support for Jcc tail-calls Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 33/46] Bluetooth: btusb: Add more device IDs for WCN6855 Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 34/46] riscv: remove special treatment for the link order of head.o Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 35/46] arm64: " Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 36/46] arch: fix broken BuildID for arm64 and riscv Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 37/46] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 38/46] powerpc/vmlinux.lds: Dont discard .rela* for relocatable builds Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 39/46] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36 Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 40/46] sh: define RUNTIME_DISCARD_EXIT Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 41/46] wifi: mwifiex: Add missing compatible string for SD8787 Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 42/46] audit: update the mailing list in MAINTAINERS Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 43/46] platform/x86/amd/pmf: Add depends on CONFIG_POWER_SUPPLY Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 44/46] platform/x86: nvidia-wmi-ec-backlight: Add force module parameter Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 45/46] ext4: Fix function prototype mismatch for ext4_feat_ktype Greg Kroah-Hartman
2023-02-23 13:06 ` [PATCH 6.1 46/46] randstruct: disable Clang 15 support Greg Kroah-Hartman
2023-02-23 14:33 ` [PATCH 6.1 00/46] 6.1.14-rc1 review Conor Dooley
2023-02-23 14:37   ` Greg Kroah-Hartman
2023-02-23 14:41     ` Conor Dooley
2023-02-23 14:38   ` Naresh Kamboju
2023-02-23 16:31     ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230223130433.029351046@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=nathan@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=peterz@infradead.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).