Skip to content

Commit fcaa0ad

Browse files
committed
Merge tag 'for-linus-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML updates from Richard Weinberger: - Fixes for our new virtio code - Fix for the irqflags tracer - Kconfig coding style fixes - Allow BPF firmware loading in our vector driver * tag 'for-linus-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: um: Loadable BPF "Firmware" for vector drivers um: Fix Kconfig indentation um: virtio_uml: Disallow modular build um: virtio: Keep reading on -EAGAIN um: virtio: Remove device on disconnect um: Don't trace irqflags during shutdown
2 parents e3a251e + 9807019 commit fcaa0ad

File tree

8 files changed

+247
-58
lines changed

8 files changed

+247
-58
lines changed

arch/um/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ config KERNEL_STACK_ORDER
153153
It is possible to reduce the stack to 1 for 64BIT and 0 for 32BIT on
154154
older (pre-2017) CPUs. It is not recommended on newer CPUs due to the
155155
increase in the size of the state which needs to be saved when handling
156-
signals.
156+
signals.
157157

158158
config MMAPPER
159159
tristate "iomem emulation driver"

arch/um/drivers/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ config UML_NET_SLIRP
337337
endmenu
338338

339339
config VIRTIO_UML
340-
tristate "UML driver for virtio devices"
340+
bool "UML driver for virtio devices"
341341
select VIRTIO
342342
help
343343
This driver provides support for virtio based paravirtual device

