From: Ingo Molnar <mingo@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
x86@kernel.org, Juergen Gross <jgross@suse.com>,
Andi Kleen <ak@linux.intel.com>
Subject: [PATCH] x86/paravirt: Match paravirt patchlet field definition ordering to initialization ordering
Date: Thu, 25 Apr 2019 10:10:12 +0200 [thread overview]
Message-ID: <20190425081012.GA115378@gmail.com> (raw)
In-Reply-To: <alpine.DEB.2.21.1904250921010.1762@nanos.tec.linutronix.de>
* Thomas Gleixner <tglx@linutronix.de> wrote:
> On Thu, 25 Apr 2019, Ingo Molnar wrote:
> > > +# else
> > > + .irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf
> > > + .mmu_write_cr3 = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3
> > > + .cpu_iret = { 0xcf }, // iret
> > > +# endif
> >
> > I think these open-coded hexa versions are somewhat fragile as well, how
> > about putting these into a .S file and controlling the sections in an LTO
> > safe manner there?
> >
> > That will also allow us to write proper asm, and global labels can be
> > used to extract the patchlets and their length?
>
> We are not changing these any other day and I really don't see a reason to
> have these things global just because.
Firstly, I'm not sure I understand the objection to using symbols: in an
average distro kernel we have more than 75,000 symbols - as long as the
namespace is clear they are there to be used, there's nothing wrong with
them per se.
Secondly, my main point is that putting these code patching sequences
into the .S it's easy to verify that the instructions and patchlets are
what we claim them to be.
Right now they are randomly ordered data tables that don't match to the
source code.
I know, because I tried. :-)
Here's the objdump -D output of the PATCH_XXL data table:
0000000000000010 <patch_data_xxl>:
10: fa cli
11: fb sti
12: 57 push %rdi
13: 9d popfq
14: 9c pushfq
15: 58 pop %rax
16: 0f 20 d0 mov %cr2,%rax
19: 0f 20 d8 mov %cr3,%rax
1c: 0f 22 df mov %rdi,%cr3
1f: 0f 09 wbinvd
21: 0f 01 f8 swapgs
24: 48 0f 07 sysretq
27: 0f 01 f8 swapgs
2a: 48 89 f8 mov %rdi,%rax
Note how this doesn't match up to the source code:
static const struct patch_xxl patch_data_xxl = {
.irq_irq_disable = { 0xfa }, // cli
.irq_irq_enable = { 0xfb }, // sti
.irq_save_fl = { 0x9c, 0x58 }, // pushf; pop %[re]ax
.mmu_read_cr2 = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax
.mmu_read_cr3 = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax
# ifdef CONFIG_X86_64
.irq_restore_fl = { 0x57, 0x9d }, // push %rdi; popfq
.mmu_write_cr3 = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3
.cpu_wbinvd = { 0x0f, 0x09 }, // wbinvd
.cpu_usergs_sysret64 = { 0x0f, 0x01, 0xf8,
0x48, 0x0f, 0x07 }, // swapgs; sysretq
.cpu_swapgs = { 0x0f, 0x01, 0xf8 }, // swapgs
.mov64 = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax
# else
.irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf
.mmu_write_cr3 = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3
.cpu_iret = { 0xcf }, // iret
# endif
};
Note how they are reordered: in the generated code .irq_restore_fl comes
before .irq_save_fl, etc. This is because the field ordering in struct
patch_xxl does not match the initialization ordering of patch_data_xxl.
Third, beyond readability there's another advantage of my suggested
approach as well: for example that way we could verify the passed in
length with the patchlet length. Right now it's completely unverified:
case PARAVIRT_PATCH(ops.m): \
return PATCH(data, ops##_##m, ibuf, len)
right now we don't check whether the 'len' passed in by the usage site
matches the actual structure field length.
Although maybe we could do that with your C space structure as well.
Anyway, no strong feelings and I didn't want to create extra work for you
- but I think at minimum we should do the patch below, which matches up
the initialization order with the definition order - this at least makes
the disassembly reviewable:
0000000000000010 <patch_data_xxl>:
10: fa cli
11: fb sti
12: 9c pushfq
13: 58 pop %rax
14: 0f 20 d0 mov %cr2,%rax
17: 0f 20 d8 mov %cr3,%rax
1a: 0f 22 df mov %rdi,%cr3
1d: 57 push %rdi
1e: 9d popfq
1f: 0f 09 wbinvd
21: 0f 01 f8 swapgs
24: 48 0f 07 sysretq
27: 0f 01 f8 swapgs
2a: 48 89 f8 mov %rdi,%rax
And yes, with that applied it verifies 100%. :-)
Thanks,
Ingo
Signed-off-by: Ingo Molnar <mingo@kernel.org>
--- tip.orig/arch/x86/kernel/paravirt_patch.c
+++ tip/arch/x86/kernel/paravirt_patch.c
@@ -21,11 +21,11 @@
struct patch_xxl {
const unsigned char irq_irq_disable[1];
const unsigned char irq_irq_enable[1];
- const unsigned char irq_restore_fl[2];
const unsigned char irq_save_fl[2];
const unsigned char mmu_read_cr2[3];
const unsigned char mmu_read_cr3[3];
const unsigned char mmu_write_cr3[3];
+ const unsigned char irq_restore_fl[2];
# ifdef CONFIG_X86_64
const unsigned char cpu_wbinvd[2];
const unsigned char cpu_usergs_sysret64[6];
@@ -43,16 +43,16 @@ static const struct patch_xxl patch_data
.mmu_read_cr2 = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax
.mmu_read_cr3 = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax
# ifdef CONFIG_X86_64
- .irq_restore_fl = { 0x57, 0x9d }, // push %rdi; popfq
.mmu_write_cr3 = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3
+ .irq_restore_fl = { 0x57, 0x9d }, // push %rdi; popfq
.cpu_wbinvd = { 0x0f, 0x09 }, // wbinvd
.cpu_usergs_sysret64 = { 0x0f, 0x01, 0xf8,
0x48, 0x0f, 0x07 }, // swapgs; sysretq
.cpu_swapgs = { 0x0f, 0x01, 0xf8 }, // swapgs
.mov64 = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax
# else
- .irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf
.mmu_write_cr3 = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3
+ .irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf
.cpu_iret = { 0xcf }, // iret
# endif
};
next prev parent reply other threads:[~2019-04-25 8:10 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-24 13:41 [patch 0/3] x86/paravirt: Rework paravirt patching Thomas Gleixner
2019-04-24 13:41 ` [patch 1/3] x86/paravirt: Remove bogus extern declarations Thomas Gleixner
2019-04-25 7:31 ` [tip:x86/paravirt] " tip-bot for Thomas Gleixner
2019-05-24 7:58 ` tip-bot for Thomas Gleixner
2019-04-24 13:41 ` [patch 2/3] x86/paravirt: Unify 32/64 bit patch code Thomas Gleixner
2019-04-25 7:32 ` [tip:x86/paravirt] " tip-bot for Thomas Gleixner
2019-05-24 8:00 ` [tip:x86/paravirt] x86/paravirt: Unify the 32/64 bit paravirt patching code tip-bot for Thomas Gleixner
2019-04-24 13:41 ` [patch 3/3] x86/paravirt: Replace paravirt patch asm magic Thomas Gleixner
2019-04-25 6:52 ` Ingo Molnar
2019-04-25 7:22 ` Thomas Gleixner
2019-04-25 7:46 ` Juergen Gross
2019-04-25 8:10 ` Ingo Molnar [this message]
2019-04-25 9:17 ` [PATCH] x86/paravirt: Detect oversized patching bugs as they happen and BUG_ON() to avoid later crashes Ingo Molnar
2019-04-25 9:21 ` Peter Zijlstra
2019-04-25 9:50 ` x86/paravirt: Detect over-sized patching bugs in paravirt_patch_call() Ingo Molnar
2019-04-25 10:22 ` Peter Zijlstra
2019-04-25 10:57 ` Ingo Molnar
2019-04-25 11:30 ` Juergen Gross
2019-04-25 12:30 ` Juergen Gross
2019-04-25 11:40 ` Peter Zijlstra
2019-04-25 12:30 ` Peter Zijlstra
2019-05-24 7:59 ` [tip:x86/paravirt] " tip-bot for Ingo Molnar
2019-05-24 7:58 ` [tip:x86/paravirt] x86/paravirt: Detect over-sized patching bugs in paravirt_patch_insns() tip-bot for Ingo Molnar
2019-05-24 8:01 ` [tip:x86/paravirt] x86/paravirt: Match paravirt patchlet field definition ordering to initialization ordering tip-bot for Ingo Molnar
2019-04-25 8:08 ` [patch 3/3] x86/paravirt: Replace paravirt patch asm magic Peter Zijlstra
2019-04-25 8:19 ` Peter Zijlstra
2019-04-25 9:20 ` Ingo Molnar
2019-05-24 8:00 ` [tip:x86/paravirt] x86/paravirt: Replace the " tip-bot for Thomas Gleixner
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=20190425081012.GA115378@gmail.com \
--to=mingo@kernel.org \
--cc=ak@linux.intel.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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