Compare commits
15 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f72515dd8b | ||
|
|
7490b76e19 | ||
|
|
c3863c816e | ||
|
|
37608f5d89 | ||
|
|
24e155b60d | ||
|
|
86dbccba26 | ||
|
|
aa6e17cc27 | ||
|
|
6f9b812905 | ||
|
|
fc3d63c3dc | ||
|
|
5f155647b3 | ||
|
|
e7122f27e1 | ||
|
|
0af4083600 | ||
|
|
298b801f9a | ||
|
|
39685fac18 | ||
|
|
22d02a7039 |
23 changed files with 9345 additions and 1321 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -6,4 +6,4 @@ lwip-1.3.0.tar.gz
|
|||
pciutils-2.2.9.tar.bz2
|
||||
zlib-1.2.3.tar.gz
|
||||
polarssl-1.1.4-gpl.tgz
|
||||
/xen-4.13.1.tar.gz
|
||||
/xen-4.13.3.tar.gz
|
||||
|
|
|
|||
2
sources
2
sources
|
|
@ -4,4 +4,4 @@ SHA512 (newlib-1.16.0.tar.gz) = 40eb96bbc6736a16b6399e0cdb73e853d0d90b685c967e77
|
|||
SHA512 (zlib-1.2.3.tar.gz) = 021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea34a70504ce9622b1c2626fce40675bc8282cf5f5ade18473656abc38050f72f5d6480507a2106e
|
||||
SHA512 (polarssl-1.1.4-gpl.tgz) = 88da614e4d3f4409c4fd3bb3e44c7587ba051e3fed4e33d526069a67e8180212e1ea22da984656f50e290049f60ddca65383e5983c0f8884f648d71f698303ad
|
||||
SHA512 (pciutils-2.2.9.tar.bz2) = 2b3d98d027e46d8c08037366dde6f0781ca03c610ef2b380984639e4ef39899ed8d8b8e4cd9c9dc54df101279b95879bd66bfd4d04ad07fef41e847ea7ae32b5
|
||||
SHA512 (xen-4.13.1.tar.gz) = b56d20704155d98d803496cba83eb928e0f986a750831cd5600fc88d0ae772fe1456571654375054043d2da8daca255cc98385ebf08b1b1a75ecf7f4b7a0ee90
|
||||
SHA512 (xen-4.13.3.tar.gz) = 622127d824b9c49b57282a887fb404e0bad05ff60bccade82e4e0e9b5ad975ff9aa1fba83392e6d8379e9a15340e8ae9785c0913eb11027816e4600432eea6b6
|
||||
|
|
|
|||
|
|
@ -38,17 +38,17 @@
|
|||
return get_node(conn, ctx, *canonical_name, perm);
|
||||
}
|
||||
|
||||
--- xen-4.9.0-rc1.2/tools/xenstore/xenstored_core.h.orig 2017-04-12 16:18:57.000000000 +0100
|
||||
+++ xen-4.9.0-rc1.2/tools/xenstore/xenstored_core.h 2017-04-13 21:20:29.146368478 +0100
|
||||
@@ -148,7 +148,7 @@
|
||||
--- xen-4.13.3/tools/xenstore/xenstored_core.h.orig 2021-03-22 16:57:42.000000000 +0000
|
||||
+++ xen-4.13.3/tools/xenstore/xenstored_core.h 2021-03-29 19:56:36.642394283 +0100
|
||||
@@ -153,7 +153,7 @@
|
||||
void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
|
||||
|
||||
/* Canonicalize this path if possible. */
|
||||
-char *canonicalize(struct connection *conn, const void *ctx, const char *node);
|
||||
+char *xenstore_canonicalize(struct connection *conn, const void *ctx, const char *node);
|
||||
|
||||
/* Write a node to the tdb data base. */
|
||||
int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
|
||||
/* Get access permissions. */
|
||||
enum xs_perm_type perm_for_conn(struct connection *conn,
|
||||
--- xen-4.8.0/tools/console/testsuite/console-dom0.c.orig 2016-12-05 12:03:27.000000000 +0000
|
||||
+++ xen-4.8.0/tools/console/testsuite/console-dom0.c 2017-02-26 21:52:24.554678631 +0000
|
||||
@@ -18,7 +18,7 @@
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
--- xen-4.13.0/tools/xenstore/utils.h.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/xenstore/utils.h 2020-01-21 21:13:05.108957447 +0000
|
||||
@@ -24,7 +24,7 @@
|
||||
void barf(const char *fmt, ...) __attribute__((noreturn));
|
||||
void barf_perror(const char *fmt, ...) __attribute__((noreturn));
|
||||
|
||||
-void (*xprintf)(const char *fmt, ...);
|
||||
+extern void (*xprintf)(const char *fmt, ...);
|
||||
|
||||
#define eprintf(_fmt, _args...) xprintf("[ERR] %s" _fmt, __FUNCTION__, ##_args)
|
||||
|
||||
--- xen-4.13.0/tools/xenstore/xenstored_core.h.orig 2020-01-21 21:15:19.243931307 +0000
|
||||
+++ xen-4.13.0/tools/xenstore/xenstored_core.h 2020-01-21 21:38:35.340617819 +0000
|
||||
@@ -204,7 +204,7 @@
|
||||
/* Open a pipe for signal handling */
|
||||
void init_pipe(int reopen_log_pipe[2]);
|
||||
|
||||
-xengnttab_handle **xgt_handle;
|
||||
+extern xengnttab_handle **xgt_handle;
|
||||
|
||||
int remember_string(struct hashtable *hash, const char *str);
|
||||
|
||||
--- xen-4.13.0/tools/libxl/libxlu_pci.c.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/libxl/libxlu_pci.c 2020-01-21 21:56:26.812212916 +0000
|
||||
@@ -48,7 +48,7 @@
|
||||
int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str)
|
||||
{
|
||||
unsigned state = STATE_DOMAIN;
|
||||
- unsigned dom, bus, dev, func, vslot = 0;
|
||||
+ unsigned dom = 0, bus = 0, dev = 0, func = 0, vslot = 0;
|
||||
char *buf2, *tok, *ptr, *end, *optkey = NULL;
|
||||
|
||||
if ( NULL == (buf2 = ptr = strdup(str)) )
|
||||
--- xen-4.13.0/tools/libxl/libxl_utils.c.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/libxl/libxl_utils.c 2020-01-21 22:34:52.096300774 +0000
|
||||
@@ -1259,7 +1259,7 @@
|
||||
}
|
||||
memset(un, 0, sizeof(struct sockaddr_un));
|
||||
un->sun_family = AF_UNIX;
|
||||
- strncpy(un->sun_path, path, sizeof(un->sun_path));
|
||||
+ strncpy(un->sun_path, path, sizeof(un->sun_path)-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- xen-4.13.0/tools/debugger/kdd/kdd.h.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/debugger/kdd/kdd.h 2020-01-21 23:35:55.458605582 +0000
|
||||
@@ -323,7 +323,7 @@
|
||||
kdd_msg msg;
|
||||
kdd_reg reg;
|
||||
kdd_stc stc;
|
||||
- uint8_t payload[0];
|
||||
+ uint8_t payload[65535];
|
||||
};
|
||||
} PACKED kdd_pkt;
|
||||
|
||||
--- xen-4.13.0/tools/xenpmd/Makefile.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/xenpmd/Makefile 2020-01-22 22:13:16.564873608 +0000
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += $(CFLAGS_libxenstore)
|
||||
+CFLAGS += -Wno-error=format-truncation
|
||||
|
||||
LDLIBS += $(LDLIBS_libxenstore)
|
||||
|
||||
|
|
@ -103,8 +103,10 @@ CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
|||
CONFIG_ARM64_ERRATUM_827319=y
|
||||
CONFIG_ARM64_ERRATUM_824069=y
|
||||
CONFIG_ARM64_ERRATUM_819472=y
|
||||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_ERRATUM_832075=y
|
||||
CONFIG_ARM64_ERRATUM_834220=y
|
||||
CONFIG_ARM_ERRATUM_858921=y
|
||||
CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y
|
||||
CONFIG_ALL_PLAT=y
|
||||
# CONFIG_QEMU is not set
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
ret = xc_vcpu_getcontext(_H(xch), _D(domid), Int_val(cpu), &ctxt);
|
||||
|
||||
context = caml_alloc_string(sizeof(ctxt));
|
||||
- memcpy(String_val(context), (char *) &ctxt.c, sizeof(ctxt.c));
|
||||
- memcpy((char *) String_val(context), &ctxt.c, sizeof(ctxt.c));
|
||||
+ memcpy((char *) Bp_val(context), (char *) &ctxt.c, sizeof(ctxt.c));
|
||||
|
||||
CAMLreturn(context);
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
conring_size = size;
|
||||
|
||||
ring = caml_alloc_string(count);
|
||||
- memcpy(String_val(ring), str, count);
|
||||
- memcpy((char *) String_val(ring), str, count);
|
||||
+ memcpy((char *) Bp_val(ring), str, count);
|
||||
free(str);
|
||||
|
||||
|
|
@ -45,33 +45,13 @@
|
|||
|
||||
r = xc_cpuid_set(_H(xch), _D(domid),
|
||||
c_input, (const char **)c_config, out_config);
|
||||
--- xen-4.13.0/tools/ocaml/libs/xb/xs_ring_stubs.c.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/ocaml/libs/xb/xs_ring_stubs.c 2020-01-21 23:51:35.473330934 +0000
|
||||
@@ -44,7 +44,7 @@
|
||||
CAMLlocal1(ml_result);
|
||||
|
||||
struct mmap_interface *interface = GET_C_STRUCT(ml_interface);
|
||||
- char *buffer = String_val(ml_buffer);
|
||||
+ char *buffer = (char *) Bp_val(ml_buffer);
|
||||
int len = Int_val(ml_len);
|
||||
int result;
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
CAMLlocal1(ml_result);
|
||||
|
||||
struct mmap_interface *interface = GET_C_STRUCT(ml_interface);
|
||||
- char *buffer = String_val(ml_buffer);
|
||||
+ char *buffer = (char *) Bp_val(ml_buffer);
|
||||
int len = Int_val(ml_len);
|
||||
int result;
|
||||
|
||||
--- xen-4.13.0/tools/ocaml/libs/xb/xenbus_stubs.c.orig 2019-12-17 14:23:09.000000000 +0000
|
||||
+++ xen-4.13.0/tools/ocaml/libs/xb/xenbus_stubs.c 2020-01-22 00:04:09.443168991 +0000
|
||||
@@ -65,7 +65,7 @@
|
||||
};
|
||||
|
||||
ret = caml_alloc_string(sizeof(struct xsd_sockmsg));
|
||||
- memcpy(String_val(ret), &xsd, sizeof(struct xsd_sockmsg));
|
||||
- memcpy((char *) String_val(ret), &xsd, sizeof(struct xsd_sockmsg));
|
||||
+ memcpy((char *) Bp_val(ret), &xsd, sizeof(struct xsd_sockmsg));
|
||||
|
||||
CAMLreturn(ret);
|
||||
|
|
|
|||
129
xen.spec
129
xen.spec
|
|
@ -57,8 +57,8 @@
|
|||
|
||||
Summary: Xen is a virtual machine monitor
|
||||
Name: xen
|
||||
Version: 4.13.1
|
||||
Release: 4%{?dist}
|
||||
Version: 4.13.3
|
||||
Release: 1%{?dist}
|
||||
License: GPLv2+ and LGPLv2+ and BSD
|
||||
URL: http://xen.org/
|
||||
Source0: https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.tar.gz
|
||||
|
|
@ -113,21 +113,8 @@ Patch40: xen.drop.brctl.patch
|
|||
Patch41: xen.python.env.patch
|
||||
Patch42: xen.gcc9.fixes.patch
|
||||
Patch44: xen.ocaml.4.10.patch
|
||||
Patch45: xen.gcc10.fixes.patch
|
||||
Patch46: xsa320-4.13-1.patch
|
||||
Patch47: xsa320-4.13-2.patch
|
||||
Patch48: xsa317.patch
|
||||
Patch49: xsa319.patch
|
||||
Patch50: xsa328-4.13-1.patch
|
||||
Patch51: xsa328-4.13-2.patch
|
||||
Patch52: xsa321-4.13-1.patch
|
||||
Patch53: xsa321-4.13-2.patch
|
||||
Patch54: xsa321-4.13-3.patch
|
||||
Patch55: xsa321-4.13-4.patch
|
||||
Patch56: xsa321-4.13-5.patch
|
||||
Patch57: xsa321-4.13-6.patch
|
||||
Patch58: xsa321-4.13-7.patch
|
||||
Patch59: xsa327.patch
|
||||
Patch65: zstd-dom0.patch
|
||||
Patch100: xsa363.patch
|
||||
|
||||
|
||||
%if %build_qemutrad
|
||||
|
|
@ -333,21 +320,8 @@ manage Xen virtual machines.
|
|||
%patch41 -p1
|
||||
%patch42 -p1
|
||||
%patch44 -p1
|
||||
%patch45 -p1
|
||||
%patch46 -p1
|
||||
%patch47 -p1
|
||||
%patch48 -p1
|
||||
%patch49 -p1
|
||||
%patch50 -p1
|
||||
%patch51 -p1
|
||||
%patch52 -p1
|
||||
%patch53 -p1
|
||||
%patch54 -p1
|
||||
%patch55 -p1
|
||||
%patch56 -p1
|
||||
%patch57 -p1
|
||||
%patch58 -p1
|
||||
%patch59 -p1
|
||||
%patch65 -p1
|
||||
%patch100 -p1
|
||||
|
||||
# qemu-xen-traditional patches
|
||||
pushd tools/qemu-xen-traditional
|
||||
|
|
@ -940,6 +914,97 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Mar 29 2021 Michael Young <m.a.young@durham.ac.uk> - 4.13.3-1
|
||||
- update to 4.13.3
|
||||
remove patches now included or superceded upstream
|
||||
adjust xen.hypervisor.config
|
||||
|
||||
* Thu Mar 18 2021 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-8
|
||||
- HVM soft-reset crashes toolstack [XSA-368, CVE-2021-28687] (#1940610)
|
||||
|
||||
* Wed Feb 17 2021 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-7
|
||||
- Linux: display frontend "be-alloc" mode is unsupported (comment only)
|
||||
[XSA-363, CVE-2021-26934] (#1929549)
|
||||
- arm: The cache may not be cleaned for newly allocated scrubbed pages
|
||||
[XSA-364, CVE-2021-26933] (#1929547)
|
||||
|
||||
* Thu Jan 21 2021 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-6
|
||||
- IRQ vector leak on x86 [XSA-360]
|
||||
|
||||
* Wed Dec 16 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-5
|
||||
- xenstore watch notifications lacking permission checks [XSA-115,
|
||||
CVE-2020-29480] (#1908091)
|
||||
- Xenstore: new domains inheriting existing node permissions [XSA-322,
|
||||
CVE-2020-29481] (#1908095)
|
||||
- Xenstore: wrong path length check [XSA-323, CVE-2020-29482] (#1908096)
|
||||
- Xenstore: guests can crash xenstored via watchs [XSA-324, CVE-2020-29484]
|
||||
(#1908088)
|
||||
- Xenstore: guests can disturb domain cleanup [XSA-325, CVE-2020-29483]
|
||||
(#1908087)
|
||||
- oxenstored memory leak in reset_watches [XSA-330, CVE-2020-29485]
|
||||
(#1908000)
|
||||
- undue recursion in x86 HVM context switch code [XSA-348, CVE-2020-29566]
|
||||
(#1908085)
|
||||
- oxenstored: node ownership can be changed by unprivileged clients
|
||||
[XSA-352, CVE-2020-29486] (#1908003)
|
||||
- oxenstored: permissions not checked on root node [XSA-353, CVE-2020-29479]
|
||||
(#1908002)
|
||||
- FIFO event channels control block related ordering [XSA-358,
|
||||
CVE-2020-29570] (#1907931)
|
||||
- FIFO event channels control structure ordering [XSA-359, CVE-2020-29571]
|
||||
(#1908089)
|
||||
|
||||
* Tue Nov 24 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-4
|
||||
- stack corruption from XSA-346 change [XSA-355]
|
||||
|
||||
* Mon Nov 23 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-3
|
||||
- support zstd compressed kernels (dom0 only) based on linux kernel code
|
||||
|
||||
* Tue Nov 10 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-2
|
||||
- Information leak via power sidechannel [XSA-351, CVE-2020-28368]
|
||||
(#1897146)
|
||||
|
||||
* Tue Nov 03 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.2-1
|
||||
- update to 4.13.2
|
||||
remove patches now included or superceded upstream
|
||||
|
||||
* Wed Oct 28 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.1-8
|
||||
- x86 PV guest INVLPG-like flushes may leave stale TLB entries
|
||||
[XSA-286, CVE-2020-27674] (#1891092)
|
||||
|
||||
* Tue Oct 20 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.1-7
|
||||
- x86: Race condition in Xen mapping code [XSA-345, CVE-2020-27672]
|
||||
(#1891097)
|
||||
- undue deferral of IOMMU TLB flushes [XSA-346, CVE-2020-27671]
|
||||
(#1891093)
|
||||
- unsafe AMD IOMMU page table updates [XSA-347 CVE-2020-27670]
|
||||
(#1891088)
|
||||
|
||||
* Tue Sep 22 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.1-6
|
||||
- x86 pv: Crash when handling guest access to MSR_MISC_ENABLE [XSA-333,
|
||||
CVE-2020-25602] (#1881619)
|
||||
- Missing unlock in XENMEM_acquire_resource error path [XSA-334,
|
||||
CVE-2020-25598] (#1881616)
|
||||
- race when migrating timers between x86 HVM vCPU-s [XSA-336,
|
||||
CVE-2020-25604] (#1881618)
|
||||
- PCI passthrough code reading back hardware registers [XSA-337,
|
||||
CVE-2020-25595] (#1881587)
|
||||
- once valid event channels may not turn invalid [XSA-338, CVE-2020-25597]
|
||||
(#1881588)
|
||||
- x86 pv guest kernel DoS via SYSENTER [XSA-339, CVE-2020-25596]
|
||||
(#1881617)
|
||||
- Missing memory barriers when accessing/allocating an event channel [XSA-340,
|
||||
CVE-2020-25603] (#1881583)
|
||||
- out of bounds event channels available to 32-bit x86 domains [XSA-342,
|
||||
CVE-2020-25600] (#1881582)
|
||||
- races with evtchn_reset() [XSA-343, CVE-2020-25599] (#1881581)
|
||||
- lack of preemption in evtchn_reset() / evtchn_destroy() [XSA-344,
|
||||
CVE-2020-25601] (#1881586)
|
||||
|
||||
* Tue Aug 25 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.1-5
|
||||
- QEMU: usb: out-of-bounds r/w access issue [XSA-335, CVE-2020-14364]
|
||||
(#1871850)
|
||||
|
||||
* Tue Jul 07 2020 Michael Young <m.a.young@durham.ac.uk> - 4.13.1-4
|
||||
- incorrect error handling in event channel port allocation leads to
|
||||
DoS [XSA-317, CVE-2020-15566] (#1854465)
|
||||
|
|
|
|||
50
xsa317.patch
50
xsa317.patch
|
|
@ -1,50 +0,0 @@
|
|||
From aeb46e92f915f19a61d5a8a1f4b696793f64e6fb Mon Sep 17 00:00:00 2001
|
||||
From: Julien Grall <jgrall@amazon.com>
|
||||
Date: Thu, 19 Mar 2020 13:17:31 +0000
|
||||
Subject: [PATCH] xen/common: event_channel: Don't ignore error in
|
||||
get_free_port()
|
||||
|
||||
Currently, get_free_port() is assuming that the port has been allocated
|
||||
when evtchn_allocate_port() is not return -EBUSY.
|
||||
|
||||
However, the function may return an error when:
|
||||
- We exhausted all the event channels. This can happen if the limit
|
||||
configured by the administrator for the guest ('max_event_channels'
|
||||
in xl cfg) is higher than the ABI used by the guest. For instance,
|
||||
if the guest is using 2L, the limit should not be higher than 4095.
|
||||
- We cannot allocate memory (e.g Xen has not more memory).
|
||||
|
||||
Users of get_free_port() (such as EVTCHNOP_alloc_unbound) will validly
|
||||
assuming the port was valid and will next call evtchn_from_port(). This
|
||||
will result to a crash as the memory backing the event channel structure
|
||||
is not present.
|
||||
|
||||
Fixes: 368ae9a05fe ("xen/pvshim: forward evtchn ops between L0 Xen and L2 DomU")
|
||||
Signed-off-by: Julien Grall <jgrall@amazon.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
xen/common/event_channel.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
|
||||
index e86e2bfab0..a8d182b584 100644
|
||||
--- a/xen/common/event_channel.c
|
||||
+++ b/xen/common/event_channel.c
|
||||
@@ -195,10 +195,10 @@ static int get_free_port(struct domain *d)
|
||||
{
|
||||
int rc = evtchn_allocate_port(d, port);
|
||||
|
||||
- if ( rc == -EBUSY )
|
||||
- continue;
|
||||
-
|
||||
- return port;
|
||||
+ if ( rc == 0 )
|
||||
+ return port;
|
||||
+ else if ( rc != -EBUSY )
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
return -ENOSPC;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
27
xsa319.patch
27
xsa319.patch
|
|
@ -1,27 +0,0 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/shadow: correct an inverted conditional in dirty VRAM tracking
|
||||
|
||||
This originally was "mfn_x(mfn) == INVALID_MFN". Make it like this
|
||||
again, taking the opportunity to also drop the unnecessary nearby
|
||||
braces.
|
||||
|
||||
This is XSA-319.
|
||||
|
||||
Fixes: 246a5a3377c2 ("xen: Use a typesafe to define INVALID_MFN")
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/shadow/common.c
|
||||
+++ b/xen/arch/x86/mm/shadow/common.c
|
||||
@@ -3252,10 +3252,8 @@ int shadow_track_dirty_vram(struct domai
|
||||
int dirty = 0;
|
||||
paddr_t sl1ma = dirty_vram->sl1ma[i];
|
||||
|
||||
- if ( !mfn_eq(mfn, INVALID_MFN) )
|
||||
- {
|
||||
+ if ( mfn_eq(mfn, INVALID_MFN) )
|
||||
dirty = 1;
|
||||
- }
|
||||
else
|
||||
{
|
||||
page = mfn_to_page(mfn);
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/spec-ctrl: CPUID/MSR definitions for Special Register Buffer Data Sampling
|
||||
|
||||
This is part of XSA-320 / CVE-2020-0543
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Wei Liu <wl@xen.org>
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
|
||||
index 1d9d816622..9268454297 100644
|
||||
--- a/docs/misc/xen-command-line.pandoc
|
||||
+++ b/docs/misc/xen-command-line.pandoc
|
||||
@@ -483,10 +483,10 @@ accounting for hardware capabilities as enumerated via CPUID.
|
||||
|
||||
Currently accepted:
|
||||
|
||||
-The Speculation Control hardware features `md-clear`, `ibrsb`, `stibp`, `ibpb`,
|
||||
-`l1d-flush` and `ssbd` are used by default if available and applicable. They can
|
||||
-be ignored, e.g. `no-ibrsb`, at which point Xen won't use them itself, and
|
||||
-won't offer them to guests.
|
||||
+The Speculation Control hardware features `srbds-ctrl`, `md-clear`, `ibrsb`,
|
||||
+`stibp`, `ibpb`, `l1d-flush` and `ssbd` are used by default if available and
|
||||
+applicable. They can be ignored, e.g. `no-ibrsb`, at which point Xen won't
|
||||
+use them itself, and won't offer them to guests.
|
||||
|
||||
### cpuid_mask_cpu
|
||||
> `= fam_0f_rev_[cdefg] | fam_10_rev_[bc] | fam_11_rev_b`
|
||||
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
|
||||
index 6cea4227ba..a78f08b927 100644
|
||||
--- a/tools/libxl/libxl_cpuid.c
|
||||
+++ b/tools/libxl/libxl_cpuid.c
|
||||
@@ -213,6 +213,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
|
||||
|
||||
{"avx512-4vnniw",0x00000007, 0, CPUID_REG_EDX, 2, 1},
|
||||
{"avx512-4fmaps",0x00000007, 0, CPUID_REG_EDX, 3, 1},
|
||||
+ {"srbds-ctrl", 0x00000007, 0, CPUID_REG_EDX, 9, 1},
|
||||
{"md-clear", 0x00000007, 0, CPUID_REG_EDX, 10, 1},
|
||||
{"cet-ibt", 0x00000007, 0, CPUID_REG_EDX, 20, 1},
|
||||
{"ibrsb", 0x00000007, 0, CPUID_REG_EDX, 26, 1},
|
||||
diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
|
||||
index 603e1d65fd..a09440813b 100644
|
||||
--- a/tools/misc/xen-cpuid.c
|
||||
+++ b/tools/misc/xen-cpuid.c
|
||||
@@ -157,6 +157,7 @@ static const char *const str_7d0[32] =
|
||||
[ 2] = "avx512_4vnniw", [ 3] = "avx512_4fmaps",
|
||||
[ 4] = "fsrm",
|
||||
|
||||
+ /* 8 */ [ 9] = "srbds-ctrl",
|
||||
[10] = "md-clear",
|
||||
/* 12 */ [13] = "tsx-force-abort",
|
||||
|
||||
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
|
||||
index 4b12103482..0cded3c0ad 100644
|
||||
--- a/xen/arch/x86/msr.c
|
||||
+++ b/xen/arch/x86/msr.c
|
||||
@@ -134,6 +134,7 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val)
|
||||
/* Write-only */
|
||||
case MSR_TSX_FORCE_ABORT:
|
||||
case MSR_TSX_CTRL:
|
||||
+ case MSR_MCU_OPT_CTRL:
|
||||
case MSR_U_CET:
|
||||
case MSR_S_CET:
|
||||
case MSR_PL0_SSP ... MSR_INTERRUPT_SSP_TABLE:
|
||||
@@ -288,6 +289,7 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
/* Read-only */
|
||||
case MSR_TSX_FORCE_ABORT:
|
||||
case MSR_TSX_CTRL:
|
||||
+ case MSR_MCU_OPT_CTRL:
|
||||
case MSR_U_CET:
|
||||
case MSR_S_CET:
|
||||
case MSR_PL0_SSP ... MSR_INTERRUPT_SSP_TABLE:
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 6656c44aec..5fc1c6827e 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -312,12 +312,13 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
printk("Speculative mitigation facilities:\n");
|
||||
|
||||
/* Hardware features which pertain to speculative mitigations. */
|
||||
- printk(" Hardware features:%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
+ printk(" Hardware features:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_L1D_FLUSH)) ? " L1D_FLUSH" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_SSBD)) ? " SSBD" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_MD_CLEAR)) ? " MD_CLEAR" : "",
|
||||
+ (_7d0 & cpufeat_mask(X86_FEATURE_SRBDS_CTRL)) ? " SRBDS_CTRL" : "",
|
||||
(e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "",
|
||||
(caps & ARCH_CAPS_IBRS_ALL) ? " IBRS_ALL" : "",
|
||||
(caps & ARCH_CAPS_RDCL_NO) ? " RDCL_NO" : "",
|
||||
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
|
||||
index 7693c4a71a..91994669e1 100644
|
||||
--- a/xen/include/asm-x86/msr-index.h
|
||||
+++ b/xen/include/asm-x86/msr-index.h
|
||||
@@ -179,6 +179,9 @@
|
||||
#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x490
|
||||
#define MSR_IA32_VMX_VMFUNC 0x491
|
||||
|
||||
+#define MSR_MCU_OPT_CTRL 0x00000123
|
||||
+#define MCU_OPT_CTRL_RNGDS_MITG_DIS (_AC(1, ULL) << 0)
|
||||
+
|
||||
#define MSR_U_CET 0x000006a0
|
||||
#define MSR_S_CET 0x000006a2
|
||||
#define MSR_PL0_SSP 0x000006a4
|
||||
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
index 2835688f1c..a2482c3627 100644
|
||||
--- a/xen/include/public/arch-x86/cpufeatureset.h
|
||||
+++ b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
@@ -252,6 +252,7 @@ XEN_CPUFEATURE(IBPB, 8*32+12) /*A IBPB support only (no IBRS, used by
|
||||
/* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
|
||||
XEN_CPUFEATURE(AVX512_4VNNIW, 9*32+ 2) /*A AVX512 Neural Network Instructions */
|
||||
XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single Precision */
|
||||
+XEN_CPUFEATURE(SRBDS_CTRL, 9*32+ 9) /* MSR_MCU_OPT_CTRL and RNGDS_MITG_DIS. */
|
||||
XEN_CPUFEATURE(MD_CLEAR, 9*32+10) /*A VERW clears microarchitectural buffers */
|
||||
XEN_CPUFEATURE(TSX_FORCE_ABORT, 9*32+13) /* MSR_TSX_FORCE_ABORT.RTM_ABORT */
|
||||
XEN_CPUFEATURE(CET_IBT, 9*32+20) /* CET - Indirect Branch Tracking */
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/spec-ctrl: Mitigate the Special Register Buffer Data Sampling sidechannel
|
||||
|
||||
See patch documentation and comments.
|
||||
|
||||
This is part of XSA-320 / CVE-2020-0543
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
|
||||
index 9268454297..c780312531 100644
|
||||
--- a/docs/misc/xen-command-line.pandoc
|
||||
+++ b/docs/misc/xen-command-line.pandoc
|
||||
@@ -1991,7 +1991,7 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).
|
||||
### spec-ctrl (x86)
|
||||
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb,md-clear}=<bool>,
|
||||
> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu,
|
||||
-> l1d-flush,branch-harden}=<bool> ]`
|
||||
+> l1d-flush,branch-harden,srb-lock}=<bool> ]`
|
||||
|
||||
Controls for speculative execution sidechannel mitigations. By default, Xen
|
||||
will pick the most appropriate mitigations based on compiled in support,
|
||||
@@ -2068,6 +2068,12 @@ If Xen is compiled with `CONFIG_SPECULATIVE_HARDEN_BRANCH`, the
|
||||
speculation barriers to protect selected conditional branches. By default,
|
||||
Xen will enable this mitigation.
|
||||
|
||||
+On hardware supporting SRBDS_CTRL, the `srb-lock=` option can be used to force
|
||||
+or prevent Xen from protect the Special Register Buffer from leaking stale
|
||||
+data. By default, Xen will enable this mitigation, except on parts where MDS
|
||||
+is fixed and TAA is fixed/mitigated (in which case, there is believed to be no
|
||||
+way for an attacker to obtain the stale data).
|
||||
+
|
||||
### sync_console
|
||||
> `= <boolean>`
|
||||
|
||||
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
|
||||
index feb0f6ce20..75c6e34164 100644
|
||||
--- a/xen/arch/x86/acpi/power.c
|
||||
+++ b/xen/arch/x86/acpi/power.c
|
||||
@@ -295,6 +295,9 @@ static int enter_state(u32 state)
|
||||
ci->spec_ctrl_flags |= (default_spec_ctrl_flags & SCF_ist_wrmsr);
|
||||
spec_ctrl_exit_idle(ci);
|
||||
|
||||
+ if ( boot_cpu_has(X86_FEATURE_SRBDS_CTRL) )
|
||||
+ wrmsrl(MSR_MCU_OPT_CTRL, default_xen_mcu_opt_ctrl);
|
||||
+
|
||||
done:
|
||||
spin_debug_enable();
|
||||
local_irq_restore(flags);
|
||||
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
|
||||
index dc8fdac1a1..b1e51b3aff 100644
|
||||
--- a/xen/arch/x86/smpboot.c
|
||||
+++ b/xen/arch/x86/smpboot.c
|
||||
@@ -361,12 +361,14 @@ void start_secondary(void *unused)
|
||||
microcode_update_one(false);
|
||||
|
||||
/*
|
||||
- * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard
|
||||
- * any firmware settings. Note: MSR_SPEC_CTRL may only become available
|
||||
- * after loading microcode.
|
||||
+ * If any speculative control MSRs are available, apply Xen's default
|
||||
+ * settings. Note: These MSRs may only become available after loading
|
||||
+ * microcode.
|
||||
*/
|
||||
if ( boot_cpu_has(X86_FEATURE_IBRSB) )
|
||||
wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl);
|
||||
+ if ( boot_cpu_has(X86_FEATURE_SRBDS_CTRL) )
|
||||
+ wrmsrl(MSR_MCU_OPT_CTRL, default_xen_mcu_opt_ctrl);
|
||||
|
||||
tsx_init(); /* Needs microcode. May change HLE/RTM feature bits. */
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 5fc1c6827e..33343062a7 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -65,6 +65,9 @@ static unsigned int __initdata l1d_maxphysaddr;
|
||||
static bool __initdata cpu_has_bug_msbds_only; /* => minimal HT impact. */
|
||||
static bool __initdata cpu_has_bug_mds; /* Any other M{LP,SB,FB}DS combination. */
|
||||
|
||||
+static int8_t __initdata opt_srb_lock = -1;
|
||||
+uint64_t __read_mostly default_xen_mcu_opt_ctrl;
|
||||
+
|
||||
static int __init parse_spec_ctrl(const char *s)
|
||||
{
|
||||
const char *ss;
|
||||
@@ -112,6 +115,7 @@ static int __init parse_spec_ctrl(const char *s)
|
||||
opt_ssbd = false;
|
||||
opt_l1d_flush = 0;
|
||||
opt_branch_harden = false;
|
||||
+ opt_srb_lock = 0;
|
||||
}
|
||||
else if ( val > 0 )
|
||||
rc = -EINVAL;
|
||||
@@ -178,6 +182,8 @@ static int __init parse_spec_ctrl(const char *s)
|
||||
opt_l1d_flush = val;
|
||||
else if ( (val = parse_boolean("branch-harden", s, ss)) >= 0 )
|
||||
opt_branch_harden = val;
|
||||
+ else if ( (val = parse_boolean("srb-lock", s, ss)) >= 0 )
|
||||
+ opt_srb_lock = val;
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
@@ -341,7 +347,7 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
"\n");
|
||||
|
||||
/* Settings for Xen's protection, irrespective of guests. */
|
||||
- printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s, Other:%s%s%s%s\n",
|
||||
+ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s, Other:%s%s%s%s%s\n",
|
||||
thunk == THUNK_NONE ? "N/A" :
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
@@ -352,6 +358,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
(default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-",
|
||||
!(caps & ARCH_CAPS_TSX_CTRL) ? "" :
|
||||
(opt_tsx & 1) ? " TSX+" : " TSX-",
|
||||
+ !boot_cpu_has(X86_FEATURE_SRBDS_CTRL) ? "" :
|
||||
+ opt_srb_lock ? " SRB_LOCK+" : " SRB_LOCK-",
|
||||
opt_ibpb ? " IBPB" : "",
|
||||
opt_l1d_flush ? " L1D_FLUSH" : "",
|
||||
opt_md_clear_pv || opt_md_clear_hvm ? " VERW" : "",
|
||||
@@ -1149,6 +1157,34 @@ void __init init_speculation_mitigations(void)
|
||||
tsx_init();
|
||||
}
|
||||
|
||||
+ /* Calculate suitable defaults for MSR_MCU_OPT_CTRL */
|
||||
+ if ( boot_cpu_has(X86_FEATURE_SRBDS_CTRL) )
|
||||
+ {
|
||||
+ uint64_t val;
|
||||
+
|
||||
+ rdmsrl(MSR_MCU_OPT_CTRL, val);
|
||||
+
|
||||
+ /*
|
||||
+ * On some SRBDS-affected hardware, it may be safe to relax srb-lock
|
||||
+ * by default.
|
||||
+ *
|
||||
+ * On parts which enumerate MDS_NO and not TAA_NO, TSX is the only way
|
||||
+ * to access the Fill Buffer. If TSX isn't available (inc. SKU
|
||||
+ * reasons on some models), or TSX is explicitly disabled, then there
|
||||
+ * is no need for the extra overhead to protect RDRAND/RDSEED.
|
||||
+ */
|
||||
+ if ( opt_srb_lock == -1 &&
|
||||
+ (caps & (ARCH_CAPS_MDS_NO|ARCH_CAPS_TAA_NO)) == ARCH_CAPS_MDS_NO &&
|
||||
+ (!cpu_has_hle || ((caps & ARCH_CAPS_TSX_CTRL) && opt_tsx == 0)) )
|
||||
+ opt_srb_lock = 0;
|
||||
+
|
||||
+ val &= ~MCU_OPT_CTRL_RNGDS_MITG_DIS;
|
||||
+ if ( !opt_srb_lock )
|
||||
+ val |= MCU_OPT_CTRL_RNGDS_MITG_DIS;
|
||||
+
|
||||
+ default_xen_mcu_opt_ctrl = val;
|
||||
+ }
|
||||
+
|
||||
print_details(thunk, caps);
|
||||
|
||||
/*
|
||||
@@ -1180,6 +1216,9 @@ void __init init_speculation_mitigations(void)
|
||||
|
||||
wrmsrl(MSR_SPEC_CTRL, bsp_delay_spec_ctrl ? 0 : default_xen_spec_ctrl);
|
||||
}
|
||||
+
|
||||
+ if ( boot_cpu_has(X86_FEATURE_SRBDS_CTRL) )
|
||||
+ wrmsrl(MSR_MCU_OPT_CTRL, default_xen_mcu_opt_ctrl);
|
||||
}
|
||||
|
||||
static void __init __maybe_unused build_assertions(void)
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 9caecddfec..b252bb8631 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -54,6 +54,8 @@ extern int8_t opt_pv_l1tf_hwdom, opt_pv_l1tf_domu;
|
||||
*/
|
||||
extern paddr_t l1tf_addr_mask, l1tf_safe_maddr;
|
||||
|
||||
+extern uint64_t default_xen_mcu_opt_ctrl;
|
||||
+
|
||||
static inline void init_shadow_spec_ctrl_state(void)
|
||||
{
|
||||
struct cpu_info *info = get_cpu_info();
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: vtd: improve IOMMU TLB flush
|
||||
|
||||
Do not limit PSI flushes to order 0 pages, in order to avoid doing a
|
||||
full TLB flush if the passed in page has an order greater than 0 and
|
||||
is aligned. Should increase the performance of IOMMU TLB flushes when
|
||||
dealing with page orders greater than 0.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -570,13 +570,14 @@ static int __must_check iommu_flush_iotl
|
||||
if ( iommu_domid == -1 )
|
||||
continue;
|
||||
|
||||
- if ( page_count != 1 || dfn_eq(dfn, INVALID_DFN) )
|
||||
+ if ( !page_count || (page_count & (page_count - 1)) ||
|
||||
+ dfn_eq(dfn, INVALID_DFN) || !IS_ALIGNED(dfn_x(dfn), page_count) )
|
||||
rc = iommu_flush_iotlb_dsi(iommu, iommu_domid,
|
||||
0, flush_dev_iotlb);
|
||||
else
|
||||
rc = iommu_flush_iotlb_psi(iommu, iommu_domid,
|
||||
dfn_to_daddr(dfn),
|
||||
- PAGE_ORDER_4K,
|
||||
+ get_order_from_pages(page_count),
|
||||
!dma_old_pte_present,
|
||||
flush_dev_iotlb);
|
||||
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: vtd: prune (and rename) cache flush functions
|
||||
|
||||
Rename __iommu_flush_cache to iommu_sync_cache and remove
|
||||
iommu_flush_cache_page. Also remove the iommu_flush_cache_entry
|
||||
wrapper and just use iommu_sync_cache instead. Note the _entry suffix
|
||||
was meaningless as the wrapper was already taking a size parameter in
|
||||
bytes. While there also constify the addr parameter.
|
||||
|
||||
No functional change intended.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/extern.h
|
||||
+++ b/xen/drivers/passthrough/vtd/extern.h
|
||||
@@ -43,8 +43,7 @@ void disable_qinval(struct vtd_iommu *io
|
||||
int enable_intremap(struct vtd_iommu *iommu, int eim);
|
||||
void disable_intremap(struct vtd_iommu *iommu);
|
||||
|
||||
-void iommu_flush_cache_entry(void *addr, unsigned int size);
|
||||
-void iommu_flush_cache_page(void *addr, unsigned long npages);
|
||||
+void iommu_sync_cache(const void *addr, unsigned int size);
|
||||
int iommu_alloc(struct acpi_drhd_unit *drhd);
|
||||
void iommu_free(struct acpi_drhd_unit *drhd);
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/intremap.c
|
||||
+++ b/xen/drivers/passthrough/vtd/intremap.c
|
||||
@@ -230,7 +230,7 @@ static void free_remap_entry(struct vtd_
|
||||
iremap_entries, iremap_entry);
|
||||
|
||||
update_irte(iommu, iremap_entry, &new_ire, false);
|
||||
- iommu_flush_cache_entry(iremap_entry, sizeof(*iremap_entry));
|
||||
+ iommu_sync_cache(iremap_entry, sizeof(*iremap_entry));
|
||||
iommu_flush_iec_index(iommu, 0, index);
|
||||
|
||||
unmap_vtd_domain_page(iremap_entries);
|
||||
@@ -406,7 +406,7 @@ static int ioapic_rte_to_remap_entry(str
|
||||
}
|
||||
|
||||
update_irte(iommu, iremap_entry, &new_ire, !init);
|
||||
- iommu_flush_cache_entry(iremap_entry, sizeof(*iremap_entry));
|
||||
+ iommu_sync_cache(iremap_entry, sizeof(*iremap_entry));
|
||||
iommu_flush_iec_index(iommu, 0, index);
|
||||
|
||||
unmap_vtd_domain_page(iremap_entries);
|
||||
@@ -695,7 +695,7 @@ static int msi_msg_to_remap_entry(
|
||||
update_irte(iommu, iremap_entry, &new_ire, msi_desc->irte_initialized);
|
||||
msi_desc->irte_initialized = true;
|
||||
|
||||
- iommu_flush_cache_entry(iremap_entry, sizeof(*iremap_entry));
|
||||
+ iommu_sync_cache(iremap_entry, sizeof(*iremap_entry));
|
||||
iommu_flush_iec_index(iommu, 0, index);
|
||||
|
||||
unmap_vtd_domain_page(iremap_entries);
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -140,7 +140,8 @@ static int context_get_domain_id(struct
|
||||
}
|
||||
|
||||
static int iommus_incoherent;
|
||||
-static void __iommu_flush_cache(void *addr, unsigned int size)
|
||||
+
|
||||
+void iommu_sync_cache(const void *addr, unsigned int size)
|
||||
{
|
||||
int i;
|
||||
static unsigned int clflush_size = 0;
|
||||
@@ -155,16 +156,6 @@ static void __iommu_flush_cache(void *ad
|
||||
cacheline_flush((char *)addr + i);
|
||||
}
|
||||
|
||||
-void iommu_flush_cache_entry(void *addr, unsigned int size)
|
||||
-{
|
||||
- __iommu_flush_cache(addr, size);
|
||||
-}
|
||||
-
|
||||
-void iommu_flush_cache_page(void *addr, unsigned long npages)
|
||||
-{
|
||||
- __iommu_flush_cache(addr, PAGE_SIZE * npages);
|
||||
-}
|
||||
-
|
||||
/* Allocate page table, return its machine address */
|
||||
uint64_t alloc_pgtable_maddr(unsigned long npages, nodeid_t node)
|
||||
{
|
||||
@@ -183,7 +174,7 @@ uint64_t alloc_pgtable_maddr(unsigned lo
|
||||
vaddr = __map_domain_page(cur_pg);
|
||||
memset(vaddr, 0, PAGE_SIZE);
|
||||
|
||||
- iommu_flush_cache_page(vaddr, 1);
|
||||
+ iommu_sync_cache(vaddr, PAGE_SIZE);
|
||||
unmap_domain_page(vaddr);
|
||||
cur_pg++;
|
||||
}
|
||||
@@ -216,7 +207,7 @@ static u64 bus_to_context_maddr(struct v
|
||||
}
|
||||
set_root_value(*root, maddr);
|
||||
set_root_present(*root);
|
||||
- iommu_flush_cache_entry(root, sizeof(struct root_entry));
|
||||
+ iommu_sync_cache(root, sizeof(struct root_entry));
|
||||
}
|
||||
maddr = (u64) get_context_addr(*root);
|
||||
unmap_vtd_domain_page(root_entries);
|
||||
@@ -263,7 +254,7 @@ static u64 addr_to_dma_page_maddr(struct
|
||||
*/
|
||||
dma_set_pte_readable(*pte);
|
||||
dma_set_pte_writable(*pte);
|
||||
- iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
|
||||
+ iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
}
|
||||
|
||||
if ( level == 2 )
|
||||
@@ -640,7 +631,7 @@ static int __must_check dma_pte_clear_on
|
||||
*flush_flags |= IOMMU_FLUSHF_modified;
|
||||
|
||||
spin_unlock(&hd->arch.mapping_lock);
|
||||
- iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
|
||||
+ iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
|
||||
unmap_vtd_domain_page(page);
|
||||
|
||||
@@ -679,7 +670,7 @@ static void iommu_free_page_table(struct
|
||||
iommu_free_pagetable(dma_pte_addr(*pte), next_level);
|
||||
|
||||
dma_clear_pte(*pte);
|
||||
- iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
|
||||
+ iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
}
|
||||
|
||||
unmap_vtd_domain_page(pt_vaddr);
|
||||
@@ -1400,7 +1391,7 @@ int domain_context_mapping_one(
|
||||
context_set_address_width(*context, agaw);
|
||||
context_set_fault_enable(*context);
|
||||
context_set_present(*context);
|
||||
- iommu_flush_cache_entry(context, sizeof(struct context_entry));
|
||||
+ iommu_sync_cache(context, sizeof(struct context_entry));
|
||||
spin_unlock(&iommu->lock);
|
||||
|
||||
/* Context entry was previously non-present (with domid 0). */
|
||||
@@ -1564,7 +1555,7 @@ int domain_context_unmap_one(
|
||||
|
||||
context_clear_present(*context);
|
||||
context_clear_entry(*context);
|
||||
- iommu_flush_cache_entry(context, sizeof(struct context_entry));
|
||||
+ iommu_sync_cache(context, sizeof(struct context_entry));
|
||||
|
||||
iommu_domid= domain_iommu_domid(domain, iommu);
|
||||
if ( iommu_domid == -1 )
|
||||
@@ -1791,7 +1782,7 @@ static int __must_check intel_iommu_map_
|
||||
|
||||
*pte = new;
|
||||
|
||||
- iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
|
||||
+ iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
spin_unlock(&hd->arch.mapping_lock);
|
||||
unmap_vtd_domain_page(page);
|
||||
|
||||
@@ -1866,7 +1857,7 @@ int iommu_pte_flush(struct domain *d, ui
|
||||
int iommu_domid;
|
||||
int rc = 0;
|
||||
|
||||
- iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
|
||||
+ iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
|
||||
for_each_drhd_unit ( drhd )
|
||||
{
|
||||
@@ -2724,7 +2715,7 @@ static int __init intel_iommu_quarantine
|
||||
dma_set_pte_addr(*pte, maddr);
|
||||
dma_set_pte_readable(*pte);
|
||||
}
|
||||
- iommu_flush_cache_page(parent, 1);
|
||||
+ iommu_sync_cache(parent, PAGE_SIZE);
|
||||
|
||||
unmap_vtd_domain_page(parent);
|
||||
parent = map_vtd_domain_page(maddr);
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: x86/iommu: introduce a cache sync hook
|
||||
|
||||
The hook is only implemented for VT-d and it uses the already existing
|
||||
iommu_sync_cache function present in VT-d code. The new hook is
|
||||
added so that the cache can be flushed by code outside of VT-d when
|
||||
using shared page tables.
|
||||
|
||||
Note that alloc_pgtable_maddr must use the now locally defined
|
||||
sync_cache function, because IOMMU ops are not yet setup the first
|
||||
time the function gets called during IOMMU initialization.
|
||||
|
||||
No functional change intended.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/extern.h
|
||||
+++ b/xen/drivers/passthrough/vtd/extern.h
|
||||
@@ -43,7 +43,6 @@ void disable_qinval(struct vtd_iommu *io
|
||||
int enable_intremap(struct vtd_iommu *iommu, int eim);
|
||||
void disable_intremap(struct vtd_iommu *iommu);
|
||||
|
||||
-void iommu_sync_cache(const void *addr, unsigned int size);
|
||||
int iommu_alloc(struct acpi_drhd_unit *drhd);
|
||||
void iommu_free(struct acpi_drhd_unit *drhd);
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -141,7 +141,7 @@ static int context_get_domain_id(struct
|
||||
|
||||
static int iommus_incoherent;
|
||||
|
||||
-void iommu_sync_cache(const void *addr, unsigned int size)
|
||||
+static void sync_cache(const void *addr, unsigned int size)
|
||||
{
|
||||
int i;
|
||||
static unsigned int clflush_size = 0;
|
||||
@@ -174,7 +174,7 @@ uint64_t alloc_pgtable_maddr(unsigned lo
|
||||
vaddr = __map_domain_page(cur_pg);
|
||||
memset(vaddr, 0, PAGE_SIZE);
|
||||
|
||||
- iommu_sync_cache(vaddr, PAGE_SIZE);
|
||||
+ sync_cache(vaddr, PAGE_SIZE);
|
||||
unmap_domain_page(vaddr);
|
||||
cur_pg++;
|
||||
}
|
||||
@@ -2763,6 +2763,7 @@ const struct iommu_ops __initconstrel in
|
||||
.iotlb_flush_all = iommu_flush_iotlb_all,
|
||||
.get_reserved_device_memory = intel_iommu_get_reserved_device_memory,
|
||||
.dump_p2m_table = vtd_dump_p2m_table,
|
||||
+ .sync_cache = sync_cache,
|
||||
};
|
||||
|
||||
const struct iommu_init_ops __initconstrel intel_iommu_init_ops = {
|
||||
--- a/xen/include/asm-x86/iommu.h
|
||||
+++ b/xen/include/asm-x86/iommu.h
|
||||
@@ -121,6 +121,13 @@ extern bool untrusted_msi;
|
||||
int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
|
||||
const uint8_t gvec);
|
||||
|
||||
+#define iommu_sync_cache(addr, size) ({ \
|
||||
+ const struct iommu_ops *ops = iommu_get_ops(); \
|
||||
+ \
|
||||
+ if ( ops->sync_cache ) \
|
||||
+ iommu_vcall(ops, sync_cache, addr, size); \
|
||||
+})
|
||||
+
|
||||
#endif /* !__ARCH_X86_IOMMU_H__ */
|
||||
/*
|
||||
* Local variables:
|
||||
--- a/xen/include/xen/iommu.h
|
||||
+++ b/xen/include/xen/iommu.h
|
||||
@@ -250,6 +250,7 @@ struct iommu_ops {
|
||||
int (*setup_hpet_msi)(struct msi_desc *);
|
||||
|
||||
int (*adjust_irq_affinities)(void);
|
||||
+ void (*sync_cache)(const void *addr, unsigned int size);
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
int __must_check (*suspend)(void);
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: vtd: don't assume addresses are aligned in sync_cache
|
||||
|
||||
Current code in sync_cache assume that the address passed in is
|
||||
aligned to a cache line size. Fix the code to support passing in
|
||||
arbitrary addresses not necessarily aligned to a cache line size.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -143,8 +143,8 @@ static int iommus_incoherent;
|
||||
|
||||
static void sync_cache(const void *addr, unsigned int size)
|
||||
{
|
||||
- int i;
|
||||
- static unsigned int clflush_size = 0;
|
||||
+ static unsigned long clflush_size = 0;
|
||||
+ const void *end = addr + size;
|
||||
|
||||
if ( !iommus_incoherent )
|
||||
return;
|
||||
@@ -152,8 +152,9 @@ static void sync_cache(const void *addr,
|
||||
if ( clflush_size == 0 )
|
||||
clflush_size = get_cache_line_size();
|
||||
|
||||
- for ( i = 0; i < size; i += clflush_size )
|
||||
- cacheline_flush((char *)addr + i);
|
||||
+ addr -= (unsigned long)addr & (clflush_size - 1);
|
||||
+ for ( ; addr < end; addr += clflush_size )
|
||||
+ cacheline_flush((char *)addr);
|
||||
}
|
||||
|
||||
/* Allocate page table, return its machine address */
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: x86/alternative: introduce alternative_2
|
||||
|
||||
It's based on alternative_io_2 without inputs or outputs but with an
|
||||
added memory clobber.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Acked-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/include/asm-x86/alternative.h
|
||||
+++ b/xen/include/asm-x86/alternative.h
|
||||
@@ -114,6 +114,11 @@ extern void alternative_branches(void);
|
||||
#define alternative(oldinstr, newinstr, feature) \
|
||||
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory")
|
||||
|
||||
+#define alternative_2(oldinstr, newinstr1, feature1, newinstr2, feature2) \
|
||||
+ asm volatile (ALTERNATIVE_2(oldinstr, newinstr1, feature1, \
|
||||
+ newinstr2, feature2) \
|
||||
+ : : : "memory")
|
||||
+
|
||||
/*
|
||||
* Alternative inline assembly with input.
|
||||
*
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: vtd: optimize CPU cache sync
|
||||
|
||||
Some VT-d IOMMUs are non-coherent, which requires a cache write back
|
||||
in order for the changes made by the CPU to be visible to the IOMMU.
|
||||
This cache write back was unconditionally done using clflush, but there are
|
||||
other more efficient instructions to do so, hence implement support
|
||||
for them using the alternative framework.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/extern.h
|
||||
+++ b/xen/drivers/passthrough/vtd/extern.h
|
||||
@@ -68,7 +68,6 @@ int __must_check qinval_device_iotlb_syn
|
||||
u16 did, u16 size, u64 addr);
|
||||
|
||||
unsigned int get_cache_line_size(void);
|
||||
-void cacheline_flush(char *);
|
||||
void flush_all_cache(void);
|
||||
|
||||
uint64_t alloc_pgtable_maddr(unsigned long npages, nodeid_t node);
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <xen/pci_regs.h>
|
||||
#include <xen/keyhandler.h>
|
||||
#include <asm/msi.h>
|
||||
+#include <asm/nops.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hvm/vmx/vmx.h>
|
||||
#include <asm/p2m.h>
|
||||
@@ -154,7 +155,42 @@ static void sync_cache(const void *addr,
|
||||
|
||||
addr -= (unsigned long)addr & (clflush_size - 1);
|
||||
for ( ; addr < end; addr += clflush_size )
|
||||
- cacheline_flush((char *)addr);
|
||||
+/*
|
||||
+ * The arguments to a macro must not include preprocessor directives. Doing so
|
||||
+ * results in undefined behavior, so we have to create some defines here in
|
||||
+ * order to avoid it.
|
||||
+ */
|
||||
+#if defined(HAVE_AS_CLWB)
|
||||
+# define CLWB_ENCODING "clwb %[p]"
|
||||
+#elif defined(HAVE_AS_XSAVEOPT)
|
||||
+# define CLWB_ENCODING "data16 xsaveopt %[p]" /* clwb */
|
||||
+#else
|
||||
+# define CLWB_ENCODING ".byte 0x66, 0x0f, 0xae, 0x30" /* clwb (%%rax) */
|
||||
+#endif
|
||||
+
|
||||
+#define BASE_INPUT(addr) [p] "m" (*(const char *)(addr))
|
||||
+#if defined(HAVE_AS_CLWB) || defined(HAVE_AS_XSAVEOPT)
|
||||
+# define INPUT BASE_INPUT
|
||||
+#else
|
||||
+# define INPUT(addr) "a" (addr), BASE_INPUT(addr)
|
||||
+#endif
|
||||
+ /*
|
||||
+ * Note regarding the use of NOP_DS_PREFIX: it's faster to do a clflush
|
||||
+ * + prefix than a clflush + nop, and hence the prefix is added instead
|
||||
+ * of letting the alternative framework fill the gap by appending nops.
|
||||
+ */
|
||||
+ alternative_io_2(".byte " __stringify(NOP_DS_PREFIX) "; clflush %[p]",
|
||||
+ "data16 clflush %[p]", /* clflushopt */
|
||||
+ X86_FEATURE_CLFLUSHOPT,
|
||||
+ CLWB_ENCODING,
|
||||
+ X86_FEATURE_CLWB, /* no outputs */,
|
||||
+ INPUT(addr));
|
||||
+#undef INPUT
|
||||
+#undef BASE_INPUT
|
||||
+#undef CLWB_ENCODING
|
||||
+
|
||||
+ alternative_2("", "sfence", X86_FEATURE_CLFLUSHOPT,
|
||||
+ "sfence", X86_FEATURE_CLWB);
|
||||
}
|
||||
|
||||
/* Allocate page table, return its machine address */
|
||||
--- a/xen/drivers/passthrough/vtd/x86/vtd.c
|
||||
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c
|
||||
@@ -51,11 +51,6 @@ unsigned int get_cache_line_size(void)
|
||||
return ((cpuid_ebx(1) >> 8) & 0xff) * 8;
|
||||
}
|
||||
|
||||
-void cacheline_flush(char * addr)
|
||||
-{
|
||||
- clflush(addr);
|
||||
-}
|
||||
-
|
||||
void flush_all_cache()
|
||||
{
|
||||
wbinvd();
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: x86/ept: flush cache when modifying PTEs and sharing page tables
|
||||
|
||||
Modifications made to the page tables by EPT code need to be written
|
||||
to memory when the page tables are shared with the IOMMU, as Intel
|
||||
IOMMUs can be non-coherent and thus require changes to be written to
|
||||
memory in order to be visible to the IOMMU.
|
||||
|
||||
In order to achieve this make sure data is written back to memory
|
||||
after writing an EPT entry when the recalc bit is not set in
|
||||
atomic_write_ept_entry. If such bit is set, the entry will be
|
||||
adjusted and atomic_write_ept_entry will be called a second time
|
||||
without the recalc bit set. Note that when splitting a super page the
|
||||
new tables resulting of the split should also be written back.
|
||||
|
||||
Failure to do so can allow devices behind the IOMMU access to the
|
||||
stale super page, or cause coherency issues as changes made by the
|
||||
processor to the page tables are not visible to the IOMMU.
|
||||
|
||||
This allows to remove the VT-d specific iommu_pte_flush helper, since
|
||||
the cache write back is now performed by atomic_write_ept_entry, and
|
||||
hence iommu_iotlb_flush can be used to flush the IOMMU TLB. The newly
|
||||
used method (iommu_iotlb_flush) can result in less flushes, since it
|
||||
might sometimes be called rightly with 0 flags, in which case it
|
||||
becomes a no-op.
|
||||
|
||||
This is part of XSA-321.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m-ept.c
|
||||
+++ b/xen/arch/x86/mm/p2m-ept.c
|
||||
@@ -58,6 +58,19 @@ static int atomic_write_ept_entry(struct
|
||||
|
||||
write_atomic(&entryptr->epte, new.epte);
|
||||
|
||||
+ /*
|
||||
+ * The recalc field on the EPT is used to signal either that a
|
||||
+ * recalculation of the EMT field is required (which doesn't effect the
|
||||
+ * IOMMU), or a type change. Type changes can only be between ram_rw,
|
||||
+ * logdirty and ioreq_server: changes to/from logdirty won't work well with
|
||||
+ * an IOMMU anyway, as IOMMU #PFs are not synchronous and will lead to
|
||||
+ * aborts, and changes to/from ioreq_server are already fully flushed
|
||||
+ * before returning to guest context (see
|
||||
+ * XEN_DMOP_map_mem_type_to_ioreq_server).
|
||||
+ */
|
||||
+ if ( !new.recalc && iommu_use_hap_pt(p2m->domain) )
|
||||
+ iommu_sync_cache(entryptr, sizeof(*entryptr));
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -278,6 +291,9 @@ static bool_t ept_split_super_page(struc
|
||||
break;
|
||||
}
|
||||
|
||||
+ if ( iommu_use_hap_pt(p2m->domain) )
|
||||
+ iommu_sync_cache(table, EPT_PAGETABLE_ENTRIES * sizeof(ept_entry_t));
|
||||
+
|
||||
unmap_domain_page(table);
|
||||
|
||||
/* Even failed we should install the newly allocated ept page. */
|
||||
@@ -337,6 +353,9 @@ static int ept_next_level(struct p2m_dom
|
||||
if ( !next )
|
||||
return GUEST_TABLE_MAP_FAILED;
|
||||
|
||||
+ if ( iommu_use_hap_pt(p2m->domain) )
|
||||
+ iommu_sync_cache(next, EPT_PAGETABLE_ENTRIES * sizeof(ept_entry_t));
|
||||
+
|
||||
rc = atomic_write_ept_entry(p2m, ept_entry, e, next_level);
|
||||
ASSERT(rc == 0);
|
||||
}
|
||||
@@ -821,7 +840,10 @@ out:
|
||||
need_modify_vtd_table )
|
||||
{
|
||||
if ( iommu_use_hap_pt(d) )
|
||||
- rc = iommu_pte_flush(d, gfn, &ept_entry->epte, order, vtd_pte_present);
|
||||
+ rc = iommu_iotlb_flush(d, _dfn(gfn), (1u << order),
|
||||
+ (iommu_flags ? IOMMU_FLUSHF_added : 0) |
|
||||
+ (vtd_pte_present ? IOMMU_FLUSHF_modified
|
||||
+ : 0));
|
||||
else if ( need_iommu_pt_sync(d) )
|
||||
rc = iommu_flags ?
|
||||
iommu_legacy_map(d, _dfn(gfn), mfn, order, iommu_flags) :
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -1884,53 +1884,6 @@ static int intel_iommu_lookup_page(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int iommu_pte_flush(struct domain *d, uint64_t dfn, uint64_t *pte,
|
||||
- int order, int present)
|
||||
-{
|
||||
- struct acpi_drhd_unit *drhd;
|
||||
- struct vtd_iommu *iommu = NULL;
|
||||
- struct domain_iommu *hd = dom_iommu(d);
|
||||
- bool_t flush_dev_iotlb;
|
||||
- int iommu_domid;
|
||||
- int rc = 0;
|
||||
-
|
||||
- iommu_sync_cache(pte, sizeof(struct dma_pte));
|
||||
-
|
||||
- for_each_drhd_unit ( drhd )
|
||||
- {
|
||||
- iommu = drhd->iommu;
|
||||
- if ( !test_bit(iommu->index, &hd->arch.iommu_bitmap) )
|
||||
- continue;
|
||||
-
|
||||
- flush_dev_iotlb = !!find_ats_dev_drhd(iommu);
|
||||
- iommu_domid= domain_iommu_domid(d, iommu);
|
||||
- if ( iommu_domid == -1 )
|
||||
- continue;
|
||||
-
|
||||
- rc = iommu_flush_iotlb_psi(iommu, iommu_domid,
|
||||
- __dfn_to_daddr(dfn),
|
||||
- order, !present, flush_dev_iotlb);
|
||||
- if ( rc > 0 )
|
||||
- {
|
||||
- iommu_flush_write_buffer(iommu);
|
||||
- rc = 0;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if ( unlikely(rc) )
|
||||
- {
|
||||
- if ( !d->is_shutting_down && printk_ratelimit() )
|
||||
- printk(XENLOG_ERR VTDPREFIX
|
||||
- " d%d: IOMMU pages flush failed: %d\n",
|
||||
- d->domain_id, rc);
|
||||
-
|
||||
- if ( !is_hardware_domain(d) )
|
||||
- domain_crash(d);
|
||||
- }
|
||||
-
|
||||
- return rc;
|
||||
-}
|
||||
-
|
||||
static int __init vtd_ept_page_compatible(struct vtd_iommu *iommu)
|
||||
{
|
||||
u64 ept_cap, vtd_cap = iommu->cap;
|
||||
--- a/xen/include/asm-x86/iommu.h
|
||||
+++ b/xen/include/asm-x86/iommu.h
|
||||
@@ -97,10 +97,6 @@ static inline int iommu_adjust_irq_affin
|
||||
: 0;
|
||||
}
|
||||
|
||||
-/* While VT-d specific, this must get declared in a generic header. */
|
||||
-int __must_check iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
|
||||
- int order, int present);
|
||||
-
|
||||
static inline bool iommu_supports_x2apic(void)
|
||||
{
|
||||
return iommu_init_ops && iommu_init_ops->supports_x2apic
|
||||
63
xsa327.patch
63
xsa327.patch
|
|
@ -1,63 +0,0 @@
|
|||
From 030300ebbb86c40c12db038714479d746167c767 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Grall <jgrall@amazon.com>
|
||||
Date: Tue, 26 May 2020 18:31:33 +0100
|
||||
Subject: [PATCH] xen: Check the alignment of the offset pased via
|
||||
VCPUOP_register_vcpu_info
|
||||
|
||||
Currently a guest is able to register any guest physical address to use
|
||||
for the vcpu_info structure as long as the structure can fits in the
|
||||
rest of the frame.
|
||||
|
||||
This means a guest can provide an address that is not aligned to the
|
||||
natural alignment of the structure.
|
||||
|
||||
On Arm 32-bit, unaligned access are completely forbidden by the
|
||||
hypervisor. This will result to a data abort which is fatal.
|
||||
|
||||
On Arm 64-bit, unaligned access are only forbidden when used for atomic
|
||||
access. As the structure contains fields (such as evtchn_pending_self)
|
||||
that are updated using atomic operations, any unaligned access will be
|
||||
fatal as well.
|
||||
|
||||
While the misalignment is only fatal on Arm, a generic check is added
|
||||
as an x86 guest shouldn't sensibly pass an unaligned address (this
|
||||
would result to a split lock).
|
||||
|
||||
This is XSA-327.
|
||||
|
||||
Reported-by: Julien Grall <jgrall@amazon.com>
|
||||
Signed-off-by: Julien Grall <jgrall@amazon.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
|
||||
---
|
||||
xen/common/domain.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/xen/common/domain.c b/xen/common/domain.c
|
||||
index 7cc9526139a6..e9be05f1d05f 100644
|
||||
--- a/xen/common/domain.c
|
||||
+++ b/xen/common/domain.c
|
||||
@@ -1227,10 +1227,20 @@ int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset)
|
||||
void *mapping;
|
||||
vcpu_info_t *new_info;
|
||||
struct page_info *page;
|
||||
+ unsigned int align;
|
||||
|
||||
if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) )
|
||||
return -EINVAL;
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if ( has_32bit_shinfo(d) )
|
||||
+ align = alignof(new_info->compat);
|
||||
+ else
|
||||
+#endif
|
||||
+ align = alignof(*new_info);
|
||||
+ if ( offset & (align - 1) )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if ( !mfn_eq(v->vcpu_info_mfn, INVALID_MFN) )
|
||||
return -EINVAL;
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/EPT: ept_set_middle_entry() related adjustments
|
||||
|
||||
ept_split_super_page() wants to further modify the newly allocated
|
||||
table, so have ept_set_middle_entry() return the mapped pointer rather
|
||||
than tearing it down and then getting re-established right again.
|
||||
|
||||
Similarly ept_next_level() wants to hand back a mapped pointer of
|
||||
the next level page, so re-use the one established by
|
||||
ept_set_middle_entry() in case that path was taken.
|
||||
|
||||
Pull the setting of suppress_ve ahead of insertion into the higher level
|
||||
table, and don't have ept_split_super_page() set the field a 2nd time.
|
||||
|
||||
This is part of XSA-328.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m-ept.c
|
||||
+++ b/xen/arch/x86/mm/p2m-ept.c
|
||||
@@ -187,8 +187,9 @@ static void ept_p2m_type_to_flags(struct
|
||||
#define GUEST_TABLE_SUPER_PAGE 2
|
||||
#define GUEST_TABLE_POD_PAGE 3
|
||||
|
||||
-/* Fill in middle levels of ept table */
|
||||
-static int ept_set_middle_entry(struct p2m_domain *p2m, ept_entry_t *ept_entry)
|
||||
+/* Fill in middle level of ept table; return pointer to mapped new table. */
|
||||
+static ept_entry_t *ept_set_middle_entry(struct p2m_domain *p2m,
|
||||
+ ept_entry_t *ept_entry)
|
||||
{
|
||||
mfn_t mfn;
|
||||
ept_entry_t *table;
|
||||
@@ -196,7 +197,12 @@ static int ept_set_middle_entry(struct p
|
||||
|
||||
mfn = p2m_alloc_ptp(p2m, 0);
|
||||
if ( mfn_eq(mfn, INVALID_MFN) )
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
+
|
||||
+ table = map_domain_page(mfn);
|
||||
+
|
||||
+ for ( i = 0; i < EPT_PAGETABLE_ENTRIES; i++ )
|
||||
+ table[i].suppress_ve = 1;
|
||||
|
||||
ept_entry->epte = 0;
|
||||
ept_entry->mfn = mfn_x(mfn);
|
||||
@@ -208,14 +214,7 @@ static int ept_set_middle_entry(struct p
|
||||
|
||||
ept_entry->suppress_ve = 1;
|
||||
|
||||
- table = map_domain_page(mfn);
|
||||
-
|
||||
- for ( i = 0; i < EPT_PAGETABLE_ENTRIES; i++ )
|
||||
- table[i].suppress_ve = 1;
|
||||
-
|
||||
- unmap_domain_page(table);
|
||||
-
|
||||
- return 1;
|
||||
+ return table;
|
||||
}
|
||||
|
||||
/* free ept sub tree behind an entry */
|
||||
@@ -253,10 +252,10 @@ static bool_t ept_split_super_page(struc
|
||||
|
||||
ASSERT(is_epte_superpage(ept_entry));
|
||||
|
||||
- if ( !ept_set_middle_entry(p2m, &new_ept) )
|
||||
+ table = ept_set_middle_entry(p2m, &new_ept);
|
||||
+ if ( !table )
|
||||
return 0;
|
||||
|
||||
- table = map_domain_page(_mfn(new_ept.mfn));
|
||||
trunk = 1UL << ((level - 1) * EPT_TABLE_ORDER);
|
||||
|
||||
for ( i = 0; i < EPT_PAGETABLE_ENTRIES; i++ )
|
||||
@@ -267,7 +266,6 @@ static bool_t ept_split_super_page(struc
|
||||
epte->sp = (level > 1);
|
||||
epte->mfn += i * trunk;
|
||||
epte->snp = is_iommu_enabled(p2m->domain) && iommu_snoop;
|
||||
- epte->suppress_ve = 1;
|
||||
|
||||
ept_p2m_type_to_flags(p2m, epte, epte->sa_p2mt, epte->access);
|
||||
|
||||
@@ -306,8 +304,7 @@ static int ept_next_level(struct p2m_dom
|
||||
ept_entry_t **table, unsigned long *gfn_remainder,
|
||||
int next_level)
|
||||
{
|
||||
- unsigned long mfn;
|
||||
- ept_entry_t *ept_entry, e;
|
||||
+ ept_entry_t *ept_entry, *next = NULL, e;
|
||||
u32 shift, index;
|
||||
|
||||
shift = next_level * EPT_TABLE_ORDER;
|
||||
@@ -332,19 +329,17 @@ static int ept_next_level(struct p2m_dom
|
||||
if ( read_only )
|
||||
return GUEST_TABLE_MAP_FAILED;
|
||||
|
||||
- if ( !ept_set_middle_entry(p2m, ept_entry) )
|
||||
+ next = ept_set_middle_entry(p2m, ept_entry);
|
||||
+ if ( !next )
|
||||
return GUEST_TABLE_MAP_FAILED;
|
||||
- else
|
||||
- e = atomic_read_ept_entry(ept_entry); /* Refresh */
|
||||
+ /* e is now stale and hence may not be used anymore below. */
|
||||
}
|
||||
-
|
||||
/* The only time sp would be set here is if we had hit a superpage */
|
||||
- if ( is_epte_superpage(&e) )
|
||||
+ else if ( is_epte_superpage(&e) )
|
||||
return GUEST_TABLE_SUPER_PAGE;
|
||||
|
||||
- mfn = e.mfn;
|
||||
unmap_domain_page(*table);
|
||||
- *table = map_domain_page(_mfn(mfn));
|
||||
+ *table = next ?: map_domain_page(_mfn(e.mfn));
|
||||
*gfn_remainder &= (1UL << shift) - 1;
|
||||
return GUEST_TABLE_NORMAL_PAGE;
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From: <security@xenproject.org>
|
||||
Subject: x86/ept: atomically modify entries in ept_next_level
|
||||
|
||||
ept_next_level was passing a live PTE pointer to ept_set_middle_entry,
|
||||
which was then modified without taking into account that the PTE could
|
||||
be part of a live EPT table. This wasn't a security issue because the
|
||||
pages returned by p2m_alloc_ptp are zeroed, so adding such an entry
|
||||
before actually initializing it didn't allow a guest to access
|
||||
physical memory addresses it wasn't supposed to access.
|
||||
|
||||
This is part of XSA-328.
|
||||
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m-ept.c
|
||||
+++ b/xen/arch/x86/mm/p2m-ept.c
|
||||
@@ -307,6 +307,8 @@ static int ept_next_level(struct p2m_dom
|
||||
ept_entry_t *ept_entry, *next = NULL, e;
|
||||
u32 shift, index;
|
||||
|
||||
+ ASSERT(next_level);
|
||||
+
|
||||
shift = next_level * EPT_TABLE_ORDER;
|
||||
|
||||
index = *gfn_remainder >> shift;
|
||||
@@ -323,16 +325,20 @@ static int ept_next_level(struct p2m_dom
|
||||
|
||||
if ( !is_epte_present(&e) )
|
||||
{
|
||||
+ int rc;
|
||||
+
|
||||
if ( e.sa_p2mt == p2m_populate_on_demand )
|
||||
return GUEST_TABLE_POD_PAGE;
|
||||
|
||||
if ( read_only )
|
||||
return GUEST_TABLE_MAP_FAILED;
|
||||
|
||||
- next = ept_set_middle_entry(p2m, ept_entry);
|
||||
+ next = ept_set_middle_entry(p2m, &e);
|
||||
if ( !next )
|
||||
return GUEST_TABLE_MAP_FAILED;
|
||||
- /* e is now stale and hence may not be used anymore below. */
|
||||
+
|
||||
+ rc = atomic_write_ept_entry(p2m, ept_entry, e, next_level);
|
||||
+ ASSERT(rc == 0);
|
||||
}
|
||||
/* The only time sp would be set here is if we had hit a superpage */
|
||||
else if ( is_epte_superpage(&e) )
|
||||
22
xsa363.patch
Normal file
22
xsa363.patch
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: SUPPORT.md: PV display frontend is unsupported in "backend allocation" mode
|
||||
|
||||
This wasn't meant to be supported, but wasn't stated this way.
|
||||
|
||||
This is XSA-363.
|
||||
|
||||
Reported-by: Jan Belich <jbeulich@suse.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/SUPPORT.md
|
||||
+++ b/SUPPORT.md
|
||||
@@ -414,7 +414,8 @@ Guest-side driver capable of speaking th
|
||||
|
||||
Guest-side driver capable of speaking the Xen PV display protocol
|
||||
|
||||
- Status, Linux: Supported
|
||||
+ Status, Linux: Supported (outside of "backend allocation" mode)
|
||||
+ Status, Linux: Experimental (in "backend allocation" mode)
|
||||
|
||||
### PV Console (frontend)
|
||||
|
||||
9214
zstd-dom0.patch
Normal file
9214
zstd-dom0.patch
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue