Compare commits

..

4 Commits

Author SHA1 Message Date
Marek Marczykowski-Górecki ad69c41ae9 version 3.19.3-4
9 years ago
Marek Marczykowski-Górecki 2cc7eac615 Disable Xen memory hotplug
9 years ago
Marek Marczykowski-Górecki cce68315d9 version 3.19.3-3
9 years ago
Marek Marczykowski-Górecki 624ecc4657 Update to 3.19.3, config changes
9 years ago

6
.gitignore vendored

@ -1,8 +1,4 @@
linux-*.tar.gz
linux-*.tar.bz2
linux-*.tar.xz
linux-*.sign
WireGuard-*.tar.xz
WireGuard-*.tar.asc
kernel-*/
config-base-*
macbook12-spi-driver-*.tar.gz

@ -1,38 +0,0 @@
From a6b3add4337101ef875423c0888b8ac1cde47c2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Thu, 6 Sep 2018 15:09:44 +0200
Subject: [PATCH] xen-netfront-detach-crash
When it get to free_page(queue->grant_tx_page[i]), the use counter on this page
is already 0, which cause a crash. Not sure if this is the proper fix
(according to git log this may introduce some memory leak), but at least it
prevent the crash.
Details in this thread:
http://xen.markmail.org/thread/pw5edbtqienjx4q5
---
drivers/net/xen-netfront.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 482c6c8b0fb7..8f0a790ec5e7 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1138,9 +1138,10 @@ static void xennet_release_tx_bufs(struct netfront_queue *queue)
skb = queue->tx_skbs[i].skb;
get_page(queue->grant_tx_page[i]);
- gnttab_end_foreign_access(queue->grant_tx_ref[i],
- GNTMAP_readonly,
- (unsigned long)page_address(queue->grant_tx_page[i]));
+ gnttab_end_foreign_access_ref(
+ queue->grant_tx_ref[i], GNTMAP_readonly);
+ gnttab_release_grant_reference(
+ &queue->gref_tx_head, queue->grant_tx_ref[i]);
queue->grant_tx_page[i] = NULL;
queue->grant_tx_ref[i] = GRANT_INVALID_REF;
add_id_to_freelist(&queue->tx_skb_freelist, queue->tx_skbs, i);
--
2.21.0

@ -1,70 +0,0 @@
From a58197258286cf8dce45cf03b3b2b436b3cf8a99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 5 Jan 2016 02:44:04 +0100
Subject: [PATCH] mce: hide EBUSY initialization error on Xen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case of Xen, the device is already registered by xen mcelog (in
xen_late_init_mcelog), so fail here is expected. Note that
mcheck_init_device call is still expected to initialize mce_device. Comment
from threshold_init_device explaining the situation:
/*
* there are 3 funcs which need to be _initcalled in a logic sequence:
* 1. xen_late_init_mcelog
* 2. mcheck_init_device
* 3. threshold_init_device
*
* xen_late_init_mcelog must register xen_mce_chrdev_device before
* native mce_chrdev_device registration if running under xen platform;
*
* mcheck_init_device should be inited before threshold_init_device to
* initialize mce_device, otherwise a NULL ptr dereference will cause panic.
*
* so we use following _initcalls
* 1. device_initcall(xen_late_init_mcelog);
* 2. device_initcall_sync(mcheck_init_device);
* 3. late_initcall(threshold_init_device);
*
* when running under xen, the initcall order is 1,2,3;
* on baremetal, we skip 1 and we do only 2 and 3.
*/
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
arch/x86/kernel/cpu/mce/core.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 743370ee4983..3af7521b2279 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -51,6 +51,10 @@
#include <asm/msr.h>
#include <asm/reboot.h>
+#ifdef CONFIG_XEN_MCE_LOG
+#include <xen/xen.h>
+#endif
+
#include "internal.h"
static DEFINE_MUTEX(mce_log_mutex);
@@ -2464,6 +2468,11 @@ static __init int mcheck_init_device(void)
free_cpumask_var(mce_device_initialized);
err_out:
+#ifdef CONFIG_XEN_MCE_LOG
+ /* in case of Xen, the character device was already registered, so do not
+ * treat this as an error */
+ if (!xen_initial_domain() || err != -EBUSY)
+#endif
pr_err("Unable to init MCE device (rc: %d)\n", err);
return err;
--
2.21.0

@ -1,27 +0,0 @@
From da15c0c3af84be25fdd695dddf61524099f4322e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Sat, 30 Jan 2016 01:53:26 +0100
Subject: [PATCH] Log error code of EVTCHNOP_bind_pirq failure
Ease debugging of PCI passthrough problems.
---
drivers/xen/events/events_base.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 6c8843968a52..54d2e30683c4 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -522,7 +522,7 @@ static unsigned int __startup_pirq(unsigned int irq)
BIND_PIRQ__WILL_SHARE : 0;
rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
if (rc != 0) {
- pr_warn("Failed to obtain physical IRQ %d\n", irq);
+ pr_warn("Failed to obtain physical IRQ %d (error %d)\n", irq, rc);
return 0;
}
evtchn = bind_pirq.port;
--
2.21.0

@ -1,39 +0,0 @@
From 1b9928a04716a54933dcaff9ec7e68323f58090b Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Mon, 11 Jun 2012 22:49:31 +0200
Subject: [PATCH] pvops: respect 'removable' xenstore flag for block devices
Especially this is needed by pmount to allow mount qvm-block attached devices
by normal user.
---
drivers/block/xen-blkfront.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index a74d03913822..e76b999fceca 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -2339,6 +2339,7 @@ static void blkfront_connect(struct blkfront_info *info)
unsigned int binfo;
char *envp[] = { "RESIZE=1", NULL };
int err, i;
+ int removable;
switch (info->connected) {
case BLKIF_STATE_CONNECTED:
@@ -2406,6 +2407,12 @@ static void blkfront_connect(struct blkfront_info *info)
}
}
+ err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+ "removable", "%d", &removable,
+ NULL);
+ if (!err && removable)
+ binfo |= VDISK_REMOVABLE;
+
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size,
physical_sector_size);
if (err) {
--
2.21.0

@ -1,34 +0,0 @@
From 61d8059c42eaf388b857e0d5c8460ccb76c2f97c Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Sun, 15 Jul 2012 19:57:47 +0200
Subject: [PATCH] pvops/xen-blkfront: handle FDEJECT as detach request (#630)
---
drivers/block/xen-blkfront.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index e76b999fceca..db7d28ac9747 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -47,6 +47,7 @@
#include <linux/bitmap.h>
#include <linux/list.h>
#include <linux/workqueue.h>
+#include <linux/fd.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -511,6 +512,9 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
return 0;
return -EINVAL;
}
+ case FDEJECT:
+ xenbus_switch_state(info->xbdev, XenbusStateClosing);
+ return 0;
default:
/*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
--
2.21.0

@ -1,49 +0,0 @@
From 56ce69a0260413418c2845182aa93165c4a1ce42 Mon Sep 17 00:00:00 2001
From: Rusty Bird <rustybird@openmailbox.org>
Date: Mon, 11 Jul 2016 13:05:38 +0000
Subject: [PATCH] block: add no_part_scan module parameter
Define a boolean module parameter named "no_part_scan" defaulting to N,
which, if set to Y, always causes the GENHD_FL_NO_PART_SCAN flag to be
added to subsequently created block devices, thereby disabling the
kernel's various partition table parsers for them.
The parameter's current value can be changed at any time by writing to
the /sys/module/block/parameters/no_part_scan file.
---
block/genhd.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/block/genhd.c b/block/genhd.c
index 26b31fcae217..75993c12e123 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -676,6 +676,15 @@ static void register_disk(struct device *parent, struct gendisk *disk,
}
}
+/* copied (not moved) from far down below, to have fewer patch hunks */
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "block."
+
+/* partition scanning policy */
+static bool disk_no_part_scan = 0;
+module_param_named(no_part_scan, disk_no_part_scan, bool, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(no_part_scan, "When adding block devices, always mark them as not to be scanned for partitions");
+
/**
* __device_add_disk - add disk information to kernel list
* @parent: parent device for the disk
@@ -704,6 +713,9 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
if (register_queue)
elevator_init_mq(disk->queue);
+ if (disk_no_part_scan)
+ disk->flags |= GENHD_FL_NO_PART_SCAN;
+
/* minors == 0 indicates to use ext devt from part0 and should
* be accompanied with EXT_DEVT flag. Make sure all
* parameters make sense.
--
2.21.0

@ -1,58 +0,0 @@
From 76c089d06f5ff8dc7a54c3e5ef7d2f1447ca8ec4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Tue, 15 Dec 2015 21:35:14 +0100
Subject: [PATCH] xen: Add RING_COPY_RESPONSE()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Using RING_GET_RESPONSE() on a shared ring is easy to use incorrectly
(i.e., by not considering that the other end may alter the data in the
shared ring while it is being inspected). Safe usage of a response
generally requires taking a local copy.
Provide a RING_COPY_RESPONSE() macro to use instead of
RING_GET_RESPONSE() and an open-coded memcpy(). This takes care of
ensuring that the copy is done correctly regardless of any possible
compiler optimizations.
Use a volatile source to prevent the compiler from reordering or
omitting the copy.
This is part of XSA155.
CC: stable@vger.kernel.org
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
include/xen/interface/io/ring.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index 3f40501fc60b..03702f6874df 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -201,6 +201,20 @@ struct __name##_back_ring { \
#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
+/*
+ * Get a local copy of a response.
+ *
+ * Use this in preference to RING_GET_RESPONSE() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _rsp is a struct which consists of only bitfields.
+ */
+#define RING_COPY_RESPONSE(_r, _idx, _rsp) do { \
+ /* Use volatile to force the copy into _rsp. */ \
+ *(_rsp) = *(volatile typeof(_rsp))RING_GET_RESPONSE(_r, _idx); \
+} while (0)
+
/* Loop termination condition: Would the specified index overflow the ring? */
#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
(((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
--
2.21.0

@ -1,177 +0,0 @@
From 688769df7c2365ae836eb755ccf5b196b45cbd56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 16 Dec 2015 05:09:55 +0100
Subject: [PATCH] xen-netfront: copy response out of shared buffer before
accessing it
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Make local copy of the response, otherwise backend might modify it while
frontend is already processing it - leading to time of check / time of
use issue.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/net/xen-netfront.c | 51 +++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 26 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 8f0a790ec5e7..abb9b3cd87b8 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -385,13 +385,13 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
rmb(); /* Ensure we see responses up to 'rp'. */
for (cons = queue->tx.rsp_cons; cons != prod; cons++) {
- struct xen_netif_tx_response *txrsp;
+ struct xen_netif_tx_response txrsp;
- txrsp = RING_GET_RESPONSE(&queue->tx, cons);
- if (txrsp->status == XEN_NETIF_RSP_NULL)
+ RING_COPY_RESPONSE(&queue->tx, cons, &txrsp);
+ if (txrsp.status == XEN_NETIF_RSP_NULL)
continue;
- id = txrsp->id;
+ id = txrsp.id;
skb = queue->tx_skbs[id].skb;
if (unlikely(gnttab_query_foreign_access(
queue->grant_tx_ref[id]) != 0)) {
@@ -739,7 +739,7 @@ static int xennet_get_extras(struct netfront_queue *queue,
RING_IDX rp)
{
- struct xen_netif_extra_info *extra;
+ struct xen_netif_extra_info extra;
struct device *dev = &queue->info->netdev->dev;
RING_IDX cons = queue->rx.rsp_cons;
int err = 0;
@@ -755,24 +755,23 @@ static int xennet_get_extras(struct netfront_queue *queue,
break;
}
- extra = (struct xen_netif_extra_info *)
- RING_GET_RESPONSE(&queue->rx, ++cons);
+ RING_COPY_RESPONSE(&queue->rx, ++cons, &extra);
- if (unlikely(!extra->type ||
- extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+ if (unlikely(!extra.type ||
+ extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
if (net_ratelimit())
dev_warn(dev, "Invalid extra type: %d\n",
- extra->type);
+ extra.type);
err = -EINVAL;
} else {
- memcpy(&extras[extra->type - 1], extra,
- sizeof(*extra));
+ memcpy(&extras[extra.type - 1], &extra,
+ sizeof(extra));
}
skb = xennet_get_rx_skb(queue, cons);
ref = xennet_get_rx_ref(queue, cons);
xennet_move_rx_slot(queue, skb, ref);
- } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+ } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
queue->rx.rsp_cons = cons;
return err;
@@ -782,28 +781,28 @@ static int xennet_get_responses(struct netfront_queue *queue,
struct netfront_rx_info *rinfo, RING_IDX rp,
struct sk_buff_head *list)
{
- struct xen_netif_rx_response *rx = &rinfo->rx;
+ struct xen_netif_rx_response rx = rinfo->rx;
struct xen_netif_extra_info *extras = rinfo->extras;
struct device *dev = &queue->info->netdev->dev;
RING_IDX cons = queue->rx.rsp_cons;
struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
grant_ref_t ref = xennet_get_rx_ref(queue, cons);
- int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
+ int max = XEN_NETIF_NR_SLOTS_MIN + (rx.status <= RX_COPY_THRESHOLD);
int slots = 1;
int err = 0;
unsigned long ret;
- if (rx->flags & XEN_NETRXF_extra_info) {
+ if (rx.flags & XEN_NETRXF_extra_info) {
err = xennet_get_extras(queue, extras, rp);
cons = queue->rx.rsp_cons;
}
for (;;) {
- if (unlikely(rx->status < 0 ||
- rx->offset + rx->status > XEN_PAGE_SIZE)) {
+ if (unlikely(rx.status < 0 ||
+ rx.offset + rx.status > XEN_PAGE_SIZE)) {
if (net_ratelimit())
dev_warn(dev, "rx->offset: %u, size: %d\n",
- rx->offset, rx->status);
+ rx.offset, rx.status);
xennet_move_rx_slot(queue, skb, ref);
err = -EINVAL;
goto next;
@@ -817,7 +816,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
if (ref == GRANT_INVALID_REF) {
if (net_ratelimit())
dev_warn(dev, "Bad rx response id %d.\n",
- rx->id);
+ rx.id);
err = -EINVAL;
goto next;
}
@@ -830,7 +829,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
__skb_queue_tail(list, skb);
next:
- if (!(rx->flags & XEN_NETRXF_more_data))
+ if (!(rx.flags & XEN_NETRXF_more_data))
break;
if (cons + slots == rp) {
@@ -840,7 +839,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
break;
}
- rx = RING_GET_RESPONSE(&queue->rx, cons + slots);
+ RING_COPY_RESPONSE(&queue->rx, cons + slots, &rx);
skb = xennet_get_rx_skb(queue, cons + slots);
ref = xennet_get_rx_ref(queue, cons + slots);
slots++;
@@ -895,9 +894,9 @@ static int xennet_fill_frags(struct netfront_queue *queue,
struct sk_buff *nskb;
while ((nskb = __skb_dequeue(list))) {
- struct xen_netif_rx_response *rx =
- RING_GET_RESPONSE(&queue->rx, ++cons);
+ struct xen_netif_rx_response rx;
skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
+ RING_COPY_RESPONSE(&queue->rx, ++cons, &rx);
if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {
unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
@@ -913,7 +912,7 @@ static int xennet_fill_frags(struct netfront_queue *queue,
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
skb_frag_page(nfrag),
- rx->offset, rx->status, PAGE_SIZE);
+ rx.offset, rx.status, PAGE_SIZE);
skb_shinfo(nskb)->nr_frags = 0;
kfree_skb(nskb);
@@ -1011,7 +1010,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
i = queue->rx.rsp_cons;
work_done = 0;
while ((i != rp) && (work_done < budget)) {
- memcpy(rx, RING_GET_RESPONSE(&queue->rx, i), sizeof(*rx));
+ RING_COPY_RESPONSE(&queue->rx, i, rx);
memset(extras, 0, sizeof(rinfo.extras));
err = xennet_get_responses(queue, &rinfo, rp, &tmpq);
--
2.21.0

@ -1,64 +0,0 @@
From f2452d28602c2de1d69d5ca2e34e6771374414a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 16 Dec 2015 05:19:37 +0100
Subject: [PATCH] xen-netfront: do not use data already exposed to backend
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Backend may freely modify anything on shared page, so use data which was
supposed to be written there, instead of reading it back from the shared
page.
This is part of XSA155.
CC: stable@vger.kernel.org
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/net/xen-netfront.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index abb9b3cd87b8..56c8a4a32672 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -456,7 +456,7 @@ static void xennet_tx_setup_grant(unsigned long gfn, unsigned int offset,
tx->flags = 0;
info->tx = tx;
- info->size += tx->size;
+ info->size += len;
}
static struct xen_netif_tx_request *xennet_make_first_txreq(
@@ -572,7 +572,7 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
int slots;
struct page *page;
unsigned int offset;
- unsigned int len;
+ unsigned int len, this_len;
unsigned long flags;
struct netfront_queue *queue = NULL;
unsigned int num_queues = dev->real_num_tx_queues;
@@ -632,14 +632,15 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
}
/* First request for the linear area. */
+ this_len = min_t(unsigned int, XEN_PAGE_SIZE - offset, len);
first_tx = tx = xennet_make_first_txreq(queue, skb,
page, offset, len);
- offset += tx->size;
+ offset += this_len;
if (offset == PAGE_SIZE) {
page++;
offset = 0;
}
- len -= tx->size;
+ len -= this_len;
if (skb->ip_summed == CHECKSUM_PARTIAL)
/* local packet? */
--
2.21.0

@ -1,35 +0,0 @@
From b5bc80763b7bf0f9e32a9a4d4f930ff50d02385d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 16 Dec 2015 05:22:24 +0100
Subject: [PATCH] xen-netfront: add range check for Tx response id
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Tx response ID is fetched from shared page, so make sure it is sane
before using it as an array index.
This is part of XSA155.
CC: stable@vger.kernel.org
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/net/xen-netfront.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 56c8a4a32672..e11df925c0dc 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -392,6 +392,7 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
continue;
id = txrsp.id;
+ BUG_ON(id >= NET_TX_RING_SIZE);
skb = queue->tx_skbs[id].skb;
if (unlikely(gnttab_query_foreign_access(
queue->grant_tx_ref[id]) != 0)) {
--
2.21.0

@ -1,128 +0,0 @@
From def16082c5e64f97d5d138ae638a6cde7a136432 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 16 Dec 2015 05:51:10 +0100
Subject: [PATCH] xen-blkfront: make local copy of response before using it
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Data on the shared page can be changed at any time by the backend. Make
a local copy, which is no longer controlled by the backend. And only
then access it.
This is part of XSA155.
CC: stable@vger.kernel.org
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/block/xen-blkfront.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index db7d28ac9747..3f6dbaf0265b 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1551,7 +1551,7 @@ static bool blkif_completion(unsigned long *id,
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
{
struct request *req;
- struct blkif_response *bret;
+ struct blkif_response bret;
RING_IDX i, rp;
unsigned long flags;
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
@@ -1568,8 +1568,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
for (i = rinfo->ring.rsp_cons; i != rp; i++) {
unsigned long id;
- bret = RING_GET_RESPONSE(&rinfo->ring, i);
- id = bret->id;
+ RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
+ id = bret.id;
/*
* The backend has messed up and given us an id that we would
* never have given to it (we stamp it up to BLK_RING_SIZE -
@@ -1577,39 +1577,39 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
*/
if (id >= BLK_RING_SIZE(info)) {
WARN(1, "%s: response to %s has incorrect id (%ld)\n",
- info->gd->disk_name, op_name(bret->operation), id);
+ info->gd->disk_name, op_name(bret.operation), id);
/* We can't safely get the 'struct request' as
* the id is busted. */
continue;
}
req = rinfo->shadow[id].request;
- if (bret->operation != BLKIF_OP_DISCARD) {
+ if (bret.operation != BLKIF_OP_DISCARD) {
/*
* We may need to wait for an extra response if the
* I/O request is split in 2
*/
- if (!blkif_completion(&id, rinfo, bret))
+ if (!blkif_completion(&id, rinfo, &bret))
continue;
}
if (add_id_to_freelist(rinfo, id)) {
WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
- info->gd->disk_name, op_name(bret->operation), id);
+ info->gd->disk_name, op_name(bret.operation), id);
continue;
}
- if (bret->status == BLKIF_RSP_OKAY)
+ if (bret.status == BLKIF_RSP_OKAY)
blkif_req(req)->error = BLK_STS_OK;
else
blkif_req(req)->error = BLK_STS_IOERR;
- switch (bret->operation) {
+ switch (bret.operation) {
case BLKIF_OP_DISCARD:
- if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
+ if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
struct request_queue *rq = info->rq;
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
- info->gd->disk_name, op_name(bret->operation));
+ info->gd->disk_name, op_name(bret.operation));
blkif_req(req)->error = BLK_STS_NOTSUPP;
info->feature_discard = 0;
info->feature_secdiscard = 0;
@@ -1619,15 +1619,15 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
break;
case BLKIF_OP_FLUSH_DISKCACHE:
case BLKIF_OP_WRITE_BARRIER:
- if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
+ if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
- info->gd->disk_name, op_name(bret->operation));
+ info->gd->disk_name, op_name(bret.operation));
blkif_req(req)->error = BLK_STS_NOTSUPP;
}
- if (unlikely(bret->status == BLKIF_RSP_ERROR &&
+ if (unlikely(bret.status == BLKIF_RSP_ERROR &&
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
- info->gd->disk_name, op_name(bret->operation));
+ info->gd->disk_name, op_name(bret.operation));
blkif_req(req)->error = BLK_STS_NOTSUPP;
}
if (unlikely(blkif_req(req)->error)) {
@@ -1640,9 +1640,9 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
/* fall through */
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
- if (unlikely(bret->status != BLKIF_RSP_OKAY))
+ if (unlikely(bret.status != BLKIF_RSP_OKAY))
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
- "request: %x\n", bret->status);
+ "request: %x\n", bret.status);
break;
default:
--
2.21.0

@ -1,191 +0,0 @@
From 115094605c08f2e2790f6110f7fdc002122e0788 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Wed, 16 Dec 2015 06:07:14 +0100
Subject: [PATCH] xen-blkfront: prepare request locally, only then put it on
the shared ring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Do not reuse data which theoretically might be already modified by the
backend. This is mostly about private copy of the request
(info->shadow[id].req) - make sure the request saved there is really the
one just filled.
This is part of XSA155.
CC: stable@vger.kernel.org
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/block/xen-blkfront.c | 76 +++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 32 deletions(-)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 3f6dbaf0265b..37235ab63ca9 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -527,19 +527,16 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
struct request *req,
- struct blkif_request **ring_req)
+ struct blkif_request *ring_req)
{
unsigned long id;
- *ring_req = RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt);
- rinfo->ring.req_prod_pvt++;
-
id = get_id_from_freelist(rinfo);
rinfo->shadow[id].request = req;
rinfo->shadow[id].status = REQ_WAITING;
rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
- (*ring_req)->u.rw.id = id;
+ ring_req->u.rw.id = id;
return id;
}
@@ -547,23 +544,28 @@ static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
{
struct blkfront_info *info = rinfo->dev_info;
- struct blkif_request *ring_req;
+ struct blkif_request ring_req = { 0 };
unsigned long id;
/* Fill out a communications ring structure. */
id = blkif_ring_get_request(rinfo, req, &ring_req);
- ring_req->operation = BLKIF_OP_DISCARD;
- ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
- ring_req->u.discard.id = id;
- ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
+ ring_req.operation = BLKIF_OP_DISCARD;
+ ring_req.u.discard.nr_sectors = blk_rq_sectors(req);
+ ring_req.u.discard.id = id;
+ ring_req.u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
if (req_op(req) == REQ_OP_SECURE_ERASE && info->feature_secdiscard)
- ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
+ ring_req.u.discard.flag = BLKIF_DISCARD_SECURE;
else
- ring_req->u.discard.flag = 0;
+ ring_req.u.discard.flag = 0;
+
+ /* make the request available to the backend */
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = ring_req;
+ wmb();
+ rinfo->ring.req_prod_pvt++;
/* Keep a private copy so we can reissue requests when recovering. */
- rinfo->shadow[id].req = *ring_req;
+ rinfo->shadow[id].req = ring_req;
return 0;
}
@@ -695,7 +697,7 @@ static void blkif_setup_extra_req(struct blkif_request *first,
static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *rinfo)
{
struct blkfront_info *info = rinfo->dev_info;
- struct blkif_request *ring_req, *extra_ring_req = NULL;
+ struct blkif_request ring_req = { 0 }, extra_ring_req = { 0 };
unsigned long id, extra_id = NO_ASSOCIATED_ID;
bool require_extra_req = false;
int i;
@@ -760,16 +762,16 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
* BLKIF_OP_WRITE
*/
BUG_ON(req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA);
- ring_req->operation = BLKIF_OP_INDIRECT;
- ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
+ ring_req.operation = BLKIF_OP_INDIRECT;
+ ring_req.u.indirect.indirect_op = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
- ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
- ring_req->u.indirect.handle = info->handle;
- ring_req->u.indirect.nr_segments = num_grant;
+ ring_req.u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
+ ring_req.u.indirect.handle = info->handle;
+ ring_req.u.indirect.nr_segments = num_grant;
} else {
- ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
- ring_req->u.rw.handle = info->handle;
- ring_req->operation = rq_data_dir(req) ?
+ ring_req.u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
+ ring_req.u.rw.handle = info->handle;
+ ring_req.operation = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) {
/*
@@ -780,15 +782,15 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
* since it is guaranteed ordered WRT previous writes.)
*/
if (info->feature_flush && info->feature_fua)
- ring_req->operation =
+ ring_req.operation =
BLKIF_OP_WRITE_BARRIER;
else if (info->feature_flush)
- ring_req->operation =
+ ring_req.operation =
BLKIF_OP_FLUSH_DISKCACHE;
else
- ring_req->operation = 0;
+ ring_req.operation = 0;
}
- ring_req->u.rw.nr_segments = num_grant;
+ ring_req.u.rw.nr_segments = num_grant;
if (unlikely(require_extra_req)) {
extra_id = blkif_ring_get_request(rinfo, req,
&extra_ring_req);
@@ -798,7 +800,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
*/
rinfo->shadow[extra_id].num_sg = 0;
- blkif_setup_extra_req(ring_req, extra_ring_req);
+ blkif_setup_extra_req(&ring_req, &extra_ring_req);
/* Link the 2 requests together */
rinfo->shadow[extra_id].associated_id = id;
@@ -806,12 +808,12 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
}
}
- setup.ring_req = ring_req;
+ setup.ring_req = &ring_req;
setup.id = id;
setup.require_extra_req = require_extra_req;
if (unlikely(require_extra_req))
- setup.extra_ring_req = extra_ring_req;
+ setup.extra_ring_req = &extra_ring_req;
for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i) {
BUG_ON(sg->offset + sg->length > PAGE_SIZE);
@@ -833,10 +835,20 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
if (setup.segments)
kunmap_atomic(setup.segments);
+ /* make the request available to the backend */
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = ring_req;
+ wmb();
+ rinfo->ring.req_prod_pvt++;
/* Keep a private copy so we can reissue requests when recovering. */
- rinfo->shadow[id].req = *ring_req;
- if (unlikely(require_extra_req))
- rinfo->shadow[extra_id].req = *extra_ring_req;
+ rinfo->shadow[id].req = ring_req;
+
+ if (unlikely(require_extra_req)) {
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = extra_ring_req;
+ wmb();
+ rinfo->ring.req_prod_pvt++;
+ /* Keep a private copy so we can reissue requests when recovering. */
+ rinfo->shadow[extra_id].req = extra_ring_req;
+ }
if (new_persistent_gnts)
gnttab_free_grant_references(setup.gref_head);
--
2.21.0

@ -1,75 +0,0 @@
From 6a9f5a2435d3845b41f32b3768bb1c25bba1be2d Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Wed, 1 Apr 2015 17:01:26 -0400
Subject: [PATCH] xen/pcifront/pciback: Update pciif.h with ->err and ->result
values.
The '->err' should contain only the XEN_PCI_ERR_* type values.
The '->result' may contain -EXX values or any other value
that the XEN_PCI_OP_* deems appropiate.
As such update the header and also the implementations.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Details in this thread:
https://patchwork.kernel.org/patch/8258431/
---
drivers/pci/xen-pcifront.c | 2 +-
drivers/xen/xen-pciback/pciback_ops.c | 2 +-
include/xen/interface/io/pciif.h | 6 ++++--
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index d1b16cf3403f..4d6f2513b104 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -297,7 +297,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
} else {
pci_err(dev, "enable msix get err %x\n", err);
}
- return err;
+ return err ? -EINVAL : 0;
}
static void pci_frontend_disable_msix(struct pci_dev *dev)
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 787966f44589..0574c9121124 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -266,7 +266,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
if (dev_data)
dev_data->ack_intr = 0;
- return result > 0 ? 0 : result;
+ return result >= 0 ? 0 : XEN_PCI_ERR_op_failed;
}
static
diff --git a/include/xen/interface/io/pciif.h b/include/xen/interface/io/pciif.h
index d9922ae36eb5..c8b674fd2455 100644
--- a/include/xen/interface/io/pciif.h
+++ b/include/xen/interface/io/pciif.h
@@ -70,7 +70,7 @@ struct xen_pci_op {
/* IN: what action to perform: XEN_PCI_OP_* */
uint32_t cmd;
- /* OUT: will contain an error number (if any) from errno.h */
+ /* OUT: will contain an XEN_PCI_ERR_* number. */
int32_t err;
/* IN: which device to touch */
@@ -82,7 +82,9 @@ struct xen_pci_op {
int32_t offset;
int32_t size;
- /* IN/OUT: Contains the result after a READ or the value to WRITE */
+ /* IN/OUT: Contains the result after a READ or the value to WRITE.
+ * If the err does not have XEN_PCI_ERR_success, depending on
+ * XEN_PCI_OP_* might have the errno value. */
uint32_t value;
/* IN: Contains extra infor for this operation */
uint32_t info;
--
2.21.0

@ -1,194 +0,0 @@
From 3a7edaa90f1b3d7066ba9c227577039e4285cb3d Mon Sep 17 00:00:00 2001
From: HW42 <hw42@ipsumj.de>
Date: Tue, 12 Sep 2017 00:49:02 +0200
Subject: [PATCH] xen-pciback: add attribute to allow MSI enable flag writes
QEMU running in a stubdom needs to be able to set the MSI enable flag in
the PCI config space. This adds an attribute 'allow_msi_enable' which
when set for a PCI device allows writes to this flag. The toolstack will
need to set this for stubdoms.
This should not introduce any new security issues since a malicious
guest (or stubdom) can already generate MSIs through other ways, see
[1] page 8.
[1]: https://invisiblethingslab.com/resources/2011/Software%20Attacks%20on%20Intel%20VT-d.pdf
---
.../xen/xen-pciback/conf_space_capability.c | 39 +++++++++++
drivers/xen/xen-pciback/pci_stub.c | 64 +++++++++++++++++++
drivers/xen/xen-pciback/pciback.h | 1 +
3 files changed, 104 insertions(+)
diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
index e5694133ebe5..4be817f448c3 100644
--- a/drivers/xen/xen-pciback/conf_space_capability.c
+++ b/drivers/xen/xen-pciback/conf_space_capability.c
@@ -189,6 +189,40 @@ static const struct config_field caplist_pm[] = {
{}
};
+#define MSI_OK_BITS (PCI_MSI_FLAGS_ENABLE)
+
+static int msi_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+ void *data)
+{
+ int err;
+ u16 old_value;
+ struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
+
+ if (xen_pcibk_permissive || dev_data->permissive)
+ goto write;
+
+ err = pci_read_config_word(dev, offset, &old_value);
+ if (err)
+ return err;
+
+ if (!dev_data->allow_msi_enable
+ || (new_value ^ old_value) & ~MSI_OK_BITS)
+ return PCIBIOS_SET_FAILED;
+
+write:
+ return pci_write_config_word(dev, offset, new_value);
+}
+
+static const struct config_field caplist_msi[] = {
+ {
+ .offset = PCI_MSI_FLAGS,
+ .size = 2,
+ .u.w.read = xen_pcibk_read_config_word,
+ .u.w.write = msi_flags_write,
+ },
+ {}
+};
+
static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
.capability = PCI_CAP_ID_PM,
.fields = caplist_pm,
@@ -197,11 +231,16 @@ static struct xen_pcibk_config_capability xen_pcibk_config_capability_vpd = {
.capability = PCI_CAP_ID_VPD,
.fields = caplist_vpd,
};
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
+ .capability = PCI_CAP_ID_MSI,
+ .fields = caplist_msi,
+};
int xen_pcibk_config_capability_init(void)
{
register_capability(&xen_pcibk_config_capability_vpd);
register_capability(&xen_pcibk_config_capability_pm);
+ register_capability(&xen_pcibk_config_capability_msi);
return 0;
}
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 097410a7cdb7..fb6a4a43c11d 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -304,6 +304,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
xen_pcibk_config_reset_dev(dev);
xen_pcibk_config_free_dyn_fields(dev);
+ dev_data->allow_msi_enable = 0;
+
xen_unregister_device_domain_owner(dev);
spin_lock_irqsave(&found_psdev->lock, flags);
@@ -1431,6 +1433,63 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
}
static DRIVER_ATTR_RW(permissive);
+static ssize_t allow_msi_enable_store(struct device_driver *drv, const char *buf,
+ size_t count)
+{
+ int domain, bus, slot, func;
+ int err;
+ struct pcistub_device *psdev;
+ struct xen_pcibk_dev_data *dev_data;
+
+ err = str_to_slot(buf, &domain, &bus, &slot, &func);
+ if (err)
+ goto out;
+
+ psdev = pcistub_device_find(domain, bus, slot, func);
+ if (!psdev) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ dev_data = pci_get_drvdata(psdev->dev);
+ /* the driver data for a device should never be null at this point */
+ if (!dev_data) {
+ err = -ENXIO;
+ goto release;
+ }
+ dev_data->allow_msi_enable = 1;
+release:
+ pcistub_device_put(psdev);
+out:
+ if (!err)
+ err = count;
+ return err;
+}
+
+static ssize_t allow_msi_enable_show(struct device_driver *drv, char *buf)
+{
+ struct pcistub_device *psdev;
+ struct xen_pcibk_dev_data *dev_data;
+ size_t count = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
+ if (count >= PAGE_SIZE)
+ break;
+ if (!psdev->dev)
+ continue;
+ dev_data = pci_get_drvdata(psdev->dev);
+ if (!dev_data || !dev_data->allow_msi_enable)
+ continue;
+ count +=
+ scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
+ pci_name(psdev->dev));
+ }
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+ return count;
+}
+static DRIVER_ATTR_RW(allow_msi_enable);
+
static void pcistub_exit(void)
{
driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);
@@ -1440,6 +1499,8 @@ static void pcistub_exit(void)
driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_quirks);
driver_remove_file(&xen_pcibk_pci_driver.driver,
&driver_attr_permissive);
+ driver_remove_file(&xen_pcibk_pci_driver.driver,
+ &driver_attr_allow_msi_enable);
driver_remove_file(&xen_pcibk_pci_driver.driver,
&driver_attr_irq_handlers);
driver_remove_file(&xen_pcibk_pci_driver.driver,
@@ -1530,6 +1591,9 @@ static int __init pcistub_init(void)
if (!err)
err = driver_create_file(&xen_pcibk_pci_driver.driver,
&driver_attr_permissive);
+ if (!err)
+ err = driver_create_file(&xen_pcibk_pci_driver.driver,
+ &driver_attr_allow_msi_enable);
if (!err)
err = driver_create_file(&xen_pcibk_pci_driver.driver,
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index 263c059bff90..796f949c92be 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -45,6 +45,7 @@ struct xen_pcibk_dev_data {
struct list_head config_fields;
struct pci_saved_state *pci_saved_state;
unsigned int permissive:1;
+ unsigned int allow_msi_enable:1;
unsigned int warned_on_write:1;
unsigned int enable_intx:1;
unsigned int isr_on:1; /* Whether the IRQ handler is installed. */
--
2.21.0

@ -11,67 +11,43 @@ SOURCEDIR := $(WORKDIR)
NO_OF_CPUS := $(shell grep -c ^processor /proc/cpuinfo)
BUILD_FLAVOR := pvops
RPM_DEFINES := --define "_sourcedir $(SOURCEDIR)" \
--define "_specdir $(SPECDIR)" \
--define "_builddir $(BUILDDIR)" \
--define "_srcrpmdir $(SRCRPMDIR)" \
--define "_rpmdir $(RPMDIR)"
--define "_rpmdir $(RPMDIR)" \
--define "build_flavor $(BUILD_FLAVOR)"
VER_REL := $(shell rpm $(RPM_DEFINES) -q --qf "%{VERSION} %{RELEASE}\n" --specfile $(SPECFILE)| head -1)
ifndef NAME
$(error "You can not run this Makefile without having NAME defined")
endif
ifndef VERSION
VERSION := $(shell cat version)
VERSION := $(word 1, $(VER_REL))
endif
ifndef RELEASE
RELEASE := $(shell cat rel)
endif
ifneq ($(VERSION),$(subst -rc,,$(VERSION)))
DOWNLOAD_FROM_GIT=1
VERIFICATION := hash
else
VERIFICATION := signature
RELEASE := $(word 2, $(VER_REL))
endif
all: help
MIRROR := cdn.kernel.org
ifeq (,$(DISTFILES_MIRROR))
SRC_BASEURL := https://${MIRROR}/pub/linux/kernel/v$(shell echo $(VERSION) | sed 's/^\(2\.[0-9]*\).*/\1/;s/^3\..*/3.x/;s/^4\..*/4.x/;s/^5\..*/5.x/')
else
SRC_BASEURL := $(DISTFILES_MIRROR)
endif
ifeq ($(VERIFICATION),signature)
MIRROR := ftp.kernel.org
SRC_BASEURL := http://${MIRROR}/pub/linux/kernel/v$(shell echo $(VERSION) | sed 's/^\(2\.[0-9]*\).*/\1/;s/^3\..*/3.x/')
SRC_FILE := linux-${VERSION}.tar.xz
ifeq ($(BUILD_FLAVOR),pvops)
SIGN_FILE := linux-${VERSION}.tar.sign
else
SRC_FILE := linux-${VERSION}.tar.gz
HASH_FILE := $(SRC_FILE).sha512
SIGN_FILE := linux-${VERSION}.tar.bz2.sign
endif
WG_BASE_URL := https://git.zx2c4.com/wireguard-linux-compat/snapshot
WG_SRC_FILE := wireguard-linux-compat-0.0.20200121.tar.xz
WG_SRC_URL := $(WG_BASE_URL)/$(WG_SRC_FILE)
WG_SIG_FILE := $(WG_SRC_FILE:%.xz=%.asc)
WG_SIG_URL := $(WG_BASE_URL)/$(WG_SIG_FILE)
SPI_BASE_URL := https://github.com/roadrunner2/macbook12-spi-driver/archive
SPI_REVISION := ddfbc7733542b8474a0e8f593aba91e06542be4f
SPI_SRC_URL := $(SPI_BASE_URL)/$(SPI_REVISION).tar.gz
SPI_SRC_FILE := macbook12-spi-driver-$(SPI_REVISION).tar.gz
SPI_HASH_SHA256 := 8039f103fbb351ecbbaddd540feeb7b0b1abfa216f0689a611e43d997426470e
HASH_FILE :=${SRC_FILE}.sha1sum
URL := $(SRC_BASEURL)/$(SRC_FILE)
URL_SIGN := $(SRC_BASEURL)/$(SIGN_FILE)
ifeq ($(DOWNLOAD_FROM_GIT),1)
URL := https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot/linux-$(VERSION).tar.gz
endif
get-sources: $(SRC_FILE) $(SIGN_FILE) $(WG_SRC_FILE) $(WG_SIG_FILE) $(SPI_SRC_FILE)
get-sources: $(SRC_FILE) $(SIGN_FILE)
$(SRC_FILE):
@wget -q -N $(URL)
@ -79,42 +55,24 @@ $(SRC_FILE):
$(SIGN_FILE):
@wget -q -N $(URL_SIGN)
$(WG_SRC_FILE):
@wget -q -N $(WG_SRC_URL)
$(WG_SIG_FILE):
@wget -q -N $(WG_SIG_URL)
$(SPI_SRC_FILE):
@wget -q -N -O $(SPI_SRC_FILE) $(SPI_SRC_URL)
import-keys:
@if [ -n "$$GNUPGHOME" ]; then rm -f "$$GNUPGHOME/linux-kernel-trustedkeys.gpg"; fi
@gpg --no-auto-check-trustdb --no-default-keyring --keyring linux-kernel-trustedkeys.gpg -q --import kernel*-key.asc
@if [ -n "$$GNUPGHOME" ]; then rm -f "$$GNUPGHOME/wireguard-trustedkeys.gpg"; fi
@gpg --no-auto-check-trustdb --no-default-keyring --keyring wireguard-trustedkeys.gpg -q --import wireguard*-key.asc
gpg -q --import *-key.asc
verify-sources: import-keys
@xzcat $(WG_SRC_FILE) | gpgv --keyring wireguard-trustedkeys.gpg $(WG_SIG_FILE) - 2>/dev/null
ifeq ($(VERIFICATION),signature)
@xzcat $(SRC_FILE) | gpgv --keyring linux-kernel-trustedkeys.gpg $(SIGN_FILE) - 2>/dev/null
ifeq ($(BUILD_FLAVOR),pvops)
@xzcat $(SRC_FILE) | gpg -q --verify $(SIGN_FILE) - 2>/dev/null
else
# there are no signatures for rc tarballs
# verify locally based on a signed git tag and commit hash file
sha512sum --quiet -c $(HASH_FILE)
# @gpg --verify $(SIGN_FILE) $(SRC_FILE)
# The key has been compromised
# and kernel.org decided not to release signature
# with a new key... oh, well...
sha1sum --quiet -c ${HASH_FILE}
endif
@gunzip -c $(SPI_SRC_FILE) | sha256sum | head -c64 | grep -q "^$(SPI_HASH_SHA256)$$"
.PHONY: clean-sources
clean-sources:
ifneq ($(SRC_FILE), None)
-rm $(SRC_FILE) $(SIGN_FILE)
endif
ifneq ($(WG_SRC_FILE), None)
-rm $(WG_SRC_FILE) $(WG_SIG_FILE)
endif
ifneq ($(SPI_SRC_FILE), None)
-rm $(SPI_SRC_FILE)
-rm $(SRC_FILE)
endif

@ -1,4 +1,8 @@
ifeq ($(PACKAGE_SET),dom0)
RPM_SPEC_FILES := kernel.spec
NO_ARCHIVE := 1
else ifeq ($(PACKAGE_SET),vm)
ifdef UPDATE_REPO
# Include kernel-devel packages in VM repo - dummy spec file
RPM_SPEC_FILES := kernel-devel.spec
endif
endif

File diff suppressed because it is too large Load Diff

@ -1,138 +0,0 @@
## Qubes specific config settings.
##
## Lines starting with ## are comments.
################################################################################
## Enable expert options
CONFIG_EXPERT=y
################################################################################
## Use xz to save space on /boot
# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_XZ=y
################################################################################
## Enable /proc/config.gz to help debugging etc.
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
################################################################################
## Enable some more hardening options
CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
CONFIG_GCC_PLUGIN_STRUCTLEAK=y
CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y
## XXX: What's about RANDSTRUCT?
## Those depend on CONFIG_EXPERT
CONFIG_ARCH_MMAP_RND_BITS=32
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_REFCOUNT_FULL=y
# CONFIG_KEXEC is not set
# CONFIG_LEGACY_VSYSCALL_EMULATE is not set
CONFIG_LEGACY_VSYSCALL_NONE=y
# CONFIG_ACPI_CUSTOM_METHOD is not set
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
# CONFIG_PROC_KCORE is not set
CONFIG_PAGE_POISONING=y
# CONFIG_PAGE_POISONING_NO_SANITY is not set
CONFIG_PAGE_POISONING_ZERO=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_ON_OOPS_VALUE=1
CONFIG_PANIC_TIMEOUT=-1
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_TIMEKEEPING=y
CONFIG_IO_STRICT_DEVMEM=y
CONFIG_SECURITY_YAMA=y
# CONFIG_HIBERNATION is not set
################################################################################
## Disable PCI hotplug to prevent DMA attacks via ExpressCard or Thunderbolt
## ports. QubesOS/qubes-issues#1673
# CONFIG_HOTPLUG_PCI is not set
################################################################################
## Deactivate selinux by default
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_LSM="yama,loadpin,safesetid,integrity"
################################################################################
## Enable paravirt spinlocks. This should be more performant.
CONFIG_PARAVIRT_SPINLOCKS=y
################################################################################
## Disable DEBUG_WX. Xen PV guests currently have some WX pages, so suppress
## the useless Warning.
# CONFIG_DEBUG_WX is not set
################################################################################
## Set USB drivers to module to allow attaching PCI devices to pciback before
## those get loaded.
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_XHCI_HCD=m
################################################################################
## USB gadget driver support for testing qvm-usb
CONFIG_USB_GADGET=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_DUMMY_HCD=m
################################################################################
## Enable AppArmor
## It's optionally used by Whonix (https://www.whonix.org/wiki/AppArmor).
CONFIG_SECURITY_APPARMOR=y
################################################################################
## TODO: from diff to old config
## CONFIG_X86_AMD_PLATFORM_DEVICE=y
##
## # CONFIG_X86_MCELOG_LEGACY is not set
## # CONFIG_X86_MCE_INJECT is not set
##
## CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
##
## sensors from 0f976d972a1671a303fad30a5e690304b0b82ee0
##
## Intel ME driver e0f8e9ca81b80d897b190f48a4af80eff3198cb1

@ -1,95 +0,0 @@
## Minimal config for a Qubes VM. Intended for easier testing (git bisect, etc.)
##
## Lines starting with ## are comments.
##
## Run
##
## .../linux-kernel/gen-config arch/x86/configs/x86_64_defconfig .../linux-kernel/config-qubes-minimal
##
## in a linux tree to generate a complete config file.
################################################################################
## linux/kernel/configs/xen.config
## global stuff - these enable us to allow some
## of the not so generic stuff below for xen
CONFIG_PARAVIRT=y
CONFIG_NET=y
CONFIG_NET_CORE=y
CONFIG_NETDEVICES=y
CONFIG_BLOCK=y
CONFIG_WATCHDOG=y
CONFIG_TARGET_CORE=y
CONFIG_SCSI=y
CONFIG_FB=y
CONFIG_INPUT_MISC=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_TTY=y
## Technically not required but otherwise produces
## pretty useless systems starting from allnoconfig
## You want TCP/IP and ELF binaries right?
CONFIG_INET=y
CONFIG_BINFMT_ELF=y
## generic config
CONFIG_XEN=y
CONFIG_XEN_DOM0=y
## backend drivers
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_NETDEV_BACKEND=m
CONFIG_HVC_XEN=y
CONFIG_XEN_WDT=m
CONFIG_XEN_SCSI_BACKEND=m
## frontend drivers
CONFIG_XEN_FBDEV_FRONTEND=m
CONFIG_HVC_XEN_FRONTEND=y
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
## others
CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XENFS=m
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_SYS_HYPERVISOR=y
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XEN_GNTDEV=m
CONFIG_XEN_GRANT_DEV_ALLOC=m
CONFIG_SWIOTLB_XEN=y
CONFIG_XEN_PRIVCMD=m
################################################################################
## linux/arch/x86/configs/xen.config
## global x86 required specific stuff
CONFIG_64BIT=y
## These enable us to allow some of the
## not so generic stuff below
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_X86_MCE=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_CPU_FREQ=y
## x86 xen specific config options
CONFIG_XEN_PVH=y
CONFIG_XEN_SAVE_RESTORE=y
## CONFIG_XEN_DEBUG_FS is not set
CONFIG_XEN_MCE_LOG=y
CONFIG_XEN_ACPI_PROCESSOR=m
## x86 specific backend drivers
CONFIG_XEN_PCIDEV_BACKEND=m
## x86 specific frontend drivers
CONFIG_XEN_PCIDEV_FRONTEND=m
## depends on MEMORY_HOTPLUG, arm64 doesn't enable this yet,
## move to generic config if it ever does.
CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y
################################################################################
## Some basic stuff required in an Qubes VM
CONFIG_DM_SNAPSHOT=m

@ -1,61 +0,0 @@
#!/bin/bash
# The Qubes OS Project, https://www.qubes-os.org
#
# Copyright (C) 2017 Simon Gaiser <simon@invisiblethingslab.com>
# Copyright (c) 2009-2010 Wind River Systems, Inc.
# Copyright 2011 Linaro
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
set -eu -o pipefail
linux_merge_config="./scripts/kconfig/merge_config.sh"
make_opts=""
if [ -n "${LINUX_UPSTREAM_VERSION:-}" ]; then
linux_merge_config="../linux-$LINUX_UPSTREAM_VERSION/scripts/kconfig/merge_config.sh"
make_opts="-C ../linux-$LINUX_UPSTREAM_VERSION O=$PWD"
fi
if [ -z "$linux_merge_config" ]; then
printf 'Error: Could not find merge_config.sh from the linux source tree!\n'
exit 1
fi
sed_config_exp='s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p'
if [ $# -ne 2 ]; then
printf 'Usage: gen-config base.config local.config\n'
exit 1
fi
base_config="$1"
local_config="$2"
grep -v '^##' "$local_config" > "$local_config.gen" || [ $? -le 1 ]
$linux_merge_config -m "$base_config" "$local_config.gen"
make $make_opts KCONFIG_ALLCONFIG=.config alldefconfig
rc=0
for cfg in $(sed -n "$sed_config_exp" "$local_config.gen"); do
requested="$(grep -w "$cfg" "$local_config.gen" || true)"
actual="$(grep -w "$cfg" .config || true)"
if [ "$requested" != "$actual" ]; then
printf 'Local config setting for %s didn'\''t make it into the final config\n' "$cfg"
rc=1
fi
done
rm "$local_config.gen"
exit $rc

@ -1,96 +0,0 @@
#!/bin/bash
# vim: set ts=4 sw=4 sts=4 et :
set -e
if [ "${VERBOSE:-0}" -ge 2 ] || [ "${DEBUG:-0}" -eq 1 ]; then
debug=1
set -x
fi
localdir="$(dirname "$(readlink -f "$0")")"
releasever="$1"
# Set to 1 to include rc srpm
rc="$2"
kernelver="$(cat "$localdir/version")"
kernelsrc="linux-$kernelver"
exit_clean() {
local exit_code=$?
rm -rf "$tmpdir"
exit "${exit_code}"
}
errecho() {
>&2 echo "$@"
}
# example of releasever: '29' or 'rawhide'
if [ "x$releasever" != "x" ]; then
if [[ ! "$releasever" =~ ^[1-9][0-9]$ ]] && [ "$releasever" != "rawhide" ]; then
errecho "Invalid release format"
exit 1
fi
elif [ "x$releasever" == "x" ]; then
listver="$(curl -s -L https://dl.fedoraproject.org/pub/fedora/linux/releases 2> /dev/null)"
releasever="$(echo "$listver" | sed -e 's/<[^>]*>//g' | awk '{print $1}' | grep -o "[1-9][0-9]" | tail -1)"
if ! [[ "$releasever" =~ ^[1-9][0-9]$ ]]; then
errecho "An error occurred while trying to determine latest Fedora version"
exit 1
fi
fi
# get the latest kernel rpm
latestver=$(dnf -q repoquery kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever")
if [ "$rc" != "1" ]; then
latestver=$(echo "$latestver" | grep -v "rc[0-9]*")
fi
latestver=$(echo "$latestver" | sort -V | tail -1 | cut -d ':' -f2)
latestrpm="kernel-core-$latestver.rpm"
if [ "$releasever" == 'rawhide' ]; then
releasever="$(echo "$latestver" | grep -o "fc[1-9][0-9]" | sed 's/fc//')"
fi
if [ "x$latestrpm" != "x" ] && [ "x$releasever" != "x" ]; then
key="$localdir/../builder-rpm/keys/RPM-GPG-KEY-fedora-$releasever-primary"
trap 'exit_clean' 0 1 2 3 6 15
tmpdir="$(mktemp -d -p "$localdir")"
# download latest kernel rpm
dnf -q download kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever"
mv "$latestrpm" "$tmpdir/$latestrpm.untrusted"
# check signature
mkdir -p "$tmpdir/rpmdb"
rpmkeys --dbpath="$tmpdir/rpmdb" --import "$key"
{ rpmkeys --dbpath="$tmpdir/rpmdb" --checksig "$tmpdir/$latestrpm.untrusted" | grep -q 'signatures OK' ; } || { errecho "Failed to check signature"; exit 1; }
mv "$tmpdir/$latestrpm.untrusted" "$tmpdir/$latestrpm"
# extract kernel sources in qubes-linux-kernel
tar xf "$localdir/$kernelsrc.tar.xz" -C "$tmpdir"
# get latest config and put it in extracted sources
rpm2cpio "$tmpdir/$latestrpm" | cpio --quiet -i --to-stdout "./lib/modules/$latestver/config" > "$tmpdir/$kernelsrc/.config"
# generate new config with: yes '' | make oldconfig
cd "$tmpdir/$kernelsrc/"
## drop config settings which depend on Fedora patches and adjust for the small version difference
if [ "$debug" == "1" ]; then
yes '' | make oldconfig
else
yes '' | make oldconfig > /dev/null 2>&1
fi
## remove comments in header
sed -i '1,4d' "$tmpdir/$kernelsrc/.config"
# create final config
cat - "$tmpdir/$kernelsrc/.config" > "$localdir/config-base-$(echo "$latestver" | cut -d '-' -f1)" << EOF
# Base config based on Fedora's config ($latestrpm)
# Only modification is \`yes '' | make oldconfig\` to drop config settings which
# depend on Fedora patches and adjust for the small version difference.
EOF
rm -rf "$tmpdir"
else
errecho "Unable to find the latest kernel rpm for Fedora $releasever"; exit 1
fi

@ -1,13 +1,15 @@
# default to pvops build
%{!?build_flavor:%define build_flavor pvops}
%if 0%{?qubes_builder}
%define _sourcedir %(pwd)
%endif
#%define _unpackaged_files_terminate_build 0
%define variant pvops.qubes
%define plainrel %(cat rel)
%define variant %{build_flavor}.qubes
%define plainrel %(cat rel-%{build_flavor})
%define rel %{plainrel}.%{variant}
%define version %(cat version)
%define version %(cat version-%{build_flavor})
Name: kernel-devel
Version: %{version}
@ -21,7 +23,7 @@ Url: http://www.kernel.org/
%description
This package contains files necessary for building kernel modules (and
kernel module packages) against the pvops flavor of the kernel.
kernel module packages) against the %build_flavor flavor of the kernel.
%prep
echo "Dummy spec, do not try to build, use kernel.spec instead"

@ -1,37 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=d8eq
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,502 @@
# A spec file for building xenlinux Dom0 kernel for Qubes
# Based on the Open SUSE kernel-spec & Fedora kernel-spec.
#
# default to pvops build
%{!?build_flavor:%define build_flavor pvops}
%if 0%{?qubes_builder}
%define _sourcedir %(pwd)
%endif
#%define _unpackaged_files_terminate_build 0
%define variant %{build_flavor}.qubes
%define plainrel %(cat rel-%{build_flavor})
%define rel %{plainrel}.%{variant}
%define version %(cat version-%{build_flavor})
%define _buildshell /bin/bash
%define build_xen 1
%global cpu_arch x86_64
%define cpu_arch_flavor %cpu_arch/%build_flavor
%define kernelrelease %(echo %{version} | sed 's/^3\\.[0-9]\\+$/\\0.0/')-%rel.%cpu_arch
%define my_builddir %_builddir/%{name}-%{version}
%define build_src_dir %my_builddir/linux-%version
%define src_install_dir /usr/src/kernels/%kernelrelease
%define kernel_build_dir %my_builddir/linux-obj
%define vm_install_dir /var/lib/qubes/vm-kernels/%version-%{plainrel}
%(chmod +x %_sourcedir/{guards,apply-patches,check-for-config-changes})
%define install_vdso 1
%define debuginfodir /usr/lib/debug
# If you want to build debuginfo package, enable also CONFIG_DEBUG_INFO in %%setup section
# Otherwise debuginfo build is disabled by default to save disk space (it needs 2-3GB build time)
%global debug_package %{nil}
Name: kernel
Summary: The Xen Kernel
Version: %{version}
Epoch: 1000
Release: %{rel}
License: GPL v2 only
Group: System/Kernel
Url: http://www.kernel.org/
AutoReqProv: on
BuildRequires: coreutils module-init-tools sparse
BuildRequires: qubes-kernel-vm-support
BuildRequires: dracut
BuildRequires: busybox
Provides: multiversion(kernel)
Provides: %name = %kernelrelease
Provides: kernel-xen-dom0
Provides: kernel-qubes-dom0
Provides: kernel-qubes-dom0-%{build_flavor}
Provides: kernel-drm = 4.3.0
Provides: kernel-drm-nouveau = 16
Provides: kernel-modules-extra = %kernelrelease
Provides: kernel-modeset = 1
Requires(post): /sbin/new-kernel-pkg
Requires(preun):/sbin/new-kernel-pkg
Requires(pre): coreutils gawk
Requires(post): dracut binutils
Conflicts: sysfsutils < 2.0
# root-lvm only works with newer udevs
Conflicts: udev < 118
Conflicts: lvm2 < 2.02.33
Provides: kernel = %kernelrelease
Provides: kernel-uname-r = %kernelrelease
Source0: linux-%version.tar.xz
Source14: series-%{build_flavor}.conf
Source16: guards
Source17: apply-patches
Source33: check-for-config-changes
Source100: config-%{build_flavor}
# FIXME: Including dirs this way does NOT produce proper src.rpms
Source204: patches.rpmify
Source205: patches.xen
Source300: patches.qubes
BuildRoot: %{_tmppath}/%{name}-%{version}-build
ExclusiveArch: x86_64
%description
Qubes Dom0 kernel.
%prep
if ! [ -e %_sourcedir/linux-%version.tar.xz ]; then
echo "The %name-%version.nosrc.rpm package does not contain the" \
"complete sources. Please install kernel-source-%version.src.rpm."
exit 1
fi
SYMBOLS="xen-dom0 %{build_flavor}"
# Unpack all sources and patches
%setup -q -c -T -a 0
mkdir -p %kernel_build_dir
cd linux-%version
if [ -r %_sourcedir/series-%{version}-%{build_flavor}.conf ]; then
%_sourcedir/apply-patches %_sourcedir/series-%{version}-%{build_flavor}.conf %_sourcedir $SYMBOLS
else
%_sourcedir/apply-patches %_sourcedir/series-%{build_flavor}.conf %_sourcedir $SYMBOLS
fi
cd %kernel_build_dir
if [ -f %_sourcedir/config-%{version}-%{build_flavor} ]; then
cp %_sourcedir/config-%{version}-%{build_flavor} .config
else
cp %_sourcedir/config-%{build_flavor} .config
fi
%build_src_dir/scripts/config \
--set-str CONFIG_LOCALVERSION -%release.%cpu_arch \
--disable CONFIG_DEBUG_INFO
# --enable CONFIG_DEBUG_INFO \
# --disable CONFIG_DEBUG_INFO_REDUCED
# Enabling CONFIG_DEBUG_INFO produces *huge* packages!
MAKE_ARGS="$MAKE_ARGS -C %build_src_dir O=$PWD"
if test -e %_sourcedir/TOLERATE-UNKNOWN-NEW-CONFIG-OPTIONS; then
yes '' | make oldconfig $MAKE_ARGS
else
cp .config .config.orig
make silentoldconfig $MAKE_ARGS < /dev/null
%_sourcedir/check-for-config-changes .config.orig .config
rm .config.orig
fi
make prepare $MAKE_ARGS
make scripts $MAKE_ARGS
make scripts_basic $MAKE_ARGS
krel=$(make -s kernelrelease $MAKE_ARGS)
if [ "$krel" != "%kernelrelease" ]; then
echo "Kernel release mismatch: $krel != %kernelrelease" >&2
exit 1
fi
make clean $MAKE_ARGS
rm -f source
find . ! -type d -printf '%%P\n' > %my_builddir/obj-files
u2mfn_ver=`dkms status u2mfn|tail -n 1|cut -f 2 -d ' '|tr -d ':,:'`
rm -rf %_builddir/u2mfn
cp -r /usr/src/u2mfn-$u2mfn_ver %_builddir/u2mfn
%build
cd %kernel_build_dir
# This override tweaks the kernel makefiles so that we run debugedit on an
# object before embedding it. When we later run find-debuginfo.sh, it will
# run debugedit again. The edits it does change the build ID bits embedded
# in the stripped object, but repeating debugedit is a no-op. We do it
# beforehand to get the proper final build ID bits into the embedded image.
# This affects the vDSO images in vmlinux, and the vmlinux image in bzImage.
export AFTER_LINK=\
'sh -xc "/usr/lib/rpm/debugedit -b $$RPM_BUILD_DIR -d /usr/src/debug \
-i $@ > $@.id"'
make %{?_smp_mflags} all $MAKE_ARGS CONFIG_DEBUG_SECTION_MISMATCH=y
# Build u2mfn module
make -C %kernel_build_dir M=%_builddir/u2mfn modules
%install
# get rid of /usr/lib/rpm/brp-strip-debug
# strip removes too much from the vmlinux ELF binary
export NO_BRP_STRIP_DEBUG=true
export STRIP_KEEP_SYMTAB='*/vmlinux-*'
# /lib/modules/%kernelrelease-%build_flavor/build will be a stale symlink until the
# kernel-devel package is installed. Don't check for stale symlinks
# in the brp-symlink check:
export NO_BRP_STALE_LINK_ERROR=yes
cd %kernel_build_dir
mkdir -p %buildroot/boot
cp -p System.map %buildroot/boot/System.map-%kernelrelease
if [ "%{build_flavor}" == "xenlinux" ]; then
cp -p arch/x86/boot/vmlinuz %buildroot/boot/vmlinuz-%kernelrelease
else
cp -p arch/x86/boot/bzImage %buildroot/boot/vmlinuz-%kernelrelease
fi
cp .config %buildroot/boot/config-%kernelrelease
%if %install_vdso
# Install the unstripped vdso's that are linked in the kernel image
make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
%endif
# Create a dummy initramfs with roughly the size the real one will have.
# That way, rpm will know that this package requires some additional
# space in /boot.
dd if=/dev/zero of=%buildroot/boot/initramfs-%kernelrelease.img \
bs=1M count=20
gzip -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease.gz
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/u2mfn
mkdir -p %buildroot/%src_install_dir
rm -f %buildroot/lib/modules/%kernelrelease/build
rm -f %buildroot/lib/modules/%kernelrelease/source
mkdir -p %buildroot/lib/modules/%kernelrelease/build
(cd %buildroot/lib/modules/%kernelrelease ; ln -s build source)
# dirs for additional modules per module-init-tools, kbuild/modules.txt
mkdir -p %buildroot/lib/modules/%kernelrelease/extra
mkdir -p %buildroot/lib/modules/%kernelrelease/updates
mkdir -p %buildroot/lib/modules/%kernelrelease/weak-updates
pushd %build_src_dir
cp --parents `find -type f -name "Makefile*" -o -name "Kconfig*"` %buildroot/lib/modules/%kernelrelease/build
cp -a scripts %buildroot/lib/modules/%kernelrelease/build
cp -a --parents arch/x86/include %buildroot/lib/modules/%kernelrelease/build/
if [ "%{build_flavor}" == "xenlinux" ]; then
cp -a --parents arch/x86/include/mach-xen %buildroot/lib/modules/%kernelrelease/build/
fi
cp -a include %buildroot/lib/modules/%kernelrelease/build/include
popd
cp Module.symvers %buildroot/lib/modules/%kernelrelease/build
cp System.map %buildroot/lib/modules/%kernelrelease/build
if [ -s Module.markers ]; then
cp Module.markers %buildroot/lib/modules/%kernelrelease/build
fi
rm -rf %buildroot/lib/modules/%kernelrelease/build/Documentation
cp .config %buildroot/lib/modules/%kernelrelease/build
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*.o
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*/*.o
cp -a scripts/* %buildroot/lib/modules/%kernelrelease/build/scripts/
cp -a include/* %buildroot/lib/modules/%kernelrelease/build/include
if [ "%{build_flavor}" != "xenlinux" ]; then
cp -a --parents arch/x86/include/generated %buildroot/lib/modules/%kernelrelease/build/
fi
# Copy .config to include/config/auto.conf so "make prepare" is unnecessary.
cp %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
# Make sure the Makefile and version.h have a matching timestamp so that
# external modules can be built
touch -r %buildroot/lib/modules/%kernelrelease/build/Makefile %buildroot/lib/modules/%kernelrelease/build/include/generated/uapi/linux/version.h
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
if test -s vmlinux.id; then
cp vmlinux.id %buildroot/lib/modules/%kernelrelease/build/vmlinux.id
else
echo >&2 "*** WARNING *** no vmlinux build ID! ***"
fi
#
# save the vmlinux file for kernel debugging into the kernel-debuginfo rpm
#
mkdir -p %buildroot%{debuginfodir}/lib/modules/%kernelrelease
cp vmlinux %buildroot%{debuginfodir}/lib/modules/%kernelrelease
find %buildroot/lib/modules/%kernelrelease -name "*.ko" -type f >modnames
# mark modules executable so that strip-to-file can strip them
xargs --no-run-if-empty chmod u+x < modnames
# Generate a list of modules for block and networking.
fgrep /drivers/ modnames | xargs --no-run-if-empty nm -upA |
sed -n 's,^.*/\([^/]*\.ko\): *U \(.*\)$,\1 \2,p' > drivers.undef
collect_modules_list()
{
sed -r -n -e "s/^([^ ]+) \\.?($2)\$/\\1/p" drivers.undef |
LC_ALL=C sort -u > %buildroot/lib/modules/%kernelrelease/modules.$1
}
collect_modules_list networking \
'register_netdev|ieee80211_register_hw|usbnet_probe'
collect_modules_list block \
'ata_scsi_ioctl|scsi_add_host|scsi_add_host_with_dma|blk_init_queue|register_mtd_blktrans|scsi_esp_register|scsi_register_device_handler'
collect_modules_list drm \
'drm_open|drm_init'
collect_modules_list modesetting \
'drm_crtc_init'
# detect missing or incorrect license tags
rm -f modinfo
while read i
do
echo -n "${i#%buildroot/lib/modules/%kernelrelease/} " >> modinfo
/sbin/modinfo -l $i >> modinfo
done < modnames
egrep -v \
'GPL( v2)?$|Dual BSD/GPL$|Dual MPL/GPL$|GPL and additional rights$' \
modinfo && exit 1
rm -f modinfo modnames
# Move the devel headers out of the root file system
mkdir -p %buildroot/usr/src/kernels
mv %buildroot/lib/modules/%kernelrelease/build/* %buildroot/%src_install_dir/
mv %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/%src_install_dir
rmdir %buildroot/lib/modules/%kernelrelease/build
ln -sf %src_install_dir %buildroot/lib/modules/%kernelrelease/build
# Abort if there are any undefined symbols
msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease \
-b %buildroot -ae %kernelrelease 2>&1)"
if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then
exit 1
fi
if [ "%{build_flavor}" == "pvops" ]; then
# in case of no firmware built - place empty dir
mkdir -p %buildroot/lib/firmware
mv %buildroot/lib/firmware %buildroot/lib/firmware-all
mkdir -p %buildroot/lib/firmware
mv %buildroot/lib/firmware-all %buildroot/lib/firmware/%kernelrelease
fi
# Prepare initramfs for Qubes VM
mkdir -p %buildroot/%vm_install_dir
/sbin/dracut --nomdadmconf --nolvmconf \
--kmoddir %buildroot/lib/modules/%kernelrelease \
--modules "kernel-modules qubes-vm-simple" \
--conf /dev/null --confdir /var/empty \
-d "xenblk xen-blkfront cdrom ext4 jbd2 crc16 dm_snapshot" \
%buildroot/%vm_install_dir/initramfs %kernelrelease
if [ "%{build_flavor}" == "xenlinux" ]; then
cp -p arch/x86/boot/vmlinuz %buildroot/%vm_install_dir/vmlinuz
else
cp -p arch/x86/boot/bzImage %buildroot/%vm_install_dir/vmlinuz
fi
# Modules for Qubes VM
mkdir -p %buildroot%vm_install_dir/modules
cp -a %buildroot/lib/modules/%kernelrelease %buildroot%vm_install_dir/modules/
mkdir -p %buildroot%vm_install_dir/modules/firmware
cp -a %buildroot/lib/firmware/%kernelrelease %buildroot%vm_install_dir/modules/firmware/
# remove files that will be auto generated by depmod at rpm -i time
for i in alias alias.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap
do
rm -f %buildroot/lib/modules/%kernelrelease/modules.$i
done
%post
INITRD_OPT="--mkinitrd --dracut"
/sbin/new-kernel-pkg --package %{name}-%{kernelrelease}\
$INITRD_OPT \
--depmod --kernel-args="max_loop=255"\
--multiboot=/boot/xen.gz --mbargs="console=none" \
--banner="Qubes"\
--make-default --install %{kernelrelease}
if [ -e /boot/grub/grub.conf ]; then
# Make it possible to enter GRUB menu if something goes wrong...
sed -i "s/^timeout *=.*/timeout=3/" /boot/grub/grub.conf
fi
%posttrans
/sbin/new-kernel-pkg --package %{name}-%{kernelrelease} --rpmposttrans %{kernelrelease}
# grubby (used by new-kernel-pkg) do not understand xen entries in grub2 config
if [ -e /boot/grub2/grub.cfg ]; then
grub2-mkconfig > /boot/grub2/grub.cfg
fi
%preun
/sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{kernelrelease}
%files
%defattr(-, root, root)
%ghost /boot/initramfs-%{kernelrelease}.img
/boot/System.map-%{kernelrelease}
/boot/config-%{kernelrelease}
/boot/symvers-%kernelrelease.gz
%attr(0644, root, root) /boot/vmlinuz-%{kernelrelease}
/lib/firmware/%{kernelrelease}
/lib/modules/%{kernelrelease}
%package devel
Summary: Development files necessary for building kernel modules
License: GPL v2 only
Group: Development/Sources
Provides: multiversion(kernel)
Provides: %name-devel = %kernelrelease
Provides: kernel-devel-uname-r = %kernelrelease
AutoReqProv: on
%description devel
This package contains files necessary for building kernel modules (and
kernel module packages) against the %build_flavor flavor of the kernel.
%post devel
if [ -f /etc/sysconfig/kernel ]
then
. /etc/sysconfig/kernel || exit $?
fi
if [ "$HARDLINK" != "no" -a -x /usr/sbin/hardlink ]
then
(cd /usr/src/kernels/%{kernelrelease} &&
/usr/bin/find . -type f | while read f; do
hardlink -c /usr/src/kernels/*.fc*.*/$f $f
done)
fi
%files devel
%defattr(-,root,root)
/usr/src/kernels/%{kernelrelease}
%package qubes-vm
Summary: The Xen Kernel
Version: %{version}
Release: %{rel}
License: GPL v2 only
Group: System/Kernel
Url: http://www.kernel.org/
AutoReqProv: on
BuildRequires: coreutils module-init-tools sparse
Provides: multiversion(kernel-qubes-vm)
Provides: kernel-xen-domU
Provides: kernel-qubes-domU
Requires(pre): coreutils gawk
Requires(post): dracut
Requires(post): qubes-core-dom0
Conflicts: sysfsutils < 2.0
# root-lvm only works with newer udevs
Conflicts: udev < 118
Conflicts: lvm2 < 2.02.33
Provides: kernel-qubes-vm = %kernelrelease
%description qubes-vm
Qubes domU kernel.
%post qubes-vm
mkdir /tmp/qubes-modules-%kernelrelease
truncate -s 400M /tmp/qubes-modules-%kernelrelease.img
mkfs -t ext3 -F /tmp/qubes-modules-%kernelrelease.img > /dev/null
mount /tmp/qubes-modules-%kernelrelease.img /tmp/qubes-modules-%kernelrelease -o loop
cp -a -t /tmp/qubes-modules-%kernelrelease %vm_install_dir/modules/%kernelrelease
mkdir /tmp/qubes-modules-%kernelrelease/firmware
cp -a -t /tmp/qubes-modules-%kernelrelease/firmware %vm_install_dir/modules/firmware/%kernelrelease
umount /tmp/qubes-modules-%kernelrelease
rmdir /tmp/qubes-modules-%kernelrelease
mv /tmp/qubes-modules-%kernelrelease.img %vm_install_dir/modules.img
# If qubes-prefs isn't installed yet, the default kernel will be set by %post
# of qubes-core-dom0
type qubes-prefs &>/dev/null && qubes-prefs --set default-kernel %version-%plainrel
exit 0
%preun qubes-vm
if [ "`qubes-prefs -g default-kernel`" == "%version-%plainrel" ]; then
echo "This kernel version is set as default VM kernel, cannot remove"
exit 1
fi
if qvm-ls --kernel | grep -qw "%version-%plainrel"; then
echo "This kernel version is used by at least one VM, cannot remove"
exit 1
fi
exit 0
%files qubes-vm
%defattr(-, root, root)
%dir %vm_install_dir
%ghost %attr(0644, root, root) %vm_install_dir/modules.img
%attr(0644, root, root) %vm_install_dir/initramfs
%attr(0644, root, root) %vm_install_dir/vmlinuz
%vm_install_dir/modules
%changelog

@ -1,679 +0,0 @@
# A spec file for building xenlinux Dom0 kernel for Qubes
# Based on the Open SUSE kernel-spec & Fedora kernel-spec.
#
%define variant qubes
%define plainrel @REL@
%define rel %{plainrel}.%{variant}
%define version %(echo '@VERSION@' | sed 's/~rc.*/.0/')
%define upstream_version %(echo '@VERSION@' | sed 's/~rc/-rc/')
%if "%{version}" != "%{upstream_version}"
%define prerelease 1
%define rel 0.%(echo '@VERSION@' | sed 's/.*~rc/rc/').%{plainrel}.%{variant}
%else
%define prerelease 0
%define rel %{plainrel}.%{variant}
%endif
%define name_suffix -latest
%define _buildshell /bin/bash
%define build_xen 1
%global cpu_arch x86_64
%define cpu_arch_flavor %cpu_arch
%define kernelrelease %(echo %{upstream_version} | sed 's/^[0-9]\\.[0-9]\\+$/\\0.0/;s/-rc.*/.0/')-%rel.%cpu_arch
%define my_builddir %_builddir/%{name}-%{version}
%define build_src_dir %my_builddir/linux-%upstream_version
%define src_install_dir /usr/src/kernels/%kernelrelease
%define kernel_build_dir %my_builddir/linux-obj
%define vm_install_dir /var/lib/qubes/vm-kernels/%upstream_version-%{plainrel}
%define install_vdso 1
%define debuginfodir /usr/lib/debug
# debuginfo build is disabled by default to save disk space (it needs 2-3GB build time)
%define with_debuginfo 0
# Sign all modules
%global signmodules 1
%if !%{with_debuginfo}
%global debug_package %{nil}
%define setup_config --disable CONFIG_DEBUG_INFO
%else
%define setup_config --enable CONFIG_DEBUG_INFO --disable CONFIG_DEBUG_INFO_REDUCED
%endif
Name: kernel%{?name_suffix}
Summary: The Xen Kernel
Version: %{version}
Epoch: 1000
Release: %{rel}
License: GPL v2 only
Group: System/Kernel
Url: http://www.kernel.org/
AutoReqProv: on
BuildRequires: coreutils module-init-tools sparse
BuildRequires: qubes-kernel-vm-support
BuildRequires: dracut
BuildRequires: busybox
BuildRequires: bc
BuildRequires: openssl
BuildRequires: openssl-devel
BuildRequires: python3-devel
BuildRequires: gcc-plugin-devel
BuildRequires: elfutils-libelf-devel
BuildRequires: bison
BuildRequires: flex
BuildRequires: e2fsprogs
# gcc with support for BTI mitigation
%if 0%{?fedora} == 23
BuildRequires: gcc >= 5.3.1-6.qubes1
%else
%if 0%{?fedora} == 25
BuildRequires: gcc >= 6.4.1-1.qubes1
%else
BuildRequires: gcc
%endif
%endif
# Needed for building GCC hardened plugins
BuildRequires: gcc-c++
Provides: multiversion(kernel)
Provides: %name = %kernelrelease
Provides: kernel-xen-dom0
Provides: kernel-qubes-dom0
Provides: kernel-qubes-dom0-pvops
Provides: kernel-drm = 4.3.0
Provides: kernel-drm-nouveau = 16
Provides: kernel-modules-extra = %kernelrelease
Provides: kernel-modeset = 1
Requires(pre): coreutils gawk
Requires(post): dracut binutils
Requires: qubes-core-dom0-linux-kernel-install
Conflicts: sysfsutils < 2.0
# root-lvm only works with newer udevs
Conflicts: udev < 118
Conflicts: lvm2 < 2.02.33
Provides: kernel = %kernelrelease
Provides: kernel-uname-r = %kernelrelease
ExclusiveArch: x86_64
%if !%{prerelease}
Source0: linux-%{upstream_version}.tar.xz
%else
Source0: linux-%{upstream_version}.tar.gz
%endif
Source5: wireguard-linux-compat-0.0.20200121.tar.xz
Source6: macbook12-spi-driver-ddfbc7733542b8474a0e8f593aba91e06542be4f.tar.gz
Source16: guards
Source17: apply-patches
Source18: mod-sign.sh
Source33: check-for-config-changes
Source34: gen-config
Source100: config-base
Source101: config-qubes
%define modsign_cmd %{SOURCE18}
Patch0: 0001-xen-netfront-detach-crash.patch
Patch1: 0002-mce-hide-EBUSY-initialization-error-on-Xen.patch
Patch2: 0003-Log-error-code-of-EVTCHNOP_bind_pirq-failure.patch
Patch3: 0004-pvops-respect-removable-xenstore-flag-for-block-devi.patch
Patch4: 0005-pvops-xen-blkfront-handle-FDEJECT-as-detach-request-.patch
Patch5: 0006-block-add-no_part_scan-module-parameter.patch
Patch6: 0007-xen-Add-RING_COPY_RESPONSE.patch
Patch7: 0008-xen-netfront-copy-response-out-of-shared-buffer-befo.patch
Patch8: 0009-xen-netfront-do-not-use-data-already-exposed-to-back.patch
Patch9: 0010-xen-netfront-add-range-check-for-Tx-response-id.patch
Patch10: 0011-xen-blkfront-make-local-copy-of-response-before-usin.patch
Patch11: 0012-xen-blkfront-prepare-request-locally-only-then-put-i.patch
Patch12: 0013-xen-pcifront-pciback-Update-pciif.h-with-err-and-res.patch
Patch13: 0014-xen-pciback-add-attribute-to-allow-MSI-enable-flag-w.patch
%description
Qubes Dom0 kernel.
%prep
SYMBOLS="xen-dom0 pvops"
# Unpack all sources and patches
%autosetup -N -c -T -a 0
export LINUX_UPSTREAM_VERSION=%{upstream_version}
mkdir -p %kernel_build_dir
cd linux-%upstream_version
%autopatch -p1
# drop EXTRAVERSION - possible -rc suffix already included in %release
sed -i -e 's/^EXTRAVERSION = -rc.*/EXTRAVERSION =/' Makefile
%if 0%{?fedora} >= 31
# Mangle /usr/bin/python shebangs to /usr/bin/python3
# Mangle all Python shebangs to be Python 3 explicitly
# -p preserves timestamps
# -n prevents creating ~backup files
# -i specifies the interpreter for the shebang
# This fixes errors such as
# *** ERROR: ambiguous python shebang in /usr/bin/kvm_stat: #!/usr/bin/python. Change it to python3 (or python2) explicitly.
# We patch all sources below for which we got a report/error.
pathfix.py -i "%{__python3} %{py3_shbang_opts}" -p -n \
tools/kvm/kvm_stat/kvm_stat \
scripts/show_delta \
scripts/diffconfig \
scripts/bloat-o-meter \
tools/perf/tests/attr.py \
tools/perf/scripts/python/stat-cpi.py \
tools/perf/scripts/python/sched-migration.py \
Documentation \
scripts/gen_compile_commands.py
%endif
cd %kernel_build_dir
# Create QubesOS config kernel
%{SOURCE34} %{SOURCE100} %{SOURCE101}
%build_src_dir/scripts/config \
--set-str CONFIG_LOCALVERSION -%release.%cpu_arch %{setup_config}
MAKE_ARGS="$MAKE_ARGS -C %build_src_dir O=$PWD KERNELRELEASE=%{kernelrelease}"
make prepare $MAKE_ARGS
make scripts $MAKE_ARGS
make scripts_basic $MAKE_ARGS
krel=$(make -s kernelrelease $MAKE_ARGS)
if [ "$krel" != "%kernelrelease" ]; then
echo "Kernel release mismatch: $krel != %kernelrelease" >&2
exit 1
fi
make clean $MAKE_ARGS
rm -f source
find . ! -type d -printf '%%P\n' > %my_builddir/obj-files
rm -rf %_builddir/u2mfn
u2mfn_ver=`dkms status u2mfn|tail -n 1|cut -f 2 -d ' '|tr -d ':,:'`
if [ -n "$u2mfn_ver" ]; then
cp -r /usr/src/u2mfn-$u2mfn_ver %_builddir/u2mfn
fi
rm -rf %_builddir/wireguard
tar x -C %_builddir -Jpf %{SOURCE5}
mv %_builddir/$(basename %{SOURCE5} .tar.xz) %_builddir/wireguard
rm -rf %_builddir/macbook12-spi-driver
tar -x -C %_builddir -zf %{SOURCE6}
mv %_builddir/$(basename %{SOURCE6} .tar.gz) %_builddir/macbook12-spi-driver
%build
cd %kernel_build_dir
make %{?_smp_mflags} all $MAKE_ARGS CONFIG_DEBUG_SECTION_MISMATCH=y
# Build u2mfn module
if [ -d "%_builddir/u2mfn" ]; then
make -C %kernel_build_dir M=%_builddir/u2mfn modules
fi
if [ -d "%_builddir/wireguard" ]; then
make -C %kernel_build_dir M=%_builddir/wireguard/src modules
fi
# Build applespi, apple-ibridge, apple-ib-tb, apple-ib-als modules
if [ -d "%_builddir/macbook12-spi-driver" ]; then
make -C %kernel_build_dir M=%_builddir/macbook12-spi-driver modules
fi
%define __modsign_install_post \
if [ "%{signmodules}" -eq "1" ]; then \
%{modsign_cmd} certs/signing_key.pem certs/signing_key.x509 $RPM_BUILD_ROOT/lib/modules/%kernelrelease/ \
fi \
%{nil}
#
# Disgusting hack alert! We need to ensure we sign modules *after* all
# invocations of strip occur, which is in __debug_install_post if
# find-debuginfo.sh runs, and __os_install_post if not.
#
%define __spec_install_post \
%{?__debug_package:%{__debug_install_post}}\
%{__arch_install_post}\
%{__os_install_post}\
%{?__remove_unwanted_dbginfo_install_post}\
%{__modsign_install_post}
%install
# get rid of /usr/lib/rpm/brp-strip-debug
# strip removes too much from the vmlinux ELF binary
export NO_BRP_STRIP_DEBUG=true
export STRIP_KEEP_SYMTAB='*/vmlinux-*'
# /lib/modules/%kernelrelease-%build_flavor/build will be a stale symlink until the
# kernel-devel package is installed. Don't check for stale symlinks
# in the brp-symlink check:
export NO_BRP_STALE_LINK_ERROR=yes
cd %kernel_build_dir
mkdir -p %buildroot/boot
cp -p System.map %buildroot/boot/System.map-%kernelrelease
cp -p arch/x86/boot/bzImage %buildroot/boot/vmlinuz-%kernelrelease
cp .config %buildroot/boot/config-%kernelrelease
%if %install_vdso
# Install the unstripped vdso's that are linked in the kernel image
make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
%endif
# Create a dummy initramfs with roughly the size the real one will have.
# That way, rpm will know that this package requires some additional
# space in /boot.
dd if=/dev/zero of=%buildroot/boot/initramfs-%kernelrelease.img \
bs=1M count=20
gzip -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease.gz
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
if [ -d "%_builddir/u2mfn" ]; then
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/u2mfn
fi
if [ -d "%_builddir/wireguard" ]; then
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/wireguard/src
fi
if [ -d "%_builddir/macbook12-spi-driver" ]; then
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/macbook12-spi-driver
fi
mkdir -p %buildroot/%src_install_dir
rm -f %buildroot/lib/modules/%kernelrelease/build
rm -f %buildroot/lib/modules/%kernelrelease/source
mkdir -p %buildroot/lib/modules/%kernelrelease/build
(cd %buildroot/lib/modules/%kernelrelease ; ln -s build source)
# dirs for additional modules per module-init-tools, kbuild/modules.txt
mkdir -p %buildroot/lib/modules/%kernelrelease/extra
mkdir -p %buildroot/lib/modules/%kernelrelease/updates
mkdir -p %buildroot/lib/modules/%kernelrelease/weak-updates
pushd %build_src_dir
cp --parents `find -type f -name "Makefile*" -o -name "Kconfig*"` %buildroot/lib/modules/%kernelrelease/build
cp -a scripts %buildroot/lib/modules/%kernelrelease/build
cp -a --parents arch/x86/include %buildroot/lib/modules/%kernelrelease/build/
cp -a include %buildroot/lib/modules/%kernelrelease/build/include
popd
cp Module.symvers %buildroot/lib/modules/%kernelrelease/build
cp System.map %buildroot/lib/modules/%kernelrelease/build
if [ -s Module.markers ]; then
cp Module.markers %buildroot/lib/modules/%kernelrelease/build
fi
rm -rf %buildroot/lib/modules/%kernelrelease/build/Documentation
# Remove useless scripts that creates ERROR with ambiguous shebang
# that are removed too in Fedora
rm -rf %buildroot/lib/modules/%kernelrelease/build/scripts/tracing
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/spdxcheck.py
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*.o
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*/*.o
cp -a scripts/* %buildroot/lib/modules/%kernelrelease/build/scripts/
cp -a include/* %buildroot/lib/modules/%kernelrelease/build/include/
cp -a --parents arch/x86/include/* %buildroot/lib/modules/%kernelrelease/build/
if [ -f tools/objtool/objtool ]; then
cp -a --parents tools/objtool %buildroot/lib/modules/%kernelrelease/build/
pushd %build_src_dir
cp -a --parents tools/objtool %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/build/Build.include %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/build/Build %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/build/fixdep.c %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/scripts/utilities.mak %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/lib/str_error_r.c %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/lib/string.c %buildroot/lib/modules/%kernelrelease/build/
cp -a --parents tools/lib/subcmd/* %buildroot/lib/modules/%kernelrelease/build/
popd
fi
# disable GCC plugins for external modules build, to not fail if different gcc
# version is used
sed -e 's/^\(CONFIG_GCC_PLUGIN.*\)=y/# \1 is not set/' .config > \
%buildroot/lib/modules/%kernelrelease/build/.config
sed -e '/^#define CONFIG_GCC_PLUGIN/d' include/generated/autoconf.h > \
%buildroot/lib/modules/%kernelrelease/build/include/generated/autoconf.h
# Copy .config to include/config/auto.conf so "make prepare" is unnecessary.
cp %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
# Make sure the Makefile and version.h have a matching timestamp so that
# external modules can be built
touch -r %buildroot/lib/modules/%kernelrelease/build/Makefile %buildroot/lib/modules/%kernelrelease/build/include/generated/uapi/linux/version.h
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/generated/autoconf.h
if test -s vmlinux.id; then
cp vmlinux.id %buildroot/lib/modules/%kernelrelease/build/vmlinux.id
else
echo >&2 "*** WARNING *** no vmlinux build ID! ***"
fi
#
# save the vmlinux file for kernel debugging into the kernel-debuginfo rpm
#
%if %{with_debuginfo}
mkdir -p %buildroot%{debuginfodir}/lib/modules/%kernelrelease
cp vmlinux %buildroot%{debuginfodir}/lib/modules/%kernelrelease
%endif
find %buildroot/lib/modules/%kernelrelease -name "*.ko" -type f >modnames
# mark modules executable so that strip-to-file can strip them
xargs --no-run-if-empty chmod u+x < modnames
# Generate a list of modules for block and networking.
fgrep /drivers/ modnames | xargs --no-run-if-empty nm -upA |
sed -n 's,^.*/\([^/]*\.ko\): *U \(.*\)$,\1 \2,p' > drivers.undef
collect_modules_list()
{
sed -r -n -e "s/^([^ ]+) \\.?($2)\$/\\1/p" drivers.undef |
LC_ALL=C sort -u > %buildroot/lib/modules/%kernelrelease/modules.$1
}
collect_modules_list networking \
'register_netdev|ieee80211_register_hw|usbnet_probe'
collect_modules_list block \
'ata_scsi_ioctl|scsi_add_host|scsi_add_host_with_dma|blk_init_queue|register_mtd_blktrans|scsi_esp_register|scsi_register_device_handler'
collect_modules_list drm \
'drm_open|drm_init'
collect_modules_list modesetting \
'drm_crtc_init'
# detect missing or incorrect license tags
rm -f modinfo
while read i
do
echo -n "${i#%buildroot/lib/modules/%kernelrelease/} " >> modinfo
/sbin/modinfo -l $i >> modinfo
done < modnames
egrep -v \
'GPL( v2)?$|Dual BSD/GPL$|Dual MPL/GPL$|GPL and additional rights$' \
modinfo && exit 1
rm -f modinfo modnames
# Move the devel headers out of the root file system
mkdir -p %buildroot/usr/src/kernels
mv %buildroot/lib/modules/%kernelrelease/build/* %buildroot/%src_install_dir/
mv %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/%src_install_dir
rmdir %buildroot/lib/modules/%kernelrelease/build
ln -sf %src_install_dir %buildroot/lib/modules/%kernelrelease/build
# Abort if there are any undefined symbols
msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease \
-b %buildroot -ae %kernelrelease 2>&1)"
if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then
exit 1
fi
# in case of no firmware built - place empty dir
mkdir -p %buildroot/lib/firmware
mv %buildroot/lib/firmware %buildroot/lib/firmware-all
mkdir -p %buildroot/lib/firmware
mv %buildroot/lib/firmware-all %buildroot/lib/firmware/%kernelrelease
# Prepare initramfs for Qubes VM
mkdir -p %buildroot/%vm_install_dir
PATH="/sbin:$PATH" dracut --nomdadmconf --nolvmconf \
--kmoddir %buildroot/lib/modules/%kernelrelease \
--modules "kernel-modules qubes-vm-simple" \
--conf /dev/null --confdir /var/empty \
-d "xenblk xen-blkfront cdrom ext4 jbd2 crc16 dm_snapshot" \
%buildroot/%vm_install_dir/initramfs %kernelrelease || exit 1
# workaround for buggy dracut-044 in Fedora 25
# https://bugzilla.redhat.com/show_bug.cgi?id=1431317
# https://github.com/dracutdevs/dracut/issues/194
modules_dep=$(lsinitrd "%buildroot/%vm_install_dir/initramfs" \
"usr/lib/modules/%kernelrelease/modules.dep")
if [ -z "$modules_dep" ]; then
tmpdir=$(mktemp -d)
zcat "%buildroot/%vm_install_dir/initramfs" | cpio -imd -D "$tmpdir" || exit 1
mv "$tmpdir"/%buildroot/lib/modules/%kernelrelease/kernel \
"$tmpdir"/lib/modules/%kernelrelease/ || exit 1
depmod -F %buildroot/boot/System.map-%kernelrelease \
-b "$tmpdir" -a %kernelrelease || exit 1
pushd "$tmpdir"
if [ -n "$SOURCE_DATE_EPOCH" ]; then
find . -exec touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} +
fi
find . -print0 | sort -z \
| cpio --null -R 0:0 -H newc -o --reproducible --quiet \
| gzip -n > %buildroot/%vm_install_dir/initramfs || exit 1
popd
fi
cp -p arch/x86/boot/bzImage %buildroot/%vm_install_dir/vmlinuz
# default kernel options for this kernel
def_kernelopts="root=/dev/mapper/dmroot ro nomodeset console=hvc0"
def_kernelopts="$def_kernelopts rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0"
if [ -e /usr/lib/dracut/modules.d/90qubes-vm-simple/xen-scrub-pages-supported ]; then
# set xen_scrub_pages=0 _only_ when included initramfs does support
# re-enabling it
def_kernelopts="$def_kernelopts xen_scrub_pages=0"
fi
echo "$def_kernelopts " > %buildroot/%vm_install_dir/default-kernelopts-common.txt
# Modules for Qubes VM
mkdir -p %buildroot%vm_install_dir/modules
cp -a %buildroot/lib/modules/%kernelrelease %buildroot%vm_install_dir/modules/
mkdir -p %buildroot%vm_install_dir/modules/firmware
cp -a %buildroot/lib/firmware/%kernelrelease %buildroot%vm_install_dir/modules/firmware/
# Include kernel headers for Qubes VM in "/lib/modules" - so kernel-devel
# package will be unnecessary there, regardless of distribution
rm -f %buildroot%vm_install_dir/modules/%kernelrelease/build
cp -a %buildroot/%src_install_dir %buildroot%vm_install_dir/modules/%kernelrelease/build
%if 0%{?fedora} >= 25
# include kernel+initramfs also inside modules.img, for direct kernel boot with
# stubdomain
cp %buildroot%vm_install_dir/vmlinuz %buildroot%vm_install_dir/modules/
cp %buildroot%vm_install_dir/initramfs %buildroot%vm_install_dir/modules/
if [ -n "$SOURCE_DATE_EPOCH" ]; then
find %buildroot%vm_install_dir/modules \
-exec touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} +
fi
PATH="/sbin:$PATH" mkfs.ext3 -d %buildroot%vm_install_dir/modules \
-U dcee2318-92bd-47a5-a15d-e79d1412cdce \
%buildroot%vm_install_dir/modules.img 1024M
rm -rf %buildroot%vm_install_dir/modules
%endif
# remove files that will be auto generated by depmod at rpm -i time
for i in alias alias.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap
do
rm -f %buildroot/lib/modules/%kernelrelease/modules.$i
done
%post
/sbin/depmod -a %{kernelrelease}
%posttrans
# with kernel-4.14+ plymouth detects hvc0 serial console and forces text boot
# we simply make plymouth ignore it to recover the splash screen
if [ -f /etc/default/grub ]; then
if ! grep -q plymouth.ignore-serial-consoles /etc/default/grub; then
echo 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX plymouth.ignore-serial-consoles"' >> /etc/default/grub
fi
fi
if [ -f /boot/efi/EFI/qubes/xen.cfg ]; then
if ! grep -q plymouth.ignore-serial-consoles /boot/efi/EFI/qubes/xen.cfg; then
sed -i 's/kernel=.*/& plymouth.ignore-serial-consoles/g' /boot/efi/EFI/qubes/xen.cfg
fi
fi
/bin/kernel-install add %{kernelrelease} /boot/vmlinuz-%{kernelrelease} || exit $?
# grubby (used by new-kernel-pkg) do not understand xen entries in grub2 config
if [ -x /sbin/new-kernel-pkg -a -e /boot/grub2/grub.cfg ]; then
grub2-mkconfig > /boot/grub2/grub.cfg
fi
%preun
/bin/kernel-install remove %{kernelrelease} /boot/vmlinuz-%{kernelrelease} || exit $?
%files
%defattr(-, root, root)
%ghost /boot/initramfs-%{kernelrelease}.img
/boot/System.map-%{kernelrelease}
/boot/config-%{kernelrelease}
/boot/symvers-%kernelrelease.gz
%attr(0644, root, root) /boot/vmlinuz-%{kernelrelease}
/lib/firmware/%{kernelrelease}
/lib/modules/%{kernelrelease}
%package devel
Summary: Development files necessary for building kernel modules
License: GPL v2 only
Group: Development/Sources
Provides: multiversion(kernel)
Provides: %name-devel = %kernelrelease
%if "%{?name_suffix}" != ""
Provides: kernel-devel = %kernelrelease
%endif
Provides: kernel-devel-uname-r = %kernelrelease
Requires: elfutils-libelf-devel
AutoReqProv: on
%description devel
This package contains files necessary for building kernel modules (and
kernel module packages) against the kernel.
%post devel
if [ -f /etc/sysconfig/kernel ]
then
. /etc/sysconfig/kernel || exit $?
fi
if [ "$HARDLINK" != "no" -a -x /usr/sbin/hardlink ]
then
(cd /usr/src/kernels/%{kernelrelease} &&
/usr/bin/find . -type f | while read f; do
hardlink -c /usr/src/kernels/*.fc*.*/$f $f
done)
fi
%files devel
%defattr(-,root,root)
/usr/src/kernels/%{kernelrelease}
%package qubes-vm
Summary: The Xen Kernel
Version: %{version}
Release: %{rel}
License: GPL v2 only
Group: System/Kernel
Url: http://www.kernel.org/
AutoReqProv: on
BuildRequires: coreutils module-init-tools sparse
Provides: multiversion(kernel-qubes-vm)
Provides: kernel-xen-domU
Provides: kernel-qubes-domU
Requires(pre): coreutils gawk
Requires(post): dracut
Requires(post): qubes-core-dom0
Conflicts: sysfsutils < 2.0
# root-lvm only works with newer udevs
Conflicts: udev < 118
Conflicts: lvm2 < 2.02.33
Provides: kernel-qubes-vm = %kernelrelease
%description qubes-vm
Qubes domU kernel.
%post qubes-vm
%if 0%{?fedora} < 25
mkdir /tmp/qubes-modules-%kernelrelease
truncate -s 500M /tmp/qubes-modules-%kernelrelease.img
mkfs -t ext3 -F /tmp/qubes-modules-%kernelrelease.img > /dev/null
mount /tmp/qubes-modules-%kernelrelease.img /tmp/qubes-modules-%kernelrelease -o loop
cp -a -t /tmp/qubes-modules-%kernelrelease %vm_install_dir/modules/%kernelrelease
mkdir /tmp/qubes-modules-%kernelrelease/firmware
cp -a -t /tmp/qubes-modules-%kernelrelease/firmware %vm_install_dir/modules/firmware/%kernelrelease
cp %vm_install_dir/vmlinuz /tmp/qubes-modules-%kernelrelease/
cp %vm_install_dir/initramfs /tmp/qubes-modules-%kernelrelease/
umount /tmp/qubes-modules-%kernelrelease
rmdir /tmp/qubes-modules-%kernelrelease
mv /tmp/qubes-modules-%kernelrelease.img %vm_install_dir/modules.img
%endif
current_default="$(qubes-prefs default-kernel)"
current_default_path="/var/lib/qubes/vm-kernels/$current_default"
current_default_package="$(rpm --qf '%{NAME}' -qf "$current_default_path")"
if [ "$current_default_package" = "%{name}-qubes-vm" ]; then
# Set kernel as default VM kernel if we are the default package.
# If qubes-prefs isn't installed yet, the default kernel will be set by %post
# of qubes-core-dom0
type qubes-prefs &>/dev/null && qubes-prefs --set default-kernel %upstream_version-%plainrel
fi
exit 0
%preun qubes-vm
if [ "`qubes-prefs -g default-kernel`" == "%upstream_version-%plainrel" ]; then
echo "This kernel version is set as default VM kernel, cannot remove"
exit 1
fi
if qvm-ls --kernel | grep -qw "%upstream_version-%plainrel"; then
echo "This kernel version is used by at least one VM, cannot remove"
exit 1
fi
exit 0
%files qubes-vm
%defattr(-, root, root)
%dir %vm_install_dir
%if 0%{?fedora} < 25
%ghost %attr(0644, root, root) %vm_install_dir/modules.img
%else
%attr(0644, root, root) %vm_install_dir/modules.img
%endif
%attr(0644, root, root) %vm_install_dir/initramfs
%attr(0644, root, root) %vm_install_dir/vmlinuz
%if 0%{?fedora} < 25
%vm_install_dir/modules
%endif
%attr(0644, root, root) %vm_install_dir/default-kernelopts-common.txt
%changelog
@CHANGELOG@

@ -1,37 +0,0 @@
#! /bin/bash
# The modules_sign target checks for corresponding .o files for every .ko that
# is signed. This doesn't work for package builds which re-use the same build
# directory for every flavour, and the .config may change between flavours.
# So instead of using this script to just sign lib/modules/$KernelVer/extra,
# sign all .ko in the buildroot.
# This essentially duplicates the 'modules_sign' Kbuild target and runs the
# same commands for those modules.
MODSECKEY=$1
MODPUBKEY=$2
moddir=$3
modules=`find $moddir -type f -name '*.ko'`
NPROC=`nproc`
[ -z "$NPROC" ] && NPROC=1
# NB: this loop runs 2000+ iterations. Try to be fast.
echo "$modules" | xargs -r -n16 -P $NPROC sh -c "
for mod; do
./scripts/sign-file sha256 $MODSECKEY $MODPUBKEY \$mod
rm -f \$mod.sig \$mod.dig
done
" DUMMYARG0 # xargs appends ARG1 ARG2..., which go into $mod in for loop.
RANDOMMOD=$(echo "$modules" | sort -R | head -n 1)
if [ "~Module signature appended~" != "$(tail -c 28 $RANDOMMOD)" ]; then
echo "*****************************"
echo "*** Modules are unsigned! ***"
echo "*****************************"
exit 1
fi
exit 0

@ -0,0 +1,100 @@
From b707aea6a4947c3806ced2c23e889943a0f36876 Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland@redhat.com>
Date: Mon, 6 Oct 2008 23:03:03 -0700
Subject: [PATCH] kbuild: AFTER_LINK
If the make variable AFTER_LINK is set, it is a command line to run
after each final link. This includes vmlinux itself and vDSO images.
Signed-off-by: Roland McGrath <roland@redhat.com>
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index 9a7946c..28d6765 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -41,7 +41,8 @@ $(obj-vdso32): %.o: %.S
# actual build commands
quiet_cmd_vdso32ld = VDSO32L $@
- cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@
+ cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@ \
+ $(if $(AFTER_LINK),; $(AFTER_LINK))
quiet_cmd_vdso32as = VDSO32A $@
cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index 8c500d8..d27737b 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -36,7 +36,8 @@ $(obj-vdso64): %.o: %.S
# actual build commands
quiet_cmd_vdso64ld = VDSO64L $@
- cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+ cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@ \
+ $(if $(AFTER_LINK),; $(AFTER_LINK))
quiet_cmd_vdso64as = VDSO64A $@
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index 8ad2b34..e153572 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -43,7 +43,8 @@ $(obj-vdso32): %.o: %.S
# actual build commands
quiet_cmd_vdso32ld = VDSO32L $@
- cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+ cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $^ -o $@ \
+ $(if $(AFTER_LINK),; $(AFTER_LINK))
quiet_cmd_vdso32as = VDSO32A $@
cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index 2a8ddfd..452ca53 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -43,7 +43,8 @@ $(obj-vdso64): %.o: %.S
# actual build commands
quiet_cmd_vdso64ld = VDSO64L $@
- cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+ cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@ \
+ $(if $(AFTER_LINK),; $(AFTER_LINK))
quiet_cmd_vdso64as = VDSO64A $@
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index fd14be1..1f3eb19 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -178,8 +178,9 @@ $(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
quiet_cmd_vdso = VDSO $@
cmd_vdso = $(CC) -nostdlib -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
- -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
- sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
+ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) \
+ $(if $(AFTER_LINK),; $(AFTER_LINK)) && \
+ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
$(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index cd9c6c6..3edf048 100644
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -65,6 +65,10 @@ vmlinux_link()
-lutil ${1}
rm -f linux
fi
+ if [ -n "${AFTER_LINK}" ]; then
+ /usr/lib/rpm/debugedit -b ${RPM_BUILD_DIR} -d /usr/src/debug -i ${2} \
+ > ${2}.id
+ fi
}
--
1.7.7.6

@ -0,0 +1,98 @@
From 7bfd448aed6e20757f94cc4ef74b3da763eb9c48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Sat, 21 Feb 2015 02:43:29 +0100
Subject: [PATCH] Revert "xen/xenbus: Avoid synchronous wait on XenBus stalling
shutdown/restart."
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This reverts commit 027bd7e89906a076225b23d1ca4b6702c84e72dc.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/xen/xenbus/xenbus_xs.c | 44 +++---------------------------------------
1 file changed, 3 insertions(+), 41 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index ba804f3..b6d5fff 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -50,7 +50,6 @@
#include <xen/xenbus.h>
#include <xen/xen.h>
#include "xenbus_comms.h"
-#include "xenbus_probe.h"
struct xs_stored_msg {
struct list_head list;
@@ -140,29 +139,6 @@ static int get_error(const char *errorstring)
return xsd_errors[i].errnum;
}
-static bool xenbus_ok(void)
-{
- switch (xen_store_domain_type) {
- case XS_LOCAL:
- switch (system_state) {
- case SYSTEM_POWER_OFF:
- case SYSTEM_RESTART:
- case SYSTEM_HALT:
- return false;
- default:
- break;
- }
- return true;
- case XS_PV:
- case XS_HVM:
- /* FIXME: Could check that the remote domain is alive,
- * but it is normally initial domain. */
- return true;
- default:
- break;
- }
- return false;
-}
static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
{
struct xs_stored_msg *msg;
@@ -172,20 +148,9 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
while (list_empty(&xs_state.reply_list)) {
spin_unlock(&xs_state.reply_lock);
- if (xenbus_ok())
- /* XXX FIXME: Avoid synchronous wait for response here. */
- wait_event_timeout(xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list),
- msecs_to_jiffies(500));
- else {
- /*
- * If we are in the process of being shut-down there is
- * no point of trying to contact XenBus - it is either
- * killed (xenstored application) or the other domain
- * has been killed or is unreachable.
- */
- return ERR_PTR(-EIO);
- }
+ /* XXX FIXME: Avoid synchronous wait for response here. */
+ wait_event(xs_state.reply_waitq,
+ !list_empty(&xs_state.reply_list));
spin_lock(&xs_state.reply_lock);
}
@@ -250,9 +215,6 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
mutex_unlock(&xs_state.request_mutex);
- if (IS_ERR(ret))
- return ret;
-
if ((msg->type == XS_TRANSACTION_END) ||
((req_msg.type == XS_TRANSACTION_START) &&
(msg->type == XS_ERROR)))
--
1.8.3.1

@ -0,0 +1,34 @@
From 4e3eb4f6782da3f326879622e28a5efd3a1d26bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
<marmarek@invisiblethingslab.com>
Date: Fri, 20 Mar 2015 05:08:13 +0100
Subject: [PATCH] xen: fix deadlock on /proc/xen/xenbus access
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Details here:
http://lists.xenproject.org/archives/html/xen-devel/2015-03/msg02501.html
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
drivers/xen/xenbus/xenbus_dev_frontend.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 9433e46..3d333b13 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -535,6 +535,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
return -ENOENT;
nonseekable_open(inode, filp);
+ filp->f_mode &= ~FMODE_ATOMIC_POS;
u = kzalloc(sizeof(*u), GFP_KERNEL);
if (u == NULL)
--
2.1.0

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
--- linux-3.4.1.orig/drivers/block/xen-blkfront.c 2012-06-01 09:18:44.000000000 +0200
+++ linux-3.4.1/drivers/block/xen-blkfront.c 2012-07-15 15:54:31.350255623 +0200
@@ -44,6 +44,7 @@
#include <linux/scatterlist.h>
#include <linux/bitmap.h>
#include <linux/list.h>
+#include <linux/fd.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -241,6 +264,9 @@
return 0;
return -EINVAL;
}
+ case FDEJECT:
+ xenbus_switch_state(info->xbdev, XenbusStateClosing);
+ return 0;
default:
/*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",

@ -0,0 +1,26 @@
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4e86393..34493d7 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1188,7 +1188,7 @@ static void blkfront_connect(struct blkfront_info *info)
unsigned int physical_sector_size;
unsigned int binfo;
int err;
- int barrier, flush, discard, persistent;
+ int barrier, flush, discard, persistent, removable;
switch (info->connected) {
case BLKIF_STATE_CONNECTED:
@@ -1266,6 +1266,12 @@ static void blkfront_connect(struct blkfront_info *info)
if (!err && discard)
blkfront_setup_discard(info);
+ err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+ "removable", "%d", &removable,
+ NULL);
+ if (!err && removable)
+ binfo |= VDISK_REMOVABLE;
+
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
"feature-persistent", "%u", &persistent,
NULL);

2
pkgs/.gitignore vendored

@ -1,2 +0,0 @@
dom0-*/
fc*

1
rel

@ -1 +0,0 @@
1

@ -0,0 +1,9 @@
patches.rpmify/makefile-after_link.patch
patches.xen/0001-Revert-xen-xenbus-Avoid-synchronous-wait-on-XenBus-s.patch
patches.xen/0001-xen-fix-deadlock-on-proc-xen-xenbus-access.patch
# Additional features
#patches.xen/pvops-0100-usb-xen-pvusb-driver.patch
patches.xen/pvops-blkfront-removable-flag.patch
patches.xen/pvops-blkfront-eject-support.patch

@ -1,23 +0,0 @@
0001-kbuild-AFTER_LINK.patch
0002-xen-netfront-detach-crash.patch
0003-mce-hide-EBUSY-initialization-error-on-Xen.patch
0004-Log-error-code-of-EVTCHNOP_bind_pirq-failure.patch
# Additional features
0005-pvops-respect-removable-xenstore-flag-for-block-devi.patch
0006-pvops-xen-blkfront-handle-FDEJECT-as-detach-request-.patch
0007-block-add-no_part_scan-module-parameter.patch
# Security fixes
0008-xen-Add-RING_COPY_RESPONSE.patch
0009-xen-netfront-copy-response-out-of-shared-buffer-befo.patch
0010-xen-netfront-do-not-use-data-already-exposed-to-back.patch
0011-xen-netfront-add-range-check-for-Tx-response-id.patch
0012-xen-blkfront-make-local-copy-of-response-before-usin.patch
0013-xen-blkfront-prepare-request-locally-only-then-put-i.patch
# MSI-X enabled device passthrough fix (#1734)
0014-xen-pcifront-pciback-Update-pciif.h-with-err-and-res.patch
# Fix for MSI support with stubdoms
0015-xen-pciback-add-attribute-to-allow-MSI-enable-flag-w.patch

@ -1 +0,0 @@
5.4.16

@ -0,0 +1 @@
3.19.3

@ -1,446 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
P1KnZADhMyvGjSc88Ko=
=Njos
-----END PGP PUBLIC KEY BLOCK-----
Loading…
Cancel
Save