* [PATCH 1/6] x86/sev-es: Don't return NULL from sev_es_get_ghcb()
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
2021-05-12 7:54 ` [PATCH 2/6] x86/sev-es: Forward page-faults which happen during emulation Joerg Roedel
` (4 subsequent siblings)
5 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, stable, Masami Hiramatsu,
Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
The sev_es_get_ghcb() is called from several places, but only one of
them checks the return value. The reaction to returning NULL is always
the same: Calling panic() and kill the machine.
Instead of adding checks to all call-places, move the panic() into the
function itself so that it will no longer return NULL.
Fixes: 0786138c78e7 ("x86/sev-es: Add a Runtime #VC Exception Handler")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 9578c82832aa..c49270c7669e 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -203,8 +203,18 @@ static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state)
if (unlikely(data->ghcb_active)) {
/* GHCB is already in use - save its contents */
- if (unlikely(data->backup_ghcb_active))
- return NULL;
+ if (unlikely(data->backup_ghcb_active)) {
+ /*
+ * Backup-GHCB is also already in use. There is no way
+ * to continue here so just kill the machine. To make
+ * panic() work, mark GHCBs inactive so that messages
+ * can be printed out.
+ */
+ data->ghcb_active = false;
+ data->backup_ghcb_active = false;
+
+ panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use");
+ }
/* Mark backup_ghcb active before writing to it */
data->backup_ghcb_active = true;
@@ -1284,7 +1294,6 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs)
*/
DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
{
- struct sev_es_runtime_data *data = this_cpu_read(runtime_data);
irqentry_state_t irq_state;
struct ghcb_state state;
struct es_em_ctxt ctxt;
@@ -1310,16 +1319,6 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
*/
ghcb = sev_es_get_ghcb(&state);
- if (!ghcb) {
- /*
- * Mark GHCBs inactive so that panic() is able to print the
- * message.
- */
- data->ghcb_active = false;
- data->backup_ghcb_active = false;
-
- panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use");
- }
vc_ghcb_invalidate(ghcb);
result = vc_init_em_ctxt(&ctxt, regs, error_code);
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 2/6] x86/sev-es: Forward page-faults which happen during emulation
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
2021-05-12 7:54 ` [PATCH 1/6] x86/sev-es: Don't return NULL from sev_es_get_ghcb() Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
[not found] ` <YJwQ1xsiDtv3LkBe@google.com>
2021-05-12 7:54 ` [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user Joerg Roedel
` (3 subsequent siblings)
5 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, stable, Masami Hiramatsu,
Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
When emulating guest instructions for MMIO or IOIO accesses the #VC
handler might get a page-fault and will not be able to complete. Forward
the page-fault in this case to the correct handler instead of killing
the machine.
Fixes: 0786138c78e7 ("x86/sev-es: Add a Runtime #VC Exception Handler")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index c49270c7669e..6530a844eb61 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -1265,6 +1265,10 @@ static __always_inline void vc_forward_exception(struct es_em_ctxt *ctxt)
case X86_TRAP_UD:
exc_invalid_op(ctxt->regs);
break;
+ case X86_TRAP_PF:
+ write_cr2(ctxt->fi.cr2);
+ exc_page_fault(ctxt->regs, error_code);
+ break;
case X86_TRAP_AC:
exc_alignment_check(ctxt->regs, error_code);
break;
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
2021-05-12 7:54 ` [PATCH 1/6] x86/sev-es: Don't return NULL from sev_es_get_ghcb() Joerg Roedel
2021-05-12 7:54 ` [PATCH 2/6] x86/sev-es: Forward page-faults which happen during emulation Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
2021-05-12 8:04 ` David Laight
2021-05-12 15:57 ` Dave Hansen
2021-05-12 7:54 ` [PATCH 4/6] Revert "x86/sev-es: Handle string port IO to kernel memory properly" Joerg Roedel
` (2 subsequent siblings)
5 siblings, 2 replies; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, stable, Masami Hiramatsu,
Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
The put_user() and get_user() functions do checks on the address which is
passed to them. They check whether the address is actually a user-space
address and whether its fine to access it. They also call might_fault()
to indicate that they could fault and possibly sleep.
All of these checks are neither wanted nor required in the #VC exception
handler, which can be invoked from almost any context and also for MMIO
instructions from kernel space on kernel memory. All the #VC handler
wants to know is whether a fault happened when the access was tried.
This is provided by __put_user()/__get_user(), which just do the access
no matter what.
Fixes: f980f9c31a92 ("x86/sev-es: Compile early handler code into kernel image")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 6530a844eb61..110b39345b40 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -342,22 +342,22 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
switch (size) {
case 1:
memcpy(&d1, buf, 1);
- if (put_user(d1, target))
+ if (__put_user(d1, target))
goto fault;
break;
case 2:
memcpy(&d2, buf, 2);
- if (put_user(d2, target))
+ if (__put_user(d2, target))
goto fault;
break;
case 4:
memcpy(&d4, buf, 4);
- if (put_user(d4, target))
+ if (__put_user(d4, target))
goto fault;
break;
case 8:
memcpy(&d8, buf, 8);
- if (put_user(d8, target))
+ if (__put_user(d8, target))
goto fault;
break;
default:
@@ -396,22 +396,22 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
switch (size) {
case 1:
- if (get_user(d1, s))
+ if (__get_user(d1, s))
goto fault;
memcpy(buf, &d1, 1);
break;
case 2:
- if (get_user(d2, s))
+ if (__get_user(d2, s))
goto fault;
memcpy(buf, &d2, 2);
break;
case 4:
- if (get_user(d4, s))
+ if (__get_user(d4, s))
goto fault;
memcpy(buf, &d4, 4);
break;
case 8:
- if (get_user(d8, s))
+ if (__get_user(d8, s))
goto fault;
memcpy(buf, &d8, 8);
break;
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread* RE: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 7:54 ` [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user Joerg Roedel
@ 2021-05-12 8:04 ` David Laight
2021-05-12 8:16 ` Juergen Gross via Virtualization
2021-05-12 8:37 ` 'Joerg Roedel'
2021-05-12 15:57 ` Dave Hansen
1 sibling, 2 replies; 20+ messages in thread
From: David Laight @ 2021-05-12 8:04 UTC (permalink / raw)
To: 'Joerg Roedel', x86@kernel.org, Hyunwook Baek
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
linux-coco@lists.linux.dev, Andy Lutomirski, Dan Williams,
Juergen Gross, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Masami Hiramatsu, Erdem Aktas
From: Joerg
> Sent: 12 May 2021 08:55
>
> From: Joerg Roedel <jroedel@suse.de>
>
> The put_user() and get_user() functions do checks on the address which is
> passed to them. They check whether the address is actually a user-space
> address and whether its fine to access it. They also call might_fault()
> to indicate that they could fault and possibly sleep.
>
> All of these checks are neither wanted nor required in the #VC exception
> handler, which can be invoked from almost any context and also for MMIO
> instructions from kernel space on kernel memory. All the #VC handler
> wants to know is whether a fault happened when the access was tried.
>
> This is provided by __put_user()/__get_user(), which just do the access
> no matter what.
That can't be right at all.
__put/get_user() are only valid on user addresses and will try to
fault in a missing page - so can sleep.
At best this is abused the calls.
David
> Fixes: f980f9c31a92 ("x86/sev-es: Compile early handler code into kernel image")
> Cc: stable@vger.kernel.org # v5.10+
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
> arch/x86/kernel/sev.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
> index 6530a844eb61..110b39345b40 100644
> --- a/arch/x86/kernel/sev.c
> +++ b/arch/x86/kernel/sev.c
> @@ -342,22 +342,22 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
> switch (size) {
> case 1:
> memcpy(&d1, buf, 1);
> - if (put_user(d1, target))
> + if (__put_user(d1, target))
> goto fault;
> break;
> case 2:
> memcpy(&d2, buf, 2);
> - if (put_user(d2, target))
> + if (__put_user(d2, target))
> goto fault;
> break;
> case 4:
> memcpy(&d4, buf, 4);
> - if (put_user(d4, target))
> + if (__put_user(d4, target))
> goto fault;
> break;
> case 8:
> memcpy(&d8, buf, 8);
> - if (put_user(d8, target))
> + if (__put_user(d8, target))
> goto fault;
> break;
> default:
> @@ -396,22 +396,22 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
>
> switch (size) {
> case 1:
> - if (get_user(d1, s))
> + if (__get_user(d1, s))
> goto fault;
> memcpy(buf, &d1, 1);
> break;
> case 2:
> - if (get_user(d2, s))
> + if (__get_user(d2, s))
> goto fault;
> memcpy(buf, &d2, 2);
> break;
> case 4:
> - if (get_user(d4, s))
> + if (__get_user(d4, s))
> goto fault;
> memcpy(buf, &d4, 4);
> break;
> case 8:
> - if (get_user(d8, s))
> + if (__get_user(d8, s))
> goto fault;
> memcpy(buf, &d8, 8);
> break;
> --
> 2.31.1
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:04 ` David Laight
@ 2021-05-12 8:16 ` Juergen Gross via Virtualization
2021-05-12 8:50 ` 'Joerg Roedel'
2021-05-12 8:37 ` 'Joerg Roedel'
1 sibling, 1 reply; 20+ messages in thread
From: Juergen Gross via Virtualization @ 2021-05-12 8:16 UTC (permalink / raw)
To: David Laight, 'Joerg Roedel', x86@kernel.org,
Hyunwook Baek
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
linux-coco@lists.linux.dev, Andy Lutomirski, Dan Williams,
Mike Stunes, Sean Christopherson, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, Masami Hiramatsu, Erdem Aktas
[-- Attachment #1.1.1.1: Type: text/plain, Size: 1082 bytes --]
On 12.05.21 10:04, David Laight wrote:
> From: Joerg
>> Sent: 12 May 2021 08:55
>>
>> From: Joerg Roedel <jroedel@suse.de>
>>
>> The put_user() and get_user() functions do checks on the address which is
>> passed to them. They check whether the address is actually a user-space
>> address and whether its fine to access it. They also call might_fault()
>> to indicate that they could fault and possibly sleep.
>>
>> All of these checks are neither wanted nor required in the #VC exception
>> handler, which can be invoked from almost any context and also for MMIO
>> instructions from kernel space on kernel memory. All the #VC handler
>> wants to know is whether a fault happened when the access was tried.
>>
>> This is provided by __put_user()/__get_user(), which just do the access
>> no matter what.
>
> That can't be right at all.
> __put/get_user() are only valid on user addresses and will try to
> fault in a missing page - so can sleep.
>
> At best this is abused the calls.
You want something like xen_safe_[read|write]_ulong().
Juergen
[-- Attachment #1.1.1.2: OpenPGP_0xB0DE9DD628BF132F.asc --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:16 ` Juergen Gross via Virtualization
@ 2021-05-12 8:50 ` 'Joerg Roedel'
2021-05-12 8:58 ` Juergen Gross via Virtualization
0 siblings, 1 reply; 20+ messages in thread
From: 'Joerg Roedel' @ 2021-05-12 8:50 UTC (permalink / raw)
To: Juergen Gross
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
David Laight, Masami Hiramatsu, Erdem Aktas
On Wed, May 12, 2021 at 10:16:12AM +0200, Juergen Gross wrote:
> You want something like xen_safe_[read|write]_ulong().
From a first glance I can't see it, what is the difference between the
xen_safe_*_ulong() functions and __get_user()/__put_user()? The only
difference I can see is that __get/__put_user() support different access
sizes, but neither of those disables page-faults by itself, for example.
Couldn't these xen-specific functions not also be replaces by
__get_user()/__put_user()?
Regards,
Joerg
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:50 ` 'Joerg Roedel'
@ 2021-05-12 8:58 ` Juergen Gross via Virtualization
2021-05-12 9:31 ` David Laight
2021-05-12 9:32 ` Joerg Roedel
0 siblings, 2 replies; 20+ messages in thread
From: Juergen Gross via Virtualization @ 2021-05-12 8:58 UTC (permalink / raw)
To: 'Joerg Roedel'
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
David Laight, Masami Hiramatsu, Erdem Aktas
[-- Attachment #1.1.1.1: Type: text/plain, Size: 702 bytes --]
On 12.05.21 10:50, 'Joerg Roedel' wrote:
> On Wed, May 12, 2021 at 10:16:12AM +0200, Juergen Gross wrote:
>> You want something like xen_safe_[read|write]_ulong().
>
> From a first glance I can't see it, what is the difference between the
> xen_safe_*_ulong() functions and __get_user()/__put_user()? The only
> difference I can see is that __get/__put_user() support different access
> sizes, but neither of those disables page-faults by itself, for example.
>
> Couldn't these xen-specific functions not also be replaces by
> __get_user()/__put_user()?
No, those were used before, but commit 9da3f2b7405440 broke Xen's use
case. That is why I did commit 1457d8cf7664f.
Juergen
[-- Attachment #1.1.1.2: OpenPGP_0xB0DE9DD628BF132F.asc --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:58 ` Juergen Gross via Virtualization
@ 2021-05-12 9:31 ` David Laight
2021-05-12 9:32 ` Joerg Roedel
1 sibling, 0 replies; 20+ messages in thread
From: David Laight @ 2021-05-12 9:31 UTC (permalink / raw)
To: 'Juergen Gross', 'Joerg Roedel'
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Masami Hiramatsu, Erdem Aktas
From: Juergen Gross
> Sent: 12 May 2021 09:58
>
> On 12.05.21 10:50, 'Joerg Roedel' wrote:
> > On Wed, May 12, 2021 at 10:16:12AM +0200, Juergen Gross wrote:
> >> You want something like xen_safe_[read|write]_ulong().
> >
> > From a first glance I can't see it, what is the difference between the
> > xen_safe_*_ulong() functions and __get_user()/__put_user()? The only
> > difference I can see is that __get/__put_user() support different access
> > sizes, but neither of those disables page-faults by itself, for example.
> >
> > Couldn't these xen-specific functions not also be replaces by
> > __get_user()/__put_user()?
>
> No, those were used before, but commit 9da3f2b7405440 broke Xen's use
> case. That is why I did commit 1457d8cf7664f.
I've just looked at 9da3f2b7405440.
It doesn't look right to me - wrong return value for a lot of cases.
OTOH it isn't in my newest tree at all.
If bogus_uaccess() is now elsewhere I can't see how (without changes)
it would allow through these faults.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:58 ` Juergen Gross via Virtualization
2021-05-12 9:31 ` David Laight
@ 2021-05-12 9:32 ` Joerg Roedel
2021-05-19 11:33 ` 'Joerg Roedel'
1 sibling, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 9:32 UTC (permalink / raw)
To: Juergen Gross
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, 'Joerg Roedel', x86@kernel.org,
David Rientjes, Martin Radev, Tom Lendacky, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
David Laight, Masami Hiramatsu, Erdem Aktas
On Wed, May 12, 2021 at 10:58:20AM +0200, Juergen Gross wrote:
> No, those were used before, but commit 9da3f2b7405440 broke Xen's use
> case. That is why I did commit 1457d8cf7664f.
I see, thanks for the heads-up. So here this is not a big issue, because
when an access to kernel space faults under SEV-ES, its a kernel bug
anyway. The issue is that it is not reported correctly.
I think I need to re-work the helper and use probe_kernel_read/write()
when the address is in kernel space. This distinction is already made
when fetching instruction bytes in the #VC handler, but I thought I
could get around it for data accesses.
Having the distinction between user and kernel memory accesses
explicitly in the code seems to be the most robust solution.
Regards,
Joerg
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 9:32 ` Joerg Roedel
@ 2021-05-19 11:33 ` 'Joerg Roedel'
0 siblings, 0 replies; 20+ messages in thread
From: 'Joerg Roedel' @ 2021-05-19 11:33 UTC (permalink / raw)
To: Joerg Roedel
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Kees Cook, Cfir Cohen, Hyunwook Baek,
linux-coco@lists.linux.dev, Andy Lutomirski, Dan Williams,
Juergen Gross, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
David Laight, Masami Hiramatsu, Erdem Aktas
On Wed, May 12, 2021 at 11:32:35AM +0200, Joerg Roedel wrote:
> On Wed, May 12, 2021 at 10:58:20AM +0200, Juergen Gross wrote:
> > No, those were used before, but commit 9da3f2b7405440 broke Xen's use
> > case. That is why I did commit 1457d8cf7664f.
>
> [...]
>
> Having the distinction between user and kernel memory accesses
> explicitly in the code seems to be the most robust solution.
On the other hand, as I found out today, 9da3f2b7405440 had a short
life-time and got reverted upstream. So using __get_user()/__put_user()
should be fine in this code path. It just deserves a comment explaining
its use here and why pagefault_enable()/disable() is not needed.
Even the get_kernel* helpers use __get_user_size() internally.
Regards,
Joerg
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:04 ` David Laight
2021-05-12 8:16 ` Juergen Gross via Virtualization
@ 2021-05-12 8:37 ` 'Joerg Roedel'
2021-05-12 15:59 ` Dave Hansen
1 sibling, 1 reply; 20+ messages in thread
From: 'Joerg Roedel' @ 2021-05-12 8:37 UTC (permalink / raw)
To: David Laight
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Juergen Gross, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Masami Hiramatsu, Erdem Aktas
On Wed, May 12, 2021 at 08:04:33AM +0000, David Laight wrote:
> That can't be right at all.
> __put/get_user() are only valid on user addresses and will try to
> fault in a missing page - so can sleep.
Yes, in general these functions can sleep, but not in this context. They
are called in atomic context and the page-fault handler will notice that
and goes down the __bad_area_nosemaphore() path and only do the fixup.
I also thought about adding page_fault_disable()/page_fault_enable()
calls, but being in atomic context is enough according to the
faulthandler_disabled() implementation.
This is exactly what is needed here. All I want to know is whether a
fault happened or not, the page-fault handler must not try to fix the
fault in any way. If a fault happens it is later fixed up in
vc_forward_exception().
> At best this is abused the calls.
Yes, but that is only due to the naming of these functions. In this case
they do exactly what is needed.
Regards,
Joerg
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 8:37 ` 'Joerg Roedel'
@ 2021-05-12 15:59 ` Dave Hansen
0 siblings, 0 replies; 20+ messages in thread
From: Dave Hansen @ 2021-05-12 15:59 UTC (permalink / raw)
To: 'Joerg Roedel', David Laight
Cc: kvm@vger.kernel.org, Peter Zijlstra, Dave Hansen,
virtualization@lists.linux-foundation.org, Arvind Sankar,
hpa@zytor.com, Jiri Slaby, x86@kernel.org, David Rientjes,
Martin Radev, Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen,
Hyunwook Baek, linux-coco@lists.linux.dev, Andy Lutomirski,
Dan Williams, Juergen Gross, Mike Stunes, Sean Christopherson,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Masami Hiramatsu, Erdem Aktas
On 5/12/21 1:37 AM, 'Joerg Roedel' wrote:
> I also thought about adding page_fault_disable()/page_fault_enable()
> calls, but being in atomic context is enough according to the
> faulthandler_disabled() implementation.
That would be nice to add to a comment:
page_fault_disable()/page_fault_enable() are not needed because of the
context this must be called in.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 7:54 ` [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user Joerg Roedel
2021-05-12 8:04 ` David Laight
@ 2021-05-12 15:57 ` Dave Hansen
2021-05-12 16:00 ` Joerg Roedel
1 sibling, 1 reply; 20+ messages in thread
From: Dave Hansen @ 2021-05-12 15:57 UTC (permalink / raw)
To: Joerg Roedel, x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, David Rientjes, Martin Radev, Tom Lendacky,
Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco, Andy Lutomirski,
Dan Williams, Juergen Gross, Mike Stunes, Sean Christopherson,
linux-kernel, stable, Masami Hiramatsu, Erdem Aktas
On 5/12/21 12:54 AM, Joerg Roedel wrote:
> The put_user() and get_user() functions do checks on the address which is
> passed to them. They check whether the address is actually a user-space
> address and whether its fine to access it. They also call might_fault()
> to indicate that they could fault and possibly sleep.
>
> All of these checks are neither wanted nor required in the #VC exception
> handler, which can be invoked from almost any context and also for MMIO
> instructions from kernel space on kernel memory. All the #VC handler
> wants to know is whether a fault happened when the access was tried.
>
> This is provided by __put_user()/__get_user(), which just do the access
> no matter what.
The changelog _helps_, but using a "user" function to handle kernel MMIO
for its error handling properties seems like it's begging for a comment.
__put_user() also seems to have fun stuff like __chk_user_ptr(). It all
seems sketchy to me.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user
2021-05-12 15:57 ` Dave Hansen
@ 2021-05-12 16:00 ` Joerg Roedel
0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 16:00 UTC (permalink / raw)
To: Dave Hansen
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, x86, David Rientjes, Martin Radev, Tom Lendacky,
Joerg Roedel, Kees Cook, Cfir Cohen, Hyunwook Baek, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, stable, Masami Hiramatsu,
Erdem Aktas
On Wed, May 12, 2021 at 08:57:53AM -0700, Dave Hansen wrote:
> The changelog _helps_, but using a "user" function to handle kernel MMIO
> for its error handling properties seems like it's begging for a comment.
>
> __put_user() also seems to have fun stuff like __chk_user_ptr(). It all
> seems sketchy to me.
Yeah, as Juergen already pointed out, there are certain problems with
that too. But I don't want to write my own accessors, so I will
introduce a separate user and kernel path to these functions.
Regards,
Joerg
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 4/6] Revert "x86/sev-es: Handle string port IO to kernel memory properly"
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
` (2 preceding siblings ...)
2021-05-12 7:54 ` [PATCH 3/6] x86/sev-es: Use __put_user()/__get_user Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
[not found] ` <YJwSlVnHb0SZTSrG@google.com>
2021-05-12 7:54 ` [PATCH 5/6] x86/sev-es: Fix error message in runtime #VC handler Joerg Roedel
2021-05-12 7:54 ` [PATCH 6/6] x86/sev-es: Leave NMI-mode before sending signals Joerg Roedel
5 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, stable, Masami Hiramatsu,
Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
This reverts commit 7024f60d655272bd2ca1d3a4c9e0a63319b1eea1.
The commit reverted here introduces a short-cut into the #VC handlers
memory access code which only works reliably in task context. But the
kernels #VC handler can be invoked from any context, making the
access_ok() call trigger a warning with CONFIG_DEBUG_ATOMIC_SLEEP
enabled.
Also the memcpy() used in the reverted patch is wrong, as it has no
page-fault handling. Access to kernel memory can also fault due to
kernel bugs, and those should not be reported as faults from the #VC
handler but as bugs of their real call-site, which is correctly later
done from vc_forward_exception().
Fixes: 7024f60d6552 ("x86/sev-es: Handle string port IO to kernel memory properly")
Cc: stable@vger.kernel.org # v5.11
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 110b39345b40..f4f319004713 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -333,12 +333,6 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
u16 d2;
u8 d1;
- /* If instruction ran in kernel mode and the I/O buffer is in kernel space */
- if (!user_mode(ctxt->regs) && !access_ok(target, size)) {
- memcpy(dst, buf, size);
- return ES_OK;
- }
-
switch (size) {
case 1:
memcpy(&d1, buf, 1);
@@ -388,12 +382,6 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
u16 d2;
u8 d1;
- /* If instruction ran in kernel mode and the I/O buffer is in kernel space */
- if (!user_mode(ctxt->regs) && !access_ok(s, size)) {
- memcpy(buf, src, size);
- return ES_OK;
- }
-
switch (size) {
case 1:
if (__get_user(d1, s))
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 5/6] x86/sev-es: Fix error message in runtime #VC handler
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
` (3 preceding siblings ...)
2021-05-12 7:54 ` [PATCH 4/6] Revert "x86/sev-es: Handle string port IO to kernel memory properly" Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
2021-05-12 7:54 ` [PATCH 6/6] x86/sev-es: Leave NMI-mode before sending signals Joerg Roedel
5 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, Masami Hiramatsu, Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
The runtime #VC handler is not "early" anymore. Fix the copy&paste error
and remove that word from the error message.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index f4f319004713..77155c4f07f5 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -1326,7 +1326,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
vc_finish_insn(&ctxt);
break;
case ES_UNSUPPORTED:
- pr_err_ratelimited("Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n",
+ pr_err_ratelimited("Unsupported exit-code 0x%02lx in #VC exception (IP: 0x%lx)\n",
error_code, regs->ip);
goto fail;
case ES_VMM_ERROR:
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 6/6] x86/sev-es: Leave NMI-mode before sending signals
2021-05-12 7:54 [PATCH 0/6] x86/sev-es: Fixes for SEV-ES guest support Joerg Roedel
` (4 preceding siblings ...)
2021-05-12 7:54 ` [PATCH 5/6] x86/sev-es: Fix error message in runtime #VC handler Joerg Roedel
@ 2021-05-12 7:54 ` Joerg Roedel
5 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2021-05-12 7:54 UTC (permalink / raw)
To: x86, Hyunwook Baek
Cc: kvm, Peter Zijlstra, Dave Hansen, virtualization, Arvind Sankar,
hpa, Jiri Slaby, Joerg Roedel, David Rientjes, Martin Radev,
Tom Lendacky, Joerg Roedel, Kees Cook, Cfir Cohen, linux-coco,
Andy Lutomirski, Dan Williams, Juergen Gross, Mike Stunes,
Sean Christopherson, linux-kernel, Masami Hiramatsu, Erdem Aktas
From: Joerg Roedel <jroedel@suse.de>
The error path in the runtime #VC handler sends a signal to kill the
current task if the exception was raised from user-space. Some parts of
the #VC handler run in NMI mode, because it is critical that it is not
interrupted (except from an NMI) while the GHCB is in use.
But sending signals in NMI-mode is actually broken and triggers lockdep
warnings. On the other side, when the signal is sent, there is no reason
for the handler to still be in NMI-mode, as the GHCB is not used
anymore.
Leave NMI-mode before entering the error path to get rid of the lockdep
warnings.
Fixes: 62441a1fb532 ("x86/sev-es: Correctly track IRQ states in runtime #VC handler")
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
arch/x86/kernel/sev.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 77155c4f07f5..79cbed2f28de 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -1300,9 +1300,10 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
return;
}
+ instrumentation_begin();
+
irq_state = irqentry_nmi_enter(regs);
lockdep_assert_irqs_disabled();
- instrumentation_begin();
/*
* This is invoked through an interrupt gate, so IRQs are disabled. The
@@ -1352,13 +1353,19 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
BUG();
}
-out:
- instrumentation_end();
irqentry_nmi_exit(regs, irq_state);
+ instrumentation_end();
return;
fail:
+ /*
+ * Leave NMI mode - the GHCB is not busy anymore and depending on where
+ * the #VC came from this code is about to either kill the task (when in
+ * task context) or kill the machine.
+ */
+ irqentry_nmi_exit(regs, irq_state);
+
if (user_mode(regs)) {
/*
* Do not kill the machine if user-space triggered the
@@ -1380,7 +1387,9 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
panic("Returned from Terminate-Request to Hypervisor\n");
}
- goto out;
+ instrumentation_end();
+
+ return;
}
/* This handler runs on the #VC fall-back stack. It can cause further #VC exceptions */
--
2.31.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply related [flat|nested] 20+ messages in thread