From patchwork Tue Nov 1 23:04:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 13949 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp3261335wru; Tue, 1 Nov 2022 16:06:12 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5IwDi2nIHHgIvP+N8EM9gC0jK20tRM9/Yz9yS34AcRkeT7/ge3igRFf4do/nQY7sAm6qhL X-Received: by 2002:a17:90b:1d83:b0:212:dc2f:8fc7 with SMTP id pf3-20020a17090b1d8300b00212dc2f8fc7mr22228320pjb.131.1667343971969; Tue, 01 Nov 2022 16:06:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667343971; cv=none; d=google.com; s=arc-20160816; b=IMN+iLGza+HdZDk7jkbBLJhJz9OmgEfFjLabk8brq/SbwcPv9xBwMaKpWuFbAQoFhs u/wt5b4fsNkhFai2TuOjxaJr9jRDSLu9XYphL2p1kejGeV5KDPFZTHT5GBpMm8OsDqbt GxnYZMTRbtWCtQFI0ATrKc1lC2oEOw8AdB/xL3doe6B1s96CYGciwHbmx1jJs8mD8KHq MSt9eN5sGBfeVaKVM6u0QG/y5dTJqsYNILUqLbsFGk1tgGi/5bv/JVBZw0LrFUBfaNsR PV9LApjv7Z85W1pHhRohp0EjQuqzRKa3Y7kvdNUw2yZwvC/hcKgCz5hNWOhjSm4wOWPw Okyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:cc:subject:to:reply-to:sender:from :dkim-signature:dkim-signature:date; bh=WD+G+Uxb+v4ewbeu9TbEWW6KWo1rHolE90Dw44iBr0o=; b=dTgN5fQkFUs8nyOkh9dumUzfiRnpm7TSOsMIsgtFU1rUGmWqvheCi3CiIg1DH60QFM mPiaLN9SuRcULgDEhS9w3dtfzzC3L0uqhHpKMM37SiYDUY2R9tOl6CtSPzzIC/SUlrnC HfwQTtw3/IyT7/7Z0GfdtGFMmU1Kjs5gLnEvRiXC3LJVTgwz1iGx7/9fAsmdGmQyGPdl B11aumBKJ2jsLte8I69oA3iZrmDvah8fDZ3L0Ll62Z0qizTQtr6kDNlkJyS3+OIYcudl Pi0pl3u4iiiR+pZZsCsfYKiPuIdpKqAZA5423ahBbDjyxZAfuLiunOvo4UV5WgZsFSjj 2zeg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=zAC6ZC+Y; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h22-20020a635756000000b0046fbaeb1253si9378346pgm.49.2022.11.01.16.05.59; Tue, 01 Nov 2022 16:06:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=zAC6ZC+Y; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230466AbiKAXET (ORCPT + 99 others); Tue, 1 Nov 2022 19:04:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230292AbiKAXEM (ORCPT ); Tue, 1 Nov 2022 19:04:12 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3ABE7389A; Tue, 1 Nov 2022 16:04:11 -0700 (PDT) Date: Tue, 01 Nov 2022 23:04:08 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1667343849; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WD+G+Uxb+v4ewbeu9TbEWW6KWo1rHolE90Dw44iBr0o=; b=zAC6ZC+YghB6aUW6BAYZluADi53ONy0z6dp2pPOSBqD0ipdUM7cbY0kQ1O4SWKXWgjcmN1 /C/bkH17pide7ms/fQ/2HmV+NpX/xpKTJbRLU7RxP9WUWM9HYs0kl2aielwNz5DXGMdBkx m5M6XWkipVu+Vf4zsp0RU9RvNf6VE1UnCuVfyV57ElWS7A8+HhpfDlcMXITgrB5d0+wZWJ wF9avn8f/4+wAxWOxeZLizsxW4F7WJhswPW9xCg4acgge/kZR3Esr/wsORegYvvEZNvpf0 E2cVsFMZ+P1jVm+AyrEFipYoi4U3HUJNMu3LYwfG0w301uDIwn8WtuUk/oQ4CQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1667343849; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WD+G+Uxb+v4ewbeu9TbEWW6KWo1rHolE90Dw44iBr0o=; b=LHTftzKn6hBI9SLnbu4Cx2Mze8UMYU5Bu68lC9CShZTJvVSehqoLROz5yxmJyDISvkqjV6 nWoy9t2NQKWVflBw== From: "tip-bot2 for Rick Edgecombe" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/cleanups] x86: Separate out x86_regset for 32 and 64 bit Cc: Rick Edgecombe , Dave Hansen , x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <166734384866.7716.1523996090665390520.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748336873071203995?= X-GMAIL-MSGID: =?utf-8?q?1748336873071203995?= The following commit has been merged into the x86/cleanups branch of tip: Commit-ID: d28abd23b9270f67a9ad098d9338db6a8109fd59 Gitweb: https://git.kernel.org/tip/d28abd23b9270f67a9ad098d9338db6a8109fd59 Author: Rick Edgecombe AuthorDate: Fri, 21 Oct 2022 15:18:02 -07:00 Committer: Dave Hansen CommitterDate: Tue, 01 Nov 2022 15:36:52 -07:00 x86: Separate out x86_regset for 32 and 64 bit In fill_thread_core_info() the ptrace accessible registers are collected for a core file to be written out as notes. The note array is allocated from a size calculated by iterating the user regset view, and counting the regsets that have a non-zero core_note_type. However, this only allows for there to be non-zero core_note_type at the end of the regset view. If there are any in the middle, fill_thread_core_info() will overflow the note allocation, as it iterates over the size of the view and the allocation would be smaller than that. To apparently avoid this problem, x86_32_regsets and x86_64_regsets need to be constructed in a special way. They both draw their indices from a shared enum x86_regset, but 32 bit and 64 bit don't all support the same regsets and can be compiled in at the same time in the case of IA32_EMULATION. So this enum has to be laid out in a special way such that there are no gaps for both x86_32_regsets and x86_64_regsets. This involves ordering them just right by creating aliases for enum’s that are only in one view or the other, or creating multiple versions like REGSET32_IOPERM/REGSET64_IOPERM. So the collection of the registers tries to minimize the size of the allocation, but it doesn’t quite work. Then the x86 ptrace side works around it by constructing the enum just right to avoid a problem. In the end there is no functional problem, but it is somewhat strange and fragile. It could also be improved like this [1], by better utilizing the smaller array, but this still wastes space in the regset array’s if they are not carefully crafted to avoid gaps. Instead, just fully separate out the enums and give them separate 32 and 64 enum names. Add some bitsize-free defines for REGSET_GENERAL and REGSET_FP since they are the only two referred to in bitsize generic code. While introducing a bunch of new 32/64 enums, change the pattern of the name from REGSET_FOO32 to REGSET32_FOO to better indicate that the 32 is in reference to the CPU mode and not the register size, as suggested by Eric Biederman. This should have no functional change and is only changing how constants are generated and referred to. [1] https://lore.kernel.org/lkml/20180717162502.32274-1-yu-cheng.yu@intel.com/ Signed-off-by: Rick Edgecombe Signed-off-by: Dave Hansen Link: https://lore.kernel.org/all/20221021221803.10910-2-rick.p.edgecombe%40intel.com --- arch/x86/kernel/ptrace.c | 67 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 37c12fb..356495a 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -44,16 +44,35 @@ #include "tls.h" -enum x86_regset { - REGSET_GENERAL, - REGSET_FP, - REGSET_XFP, - REGSET_IOPERM64 = REGSET_XFP, - REGSET_XSTATE, - REGSET_TLS, - REGSET_IOPERM32, +enum x86_regset_32 { + REGSET32_GENERAL, + REGSET32_FP, + REGSET32_XFP, + REGSET32_XSTATE, + REGSET32_TLS, + REGSET32_IOPERM, }; +enum x86_regset_64 { + REGSET64_GENERAL, + REGSET64_FP, + REGSET64_IOPERM, + REGSET64_XSTATE, +}; + +#define REGSET_GENERAL \ +({ \ + BUILD_BUG_ON((int)REGSET32_GENERAL != (int)REGSET64_GENERAL); \ + REGSET32_GENERAL; \ +}) + +#define REGSET_FP \ +({ \ + BUILD_BUG_ON((int)REGSET32_FP != (int)REGSET64_FP); \ + REGSET32_FP; \ +}) + + struct pt_regs_offset { const char *name; int offset; @@ -788,13 +807,13 @@ long arch_ptrace(struct task_struct *child, long request, #ifdef CONFIG_X86_32 case PTRACE_GETFPXREGS: /* Get the child extended FPU state. */ return copy_regset_to_user(child, &user_x86_32_view, - REGSET_XFP, + REGSET32_XFP, 0, sizeof(struct user_fxsr_struct), datap) ? -EIO : 0; case PTRACE_SETFPXREGS: /* Set the child extended FPU state. */ return copy_regset_from_user(child, &user_x86_32_view, - REGSET_XFP, + REGSET32_XFP, 0, sizeof(struct user_fxsr_struct), datap) ? -EIO : 0; #endif @@ -1086,13 +1105,13 @@ static long ia32_arch_ptrace(struct task_struct *child, compat_long_t request, case PTRACE_GETFPXREGS: /* Get the child extended FPU state. */ return copy_regset_to_user(child, &user_x86_32_view, - REGSET_XFP, 0, + REGSET32_XFP, 0, sizeof(struct user32_fxsr_struct), datap); case PTRACE_SETFPXREGS: /* Set the child extended FPU state. */ return copy_regset_from_user(child, &user_x86_32_view, - REGSET_XFP, 0, + REGSET32_XFP, 0, sizeof(struct user32_fxsr_struct), datap); @@ -1215,25 +1234,25 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, #ifdef CONFIG_X86_64 static struct user_regset x86_64_regsets[] __ro_after_init = { - [REGSET_GENERAL] = { + [REGSET64_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = sizeof(struct user_regs_struct) / sizeof(long), .size = sizeof(long), .align = sizeof(long), .regset_get = genregs_get, .set = genregs_set }, - [REGSET_FP] = { + [REGSET64_FP] = { .core_note_type = NT_PRFPREG, .n = sizeof(struct fxregs_state) / sizeof(long), .size = sizeof(long), .align = sizeof(long), .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set }, - [REGSET_XSTATE] = { + [REGSET64_XSTATE] = { .core_note_type = NT_X86_XSTATE, .size = sizeof(u64), .align = sizeof(u64), .active = xstateregs_active, .regset_get = xstateregs_get, .set = xstateregs_set }, - [REGSET_IOPERM64] = { + [REGSET64_IOPERM] = { .core_note_type = NT_386_IOPERM, .n = IO_BITMAP_LONGS, .size = sizeof(long), .align = sizeof(long), @@ -1256,31 +1275,31 @@ static const struct user_regset_view user_x86_64_view = { #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION static struct user_regset x86_32_regsets[] __ro_after_init = { - [REGSET_GENERAL] = { + [REGSET32_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = sizeof(struct user_regs_struct32) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .regset_get = genregs32_get, .set = genregs32_set }, - [REGSET_FP] = { + [REGSET32_FP] = { .core_note_type = NT_PRFPREG, .n = sizeof(struct user_i387_ia32_struct) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .active = regset_fpregs_active, .regset_get = fpregs_get, .set = fpregs_set }, - [REGSET_XFP] = { + [REGSET32_XFP] = { .core_note_type = NT_PRXFPREG, .n = sizeof(struct fxregs_state) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set }, - [REGSET_XSTATE] = { + [REGSET32_XSTATE] = { .core_note_type = NT_X86_XSTATE, .size = sizeof(u64), .align = sizeof(u64), .active = xstateregs_active, .regset_get = xstateregs_get, .set = xstateregs_set }, - [REGSET_TLS] = { + [REGSET32_TLS] = { .core_note_type = NT_386_TLS, .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN, .size = sizeof(struct user_desc), @@ -1288,7 +1307,7 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { .active = regset_tls_active, .regset_get = regset_tls_get, .set = regset_tls_set }, - [REGSET_IOPERM32] = { + [REGSET32_IOPERM] = { .core_note_type = NT_386_IOPERM, .n = IO_BITMAP_BYTES / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), @@ -1311,10 +1330,10 @@ u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; void __init update_regset_xstate_info(unsigned int size, u64 xstate_mask) { #ifdef CONFIG_X86_64 - x86_64_regsets[REGSET_XSTATE].n = size / sizeof(u64); + x86_64_regsets[REGSET64_XSTATE].n = size / sizeof(u64); #endif #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION - x86_32_regsets[REGSET_XSTATE].n = size / sizeof(u64); + x86_32_regsets[REGSET32_XSTATE].n = size / sizeof(u64); #endif xstate_fx_sw_bytes[USER_XSTATE_XCR0_WORD] = xstate_mask; }