From: Xen.org security team <security@xen.org>
To: xen-announce@lists.xen.org, xen-devel@lists.xen.org,
xen-users@lists.xen.org, oss-security@lists.openwall.com
Cc: "Xen.org security team" <security-team-members@xen.org>
Subject: [Xen-devel] Xen Security Advisory 294 v3 (CVE-2019-17348) - x86 shadow: Insufficient TLB flushing when using PCID
Date: Fri, 25 Oct 2019 11:10:41 +0000 [thread overview]
Message-ID: <E1iNxUP-0002nr-RQ@xenbits.xenproject.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 4596 bytes --]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Xen Security Advisory CVE-2019-17348 / XSA-294
version 3
x86 shadow: Insufficient TLB flushing when using PCID
UPDATES IN VERSION 3
====================
CVE assigned.
ISSUE DESCRIPTION
=================
Use of Process Context Identifiers (PCID) was introduced into Xen in
order to improve performance after XSA-254 (and in particular its
Meltdown sub-issue). This enablement implied changes to the TLB
flushing logic. One aspect which was overlooked is the safety of
switching between shadow pagetables, which previously relied on the
unconditional flushing of a write to CR3.
With PCID enabled, a switch of shadow pagetable for a 64bit PV guest
fails to invalidate the linear mappings of the previous shadow
pagetable. As a result, subsequent accesses to the shadow pagetables
may be deemed to be safe by the shadow logic (based on the old shadow
pagetable) but fault when made in practice.
IMPACT
======
Malicious 64bit PV guests may be able to cause a host crash (Denial of
Service).
Additionally, vulnerable configurations are unstable even in the absence
of an attack.
VULNERABLE SYSTEMS
==================
Only x86 systems are vulnerable. ARM systems are not vulnerable.
Only systems running 64-bit x86 PV guests are vulnerable. Systems running
only x86 HVM or PVH or 32bit PV guests are not vulnerable.
Only systems with at least one PCID-enabled PV guest are vulnerable.
Systems where PCID or INVPCID are unavailable or entirely disabled are
not vulnerable.
Note that PCID is enabled by default for both 64-bit dom0 and 64-bit
domU when hardware supports it. PCID acceleration has been backported
to the following versions:
- Xen 4.11.x,
- Xen 4.10.2 and onwards,
- Xen 4.9.3 and onwards,
- Xen 4.8.4 and onwards,
- Xen 4.7.6.
MITIGATION
==========
Running only HVM or PVH guests will avoid this vulnerability.
Disabling use of PCID entirely, by passing "pcid=0" or "invpcid=0" as a
command line option to the hypervisor, will also avoid this
vulnerability (albeit re-introducing the XPTI performance regression
use of PCID was intended to reduce).
CREDITS
=======
This issue was discovered by Jan Beulich of SUSE.
RESOLUTION
==========
Applying the appropriate attached patch resolves this issue.
xsa294/unstable.patch xen-unstable
xsa294/4.11.patch Xen 4.11.x
xsa294/4.10.patch Xen 4.10.x
xsa294/4.9.patch Xen 4.9.x
xsa294/4.8.patch Xen 4.8.x
xsa294/4.7.patch Xen 4.7.x
$ sha256sum xsa294*/*
c10b7b79a2067cc6d95e40bc78ee8fddaf31f8614bb183fdd5f00e4272e08a0e xsa294/4.7.patch
3ac1c3caf01feaf341e977fcbae691f2e4425aa9691f2dfa66795acfe823d76e xsa294/4.8.patch
a8dfc8b2d2f0d0865b70fb0051f9d5a80a6c7456d004957a0155d989ec875611 xsa294/4.9.patch
c6fe1e0173b665a88cbab423737dcb060eed1f634f9bca880d9ddfa2ac855d03 xsa294/4.10.patch
61a341510f45c0cf63a7438645f5c2b3ab1cd72bc2476e5fad331e322f834f4a xsa294/4.11.patch
1fb22eab53f9b1e93fc25f5a08d37121a9278854174f1fbd495b3fe6e8babf3a xsa294/unstable.patch
$
DEPLOYMENT DURING EMBARGO
=========================
Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.
But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).
Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.
(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable. This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)
For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----
iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAl2y1/cMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZH54H/iShmv1F1GDALKhJJdm+BOEtyVy+ZCFU5Atn97dV
3Bm+3BtX1Nfcd1pnLdzQs0ocasw+FSp0Swq93nrpM8hPK9ze4aAKwo/Srhf/WV2/
V9N5lKwxCUub6p2QbAcqj//zLxv0llkhduVGzV9/NXOzeLn5Rp2Af/rgSchQ4QHp
oEdHXNV93Pm1pi4NpCu8uXQAW4Mp7rRiWJPuBkuJDhgVftXItSNMc6jLunJS581X
z+3SmLpfF3IDVpa5GqjtFJ3Exk9DJe4oYHZPmb2qwJTsfV20emIc/7mARGErgdwT
jpRjss41gJX1l41zRF9mwKPc1qPW6Rc9xgh6q1jrjY1CCvk=
=TV/a
-----END PGP SIGNATURE-----
[-- Attachment #2: xsa294/4.7.patch --]
[-- Type: application/octet-stream, Size: 3155 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 56ed156..ee1f408 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -20,6 +20,7 @@
#include <asm/event.h>
#include <asm/msr.h>
#include <asm/page.h>
+#include <asm/shadow.h>
#include <asm/shared.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
@@ -280,6 +281,8 @@ void toggle_guest_mode(struct vcpu *v)
void toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
if ( is_pv_32bit_vcpu(v) )
return;
@@ -288,16 +291,28 @@ void toggle_guest_pt(struct vcpu *v)
update_cr3(v);
if ( d->arch.pv_domain.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = 1;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv_domain.pcid
? get_pcid_bits(v, 1) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #3: xsa294/4.8.patch --]
[-- Type: application/octet-stream, Size: 3161 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 396e677..99e995b 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -21,6 +21,7 @@
#include <asm/event.h>
#include <asm/msr.h>
#include <asm/page.h>
+#include <asm/shadow.h>
#include <asm/shared.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
@@ -282,6 +283,8 @@ void toggle_guest_mode(struct vcpu *v)
void toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
if ( is_pv_32bit_vcpu(v) )
return;
@@ -290,16 +293,28 @@ void toggle_guest_pt(struct vcpu *v)
update_cr3(v);
if ( d->arch.pv_domain.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = true;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv_domain.pcid
? get_pcid_bits(v, true) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #4: xsa294/4.9.patch --]
[-- Type: application/octet-stream, Size: 3161 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 8a06b21..0509be4 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -20,6 +20,7 @@
#include <asm/event.h>
#include <asm/msr.h>
#include <asm/page.h>
+#include <asm/shadow.h>
#include <asm/shared.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
@@ -281,6 +282,8 @@ void toggle_guest_mode(struct vcpu *v)
void toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
if ( is_pv_32bit_vcpu(v) )
return;
@@ -289,16 +292,28 @@ void toggle_guest_pt(struct vcpu *v)
update_cr3(v);
if ( d->arch.pv_domain.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = true;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv_domain.pcid
? get_pcid_bits(v, true) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #5: xsa294/4.10.patch --]
[-- Type: application/octet-stream, Size: 2956 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 958c6e3..7973155 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -320,6 +320,8 @@ void toggle_guest_mode(struct vcpu *v)
void toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
if ( is_pv_32bit_vcpu(v) )
return;
@@ -328,16 +330,28 @@ void toggle_guest_pt(struct vcpu *v)
update_cr3(v);
if ( d->arch.pv_domain.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = true;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv_domain.pcid
? get_pcid_bits(v, true) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #6: xsa294/4.11.patch --]
[-- Type: application/octet-stream, Size: 2900 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index b75ff6b..528413a 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -296,21 +296,35 @@ int pv_domain_initialise(struct domain *d)
static void _toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
v->arch.flags ^= TF_kernel_mode;
update_cr3(v);
if ( d->arch.pv_domain.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = true;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv_domain.pcid
? get_pcid_bits(v, true) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #7: xsa294/unstable.patch --]
[-- Type: application/octet-stream, Size: 2850 bytes --]
From: Jan Beulich <JBeulich@suse.com>
Subject: x86/pv: _toggle_guest_pt() may not skip TLB flush for shadow mode guests
For shadow mode guests (e.g. PV ones forced into that mode as L1TF
mitigation, or during migration) update_cr3() -> sh_update_cr3() may
result in a change to the (shadow) root page table (compared to the
previous one when running the same vCPU with the same PCID). This can,
first and foremost, be a result of memory pressure on the shadow memory
pool of the domain. Shadow code legitimately relies on the original
(prior to commit 5c81d260c2 ["xen/x86: use PCID feature"]) behavior of
the subsequent CR3 write to flush the TLB of entries still left from
walks with an earlier, different (shadow) root page table.
Restore the flushing behavior, also for the second CR3 write on the exit
path to guest context when XPTI is active. For the moment accept that
this will introduce more flushes than are strictly necessary - no flush
would be needed when the (shadow) root page table doesn't actually
change, but this information isn't readily (i.e. without introducing a
layering violation) available here.
This is XSA-294.
Reported-by: XXX PERSON <XXX EMAIL>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 7e84b04..bafb782 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -295,20 +295,34 @@ bool __init xpti_pcid_enabled(void)
static void _toggle_guest_pt(struct vcpu *v)
{
const struct domain *d = v->domain;
+ struct cpu_info *cpu_info = get_cpu_info();
+ unsigned long cr3;
v->arch.flags ^= TF_kernel_mode;
update_cr3(v);
if ( d->arch.pv.xpti )
{
- struct cpu_info *cpu_info = get_cpu_info();
-
cpu_info->root_pgt_changed = true;
cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)) |
(d->arch.pv.pcid ? get_pcid_bits(v, true) : 0);
}
- /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */
- write_cr3(v->arch.cr3);
+ /*
+ * Don't flush user global mappings from the TLB. Don't tick TLB clock.
+ *
+ * In shadow mode, though, update_cr3() may need to be accompanied by a
+ * TLB flush (for just the incoming PCID), as the top level page table may
+ * have changed behind our backs. To be on the safe side, suppress the
+ * no-flush unconditionally in this case. The XPTI CR3 write, if enabled,
+ * will then need to be a flushing one too.
+ */
+ cr3 = v->arch.cr3;
+ if ( shadow_mode_enabled(d) )
+ {
+ cr3 &= ~X86_CR3_NOFLUSH;
+ cpu_info->pv_cr3 &= ~X86_CR3_NOFLUSH;
+ }
+ write_cr3(cr3);
if ( !(v->arch.flags & TF_kernel_mode) )
return;
[-- Attachment #8: Type: text/plain, Size: 157 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
reply other threads:[~2019-10-25 11:11 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=E1iNxUP-0002nr-RQ@xenbits.xenproject.org \
--to=security@xen.org \
--cc=oss-security@lists.openwall.com \
--cc=security-team-members@xen.org \
--cc=xen-announce@lists.xen.org \
--cc=xen-devel@lists.xen.org \
--cc=xen-users@lists.xen.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.