From nobody Tue Mar 3 05:12:18 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1772234221; cv=none; d=zohomail.com; s=zohoarc; b=cdMjDN6/37ELpNE5fR1cYgXAKGx7pmGwRxBWt3XSnIwIFNCa9gQfSevHlQt6BEMa9pMAOz4qU81SZN2nn1qPWDs5GVMWZMqtr+YU/ivg0y8OAIJbRPSlIEnomF16n7v2vYp4sRhmzT+ZAlP1FVGbYLIWSkScyfReSQbxZpsqH4c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772234221; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=qm1+0hl5wg0cTPkZkQcfwjLCPbdvhVekwrZIT03s7DQ=; b=XqDrAUy/x9zCMRDtrYKguPZ0Kx/WFgJ31V192RAagsAOOuaYOH8+fiUW+N0WB5mLYzKh71kH2YOZUrfaZl57y1EpUM9swX9ZcXQZhqpEcTCB6HEdwRppvirX3bUGOB2UjYq/XwjteDucxF+/31ldLUTszws+MNflMMzBbNRfrFg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1772234221180152.98981605259178; Fri, 27 Feb 2026 15:17:01 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1243138.1543132 (Exim 4.92) (envelope-from ) id 1vw74f-0000jx-4G; Fri, 27 Feb 2026 23:16:45 +0000 Received: by outflank-mailman (output) from mailman id 1243138.1543132; Fri, 27 Feb 2026 23:16:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vw74e-0000jq-Vy; Fri, 27 Feb 2026 23:16:44 +0000 Received: by outflank-mailman (input) for mailman id 1243138; Fri, 27 Feb 2026 23:16:43 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vw74d-0008WD-T1 for xen-devel@lists.xenproject.org; Fri, 27 Feb 2026 23:16:43 +0000 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [2a00:1450:4864:20::42f]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 60dd154e-1432-11f1-b164-2bf370ae4941; Sat, 28 Feb 2026 00:16:43 +0100 (CET) Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-436309f1ad7so2114584f8f.3 for ; Fri, 27 Feb 2026 15:16:43 -0800 (PST) Received: from localhost.localdomain (host-92-22-18-152.as13285.net. [92.22.18.152]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4399c70e8e8sm9680306f8f.10.2026.02.27.15.16.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Feb 2026 15:16:40 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 60dd154e-1432-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1772234202; x=1772839002; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qm1+0hl5wg0cTPkZkQcfwjLCPbdvhVekwrZIT03s7DQ=; b=NhvaORhEENEHrYdMpzFOb00mPzdMS8s5p3eibErAyaHS4HN5cZMw0VCwtVsAfoVCUS FezmlqiwMN81ItFbwEasbRZTCpP7QdY5HXGERw0ZvGFlDrA39NOOpy8G0qLUmGn1WCdf vsr6rSX0DSuobDRlofwDyt9M2ufMohsvkWFH8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772234202; x=1772839002; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qm1+0hl5wg0cTPkZkQcfwjLCPbdvhVekwrZIT03s7DQ=; b=jtbBe6sK4hUekdOHZSj7/gFRhXMsOehouPHBhHPFf7DYOVCnFV/urAr5LClLPMJdmu c3I6yYQ8N0NonZbel7gmPgTx0BsZIgVfi500ltLJOwig1JcUZBOKX1FHnw4Aj1v0kq7M rsgAUk6e3qR/U1xMiTejgkeIghFYVEmMQMHrT8GiURTpy8bFUI0noz8ShoQLj/3ex8zO 66Zs2FxqyVARxEhvMUzkKHb0N65OyfjUIbqnqRZfHNmRUnVL64FCcy9xpOrXFCNQThP1 0M+7YyLN0/bZMdJ4QVeY1ieaiM2kNJ69H7lzcwQ+YrAZKMAsQO39SrY87OO1FviCd/F2 y30g== X-Gm-Message-State: AOJu0YxWfm9Xw5aMV35qa9obqqE3HDHEVJt3OcxxxOuS2v4fIVM3GkQE 6t2XNUXH1ME0OLfmrOOOjUldlDtmsoObosKQp/43B7PdKlw4bF58gAsQMjuXRGUAbpbVBv9cjSj q+BMS X-Gm-Gg: ATEYQzwOOi0gYW1S98Cu8s0fLFST1in5LE8muKd2HEcSE0ilbhs60OlAjjc4JjQjObp GKx6JPoNKAgJqiX9Syk3x8ZSMK807qwS5tkHn0wie++zk9JNIx5pNedmw1Dgqgr4VvxCzH1eqle odeSkCUQM+wn94ktZUF9JJSeMfPpQ2zT7TYfwL2b9wpkIfWdwZADGNrKncfgjg9PMlnPlaHvvVg VE8iN2ydvjBKl1fgX1a6ck9BKlMzmBwOFaVFDcNEpYZSxkeSlilcX8kT70MjouHu6HKsDud+Grh Qp0Rx3CP3wAfYndQs8aB3t0vCIfUCd8tC2BWNzxQwy6gXhN/3CkxFH4C5ePhCXFKrqf6dR3DxyY PJw8VvXnw++M6RWMMZ+5m+J2Z0pTlv21J7V6okdA/m2CG7hHW2atBFq/QJxfAvO114wkmUHc3VA 4Wm56gSxcj574NYLqxR0BPqgT5DNW4siz1zy8+r7SJkcxjYbLkWk9xECn4X6tuf1uuGUcCvdI= X-Received: by 2002:a05:6000:2313:b0:439:84cb:288d with SMTP id ffacd0b85a97d-4399de2cb36mr7877033f8f.41.1772234201407; Fri, 27 Feb 2026 15:16:41 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v4 01/14] x86/pv: Don't assume that INT $imm8 instructions are two bytes long Date: Fri, 27 Feb 2026 23:16:23 +0000 Message-Id: <20260227231636.3955109-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260227231636.3955109-1-andrew.cooper3@citrix.com> References: <20260227231636.3955109-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1772234222339158500 For INT $N instructions (besides $0x80 for which there is a dedicated fast path), handling is mostly fault-based because of DPL0 gates in the IDT. Th= is means that when the guest kernel allows the instruction too, Xen must increment %rip to the end of the instruction before passing a trap to the guest kernel. When an INT $N instruction has a prefix, it's longer than two bytes, and Xen will deliver the "trap" with %rip pointing into the middle of the instructi= on. Introduce a new pv_emulate_sw_interrupt() which uses x86_insn_length() to determine the instruction length, rather than assuming two. This is a change in behaviour for PV guests, but the prior behaviour cannot reasonably be said to be intentional. This change does not affect the INT $0x80 fastpath. Prefixed INT $N instructions occur almost exclusively in test code or exploits, and INT $0x= 80 appears to be the only user-usable interrupt gate in contemporary PV guests. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 v4: * New --- xen/arch/x86/include/asm/pv/traps.h | 2 ++ xen/arch/x86/pv/emul-priv-op.c | 48 +++++++++++++++++++++++++++++ xen/arch/x86/traps.c | 3 +- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/include/asm/pv/traps.h b/xen/arch/x86/include/asm= /pv/traps.h index 8c201190923d..16e9a8d2aa3f 100644 --- a/xen/arch/x86/include/asm/pv/traps.h +++ b/xen/arch/x86/include/asm/pv/traps.h @@ -17,6 +17,7 @@ int pv_raise_nmi(struct vcpu *v); =20 int pv_emulate_privileged_op(struct cpu_user_regs *regs); +void pv_emulate_sw_interrupt(struct cpu_user_regs *regs); void pv_emulate_gate_op(struct cpu_user_regs *regs); bool pv_emulate_invalid_op(struct cpu_user_regs *regs); =20 @@ -31,6 +32,7 @@ static inline bool pv_trap_callback_registered(const stru= ct vcpu *v, static inline int pv_raise_nmi(struct vcpu *v) { return -EOPNOTSUPP; } =20 static inline int pv_emulate_privileged_op(struct cpu_user_regs *regs) { r= eturn 0; } +static inline void pv_emulate_sw_interrupt(struct cpu_user_regs *regs) {} static inline void pv_emulate_gate_op(struct cpu_user_regs *regs) {} static inline bool pv_emulate_invalid_op(struct cpu_user_regs *regs) { ret= urn true; } =20 diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index a3c1fd12621d..87d3bbcf901f 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -8,6 +8,7 @@ */ =20 #include +#include #include #include #include @@ -1401,6 +1402,53 @@ int pv_emulate_privileged_op(struct cpu_user_regs *r= egs) return 0; } =20 +/* + * Hardware already decoded the INT $N instruction and determinted that th= ere + * was a DPL issue, hence the #GP. Xen has already determined that the gu= est + * kernel has permitted this software interrupt. + * + * All that is needed is the instruction length, to turn the fault into a + * trap. All errors are turned back into the original #GP, as that's the + * action that really happened. + */ +void pv_emulate_sw_interrupt(struct cpu_user_regs *regs) +{ + struct vcpu *curr =3D current; + struct domain *currd =3D curr->domain; + struct priv_op_ctxt ctxt =3D { + .ctxt.regs =3D regs, + .ctxt.lma =3D !is_pv_32bit_domain(currd), + }; + struct x86_emulate_state *state; + uint8_t vector =3D regs->error_code >> 3; + unsigned int len, ar; + + if ( !pv_emul_read_descriptor(regs->cs, curr, &ctxt.cs.base, + &ctxt.cs.limit, &ar, 1) || + !(ar & _SEGMENT_S) || + !(ar & _SEGMENT_P) || + !(ar & _SEGMENT_CODE) ) + goto error; + + state =3D x86_decode_insn(&ctxt.ctxt, insn_fetch); + if ( IS_ERR_OR_NULL(state) ) + goto error; + + len =3D x86_insn_length(state, &ctxt.ctxt); + x86_emulate_free_state(state); + + /* Note: Checked slightly late to simplify 'state' handling. */ + if ( ctxt.ctxt.opcode !=3D 0xcd /* INT $imm8 */ ) + goto error; + + regs->rip +=3D len; + pv_inject_sw_interrupt(vector); + return; + + error: + pv_inject_hw_exception(X86_EXC_GP, regs->entry_vector); +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 5feac88d6c0b..907fb4c186c0 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1379,8 +1379,7 @@ void do_general_protection(struct cpu_user_regs *regs) =20 if ( permit_softint(TI_GET_DPL(ti), v, regs) ) { - regs->rip +=3D 2; - pv_inject_sw_interrupt(vector); + pv_emulate_sw_interrupt(regs); return; } } --=20 2.39.5