arch/um/drivers/vector_kern.c

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/*
3-
* Copyright (C) 2017 - Cambridge Greys Limited
3+
* Copyright (C) 2017 - 2019 Cambridge Greys Limited
44
* Copyright (C) 2011 - 2014 Cisco Systems Inc
55
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
66
* Copyright (C) 2001 Lennert Buytenhek ([email protected]) and
@@ -21,6 +21,9 @@
2121
#include <linux/skbuff.h>
2222
#include <linux/slab.h>
2323
#include <linux/interrupt.h>
24+
#include <linux/firmware.h>
25+
#include <linux/fs.h>
26+
#include <uapi/linux/filter.h>
2427
#include <init.h>
2528
#include <irq_kern.h>
2629
#include <irq_user.h>
@@ -128,6 +131,23 @@ static int get_mtu(struct arglist *def)
128131
return ETH_MAX_PACKET;
129132
}
130133

134+
static char *get_bpf_file(struct arglist *def)
135+
{
136+
return uml_vector_fetch_arg(def, "bpffile");
137+
}
138+
139+
static bool get_bpf_flash(struct arglist *def)
140+
{
141+
char *allow = uml_vector_fetch_arg(def, "bpfflash");
142+
long result;
143+
144+
if (allow != NULL) {
145+
if (kstrtoul(allow, 10, &result) == 0)
146+
return (allow > 0);
147+
}
148+
return false;
149+
}
150+
131151
static int get_depth(struct arglist *def)
132152
{
133153
char *mtu = uml_vector_fetch_arg(def, "depth");
@@ -176,6 +196,7 @@ static int get_transport_options(struct arglist *def)
176196
int vec_rx = VECTOR_RX;
177197
int vec_tx = VECTOR_TX;
178198
long parsed;
199+
int result = 0;
179200

180201
if (vector != NULL) {
181202
if (kstrtoul(vector, 10, &parsed) == 0) {
@@ -186,14 +207,16 @@ static int get_transport_options(struct arglist *def)
186207
}
187208
}
188209

210+
if (get_bpf_flash(def))
211+
result = VECTOR_BPF_FLASH;
189212

190213
if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
191-
return 0;
214+
return result;
192215
if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
193-
return (vec_rx | VECTOR_BPF);
216+
return (result | vec_rx | VECTOR_BPF);
194217
if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
195-
return (vec_rx | vec_tx | VECTOR_QDISC_BYPASS);
196-
return (vec_rx | vec_tx);
218+
return (result | vec_rx | vec_tx | VECTOR_QDISC_BYPASS);
219+
return (result | vec_rx | vec_tx);
197220
}
198221

199222

@@ -1139,14 +1162,19 @@ static int vector_net_close(struct net_device *dev)
11391162
}
11401163
tasklet_kill(&vp->tx_poll);
11411164
if (vp->fds->rx_fd > 0) {
1165+
if (vp->bpf)
1166+
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
11421167
os_close_file(vp->fds->rx_fd);
11431168
vp->fds->rx_fd = -1;
11441169
}
11451170
if (vp->fds->tx_fd > 0) {
11461171
os_close_file(vp->fds->tx_fd);
11471172
vp->fds->tx_fd = -1;
11481173
}
1174+
if (vp->bpf != NULL)
1175+
kfree(vp->bpf->filter);
11491176
kfree(vp->bpf);
1177+
vp->bpf = NULL;
11501178
kfree(vp->fds->remote_addr);
11511179
kfree(vp->transport_data);
11521180
kfree(vp->header_rxbuffer);
@@ -1181,6 +1209,7 @@ static void vector_reset_tx(struct work_struct *work)
11811209
netif_start_queue(vp->dev);
11821210
netif_wake_queue(vp->dev);
11831211
}
1212+
11841213
static int vector_net_open(struct net_device *dev)
11851214
{
11861215
struct vector_private *vp = netdev_priv(dev);
@@ -1196,6 +1225,8 @@ static int vector_net_open(struct net_device *dev)
11961225
vp->opened = true;
11971226
spin_unlock_irqrestore(&vp->lock, flags);
11981227

1228+
vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
1229+
11991230
vp->fds = uml_vector_user_open(vp->unit, vp->parsed);
12001231

12011232
if (vp->fds == NULL)
@@ -1267,8 +1298,11 @@ static int vector_net_open(struct net_device *dev)
12671298
if (!uml_raw_enable_qdisc_bypass(vp->fds->rx_fd))
12681299
vp->options |= VECTOR_BPF;
12691300
}
1270-
if ((vp->options & VECTOR_BPF) != 0)
1271-
vp->bpf = uml_vector_default_bpf(vp->fds->rx_fd, dev->dev_addr);
1301+
if (((vp->options & VECTOR_BPF) != 0) && (vp->bpf == NULL))
1302+
vp->bpf = uml_vector_default_bpf(dev->dev_addr);
1303+
1304+
if (vp->bpf != NULL)
1305+
uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
12721306

12731307
netif_start_queue(dev);
12741308

@@ -1347,6 +1381,65 @@ static void vector_net_get_drvinfo(struct net_device *dev,
13471381
strlcpy(info->version, DRIVER_VERSION, sizeof(info->version));
13481382
}
13491383

1384+
static int vector_net_load_bpf_flash(struct net_device *dev,
1385+
struct ethtool_flash *efl)
1386+
{
1387+
struct vector_private *vp = netdev_priv(dev);
1388+
struct vector_device *vdevice;
1389+
const struct firmware *fw;
1390+
int result = 0;
1391+
1392+
if (!(vp->options & VECTOR_BPF_FLASH)) {
1393+
netdev_err(dev, "loading firmware not permitted: %s\n", efl->data);
1394+
return -1;
1395+
}
1396+
1397+
spin_lock(&vp->lock);
1398+
1399+
if (vp->bpf != NULL) {
1400+
if (vp->opened)
1401+
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
1402+
kfree(vp->bpf->filter);
1403+
vp->bpf->filter = NULL;
1404+
} else {
1405+
vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
1406+
if (vp->bpf == NULL) {
1407+
netdev_err(dev, "failed to allocate memory for firmware\n");
1408+
goto flash_fail;
1409+
}
1410+
}
1411+
1412+
vdevice = find_device(vp->unit);
1413+
1414+
if (request_firmware(&fw, efl->data, &vdevice->pdev.dev))
1415+
goto flash_fail;
1416+
1417+
vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_KERNEL);
1418+
if (!vp->bpf->filter)
1419+
goto free_buffer;
1420+
1421+
vp->bpf->len = fw->size / sizeof(struct sock_filter);
1422+
release_firmware(fw);
1423+
1424+
if (vp->opened)
1425+
result = uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
1426+
1427+
spin_unlock(&vp->lock);
1428+
1429+
return result;
1430+
1431+
free_buffer:
1432+
release_firmware(fw);
1433+
1434+
flash_fail:
1435+
spin_unlock(&vp->lock);
1436+
if (vp->bpf != NULL)
1437+
kfree(vp->bpf->filter);
1438+
kfree(vp->bpf);
1439+
vp->bpf = NULL;
1440+
return -1;
1441+
}
1442+
13501443
static void vector_get_ringparam(struct net_device *netdev,
13511444
struct ethtool_ringparam *ring)
13521445
{
@@ -1424,6 +1517,7 @@ static const struct ethtool_ops vector_net_ethtool_ops = {
14241517
.get_ethtool_stats = vector_get_ethtool_stats,
14251518
.get_coalesce = vector_get_coalesce,
14261519
.set_coalesce = vector_set_coalesce,
1520+
.flash_device = vector_net_load_bpf_flash,
14271521
};
14281522

14291523

@@ -1528,8 +1622,9 @@ static void vector_eth_configure(
15281622
.in_write_poll = false,
15291623
.coalesce = 2,
15301624
.req_size = get_req_size(def),
1531-
.in_error = false
1532-
});
1625+
.in_error = false,
1626+
.bpf = NULL
1627+
});
15331628

15341629
dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST);
15351630
tasklet_init(&vp->tx_poll, vector_tx_poll, (unsigned long)vp);

arch/um/drivers/vector_kern.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@
2929
#define VECTOR_TX (1 << 1)
3030
#define VECTOR_BPF (1 << 2)
3131
#define VECTOR_QDISC_BYPASS (1 << 3)
32+
#define VECTOR_BPF_FLASH (1 << 4)
3233

3334
#define ETH_MAX_PACKET 1500
3435
#define ETH_HEADER_OTHER 32 /* just in case someone decides to go mad on QnQ */
3536

