Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp10897581imu; Thu, 6 Dec 2018 08:25:41 -0800 (PST) X-Google-Smtp-Source: AFSGD/Wqz8Ri3yMKfqpXB0I8xL8BrdW41X2gybigQKbmnXCQXyoD5p6EqClKNR/QJJ8ejzwTIMdZ X-Received: by 2002:a63:d655:: with SMTP id d21mr23474966pgj.280.1544113541756; Thu, 06 Dec 2018 08:25:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544113541; cv=none; d=google.com; s=arc-20160816; b=Gywcfzkc/q5Lx6D7RO/5kqt7gmxY7S270EzLau6RDsGKs63vbEHUlVT1VsXgFvQImW 1P7p2ZpK/VVWZp2iqOWszYxYKqe7bLcubhrymKyV+ALN6m6gAZVw8/8207zrwxMzsKHS XPhlPc7hdi6+LYUhtqcSXBN7w00ouKoQi/EniF+hVlggrO5p2yuIwcgodSfhptTWRosH iSYDAiJT7erwpU5iLNOVZOaQhLKYWTk7Cdo5qSsDmCwF7adcdompza3enRJnG1d5GsrN e7Q/zxpEKYFhY4yh4Q77w85QnvUlHPp0PruTBHIVSaqhqOKHngeRi4T6nT7JGl5zjvQR OqfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=VWAAkCawjwQLxdAls8KtL7gJfoLNQB5klFgyJ1pyUkY=; b=ZAHK4/QeFVTGbeYkFTaibNUoQKInkSV/e50V0n/0hu5M6KlRGyV8BsJ2wP4vFEjT1P T/DTGtbBUDg/7M/vk6aCrxv9i41WkWk5LtGzB9J+CTT4gW92u8YnypAIcf+NA0FfSqto 7ZfbK1Vp6B4x7Xtt+AGpdWkqhFiZQ2tjpW27oGf+UJ0eIAb+oo4lCjpu9fBlbM9pyhys MuFz5mID8ybXriwHLt4z/HeNpR44qLB9LR8/BTZmXyBxR8UaL8/llGK96O0VU/jNWuKL yK61oaQ5OPjn5SJb6LV3k/8zT6+Lz9wqU04C2qdRlF71NfsSxTIl1tLZaCM6xADuNXII YibQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=Byds0QY4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d125si620452pfc.114.2018.12.06.08.25.12; Thu, 06 Dec 2018 08:25:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=Byds0QY4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726208AbeLFQYA (ORCPT + 99 others); Thu, 6 Dec 2018 11:24:00 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:38062 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725908AbeLFQX7 (ORCPT ); Thu, 6 Dec 2018 11:23:59 -0500 Received: by mail-wr1-f67.google.com with SMTP id v13so1085410wrw.5 for ; Thu, 06 Dec 2018 08:23:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=VWAAkCawjwQLxdAls8KtL7gJfoLNQB5klFgyJ1pyUkY=; b=Byds0QY4m5ogBT0O7P0bfolIhN+JQloJHaMEZ5MNi4jqjrNTsdcG/1PNpun76E7NXF 0xdmZmMALtYolCtSyAVrArOGqofypvgnA1DxD8CJtxNAAvxWuZcjEK8P3/MyYTdcXHQE ew5URbwR8SN833SpKRGFO//bZ0JNvRLO0Fje2i0KVviQjn9YEcMFQNXqIUPCY1+z7ydq NH4JO0Vyf4ROFoXr3sqUOEhkzP/EsaomLRzpTvWwVubBu+K5ZQKokrGRwHYJI4P5mxqI BE7ZmNFM5GuazpeBYEj8sSFLbrwqBicqJc9KlwjYXAZOUxM+hI7tIkK69wVrK/iEeAyy 7pDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=VWAAkCawjwQLxdAls8KtL7gJfoLNQB5klFgyJ1pyUkY=; b=OqmdKd/l4PRvVzIVnfYABk2skUlENgY9SsFS0HGH2S299w6odqhih+/0kcRv6DBaCT jvXnSkctIQxzQytuJHcCRl6lxKe4FsuGKAy33cDwDaGkNBzDB0XYlCZTwz1mgOXSQm69 nZ2HVcMYAUvF/O7UzaPg7n8JG5HgL6urn8AFLcDoUK2G1PuINrpQU3aik4dCv/tfrB9u YaK9j1vdH9y/8mCOo0+flN6xsRniFsBKy/+Up+8jqgdswH04jemiP5GDIKlJzOKOg2dr sHlQ7whP2LdqB2A2vPDh9cxNyfWHPttuiRkmLzM9KvDXzc3vFRKACVPrPR+lOMQ78WA2 7KTA== X-Gm-Message-State: AA+aEWbQBmiCcYFV26My998L1z3hbZIBozo4y4CWy2N873AKWc90RT8y X6p7sUcL6KVV1vx5riIf+Js= X-Received: by 2002:a5d:6710:: with SMTP id o16mr26444446wru.152.1544113436720; Thu, 06 Dec 2018 08:23:56 -0800 (PST) Received: from gmail.com (2E8B0CD5.catv.pool.telekom.hu. [46.139.12.213]) by smtp.gmail.com with ESMTPSA id z9sm1250760wrs.63.2018.12.06.08.23.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 06 Dec 2018 08:23:56 -0800 (PST) Date: Thu, 6 Dec 2018 17:23:53 +0100 From: Ingo Molnar To: Sean Christopherson Cc: Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org, Linus Torvalds , Rik van Riel , Yu-cheng Yu Subject: Re: [PATCH] x86/mm/fault: Streamline the fault error_code decoder some more Message-ID: <20181206162353.GA119052@gmail.com> References: <20181205163624.1842-1-sean.j.christopherson@intel.com> <20181206073409.GA64887@gmail.com> <20181206155336.GC31263@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20181206155336.GC31263@linux.intel.com> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Sean Christopherson wrote: > On Thu, Dec 06, 2018 at 08:34:09AM +0100, Ingo Molnar wrote: > > I like your '!' idea, but with a further simplification: how about using > > '-/+' differentiation and a single character and a fixed-length message. > > > > The new output will be lines of: > > > > #PF error code: -P -W -U -S -I -K (0x00) > > ... > > #PF error code: -P -W +U +S -I -K (0x0c) > > ... > > #PF error code: +P +W +U +S +I +K (0x3f) > > > > The symbol abbreviations are pretty self-explanatory: > > > > P = protection fault (X86_PF_PROT) > > W = write access (X86_PF_WRITE) > > U = user-mode access (X86_PF_USER) > > S = supervisor mode (X86_PF_RSVD) > > I = instruction fault (X86_PF_INSTR) > > K = keys fault (X86_PF_PK) > > > > Misc notes: > > > > - In principle the new text is now short enough to include it in one of > > the existing output lines, further shortening the oops output - but I > > havent done that in this patch. > > > > - Another question is the ordering of the bits: the symbolic display is > > actually big endian, while the numeric hexa printout is little endian. > > > > I kind of still like it that way, not just because the decoding loop is > > more natural, but because the bits are actually ordered by importance: > > the PROT bits is more important than the INSTR or the PK bits - and the > > more important bits are displayed first. > > Hmm, my eyes tend to be drawn to the end of the line, e.g. having PROT > be the last thing makes it stand out more than being buried in the middle > of the line. Inverting the ordering between raw and decoded also makes > it very difficult to correlate the raw value with each bit. > > > - Only build-tested the patch and looked at the generated assembly, but > > it all looks sane enough so will obviously work just fine! ;-) > > ... > > > /* > > - * This helper function transforms the #PF error_code bits into > > - * "[PROT] [USER]" type of descriptive, almost human-readable error strings: > > + * This maps the somewhat obscure error_code number to symbolic text: > > + * > > + * P = protection fault (X86_PF_PROT) > > + * W = write access (X86_PF_WRITE) > > + * U = user-mode access (X86_PF_USER) > > + * S = supervisor mode (X86_PF_RSVD) > > + * I = instruction fault (X86_PF_INSTR) > > + * K = keys fault (X86_PF_PK) > > */ > > -static void err_str_append(unsigned long error_code, char *buf, unsigned long mask, const char *txt) > > +static const char error_code_chars[] = "PWUSIK"; > > + > > +/* > > + * This helper function transforms the #PF error_code bits into " +P -W +U -R -I -K" > > + * type of descriptive, almost human-readable error strings: > > + */ > > +static void show_error_code(struct pt_regs *regs, unsigned long error_code) > > No need for @regs. > > > { > > - if (error_code & mask) { > > - if (buf[0]) > > - strcat(buf, " "); > > - strcat(buf, txt); > > + unsigned int bit, mask; > > + char err_txt[6*3+1]; /* Fixed length of 6 bits decoded plus zero at the end */ > > Assuming the error code bits are contiguous breaks if/when SGX gets added, > which uses bit 15. Oopsing on an SGX fault should be nigh impossible, but > it might be nice to be able to reuse show_error_code in other places. > > Hardcoding "6" is also a bit painful. > > > + > > + /* We go from the X86_PF_PROT bit to the X86_PF_PK bit: */ > > + > > + for (bit = 0; bit < 6; bit++) { > > + unsigned int offset = bit*3; > > + > > + err_txt[offset+0] = ' '; > > + > > + mask = 1 << bit; > > + if (error_code & mask) > > + err_txt[offset+1] = '+'; > > + else > > + err_txt[offset+1] = '-'; > > To me, using '!' contrasts better when side-by-side with '+'. > > > + > > + err_txt[offset+2] = error_code_chars[bit]; > > } > > + > > + /* Close the string: */ > > + err_txt[sizeof(err_txt)-1] = 0; > > + > > + pr_alert("#PF error code: %s (%02lx)\n", err_txt, error_code); > > The changelog example has a leading "0x" on the error code. That being > said, I actually like it without the "0x". > > How about printing the raw value before the colon? Having it at the end > makes it look like extra noise. And for me, seeing the raw code first > (reading left to right) cue's my brain that it's about to decode some > bits. > > SGX will also break the two digit printing. And for whatever reason four > digits makes me think "this is an error code!". IIRC the vectoring ucode > makes a lot of assumptions about the error code being at most 16 bits, so > in theory four digits is all we'll ever need. > > E.g. > > [ 0.144247] #PF error code: +P -W -U -S -I -K (01) > [ 0.144411] #PF error code: +P +W -U -S -I -K (03) > [ 0.144826] #PF error code: +P +W +U -S -I -K (07) > [ 0.145252] #PF error code: +P -W +U -S -I +K (25) > [ 0.145706] #PF error code: -P +W -U -S -I -K (02) > [ 0.146111] #PF error code: -P -W +U -S -I -K (04) > [ 0.146521] #PF error code: -P +W +U -S -I -K (06) > [ 0.146934] #PF error code: -P -W +U -S +I -K (14) > [ 0.147348] #PF error code: +P -W -U -S +I -K (11) > [ 0.147767] #PF error code: -P -W -U -S -I -K (00) > > vs. (with SGX added as 'G' for testing purposes) > > [ 0.158849] #PF error code(0001): +P !W !U !S !I !K !G > [ 0.159292] #PF error code(0003): +P +W !U !S !I !K !G > [ 0.159742] #PF error code(0007): +P +W +U !S !I !K !G > [ 0.160190] #PF error code(0025): +P !W +U !S !I +K !G > [ 0.160638] #PF error code(0002): !P +W !U !S !I !K !G > [ 0.161087] #PF error code(0004): !P !W +U !S !I !K !G > [ 0.161538] #PF error code(0006): !P +W +U !S !I !K !G > [ 0.161992] #PF error code(0014): !P !W +U !S +I !K !G > [ 0.162450] #PF error code(0011): +P !W !U !S +I !K !G > [ 0.162667] #PF error code(8001): +P !W !U !S !I !K +G > [ 0.162667] #PF error code(8003): +P +W !U !S !I !K +G > [ 0.162667] #PF error code(8007): +P +W +U !S !I !K +G > [ 0.162667] #PF error code(8025): +P !W +U !S !I +K +G > [ 0.162667] #PF error code(8002): !P +W !U !S !I !K +G > [ 0.162667] #PF error code(8004): !P !W +U !S !I !K +G > [ 0.162667] #PF error code(8006): !P +W +U !S !I !K +G > [ 0.162667] #PF error code(8014): !P !W +U !S +I !K +G > [ 0.162667] #PF error code(8011): +P !W !U !S +I !K +G > [ 0.162667] #PF error code(0000): !P !W !U !S !I !K !G > > vs. (with consistent ordering between raw and decoded) > > [ 0.153004] #PF error code(0001): !K !I !S !U !W +P > [ 0.153004] #PF error code(0003): !K !I !S !U +W +P > [ 0.153004] #PF error code(0007): !K !I !S +U +W +P > [ 0.153004] #PF error code(0025): +K !I !S +U !W +P > [ 0.153004] #PF error code(0002): !K !I !S !U +W !P > [ 0.153004] #PF error code(0004): !K !I !S +U !W !P > [ 0.153004] #PF error code(0006): !K !I !S +U +W !P > [ 0.153362] #PF error code(0014): !K +I !S +U !W !P > [ 0.153788] #PF error code(0011): !K +I !S !U !W +P > [ 0.154104] #PF error code(0000): !K !I !S !U !W !P Ok, looks nice enough to me, with one request: please make it 0x prefixed as is common with hexa code: "0010" could be binary, octal or decimal as well. Since this is a separate line we don't lack the space. Also some nits: > A patch with the kitchen sink... > ================================> > > From 22e6d40e52b4341a424f065a138be54bc79d4db4 Mon Sep 17 00:00:00 2001 > From: Sean Christopherson > Date: Thu, 6 Dec 2018 07:25:13 -0800 > Subject: [PATCH] x86/fault: Make show_error_code() more extensible and tweak > its formatting > > - Initialize each bit individually in the error_code_chars array. This > allows for non-contiguous bits and is self-documenting. Define a > macro to make the initialization code somewhatmore readable. > > - Reverse the decode order so it's consistent with the raw display. > > - Use ARRAY_SIZE instead of hardcoding '6' in multiple locations. > > - Use '!' for the negative case to better contrast against '+'. > > - Display four digits (was two) when printing the raw error code. > > - Remove @regs from show_error_code(). > > Signed-off-by: Sean Christopherson > --- > arch/x86/mm/fault.c | 47 ++++++++++++++++++++++++--------------------- > 1 file changed, 25 insertions(+), 22 deletions(-) > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index 23dc7163f6ac..cd28d058ed39 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -605,45 +605,48 @@ static void show_ldttss(const struct desc_ptr *gdt, const char *name, u16 index) > > /* > * This maps the somewhat obscure error_code number to symbolic text: > - * > - * P = protection fault (X86_PF_PROT) > - * W = write access (X86_PF_WRITE) > - * U = user-mode access (X86_PF_USER) > - * S = supervisor mode (X86_PF_RSVD) > - * I = instruction fault (X86_PF_INSTR) > - * K = keys fault (X86_PF_PK) > */ > -static const char error_code_chars[] = "PWUSIK"; > +#define EC(x) ilog2(X86_PF_##x) > +static const char error_code_chars[] = { > + [EC(PROT)] = 'P', > + [EC(WRITE)] = 'W', > + [EC(USER)] = 'U', > + [EC(RSVD)] = 'S', > + [EC(INSTR)] = 'I', > + [EC(PK)] = 'K', > +}; Please use an extra newline between the #define and the variable definition. > > /* > - * This helper function transforms the #PF error_code bits into " +P -W +U -R -I -K" > + * This helper function transforms the #PF error_code bits into " +P !W +U !R !I !K" > * type of descriptive, almost human-readable error strings: > */ > -static void show_error_code(struct pt_regs *regs, unsigned long error_code) > +static void show_error_code(unsigned long error_code) > { > - unsigned int bit, mask; > - char err_txt[6*3+1]; /* Fixed length of 6 bits decoded plus zero at the end */ > + char err_txt[ARRAY_SIZE(error_code_chars)*3+1]; /* 3 chars per bit plus zero at the end */ > + unsigned offset = 0; > + unsigned long mask; > + int i; > > - /* We go from the X86_PF_PROT bit to the X86_PF_PK bit: */ > - > - for (bit = 0; bit < 6; bit++) { > - unsigned int offset = bit*3; > + for (i = ARRAY_SIZE(error_code_chars) - 1; i >= 0; i--) { > + if (!error_code_chars[i]) > + continue; > > err_txt[offset+0] = ' '; > > - mask = 1 << bit; > + mask = 1 << i; > if (error_code & mask) > err_txt[offset+1] = '+'; > else > - err_txt[offset+1] = '-'; > + err_txt[offset+1] = '!'; > > - err_txt[offset+2] = error_code_chars[bit]; > + err_txt[offset+2] = error_code_chars[i]; > + offset += 3; > } > > /* Close the string: */ > - err_txt[sizeof(err_txt)-1] = 0; > + err_txt[offset] = 0; > > - pr_alert("#PF error code: %s (%02lx)\n", err_txt, error_code); > + pr_alert("#PF error code(%04lx): %s\n", error_code, err_txt); 0x%04lx here, but other than that looks good to me! Thanks, Ingo