From: Sean Christopherson <seanjc@google.com>
To: Michal Luczaj <mhal@rbox.co>
Cc: kvm@vger.kernel.org, pbonzini@redhat.com, shuah@kernel.org,
linux-kselftest@vger.kernel.org
Subject: Re: [kvm-unit-tests PATCH 4/4] x86: Extend ASM_TRY to handle #UD thrown by FEP-triggered emulator
Date: Wed, 3 Aug 2022 18:16:32 +0000 [thread overview]
Message-ID: <Yuq7gMTpRqGlVdcW@google.com> (raw)
In-Reply-To: <20220803172508.1215-4-mhal@rbox.co>
On Wed, Aug 03, 2022, Michal Luczaj wrote:
> TRY_ASM() mishandles #UD thrown by the forced-emulation-triggered emulator.
> While the faulting address stored in the exception table points at forced
> emulation prefix, when #UD comes, RIP is 5 bytes (size of KVM_FEP) ahead
> and the exception ends up unhandled.
Ah, but that's only the behavior if FEP is allowed. If FEP is disabled, then the
#UD will be on the prefix.
> Suggested-by: Sean Christopherson <seanjc@google.com>
Heh, I didn't really suggest this because I didn't even realize it was a problem :-)
> Signed-off-by: Michal Luczaj <mhal@rbox.co>
> ---
> While here, I've also took the opportunity to merge both 32 and 64-bit
> versions of ASM_TRY() (.dc.a for .long and .quad), but perhaps there
> were some reasons for not using .dc.a?
This should be a separate patch, and probably as the very last patch in case dc.a
isn't viable for whatever reason. I've never seen/used dc.a so I really have no
idea whether or not it's ok to use.
As a "safe" alternative that can be done before adding ASM_TRY_FEP(), we can steal
the kernel's __ASM_SEL() approach so that you don't have to implement two versions
of ASM_TRY_FEP(). That's worth doing because __ASM_SEL() can probably be used in
other places too. Patch at the bottom.
> lib/x86/desc.h | 11 +++++------
> x86/emulator.c | 4 ++--
> 2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/lib/x86/desc.h b/lib/x86/desc.h
> index 2a285eb..99cc224 100644
> --- a/lib/x86/desc.h
> +++ b/lib/x86/desc.h
> @@ -80,21 +80,20 @@ typedef struct __attribute__((packed)) {
> u16 iomap_base;
> } tss64_t;
>
> -#ifdef __x86_64
> #define ASM_TRY(catch) \
> "movl $0, %%gs:4 \n\t" \
> ".pushsection .data.ex \n\t" \
> - ".quad 1111f, " catch "\n\t" \
> + ".dc.a 1111f, " catch "\n\t" \
> ".popsection \n\t" \
> "1111:"
> -#else
> -#define ASM_TRY(catch) \
> +
> +#define ASM_TRY_PREFIXED(prefix, catch) \
Rather than a generic ASM_TRY_PREFIXED, I think it makes sense to add an explicit
ASM_TRY_FEP() that takes in only the label and hardcodes the FEP prefix. The "#UD
skips the prefix" behavior is unique to "successful" forced emulation, so this is
literally the only scenario where skipping a prefix is expected/correct.
*sigh*
That'll require moving the KVM_FEP definition, but that's a good change on its
own. Probably throw it in lib/x86/processor.h?
> "movl $0, %%gs:4 \n\t" \
> ".pushsection .data.ex \n\t" \
> - ".long 1111f, " catch "\n\t" \
> + ".dc.a 1111f, " catch "\n\t" \
> ".popsection \n\t" \
> + prefix "\n\t" \
> "1111:"
> -#endif
>
> /*
> * selector 32-bit 64-bit
> diff --git a/x86/emulator.c b/x86/emulator.c
> index df0bc49..d2a5302 100644
> --- a/x86/emulator.c
> +++ b/x86/emulator.c
> @@ -900,8 +900,8 @@ static void test_illegal_lea(void)
> {
> unsigned int vector;
>
> - asm volatile (ASM_TRY("1f")
> - KVM_FEP ".byte 0x8d; .byte 0xc0\n\t"
> + asm volatile (ASM_TRY_PREFIXED(KVM_FEP, "1f")
> + ".byte 0x8d; .byte 0xc0\n\t"
Put this patch earlier in the series, before test_illegal_lea() is introduced.
Both so that there's no unnecessary churn, and also because running the illegal
LEA testcase without this patch will fail.
> "1:"
> : : : "memory", "eax");
---
From: Sean Christopherson <seanjc@google.com>
Date: Wed, 3 Aug 2022 11:09:41 -0700
Subject: [PATCH] x86: Dedup 32-bit vs. 64-bit ASM_TRY() by stealing kernel's
__ASM_SEL()
Steal the kernel's __ASM_SEL() implementation and use it to consolidate
ASM_TRY(). The only difference between the 32-bit and 64-bit versions is
the size of the address stored in the table.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
lib/x86/desc.h | 19 +++++--------------
lib/x86/processor.h | 12 ++++++++++++
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index 2a285eb6..e670ebf2 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -80,21 +80,12 @@ typedef struct __attribute__((packed)) {
u16 iomap_base;
} tss64_t;
-#ifdef __x86_64
-#define ASM_TRY(catch) \
- "movl $0, %%gs:4 \n\t" \
- ".pushsection .data.ex \n\t" \
- ".quad 1111f, " catch "\n\t" \
- ".popsection \n\t" \
+#define ASM_TRY(catch) \
+ "movl $0, %%gs:4 \n\t" \
+ ".pushsection .data.ex \n\t" \
+ __ASM_SEL(.long, .quad) " 1111f, " catch "\n\t" \
+ ".popsection \n\t" \
"1111:"
-#else
-#define ASM_TRY(catch) \
- "movl $0, %%gs:4 \n\t" \
- ".pushsection .data.ex \n\t" \
- ".long 1111f, " catch "\n\t" \
- ".popsection \n\t" \
- "1111:"
-#endif
/*
* selector 32-bit 64-bit
diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 03242206..30e2de87 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -19,6 +19,18 @@
# define S "4"
#endif
+#ifdef __ASSEMBLY__
+#define __ASM_FORM(x, ...) x,## __VA_ARGS__
+#else
+#define __ASM_FORM(x, ...) " " xstr(x,##__VA_ARGS__) " "
+#endif
+
+#ifndef __x86_64__
+#define __ASM_SEL(a,b) __ASM_FORM(a)
+#else
+#define __ASM_SEL(a,b) __ASM_FORM(b)
+#endif
+
#define DB_VECTOR 1
#define BP_VECTOR 3
#define UD_VECTOR 6
base-commit: a106b30d39425b7afbaa3bbd4aab16fd26d333e7
--
next prev parent reply other threads:[~2022-08-03 18:16 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-29 13:48 [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling Michal Luczaj
2022-07-29 13:48 ` [PATCH 2/2] KVM: selftests: x86: Test " Michal Luczaj
2022-07-29 16:53 ` Sean Christopherson
2022-07-31 20:43 ` Michal Luczaj
2022-07-31 20:46 ` [kvm-unit-tests PATCH v2] " Michal Luczaj
2022-08-01 16:44 ` Sean Christopherson
2022-08-02 23:07 ` Michal Luczaj
2022-08-02 23:41 ` Sean Christopherson
2022-08-03 17:21 ` Michal Luczaj
2022-08-03 17:25 ` [kvm-unit-tests PATCH 1/4] x86: emulator.c cleanup: Save and restore exception handlers Michal Luczaj
2022-08-03 17:25 ` [kvm-unit-tests PATCH 2/4] x86: emulator.c cleanup: Use ASM_TRY for the UD_VECTOR cases Michal Luczaj
2022-08-03 18:21 ` Sean Christopherson
2022-08-05 11:42 ` Paolo Bonzini
2022-08-05 18:55 ` Michal Luczaj
2022-08-05 19:59 ` Sean Christopherson
2022-08-06 2:00 ` Nadav Amit
2022-08-06 11:08 ` Michal Luczaj
2022-08-03 17:25 ` [kvm-unit-tests PATCH 3/4] x86: Test emulator's handling of LEA with /reg Michal Luczaj
2022-08-03 17:25 ` [kvm-unit-tests PATCH 4/4] x86: Extend ASM_TRY to handle #UD thrown by FEP-triggered emulator Michal Luczaj
2022-08-03 18:16 ` Sean Christopherson [this message]
2022-08-05 11:50 ` Paolo Bonzini
2022-07-29 16:41 ` [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling Sean Christopherson
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=Yuq7gMTpRqGlVdcW@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mhal@rbox.co \
--cc=pbonzini@redhat.com \
--cc=shuah@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