Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

- Improve support for non-glibc systems

- Vector: Add support for scripting and dynamic tap devices

- Various fixes for the vector networking driver

- Various fixes for time travel mode

* tag 'for-linus-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: vector: Add dynamic tap interfaces and scripting
um: Clean up stacktrace dump
um: Fix incorrect assumptions about max pid length
um: Remove dead usage of TIF_IA32
um: Remove redundant NULL check
um: change sigio_spinlock to a mutex
um: time-travel: Return the sequence number in ACK messages
um: time-travel: Fix IRQ handling in time_travel_handle_message()
um: Allow static linking for non-glibc implementations
um: Some fixes to build UML with musl
um: vector: Use GFP_ATOMIC under spin lock
um: Fix null pointer dereference in vector_user_bpf

+91 -61
+3 -3
arch/um/Kconfig
··· 62 62 63 63 source "arch/$(HEADER_ARCH)/um/Kconfig" 64 64 65 - config FORBID_STATIC_LINK 66 - bool 65 + config MAY_HAVE_RUNTIME_DEPS 66 + bool 67 67 68 68 config STATIC_LINK 69 69 bool "Force a static link" 70 - depends on !FORBID_STATIC_LINK 70 + depends on CC_CAN_LINK_STATIC_NO_RUNTIME_DEPS || !MAY_HAVE_RUNTIME_DEPS 71 71 help 72 72 This option gives you the ability to force a static link of UML. 73 73 Normally, UML is linked as a shared binary. This is inconvenient for
+3 -3
arch/um/drivers/Kconfig
··· 234 234 config UML_NET_VECTOR 235 235 bool "Vector I/O high performance network devices" 236 236 depends on UML_NET 237 - select FORBID_STATIC_LINK 237 + select MAY_HAVE_RUNTIME_DEPS 238 238 help 239 239 This User-Mode Linux network driver uses multi-message send 240 240 and receive functions. The host running the UML guest must have ··· 246 246 config UML_NET_VDE 247 247 bool "VDE transport (obsolete)" 248 248 depends on UML_NET 249 - select FORBID_STATIC_LINK 249 + select MAY_HAVE_RUNTIME_DEPS 250 250 help 251 251 This User-Mode Linux network transport allows one or more running 252 252 UMLs on a single host to communicate with each other and also ··· 294 294 config UML_NET_PCAP 295 295 bool "pcap transport (obsolete)" 296 296 depends on UML_NET 297 - select FORBID_STATIC_LINK 297 + select MAY_HAVE_RUNTIME_DEPS 298 298 help 299 299 The pcap transport makes a pcap packet stream on the host look 300 300 like an ethernet device inside UML. This is useful for making
+1
arch/um/drivers/daemon_user.c
··· 7 7 */ 8 8 9 9 #include <stdint.h> 10 + #include <string.h> 10 11 #include <unistd.h> 11 12 #include <errno.h> 12 13 #include <sys/types.h>
+6 -6
arch/um/drivers/pcap_user.c
··· 32 32 return 0; 33 33 } 34 34 35 - static int pcap_open(void *data) 35 + static int pcap_user_open(void *data) 36 36 { 37 37 struct pcap_data *pri = data; 38 38 __u32 netmask; ··· 44 44 if (pri->filter != NULL) { 45 45 err = dev_netmask(pri->dev, &netmask); 46 46 if (err < 0) { 47 - printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); 47 + printk(UM_KERN_ERR "pcap_user_open : dev_netmask failed\n"); 48 48 return -EIO; 49 49 } 50 50 51 51 pri->compiled = uml_kmalloc(sizeof(struct bpf_program), 52 52 UM_GFP_KERNEL); 53 53 if (pri->compiled == NULL) { 54 - printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); 54 + printk(UM_KERN_ERR "pcap_user_open : kmalloc failed\n"); 55 55 return -ENOMEM; 56 56 } 57 57 ··· 59 59 (struct bpf_program *) pri->compiled, 60 60 pri->filter, pri->optimize, netmask); 61 61 if (err < 0) { 62 - printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " 62 + printk(UM_KERN_ERR "pcap_user_open : pcap_compile failed - " 63 63 "'%s'\n", pcap_geterr(pri->pcap)); 64 64 goto out; 65 65 } 66 66 67 67 err = pcap_setfilter(pri->pcap, pri->compiled); 68 68 if (err < 0) { 69 - printk(UM_KERN_ERR "pcap_open : pcap_setfilter " 69 + printk(UM_KERN_ERR "pcap_user_open : pcap_setfilter " 70 70 "failed - '%s'\n", pcap_geterr(pri->pcap)); 71 71 goto out; 72 72 } ··· 127 127 128 128 const struct net_user_info pcap_user_info = { 129 129 .init = pcap_user_init, 130 - .open = pcap_open, 130 + .open = pcap_user_open, 131 131 .close = NULL, 132 132 .remove = pcap_remove, 133 133 .add_address = NULL,
+1 -1
arch/um/drivers/slip_user.c
··· 9 9 #include <errno.h> 10 10 #include <fcntl.h> 11 11 #include <string.h> 12 - #include <sys/termios.h> 12 + #include <termios.h> 13 13 #include <sys/wait.h> 14 14 #include <net_user.h> 15 15 #include <os.h>
+2 -2
arch/um/drivers/vector_kern.c
··· 1403 1403 kfree(vp->bpf->filter); 1404 1404 vp->bpf->filter = NULL; 1405 1405 } else { 1406 - vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL); 1406 + vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC); 1407 1407 if (vp->bpf == NULL) { 1408 1408 netdev_err(dev, "failed to allocate memory for firmware\n"); 1409 1409 goto flash_fail; ··· 1415 1415 if (request_firmware(&fw, efl->data, &vdevice->pdev.dev)) 1416 1416 goto flash_fail; 1417 1417 1418 - vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_KERNEL); 1418 + vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_ATOMIC); 1419 1419 if (!vp->bpf->filter) 1420 1420 goto free_buffer; 1421 1421
+54 -17
arch/um/drivers/vector_user.c
··· 18 18 #include <fcntl.h> 19 19 #include <sys/socket.h> 20 20 #include <sys/un.h> 21 - #include <net/ethernet.h> 22 21 #include <netinet/ip.h> 23 - #include <netinet/ether.h> 24 22 #include <linux/if_ether.h> 25 23 #include <linux/if_packet.h> 26 24 #include <sys/wait.h> ··· 37 39 #define ID_MAX 2 38 40 39 41 #define TOKEN_IFNAME "ifname" 42 + #define TOKEN_SCRIPT "ifup" 40 43 41 44 #define TRANS_RAW "raw" 42 45 #define TRANS_RAW_LEN strlen(TRANS_RAW) ··· 53 54 #define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n" 54 55 55 56 #define MAX_UN_LEN 107 57 + 58 + static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 59 + static const char *template = "tapXXXXXX"; 56 60 57 61 /* This is very ugly and brute force lookup, but it is done 58 62 * only once at initialization so not worth doing hashes or ··· 193 191 return err; 194 192 } 195 193 194 + 196 195 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) 197 196 { 198 - int fd = -1; 197 + int fd = -1, i; 199 198 char *iface; 200 199 struct vector_fds *result = NULL; 200 + bool dynamic = false; 201 + char dynamic_ifname[IFNAMSIZ]; 202 + char *argv[] = {NULL, NULL, NULL, NULL}; 201 203 202 204 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 203 205 if (iface == NULL) { 204 - printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); 205 - goto tap_cleanup; 206 + dynamic = true; 207 + iface = dynamic_ifname; 208 + srand(getpid()); 206 209 } 207 210 208 211 result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); ··· 221 214 result->remote_addr_size = 0; 222 215 223 216 /* TAP */ 217 + do { 218 + if (dynamic) { 219 + strcpy(iface, template); 220 + for (i = 0; i < strlen(iface); i++) { 221 + if (iface[i] == 'X') { 222 + iface[i] = padchar[rand() % strlen(padchar)]; 223 + } 224 + } 225 + } 226 + fd = create_tap_fd(iface); 227 + if ((fd < 0) && (!dynamic)) { 228 + printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); 229 + goto tap_cleanup; 230 + } 231 + result->tx_fd = fd; 232 + result->rx_fd = fd; 233 + } while (fd < 0); 224 234 225 - fd = create_tap_fd(iface); 226 - if (fd < 0) { 227 - printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); 228 - goto tap_cleanup; 235 + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 236 + if (argv[0]) { 237 + argv[1] = iface; 238 + run_helper(NULL, NULL, argv); 229 239 } 230 - result->tx_fd = fd; 231 - result->rx_fd = fd; 240 + 232 241 return result; 233 242 tap_cleanup: 234 243 printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); ··· 256 233 { 257 234 char *iface; 258 235 struct vector_fds *result = NULL; 236 + char *argv[] = {NULL, NULL, NULL, NULL}; 259 237 260 238 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 261 239 if (iface == NULL) { ··· 289 265 printk(UM_KERN_ERR 290 266 "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); 291 267 goto hybrid_cleanup; 268 + } 269 + 270 + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 271 + if (argv[0]) { 272 + argv[1] = iface; 273 + run_helper(NULL, NULL, argv); 292 274 } 293 275 return result; 294 276 hybrid_cleanup: ··· 362 332 } 363 333 switch (id) { 364 334 case ID_BESS: 365 - if (connect(fd, remote_addr, sizeof(struct sockaddr_un)) < 0) { 335 + if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) { 366 336 printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno); 367 337 goto unix_cleanup; 368 338 } ··· 429 399 fd_cleanup: 430 400 if (fd >= 0) 431 401 os_close_file(fd); 432 - if (result != NULL) 433 - kfree(result); 402 + kfree(result); 434 403 return NULL; 435 404 } 436 405 ··· 439 410 int err = -ENOMEM; 440 411 char *iface; 441 412 struct vector_fds *result = NULL; 413 + char *argv[] = {NULL, NULL, NULL, NULL}; 442 414 443 415 iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); 444 416 if (iface == NULL) ··· 461 431 result->tx_fd = txfd; 462 432 result->remote_addr = NULL; 463 433 result->remote_addr_size = 0; 434 + } 435 + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); 436 + if (argv[0]) { 437 + argv[1] = iface; 438 + run_helper(NULL, NULL, argv); 464 439 } 465 440 return result; 466 441 raw_cleanup: ··· 824 789 return false; 825 790 } 826 791 bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL); 827 - if (bpf_prog != NULL) { 828 - bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); 829 - bpf_prog->filter = NULL; 792 + if (bpf_prog == NULL) { 793 + printk(KERN_ERR "Failed to allocate bpf prog buffer"); 794 + return NULL; 830 795 } 796 + bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); 797 + bpf_prog->filter = NULL; 831 798 ffd = os_open_file(filename, of_read(OPENFLAGS()), 0); 832 799 if (ffd < 0) { 833 800 printk(KERN_ERR "Error %d opening bpf file", -errno);
+3 -3
arch/um/kernel/sigio.c
··· 35 35 } 36 36 37 37 /* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ 38 - static DEFINE_SPINLOCK(sigio_spinlock); 38 + static DEFINE_MUTEX(sigio_mutex); 39 39 40 40 void sigio_lock(void) 41 41 { 42 - spin_lock(&sigio_spinlock); 42 + mutex_lock(&sigio_mutex); 43 43 } 44 44 45 45 void sigio_unlock(void) 46 46 { 47 - spin_unlock(&sigio_spinlock); 47 + mutex_unlock(&sigio_mutex); 48 48 }
+1 -3
arch/um/kernel/sysrq.c
··· 47 47 if (kstack_end(stack)) 48 48 break; 49 49 if (i && ((i % STACKSLOTS_PER_LINE) == 0)) 50 - printk("%s\n", loglvl); 50 + pr_cont("\n"); 51 51 pr_cont(" %08lx", *stack++); 52 52 } 53 - printk("%s\n", loglvl); 54 53 55 54 printk("%sCall Trace:\n", loglvl); 56 55 dump_trace(current, &stackops, (void *)loglvl); 57 - printk("%s\n", loglvl); 58 56 }
+10 -5
arch/um/kernel/time.c
··· 70 70 * read of the message and write of the ACK. 71 71 */ 72 72 if (mode != TTMH_READ) { 73 + bool disabled = irqs_disabled(); 74 + 75 + BUG_ON(mode == TTMH_IDLE && !disabled); 76 + 77 + if (disabled) 78 + local_irq_enable(); 73 79 while (os_poll(1, &time_travel_ext_fd) != 0) { 74 - if (mode == TTMH_IDLE) { 75 - BUG_ON(!irqs_disabled()); 76 - local_irq_enable(); 77 - local_irq_disable(); 78 - } 80 + /* nothing */ 79 81 } 82 + if (disabled) 83 + local_irq_disable(); 80 84 } 81 85 82 86 ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); ··· 106 102 break; 107 103 } 108 104 105 + resp.seq = msg->seq; 109 106 os_write_file(time_travel_ext_fd, &resp, sizeof(resp)); 110 107 } 111 108
+4 -4
arch/um/os-Linux/umid.c
··· 97 97 while ((ent = readdir(directory)) != NULL) { 98 98 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) 99 99 continue; 100 - len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; 100 + len = strlen(dir) + strlen("/") + strlen(ent->d_name) + 1; 101 101 if (len > sizeof(file)) { 102 102 ret = -E2BIG; 103 103 goto out; ··· 135 135 */ 136 136 static inline int is_umdir_used(char *dir) 137 137 { 138 - char pid[sizeof("nnnnn\0")], *end, *file; 138 + char pid[sizeof("nnnnnnnnn")], *end, *file; 139 139 int dead, fd, p, n, err; 140 140 size_t filelen; 141 141 ··· 217 217 218 218 static void __init create_pid_file(void) 219 219 { 220 - char pid[sizeof("nnnnn\0")], *file; 220 + char pid[sizeof("nnnnnnnnn")], *file; 221 221 int fd, n; 222 222 223 - n = strlen(uml_dir) + UMID_LEN + sizeof("/pid\0"); 223 + n = strlen(uml_dir) + UMID_LEN + sizeof("/pid"); 224 224 file = malloc(n); 225 225 if (!file) 226 226 return;
+1 -1
arch/um/os-Linux/util.c
··· 10 10 #include <signal.h> 11 11 #include <string.h> 12 12 #include <termios.h> 13 - #include <wait.h> 13 + #include <sys/wait.h> 14 14 #include <sys/mman.h> 15 15 #include <sys/utsname.h> 16 16 #include <init.h>
+1 -12
arch/x86/um/ptrace_64.c
··· 52 52 53 53 int putreg(struct task_struct *child, int regno, unsigned long value) 54 54 { 55 - #ifdef TIF_IA32 56 - /* 57 - * Some code in the 64bit emulation may not be 64bit clean. 58 - * Don't take any chances. 59 - */ 60 - if (test_tsk_thread_flag(child, TIF_IA32)) 61 - value &= 0xffffffff; 62 - #endif 63 55 switch (regno) { 64 56 case R8: 65 57 case R9: ··· 129 137 unsigned long getreg(struct task_struct *child, int regno) 130 138 { 131 139 unsigned long mask = ~0UL; 132 - #ifdef TIF_IA32 133 - if (test_tsk_thread_flag(child, TIF_IA32)) 134 - mask = 0xffffffff; 135 - #endif 140 + 136 141 switch (regno) { 137 142 case R8: 138 143 case R9:
+1 -1
arch/x86/um/user-offsets.c
··· 2 2 #include <stdio.h> 3 3 #include <stddef.h> 4 4 #include <signal.h> 5 - #include <sys/poll.h> 5 + #include <poll.h> 6 6 #include <sys/mman.h> 7 7 #include <sys/user.h> 8 8 #define __FRAME_OFFSETS