From: kan.liang@intel.com
To: peterz@infradead.org
Cc: andi@firstfloor.org, alexander.shishkin@linux.intel.com,
linux-kernel@vger.kernel.org, Kan Liang <kan.liang@intel.com>
Subject: [PATCH 1/3] x86 msr: msr goto extension support
Date: Thu, 31 Jul 2014 02:41:01 -0700 [thread overview]
Message-ID: <1406799663-18192-1-git-send-email-kan.liang@intel.com> (raw)
From: Kan Liang <kan.liang@intel.com>
Currently, {rd,wr}msrl_safe can handle the exception which caused by accessing
specific MSR.
However, it will introduce extra conditional branch for testing errors. That
will impact the "fast" path's performance.
The newly implemented {rd,wr}msrl_goto function can not only handle the
exception which caused by accessing specific MSR,
but also takes advantage of the asm goto extension to eliminate the impact of
performance.
The asm goto extension is supported by GCC 4.5 and later versions. If the
compiler doesn't support goto extension, _safe will be used to replace _goto.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
arch/x86/include/asm/msr.h | 60 +++++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/paravirt.h | 18 +++++++++++++
2 files changed, 78 insertions(+)
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index de36f22..55438da 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -203,6 +203,66 @@ do { \
#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
+#ifdef CC_HAVE_ASM_GOTO
+
+/*
+ * The _goto version is rdmsrl/wrmsrl with exception handling
+ * The advantage (than _safe) is that it can directly jump in the
+ * exception handling code, and never test in the "fast" path.
+ *
+ * Since _goto doesn't support output, try to protect the output
+ * registers by clobbers, and process the registers immediately.
+ */
+#define rdmsrl_goto(msr, result, fail_label) \
+do { \
+ DECLARE_ARGS(val, low, high); \
+ asm_volatile_goto("2: rdmsr\n" \
+ "1:\n\t" \
+ _ASM_EXTABLE(2b, %l[fail_label]) \
+ : /* No outputs. */ \
+ : "c" (msr) \
+ : "%rax", "%rdx" \
+ : fail_label); \
+ asm volatile ("" \
+ : EAX_EDX_RET(val, low, high) \
+ : ); \
+ result = EAX_EDX_VAL(val, low, high); \
+} while (0)
+
+#define wrmsrl_goto(msr, val, fail_label) \
+do { \
+ unsigned low, high; \
+ low = (u32)val; \
+ high = (u32)(val >> 32); \
+ asm_volatile_goto("2: wrmsr\n" \
+ "1:\n\t" \
+ _ASM_EXTABLE(2b, %l[fail_label]) \
+ : /* No outputs. */ \
+ : "c" (msr), "a" (low), "d" (high) \
+ : "memory" \
+ : fail_label); \
+} while (0)
+
+#else /* CC_HAVE_ASM_GOTO */
+
+/*
+ * If compiler doesn't support asm goto, use _safe to replace
+ */
+#define rdmsrl_goto(msr, result, fail_label) \
+do { \
+ if (rdmsrl_safe(msr, &result)) \
+ goto fail_label; \
+} while (0)
+
+#define wrmsrl_goto(msr, result, fail_label) \
+do { \
+ if (wrmsr_safe((msr), (u32)(result), \
+ (u32)((result) >> 32))) \
+ goto fail_label; \
+} while (0)
+
+#endif /* CC_HAVE_ASM_GOTO */
+
#endif /* !CONFIG_PARAVIRT */
#define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index cd6e161..1fa18a1 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -174,6 +174,24 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
return err;
}
+/*
+ * TODO: paravirt _goto doesn't support yet.
+ * But the implementation as below doesn't impact the current performance,
+ * since rdmsrl/wrmsrl eventually call _safe version in paravirt now.
+ */
+#define rdmsrl_goto(msr, result, fail_label) \
+do { \
+ if (rdmsrl_safe(msr, &result)) \
+ goto fail_label; \
+} while (0)
+
+#define wrmsrl_goto(msr, result, fail_label) \
+do { \
+ if (wrmsr_safe((msr), (u32)(result), \
+ (u32)((result) >> 32))) \
+ goto fail_label; \
+} while (0)
+
static inline u64 paravirt_read_tsc(void)
{
return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);
--
1.8.3.1
next reply other threads:[~2014-07-31 17:30 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-31 9:41 kan.liang [this message]
2014-07-31 9:41 ` [PATCH 2/3] x86 perf: Protect LBR msrs accessing against potential #GP kan.liang
2014-08-01 7:38 ` Peter Zijlstra
2014-08-01 7:44 ` Peter Zijlstra
2014-08-01 13:21 ` Andi Kleen
2014-08-01 18:50 ` Peter Zijlstra
2014-08-02 5:27 ` Ingo Molnar
2014-07-31 9:41 ` [PATCH 3/3] x86 perf: Protect LBR and BTS enabling kan.liang
2014-07-31 21:05 ` [PATCH 1/3] x86 msr: msr goto extension support Andy Lutomirski
2014-08-01 8:05 ` Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1406799663-18192-1-git-send-email-kan.liang@intel.com \
--to=kan.liang@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=andi@firstfloor.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome