Compare commits
215 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8af4d85b6 | ||
|
|
5bd254f006 | ||
|
|
87e40ff1ba | ||
|
|
1e49e52adb | ||
|
|
0c18c23c4c | ||
|
|
124455e632 | ||
|
|
f67d5718e2 | ||
|
|
b448fd6e2f | ||
|
|
cf70d8c84e | ||
|
|
18cf277715 | ||
|
|
545511922a | ||
|
|
30cb19d1ba | ||
|
|
fbec0bc65a | ||
|
|
2b36f2e8ca | ||
|
|
d409186bf5 | ||
|
|
461c19a5ca | ||
|
|
ca06290682 | ||
|
|
aa9dce01d1 | ||
|
|
b27c4b799d | ||
|
|
310309c8d5 | ||
|
|
932125ac66 | ||
|
|
d001d8f7cf | ||
|
|
8bc3f5aa32 | ||
|
|
ca8c5d5135 | ||
|
|
39101b511c | ||
|
|
e2d4d104a0 | ||
|
|
d382b68b39 | ||
|
|
80e497a295 | ||
|
|
41f5d9097f | ||
|
|
3a0543c8d6 | ||
|
|
88c9f05c39 | ||
|
|
59fe5ad165 | ||
|
|
0e81fe4bff | ||
|
|
0d1f7da88a | ||
|
|
5c740ce63a | ||
|
|
d458004d8b | ||
|
|
ebbbc5ccb7 | ||
|
|
2b88083cfc | ||
|
|
a322535e9f | ||
|
|
417c2eb41a | ||
|
|
b5342a4b67 | ||
|
|
ef4574608a | ||
|
|
08778ae14d | ||
|
|
589e86cf56 | ||
|
|
1b82c01894 | ||
|
|
9e3a14be33 | ||
|
|
269fa36c52 | ||
|
|
bac467190c | ||
|
|
254a309537 | ||
|
|
c762409b33 | ||
|
|
4dc6f761c8 | ||
|
|
81b1db8227 | ||
|
|
4d6e2c0007 | ||
|
|
ef85dabcd3 | ||
|
|
950832bad0 | ||
|
|
b644c52cfa | ||
|
|
869574bf2f | ||
|
|
343a901c21 | ||
|
|
99dc35fd60 | ||
|
|
b5231bddba | ||
|
|
ad078f957f | ||
|
|
7fa4a3eee6 | ||
|
|
afce7b2845 | ||
|
|
9f61265760 | ||
|
|
c0ff82bee4 | ||
|
|
ca3f59d0e3 | ||
|
|
eb85956ccc | ||
|
|
c09e550528 | ||
|
|
baa6ba2e5a | ||
|
|
14c61e3105 | ||
|
|
7669a61055 | ||
|
|
70cfe51077 | ||
|
|
19ebd639fc | ||
|
|
b65002c5bf | ||
|
|
f3cac52735 | ||
|
|
d6d8d8a393 | ||
|
|
e44f0d9ede | ||
|
|
bf947f8f93 | ||
|
|
04f2270c6e | ||
|
|
cef4bbf959 | ||
|
|
d59e49c417 | ||
|
|
eadd06a27e | ||
|
|
e92b341446 | ||
|
|
0e3619e057 | ||
|
|
8695caf85a | ||
|
|
766c47c1cb | ||
|
|
a54439cc72 | ||
|
|
0aca66e99a | ||
|
|
97374c0faa | ||
|
|
ca586624b1 | ||
|
|
ebc4dec9e2 | ||
|
|
136d0a1506 | ||
|
|
744bd15194 | ||
|
|
305416ce5a | ||
|
|
abd09f4c10 | ||
|
|
ab3164079e | ||
|
|
a743b10608 | ||
|
|
9381fafa32 | ||
|
|
6cac8ee872 | ||
|
|
25f5ec29c8 | ||
|
|
161d5c0fe9 | ||
|
|
7c54ce20c6 | ||
|
|
cac6545cdc | ||
|
|
288b363e21 | ||
|
|
f1540fc363 | ||
|
|
d3847f2127 | ||
|
|
a1bf0486e5 | ||
|
|
6ccd000828 | ||
|
|
f752e6d4e7 | ||
|
|
8c923532c1 | ||
|
|
25ef88628b | ||
|
|
6e2824bf21 | ||
|
|
41796d118d | ||
|
|
7724e33e73 | ||
|
|
84657107f4 | ||
|
|
3b4e0888e1 | ||
|
|
2a7e6767df | ||
|
|
0fd71b054e | ||
|
|
be07911010 | ||
|
|
cf76d0c21e | ||
|
|
2f753f7e9b | ||
|
|
84f0fa5dbf | ||
|
|
e525cde881 | ||
|
|
e48c1754f3 | ||
|
|
0736a4dbf1 | ||
|
|
520a08e991 | ||
|
|
2ba51878a6 | ||
|
|
a8899f28f9 | ||
|
|
811d8e19d1 | ||
|
|
ab9408e4e3 | ||
|
|
7794fedff3 | ||
|
|
5f1904ebd4 | ||
|
|
e30580581d | ||
|
|
05650b8adf | ||
|
|
3f30b99783 | ||
|
|
960733fb60 | ||
|
|
77c10a7976 | ||
|
|
34e0b01ed4 | ||
|
|
32c79cab5f | ||
|
|
4d1f7dbe43 | ||
|
|
30f2ec4b6c | ||
|
|
f458ebe460 | ||
|
|
6554d4f557 | ||
|
|
a104bbcf02 | ||
|
|
054f9045ad | ||
|
|
4cbc5a57f1 | ||
|
|
205c567efb | ||
|
|
6594c32499 | ||
|
|
066167cb69 | ||
|
|
3ba0708ee8 | ||
|
|
62a55dab2d | ||
|
|
f15c128730 | ||
|
|
5c5498aae8 | ||
|
|
9d8391a472 | ||
|
|
0e913fb9ea | ||
|
|
a23d05f0ce | ||
|
|
4dbcf4d3f7 | ||
|
|
5b7f356ae7 | ||
|
|
b801938d78 | ||
|
|
e6b8299a36 | ||
|
|
b64e04acdf | ||
|
|
fa37c9fcb0 | ||
|
|
1e9fc415c6 | ||
|
|
05b5d868bc | ||
|
|
b1a2540d9f | ||
|
|
75bef3ece1 | ||
|
|
7fc59869cb | ||
|
|
8a43935ac4 | ||
|
|
5f01f1feca | ||
|
|
e4c797f0d8 | ||
|
|
b6c6fc0ef1 | ||
|
|
3b402adc22 | ||
|
|
e1f73cd699 | ||
|
|
181c01aee5 | ||
|
|
0b616dfcac | ||
|
|
ed166e2fa9 | ||
|
|
9e7881994e | ||
|
|
a5572496fb | ||
|
|
8e8503393c | ||
|
|
9aac9aad77 | ||
|
|
fcaf32cd71 | ||
|
|
7829dfecf9 | ||
| c362e0407d | |||
|
|
0b88acdac0 | ||
|
|
6ea38f207f | ||
|
|
852b076a0e | ||
|
|
995f98f000 | ||
|
|
ba63a02fbc | ||
|
|
937578a14e | ||
|
|
593eb17437 | ||
|
|
6c22ec879a | ||
|
|
a9fcba2c11 | ||
| e03e4d3811 | |||
|
|
b5b754ce6a | ||
|
|
fbe16bba56 | ||
|
|
7b4d0d1171 | ||
|
|
bae3b798c8 | ||
|
|
834ca81402 | ||
|
|
c3ca819bab | ||
|
|
fb94fb22a3 | ||
|
|
83a7abe677 | ||
|
|
476f568d2e | ||
|
|
06b9276964 | ||
|
|
51cdff244e | ||
|
|
ccb3d5f799 | ||
|
|
57295488a1 | ||
|
|
a6bb4c145b | ||
|
|
03a5477b96 | ||
|
|
c6bfd9a2dd | ||
|
43fce97b00 |
|||
|
|
86492e72ca | ||
|
|
fd9d08821d | ||
|
|
a63e14184f | ||
|
|
8dcf680a4d | ||
|
|
52ff364dd3 |
110 changed files with 6031 additions and 6266 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -6,4 +6,5 @@ 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.10.1.tar.gz
|
||||
/mini-os-4.21.0.tar.xz
|
||||
/xen-4.21.1.tar.xz
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
--- xen-4.4.1/tools/qemu-xen-traditional/hw/virtio-net.c.orig 2014-07-02 15:54:37.000000000 +0100
|
||||
+++ xen-4.4.1/tools/qemu-xen-traditional/hw/virtio-net.c 2014-11-18 20:50:13.593122915 +0000
|
||||
@@ -192,7 +192,7 @@
|
||||
return VIRTIO_NET_ERR;
|
||||
|
||||
if (mac_data.entries) {
|
||||
- if (n->mac_table.in_use + mac_data.entries <= MAC_TABLE_ENTRIES) {
|
||||
+ if (n->mac_table.in_use <= MAC_TABLE_ENTRIES - mac_data.entries) {
|
||||
memcpy(n->mac_table.macs + (n->mac_table.in_use * ETH_ALEN),
|
||||
elem->out_sg[2].iov_base + sizeof(mac_data),
|
||||
mac_data.entries * ETH_ALEN);
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/ne2000.c.orig 2015-09-26 17:27:49.494334726 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/ne2000.c 2015-09-26 17:31:53.107474932 +0100
|
||||
@@ -331,7 +331,7 @@
|
||||
if (index <= s->stop)
|
||||
avail = s->stop - index;
|
||||
else
|
||||
- avail = 0;
|
||||
+ break;
|
||||
len = size;
|
||||
if (len > avail)
|
||||
len = avail;
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/ne2000.c.orig 2015-06-09 16:32:24.000000000 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/ne2000.c 2015-09-26 17:27:49.494334726 +0100
|
||||
@@ -304,6 +304,9 @@
|
||||
}
|
||||
|
||||
index = s->curpag << 8;
|
||||
+ if (index >= NE2000_PMEM_END) {
|
||||
+ index = s->start;
|
||||
+ }
|
||||
/* 4 bytes for header */
|
||||
total_len = size + 4;
|
||||
/* address for next packet (4 bytes for CRC) */
|
||||
@@ -387,15 +390,21 @@
|
||||
offset = addr | (page << 4);
|
||||
switch(offset) {
|
||||
case EN0_STARTPG:
|
||||
- s->start = val << 8;
|
||||
+ if (val << 8 <= NE2000_PMEM_END) {
|
||||
+ s->start = val << 8;
|
||||
+ }
|
||||
s->tainted = 1;
|
||||
break;
|
||||
case EN0_STOPPG:
|
||||
- s->stop = val << 8;
|
||||
+ if (val << 8 <= NE2000_PMEM_END) {
|
||||
+ s->stop = val << 8;
|
||||
+ }
|
||||
s->tainted = 1;
|
||||
break;
|
||||
case EN0_BOUNDARY:
|
||||
- s->boundary = val;
|
||||
+ if (val << 8 < NE2000_PMEM_END) {
|
||||
+ s->boundary = val;
|
||||
+ }
|
||||
break;
|
||||
case EN0_IMR:
|
||||
s->imr = val;
|
||||
@@ -436,7 +445,9 @@
|
||||
s->phys[offset - EN1_PHYS] = val;
|
||||
break;
|
||||
case EN1_CURPAG:
|
||||
- s->curpag = val;
|
||||
+ if (val << 8 < NE2000_PMEM_END) {
|
||||
+ s->curpag = val;
|
||||
+ }
|
||||
s->tainted = 1;
|
||||
break;
|
||||
case EN1_MULT ... EN1_MULT + 7:
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/e1000.c.orig 2015-06-09 16:32:24.000000000 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/e1000.c 2015-09-26 17:16:36.406544380 +0100
|
||||
@@ -461,7 +461,8 @@
|
||||
memmove(tp->data, tp->header, hdr);
|
||||
tp->size = hdr;
|
||||
}
|
||||
- } while (split_size -= bytes);
|
||||
+ split_size -= bytes;
|
||||
+ } while (bytes && split_size);
|
||||
} else if (!tp->tse && tp->cptse) {
|
||||
// context descriptor TSE is not set, while data descriptor TSE is set
|
||||
DBGOUT(TXERR, "TCP segmentaion Error\n");
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/virtio.c.orig 2015-06-09 16:32:24.000000000 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/virtio.c 2015-10-10 16:57:01.806370020 +0100
|
||||
@@ -268,8 +268,8 @@
|
||||
return vring_avail_idx(vq) == vq->last_avail_idx;
|
||||
}
|
||||
|
||||
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
- unsigned int len, unsigned int idx)
|
||||
+static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
+ unsigned int len)
|
||||
{
|
||||
unsigned int offset;
|
||||
int i;
|
||||
@@ -302,7 +302,19 @@
|
||||
|
||||
offset += size;
|
||||
}
|
||||
+}
|
||||
|
||||
+void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
+ unsigned int len)
|
||||
+{
|
||||
+ vq->last_avail_idx--;
|
||||
+ virtqueue_unmap_sg(vq, elem, len);
|
||||
+}
|
||||
+
|
||||
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
+ unsigned int len, unsigned int idx)
|
||||
+{
|
||||
+ virtqueue_unmap_sg(vq, elem, len);
|
||||
idx = (idx + vring_used_idx(vq)) % vq->vring.num;
|
||||
|
||||
/* Get a pointer to the next entry in the used ring. */
|
||||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/virtio.h.orig 2015-06-09 16:32:24.000000000 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/virtio.h 2015-10-10 16:57:53.146216039 +0100
|
||||
@@ -105,6 +105,8 @@
|
||||
void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
unsigned int len);
|
||||
void virtqueue_flush(VirtQueue *vq, unsigned int count);
|
||||
+void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
+ unsigned int len);
|
||||
void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
unsigned int len, unsigned int idx);
|
||||
|
||||
--- xen-4.5.1/tools/qemu-xen-traditional/hw/virtio-net.c.orig 2015-10-10 16:10:05.071786348 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/hw/virtio-net.c 2015-10-10 19:05:34.510029916 +0100
|
||||
@@ -424,11 +424,15 @@
|
||||
len = iov_fill(sg, elem.in_num,
|
||||
buf + offset, size - offset);
|
||||
total += len;
|
||||
+ offset += len;
|
||||
+ if (!n->mergeable_rx_bufs && offset < size) {
|
||||
+ virtqueue_discard(n->rx_vq, &elem, total);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* signal other side */
|
||||
virtqueue_fill(n->rx_vq, &elem, total, i++);
|
||||
|
||||
- offset += len;
|
||||
}
|
||||
|
||||
if (mhdr)
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 8b98a2f07175d46c3f7217639bd5e03f2ec56343 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Mon, 30 Nov 2015 15:00:06 +0800
|
||||
Subject: [PATCH] pcnet: fix rx buffer overflow(CVE-2015-7512)
|
||||
|
||||
Backends could provide a packet whose length is greater than buffer
|
||||
size. Check for this and truncate the packet to avoid rx buffer
|
||||
overflow in this case.
|
||||
|
||||
Cc: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
---
|
||||
tools/qemu-xen-traditional/hw/pcnet.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/pcnet.c b/tools/qemu-xen-traditional/hw/pcnet.c
|
||||
index 309c40b..1f4a3db 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/pcnet.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/pcnet.c
|
||||
@@ -1064,6 +1064,12 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
|
||||
int pktcount = 0;
|
||||
|
||||
if (!s->looptest) {
|
||||
+ if (size > 4092) {
|
||||
+#ifdef PCNET_DEBUG_RMD
|
||||
+ fprintf(stderr, "pcnet: truncates rx packet.\n");
|
||||
+#endif
|
||||
+ size = 4092;
|
||||
+ }
|
||||
memcpy(src, buf, size);
|
||||
/* no need to compute the CRC */
|
||||
src[size] = 0;
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 00837731d254908a841d69298a4f9f077babaf24 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Weil <sw@weilnetz.de>
|
||||
Date: Fri, 20 Nov 2015 08:42:33 +0100
|
||||
Subject: [PATCH] eepro100: Prevent two endless loops
|
||||
|
||||
http://lists.nongnu.org/archive/html/qemu-devel/2015-11/msg04592.html
|
||||
shows an example how an endless loop in function action_command can
|
||||
be achieved.
|
||||
|
||||
During my code review, I noticed a 2nd case which can result in an
|
||||
endless loop.
|
||||
|
||||
Reported-by: Qinghao Tang <luodalongde@gmail.com>
|
||||
Signed-off-by: Stefan Weil <sw@weilnetz.de>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
---
|
||||
tools/qemu-xen-traditional/hw/eepro100.c | 16 ++++++++++++++++
|
||||
1 files changed, 16 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/eepro100.c b/tools/qemu-xen-traditional/hw/eepro100.c
|
||||
index 60333b7..685a478 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/eepro100.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/eepro100.c
|
||||
@@ -774,6 +774,11 @@ static void tx_command(EEPRO100State *s)
|
||||
uint32_t tx_buffer_address = ldl_phys(tbd_address);
|
||||
uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
|
||||
//~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
|
||||
+ if (tx_buffer_size == 0) {
|
||||
+ /* Prevent an endless loop. */
|
||||
+ logout("loop in %s:%u\n", __FILE__, __LINE__);
|
||||
+ break;
|
||||
+ }
|
||||
tbd_address += 8;
|
||||
logout
|
||||
("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
From 4c65fed8bdf96780735dbdb92a8bd0d6b6526cc3 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Thu, 3 Dec 2015 18:54:17 +0530
|
||||
Subject: [PATCH] ui: vnc: avoid floating point exception
|
||||
|
||||
While sending 'SetPixelFormat' messages to a VNC server,
|
||||
the client could set the 'red-max', 'green-max' and 'blue-max'
|
||||
values to be zero. This leads to a floating point exception in
|
||||
write_png_palette while doing frame buffer updates.
|
||||
|
||||
Reported-by: Lian Yihan <lianyihan@360.cn>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
tools/qemu-xen-traditional/vnc.c | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/vnc.c b/tools/qemu-xen-traditional/vnc.c
|
||||
index 7538405..cbe4d33 100644
|
||||
--- a/tools/qemu-xen-traditional/vnc.c
|
||||
+++ b/tools/qemu-xen-traditional/vnc.c
|
||||
@@ -2198,15 +2198,15 @@ static void set_pixel_format(VncState *vs,
|
||||
}
|
||||
|
||||
vs->clientds = vs->serverds;
|
||||
- vs->clientds.pf.rmax = red_max;
|
||||
+ vs->clientds.pf.rmax = red_max ? red_max : 0xFF;
|
||||
count_bits(vs->clientds.pf.rbits, red_max);
|
||||
vs->clientds.pf.rshift = red_shift;
|
||||
vs->clientds.pf.rmask = red_max << red_shift;
|
||||
- vs->clientds.pf.gmax = green_max;
|
||||
+ vs->clientds.pf.gmax = green_max ? green_max : 0xFF;
|
||||
count_bits(vs->clientds.pf.gbits, green_max);
|
||||
vs->clientds.pf.gshift = green_shift;
|
||||
vs->clientds.pf.gmask = green_max << green_shift;
|
||||
- vs->clientds.pf.bmax = blue_max;
|
||||
+ vs->clientds.pf.bmax = blue_max ? blue_max : 0xFF;
|
||||
count_bits(vs->clientds.pf.bbits, blue_max);
|
||||
vs->clientds.pf.bshift = blue_shift;
|
||||
vs->clientds.pf.bmask = blue_max << blue_shift;
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
--- xen-4.6.1/tools/qemu-xen-traditional/hw/fw_cfg.c.orig 2016-01-04 15:35:42.000000000 +0000
|
||||
+++ xen-4.6.1/tools/qemu-xen-traditional/hw/fw_cfg.c 2016-03-06 16:42:33.464296362 +0000
|
||||
@@ -54,11 +54,15 @@
|
||||
static void fw_cfg_write(FWCfgState *s, uint8_t value)
|
||||
{
|
||||
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
|
||||
- FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
+ FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
|
||||
+ &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
|
||||
FW_CFG_DPRINTF("write %d\n", value);
|
||||
|
||||
- if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) {
|
||||
+ if (s->cur_entry & FW_CFG_WRITE_CHANNEL
|
||||
+ && e != NULL
|
||||
+ && e->callback
|
||||
+ && s->cur_offset < e->len) {
|
||||
e->data[s->cur_offset++] = value;
|
||||
if (s->cur_offset == e->len) {
|
||||
e->callback(e->callback_opaque, e->data);
|
||||
@@ -88,7 +92,8 @@
|
||||
static uint8_t fw_cfg_read(FWCfgState *s)
|
||||
{
|
||||
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
|
||||
- FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
+ FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
|
||||
+ &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
uint8_t ret;
|
||||
|
||||
if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
*From*: Laszlo Ersek
|
||||
*Subject*: [Qemu-devel] [PATCH] e1000: eliminate infinite loops on
|
||||
out-of-bounds transfer start
|
||||
*Date*: Tue, 19 Jan 2016 14:17:20 +0100
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The start_xmit() and e1000_receive_iov() functions implement DMA transfers
|
||||
iterating over a set of descriptors that the guest's e1000 driver
|
||||
prepares:
|
||||
|
||||
- the TDLEN and RDLEN registers store the total size of the descriptor
|
||||
area,
|
||||
|
||||
- while the TDH and RDH registers store the offset (in whole tx / rx
|
||||
descriptors) into the area where the transfer is supposed to start.
|
||||
|
||||
Each time a descriptor is processed, the TDH and RDH register is bumped
|
||||
(as appropriate for the transfer direction).
|
||||
|
||||
QEMU already contains logic to deal with bogus transfers submitted by the
|
||||
guest:
|
||||
|
||||
- Normally, the transmit case wants to increase TDH from its initial value
|
||||
to TDT. (TDT is allowed to be numerically smaller than the initial TDH
|
||||
value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
|
||||
that QEMU currently has here is a check against reaching the original
|
||||
TDH value again -- a complete wraparound, which should never happen.
|
||||
|
||||
- In the receive case RDH is increased from its initial value until
|
||||
"total_size" bytes have been received; preferably in a single step, or
|
||||
in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
|
||||
RX descriptors are skipped without receiving data, while RDH is
|
||||
incremented just the same. QEMU tries to prevent an infinite loop
|
||||
(processing only null RX descriptors) by detecting whether RDH assumes
|
||||
its original value during the loop. (Again, wrapping from RDLEN to 0 is
|
||||
normal.)
|
||||
|
||||
What both directions miss is that the guest could program TDLEN and RDLEN
|
||||
so low, and the initial TDH and RDH so high, that these registers will
|
||||
immediately be truncated to zero, and then never reassume their initial
|
||||
values in the loop -- a full wraparound will never occur.
|
||||
|
||||
The condition that expresses this is:
|
||||
|
||||
xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
|
||||
|
||||
i.e., TDH or RDH start out after the last whole rx or tx descriptor that
|
||||
fits into the TDLEN or RDLEN sized area.
|
||||
|
||||
This condition could be checked before we enter the loops, but
|
||||
pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
|
||||
bogus DMA addresses, so we just extend the existing failsafes with the
|
||||
above condition.
|
||||
|
||||
Cc: "Michael S. Tsirkin" <address@hidden>
|
||||
Cc: Petr Matousek <address@hidden>
|
||||
Cc: Stefano Stabellini <address@hidden>
|
||||
Cc: Prasad Pandit <address@hidden>
|
||||
Cc: Michael Roth <address@hidden>
|
||||
Cc: Jason Wang <address@hidden>
|
||||
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
|
||||
Signed-off-by: Laszlo Ersek <address@hidden>
|
||||
Reviewed-by: Jason Wang <address@hidden>
|
||||
---
|
||||
|
||||
Notes:
|
||||
Regarding the public posting: we made an honest effort to vet this
|
||||
vulnerability, and the impact seems low -- no host side reads/writes,
|
||||
"just" a DoS (infinite loop). We decided the patch could be posted
|
||||
publicly, for the usual review process. Jason and Prasad checked the
|
||||
patch in the internal discussion already, but comments, improvements
|
||||
etc. are clearly welcome. The CVE request is underway. Thanks.
|
||||
|
||||
hw/net/e1000.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
||||
index bec06e9..34d0823 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/e1000.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/e1000.c
|
||||
@@ -908,7 +908,8 @@ start_xmit(E1000State *s)
|
||||
* bogus values to TDT/TDLEN.
|
||||
* there's nothing too intelligent we could do about this.
|
||||
*/
|
||||
- if (s->mac_reg[TDH] == tdh_start) {
|
||||
+ if (s->mac_reg[TDH] == tdh_start ||
|
||||
+ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
|
||||
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
|
||||
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
|
||||
break;
|
||||
@@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
||||
s->mac_reg[RDH] = 0;
|
||||
s->check_rxov = 1;
|
||||
/* see comment in start_xmit; same here */
|
||||
- if (s->mac_reg[RDH] == rdh_start) {
|
||||
+ if (s->mac_reg[RDH] == rdh_start ||
|
||||
+ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
|
||||
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
||||
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
||||
set_ics(s, 0, E1000_ICS_RXO);
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
When processing remote NDIS control message packets,
|
||||
the USB Net device emulator uses a fixed length(4096) data buffer.
|
||||
The incoming informationBufferOffset & Length combination could
|
||||
overflow and cross that range. Check control message buffer
|
||||
offsets and length to avoid it.
|
||||
|
||||
Reported-by: Qinghao Tang <address@hidden>
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/usb/dev-network.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
Update as per review
|
||||
-> https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg03475.html
|
||||
|
||||
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
|
||||
index 8a4ff49..180adce 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/usb-net.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/usb-net.c
|
||||
@@ -915,8 +915,9 @@ static int rndis_query_response(USBNetState *s,
|
||||
|
||||
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||
- if (bufoffs + buflen > length)
|
||||
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||
return USB_RET_STALL;
|
||||
+ }
|
||||
|
||||
infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
|
||||
bufoffs + (uint8_t *) buf, buflen, infobuf,
|
||||
@@ -961,8 +962,9 @@ static int rndis_set_response(USBNetState *s,
|
||||
|
||||
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||
- if (bufoffs + buflen > length)
|
||||
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||
return USB_RET_STALL;
|
||||
+ }
|
||||
|
||||
ret = ndis_set(s, le32_to_cpu(buf->OID),
|
||||
bufoffs + (uint8_t *) buf, buflen);
|
||||
@@ -1212,8 +1214,9 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
|
||||
if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
|
||||
uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
|
||||
uint32_t size = le32_to_cpu(msg->DataLength);
|
||||
- if (offs + size <= len)
|
||||
+ if (offs < len && size < len && offs + size <= len) {
|
||||
qemu_send_packet(s->vc, s->out_buf + offs, size);
|
||||
+ }
|
||||
}
|
||||
s->out_ptr -= len;
|
||||
memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
|
||||
--
|
||||
2.5.0
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
|
||||
bytes to process network packets. Registers PSTART & PSTOP
|
||||
define ring buffer size & location. Setting these registers
|
||||
to invalid values could lead to infinite loop or OOB r/w
|
||||
access issues. Add check to avoid it.
|
||||
|
||||
Reported-by: Yang Hongke <address@hidden>
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/net/ne2000.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
Update per review:
|
||||
-> https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg05522.html
|
||||
|
||||
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
|
||||
index b032212..ced4666 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/ne2000.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/ne2000.c
|
||||
@@ -154,6 +154,10 @@ static int ne2000_buffer_full(NE2000State *s)
|
||||
{
|
||||
int avail, index, boundary;
|
||||
|
||||
+ if (s->stop <= s->start) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
index = s->curpag << 8;
|
||||
boundary = s->boundary << 8;
|
||||
if (index < boundary)
|
||||
--
|
||||
2.5.0
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
While computing IP checksum, 'net_checksum_calculate' reads
|
||||
payload length from the packet. It could exceed the given 'data'
|
||||
buffer size. Add a check to avoid it.
|
||||
|
||||
Reported-by: Liu Ling <address@hidden>
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
net/checksum.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
Update as per review:
|
||||
-> https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg06121.html
|
||||
|
||||
diff --git a/net/checksum.c b/net/checksum.c
|
||||
index 14c0855..0942437 100644
|
||||
--- a/tools/qemu-xen-traditional/net-checksum.c
|
||||
+++ b/tools/qemu-xen-traditional/net-checksum.c
|
||||
@@ -59,6 +59,11 @@ void net_checksum_calculate(uint8_t *data, int length)
|
||||
int hlen, plen, proto, csum_offset;
|
||||
uint16_t csum;
|
||||
|
||||
+ /* Ensure data has complete L2 & L3 headers. */
|
||||
+ if (length < 14 + 20) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if ((data[14] & 0xf0) != 0x40)
|
||||
return; /* not IPv4 */
|
||||
hlen = (data[14] & 0x0f) * 4;
|
||||
@@ -76,8 +81,9 @@ void net_checksum_calculate(uint8_t *data, int length)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (plen < csum_offset+2)
|
||||
- return;
|
||||
+ if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
data[14+hlen+csum_offset] = 0;
|
||||
data[14+hlen+csum_offset+1] = 0;
|
||||
--
|
||||
2.5.0
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
From 3a15cc0e1ee7168db0782133d2607a6bfa422d66 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Fri, 8 Apr 2016 11:33:48 +0530
|
||||
Subject: [PATCH] net: stellaris_enet: check packet length against receive buffer
|
||||
|
||||
When receiving packets over Stellaris ethernet controller, it
|
||||
uses receive buffer of size 2048 bytes. In case the controller
|
||||
accepts large(MTU) packets, it could lead to memory corruption.
|
||||
Add check to avoid it.
|
||||
|
||||
Reported-by: Oleksandr Bazhaniuk <oleksandr.bazhaniuk@intel.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Message-id: 1460095428-22698-1-git-send-email-ppandit@redhat.com
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
tools/qemu-xen-traditional/hw/stellaris_enet.c | 12 +++++++++++-
|
||||
1 files changed, 11 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/stellaris_enet.c b/tools/qemu-xen-traditional/hw/stellaris_enet.c
|
||||
index 84cf60b..6880894 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/stellaris_enet.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/stellaris_enet.c
|
||||
@@ -236,8 +236,18 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
|
||||
n = s->next_packet + s->np;
|
||||
if (n >= 31)
|
||||
n -= 31;
|
||||
- s->np++;
|
||||
|
||||
+ if (size >= sizeof(s->rx[n].data) - 6) {
|
||||
+ /* If the packet won't fit into the
|
||||
+ * emulated 2K RAM, this is reported
|
||||
+ * as a FIFO overrun error.
|
||||
+ */
|
||||
+ s->ris |= SE_INT_FOV;
|
||||
+ stellaris_enet_update(s);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ s->np++;
|
||||
s->rx[n].len = size + 6;
|
||||
p = s->rx[n].data;
|
||||
*(p++) = (size + 6);
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
When receiving packets over MIPSnet network device, it uses
|
||||
receive buffer of size 1514 bytes. In case the controller
|
||||
accepts large(MTU) packets, it could lead to memory corruption.
|
||||
Add check to avoid it.
|
||||
|
||||
Reported by: Oleksandr Bazhaniuk <address@hidden>
|
||||
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
tools/qemu-xen-traditional/hw/mipsnet.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/mipsnet.c b/tools/qemu-xen-traditional/hw/mipsnet.c
|
||||
index f261011..e134b31 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/mipsnet.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/mipsnet.c
|
||||
@@ -82,6 +82,9 @@ static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t si
|
||||
if (!mipsnet_can_receive(opaque))
|
||||
return;
|
||||
|
||||
+ if (size >= sizeof(s->rx_buffer)) {
|
||||
+ return;
|
||||
+ }
|
||||
s->busy = 1;
|
||||
|
||||
/* Just accept everything. */
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
*From*: P J P
|
||||
*Subject*: [Qemu-devel] [PATCH 1/2] scsi: check command buffer length
|
||||
before write(CVE-2016-4439)
|
||||
*Date*: Thu, 19 May 2016 16:09:30 +0530
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte
|
||||
FIFO buffer. It is used to handle command and data transfer. While
|
||||
writing to this command buffer 's->cmdbuf[TI_BUFSZ=16]', a check
|
||||
was missing to validate input length. Add check to avoid OOB write
|
||||
access.
|
||||
|
||||
Fixes CVE-2016-4439
|
||||
Reported-by: Li Qiang <address@hidden>
|
||||
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/scsi/esp.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/esp.c b/tools/qemu-xen-traditional/hw/esp.c
|
||||
index 8961be2..01497e6 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/esp.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/esp.c
|
||||
@@ -448,7 +448,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||
break;
|
||||
case ESP_FIFO:
|
||||
if (s->do_cmd) {
|
||||
- s->cmdbuf[s->cmdlen++] = val & 0xff;
|
||||
+ if (s->cmdlen < TI_BUFSZ) {
|
||||
+ s->cmdbuf[s->cmdlen++] = val & 0xff;
|
||||
+ } else {
|
||||
+ ESP_ERROR("fifo overrun\n");
|
||||
+ }
|
||||
} else if (s->ti_size == TI_BUFSZ - 1) {
|
||||
ESP_ERROR("fifo overrun\n");
|
||||
} else {
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
*From*: P J P
|
||||
*Subject*: [Qemu-devel] [PATCH 2/2] scsi: check dma length before
|
||||
reading scsi command(CVE-2016-4441)
|
||||
*Date*: Thu, 19 May 2016 16:09:31 +0530
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte
|
||||
FIFO buffer. It is used to handle command and data transfer.
|
||||
Routine get_cmd() uses DMA to read scsi commands into this buffer.
|
||||
Add check to validate DMA length against buffer size to avoid any
|
||||
overrun.
|
||||
|
||||
Fixes CVE-2016-4441
|
||||
Reported-by: Li Qiang <address@hidden>
|
||||
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/scsi/esp.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/esp.c b/tools/qemu-xen-traditional/hw/esp.c
|
||||
index 01497e6..591c817 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/esp.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/esp.c
|
||||
@@ -82,7 +82,7 @@ void esp_request_cancelled(SCSIRequest *req)
|
||||
}
|
||||
}
|
||||
|
||||
-static uint32_t get_cmd(ESPState *s, uint8_t *buf)
|
||||
+static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
|
||||
{
|
||||
uint32_t dmalen;
|
||||
int target;
|
||||
@@ -92,6 +92,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
|
||||
target = s->wregs[ESP_WBUSID] & BUSID_DID;
|
||||
if (s->dma) {
|
||||
dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
|
||||
+ if (dmalen > buflen) {
|
||||
+ return 0;
|
||||
+ }
|
||||
s->dma_memory_read(s->dma_opaque, buf, dmalen);
|
||||
} else {
|
||||
dmalen = s->ti_size;
|
||||
@@ -166,7 +169,7 @@ static void handle_satn(ESPState *s)
|
||||
uint8_t buf[32];
|
||||
int len;
|
||||
|
||||
- len = get_cmd(s, buf);
|
||||
+ len = get_cmd(s, buf, sizeof(buf));
|
||||
if (len)
|
||||
do_cmd(s, buf);
|
||||
}
|
||||
@@ -192,7 +195,7 @@ static void handle_satn_stop(ESPState *s)
|
||||
|
||||
static void handle_satn_stop(ESPState *s)
|
||||
{
|
||||
- s->cmdlen = get_cmd(s, s->cmdbuf);
|
||||
+ s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
|
||||
if (s->cmdlen) {
|
||||
DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
|
||||
s->do_cmd = 1;
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
*From*: Paolo Bonzini
|
||||
*Subject*: Re: [Qemu-devel] [PATCH] scsi: check buffer length before
|
||||
reading scsi command
|
||||
*Date*: Wed, 1 Jun 2016 15:10:16 +0200
|
||||
*User-agent*: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
|
||||
Thunderbird/45.1.0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
On 31/05/2016 19:53, P J P wrote:
|
||||
>/ From: Prasad J Pandit <address@hidden>/
|
||||
>/ /
|
||||
>/ The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte/
|
||||
>/ FIFO buffer. It is used to handle command and data transfer./
|
||||
>/ Routine get_cmd() in non-DMA mode, uses 'ti_size' to read scsi/
|
||||
>/ command into a buffer. Add check to validate command length against/
|
||||
>/ buffer size to avoid any overrun./
|
||||
>/ /
|
||||
>/ Reported-by: Li Qiang <address@hidden>/
|
||||
>/ Signed-off-by: Prasad J Pandit <address@hidden>/
|
||||
>/ ---/
|
||||
>/ hw/scsi/esp.c | 3 +++/
|
||||
>/ 1 file changed, 3 insertions(+)/
|
||||
>/ /
|
||||
>/ diff --git a/tools/qemu-xen-traditional/hw/esp.c b/tools/qemu-xen-traditional/hw/esp.c/
|
||||
>/ index 60c1b28..953027a 100644/
|
||||
>/ --- a/tools/qemu-xen-traditional/hw/esp.c/
|
||||
>/ +++ b/tools/qemu-xen-traditional/hw/esp.c/
|
||||
>/ @@ -98,6 +98,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t /
|
||||
>/ buflen)/
|
||||
>/ s->dma_memory_read(s->dma_opaque, buf, dmalen);/
|
||||
>/ } else {/
|
||||
>/ dmalen = s->ti_size;/
|
||||
>/ + if (dmalen > TI_BUFSZ) {/
|
||||
>/ + return 0;/
|
||||
>/ + }/
|
||||
>/ memcpy(buf, s->ti_buf, dmalen);/
|
||||
>/ buf[0] = buf[2] >> 5;/
|
||||
>/ }/
|
||||
>/ /
|
||||
|
||||
In theory this shouldn't happen, but I agree that it is better to be
|
||||
defensive. I'm queuing this patch.
|
||||
|
||||
At least the following patch is needed to ensure that ti_size always
|
||||
matches ti_rptr/ti_wptr (Hervé, what do you think about it? should I
|
||||
resubmit it formally?). Also, things are more complicated than
|
||||
necessary due to ti_size being used for both DMA and FIFO transfers.
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/esp.c b/tools/qemu-xen-traditional/hw/esp.c
|
||||
index c2f6f8f..6407844 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/esp.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/esp.c
|
||||
@@ -222,7 +222,7 @@ static void write_response(ESPState *s)
|
||||
} else {
|
||||
s->ti_size = 2;
|
||||
s->ti_rptr = 0;
|
||||
- s->ti_wptr = 0;
|
||||
+ s->ti_wptr = 2;
|
||||
s->rregs[ESP_RFLAGS] = 2;
|
||||
}
|
||||
esp_raise_irq(s);
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
*From*: P J P
|
||||
*Subject*: [Qemu-devel] [PATCH v3] scsi: esp: check TI buffer index
|
||||
before read/write
|
||||
*Date*: Mon, 6 Jun 2016 22:04:43 +0530
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
The 53C9X Fast SCSI Controller(FSC) comes with internal 16-byte
|
||||
FIFO buffers. One is used to handle commands and other is for
|
||||
information transfer. Three control variables 'ti_rptr',
|
||||
'ti_wptr' and 'ti_size' are used to control r/w access to the
|
||||
information transfer buffer ti_buf[TI_BUFSZ=16]. In that,
|
||||
|
||||
'ti_rptr' is used as read index, where read occurs.
|
||||
'ti_wptr' is a write index, where write would occur.
|
||||
'ti_size' indicates total bytes to be read from the buffer.
|
||||
|
||||
While reading/writing to this buffer, index could exceed its
|
||||
size. Add check to avoid OOB r/w access.
|
||||
|
||||
Reported-by: Huawei PSIRT <address@hidden>
|
||||
Reported-by: Li Qiang <address@hidden>
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/scsi/esp.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
Update as per:
|
||||
-> https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg01326.html
|
||||
|
||||
diff --git a/tools/qemu-xen-traditional/hw/esp.c b/tools/qemu-xen-traditional/hw/esp.c
|
||||
index c2f6f8f..4b94bbc 100644
|
||||
--- a/tools/qemu-xen-traditional/hw/esp.c
|
||||
+++ b/tools/qemu-xen-traditional/hw/esp.c
|
||||
@@ -403,18 +403,17 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
|
||||
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
|
||||
switch (saddr) {
|
||||
case ESP_FIFO:
|
||||
- if (s->ti_size > 0) {
|
||||
+ if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
|
||||
+ /* Data out. */
|
||||
+ ESP_ERROR("PIO data read not implemented\n");
|
||||
+ s->rregs[ESP_FIFO] = 0;
|
||||
+ esp_raise_irq(s);
|
||||
+ } else if (s->ti_rptr < s->ti_wptr) {
|
||||
s->ti_size--;
|
||||
- if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
|
||||
- /* Data out. */
|
||||
- ESP_ERROR("PIO data read not implemented\n");
|
||||
- s->rregs[ESP_FIFO] = 0;
|
||||
- } else {
|
||||
- s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
|
||||
- }
|
||||
+ s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
|
||||
esp_raise_irq(s);
|
||||
}
|
||||
- if (s->ti_size == 0) {
|
||||
+ if (s->ti_rptr == s->ti_wptr) {
|
||||
s->ti_rptr = 0;
|
||||
s->ti_wptr = 0;
|
||||
}
|
||||
@@ -459,7 +457,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||
} else {
|
||||
ESP_ERROR("fifo overrun\n");
|
||||
}
|
||||
- } else if (s->ti_size == TI_BUFSZ - 1) {
|
||||
+ } else if (s->ti_wptr == TI_BUFSZ - 1) {
|
||||
ESP_ERROR("fifo overrun\n");
|
||||
} else {
|
||||
s->ti_size++;
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
From 926cde5f3e4d2504ed161ed0cb771ac7cad6fd11 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Thu, 16 Jun 2016 00:22:35 +0200
|
||||
Subject: [PATCH] scsi: esp: make cmdbuf big enough for maximum CDB size
|
||||
|
||||
While doing DMA read into ESP command buffer 's->cmdbuf', it could
|
||||
write past the 's->cmdbuf' area, if it was transferring more than 16
|
||||
bytes. Increase the command buffer size to 32, which is maximum when
|
||||
's->do_cmd' is set, and add a check on 'len' to avoid OOB access.
|
||||
|
||||
Reported-by: Li Qiang <liqiang6-s@360.cn>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
hw/esp.c | 6 ++++--
|
||||
hw/esp.c | 3 ++-
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/esp.c b/hw/esp.c
|
||||
index 64680b3..baa0a2c 100644
|
||||
--- a/hw/esp.c
|
||||
+++ b/hw/esp.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "hw.h"
|
||||
#include "scsi-disk.h"
|
||||
#include "scsi.h"
|
||||
+#include <assert.h>
|
||||
|
||||
/* debug ESP card */
|
||||
//#define DEBUG_ESP
|
||||
@@ -248,6 +248,8 @@ static void esp_do_dma(ESPState *s)
|
||||
len = s->dma_left;
|
||||
if (s->do_cmd) {
|
||||
DPRINTF("command len %d + %d\n", s->cmdlen, len);
|
||||
+ assert (s->cmdlen <= sizeof(s->cmdbuf) &&
|
||||
+ len <= sizeof(s->cmdbuf) - s->cmdlen);
|
||||
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
|
||||
s->ti_size = 0;
|
||||
s->cmdlen = 0;
|
||||
@@ -345,7 +347,7 @@ static void handle_ti(ESPState *s)
|
||||
s->dma_counter = dmalen;
|
||||
|
||||
if (s->do_cmd)
|
||||
- minlen = (dmalen < 32) ? dmalen : 32;
|
||||
+ minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
|
||||
else if (s->ti_size < 0)
|
||||
minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
|
||||
else
|
||||
@@ -449,7 +451,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||
break;
|
||||
case ESP_FIFO:
|
||||
if (s->do_cmd) {
|
||||
- if (s->cmdlen < TI_BUFSZ) {
|
||||
+ if (s->cmdlen < ESP_CMDBUF_SZ) {
|
||||
s->cmdbuf[s->cmdlen++] = val & 0xff;
|
||||
} else {
|
||||
ESP_ERROR("fifo overrun\n");
|
||||
diff --git a/hw/esp.c b/hw/esp.c
|
||||
index 6c79527..d2c4886 100644
|
||||
--- a/hw/esp.c
|
||||
+++ b/hw/esp.c
|
||||
@@ -14,6 +14,7 @@ void esp_init(hwaddr espaddr, int it_shift,
|
||||
|
||||
#define ESP_REGS 16
|
||||
#define TI_BUFSZ 16
|
||||
+#define ESP_CMDBUF_SZ 32
|
||||
|
||||
typedef struct ESPState ESPState;
|
||||
|
||||
@@ -31,7 +32,7 @@ struct ESPState {
|
||||
uint32_t dma;
|
||||
SCSIDevice *scsi_dev[ESP_MAX_DEVS];
|
||||
SCSIDevice *current_dev;
|
||||
- uint8_t cmdbuf[TI_BUFSZ];
|
||||
+ uint8_t cmdbuf[ESP_CMDBUF_SZ];
|
||||
uint32_t cmdlen;
|
||||
uint32_t do_cmd;
|
||||
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 3592fe0c919cf27a81d8e9f9b4f269553418bb01 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Wed, 12 Oct 2016 11:28:08 +0530
|
||||
Subject: [PATCH] char: serial: check divider value against baud base
|
||||
|
||||
16550A UART device uses an oscillator to generate frequencies
|
||||
(baud base), which decide communication speed. This speed could
|
||||
be changed by dividing it by a divider. If the divider is
|
||||
greater than the baud base, speed is set to zero, leading to a
|
||||
divide by zero error. Add check to avoid it.
|
||||
|
||||
Reported-by: Huawei PSIRT <psirt@huawei.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Message-Id: <1476251888-20238-1-git-send-email-ppandit@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
hw/char/serial.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/hw/serial.c b/hw/serial.c
|
||||
index 3442f47..eec72b7 100644
|
||||
--- a/hw/serial.c
|
||||
+++ b/hw/serial.c
|
||||
@@ -153,8 +153,9 @@ static void serial_update_parameters(SerialState *s)
|
||||
int speed, parity, data_bits, stop_bits, frame_size;
|
||||
QEMUSerialSetParams ssp;
|
||||
|
||||
- if (s->divider == 0)
|
||||
+ if (s->divider == 0 || s->divider > s->baudbase) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
frame_size = 1;
|
||||
if (s->lcr & 0x08) {
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From: Prasad J Pandit <address@hidden>
|
||||
|
||||
RTL8139 ethernet controller in C+ mode supports multiple
|
||||
descriptor rings, each with maximum of 64 descriptors. While
|
||||
processing transmit descriptor ring in 'rtl8139_cplus_transmit',
|
||||
it does not limit the descriptor count and runs forever. Add
|
||||
check to avoid it.
|
||||
|
||||
Reported-by: Andrew Henderson <address@hidden>
|
||||
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||
---
|
||||
hw/net/rtl8139.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
|
||||
index 3345bc6..f05e59c 100644
|
||||
--- a/hw/rtl8139.c
|
||||
+++ b/hw/rtl8139.c
|
||||
@@ -2350,7 +2350,7 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
|
||||
{
|
||||
int txcount = 0;
|
||||
|
||||
- while (rtl8139_cplus_transmit_one(s))
|
||||
+ while (txcount < 64 && rtl8139_cplus_transmit_one(s))
|
||||
{
|
||||
++txcount;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 77d54985b85a0cb760330ec2bd92505e0a2a97a9 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Tue, 29 Nov 2016 00:38:39 +0530
|
||||
Subject: [PATCH] net: mcf: check receive buffer size register value
|
||||
|
||||
ColdFire Fast Ethernet Controller uses a receive buffer size
|
||||
register(EMRBR) to hold maximum size of all receive buffers.
|
||||
It is set by a user before any operation. If it was set to be
|
||||
zero, ColdFire emulator would go into an infinite loop while
|
||||
receiving data in mcf_fec_receive. Add check to avoid it.
|
||||
|
||||
Reported-by: Wjjzhang <wjjzhang@tencent.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
---
|
||||
hw/net/mcf_fec.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
|
||||
index dc61bac..4025eb3 100644
|
||||
--- a/hw/mcf_fec.c
|
||||
+++ b/hw/mcf_fec.c
|
||||
@@ -393,7 +393,7 @@ static void mcf_fec_write(void *opaque, hwaddr addr,
|
||||
s->tx_descriptor = s->etdsr;
|
||||
break;
|
||||
case 0x188:
|
||||
- s->emrbr = value & 0x7f0;
|
||||
+ s->emrbr = value > 0 ? value & 0x7F0 : 0x7F0;
|
||||
break;
|
||||
default:
|
||||
cpu_abort(cpu_single_env, "mcf_fec_write Bad address 0x%x\n",
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From 95ed56939eb2eaa4e2f349fe6dcd13ca4edfd8fb Mon Sep 17 00:00:00 2001
|
||||
From: Li Qiang <liqiang6-s@360.cn>
|
||||
Date: Tue, 7 Feb 2017 02:23:33 -0800
|
||||
Subject: [PATCH] usb: ohci: limit the number of link eds
|
||||
|
||||
The guest may builds an infinite loop with link eds. This patch
|
||||
limit the number of linked ed to avoid this.
|
||||
|
||||
Signed-off-by: Li Qiang <liqiang6-s@360.cn>
|
||||
Message-id: 5899a02e.45ca240a.6c373.93c1@mx.google.com
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
---
|
||||
hw/usb-ohci.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
|
||||
index 2cba3e3..21c93e0 100644
|
||||
--- a/hw/usb-ohci.c
|
||||
+++ b/hw/usb-ohci.c
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
#define OHCI_MAX_PORTS 15
|
||||
|
||||
+#define ED_LINK_LIMIT 4
|
||||
+
|
||||
static int64_t usb_frame_time;
|
||||
static int64_t usb_bit_time;
|
||||
|
||||
@@ -1184,7 +1186,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
|
||||
uint32_t next_ed;
|
||||
uint32_t cur;
|
||||
int active;
|
||||
-
|
||||
+ uint32_t link_cnt = 0;
|
||||
active = 0;
|
||||
|
||||
if (head == 0)
|
||||
@@ -1199,6 +1201,10 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
|
||||
|
||||
next_ed = ed.next & OHCI_DPTR_MASK;
|
||||
|
||||
+ if (++link_cnt > ED_LINK_LIMIT) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
|
||||
uint32_t addr;
|
||||
/* Cancel pending packets for ED that have been paused. */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From 215902d7b6fb50c6fc216fc74f770858278ed904 Mon Sep 17 00:00:00 2001
|
||||
From: hangaohuai <hangaohuai@huawei.com>
|
||||
Date: Tue, 14 Mar 2017 14:39:19 +0800
|
||||
Subject: [PATCH] fix :cirrus_vga fix OOB read case qemu Segmentation fault
|
||||
|
||||
check the validity of parameters in cirrus_bitblt_rop_fwd_transp_xxx
|
||||
and cirrus_bitblt_rop_fwd_xxx to avoid the OOB read which causes qemu Segmentation fault.
|
||||
|
||||
After the fix, we will touch the assert in
|
||||
cirrus_invalidate_region:
|
||||
assert(off_cur_end >= off_cur);
|
||||
|
||||
Signed-off-by: fangying <fangying1@huawei.com>
|
||||
Signed-off-by: hangaohuai <hangaohuai@huawei.com>
|
||||
Message-id: 20170314063919.16200-1-hangaohuai@huawei.com
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
---
|
||||
hw/cirrus_vga_rop.h | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
|
||||
index 0925a00..b7447f8 100644
|
||||
--- a/hw/cirrus_vga_rop.h
|
||||
+++ b/hw/cirrus_vga_rop.h
|
||||
@@ -97,6 +97,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||
src = src_ - src_base;
|
||||
dstpitch -= bltwidth;
|
||||
srcpitch -= bltwidth;
|
||||
+
|
||||
+ if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x++) {
|
||||
p = *(dst_base + m(dst));
|
||||
@@ -143,6 +148,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||
src = src_ - src_base;
|
||||
dstpitch -= bltwidth;
|
||||
srcpitch -= bltwidth;
|
||||
+
|
||||
+ if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x+=2) {
|
||||
p1 = *(dst_base + m(dst));
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 3268a845f41253fb55852a8429c32b50f36f349a Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Fri, 28 Apr 2017 09:56:12 +0200
|
||||
Subject: [PATCH] audio: release capture buffers
|
||||
|
||||
AUD_add_capture() allocates two buffers which are never released.
|
||||
Add the missing calls to AUD_del_capture().
|
||||
|
||||
Impact: Allows vnc clients to exhaust host memory by repeatedly
|
||||
starting and stopping audio capture.
|
||||
|
||||
Fixes: CVE-2017-8309
|
||||
Cc: P J P <ppandit@redhat.com>
|
||||
Cc: Huawei PSIRT <PSIRT@huawei.com>
|
||||
Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com>
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Message-id: 20170428075612.9997-1-kraxel@redhat.com
|
||||
---
|
||||
audio/audio.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/audio/audio.c b/audio/audio.c
|
||||
index c8898d8..beafed2 100644
|
||||
--- a/audio/audio.c
|
||||
+++ b/audio/audio.c
|
||||
@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
|
||||
sw = sw1;
|
||||
}
|
||||
LIST_REMOVE (cap, entries);
|
||||
+ qemu_free (cap->hw.mix_buf);
|
||||
+ qemu_free (cap->buf);
|
||||
qemu_free (cap);
|
||||
}
|
||||
return;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 26f670a244982335cc08943fb1ec099a2c81e42d Mon Sep 17 00:00:00 2001
|
||||
From: Li Qiang <liqiang6-s@360.cn>
|
||||
Date: Tue, 7 Feb 2017 03:15:03 -0800
|
||||
Subject: [PATCH] usb: ohci: fix error return code in servicing iso td
|
||||
|
||||
It should return 1 if an error occurs when reading iso td.
|
||||
This will avoid an infinite loop issue in ohci_service_ed_list.
|
||||
|
||||
Signed-off-by: Li Qiang <liqiang6-s@360.cn>
|
||||
Message-id: 5899ac3e.1033240a.944d5.9a2d@mx.google.com
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
---
|
||||
hw/usb-ohci.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
|
||||
index c82a92f..2cba3e3 100644
|
||||
--- a/hw/usb-ohci.c
|
||||
+++ b/hw/usb-ohci.c
|
||||
@@ -725,7 +725,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
|
||||
|
||||
if (!ohci_read_iso_td(addr, &iso_td)) {
|
||||
printf("usb-ohci: ISO_TD read error at %x\n", addr);
|
||||
- return 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
starting_frame = OHCI_BM(iso_td.flags, TD_SF);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
From 4299b90e9ba9ce5ca9024572804ba751aa1a7e70 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Tue, 18 Oct 2016 13:15:17 +0530
|
||||
Subject: [PATCH] display: cirrus: check vga bits per pixel(bpp) value
|
||||
|
||||
In Cirrus CLGD 54xx VGA Emulator, if cirrus graphics mode is VGA,
|
||||
'cirrus_get_bpp' returns zero(0), which could lead to a divide
|
||||
by zero error in while copying pixel data. The same could occur
|
||||
via blit pitch values. Add check to avoid it.
|
||||
|
||||
Reported-by: Huawei PSIRT <psirt@huawei.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Message-id: 1476776717-24807-1-git-send-email-ppandit@redhat.com
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
---
|
||||
hw/cirrus_vga.c | 14 ++++++++++----
|
||||
1 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
|
||||
index 3d712d5..bdb092e 100644
|
||||
--- a/hw/cirrus_vga.c
|
||||
+++ b/hw/cirrus_vga.c
|
||||
@@ -272,6 +272,9 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
|
||||
static bool blit_region_is_unsafe(struct CirrusVGAState *s,
|
||||
int32_t pitch, int32_t addr)
|
||||
{
|
||||
+ if (!pitch) {
|
||||
+ return true;
|
||||
+ }
|
||||
if (pitch < 0) {
|
||||
int64_t min = addr
|
||||
+ ((int64_t)s->cirrus_blt_height - 1) * pitch
|
||||
@@ -715,7 +718,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
|
||||
s->cirrus_addr_mask));
|
||||
}
|
||||
|
||||
-static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
+static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
{
|
||||
int sx = 0, sy = 0;
|
||||
int dx = 0, dy = 0;
|
||||
@@ -729,6 +732,9 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
int width, height;
|
||||
|
||||
depth = s->get_bpp((VGAState *)s) / 8;
|
||||
+ if (!depth) {
|
||||
+ return 0;
|
||||
+ }
|
||||
s->get_resolution((VGAState *)s, &width, &height);
|
||||
|
||||
/* extra x, y */
|
||||
@@ -783,6 +789,8 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
|
||||
s->cirrus_blt_height);
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
|
||||
@@ -790,11 +798,9 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
|
||||
if (blit_is_unsafe(s))
|
||||
return 0;
|
||||
|
||||
- cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
|
||||
+ return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
|
||||
s->cirrus_blt_srcaddr - s->start_addr,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
-
|
||||
- return 1;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
--
|
||||
1.7.0.4
|
||||
|
||||
3
sources
3
sources
|
|
@ -4,4 +4,5 @@ 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.10.1.tar.gz) = 236c02bee69e33644703ed26d323d4c491a91fc05bd0ee0990a7368579f7c82f5bb4510845bf80348fd923024d7d60d521f593dfd0365d971dc592f8ef10fbea
|
||||
SHA512 (mini-os-4.21.0.tar.xz) = 7543774d15da84476d93d04154990923c82209cb3fa125574c0383652c5a310957200f54b63b34502161f9c3afce4907e0060d9036f3eaf3a7cb6b1b3119b546
|
||||
SHA512 (xen-4.21.1.tar.xz) = 8dfe65255e202b3dacf9d0d7265636bc1f97627c11b08babc13a5b8e74c7c65e7e2c6a1513e28b3c713fe512edb6702a73b2bf667e2a8f2ce825b196a2cd5aab
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
--- xen-4.1.0-orig/tools/hotplug/Linux/vif-bridge 2008-08-22 10:49:07.000000000 +0100
|
||||
+++ xen-4.1.0-new/tools/hotplug/Linux/vif-bridge 2008-08-29 11:29:38.000000000 +0100
|
||||
@@ -96,8 +96,6 @@ case "$command" in
|
||||
;;
|
||||
esac
|
||||
|
||||
-handle_iptable
|
||||
-
|
||||
call_hooks vif post
|
||||
|
||||
log debug "Successful vif-bridge $command for $dev, bridge $bridge."
|
||||
--- xen-3.3.0-orig/tools/hotplug/Linux/xen-network-common.sh 2008-08-22 10:49:07.000000000 +0100
|
||||
+++ xen-3.3.0-new/tools/hotplug/Linux/xen-network-common.sh 2008-08-29 11:29:38.000000000 +0100
|
||||
@@ -99,6 +99,13 @@ create_bridge () {
|
||||
brctl addbr ${bridge}
|
||||
brctl stp ${bridge} off
|
||||
brctl setfd ${bridge} 0
|
||||
+ # Setting these to zero stops guest<->LAN traffic
|
||||
+ # traversing the bridge from hitting the *tables
|
||||
+ # rulesets. guest<->host traffic still gets processed
|
||||
+ # by the host's iptables rules so this isn't a hole
|
||||
+ sysctl -q -w "net.bridge.bridge-nf-call-arptables=0"
|
||||
+ sysctl -q -w "net.bridge.bridge-nf-call-ip6tables=0"
|
||||
+ sysctl -q -w "net.bridge.bridge-nf-call-iptables=0"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -1,56 +1,54 @@
|
|||
--- xen-4.9.0-rc1.2/tools/xenstore/xenstored_watch.c.orig 2017-04-12 16:18:57.000000000 +0100
|
||||
+++ xen-4.9.0-rc1.2/tools/xenstore/xenstored_watch.c 2017-04-13 21:17:12.255231094 +0100
|
||||
@@ -166,7 +166,7 @@
|
||||
/* check if valid event */
|
||||
} else {
|
||||
relative = !strstarts(vec[0], "/");
|
||||
- vec[0] = canonicalize(conn, in, vec[0]);
|
||||
+ vec[0] = xenstore_canonicalize(conn, in, vec[0]);
|
||||
if (!vec[0])
|
||||
return ENOMEM;
|
||||
if (!is_valid_nodename(vec[0]))
|
||||
@@ -219,7 +219,7 @@
|
||||
--- xen-4.18.0-rc1/tools/xenstored/watch.c.orig 2023-09-29 09:09:29.000000000 +0100
|
||||
+++ xen-4.18.0-rc1/tools/xenstored/watch.c 2023-10-02 16:12:14.971264769 +0100
|
||||
@@ -164,7 +164,7 @@
|
||||
const char **path, bool *relative)
|
||||
{
|
||||
*relative = !strstarts(*path, "/") && !strstarts(*path, "@");
|
||||
- *path = canonicalize(conn, ctx, *path, true);
|
||||
+ *path = xenstore_canonicalize(conn, ctx, *path, true);
|
||||
|
||||
return *path ? 0 : errno;
|
||||
}
|
||||
@@ -250,7 +250,7 @@
|
||||
if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec))
|
||||
return EINVAL;
|
||||
|
||||
- node = canonicalize(conn, in, vec[0]);
|
||||
+ node = xenstore_canonicalize(conn, in, vec[0]);
|
||||
- node = canonicalize(conn, ctx, vec[0], true);
|
||||
+ node = xenstore_canonicalize(conn, ctx, vec[0], true);
|
||||
if (!node)
|
||||
return ENOMEM;
|
||||
return errno;
|
||||
list_for_each_entry(watch, &conn->watches, list) {
|
||||
--- xen-4.9.0-rc1.2/tools/xenstore/xenstored_core.c.orig 2017-04-12 16:18:57.000000000 +0100
|
||||
+++ xen-4.9.0-rc1.2/tools/xenstore/xenstored_core.c 2017-04-13 21:19:35.668429881 +0100
|
||||
@@ -777,7 +777,7 @@
|
||||
--- xen-4.18.0-rc1/tools/xenstored/core.c.orig 2023-09-29 09:09:29.000000000 +0100
|
||||
+++ xen-4.18.0-rc1/tools/xenstored/core.c 2023-10-02 16:12:14.993264626 +0100
|
||||
@@ -1249,7 +1249,7 @@
|
||||
return strings;
|
||||
}
|
||||
|
||||
-char *canonicalize(struct connection *conn, const void *ctx, const char *node)
|
||||
+char *xenstore_canonicalize(struct connection *conn, const void *ctx, const char *node)
|
||||
-const char *canonicalize(struct connection *conn, const void *ctx,
|
||||
+const char *xenstore_canonicalize(struct connection *conn, const void *ctx,
|
||||
const char *node, bool allow_special)
|
||||
{
|
||||
const char *prefix;
|
||||
const char *name;
|
||||
@@ -1303,7 +1303,7 @@
|
||||
{
|
||||
struct node *node;
|
||||
|
||||
@@ -799,7 +799,7 @@
|
||||
- *canonical_name = canonicalize(conn, ctx, name, allow_special);
|
||||
+ *canonical_name = xenstore_canonicalize(conn, ctx, name, allow_special);
|
||||
if (!*canonical_name)
|
||||
return NULL;
|
||||
|
||||
if (!canonical_name)
|
||||
canonical_name = &tmp_name;
|
||||
- *canonical_name = canonicalize(conn, ctx, name);
|
||||
+ *canonical_name = xenstore_canonicalize(conn, ctx, name);
|
||||
return get_node(conn, ctx, *canonical_name, perm);
|
||||
}
|
||||
@@ -1320,7 +1320,7 @@
|
||||
const char *tmp_name;
|
||||
const struct node *node;
|
||||
|
||||
--- 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 @@
|
||||
void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
|
||||
- tmp_name = canonicalize(conn, ctx, name, allow_special);
|
||||
+ tmp_name = xenstore_canonicalize(conn, ctx, name, allow_special);
|
||||
if (!tmp_name)
|
||||
return NULL;
|
||||
|
||||
/* 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);
|
||||
--- 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
|
||||
--- xen-4.18.0-rc1/tools/console/testsuite/console-dom0.c.orig 2023-09-29 09:09:29.000000000 +0100
|
||||
+++ xen-4.18.0-rc1/tools/console/testsuite/console-dom0.c 2023-10-02 16:12:15.001264574 +0100
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
}
|
||||
|
|
@ -87,8 +85,8 @@
|
|||
fprintf(stderr, "%s", line);
|
||||
} while (strcmp(line, "Okay.\n") != 0);
|
||||
|
||||
--- xen-4.8.0/tools/console/testsuite/console-domU.c.orig 2016-12-05 12:03:27.000000000 +0000
|
||||
+++ xen-4.8.0/tools/console/testsuite/console-domU.c 2017-02-26 21:52:50.320622804 +0000
|
||||
--- xen-4.18.0-rc1/tools/console/testsuite/console-domU.c.orig 2023-09-29 09:09:29.000000000 +0100
|
||||
+++ xen-4.18.0-rc1/tools/console/testsuite/console-domU.c 2023-10-02 16:12:15.008264528 +0100
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -107,3 +105,14 @@
|
|||
seed = strtoul(line, 0, 0);
|
||||
|
||||
printf("Seed Okay.\n"); fflush(stdout);
|
||||
--- xen-4.18.0-rc1/tools/xenstored/core.h.orig 2023-09-29 09:09:29.000000000 +0100
|
||||
+++ xen-4.18.0-rc1/tools/xenstored/core.h 2023-10-02 16:12:15.015264482 +0100
|
||||
@@ -240,7 +240,7 @@
|
||||
void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
|
||||
|
||||
/* Canonicalize this path if possible. */
|
||||
-const char *canonicalize(struct connection *conn, const void *ctx,
|
||||
+const char *xenstore_canonicalize(struct connection *conn, const void *ctx,
|
||||
const char *node, bool allow_special);
|
||||
|
||||
/* Get access permissions. */
|
||||
|
|
|
|||
13
xen.efi.build.patch
Normal file
13
xen.efi.build.patch
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
--- xen-4.20.0-rc4/xen/arch/x86/arch.mk.orig 2025-02-07 11:56:01.000000000 +0000
|
||||
+++ xen-4.20.0-rc4/xen/arch/x86/arch.mk 2025-02-09 22:56:05.579507311 +0000
|
||||
@@ -95,7 +95,9 @@
|
||||
-c $(srctree)/$(efi-check).c -o $(efi-check).o,y)
|
||||
|
||||
# Check if the linker supports PE.
|
||||
-EFI_LDFLAGS := $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10 --enable-long-section-names
|
||||
+#EFI_LDFLAGS := $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10 --enable-long-section-names
|
||||
+# use a reduced set of options from LDFLAGS
|
||||
+EFI_LDFLAGS = --as-needed --build-id=sha1 -mi386pep --subsystem=10 --enable-long-section-names
|
||||
LD_PE_check_cmd = $(call ld-option,$(EFI_LDFLAGS) --image-base=0x100000000 -o $(efi-check).efi $(efi-check).o)
|
||||
XEN_BUILD_PE := $(LD_PE_check_cmd)
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
--- xen-4.5.1/tools/qemu-xen-traditional/vnc.c.orig 2015-07-12 21:55:32.875504811 +0100
|
||||
+++ xen-4.5.1/tools/qemu-xen-traditional/vnc.c 2015-07-12 22:03:03.860005391 +0100
|
||||
@@ -2140,7 +2140,7 @@
|
||||
GNUTLS_VERSION_NUMBER >= 0x020200 /* 2.2.0 */
|
||||
static int vnc_set_gnutls_priority(gnutls_session_t s, int x509)
|
||||
{
|
||||
- const char *priority = x509 ? "NORMAL" : "NORMAL:+ANON-DH";
|
||||
+ const char *priority = x509 ? "@SYSTEM" : "@SYSTEM:+ANON-DH";
|
||||
int rc;
|
||||
|
||||
rc = gnutls_priority_set_direct(s, priority, NULL);
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
--- xen-4.8.0/xen/arch/x86/Makefile.orig 2016-12-05 12:03:27.000000000 +0000
|
||||
+++ xen-4.8.0/xen/arch/x86/Makefile 2017-02-28 00:02:27.989589825 +0000
|
||||
@@ -73,6 +73,7 @@
|
||||
efi-y := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
|
||||
-O $(BASEDIR)/include/xen/compile.h ]; then \
|
||||
echo '$(TARGET).efi'; fi)
|
||||
+LD_EFI ?= $(LD)
|
||||
|
||||
ifneq ($(build_id_linker),)
|
||||
notes_phdrs = --notes
|
||||
@@ -173,20 +174,20 @@
|
||||
|
||||
$(TARGET).efi: prelink-efi.o $(note_file) efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc
|
||||
$(foreach base, $(VIRT_BASE) $(ALT_BASE), \
|
||||
- $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
|
||||
+ $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
|
||||
$(BASEDIR)/common/symbols-dummy.o $(note_file) -o $(@D)/.$(@F).$(base).0 &&) :
|
||||
$(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S
|
||||
$(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).0 \
|
||||
| $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).0s.S
|
||||
$(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o
|
||||
$(foreach base, $(VIRT_BASE) $(ALT_BASE), \
|
||||
- $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
|
||||
+ $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
|
||||
$(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o $(note_file) -o $(@D)/.$(@F).$(base).1 &&) :
|
||||
$(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S
|
||||
$(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \
|
||||
| $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S
|
||||
$(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o
|
||||
- $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
|
||||
+ $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
|
||||
$(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(note_file) -o $@
|
||||
if $(guard) false; then rm -f $@; echo 'EFI support disabled'; \
|
||||
else $(NM) -pa --format=sysv $(@D)/$(@F) \
|
||||
--- xen-4.9.0-rc1.2/xen/arch/x86/efi/Makefile.orig 2017-04-12 16:18:57.000000000 +0100
|
||||
+++ xen-4.9.0-rc1.2/xen/arch/x86/efi/Makefile 2017-04-13 21:05:54.170387130 +0100
|
||||
@@ -1,8 +1,9 @@
|
||||
CFLAGS += -fshort-wchar
|
||||
+LD_EFI ?= $(LD)
|
||||
|
||||
efi := y$(shell rm -f disabled)
|
||||
efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
|
||||
-efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
|
||||
+efi := $(if $(efi),$(shell $(LD_EFI) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
|
||||
efi := $(if $(efi),$(shell rm disabled)y)
|
||||
|
||||
%.o: %.ihex
|
||||
--- xen-4.8.0/xen/Makefile.orig 2016-12-05 12:03:27.000000000 +0000
|
||||
+++ xen-4.8.0/xen/Makefile 2017-02-28 00:02:54.080529810 +0000
|
||||
@@ -20,6 +20,7 @@
|
||||
MAKEFLAGS += -rR
|
||||
|
||||
EFI_MOUNTPOINT ?= $(BOOT_DIR)/efi
|
||||
+EFI_VENDOR=fedora
|
||||
|
||||
ARCH=$(XEN_TARGET_ARCH)
|
||||
SRCARCH=$(shell echo $(ARCH) | sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g')
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
diff -uN xen-4.5.0/tools/hotplug/Linux/systemd.orig/Makefile xen-4.5.0/tools/hotplug/Linux/systemd/Makefile
|
||||
--- xen-4.5.0/tools/hotplug/Linux/systemd.orig/Makefile 2015-01-12 16:53:24.000000000 +0000
|
||||
+++ xen-4.5.0/tools/hotplug/Linux/systemd/Makefile 2015-01-25 22:23:26.000000000 +0000
|
||||
@@ -14,7 +14,8 @@
|
||||
--- xen-4.17.0/tools/hotplug/Linux/systemd/Makefile.orig 2022-12-08 18:03:08.000000000 +0000
|
||||
+++ xen-4.17.0/tools/hotplug/Linux/systemd/Makefile 2022-12-09 19:47:53.227189371 +0000
|
||||
@@ -10,7 +10,8 @@
|
||||
XEN_SYSTEMD_SERVICE += xen-qemu-dom0-disk-backend.service
|
||||
XEN_SYSTEMD_SERVICE += xendomains.service
|
||||
XEN_SYSTEMD_SERVICE += xen-watchdog.service
|
||||
|
|
@ -10,16 +9,7 @@ diff -uN xen-4.5.0/tools/hotplug/Linux/systemd.orig/Makefile xen-4.5.0/tools/hot
|
|||
+XEN_SYSTEMD_SERVICE += oxenstored.service
|
||||
XEN_SYSTEMD_SERVICE += xendriverdomain.service
|
||||
|
||||
ALL_XEN_SYSTEMD = $(XEN_SYSTEMD_MODULES) \
|
||||
diff -uN xen-4.5.0/tools/hotplug/Linux/systemd.orig/var-lib-xenstored.mount.in xen-4.5.0/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in
|
||||
--- xen-4.5.0/tools/hotplug/Linux/systemd.orig/var-lib-xenstored.mount.in 2015-01-12 16:53:24.000000000 +0000
|
||||
+++ xen-4.5.0/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in 2015-01-25 22:28:59.000000000 +0000
|
||||
@@ -9,4 +9,4 @@
|
||||
What=xenstore
|
||||
Where=@XEN_LIB_STORED@
|
||||
Type=tmpfs
|
||||
-Options=mode=755
|
||||
+Options=mode=755,context="system_u:object_r:xenstored_var_lib_t:s0"
|
||||
ALL_XEN_SYSTEMD := $(XEN_SYSTEMD_MODULES) \
|
||||
diff -uN xen-4.5.0/tools/hotplug/Linux/systemd.orig/xenconsoled.service.in xen-4.5.0/tools/hotplug/Linux/systemd/xenconsoled.service.in
|
||||
--- xen-4.5.0/tools/hotplug/Linux/systemd.orig/xenconsoled.service.in 2015-01-12 16:53:24.000000000 +0000
|
||||
+++ xen-4.5.0/tools/hotplug/Linux/systemd/xenconsoled.service.in 2015-01-25 22:30:26.000000000 +0000
|
||||
|
|
@ -59,27 +49,26 @@ diff -uN xen-4.5.0/tools/hotplug/Linux/systemd.orig/xen-qemu-dom0-disk-backend.s
|
|||
Before=xendomains.service libvirtd.service libvirt-guests.service
|
||||
RefuseManualStop=true
|
||||
ConditionPathExists=/proc/xen/capabilities
|
||||
--- xen-4.6.0/tools/configure.ac.orig 2015-02-15 16:47:22.000000000 +0000
|
||||
+++ xen-4.6.0/tools/configure.ac 2015-03-01 16:18:30.493647587 +0000
|
||||
@@ -382,9 +382,9 @@
|
||||
--- xen-4.17.0/tools/configure.ac.orig 2022-12-08 18:03:08.000000000 +0000
|
||||
+++ xen-4.17.0/tools/configure.ac 2022-12-09 19:50:24.773193862 +0000
|
||||
@@ -481,8 +481,8 @@
|
||||
|
||||
AS_IF([test "x$systemd" = "xy"], [
|
||||
AC_CONFIG_FILES([
|
||||
+ hotplug/Linux/systemd/oxenstored.service
|
||||
hotplug/Linux/systemd/proc-xen.mount
|
||||
hotplug/Linux/systemd/var-lib-xenstored.mount
|
||||
- hotplug/Linux/systemd/xen-init-dom0.service
|
||||
hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service
|
||||
hotplug/Linux/systemd/xen-watchdog.service
|
||||
hotplug/Linux/systemd/xenconsoled.service
|
||||
--- xen-4.6.0/tools/configure.orig 2015-02-15 16:47:22.000000000 +0000
|
||||
+++ xen-4.6.0/tools/configure 2015-03-01 16:20:10.648285840 +0000
|
||||
@@ -8995,7 +8995,7 @@
|
||||
--- xen-4.17.0/tools/configure.orig 2022-12-08 18:03:08.000000000 +0000
|
||||
+++ xen-4.17.0/tools/configure 2022-12-09 19:51:43.278708226 +0000
|
||||
@@ -10081,7 +10081,7 @@
|
||||
if test "x$systemd" = "xy"
|
||||
then :
|
||||
|
||||
if test "x$systemd" = "xy"; then :
|
||||
|
||||
- ac_config_files="$ac_config_files hotplug/Linux/systemd/proc-xen.mount hotplug/Linux/systemd/var-lib-xenstored.mount hotplug/Linux/systemd/xen-init-dom0.service hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hotplug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.service hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xenstored.service"
|
||||
+ ac_config_files="$ac_config_files hotplug/Linux/systemd/oxenstored.service hotplug/Linux/systemd/proc-xen.mount hotplug/Linux/systemd/var-lib-xenstored.mount hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hotplug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.service hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xenstored.service"
|
||||
- ac_config_files="$ac_config_files hotplug/Linux/systemd/proc-xen.mount hotplug/Linux/systemd/xen-init-dom0.service hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hotplug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.service hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xenstored.service"
|
||||
+ ac_config_files="$ac_config_files hotplug/Linux/systemd/oxenstored.service hotplug/Linux/systemd/proc-xen.mount hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hotplug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.service hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xenstored.service"
|
||||
|
||||
|
||||
fi
|
||||
|
|
|
|||
24
xen.gcc11.fixes.patch
Normal file
24
xen.gcc11.fixes.patch
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
--- xen-4.14.0/xen/include/crypto/vmac.h.orig 2020-07-23 16:07:51.000000000 +0100
|
||||
+++ xen-4.14.0/xen/include/crypto/vmac.h 2020-10-24 15:45:49.246467465 +0100
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
#define vmac_update vhash_update
|
||||
|
||||
-void vhash_update(unsigned char m[],
|
||||
+void vhash_update(uint8_t *m,
|
||||
unsigned int mbytes,
|
||||
vmac_ctx_t *ctx);
|
||||
|
||||
diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c
|
||||
index 320e06f..618ae92 100644
|
||||
--- a/xen/arch/x86/tboot.c
|
||||
+++ b/xen/arch/x86/tboot.c
|
||||
@@ -91,7 +91,7 @@ static void __init tboot_copy_memory(unsigned char *va, uint32_t size,
|
||||
|
||||
void __init tboot_probe(void)
|
||||
{
|
||||
- tboot_shared_t *tboot_shared;
|
||||
+ tboot_shared_t * volatile tboot_shared;
|
||||
static const uuid_t __initconst tboot_shared_uuid = TBOOT_SHARED_UUID;
|
||||
|
||||
/* Look for valid page-aligned address for shared page. */
|
||||
10
xen.gcc12.fixes.patch
Normal file
10
xen.gcc12.fixes.patch
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
--- xen-4.16.0/Config.mk.orig 2021-11-30 11:42:42.000000000 +0000
|
||||
+++ xen-4.16.0/Config.mk 2022-01-24 20:25:16.687125822 +0000
|
||||
@@ -186,6 +186,7 @@
|
||||
|
||||
$(call cc-option-add,CFLAGS,CC,-Wno-unused-but-set-variable)
|
||||
$(call cc-option-add,CFLAGS,CC,-Wno-unused-local-typedefs)
|
||||
+$(call cc-option-add,CFLAGS,CC,-Wno-error=array-bounds)
|
||||
|
||||
LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i))
|
||||
CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
--- xen-4.8.0/extras/mini-os/Makefile.orig 2016-09-28 12:09:38.000000000 +0100
|
||||
+++ xen-4.8.0/extras/mini-os/Makefile 2017-02-15 21:15:19.340197960 +0000
|
||||
@@ -142,6 +142,9 @@
|
||||
APP_LDLIBS += -lz
|
||||
APP_LDLIBS += -lm
|
||||
LDLIBS += -lc
|
||||
+ifeq ($(MINIOS_TARGET_ARCH),x86_32)
|
||||
+LDLIBS += -L$(shell dirname `gcc -m32 -print-libgcc-file-name`) -lgcc
|
||||
+endif
|
||||
endif
|
||||
|
||||
ifneq ($(APP_OBJS)-$(lwip),-y)
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
--- xen-4.10.0/tools/libxc/xc_pm.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/libxc/xc_pm.c 2018-02-10 21:33:02.116856335 +0000
|
||||
@@ -305,7 +305,7 @@
|
||||
sysctl.cmd = XEN_SYSCTL_pm_op;
|
||||
sysctl.u.pm_op.cmd = SET_CPUFREQ_GOV;
|
||||
sysctl.u.pm_op.cpuid = cpuid;
|
||||
- strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN);
|
||||
+ strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN - 1);
|
||||
scaling_governor[CPUFREQ_NAME_LEN - 1] = '\0';
|
||||
|
||||
return xc_sysctl(xch, &sysctl);
|
||||
--- xen-4.10.0/tools/misc/xenperf.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/misc/xenperf.c 2018-02-10 21:46:09.154694376 +0000
|
||||
@@ -176,7 +176,7 @@
|
||||
continue;
|
||||
if ( (j < 64) && hypercall_name_table[j] )
|
||||
strncpy(hypercall_name, hypercall_name_table[j],
|
||||
- sizeof(hypercall_name));
|
||||
+ sizeof(hypercall_name)-1);
|
||||
else
|
||||
snprintf(hypercall_name, sizeof(hypercall_name), "[%d]", j);
|
||||
hypercall_name[sizeof(hypercall_name)-1]='\0';
|
||||
--- xen-4.10.0/tools/misc/xen-lowmemd.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/misc/xen-lowmemd.c 2018-02-10 22:12:45.366114605 +0000
|
||||
@@ -41,7 +41,7 @@
|
||||
xc_dominfo_t dom0_info;
|
||||
xc_physinfo_t info;
|
||||
unsigned long long free_pages, dom0_pages, diff, dom0_target;
|
||||
- char data[BUFSZ], error[BUFSZ];
|
||||
+ char data[BUFSZ], error[BUFSZ + 36];
|
||||
|
||||
if (xc_physinfo(xch, &info) < 0)
|
||||
{
|
||||
@@ -77,7 +77,7 @@
|
||||
if (!xs_write(xs_handle, XBT_NULL,
|
||||
"/local/domain/0/memory/target", data, strlen(data)))
|
||||
{
|
||||
- snprintf(error, BUFSZ,"Failed to write target %s to xenstore", data);
|
||||
+ snprintf(error, BUFSZ + 36,"Failed to write target %s to xenstore", data);
|
||||
perror(error);
|
||||
}
|
||||
}
|
||||
--- xen-4.10.0/tools/xenpmd/xenpmd.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/xenpmd/xenpmd.c 2018-02-10 23:02:16.162049075 +0000
|
||||
@@ -186,25 +186,25 @@
|
||||
|
||||
if ( strstr(attrib_name, "model number") )
|
||||
{
|
||||
- strncpy(info->model_number, attrib_value, 32);
|
||||
+ strncpy(info->model_number, attrib_value, 31);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strstr(attrib_name, "serial number") )
|
||||
{
|
||||
- strncpy(info->serial_number, attrib_value, 32);
|
||||
+ strncpy(info->serial_number, attrib_value, 31);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strstr(attrib_name, "battery type") )
|
||||
{
|
||||
- strncpy(info->battery_type, attrib_value, 32);
|
||||
+ strncpy(info->battery_type, attrib_value, 31);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strstr(attrib_name, "OEM info") )
|
||||
{
|
||||
- strncpy(info->oem_info, attrib_value, 32);
|
||||
+ strncpy(info->oem_info, attrib_value, 31);
|
||||
return;
|
||||
}
|
||||
|
||||
--- xen-4.10.0/tools/debugger/gdbsx/gx/gx_main.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/debugger/gdbsx/gx/gx_main.c 2018-02-10 23:39:39.211459635 +0000
|
||||
@@ -382,7 +382,7 @@
|
||||
|
||||
/* TBD: check if we stopped because of watchpoint */
|
||||
if (watchpoint_stop()) {
|
||||
- strncpy(buf, "watch:", 6);
|
||||
+ strncpy(buf, "watch:", 7);
|
||||
buf += 6;
|
||||
/* TBD: **/
|
||||
}
|
||||
--- xen-4.10.0/tools/ocaml/libs/xc/xenctrl_stubs.c.orig 2018-02-22 19:09:08.609546441 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/libs/xc/xenctrl_stubs.c 2018-02-22 19:24:25.622166925 +0000
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
static void Noreturn failwith_xc(xc_interface *xch)
|
||||
{
|
||||
- char error_str[1028];
|
||||
+ char error_str[1029];
|
||||
if (xch) {
|
||||
const xc_error *error = xc_get_last_error(xch);
|
||||
if (error->code == XC_ERROR_NONE)
|
||||
--- xen-4.10.0/tools/libxl/libxl_arm_acpi.c.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/libxl/libxl_arm_acpi.c 2018-02-28 12:37:08.887221211 +0000
|
||||
@@ -190,7 +190,7 @@
|
||||
struct acpi_table_rsdp *rsdp = (void *)dom->acpi_modules[0].data + offset;
|
||||
|
||||
memcpy(rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
|
||||
- memcpy(rsdp->oem_id, ACPI_OEM_ID, sizeof(rsdp->oem_id));
|
||||
+ memcpy(rsdp->oem_id, ACPI_OEM_ID, sizeof(ACPI_OEM_ID));
|
||||
rsdp->length = acpitables[RSDP].size;
|
||||
rsdp->revision = 0x02;
|
||||
rsdp->xsdt_physical_address = acpitables[XSDT].addr;
|
||||
@@ -205,11 +205,11 @@
|
||||
memcpy(h->signature, sig, 4);
|
||||
h->length = len;
|
||||
h->revision = rev;
|
||||
- memcpy(h->oem_id, ACPI_OEM_ID, sizeof(h->oem_id));
|
||||
- memcpy(h->oem_table_id, ACPI_OEM_TABLE_ID, sizeof(h->oem_table_id));
|
||||
+ memcpy(h->oem_id, ACPI_OEM_ID, sizeof(ACPI_OEM_ID));
|
||||
+ memcpy(h->oem_table_id, ACPI_OEM_TABLE_ID, sizeof(ACPI_OEM_TABLE_ID));
|
||||
h->oem_revision = 0;
|
||||
memcpy(h->asl_compiler_id, ACPI_ASL_COMPILER_ID,
|
||||
- sizeof(h->asl_compiler_id));
|
||||
+ sizeof(ACPI_ASL_COMPILER_ID));
|
||||
h->asl_compiler_revision = 0;
|
||||
h->checksum = 0;
|
||||
}
|
||||
--- xen-4.10.0/tools/xenpmd/xenpmd.c.orig 2018-02-28 16:18:50.377726049 +0000
|
||||
+++ xen-4.10.0/tools/xenpmd/xenpmd.c 2018-02-28 16:20:31.502426829 +0000
|
||||
@@ -352,7 +352,7 @@
|
||||
strlen(info->model_number) +
|
||||
strlen(info->serial_number) +
|
||||
strlen(info->battery_type) +
|
||||
- strlen(info->oem_info) + 4));
|
||||
+ strlen(info->oem_info) + 4) & 0xff);
|
||||
write_ulong_lsb_first(val+2, info->present);
|
||||
write_ulong_lsb_first(val+10, info->design_capacity);
|
||||
write_ulong_lsb_first(val+18, info->last_full_capacity);
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
--- xen-4.10.0/tools/Makefile.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/Makefile 2018-02-27 12:04:44.376192357 +0000
|
||||
@@ -8,7 +8,7 @@
|
||||
SUBDIRS-y += libs
|
||||
SUBDIRS-y += libxc
|
||||
SUBDIRS-y += flask
|
||||
-SUBDIRS-y += fuzz
|
||||
+#SUBDIRS-y += fuzz
|
||||
SUBDIRS-y += xenstore
|
||||
SUBDIRS-y += misc
|
||||
SUBDIRS-y += examples
|
||||
--- xen-4.10.0/tools/libacpi/Makefile.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/libacpi/Makefile 2018-02-27 21:12:56.928470227 +0000
|
||||
@@ -89,7 +89,7 @@
|
||||
@echo
|
||||
@exit 1
|
||||
|
||||
-build.o: ssdt_s3.h ssdt_s4.h ssdt_pm.h ssdt_tpm.h ssdt_laptop_slate.h
|
||||
+build.o: ssdt_s3.h ssdt_s4.h ssdt_pm.h ssdt_tpm.h ssdt_laptop_slate.h $(H_SRC)
|
||||
|
||||
acpi.a: $(OBJS)
|
||||
$(AR) rc $@ $(OBJS)
|
||||
--- xen-4.10.0/tools/debugger/kdd/kdd.c.orig 2018-02-22 12:31:57.007039159 +0000
|
||||
+++ xen-4.10.0/tools/debugger/kdd/kdd.c 2018-02-22 18:27:37.213653422 +0000
|
||||
@@ -687,7 +687,7 @@
|
||||
}
|
||||
} else {
|
||||
/* 32-bit control-register space starts at 0x[2]cc, for 84 bytes */
|
||||
- uint64_t offset = addr;
|
||||
+/* uint64_t offset = addr;
|
||||
if (offset > 0x200)
|
||||
offset -= 0x200;
|
||||
offset -= 0xcc;
|
||||
@@ -696,7 +696,9 @@
|
||||
len = 0;
|
||||
} else {
|
||||
memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
|
||||
- }
|
||||
+ } */
|
||||
+ /* disable above code due to compile issue for now */
|
||||
+ len = 0;
|
||||
}
|
||||
|
||||
s->txp.cmd.mem.addr = addr;
|
||||
23
xen.gcc9.fixes.patch
Normal file
23
xen.gcc9.fixes.patch
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
--- xen-4.11.1/xen/drivers/passthrough/vtd/vtd.h.orig 2018-11-29 14:04:11.000000000 +0000
|
||||
+++ xen-4.11.1/xen/drivers/passthrough/vtd/vtd.h 2019-02-05 21:32:50.056774501 +0000
|
||||
@@ -28,7 +28,7 @@
|
||||
/* Allow for both IOAPIC and IOSAPIC. */
|
||||
#define IO_xAPIC_route_entry IO_APIC_route_entry
|
||||
|
||||
-struct IO_APIC_route_remap_entry {
|
||||
+struct __packed IO_APIC_route_remap_entry {
|
||||
union {
|
||||
u64 val;
|
||||
struct {
|
||||
--- xen-4.11.1/xen/arch/x86/cpu/mtrr/generic.c.orig 2018-11-29 14:04:11.000000000 +0000
|
||||
+++ xen-4.11.1/xen/arch/x86/cpu/mtrr/generic.c 2019-02-10 19:24:09.378805103 +0000
|
||||
@@ -171,6 +171,9 @@
|
||||
printk("%sMTRR variable ranges %sabled:\n", level,
|
||||
mtrr_state.enabled ? "en" : "dis");
|
||||
width = (paddr_bits - PAGE_SHIFT + 3) / 4;
|
||||
+ if ( width > 64 ) {
|
||||
+ width=64;
|
||||
+ }
|
||||
|
||||
for (i = 0; i < num_var_ranges; ++i) {
|
||||
if (mtrr_state.var_ranges[i].mask & MTRR_PHYSMASK_VALID)
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
From 6b8d820bbe5c4aeba8601b31a650f6e6cd12843e Mon Sep 17 00:00:00 2001
|
||||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Date: Fri, 18 May 2018 11:39:07 +0200
|
||||
Subject: [PATCH] x86: correct ordering of operations during S3 resume
|
||||
|
||||
Microcode loading needs to happen before re-enabling interrupts, in case
|
||||
only updated microcode allows the use of e.g. the SPEC_{CTRL,CMD} MSRs.
|
||||
Otoh it doesn't need to happen at all when we didn't suspend in the
|
||||
first place. It needs to happen before spin_debug_enable() though, as it
|
||||
acquires a lock and hence would otherwise make
|
||||
common/spinlock.c:check_lock() unhappy. As micrcode loading can be
|
||||
pretty verbose, also make sure it only runs after console_end_sync().
|
||||
|
||||
cpufreq_add_cpu() doesn't need calling on the only "goto enable_cpu"
|
||||
path, which sits ahead of cpufreq_del_cpu().
|
||||
|
||||
Reported-by: Simon Gaiser <simon@invisiblethingslab.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
master commit: cb2a4a449dfd50af309a333aa805835015fbc8c8
|
||||
master date: 2018-04-16 14:08:30 +0200
|
||||
---
|
||||
xen/arch/x86/acpi/power.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
|
||||
index 1e4e5680a7..cb06f842cd 100644
|
||||
--- a/xen/arch/x86/acpi/power.c
|
||||
+++ b/xen/arch/x86/acpi/power.c
|
||||
@@ -203,6 +203,7 @@ static int enter_state(u32 state)
|
||||
printk(XENLOG_ERR "Some devices failed to power down.");
|
||||
system_state = SYS_STATE_resume;
|
||||
device_power_up(error);
|
||||
+ console_end_sync();
|
||||
error = -EIO;
|
||||
goto done;
|
||||
}
|
||||
@@ -243,17 +244,19 @@ static int enter_state(u32 state)
|
||||
if ( (state == ACPI_STATE_S3) && error )
|
||||
tboot_s3_error(error);
|
||||
|
||||
+ console_end_sync();
|
||||
+
|
||||
+ microcode_resume_cpu(0);
|
||||
+
|
||||
done:
|
||||
spin_debug_enable();
|
||||
local_irq_restore(flags);
|
||||
- console_end_sync();
|
||||
acpi_sleep_post(state);
|
||||
if ( hvm_cpu_up() )
|
||||
BUG();
|
||||
+ cpufreq_add_cpu(0);
|
||||
|
||||
enable_cpu:
|
||||
- cpufreq_add_cpu(0);
|
||||
- microcode_resume_cpu(0);
|
||||
rcu_barrier();
|
||||
mtrr_aps_sync_begin();
|
||||
enable_nonboot_cpus();
|
||||
--
|
||||
2.11.0
|
||||
|
||||
88
xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch
Normal file
88
xen.git-90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3.patch
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
From 90b20547b756a5cf9b0fec9fb0de5b361e8bf4c3 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Fri, 10 Apr 2026 21:55:46 +0100
|
||||
Subject: [PATCH] x86/amd: Mitigate AMD-SN-7053 / FP-DSS
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=utf8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is XSA-488 / CVE-2025-54505
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
(cherry picked from commit 99912d346009fda1e7fb1510c9501fbab17e92a0)
|
||||
---
|
||||
xen/arch/x86/cpu/amd.c | 37 ++++++++++++++++++++++++++++
|
||||
xen/arch/x86/include/asm/msr-index.h | 1 +
|
||||
2 files changed, 38 insertions(+)
|
||||
|
||||
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
|
||||
index 8c55d233f3..1bb0766ebf 100644
|
||||
--- a/xen/arch/x86/cpu/amd.c
|
||||
+++ b/xen/arch/x86/cpu/amd.c
|
||||
@@ -1048,6 +1048,42 @@ void amd_init_de_cfg(const struct cpuinfo_x86 *c)
|
||||
wrmsrl(MSR_AMD64_DE_CFG, val | new);
|
||||
}
|
||||
|
||||
+static void amd_init_fp_cfg(const struct cpuinfo_x86 *c)
|
||||
+{
|
||||
+ uint64_t val, new = 0;
|
||||
+
|
||||
+ /* If virtualised, we won't have mutable access even if we can read it. */
|
||||
+ if ( cpu_has_hypervisor )
|
||||
+ return;
|
||||
+
|
||||
+ /*
|
||||
+ * On Zen1, mitigate SB-7053 / FP-DSS Floating Point Divider State
|
||||
+ * Sampling by setting bit 9 as instructed.
|
||||
+ */
|
||||
+ if ( c->family == 0x17 && is_zen1_uarch() )
|
||||
+ new |= 1 << 9;
|
||||
+
|
||||
+ /*
|
||||
+ * Avoid reading FP_CFG if we don't intend to change anything. The
|
||||
+ * register doesn't exist on all families.
|
||||
+ */
|
||||
+ if ( !new )
|
||||
+ return;
|
||||
+
|
||||
+ val = rdmsr(MSR_AMD64_FP_CFG);
|
||||
+
|
||||
+ if ( (val & new) == new )
|
||||
+ return;
|
||||
+
|
||||
+ /*
|
||||
+ * FP_CFG is a Core-scoped MSR, and this write is racy. However, both
|
||||
+ * threads calculate the new value from state which expected to be
|
||||
+ * consistent across CPUs and unrelated to the old value, so the result
|
||||
+ * should be consistent.
|
||||
+ */
|
||||
+ wrmsr(MSR_AMD64_FP_CFG, val | new);
|
||||
+}
|
||||
+
|
||||
void __init amd_init_lfence_dispatch(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
@@ -1120,6 +1156,7 @@ static void cf_check init_amd(struct cpuinfo_x86 *c)
|
||||
uint64_t value;
|
||||
|
||||
amd_init_de_cfg(c);
|
||||
+ amd_init_fp_cfg(c);
|
||||
|
||||
if (c == &boot_cpu_data)
|
||||
amd_init_lfence_dispatch(); /* Needs amd_init_de_cfg() */
|
||||
diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h
|
||||
index df52587c85..6c5b2569e1 100644
|
||||
--- a/xen/arch/x86/include/asm/msr-index.h
|
||||
+++ b/xen/arch/x86/include/asm/msr-index.h
|
||||
@@ -428,6 +428,7 @@
|
||||
#define MSR_AMD64_LS_CFG 0xc0011020U
|
||||
#define MSR_AMD64_IC_CFG 0xc0011021U
|
||||
#define MSR_AMD64_DC_CFG 0xc0011022U
|
||||
+#define MSR_AMD64_FP_CFG 0xc0011028U
|
||||
#define MSR_AMD64_DE_CFG 0xc0011029U
|
||||
#define AMD64_DE_CFG_LFENCE_SERIALISE (_AC(1, ULL) << 1)
|
||||
#define MSR_AMD64_EX_CFG 0xc001102cU
|
||||
--
|
||||
2.39.5
|
||||
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
From a7f8880adc1604335e42920340c127ba7c51b0a5 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Fri, 18 May 2018 11:41:53 +0200
|
||||
Subject: [PATCH] x86/spec_ctrl: Updates to retpoline-safety decision making
|
||||
|
||||
All of this is as recommended by the Intel whitepaper:
|
||||
|
||||
https://software.intel.com/sites/default/files/managed/1d/46/Retpoline-A-Branch-Target-Injection-Mitigation.pdf
|
||||
|
||||
The 'RSB Alternative' bit in MSR_ARCH_CAPABILITIES may be set by a hypervisor
|
||||
to indicate that the virtual machine may migrate to a processor which isn't
|
||||
retpoline-safe. Introduce a shortened name (to reduce code volume), treat it
|
||||
as authorative in retpoline_safe(), and print its value along with the other
|
||||
ARCH_CAPS bits.
|
||||
|
||||
The exact processor models which do have RSB semantics which fall back to BTB
|
||||
predictions are enumerated, and include Kabylake and Coffeelake. Leave a
|
||||
printk() in the default case to help identify cases which aren't covered.
|
||||
|
||||
The exact microcode versions from Broadwell RSB-safety are taken from the
|
||||
referenced microcode update file (adjusting for the known-bad microcode
|
||||
versions). Despite the exact wording of the text, it is only Broadwell
|
||||
processors which need a microcode check.
|
||||
|
||||
In practice, this means that all Broadwell hardware with up-to-date microcode
|
||||
will use retpoline in preference to IBRS, which will be a performance
|
||||
improvement for desktop and server systems which would previously always opt
|
||||
for IBRS over retpoline.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
x86/spec_ctrl: Fix typo in ARCH_CAPS decode
|
||||
|
||||
Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Acked-by: Jan Beulich <jbeulich@suse.com>
|
||||
master commit: 1232378bd2fef45f613db049b33852fdf84d7ddf
|
||||
master date: 2018-04-19 17:28:23 +0100
|
||||
master commit: 27170adb54a558e11defcd51989326a9beb95afe
|
||||
master date: 2018-04-24 13:34:12 +0100
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 51 +++++++++++++++++++++++++++++++++++------
|
||||
xen/include/asm-x86/msr-index.h | 1 +
|
||||
2 files changed, 45 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 3c7447bfe6..fa67a0ffbd 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -97,12 +97,13 @@ static void __init print_details(enum ind_thunk thunk)
|
||||
printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
|
||||
|
||||
/* Hardware features which pertain to speculative mitigations. */
|
||||
- printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s\n",
|
||||
+ printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s%s\n",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "",
|
||||
(e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "",
|
||||
(caps & ARCH_CAPABILITIES_IBRS_ALL) ? " IBRS_ALL" : "",
|
||||
- (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : "");
|
||||
+ (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : "",
|
||||
+ (caps & ARCH_CAPS_RSBA) ? " RSBA" : "");
|
||||
|
||||
/* Compiled-in support which pertains to BTI mitigations. */
|
||||
if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
|
||||
@@ -135,6 +136,20 @@ static bool __init retpoline_safe(void)
|
||||
boot_cpu_data.x86 != 6 )
|
||||
return false;
|
||||
|
||||
+ if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
|
||||
+ {
|
||||
+ uint64_t caps;
|
||||
+
|
||||
+ rdmsrl(MSR_ARCH_CAPABILITIES, caps);
|
||||
+
|
||||
+ /*
|
||||
+ * RBSA may be set by a hypervisor to indicate that we may move to a
|
||||
+ * processor which isn't retpoline-safe.
|
||||
+ */
|
||||
+ if ( caps & ARCH_CAPS_RSBA )
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
switch ( boot_cpu_data.x86_model )
|
||||
{
|
||||
case 0x17: /* Penryn */
|
||||
@@ -161,18 +176,40 @@ static bool __init retpoline_safe(void)
|
||||
* versions.
|
||||
*/
|
||||
case 0x3d: /* Broadwell */
|
||||
- return ucode_rev >= 0x28;
|
||||
+ return ucode_rev >= 0x2a;
|
||||
case 0x47: /* Broadwell H */
|
||||
- return ucode_rev >= 0x1b;
|
||||
+ return ucode_rev >= 0x1d;
|
||||
case 0x4f: /* Broadwell EP/EX */
|
||||
- return ucode_rev >= 0xb000025;
|
||||
+ return ucode_rev >= 0xb000021;
|
||||
case 0x56: /* Broadwell D */
|
||||
- return false; /* TBD. */
|
||||
+ switch ( boot_cpu_data.x86_mask )
|
||||
+ {
|
||||
+ case 2: return ucode_rev >= 0x15;
|
||||
+ case 3: return ucode_rev >= 0x7000012;
|
||||
+ case 4: return ucode_rev >= 0xf000011;
|
||||
+ case 5: return ucode_rev >= 0xe000009;
|
||||
+ default:
|
||||
+ printk("Unrecognised CPU stepping %#x - assuming not reptpoline safe\n",
|
||||
+ boot_cpu_data.x86_mask);
|
||||
+ return false;
|
||||
+ }
|
||||
+ break;
|
||||
|
||||
/*
|
||||
- * Skylake and later processors are not retpoline-safe.
|
||||
+ * Skylake, Kabylake and Cannonlake processors are not retpoline-safe.
|
||||
*/
|
||||
+ case 0x4e:
|
||||
+ case 0x55:
|
||||
+ case 0x5e:
|
||||
+ case 0x66:
|
||||
+ case 0x67:
|
||||
+ case 0x8e:
|
||||
+ case 0x9e:
|
||||
+ return false;
|
||||
+
|
||||
default:
|
||||
+ printk("Unrecognised CPU model %#x - assuming not reptpoline safe\n",
|
||||
+ boot_cpu_data.x86_model);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
|
||||
index a8ceecf3e2..bb6295790c 100644
|
||||
--- a/xen/include/asm-x86/msr-index.h
|
||||
+++ b/xen/include/asm-x86/msr-index.h
|
||||
@@ -42,6 +42,7 @@
|
||||
#define MSR_ARCH_CAPABILITIES 0x0000010a
|
||||
#define ARCH_CAPABILITIES_RDCL_NO (_AC(1, ULL) << 0)
|
||||
#define ARCH_CAPABILITIES_IBRS_ALL (_AC(1, ULL) << 1)
|
||||
+#define ARCH_CAPS_RSBA (_AC(1, ULL) << 2)
|
||||
|
||||
/* Intel MSRs. Some also available on other CPUs */
|
||||
#define MSR_IA32_PERFCTR0 0x000000c1
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
From d93ae631a49289992dabb7bcd08358afc5f22b56 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Date: Fri, 18 May 2018 11:39:38 +0200
|
||||
Subject: [PATCH] x86: suppress BTI mitigations around S3 suspend/resume
|
||||
|
||||
NMI and #MC can occur at any time after S3 resume, yet the MSR_SPEC_CTRL
|
||||
may become available only once we're reloaded microcode. Make
|
||||
SPEC_CTRL_ENTRY_FROM_INTR_IST and DO_SPEC_CTRL_EXIT_TO_XEN no-ops for
|
||||
the critical period of time.
|
||||
|
||||
Also set the MSR back to its intended value.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
x86: Use spec_ctrl_{enter,exit}_idle() in the S3/S5 path
|
||||
|
||||
The main purpose of this patch is to avoid opencoding the recovery logic at
|
||||
the end, but also has the positive side effect of relaxing the SPEC_CTRL
|
||||
mitigations when working to shut the final CPU down.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
master commit: 710a8ebf2bc111a34bba04d1c85b6d07ed3d9389
|
||||
master date: 2018-04-16 14:09:55 +0200
|
||||
master commit: ef3ab46493f650b7e5cca2b2578a99ca0cbff195
|
||||
master date: 2018-04-19 10:55:59 +0100
|
||||
---
|
||||
xen/arch/x86/acpi/power.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
|
||||
index cb06f842cd..f7085d3c7b 100644
|
||||
--- a/xen/arch/x86/acpi/power.c
|
||||
+++ b/xen/arch/x86/acpi/power.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <asm/tboot.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/io_apic.h>
|
||||
+#include <asm/spec_ctrl.h>
|
||||
#include <acpi/cpufreq/cpufreq.h>
|
||||
|
||||
uint32_t system_reset_counter = 1;
|
||||
@@ -163,6 +164,7 @@ static int enter_state(u32 state)
|
||||
{
|
||||
unsigned long flags;
|
||||
int error;
|
||||
+ struct cpu_info *ci;
|
||||
unsigned long cr4;
|
||||
|
||||
if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
|
||||
@@ -210,6 +212,11 @@ static int enter_state(u32 state)
|
||||
else
|
||||
error = 0;
|
||||
|
||||
+ ci = get_cpu_info();
|
||||
+ spec_ctrl_enter_idle(ci);
|
||||
+ /* Avoid NMI/#MC using MSR_SPEC_CTRL until we've reloaded microcode. */
|
||||
+ ci->bti_ist_info = 0;
|
||||
+
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
switch ( state )
|
||||
@@ -248,6 +255,10 @@ static int enter_state(u32 state)
|
||||
|
||||
microcode_resume_cpu(0);
|
||||
|
||||
+ /* Re-enabled default NMI/#MC use of MSR_SPEC_CTRL. */
|
||||
+ ci->bti_ist_info = default_bti_ist_info;
|
||||
+ spec_ctrl_exit_idle(ci);
|
||||
+
|
||||
done:
|
||||
spin_debug_enable();
|
||||
local_irq_restore(flags);
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
--- xen-4.7.0/tools/blktap2/control/tap-ctl-allocate.c.orig 2016-06-20 11:38:15.000000000 +0100
|
||||
+++ xen-4.7.0/tools/blktap2/control/tap-ctl-allocate.c 2016-09-02 10:07:55.964084808 +0100
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
+#include <sys/sysmacros.h>
|
||||
#include <linux/major.h>
|
||||
|
||||
#include "tap-ctl.h"
|
||||
--- xen-4.7.0/tools/libxl/libxl_internal.h.orig 2016-06-20 11:38:15.000000000 +0100
|
||||
+++ xen-4.7.0/tools/libxl/libxl_internal.h 2016-09-02 17:35:24.853783711 +0100
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
+#include <sys/sysmacros.h>
|
||||
|
||||
#include <xenevtchn.h>
|
||||
#include <xenstore.h>
|
||||
|
|
@ -1,79 +1,208 @@
|
|||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Xen/x86 4.10.0 Configuration
|
||||
# Xen/x86 4.20 Configuration
|
||||
#
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=150001
|
||||
CONFIG_CLANG_VERSION=0
|
||||
CONFIG_LD_IS_GNU=y
|
||||
CONFIG_CC_HAS_VISIBILITY_ATTRIBUTE=y
|
||||
CONFIG_CC_SPLIT_SECTIONS=y
|
||||
CONFIG_FUNCTION_ALIGNMENT_16B=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=16
|
||||
CONFIG_X86_64=y
|
||||
CONFIG_X86=y
|
||||
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
|
||||
CONFIG_CC_HAS_INDIRECT_THUNK=y
|
||||
CONFIG_HAS_AS_CET_SS=y
|
||||
CONFIG_HAS_CC_CET_IBT=y
|
||||
|
||||
#
|
||||
# Architecture Features
|
||||
#
|
||||
CONFIG_AMD=y
|
||||
CONFIG_INTEL=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_NR_NUMA_NODES=64
|
||||
CONFIG_PV=y
|
||||
CONFIG_PV32=y
|
||||
CONFIG_PV_LINEAR_PT=y
|
||||
CONFIG_HVM=y
|
||||
CONFIG_AMD_SVM=y
|
||||
CONFIG_INTEL_VMX=y
|
||||
CONFIG_XEN_SHSTK=y
|
||||
CONFIG_XEN_IBT=y
|
||||
CONFIG_SHADOW_PAGING=y
|
||||
# CONFIG_BIGMEM is not set
|
||||
# CONFIG_HVM_FEP is not set
|
||||
CONFIG_TBOOT=y
|
||||
CONFIG_HVM_FEP=y
|
||||
CONFIG_X86_PSR=y
|
||||
CONFIG_XEN_ALIGN_DEFAULT=y
|
||||
# CONFIG_XEN_ALIGN_2M is not set
|
||||
# CONFIG_X2APIC_PHYSICAL is not set
|
||||
CONFIG_X2APIC_MIXED=y
|
||||
# CONFIG_XEN_GUEST is not set
|
||||
# CONFIG_HYPERV_GUEST is not set
|
||||
# CONFIG_REQUIRE_NX is not set
|
||||
CONFIG_ALTP2M=y
|
||||
# end of Architecture Features
|
||||
|
||||
#
|
||||
# Common Features
|
||||
#
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_CORE_PARKING=y
|
||||
CONFIG_GRANT_TABLE=y
|
||||
CONFIG_ALTERNATIVE_CALL=y
|
||||
CONFIG_ARCH_MAP_DOMAIN_PAGE=y
|
||||
CONFIG_GENERIC_BUG_FRAME=y
|
||||
CONFIG_HAS_ALTERNATIVE=y
|
||||
CONFIG_HAS_COMPAT=y
|
||||
CONFIG_HAS_DIT=y
|
||||
CONFIG_HAS_EX_TABLE=y
|
||||
CONFIG_HAS_MEM_ACCESS=y
|
||||
CONFIG_HAS_MEM_PAGING=y
|
||||
CONFIG_HAS_MEM_SHARING=y
|
||||
CONFIG_HAS_PDX=y
|
||||
CONFIG_HAS_KEXEC=y
|
||||
CONFIG_HAS_GDBSX=y
|
||||
CONFIG_HAS_FAST_MULTIPLY=y
|
||||
CONFIG_HAS_IOPORTS=y
|
||||
CONFIG_HAS_KEXEC=y
|
||||
CONFIG_HAS_PIRQ=y
|
||||
CONFIG_HAS_SCHED_GRANULARITY=y
|
||||
CONFIG_HAS_UBSAN=y
|
||||
CONFIG_HAS_VMAP=y
|
||||
CONFIG_MEM_ACCESS_ALWAYS_ON=y
|
||||
CONFIG_MEM_ACCESS=y
|
||||
CONFIG_NEEDS_LIBELF=y
|
||||
CONFIG_NUMA=y
|
||||
|
||||
#
|
||||
# Speculative hardening
|
||||
#
|
||||
CONFIG_INDIRECT_THUNK=y
|
||||
CONFIG_RETURN_THUNK=y
|
||||
CONFIG_SPECULATIVE_HARDEN_ARRAY=y
|
||||
CONFIG_SPECULATIVE_HARDEN_BRANCH=y
|
||||
CONFIG_SPECULATIVE_HARDEN_GUEST_ACCESS=y
|
||||
CONFIG_SPECULATIVE_HARDEN_LOCK=y
|
||||
# end of Speculative hardening
|
||||
|
||||
# CONFIG_DIT_DEFAULT is not set
|
||||
CONFIG_HYPFS=y
|
||||
CONFIG_HYPFS_CONFIG=y
|
||||
CONFIG_IOREQ_SERVER=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_TMEM=y
|
||||
CONFIG_XENOPROF=y
|
||||
# CONFIG_XSM is not set
|
||||
CONFIG_SCHED_CREDIT=y
|
||||
CONFIG_SCHED_CREDIT2=y
|
||||
CONFIG_SCHED_RTDS=y
|
||||
CONFIG_SCHED_ARINC653=y
|
||||
CONFIG_SCHED_NULL=y
|
||||
CONFIG_SCHED_DEFAULT="credit"
|
||||
CONFIG_CRYPTO=y
|
||||
CONFIG_SCHED_DEFAULT="credit2"
|
||||
# CONFIG_BOOT_TIME_CPUPOOLS is not set
|
||||
CONFIG_LIVEPATCH=y
|
||||
CONFIG_FAST_SYMBOL_LOOKUP=y
|
||||
CONFIG_ENFORCE_UNIQUE_SYMBOLS=y
|
||||
CONFIG_CMDLINE=""
|
||||
CONFIG_DOM0_MEM=""
|
||||
CONFIG_DTB_FILE=""
|
||||
CONFIG_TRACEBUFFER=y
|
||||
# end of Common Features
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
CONFIG_ACPI=y
|
||||
CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_ACPI_NUMA=y
|
||||
CONFIG_HAS_NS16550=y
|
||||
CONFIG_HAS_EHCI=y
|
||||
CONFIG_SERIAL_TX_BUFSIZE=32768
|
||||
# CONFIG_XHCI is not set
|
||||
CONFIG_HAS_CPUFREQ=y
|
||||
CONFIG_HAS_PASSTHROUGH=y
|
||||
CONFIG_AMD_IOMMU=y
|
||||
CONFIG_INTEL_IOMMU=y
|
||||
# CONFIG_IOMMU_QUARANTINE_NONE is not set
|
||||
CONFIG_IOMMU_QUARANTINE_BASIC=y
|
||||
# CONFIG_IOMMU_QUARANTINE_SCRATCH_PAGE is not set
|
||||
CONFIG_HAS_PCI=y
|
||||
CONFIG_HAS_PCI_MSI=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_VGA=y
|
||||
CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
|
||||
CONFIG_XEN_GUEST=n
|
||||
CONFIG_HAS_VPCI=y
|
||||
# end of Device Drivers
|
||||
|
||||
# CONFIG_EXPERT is not set
|
||||
# CONFIG_UNSUPPORTED is not set
|
||||
CONFIG_ARCH_SUPPORTS_INT128=y
|
||||
CONFIG_ARCH_VCPU_IOREQ_COMPLETION=y
|
||||
|
||||
#
|
||||
# Debugging Options
|
||||
#
|
||||
# CONFIG_DEBUG is not set
|
||||
CONFIG_GDBSX=y
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_SELF_TESTS=y
|
||||
# CONFIG_DEBUG_LOCK_PROFILE is not set
|
||||
CONFIG_DEBUG_LOCKS=y
|
||||
# CONFIG_PERF_COUNTERS is not set
|
||||
CONFIG_VERBOSE_DEBUG=y
|
||||
CONFIG_SCRUB_DEBUG=y
|
||||
# CONFIG_UBSAN is not set
|
||||
# CONFIG_DEBUG_TRACE is not set
|
||||
CONFIG_XMEM_POOL_POISON=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# end of Debugging Options
|
||||
|
||||
# ARM64 settings
|
||||
CONFIG_MMU=y
|
||||
CONFIG_ARM_64=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_EFI=y
|
||||
CONFIG_GICV2=y
|
||||
CONFIG_GICV3=y
|
||||
CONFIG_VGICV2=y
|
||||
# CONFIG_NEW_VGIC is not set
|
||||
CONFIG_SBSA_VUART_CONSOLE=y
|
||||
CONFIG_HWDOM_VUART=y
|
||||
CONFIG_ARM_SSBD=y
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
||||
CONFIG_STATIC_EVTCHN=y
|
||||
CONFIG_PARTIAL_EMULATION=y
|
||||
|
||||
#
|
||||
# ARM errata workaround via the alternative framework
|
||||
#
|
||||
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_WORKAROUND_REPEAT_TLBI=y
|
||||
CONFIG_ARM64_ERRATUM_1286807=y
|
||||
CONFIG_ARM64_ERRATUM_1508412=y
|
||||
|
||||
CONFIG_SBSA_VUART_CONSOLE=y
|
||||
# end of ARM errata workaround via the alternative framework
|
||||
CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR=y
|
||||
CONFIG_ALL_PLAT=y
|
||||
# CONFIG_QEMU is not set
|
||||
# CONFIG_RCAR3 is not set
|
||||
# CONFIG_MPSOC is not set
|
||||
# CONFIG_NO_PLAT is not set
|
||||
CONFIG_ALL64_PLAT=y
|
||||
CONFIG_MPSOC_PLATFORM=y
|
||||
|
||||
#
|
||||
# Common Features
|
||||
#
|
||||
CONFIG_HAS_DEVICE_TREE=y
|
||||
CONFIG_HAS_CADENCE_UART=y
|
||||
CONFIG_HAS_LINFLEX=y
|
||||
CONFIG_HAS_IMX_LPUART=y
|
||||
CONFIG_HAS_MVEBU=y
|
||||
CONFIG_HAS_MESON=y
|
||||
CONFIG_HAS_PL011=y
|
||||
CONFIG_HAS_OMAP=y
|
||||
CONFIG_HAS_SCIF=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
# CONFIG_IPMMU_VMSA is not set
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
--- xen-4.10.1/tools/libacpi/Makefile.orig 2018-06-15 22:05:18.875735520 +0100
|
||||
+++ xen-4.10.1/tools/libacpi/Makefile 2018-06-15 22:07:16.087982920 +0100
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
$(H_SRC): $(ACPI_BUILD_DIR)/%.h: %.asl iasl
|
||||
iasl -vs -p $(ACPI_BUILD_DIR)/$*.$(TMP_SUFFIX) -tc $<
|
||||
- sed -e 's/AmlCode/$*/g' $(ACPI_BUILD_DIR)/$*.hex >$@
|
||||
+ sed -e 's/_aml_code//g' $(ACPI_BUILD_DIR)/$*.hex >$@
|
||||
rm -f $(addprefix $(ACPI_BUILD_DIR)/, $*.aml $*.hex)
|
||||
|
||||
$(MK_DSDT): mk_dsdt.c
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
$(C_SRC): $(ACPI_BUILD_DIR)/%.c: iasl $(ACPI_BUILD_DIR)/%.asl
|
||||
iasl -vs -p $(ACPI_BUILD_DIR)/$*.$(TMP_SUFFIX) -tc $(ACPI_BUILD_DIR)/$*.asl
|
||||
- sed -e 's/AmlCode/$*/g' $(ACPI_BUILD_DIR)/$*.hex > $@.$(TMP_SUFFIX)
|
||||
+ sed -e 's/_aml_code//g' $(ACPI_BUILD_DIR)/$*.hex > $@.$(TMP_SUFFIX)
|
||||
echo "int $*_len=sizeof($*);" >> $@.$(TMP_SUFFIX)
|
||||
mv -f $@.$(TMP_SUFFIX) $@
|
||||
rm -f $(addprefix $(ACPI_BUILD_DIR)/, $*.aml $*.hex)
|
||||
27
xen.json.nocpuid.patch
Normal file
27
xen.json.nocpuid.patch
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
--- xen-4.21.0/tools/libs/light/libxl_nocpuid.c.orig 2025-11-18 18:02:13.000000000 +0000
|
||||
+++ xen-4.21.0/tools/libs/light/libxl_nocpuid.c 2025-11-20 09:03:56.517804514 +0000
|
||||
@@ -40,11 +40,24 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_LIBJSONC
|
||||
+#ifndef _hidden
|
||||
+#define _hidden
|
||||
+#endif
|
||||
+_hidden int libxl_cpuid_policy_list_gen_jso(json_object **jso_r,
|
||||
+ libxl_cpuid_policy_list *pcpuid)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#if defined(HAVE_LIBYAJL)
|
||||
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
|
||||
libxl_cpuid_policy_list *pcpuid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
|
||||
const libxl__json_object *o,
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
--- xen-4.10.0/tools/ocaml/libs/xc/xenctrl.ml.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/libs/xc/xenctrl.ml 2017-12-16 15:01:29.683432280 +0000
|
||||
@@ -263,7 +263,7 @@
|
||||
(* coredump *)
|
||||
let coredump xch domid fd =
|
||||
let dump s =
|
||||
- let wd = Unix.write fd s 0 (String.length s) in
|
||||
+ let wd = Unix.write fd (Bytes.of_string s) 0 (String.length s) in
|
||||
if wd <> String.length s then
|
||||
failwith "error while writing";
|
||||
in
|
||||
--- xen-4.10.0/tools/ocaml/libs/xb/xb.ml.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/libs/xb/xb.ml 2017-12-16 16:30:25.195726461 +0000
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
type backend = Fd of backend_fd | Xenmmap of backend_mmap
|
||||
|
||||
-type partial_buf = HaveHdr of Partial.pkt | NoHdr of int * string
|
||||
+type partial_buf = HaveHdr of Partial.pkt | NoHdr of int * bytes
|
||||
|
||||
type t =
|
||||
{
|
||||
@@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
let init_partial_in () = NoHdr
|
||||
- (Partial.header_size (), String.make (Partial.header_size()) '\000')
|
||||
+ (Partial.header_size (), Bytes.make (Partial.header_size()) '\000')
|
||||
|
||||
let reconnect t = match t.backend with
|
||||
| Fd _ ->
|
||||
@@ -76,7 +76,9 @@
|
||||
rd
|
||||
|
||||
let read_mmap back con s len =
|
||||
- let rd = Xs_ring.read back.mmap s len in
|
||||
+ let stmp = String.make len (char_of_int 0) in
|
||||
+ let rd = Xs_ring.read back.mmap stmp len in
|
||||
+ Bytes.blit_string stmp 0 s 0 rd;
|
||||
back.work_again <- (rd > 0);
|
||||
if rd > 0 then
|
||||
back.eventchn_notify ();
|
||||
@@ -100,7 +98,7 @@
|
||||
|
||||
let write con s len =
|
||||
match con.backend with
|
||||
- | Fd backfd -> write_fd backfd con s len
|
||||
+ | Fd backfd -> write_fd backfd con (Bytes.of_string s) len
|
||||
| Xenmmap backmmap -> write_mmap backmmap con s len
|
||||
|
||||
(* NB: can throw Reconnect *)
|
||||
@@ -131,7 +129,7 @@
|
||||
| NoHdr (i, buf) -> i in
|
||||
|
||||
(* try to get more data from input stream *)
|
||||
- let s = String.make to_read '\000' in
|
||||
+ let s = Bytes.make to_read '\000' in
|
||||
let sz = if to_read > 0 then read con s to_read else 0 in
|
||||
|
||||
(
|
||||
@@ -139,7 +137,7 @@
|
||||
| HaveHdr partial_pkt ->
|
||||
(* we complete the data *)
|
||||
if sz > 0 then
|
||||
- Partial.append partial_pkt s sz;
|
||||
+ Partial.append partial_pkt (Bytes.to_string s) sz;
|
||||
if Partial.to_complete partial_pkt = 0 then (
|
||||
let pkt = Packet.of_partialpkt partial_pkt in
|
||||
con.partial_in <- init_partial_in ();
|
||||
@@ -149,9 +147,9 @@
|
||||
| NoHdr (i, buf) ->
|
||||
(* we complete the partial header *)
|
||||
if sz > 0 then
|
||||
- String.blit s 0 buf (Partial.header_size () - i) sz;
|
||||
+ Bytes.blit s 0 buf (Partial.header_size () - i) sz;
|
||||
con.partial_in <- if sz = i then
|
||||
- HaveHdr (Partial.of_string buf) else NoHdr (i - sz, buf)
|
||||
+ HaveHdr (Partial.of_string (Bytes.to_string buf)) else NoHdr (i - sz, buf)
|
||||
);
|
||||
!newpacket
|
||||
|
||||
--- xen-4.10.0/tools/ocaml/libs/xb/xb.mli.orig 2018-03-09 19:02:47.853172392 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/libs/xb/xb.mli 2017-12-13 11:37:59.000000000 +0000
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
type backend_fd = { fd : Unix.file_descr; }
|
||||
type backend = Fd of backend_fd | Xenmmap of backend_mmap
|
||||
-type partial_buf = HaveHdr of Partial.pkt | NoHdr of int * string
|
||||
+type partial_buf = HaveHdr of Partial.pkt | NoHdr of int * bytes
|
||||
type t = {
|
||||
backend : backend;
|
||||
pkt_in : Packet.t Queue.t;
|
||||
@@ -76,10 +76,10 @@
|
||||
val init_partial_in : unit -> partial_buf
|
||||
val reconnect : t -> unit
|
||||
val queue : t -> Packet.t -> unit
|
||||
-val read_fd : backend_fd -> 'a -> string -> int -> int
|
||||
-val read_mmap : backend_mmap -> 'a -> string -> int -> int
|
||||
-val read : t -> string -> int -> int
|
||||
-val write_fd : backend_fd -> 'a -> string -> int -> int
|
||||
+val read_fd : backend_fd -> 'a -> bytes -> int -> int
|
||||
+val read_mmap : backend_mmap -> 'a -> bytes -> int -> int
|
||||
+val read : t -> bytes -> int -> int
|
||||
+val write_fd : backend_fd -> 'a -> bytes -> int -> int
|
||||
val write_mmap : backend_mmap -> 'a -> string -> int -> int
|
||||
val write : t -> string -> int -> int
|
||||
val output : t -> bool
|
||||
--- xen-4.10.0/tools/ocaml/xenstored/stdext.ml.orig 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/xenstored/stdext.ml 2017-12-16 16:39:35.645109021 +0000
|
||||
@@ -122,7 +122,7 @@
|
||||
let pid = Unix.getpid () in
|
||||
let buf = string_of_int pid ^ "\n" in
|
||||
let len = String.length buf in
|
||||
- if Unix.write fd buf 0 len <> len
|
||||
+ if Unix.write fd (Bytes.of_string buf) 0 len <> len
|
||||
then failwith "pidfile_write failed";
|
||||
)
|
||||
(fun () -> Unix.close fd)
|
||||
diff -ur xen-4.10.0.orig/tools/ocaml/xenstored/logging.ml xen-4.10.0/tools/ocaml/xenstored/logging.ml
|
||||
--- xen-4.10.0.orig/tools/ocaml/xenstored/logging.ml 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/xenstored/logging.ml 2017-12-16 23:24:47.402606119 +0000
|
||||
@@ -60,11 +60,11 @@
|
||||
let truncate_line nb_chars line =
|
||||
if String.length line > nb_chars - 1 then
|
||||
let len = max (nb_chars - 1) 2 in
|
||||
- let dst_line = String.create len in
|
||||
- String.blit line 0 dst_line 0 (len - 2);
|
||||
- dst_line.[len-2] <- '.';
|
||||
- dst_line.[len-1] <- '.';
|
||||
- dst_line
|
||||
+ let dst_line = Bytes.create len in
|
||||
+ Bytes.blit_string line 0 dst_line 0 (len - 2);
|
||||
+ Bytes.set dst_line (len-2) '.';
|
||||
+ Bytes.set dst_line (len-1) '.';
|
||||
+ Bytes.to_string dst_line
|
||||
else line
|
||||
|
||||
let log_rotate ref_ch log_file log_nb_files =
|
||||
@@ -252,13 +252,13 @@
|
||||
*)
|
||||
|
||||
let sanitize_data data =
|
||||
- let data = String.copy data in
|
||||
- for i = 0 to String.length data - 1
|
||||
+ let data = Bytes.copy data in
|
||||
+ for i = 0 to Bytes.length data - 1
|
||||
do
|
||||
- if data.[i] = '\000' then
|
||||
- data.[i] <- ' '
|
||||
+ if Bytes.get data i = '\000' then
|
||||
+ Bytes.set data i ' '
|
||||
done;
|
||||
- String.escaped data
|
||||
+ String.escaped (Bytes.to_string data)
|
||||
|
||||
let activate_access_log = ref true
|
||||
let access_log_destination = ref (File (Paths.xen_log_dir ^ "/xenstored-access.log"))
|
||||
@@ -291,7 +291,7 @@
|
||||
let date = string_of_date() in
|
||||
let tid = string_of_tid ~con tid in
|
||||
let access_type = string_of_access_type access_type in
|
||||
- let data = sanitize_data data in
|
||||
+ let data = sanitize_data (Bytes.of_string data) in
|
||||
let prefix = prefix !access_log_destination date in
|
||||
let msg = Printf.sprintf "%s %s %s %s" prefix tid access_type data in
|
||||
logger.write ~level msg)
|
||||
diff -ur xen-4.10.0.orig/tools/ocaml/xenstored/utils.ml xen-4.10.0/tools/ocaml/xenstored/utils.ml
|
||||
--- xen-4.10.0.orig/tools/ocaml/xenstored/utils.ml 2017-12-13 11:37:59.000000000 +0000
|
||||
+++ xen-4.10.0/tools/ocaml/xenstored/utils.ml 2017-12-16 23:26:24.968649002 +0000
|
||||
@@ -45,23 +45,23 @@
|
||||
|
||||
let hexify s =
|
||||
let hexseq_of_char c = sprintf "%02x" (Char.code c) in
|
||||
- let hs = String.create (String.length s * 2) in
|
||||
+ let hs = Bytes.create (String.length s * 2) in
|
||||
for i = 0 to String.length s - 1
|
||||
do
|
||||
let seq = hexseq_of_char s.[i] in
|
||||
- hs.[i * 2] <- seq.[0];
|
||||
- hs.[i * 2 + 1] <- seq.[1];
|
||||
+ Bytes.set hs (i * 2) seq.[0];
|
||||
+ Bytes.set hs (i * 2 + 1) seq.[1];
|
||||
done;
|
||||
- hs
|
||||
+ Bytes.to_string hs
|
||||
|
||||
let unhexify hs =
|
||||
let char_of_hexseq seq0 seq1 = Char.chr (int_of_string (sprintf "0x%c%c" seq0 seq1)) in
|
||||
- let s = String.create (String.length hs / 2) in
|
||||
- for i = 0 to String.length s - 1
|
||||
+ let s = Bytes.create (String.length hs / 2) in
|
||||
+ for i = 0 to Bytes.length s - 1
|
||||
do
|
||||
- s.[i] <- char_of_hexseq hs.[i * 2] hs.[i * 2 + 1]
|
||||
+ Bytes.set s i (char_of_hexseq hs.[i * 2] hs.[i * 2 + 1])
|
||||
done;
|
||||
- s
|
||||
+ Bytes.to_string s
|
||||
|
||||
let trim_path path =
|
||||
try
|
||||
@@ -84,10 +84,10 @@
|
||||
|
||||
let read_file_single_integer filename =
|
||||
let fd = Unix.openfile filename [ Unix.O_RDONLY ] 0o640 in
|
||||
- let buf = String.make 20 (char_of_int 0) in
|
||||
+ let buf = Bytes.make 20 (char_of_int 0) in
|
||||
let sz = Unix.read fd buf 0 20 in
|
||||
Unix.close fd;
|
||||
- int_of_string (String.sub buf 0 sz)
|
||||
+ int_of_string (Bytes.to_string (Bytes.sub buf 0 sz))
|
||||
|
||||
let path_complete path connection_path =
|
||||
if String.get path 0 <> '/' then
|
||||
22
xen.python3.12.patch
Normal file
22
xen.python3.12.patch
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
--- xen-4.17.1/tools/python/Makefile.orig 2023-04-27 13:53:19.000000000 +0100
|
||||
+++ xen-4.17.1/tools/python/Makefile 2023-06-22 22:21:25.287486906 +0100
|
||||
@@ -4,7 +4,7 @@
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
-PY_CFLAGS = $(CFLAGS) $(PY_NOOPT_CFLAGS)
|
||||
+PY_CFLAGS = $(CFLAGS) $(PY_NOOPT_CFLAGS) -Wno-error=declaration-after-statement
|
||||
PY_LDFLAGS = $(SHLIB_LDFLAGS) $(APPEND_LDFLAGS)
|
||||
INSTALL_LOG = build/installed_files.txt
|
||||
|
||||
--- xen-4.17.1/tools/pygrub/Makefile.orig 2023-04-27 13:53:19.000000000 +0100
|
||||
+++ xen-4.17.1/tools/pygrub/Makefile 2023-06-22 22:52:52.803047401 +0100
|
||||
@@ -2,7 +2,7 @@
|
||||
XEN_ROOT = $(CURDIR)/../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
-PY_CFLAGS = $(CFLAGS) $(PY_NOOPT_CFLAGS)
|
||||
+PY_CFLAGS = $(CFLAGS) $(PY_NOOPT_CFLAGS) -Wno-error=declaration-after-statement
|
||||
PY_LDFLAGS = $(SHLIB_LDFLAGS) $(APPEND_LDFLAGS)
|
||||
INSTALL_LOG = build/installed_files.txt
|
||||
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
--- xen-4.2.0/tools/firmware/hvmloader/Makefile.orig 2012-05-27 21:57:04.481812859 +0100
|
||||
+++ xen-4.2.0/tools/firmware/hvmloader/Makefile 2012-06-02 18:52:44.935034128 +0100
|
||||
@@ -48,7 +48,7 @@
|
||||
else
|
||||
CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
|
||||
endif
|
||||
-ETHERBOOT_ROMS := $(addprefix ../etherboot/ipxe/src/bin/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
|
||||
+ETHERBOOT_ROMS := $(addprefix /usr/share/ipxe/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
|
||||
endif
|
||||
|
||||
ROMS :=
|
||||
--- xen-4.2.0/Config.mk.orig 2012-05-27 21:57:04.479812884 +0100
|
||||
+++ xen-4.2.0/Config.mk 2012-06-02 18:55:14.087169469 +0100
|
||||
@@ -206,7 +206,7 @@
|
||||
# Wed Jun 22 14:53:24 2016 +0800
|
||||
# fw/msr_feature_control: add support to set MSR_IA32_FEATURE_CONTROL
|
||||
|
||||
-ETHERBOOT_NICS ?= rtl8139 8086100e
|
||||
+ETHERBOOT_NICS ?= 10ec8139 8086100e
|
||||
|
||||
|
||||
QEMU_TRADITIONAL_REVISION ?= xen-4.10.1
|
||||
--- xen-4.2.0/tools/firmware/Makefile.orig 2012-05-27 21:57:04.480812871 +0100
|
||||
+++ xen-4.2.0/tools/firmware/Makefile 2012-06-02 19:03:52.254691484 +0100
|
||||
@@ -10,7 +10,7 @@
|
||||
SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
|
||||
SUBDIRS-$(CONFIG_ROMBIOS) += rombios
|
||||
SUBDIRS-$(CONFIG_ROMBIOS) += vgabios
|
||||
-SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
|
||||
+#SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
|
||||
SUBDIRS-$(CONFIG_PV_SHIM) += xen-dir
|
||||
SUBDIRS-y += hvmloader
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
--- xen-4.6.3/tools/xenstore/xs.c.orig 2016-06-20 13:08:22.000000000 +0100
|
||||
+++ xen-4.6.3/tools/xenstore/xs.c 2016-07-10 21:05:57.082217329 +0100
|
||||
@@ -733,6 +733,7 @@
|
||||
if (!h->read_thr_exists) {
|
||||
sigset_t set, old_set;
|
||||
pthread_attr_t attr;
|
||||
+ int ptret;
|
||||
|
||||
if (pthread_attr_init(&attr) != 0) {
|
||||
mutex_unlock(&h->request_mutex);
|
||||
@@ -747,7 +748,12 @@
|
||||
sigfillset(&set);
|
||||
pthread_sigmask(SIG_SETMASK, &set, &old_set);
|
||||
|
||||
- if (pthread_create(&h->read_thr, &attr, read_thread, h) != 0) {
|
||||
+ ptret = pthread_create(&h->read_thr, &attr, read_thread, h);
|
||||
+ if ( (ptret == EINVAL) && (pthread_attr_setstacksize(&attr, READ_THREAD_STACKSIZE + (8*1024)) == 0) ) {
|
||||
+ /* have a second try with the bigger stacksize */
|
||||
+ ptret = pthread_create(&h->read_thr, &attr, read_thread, h);
|
||||
+ }
|
||||
+ if (ptret != 0) {
|
||||
pthread_sigmask(SIG_SETMASK, &old_set, NULL);
|
||||
pthread_attr_destroy(&attr);
|
||||
mutex_unlock(&h->request_mutex);
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/traps: Fix %dr6 handing in #DB handler
|
||||
|
||||
Most bits in %dr6 accumulate, rather than being set directly based on the
|
||||
current source of #DB. Have the handler follow the manuals guidance, which
|
||||
avoids leaking hypervisor debugging activities into guest context.
|
||||
|
||||
This is part of XSA-260 / CVE-2018-8897.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/traps.c 2018-04-13 15:29:36.006747135 +0200
|
||||
+++ b/xen/arch/x86/traps.c 2018-04-13 15:44:57.015516185 +0200
|
||||
@@ -1761,11 +1761,36 @@ static void ler_enable(void)
|
||||
|
||||
void do_debug(struct cpu_user_regs *regs)
|
||||
{
|
||||
+ unsigned long dr6;
|
||||
struct vcpu *v = current;
|
||||
|
||||
+ /* Stash dr6 as early as possible. */
|
||||
+ dr6 = read_debugreg(6);
|
||||
+
|
||||
if ( debugger_trap_entry(TRAP_debug, regs) )
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * At the time of writing (March 2018), on the subject of %dr6:
|
||||
+ *
|
||||
+ * The Intel manual says:
|
||||
+ * Certain debug exceptions may clear bits 0-3. The remaining contents
|
||||
+ * of the DR6 register are never cleared by the processor. To avoid
|
||||
+ * confusion in identifying debug exceptions, debug handlers should
|
||||
+ * clear the register (except bit 16, which they should set) before
|
||||
+ * returning to the interrupted task.
|
||||
+ *
|
||||
+ * The AMD manual says:
|
||||
+ * Bits 15:13 of the DR6 register are not cleared by the processor and
|
||||
+ * must be cleared by software after the contents have been read.
|
||||
+ *
|
||||
+ * Some bits are reserved set, some are reserved clear, and some bits
|
||||
+ * which were previously reserved set are reused and cleared by hardware.
|
||||
+ * For future compatibility, reset to the default value, which will allow
|
||||
+ * us to spot any bit being changed by hardware to its non-default value.
|
||||
+ */
|
||||
+ write_debugreg(6, X86_DR6_DEFAULT);
|
||||
+
|
||||
if ( !guest_mode(regs) )
|
||||
{
|
||||
if ( regs->eflags & X86_EFLAGS_TF )
|
||||
@@ -1798,7 +1823,8 @@ void do_debug(struct cpu_user_regs *regs
|
||||
}
|
||||
|
||||
/* Save debug status register where guest OS can peek at it */
|
||||
- v->arch.debugreg[6] = read_debugreg(6);
|
||||
+ v->arch.debugreg[6] |= (dr6 & ~X86_DR6_DEFAULT);
|
||||
+ v->arch.debugreg[6] &= (dr6 | ~X86_DR6_DEFAULT);
|
||||
|
||||
ler_enable();
|
||||
pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
|
||||
--- a/xen/include/asm-x86/debugreg.h 2015-02-11 09:36:29.000000000 +0100
|
||||
+++ b/xen/include/asm-x86/debugreg.h 2018-04-13 15:44:57.015516185 +0200
|
||||
@@ -24,6 +24,8 @@
|
||||
#define DR_STATUS_RESERVED_ZERO (~0xffffeffful) /* Reserved, read as zero */
|
||||
#define DR_STATUS_RESERVED_ONE 0xffff0ff0ul /* Reserved, read as one */
|
||||
|
||||
+#define X86_DR6_DEFAULT 0xffff0ff0ul /* Default %dr6 value. */
|
||||
+
|
||||
/* Now define a bunch of things for manipulating the control register.
|
||||
The top two bytes of the control register consist of 4 fields of 4
|
||||
bits - each field corresponds to one of the four debug registers,
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/pv: Move exception injection into {,compat_}test_all_events()
|
||||
|
||||
This allows paths to jump straight to {,compat_}test_all_events() and have
|
||||
injection of pending exceptions happen automatically, rather than requiring
|
||||
all calling paths to handle exceptions themselves.
|
||||
|
||||
The normal exception path is simplified as a result, and
|
||||
compat_post_handle_exception() is removed entirely.
|
||||
|
||||
This is part of XSA-260 / CVE-2018-8897.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/x86_64/compat/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/compat/entry.S
|
||||
@@ -39,6 +39,12 @@ ENTRY(compat_test_all_events)
|
||||
leaq irq_stat+IRQSTAT_softirq_pending(%rip),%rcx
|
||||
cmpl $0,(%rcx,%rax,1)
|
||||
jne compat_process_softirqs
|
||||
+
|
||||
+ /* Inject exception if pending. */
|
||||
+ lea VCPU_trap_bounce(%rbx), %rdx
|
||||
+ testb $TBF_EXCEPTION, TRAPBOUNCE_flags(%rdx)
|
||||
+ jnz .Lcompat_process_trapbounce
|
||||
+
|
||||
testb $1,VCPU_mce_pending(%rbx)
|
||||
jnz compat_process_mce
|
||||
.Lcompat_test_guest_nmi:
|
||||
@@ -68,6 +74,15 @@ compat_process_softirqs:
|
||||
call do_softirq
|
||||
jmp compat_test_all_events
|
||||
|
||||
+ ALIGN
|
||||
+/* %rbx: struct vcpu, %rdx: struct trap_bounce */
|
||||
+.Lcompat_process_trapbounce:
|
||||
+ sti
|
||||
+.Lcompat_bounce_exception:
|
||||
+ call compat_create_bounce_frame
|
||||
+ movb $0, TRAPBOUNCE_flags(%rdx)
|
||||
+ jmp compat_test_all_events
|
||||
+
|
||||
ALIGN
|
||||
/* %rbx: struct vcpu */
|
||||
compat_process_mce:
|
||||
@@ -189,15 +204,6 @@ ENTRY(cr4_pv32_restore)
|
||||
xor %eax, %eax
|
||||
ret
|
||||
|
||||
-/* %rdx: trap_bounce, %rbx: struct vcpu */
|
||||
-ENTRY(compat_post_handle_exception)
|
||||
- testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
|
||||
- jz compat_test_all_events
|
||||
-.Lcompat_bounce_exception:
|
||||
- call compat_create_bounce_frame
|
||||
- movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
- jmp compat_test_all_events
|
||||
-
|
||||
.section .text.entry, "ax", @progbits
|
||||
|
||||
/* See lstar_enter for entry register state. */
|
||||
--- a/xen/arch/x86/x86_64/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/entry.S
|
||||
@@ -42,6 +42,12 @@ test_all_events:
|
||||
leaq irq_stat+IRQSTAT_softirq_pending(%rip), %rcx
|
||||
cmpl $0, (%rcx, %rax, 1)
|
||||
jne process_softirqs
|
||||
+
|
||||
+ /* Inject exception if pending. */
|
||||
+ lea VCPU_trap_bounce(%rbx), %rdx
|
||||
+ testb $TBF_EXCEPTION, TRAPBOUNCE_flags(%rdx)
|
||||
+ jnz .Lprocess_trapbounce
|
||||
+
|
||||
cmpb $0, VCPU_mce_pending(%rbx)
|
||||
jne process_mce
|
||||
.Ltest_guest_nmi:
|
||||
@@ -70,6 +76,15 @@ process_softirqs:
|
||||
jmp test_all_events
|
||||
|
||||
ALIGN
|
||||
+/* %rbx: struct vcpu, %rdx struct trap_bounce */
|
||||
+.Lprocess_trapbounce:
|
||||
+ sti
|
||||
+.Lbounce_exception:
|
||||
+ call create_bounce_frame
|
||||
+ movb $0, TRAPBOUNCE_flags(%rdx)
|
||||
+ jmp test_all_events
|
||||
+
|
||||
+ ALIGN
|
||||
/* %rbx: struct vcpu */
|
||||
process_mce:
|
||||
testb $1 << VCPU_TRAP_MCE, VCPU_async_exception_mask(%rbx)
|
||||
@@ -667,15 +682,9 @@ handle_exception_saved:
|
||||
mov %r15, STACK_CPUINFO_FIELD(xen_cr3)(%r14)
|
||||
testb $3,UREGS_cs(%rsp)
|
||||
jz restore_all_xen
|
||||
- leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
movq VCPU_domain(%rbx),%rax
|
||||
testb $1,DOMAIN_is_32bit_pv(%rax)
|
||||
- jnz compat_post_handle_exception
|
||||
- testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
|
||||
- jz test_all_events
|
||||
-.Lbounce_exception:
|
||||
- call create_bounce_frame
|
||||
- movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
+ jnz compat_test_all_events
|
||||
jmp test_all_events
|
||||
|
||||
/* No special register assumptions. */
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/traps: Use an Interrupt Stack Table for #DB
|
||||
|
||||
PV guests can use architectural corner cases to cause #DB to be raised after
|
||||
transitioning into supervisor mode.
|
||||
|
||||
Use an interrupt stack table for #DB to prevent the exception being taken with
|
||||
a guest controlled stack pointer.
|
||||
|
||||
This is part of XSA-260 / CVE-2018-8897.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/cpu/common.c
|
||||
+++ b/xen/arch/x86/cpu/common.c
|
||||
@@ -679,6 +679,7 @@ void load_system_tables(void)
|
||||
[IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE,
|
||||
[IST_DF - 1] = stack_top + IST_DF * PAGE_SIZE,
|
||||
[IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE,
|
||||
+ [IST_DB - 1] = stack_top + IST_DB * PAGE_SIZE,
|
||||
|
||||
[IST_MAX ... ARRAY_SIZE(tss->ist) - 1] =
|
||||
0x8600111111111111ul,
|
||||
@@ -706,6 +707,7 @@ void load_system_tables(void)
|
||||
set_ist(&idt_tables[cpu][TRAP_double_fault], IST_DF);
|
||||
set_ist(&idt_tables[cpu][TRAP_nmi], IST_NMI);
|
||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_MCE);
|
||||
+ set_ist(&idt_tables[cpu][TRAP_debug], IST_DB);
|
||||
|
||||
/*
|
||||
* Bottom-of-stack must be 16-byte aligned!
|
||||
--- a/xen/arch/x86/hvm/svm/svm.c
|
||||
+++ b/xen/arch/x86/hvm/svm/svm.c
|
||||
@@ -1046,6 +1046,7 @@ static void svm_ctxt_switch_from(struct
|
||||
set_ist(&idt_tables[cpu][TRAP_double_fault], IST_DF);
|
||||
set_ist(&idt_tables[cpu][TRAP_nmi], IST_NMI);
|
||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_MCE);
|
||||
+ set_ist(&idt_tables[cpu][TRAP_debug], IST_DB);
|
||||
}
|
||||
|
||||
static void svm_ctxt_switch_to(struct vcpu *v)
|
||||
@@ -1067,6 +1068,7 @@ static void svm_ctxt_switch_to(struct vc
|
||||
set_ist(&idt_tables[cpu][TRAP_double_fault], IST_NONE);
|
||||
set_ist(&idt_tables[cpu][TRAP_nmi], IST_NONE);
|
||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
|
||||
+ set_ist(&idt_tables[cpu][TRAP_debug], IST_NONE);
|
||||
|
||||
svm_restore_dr(v);
|
||||
|
||||
--- a/xen/arch/x86/smpboot.c
|
||||
+++ b/xen/arch/x86/smpboot.c
|
||||
@@ -964,6 +964,7 @@ static int cpu_smpboot_alloc(unsigned in
|
||||
set_ist(&idt_tables[cpu][TRAP_double_fault], IST_NONE);
|
||||
set_ist(&idt_tables[cpu][TRAP_nmi], IST_NONE);
|
||||
set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
|
||||
+ set_ist(&idt_tables[cpu][TRAP_debug], IST_NONE);
|
||||
|
||||
for ( stub_page = 0, i = cpu & ~(STUBS_PER_PAGE - 1);
|
||||
i < nr_cpu_ids && i <= (cpu | (STUBS_PER_PAGE - 1)); ++i )
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -325,13 +325,13 @@ static void show_guest_stack(struct vcpu
|
||||
/*
|
||||
* Notes for get_stack_trace_bottom() and get_stack_dump_bottom()
|
||||
*
|
||||
- * Stack pages 0, 1 and 2:
|
||||
+ * Stack pages 0 - 3:
|
||||
* These are all 1-page IST stacks. Each of these stacks have an exception
|
||||
* frame and saved register state at the top. The interesting bound for a
|
||||
* trace is the word adjacent to this, while the bound for a dump is the
|
||||
* very top, including the exception frame.
|
||||
*
|
||||
- * Stack pages 3, 4 and 5:
|
||||
+ * Stack pages 4 and 5:
|
||||
* None of these are particularly interesting. With MEMORY_GUARD, page 5 is
|
||||
* explicitly not present, so attempting to dump or trace it is
|
||||
* counterproductive. Without MEMORY_GUARD, it is possible for a call chain
|
||||
@@ -352,12 +352,12 @@ unsigned long get_stack_trace_bottom(uns
|
||||
{
|
||||
switch ( get_stack_page(sp) )
|
||||
{
|
||||
- case 0 ... 2:
|
||||
+ case 0 ... 3:
|
||||
return ROUNDUP(sp, PAGE_SIZE) -
|
||||
offsetof(struct cpu_user_regs, es) - sizeof(unsigned long);
|
||||
|
||||
#ifndef MEMORY_GUARD
|
||||
- case 3 ... 5:
|
||||
+ case 4 ... 5:
|
||||
#endif
|
||||
case 6 ... 7:
|
||||
return ROUNDUP(sp, STACK_SIZE) -
|
||||
@@ -372,11 +372,11 @@ unsigned long get_stack_dump_bottom(unsi
|
||||
{
|
||||
switch ( get_stack_page(sp) )
|
||||
{
|
||||
- case 0 ... 2:
|
||||
+ case 0 ... 3:
|
||||
return ROUNDUP(sp, PAGE_SIZE) - sizeof(unsigned long);
|
||||
|
||||
#ifndef MEMORY_GUARD
|
||||
- case 3 ... 5:
|
||||
+ case 4 ... 5:
|
||||
#endif
|
||||
case 6 ... 7:
|
||||
return ROUNDUP(sp, STACK_SIZE) - sizeof(unsigned long);
|
||||
@@ -1943,6 +1943,7 @@ void __init init_idt_traps(void)
|
||||
set_ist(&idt_table[TRAP_double_fault], IST_DF);
|
||||
set_ist(&idt_table[TRAP_nmi], IST_NMI);
|
||||
set_ist(&idt_table[TRAP_machine_check], IST_MCE);
|
||||
+ set_ist(&idt_table[TRAP_debug], IST_DB);
|
||||
|
||||
/* CPU0 uses the master IDT. */
|
||||
idt_tables[0] = idt_table;
|
||||
--- a/xen/arch/x86/x86_64/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/entry.S
|
||||
@@ -739,7 +739,7 @@ ENTRY(device_not_available)
|
||||
ENTRY(debug)
|
||||
pushq $0
|
||||
movl $TRAP_debug,4(%rsp)
|
||||
- jmp handle_exception
|
||||
+ jmp handle_ist_exception
|
||||
|
||||
ENTRY(int3)
|
||||
pushq $0
|
||||
--- a/xen/include/asm-x86/processor.h
|
||||
+++ b/xen/include/asm-x86/processor.h
|
||||
@@ -443,7 +443,8 @@ struct __packed __cacheline_aligned tss_
|
||||
#define IST_DF 1UL
|
||||
#define IST_NMI 2UL
|
||||
#define IST_MCE 3UL
|
||||
-#define IST_MAX 3UL
|
||||
+#define IST_DB 4UL
|
||||
+#define IST_MAX 4UL
|
||||
|
||||
/* Set the interrupt stack table used by a particular interrupt
|
||||
* descriptor table entry. */
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/traps: Fix handling of #DB exceptions in hypervisor context
|
||||
|
||||
The WARN_ON() can be triggered by guest activities, and emits a full stack
|
||||
trace without rate limiting. Swap it out for a ratelimited printk with just
|
||||
enough information to work out what is going on.
|
||||
|
||||
Not all #DB exceptions are traps, so blindly continuing is not a safe action
|
||||
to take. We don't let PV guests select these settings in the real %dr7 to
|
||||
begin with, but for added safety against unexpected situations, detect the
|
||||
fault cases and crash in an obvious manner.
|
||||
|
||||
This is part of XSA-260 / CVE-2018-8897.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -1809,16 +1809,44 @@ void do_debug(struct cpu_user_regs *regs
|
||||
regs->eflags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
}
|
||||
- else
|
||||
+
|
||||
+ /*
|
||||
+ * Check for fault conditions. General Detect, and instruction
|
||||
+ * breakpoints are faults rather than traps, at which point attempting
|
||||
+ * to ignore and continue will result in a livelock.
|
||||
+ */
|
||||
+ if ( dr6 & DR_GENERAL_DETECT )
|
||||
+ {
|
||||
+ printk(XENLOG_ERR "Hit General Detect in Xen context\n");
|
||||
+ fatal_trap(regs, 0);
|
||||
+ }
|
||||
+
|
||||
+ if ( dr6 & (DR_TRAP3 | DR_TRAP2 | DR_TRAP1 | DR_TRAP0) )
|
||||
{
|
||||
- /*
|
||||
- * We ignore watchpoints when they trigger within Xen. This may
|
||||
- * happen when a buffer is passed to us which previously had a
|
||||
- * watchpoint set on it. No need to bump EIP; the only faulting
|
||||
- * trap is an instruction breakpoint, which can't happen to us.
|
||||
- */
|
||||
- WARN_ON(!search_exception_table(regs));
|
||||
+ unsigned int bp, dr7 = read_debugreg(7) >> DR_CONTROL_SHIFT;
|
||||
+
|
||||
+ for ( bp = 0; bp < 4; ++bp )
|
||||
+ {
|
||||
+ if ( (dr6 & (1u << bp)) && /* Breakpoint triggered? */
|
||||
+ ((dr7 & (3u << (bp * DR_CONTROL_SIZE))) == 0) /* Insn? */ )
|
||||
+ {
|
||||
+ printk(XENLOG_ERR
|
||||
+ "Hit instruction breakpoint in Xen context\n");
|
||||
+ fatal_trap(regs, 0);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Whatever caused this #DB should be a trap. Note it and continue.
|
||||
+ * Guests can trigger this in certain corner cases, so ensure the
|
||||
+ * message is ratelimited.
|
||||
+ */
|
||||
+ gprintk(XENLOG_WARNING,
|
||||
+ "Hit #DB in Xen context: %04x:%p [%ps], stk %04x:%p, dr6 %lx\n",
|
||||
+ regs->cs, _p(regs->rip), _p(regs->rip),
|
||||
+ regs->ss, _p(regs->rsp), dr6);
|
||||
+
|
||||
goto out;
|
||||
}
|
||||
|
||||
279
xsa261.patch
279
xsa261.patch
|
|
@ -1,279 +0,0 @@
|
|||
From: Xen Project Security Team <security@xenproject.org>
|
||||
Subject: x86/vpt: add support for IO-APIC routed interrupts
|
||||
|
||||
And modify the HPET code to make use of it. Currently HPET interrupts
|
||||
are always treated as ISA and thus injected through the vPIC. This is
|
||||
wrong because HPET interrupts when not in legacy mode should be
|
||||
injected from the IO-APIC.
|
||||
|
||||
To make things worse, the supported interrupt routing values are set
|
||||
to [20..23], which clearly falls outside of the ISA range, thus
|
||||
leading to an ASSERT in debug builds or memory corruption in non-debug
|
||||
builds because the interrupt injection code will write out of the
|
||||
bounds of the arch.hvm_domain.vpic array.
|
||||
|
||||
Since the HPET interrupt source can change between ISA and IO-APIC
|
||||
always destroy the timer before changing the mode, or else Xen risks
|
||||
changing it while the timer is active.
|
||||
|
||||
Note that vpt interrupt injection is racy in the sense that the
|
||||
vIO-APIC RTE entry can be written by the guest in between the call to
|
||||
pt_irq_masked and hvm_ioapic_assert, or the call to pt_update_irq and
|
||||
pt_intr_post. Those are not deemed to be security issues, but rather
|
||||
quirks of the current implementation. In the worse case the guest
|
||||
might lose interrupts or get multiple interrupt vectors injected for
|
||||
the same timer source.
|
||||
|
||||
This is part of XSA-261.
|
||||
|
||||
Address actual and potential compiler warnings. Fix formatting.
|
||||
|
||||
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
Changes since v2:
|
||||
- Move fallthrough comment to be just above the case label.
|
||||
- Fix now stale comment in pt_update_irq.
|
||||
- Use NR_ISAIRQS instead of 16.
|
||||
- Expand commit message to mention the quirkiness of vpt interrupt
|
||||
injection.
|
||||
|
||||
Changes since v1:
|
||||
- Simply usage of gsi in pt_irq_masked.
|
||||
- Introduce hvm_ioapic_assert.
|
||||
- Fix pt->source == PTSRC_isa in create_periodic_time.
|
||||
|
||||
--- a/xen/arch/x86/hvm/hpet.c
|
||||
+++ b/xen/arch/x86/hvm/hpet.c
|
||||
@@ -264,13 +264,20 @@ static void hpet_set_timer(HPETState *h,
|
||||
diff = (timer_is_32bit(h, tn) && (-diff > HPET_TINY_TIME_SPAN))
|
||||
? (uint32_t)diff : 0;
|
||||
|
||||
+ destroy_periodic_time(&h->pt[tn]);
|
||||
if ( (tn <= 1) && (h->hpet.config & HPET_CFG_LEGACY) )
|
||||
+ {
|
||||
/* if LegacyReplacementRoute bit is set, HPET specification requires
|
||||
timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
|
||||
timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */
|
||||
irq = (tn == 0) ? 0 : 8;
|
||||
+ h->pt[tn].source = PTSRC_isa;
|
||||
+ }
|
||||
else
|
||||
+ {
|
||||
irq = timer_int_route(h, tn);
|
||||
+ h->pt[tn].source = PTSRC_ioapic;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* diff is the time from now when the timer should fire, for a periodic
|
||||
--- a/xen/arch/x86/hvm/irq.c
|
||||
+++ b/xen/arch/x86/hvm/irq.c
|
||||
@@ -41,6 +41,26 @@ static void assert_gsi(struct domain *d,
|
||||
vioapic_irq_positive_edge(d, ioapic_gsi);
|
||||
}
|
||||
|
||||
+int hvm_ioapic_assert(struct domain *d, unsigned int gsi, bool level)
|
||||
+{
|
||||
+ struct hvm_irq *hvm_irq = hvm_domain_irq(d);
|
||||
+ int vector;
|
||||
+
|
||||
+ if ( gsi >= hvm_irq->nr_gsis )
|
||||
+ {
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ spin_lock(&d->arch.hvm_domain.irq_lock);
|
||||
+ if ( !level || hvm_irq->gsi_assert_count[gsi]++ == 0 )
|
||||
+ assert_gsi(d, gsi);
|
||||
+ vector = vioapic_get_vector(d, gsi);
|
||||
+ spin_unlock(&d->arch.hvm_domain.irq_lock);
|
||||
+
|
||||
+ return vector;
|
||||
+}
|
||||
+
|
||||
static void assert_irq(struct domain *d, unsigned ioapic_gsi, unsigned pic_irq)
|
||||
{
|
||||
assert_gsi(d, ioapic_gsi);
|
||||
--- a/xen/arch/x86/hvm/vpt.c
|
||||
+++ b/xen/arch/x86/hvm/vpt.c
|
||||
@@ -107,31 +107,49 @@ static int pt_irq_vector(struct periodic
|
||||
static int pt_irq_masked(struct periodic_time *pt)
|
||||
{
|
||||
struct vcpu *v = pt->vcpu;
|
||||
- unsigned int gsi, isa_irq;
|
||||
- int mask;
|
||||
- uint8_t pic_imr;
|
||||
+ unsigned int gsi = pt->irq;
|
||||
|
||||
- if ( pt->source == PTSRC_lapic )
|
||||
+ switch ( pt->source )
|
||||
+ {
|
||||
+ case PTSRC_lapic:
|
||||
{
|
||||
struct vlapic *vlapic = vcpu_vlapic(v);
|
||||
+
|
||||
return (!vlapic_enabled(vlapic) ||
|
||||
(vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_MASKED));
|
||||
}
|
||||
|
||||
- isa_irq = pt->irq;
|
||||
- gsi = hvm_isa_irq_to_gsi(isa_irq);
|
||||
- pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
|
||||
- mask = vioapic_get_mask(v->domain, gsi);
|
||||
- if ( mask < 0 )
|
||||
- {
|
||||
- dprintk(XENLOG_WARNING, "d%u: invalid GSI (%u) for platform timer\n",
|
||||
- v->domain->domain_id, gsi);
|
||||
- domain_crash(v->domain);
|
||||
- return -1;
|
||||
+ case PTSRC_isa:
|
||||
+ {
|
||||
+ uint8_t pic_imr = v->domain->arch.hvm_domain.vpic[pt->irq >> 3].imr;
|
||||
+
|
||||
+ /* Check if the interrupt is unmasked in the PIC. */
|
||||
+ if ( !(pic_imr & (1 << (pt->irq & 7))) && vlapic_accept_pic_intr(v) )
|
||||
+ return 0;
|
||||
+
|
||||
+ gsi = hvm_isa_irq_to_gsi(pt->irq);
|
||||
+ }
|
||||
+
|
||||
+ /* Fallthrough to check if the interrupt is masked on the IO APIC. */
|
||||
+ case PTSRC_ioapic:
|
||||
+ {
|
||||
+ int mask = vioapic_get_mask(v->domain, gsi);
|
||||
+
|
||||
+ if ( mask < 0 )
|
||||
+ {
|
||||
+ dprintk(XENLOG_WARNING,
|
||||
+ "d%d: invalid GSI (%u) for platform timer\n",
|
||||
+ v->domain->domain_id, gsi);
|
||||
+ domain_crash(v->domain);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return mask;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) &&
|
||||
- mask);
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static void pt_lock(struct periodic_time *pt)
|
||||
@@ -252,7 +270,7 @@ int pt_update_irq(struct vcpu *v)
|
||||
struct list_head *head = &v->arch.hvm_vcpu.tm_list;
|
||||
struct periodic_time *pt, *temp, *earliest_pt;
|
||||
uint64_t max_lag;
|
||||
- int irq, is_lapic, pt_vector;
|
||||
+ int irq, pt_vector = -1;
|
||||
|
||||
spin_lock(&v->arch.hvm_vcpu.tm_lock);
|
||||
|
||||
@@ -288,29 +306,26 @@ int pt_update_irq(struct vcpu *v)
|
||||
|
||||
earliest_pt->irq_issued = 1;
|
||||
irq = earliest_pt->irq;
|
||||
- is_lapic = (earliest_pt->source == PTSRC_lapic);
|
||||
|
||||
spin_unlock(&v->arch.hvm_vcpu.tm_lock);
|
||||
|
||||
- /*
|
||||
- * If periodic timer interrut is handled by lapic, its vector in
|
||||
- * IRR is returned and used to set eoi_exit_bitmap for virtual
|
||||
- * interrupt delivery case. Otherwise return -1 to do nothing.
|
||||
- */
|
||||
- if ( is_lapic )
|
||||
+ switch ( earliest_pt->source )
|
||||
{
|
||||
+ case PTSRC_lapic:
|
||||
+ /*
|
||||
+ * If periodic timer interrupt is handled by lapic, its vector in
|
||||
+ * IRR is returned and used to set eoi_exit_bitmap for virtual
|
||||
+ * interrupt delivery case. Otherwise return -1 to do nothing.
|
||||
+ */
|
||||
vlapic_set_irq(vcpu_vlapic(v), irq, 0);
|
||||
pt_vector = irq;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
+ break;
|
||||
+
|
||||
+ case PTSRC_isa:
|
||||
hvm_isa_irq_deassert(v->domain, irq);
|
||||
if ( platform_legacy_irq(irq) && vlapic_accept_pic_intr(v) &&
|
||||
v->domain->arch.hvm_domain.vpic[irq >> 3].int_output )
|
||||
- {
|
||||
hvm_isa_irq_assert(v->domain, irq, NULL);
|
||||
- pt_vector = -1;
|
||||
- }
|
||||
else
|
||||
{
|
||||
pt_vector = hvm_isa_irq_assert(v->domain, irq, vioapic_get_vector);
|
||||
@@ -321,6 +336,17 @@ int pt_update_irq(struct vcpu *v)
|
||||
if ( pt_vector < 0 || !vlapic_test_irq(vcpu_vlapic(v), pt_vector) )
|
||||
pt_vector = -1;
|
||||
}
|
||||
+ break;
|
||||
+
|
||||
+ case PTSRC_ioapic:
|
||||
+ /*
|
||||
+ * NB: At the moment IO-APIC routed interrupts generated by vpt devices
|
||||
+ * (HPET) are edge-triggered.
|
||||
+ */
|
||||
+ pt_vector = hvm_ioapic_assert(v->domain, irq, false);
|
||||
+ if ( pt_vector < 0 || !vlapic_test_irq(vcpu_vlapic(v), pt_vector) )
|
||||
+ pt_vector = -1;
|
||||
+ break;
|
||||
}
|
||||
|
||||
return pt_vector;
|
||||
@@ -418,7 +444,14 @@ void create_periodic_time(
|
||||
struct vcpu *v, struct periodic_time *pt, uint64_t delta,
|
||||
uint64_t period, uint8_t irq, time_cb *cb, void *data)
|
||||
{
|
||||
- ASSERT(pt->source != 0);
|
||||
+ if ( !pt->source ||
|
||||
+ (pt->irq >= NR_ISAIRQS && pt->source == PTSRC_isa) ||
|
||||
+ (pt->irq >= hvm_domain_irq(v->domain)->nr_gsis &&
|
||||
+ pt->source == PTSRC_ioapic) )
|
||||
+ {
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
destroy_periodic_time(pt);
|
||||
|
||||
@@ -498,7 +531,7 @@ static void pt_adjust_vcpu(struct period
|
||||
{
|
||||
int on_list;
|
||||
|
||||
- ASSERT(pt->source == PTSRC_isa);
|
||||
+ ASSERT(pt->source == PTSRC_isa || pt->source == PTSRC_ioapic);
|
||||
|
||||
if ( pt->vcpu == NULL )
|
||||
return;
|
||||
--- a/xen/include/asm-x86/hvm/irq.h
|
||||
+++ b/xen/include/asm-x86/hvm/irq.h
|
||||
@@ -207,6 +207,9 @@ int hvm_set_pci_link_route(struct domain
|
||||
|
||||
int hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data);
|
||||
|
||||
+/* Assert an IO APIC pin. */
|
||||
+int hvm_ioapic_assert(struct domain *d, unsigned int gsi, bool level);
|
||||
+
|
||||
void hvm_maybe_deassert_evtchn_irq(void);
|
||||
void hvm_assert_evtchn_irq(struct vcpu *v);
|
||||
void hvm_set_callback_via(struct domain *d, uint64_t via);
|
||||
--- a/xen/include/asm-x86/hvm/vpt.h
|
||||
+++ b/xen/include/asm-x86/hvm/vpt.h
|
||||
@@ -44,6 +44,7 @@ struct periodic_time {
|
||||
bool_t warned_timeout_too_short;
|
||||
#define PTSRC_isa 1 /* ISA time source */
|
||||
#define PTSRC_lapic 2 /* LAPIC time source */
|
||||
+#define PTSRC_ioapic 3 /* IOAPIC time source */
|
||||
u8 source; /* PTSRC_ */
|
||||
u8 irq;
|
||||
struct vcpu *vcpu; /* vcpu timer interrupt delivers to */
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/HVM: guard against emulator driving ioreq state in weird ways
|
||||
|
||||
In the case where hvm_wait_for_io() calls wait_on_xen_event_channel(),
|
||||
p->state ends up being read twice in succession: once to determine that
|
||||
state != p->state, and then again at the top of the loop. This gives a
|
||||
compromised emulator a chance to change the state back between the two
|
||||
reads, potentially keeping Xen in a loop indefinitely.
|
||||
|
||||
Instead:
|
||||
* Read p->state once in each of the wait_on_xen_event_channel() tests,
|
||||
* re-use that value the next time around,
|
||||
* and insist that the states continue to transition "forward" (with the
|
||||
exception of the transition to STATE_IOREQ_NONE).
|
||||
|
||||
This is XSA-262.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/hvm/ioreq.c
|
||||
+++ b/xen/arch/x86/hvm/ioreq.c
|
||||
@@ -87,14 +87,17 @@ static void hvm_io_assist(struct hvm_ior
|
||||
|
||||
static bool hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
|
||||
{
|
||||
+ unsigned int prev_state = STATE_IOREQ_NONE;
|
||||
+
|
||||
while ( sv->pending )
|
||||
{
|
||||
unsigned int state = p->state;
|
||||
|
||||
- rmb();
|
||||
- switch ( state )
|
||||
+ smp_rmb();
|
||||
+
|
||||
+ recheck:
|
||||
+ if ( unlikely(state == STATE_IOREQ_NONE) )
|
||||
{
|
||||
- case STATE_IOREQ_NONE:
|
||||
/*
|
||||
* The only reason we should see this case is when an
|
||||
* emulator is dying and it races with an I/O being
|
||||
@@ -102,14 +105,30 @@ static bool hvm_wait_for_io(struct hvm_i
|
||||
*/
|
||||
hvm_io_assist(sv, ~0ul);
|
||||
break;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(state < prev_state) )
|
||||
+ {
|
||||
+ gdprintk(XENLOG_ERR, "Weird HVM ioreq state transition %u -> %u\n",
|
||||
+ prev_state, state);
|
||||
+ sv->pending = false;
|
||||
+ domain_crash(sv->vcpu->domain);
|
||||
+ return false; /* bail */
|
||||
+ }
|
||||
+
|
||||
+ switch ( prev_state = state )
|
||||
+ {
|
||||
case STATE_IORESP_READY: /* IORESP_READY -> NONE */
|
||||
p->state = STATE_IOREQ_NONE;
|
||||
hvm_io_assist(sv, p->data);
|
||||
break;
|
||||
case STATE_IOREQ_READY: /* IOREQ_{READY,INPROCESS} -> IORESP_READY */
|
||||
case STATE_IOREQ_INPROCESS:
|
||||
- wait_on_xen_event_channel(sv->ioreq_evtchn, p->state != state);
|
||||
- break;
|
||||
+ wait_on_xen_event_channel(sv->ioreq_evtchn,
|
||||
+ ({ state = p->state;
|
||||
+ smp_rmb();
|
||||
+ state != prev_state; }));
|
||||
+ goto recheck;
|
||||
default:
|
||||
gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
|
||||
sv->pending = false;
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
From 13fafdf5c97d3bc2a8851c4d1796feac0f82d498 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Thu, 26 Apr 2018 12:21:00 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Read MSR_ARCH_CAPABILITIES only once
|
||||
|
||||
Make it available from the beginning of init_speculation_mitigations(), and
|
||||
pass it into appropriate functions. Fix an RSBA typo while moving the
|
||||
affected comment.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit d6c65187252a6c1810fd24c4d46f812840de8d3c)
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 34 ++++++++++++++--------------------
|
||||
1 file changed, 14 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index fa67a0f..dc90743 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -81,18 +81,15 @@ static int __init parse_bti(const char *s)
|
||||
}
|
||||
custom_param("bti", parse_bti);
|
||||
|
||||
-static void __init print_details(enum ind_thunk thunk)
|
||||
+static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
{
|
||||
unsigned int _7d0 = 0, e8b = 0, tmp;
|
||||
- uint64_t caps = 0;
|
||||
|
||||
/* Collect diagnostics about available mitigations. */
|
||||
if ( boot_cpu_data.cpuid_level >= 7 )
|
||||
cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0);
|
||||
if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 )
|
||||
cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp);
|
||||
- if ( _7d0 & cpufeat_mask(X86_FEATURE_ARCH_CAPS) )
|
||||
- rdmsrl(MSR_ARCH_CAPABILITIES, caps);
|
||||
|
||||
printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
|
||||
|
||||
@@ -125,7 +122,7 @@ static void __init print_details(enum ind_thunk thunk)
|
||||
}
|
||||
|
||||
/* Calculate whether Retpoline is known-safe on this CPU. */
|
||||
-static bool __init retpoline_safe(void)
|
||||
+static bool __init retpoline_safe(uint64_t caps)
|
||||
{
|
||||
unsigned int ucode_rev = this_cpu(ucode_cpu_info).cpu_sig.rev;
|
||||
|
||||
@@ -136,19 +133,12 @@ static bool __init retpoline_safe(void)
|
||||
boot_cpu_data.x86 != 6 )
|
||||
return false;
|
||||
|
||||
- if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
|
||||
- {
|
||||
- uint64_t caps;
|
||||
-
|
||||
- rdmsrl(MSR_ARCH_CAPABILITIES, caps);
|
||||
-
|
||||
- /*
|
||||
- * RBSA may be set by a hypervisor to indicate that we may move to a
|
||||
- * processor which isn't retpoline-safe.
|
||||
- */
|
||||
- if ( caps & ARCH_CAPS_RSBA )
|
||||
- return false;
|
||||
- }
|
||||
+ /*
|
||||
+ * RSBA may be set by a hypervisor to indicate that we may move to a
|
||||
+ * processor which isn't retpoline-safe.
|
||||
+ */
|
||||
+ if ( caps & ARCH_CAPS_RSBA )
|
||||
+ return false;
|
||||
|
||||
switch ( boot_cpu_data.x86_model )
|
||||
{
|
||||
@@ -218,6 +208,10 @@ void __init init_speculation_mitigations(void)
|
||||
{
|
||||
enum ind_thunk thunk = THUNK_DEFAULT;
|
||||
bool ibrs = false;
|
||||
+ uint64_t caps = 0;
|
||||
+
|
||||
+ if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
|
||||
+ rdmsrl(MSR_ARCH_CAPABILITIES, caps);
|
||||
|
||||
/*
|
||||
* Has the user specified any custom BTI mitigations? If so, follow their
|
||||
@@ -246,7 +240,7 @@ void __init init_speculation_mitigations(void)
|
||||
* On Intel hardware, we'd like to use retpoline in preference to
|
||||
* IBRS, but only if it is safe on this hardware.
|
||||
*/
|
||||
- else if ( retpoline_safe() )
|
||||
+ else if ( retpoline_safe(caps) )
|
||||
thunk = THUNK_RETPOLINE;
|
||||
else if ( boot_cpu_has(X86_FEATURE_IBRSB) )
|
||||
ibrs = true;
|
||||
@@ -331,7 +325,7 @@ void __init init_speculation_mitigations(void)
|
||||
/* (Re)init BSP state now that default_bti_ist_info has been calculated. */
|
||||
init_shadow_spec_ctrl_state();
|
||||
|
||||
- print_details(thunk);
|
||||
+ print_details(thunk, caps);
|
||||
}
|
||||
|
||||
static void __init __maybe_unused build_assertions(void)
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
From d7b345e4ca136a995bfaaf2ee20901ee20e63570 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Tue, 17 Apr 2018 14:15:04 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Express Xen's choice of MSR_SPEC_CTRL value as
|
||||
a variable
|
||||
|
||||
At the moment, we have two different encodings of Xen's MSR_SPEC_CTRL value,
|
||||
which is a side effect of how the Spectre series developed. One encoding is
|
||||
via an alias with the bottom bit of bti_ist_info, and can encode IBRS or not,
|
||||
but not other configurations such as STIBP.
|
||||
|
||||
Break Xen's value out into a separate variable (in the top of stack block for
|
||||
XPTI reasons) and use this instead of bti_ist_info in the IST path.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit 66dfae0f32bfbc899c2f3446d5ee57068cb7f957)
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 8 +++++---
|
||||
xen/arch/x86/x86_64/asm-offsets.c | 1 +
|
||||
xen/include/asm-x86/current.h | 1 +
|
||||
xen/include/asm-x86/spec_ctrl.h | 2 ++
|
||||
xen/include/asm-x86/spec_ctrl_asm.h | 8 ++------
|
||||
5 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index dc90743..1143521 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -38,6 +38,7 @@ static int8_t __initdata opt_ibrs = -1;
|
||||
static bool __initdata opt_rsb_native = true;
|
||||
static bool __initdata opt_rsb_vmexit = true;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
+uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
uint8_t __read_mostly default_bti_ist_info;
|
||||
|
||||
static int __init parse_bti(const char *s)
|
||||
@@ -285,11 +286,14 @@ void __init init_speculation_mitigations(void)
|
||||
* guests.
|
||||
*/
|
||||
if ( ibrs )
|
||||
+ {
|
||||
+ default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
|
||||
setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET);
|
||||
+ }
|
||||
else
|
||||
setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
|
||||
|
||||
- default_bti_ist_info |= BTI_IST_WRMSR | ibrs;
|
||||
+ default_bti_ist_info |= BTI_IST_WRMSR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -330,8 +334,6 @@ void __init init_speculation_mitigations(void)
|
||||
|
||||
static void __init __maybe_unused build_assertions(void)
|
||||
{
|
||||
- /* The optimised assembly relies on this alias. */
|
||||
- BUILD_BUG_ON(BTI_IST_IBRS != SPEC_CTRL_IBRS);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
|
||||
index 13478d4..0726147 100644
|
||||
--- a/xen/arch/x86/x86_64/asm-offsets.c
|
||||
+++ b/xen/arch/x86/x86_64/asm-offsets.c
|
||||
@@ -142,6 +142,7 @@ void __dummy__(void)
|
||||
OFFSET(CPUINFO_xen_cr3, struct cpu_info, xen_cr3);
|
||||
OFFSET(CPUINFO_pv_cr3, struct cpu_info, pv_cr3);
|
||||
OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl);
|
||||
+ OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl);
|
||||
OFFSET(CPUINFO_use_shadow_spec_ctrl, struct cpu_info, use_shadow_spec_ctrl);
|
||||
OFFSET(CPUINFO_bti_ist_info, struct cpu_info, bti_ist_info);
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
|
||||
index 4678a0f..d10b13c 100644
|
||||
--- a/xen/include/asm-x86/current.h
|
||||
+++ b/xen/include/asm-x86/current.h
|
||||
@@ -56,6 +56,7 @@ struct cpu_info {
|
||||
|
||||
/* See asm-x86/spec_ctrl_asm.h for usage. */
|
||||
unsigned int shadow_spec_ctrl;
|
||||
+ uint8_t xen_spec_ctrl;
|
||||
bool use_shadow_spec_ctrl;
|
||||
uint8_t bti_ist_info;
|
||||
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 5ab4ff3..5e4fc84 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -27,6 +27,7 @@
|
||||
void init_speculation_mitigations(void);
|
||||
|
||||
extern bool opt_ibpb;
|
||||
+extern uint8_t default_xen_spec_ctrl;
|
||||
extern uint8_t default_bti_ist_info;
|
||||
|
||||
static inline void init_shadow_spec_ctrl_state(void)
|
||||
@@ -34,6 +35,7 @@ static inline void init_shadow_spec_ctrl_state(void)
|
||||
struct cpu_info *info = get_cpu_info();
|
||||
|
||||
info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
|
||||
+ info->xen_spec_ctrl = default_xen_spec_ctrl;
|
||||
info->bti_ist_info = default_bti_ist_info;
|
||||
}
|
||||
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
index 1f2b6f3..697da13 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
@@ -21,7 +21,6 @@
|
||||
#define __X86_SPEC_CTRL_ASM_H__
|
||||
|
||||
/* Encoding of the bottom bits in cpuinfo.bti_ist_info */
|
||||
-#define BTI_IST_IBRS (1 << 0)
|
||||
#define BTI_IST_WRMSR (1 << 1)
|
||||
#define BTI_IST_RSB (1 << 2)
|
||||
|
||||
@@ -286,12 +285,9 @@
|
||||
setz %dl
|
||||
and %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14)
|
||||
|
||||
- /*
|
||||
- * Load Xen's intended value. SPEC_CTRL_IBRS vs 0 is encoded in the
|
||||
- * bottom bit of bti_ist_info, via a deliberate alias with BTI_IST_IBRS.
|
||||
- */
|
||||
+ /* Load Xen's intended value. */
|
||||
mov $MSR_SPEC_CTRL, %ecx
|
||||
- and $BTI_IST_IBRS, %eax
|
||||
+ movzbl STACK_CPUINFO_FIELD(xen_spec_ctrl)(%r14), %eax
|
||||
xor %edx, %edx
|
||||
wrmsr
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
From a0c2f734b4c683cb407e10ff943671c413480287 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Tue, 17 Apr 2018 14:15:04 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Merge bti_ist_info and use_shadow_spec_ctrl
|
||||
into spec_ctrl_flags
|
||||
|
||||
All 3 bits of information here are control flags for the entry/exit code
|
||||
behaviour. Treat them as such, rather than having two different variables.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit 5262ba2e7799001402dfe139ff944e035dfff928)
|
||||
---
|
||||
xen/arch/x86/acpi/power.c | 4 +--
|
||||
xen/arch/x86/spec_ctrl.c | 10 ++++---
|
||||
xen/arch/x86/x86_64/asm-offsets.c | 3 +--
|
||||
xen/include/asm-x86/current.h | 3 +--
|
||||
xen/include/asm-x86/nops.h | 5 ++--
|
||||
xen/include/asm-x86/spec_ctrl.h | 10 +++----
|
||||
xen/include/asm-x86/spec_ctrl_asm.h | 52 ++++++++++++++++++++-----------------
|
||||
7 files changed, 45 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
|
||||
index f7085d3..f3480aa 100644
|
||||
--- a/xen/arch/x86/acpi/power.c
|
||||
+++ b/xen/arch/x86/acpi/power.c
|
||||
@@ -215,7 +215,7 @@ static int enter_state(u32 state)
|
||||
ci = get_cpu_info();
|
||||
spec_ctrl_enter_idle(ci);
|
||||
/* Avoid NMI/#MC using MSR_SPEC_CTRL until we've reloaded microcode. */
|
||||
- ci->bti_ist_info = 0;
|
||||
+ ci->spec_ctrl_flags &= ~SCF_ist_wrmsr;
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
@@ -256,7 +256,7 @@ static int enter_state(u32 state)
|
||||
microcode_resume_cpu(0);
|
||||
|
||||
/* Re-enabled default NMI/#MC use of MSR_SPEC_CTRL. */
|
||||
- ci->bti_ist_info = default_bti_ist_info;
|
||||
+ ci->spec_ctrl_flags |= (default_spec_ctrl_flags & SCF_ist_wrmsr);
|
||||
spec_ctrl_exit_idle(ci);
|
||||
|
||||
done:
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 1143521..2d69910 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -39,7 +39,7 @@ static bool __initdata opt_rsb_native = true;
|
||||
static bool __initdata opt_rsb_vmexit = true;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
-uint8_t __read_mostly default_bti_ist_info;
|
||||
+uint8_t __read_mostly default_spec_ctrl_flags;
|
||||
|
||||
static int __init parse_bti(const char *s)
|
||||
{
|
||||
@@ -293,7 +293,7 @@ void __init init_speculation_mitigations(void)
|
||||
else
|
||||
setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
|
||||
|
||||
- default_bti_ist_info |= BTI_IST_WRMSR;
|
||||
+ default_spec_ctrl_flags |= SCF_ist_wrmsr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -312,7 +312,7 @@ void __init init_speculation_mitigations(void)
|
||||
if ( opt_rsb_native )
|
||||
{
|
||||
setup_force_cpu_cap(X86_FEATURE_RSB_NATIVE);
|
||||
- default_bti_ist_info |= BTI_IST_RSB;
|
||||
+ default_spec_ctrl_flags |= SCF_ist_rsb;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -326,7 +326,7 @@ void __init init_speculation_mitigations(void)
|
||||
if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) )
|
||||
opt_ibpb = false;
|
||||
|
||||
- /* (Re)init BSP state now that default_bti_ist_info has been calculated. */
|
||||
+ /* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */
|
||||
init_shadow_spec_ctrl_state();
|
||||
|
||||
print_details(thunk, caps);
|
||||
@@ -334,6 +334,8 @@ void __init init_speculation_mitigations(void)
|
||||
|
||||
static void __init __maybe_unused build_assertions(void)
|
||||
{
|
||||
+ /* The optimised assembly relies on this alias. */
|
||||
+ BUILD_BUG_ON(SCF_use_shadow != 1);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
|
||||
index 0726147..97242e5 100644
|
||||
--- a/xen/arch/x86/x86_64/asm-offsets.c
|
||||
+++ b/xen/arch/x86/x86_64/asm-offsets.c
|
||||
@@ -143,8 +143,7 @@ void __dummy__(void)
|
||||
OFFSET(CPUINFO_pv_cr3, struct cpu_info, pv_cr3);
|
||||
OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl);
|
||||
OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl);
|
||||
- OFFSET(CPUINFO_use_shadow_spec_ctrl, struct cpu_info, use_shadow_spec_ctrl);
|
||||
- OFFSET(CPUINFO_bti_ist_info, struct cpu_info, bti_ist_info);
|
||||
+ OFFSET(CPUINFO_spec_ctrl_flags, struct cpu_info, spec_ctrl_flags);
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
BLANK();
|
||||
|
||||
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
|
||||
index d10b13c..7afff0e 100644
|
||||
--- a/xen/include/asm-x86/current.h
|
||||
+++ b/xen/include/asm-x86/current.h
|
||||
@@ -57,8 +57,7 @@ struct cpu_info {
|
||||
/* See asm-x86/spec_ctrl_asm.h for usage. */
|
||||
unsigned int shadow_spec_ctrl;
|
||||
uint8_t xen_spec_ctrl;
|
||||
- bool use_shadow_spec_ctrl;
|
||||
- uint8_t bti_ist_info;
|
||||
+ uint8_t spec_ctrl_flags;
|
||||
|
||||
unsigned long __pad;
|
||||
/* get_stack_bottom() must be 16-byte aligned */
|
||||
diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h
|
||||
index 37f9819..b744895 100644
|
||||
--- a/xen/include/asm-x86/nops.h
|
||||
+++ b/xen/include/asm-x86/nops.h
|
||||
@@ -62,10 +62,9 @@
|
||||
#define ASM_NOP8 _ASM_MK_NOP(K8_NOP8)
|
||||
|
||||
#define ASM_NOP17 ASM_NOP8; ASM_NOP7; ASM_NOP2
|
||||
-#define ASM_NOP21 ASM_NOP8; ASM_NOP8; ASM_NOP5
|
||||
+#define ASM_NOP22 ASM_NOP8; ASM_NOP8; ASM_NOP6
|
||||
#define ASM_NOP24 ASM_NOP8; ASM_NOP8; ASM_NOP8
|
||||
-#define ASM_NOP29 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP5
|
||||
-#define ASM_NOP32 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8
|
||||
+#define ASM_NOP33 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2
|
||||
#define ASM_NOP40 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8
|
||||
|
||||
#define ASM_NOP_MAX 8
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 5e4fc84..059e291 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -28,15 +28,15 @@ void init_speculation_mitigations(void);
|
||||
|
||||
extern bool opt_ibpb;
|
||||
extern uint8_t default_xen_spec_ctrl;
|
||||
-extern uint8_t default_bti_ist_info;
|
||||
+extern uint8_t default_spec_ctrl_flags;
|
||||
|
||||
static inline void init_shadow_spec_ctrl_state(void)
|
||||
{
|
||||
struct cpu_info *info = get_cpu_info();
|
||||
|
||||
- info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
|
||||
+ info->shadow_spec_ctrl = 0;
|
||||
info->xen_spec_ctrl = default_xen_spec_ctrl;
|
||||
- info->bti_ist_info = default_bti_ist_info;
|
||||
+ info->spec_ctrl_flags = default_spec_ctrl_flags;
|
||||
}
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */
|
||||
@@ -50,7 +50,7 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
|
||||
*/
|
||||
info->shadow_spec_ctrl = val;
|
||||
barrier();
|
||||
- info->use_shadow_spec_ctrl = true;
|
||||
+ info->spec_ctrl_flags |= SCF_use_shadow;
|
||||
barrier();
|
||||
asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
@@ -65,7 +65,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
|
||||
* Disable shadowing before updating the MSR. There are no SMP issues
|
||||
* here; only local processor ordering concerns.
|
||||
*/
|
||||
- info->use_shadow_spec_ctrl = false;
|
||||
+ info->spec_ctrl_flags &= ~SCF_use_shadow;
|
||||
barrier();
|
||||
asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
index 697da13..39fb4f8 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
@@ -20,9 +20,10 @@
|
||||
#ifndef __X86_SPEC_CTRL_ASM_H__
|
||||
#define __X86_SPEC_CTRL_ASM_H__
|
||||
|
||||
-/* Encoding of the bottom bits in cpuinfo.bti_ist_info */
|
||||
-#define BTI_IST_WRMSR (1 << 1)
|
||||
-#define BTI_IST_RSB (1 << 2)
|
||||
+/* Encoding of cpuinfo.spec_ctrl_flags */
|
||||
+#define SCF_use_shadow (1 << 0)
|
||||
+#define SCF_ist_wrmsr (1 << 1)
|
||||
+#define SCF_ist_rsb (1 << 2)
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#include <asm/msr-index.h>
|
||||
@@ -49,20 +50,20 @@
|
||||
* after VMEXIT. The VMEXIT-specific code reads MSR_SPEC_CTRL and updates
|
||||
* current before loading Xen's MSR_SPEC_CTRL setting.
|
||||
*
|
||||
- * Factor 2 is harder. We maintain a shadow_spec_ctrl value, and
|
||||
- * use_shadow_spec_ctrl boolean per cpu. The synchronous use is:
|
||||
+ * Factor 2 is harder. We maintain a shadow_spec_ctrl value, and a use_shadow
|
||||
+ * boolean in the per cpu spec_ctrl_flags. The synchronous use is:
|
||||
*
|
||||
* 1) Store guest value in shadow_spec_ctrl
|
||||
- * 2) Set use_shadow_spec_ctrl boolean
|
||||
+ * 2) Set the use_shadow boolean
|
||||
* 3) Load guest value into MSR_SPEC_CTRL
|
||||
* 4) Exit to guest
|
||||
* 5) Entry from guest
|
||||
- * 6) Clear use_shadow_spec_ctrl boolean
|
||||
+ * 6) Clear the use_shadow boolean
|
||||
* 7) Load Xen's value into MSR_SPEC_CTRL
|
||||
*
|
||||
* The asynchronous use for interrupts/exceptions is:
|
||||
* - Set/clear IBRS on entry to Xen
|
||||
- * - On exit to Xen, check use_shadow_spec_ctrl
|
||||
+ * - On exit to Xen, check use_shadow
|
||||
* - If set, load shadow_spec_ctrl
|
||||
*
|
||||
* Therefore, an interrupt/exception which hits the synchronous path between
|
||||
@@ -134,7 +135,7 @@
|
||||
xor %edx, %edx
|
||||
|
||||
/* Clear SPEC_CTRL shadowing *before* loading Xen's value. */
|
||||
- movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp)
|
||||
+ andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp)
|
||||
|
||||
/* Load Xen's intended value. */
|
||||
mov $\ibrs_val, %eax
|
||||
@@ -160,12 +161,14 @@
|
||||
* block so calculate the position directly.
|
||||
*/
|
||||
.if \maybexen
|
||||
+ xor %eax, %eax
|
||||
/* Branchless `if ( !xen ) clear_shadowing` */
|
||||
testb $3, UREGS_cs(%rsp)
|
||||
- setz %al
|
||||
- and %al, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14)
|
||||
+ setnz %al
|
||||
+ not %eax
|
||||
+ and %al, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
|
||||
.else
|
||||
- movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp)
|
||||
+ andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp)
|
||||
.endif
|
||||
|
||||
/* Load Xen's intended value. */
|
||||
@@ -184,8 +187,8 @@
|
||||
*/
|
||||
xor %edx, %edx
|
||||
|
||||
- cmpb %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%rbx)
|
||||
- je .L\@_skip
|
||||
+ testb $SCF_use_shadow, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%rbx)
|
||||
+ jz .L\@_skip
|
||||
|
||||
mov STACK_CPUINFO_FIELD(shadow_spec_ctrl)(%rbx), %eax
|
||||
mov $MSR_SPEC_CTRL, %ecx
|
||||
@@ -206,7 +209,7 @@
|
||||
mov %eax, CPUINFO_shadow_spec_ctrl(%rsp)
|
||||
|
||||
/* Set SPEC_CTRL shadowing *before* loading the guest value. */
|
||||
- movb $1, CPUINFO_use_shadow_spec_ctrl(%rsp)
|
||||
+ orb $SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp)
|
||||
|
||||
mov $MSR_SPEC_CTRL, %ecx
|
||||
xor %edx, %edx
|
||||
@@ -217,7 +220,7 @@
|
||||
#define SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP32), \
|
||||
+ ALTERNATIVE_2 __stringify(ASM_NOP33), \
|
||||
__stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
ibrs_val=SPEC_CTRL_IBRS), \
|
||||
X86_FEATURE_XEN_IBRS_SET, \
|
||||
@@ -229,7 +232,7 @@
|
||||
#define SPEC_CTRL_ENTRY_FROM_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP21), \
|
||||
+ ALTERNATIVE_2 __stringify(ASM_NOP22), \
|
||||
__stringify(DO_SPEC_CTRL_ENTRY maybexen=0 \
|
||||
ibrs_val=SPEC_CTRL_IBRS), \
|
||||
X86_FEATURE_XEN_IBRS_SET, \
|
||||
@@ -240,7 +243,7 @@
|
||||
#define SPEC_CTRL_ENTRY_FROM_INTR \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP29), \
|
||||
+ ALTERNATIVE_2 __stringify(ASM_NOP33), \
|
||||
__stringify(DO_SPEC_CTRL_ENTRY maybexen=1 \
|
||||
ibrs_val=SPEC_CTRL_IBRS), \
|
||||
X86_FEATURE_XEN_IBRS_SET, \
|
||||
@@ -268,22 +271,23 @@
|
||||
* This is logical merge of DO_OVERWRITE_RSB and DO_SPEC_CTRL_ENTRY
|
||||
* maybexen=1, but with conditionals rather than alternatives.
|
||||
*/
|
||||
- movzbl STACK_CPUINFO_FIELD(bti_ist_info)(%r14), %eax
|
||||
+ movzbl STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14), %eax
|
||||
|
||||
- testb $BTI_IST_RSB, %al
|
||||
+ test $SCF_ist_rsb, %al
|
||||
jz .L\@_skip_rsb
|
||||
|
||||
DO_OVERWRITE_RSB tmp=rdx /* Clobbers %rcx/%rdx */
|
||||
|
||||
.L\@_skip_rsb:
|
||||
|
||||
- testb $BTI_IST_WRMSR, %al
|
||||
+ test $SCF_ist_wrmsr, %al
|
||||
jz .L\@_skip_wrmsr
|
||||
|
||||
xor %edx, %edx
|
||||
testb $3, UREGS_cs(%rsp)
|
||||
- setz %dl
|
||||
- and %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14)
|
||||
+ setnz %dl
|
||||
+ not %edx
|
||||
+ and %dl, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
|
||||
|
||||
/* Load Xen's intended value. */
|
||||
mov $MSR_SPEC_CTRL, %ecx
|
||||
@@ -310,7 +314,7 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise):
|
||||
* Requires %rbx=stack_end
|
||||
* Clobbers %rax, %rcx, %rdx
|
||||
*/
|
||||
- testb $BTI_IST_WRMSR, STACK_CPUINFO_FIELD(bti_ist_info)(%rbx)
|
||||
+ testb $SCF_ist_wrmsr, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%rbx)
|
||||
jz .L\@_skip
|
||||
|
||||
DO_SPEC_CTRL_EXIT_TO_XEN
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
From 0b1aded85866f48cdede20c54d30cf593f8a83f7 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Tue, 17 Apr 2018 14:15:04 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Fold the XEN_IBRS_{SET,CLEAR} ALTERNATIVES
|
||||
together
|
||||
|
||||
Currently, the SPEC_CTRL_{ENTRY,EXIT}_* macros encode Xen's choice of
|
||||
MSR_SPEC_CTRL as an immediate constant, and chooses between IBRS or not by
|
||||
doubling up the entire alternative block.
|
||||
|
||||
There is now a variable holding Xen's choice of value, so use that and
|
||||
simplify the alternatives.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit af949407eaba7af71067f23d5866cd0bf1f1144d)
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 12 +++++-----
|
||||
xen/include/asm-x86/cpufeatures.h | 3 +--
|
||||
xen/include/asm-x86/nops.h | 3 ++-
|
||||
xen/include/asm-x86/spec_ctrl.h | 6 ++---
|
||||
xen/include/asm-x86/spec_ctrl_asm.h | 45 +++++++++++++------------------------
|
||||
5 files changed, 26 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 2d69910..b62cfcc 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -112,8 +112,9 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
thunk == THUNK_JMP ? "JMP" : "?",
|
||||
- boot_cpu_has(X86_FEATURE_XEN_IBRS_SET) ? " IBRS+" :
|
||||
- boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR) ? " IBRS-" : "",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_MSR) ?
|
||||
+ default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" :
|
||||
+ " IBRS-" : "",
|
||||
opt_ibpb ? " IBPB" : "",
|
||||
boot_cpu_has(X86_FEATURE_RSB_NATIVE) ? " RSB_NATIVE" : "",
|
||||
boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ? " RSB_VMEXIT" : "");
|
||||
@@ -285,13 +286,10 @@ void __init init_speculation_mitigations(void)
|
||||
* need the IBRS entry/exit logic to virtualise IBRS support for
|
||||
* guests.
|
||||
*/
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR);
|
||||
+
|
||||
if ( ibrs )
|
||||
- {
|
||||
default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
|
||||
- setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET);
|
||||
- }
|
||||
- else
|
||||
- setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR);
|
||||
|
||||
default_spec_ctrl_flags |= SCF_ist_wrmsr;
|
||||
}
|
||||
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
|
||||
index c9b1a48..ca58b0e 100644
|
||||
--- a/xen/include/asm-x86/cpufeatures.h
|
||||
+++ b/xen/include/asm-x86/cpufeatures.h
|
||||
@@ -26,8 +26,7 @@ XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch S
|
||||
XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+13) /* Use IND_THUNK_LFENCE */
|
||||
XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
|
||||
XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+15) /* IBRSB || IBPB */
|
||||
-XEN_CPUFEATURE(XEN_IBRS_SET, (FSCAPINTS+0)*32+16) /* IBRSB && IRBS set in Xen */
|
||||
-XEN_CPUFEATURE(XEN_IBRS_CLEAR, (FSCAPINTS+0)*32+17) /* IBRSB && IBRS clear in Xen */
|
||||
+XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+16) /* MSR_SPEC_CTRL used by Xen */
|
||||
XEN_CPUFEATURE(RSB_NATIVE, (FSCAPINTS+0)*32+18) /* RSB overwrite needed for native */
|
||||
XEN_CPUFEATURE(RSB_VMEXIT, (FSCAPINTS+0)*32+19) /* RSB overwrite needed for vmexit */
|
||||
XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+20) /* XPTI mitigation not in use */
|
||||
diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h
|
||||
index b744895..913e9f0 100644
|
||||
--- a/xen/include/asm-x86/nops.h
|
||||
+++ b/xen/include/asm-x86/nops.h
|
||||
@@ -62,9 +62,10 @@
|
||||
#define ASM_NOP8 _ASM_MK_NOP(K8_NOP8)
|
||||
|
||||
#define ASM_NOP17 ASM_NOP8; ASM_NOP7; ASM_NOP2
|
||||
-#define ASM_NOP22 ASM_NOP8; ASM_NOP8; ASM_NOP6
|
||||
#define ASM_NOP24 ASM_NOP8; ASM_NOP8; ASM_NOP8
|
||||
+#define ASM_NOP25 ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2
|
||||
#define ASM_NOP33 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2
|
||||
+#define ASM_NOP36 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP4
|
||||
#define ASM_NOP40 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8
|
||||
|
||||
#define ASM_NOP_MAX 8
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 059e291..7d7c42e 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -52,14 +52,14 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
|
||||
barrier();
|
||||
info->spec_ctrl_flags |= SCF_use_shadow;
|
||||
barrier();
|
||||
- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
|
||||
+ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
}
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe before this call. */
|
||||
static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
|
||||
{
|
||||
- uint32_t val = SPEC_CTRL_IBRS;
|
||||
+ uint32_t val = info->xen_spec_ctrl;
|
||||
|
||||
/*
|
||||
* Disable shadowing before updating the MSR. There are no SMP issues
|
||||
@@ -67,7 +67,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
|
||||
*/
|
||||
info->spec_ctrl_flags &= ~SCF_use_shadow;
|
||||
barrier();
|
||||
- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
|
||||
+ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
}
|
||||
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
index 39fb4f8..17dd2cc 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
@@ -117,7 +117,7 @@
|
||||
mov %\tmp, %rsp /* Restore old %rsp */
|
||||
.endm
|
||||
|
||||
-.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req
|
||||
+.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT
|
||||
/*
|
||||
* Requires %rbx=current, %rsp=regs/cpuinfo
|
||||
* Clobbers %rax, %rcx, %rdx
|
||||
@@ -138,11 +138,11 @@
|
||||
andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp)
|
||||
|
||||
/* Load Xen's intended value. */
|
||||
- mov $\ibrs_val, %eax
|
||||
+ movzbl CPUINFO_xen_spec_ctrl(%rsp), %eax
|
||||
wrmsr
|
||||
.endm
|
||||
|
||||
-.macro DO_SPEC_CTRL_ENTRY maybexen:req ibrs_val:req
|
||||
+.macro DO_SPEC_CTRL_ENTRY maybexen:req
|
||||
/*
|
||||
* Requires %rsp=regs (also cpuinfo if !maybexen)
|
||||
* Requires %r14=stack_end (if maybexen)
|
||||
@@ -167,12 +167,12 @@
|
||||
setnz %al
|
||||
not %eax
|
||||
and %al, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14)
|
||||
+ movzbl STACK_CPUINFO_FIELD(xen_spec_ctrl)(%r14), %eax
|
||||
.else
|
||||
andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp)
|
||||
+ movzbl CPUINFO_xen_spec_ctrl(%rsp), %eax
|
||||
.endif
|
||||
|
||||
- /* Load Xen's intended value. */
|
||||
- mov $\ibrs_val, %eax
|
||||
wrmsr
|
||||
.endm
|
||||
|
||||
@@ -220,47 +220,32 @@
|
||||
#define SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP33), \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
- ibrs_val=SPEC_CTRL_IBRS), \
|
||||
- X86_FEATURE_XEN_IBRS_SET, \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
- ibrs_val=0), \
|
||||
- X86_FEATURE_XEN_IBRS_CLEAR
|
||||
+ ALTERNATIVE __stringify(ASM_NOP36), \
|
||||
+ DO_SPEC_CTRL_ENTRY_FROM_VMEXIT, X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */
|
||||
#define SPEC_CTRL_ENTRY_FROM_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP22), \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 \
|
||||
- ibrs_val=SPEC_CTRL_IBRS), \
|
||||
- X86_FEATURE_XEN_IBRS_SET, \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 ibrs_val=0), \
|
||||
- X86_FEATURE_XEN_IBRS_CLEAR
|
||||
+ ALTERNATIVE __stringify(ASM_NOP25), \
|
||||
+ __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use in interrupt/exception context. May interrupt Xen or PV context. */
|
||||
#define SPEC_CTRL_ENTRY_FROM_INTR \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP33), \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 \
|
||||
- ibrs_val=SPEC_CTRL_IBRS), \
|
||||
- X86_FEATURE_XEN_IBRS_SET, \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 ibrs_val=0), \
|
||||
- X86_FEATURE_XEN_IBRS_CLEAR
|
||||
+ ALTERNATIVE __stringify(ASM_NOP33), \
|
||||
+ __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use when exiting to Xen context. */
|
||||
#define SPEC_CTRL_EXIT_TO_XEN \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP17), \
|
||||
- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_SET, \
|
||||
- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_CLEAR
|
||||
+ ALTERNATIVE __stringify(ASM_NOP17), \
|
||||
+ DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use when exiting to guest context. */
|
||||
#define SPEC_CTRL_EXIT_TO_GUEST \
|
||||
- ALTERNATIVE_2 __stringify(ASM_NOP24), \
|
||||
- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_SET, \
|
||||
- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_CLEAR
|
||||
+ ALTERNATIVE __stringify(ASM_NOP24), \
|
||||
+ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR
|
||||
|
||||
/* TODO: Drop these when the alternatives infrastructure is NMI/#MC safe. */
|
||||
.macro SPEC_CTRL_ENTRY_FROM_INTR_IST
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,273 +0,0 @@
|
|||
From 5cc3611de7d09140e55caa2c2d120ad326fff937 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Mon, 30 Apr 2018 14:20:23 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Rename bits of infrastructure to avoid NATIVE
|
||||
and VMEXIT
|
||||
|
||||
In hindsight, using NATIVE and VMEXIT as naming terminology was not clever.
|
||||
A future change wants to split SPEC_CTRL_EXIT_TO_GUEST into PV and HVM
|
||||
specific implementations, and using VMEXIT as a term is completely wrong.
|
||||
|
||||
Take the opportunity to fix some stale documentation in spec_ctrl_asm.h. The
|
||||
IST helpers were missing from the large comment block, and since
|
||||
SPEC_CTRL_ENTRY_FROM_INTR_IST was introduced, we've gained a new piece of
|
||||
functionality which currently depends on the fine grain control, which exists
|
||||
in lieu of livepatching. Note this in the comment.
|
||||
|
||||
No functional change.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit d9822b8a38114e96e4516dc998f4055249364d5d)
|
||||
---
|
||||
xen/arch/x86/hvm/svm/entry.S | 4 ++--
|
||||
xen/arch/x86/hvm/vmx/entry.S | 4 ++--
|
||||
xen/arch/x86/spec_ctrl.c | 20 ++++++++++----------
|
||||
xen/arch/x86/x86_64/compat/entry.S | 2 +-
|
||||
xen/arch/x86/x86_64/entry.S | 2 +-
|
||||
xen/include/asm-x86/cpufeatures.h | 4 ++--
|
||||
xen/include/asm-x86/spec_ctrl_asm.h | 36 +++++++++++++++++++++++++-----------
|
||||
7 files changed, 43 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S
|
||||
index bf092fe..5e7c080 100644
|
||||
--- a/xen/arch/x86/hvm/svm/entry.S
|
||||
+++ b/xen/arch/x86/hvm/svm/entry.S
|
||||
@@ -83,7 +83,7 @@ UNLIKELY_END(svm_trace)
|
||||
mov VCPUMSR_spec_ctrl_raw(%rax), %eax
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
|
||||
- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
+ SPEC_CTRL_EXIT_TO_HVM /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
|
||||
pop %r15
|
||||
pop %r14
|
||||
@@ -108,7 +108,7 @@ UNLIKELY_END(svm_trace)
|
||||
|
||||
GET_CURRENT(bx)
|
||||
|
||||
- SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
|
||||
+ SPEC_CTRL_ENTRY_FROM_HVM /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
|
||||
|
||||
mov VCPU_svm_vmcb(%rbx),%rcx
|
||||
diff --git a/xen/arch/x86/hvm/vmx/entry.S b/xen/arch/x86/hvm/vmx/entry.S
|
||||
index e750544..aa2f103 100644
|
||||
--- a/xen/arch/x86/hvm/vmx/entry.S
|
||||
+++ b/xen/arch/x86/hvm/vmx/entry.S
|
||||
@@ -38,7 +38,7 @@ ENTRY(vmx_asm_vmexit_handler)
|
||||
movb $1,VCPU_vmx_launched(%rbx)
|
||||
mov %rax,VCPU_hvm_guest_cr2(%rbx)
|
||||
|
||||
- SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
|
||||
+ SPEC_CTRL_ENTRY_FROM_HVM /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */
|
||||
|
||||
mov %rsp,%rdi
|
||||
@@ -76,7 +76,7 @@ UNLIKELY_END(realmode)
|
||||
mov VCPUMSR_spec_ctrl_raw(%rax), %eax
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
|
||||
- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
+ SPEC_CTRL_EXIT_TO_HVM /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
|
||||
mov VCPU_hvm_guest_cr2(%rbx),%rax
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index b62cfcc..015a9e2 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -35,8 +35,8 @@ static enum ind_thunk {
|
||||
THUNK_JMP,
|
||||
} opt_thunk __initdata = THUNK_DEFAULT;
|
||||
static int8_t __initdata opt_ibrs = -1;
|
||||
-static bool __initdata opt_rsb_native = true;
|
||||
-static bool __initdata opt_rsb_vmexit = true;
|
||||
+static bool __initdata opt_rsb_pv = true;
|
||||
+static bool __initdata opt_rsb_hvm = true;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
uint8_t __read_mostly default_spec_ctrl_flags;
|
||||
@@ -69,9 +69,9 @@ static int __init parse_bti(const char *s)
|
||||
else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
|
||||
opt_ibpb = val;
|
||||
else if ( (val = parse_boolean("rsb_native", s, ss)) >= 0 )
|
||||
- opt_rsb_native = val;
|
||||
+ opt_rsb_pv = val;
|
||||
else if ( (val = parse_boolean("rsb_vmexit", s, ss)) >= 0 )
|
||||
- opt_rsb_vmexit = val;
|
||||
+ opt_rsb_hvm = val;
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
@@ -116,8 +116,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" :
|
||||
" IBRS-" : "",
|
||||
opt_ibpb ? " IBPB" : "",
|
||||
- boot_cpu_has(X86_FEATURE_RSB_NATIVE) ? " RSB_NATIVE" : "",
|
||||
- boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ? " RSB_VMEXIT" : "");
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB_NATIVE" : "",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB_VMEXIT" : "");
|
||||
|
||||
printk("XPTI: %s\n",
|
||||
boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled");
|
||||
@@ -307,9 +307,9 @@ void __init init_speculation_mitigations(void)
|
||||
* If a processors speculates to 32bit PV guest kernel mappings, it is
|
||||
* speculating in 64bit supervisor mode, and can leak data.
|
||||
*/
|
||||
- if ( opt_rsb_native )
|
||||
+ if ( opt_rsb_pv )
|
||||
{
|
||||
- setup_force_cpu_cap(X86_FEATURE_RSB_NATIVE);
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_RSB_PV);
|
||||
default_spec_ctrl_flags |= SCF_ist_rsb;
|
||||
}
|
||||
|
||||
@@ -317,8 +317,8 @@ void __init init_speculation_mitigations(void)
|
||||
* HVM guests can always poison the RSB to point at Xen supervisor
|
||||
* mappings.
|
||||
*/
|
||||
- if ( opt_rsb_vmexit )
|
||||
- setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
|
||||
+ if ( opt_rsb_hvm )
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_RSB_HVM);
|
||||
|
||||
/* Check we have hardware IBPB support before using it... */
|
||||
if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) )
|
||||
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
|
||||
index a47cb9d..6a27d98 100644
|
||||
--- a/xen/arch/x86/x86_64/compat/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/compat/entry.S
|
||||
@@ -166,7 +166,7 @@ ENTRY(compat_restore_all_guest)
|
||||
mov VCPUMSR_spec_ctrl_raw(%rax), %eax
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
|
||||
- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
+ SPEC_CTRL_EXIT_TO_PV /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
|
||||
RESTORE_ALL adj=8 compat=1
|
||||
.Lft0: iretq
|
||||
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
|
||||
index 41d3ec2..0a0763a 100644
|
||||
--- a/xen/arch/x86/x86_64/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/entry.S
|
||||
@@ -196,7 +196,7 @@ restore_all_guest:
|
||||
mov %r15d, %eax
|
||||
|
||||
/* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */
|
||||
- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
+ SPEC_CTRL_EXIT_TO_PV /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */
|
||||
|
||||
RESTORE_ALL
|
||||
testw $TRAP_syscall,4(%rsp)
|
||||
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
|
||||
index ca58b0e..f9aa5d7 100644
|
||||
--- a/xen/include/asm-x86/cpufeatures.h
|
||||
+++ b/xen/include/asm-x86/cpufeatures.h
|
||||
@@ -27,6 +27,6 @@ XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+13) /* Use IND_THUNK_LFENCE */
|
||||
XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
|
||||
XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+15) /* IBRSB || IBPB */
|
||||
XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+16) /* MSR_SPEC_CTRL used by Xen */
|
||||
-XEN_CPUFEATURE(RSB_NATIVE, (FSCAPINTS+0)*32+18) /* RSB overwrite needed for native */
|
||||
-XEN_CPUFEATURE(RSB_VMEXIT, (FSCAPINTS+0)*32+19) /* RSB overwrite needed for vmexit */
|
||||
+XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+18) /* RSB overwrite needed for PV */
|
||||
+XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+19) /* RSB overwrite needed for HVM */
|
||||
XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+20) /* XPTI mitigation not in use */
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
index 17dd2cc..3d156ed 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
@@ -72,11 +72,14 @@
|
||||
*
|
||||
* The following ASM fragments implement this algorithm. See their local
|
||||
* comments for further details.
|
||||
- * - SPEC_CTRL_ENTRY_FROM_VMEXIT
|
||||
+ * - SPEC_CTRL_ENTRY_FROM_HVM
|
||||
* - SPEC_CTRL_ENTRY_FROM_PV
|
||||
* - SPEC_CTRL_ENTRY_FROM_INTR
|
||||
+ * - SPEC_CTRL_ENTRY_FROM_INTR_IST
|
||||
+ * - SPEC_CTRL_EXIT_TO_XEN_IST
|
||||
* - SPEC_CTRL_EXIT_TO_XEN
|
||||
- * - SPEC_CTRL_EXIT_TO_GUEST
|
||||
+ * - SPEC_CTRL_EXIT_TO_PV
|
||||
+ * - SPEC_CTRL_EXIT_TO_HVM
|
||||
*/
|
||||
|
||||
.macro DO_OVERWRITE_RSB tmp=rax
|
||||
@@ -117,7 +120,7 @@
|
||||
mov %\tmp, %rsp /* Restore old %rsp */
|
||||
.endm
|
||||
|
||||
-.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT
|
||||
+.macro DO_SPEC_CTRL_ENTRY_FROM_HVM
|
||||
/*
|
||||
* Requires %rbx=current, %rsp=regs/cpuinfo
|
||||
* Clobbers %rax, %rcx, %rdx
|
||||
@@ -217,23 +220,23 @@
|
||||
.endm
|
||||
|
||||
/* Use after a VMEXIT from an HVM guest. */
|
||||
-#define SPEC_CTRL_ENTRY_FROM_VMEXIT \
|
||||
+#define SPEC_CTRL_ENTRY_FROM_HVM \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
- DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \
|
||||
+ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_HVM; \
|
||||
ALTERNATIVE __stringify(ASM_NOP36), \
|
||||
- DO_SPEC_CTRL_ENTRY_FROM_VMEXIT, X86_FEATURE_SC_MSR
|
||||
+ DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */
|
||||
#define SPEC_CTRL_ENTRY_FROM_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
- DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
+ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \
|
||||
ALTERNATIVE __stringify(ASM_NOP25), \
|
||||
__stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR
|
||||
|
||||
/* Use in interrupt/exception context. May interrupt Xen or PV context. */
|
||||
#define SPEC_CTRL_ENTRY_FROM_INTR \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
- DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \
|
||||
+ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \
|
||||
ALTERNATIVE __stringify(ASM_NOP33), \
|
||||
__stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR
|
||||
|
||||
@@ -242,12 +245,22 @@
|
||||
ALTERNATIVE __stringify(ASM_NOP17), \
|
||||
DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR
|
||||
|
||||
-/* Use when exiting to guest context. */
|
||||
-#define SPEC_CTRL_EXIT_TO_GUEST \
|
||||
+/* Use when exiting to PV guest context. */
|
||||
+#define SPEC_CTRL_EXIT_TO_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP24), \
|
||||
DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR
|
||||
|
||||
-/* TODO: Drop these when the alternatives infrastructure is NMI/#MC safe. */
|
||||
+/* Use when exiting to HVM guest context. */
|
||||
+#define SPEC_CTRL_EXIT_TO_HVM \
|
||||
+ ALTERNATIVE __stringify(ASM_NOP24), \
|
||||
+ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR
|
||||
+
|
||||
+/*
|
||||
+ * Use in IST interrupt/exception context. May interrupt Xen or PV context.
|
||||
+ * Fine grain control of SCF_ist_wrmsr is needed for safety in the S3 resume
|
||||
+ * path to avoid using MSR_SPEC_CTRL before the microcode introducing it has
|
||||
+ * been reloaded.
|
||||
+ */
|
||||
.macro SPEC_CTRL_ENTRY_FROM_INTR_IST
|
||||
/*
|
||||
* Requires %rsp=regs, %r14=stack_end
|
||||
@@ -294,6 +307,7 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise):
|
||||
UNLIKELY_END(\@_serialise)
|
||||
.endm
|
||||
|
||||
+/* Use when exiting to Xen in IST context. */
|
||||
.macro SPEC_CTRL_EXIT_TO_XEN_IST
|
||||
/*
|
||||
* Requires %rbx=stack_end
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
From 811fcf5137abdcd5b9ea7e5212098adb5bedae0f Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Mon, 7 May 2018 14:06:16 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Elide MSR_SPEC_CTRL handling in idle context
|
||||
when possible
|
||||
|
||||
If Xen is virtualising MSR_SPEC_CTRL handling for guests, but using 0 as its
|
||||
own MSR_SPEC_CTRL value, spec_ctrl_{enter,exit}_idle() need not write to the
|
||||
MSR.
|
||||
|
||||
Requested-by: Jan Beulich <JBeulich@suse.com>
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit 94df6e8588e35cc2028ccb3fd2921c6e6360605e)
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 4 ++++
|
||||
xen/include/asm-x86/cpufeatures.h | 1 +
|
||||
xen/include/asm-x86/spec_ctrl.h | 4 ++--
|
||||
3 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 015a9e2..55ef79f 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -327,6 +327,10 @@ void __init init_speculation_mitigations(void)
|
||||
/* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */
|
||||
init_shadow_spec_ctrl_state();
|
||||
|
||||
+ /* If Xen is using any MSR_SPEC_CTRL settings, adjust the idle path. */
|
||||
+ if ( default_xen_spec_ctrl )
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE);
|
||||
+
|
||||
print_details(thunk, caps);
|
||||
}
|
||||
|
||||
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
|
||||
index f9aa5d7..32b7f04 100644
|
||||
--- a/xen/include/asm-x86/cpufeatures.h
|
||||
+++ b/xen/include/asm-x86/cpufeatures.h
|
||||
@@ -30,3 +30,4 @@ XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+16) /* MSR_SPEC_CTRL used by Xe
|
||||
XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+18) /* RSB overwrite needed for PV */
|
||||
XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+19) /* RSB overwrite needed for HVM */
|
||||
XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+20) /* XPTI mitigation not in use */
|
||||
+XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+21) /* SC_MSR && default_xen_spec_ctrl */
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 7d7c42e..77f92ba 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -52,7 +52,7 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
|
||||
barrier();
|
||||
info->spec_ctrl_flags |= SCF_use_shadow;
|
||||
barrier();
|
||||
- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR)
|
||||
+ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR_IDLE)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
|
||||
*/
|
||||
info->spec_ctrl_flags &= ~SCF_use_shadow;
|
||||
barrier();
|
||||
- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR)
|
||||
+ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR_IDLE)
|
||||
:: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" );
|
||||
}
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
From 2acc4cba7eb2559bafdd4d8238466ad81322a35a Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Tue, 17 Apr 2018 14:15:04 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Split X86_FEATURE_SC_MSR into PV and HVM
|
||||
variants
|
||||
|
||||
In order to separately control whether MSR_SPEC_CTRL is virtualised for PV and
|
||||
HVM guests, split the feature used to control runtime alternatives into two.
|
||||
Xen will use MSR_SPEC_CTRL itself if either of these features are active.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit fa9eb09d446a1279f5e861e6b84fa8675dabf148)
|
||||
---
|
||||
xen/arch/x86/spec_ctrl.c | 6 ++++--
|
||||
xen/include/asm-x86/cpufeatures.h | 5 +++--
|
||||
xen/include/asm-x86/spec_ctrl_asm.h | 12 ++++++------
|
||||
3 files changed, 13 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 55ef79f..a940308 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -112,7 +112,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
thunk == THUNK_JMP ? "JMP" : "?",
|
||||
- boot_cpu_has(X86_FEATURE_SC_MSR) ?
|
||||
+ (boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
|
||||
+ boot_cpu_has(X86_FEATURE_SC_MSR_HVM)) ?
|
||||
default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" :
|
||||
" IBRS-" : "",
|
||||
opt_ibpb ? " IBPB" : "",
|
||||
@@ -286,7 +287,8 @@ void __init init_speculation_mitigations(void)
|
||||
* need the IBRS entry/exit logic to virtualise IBRS support for
|
||||
* guests.
|
||||
*/
|
||||
- setup_force_cpu_cap(X86_FEATURE_SC_MSR);
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV);
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM);
|
||||
|
||||
if ( ibrs )
|
||||
default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
|
||||
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
|
||||
index 32b7f04..b90aa2d 100644
|
||||
--- a/xen/include/asm-x86/cpufeatures.h
|
||||
+++ b/xen/include/asm-x86/cpufeatures.h
|
||||
@@ -26,8 +26,9 @@ XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+12) /* lfence set as Dispatch S
|
||||
XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+13) /* Use IND_THUNK_LFENCE */
|
||||
XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+14) /* Use IND_THUNK_JMP */
|
||||
XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+15) /* IBRSB || IBPB */
|
||||
-XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+16) /* MSR_SPEC_CTRL used by Xen */
|
||||
+XEN_CPUFEATURE(SC_MSR_PV, (FSCAPINTS+0)*32+16) /* MSR_SPEC_CTRL used by Xen for PV */
|
||||
+XEN_CPUFEATURE(SC_MSR_HVM, (FSCAPINTS+0)*32+17) /* MSR_SPEC_CTRL used by Xen for HVM */
|
||||
XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+18) /* RSB overwrite needed for PV */
|
||||
XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+19) /* RSB overwrite needed for HVM */
|
||||
XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+20) /* XPTI mitigation not in use */
|
||||
-XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+21) /* SC_MSR && default_xen_spec_ctrl */
|
||||
+XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+21) /* (SC_MSR_PV || SC_MSR_HVM) && default_xen_spec_ctrl */
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
index 3d156ed..c659f3f 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl_asm.h
|
||||
@@ -224,36 +224,36 @@
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_HVM; \
|
||||
ALTERNATIVE __stringify(ASM_NOP36), \
|
||||
- DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR
|
||||
+ DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR_HVM
|
||||
|
||||
/* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */
|
||||
#define SPEC_CTRL_ENTRY_FROM_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \
|
||||
ALTERNATIVE __stringify(ASM_NOP25), \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR
|
||||
+ __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR_PV
|
||||
|
||||
/* Use in interrupt/exception context. May interrupt Xen or PV context. */
|
||||
#define SPEC_CTRL_ENTRY_FROM_INTR \
|
||||
ALTERNATIVE __stringify(ASM_NOP40), \
|
||||
DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \
|
||||
ALTERNATIVE __stringify(ASM_NOP33), \
|
||||
- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR
|
||||
+ __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR_PV
|
||||
|
||||
/* Use when exiting to Xen context. */
|
||||
#define SPEC_CTRL_EXIT_TO_XEN \
|
||||
ALTERNATIVE __stringify(ASM_NOP17), \
|
||||
- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR
|
||||
+ DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR_PV
|
||||
|
||||
/* Use when exiting to PV guest context. */
|
||||
#define SPEC_CTRL_EXIT_TO_PV \
|
||||
ALTERNATIVE __stringify(ASM_NOP24), \
|
||||
- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR
|
||||
+ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR_PV
|
||||
|
||||
/* Use when exiting to HVM guest context. */
|
||||
#define SPEC_CTRL_EXIT_TO_HVM \
|
||||
ALTERNATIVE __stringify(ASM_NOP24), \
|
||||
- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR
|
||||
+ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR_HVM
|
||||
|
||||
/*
|
||||
* Use in IST interrupt/exception context. May interrupt Xen or PV context.
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
From 5b223f41d59887ea5d13e2406597ff472ba6f2fc Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Wed, 9 May 2018 13:59:56 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Explicitly set Xen's default MSR_SPEC_CTRL
|
||||
value
|
||||
|
||||
With the impending ability to disable MSR_SPEC_CTRL handling on a
|
||||
per-guest-type basis, the first exit-from-guest may not have the side effect
|
||||
of loading Xen's choice of value. Explicitly set Xen's default during the BSP
|
||||
and AP boot paths.
|
||||
|
||||
For the BSP however, delay setting a non-zero MSR_SPEC_CTRL default until
|
||||
after dom0 has been constructed when safe to do so. Oracle report that this
|
||||
speeds up boots of some hardware by 50s.
|
||||
|
||||
"when safe to do so" is based on whether we are virtualised. A native boot
|
||||
won't have any other code running in a position to mount an attack.
|
||||
|
||||
Reported-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit cb8c12020307b39a89273d7699e89000451987ab)
|
||||
---
|
||||
xen/arch/x86/setup.c | 7 +++++++
|
||||
xen/arch/x86/smpboot.c | 8 ++++++++
|
||||
xen/arch/x86/spec_ctrl.c | 32 ++++++++++++++++++++++++++++++++
|
||||
xen/include/asm-x86/spec_ctrl.h | 2 ++
|
||||
4 files changed, 49 insertions(+)
|
||||
|
||||
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
|
||||
index 482fe11..1995c4c 100644
|
||||
--- a/xen/arch/x86/setup.c
|
||||
+++ b/xen/arch/x86/setup.c
|
||||
@@ -1746,6 +1746,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
|
||||
|
||||
setup_io_bitmap(dom0);
|
||||
|
||||
+ if ( bsp_delay_spec_ctrl )
|
||||
+ {
|
||||
+ get_cpu_info()->spec_ctrl_flags &= ~SCF_use_shadow;
|
||||
+ barrier();
|
||||
+ wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl);
|
||||
+ }
|
||||
+
|
||||
/* Jump to the 1:1 virtual mappings of cpu0_stack. */
|
||||
asm volatile ("mov %[stk], %%rsp; jmp %c[fn]" ::
|
||||
[stk] "g" (__va(__pa(get_stack_bottom()))),
|
||||
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
|
||||
index f81fc2c..ee8b183 100644
|
||||
--- a/xen/arch/x86/smpboot.c
|
||||
+++ b/xen/arch/x86/smpboot.c
|
||||
@@ -351,6 +351,14 @@ void start_secondary(void *unused)
|
||||
else
|
||||
microcode_resume_cpu(cpu);
|
||||
|
||||
+ /*
|
||||
+ * 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 ( boot_cpu_has(X86_FEATURE_IBRSB) )
|
||||
+ wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl);
|
||||
+
|
||||
if ( xen_guest )
|
||||
hypervisor_ap_setup();
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index a940308..3adec1a 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -38,6 +38,8 @@ static int8_t __initdata opt_ibrs = -1;
|
||||
static bool __initdata opt_rsb_pv = true;
|
||||
static bool __initdata opt_rsb_hvm = true;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
+
|
||||
+bool __initdata bsp_delay_spec_ctrl;
|
||||
uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
uint8_t __read_mostly default_spec_ctrl_flags;
|
||||
|
||||
@@ -334,6 +336,36 @@ void __init init_speculation_mitigations(void)
|
||||
setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE);
|
||||
|
||||
print_details(thunk, caps);
|
||||
+
|
||||
+ /*
|
||||
+ * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard
|
||||
+ * any firmware settings. For performance reasons, when safe to do so, we
|
||||
+ * delay applying non-zero settings until after dom0 has been constructed.
|
||||
+ *
|
||||
+ * "when safe to do so" is based on whether we are virtualised. A native
|
||||
+ * boot won't have any other code running in a position to mount an
|
||||
+ * attack.
|
||||
+ */
|
||||
+ if ( boot_cpu_has(X86_FEATURE_IBRSB) )
|
||||
+ {
|
||||
+ bsp_delay_spec_ctrl = !cpu_has_hypervisor && default_xen_spec_ctrl;
|
||||
+
|
||||
+ /*
|
||||
+ * If delaying MSR_SPEC_CTRL setup, use the same mechanism as
|
||||
+ * spec_ctrl_enter_idle(), by using a shadow value of zero.
|
||||
+ */
|
||||
+ if ( bsp_delay_spec_ctrl )
|
||||
+ {
|
||||
+ struct cpu_info *info = get_cpu_info();
|
||||
+
|
||||
+ info->shadow_spec_ctrl = 0;
|
||||
+ barrier();
|
||||
+ info->spec_ctrl_flags |= SCF_use_shadow;
|
||||
+ barrier();
|
||||
+ }
|
||||
+
|
||||
+ wrmsrl(MSR_SPEC_CTRL, bsp_delay_spec_ctrl ? 0 : default_xen_spec_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 77f92ba..c6a38f4 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -27,6 +27,8 @@
|
||||
void init_speculation_mitigations(void);
|
||||
|
||||
extern bool opt_ibpb;
|
||||
+
|
||||
+extern bool bsp_delay_spec_ctrl;
|
||||
extern uint8_t default_xen_spec_ctrl;
|
||||
extern uint8_t default_spec_ctrl_flags;
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
From bce7a2145abc3c7e5bfd7e2168714d194124a3ab Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Tue, 1 May 2018 11:59:03 +0100
|
||||
Subject: [PATCH] x86/cpuid: Improvements to guest policies for speculative
|
||||
sidechannel features
|
||||
|
||||
If Xen isn't virtualising MSR_SPEC_CTRL for guests, IBRSB shouldn't be
|
||||
advertised. It is not currently possible to express this via the existing
|
||||
command line options, but such an ability will be introduced.
|
||||
|
||||
Another useful option in some usecases is to offer IBPB without IBRS. When a
|
||||
guest kernel is known to be compatible (uses retpoline and knows about the AMD
|
||||
IBPB feature bit), an administrator with pre-Skylake hardware may wish to hide
|
||||
IBRS. This allows the VM to have full protection, without Xen or the VM
|
||||
needing to touch MSR_SPEC_CTRL, which can reduce the overhead of Spectre
|
||||
mitigations.
|
||||
|
||||
Break the logic common to both PV and HVM CPUID calculations into a common
|
||||
helper, to avoid duplication.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit cb06b308ec71b23f37a44f5e2351fe2cae0306e9)
|
||||
---
|
||||
xen/arch/x86/cpuid.c | 60 ++++++++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 37 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
|
||||
index b3c9ac6..b45b145 100644
|
||||
--- a/xen/arch/x86/cpuid.c
|
||||
+++ b/xen/arch/x86/cpuid.c
|
||||
@@ -368,6 +368,28 @@ static void __init calculate_host_policy(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void __init guest_common_feature_adjustments(uint32_t *fs)
|
||||
+{
|
||||
+ /* Unconditionally claim to be able to set the hypervisor bit. */
|
||||
+ __set_bit(X86_FEATURE_HYPERVISOR, fs);
|
||||
+
|
||||
+ /*
|
||||
+ * If IBRS is offered to the guest, unconditionally offer STIBP. It is a
|
||||
+ * nop on non-HT hardware, and has this behaviour to make heterogeneous
|
||||
+ * setups easier to manage.
|
||||
+ */
|
||||
+ if ( test_bit(X86_FEATURE_IBRSB, fs) )
|
||||
+ __set_bit(X86_FEATURE_STIBP, fs);
|
||||
+
|
||||
+ /*
|
||||
+ * On hardware which supports IBRS/IBPB, we can offer IBPB independently
|
||||
+ * of IBRS by using the AMD feature bit. An administrator may wish for
|
||||
+ * performance reasons to offer IBPB without IBRS.
|
||||
+ */
|
||||
+ if ( host_cpuid_policy.feat.ibrsb )
|
||||
+ __set_bit(X86_FEATURE_IBPB, fs);
|
||||
+}
|
||||
+
|
||||
static void __init calculate_pv_max_policy(void)
|
||||
{
|
||||
struct cpuid_policy *p = &pv_max_cpuid_policy;
|
||||
@@ -380,18 +402,14 @@ static void __init calculate_pv_max_policy(void)
|
||||
for ( i = 0; i < ARRAY_SIZE(pv_featureset); ++i )
|
||||
pv_featureset[i] &= pv_featuremask[i];
|
||||
|
||||
- /* Unconditionally claim to be able to set the hypervisor bit. */
|
||||
- __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset);
|
||||
-
|
||||
- /* On hardware with IBRS/IBPB support, there are further adjustments. */
|
||||
- if ( test_bit(X86_FEATURE_IBRSB, pv_featureset) )
|
||||
- {
|
||||
- /* Offer STIBP unconditionally. It is a nop on non-HT hardware. */
|
||||
- __set_bit(X86_FEATURE_STIBP, pv_featureset);
|
||||
+ /*
|
||||
+ * If Xen isn't virtualising MSR_SPEC_CTRL for PV guests because of
|
||||
+ * administrator choice, hide the feature.
|
||||
+ */
|
||||
+ if ( !boot_cpu_has(X86_FEATURE_SC_MSR_PV) )
|
||||
+ __clear_bit(X86_FEATURE_IBRSB, pv_featureset);
|
||||
|
||||
- /* AMD's IBPB is a subset of IBRS/IBPB. */
|
||||
- __set_bit(X86_FEATURE_IBPB, pv_featureset);
|
||||
- }
|
||||
+ guest_common_feature_adjustments(pv_featureset);
|
||||
|
||||
sanitise_featureset(pv_featureset);
|
||||
cpuid_featureset_to_policy(pv_featureset, p);
|
||||
@@ -419,9 +437,6 @@ static void __init calculate_hvm_max_policy(void)
|
||||
for ( i = 0; i < ARRAY_SIZE(hvm_featureset); ++i )
|
||||
hvm_featureset[i] &= hvm_featuremask[i];
|
||||
|
||||
- /* Unconditionally claim to be able to set the hypervisor bit. */
|
||||
- __set_bit(X86_FEATURE_HYPERVISOR, hvm_featureset);
|
||||
-
|
||||
/*
|
||||
* Xen can provide an APIC emulation to HVM guests even if the host's APIC
|
||||
* isn't enabled.
|
||||
@@ -438,6 +453,13 @@ static void __init calculate_hvm_max_policy(void)
|
||||
__set_bit(X86_FEATURE_SEP, hvm_featureset);
|
||||
|
||||
/*
|
||||
+ * If Xen isn't virtualising MSR_SPEC_CTRL for HVM guests because of
|
||||
+ * administrator choice, hide the feature.
|
||||
+ */
|
||||
+ if ( !boot_cpu_has(X86_FEATURE_SC_MSR_HVM) )
|
||||
+ __clear_bit(X86_FEATURE_IBRSB, hvm_featureset);
|
||||
+
|
||||
+ /*
|
||||
* With VT-x, some features are only supported by Xen if dedicated
|
||||
* hardware support is also available.
|
||||
*/
|
||||
@@ -450,15 +472,7 @@ static void __init calculate_hvm_max_policy(void)
|
||||
__clear_bit(X86_FEATURE_XSAVES, hvm_featureset);
|
||||
}
|
||||
|
||||
- /* On hardware with IBRS/IBPB support, there are further adjustments. */
|
||||
- if ( test_bit(X86_FEATURE_IBRSB, hvm_featureset) )
|
||||
- {
|
||||
- /* Offer STIBP unconditionally. It is a nop on non-HT hardware. */
|
||||
- __set_bit(X86_FEATURE_STIBP, hvm_featureset);
|
||||
-
|
||||
- /* AMD's IBPB is a subset of IBRS/IBPB. */
|
||||
- __set_bit(X86_FEATURE_IBPB, hvm_featureset);
|
||||
- }
|
||||
+ guest_common_feature_adjustments(hvm_featureset);
|
||||
|
||||
sanitise_featureset(hvm_featureset);
|
||||
cpuid_featureset_to_policy(hvm_featureset, p);
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,344 +0,0 @@
|
|||
From 952ff9f5590e37952d7dd3d89e16a47a238ab079 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Thu, 26 Apr 2018 10:52:55 +0100
|
||||
Subject: [PATCH] x86/spec_ctrl: Introduce a new `spec-ctrl=` command line
|
||||
argument to replace `bti=`
|
||||
|
||||
In hindsight, the options for `bti=` aren't as flexible or useful as expected
|
||||
(including several options which don't appear to behave as intended).
|
||||
Changing the behaviour of an existing option is problematic for compatibility,
|
||||
so introduce a new `spec-ctrl=` in the hopes that we can do better.
|
||||
|
||||
One common way of deploying Xen is with a single PV dom0 and all domUs being
|
||||
HVM domains. In such a setup, an administrator who has weighed up the risks
|
||||
may wish to forgo protection against malicious PV domains, to reduce the
|
||||
overall performance hit. To cater for this usecase, `spec-ctrl=no-pv` will
|
||||
disable all speculative protection for PV domains, while leaving all
|
||||
speculative protection for HVM domains intact.
|
||||
|
||||
For coding clarity as much as anything else, the suboptions are grouped by
|
||||
logical area; those which affect the alternatives blocks, and those which
|
||||
affect Xen's in-hypervisor settings. See the xen-command-line.markdown for
|
||||
full details of the new options.
|
||||
|
||||
While changing the command line options, take the time to change how the data
|
||||
is reported to the user. The three DEBUG printks are upgraded to unilateral,
|
||||
as they are all relevant pieces of information, and the old "mitigations:"
|
||||
line is split in the two logical areas described above.
|
||||
|
||||
Sample output from booting with `spec-ctrl=no-pv` looks like:
|
||||
|
||||
(XEN) Speculative mitigation facilities:
|
||||
(XEN) Hardware features: IBRS/IBPB STIBP IBPB
|
||||
(XEN) Compiled-in support: INDIRECT_THUNK
|
||||
(XEN) Xen settings: BTI-Thunk RETPOLINE, SPEC_CTRL: IBRS-, Other: IBPB
|
||||
(XEN) Support for VMs: PV: None, HVM: MSR_SPEC_CTRL RSB
|
||||
(XEN) XPTI (64-bit PV only): Dom0 enabled, DomU enabled
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Release-acked-by: Juergen Gross <jgross@suse.com>
|
||||
(cherry picked from commit 3352afc26c497d26ecb70527db3cb29daf7b1422)
|
||||
---
|
||||
docs/misc/xen-command-line.markdown | 49 +++++++++++
|
||||
xen/arch/x86/spec_ctrl.c | 160 ++++++++++++++++++++++++++++++------
|
||||
2 files changed, 186 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
||||
index 6c673ee..43a6ddb 100644
|
||||
--- a/docs/misc/xen-command-line.markdown
|
||||
+++ b/docs/misc/xen-command-line.markdown
|
||||
@@ -248,6 +248,9 @@ the NMI watchdog is also enabled.
|
||||
### bti (x86)
|
||||
> `= List of [ thunk=retpoline|lfence|jmp, ibrs=<bool>, ibpb=<bool>, rsb_{vmexit,native}=<bool> ]`
|
||||
|
||||
+**WARNING: This command line option is deprecated, and superseded by
|
||||
+_spec-ctrl=_ - using both options in combination is undefined.**
|
||||
+
|
||||
Branch Target Injection controls. By default, Xen will pick the most
|
||||
appropriate BTI mitigations based on compiled in support, loaded microcode,
|
||||
and hardware details.
|
||||
@@ -1698,6 +1701,52 @@ enforces the maximum theoretically necessary timeout of 670ms. Any number
|
||||
is being interpreted as a custom timeout in milliseconds. Zero or boolean
|
||||
false disable the quirk workaround, which is also the default.
|
||||
|
||||
+### spec-ctrl (x86)
|
||||
+> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>,
|
||||
+> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb}=<bool> ]`
|
||||
+
|
||||
+Controls for speculative execution sidechannel mitigations. By default, Xen
|
||||
+will pick the most appropriate mitigations based on compiled in support,
|
||||
+loaded microcode, and hardware details, and will virtualise appropriate
|
||||
+mitigations for guests to use.
|
||||
+
|
||||
+**WARNING: Any use of this option may interfere with heuristics. Use with
|
||||
+extreme care.**
|
||||
+
|
||||
+An overall boolean value, `spec-ctrl=no`, can be specified to turn off all
|
||||
+mitigations, including pieces of infrastructure used to virtualise certain
|
||||
+mitigation features for guests. Alternatively, a slightly more restricted
|
||||
+`spec-ctrl=no-xen` can be used to turn off all of Xen's mitigations, while
|
||||
+leaving the virtualisation support in place for guests to use. Use of a
|
||||
+positive boolean value for either of these options is invalid.
|
||||
+
|
||||
+The booleans `pv=`, `hvm=`, `msr-sc=` and `rsb=` offer fine grained control
|
||||
+over the alternative blocks used by Xen. These impact Xen's ability to
|
||||
+protect itself, and Xen's ability to virtualise support for guests to use.
|
||||
+
|
||||
+* `pv=` and `hvm=` offer control over all suboptions for PV and HVM guests
|
||||
+ respectively.
|
||||
+* `msr-sc=` offers control over Xen's support for manipulating MSR\_SPEC\_CTRL
|
||||
+ on entry and exit. These blocks are necessary to virtualise support for
|
||||
+ guests and if disabled, guests will be unable to use IBRS/STIBP/etc.
|
||||
+* `rsb=` offers control over whether to overwrite the Return Stack Buffer /
|
||||
+ Return Address Stack on entry to Xen.
|
||||
+
|
||||
+If Xen was compiled with INDIRECT\_THUNK support, `bti-thunk=` can be used to
|
||||
+select which of the thunks gets patched into the `__x86_indirect_thunk_%reg`
|
||||
+locations. The default thunk is `retpoline` (generally preferred for Intel
|
||||
+hardware), with the alternatives being `jmp` (a `jmp *%reg` gadget, minimal
|
||||
+overhead), and `lfence` (an `lfence; jmp *%reg` gadget, preferred for AMD).
|
||||
+
|
||||
+On hardware supporting IBRS (Indirect Branch Restricted Speculation), the
|
||||
+`ibrs=` option can be used to force or prevent Xen using the feature itself.
|
||||
+If Xen is not using IBRS itself, functionality is still set up so IBRS can be
|
||||
+virtualised for guests.
|
||||
+
|
||||
+On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=`
|
||||
+option can be used to force (the default) or prevent Xen from issuing branch
|
||||
+prediction barriers on vcpu context switches.
|
||||
+
|
||||
### sync\_console
|
||||
> `= <boolean>`
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 3adec1a..4f9282f 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -26,6 +26,13 @@
|
||||
#include <asm/spec_ctrl.h>
|
||||
#include <asm/spec_ctrl_asm.h>
|
||||
|
||||
+/* Cmdline controls for Xen's alternative blocks. */
|
||||
+static bool __initdata opt_msr_sc_pv = true;
|
||||
+static bool __initdata opt_msr_sc_hvm = true;
|
||||
+static bool __initdata opt_rsb_pv = true;
|
||||
+static bool __initdata opt_rsb_hvm = true;
|
||||
+
|
||||
+/* Cmdline controls for Xen's speculative settings. */
|
||||
static enum ind_thunk {
|
||||
THUNK_DEFAULT, /* Decide which thunk to use at boot time. */
|
||||
THUNK_NONE, /* Missing compiler support for thunks. */
|
||||
@@ -35,8 +42,6 @@ static enum ind_thunk {
|
||||
THUNK_JMP,
|
||||
} opt_thunk __initdata = THUNK_DEFAULT;
|
||||
static int8_t __initdata opt_ibrs = -1;
|
||||
-static bool __initdata opt_rsb_pv = true;
|
||||
-static bool __initdata opt_rsb_hvm = true;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
|
||||
bool __initdata bsp_delay_spec_ctrl;
|
||||
@@ -84,8 +89,95 @@ static int __init parse_bti(const char *s)
|
||||
}
|
||||
custom_param("bti", parse_bti);
|
||||
|
||||
+static int __init parse_spec_ctrl(const char *s)
|
||||
+{
|
||||
+ const char *ss;
|
||||
+ int val, rc = 0;
|
||||
+
|
||||
+ do {
|
||||
+ ss = strchr(s, ',');
|
||||
+ if ( !ss )
|
||||
+ ss = strchr(s, '\0');
|
||||
+
|
||||
+ /* Global and Xen-wide disable. */
|
||||
+ val = parse_bool(s, ss);
|
||||
+ if ( !val )
|
||||
+ {
|
||||
+ opt_msr_sc_pv = false;
|
||||
+ opt_msr_sc_hvm = false;
|
||||
+
|
||||
+ disable_common:
|
||||
+ opt_rsb_pv = false;
|
||||
+ opt_rsb_hvm = false;
|
||||
+
|
||||
+ opt_thunk = THUNK_JMP;
|
||||
+ opt_ibrs = 0;
|
||||
+ opt_ibpb = false;
|
||||
+ }
|
||||
+ else if ( val > 0 )
|
||||
+ rc = -EINVAL;
|
||||
+ else if ( (val = parse_boolean("xen", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ if ( !val )
|
||||
+ goto disable_common;
|
||||
+
|
||||
+ rc = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Xen's alternative blocks. */
|
||||
+ else if ( (val = parse_boolean("pv", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ opt_msr_sc_pv = val;
|
||||
+ opt_rsb_pv = val;
|
||||
+ }
|
||||
+ else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ opt_msr_sc_hvm = val;
|
||||
+ opt_rsb_hvm = val;
|
||||
+ }
|
||||
+ else if ( (val = parse_boolean("msr-sc", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ opt_msr_sc_pv = val;
|
||||
+ opt_msr_sc_hvm = val;
|
||||
+ }
|
||||
+ else if ( (val = parse_boolean("rsb", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ opt_rsb_pv = val;
|
||||
+ opt_rsb_hvm = val;
|
||||
+ }
|
||||
+
|
||||
+ /* Xen's speculative sidechannel mitigation settings. */
|
||||
+ else if ( !strncmp(s, "bti-thunk=", 10) )
|
||||
+ {
|
||||
+ s += 10;
|
||||
+
|
||||
+ if ( !strncmp(s, "retpoline", ss - s) )
|
||||
+ opt_thunk = THUNK_RETPOLINE;
|
||||
+ else if ( !strncmp(s, "lfence", ss - s) )
|
||||
+ opt_thunk = THUNK_LFENCE;
|
||||
+ else if ( !strncmp(s, "jmp", ss - s) )
|
||||
+ opt_thunk = THUNK_JMP;
|
||||
+ else
|
||||
+ rc = -EINVAL;
|
||||
+ }
|
||||
+ else if ( (val = parse_boolean("ibrs", s, ss)) >= 0 )
|
||||
+ opt_ibrs = val;
|
||||
+ else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
|
||||
+ opt_ibpb = val;
|
||||
+ else
|
||||
+ rc = -EINVAL;
|
||||
+
|
||||
+ s = ss + 1;
|
||||
+ } while ( *ss );
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+custom_param("spec-ctrl", parse_spec_ctrl);
|
||||
+
|
||||
static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
{
|
||||
+ bool use_spec_ctrl = (boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
|
||||
+ boot_cpu_has(X86_FEATURE_SC_MSR_HVM));
|
||||
unsigned int _7d0 = 0, e8b = 0, tmp;
|
||||
|
||||
/* Collect diagnostics about available mitigations. */
|
||||
@@ -94,10 +186,10 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 )
|
||||
cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp);
|
||||
|
||||
- printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
|
||||
+ printk("Speculative mitigation facilities:\n");
|
||||
|
||||
/* Hardware features which pertain to speculative mitigations. */
|
||||
- printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s%s\n",
|
||||
+ printk(" Hardware features:%s%s%s%s%s%s\n",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
|
||||
(_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "",
|
||||
(e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "",
|
||||
@@ -107,20 +199,31 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
|
||||
/* Compiled-in support which pertains to BTI mitigations. */
|
||||
if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
|
||||
- printk(XENLOG_DEBUG " Compiled-in support: INDIRECT_THUNK\n");
|
||||
+ printk(" Compiled-in support: INDIRECT_THUNK\n");
|
||||
|
||||
- printk("BTI mitigations: Thunk %s, Others:%s%s%s%s\n",
|
||||
+ /* Settings for Xen's protection, irrespective of guests. */
|
||||
+ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s, Other:%s\n",
|
||||
thunk == THUNK_NONE ? "N/A" :
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
thunk == THUNK_JMP ? "JMP" : "?",
|
||||
+ !use_spec_ctrl ? "No" :
|
||||
+ (default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-",
|
||||
+ opt_ibpb ? " IBPB" : "");
|
||||
+
|
||||
+ /*
|
||||
+ * Alternatives blocks for protecting against and/or virtualising
|
||||
+ * mitigation support for guests.
|
||||
+ */
|
||||
+ printk(" Support for VMs: PV:%s%s%s, HVM:%s%s%s\n",
|
||||
(boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
|
||||
- boot_cpu_has(X86_FEATURE_SC_MSR_HVM)) ?
|
||||
- default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" :
|
||||
- " IBRS-" : "",
|
||||
- opt_ibpb ? " IBPB" : "",
|
||||
- boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB_NATIVE" : "",
|
||||
- boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB_VMEXIT" : "");
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_PV)) ? "" : " None",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_MSR_PV) ? " MSR_SPEC_CTRL" : "",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB" : "",
|
||||
+ (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM)) ? "" : " None",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "");
|
||||
|
||||
printk("XPTI: %s\n",
|
||||
boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled");
|
||||
@@ -212,7 +315,7 @@ static bool __init retpoline_safe(uint64_t caps)
|
||||
void __init init_speculation_mitigations(void)
|
||||
{
|
||||
enum ind_thunk thunk = THUNK_DEFAULT;
|
||||
- bool ibrs = false;
|
||||
+ bool use_spec_ctrl = false, ibrs = false;
|
||||
uint64_t caps = 0;
|
||||
|
||||
if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
|
||||
@@ -282,20 +385,31 @@ void __init init_speculation_mitigations(void)
|
||||
else if ( thunk == THUNK_JMP )
|
||||
setup_force_cpu_cap(X86_FEATURE_IND_THUNK_JMP);
|
||||
|
||||
+ /*
|
||||
+ * If we are on hardware supporting MSR_SPEC_CTRL, see about setting up
|
||||
+ * the alternatives blocks so we can virtualise support for guests.
|
||||
+ */
|
||||
if ( boot_cpu_has(X86_FEATURE_IBRSB) )
|
||||
{
|
||||
- /*
|
||||
- * Even if we've chosen to not have IBRS set in Xen context, we still
|
||||
- * need the IBRS entry/exit logic to virtualise IBRS support for
|
||||
- * guests.
|
||||
- */
|
||||
- setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV);
|
||||
- setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM);
|
||||
+ if ( opt_msr_sc_pv )
|
||||
+ {
|
||||
+ use_spec_ctrl = true;
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV);
|
||||
+ }
|
||||
|
||||
- if ( ibrs )
|
||||
- default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
|
||||
+ if ( opt_msr_sc_hvm )
|
||||
+ {
|
||||
+ use_spec_ctrl = true;
|
||||
+ setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM);
|
||||
+ }
|
||||
+
|
||||
+ if ( use_spec_ctrl )
|
||||
+ {
|
||||
+ if ( ibrs )
|
||||
+ default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
|
||||
|
||||
- default_spec_ctrl_flags |= SCF_ist_wrmsr;
|
||||
+ default_spec_ctrl_flags |= SCF_ist_wrmsr;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
From 918320daf34931cd5c1c0d9c439ce853f6575970 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Thu, 26 Apr 2018 10:56:28 +0100
|
||||
Subject: [PATCH] x86/AMD: Mitigations for GPZ SP4 - Speculative Store Bypass
|
||||
|
||||
AMD processors will execute loads and stores with the same base register in
|
||||
program order, which is typically how a compiler emits code.
|
||||
|
||||
Therefore, by default no mitigating actions are taken, despite there being
|
||||
corner cases which are vulnerable to the issue.
|
||||
|
||||
For performance testing, or for users with particularly sensitive workloads,
|
||||
the `spec-ctrl=ssbd` command line option is available to force Xen to disable
|
||||
Memory Disambiguation on applicable hardware.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
docs/misc/xen-command-line.markdown | 7 ++++++-
|
||||
xen/arch/x86/cpu/amd.c | 20 ++++++++++++++++++++
|
||||
xen/arch/x86/spec_ctrl.c | 3 +++
|
||||
xen/include/asm-x86/spec_ctrl.h | 1 +
|
||||
4 files changed, 30 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
||||
index 43a6ddb..4e0e580 100644
|
||||
--- a/docs/misc/xen-command-line.markdown
|
||||
+++ b/docs/misc/xen-command-line.markdown
|
||||
@@ -1703,7 +1703,7 @@ false disable the quirk workaround, which is also the default.
|
||||
|
||||
### spec-ctrl (x86)
|
||||
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>,
|
||||
-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb}=<bool> ]`
|
||||
+> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]`
|
||||
|
||||
Controls for speculative execution sidechannel mitigations. By default, Xen
|
||||
will pick the most appropriate mitigations based on compiled in support,
|
||||
@@ -1747,6 +1747,11 @@ On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=`
|
||||
option can be used to force (the default) or prevent Xen from issuing branch
|
||||
prediction barriers on vcpu context switches.
|
||||
|
||||
+On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=`
|
||||
+option can be used to force or prevent Xen using the feature itself. On AMD
|
||||
+hardware, this is a global option applied at boot, and not virtualised for
|
||||
+guest use.
|
||||
+
|
||||
### sync\_console
|
||||
> `= <boolean>`
|
||||
|
||||
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
|
||||
index fc9677f..458a3fe 100644
|
||||
--- a/xen/arch/x86/cpu/amd.c
|
||||
+++ b/xen/arch/x86/cpu/amd.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <asm/amd.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/setup.h> /* amd_init_cpu */
|
||||
+#include <asm/spec_ctrl.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/apic.h>
|
||||
|
||||
@@ -594,6 +595,25 @@ static void init_amd(struct cpuinfo_x86 *c)
|
||||
c->x86_capability);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If the user has explicitly chosen to disable Memory Disambiguation
|
||||
+ * to mitigiate Speculative Store Bypass, poke the appropriate MSR.
|
||||
+ */
|
||||
+ if (opt_ssbd) {
|
||||
+ int bit = -1;
|
||||
+
|
||||
+ switch (c->x86) {
|
||||
+ case 0x15: bit = 54; break;
|
||||
+ case 0x16: bit = 33; break;
|
||||
+ case 0x17: bit = 10; break;
|
||||
+ }
|
||||
+
|
||||
+ if (bit >= 0 && !rdmsr_safe(MSR_AMD64_LS_CFG, value)) {
|
||||
+ value |= 1ull << bit;
|
||||
+ wrmsr_safe(MSR_AMD64_LS_CFG, value);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* MFENCE stops RDTSC speculation */
|
||||
if (!cpu_has_lfence_dispatch)
|
||||
__set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index 4f9282f..e326056 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -43,6 +43,7 @@ static enum ind_thunk {
|
||||
} opt_thunk __initdata = THUNK_DEFAULT;
|
||||
static int8_t __initdata opt_ibrs = -1;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
+bool __read_mostly opt_ssbd = false;
|
||||
|
||||
bool __initdata bsp_delay_spec_ctrl;
|
||||
uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
@@ -164,6 +165,8 @@ static int __init parse_spec_ctrl(const char *s)
|
||||
opt_ibrs = val;
|
||||
else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
|
||||
opt_ibpb = val;
|
||||
+ else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
|
||||
+ opt_ssbd = val;
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index c6a38f4..4678a40 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -27,6 +27,7 @@
|
||||
void init_speculation_mitigations(void);
|
||||
|
||||
extern bool opt_ibpb;
|
||||
+extern bool opt_ssbd;
|
||||
|
||||
extern bool bsp_delay_spec_ctrl;
|
||||
extern uint8_t default_xen_spec_ctrl;
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
From db6adc8e55dd43a1b4bb20e06a69475c503cb934 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Wed, 28 Mar 2018 15:21:39 +0100
|
||||
Subject: [PATCH] x86/Intel: Mitigations for GPZ SP4 - Speculative Store Bypass
|
||||
|
||||
To combat GPZ SP4 "Speculative Store Bypass", Intel have extended their
|
||||
speculative sidechannel mitigations specification as follows:
|
||||
|
||||
* A feature bit to indicate that Speculative Store Bypass Disable is
|
||||
supported.
|
||||
* A new bit in MSR_SPEC_CTRL which, when set, disables memory disambiguation
|
||||
in the pipeline.
|
||||
* A new bit in MSR_ARCH_CAPABILITIES, which will be set in future hardware,
|
||||
indicating that the hardware is not susceptible to Speculative Store Bypass
|
||||
sidechannels.
|
||||
|
||||
For contemporary processors, this interface will be implemented via a
|
||||
microcode update.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
docs/misc/xen-command-line.markdown | 12 +++++++-----
|
||||
tools/libxl/libxl_cpuid.c | 1 +
|
||||
tools/misc/xen-cpuid.c | 3 +--
|
||||
xen/arch/x86/cpuid.c | 5 +++++
|
||||
xen/arch/x86/spec_ctrl.c | 15 ++++++++++++---
|
||||
xen/include/asm-x86/msr-index.h | 2 ++
|
||||
xen/include/public/arch-x86/cpufeatureset.h | 1 +
|
||||
xen/tools/gen-cpuid.py | 17 +++++++++++++----
|
||||
8 files changed, 42 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
||||
index 4e0e580..107889d 100644
|
||||
--- a/docs/misc/xen-command-line.markdown
|
||||
+++ b/docs/misc/xen-command-line.markdown
|
||||
@@ -496,9 +496,10 @@ accounting for hardware capabilities as enumerated via CPUID.
|
||||
|
||||
Currently accepted:
|
||||
|
||||
-The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb` are used by
|
||||
-default if avaiable. 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 `ibrsb`, `stibp`, `ibpb`, `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 (AMD only)
|
||||
> `= fam_0f_rev_c | fam_0f_rev_d | fam_0f_rev_e | fam_0f_rev_f | fam_0f_rev_g | fam_10_rev_b | fam_10_rev_c | fam_11_rev_b`
|
||||
@@ -1728,7 +1729,7 @@ protect itself, and Xen's ability to virtualise support for guests to use.
|
||||
respectively.
|
||||
* `msr-sc=` offers control over Xen's support for manipulating MSR\_SPEC\_CTRL
|
||||
on entry and exit. These blocks are necessary to virtualise support for
|
||||
- guests and if disabled, guests will be unable to use IBRS/STIBP/etc.
|
||||
+ guests and if disabled, guests will be unable to use IBRS/STIBP/SSBD/etc.
|
||||
* `rsb=` offers control over whether to overwrite the Return Stack Buffer /
|
||||
Return Address Stack on entry to Xen.
|
||||
|
||||
@@ -1750,7 +1751,8 @@ prediction barriers on vcpu context switches.
|
||||
On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=`
|
||||
option can be used to force or prevent Xen using the feature itself. On AMD
|
||||
hardware, this is a global option applied at boot, and not virtualised for
|
||||
-guest use.
|
||||
+guest use. On Intel hardware, the feature is virtualised for guests,
|
||||
+independently of Xen's choice of setting.
|
||||
|
||||
### sync\_console
|
||||
> `= <boolean>`
|
||||
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
|
||||
index 3a21f4e..7b0f594 100644
|
||||
--- a/tools/libxl/libxl_cpuid.c
|
||||
+++ b/tools/libxl/libxl_cpuid.c
|
||||
@@ -205,6 +205,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
|
||||
{"ibrsb", 0x00000007, 0, CPUID_REG_EDX, 26, 1},
|
||||
{"stibp", 0x00000007, 0, CPUID_REG_EDX, 27, 1},
|
||||
{"arch-caps", 0x00000007, 0, CPUID_REG_EDX, 29, 1},
|
||||
+ {"ssbd", 0x00000007, 0, CPUID_REG_EDX, 31, 1},
|
||||
|
||||
{"lahfsahf", 0x80000001, NA, CPUID_REG_ECX, 0, 1},
|
||||
{"cmplegacy", 0x80000001, NA, CPUID_REG_ECX, 1, 1},
|
||||
diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
|
||||
index b1a46c6..2483a81 100644
|
||||
--- a/tools/misc/xen-cpuid.c
|
||||
+++ b/tools/misc/xen-cpuid.c
|
||||
@@ -166,8 +166,7 @@ static const char *str_7d0[32] =
|
||||
|
||||
[26] = "ibrsb", [27] = "stibp",
|
||||
[28] = "REZ", [29] = "arch_caps",
|
||||
-
|
||||
- [30 ... 31] = "REZ",
|
||||
+ [30] = "REZ", [31] = "ssbd",
|
||||
};
|
||||
|
||||
static struct {
|
||||
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
|
||||
index b45b145..6a710b7 100644
|
||||
--- a/xen/arch/x86/cpuid.c
|
||||
+++ b/xen/arch/x86/cpuid.c
|
||||
@@ -43,6 +43,11 @@ static int __init parse_xen_cpuid(const char *s)
|
||||
if ( !val )
|
||||
setup_clear_cpu_cap(X86_FEATURE_STIBP);
|
||||
}
|
||||
+ else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
|
||||
+ {
|
||||
+ if ( !val )
|
||||
+ setup_clear_cpu_cap(X86_FEATURE_SSBD);
|
||||
+ }
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index e326056..89e3825 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -192,26 +192,31 @@ 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\n",
|
||||
+ printk(" Hardware features:%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_SSBD)) ? " SSBD" : "",
|
||||
(e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "",
|
||||
(caps & ARCH_CAPABILITIES_IBRS_ALL) ? " IBRS_ALL" : "",
|
||||
(caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : "",
|
||||
- (caps & ARCH_CAPS_RSBA) ? " RSBA" : "");
|
||||
+ (caps & ARCH_CAPS_RSBA) ? " RSBA" : "",
|
||||
+ (caps & ARCH_CAPS_SSB_NO) ? " SSB_NO" : "");
|
||||
|
||||
/* Compiled-in support which pertains to BTI mitigations. */
|
||||
if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) )
|
||||
printk(" Compiled-in support: INDIRECT_THUNK\n");
|
||||
|
||||
/* Settings for Xen's protection, irrespective of guests. */
|
||||
- printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s, Other:%s\n",
|
||||
+ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s\n",
|
||||
thunk == THUNK_NONE ? "N/A" :
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
thunk == THUNK_JMP ? "JMP" : "?",
|
||||
!use_spec_ctrl ? "No" :
|
||||
(default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-",
|
||||
+ !use_spec_ctrl || !boot_cpu_has(X86_FEATURE_SSBD)
|
||||
+ ? "" :
|
||||
+ (default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-",
|
||||
opt_ibpb ? " IBPB" : "");
|
||||
|
||||
/*
|
||||
@@ -415,6 +420,10 @@ void __init init_speculation_mitigations(void)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* If we have SSBD available, see whether we should use it. */
|
||||
+ if ( boot_cpu_has(X86_FEATURE_SSBD) && use_spec_ctrl && opt_ssbd )
|
||||
+ default_xen_spec_ctrl |= SPEC_CTRL_SSBD;
|
||||
+
|
||||
/*
|
||||
* PV guests can poison the RSB to any virtual address from which
|
||||
* they can execute a call instruction. This is necessarily outside
|
||||
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
|
||||
index 68fae91..93d6f4e 100644
|
||||
--- a/xen/include/asm-x86/msr-index.h
|
||||
+++ b/xen/include/asm-x86/msr-index.h
|
||||
@@ -38,6 +38,7 @@
|
||||
#define MSR_SPEC_CTRL 0x00000048
|
||||
#define SPEC_CTRL_IBRS (_AC(1, ULL) << 0)
|
||||
#define SPEC_CTRL_STIBP (_AC(1, ULL) << 1)
|
||||
+#define SPEC_CTRL_SSBD (_AC(1, ULL) << 2)
|
||||
|
||||
#define MSR_PRED_CMD 0x00000049
|
||||
#define PRED_CMD_IBPB (_AC(1, ULL) << 0)
|
||||
@@ -46,6 +47,7 @@
|
||||
#define ARCH_CAPABILITIES_RDCL_NO (_AC(1, ULL) << 0)
|
||||
#define ARCH_CAPABILITIES_IBRS_ALL (_AC(1, ULL) << 1)
|
||||
#define ARCH_CAPS_RSBA (_AC(1, ULL) << 2)
|
||||
+#define ARCH_CAPS_SSB_NO (_AC(1, ULL) << 4)
|
||||
|
||||
/* Intel MSRs. Some also available on other CPUs */
|
||||
#define MSR_IA32_PERFCTR0 0x000000c1
|
||||
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
index 8da5783..7acf822 100644
|
||||
--- a/xen/include/public/arch-x86/cpufeatureset.h
|
||||
+++ b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
@@ -245,6 +245,7 @@ XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single
|
||||
XEN_CPUFEATURE(IBRSB, 9*32+26) /*A IBRS and IBPB support (used by Intel) */
|
||||
XEN_CPUFEATURE(STIBP, 9*32+27) /*A! STIBP */
|
||||
XEN_CPUFEATURE(ARCH_CAPS, 9*32+29) /* IA32_ARCH_CAPABILITIES MSR */
|
||||
+XEN_CPUFEATURE(SSBD, 9*32+31) /* MSR_SPEC_CTRL.SSBD available */
|
||||
|
||||
#endif /* XEN_CPUFEATURE */
|
||||
|
||||
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
|
||||
index 613b909..65526ff 100755
|
||||
--- a/xen/tools/gen-cpuid.py
|
||||
+++ b/xen/tools/gen-cpuid.py
|
||||
@@ -257,10 +257,19 @@ def crunch_numbers(state):
|
||||
AVX512BW, AVX512VL, AVX512VBMI, AVX512_4VNNIW,
|
||||
AVX512_4FMAPS, AVX512_VPOPCNTDQ],
|
||||
|
||||
- # Single Thread Indirect Branch Predictors enumerates a new bit in the
|
||||
- # MSR enumerated by Indirect Branch Restricted Speculation/Indirect
|
||||
- # Branch Prediction Barrier enumeration.
|
||||
- IBRSB: [STIBP],
|
||||
+ # The features:
|
||||
+ # * Single Thread Indirect Branch Predictors
|
||||
+ # * Speculative Store Bypass Disable
|
||||
+ #
|
||||
+ # enumerate new bits in MSR_SPEC_CTRL, which is enumerated by Indirect
|
||||
+ # Branch Restricted Speculation/Indirect Branch Prediction Barrier.
|
||||
+ #
|
||||
+ # In practice, these features also enumerate the presense of
|
||||
+ # MSR_SPEC_CTRL. However, no real hardware will exist with SSBD but
|
||||
+ # not IBRSB, and we pass this MSR directly to guests. Treating them
|
||||
+ # as dependent features simplifies Xen's logic, and prevents the guest
|
||||
+ # from seeing implausible configurations.
|
||||
+ IBRSB: [STIBP, SSBD],
|
||||
}
|
||||
|
||||
deep_features = tuple(sorted(deps.keys()))
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
From 02d0027a89dc49875a41e939498936874a32360f Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Date: Fri, 13 Apr 2018 15:42:34 +0000
|
||||
Subject: [PATCH] x86/msr: Virtualise MSR_SPEC_CTRL.SSBD for guests to use
|
||||
|
||||
Almost all infrastructure is already in place. Update the reserved bits
|
||||
calculation in guest_wrmsr(), and offer SSBD to guests by default.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
xen/arch/x86/msr.c | 8 ++++++--
|
||||
xen/include/public/arch-x86/cpufeatureset.h | 2 +-
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
|
||||
index 48d061d..21219c4 100644
|
||||
--- a/xen/arch/x86/msr.c
|
||||
+++ b/xen/arch/x86/msr.c
|
||||
@@ -178,6 +178,8 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
|
||||
switch ( msr )
|
||||
{
|
||||
+ uint64_t rsvd;
|
||||
+
|
||||
case MSR_INTEL_PLATFORM_INFO:
|
||||
case MSR_ARCH_CAPABILITIES:
|
||||
/* Read-only */
|
||||
@@ -213,8 +215,10 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
* Note: SPEC_CTRL_STIBP is specified as safe to use (i.e. ignored)
|
||||
* when STIBP isn't enumerated in hardware.
|
||||
*/
|
||||
+ rsvd = ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP |
|
||||
+ (cp->feat.ssbd ? SPEC_CTRL_SSBD : 0));
|
||||
|
||||
- if ( val & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP) )
|
||||
+ if ( val & rsvd )
|
||||
goto gp_fault; /* Rsvd bit set? */
|
||||
|
||||
vp->spec_ctrl.raw = val;
|
||||
@@ -233,12 +237,12 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
|
||||
case MSR_INTEL_MISC_FEATURES_ENABLES:
|
||||
{
|
||||
- uint64_t rsvd = ~0ull;
|
||||
bool old_cpuid_faulting = vp->misc_features_enables.cpuid_faulting;
|
||||
|
||||
if ( !vp->misc_features_enables.available )
|
||||
goto gp_fault;
|
||||
|
||||
+ rsvd = ~0ull;
|
||||
if ( dp->plaform_info.cpuid_faulting )
|
||||
rsvd &= ~MSR_MISC_FEATURES_CPUID_FAULTING;
|
||||
|
||||
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
index 7acf822..c721c12 100644
|
||||
--- a/xen/include/public/arch-x86/cpufeatureset.h
|
||||
+++ b/xen/include/public/arch-x86/cpufeatureset.h
|
||||
@@ -245,7 +245,7 @@ XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single
|
||||
XEN_CPUFEATURE(IBRSB, 9*32+26) /*A IBRS and IBPB support (used by Intel) */
|
||||
XEN_CPUFEATURE(STIBP, 9*32+27) /*A! STIBP */
|
||||
XEN_CPUFEATURE(ARCH_CAPS, 9*32+29) /* IA32_ARCH_CAPABILITIES MSR */
|
||||
-XEN_CPUFEATURE(SSBD, 9*32+31) /* MSR_SPEC_CTRL.SSBD available */
|
||||
+XEN_CPUFEATURE(SSBD, 9*32+31) /*A MSR_SPEC_CTRL.SSBD available */
|
||||
|
||||
#endif /* XEN_CPUFEATURE */
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/mm: don't bypass preemption checks
|
||||
|
||||
While unlikely, it is not impossible for a multi-vCPU guest to leverage
|
||||
bypasses of preemption checks to drive Xen into an unbounded loop.
|
||||
|
||||
This is XSA-264.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -2526,7 +2526,7 @@ static int _put_page_type(struct page_in
|
||||
nx = x & ~(PGT_validated|PGT_partial);
|
||||
if ( unlikely((y = cmpxchg(&page->u.inuse.type_info,
|
||||
x, nx)) != x) )
|
||||
- continue;
|
||||
+ goto maybe_preempt;
|
||||
/* We cleared the 'valid bit' so we do the clean up. */
|
||||
rc = _put_final_page_type(page, x, preemptible, ptpg);
|
||||
ptpg = NULL;
|
||||
@@ -2558,12 +2558,13 @@ static int _put_page_type(struct page_in
|
||||
*/
|
||||
cpu_relax();
|
||||
y = page->u.inuse.type_info;
|
||||
- continue;
|
||||
+ goto maybe_preempt;
|
||||
}
|
||||
|
||||
if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
|
||||
break;
|
||||
|
||||
+ maybe_preempt:
|
||||
if ( preemptible && hypercall_preempt_check() )
|
||||
return -EINTR;
|
||||
}
|
||||
@@ -2676,12 +2677,11 @@ static int __get_page_type(struct page_i
|
||||
if ( !(x & PGT_partial) )
|
||||
{
|
||||
/* Someone else is updating validation of this page. Wait... */
|
||||
- while ( (y = page->u.inuse.type_info) == x )
|
||||
- {
|
||||
+ do {
|
||||
if ( preemptible && hypercall_preempt_check() )
|
||||
return -EINTR;
|
||||
cpu_relax();
|
||||
- }
|
||||
+ } while ( (y = page->u.inuse.type_info) == x );
|
||||
continue;
|
||||
}
|
||||
/* Type ref count was left at 1 when PGT_partial got set. */
|
||||
104
xsa265.patch
104
xsa265.patch
|
|
@ -1,104 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86: Refine checks in #DB handler for faulting conditions
|
||||
|
||||
One of the fix for XSA-260 (c/s 75d6828bc2 "x86/traps: Fix handling of #DB
|
||||
exceptions in hypervisor context") added some safety checks to help avoid
|
||||
livelocks of #DB faults.
|
||||
|
||||
While a General Detect #DB exception does have fault semantics, hardware
|
||||
clears %dr7.gd on entry to the handler, meaning that it is actually safe to
|
||||
return to. Furthermore, %dr6.gd is guest controlled and sticky (never cleared
|
||||
by hardware). A malicious PV guest can therefore trigger the fatal_trap() and
|
||||
crash Xen.
|
||||
|
||||
Instruction breakpoints are more tricky. The breakpoint match bits in %dr6
|
||||
are not sticky, but the Intel manual warns that they may be set for
|
||||
non-enabled breakpoints, so add a breakpoint enabled check.
|
||||
|
||||
Beyond that, because of the restriction on the linear addresses PV guests can
|
||||
set, and the fault (rather than trap) nature of instruction breakpoints
|
||||
(i.e. can't be deferred by a MovSS shadow), there should be no way to
|
||||
encounter an instruction breakpoint in Xen context. However, for extra
|
||||
robustness, deal with this situation by clearing the breakpoint configuration,
|
||||
rather than crashing.
|
||||
|
||||
This is XSA-265
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
|
||||
index e79ca88..3e05cf1 100644
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -1809,6 +1809,13 @@ void do_debug(struct cpu_user_regs *regs)
|
||||
|
||||
if ( !guest_mode(regs) )
|
||||
{
|
||||
+ /*
|
||||
+ * !!! WARNING !!!
|
||||
+ *
|
||||
+ * %dr6 is mostly guest controlled at this point. Any decsions base
|
||||
+ * on its value must be crosschecked with non-guest controlled state.
|
||||
+ */
|
||||
+
|
||||
if ( regs->eflags & X86_EFLAGS_TF )
|
||||
{
|
||||
/* In SYSENTER entry path we can't zap TF until EFLAGS is saved. */
|
||||
@@ -1830,33 +1837,44 @@ void do_debug(struct cpu_user_regs *regs)
|
||||
* Check for fault conditions. General Detect, and instruction
|
||||
* breakpoints are faults rather than traps, at which point attempting
|
||||
* to ignore and continue will result in a livelock.
|
||||
+ *
|
||||
+ * However, on entering the #DB handler, hardware clears %dr7.gd for
|
||||
+ * us (as confirmed by the earlier %dr6 accesses succeeding), meaning
|
||||
+ * that a real General Detect exception is restartable.
|
||||
+ *
|
||||
+ * PV guests are not permitted to point %dr{0..3} at Xen linear
|
||||
+ * addresses, and Instruction Breakpoints (being faults) don't get
|
||||
+ * delayed by a MovSS shadow, so we should never encounter one in
|
||||
+ * hypervisor context.
|
||||
+ *
|
||||
+ * If however we do, safety measures need to be enacted. Use a big
|
||||
+ * hammer and clear all debug settings.
|
||||
*/
|
||||
- if ( dr6 & DR_GENERAL_DETECT )
|
||||
- {
|
||||
- printk(XENLOG_ERR "Hit General Detect in Xen context\n");
|
||||
- fatal_trap(regs, 0);
|
||||
- }
|
||||
-
|
||||
if ( dr6 & (DR_TRAP3 | DR_TRAP2 | DR_TRAP1 | DR_TRAP0) )
|
||||
{
|
||||
- unsigned int bp, dr7 = read_debugreg(7) >> DR_CONTROL_SHIFT;
|
||||
+ unsigned int bp, dr7 = read_debugreg(7);
|
||||
|
||||
for ( bp = 0; bp < 4; ++bp )
|
||||
{
|
||||
if ( (dr6 & (1u << bp)) && /* Breakpoint triggered? */
|
||||
- ((dr7 & (3u << (bp * DR_CONTROL_SIZE))) == 0) /* Insn? */ )
|
||||
+ (dr7 & (3u << (bp * DR_ENABLE_SIZE))) && /* Enabled? */
|
||||
+ ((dr7 & (3u << ((bp * DR_CONTROL_SIZE) + /* Insn? */
|
||||
+ DR_CONTROL_SHIFT))) == DR_RW_EXECUTE) )
|
||||
{
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+
|
||||
printk(XENLOG_ERR
|
||||
"Hit instruction breakpoint in Xen context\n");
|
||||
- fatal_trap(regs, 0);
|
||||
+ write_debugreg(7, 0);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- * Whatever caused this #DB should be a trap. Note it and continue.
|
||||
- * Guests can trigger this in certain corner cases, so ensure the
|
||||
- * message is ratelimited.
|
||||
+ * Whatever caused this #DB should be restartable by this point. Note
|
||||
+ * it and continue. Guests can trigger this in certain corner cases,
|
||||
+ * so ensure the message is ratelimited.
|
||||
*/
|
||||
gprintk(XENLOG_WARNING,
|
||||
"Hit #DB in Xen context: %04x:%p [%ps], stk %04x:%p, dr6 %lx\n",
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
From 82f98f8484f47163a06e4d5610dba6e5fc459e78 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Wed, 13 Jun 2018 15:51:36 +0100
|
||||
Subject: [PATCH 1/2] libxl: qemu_disk_scsi_drive_string: Break out common
|
||||
parts of disk config
|
||||
|
||||
The generated configurations are identical apart from, in some cases,
|
||||
reordering of the id=%s element. So, overall, no functional change.
|
||||
|
||||
This is part of XSA-266.
|
||||
|
||||
Reported-by: Andrew Reimers <andrew.reimers@orionvm.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxl/libxl_dm.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
|
||||
index b51178b..28bbeb6 100644
|
||||
--- a/tools/libxl/libxl_dm.c
|
||||
+++ b/tools/libxl/libxl_dm.c
|
||||
@@ -798,6 +798,7 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
int colo_mode)
|
||||
{
|
||||
char *drive = NULL;
|
||||
+ char *common = GCSPRINTF("cache=writeback");
|
||||
const char *exportname = disk->colo_export;
|
||||
const char *active_disk = disk->active_disk;
|
||||
const char *hidden_disk = disk->hidden_disk;
|
||||
@@ -805,8 +806,8 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
switch (colo_mode) {
|
||||
case LIBXL__COLO_NONE:
|
||||
drive = libxl__sprintf
|
||||
- (gc, "file=%s,if=scsi,bus=0,unit=%d,format=%s,cache=writeback",
|
||||
- target_path, unit, format);
|
||||
+ (gc, "%s,file=%s,if=scsi,bus=0,unit=%d,format=%s",
|
||||
+ common, target_path, unit, format);
|
||||
break;
|
||||
case LIBXL__COLO_PRIMARY:
|
||||
/*
|
||||
@@ -819,13 +820,13 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
* vote-threshold=1
|
||||
*/
|
||||
drive = GCSPRINTF(
|
||||
- "if=scsi,bus=0,unit=%d,cache=writeback,driver=quorum,"
|
||||
+ "%s,if=scsi,bus=0,unit=%d,,driver=quorum,"
|
||||
"id=%s,"
|
||||
"children.0.file.filename=%s,"
|
||||
"children.0.driver=%s,"
|
||||
"read-pattern=fifo,"
|
||||
"vote-threshold=1",
|
||||
- unit, exportname, target_path, format);
|
||||
+ common, unit, exportname, target_path, format);
|
||||
break;
|
||||
case LIBXL__COLO_SECONDARY:
|
||||
/*
|
||||
@@ -839,7 +840,7 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
* file.backing.backing=exportname,
|
||||
*/
|
||||
drive = GCSPRINTF(
|
||||
- "if=scsi,id=top-colo,bus=0,unit=%d,cache=writeback,"
|
||||
+ "%s,if=scsi,id=top-colo,bus=0,unit=%d,"
|
||||
"driver=replication,"
|
||||
"mode=secondary,"
|
||||
"top-id=top-colo,"
|
||||
@@ -848,7 +849,7 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
"file.backing.driver=qcow2,"
|
||||
"file.backing.file.filename=%s,"
|
||||
"file.backing.backing=%s",
|
||||
- unit, active_disk, hidden_disk, exportname);
|
||||
+ common, unit, active_disk, hidden_disk, exportname);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
From ba3f1fa1ab6e83745682cac784e680a1abf7da7d Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Wed, 13 Jun 2018 15:54:53 +0100
|
||||
Subject: [PATCH 2/2] libxl: restore passing "readonly=" to qemu for SCSI disks
|
||||
|
||||
A read-only check was introduced for XSA-142, commit ef6cb76026 ("libxl:
|
||||
relax readonly check introduced by XSA-142 fix") added the passing of
|
||||
the extra setting, but commit dab0539568 ("Introduce COLO mode and
|
||||
refactor relevant function") dropped the passing of the setting again,
|
||||
quite likely due to improper re-basing.
|
||||
|
||||
Restore the readonly= parameter to SCSI disks. For IDE disks this is
|
||||
supposed to be rejected; add an assert. And there is a bare ad-hoc
|
||||
disk drive string in libxl__build_device_model_args_new, which we also
|
||||
update.
|
||||
|
||||
This is XSA-266.
|
||||
|
||||
Reported-by: Andrew Reimers <andrew.reimers@orionvm.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxl/libxl_dm.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
|
||||
index 28bbeb6..3dc317a 100644
|
||||
--- a/tools/libxl/libxl_dm.c
|
||||
+++ b/tools/libxl/libxl_dm.c
|
||||
@@ -798,7 +798,8 @@ static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
|
||||
int colo_mode)
|
||||
{
|
||||
char *drive = NULL;
|
||||
- char *common = GCSPRINTF("cache=writeback");
|
||||
+ char *common = GCSPRINTF("cache=writeback,readonly=%s",
|
||||
+ disk->readwrite ? "off" : "on");
|
||||
const char *exportname = disk->colo_export;
|
||||
const char *active_disk = disk->active_disk;
|
||||
const char *hidden_disk = disk->hidden_disk;
|
||||
@@ -867,6 +868,8 @@ static char *qemu_disk_ide_drive_string(libxl__gc *gc, const char *target_path,
|
||||
const char *exportname = disk->colo_export;
|
||||
const char *active_disk = disk->active_disk;
|
||||
const char *hidden_disk = disk->hidden_disk;
|
||||
+
|
||||
+ assert(disk->readwrite); /* should have been checked earlier */
|
||||
|
||||
switch (colo_mode) {
|
||||
case LIBXL__COLO_NONE:
|
||||
@@ -1576,8 +1579,9 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
|
||||
if (strncmp(disks[i].vdev, "sd", 2) == 0) {
|
||||
if (colo_mode == LIBXL__COLO_SECONDARY) {
|
||||
drive = libxl__sprintf
|
||||
- (gc, "if=none,driver=%s,file=%s,id=%s",
|
||||
- format, target_path, disks[i].colo_export);
|
||||
+ (gc, "if=none,driver=%s,file=%s,id=%s,readonly=%s",
|
||||
+ format, target_path, disks[i].colo_export,
|
||||
+ disks[i].readwrite ? "off" : "on");
|
||||
|
||||
flexarray_append(dm_args, "-drive");
|
||||
flexarray_append(dm_args, drive);
|
||||
--
|
||||
2.1.4
|
||||
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86: Support fully eager FPU context switching
|
||||
|
||||
This is controlled on a per-vcpu bases for flexibility.
|
||||
|
||||
This is part of XSA-267 / CVE-2018-3665
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
|
||||
index 8845252..50116d5 100644
|
||||
--- a/xen/arch/x86/i387.c
|
||||
+++ b/xen/arch/x86/i387.c
|
||||
@@ -210,7 +210,7 @@ void vcpu_restore_fpu_eager(struct vcpu *v)
|
||||
ASSERT(!is_idle_vcpu(v));
|
||||
|
||||
/* Restore nonlazy extended state (i.e. parts not tracked by CR0.TS). */
|
||||
- if ( !v->arch.nonlazy_xstate_used )
|
||||
+ if ( !v->arch.fully_eager_fpu && !v->arch.nonlazy_xstate_used )
|
||||
return;
|
||||
|
||||
/* Avoid recursion */
|
||||
@@ -221,11 +221,19 @@ void vcpu_restore_fpu_eager(struct vcpu *v)
|
||||
* above) we also need to restore full state, to prevent subsequently
|
||||
* saving state belonging to another vCPU.
|
||||
*/
|
||||
- if ( xstate_all(v) )
|
||||
+ if ( v->arch.fully_eager_fpu || (v->arch.xsave_area && xstate_all(v)) )
|
||||
{
|
||||
- fpu_xrstor(v, XSTATE_ALL);
|
||||
+ if ( cpu_has_xsave )
|
||||
+ fpu_xrstor(v, XSTATE_ALL);
|
||||
+ else
|
||||
+ fpu_fxrstor(v);
|
||||
+
|
||||
v->fpu_initialised = 1;
|
||||
v->fpu_dirtied = 1;
|
||||
+
|
||||
+ /* Xen doesn't need TS set, but the guest might. */
|
||||
+ if ( is_pv_vcpu(v) && (v->arch.pv_vcpu.ctrlreg[0] & X86_CR0_TS) )
|
||||
+ stts();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -247,6 +255,8 @@ void vcpu_restore_fpu_lazy(struct vcpu *v)
|
||||
if ( v->fpu_dirtied )
|
||||
return;
|
||||
|
||||
+ ASSERT(!v->arch.fully_eager_fpu);
|
||||
+
|
||||
if ( cpu_has_xsave )
|
||||
fpu_xrstor(v, XSTATE_LAZY);
|
||||
else
|
||||
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
|
||||
index 2ba21e1..7759332 100644
|
||||
--- a/xen/include/asm-x86/domain.h
|
||||
+++ b/xen/include/asm-x86/domain.h
|
||||
@@ -569,6 +569,9 @@ struct arch_vcpu
|
||||
* and thus should be saved/restored. */
|
||||
bool_t nonlazy_xstate_used;
|
||||
|
||||
+ /* Restore all FPU state (lazy and non-lazy state) on context switch? */
|
||||
+ bool fully_eager_fpu;
|
||||
+
|
||||
/*
|
||||
* The SMAP check policy when updating runstate_guest(v) and the
|
||||
* secondary system time.
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/spec-ctrl: Mitigations for LazyFPU
|
||||
|
||||
Intel Core processors since at least Nehalem speculate past #NM, which is the
|
||||
mechanism by which lazy FPU context switching is implemented.
|
||||
|
||||
On affected processors, Xen must use fully eager FPU context switching to
|
||||
prevent guests from being able to read FPU state (SSE/AVX/etc) from previously
|
||||
scheduled vcpus.
|
||||
|
||||
This is part of XSA-267 / CVE-2018-3665
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
||||
index 5c13f6f..cb81a9c 100644
|
||||
--- a/docs/misc/xen-command-line.markdown
|
||||
+++ b/docs/misc/xen-command-line.markdown
|
||||
@@ -1727,7 +1727,7 @@ false disable the quirk workaround, which is also the default.
|
||||
|
||||
### spec-ctrl (x86)
|
||||
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>,
|
||||
-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]`
|
||||
+> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu}=<bool> ]`
|
||||
|
||||
Controls for speculative execution sidechannel mitigations. By default, Xen
|
||||
will pick the most appropriate mitigations based on compiled in support,
|
||||
@@ -1777,6 +1777,11 @@ hardware, this is a global option applied at boot, and not virtualised for
|
||||
guest use. On Intel hardware, the feature is virtualised for guests,
|
||||
independently of Xen's choice of setting.
|
||||
|
||||
+On all hardware, the `eager-fpu=` option can be used to force or prevent Xen
|
||||
+from using fully eager FPU context switches. This is currently implemented as
|
||||
+a global control. By default, Xen will choose to use fully eager context
|
||||
+switches on hardware believed to speculate past #NM exceptions.
|
||||
+
|
||||
### sync\_console
|
||||
> `= <boolean>`
|
||||
|
||||
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
|
||||
index 50116d5..dbdf1b4 100644
|
||||
--- a/xen/arch/x86/i387.c
|
||||
+++ b/xen/arch/x86/i387.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <asm/i387.h>
|
||||
#include <asm/xstate.h>
|
||||
#include <asm/asm_defns.h>
|
||||
+#include <asm/spec_ctrl.h>
|
||||
|
||||
/*******************************/
|
||||
/* FPU Restore Functions */
|
||||
@@ -307,6 +308,8 @@ int vcpu_init_fpu(struct vcpu *v)
|
||||
{
|
||||
int rc;
|
||||
|
||||
+ v->arch.fully_eager_fpu = opt_eager_fpu;
|
||||
+
|
||||
if ( (rc = xstate_alloc_save_area(v)) != 0 )
|
||||
return rc;
|
||||
|
||||
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
||||
index b5a7f9c..cf255ac 100644
|
||||
--- a/xen/arch/x86/spec_ctrl.c
|
||||
+++ b/xen/arch/x86/spec_ctrl.c
|
||||
@@ -44,6 +44,7 @@ static enum ind_thunk {
|
||||
static int8_t __initdata opt_ibrs = -1;
|
||||
bool __read_mostly opt_ibpb = true;
|
||||
bool __read_mostly opt_ssbd = false;
|
||||
+int8_t __read_mostly opt_eager_fpu = -1;
|
||||
|
||||
bool __initdata bsp_delay_spec_ctrl;
|
||||
uint8_t __read_mostly default_xen_spec_ctrl;
|
||||
@@ -114,6 +115,7 @@ static int __init parse_spec_ctrl(const char *s)
|
||||
opt_thunk = THUNK_JMP;
|
||||
opt_ibrs = 0;
|
||||
opt_ibpb = false;
|
||||
+ opt_eager_fpu = 0;
|
||||
}
|
||||
else if ( val > 0 )
|
||||
rc = -EINVAL;
|
||||
@@ -167,6 +169,8 @@ static int __init parse_spec_ctrl(const char *s)
|
||||
opt_ibpb = val;
|
||||
else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
|
||||
opt_ssbd = val;
|
||||
+ else if ( (val = parse_boolean("eager-fpu", s, ss)) >= 0 )
|
||||
+ opt_eager_fpu = val;
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
@@ -223,15 +227,19 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
||||
* Alternatives blocks for protecting against and/or virtualising
|
||||
* mitigation support for guests.
|
||||
*/
|
||||
- printk(" Support for VMs: PV:%s%s%s, HVM:%s%s%s\n",
|
||||
+ printk(" Support for VMs: PV:%s%s%s%s, HVM:%s%s%s%s\n",
|
||||
(boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
|
||||
- boot_cpu_has(X86_FEATURE_SC_RSB_PV)) ? "" : " None",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ||
|
||||
+ opt_eager_fpu) ? "" : " None",
|
||||
boot_cpu_has(X86_FEATURE_SC_MSR_PV) ? " MSR_SPEC_CTRL" : "",
|
||||
boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB" : "",
|
||||
+ opt_eager_fpu ? " EAGER_FPU" : "",
|
||||
(boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
|
||||
- boot_cpu_has(X86_FEATURE_SC_RSB_HVM)) ? "" : " None",
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ||
|
||||
+ opt_eager_fpu) ? "" : " None",
|
||||
boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "",
|
||||
- boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "");
|
||||
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "",
|
||||
+ opt_eager_fpu ? " EAGER_FPU" : "");
|
||||
|
||||
printk("XPTI: %s\n",
|
||||
boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled");
|
||||
@@ -321,6 +329,82 @@ static bool __init retpoline_safe(uint64_t caps)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Calculate whether this CPU speculates past #NM */
|
||||
+static bool __init should_use_eager_fpu(void)
|
||||
+{
|
||||
+ /*
|
||||
+ * Assume all unrecognised processors are ok. This is only known to
|
||||
+ * affect Intel Family 6 processors.
|
||||
+ */
|
||||
+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
|
||||
+ boot_cpu_data.x86 != 6 )
|
||||
+ return false;
|
||||
+
|
||||
+ switch ( boot_cpu_data.x86_model )
|
||||
+ {
|
||||
+ /*
|
||||
+ * Core processors since at least Nehalem are vulnerable.
|
||||
+ */
|
||||
+ case 0x1e: /* Nehalem */
|
||||
+ case 0x1f: /* Auburndale / Havendale */
|
||||
+ case 0x1a: /* Nehalem EP */
|
||||
+ case 0x2e: /* Nehalem EX */
|
||||
+ case 0x25: /* Westmere */
|
||||
+ case 0x2c: /* Westmere EP */
|
||||
+ case 0x2f: /* Westmere EX */
|
||||
+ case 0x2a: /* SandyBridge */
|
||||
+ case 0x2d: /* SandyBridge EP/EX */
|
||||
+ case 0x3a: /* IvyBridge */
|
||||
+ case 0x3e: /* IvyBridge EP/EX */
|
||||
+ case 0x3c: /* Haswell */
|
||||
+ case 0x3f: /* Haswell EX/EP */
|
||||
+ case 0x45: /* Haswell D */
|
||||
+ case 0x46: /* Haswell H */
|
||||
+ case 0x3d: /* Broadwell */
|
||||
+ case 0x47: /* Broadwell H */
|
||||
+ case 0x4f: /* Broadwell EP/EX */
|
||||
+ case 0x56: /* Broadwell D */
|
||||
+ case 0x4e: /* Skylake M */
|
||||
+ case 0x55: /* Skylake X */
|
||||
+ case 0x5e: /* Skylake D */
|
||||
+ case 0x66: /* Cannonlake */
|
||||
+ case 0x67: /* Cannonlake? */
|
||||
+ case 0x8e: /* Kabylake M */
|
||||
+ case 0x9e: /* Kabylake D */
|
||||
+ return true;
|
||||
+
|
||||
+ /*
|
||||
+ * Atom processors are not vulnerable.
|
||||
+ */
|
||||
+ case 0x1c: /* Pineview */
|
||||
+ case 0x26: /* Lincroft */
|
||||
+ case 0x27: /* Penwell */
|
||||
+ case 0x35: /* Cloverview */
|
||||
+ case 0x36: /* Cedarview */
|
||||
+ case 0x37: /* Baytrail / Valleyview (Silvermont) */
|
||||
+ case 0x4d: /* Avaton / Rangely (Silvermont) */
|
||||
+ case 0x4c: /* Cherrytrail / Brasswell */
|
||||
+ case 0x4a: /* Merrifield */
|
||||
+ case 0x5a: /* Moorefield */
|
||||
+ case 0x5c: /* Goldmont */
|
||||
+ case 0x5f: /* Denverton */
|
||||
+ case 0x7a: /* Gemini Lake */
|
||||
+ return false;
|
||||
+
|
||||
+ /*
|
||||
+ * Knights processors are not vulnerable.
|
||||
+ */
|
||||
+ case 0x57: /* Knights Landing */
|
||||
+ case 0x85: /* Knights Mill */
|
||||
+ return false;
|
||||
+
|
||||
+ default:
|
||||
+ printk("Unrecognised CPU model %#x - assuming vulnerable to LazyFPU\n",
|
||||
+ boot_cpu_data.x86_model);
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void __init init_speculation_mitigations(void)
|
||||
{
|
||||
enum ind_thunk thunk = THUNK_DEFAULT;
|
||||
@@ -519,6 +603,10 @@ void __init init_speculation_mitigations(void)
|
||||
if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) )
|
||||
opt_ibpb = false;
|
||||
|
||||
+ /* Check whether Eager FPU should be enabled by default. */
|
||||
+ if ( opt_eager_fpu == -1 )
|
||||
+ opt_eager_fpu = should_use_eager_fpu();
|
||||
+
|
||||
/* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */
|
||||
init_shadow_spec_ctrl_state();
|
||||
|
||||
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
||||
index 91bed1b..5b40afb 100644
|
||||
--- a/xen/include/asm-x86/spec_ctrl.h
|
||||
+++ b/xen/include/asm-x86/spec_ctrl.h
|
||||
@@ -28,6 +28,7 @@ void init_speculation_mitigations(void);
|
||||
|
||||
extern bool opt_ibpb;
|
||||
extern bool opt_ssbd;
|
||||
+extern int8_t opt_eager_fpu;
|
||||
|
||||
extern bool bsp_delay_spec_ctrl;
|
||||
extern uint8_t default_xen_spec_ctrl;
|
||||
30
xsa483.patch
Normal file
30
xsa483.patch
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
From: Andrii Sultanov <andriy.sultanov@vates.tech>
|
||||
Subject: tools/oxenstored: Reset quota when resetting permissions
|
||||
|
||||
The quota object contains both limits and the current node usage counts.
|
||||
|
||||
When a domain is torn down, the node data itself is cleaned up but the node
|
||||
usage counts are not. A later domain reusing the same domid can create fewer
|
||||
nodes before being deemed to be over quota.
|
||||
|
||||
Reset the count when the node permissions are cleaned up.
|
||||
|
||||
This is XSA-483 / CVE-2026-23556.
|
||||
|
||||
Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
|
||||
index 9b8dd2812df0..aa9204ead3ec 100644
|
||||
--- a/tools/ocaml/xenstored/store.ml
|
||||
+++ b/tools/ocaml/xenstored/store.ml
|
||||
@@ -465,7 +465,8 @@ let reset_permissions store domid =
|
||||
if perms <> node.perms then
|
||||
Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
|
||||
Some { node with Node.perms }
|
||||
- ) store.root
|
||||
+ ) store.root;
|
||||
+ store.quota <- Quota.del store.quota domid
|
||||
|
||||
type ops = {
|
||||
store: t;
|
||||
89
xsa484.patch
Normal file
89
xsa484.patch
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
From 3d0d19ad17f29c64dde4a7baf392da4fd58f3654 Mon Sep 17 00:00:00 2001
|
||||
From: Juergen Gross <jgross@suse.com>
|
||||
Date: Mon, 16 Mar 2026 15:06:11 +0100
|
||||
Subject: [PATCH] tools/xenstored: make conn_delete_all_transactions()
|
||||
idempotent
|
||||
|
||||
conn_delete_all_transactions() should be callable in any context,
|
||||
resetting ALL transaction related data.
|
||||
|
||||
This includes number of active transactions and the transaction
|
||||
pointer in struct connection.
|
||||
|
||||
So reset conn->trans to NULL in conn_delete_all_transactions() and
|
||||
do the cleanup for each transaction in destroy_transaction().
|
||||
|
||||
This avoids triggering the assert() in conn_delete_all_transactions()
|
||||
in case e.g. ignore_connection() was called while an operation inside
|
||||
a transaction was performed, or XS_RESET_WATCHES was called in a
|
||||
transaction.
|
||||
|
||||
This is XSA-484 / CVE-2026-23557.
|
||||
|
||||
Reported-by: Andrii Sultanov <andriy.sultanov@vates.tech>
|
||||
Fixes: 1f9d04fb021c ("xenstored: allow guest to shutdown all its watches/transactions")
|
||||
Signed-off-by: Juergen Gross <jgross@suse.com>
|
||||
---
|
||||
tools/xenstored/transaction.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/tools/xenstored/transaction.c b/tools/xenstored/transaction.c
|
||||
index 167cd597fd..0825c48859 100644
|
||||
--- a/tools/xenstored/transaction.c
|
||||
+++ b/tools/xenstored/transaction.c
|
||||
@@ -432,17 +432,23 @@ static int finalize_transaction(struct connection *conn,
|
||||
static int destroy_transaction(void *_transaction)
|
||||
{
|
||||
struct transaction *trans = _transaction;
|
||||
+ struct connection *conn = trans->conn;
|
||||
struct accessed_node *i;
|
||||
|
||||
wrl_ntransactions--;
|
||||
trace_destroy(trans, "transaction");
|
||||
while ((i = list_top(&trans->accessed, struct accessed_node, list))) {
|
||||
if (i->ta_node)
|
||||
- db_delete(trans->conn, i->trans_name, NULL);
|
||||
+ db_delete(conn, i->trans_name, NULL);
|
||||
list_del(&i->list);
|
||||
talloc_free(i);
|
||||
}
|
||||
|
||||
+ list_del(&trans->list);
|
||||
+ domain_transaction_dec(conn);
|
||||
+ if (list_empty(&conn->transaction_list))
|
||||
+ conn->ta_start_time = 0;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,10 +529,6 @@ int do_transaction_end(const void *ctx, struct connection *conn,
|
||||
return ENOENT;
|
||||
|
||||
conn->transaction = NULL;
|
||||
- list_del(&trans->list);
|
||||
- domain_transaction_dec(conn);
|
||||
- if (list_empty(&conn->transaction_list))
|
||||
- conn->ta_start_time = 0;
|
||||
|
||||
chk_quota = trans->node_created && domain_is_unprivileged(conn);
|
||||
|
||||
@@ -572,14 +574,10 @@ void conn_delete_all_transactions(struct connection *conn)
|
||||
struct transaction *trans;
|
||||
|
||||
while ((trans = list_top(&conn->transaction_list,
|
||||
- struct transaction, list))) {
|
||||
- list_del(&trans->list);
|
||||
+ struct transaction, list)))
|
||||
talloc_free(trans);
|
||||
- }
|
||||
-
|
||||
- assert(conn->transaction == NULL);
|
||||
|
||||
- conn->ta_start_time = 0;
|
||||
+ conn->transaction = NULL;
|
||||
}
|
||||
|
||||
int check_transactions(struct hashtable *hash)
|
||||
--
|
||||
2.53.0
|
||||
|
||||
181
xsa486.patch
Normal file
181
xsa486.patch
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: gnttab: split gnttab_map_frame()
|
||||
|
||||
If a domain tries to map status frames in parallel to switching grant
|
||||
table version from 2 to 1, the mapping operation may put in place P2M
|
||||
entries referencing MFNs which gnttab_unpopulate_status_frames() is in the
|
||||
process of freeing.
|
||||
|
||||
Ideally we would refcount pages when entered into P2M tables, but that's a
|
||||
significant change. Extend the grant-table-locked region instead in
|
||||
xenmem_add_to_physmap_one() (being the sole caller of gnttab_map_frame()),
|
||||
such that a race with gnttab_unpopulate_status_frames() is no longer
|
||||
possible.
|
||||
|
||||
This is XSA-486 / CVE-2026-23558.
|
||||
|
||||
Fixes: 5ce8fafa947c ("Dynamic grant-table sizing")
|
||||
Fixes: a98dc13703e0 ("Introduce a grant_entry_v2 structure")
|
||||
Reported-by: Rafal Wojtczuk <rafal.wojtczuk@7bulls.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/arm/mm.c
|
||||
+++ b/xen/arch/arm/mm.c
|
||||
@@ -174,12 +174,10 @@ int xenmem_add_to_physmap_one(
|
||||
switch ( space )
|
||||
{
|
||||
case XENMAPSPACE_grant_table:
|
||||
- rc = gnttab_map_frame(d, idx, gfn, &mfn);
|
||||
+ rc = gnttab_map_frame_begin(d, idx, gfn, &mfn);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
- /* Need to take care of the reference obtained in gnttab_map_frame(). */
|
||||
- page = mfn_to_page(mfn);
|
||||
t = p2m_ram_rw;
|
||||
|
||||
break;
|
||||
@@ -281,10 +279,23 @@ int xenmem_add_to_physmap_one(
|
||||
* to drop the reference we took earlier. In all other cases we need to
|
||||
* drop any reference we took earlier (perhaps indirectly).
|
||||
*/
|
||||
- if ( space == XENMAPSPACE_gmfn_foreign ? rc : page != NULL )
|
||||
+ switch ( space )
|
||||
{
|
||||
+ default:
|
||||
+ if ( page )
|
||||
+ put_page(page);
|
||||
+ break;
|
||||
+
|
||||
+ case XENMAPSPACE_grant_table:
|
||||
+ gnttab_map_frame_end(d, mfn);
|
||||
+ break;
|
||||
+
|
||||
+ case XENMAPSPACE_gmfn_foreign:
|
||||
+ if ( !rc )
|
||||
+ break;
|
||||
ASSERT(page != NULL);
|
||||
put_page(page);
|
||||
+ break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
--- a/xen/arch/x86/mm/p2m.c
|
||||
+++ b/xen/arch/x86/mm/p2m.c
|
||||
@@ -2009,11 +2009,9 @@ int xenmem_add_to_physmap_one(
|
||||
break;
|
||||
|
||||
case XENMAPSPACE_grant_table:
|
||||
- rc = gnttab_map_frame(d, idx, gfn, &mfn);
|
||||
+ rc = gnttab_map_frame_begin(d, idx, gfn, &mfn);
|
||||
if ( rc )
|
||||
return rc;
|
||||
- /* Need to take care of the reference obtained in gnttab_map_frame(). */
|
||||
- page = mfn_to_page(mfn);
|
||||
break;
|
||||
|
||||
case XENMAPSPACE_gmfn:
|
||||
@@ -2095,19 +2093,28 @@ int xenmem_add_to_physmap_one(
|
||||
put_gfn(d, gfn_x(gfn));
|
||||
|
||||
put_both:
|
||||
- /*
|
||||
- * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
|
||||
- * We also may need to transfer ownership of the page reference to our
|
||||
- * caller.
|
||||
- */
|
||||
- if ( space == XENMAPSPACE_gmfn )
|
||||
+ switch ( space )
|
||||
{
|
||||
+ case XENMAPSPACE_gmfn:
|
||||
+ /*
|
||||
+ * We took a ref of the gfn at the top. We also may need to transfer
|
||||
+ * ownership of the page reference to our caller.
|
||||
+ */
|
||||
put_gfn(d, gmfn);
|
||||
if ( !rc && extra.ppage )
|
||||
{
|
||||
*extra.ppage = page;
|
||||
page = NULL;
|
||||
}
|
||||
+ break;
|
||||
+
|
||||
+ case XENMAPSPACE_grant_table:
|
||||
+ /*
|
||||
+ * We (gnttab_map_frame_begin()) acquired a lock and took a ref of the
|
||||
+ * page underlying the MFN at the top.
|
||||
+ */
|
||||
+ gnttab_map_frame_end(d, mfn);
|
||||
+ break;
|
||||
}
|
||||
|
||||
if ( page )
|
||||
--- a/xen/common/grant_table.c
|
||||
+++ b/xen/common/grant_table.c
|
||||
@@ -4250,7 +4250,8 @@ int gnttab_acquire_resource(
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn)
|
||||
+int gnttab_map_frame_begin(
|
||||
+ struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn)
|
||||
{
|
||||
int rc = 0;
|
||||
struct grant_table *gt = d->grant_table;
|
||||
@@ -4288,11 +4289,19 @@ int gnttab_map_frame(struct domain *d, u
|
||||
put_page(pg);
|
||||
}
|
||||
|
||||
- grant_write_unlock(gt);
|
||||
+ if ( rc )
|
||||
+ grant_write_unlock(d->grant_table);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
+void gnttab_map_frame_end(struct domain *d, mfn_t mfn)
|
||||
+{
|
||||
+ put_page(mfn_to_page(mfn));
|
||||
+
|
||||
+ grant_write_unlock(d->grant_table);
|
||||
+}
|
||||
+
|
||||
static void gnttab_usage_print(struct domain *rd)
|
||||
{
|
||||
int first = 1;
|
||||
--- a/xen/include/xen/grant_table.h
|
||||
+++ b/xen/include/xen/grant_table.h
|
||||
@@ -60,8 +60,13 @@ int gnttab_release_mappings(struct domai
|
||||
int mem_sharing_gref_to_gfn(struct grant_table *gt, grant_ref_t ref,
|
||||
gfn_t *gfn, uint16_t *status);
|
||||
|
||||
-int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn,
|
||||
- mfn_t *mfn);
|
||||
+/*
|
||||
+ * These need to be used as a pair, as the first (in the success case) returns
|
||||
+ * with a lock and page reference held which the second needs to drop.
|
||||
+ */
|
||||
+int gnttab_map_frame_begin(struct domain *d, unsigned long idx, gfn_t gfn,
|
||||
+ mfn_t *mfn);
|
||||
+void gnttab_map_frame_end(struct domain *d, mfn_t mfn);
|
||||
|
||||
unsigned int gnttab_resource_max_frames(const struct domain *d, unsigned int id);
|
||||
|
||||
@@ -100,12 +105,14 @@ static inline int mem_sharing_gref_to_gf
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-static inline int gnttab_map_frame(struct domain *d, unsigned long idx,
|
||||
- gfn_t gfn, mfn_t *mfn)
|
||||
+static inline int gnttab_map_frame_begin(struct domain *d, unsigned long idx,
|
||||
+ gfn_t gfn, mfn_t *mfn)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static inline void gnttab_map_frame_end(struct domain *d, mfn_t mfn) {}
|
||||
+
|
||||
static inline unsigned int gnttab_resource_max_frames(
|
||||
const struct domain *d, unsigned int id)
|
||||
{
|
||||
43
xsa490-4.21.patch
Normal file
43
xsa490-4.21.patch
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Subject: x86/amd: Mitigate AMD-SN-7052
|
||||
|
||||
This is XSA-490 / CVE-2025-54518.
|
||||
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
|
||||
index 1bb0766ebf13..b5bf2b732e8f 100644
|
||||
--- a/xen/arch/x86/cpu/amd.c
|
||||
+++ b/xen/arch/x86/cpu/amd.c
|
||||
@@ -1116,11 +1116,25 @@ static void amd_check_bp_cfg(void)
|
||||
{
|
||||
uint64_t val, new = 0;
|
||||
|
||||
- /*
|
||||
- * AMD Erratum #1485. Set bit 5, as instructed.
|
||||
- */
|
||||
- if (!cpu_has_hypervisor && boot_cpu_data.x86 == 0x19 && is_zen4_uarch())
|
||||
- new |= (1 << 5);
|
||||
+ if (!cpu_has_hypervisor) {
|
||||
+ /*
|
||||
+ * AMD Erratum #1485. If SMT is enabled and STIBP disabled,
|
||||
+ * the CPU may fetch incorrect instruction bytes.
|
||||
+ *
|
||||
+ * Set bit 5, as instructed.
|
||||
+ */
|
||||
+ if (boot_cpu_data.x86 == 0x19 && is_zen4_uarch())
|
||||
+ new |= (1 << 5);
|
||||
+
|
||||
+ /*
|
||||
+ * AMD SB-7052. CPU OP Cache corruption, causing instructions
|
||||
+ * to be executed at a higher privilege.
|
||||
+ *
|
||||
+ * Set bit 33, as instructed.
|
||||
+ */
|
||||
+ if (boot_cpu_data.x86 == 0x17 && is_zen2_uarch())
|
||||
+ new |= (1UL << 33);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* On hardware supporting SRSO_MSR_FIX, activate BP_SPEC_REDUCE by
|
||||
211
xsa491-4.21.patch
Normal file
211
xsa491-4.21.patch
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/HVM: add locking to I/O port translation list traversal
|
||||
|
||||
XEN_DOMCTL_ioport_mapping is usable by DM stubdoms, and hence we can't
|
||||
assume the list to be left unaltered while the guest (really: the
|
||||
hypervisor on behalf of the guest) is accessing it.
|
||||
|
||||
This is XSA-491 / CVE-2026-42487.
|
||||
|
||||
Fixes: 192c4dabc344 ("domctl and p2m changes for PCI passthru")
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -663,6 +663,7 @@ long arch_do_domctl(
|
||||
"ioport_map:add: dom%d gport=%x mport=%x nr=%x\n",
|
||||
d->domain_id, fgp, fmp, np);
|
||||
|
||||
+ write_lock(&hvm->g2m_ioport_lock);
|
||||
list_for_each_entry(g2m_ioport, &hvm->g2m_ioport_list, list)
|
||||
if (g2m_ioport->mport == fmp )
|
||||
{
|
||||
@@ -684,11 +685,14 @@ long arch_do_domctl(
|
||||
g2m_ioport->np = np;
|
||||
list_add_tail(&g2m_ioport->list, &hvm->g2m_ioport_list);
|
||||
}
|
||||
+ write_unlock(&hvm->g2m_ioport_lock);
|
||||
if ( !ret )
|
||||
ret = ioports_permit_access(d, fmp, fmp + np - 1);
|
||||
if ( ret && !found && g2m_ioport )
|
||||
{
|
||||
+ write_lock(&hvm->g2m_ioport_lock);
|
||||
list_del(&g2m_ioport->list);
|
||||
+ write_unlock(&hvm->g2m_ioport_lock);
|
||||
xfree(g2m_ioport);
|
||||
}
|
||||
}
|
||||
@@ -697,6 +701,8 @@ long arch_do_domctl(
|
||||
printk(XENLOG_G_INFO
|
||||
"ioport_map:remove: dom%d gport=%x mport=%x nr=%x\n",
|
||||
d->domain_id, fgp, fmp, np);
|
||||
+
|
||||
+ write_lock(&hvm->g2m_ioport_lock);
|
||||
list_for_each_entry(g2m_ioport, &hvm->g2m_ioport_list, list)
|
||||
if ( g2m_ioport->mport == fmp )
|
||||
{
|
||||
@@ -704,6 +710,8 @@ long arch_do_domctl(
|
||||
xfree(g2m_ioport);
|
||||
break;
|
||||
}
|
||||
+ write_unlock(&hvm->g2m_ioport_lock);
|
||||
+
|
||||
ret = ioports_deny_access(d, fmp, fmp + np - 1);
|
||||
if ( ret && is_hardware_domain(currd) )
|
||||
printk(XENLOG_ERR
|
||||
--- a/xen/arch/x86/hvm/emulate.c
|
||||
+++ b/xen/arch/x86/hvm/emulate.c
|
||||
@@ -160,7 +160,6 @@ void hvmemul_cancel(struct vcpu *v)
|
||||
hvio->mmio_insn_bytes = 0;
|
||||
hvio->mmio_access = (struct npfec){};
|
||||
hvio->mmio_retry = false;
|
||||
- hvio->g2m_ioport = NULL;
|
||||
|
||||
hvmemul_cache_disable(v);
|
||||
}
|
||||
--- a/xen/arch/x86/hvm/hvm.c
|
||||
+++ b/xen/arch/x86/hvm/hvm.c
|
||||
@@ -610,6 +610,7 @@ int hvm_domain_initialise(struct domain
|
||||
spin_lock_init(&d->arch.hvm.irq_lock);
|
||||
spin_lock_init(&d->arch.hvm.uc_lock);
|
||||
spin_lock_init(&d->arch.hvm.write_map.lock);
|
||||
+ rwlock_init(&d->arch.hvm.g2m_ioport_lock);
|
||||
rwlock_init(&d->arch.hvm.mmcfg_lock);
|
||||
INIT_LIST_HEAD(&d->arch.hvm.write_map.list);
|
||||
INIT_LIST_HEAD(&d->arch.hvm.g2m_ioport_list);
|
||||
--- a/xen/arch/x86/hvm/io.c
|
||||
+++ b/xen/arch/x86/hvm/io.c
|
||||
@@ -143,36 +143,56 @@ bool handle_pio(uint16_t port, unsigned
|
||||
return true;
|
||||
}
|
||||
|
||||
-static bool cf_check g2m_portio_accept(
|
||||
- const struct hvm_io_handler *handler, const ioreq_t *p)
|
||||
+/* NB: Returns with the lock held in the success case. */
|
||||
+static const struct g2m_ioport *g2m_portio_find_and_lock(struct hvm_domain *hvm,
|
||||
+ uint64_t addr,
|
||||
+ uint32_t size)
|
||||
{
|
||||
- struct vcpu *curr = current;
|
||||
- const struct hvm_domain *hvm = &curr->domain->arch.hvm;
|
||||
- struct hvm_vcpu_io *hvio = &curr->arch.hvm.hvm_io;
|
||||
- struct g2m_ioport *g2m_ioport;
|
||||
- unsigned int start, end;
|
||||
+ const struct g2m_ioport *g2m_ioport;
|
||||
+
|
||||
+ read_lock(&hvm->g2m_ioport_lock);
|
||||
|
||||
list_for_each_entry( g2m_ioport, &hvm->g2m_ioport_list, list )
|
||||
{
|
||||
- start = g2m_ioport->gport;
|
||||
- end = start + g2m_ioport->np;
|
||||
- if ( (p->addr >= start) && (p->addr + p->size <= end) )
|
||||
- {
|
||||
- hvio->g2m_ioport = g2m_ioport;
|
||||
- return 1;
|
||||
- }
|
||||
+ unsigned int start = g2m_ioport->gport;
|
||||
+
|
||||
+ if ( addr >= start && addr + size <= start + g2m_ioport->np )
|
||||
+ return g2m_ioport;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ read_unlock(&hvm->g2m_ioport_lock);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static bool cf_check g2m_portio_accept(
|
||||
+ const struct hvm_io_handler *handler, const ioreq_t *p)
|
||||
+{
|
||||
+ struct hvm_domain *hvm = ¤t->domain->arch.hvm;
|
||||
+ const struct g2m_ioport *g2m_ioport =
|
||||
+ g2m_portio_find_and_lock(hvm, p->addr, p->size);
|
||||
+
|
||||
+ if ( !g2m_ioport )
|
||||
+ return false;
|
||||
+
|
||||
+ read_unlock(&hvm->g2m_ioport_lock);
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static int cf_check g2m_portio_read(
|
||||
const struct hvm_io_handler *handler, uint64_t addr, uint32_t size,
|
||||
uint64_t *data)
|
||||
{
|
||||
- struct hvm_vcpu_io *hvio = ¤t->arch.hvm.hvm_io;
|
||||
- const struct g2m_ioport *g2m_ioport = hvio->g2m_ioport;
|
||||
- unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
|
||||
+ struct hvm_domain *hvm = ¤t->domain->arch.hvm;
|
||||
+ const struct g2m_ioport *g2m_ioport =
|
||||
+ g2m_portio_find_and_lock(hvm, addr, size);
|
||||
+ unsigned int mport;
|
||||
+
|
||||
+ if ( !g2m_ioport )
|
||||
+ return X86EMUL_RETRY;
|
||||
+
|
||||
+ mport = addr - g2m_ioport->gport + g2m_ioport->mport;
|
||||
|
||||
switch ( size )
|
||||
{
|
||||
@@ -189,6 +209,8 @@ static int cf_check g2m_portio_read(
|
||||
BUG();
|
||||
}
|
||||
|
||||
+ read_unlock(&hvm->g2m_ioport_lock);
|
||||
+
|
||||
return X86EMUL_OKAY;
|
||||
}
|
||||
|
||||
@@ -196,9 +218,15 @@ static int cf_check g2m_portio_write(
|
||||
const struct hvm_io_handler *handler, uint64_t addr, uint32_t size,
|
||||
uint64_t data)
|
||||
{
|
||||
- struct hvm_vcpu_io *hvio = ¤t->arch.hvm.hvm_io;
|
||||
- const struct g2m_ioport *g2m_ioport = hvio->g2m_ioport;
|
||||
- unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
|
||||
+ struct hvm_domain *hvm = ¤t->domain->arch.hvm;
|
||||
+ const struct g2m_ioport *g2m_ioport =
|
||||
+ g2m_portio_find_and_lock(hvm, addr, size);
|
||||
+ unsigned int mport;
|
||||
+
|
||||
+ if ( !g2m_ioport )
|
||||
+ return X86EMUL_RETRY;
|
||||
+
|
||||
+ mport = addr - g2m_ioport->gport + g2m_ioport->mport;
|
||||
|
||||
switch ( size )
|
||||
{
|
||||
@@ -215,6 +243,8 @@ static int cf_check g2m_portio_write(
|
||||
BUG();
|
||||
}
|
||||
|
||||
+ read_unlock(&hvm->g2m_ioport_lock);
|
||||
+
|
||||
return X86EMUL_OKAY;
|
||||
}
|
||||
|
||||
--- a/xen/arch/x86/include/asm/hvm/domain.h
|
||||
+++ b/xen/arch/x86/include/asm/hvm/domain.h
|
||||
@@ -125,6 +125,7 @@ struct hvm_domain {
|
||||
|
||||
/* List of guest to machine IO ports mapping. */
|
||||
struct list_head g2m_ioport_list;
|
||||
+ rwlock_t g2m_ioport_lock;
|
||||
|
||||
/* List of MMCFG regions trapped by Xen. */
|
||||
struct list_head mmcfg_regions;
|
||||
--- a/xen/arch/x86/include/asm/hvm/vcpu.h
|
||||
+++ b/xen/arch/x86/include/asm/hvm/vcpu.h
|
||||
@@ -54,8 +54,6 @@ struct hvm_vcpu_io {
|
||||
unsigned long msix_unmask_address;
|
||||
unsigned long msix_snoop_address;
|
||||
unsigned long msix_snoop_gpa;
|
||||
-
|
||||
- const struct g2m_ioport *g2m_ioport;
|
||||
};
|
||||
|
||||
struct nestedvcpu {
|
||||
264
xsa492-4.21-01.patch
Normal file
264
xsa492-4.21-01.patch
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: sched: use sequence counter to enlighten vcpu_runstate_get()
|
||||
|
||||
Subsequently XEN_DOMCTL_getdomaininfo will want to invoke the function
|
||||
without holding a lock, thus allowing parallel execution of potentially
|
||||
many instances. As was learned from 228ab9992ffb ("domctl: improve
|
||||
locking during domain destruction"), reverted by d0887cc6b16e, such
|
||||
parallelism can result in severe lock contention on any (previously)
|
||||
inner lock. To avoid taking that risk replace the use of the scheduler
|
||||
lock in vcpu_runstate_get() by a newly introduced sequence counter.
|
||||
Convert the "no lock if current" property to "use a local counter
|
||||
instance", thus guaranteeing the loop to exit after the first iteration.
|
||||
|
||||
Skeleton and commentary of the seqcount implementation based on /
|
||||
derived from Linux 6.11-rc.
|
||||
|
||||
To have runstate_seq placed next to runstate in struct vcpu, without
|
||||
introducing a new obvious padding hole, yet while keeping the latter
|
||||
adjacent to runstate_guest{,_area} as well, move runstate down a little.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Requested-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Reviewed-by: Juergen Gross <jgross@suse.com>
|
||||
|
||||
--- a/xen/common/sched/core.c
|
||||
+++ b/xen/common/sched/core.c
|
||||
@@ -281,13 +281,18 @@ static inline void vcpu_runstate_change(
|
||||
}
|
||||
|
||||
delta = new_entry_time - v->runstate.state_entry_time;
|
||||
- if ( delta > 0 )
|
||||
+
|
||||
+ /* Serialization: ->schedule_lock (see ASSERT() above). */
|
||||
+ with_seq_write(&v->runstate_seq)
|
||||
{
|
||||
- v->runstate.time[v->runstate.state] += delta;
|
||||
- v->runstate.state_entry_time = new_entry_time;
|
||||
- }
|
||||
+ if ( delta > 0 )
|
||||
+ {
|
||||
+ v->runstate.time[v->runstate.state] += delta;
|
||||
+ v->runstate.state_entry_time = new_entry_time;
|
||||
+ }
|
||||
|
||||
- v->runstate.state = new_state;
|
||||
+ v->runstate.state = new_state;
|
||||
+ }
|
||||
}
|
||||
|
||||
void sched_guest_idle(void (*idle) (void), unsigned int cpu)
|
||||
@@ -307,30 +312,18 @@ void sched_guest_idle(void (*idle) (void
|
||||
void vcpu_runstate_get(const struct vcpu *v,
|
||||
struct vcpu_runstate_info *runstate)
|
||||
{
|
||||
- spinlock_t *lock;
|
||||
- s_time_t delta;
|
||||
- struct sched_unit *unit;
|
||||
+ struct seqcount seq = SEQCNT_ZERO();
|
||||
+ const struct seqcount *s = likely(v == current) ? &seq : &v->runstate_seq;
|
||||
|
||||
- rcu_read_lock(&sched_res_rculock);
|
||||
-
|
||||
- /*
|
||||
- * Be careful in case of an idle vcpu: the assignment to a unit might
|
||||
- * change even with the scheduling lock held, so be sure to use the
|
||||
- * correct unit for locking in order to avoid triggering an ASSERT() in
|
||||
- * the unlock function.
|
||||
- */
|
||||
- unit = is_idle_vcpu(v) ? get_sched_res(v->processor)->sched_unit_idle
|
||||
- : v->sched_unit;
|
||||
- lock = likely(v == current) ? NULL : unit_schedule_lock_irq(unit);
|
||||
- memcpy(runstate, &v->runstate, sizeof(*runstate));
|
||||
- delta = NOW() - runstate->state_entry_time;
|
||||
- if ( delta > 0 )
|
||||
- runstate->time[runstate->state] += delta;
|
||||
-
|
||||
- if ( unlikely(lock != NULL) )
|
||||
- unit_schedule_unlock_irq(lock, unit);
|
||||
+ until_seq_read(s)
|
||||
+ {
|
||||
+ s_time_t delta;
|
||||
|
||||
- rcu_read_unlock(&sched_res_rculock);
|
||||
+ *runstate = v->runstate;
|
||||
+ delta = NOW() - runstate->state_entry_time;
|
||||
+ if ( delta > 0 )
|
||||
+ runstate->time[runstate->state] += delta;
|
||||
+ }
|
||||
}
|
||||
|
||||
uint64_t get_cpu_idle_time(unsigned int cpu)
|
||||
--- a/xen/include/xen/sched.h
|
||||
+++ b/xen/include/xen/sched.h
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <xen/radix-tree.h>
|
||||
#include <xen/multicall.h>
|
||||
#include <xen/nospec.h>
|
||||
+#include <xen/seqcount.h>
|
||||
#include <xen/tasklet.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/smp.h>
|
||||
@@ -198,7 +199,6 @@ struct vcpu
|
||||
|
||||
struct sched_unit *sched_unit;
|
||||
|
||||
- struct vcpu_runstate_info runstate;
|
||||
#ifndef CONFIG_COMPAT
|
||||
# define runstate_guest(v) ((v)->runstate_guest)
|
||||
XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
|
||||
@@ -210,6 +210,8 @@ struct vcpu
|
||||
} runstate_guest; /* guest address */
|
||||
#endif
|
||||
struct guest_area runstate_guest_area;
|
||||
+ struct vcpu_runstate_info runstate;
|
||||
+ struct seqcount runstate_seq;
|
||||
unsigned int new_state;
|
||||
|
||||
/* Has the FPU been initialised? */
|
||||
--- /dev/null
|
||||
+++ b/xen/include/xen/seqcount.h
|
||||
@@ -0,0 +1,139 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+#ifndef XEN_SEQCOUNT_H
|
||||
+#define XEN_SEQCOUNT_H
|
||||
+
|
||||
+#include <xen/lib.h>
|
||||
+#include <xen/nospec.h>
|
||||
+
|
||||
+#include <asm/atomic.h>
|
||||
+#include <asm/system.h>
|
||||
+
|
||||
+/*
|
||||
+ * Sequence counters (seqcount_t)
|
||||
+ *
|
||||
+ * This is the raw counting mechanism, without any writer protection.
|
||||
+ *
|
||||
+ * Write side critical sections must be serialized (and non-preemptible).
|
||||
+ *
|
||||
+ * If readers can be invoked from interrupt contexts, interrupts must also
|
||||
+ * be respectively disabled before entering the write section.
|
||||
+ *
|
||||
+ * This mechanism can't be used if the protected data contains pointers,
|
||||
+ * as the writer can invalidate a pointer that a reader is following.
|
||||
+ */
|
||||
+struct seqcount {
|
||||
+ unsigned int sequence;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * SEQCNT_ZERO() - initializer for seqcount_t
|
||||
+ * @name: Name of the struct seqcount instance
|
||||
+ */
|
||||
+#define SEQCNT_ZERO() { .sequence = 0 }
|
||||
+
|
||||
+static inline unsigned int seqprop_sequence(const struct seqcount *s)
|
||||
+{
|
||||
+ return ACCESS_ONCE(s->sequence);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * read_seqcount_begin() - begin a seqcount read critical section
|
||||
+ * @s: Pointer to struct seqcount
|
||||
+ *
|
||||
+ * Return: count to be passed to read_seqcount_retry()
|
||||
+ */
|
||||
+static inline unsigned int _read_seqcount_begin(const struct seqcount *s)
|
||||
+{
|
||||
+ unsigned int seq;
|
||||
+
|
||||
+ while ((seq = seqprop_sequence(s)) & 1)
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ smp_rmb();
|
||||
+
|
||||
+ return seq;
|
||||
+}
|
||||
+
|
||||
+static always_inline unsigned int read_seqcount_begin(const struct seqcount *s)
|
||||
+{
|
||||
+ unsigned int seq = _read_seqcount_begin(s);
|
||||
+
|
||||
+ block_lock_speculation();
|
||||
+
|
||||
+ return seq;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * read_seqcount_retry() - end a seqcount read critical section
|
||||
+ * @s: Pointer to struct seqcount
|
||||
+ * @start: count, from read_seqcount_begin()
|
||||
+ *
|
||||
+ * read_seqcount_retry closes the read critical section of given struct
|
||||
+ * seqcount. If the critical section was invalid, it must be ignored
|
||||
+ * (and typically retried).
|
||||
+ *
|
||||
+ * Return: true if a read section retry is required, else false
|
||||
+ */
|
||||
+static inline bool _read_seqcount_retry(const struct seqcount *s,
|
||||
+ unsigned int start)
|
||||
+{
|
||||
+ smp_rmb();
|
||||
+ return unlikely(seqprop_sequence(s) != start);
|
||||
+}
|
||||
+
|
||||
+static always_inline bool read_seqcount_retry(const struct seqcount *s,
|
||||
+ unsigned int start)
|
||||
+{
|
||||
+ return lock_evaluate_nospec(_read_seqcount_retry(s, start));
|
||||
+}
|
||||
+
|
||||
+/* Loops until a consistent count has been observed across the loop body. */
|
||||
+#define until_seq_read(seq) \
|
||||
+ for ( unsigned int retry_ = 1, count_; \
|
||||
+ retry_ && (count_ = read_seqcount_begin(seq), true); \
|
||||
+ retry_ = read_seqcount_retry(seq, count_) )
|
||||
+
|
||||
+/*
|
||||
+ * write_seqcount_begin() - start a struct seqcount write side critical section
|
||||
+ * @s: Pointer to struct seqcount
|
||||
+ *
|
||||
+ * Context: sequence counter write side sections must be serialized.
|
||||
+ * If readers can be invoked from interrupt context, interrupts must be
|
||||
+ * respectively disabled.
|
||||
+ */
|
||||
+static inline void write_seqcount_begin(struct seqcount *s)
|
||||
+{
|
||||
+ add_sized(&s->sequence, 1);
|
||||
+ smp_wmb();
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * write_seqcount_end() - end a struct seqcount write side critical section
|
||||
+ * @s: Pointer to seqcount
|
||||
+ */
|
||||
+static inline void write_seqcount_end(struct seqcount *s)
|
||||
+{
|
||||
+ smp_wmb();
|
||||
+ add_sized(&s->sequence, 1);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Not really a loop, but we need write_seqcount_{begin,end}() in the correct
|
||||
+ * position.
|
||||
+ */
|
||||
+#define with_seq_write(seq) \
|
||||
+ for ( bool once_ = true; \
|
||||
+ once_ && (write_seqcount_begin(seq), true); \
|
||||
+ (write_seqcount_end(seq), once_ = false) )
|
||||
+
|
||||
+#endif /* XEN_SEQCOUNT_H */
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-file-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
104
xsa492-4.21-02.patch
Normal file
104
xsa492-4.21-02.patch
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_getdomaininfo without acquiring domctl lock
|
||||
|
||||
getdomaininfo() is not called under consistently the same lock. Thus,
|
||||
with caller side locking irrelevant, it can as well be called with the
|
||||
domctl lock not held. (Callers not pausing the domain they want to
|
||||
retrieve information for already need to be aware that not all of the
|
||||
data returned can be relied on as being consistent; most data will also
|
||||
be stale by the time the caller gets to look at it.)
|
||||
|
||||
Move the handling not only ahead of acquiring the lock, but also ahead
|
||||
of the XSM check, leveraging that the sub-op has its own hook.
|
||||
|
||||
While moving, convert an assignment to an assertion: The domain in
|
||||
question was determined from the field which previously was "updated".
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Fixes: 5513bd0b4675 ("add xenstore domain flag to hypervisor")
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -318,6 +318,26 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* Handle sub-ops not requiring the domctl lock. */
|
||||
+ switch ( op->cmd )
|
||||
+ {
|
||||
+ case XEN_DOMCTL_getdomaininfo:
|
||||
+ ret = xsm_getdomaininfo(XSM_XS_PRIV, d);
|
||||
+ if ( !ret )
|
||||
+ {
|
||||
+ getdomaininfo(d, &op->u.getdomaininfo);
|
||||
+
|
||||
+ ASSERT(op->domain == op->u.getdomaininfo.domain);
|
||||
+ copyback = true;
|
||||
+ }
|
||||
+
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ default:
|
||||
+ /* Everything else handled further down. */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
ret = xsm_domctl(XSM_OTHER, d, op->cmd,
|
||||
/* SSIDRef only applicable for cmd == createdomain */
|
||||
op->u.createdomain.ssidref);
|
||||
@@ -516,17 +536,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
copyback = 1;
|
||||
break;
|
||||
|
||||
- case XEN_DOMCTL_getdomaininfo:
|
||||
- ret = xsm_getdomaininfo(XSM_XS_PRIV, d);
|
||||
- if ( ret )
|
||||
- break;
|
||||
-
|
||||
- getdomaininfo(d, &op->u.getdomaininfo);
|
||||
-
|
||||
- op->domain = op->u.getdomaininfo.domain;
|
||||
- copyback = 1;
|
||||
- break;
|
||||
-
|
||||
case XEN_DOMCTL_getvcpucontext:
|
||||
{
|
||||
vcpu_guest_context_u c = { .nat = NULL };
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -172,9 +172,13 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
return xsm_default_action(XSM_DM_PRIV, current->domain, d);
|
||||
- case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
return xsm_default_action(XSM_XS_PRIV, current->domain, d);
|
||||
+
|
||||
+ case XEN_DOMCTL_getdomaininfo:
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return -EILSEQ;
|
||||
+
|
||||
default:
|
||||
return xsm_default_action(XSM_PRIV, current->domain, d);
|
||||
}
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -682,8 +682,12 @@ static int cf_check flask_domctl(struct
|
||||
*/
|
||||
return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
|
||||
|
||||
- /* These have individual XSM hooks (common/domctl.c) */
|
||||
+ /* These have individual XSM hooks and don't make it here. */
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return -EILSEQ;
|
||||
+
|
||||
+ /* These have individual XSM hooks (common/domctl.c) */
|
||||
case XEN_DOMCTL_scheduler_op:
|
||||
case XEN_DOMCTL_irq_permission:
|
||||
case XEN_DOMCTL_iomem_permission:
|
||||
87
xsa492-4.21-03.patch
Normal file
87
xsa492-4.21-03.patch
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
From: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Subject: domctl: protect locking for get_domain_state
|
||||
|
||||
When DOMID_INVALID is passed, the dom exec handler lock is being taken
|
||||
without any check that the domain is even allowed to take the lock. This
|
||||
allows for an unauthorized domain to DoS the get_domain_state domctl op.
|
||||
Move to consider the op effectively being called against the hypervisor.
|
||||
Thus it is the target of the call being invoked to identify the last
|
||||
domain with a state change. The subsequent check of whether the source
|
||||
domain is allowed the state of the last domain to change state is still
|
||||
relevant.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/tools/flask/policy/modules/xenstore.te
|
||||
+++ b/tools/flask/policy/modules/xenstore.te
|
||||
@@ -14,6 +14,7 @@ allow xenstore_t xen_t:xen writeconsole;
|
||||
# Xenstore queries domaininfo on all domains
|
||||
allow xenstore_t domain_type:domain getdomaininfo;
|
||||
allow xenstore_t domain_type:domain2 get_domain_state;
|
||||
+allow xenstore_t domxen_t:domain2 get_domain_state;
|
||||
|
||||
# As a shortcut, the following 3 rules are used instead of adding a domain_comms
|
||||
# rule between xenstore_t and every domain type that talks to xenstore
|
||||
--- a/xen/common/domain.c
|
||||
+++ b/xen/common/domain.c
|
||||
@@ -216,12 +216,8 @@ int get_domain_state(struct xen_domctl_g
|
||||
if ( info->pad0 )
|
||||
return -EINVAL;
|
||||
|
||||
- if ( d )
|
||||
+ if ( d != dom_xen )
|
||||
{
|
||||
- rc = xsm_get_domain_state(XSM_XS_PRIV, d);
|
||||
- if ( rc )
|
||||
- return rc;
|
||||
-
|
||||
set_domain_state_info(info, d);
|
||||
|
||||
return 0;
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -304,13 +304,19 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
fallthrough;
|
||||
case XEN_DOMCTL_test_assign_device:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
- case XEN_DOMCTL_get_domain_state:
|
||||
if ( op->domain == DOMID_INVALID )
|
||||
{
|
||||
d = NULL;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
+ case XEN_DOMCTL_get_domain_state:
|
||||
+ if ( op->domain == DOMID_INVALID )
|
||||
+ {
|
||||
+ d = dom_xen;
|
||||
+ break;
|
||||
+ }
|
||||
+ fallthrough;
|
||||
default:
|
||||
d = rcu_lock_domain_by_id(op->domain);
|
||||
if ( !d )
|
||||
@@ -863,7 +869,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
break;
|
||||
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
- ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
|
||||
+ ret = xsm_get_domain_state(XSM_XS_PRIV, d);
|
||||
+ if ( !ret )
|
||||
+ ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
|
||||
if ( !ret )
|
||||
copyback = true;
|
||||
break;
|
||||
@@ -876,7 +884,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
domctl_lock_release();
|
||||
|
||||
domctl_out_unlock_domonly:
|
||||
- if ( d && d != dom_io )
|
||||
+ if ( d && !is_system_domain(d) )
|
||||
rcu_unlock_domain(d);
|
||||
|
||||
if ( copyback && __copy_to_guest(u_domctl, op, 1) )
|
||||
81
xsa492-4.21-04.patch
Normal file
81
xsa492-4.21-04.patch
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_get_domain_state without acquiring domctl lock
|
||||
|
||||
get_domain_state() uses its own locking. Thus, with caller side locking
|
||||
irrelevant, it can as well be called with the domctl lock not held.
|
||||
|
||||
Move the handling not only ahead of acquiring the lock, but also ahead
|
||||
of the XSM check, leveraging that the sub-op has its own hook.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Fixes: 3ad3df1bd0aa ("xen: add new domctl get_domain_state")
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -339,6 +339,14 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
|
||||
goto domctl_out_unlock_domonly;
|
||||
|
||||
+ case XEN_DOMCTL_get_domain_state:
|
||||
+ ret = xsm_get_domain_state(XSM_XS_PRIV, d);
|
||||
+ if ( !ret )
|
||||
+ ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
|
||||
+ if ( !ret )
|
||||
+ copyback = true;
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
default:
|
||||
/* Everything else handled further down. */
|
||||
break;
|
||||
@@ -868,14 +876,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
- case XEN_DOMCTL_get_domain_state:
|
||||
- ret = xsm_get_domain_state(XSM_XS_PRIV, d);
|
||||
- if ( !ret )
|
||||
- ret = get_domain_state(&op->u.get_domain_state, d, &op->domain);
|
||||
- if ( !ret )
|
||||
- copyback = true;
|
||||
- break;
|
||||
-
|
||||
default:
|
||||
ret = arch_do_domctl(op, d, u_domctl);
|
||||
break;
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -172,10 +172,9 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
return xsm_default_action(XSM_DM_PRIV, current->domain, d);
|
||||
- case XEN_DOMCTL_get_domain_state:
|
||||
- return xsm_default_action(XSM_XS_PRIV, current->domain, d);
|
||||
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
+ case XEN_DOMCTL_get_domain_state:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -684,6 +684,7 @@ static int cf_check flask_domctl(struct
|
||||
|
||||
/* These have individual XSM hooks and don't make it here. */
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
+ case XEN_DOMCTL_get_domain_state:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -694,7 +695,6 @@ static int cf_check flask_domctl(struct
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_set_target:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
- case XEN_DOMCTL_get_domain_state:
|
||||
|
||||
/* These have individual XSM hooks (arch/../domctl.c) */
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
156
xsa492-4.21-05.patch
Normal file
156
xsa492-4.21-05.patch
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domain: locking for iomem_caps accesses
|
||||
|
||||
In order to be able to pull at least the XEN_DOMCTL_iomem_mapping handling
|
||||
out of the domctl-locked region, a separate (per-domain) lock is needed to
|
||||
synchronize in particular with XEN_DOMCTL_iomem_permission.
|
||||
|
||||
Locking is added only as far as domctl-s are affected. Uses presently
|
||||
outside of the domctl lock may want dealing with subsequently (perhaps
|
||||
limited to non-__init code).
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/common/domain.c
|
||||
+++ b/xen/common/domain.c
|
||||
@@ -518,10 +518,15 @@ static int late_hwdom_init(struct domain
|
||||
* may be modified after this hypercall returns if a more complex
|
||||
* device model is desired.
|
||||
*/
|
||||
+ write_lock(&dom0->caps_lock);
|
||||
rangeset_swap(d->irq_caps, dom0->irq_caps);
|
||||
rangeset_swap(d->iomem_caps, dom0->iomem_caps);
|
||||
#ifdef CONFIG_X86
|
||||
rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
|
||||
+#endif
|
||||
+ write_unlock(&dom0->caps_lock);
|
||||
+
|
||||
+#ifdef CONFIG_X86
|
||||
setup_io_bitmap(d);
|
||||
setup_io_bitmap(dom0);
|
||||
#endif
|
||||
@@ -873,6 +878,7 @@ struct domain *domain_create(domid_t dom
|
||||
rspin_lock_init_prof(d, domain_lock);
|
||||
rspin_lock_init_prof(d, page_alloc_lock);
|
||||
spin_lock_init(&d->hypercall_deadlock_mutex);
|
||||
+ rwlock_init(&d->caps_lock);
|
||||
INIT_PAGE_LIST_HEAD(&d->page_list);
|
||||
INIT_PAGE_LIST_HEAD(&d->extra_page_list);
|
||||
INIT_PAGE_LIST_HEAD(&d->xenpage_list);
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -267,6 +267,35 @@ static struct vnuma_info *vnuma_init(con
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
+void iocaps_double_lock(struct domain *d, bool write)
|
||||
+{
|
||||
+ struct domain *currd = current->domain;
|
||||
+
|
||||
+ if ( d->domain_id > currd->domain_id )
|
||||
+ read_lock(&currd->caps_lock);
|
||||
+
|
||||
+ if ( write )
|
||||
+ write_lock(&d->caps_lock);
|
||||
+ else
|
||||
+ read_lock(&d->caps_lock);
|
||||
+
|
||||
+ if ( d->domain_id < currd->domain_id )
|
||||
+ read_lock(&currd->caps_lock);
|
||||
+}
|
||||
+
|
||||
+void iocaps_double_unlock(struct domain *d, bool write)
|
||||
+{
|
||||
+ struct domain *currd = current->domain;
|
||||
+
|
||||
+ if ( d != currd )
|
||||
+ read_unlock(&currd->caps_lock);
|
||||
+
|
||||
+ if ( write )
|
||||
+ write_unlock(&d->caps_lock);
|
||||
+ else
|
||||
+ read_unlock(&d->caps_lock);
|
||||
+}
|
||||
+
|
||||
static bool is_stable_domctl(uint32_t cmd)
|
||||
{
|
||||
return cmd == XEN_DOMCTL_get_domain_state;
|
||||
@@ -687,6 +716,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
|
||||
break;
|
||||
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
if ( !iomem_access_permitted(current->domain,
|
||||
mfn, mfn + nr_mfns - 1) ||
|
||||
xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) )
|
||||
@@ -695,6 +726,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
|
||||
else
|
||||
ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -719,19 +752,15 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
break;
|
||||
#endif
|
||||
|
||||
+ iocaps_double_lock(d, false);
|
||||
+
|
||||
ret = -EPERM;
|
||||
if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
|
||||
- !iomem_access_permitted(d, mfn, mfn_end) )
|
||||
- break;
|
||||
-
|
||||
- ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
|
||||
- if ( ret )
|
||||
- break;
|
||||
-
|
||||
- if ( !paging_mode_translate(d) )
|
||||
- break;
|
||||
-
|
||||
- if ( add )
|
||||
+ !iomem_access_permitted(d, mfn, mfn_end) ||
|
||||
+ (ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add)) ||
|
||||
+ !paging_mode_translate(d) )
|
||||
+ /* Nothing. */;
|
||||
+ else if ( add )
|
||||
{
|
||||
printk(XENLOG_G_DEBUG
|
||||
"memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
|
||||
@@ -755,6 +784,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
"memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
|
||||
ret, d->domain_id, mfn, mfn_end);
|
||||
}
|
||||
+
|
||||
+ iocaps_double_unlock(d, false);
|
||||
break;
|
||||
}
|
||||
|
||||
--- a/xen/include/xen/iocap.h
|
||||
+++ b/xen/include/xen/iocap.h
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <asm/iocap.h>
|
||||
#include <asm/p2m.h>
|
||||
|
||||
+void iocaps_double_lock(struct domain *d, bool write);
|
||||
+void iocaps_double_unlock(struct domain *d, bool write);
|
||||
+
|
||||
static inline int iomem_permit_access(struct domain *d, unsigned long s,
|
||||
unsigned long e)
|
||||
{
|
||||
--- a/xen/include/xen/sched.h
|
||||
+++ b/xen/include/xen/sched.h
|
||||
@@ -536,6 +536,7 @@ struct domain
|
||||
#endif
|
||||
|
||||
/* I/O capabilities (access to IRQs and memory-mapped I/O). */
|
||||
+ rwlock_t caps_lock;
|
||||
struct rangeset *iomem_caps;
|
||||
struct rangeset *irq_caps;
|
||||
|
||||
84
xsa492-4.21-06.patch
Normal file
84
xsa492-4.21-06.patch
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/domain: locking for ioport_caps accesses
|
||||
|
||||
In order to be able to pull at least the XEN_DOMCTL_ioport_mapping
|
||||
handling out of the domctl-locked region, the new separate (per-domain)
|
||||
lock is used to synchronize in particular with
|
||||
XEN_DOMCTL_ioport_permission.
|
||||
|
||||
Locking is added only as far as domctl-s are affected. Uses presently
|
||||
outside of the domctl lock may want dealing with subsequently (perhaps
|
||||
limited to non-__init code).
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -233,6 +233,8 @@ long arch_do_domctl(
|
||||
unsigned int np = domctl->u.ioport_permission.nr_ports;
|
||||
int allow = domctl->u.ioport_permission.allow_access;
|
||||
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
|
||||
ret = -EINVAL;
|
||||
else if ( !ioports_access_permitted(currd, fp, fp + np - 1) ||
|
||||
@@ -242,6 +244,8 @@ long arch_do_domctl(
|
||||
ret = ioports_permit_access(d, fp, fp + np - 1);
|
||||
else
|
||||
ret = ioports_deny_access(d, fp, fp + np - 1);
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -648,16 +652,13 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
- ret = -EPERM;
|
||||
- if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) )
|
||||
- break;
|
||||
-
|
||||
- ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add);
|
||||
- if ( ret )
|
||||
- break;
|
||||
-
|
||||
hvm = &d->arch.hvm;
|
||||
- if ( add )
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
+ if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) ||
|
||||
+ (ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add)) )
|
||||
+ ret = ret ?: -EPERM;
|
||||
+ else if ( add )
|
||||
{
|
||||
printk(XENLOG_G_INFO
|
||||
"ioport_map:add: dom%d gport=%x mport=%x nr=%x\n",
|
||||
@@ -718,6 +720,8 @@ long arch_do_domctl(
|
||||
"ioport_map: error %ld denying dom%d access to [%x,%x]\n",
|
||||
ret, d->domain_id, fmp, fmp + np - 1);
|
||||
}
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
break;
|
||||
}
|
||||
|
||||
--- a/xen/arch/x86/setup.c
|
||||
+++ b/xen/arch/x86/setup.c
|
||||
@@ -2339,9 +2339,12 @@ void __hwdom_init setup_io_bitmap(struct
|
||||
return;
|
||||
|
||||
bitmap_fill(d->arch.hvm.io_bitmap, 0x10000);
|
||||
+
|
||||
+ read_lock(&d->caps_lock);
|
||||
if ( rangeset_report_ranges(d->arch.ioport_caps, 0, 0x10000,
|
||||
io_bitmap_cb, d) )
|
||||
BUG();
|
||||
+ read_unlock(&d->caps_lock);
|
||||
|
||||
/*
|
||||
* We need to trap 4-byte accesses to 0xcf8 (see admin_io_okay(),
|
||||
202
xsa492-4.21-07.patch
Normal file
202
xsa492-4.21-07.patch
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domain: locking for irq_caps accesses
|
||||
|
||||
In order to be able to pull at least the XEN_DOMCTL_{,un}bind_pt_irq
|
||||
handling out of the domctl-locked region, a separate (per-domain) lock is
|
||||
needed to synchronize in particular with XEN_DOMCTL_{irq,gsi}_permission.
|
||||
|
||||
Locking is added only as far as domctl-s are affected. Uses presently
|
||||
outside of the domctl lock may want dealing with subsequently (perhaps
|
||||
limited to non-__init code).
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Reviewed-by: Julien Grall <julien@xen.org>
|
||||
|
||||
--- a/xen/arch/arm/domctl.c
|
||||
+++ b/xen/arch/arm/domctl.c
|
||||
@@ -76,6 +76,7 @@ long arch_do_domctl(struct xen_domctl *d
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
{
|
||||
int rc;
|
||||
+ struct domain *currd = current->domain;
|
||||
struct xen_domctl_bind_pt_irq *bind = &domctl->u.bind_pt_irq;
|
||||
uint32_t irq = bind->u.spi.spi;
|
||||
uint32_t virq = bind->machine_irq;
|
||||
@@ -107,21 +108,26 @@ long arch_do_domctl(struct xen_domctl *d
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
- if ( !irq_access_permitted(current->domain, irq) )
|
||||
- return -EPERM;
|
||||
+ read_lock(&currd->caps_lock);
|
||||
|
||||
- if ( !vgic_reserve_virq(d, virq) )
|
||||
- return -EBUSY;
|
||||
-
|
||||
- rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
|
||||
- if ( rc )
|
||||
- vgic_free_virq(d, virq);
|
||||
+ if ( !irq_access_permitted(currd, irq) )
|
||||
+ rc = -EPERM;
|
||||
+ else if ( !vgic_reserve_virq(d, virq) )
|
||||
+ rc = -EBUSY;
|
||||
+ else
|
||||
+ {
|
||||
+ rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
|
||||
+ if ( rc )
|
||||
+ vgic_free_virq(d, virq);
|
||||
+ }
|
||||
|
||||
+ read_unlock(&currd->caps_lock);
|
||||
return rc;
|
||||
}
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
{
|
||||
int rc;
|
||||
+ struct domain *currd = current->domain;
|
||||
struct xen_domctl_bind_pt_irq *bind = &domctl->u.bind_pt_irq;
|
||||
uint32_t irq = bind->u.spi.spi;
|
||||
uint32_t virq = bind->machine_irq;
|
||||
@@ -138,16 +144,15 @@ long arch_do_domctl(struct xen_domctl *d
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
- if ( !irq_access_permitted(current->domain, irq) )
|
||||
- return -EPERM;
|
||||
-
|
||||
- rc = release_guest_irq(d, virq);
|
||||
- if ( rc )
|
||||
- return rc;
|
||||
+ read_lock(&currd->caps_lock);
|
||||
|
||||
- vgic_free_virq(d, virq);
|
||||
+ if ( !irq_access_permitted(currd, irq) )
|
||||
+ rc = -EPERM;
|
||||
+ else if ( !(rc = release_guest_irq(d, virq)) )
|
||||
+ vgic_free_virq(d, virq);
|
||||
|
||||
- return 0;
|
||||
+ read_unlock(&currd->caps_lock);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
case XEN_DOMCTL_vuart_op:
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -267,16 +267,17 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
- ret = -EPERM;
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
if ( !irq_access_permitted(currd, irq) ||
|
||||
xsm_irq_permission(XSM_HOOK, d, irq, flags) )
|
||||
- break;
|
||||
-
|
||||
- if ( flags )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( flags )
|
||||
ret = irq_permit_access(d, irq);
|
||||
else
|
||||
ret = irq_deny_access(d, irq);
|
||||
|
||||
+ iocaps_double_unlock(d, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -579,20 +580,27 @@ long arch_do_domctl(
|
||||
break;
|
||||
|
||||
irq = domain_pirq_to_irq(d, bind->machine_irq);
|
||||
- ret = -EPERM;
|
||||
- if ( irq <= 0 || !irq_access_permitted(currd, irq) )
|
||||
- break;
|
||||
+ if ( irq <= 0 )
|
||||
+ ret = -EPERM;
|
||||
|
||||
- ret = -ESRCH;
|
||||
- if ( is_iommu_enabled(d) )
|
||||
+ read_lock(&currd->caps_lock);
|
||||
+
|
||||
+ if ( !irq_access_permitted(currd, irq) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( is_iommu_enabled(d) )
|
||||
{
|
||||
pcidevs_lock();
|
||||
ret = pt_irq_create_bind(d, bind);
|
||||
pcidevs_unlock();
|
||||
+
|
||||
+ if ( ret < 0 )
|
||||
+ printk(XENLOG_G_ERR "pt_irq_create_bind failed (%ld) for %pd\n",
|
||||
+ ret, d);
|
||||
}
|
||||
- if ( ret < 0 )
|
||||
- printk(XENLOG_G_ERR "pt_irq_create_bind failed (%ld) for dom%d\n",
|
||||
- ret, d->domain_id);
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+
|
||||
+ read_unlock(&currd->caps_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -605,23 +613,26 @@ long arch_do_domctl(
|
||||
if ( !is_hvm_domain(d) )
|
||||
break;
|
||||
|
||||
- ret = -EPERM;
|
||||
- if ( irq <= 0 || !irq_access_permitted(currd, irq) )
|
||||
- break;
|
||||
-
|
||||
ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
|
||||
if ( ret )
|
||||
break;
|
||||
|
||||
- if ( is_iommu_enabled(d) )
|
||||
+ read_lock(&currd->caps_lock);
|
||||
+
|
||||
+ if ( !irq_access_permitted(currd, irq) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( is_iommu_enabled(d) )
|
||||
{
|
||||
pcidevs_lock();
|
||||
ret = pt_irq_destroy_bind(d, bind);
|
||||
pcidevs_unlock();
|
||||
+
|
||||
+ if ( ret < 0 )
|
||||
+ printk(XENLOG_G_ERR "pt_irq_destroy_bind failed (%ld) for %pd\n",
|
||||
+ ret, d);
|
||||
}
|
||||
- if ( ret < 0 )
|
||||
- printk(XENLOG_G_ERR "pt_irq_destroy_bind failed (%ld) for dom%d\n",
|
||||
- ret, d->domain_id);
|
||||
+
|
||||
+ read_unlock(&currd->caps_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -695,6 +695,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
irq = pirq_access_permitted(current->domain, pirq);
|
||||
if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) )
|
||||
ret = -EPERM;
|
||||
@@ -702,6 +705,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
ret = irq_permit_access(d, irq);
|
||||
else
|
||||
ret = irq_deny_access(d, irq);
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
85
xsa492-4.21-08.patch
Normal file
85
xsa492-4.21-08.patch
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: XSM/Flask: split the .iomem_mapping() hook
|
||||
|
||||
It's used twice in entirely different situations. The use in do_domctl()
|
||||
wants to become an ordinary XSM_DM_PRIV invocation, while the one in vPCI
|
||||
code need to remain XSM_HOOK (it may plausibly become XSM_TARGET). For
|
||||
Flask, the same backing function will continue to be used for the time
|
||||
being.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
|
||||
--- a/xen/drivers/vpci/header.c
|
||||
+++ b/xen/drivers/vpci/header.c
|
||||
@@ -67,7 +67,7 @@ static int cf_check map_range(
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
- rc = xsm_iomem_mapping(XSM_HOOK, map->d, map_mfn, m_end, map->map);
|
||||
+ rc = xsm_iomem_mapping_vpci(XSM_HOOK, map->d, map_mfn, m_end, map->map);
|
||||
if ( rc )
|
||||
{
|
||||
printk(XENLOG_G_WARNING
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -580,6 +580,13 @@ static XSM_INLINE int cf_check xsm_iomem
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
+static XSM_INLINE int cf_check xsm_iomem_mapping_vpci(
|
||||
+ XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
|
||||
+{
|
||||
+ XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ return xsm_default_action(action, current->domain, d);
|
||||
+}
|
||||
+
|
||||
static XSM_INLINE int cf_check xsm_pci_config_permission(
|
||||
XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf, uint16_t start,
|
||||
uint16_t end, uint8_t access)
|
||||
--- a/xen/include/xsm/xsm.h
|
||||
+++ b/xen/include/xsm/xsm.h
|
||||
@@ -118,6 +118,8 @@ struct xsm_ops {
|
||||
uint8_t allow);
|
||||
int (*iomem_mapping)(struct domain *d, uint64_t s, uint64_t e,
|
||||
uint8_t allow);
|
||||
+ int (*iomem_mapping_vpci)(struct domain *d, uint64_t s, uint64_t e,
|
||||
+ uint8_t allow);
|
||||
int (*pci_config_permission)(struct domain *d, uint32_t machine_bdf,
|
||||
uint16_t start, uint16_t end, uint8_t access);
|
||||
|
||||
@@ -523,6 +525,12 @@ static inline int xsm_iomem_mapping(
|
||||
return alternative_call(xsm_ops.iomem_mapping, d, s, e, allow);
|
||||
}
|
||||
|
||||
+static inline int xsm_iomem_mapping_vpci(
|
||||
+ xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
|
||||
+{
|
||||
+ return alternative_call(xsm_ops.iomem_mapping_vpci, d, s, e, allow);
|
||||
+}
|
||||
+
|
||||
static inline int xsm_pci_config_permission(
|
||||
xsm_default_t def, struct domain *d, uint32_t machine_bdf, uint16_t start,
|
||||
uint16_t end, uint8_t access)
|
||||
--- a/xen/xsm/dummy.c
|
||||
+++ b/xen/xsm/dummy.c
|
||||
@@ -76,6 +76,7 @@ static const struct xsm_ops __initconst_
|
||||
.irq_permission = xsm_irq_permission,
|
||||
.iomem_permission = xsm_iomem_permission,
|
||||
.iomem_mapping = xsm_iomem_mapping,
|
||||
+ .iomem_mapping_vpci = xsm_iomem_mapping_vpci,
|
||||
.pci_config_permission = xsm_pci_config_permission,
|
||||
.get_vnumainfo = xsm_get_vnumainfo,
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -1950,6 +1950,7 @@ static const struct xsm_ops __initconst_
|
||||
.irq_permission = flask_irq_permission,
|
||||
.iomem_permission = flask_iomem_permission,
|
||||
.iomem_mapping = flask_iomem_mapping,
|
||||
+ .iomem_mapping_vpci = flask_iomem_mapping,
|
||||
.pci_config_permission = flask_pci_config_permission,
|
||||
|
||||
.resource_plug_core = flask_resource_plug_core,
|
||||
194
xsa492-4.21-09.patch
Normal file
194
xsa492-4.21-09.patch
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_memory_mapping without acquiring domctl lock
|
||||
|
||||
With dedicated locking added, the domctl lock isn't required here anymore.
|
||||
Move the re-purposed dedicated XSM check as early as possible.
|
||||
|
||||
Minimal "modernization": Switch "add" to bool and use %pd in log messages.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -376,6 +376,66 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
copyback = true;
|
||||
goto domctl_out_unlock_domonly;
|
||||
|
||||
+ case XEN_DOMCTL_memory_mapping:
|
||||
+ {
|
||||
+ unsigned long gfn = op->u.memory_mapping.first_gfn;
|
||||
+ unsigned long mfn = op->u.memory_mapping.first_mfn;
|
||||
+ unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
|
||||
+ unsigned long mfn_end = mfn + nr_mfns - 1;
|
||||
+ bool add = op->u.memory_mapping.add_mapping;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ if ( mfn_end < mfn || /* Wrap? */
|
||||
+ ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
|
||||
+ (gfn + nr_mfns - 1) < gfn ) /* Wrap? */
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ ret = xsm_iomem_mapping(XSM_DM_PRIV, d, mfn, mfn_end, add);
|
||||
+ if ( ret || !paging_mode_translate(d) )
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+#ifndef CONFIG_X86 /* XXX ARM!? */
|
||||
+ ret = -E2BIG;
|
||||
+ /* Must break hypercall up as this could take a while. */
|
||||
+ if ( nr_mfns > 64 )
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+#endif
|
||||
+
|
||||
+ iocaps_double_lock(d, false);
|
||||
+
|
||||
+ ret = -EPERM;
|
||||
+ if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
|
||||
+ !iomem_access_permitted(d, mfn, mfn_end) )
|
||||
+ /* Nothing. */;
|
||||
+ else if ( add )
|
||||
+ {
|
||||
+ printk(XENLOG_G_DEBUG
|
||||
+ "memory_map:add: %pd gfn=%lx mfn=%lx nr=%lx\n",
|
||||
+ d, gfn, mfn, nr_mfns);
|
||||
+
|
||||
+ ret = map_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
|
||||
+ if ( ret < 0 )
|
||||
+ printk(XENLOG_G_WARNING
|
||||
+ "memory_map:fail: %pd gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
|
||||
+ d, gfn, mfn, nr_mfns, ret);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ printk(XENLOG_G_DEBUG
|
||||
+ "memory_map:remove: %pd gfn=%lx mfn=%lx nr=%lx\n",
|
||||
+ d, gfn, mfn, nr_mfns);
|
||||
+
|
||||
+ ret = unmap_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
|
||||
+ if ( ret < 0 && is_hardware_domain(current->domain) )
|
||||
+ printk(XENLOG_ERR
|
||||
+ "memory_map: error %ld removing %pd access to [%lx,%lx]\n",
|
||||
+ ret, d, mfn, mfn_end);
|
||||
+ }
|
||||
+
|
||||
+ iocaps_double_unlock(d, false);
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
/* Everything else handled further down. */
|
||||
break;
|
||||
@@ -736,64 +796,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
break;
|
||||
}
|
||||
|
||||
- case XEN_DOMCTL_memory_mapping:
|
||||
- {
|
||||
- unsigned long gfn = op->u.memory_mapping.first_gfn;
|
||||
- unsigned long mfn = op->u.memory_mapping.first_mfn;
|
||||
- unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
|
||||
- unsigned long mfn_end = mfn + nr_mfns - 1;
|
||||
- int add = op->u.memory_mapping.add_mapping;
|
||||
-
|
||||
- ret = -EINVAL;
|
||||
- if ( mfn_end < mfn || /* wrap? */
|
||||
- ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
|
||||
- (gfn + nr_mfns - 1) < gfn ) /* wrap? */
|
||||
- break;
|
||||
-
|
||||
-#ifndef CONFIG_X86 /* XXX ARM!? */
|
||||
- ret = -E2BIG;
|
||||
- /* Must break hypercall up as this could take a while. */
|
||||
- if ( nr_mfns > 64 )
|
||||
- break;
|
||||
-#endif
|
||||
-
|
||||
- iocaps_double_lock(d, false);
|
||||
-
|
||||
- ret = -EPERM;
|
||||
- if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
|
||||
- !iomem_access_permitted(d, mfn, mfn_end) ||
|
||||
- (ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add)) ||
|
||||
- !paging_mode_translate(d) )
|
||||
- /* Nothing. */;
|
||||
- else if ( add )
|
||||
- {
|
||||
- printk(XENLOG_G_DEBUG
|
||||
- "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
|
||||
- d->domain_id, gfn, mfn, nr_mfns);
|
||||
-
|
||||
- ret = map_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
|
||||
- if ( ret < 0 )
|
||||
- printk(XENLOG_G_WARNING
|
||||
- "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
|
||||
- d->domain_id, gfn, mfn, nr_mfns, ret);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- printk(XENLOG_G_DEBUG
|
||||
- "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
|
||||
- d->domain_id, gfn, mfn, nr_mfns);
|
||||
-
|
||||
- ret = unmap_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn));
|
||||
- if ( ret < 0 && is_hardware_domain(current->domain) )
|
||||
- printk(XENLOG_ERR
|
||||
- "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
|
||||
- ret, d->domain_id, mfn, mfn_end);
|
||||
- }
|
||||
-
|
||||
- iocaps_double_unlock(d, false);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
case XEN_DOMCTL_settimeoffset:
|
||||
domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
|
||||
break;
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -168,13 +168,13 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
switch ( cmd )
|
||||
{
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
- case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
return xsm_default_action(XSM_DM_PRIV, current->domain, d);
|
||||
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_memory_mapping:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -576,7 +576,7 @@ static XSM_INLINE int cf_check xsm_iomem
|
||||
static XSM_INLINE int cf_check xsm_iomem_mapping(
|
||||
XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_DM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -685,6 +685,7 @@ static int cf_check flask_domctl(struct
|
||||
/* These have individual XSM hooks and don't make it here. */
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_memory_mapping:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -692,7 +693,6 @@ static int cf_check flask_domctl(struct
|
||||
case XEN_DOMCTL_scheduler_op:
|
||||
case XEN_DOMCTL_irq_permission:
|
||||
case XEN_DOMCTL_iomem_permission:
|
||||
- case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_set_target:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
|
||||
97
xsa492-4.21-10.patch
Normal file
97
xsa492-4.21-10.patch
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_ioport_mapping without acquiring domctl lock
|
||||
|
||||
With dedicated locking added, the domctl lock isn't required here anymore.
|
||||
As the handling is in arch-specific code (x86 only), almost no code is
|
||||
being moved, but a 2nd (extensible to other sub-ops) invocation of
|
||||
arch_do_domctl() is being added. Move just the re-purposed dedicated XSM
|
||||
check as early as possible.
|
||||
|
||||
In flask_domctl() don't put #ifdef around the moved case label.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -663,12 +663,15 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
+ ret = xsm_ioport_mapping(XSM_DM_PRIV, d, fmp, fmp + np - 1, add);
|
||||
+ if ( ret )
|
||||
+ break;
|
||||
+
|
||||
hvm = &d->arch.hvm;
|
||||
iocaps_double_lock(d, true);
|
||||
|
||||
- if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) ||
|
||||
- (ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add)) )
|
||||
- ret = ret ?: -EPERM;
|
||||
+ if ( !ioports_access_permitted(currd, fmp, fmp + np - 1) )
|
||||
+ ret = -EPERM;
|
||||
else if ( add )
|
||||
{
|
||||
printk(XENLOG_G_INFO
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -436,6 +436,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
goto domctl_out_unlock_domonly;
|
||||
}
|
||||
|
||||
+ case XEN_DOMCTL_ioport_mapping:
|
||||
+ ret = arch_do_domctl(op, d, u_domctl);
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
default:
|
||||
/* Everything else handled further down. */
|
||||
break;
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -167,13 +167,13 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
XSM_ASSERT_ACTION(XSM_OTHER);
|
||||
switch ( cmd )
|
||||
{
|
||||
- case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
return xsm_default_action(XSM_DM_PRIV, current->domain, d);
|
||||
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
@@ -772,7 +772,7 @@ static XSM_INLINE int cf_check xsm_iopor
|
||||
static XSM_INLINE int cf_check xsm_ioport_mapping(
|
||||
XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_DM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -685,6 +685,7 @@ static int cf_check flask_domctl(struct
|
||||
/* These have individual XSM hooks and don't make it here. */
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
@@ -703,7 +704,6 @@ static int cf_check flask_domctl(struct
|
||||
/* These have individual XSM hooks (arch/x86/domctl.c) */
|
||||
case XEN_DOMCTL_shadow_op:
|
||||
case XEN_DOMCTL_ioport_permission:
|
||||
- case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_gsi_permission:
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_PASSTHROUGH
|
||||
128
xsa492-4.21-11.patch
Normal file
128
xsa492-4.21-11.patch
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_{,un}bind_pt_irq without acquiring domctl lock
|
||||
|
||||
With dedicated locking added, the domctl lock isn't required here anymore.
|
||||
(It also already isn't used when pt_irq_{create,destroy}_bind() are
|
||||
invoked for PVH Dom0.) As the handling is in arch-specific code, no code
|
||||
is being moved, but the 2nd (extensible to other sub-ops like the ones
|
||||
here) invocation of arch_do_domctl() is being re-used.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Acked-by: Julien Grall <julien@xen.org>
|
||||
|
||||
--- a/xen/arch/arm/domctl.c
|
||||
+++ b/xen/arch/arm/domctl.c
|
||||
@@ -104,7 +104,7 @@ long arch_do_domctl(struct xen_domctl *d
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
- rc = xsm_bind_pt_irq(XSM_HOOK, d, bind);
|
||||
+ rc = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
@@ -140,7 +140,7 @@ long arch_do_domctl(struct xen_domctl *d
|
||||
if ( irq != virq )
|
||||
return -EINVAL;
|
||||
|
||||
- rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
|
||||
+ rc = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -575,7 +575,7 @@ long arch_do_domctl(
|
||||
if ( !is_hvm_domain(d) )
|
||||
break;
|
||||
|
||||
- ret = xsm_bind_pt_irq(XSM_HOOK, d, bind);
|
||||
+ ret = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
|
||||
if ( ret )
|
||||
break;
|
||||
|
||||
@@ -613,7 +613,7 @@ long arch_do_domctl(
|
||||
if ( !is_hvm_domain(d) )
|
||||
break;
|
||||
|
||||
- ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
|
||||
+ ret = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
|
||||
if ( ret )
|
||||
break;
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -437,6 +437,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
}
|
||||
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
+ case XEN_DOMCTL_bind_pt_irq:
|
||||
+ case XEN_DOMCTL_unbind_pt_irq:
|
||||
ret = arch_do_domctl(op, d, u_domctl);
|
||||
goto domctl_out_unlock_domonly;
|
||||
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -168,13 +168,11 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
switch ( cmd )
|
||||
{
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
- case XEN_DOMCTL_unbind_pt_irq:
|
||||
- return xsm_default_action(XSM_DM_PRIV, current->domain, d);
|
||||
-
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
+ case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -541,14 +539,14 @@ static XSM_INLINE int cf_check xsm_unmap
|
||||
static XSM_INLINE int cf_check xsm_bind_pt_irq(
|
||||
XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_DM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
static XSM_INLINE int cf_check xsm_unbind_pt_irq(
|
||||
XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_DM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -683,10 +683,12 @@ static int cf_check flask_domctl(struct
|
||||
return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
|
||||
|
||||
/* These have individual XSM hooks and don't make it here. */
|
||||
+ case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
+ case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -697,9 +699,6 @@ static int cf_check flask_domctl(struct
|
||||
case XEN_DOMCTL_set_target:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
|
||||
- /* These have individual XSM hooks (arch/../domctl.c) */
|
||||
- case XEN_DOMCTL_bind_pt_irq:
|
||||
- case XEN_DOMCTL_unbind_pt_irq:
|
||||
#ifdef CONFIG_X86
|
||||
/* These have individual XSM hooks (arch/x86/domctl.c) */
|
||||
case XEN_DOMCTL_shadow_op:
|
||||
172
xsa492-4.21-12.patch
Normal file
172
xsa492-4.21-12.patch
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_io{mem,port}_permission without acquiring domctl lock
|
||||
|
||||
With dedicated locking added, the domctl lock isn't required here anymore.
|
||||
As the I/O port handling is in arch-specific code (x86 only), no code is
|
||||
being moved, but the 2nd invocation of arch_do_domctl() is re-used. Move
|
||||
the re-purposed dedicated XSM checks as early as possible.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -233,12 +233,17 @@ long arch_do_domctl(
|
||||
unsigned int np = domctl->u.ioport_permission.nr_ports;
|
||||
int allow = domctl->u.ioport_permission.allow_access;
|
||||
|
||||
+ ret = -EINVAL;
|
||||
+ if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
|
||||
+ break;
|
||||
+
|
||||
+ ret = xsm_ioport_permission(XSM_PRIV, d, fp, fp + np - 1, allow);
|
||||
+ if ( ret )
|
||||
+ break;
|
||||
+
|
||||
iocaps_double_lock(d, true);
|
||||
|
||||
- if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
|
||||
- ret = -EINVAL;
|
||||
- else if ( !ioports_access_permitted(currd, fp, fp + np - 1) ||
|
||||
- xsm_ioport_permission(XSM_HOOK, d, fp, fp + np - 1, allow) )
|
||||
+ if ( !ioports_access_permitted(currd, fp, fp + np - 1) )
|
||||
ret = -EPERM;
|
||||
else if ( allow )
|
||||
ret = ioports_permit_access(d, fp, fp + np - 1);
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -376,6 +376,34 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
copyback = true;
|
||||
goto domctl_out_unlock_domonly;
|
||||
|
||||
+ case XEN_DOMCTL_iomem_permission:
|
||||
+ {
|
||||
+ unsigned long mfn = op->u.iomem_permission.first_mfn;
|
||||
+ unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
|
||||
+ bool allow = op->u.iomem_permission.allow_access;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ if ( (mfn + nr_mfns - 1) < mfn ) /* Wrap? */
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ ret = xsm_iomem_permission(XSM_PRIV, d, mfn, mfn + nr_mfns - 1, allow);
|
||||
+ if ( ret )
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
+ if ( !iomem_access_permitted(current->domain,
|
||||
+ mfn, mfn + nr_mfns - 1) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( allow )
|
||||
+ ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
|
||||
+ else
|
||||
+ ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+ }
|
||||
+
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
{
|
||||
unsigned long gfn = op->u.memory_mapping.first_gfn;
|
||||
@@ -436,6 +464,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
goto domctl_out_unlock_domonly;
|
||||
}
|
||||
|
||||
+ case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
@@ -777,31 +806,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
}
|
||||
#endif
|
||||
|
||||
- case XEN_DOMCTL_iomem_permission:
|
||||
- {
|
||||
- unsigned long mfn = op->u.iomem_permission.first_mfn;
|
||||
- unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
|
||||
- int allow = op->u.iomem_permission.allow_access;
|
||||
-
|
||||
- ret = -EINVAL;
|
||||
- if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
|
||||
- break;
|
||||
-
|
||||
- iocaps_double_lock(d, true);
|
||||
-
|
||||
- if ( !iomem_access_permitted(current->domain,
|
||||
- mfn, mfn + nr_mfns - 1) ||
|
||||
- xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) )
|
||||
- ret = -EPERM;
|
||||
- else if ( allow )
|
||||
- ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
|
||||
- else
|
||||
- ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
|
||||
-
|
||||
- iocaps_double_unlock(d, true);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
case XEN_DOMCTL_settimeoffset:
|
||||
domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
|
||||
break;
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -170,7 +170,9 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_iomem_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
+ case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
@@ -567,7 +569,7 @@ static XSM_INLINE int cf_check xsm_irq_p
|
||||
static XSM_INLINE int cf_check xsm_iomem_permission(
|
||||
XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
@@ -763,7 +765,7 @@ static XSM_INLINE int cf_check xsm_priv_
|
||||
static XSM_INLINE int cf_check xsm_ioport_permission(
|
||||
XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -686,7 +686,9 @@ static int cf_check flask_domctl(struct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_iomem_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
+ case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
@@ -695,14 +697,12 @@ static int cf_check flask_domctl(struct
|
||||
/* These have individual XSM hooks (common/domctl.c) */
|
||||
case XEN_DOMCTL_scheduler_op:
|
||||
case XEN_DOMCTL_irq_permission:
|
||||
- case XEN_DOMCTL_iomem_permission:
|
||||
case XEN_DOMCTL_set_target:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
/* These have individual XSM hooks (arch/x86/domctl.c) */
|
||||
case XEN_DOMCTL_shadow_op:
|
||||
- case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_gsi_permission:
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_PASSTHROUGH
|
||||
163
xsa492-4.21-13.patch
Normal file
163
xsa492-4.21-13.patch
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl: handle XEN_DOMCTL_{irq,gsi}_permission without acquiring domctl lock
|
||||
|
||||
With dedicated locking added, the domctl lock isn't required here anymore.
|
||||
As the GSI handling is in arch-specific code (x86 only), no code is being
|
||||
moved there; the 2nd invocation of arch_do_domctl() is re-used. Move the
|
||||
re-purposed (XSM_HOOK -> XSM_PRIV, as xsm_domctl() is now bypassed)
|
||||
dedicated XSM checks as early as possible.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -272,10 +272,13 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
+ ret = xsm_irq_permission(XSM_PRIV, d, irq, flags);
|
||||
+ if ( ret )
|
||||
+ break;
|
||||
+
|
||||
iocaps_double_lock(d, true);
|
||||
|
||||
- if ( !irq_access_permitted(currd, irq) ||
|
||||
- xsm_irq_permission(XSM_HOOK, d, irq, flags) )
|
||||
+ if ( !irq_access_permitted(currd, irq) )
|
||||
ret = -EPERM;
|
||||
else if ( flags )
|
||||
ret = irq_permit_access(d, irq);
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -464,8 +464,41 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
goto domctl_out_unlock_domonly;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_HAS_PIRQ
|
||||
+ case XEN_DOMCTL_irq_permission:
|
||||
+ {
|
||||
+ unsigned int pirq = op->u.irq_permission.pirq, irq;
|
||||
+ bool allow = op->u.irq_permission.allow_access;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ if ( pirq >= current->domain->nr_pirqs )
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ irq = domain_pirq_to_irq(current->domain, pirq);
|
||||
+
|
||||
+ ret = -EPERM;
|
||||
+ if ( irq )
|
||||
+ ret = xsm_irq_permission(XSM_PRIV, d, irq, allow);
|
||||
+ if ( ret )
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+
|
||||
+ iocaps_double_lock(d, true);
|
||||
+
|
||||
+ if ( !irq_access_permitted(current->domain, irq) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( allow )
|
||||
+ ret = irq_permit_access(d, irq);
|
||||
+ else
|
||||
+ ret = irq_deny_access(d, irq);
|
||||
+
|
||||
+ iocaps_double_unlock(d, true);
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
+ case XEN_DOMCTL_gsi_permission:
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
ret = arch_do_domctl(op, d, u_domctl);
|
||||
@@ -779,33 +812,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
}
|
||||
break;
|
||||
|
||||
-#ifdef CONFIG_HAS_PIRQ
|
||||
- case XEN_DOMCTL_irq_permission:
|
||||
- {
|
||||
- unsigned int pirq = op->u.irq_permission.pirq, irq;
|
||||
- int allow = op->u.irq_permission.allow_access;
|
||||
-
|
||||
- if ( pirq >= current->domain->nr_pirqs )
|
||||
- {
|
||||
- ret = -EINVAL;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- iocaps_double_lock(d, true);
|
||||
-
|
||||
- irq = pirq_access_permitted(current->domain, pirq);
|
||||
- if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) )
|
||||
- ret = -EPERM;
|
||||
- else if ( allow )
|
||||
- ret = irq_permit_access(d, irq);
|
||||
- else
|
||||
- ret = irq_deny_access(d, irq);
|
||||
-
|
||||
- iocaps_double_unlock(d, true);
|
||||
- break;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
case XEN_DOMCTL_settimeoffset:
|
||||
domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
|
||||
break;
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -170,9 +170,11 @@ static XSM_INLINE int cf_check xsm_domct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_gsi_permission:
|
||||
case XEN_DOMCTL_iomem_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_ioport_permission:
|
||||
+ case XEN_DOMCTL_irq_permission:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
@@ -562,7 +564,7 @@ static XSM_INLINE int cf_check xsm_unmap
|
||||
static XSM_INLINE int cf_check xsm_irq_permission(
|
||||
XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow)
|
||||
{
|
||||
- XSM_ASSERT_ACTION(XSM_HOOK);
|
||||
+ XSM_ASSERT_ACTION(XSM_PRIV);
|
||||
return xsm_default_action(action, current->domain, d);
|
||||
}
|
||||
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -686,9 +686,11 @@ static int cf_check flask_domctl(struct
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_get_domain_state:
|
||||
+ case XEN_DOMCTL_gsi_permission:
|
||||
case XEN_DOMCTL_iomem_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_ioport_permission:
|
||||
+ case XEN_DOMCTL_irq_permission:
|
||||
case XEN_DOMCTL_memory_mapping:
|
||||
case XEN_DOMCTL_unbind_pt_irq:
|
||||
ASSERT_UNREACHABLE();
|
||||
@@ -696,14 +698,12 @@ static int cf_check flask_domctl(struct
|
||||
|
||||
/* These have individual XSM hooks (common/domctl.c) */
|
||||
case XEN_DOMCTL_scheduler_op:
|
||||
- case XEN_DOMCTL_irq_permission:
|
||||
case XEN_DOMCTL_set_target:
|
||||
case XEN_DOMCTL_vm_event_op:
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
/* These have individual XSM hooks (arch/x86/domctl.c) */
|
||||
case XEN_DOMCTL_shadow_op:
|
||||
- case XEN_DOMCTL_gsi_permission:
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_PASSTHROUGH
|
||||
/*
|
||||
179
xsa492-4.21-14.patch
Normal file
179
xsa492-4.21-14.patch
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl/XSM: drop vm_event_control hook
|
||||
|
||||
Integrate the checking with xsm_domctl(). Care needs to be taken with the
|
||||
GET_VERSION sub-op, which may be invoked with DOMID_INVALID, and which has
|
||||
been (and continues to be) bypassing XSM checking.
|
||||
|
||||
Since the latter two parameters were unused, monitor_domctl() invoking the
|
||||
hook was actually redundant with the earlier xsm_domctl() (as can be seen
|
||||
nicely from the hunks changing xsm/flask/hooks.c).
|
||||
|
||||
As a positive side effect, permissions are then checked at the same early
|
||||
point with and without Flask.
|
||||
|
||||
While folding XEN_DOMCTL_monitor_op and XEN_DOMCTL_vm_event_op in
|
||||
flask_domctl(), also fold in XEN_DOMCTL_set_access_required.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -496,6 +496,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
}
|
||||
#endif
|
||||
|
||||
+ case XEN_DOMCTL_vm_event_op:
|
||||
+ if ( op->u.vm_event_op.op == XEN_VM_EVENT_GET_VERSION )
|
||||
+ {
|
||||
+ /* No XSM check (and potentially d == NULL) here. */
|
||||
+ ret = vm_event_domctl(d, &op->u.vm_event_op);
|
||||
+ if ( !ret )
|
||||
+ copyback = true;
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+ }
|
||||
+ if ( !d )
|
||||
+ {
|
||||
+ ret = -ESRCH;
|
||||
+ goto domctl_out_unlock_domonly;
|
||||
+ }
|
||||
+ /* Other sub-ops handled further down. */
|
||||
+ break;
|
||||
+
|
||||
case XEN_DOMCTL_ioport_permission:
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
case XEN_DOMCTL_gsi_permission:
|
||||
--- a/xen/common/monitor.c
|
||||
+++ b/xen/common/monitor.c
|
||||
@@ -30,16 +30,11 @@
|
||||
|
||||
int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
|
||||
{
|
||||
- int rc;
|
||||
bool requested_status = false;
|
||||
|
||||
if ( unlikely(current->domain == d) ) /* no domain_pause() */
|
||||
return -EPERM;
|
||||
|
||||
- rc = xsm_vm_event_control(XSM_PRIV, d, mop->op, mop->event);
|
||||
- if ( unlikely(rc) )
|
||||
- return rc;
|
||||
-
|
||||
switch ( mop->op )
|
||||
{
|
||||
case XEN_DOMCTL_MONITOR_OP_ENABLE:
|
||||
--- a/xen/common/vm_event.c
|
||||
+++ b/xen/common/vm_event.c
|
||||
@@ -603,11 +603,10 @@ int vm_event_domctl(struct domain *d, st
|
||||
|
||||
/* All other subops need to target a real domain. */
|
||||
if ( unlikely(d == NULL) )
|
||||
- return -ESRCH;
|
||||
-
|
||||
- rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
|
||||
- if ( rc )
|
||||
- return rc;
|
||||
+ {
|
||||
+ ASSERT_UNREACHABLE();
|
||||
+ return -EILSEQ;
|
||||
+ }
|
||||
|
||||
if ( unlikely(d == current->domain) ) /* no domain_pause() */
|
||||
{
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -652,13 +652,6 @@ static XSM_INLINE int cf_check xsm_hvm_a
|
||||
}
|
||||
}
|
||||
|
||||
-static XSM_INLINE int cf_check xsm_vm_event_control(
|
||||
- XSM_DEFAULT_ARG struct domain *d, int mode, int op)
|
||||
-{
|
||||
- XSM_ASSERT_ACTION(XSM_PRIV);
|
||||
- return xsm_default_action(action, current->domain, d);
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
static XSM_INLINE int cf_check xsm_mem_access(XSM_DEFAULT_ARG struct domain *d)
|
||||
{
|
||||
--- a/xen/include/xsm/xsm.h
|
||||
+++ b/xen/include/xsm/xsm.h
|
||||
@@ -157,8 +157,6 @@ struct xsm_ops {
|
||||
int (*hvm_altp2mhvm_op)(struct domain *d, uint64_t mode, uint32_t op);
|
||||
int (*get_vnumainfo)(struct domain *d);
|
||||
|
||||
- int (*vm_event_control)(struct domain *d, int mode, int op);
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
int (*mem_access)(struct domain *d);
|
||||
#endif
|
||||
@@ -657,12 +655,6 @@ static inline int xsm_get_vnumainfo(xsm_
|
||||
return alternative_call(xsm_ops.get_vnumainfo, d);
|
||||
}
|
||||
|
||||
-static inline int xsm_vm_event_control(
|
||||
- xsm_default_t def, struct domain *d, int mode, int op)
|
||||
-{
|
||||
- return alternative_call(xsm_ops.vm_event_control, d, mode, op);
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
static inline int xsm_mem_access(xsm_default_t def, struct domain *d)
|
||||
{
|
||||
--- a/xen/xsm/dummy.c
|
||||
+++ b/xen/xsm/dummy.c
|
||||
@@ -116,8 +116,6 @@ static const struct xsm_ops __initconst_
|
||||
.remove_from_physmap = xsm_remove_from_physmap,
|
||||
.map_gmfn_foreign = xsm_map_gmfn_foreign,
|
||||
|
||||
- .vm_event_control = xsm_vm_event_control,
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
.mem_access = xsm_mem_access,
|
||||
#endif
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -699,7 +699,6 @@ static int cf_check flask_domctl(struct
|
||||
/* These have individual XSM hooks (common/domctl.c) */
|
||||
case XEN_DOMCTL_scheduler_op:
|
||||
case XEN_DOMCTL_set_target:
|
||||
- case XEN_DOMCTL_vm_event_op:
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
/* These have individual XSM hooks (arch/x86/domctl.c) */
|
||||
@@ -793,9 +792,8 @@ static int cf_check flask_domctl(struct
|
||||
return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER);
|
||||
|
||||
case XEN_DOMCTL_set_access_required:
|
||||
- return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
|
||||
-
|
||||
case XEN_DOMCTL_monitor_op:
|
||||
+ case XEN_DOMCTL_vm_event_op:
|
||||
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
|
||||
|
||||
case XEN_DOMCTL_debug_op:
|
||||
@@ -1368,11 +1366,6 @@ static int cf_check flask_hvm_altp2mhvm_
|
||||
return current_has_perm(d, SECCLASS_HVM, HVM__ALTP2MHVM_OP);
|
||||
}
|
||||
|
||||
-static int cf_check flask_vm_event_control(struct domain *d, int mode, int op)
|
||||
-{
|
||||
- return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
static int cf_check flask_mem_access(struct domain *d)
|
||||
{
|
||||
@@ -1971,8 +1964,6 @@ static const struct xsm_ops __initconst_
|
||||
.do_xsm_op = do_flask_op,
|
||||
.get_vnumainfo = flask_get_vnumainfo,
|
||||
|
||||
- .vm_event_control = flask_vm_event_control,
|
||||
-
|
||||
#ifdef CONFIG_VM_EVENT
|
||||
.mem_access = flask_mem_access,
|
||||
#endif
|
||||
108
xsa492-4.21-15.patch
Normal file
108
xsa492-4.21-15.patch
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: domctl/XSM: pass full struct xen_domctl to xsm_domctl()
|
||||
|
||||
Subsequently some sub-ops will want to inspect their sub-sub-ops. Plus
|
||||
this way we don't need to pass SSIDref separately anymore for
|
||||
domain_create.
|
||||
|
||||
This is part of XSA-492.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/paging.c
|
||||
+++ b/xen/arch/x86/mm/paging.c
|
||||
@@ -735,7 +735,7 @@ long do_paging_domctl_cont(
|
||||
if ( d == NULL )
|
||||
return -ESRCH;
|
||||
|
||||
- ret = xsm_domctl(XSM_OTHER, d, op.cmd, 0 /* SSIDref not applicable */);
|
||||
+ ret = xsm_domctl(XSM_OTHER, d, &op);
|
||||
if ( !ret )
|
||||
{
|
||||
if ( domctl_lock_acquire() )
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -526,9 +526,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
|
||||
break;
|
||||
}
|
||||
|
||||
- ret = xsm_domctl(XSM_OTHER, d, op->cmd,
|
||||
- /* SSIDRef only applicable for cmd == createdomain */
|
||||
- op->u.createdomain.ssidref);
|
||||
+ ret = xsm_domctl(XSM_OTHER, d, op);
|
||||
if ( ret )
|
||||
goto domctl_out_unlock_domonly;
|
||||
|
||||
--- a/xen/include/xsm/dummy.h
|
||||
+++ b/xen/include/xsm/dummy.h
|
||||
@@ -162,10 +162,10 @@ static XSM_INLINE int cf_check xsm_set_t
|
||||
}
|
||||
|
||||
static XSM_INLINE int cf_check xsm_domctl(
|
||||
- XSM_DEFAULT_ARG struct domain *d, unsigned int cmd, uint32_t ssidref)
|
||||
+ XSM_DEFAULT_ARG struct domain *d, struct xen_domctl *op)
|
||||
{
|
||||
XSM_ASSERT_ACTION(XSM_OTHER);
|
||||
- switch ( cmd )
|
||||
+ switch ( op->cmd )
|
||||
{
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
--- a/xen/include/xsm/xsm.h
|
||||
+++ b/xen/include/xsm/xsm.h
|
||||
@@ -61,7 +61,7 @@ struct xsm_ops {
|
||||
int (*sysctl_scheduler_op)(int op);
|
||||
#endif
|
||||
int (*set_target)(struct domain *d, struct domain *e);
|
||||
- int (*domctl)(struct domain *d, unsigned int cmd, uint32_t ssidref);
|
||||
+ int (*domctl)(struct domain *d, struct xen_domctl *op);
|
||||
int (*sysctl)(int cmd);
|
||||
int (*readconsole)(uint32_t clear);
|
||||
|
||||
@@ -260,9 +260,9 @@ static inline int xsm_set_target(
|
||||
}
|
||||
|
||||
static inline int xsm_domctl(xsm_default_t def, struct domain *d,
|
||||
- unsigned int cmd, uint32_t ssidref)
|
||||
+ struct xen_domctl *op)
|
||||
{
|
||||
- return alternative_call(xsm_ops.domctl, d, cmd, ssidref);
|
||||
+ return alternative_call(xsm_ops.domctl, d, op);
|
||||
}
|
||||
|
||||
static inline int xsm_sysctl(xsm_default_t def, int cmd)
|
||||
--- a/xen/xsm/flask/hooks.c
|
||||
+++ b/xen/xsm/flask/hooks.c
|
||||
@@ -667,10 +667,9 @@ static int cf_check flask_set_target(str
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int cf_check flask_domctl(struct domain *d, unsigned int cmd,
|
||||
- uint32_t ssidref)
|
||||
+static int cf_check flask_domctl(struct domain *d, struct xen_domctl *op)
|
||||
{
|
||||
- switch ( cmd )
|
||||
+ switch ( op->cmd )
|
||||
{
|
||||
case XEN_DOMCTL_createdomain:
|
||||
/*
|
||||
@@ -680,7 +679,8 @@ static int cf_check flask_domctl(struct
|
||||
* Note that d is NULL because we haven't even allocated memory for it
|
||||
* this early in XEN_DOMCTL_createdomain.
|
||||
*/
|
||||
- return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
|
||||
+ return avc_current_has_perm(op->u.createdomain.ssidref, SECCLASS_DOMAIN,
|
||||
+ DOMAIN__CREATE, NULL);
|
||||
|
||||
/* These have individual XSM hooks and don't make it here. */
|
||||
case XEN_DOMCTL_bind_pt_irq:
|
||||
@@ -855,7 +855,7 @@ static int cf_check flask_domctl(struct
|
||||
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_LLC_COLORS);
|
||||
|
||||
default:
|
||||
- return avc_unknown_permission("domctl", cmd);
|
||||
+ return avc_unknown_permission("domctl", op->cmd);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue