summaryrefslogtreecommitdiffstats
path: root/meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch
diff options
context:
space:
mode:
authorJakub Luzny <jakub@luzny.cz>2020-07-19 17:00:08 +0200
committerJakub Luzny <jakub@luzny.cz>2020-07-24 12:46:57 +0200
commit3f6d193683449a323a3f1d689540ab697d3d7980 (patch)
tree093ad36c5bf3f031d469a635d0f2190a57c176e0 /meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch
parentc6889de97c1af6baa7ee8006aa75da170c9bd407 (diff)
Add layer to support Jailhouse hypervisorjellyfish_9.99.2jellyfish/9.99.29.99.2
Jailhouse is a partitioning hypervisor based on Linux. It is able to run bare-metal applications or (adapted) operating systems besides Linux. For this purpose, it configures CPU and device virtualization features of the hardware platform in a way that none of these domains, called "cells" here, can interfere with each other in an unacceptable way. This layer adds the Jailhouse package into AGL and also appends the BSPs to allow it to run. Currently, Raspberry Pi 4 and QEMU x86-64 targets are supported. To enable Jailhouse and include it in the image, the AGL feature agl-jailhouse must be enabled. Bug-AGL: SPEC-3507 Signed-off-by: Jakub Luzny <jakub@luzny.cz> Change-Id: I0fbc0b5d931c85d6f22b0222da8c2b106c4115e1
Diffstat (limited to 'meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch')
-rw-r--r--meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch b/meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch
new file mode 100644
index 00000000..ecb5c485
--- /dev/null
+++ b/meta-agl-jailhouse/recipes-kernel/linux/linux/0015-ivshmem-net-fix-race-in-state-machine.patch
@@ -0,0 +1,140 @@
+From 1349a457e5e33580fb26afab087e6b932b1a4372 Mon Sep 17 00:00:00 2001
+From: Mans Rullgard <mans@mansr.com>
+Date: Thu, 24 Nov 2016 18:46:41 +0000
+Subject: [PATCH 15/32] ivshmem-net: fix race in state machine
+
+---
+ drivers/net/ivshmem-net.c | 60 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 31 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ivshmem-net.c b/drivers/net/ivshmem-net.c
+index a535cb71adde..acd00e47acd7 100644
+--- a/drivers/net/ivshmem-net.c
++++ b/drivers/net/ivshmem-net.c
+@@ -36,6 +36,8 @@
+ #define IVSHM_NET_STATE_READY 2
+ #define IVSHM_NET_STATE_RUN 3
+
++#define IVSHM_NET_FLAG_RUN 0
++
+ #define IVSHM_NET_MTU_MIN 256
+ #define IVSHM_NET_MTU_MAX 65535
+ #define IVSHM_NET_MTU_DEF 16384
+@@ -96,6 +98,8 @@ struct ivshm_net {
+ u32 lstate;
+ u32 rstate;
+
++ unsigned long flags;
++
+ struct workqueue_struct *state_wq;
+ struct work_struct state_work;
+
+@@ -529,12 +533,32 @@ static void ivshm_net_run(struct net_device *ndev)
+ {
+ struct ivshm_net *in = netdev_priv(ndev);
+
++ if (in->lstate < IVSHM_NET_STATE_READY)
++ return;
++
++ if (!netif_running(ndev))
++ return;
++
++ if (test_and_set_bit(IVSHM_NET_FLAG_RUN, &in->flags))
++ return;
++
+ netif_start_queue(ndev);
+ napi_enable(&in->napi);
+ napi_schedule(&in->napi);
+ ivshm_net_set_state(in, IVSHM_NET_STATE_RUN);
+ }
+
++static void ivshm_net_do_stop(struct net_device *ndev)
++{
++ struct ivshm_net *in = netdev_priv(ndev);
++
++ if (!test_and_clear_bit(IVSHM_NET_FLAG_RUN, &in->flags))
++ return;
++
++ netif_stop_queue(ndev);
++ napi_disable(&in->napi);
++}
++
+ static void ivshm_net_state_change(struct work_struct *work)
+ {
+ struct ivshm_net *in = container_of(work, struct ivshm_net, state_work);
+@@ -560,21 +584,13 @@ static void ivshm_net_state_change(struct work_struct *work)
+ break;
+
+ case IVSHM_NET_STATE_READY:
++ case IVSHM_NET_STATE_RUN:
+ if (rstate >= IVSHM_NET_STATE_READY) {
+ netif_carrier_on(ndev);
+- if (ndev->flags & IFF_UP)
+- ivshm_net_run(ndev);
++ ivshm_net_run(ndev);
+ } else {
+ netif_carrier_off(ndev);
+- ivshm_net_set_state(in, IVSHM_NET_STATE_RESET);
+- }
+- break;
+-
+- case IVSHM_NET_STATE_RUN:
+- if (rstate < IVSHM_NET_STATE_READY) {
+- netif_stop_queue(ndev);
+- napi_disable(&in->napi);
+- netif_carrier_off(ndev);
++ ivshm_net_do_stop(ndev);
+ ivshm_net_set_state(in, IVSHM_NET_STATE_RESET);
+ }
+ break;
+@@ -584,18 +600,13 @@ static void ivshm_net_state_change(struct work_struct *work)
+ WRITE_ONCE(in->rstate, rstate);
+ }
+
+-static bool ivshm_net_check_state(struct net_device *ndev)
++static void ivshm_net_check_state(struct net_device *ndev)
+ {
+ struct ivshm_net *in = netdev_priv(ndev);
+ u32 rstate = readl(&in->ivshm_regs->rstate);
+
+- if (rstate != READ_ONCE(in->rstate) ||
+- in->lstate != IVSHM_NET_STATE_RUN) {
++ if (rstate != in->rstate || !test_bit(IVSHM_NET_FLAG_RUN, &in->flags))
+ queue_work(in->state_wq, &in->state_work);
+- return false;
+- }
+-
+- return true;
+ }
+
+ static irqreturn_t ivshm_net_int(int irq, void *data)
+@@ -617,24 +628,15 @@ static int ivshm_net_open(struct net_device *ndev)
+
+ netdev_reset_queue(ndev);
+ ndev->operstate = IF_OPER_UP;
+-
+- if (in->lstate == IVSHM_NET_STATE_READY)
+- ivshm_net_run(ndev);
++ ivshm_net_run(ndev);
+
+ return 0;
+ }
+
+ static int ivshm_net_stop(struct net_device *ndev)
+ {
+- struct ivshm_net *in = netdev_priv(ndev);
+-
+ ndev->operstate = IF_OPER_DOWN;
+-
+- if (in->lstate == IVSHM_NET_STATE_RUN) {
+- napi_disable(&in->napi);
+- netif_stop_queue(ndev);
+- ivshm_net_set_state(in, IVSHM_NET_STATE_READY);
+- }
++ ivshm_net_do_stop(ndev);
+
+ return 0;
+ }
+--
+2.11.0
+