37+
#define MAX_FILTER_PROG (2 << 16)
38+
3639
struct vector_queue {
3740
struct mmsghdr *mmsg_vector;
3841
void **skbuff_vector;
@@ -118,10 +121,13 @@ struct vector_private {
118121
bool in_write_poll;
119122
bool in_error;
120123

124+
/* guest allowed to use ethtool flash to load bpf */
125+
bool bpf_via_flash;
126+
121127
/* ethtool stats */
122128

123129
struct vector_estats estats;
124-
void *bpf;
130+
struct sock_fprog *bpf;
125131

126132
char user[0];
127133
};

arch/um/drivers/vector_user.c

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
#define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
4747
#define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
4848
#define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
49-
#define BPF_ATTACH_FAIL "Failed to attach filter size %d to %d, err %d\n"
49+
#define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n"
50+
#define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n"
5051

5152
#define MAX_UN_LEN 107
5253

@@ -660,31 +661,44 @@ int uml_vector_recvmmsg(
660661
else
661662
return -errno;
662663
}
663-
int uml_vector_attach_bpf(int fd, void *bpf, int bpf_len)
664+
int uml_vector_attach_bpf(int fd, void *bpf)
664665
{
665-
int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, bpf_len);
666+
struct sock_fprog *prog = bpf;
667+
668+
int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(struct sock_fprog));
666669

667670
if (err < 0)
668-
printk(KERN_ERR BPF_ATTACH_FAIL, bpf_len, fd, -errno);
671+
printk(KERN_ERR BPF_ATTACH_FAIL, prog->len, prog->filter, fd, -errno);
669672
return err;
670673
}
671674

672-
#define DEFAULT_BPF_LEN 6
675+
int uml_vector_detach_bpf(int fd, void *bpf)
676+
{
677+
struct sock_fprog *prog = bpf;
673678

674-
void *uml_vector_default_bpf(int fd, void *mac)
679+
int err = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, bpf, sizeof(struct sock_fprog));
680+
if (err < 0)
681+
printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno);
682+
return err;
683+
}
684+
void *uml_vector_default_bpf(void *mac)
675685
{
676686
struct sock_filter *bpf;
677687
uint32_t *mac1 = (uint32_t *)(mac + 2);
678688
uint16_t *mac2 = (uint16_t *) mac;
679-
struct sock_fprog bpf_prog = {
680-
.len = 6,
681-
.filter = NULL,
682-
};
689+
struct sock_fprog *bpf_prog;
683690

691+
bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
692+
if (bpf_prog) {
693+
bpf_prog->len = DEFAULT_BPF_LEN;
694+
bpf_prog->filter = NULL;
695+
} else {
696+
return NULL;
697+
}
684698
bpf = uml_kmalloc(
685699
sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
686-
if (bpf != NULL) {
687-
bpf_prog.filter = bpf;
700+
if (bpf) {
701+
bpf_prog->filter = bpf;
688702
/* ld [8] */
689703
bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
690704
/* jeq #0xMAC[2-6] jt 2 jf 5*/
@@ -697,12 +711,56 @@ void *uml_vector_default_bpf(int fd, void *mac)
697711
bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
698712
/* ret #0x40000 */
699713
bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
700-
if (uml_vector_attach_bpf(
701-
fd, &bpf_prog, sizeof(struct sock_fprog)) < 0) {
702-
kfree(bpf);
703-
bpf = NULL;
704-
}
714+
} else {
715+
kfree(bpf_prog);
716+
bpf_prog = NULL;
705717
}
706-
return bpf;
718+
return bpf_prog;
707719
}
708720

721+
/* Note - this function requires a valid mac being passed as an arg */
722+
723+
void *uml_vector_user_bpf(char *filename)
724+
{
725+
struct sock_filter *bpf;
726+
struct sock_fprog *bpf_prog;
727+
struct stat statbuf;
728+
int res, ffd = -1;
729+
730+
if (filename == NULL)
731+
return NULL;
732+
733+
if (stat(filename, &statbuf) < 0) {
734+
printk(KERN_ERR "Error %d reading bpf file", -errno);
735+
return false;
736+
}
737+
bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
738+
if (bpf_prog != NULL) {
739+
bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter);
740+
bpf_prog->filter = NULL;
741+
}
742+
ffd = os_open_file(filename, of_read(OPENFLAGS()), 0);
743+
if (ffd < 0) {
744+
printk(KERN_ERR "Error %d opening bpf file", -errno);
745+
goto bpf_failed;
746+
}
747+
bpf = uml_kmalloc(statbuf.st_size, UM_GFP_KERNEL);
748+
if (bpf == NULL) {
749+
printk(KERN_ERR "Failed to allocate bpf buffer");
750+
goto bpf_failed;
751+
}
752+
bpf_prog->filter = bpf;
753+
res = os_read_file(ffd, bpf, statbuf.st_size);
754+
if (res < statbuf.st_size) {
755+
printk(KERN_ERR "Failed to read bpf program %s, error %d", filename, res);
756+
kfree(bpf);
757+
goto bpf_failed;
758+
}
759+
os_close_file(ffd);
760+
return bpf_prog;
761+
bpf_failed:
762+
if (ffd > 0)
763+
os_close_file(ffd);
764+
kfree(bpf_prog);
765+
return NULL;
766+
}

0 commit comments

Comments
 (0)