From nobody Fri Nov 29 04:51:56 2024 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=1647255699; cv=none; d=zohomail.com; s=zohoarc; b=Zw+UhvVvh0EAtGc6dCJMZMBrd1/cTp9j7TTawuvmeNLpilbXC7DTWG63/VRVJwnJ5S30wYnuYcltgCxSK3CcBflNqqVZO3CmXFwUKoH/hoVhzOPAU8WYa/xxcbpgdHz8Yz8D+sZy8yXfJVMF1FnrxcGnMdhesLBomRvKySQh9A4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1647255699; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=fhjF4JQzPYd97H9KlC/geqkwETPPVkw39X23Pp7aX0M=; b=K6Tn0KKeGiKOexHXM9S4VgeZQZHTm1S2yNy2WzfKG+b6oC1f0YNSOuusfjohU87RHCb31SLhw/7VmLZj7ad0pGjTyZWWkpws7ZtBaibQsVedhR+j+DnMMCIPD2FXTJupOQjpu5EL+mpDrkqGx+k7Unx0DEkVJsUZbZFCS8Rkt8c= 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 1647255699457413.4735904178772; Mon, 14 Mar 2022 04:01:39 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.290150.492068 (Exim 4.92) (envelope-from ) id 1nTiRd-0001wM-44; Mon, 14 Mar 2022 11:00:57 +0000 Received: by outflank-mailman (output) from mailman id 290150.492068; Mon, 14 Mar 2022 11:00:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nTiRd-0001wF-0d; Mon, 14 Mar 2022 11:00:57 +0000 Received: by outflank-mailman (input) for mailman id 290150; Mon, 14 Mar 2022 11:00:56 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nTiRc-0001w5-3j for xen-devel@lists.xenproject.org; Mon, 14 Mar 2022 11:00:56 +0000 Received: from esa1.hc3370-68.iphmx.com (esa1.hc3370-68.iphmx.com [216.71.145.142]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ff5ab574-a385-11ec-853b-5f4723681683; Mon, 14 Mar 2022 12:00:46 +0100 (CET) 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: ff5ab574-a385-11ec-853b-5f4723681683 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1647255654; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=cdyEoBU/f1cnQ43XUIskjAet3xho8xWImznx9yUFDrc=; b=cdxQ1xFjs1o8zJhYFDlPRs9kNioYkuh7BFcO6zbbrOR0TgVVoyFp9aVU YYt46cG6AWcB5Uag3SyfzORx3fyZSz7Zfj1rfA9QWqwgBKZEFLaMLBLFp rnjh9MFqbfzET+l4/jlM3E6Kdk8c68NldzZaYh0EUtTFo/D38lQ8gjKUR 8=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none X-SBRS: 5.1 X-MesageID: 66562350 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.156.83 X-Policy: $RELAYED IronPort-Data: A9a23:e0rf4KplmGQFcJ9DiZP4/BBZPnheBmIIZRIvgKrLsJaIsI4StFCzt garIBnQPP+LNDage9B0aom+pk8GvMPQzdZjT1Ruqy9nESlEpJuZCYyVIHmrMnLJJKUvbq7GA +byyDXkBJppJpMJjk71atANlVEliefQAOCU5NfsYkidfyc9IMsaoU8lyrZRbrJA24DjWVvW4 I+q+qUzBXf+s9JKGjNMg068gEsHUMTa4Fv0aXRnOJinFHeH/5UkJMp3yZOZdhMUcaENdgKOf M7RzanRw4/s10xF5uVJMFrMWhZirrb6ZWBig5fNMkSoqkAqSicais7XOBeAAKv+Zvrgc91Zk b1wWZKMpQgBGv2WwfU4XEViHXtZD+5k17/lA2XivpnGp6HGWyOEL/RGCUg3OcsT+/ptAHEI/ vsdQNwPRknd3aTsmuv9E7QywJR4RCXoFNp3VnVI5DfVF/s5B7vERL3H/4Rw1zYsnMFeW/3ZY qL1bBIxMkmeOUYSYj/7DroArcCPnCO8eAdn9nmemPsx2neU6R5Yhe2F3N39JYXRGJQ9clyjj n3C13T0BFcdLtP34T+M6HelnOLMtSL9RoMJFbe8++JqgVuc3WgaAlsdUl7Tiem0jAuyVsxSL 2QQ+zEytu4i+UqzVN7/Uhak5nmesXY0efBdDuk74wGl0bfP7kCSAW1sc9JaQIV47olsH2Vsj wLX2YOybdByjFGLYVbNrO6FiDzuAyZPCl1BRwAEbykYvta29enfkSnzZtpkFae0iPj8Fjfx3 y2GoUACulkDsSIY//7lpA6a2lpAsrCMF1dovVuPAgpJ+ysjPOaYi5qUBU83BBqqBKKQVRG/s XcNgKByB8heXMjWxERhrAjgdYxFBspp0hWB2zaD/LF7rlxBHkJPmqgKvFlDyL9BaJpsRNMQS Ba7VfltzJFSJmC2SqR8fpi8Dc8npYC5S4i6D6GLNIIRPcEpHONiwM2JTRTMt10BbWB2yf1vU XtlWZvE4Ykm5VRPk2PtGrZ1PU4DzSEi32LDLa0XPDz8uYdykEW9EO9fWHPXN7hRxPrd/G39r oYOX+PXmk43eLCvPUHqHXs7cAliwY4TXsut9aS6t4erf2JbJY3WI6SIkO17JNA9wfg9eyWh1 ijVZ3K0AWHX3RXvQThmoFg5AF8zdf6TdU4GABE= IronPort-HdrOrdr: A9a23:cPdSHqDmP59tFC/lHemf55DYdb4zR+YMi2TDgXoBMCC9E/bo8v xH/pwgvyMc7Qx9ZJhOo7y90cW7Lk80lqQFg7X5X43DYOC8ghrPEGgK1+KLqAEIfReRygc379 YCT0ERMrzN5fcRt7eD3OEVeexQpOVuUcqT9IDj80s= X-IronPort-AV: E=Sophos;i="5.90,180,1643691600"; d="scan'208";a="66562350" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Wei Liu , =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Subject: [PATCH] x86/cet: Clear IST supervisor token busy bits on S3 resume Date: Mon, 14 Mar 2022 11:00:34 +0000 Message-ID: <20220314110034.28498-1-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 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: 1647255700300100001 Stacks are not freed across S3. Execution just stops, leaving supervisor token busy bits active. Fixing this for the primary shadow stack was done previously, but there is a (rare) risk that an IST token is left busy too. This will manifest as #DF next time the IST vector gets used. Introduce rdssp() and wrss() helpers in a new shstk.h, cleaning up fixup_exception_return() and explaining the trick with the literal 1. Then this infrastructure to rewrite the IST tokens in load_system_tables() when all the other IST details are being set up. In the case that an IST token were left busy across S3, this will clear the busy bit before the sta= ck gets used. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 CC: Wei Liu CC: Marek Marczykowski-G=C3=B3recki --- xen/arch/x86/cpu/common.c | 25 ++++++++++++++++++---- xen/arch/x86/include/asm/shstk.h | 46 ++++++++++++++++++++++++++++++++++++= ++++ xen/arch/x86/traps.c | 8 +++---- 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 xen/arch/x86/include/asm/shstk.h diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index bd2207163a35..6eab7dbe894c 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include /* for XEN_INVALID_{SOCKET,CORE}_ID */ =20 @@ -826,15 +827,31 @@ void load_system_tables(void) */ if (cpu_has_xen_shstk) { volatile uint64_t *ist_ssp =3D tss_page->ist_ssp; + unsigned long + mce_ssp =3D stack_top + (IST_MCE * IST_SHSTK_SIZE) - 8, + nmi_ssp =3D stack_top + (IST_NMI * IST_SHSTK_SIZE) - 8, + db_ssp =3D stack_top + (IST_DB * IST_SHSTK_SIZE) - 8, + df_ssp =3D stack_top + (IST_DF * IST_SHSTK_SIZE) - 8; =20 ist_ssp[0] =3D 0x8600111111111111ul; - ist_ssp[IST_MCE] =3D stack_top + (IST_MCE * IST_SHSTK_SIZE) - 8; - ist_ssp[IST_NMI] =3D stack_top + (IST_NMI * IST_SHSTK_SIZE) - 8; - ist_ssp[IST_DB] =3D stack_top + (IST_DB * IST_SHSTK_SIZE) - 8; - ist_ssp[IST_DF] =3D stack_top + (IST_DF * IST_SHSTK_SIZE) - 8; + ist_ssp[IST_MCE] =3D mce_ssp; + ist_ssp[IST_NMI] =3D nmi_ssp; + ist_ssp[IST_DB] =3D db_ssp; + ist_ssp[IST_DF] =3D df_ssp; for ( i =3D IST_DF + 1; i < ARRAY_SIZE(tss_page->ist_ssp); ++i ) ist_ssp[i] =3D 0x8600111111111111ul; =20 + if (rdssp() !=3D SSP_NO_SHSTK) { + /* + * Rewrite supervisor tokens when shadow stacks are + * active. This resets any busy bits left across S3. + */ + wrss(mce_ssp, _p(mce_ssp)); + wrss(nmi_ssp, _p(nmi_ssp)); + wrss(db_ssp, _p(db_ssp)); + wrss(df_ssp, _p(df_ssp)); + } + wrmsrl(MSR_INTERRUPT_SSP_TABLE, (unsigned long)ist_ssp); } =20 diff --git a/xen/arch/x86/include/asm/shstk.h b/xen/arch/x86/include/asm/sh= stk.h new file mode 100644 index 000000000000..a26e3c70f0c6 --- /dev/null +++ b/xen/arch/x86/include/asm/shstk.h @@ -0,0 +1,46 @@ +/*************************************************************************= ***** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see . + * + * Copyright (c) 2022 Citrix Systems Ltd. + */ +#ifndef XEN_ASM_SHSTK_H +#define XEN_ASM_SHSTK_H + +/* + * RDSSP is a nop when shadow stacks are active. Also, SSP has a minimum + * alignment of 4 which enforced by hardware. + * + * We load 1 into a register, then RDSSP. If shadow stacks are not active, + * RDSSP is a nop, and the 1 is preserved. If shadow stacks are active, t= he 1 + * is clobbered with the real SSP, which has the bottom two bits clear. + */ +#define SSP_NO_SHSTK 1 + +static inline unsigned long rdssp(void) +{ + unsigned long ssp; + + asm volatile ( "rdsspq %0" : "=3Dr" (ssp) : "0" (SSP_NO_SHSTK) ); + + return ssp; +} + +static inline void wrss(unsigned long val, unsigned long *ptr) +{ + asm ( "wrssq %[val], %[ptr]" + : [ptr] "=3Dm" (*ptr) + : [val] "r" (val) ); +} + +#endif /* XEN_ASM_SHSTK_H */ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index a2278d9499d0..86595479707a 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -84,6 +84,7 @@ #include #include #include +#include =20 /* * opt_nmi: one of 'ignore', 'dom0', or 'fatal'. @@ -868,8 +869,7 @@ static void fixup_exception_return(struct cpu_user_regs= *regs, { unsigned long ssp, *ptr, *base; =20 - asm ( "rdsspq %0" : "=3Dr" (ssp) : "0" (1) ); - if ( ssp =3D=3D 1 ) + if ( (ssp =3D rdssp()) =3D=3D SSP_NO_SHSTK ) goto shstk_done; =20 ptr =3D _p(ssp); @@ -898,9 +898,7 @@ static void fixup_exception_return(struct cpu_user_regs= *regs, */ if ( ptr[0] =3D=3D regs->rip && ptr[1] =3D=3D regs->cs ) { - asm ( "wrssq %[fix], %[stk]" - : [stk] "=3Dm" (ptr[0]) - : [fix] "r" (fixup) ); + wrss(fixup, ptr); goto shstk_done; } } --=20 2.11.0