Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2530656pxa; Mon, 24 Aug 2020 17:32:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxABhTJDoXBNC8ChUZtYxvZsr/pEPzzy8KGF8yDPwgDbqEimP0kyEWWfzBRx3px/oZuKp6e X-Received: by 2002:a17:906:474f:: with SMTP id j15mr7722139ejs.329.1598315568997; Mon, 24 Aug 2020 17:32:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598315568; cv=none; d=google.com; s=arc-20160816; b=IekMPsosikrF/gz2xHybQy7y55BtxuSsREsqVGngoGpo2LFmDmA2LT1AUJ+t5lssZF VCOeM92l4jmSYhsoDZttKv0X4a/M8QwSTH2Yn83qvR+0jgZX0uHnMT+cBZiemUNeDylZ xeqUQ5wpD0Q4AWJWJUeFuZndvSR3dwRSqIeD3+govV2OBN7BaQu08cBsVxIFUCbJAAnY XmPxY/B3EUN6BUvsrpOCHuRxHj4xXDkwqPQ1t+/s4MOH2mufFKNZgblXMNENjhgS0Vf1 YL3f0RrZWLIgSrEx/SODgZYp17fTXnGqAqm+p1iwDmH0Jpj8il5Q2Nety22zmkocc7SF pmng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=NucGYhVZ22RliUza+V5v79I88QP++RZKtwu1OHelCb0=; b=uWVFiri2fD7A9mPMDYP66L9dc37AKODnaEcpLJmGtwGevlCn9WCJqwgM4tkyByFg7/ MJpZrC/t/UNr4dyTErueAK2DFFP0U+Yb0l4KqrxdOJQOgxCzvGq27U868CYoyxn8G0pP vkdJvJaHW3CrReCIRMcbET7uDuxgG1WuoNZGLtJKS0fZS5Nq7DvsZ3xiAe1HXHGW/9o1 2VB0wvJqgFeZ9Ff04lagvIiymmyCOn3Jg/Vvv+t8BUUM43SAOzdQ/XK8AlDujnxdCp7t tIBMtlwou5BZszkB3jpnfIUYbj/lhbBnURQ1auJ3FDpaS5fKnCeSJL6FDn9NndYghUAx q6qg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a24si3723984edy.429.2020.08.24.17.32.26; Mon, 24 Aug 2020 17:32:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728597AbgHYAb1 (ORCPT + 99 others); Mon, 24 Aug 2020 20:31:27 -0400 Received: from mga01.intel.com ([192.55.52.88]:28750 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728479AbgHYAak (ORCPT ); Mon, 24 Aug 2020 20:30:40 -0400 IronPort-SDR: gwqbSS0rL6CaDx7mGG+l47DFdeEAzogMte8oXw5tPg5Bei2NJG+1Y5CdcE1FwHbk8pPOdi4kCk oj8h2i9S5F8w== X-IronPort-AV: E=McAfee;i="6000,8403,9723"; a="174053275" X-IronPort-AV: E=Sophos;i="5.76,350,1592895600"; d="scan'208";a="174053275" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2020 17:30:36 -0700 IronPort-SDR: sag8XSvzJd3jS7rbio7FMhabhFQ4iyYHrusWVG806CizD/87vdJCkYCrboG5zqXv07i8o0mNfU SVNQCLxxXIKQ== X-IronPort-AV: E=Sophos;i="5.76,350,1592895600"; d="scan'208";a="443429324" Received: from yyu32-desk.sc.intel.com ([143.183.136.146]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Aug 2020 17:30:36 -0700 From: Yu-cheng Yu To: x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-api@vger.kernel.org, Arnd Bergmann , Andy Lutomirski , Balbir Singh , Borislav Petkov , Cyrill Gorcunov , Dave Hansen , Eugene Syromiatnikov , Florian Weimer , "H.J. Lu" , Jann Horn , Jonathan Corbet , Kees Cook , Mike Kravetz , Nadav Amit , Oleg Nesterov , Pavel Machek , Peter Zijlstra , Randy Dunlap , "Ravi V. Shankar" , Vedvyas Shanbhogue , Dave Martin , Weijiang Yang Cc: Yu-cheng Yu Subject: [PATCH v11 6/9] x86/cet: Add PTRACE interface for CET Date: Mon, 24 Aug 2020 17:26:41 -0700 Message-Id: <20200825002645.3658-7-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200825002645.3658-1-yu-cheng.yu@intel.com> References: <20200825002645.3658-1-yu-cheng.yu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add REGSET_CET64/REGSET_CET32 to get/set CET MSRs: IA32_U_CET (user-mode CET settings) and IA32_PL3_SSP (user-mode Shadow Stack) Signed-off-by: Yu-cheng Yu --- arch/x86/include/asm/fpu/regset.h | 7 ++--- arch/x86/kernel/fpu/regset.c | 44 +++++++++++++++++++++++++++++++ arch/x86/kernel/ptrace.c | 16 +++++++++++ include/uapi/linux/elf.h | 1 + 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/fpu/regset.h b/arch/x86/include/asm/fpu/regset.h index 4f928d6a367b..8622184d87f5 100644 --- a/arch/x86/include/asm/fpu/regset.h +++ b/arch/x86/include/asm/fpu/regset.h @@ -7,11 +7,12 @@ #include -extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active; +extern user_regset_active_fn regset_fpregs_active, regset_xregset_fpregs_active, + cetregs_active; extern user_regset_get2_fn fpregs_get, xfpregs_get, fpregs_soft_get, - xstateregs_get; + xstateregs_get, cetregs_get; extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set, - xstateregs_set; + xstateregs_set, cetregs_set; /* * xstateregs_active == regset_fpregs_active. Please refer to the comment diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index c413756ba89f..8860d57eed35 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -149,6 +149,50 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, return ret; } +int cetregs_active(struct task_struct *target, const struct user_regset *regset) +{ +#ifdef CONFIG_X86_INTEL_CET + if (target->thread.cet.shstk_size || target->thread.cet.ibt_enabled) + return regset->n; +#endif + return 0; +} + +int cetregs_get(struct task_struct *target, const struct user_regset *regset, + struct membuf to) +{ + struct fpu *fpu = &target->thread.fpu; + struct cet_user_state *cetregs; + + if (!boot_cpu_has(X86_FEATURE_SHSTK)) + return -ENODEV; + + fpu__prepare_read(fpu); + cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_CET_USER); + if (!cetregs) + return -EFAULT; + + return membuf_write(&to, cetregs, sizeof(struct cet_user_state)); +} + +int cetregs_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + struct fpu *fpu = &target->thread.fpu; + struct cet_user_state *cetregs; + + if (!boot_cpu_has(X86_FEATURE_SHSTK)) + return -ENODEV; + + fpu__prepare_write(fpu); + cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_CET_USER); + if (!cetregs) + return -EFAULT; + + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, cetregs, 0, -1); +} + #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION /* diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 5679aa3fdcb8..ea54317f087e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -52,7 +52,9 @@ enum x86_regset { REGSET_IOPERM64 = REGSET_XFP, REGSET_XSTATE, REGSET_TLS, + REGSET_CET64 = REGSET_TLS, REGSET_IOPERM32, + REGSET_CET32, }; struct pt_regs_offset { @@ -1229,6 +1231,13 @@ static struct user_regset x86_64_regsets[] __ro_after_init = { .size = sizeof(long), .align = sizeof(long), .active = ioperm_active, .regset_get = ioperm_get }, + [REGSET_CET64] = { + .core_note_type = NT_X86_CET, + .n = sizeof(struct cet_user_state) / sizeof(u64), + .size = sizeof(u64), .align = sizeof(u64), + .active = cetregs_active, .regset_get = cetregs_get, + .set = cetregs_set + }, }; static const struct user_regset_view user_x86_64_view = { @@ -1284,6 +1293,13 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { .size = sizeof(u32), .align = sizeof(u32), .active = ioperm_active, .regset_get = ioperm_get }, + [REGSET_CET32] = { + .core_note_type = NT_X86_CET, + .n = sizeof(struct cet_user_state) / sizeof(u64), + .size = sizeof(u64), .align = sizeof(u64), + .active = cetregs_active, .regset_get = cetregs_get, + .set = cetregs_set + }, }; static const struct user_regset_view user_x86_32_view = { diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index ca5875f384f6..d2a895369bcc 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -402,6 +402,7 @@ typedef struct elf64_shdr { #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ +#define NT_X86_CET 0x203 /* x86 cet state */ #define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ #define NT_S390_TIMER 0x301 /* s390 timer register */ #define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ -- 2.21.0