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

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

Pull UML updates from Johannes Berg:

- proper nofault accesses and read-only rodata

- hostfs fix for host inode number reuse

- fixes for host errno handling

- various cleanups/small fixes

* tag 'uml-for-linux-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux:
um: Rewrite the sigio workaround based on epoll and tgkill
um: Prohibit the VM_CLONE flag in run_helper_thread()
um: Switch to the pthread-based helper in sigio workaround
um: ubd: Switch to the pthread-based helper
um: Add pthread-based helper support
um: x86: clean up elf specific definitions
um: Store full CSGSFS and SS register from mcontext
um: virt-pci: Refactor virtio_pcidev into its own module
um: work around sched_yield not yielding in time-travel mode
um/locking: Remove semicolon from "lock" prefix
um: Update min_low_pfn to match changes in uml_reserved
um: use str_yes_no() to remove hardcoded "yes" and "no"
um: hostfs: avoid issues on inode number reuse by host
um: Allocate vdso page pointer statically
um: remove copy_from_kernel_nofault_allowed
um: mark rodata read-only and implement _nofault accesses
um: Pass the correct Rust target and options with gcc

+1146 -1136
+1
arch/um/Kconfig
··· 12 12 select ARCH_HAS_KCOV 13 13 select ARCH_HAS_STRNCPY_FROM_USER 14 14 select ARCH_HAS_STRNLEN_USER 15 + select ARCH_HAS_STRICT_KERNEL_RWX 15 16 select HAVE_ARCH_AUDITSYSCALL 16 17 select HAVE_ARCH_KASAN if X86_64 17 18 select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
+8 -4
arch/um/drivers/Kconfig
··· 345 345 by providing a fake RTC clock that causes a wakeup at the right 346 346 time. 347 347 348 - config UML_PCI_OVER_VIRTIO 349 - bool "Enable PCI over VIRTIO device simulation" 350 - # in theory, just VIRTIO is enough, but that causes recursion 351 - depends on VIRTIO_UML 348 + config UML_PCI 349 + bool 352 350 select FORCE_PCI 353 351 select UML_IOMEM_EMULATION 354 352 select UML_DMA_EMULATION 355 353 select PCI_MSI 356 354 select PCI_LOCKLESS_CONFIG 355 + 356 + config UML_PCI_OVER_VIRTIO 357 + bool "Enable PCI over VIRTIO device simulation" 358 + # in theory, just VIRTIO is enough, but that causes recursion 359 + depends on VIRTIO_UML 360 + select UML_PCI 357 361 358 362 config UML_PCI_OVER_VIRTIO_DEVICE_ID 359 363 int "set the virtio device ID for PCI emulation"
+2 -1
arch/um/drivers/Makefile
··· 60 60 obj-$(CONFIG_UML_RANDOM) += random.o 61 61 obj-$(CONFIG_VIRTIO_UML) += virtio_uml.o 62 62 obj-$(CONFIG_UML_RTC) += rtc.o 63 - obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virt-pci.o 63 + obj-$(CONFIG_UML_PCI) += virt-pci.o 64 + obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virtio_pcidev.o 64 65 65 66 # pcap_user.o must be added explicitly. 66 67 USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o vde_user.o vector_user.o
+1 -1
arch/um/drivers/random.c
··· 79 79 if (err < 0) 80 80 goto err_out_cleanup_hw; 81 81 82 - sigio_broken(random_fd); 82 + sigio_broken(); 83 83 hwrng.name = RNG_MODULE_NAME; 84 84 hwrng.read = rng_dev_read; 85 85
+1 -1
arch/um/drivers/rtc_user.c
··· 39 39 } 40 40 41 41 /* apparently timerfd won't send SIGIO, use workaround */ 42 - sigio_broken(uml_rtc_irq_fds[0]); 42 + sigio_broken(); 43 43 err = add_sigio_fd(uml_rtc_irq_fds[0]); 44 44 if (err < 0) { 45 45 close(uml_rtc_irq_fds[0]);
+4 -2
arch/um/drivers/ubd.h
··· 7 7 #ifndef __UM_UBD_USER_H 8 8 #define __UM_UBD_USER_H 9 9 10 - extern int start_io_thread(unsigned long sp, int *fds_out); 11 - extern int io_thread(void *arg); 10 + #include <os.h> 11 + 12 + int start_io_thread(struct os_helper_thread **td_out, int *fd_out); 13 + void *io_thread(void *arg); 12 14 extern int kernel_fd; 13 15 14 16 extern int ubd_read_poll(int timeout);
+11 -14
arch/um/drivers/ubd_kern.c
··· 474 474 } 475 475 476 476 /* Only changed by ubd_init, which is an initcall. */ 477 - static int io_pid = -1; 477 + static struct os_helper_thread *io_td; 478 478 479 479 static void kill_io_thread(void) 480 480 { 481 - if(io_pid != -1) 482 - os_kill_process(io_pid, 1); 481 + if (io_td) 482 + os_kill_helper_thread(io_td); 483 483 } 484 484 485 485 __uml_exitcall(kill_io_thread); ··· 1104 1104 1105 1105 late_initcall(ubd_init); 1106 1106 1107 - static int __init ubd_driver_init(void){ 1108 - unsigned long stack; 1107 + static int __init ubd_driver_init(void) 1108 + { 1109 1109 int err; 1110 1110 1111 1111 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/ ··· 1114 1114 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is 1115 1115 * enough. So use anyway the io thread. */ 1116 1116 } 1117 - stack = alloc_stack(0, 0); 1118 - io_pid = start_io_thread(stack + PAGE_SIZE, &thread_fd); 1119 - if(io_pid < 0){ 1117 + err = start_io_thread(&io_td, &thread_fd); 1118 + if (err < 0) { 1120 1119 printk(KERN_ERR 1121 1120 "ubd : Failed to start I/O thread (errno = %d) - " 1122 - "falling back to synchronous I/O\n", -io_pid); 1123 - io_pid = -1; 1121 + "falling back to synchronous I/O\n", -err); 1124 1122 return 0; 1125 1123 } 1126 1124 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, ··· 1494 1496 /* Only changed by the io thread. XXX: currently unused. */ 1495 1497 static int io_count; 1496 1498 1497 - int io_thread(void *arg) 1499 + void *io_thread(void *arg) 1498 1500 { 1499 1501 int n, count, written, res; 1500 1502 1501 - os_set_pdeathsig(); 1502 - os_fix_helper_signals(); 1503 + os_fix_helper_thread_signals(); 1503 1504 1504 1505 while(1){ 1505 1506 n = bulk_req_safe_read( ··· 1540 1543 } while (written < n); 1541 1544 } 1542 1545 1543 - return 0; 1546 + return NULL; 1544 1547 }
+7 -7
arch/um/drivers/ubd_user.c
··· 25 25 26 26 static struct pollfd kernel_pollfd; 27 27 28 - int start_io_thread(unsigned long sp, int *fd_out) 28 + int start_io_thread(struct os_helper_thread **td_out, int *fd_out) 29 29 { 30 - int pid, fds[2], err; 30 + int fds[2], err; 31 31 32 32 err = os_pipe(fds, 1, 1); 33 33 if(err < 0){ ··· 47 47 goto out_close; 48 48 } 49 49 50 - pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM, NULL); 51 - if(pid < 0){ 52 - err = -errno; 53 - printk("start_io_thread - clone failed : errno = %d\n", errno); 50 + err = os_run_helper_thread(td_out, io_thread, NULL); 51 + if (err < 0) { 52 + printk("%s - failed to run helper thread, err = %d\n", 53 + __func__, -err); 54 54 goto out_close; 55 55 } 56 56 57 - return(pid); 57 + return 0; 58 58 59 59 out_close: 60 60 os_close_file(fds[0]);
+137 -606
arch/um/drivers/virt-pci.c
··· 5 5 */ 6 6 #include <linux/module.h> 7 7 #include <linux/pci.h> 8 - #include <linux/virtio.h> 9 - #include <linux/virtio_config.h> 10 8 #include <linux/logic_iomem.h> 11 9 #include <linux/of_platform.h> 12 10 #include <linux/irqdomain.h> 13 - #include <linux/virtio_pcidev.h> 14 - #include <linux/virtio-uml.h> 15 - #include <linux/delay.h> 16 11 #include <linux/msi.h> 17 12 #include <linux/unaligned.h> 18 13 #include <irq_kern.h> 19 14 15 + #include "virt-pci.h" 16 + 20 17 #define MAX_DEVICES 8 21 18 #define MAX_MSI_VECTORS 32 22 19 #define CFG_SPACE_SIZE 4096 23 - 24 - /* for MSI-X we have a 32-bit payload */ 25 - #define MAX_IRQ_MSG_SIZE (sizeof(struct virtio_pcidev_msg) + sizeof(u32)) 26 - #define NUM_IRQ_MSGS 10 27 - 28 - struct um_pci_message_buffer { 29 - struct virtio_pcidev_msg hdr; 30 - u8 data[8]; 31 - }; 32 - 33 - struct um_pci_device { 34 - struct virtio_device *vdev; 35 - 36 - /* for now just standard BARs */ 37 - u8 resptr[PCI_STD_NUM_BARS]; 38 - 39 - struct virtqueue *cmd_vq, *irq_vq; 40 - 41 - #define UM_PCI_WRITE_BUFS 20 42 - struct um_pci_message_buffer bufs[UM_PCI_WRITE_BUFS + 1]; 43 - void *extra_ptrs[UM_PCI_WRITE_BUFS + 1]; 44 - DECLARE_BITMAP(used_bufs, UM_PCI_WRITE_BUFS); 45 - 46 - #define UM_PCI_STAT_WAITING 0 47 - unsigned long status; 48 - 49 - int irq; 50 - 51 - bool platform; 52 - }; 53 20 54 21 struct um_pci_device_reg { 55 22 struct um_pci_device *dev; ··· 32 65 static struct irq_domain *um_pci_msi_domain; 33 66 static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)]; 34 67 35 - static unsigned int um_pci_max_delay_us = 40000; 36 - module_param_named(max_delay_us, um_pci_max_delay_us, uint, 0644); 37 - 38 - static int um_pci_get_buf(struct um_pci_device *dev, bool *posted) 39 - { 40 - int i; 41 - 42 - for (i = 0; i < UM_PCI_WRITE_BUFS; i++) { 43 - if (!test_and_set_bit(i, dev->used_bufs)) 44 - return i; 45 - } 46 - 47 - *posted = false; 48 - return UM_PCI_WRITE_BUFS; 49 - } 50 - 51 - static void um_pci_free_buf(struct um_pci_device *dev, void *buf) 52 - { 53 - int i; 54 - 55 - if (buf == &dev->bufs[UM_PCI_WRITE_BUFS]) { 56 - kfree(dev->extra_ptrs[UM_PCI_WRITE_BUFS]); 57 - dev->extra_ptrs[UM_PCI_WRITE_BUFS] = NULL; 58 - return; 59 - } 60 - 61 - for (i = 0; i < UM_PCI_WRITE_BUFS; i++) { 62 - if (buf == &dev->bufs[i]) { 63 - kfree(dev->extra_ptrs[i]); 64 - dev->extra_ptrs[i] = NULL; 65 - WARN_ON(!test_and_clear_bit(i, dev->used_bufs)); 66 - return; 67 - } 68 - } 69 - 70 - WARN_ON(1); 71 - } 72 - 73 - static int um_pci_send_cmd(struct um_pci_device *dev, 74 - struct virtio_pcidev_msg *cmd, 75 - unsigned int cmd_size, 76 - const void *extra, unsigned int extra_size, 77 - void *out, unsigned int out_size) 78 - { 79 - struct scatterlist out_sg, extra_sg, in_sg; 80 - struct scatterlist *sgs_list[] = { 81 - [0] = &out_sg, 82 - [1] = extra ? &extra_sg : &in_sg, 83 - [2] = extra ? &in_sg : NULL, 84 - }; 85 - struct um_pci_message_buffer *buf; 86 - int delay_count = 0; 87 - bool bounce_out; 88 - int ret, len; 89 - int buf_idx; 90 - bool posted; 91 - 92 - if (WARN_ON(cmd_size < sizeof(*cmd) || cmd_size > sizeof(*buf))) 93 - return -EINVAL; 94 - 95 - switch (cmd->op) { 96 - case VIRTIO_PCIDEV_OP_CFG_WRITE: 97 - case VIRTIO_PCIDEV_OP_MMIO_WRITE: 98 - case VIRTIO_PCIDEV_OP_MMIO_MEMSET: 99 - /* in PCI, writes are posted, so don't wait */ 100 - posted = !out; 101 - WARN_ON(!posted); 102 - break; 103 - default: 104 - posted = false; 105 - break; 106 - } 107 - 108 - bounce_out = !posted && cmd_size <= sizeof(*cmd) && 109 - out && out_size <= sizeof(buf->data); 110 - 111 - buf_idx = um_pci_get_buf(dev, &posted); 112 - buf = &dev->bufs[buf_idx]; 113 - memcpy(buf, cmd, cmd_size); 114 - 115 - if (posted && extra && extra_size > sizeof(buf) - cmd_size) { 116 - dev->extra_ptrs[buf_idx] = kmemdup(extra, extra_size, 117 - GFP_ATOMIC); 118 - 119 - if (!dev->extra_ptrs[buf_idx]) { 120 - um_pci_free_buf(dev, buf); 121 - return -ENOMEM; 122 - } 123 - extra = dev->extra_ptrs[buf_idx]; 124 - } else if (extra && extra_size <= sizeof(buf) - cmd_size) { 125 - memcpy((u8 *)buf + cmd_size, extra, extra_size); 126 - cmd_size += extra_size; 127 - extra_size = 0; 128 - extra = NULL; 129 - cmd = (void *)buf; 130 - } else { 131 - cmd = (void *)buf; 132 - } 133 - 134 - sg_init_one(&out_sg, cmd, cmd_size); 135 - if (extra) 136 - sg_init_one(&extra_sg, extra, extra_size); 137 - /* allow stack for small buffers */ 138 - if (bounce_out) 139 - sg_init_one(&in_sg, buf->data, out_size); 140 - else if (out) 141 - sg_init_one(&in_sg, out, out_size); 142 - 143 - /* add to internal virtio queue */ 144 - ret = virtqueue_add_sgs(dev->cmd_vq, sgs_list, 145 - extra ? 2 : 1, 146 - out ? 1 : 0, 147 - cmd, GFP_ATOMIC); 148 - if (ret) { 149 - um_pci_free_buf(dev, buf); 150 - return ret; 151 - } 152 - 153 - if (posted) { 154 - virtqueue_kick(dev->cmd_vq); 155 - return 0; 156 - } 157 - 158 - /* kick and poll for getting a response on the queue */ 159 - set_bit(UM_PCI_STAT_WAITING, &dev->status); 160 - virtqueue_kick(dev->cmd_vq); 161 - ret = 0; 162 - 163 - while (1) { 164 - void *completed = virtqueue_get_buf(dev->cmd_vq, &len); 165 - 166 - if (completed == buf) 167 - break; 168 - 169 - if (completed) 170 - um_pci_free_buf(dev, completed); 171 - 172 - if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || 173 - ++delay_count > um_pci_max_delay_us, 174 - "um virt-pci delay: %d", delay_count)) { 175 - ret = -EIO; 176 - break; 177 - } 178 - udelay(1); 179 - } 180 - clear_bit(UM_PCI_STAT_WAITING, &dev->status); 181 - 182 - if (bounce_out) 183 - memcpy(out, buf->data, out_size); 184 - 185 - um_pci_free_buf(dev, buf); 186 - 187 - return ret; 188 - } 189 - 190 68 static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, 191 69 int size) 192 70 { 193 71 struct um_pci_device_reg *reg = priv; 194 72 struct um_pci_device *dev = reg->dev; 195 - struct virtio_pcidev_msg hdr = { 196 - .op = VIRTIO_PCIDEV_OP_CFG_READ, 197 - .size = size, 198 - .addr = offset, 199 - }; 200 - /* max 8, we might not use it all */ 201 - u8 data[8]; 202 73 203 74 if (!dev) 204 75 return ULONG_MAX; 205 - 206 - memset(data, 0xff, sizeof(data)); 207 76 208 77 switch (size) { 209 78 case 1: ··· 54 251 return ULONG_MAX; 55 252 } 56 253 57 - if (um_pci_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, data, size)) 58 - return ULONG_MAX; 59 - 60 - switch (size) { 61 - case 1: 62 - return data[0]; 63 - case 2: 64 - return le16_to_cpup((void *)data); 65 - case 4: 66 - return le32_to_cpup((void *)data); 67 - #ifdef CONFIG_64BIT 68 - case 8: 69 - return le64_to_cpup((void *)data); 70 - #endif 71 - default: 72 - return ULONG_MAX; 73 - } 254 + return dev->ops->cfgspace_read(dev, offset, size); 74 255 } 75 256 76 257 static void um_pci_cfgspace_write(void *priv, unsigned int offset, int size, ··· 62 275 { 63 276 struct um_pci_device_reg *reg = priv; 64 277 struct um_pci_device *dev = reg->dev; 65 - struct { 66 - struct virtio_pcidev_msg hdr; 67 - /* maximum size - we may only use parts of it */ 68 - u8 data[8]; 69 - } msg = { 70 - .hdr = { 71 - .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 72 - .size = size, 73 - .addr = offset, 74 - }, 75 - }; 76 278 77 279 if (!dev) 78 280 return; 79 281 80 282 switch (size) { 81 283 case 1: 82 - msg.data[0] = (u8)val; 83 - break; 84 284 case 2: 85 - put_unaligned_le16(val, (void *)msg.data); 86 - break; 87 285 case 4: 88 - put_unaligned_le32(val, (void *)msg.data); 89 - break; 90 286 #ifdef CONFIG_64BIT 91 287 case 8: 92 - put_unaligned_le64(val, (void *)msg.data); 93 - break; 94 288 #endif 289 + break; 95 290 default: 96 291 WARN(1, "invalid config space write size %d\n", size); 97 292 return; 98 293 } 99 294 100 - WARN_ON(um_pci_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0)); 295 + dev->ops->cfgspace_write(dev, offset, size, val); 101 296 } 102 297 103 298 static const struct logic_iomem_ops um_pci_device_cfgspace_ops = { 104 299 .read = um_pci_cfgspace_read, 105 300 .write = um_pci_cfgspace_write, 106 301 }; 302 + 303 + static unsigned long um_pci_bar_read(void *priv, unsigned int offset, 304 + int size) 305 + { 306 + u8 *resptr = priv; 307 + struct um_pci_device *dev = container_of(resptr - *resptr, 308 + struct um_pci_device, 309 + resptr[0]); 310 + u8 bar = *resptr; 311 + 312 + switch (size) { 313 + case 1: 314 + case 2: 315 + case 4: 316 + #ifdef CONFIG_64BIT 317 + case 8: 318 + #endif 319 + break; 320 + default: 321 + WARN(1, "invalid bar read size %d\n", size); 322 + return ULONG_MAX; 323 + } 324 + 325 + return dev->ops->bar_read(dev, bar, offset, size); 326 + } 327 + 328 + static void um_pci_bar_write(void *priv, unsigned int offset, int size, 329 + unsigned long val) 330 + { 331 + u8 *resptr = priv; 332 + struct um_pci_device *dev = container_of(resptr - *resptr, 333 + struct um_pci_device, 334 + resptr[0]); 335 + u8 bar = *resptr; 336 + 337 + switch (size) { 338 + case 1: 339 + case 2: 340 + case 4: 341 + #ifdef CONFIG_64BIT 342 + case 8: 343 + #endif 344 + break; 345 + default: 346 + WARN(1, "invalid bar write size %d\n", size); 347 + return; 348 + } 349 + 350 + dev->ops->bar_write(dev, bar, offset, size, val); 351 + } 107 352 108 353 static void um_pci_bar_copy_from(void *priv, void *buffer, 109 354 unsigned int offset, int size) ··· 144 325 struct um_pci_device *dev = container_of(resptr - *resptr, 145 326 struct um_pci_device, 146 327 resptr[0]); 147 - struct virtio_pcidev_msg hdr = { 148 - .op = VIRTIO_PCIDEV_OP_MMIO_READ, 149 - .bar = *resptr, 150 - .size = size, 151 - .addr = offset, 152 - }; 328 + u8 bar = *resptr; 153 329 154 - memset(buffer, 0xff, size); 155 - 156 - um_pci_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, buffer, size); 157 - } 158 - 159 - static unsigned long um_pci_bar_read(void *priv, unsigned int offset, 160 - int size) 161 - { 162 - /* 8 is maximum size - we may only use parts of it */ 163 - u8 data[8]; 164 - 165 - switch (size) { 166 - case 1: 167 - case 2: 168 - case 4: 169 - #ifdef CONFIG_64BIT 170 - case 8: 171 - #endif 172 - break; 173 - default: 174 - WARN(1, "invalid config space read size %d\n", size); 175 - return ULONG_MAX; 176 - } 177 - 178 - um_pci_bar_copy_from(priv, data, offset, size); 179 - 180 - switch (size) { 181 - case 1: 182 - return data[0]; 183 - case 2: 184 - return le16_to_cpup((void *)data); 185 - case 4: 186 - return le32_to_cpup((void *)data); 187 - #ifdef CONFIG_64BIT 188 - case 8: 189 - return le64_to_cpup((void *)data); 190 - #endif 191 - default: 192 - return ULONG_MAX; 193 - } 330 + dev->ops->bar_copy_from(dev, bar, buffer, offset, size); 194 331 } 195 332 196 333 static void um_pci_bar_copy_to(void *priv, unsigned int offset, ··· 156 381 struct um_pci_device *dev = container_of(resptr - *resptr, 157 382 struct um_pci_device, 158 383 resptr[0]); 159 - struct virtio_pcidev_msg hdr = { 160 - .op = VIRTIO_PCIDEV_OP_MMIO_WRITE, 161 - .bar = *resptr, 162 - .size = size, 163 - .addr = offset, 164 - }; 384 + u8 bar = *resptr; 165 385 166 - um_pci_send_cmd(dev, &hdr, sizeof(hdr), buffer, size, NULL, 0); 167 - } 168 - 169 - static void um_pci_bar_write(void *priv, unsigned int offset, int size, 170 - unsigned long val) 171 - { 172 - /* maximum size - we may only use parts of it */ 173 - u8 data[8]; 174 - 175 - switch (size) { 176 - case 1: 177 - data[0] = (u8)val; 178 - break; 179 - case 2: 180 - put_unaligned_le16(val, (void *)data); 181 - break; 182 - case 4: 183 - put_unaligned_le32(val, (void *)data); 184 - break; 185 - #ifdef CONFIG_64BIT 186 - case 8: 187 - put_unaligned_le64(val, (void *)data); 188 - break; 189 - #endif 190 - default: 191 - WARN(1, "invalid config space write size %d\n", size); 192 - return; 193 - } 194 - 195 - um_pci_bar_copy_to(priv, offset, data, size); 386 + dev->ops->bar_copy_to(dev, bar, offset, buffer, size); 196 387 } 197 388 198 389 static void um_pci_bar_set(void *priv, unsigned int offset, u8 value, int size) ··· 167 426 struct um_pci_device *dev = container_of(resptr - *resptr, 168 427 struct um_pci_device, 169 428 resptr[0]); 170 - struct { 171 - struct virtio_pcidev_msg hdr; 172 - u8 data; 173 - } msg = { 174 - .hdr = { 175 - .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 176 - .bar = *resptr, 177 - .size = size, 178 - .addr = offset, 179 - }, 180 - .data = value, 181 - }; 429 + u8 bar = *resptr; 182 430 183 - um_pci_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0); 431 + dev->ops->bar_set(dev, bar, offset, value, size); 184 432 } 185 433 186 434 static const struct logic_iomem_ops um_pci_device_bar_ops = { ··· 216 486 pci_unlock_rescan_remove(); 217 487 } 218 488 219 - static void um_pci_irq_vq_addbuf(struct virtqueue *vq, void *buf, bool kick) 220 - { 221 - struct scatterlist sg[1]; 222 - 223 - sg_init_one(sg, buf, MAX_IRQ_MSG_SIZE); 224 - if (virtqueue_add_inbuf(vq, sg, 1, buf, GFP_ATOMIC)) 225 - kfree(buf); 226 - else if (kick) 227 - virtqueue_kick(vq); 228 - } 229 - 230 - static void um_pci_handle_irq_message(struct virtqueue *vq, 231 - struct virtio_pcidev_msg *msg) 232 - { 233 - struct virtio_device *vdev = vq->vdev; 234 - struct um_pci_device *dev = vdev->priv; 235 - 236 - if (!dev->irq) 237 - return; 238 - 239 - /* we should properly chain interrupts, but on ARCH=um we don't care */ 240 - 241 - switch (msg->op) { 242 - case VIRTIO_PCIDEV_OP_INT: 243 - generic_handle_irq(dev->irq); 244 - break; 245 - case VIRTIO_PCIDEV_OP_MSI: 246 - /* our MSI message is just the interrupt number */ 247 - if (msg->size == sizeof(u32)) 248 - generic_handle_irq(le32_to_cpup((void *)msg->data)); 249 - else 250 - generic_handle_irq(le16_to_cpup((void *)msg->data)); 251 - break; 252 - case VIRTIO_PCIDEV_OP_PME: 253 - /* nothing to do - we already woke up due to the message */ 254 - break; 255 - default: 256 - dev_err(&vdev->dev, "unexpected virt-pci message %d\n", msg->op); 257 - break; 258 - } 259 - } 260 - 261 - static void um_pci_cmd_vq_cb(struct virtqueue *vq) 262 - { 263 - struct virtio_device *vdev = vq->vdev; 264 - struct um_pci_device *dev = vdev->priv; 265 - void *cmd; 266 - int len; 267 - 268 - if (test_bit(UM_PCI_STAT_WAITING, &dev->status)) 269 - return; 270 - 271 - while ((cmd = virtqueue_get_buf(vq, &len))) 272 - um_pci_free_buf(dev, cmd); 273 - } 274 - 275 - static void um_pci_irq_vq_cb(struct virtqueue *vq) 276 - { 277 - struct virtio_pcidev_msg *msg; 278 - int len; 279 - 280 - while ((msg = virtqueue_get_buf(vq, &len))) { 281 - if (len >= sizeof(*msg)) 282 - um_pci_handle_irq_message(vq, msg); 283 - 284 - /* recycle the message buffer */ 285 - um_pci_irq_vq_addbuf(vq, msg, true); 286 - } 287 - } 288 - 289 489 #ifdef CONFIG_OF 290 490 /* Copied from arch/x86/kernel/devicetree.c */ 291 491 struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) ··· 236 576 return NULL; 237 577 } 238 578 #endif 239 - 240 - static int um_pci_init_vqs(struct um_pci_device *dev) 241 - { 242 - struct virtqueue_info vqs_info[] = { 243 - { "cmd", um_pci_cmd_vq_cb }, 244 - { "irq", um_pci_irq_vq_cb }, 245 - }; 246 - struct virtqueue *vqs[2]; 247 - int err, i; 248 - 249 - err = virtio_find_vqs(dev->vdev, 2, vqs, vqs_info, NULL); 250 - if (err) 251 - return err; 252 - 253 - dev->cmd_vq = vqs[0]; 254 - dev->irq_vq = vqs[1]; 255 - 256 - virtio_device_ready(dev->vdev); 257 - 258 - for (i = 0; i < NUM_IRQ_MSGS; i++) { 259 - void *msg = kzalloc(MAX_IRQ_MSG_SIZE, GFP_KERNEL); 260 - 261 - if (msg) 262 - um_pci_irq_vq_addbuf(dev->irq_vq, msg, false); 263 - } 264 - 265 - virtqueue_kick(dev->irq_vq); 266 - 267 - return 0; 268 - } 269 - 270 - static void __um_pci_virtio_platform_remove(struct virtio_device *vdev, 271 - struct um_pci_device *dev) 272 - { 273 - virtio_reset_device(vdev); 274 - vdev->config->del_vqs(vdev); 275 - 276 - mutex_lock(&um_pci_mtx); 277 - um_pci_platform_device = NULL; 278 - mutex_unlock(&um_pci_mtx); 279 - 280 - kfree(dev); 281 - } 282 - 283 - static int um_pci_virtio_platform_probe(struct virtio_device *vdev, 284 - struct um_pci_device *dev) 285 - { 286 - int ret; 287 - 288 - dev->platform = true; 289 - 290 - mutex_lock(&um_pci_mtx); 291 - 292 - if (um_pci_platform_device) { 293 - mutex_unlock(&um_pci_mtx); 294 - ret = -EBUSY; 295 - goto out_free; 296 - } 297 - 298 - ret = um_pci_init_vqs(dev); 299 - if (ret) { 300 - mutex_unlock(&um_pci_mtx); 301 - goto out_free; 302 - } 303 - 304 - um_pci_platform_device = dev; 305 - 306 - mutex_unlock(&um_pci_mtx); 307 - 308 - ret = of_platform_default_populate(vdev->dev.of_node, NULL, &vdev->dev); 309 - if (ret) 310 - __um_pci_virtio_platform_remove(vdev, dev); 311 - 312 - return ret; 313 - 314 - out_free: 315 - kfree(dev); 316 - return ret; 317 - } 318 - 319 - static int um_pci_virtio_probe(struct virtio_device *vdev) 320 - { 321 - struct um_pci_device *dev; 322 - int i, free = -1; 323 - int err = -ENOSPC; 324 - 325 - dev = kzalloc(sizeof(*dev), GFP_KERNEL); 326 - if (!dev) 327 - return -ENOMEM; 328 - 329 - dev->vdev = vdev; 330 - vdev->priv = dev; 331 - 332 - if (of_device_is_compatible(vdev->dev.of_node, "simple-bus")) 333 - return um_pci_virtio_platform_probe(vdev, dev); 334 - 335 - mutex_lock(&um_pci_mtx); 336 - for (i = 0; i < MAX_DEVICES; i++) { 337 - if (um_pci_devices[i].dev) 338 - continue; 339 - free = i; 340 - break; 341 - } 342 - 343 - if (free < 0) 344 - goto error; 345 - 346 - err = um_pci_init_vqs(dev); 347 - if (err) 348 - goto error; 349 - 350 - dev->irq = irq_alloc_desc(numa_node_id()); 351 - if (dev->irq < 0) { 352 - err = dev->irq; 353 - goto err_reset; 354 - } 355 - um_pci_devices[free].dev = dev; 356 - vdev->priv = dev; 357 - 358 - mutex_unlock(&um_pci_mtx); 359 - 360 - device_set_wakeup_enable(&vdev->dev, true); 361 - 362 - /* 363 - * In order to do suspend-resume properly, don't allow VQs 364 - * to be suspended. 365 - */ 366 - virtio_uml_set_no_vq_suspend(vdev, true); 367 - 368 - um_pci_rescan(); 369 - return 0; 370 - err_reset: 371 - virtio_reset_device(vdev); 372 - vdev->config->del_vqs(vdev); 373 - error: 374 - mutex_unlock(&um_pci_mtx); 375 - kfree(dev); 376 - return err; 377 - } 378 - 379 - static void um_pci_virtio_remove(struct virtio_device *vdev) 380 - { 381 - struct um_pci_device *dev = vdev->priv; 382 - int i; 383 - 384 - if (dev->platform) { 385 - of_platform_depopulate(&vdev->dev); 386 - __um_pci_virtio_platform_remove(vdev, dev); 387 - return; 388 - } 389 - 390 - device_set_wakeup_enable(&vdev->dev, false); 391 - 392 - mutex_lock(&um_pci_mtx); 393 - for (i = 0; i < MAX_DEVICES; i++) { 394 - if (um_pci_devices[i].dev != dev) 395 - continue; 396 - 397 - um_pci_devices[i].dev = NULL; 398 - irq_free_desc(dev->irq); 399 - 400 - break; 401 - } 402 - mutex_unlock(&um_pci_mtx); 403 - 404 - if (i < MAX_DEVICES) { 405 - struct pci_dev *pci_dev; 406 - 407 - pci_dev = pci_get_slot(bridge->bus, i); 408 - if (pci_dev) 409 - pci_stop_and_remove_bus_device_locked(pci_dev); 410 - } 411 - 412 - /* Stop all virtqueues */ 413 - virtio_reset_device(vdev); 414 - dev->cmd_vq = NULL; 415 - dev->irq_vq = NULL; 416 - vdev->config->del_vqs(vdev); 417 - 418 - kfree(dev); 419 - } 420 - 421 - static struct virtio_device_id id_table[] = { 422 - { CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID, VIRTIO_DEV_ANY_ID }, 423 - { 0 }, 424 - }; 425 - MODULE_DEVICE_TABLE(virtio, id_table); 426 - 427 - static struct virtio_driver um_pci_virtio_driver = { 428 - .driver.name = "virtio-pci", 429 - .id_table = id_table, 430 - .probe = um_pci_virtio_probe, 431 - .remove = um_pci_virtio_remove, 432 - }; 433 579 434 580 static struct resource virt_cfgspace_resource = { 435 581 .name = "PCI config space", ··· 355 889 } 356 890 357 891 static struct irq_chip um_pci_msi_bottom_irq_chip = { 358 - .name = "UM virtio MSI", 892 + .name = "UM virtual MSI", 359 893 .irq_compose_msi_msg = um_pci_compose_msi_msg, 360 894 }; 361 895 ··· 405 939 }; 406 940 407 941 static struct irq_chip um_pci_msi_irq_chip = { 408 - .name = "UM virtio PCIe MSI", 942 + .name = "UM virtual PCIe MSI", 409 943 .irq_mask = pci_msi_mask_irq, 410 944 .irq_unmask = pci_msi_unmask_irq, 411 945 }; ··· 464 998 .flags = IORESOURCE_MEM, 465 999 }; 466 1000 1001 + int um_pci_device_register(struct um_pci_device *dev) 1002 + { 1003 + int i, free = -1; 1004 + int err = 0; 1005 + 1006 + mutex_lock(&um_pci_mtx); 1007 + for (i = 0; i < MAX_DEVICES; i++) { 1008 + if (um_pci_devices[i].dev) 1009 + continue; 1010 + free = i; 1011 + break; 1012 + } 1013 + 1014 + if (free < 0) { 1015 + err = -ENOSPC; 1016 + goto out; 1017 + } 1018 + 1019 + dev->irq = irq_alloc_desc(numa_node_id()); 1020 + if (dev->irq < 0) { 1021 + err = dev->irq; 1022 + goto out; 1023 + } 1024 + 1025 + um_pci_devices[free].dev = dev; 1026 + 1027 + out: 1028 + mutex_unlock(&um_pci_mtx); 1029 + if (!err) 1030 + um_pci_rescan(); 1031 + return err; 1032 + } 1033 + 1034 + void um_pci_device_unregister(struct um_pci_device *dev) 1035 + { 1036 + int i; 1037 + 1038 + mutex_lock(&um_pci_mtx); 1039 + for (i = 0; i < MAX_DEVICES; i++) { 1040 + if (um_pci_devices[i].dev != dev) 1041 + continue; 1042 + um_pci_devices[i].dev = NULL; 1043 + irq_free_desc(dev->irq); 1044 + break; 1045 + } 1046 + mutex_unlock(&um_pci_mtx); 1047 + 1048 + if (i < MAX_DEVICES) { 1049 + struct pci_dev *pci_dev; 1050 + 1051 + pci_dev = pci_get_slot(bridge->bus, i); 1052 + if (pci_dev) 1053 + pci_stop_and_remove_bus_device_locked(pci_dev); 1054 + } 1055 + } 1056 + 1057 + int um_pci_platform_device_register(struct um_pci_device *dev) 1058 + { 1059 + guard(mutex)(&um_pci_mtx); 1060 + if (um_pci_platform_device) 1061 + return -EBUSY; 1062 + um_pci_platform_device = dev; 1063 + return 0; 1064 + } 1065 + 1066 + void um_pci_platform_device_unregister(struct um_pci_device *dev) 1067 + { 1068 + guard(mutex)(&um_pci_mtx); 1069 + if (um_pci_platform_device == dev) 1070 + um_pci_platform_device = NULL; 1071 + } 1072 + 467 1073 static int __init um_pci_init(void) 468 1074 { 469 1075 struct irq_domain_info inner_domain_info = { ··· 551 1013 &um_pci_iomem_ops)); 552 1014 WARN_ON(logic_iomem_add_region(&virt_platform_resource, 553 1015 &um_pci_platform_ops)); 554 - 555 - if (WARN(CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID < 0, 556 - "No virtio device ID configured for PCI - no PCI support\n")) 557 - return 0; 558 1016 559 1017 bridge = pci_alloc_host_bridge(0); 560 1018 if (!bridge) { ··· 599 1065 if (err) 600 1066 goto free; 601 1067 602 - err = register_virtio_driver(&um_pci_virtio_driver); 603 - if (err) 604 - goto free; 605 1068 return 0; 1069 + 606 1070 free: 607 1071 if (!IS_ERR_OR_NULL(um_pci_inner_domain)) 608 1072 irq_domain_remove(um_pci_inner_domain); ··· 612 1080 } 613 1081 return err; 614 1082 } 615 - module_init(um_pci_init); 1083 + device_initcall(um_pci_init); 616 1084 617 1085 static void __exit um_pci_exit(void) 618 1086 { 619 - unregister_virtio_driver(&um_pci_virtio_driver); 620 1087 irq_domain_remove(um_pci_msi_domain); 621 1088 irq_domain_remove(um_pci_inner_domain); 622 1089 pci_free_resource_list(&bridge->windows);
+41
arch/um/drivers/virt-pci.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __UM_VIRT_PCI_H 3 + #define __UM_VIRT_PCI_H 4 + 5 + #include <linux/pci.h> 6 + 7 + struct um_pci_device { 8 + const struct um_pci_ops *ops; 9 + 10 + /* for now just standard BARs */ 11 + u8 resptr[PCI_STD_NUM_BARS]; 12 + 13 + int irq; 14 + }; 15 + 16 + struct um_pci_ops { 17 + unsigned long (*cfgspace_read)(struct um_pci_device *dev, 18 + unsigned int offset, int size); 19 + void (*cfgspace_write)(struct um_pci_device *dev, unsigned int offset, 20 + int size, unsigned long val); 21 + 22 + unsigned long (*bar_read)(struct um_pci_device *dev, int bar, 23 + unsigned int offset, int size); 24 + void (*bar_write)(struct um_pci_device *dev, int bar, 25 + unsigned int offset, int size, unsigned long val); 26 + 27 + void (*bar_copy_from)(struct um_pci_device *dev, int bar, void *buffer, 28 + unsigned int offset, int size); 29 + void (*bar_copy_to)(struct um_pci_device *dev, int bar, 30 + unsigned int offset, const void *buffer, int size); 31 + void (*bar_set)(struct um_pci_device *dev, int bar, 32 + unsigned int offset, u8 value, int size); 33 + }; 34 + 35 + int um_pci_device_register(struct um_pci_device *dev); 36 + void um_pci_device_unregister(struct um_pci_device *dev); 37 + 38 + int um_pci_platform_device_register(struct um_pci_device *dev); 39 + void um_pci_platform_device_unregister(struct um_pci_device *dev); 40 + 41 + #endif /* __UM_VIRT_PCI_H */
+628
arch/um/drivers/virtio_pcidev.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 Intel Corporation 4 + * Author: Johannes Berg <johannes@sipsolutions.net> 5 + */ 6 + #include <linux/module.h> 7 + #include <linux/pci.h> 8 + #include <linux/virtio.h> 9 + #include <linux/virtio_config.h> 10 + #include <linux/logic_iomem.h> 11 + #include <linux/of_platform.h> 12 + #include <linux/irqdomain.h> 13 + #include <linux/virtio_pcidev.h> 14 + #include <linux/virtio-uml.h> 15 + #include <linux/delay.h> 16 + #include <linux/msi.h> 17 + #include <linux/unaligned.h> 18 + #include <irq_kern.h> 19 + 20 + #include "virt-pci.h" 21 + 22 + #define to_virtio_pcidev(_pdev) \ 23 + container_of(_pdev, struct virtio_pcidev_device, pdev) 24 + 25 + /* for MSI-X we have a 32-bit payload */ 26 + #define MAX_IRQ_MSG_SIZE (sizeof(struct virtio_pcidev_msg) + sizeof(u32)) 27 + #define NUM_IRQ_MSGS 10 28 + 29 + struct virtio_pcidev_message_buffer { 30 + struct virtio_pcidev_msg hdr; 31 + u8 data[8]; 32 + }; 33 + 34 + struct virtio_pcidev_device { 35 + struct um_pci_device pdev; 36 + struct virtio_device *vdev; 37 + 38 + struct virtqueue *cmd_vq, *irq_vq; 39 + 40 + #define VIRTIO_PCIDEV_WRITE_BUFS 20 41 + struct virtio_pcidev_message_buffer bufs[VIRTIO_PCIDEV_WRITE_BUFS + 1]; 42 + void *extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS + 1]; 43 + DECLARE_BITMAP(used_bufs, VIRTIO_PCIDEV_WRITE_BUFS); 44 + 45 + #define UM_PCI_STAT_WAITING 0 46 + unsigned long status; 47 + 48 + bool platform; 49 + }; 50 + 51 + static unsigned int virtio_pcidev_max_delay_us = 40000; 52 + module_param_named(max_delay_us, virtio_pcidev_max_delay_us, uint, 0644); 53 + 54 + static int virtio_pcidev_get_buf(struct virtio_pcidev_device *dev, bool *posted) 55 + { 56 + int i; 57 + 58 + for (i = 0; i < VIRTIO_PCIDEV_WRITE_BUFS; i++) { 59 + if (!test_and_set_bit(i, dev->used_bufs)) 60 + return i; 61 + } 62 + 63 + *posted = false; 64 + return VIRTIO_PCIDEV_WRITE_BUFS; 65 + } 66 + 67 + static void virtio_pcidev_free_buf(struct virtio_pcidev_device *dev, void *buf) 68 + { 69 + int i; 70 + 71 + if (buf == &dev->bufs[VIRTIO_PCIDEV_WRITE_BUFS]) { 72 + kfree(dev->extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS]); 73 + dev->extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS] = NULL; 74 + return; 75 + } 76 + 77 + for (i = 0; i < VIRTIO_PCIDEV_WRITE_BUFS; i++) { 78 + if (buf == &dev->bufs[i]) { 79 + kfree(dev->extra_ptrs[i]); 80 + dev->extra_ptrs[i] = NULL; 81 + WARN_ON(!test_and_clear_bit(i, dev->used_bufs)); 82 + return; 83 + } 84 + } 85 + 86 + WARN_ON(1); 87 + } 88 + 89 + static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev, 90 + struct virtio_pcidev_msg *cmd, 91 + unsigned int cmd_size, 92 + const void *extra, unsigned int extra_size, 93 + void *out, unsigned int out_size) 94 + { 95 + struct scatterlist out_sg, extra_sg, in_sg; 96 + struct scatterlist *sgs_list[] = { 97 + [0] = &out_sg, 98 + [1] = extra ? &extra_sg : &in_sg, 99 + [2] = extra ? &in_sg : NULL, 100 + }; 101 + struct virtio_pcidev_message_buffer *buf; 102 + int delay_count = 0; 103 + bool bounce_out; 104 + int ret, len; 105 + int buf_idx; 106 + bool posted; 107 + 108 + if (WARN_ON(cmd_size < sizeof(*cmd) || cmd_size > sizeof(*buf))) 109 + return -EINVAL; 110 + 111 + switch (cmd->op) { 112 + case VIRTIO_PCIDEV_OP_CFG_WRITE: 113 + case VIRTIO_PCIDEV_OP_MMIO_WRITE: 114 + case VIRTIO_PCIDEV_OP_MMIO_MEMSET: 115 + /* in PCI, writes are posted, so don't wait */ 116 + posted = !out; 117 + WARN_ON(!posted); 118 + break; 119 + default: 120 + posted = false; 121 + break; 122 + } 123 + 124 + bounce_out = !posted && cmd_size <= sizeof(*cmd) && 125 + out && out_size <= sizeof(buf->data); 126 + 127 + buf_idx = virtio_pcidev_get_buf(dev, &posted); 128 + buf = &dev->bufs[buf_idx]; 129 + memcpy(buf, cmd, cmd_size); 130 + 131 + if (posted && extra && extra_size > sizeof(buf) - cmd_size) { 132 + dev->extra_ptrs[buf_idx] = kmemdup(extra, extra_size, 133 + GFP_ATOMIC); 134 + 135 + if (!dev->extra_ptrs[buf_idx]) { 136 + virtio_pcidev_free_buf(dev, buf); 137 + return -ENOMEM; 138 + } 139 + extra = dev->extra_ptrs[buf_idx]; 140 + } else if (extra && extra_size <= sizeof(buf) - cmd_size) { 141 + memcpy((u8 *)buf + cmd_size, extra, extra_size); 142 + cmd_size += extra_size; 143 + extra_size = 0; 144 + extra = NULL; 145 + cmd = (void *)buf; 146 + } else { 147 + cmd = (void *)buf; 148 + } 149 + 150 + sg_init_one(&out_sg, cmd, cmd_size); 151 + if (extra) 152 + sg_init_one(&extra_sg, extra, extra_size); 153 + /* allow stack for small buffers */ 154 + if (bounce_out) 155 + sg_init_one(&in_sg, buf->data, out_size); 156 + else if (out) 157 + sg_init_one(&in_sg, out, out_size); 158 + 159 + /* add to internal virtio queue */ 160 + ret = virtqueue_add_sgs(dev->cmd_vq, sgs_list, 161 + extra ? 2 : 1, 162 + out ? 1 : 0, 163 + cmd, GFP_ATOMIC); 164 + if (ret) { 165 + virtio_pcidev_free_buf(dev, buf); 166 + return ret; 167 + } 168 + 169 + if (posted) { 170 + virtqueue_kick(dev->cmd_vq); 171 + return 0; 172 + } 173 + 174 + /* kick and poll for getting a response on the queue */ 175 + set_bit(UM_PCI_STAT_WAITING, &dev->status); 176 + virtqueue_kick(dev->cmd_vq); 177 + ret = 0; 178 + 179 + while (1) { 180 + void *completed = virtqueue_get_buf(dev->cmd_vq, &len); 181 + 182 + if (completed == buf) 183 + break; 184 + 185 + if (completed) 186 + virtio_pcidev_free_buf(dev, completed); 187 + 188 + if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || 189 + ++delay_count > virtio_pcidev_max_delay_us, 190 + "um virt-pci delay: %d", delay_count)) { 191 + ret = -EIO; 192 + break; 193 + } 194 + udelay(1); 195 + } 196 + clear_bit(UM_PCI_STAT_WAITING, &dev->status); 197 + 198 + if (bounce_out) 199 + memcpy(out, buf->data, out_size); 200 + 201 + virtio_pcidev_free_buf(dev, buf); 202 + 203 + return ret; 204 + } 205 + 206 + static unsigned long virtio_pcidev_cfgspace_read(struct um_pci_device *pdev, 207 + unsigned int offset, int size) 208 + { 209 + struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 210 + struct virtio_pcidev_msg hdr = { 211 + .op = VIRTIO_PCIDEV_OP_CFG_READ, 212 + .size = size, 213 + .addr = offset, 214 + }; 215 + /* max 8, we might not use it all */ 216 + u8 data[8]; 217 + 218 + memset(data, 0xff, sizeof(data)); 219 + 220 + /* size has been checked in um_pci_cfgspace_read() */ 221 + if (virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, data, size)) 222 + return ULONG_MAX; 223 + 224 + switch (size) { 225 + case 1: 226 + return data[0]; 227 + case 2: 228 + return le16_to_cpup((void *)data); 229 + case 4: 230 + return le32_to_cpup((void *)data); 231 + #ifdef CONFIG_64BIT 232 + case 8: 233 + return le64_to_cpup((void *)data); 234 + #endif 235 + default: 236 + return ULONG_MAX; 237 + } 238 + } 239 + 240 + static void virtio_pcidev_cfgspace_write(struct um_pci_device *pdev, 241 + unsigned int offset, int size, 242 + unsigned long val) 243 + { 244 + struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 245 + struct { 246 + struct virtio_pcidev_msg hdr; 247 + /* maximum size - we may only use parts of it */ 248 + u8 data[8]; 249 + } msg = { 250 + .hdr = { 251 + .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 252 + .size = size, 253 + .addr = offset, 254 + }, 255 + }; 256 + 257 + /* size has been checked in um_pci_cfgspace_write() */ 258 + switch (size) { 259 + case 1: 260 + msg.data[0] = (u8)val; 261 + break; 262 + case 2: 263 + put_unaligned_le16(val, (void *)msg.data); 264 + break; 265 + case 4: 266 + put_unaligned_le32(val, (void *)msg.data); 267 + break; 268 + #ifdef CONFIG_64BIT 269 + case 8: 270 + put_unaligned_le64(val, (void *)msg.data); 271 + break; 272 + #endif 273 + } 274 + 275 + WARN_ON(virtio_pcidev_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0)); 276 + } 277 + 278 + static void virtio_pcidev_bar_copy_from(struct um_pci_device *pdev, 279 + int bar, void *buffer, 280 + unsigned int offset, int size) 281 + { 282 + struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 283 + struct virtio_pcidev_msg hdr = { 284 + .op = VIRTIO_PCIDEV_OP_MMIO_READ, 285 + .bar = bar, 286 + .size = size, 287 + .addr = offset, 288 + }; 289 + 290 + memset(buffer, 0xff, size); 291 + 292 + virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, buffer, size); 293 + } 294 + 295 + static unsigned long virtio_pcidev_bar_read(struct um_pci_device *pdev, int bar, 296 + unsigned int offset, int size) 297 + { 298 + /* 8 is maximum size - we may only use parts of it */ 299 + u8 data[8]; 300 + 301 + /* size has been checked in um_pci_bar_read() */ 302 + virtio_pcidev_bar_copy_from(pdev, bar, data, offset, size); 303 + 304 + switch (size) { 305 + case 1: 306 + return data[0]; 307 + case 2: 308 + return le16_to_cpup((void *)data); 309 + case 4: 310 + return le32_to_cpup((void *)data); 311 + #ifdef CONFIG_64BIT 312 + case 8: 313 + return le64_to_cpup((void *)data); 314 + #endif 315 + default: 316 + return ULONG_MAX; 317 + } 318 + } 319 + 320 + static void virtio_pcidev_bar_copy_to(struct um_pci_device *pdev, 321 + int bar, unsigned int offset, 322 + const void *buffer, int size) 323 + { 324 + struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 325 + struct virtio_pcidev_msg hdr = { 326 + .op = VIRTIO_PCIDEV_OP_MMIO_WRITE, 327 + .bar = bar, 328 + .size = size, 329 + .addr = offset, 330 + }; 331 + 332 + virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), buffer, size, NULL, 0); 333 + } 334 + 335 + static void virtio_pcidev_bar_write(struct um_pci_device *pdev, int bar, 336 + unsigned int offset, int size, 337 + unsigned long val) 338 + { 339 + /* maximum size - we may only use parts of it */ 340 + u8 data[8]; 341 + 342 + /* size has been checked in um_pci_bar_write() */ 343 + switch (size) { 344 + case 1: 345 + data[0] = (u8)val; 346 + break; 347 + case 2: 348 + put_unaligned_le16(val, (void *)data); 349 + break; 350 + case 4: 351 + put_unaligned_le32(val, (void *)data); 352 + break; 353 + #ifdef CONFIG_64BIT 354 + case 8: 355 + put_unaligned_le64(val, (void *)data); 356 + break; 357 + #endif 358 + } 359 + 360 + virtio_pcidev_bar_copy_to(pdev, bar, offset, data, size); 361 + } 362 + 363 + static void virtio_pcidev_bar_set(struct um_pci_device *pdev, int bar, 364 + unsigned int offset, u8 value, int size) 365 + { 366 + struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 367 + struct { 368 + struct virtio_pcidev_msg hdr; 369 + u8 data; 370 + } msg = { 371 + .hdr = { 372 + .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 373 + .bar = bar, 374 + .size = size, 375 + .addr = offset, 376 + }, 377 + .data = value, 378 + }; 379 + 380 + virtio_pcidev_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0); 381 + } 382 + 383 + static const struct um_pci_ops virtio_pcidev_um_pci_ops = { 384 + .cfgspace_read = virtio_pcidev_cfgspace_read, 385 + .cfgspace_write = virtio_pcidev_cfgspace_write, 386 + .bar_read = virtio_pcidev_bar_read, 387 + .bar_write = virtio_pcidev_bar_write, 388 + .bar_copy_from = virtio_pcidev_bar_copy_from, 389 + .bar_copy_to = virtio_pcidev_bar_copy_to, 390 + .bar_set = virtio_pcidev_bar_set, 391 + }; 392 + 393 + static void virtio_pcidev_irq_vq_addbuf(struct virtqueue *vq, void *buf, bool kick) 394 + { 395 + struct scatterlist sg[1]; 396 + 397 + sg_init_one(sg, buf, MAX_IRQ_MSG_SIZE); 398 + if (virtqueue_add_inbuf(vq, sg, 1, buf, GFP_ATOMIC)) 399 + kfree(buf); 400 + else if (kick) 401 + virtqueue_kick(vq); 402 + } 403 + 404 + static void virtio_pcidev_handle_irq_message(struct virtqueue *vq, 405 + struct virtio_pcidev_msg *msg) 406 + { 407 + struct virtio_device *vdev = vq->vdev; 408 + struct virtio_pcidev_device *dev = vdev->priv; 409 + 410 + if (!dev->pdev.irq) 411 + return; 412 + 413 + /* we should properly chain interrupts, but on ARCH=um we don't care */ 414 + 415 + switch (msg->op) { 416 + case VIRTIO_PCIDEV_OP_INT: 417 + generic_handle_irq(dev->pdev.irq); 418 + break; 419 + case VIRTIO_PCIDEV_OP_MSI: 420 + /* our MSI message is just the interrupt number */ 421 + if (msg->size == sizeof(u32)) 422 + generic_handle_irq(le32_to_cpup((void *)msg->data)); 423 + else 424 + generic_handle_irq(le16_to_cpup((void *)msg->data)); 425 + break; 426 + case VIRTIO_PCIDEV_OP_PME: 427 + /* nothing to do - we already woke up due to the message */ 428 + break; 429 + default: 430 + dev_err(&vdev->dev, "unexpected virt-pci message %d\n", msg->op); 431 + break; 432 + } 433 + } 434 + 435 + static void virtio_pcidev_cmd_vq_cb(struct virtqueue *vq) 436 + { 437 + struct virtio_device *vdev = vq->vdev; 438 + struct virtio_pcidev_device *dev = vdev->priv; 439 + void *cmd; 440 + int len; 441 + 442 + if (test_bit(UM_PCI_STAT_WAITING, &dev->status)) 443 + return; 444 + 445 + while ((cmd = virtqueue_get_buf(vq, &len))) 446 + virtio_pcidev_free_buf(dev, cmd); 447 + } 448 + 449 + static void virtio_pcidev_irq_vq_cb(struct virtqueue *vq) 450 + { 451 + struct virtio_pcidev_msg *msg; 452 + int len; 453 + 454 + while ((msg = virtqueue_get_buf(vq, &len))) { 455 + if (len >= sizeof(*msg)) 456 + virtio_pcidev_handle_irq_message(vq, msg); 457 + 458 + /* recycle the message buffer */ 459 + virtio_pcidev_irq_vq_addbuf(vq, msg, true); 460 + } 461 + } 462 + 463 + static int virtio_pcidev_init_vqs(struct virtio_pcidev_device *dev) 464 + { 465 + struct virtqueue_info vqs_info[] = { 466 + { "cmd", virtio_pcidev_cmd_vq_cb }, 467 + { "irq", virtio_pcidev_irq_vq_cb }, 468 + }; 469 + struct virtqueue *vqs[2]; 470 + int err, i; 471 + 472 + err = virtio_find_vqs(dev->vdev, 2, vqs, vqs_info, NULL); 473 + if (err) 474 + return err; 475 + 476 + dev->cmd_vq = vqs[0]; 477 + dev->irq_vq = vqs[1]; 478 + 479 + virtio_device_ready(dev->vdev); 480 + 481 + for (i = 0; i < NUM_IRQ_MSGS; i++) { 482 + void *msg = kzalloc(MAX_IRQ_MSG_SIZE, GFP_KERNEL); 483 + 484 + if (msg) 485 + virtio_pcidev_irq_vq_addbuf(dev->irq_vq, msg, false); 486 + } 487 + 488 + virtqueue_kick(dev->irq_vq); 489 + 490 + return 0; 491 + } 492 + 493 + static void __virtio_pcidev_virtio_platform_remove(struct virtio_device *vdev, 494 + struct virtio_pcidev_device *dev) 495 + { 496 + um_pci_platform_device_unregister(&dev->pdev); 497 + 498 + virtio_reset_device(vdev); 499 + vdev->config->del_vqs(vdev); 500 + 501 + kfree(dev); 502 + } 503 + 504 + static int virtio_pcidev_virtio_platform_probe(struct virtio_device *vdev, 505 + struct virtio_pcidev_device *dev) 506 + { 507 + int err; 508 + 509 + dev->platform = true; 510 + 511 + err = virtio_pcidev_init_vqs(dev); 512 + if (err) 513 + goto err_free; 514 + 515 + err = um_pci_platform_device_register(&dev->pdev); 516 + if (err) 517 + goto err_reset; 518 + 519 + err = of_platform_default_populate(vdev->dev.of_node, NULL, &vdev->dev); 520 + if (err) 521 + goto err_unregister; 522 + 523 + return 0; 524 + 525 + err_unregister: 526 + um_pci_platform_device_unregister(&dev->pdev); 527 + err_reset: 528 + virtio_reset_device(vdev); 529 + vdev->config->del_vqs(vdev); 530 + err_free: 531 + kfree(dev); 532 + return err; 533 + } 534 + 535 + static int virtio_pcidev_virtio_probe(struct virtio_device *vdev) 536 + { 537 + struct virtio_pcidev_device *dev; 538 + int err; 539 + 540 + dev = kzalloc(sizeof(*dev), GFP_KERNEL); 541 + if (!dev) 542 + return -ENOMEM; 543 + 544 + dev->vdev = vdev; 545 + vdev->priv = dev; 546 + 547 + dev->pdev.ops = &virtio_pcidev_um_pci_ops; 548 + 549 + if (of_device_is_compatible(vdev->dev.of_node, "simple-bus")) 550 + return virtio_pcidev_virtio_platform_probe(vdev, dev); 551 + 552 + err = virtio_pcidev_init_vqs(dev); 553 + if (err) 554 + goto err_free; 555 + 556 + err = um_pci_device_register(&dev->pdev); 557 + if (err) 558 + goto err_reset; 559 + 560 + device_set_wakeup_enable(&vdev->dev, true); 561 + 562 + /* 563 + * In order to do suspend-resume properly, don't allow VQs 564 + * to be suspended. 565 + */ 566 + virtio_uml_set_no_vq_suspend(vdev, true); 567 + 568 + return 0; 569 + 570 + err_reset: 571 + virtio_reset_device(vdev); 572 + vdev->config->del_vqs(vdev); 573 + err_free: 574 + kfree(dev); 575 + return err; 576 + } 577 + 578 + static void virtio_pcidev_virtio_remove(struct virtio_device *vdev) 579 + { 580 + struct virtio_pcidev_device *dev = vdev->priv; 581 + 582 + if (dev->platform) { 583 + of_platform_depopulate(&vdev->dev); 584 + __virtio_pcidev_virtio_platform_remove(vdev, dev); 585 + return; 586 + } 587 + 588 + device_set_wakeup_enable(&vdev->dev, false); 589 + 590 + um_pci_device_unregister(&dev->pdev); 591 + 592 + /* Stop all virtqueues */ 593 + virtio_reset_device(vdev); 594 + dev->cmd_vq = NULL; 595 + dev->irq_vq = NULL; 596 + vdev->config->del_vqs(vdev); 597 + 598 + kfree(dev); 599 + } 600 + 601 + static struct virtio_device_id id_table[] = { 602 + { CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID, VIRTIO_DEV_ANY_ID }, 603 + { 0 }, 604 + }; 605 + MODULE_DEVICE_TABLE(virtio, id_table); 606 + 607 + static struct virtio_driver virtio_pcidev_virtio_driver = { 608 + .driver.name = "virtio-pci", 609 + .id_table = id_table, 610 + .probe = virtio_pcidev_virtio_probe, 611 + .remove = virtio_pcidev_virtio_remove, 612 + }; 613 + 614 + static int __init virtio_pcidev_init(void) 615 + { 616 + if (WARN(CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID < 0, 617 + "No virtio device ID configured for PCI - no PCI support\n")) 618 + return 0; 619 + 620 + return register_virtio_driver(&virtio_pcidev_virtio_driver); 621 + } 622 + late_initcall(virtio_pcidev_init); 623 + 624 + static void __exit virtio_pcidev_exit(void) 625 + { 626 + unregister_virtio_driver(&virtio_pcidev_virtio_driver); 627 + } 628 + module_exit(virtio_pcidev_exit);
+1
arch/um/include/asm/Kbuild
··· 13 13 generic-y += kdebug.h 14 14 generic-y += mcs_spinlock.h 15 15 generic-y += mmiowb.h 16 + generic-y += module.h 16 17 generic-y += module.lds.h 17 18 generic-y += param.h 18 19 generic-y += parport.h
+2
arch/um/include/asm/processor-generic.h
··· 31 31 } thread; 32 32 } request; 33 33 34 + void *segv_continue; 35 + 34 36 /* Contains variable sized FP registers */ 35 37 struct pt_regs regs; 36 38 };
+15 -5
arch/um/include/asm/uaccess.h
··· 9 9 10 10 #include <asm/elf.h> 11 11 #include <linux/unaligned.h> 12 + #include <sysdep/faultinfo.h> 12 13 13 14 #define __under_task_size(addr, size) \ 14 15 (((unsigned long) (addr) < TASK_SIZE) && \ ··· 45 44 __access_ok_vsyscall(addr, size)); 46 45 } 47 46 48 - /* no pagefaults for kernel addresses in um */ 49 47 #define __get_kernel_nofault(dst, src, type, err_label) \ 50 48 do { \ 51 - *((type *)dst) = get_unaligned((type *)(src)); \ 52 - if (0) /* make sure the label looks used to the compiler */ \ 49 + int __faulted; \ 50 + \ 51 + ___backtrack_faulted(__faulted); \ 52 + if (__faulted) { \ 53 + *((type *)dst) = (type) 0; \ 53 54 goto err_label; \ 55 + } \ 56 + *((type *)dst) = get_unaligned((type *)(src)); \ 57 + current->thread.segv_continue = NULL; \ 54 58 } while (0) 55 59 56 60 #define __put_kernel_nofault(dst, src, type, err_label) \ 57 61 do { \ 58 - put_unaligned(*((type *)src), (type *)(dst)); \ 59 - if (0) /* make sure the label looks used to the compiler */ \ 62 + int __faulted; \ 63 + \ 64 + ___backtrack_faulted(__faulted); \ 65 + if (__faulted) \ 60 66 goto err_label; \ 67 + put_unaligned(*((type *)src), (type *)(dst)); \ 68 + current->thread.segv_continue = NULL; \ 61 69 } while (0) 62 70 63 71 #endif
+2
arch/um/include/linux/time-internal.h
··· 83 83 #define time_travel_del_event(...) time_travel_not_configured() 84 84 #endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ 85 85 86 + extern unsigned long tt_extra_sched_jiffies; 87 + 86 88 /* 87 89 * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used, 88 90 * which is intentional since we really shouldn't link it in that case.
+2
arch/um/include/shared/arch.h
··· 12 12 extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs); 13 13 extern void arch_examine_signal(int sig, struct uml_pt_regs *regs); 14 14 15 + void mc_set_rip(void *_mc, void *target); 16 + 15 17 #endif
+1 -1
arch/um/include/shared/as-layout.h
··· 50 50 extern void uml_finishsetup(void); 51 51 52 52 struct siginfo; 53 - extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); 53 + extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *, void *); 54 54 55 55 #endif 56 56
+2 -1
arch/um/include/shared/irq_user.h
··· 15 15 }; 16 16 17 17 struct siginfo; 18 - extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 18 + extern void sigio_handler(int sig, struct siginfo *unused_si, 19 + struct uml_pt_regs *regs, void *mc); 19 20 void sigio_run_timetravel_handlers(void); 20 21 extern void free_irq_by_fd(int fd); 21 22 extern void deactivate_fd(int fd, int irqnum);
+8 -4
arch/um/include/shared/kern_util.h
··· 24 24 struct pt_regs; 25 25 extern void do_signal(struct pt_regs *regs); 26 26 extern void interrupt_end(void); 27 - extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs); 27 + extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs, 28 + void *mc); 28 29 29 30 extern unsigned long segv(struct faultinfo fi, unsigned long ip, 30 - int is_user, struct uml_pt_regs *regs); 31 + int is_user, struct uml_pt_regs *regs, 32 + void *mc); 31 33 extern int handle_page_fault(unsigned long address, unsigned long ip, 32 34 int is_write, int is_user, int *code_out); 33 35 ··· 61 59 62 60 extern int singlestepping(void); 63 61 64 - extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 65 - extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 62 + extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs, 63 + void *mc); 64 + extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs, 65 + void *mc); 66 66 extern void fatal_sigsegv(void) __attribute__ ((noreturn)); 67 67 68 68 void um_idle_sleep(void);
+6 -2
arch/um/include/shared/os.h
··· 213 213 extern int os_unmap_memory(void *addr, int len); 214 214 extern int os_drop_memory(void *addr, int length); 215 215 extern int can_drop_memory(void); 216 - extern int os_mincore(void *addr, unsigned long len); 217 216 218 217 void os_set_pdeathsig(void); 219 218 ··· 224 225 unsigned int flags, unsigned long *stack_out); 225 226 extern int helper_wait(int pid); 226 227 228 + struct os_helper_thread; 229 + int os_run_helper_thread(struct os_helper_thread **td_out, 230 + void *(*routine)(void *), void *arg); 231 + void os_kill_helper_thread(struct os_helper_thread *td); 232 + void os_fix_helper_thread_signals(void); 227 233 228 234 /* umid.c */ 229 235 extern int umid_file_name(char *name, char *buf, int len); ··· 314 310 extern int add_sigio_fd(int fd); 315 311 extern int ignore_sigio_fd(int fd); 316 312 extern void maybe_sigio_broken(int fd); 317 - extern void sigio_broken(int fd); 313 + extern void sigio_broken(void); 318 314 /* 319 315 * unlocked versions for IRQ controller code. 320 316 *
-1
arch/um/include/shared/sigio.h
··· 6 6 #ifndef __SIGIO_H__ 7 7 #define __SIGIO_H__ 8 8 9 - extern int write_sigio_irq(int fd); 10 9 extern void sigio_lock(void); 11 10 extern void sigio_unlock(void); 12 11
+1 -1
arch/um/kernel/Makefile
··· 17 17 obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ 18 18 physmem.o process.o ptrace.o reboot.o sigio.o \ 19 19 signal.o sysrq.o time.o tlb.o trap.o \ 20 - um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/ 20 + um_arch.o umid.o kmsg_dump.o capflags.o skas/ 21 21 obj-y += load_file.o 22 22 23 23 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
+2 -1
arch/um/kernel/irq.c
··· 236 236 free_irqs(); 237 237 } 238 238 239 - void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) 239 + void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs, 240 + void *mc) 240 241 { 241 242 preempt_disable(); 242 243 _sigio_handler(regs, irqs_suspended);
-19
arch/um/kernel/maccess.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2013 Richard Weinberger <richrd@nod.at> 4 - */ 5 - 6 - #include <linux/uaccess.h> 7 - #include <linux/kernel.h> 8 - #include <os.h> 9 - 10 - bool copy_from_kernel_nofault_allowed(const void *src, size_t size) 11 - { 12 - void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); 13 - 14 - if ((unsigned long)src < PAGE_SIZE || size <= 0) 15 - return false; 16 - if (os_mincore(psrc, size + src - psrc) <= 0) 17 - return false; 18 - return true; 19 - }
+11
arch/um/kernel/mem.c
··· 9 9 #include <linux/mm.h> 10 10 #include <linux/swap.h> 11 11 #include <linux/slab.h> 12 + #include <linux/init.h> 13 + #include <asm/sections.h> 12 14 #include <asm/page.h> 13 15 #include <asm/pgalloc.h> 14 16 #include <as-layout.h> ··· 68 66 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); 69 67 memblock_free((void *)brk_end, uml_reserved - brk_end); 70 68 uml_reserved = brk_end; 69 + min_low_pfn = PFN_UP(__pa(uml_reserved)); 71 70 max_pfn = max_low_pfn; 72 71 } 73 72 ··· 245 242 [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED 246 243 }; 247 244 DECLARE_VM_GET_PAGE_PROT 245 + 246 + void mark_rodata_ro(void) 247 + { 248 + unsigned long rodata_start = PFN_ALIGN(__start_rodata); 249 + unsigned long rodata_end = PFN_ALIGN(__end_rodata); 250 + 251 + os_protect_memory((void *)rodata_start, rodata_end - rodata_start, 1, 0, 0); 252 + }
-26
arch/um/kernel/sigio.c
··· 8 8 #include <os.h> 9 9 #include <sigio.h> 10 10 11 - /* Protected by sigio_lock() called from write_sigio_workaround */ 12 - static int sigio_irq_fd = -1; 13 - 14 - static irqreturn_t sigio_interrupt(int irq, void *data) 15 - { 16 - char c; 17 - 18 - os_read_file(sigio_irq_fd, &c, sizeof(c)); 19 - return IRQ_HANDLED; 20 - } 21 - 22 - int write_sigio_irq(int fd) 23 - { 24 - int err; 25 - 26 - err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 27 - 0, "write sigio", NULL); 28 - if (err < 0) { 29 - printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " 30 - "err = %d\n", err); 31 - return -1; 32 - } 33 - sigio_irq_fd = fd; 34 - return 0; 35 - } 36 - 37 11 /* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ 38 12 static DEFINE_MUTEX(sigio_mutex); 39 13
+11
arch/um/kernel/skas/syscall.c
··· 31 31 goto out; 32 32 33 33 syscall = UPT_SYSCALL_NR(r); 34 + 35 + /* 36 + * If no time passes, then sched_yield may not actually yield, causing 37 + * broken spinlock implementations in userspace (ASAN) to hang for long 38 + * periods of time. 39 + */ 40 + if ((time_travel_mode == TT_MODE_INFCPU || 41 + time_travel_mode == TT_MODE_EXTERNAL) && 42 + syscall == __NR_sched_yield) 43 + tt_extra_sched_jiffies += 1; 44 + 34 45 if (syscall >= 0 && syscall < __NR_syscalls) { 35 46 unsigned long ret = EXECUTE_SYSCALL(syscall, regs); 36 47
+23 -5
arch/um/kernel/trap.c
··· 16 16 #include <kern_util.h> 17 17 #include <os.h> 18 18 #include <skas.h> 19 + #include <arch.h> 19 20 20 21 /* 21 22 * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by ··· 176 175 * @sig: the signal number 177 176 * @unused_si: the signal info struct; unused in this handler 178 177 * @regs: the ptrace register information 178 + * @mc: the mcontext of the signal 179 179 * 180 180 * The handler first extracts the faultinfo from the UML ptrace regs struct. 181 181 * If the userfault did not happen in an UML userspace process, bad_segv is called. 182 182 * Otherwise the signal did happen in a cloned userspace process, handle it. 183 183 */ 184 - void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) 184 + void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs, 185 + void *mc) 185 186 { 186 187 struct faultinfo * fi = UPT_FAULTINFO(regs); 187 188 ··· 192 189 bad_segv(*fi, UPT_IP(regs)); 193 190 return; 194 191 } 195 - segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); 192 + segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs, mc); 196 193 } 197 194 198 195 /* ··· 202 199 * give us bad data! 203 200 */ 204 201 unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, 205 - struct uml_pt_regs *regs) 202 + struct uml_pt_regs *regs, void *mc) 206 203 { 207 204 int si_code; 208 205 int err; ··· 226 223 goto out; 227 224 } 228 225 else if (current->mm == NULL) { 226 + if (current->pagefault_disabled) { 227 + if (!mc) { 228 + show_regs(container_of(regs, struct pt_regs, regs)); 229 + panic("Segfault with pagefaults disabled but no mcontext"); 230 + } 231 + if (!current->thread.segv_continue) { 232 + show_regs(container_of(regs, struct pt_regs, regs)); 233 + panic("Segfault without recovery target"); 234 + } 235 + mc_set_rip(mc, current->thread.segv_continue); 236 + current->thread.segv_continue = NULL; 237 + goto out; 238 + } 229 239 show_regs(container_of(regs, struct pt_regs, regs)); 230 240 panic("Segfault with no mm"); 231 241 } ··· 290 274 return 0; 291 275 } 292 276 293 - void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs) 277 + void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs, 278 + void *mc) 294 279 { 295 280 int code, err; 296 281 if (!UPT_IS_USER(regs)) { ··· 319 302 } 320 303 } 321 304 322 - void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) 305 + void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs, 306 + void *mc) 323 307 { 324 308 do_IRQ(WINCH_IRQ, regs); 325 309 }
+2 -1
arch/um/kernel/um_arch.c
··· 12 12 #include <linux/panic_notifier.h> 13 13 #include <linux/seq_file.h> 14 14 #include <linux/string.h> 15 + #include <linux/string_choices.h> 15 16 #include <linux/utsname.h> 16 17 #include <linux/sched.h> 17 18 #include <linux/sched/task.h> ··· 79 78 seq_printf(m, "model name\t: UML\n"); 80 79 seq_printf(m, "mode\t\t: skas\n"); 81 80 seq_printf(m, "host\t\t: %s\n", host_info); 82 - seq_printf(m, "fpu\t\t: %s\n", cpu_has(&boot_cpu_data, X86_FEATURE_FPU) ? "yes" : "no"); 81 + seq_printf(m, "fpu\t\t: %s\n", str_yes_no(cpu_has(&boot_cpu_data, X86_FEATURE_FPU))); 83 82 seq_printf(m, "flags\t\t:"); 84 83 for (i = 0; i < 32*NCAPINTS; i++) 85 84 if (cpu_has(&boot_cpu_data, i) && (x86_cap_flags[i] != NULL))
+67
arch/um/os-Linux/helper.c
··· 8 8 #include <unistd.h> 9 9 #include <errno.h> 10 10 #include <sched.h> 11 + #include <pthread.h> 11 12 #include <linux/limits.h> 12 13 #include <sys/socket.h> 13 14 #include <sys/wait.h> ··· 122 121 unsigned long stack, sp; 123 122 int pid, status, err; 124 123 124 + /* To share memory space, use os_run_helper_thread() instead. */ 125 + if (flags & CLONE_VM) 126 + return -EINVAL; 127 + 125 128 stack = alloc_stack(0, __uml_cant_sleep()); 126 129 if (stack == 0) 127 130 return -ENOMEM; ··· 171 166 return -ECHILD; 172 167 } else 173 168 return 0; 169 + } 170 + 171 + struct os_helper_thread { 172 + pthread_t handle; 173 + }; 174 + 175 + int os_run_helper_thread(struct os_helper_thread **td_out, 176 + void *(*routine)(void *), void *arg) 177 + { 178 + struct os_helper_thread *td; 179 + sigset_t sigset, oset; 180 + int err, flags; 181 + 182 + flags = __uml_cant_sleep() ? UM_GFP_ATOMIC : UM_GFP_KERNEL; 183 + td = uml_kmalloc(sizeof(*td), flags); 184 + if (!td) 185 + return -ENOMEM; 186 + 187 + sigfillset(&sigset); 188 + if (sigprocmask(SIG_SETMASK, &sigset, &oset) < 0) { 189 + err = -errno; 190 + kfree(td); 191 + return err; 192 + } 193 + 194 + err = pthread_create(&td->handle, NULL, routine, arg); 195 + 196 + if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) 197 + panic("Failed to restore the signal mask: %d", errno); 198 + 199 + if (err != 0) 200 + kfree(td); 201 + else 202 + *td_out = td; 203 + 204 + return -err; 205 + } 206 + 207 + void os_kill_helper_thread(struct os_helper_thread *td) 208 + { 209 + pthread_cancel(td->handle); 210 + pthread_join(td->handle, NULL); 211 + kfree(td); 212 + } 213 + 214 + void os_fix_helper_thread_signals(void) 215 + { 216 + sigset_t sigset; 217 + 218 + sigemptyset(&sigset); 219 + 220 + sigaddset(&sigset, SIGWINCH); 221 + sigaddset(&sigset, SIGPIPE); 222 + sigaddset(&sigset, SIGPROF); 223 + sigaddset(&sigset, SIGINT); 224 + sigaddset(&sigset, SIGTERM); 225 + sigaddset(&sigset, SIGCHLD); 226 + sigaddset(&sigset, SIGALRM); 227 + sigaddset(&sigset, SIGIO); 228 + sigaddset(&sigset, SIGUSR1); 229 + 230 + pthread_sigmask(SIG_SETMASK, &sigset, NULL); 174 231 }
-51
arch/um/os-Linux/process.c
··· 142 142 return ok; 143 143 } 144 144 145 - static int os_page_mincore(void *addr) 146 - { 147 - char vec[2]; 148 - int ret; 149 - 150 - ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); 151 - if (ret < 0) { 152 - if (errno == ENOMEM || errno == EINVAL) 153 - return 0; 154 - else 155 - return -errno; 156 - } 157 - 158 - return vec[0] & 1; 159 - } 160 - 161 - int os_mincore(void *addr, unsigned long len) 162 - { 163 - char *vec; 164 - int ret, i; 165 - 166 - if (len <= UM_KERN_PAGE_SIZE) 167 - return os_page_mincore(addr); 168 - 169 - vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); 170 - if (!vec) 171 - return -ENOMEM; 172 - 173 - ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); 174 - if (ret < 0) { 175 - if (errno == ENOMEM || errno == EINVAL) 176 - ret = 0; 177 - else 178 - ret = -errno; 179 - 180 - goto out; 181 - } 182 - 183 - for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) { 184 - if (!(vec[i] & 1)) { 185 - ret = 0; 186 - goto out; 187 - } 188 - } 189 - 190 - ret = 1; 191 - out: 192 - free(vec); 193 - return ret; 194 - } 195 - 196 145 void init_new_thread_signals(void) 197 146 { 198 147 set_handler(SIGSEGV);
+55 -303
arch/um/os-Linux/sigio.c
··· 11 11 #include <sched.h> 12 12 #include <signal.h> 13 13 #include <string.h> 14 + #include <sys/epoll.h> 14 15 #include <kern_util.h> 15 16 #include <init.h> 16 17 #include <os.h> ··· 22 21 * Protected by sigio_lock(), also used by sigio_cleanup, which is an 23 22 * exitcall. 24 23 */ 25 - static int write_sigio_pid = -1; 26 - static unsigned long write_sigio_stack; 24 + static struct os_helper_thread *write_sigio_td; 27 25 28 - /* 29 - * These arrays are initialized before the sigio thread is started, and 30 - * the descriptors closed after it is killed. So, it can't see them change. 31 - * On the UML side, they are changed under the sigio_lock. 32 - */ 33 - #define SIGIO_FDS_INIT {-1, -1} 26 + static int epollfd = -1; 34 27 35 - static int write_sigio_fds[2] = SIGIO_FDS_INIT; 36 - static int sigio_private[2] = SIGIO_FDS_INIT; 28 + #define MAX_EPOLL_EVENTS 64 37 29 38 - struct pollfds { 39 - struct pollfd *poll; 40 - int size; 41 - int used; 42 - }; 30 + static struct epoll_event epoll_events[MAX_EPOLL_EVENTS]; 43 31 44 - /* 45 - * Protected by sigio_lock(). Used by the sigio thread, but the UML thread 46 - * synchronizes with it. 47 - */ 48 - static struct pollfds current_poll; 49 - static struct pollfds next_poll; 50 - static struct pollfds all_sigio_fds; 51 - 52 - static int write_sigio_thread(void *unused) 32 + static void *write_sigio_thread(void *unused) 53 33 { 54 - struct pollfds *fds, tmp; 55 - struct pollfd *p; 56 - int i, n, respond_fd; 57 - char c; 34 + int pid = getpid(); 35 + int r; 58 36 59 - os_set_pdeathsig(); 60 - os_fix_helper_signals(); 61 - fds = &current_poll; 37 + os_fix_helper_thread_signals(); 38 + 62 39 while (1) { 63 - n = poll(fds->poll, fds->used, -1); 64 - if (n < 0) { 40 + r = epoll_wait(epollfd, epoll_events, MAX_EPOLL_EVENTS, -1); 41 + if (r < 0) { 65 42 if (errno == EINTR) 66 43 continue; 67 - printk(UM_KERN_ERR "write_sigio_thread : poll returned " 68 - "%d, errno = %d\n", n, errno); 44 + printk(UM_KERN_ERR "%s: epoll_wait failed, errno = %d\n", 45 + __func__, errno); 69 46 } 70 - for (i = 0; i < fds->used; i++) { 71 - p = &fds->poll[i]; 72 - if (p->revents == 0) 73 - continue; 74 - if (p->fd == sigio_private[1]) { 75 - CATCH_EINTR(n = read(sigio_private[1], &c, 76 - sizeof(c))); 77 - if (n != sizeof(c)) 78 - printk(UM_KERN_ERR 79 - "write_sigio_thread : " 80 - "read on socket failed, " 81 - "err = %d\n", errno); 82 - tmp = current_poll; 83 - current_poll = next_poll; 84 - next_poll = tmp; 85 - respond_fd = sigio_private[1]; 86 - } 87 - else { 88 - respond_fd = write_sigio_fds[1]; 89 - fds->used--; 90 - memmove(&fds->poll[i], &fds->poll[i + 1], 91 - (fds->used - i) * sizeof(*fds->poll)); 92 - } 93 47 94 - CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); 95 - if (n != sizeof(c)) 96 - printk(UM_KERN_ERR "write_sigio_thread : " 97 - "write on socket failed, err = %d\n", 98 - errno); 99 - } 48 + CATCH_EINTR(r = tgkill(pid, pid, SIGIO)); 49 + if (r < 0) 50 + printk(UM_KERN_ERR "%s: tgkill failed, errno = %d\n", 51 + __func__, errno); 100 52 } 101 53 102 - return 0; 103 - } 104 - 105 - static int need_poll(struct pollfds *polls, int n) 106 - { 107 - struct pollfd *new; 108 - 109 - if (n <= polls->size) 110 - return 0; 111 - 112 - new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); 113 - if (new == NULL) { 114 - printk(UM_KERN_ERR "need_poll : failed to allocate new " 115 - "pollfds\n"); 116 - return -ENOMEM; 117 - } 118 - 119 - memcpy(new, polls->poll, polls->used * sizeof(struct pollfd)); 120 - kfree(polls->poll); 121 - 122 - polls->poll = new; 123 - polls->size = n; 124 - return 0; 125 - } 126 - 127 - /* 128 - * Must be called with sigio_lock held, because it's needed by the marked 129 - * critical section. 130 - */ 131 - static void update_thread(void) 132 - { 133 - unsigned long flags; 134 - int n; 135 - char c; 136 - 137 - flags = um_set_signals_trace(0); 138 - CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c))); 139 - if (n != sizeof(c)) { 140 - printk(UM_KERN_ERR "update_thread : write failed, err = %d\n", 141 - errno); 142 - goto fail; 143 - } 144 - 145 - CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); 146 - if (n != sizeof(c)) { 147 - printk(UM_KERN_ERR "update_thread : read failed, err = %d\n", 148 - errno); 149 - goto fail; 150 - } 151 - 152 - um_set_signals_trace(flags); 153 - return; 154 - fail: 155 - /* Critical section start */ 156 - if (write_sigio_pid != -1) { 157 - os_kill_process(write_sigio_pid, 1); 158 - free_stack(write_sigio_stack, 0); 159 - } 160 - write_sigio_pid = -1; 161 - close(sigio_private[0]); 162 - close(sigio_private[1]); 163 - close(write_sigio_fds[0]); 164 - close(write_sigio_fds[1]); 165 - /* Critical section end */ 166 - um_set_signals_trace(flags); 54 + return NULL; 167 55 } 168 56 169 57 int __add_sigio_fd(int fd) 170 58 { 171 - struct pollfd *p; 172 - int err, i, n; 59 + struct epoll_event event = { 60 + .data.fd = fd, 61 + .events = EPOLLIN | EPOLLET, 62 + }; 63 + int r; 173 64 174 - for (i = 0; i < all_sigio_fds.used; i++) { 175 - if (all_sigio_fds.poll[i].fd == fd) 176 - break; 177 - } 178 - if (i == all_sigio_fds.used) 179 - return -ENOSPC; 180 - 181 - p = &all_sigio_fds.poll[i]; 182 - 183 - for (i = 0; i < current_poll.used; i++) { 184 - if (current_poll.poll[i].fd == fd) 185 - return 0; 186 - } 187 - 188 - n = current_poll.used; 189 - err = need_poll(&next_poll, n + 1); 190 - if (err) 191 - return err; 192 - 193 - memcpy(next_poll.poll, current_poll.poll, 194 - current_poll.used * sizeof(struct pollfd)); 195 - next_poll.poll[n] = *p; 196 - next_poll.used = n + 1; 197 - update_thread(); 198 - 199 - return 0; 65 + CATCH_EINTR(r = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event)); 66 + return r < 0 ? -errno : 0; 200 67 } 201 - 202 68 203 69 int add_sigio_fd(int fd) 204 70 { ··· 80 212 81 213 int __ignore_sigio_fd(int fd) 82 214 { 83 - struct pollfd *p; 84 - int err, i, n = 0; 215 + struct epoll_event event; 216 + int r; 85 217 86 - /* 87 - * This is called from exitcalls elsewhere in UML - if 88 - * sigio_cleanup has already run, then update_thread will hang 89 - * or fail because the thread is no longer running. 90 - */ 91 - if (write_sigio_pid == -1) 92 - return -EIO; 93 - 94 - for (i = 0; i < current_poll.used; i++) { 95 - if (current_poll.poll[i].fd == fd) 96 - break; 97 - } 98 - if (i == current_poll.used) 99 - return -ENOENT; 100 - 101 - err = need_poll(&next_poll, current_poll.used - 1); 102 - if (err) 103 - return err; 104 - 105 - for (i = 0; i < current_poll.used; i++) { 106 - p = &current_poll.poll[i]; 107 - if (p->fd != fd) 108 - next_poll.poll[n++] = *p; 109 - } 110 - next_poll.used = current_poll.used - 1; 111 - 112 - update_thread(); 113 - 114 - return 0; 218 + CATCH_EINTR(r = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event)); 219 + return r < 0 ? -errno : 0; 115 220 } 116 221 117 222 int ignore_sigio_fd(int fd) ··· 98 257 return err; 99 258 } 100 259 101 - static struct pollfd *setup_initial_poll(int fd) 102 - { 103 - struct pollfd *p; 104 - 105 - p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); 106 - if (p == NULL) { 107 - printk(UM_KERN_ERR "setup_initial_poll : failed to allocate " 108 - "poll\n"); 109 - return NULL; 110 - } 111 - *p = ((struct pollfd) { .fd = fd, 112 - .events = POLLIN, 113 - .revents = 0 }); 114 - return p; 115 - } 116 - 117 260 static void write_sigio_workaround(void) 118 261 { 119 - struct pollfd *p; 120 - int err; 121 - int l_write_sigio_fds[2]; 122 - int l_sigio_private[2]; 123 - int l_write_sigio_pid; 124 - 125 - /* We call this *tons* of times - and most ones we must just fail. */ 126 - sigio_lock(); 127 - l_write_sigio_pid = write_sigio_pid; 128 - sigio_unlock(); 129 - 130 - if (l_write_sigio_pid != -1) 131 - return; 132 - 133 - err = os_pipe(l_write_sigio_fds, 1, 1); 134 - if (err < 0) { 135 - printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, " 136 - "err = %d\n", -err); 137 - return; 138 - } 139 - err = os_pipe(l_sigio_private, 1, 1); 140 - if (err < 0) { 141 - printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, " 142 - "err = %d\n", -err); 143 - goto out_close1; 144 - } 145 - 146 - p = setup_initial_poll(l_sigio_private[1]); 147 - if (!p) 148 - goto out_close2; 149 - 150 - sigio_lock(); 151 - 152 - /* 153 - * Did we race? Don't try to optimize this, please, it's not so likely 154 - * to happen, and no more than once at the boot. 155 - */ 156 - if (write_sigio_pid != -1) 157 - goto out_free; 158 - 159 - current_poll = ((struct pollfds) { .poll = p, 160 - .used = 1, 161 - .size = 1 }); 162 - 163 - if (write_sigio_irq(l_write_sigio_fds[0])) 164 - goto out_clear_poll; 165 - 166 - memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds)); 167 - memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private)); 168 - 169 - write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 170 - CLONE_FILES | CLONE_VM, 171 - &write_sigio_stack); 172 - 173 - if (write_sigio_pid < 0) 174 - goto out_clear; 175 - 176 - sigio_unlock(); 177 - return; 178 - 179 - out_clear: 180 - write_sigio_pid = -1; 181 - write_sigio_fds[0] = -1; 182 - write_sigio_fds[1] = -1; 183 - sigio_private[0] = -1; 184 - sigio_private[1] = -1; 185 - out_clear_poll: 186 - current_poll = ((struct pollfds) { .poll = NULL, 187 - .size = 0, 188 - .used = 0 }); 189 - out_free: 190 - sigio_unlock(); 191 - kfree(p); 192 - out_close2: 193 - close(l_sigio_private[0]); 194 - close(l_sigio_private[1]); 195 - out_close1: 196 - close(l_write_sigio_fds[0]); 197 - close(l_write_sigio_fds[1]); 198 - } 199 - 200 - void sigio_broken(int fd) 201 - { 202 262 int err; 203 263 204 - write_sigio_workaround(); 205 - 206 264 sigio_lock(); 207 - err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); 208 - if (err) { 209 - printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd " 210 - "for descriptor %d\n", fd); 265 + if (write_sigio_td) 266 + goto out; 267 + 268 + epollfd = epoll_create(MAX_EPOLL_EVENTS); 269 + if (epollfd < 0) { 270 + printk(UM_KERN_ERR "%s: epoll_create failed, errno = %d\n", 271 + __func__, errno); 211 272 goto out; 212 273 } 213 274 214 - all_sigio_fds.poll[all_sigio_fds.used++] = 215 - ((struct pollfd) { .fd = fd, 216 - .events = POLLIN, 217 - .revents = 0 }); 275 + err = os_run_helper_thread(&write_sigio_td, write_sigio_thread, NULL); 276 + if (err < 0) { 277 + printk(UM_KERN_ERR "%s: os_run_helper_thread failed, errno = %d\n", 278 + __func__, -err); 279 + close(epollfd); 280 + epollfd = -1; 281 + goto out; 282 + } 283 + 218 284 out: 219 285 sigio_unlock(); 286 + } 287 + 288 + void sigio_broken(void) 289 + { 290 + write_sigio_workaround(); 220 291 } 221 292 222 293 /* Changed during early boot */ ··· 142 389 if (pty_output_sigio) 143 390 return; 144 391 145 - sigio_broken(fd); 392 + sigio_broken(); 146 393 } 147 394 148 395 static void sigio_cleanup(void) 149 396 { 150 - if (write_sigio_pid == -1) 397 + if (!write_sigio_td) 151 398 return; 152 399 153 - os_kill_process(write_sigio_pid, 1); 154 - free_stack(write_sigio_stack, 0); 155 - write_sigio_pid = -1; 400 + os_kill_helper_thread(write_sigio_td); 401 + write_sigio_td = NULL; 156 402 } 157 403 158 404 __uml_exitcall(sigio_cleanup);
+2 -2
arch/um/os-Linux/signal.c
··· 21 21 #include <sys/ucontext.h> 22 22 #include <timetravel.h> 23 23 24 - void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { 24 + void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *, void *mc) = { 25 25 [SIGTRAP] = relay_signal, 26 26 [SIGFPE] = relay_signal, 27 27 [SIGILL] = relay_signal, ··· 47 47 if ((sig != SIGIO) && (sig != SIGWINCH)) 48 48 unblock_signals_trace(); 49 49 50 - (*sig_info[sig])(sig, si, &r); 50 + (*sig_info[sig])(sig, si, &r, mc); 51 51 52 52 errno = save_errno; 53 53 }
+4 -4
arch/um/os-Linux/skas/process.c
··· 166 166 static void handle_segv(int pid, struct uml_pt_regs *regs) 167 167 { 168 168 get_skas_faultinfo(pid, &regs->faultinfo); 169 - segv(regs->faultinfo, 0, 1, NULL); 169 + segv(regs->faultinfo, 0, 1, NULL, NULL); 170 170 } 171 171 172 172 static void handle_trap(int pid, struct uml_pt_regs *regs) ··· 525 525 get_skas_faultinfo(pid, 526 526 &regs->faultinfo); 527 527 (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, 528 - regs); 528 + regs, NULL); 529 529 } 530 530 else handle_segv(pid, regs); 531 531 break; ··· 533 533 handle_trap(pid, regs); 534 534 break; 535 535 case SIGTRAP: 536 - relay_signal(SIGTRAP, (struct siginfo *)&si, regs); 536 + relay_signal(SIGTRAP, (struct siginfo *)&si, regs, NULL); 537 537 break; 538 538 case SIGALRM: 539 539 break; ··· 543 543 case SIGFPE: 544 544 case SIGWINCH: 545 545 block_signals_trace(); 546 - (*sig_info[sig])(sig, (struct siginfo *)&si, regs); 546 + (*sig_info[sig])(sig, (struct siginfo *)&si, regs, NULL); 547 547 unblock_signals_trace(); 548 548 break; 549 549 default:
+4 -3
arch/x86/Makefile.um
··· 7 7 # GCC versions < 11. See: 8 8 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99652 9 9 # 10 - ifeq ($(CONFIG_CC_IS_CLANG),y) 11 - KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx 12 - KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json 10 + ifeq ($(call gcc-min-version, 110000)$(CONFIG_CC_IS_CLANG),y) 11 + KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx 13 12 KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2 14 13 endif 14 + 15 + KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json 15 16 16 17 ifeq ($(CONFIG_X86_32),y) 17 18 START := 0x8048000
+3 -3
arch/x86/um/asm/barrier.h
··· 12 12 */ 13 13 #ifdef CONFIG_X86_32 14 14 15 - #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) 16 - #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) 17 - #define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) 15 + #define mb() alternative("lock addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) 16 + #define rmb() alternative("lock addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) 17 + #define wmb() alternative("lock addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) 18 18 19 19 #else /* CONFIG_X86_32 */ 20 20
-24
arch/x86/um/asm/module.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef __UM_MODULE_H 3 - #define __UM_MODULE_H 4 - 5 - /* UML is simple */ 6 - struct mod_arch_specific 7 - { 8 - }; 9 - 10 - #ifdef CONFIG_X86_32 11 - 12 - #define Elf_Shdr Elf32_Shdr 13 - #define Elf_Sym Elf32_Sym 14 - #define Elf_Ehdr Elf32_Ehdr 15 - 16 - #else 17 - 18 - #define Elf_Shdr Elf64_Shdr 19 - #define Elf_Sym Elf64_Sym 20 - #define Elf_Ehdr Elf64_Ehdr 21 - 22 - #endif 23 - 24 - #endif
+13 -2
arch/x86/um/os-Linux/mcontext.c
··· 4 4 #include <asm/ptrace.h> 5 5 #include <sysdep/ptrace.h> 6 6 #include <sysdep/mcontext.h> 7 + #include <arch.h> 7 8 8 9 void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) 9 10 { ··· 28 27 COPY(RIP); 29 28 COPY2(EFLAGS, EFL); 30 29 COPY2(CS, CSGSFS); 31 - regs->gp[CS / sizeof(unsigned long)] &= 0xffff; 32 - regs->gp[CS / sizeof(unsigned long)] |= 3; 30 + regs->gp[SS / sizeof(unsigned long)] = mc->gregs[REG_CSGSFS] >> 48; 31 + #endif 32 + } 33 + 34 + void mc_set_rip(void *_mc, void *target) 35 + { 36 + mcontext_t *mc = _mc; 37 + 38 + #ifdef __i386__ 39 + mc->gregs[REG_EIP] = (unsigned long)target; 40 + #else 41 + mc->gregs[REG_RIP] = (unsigned long)target; 33 42 #endif 34 43 }
+12
arch/x86/um/shared/sysdep/faultinfo_32.h
··· 29 29 30 30 #define PTRACE_FULL_FAULTINFO 0 31 31 32 + #define ___backtrack_faulted(_faulted) \ 33 + asm volatile ( \ 34 + "mov $0, %0\n" \ 35 + "movl $__get_kernel_nofault_faulted_%=,%1\n" \ 36 + "jmp _end_%=\n" \ 37 + "__get_kernel_nofault_faulted_%=:\n" \ 38 + "mov $1, %0;" \ 39 + "_end_%=:" \ 40 + : "=r" (_faulted), \ 41 + "=m" (current->thread.segv_continue) :: \ 42 + ) 43 + 32 44 #endif
+12
arch/x86/um/shared/sysdep/faultinfo_64.h
··· 29 29 30 30 #define PTRACE_FULL_FAULTINFO 1 31 31 32 + #define ___backtrack_faulted(_faulted) \ 33 + asm volatile ( \ 34 + "mov $0, %0\n" \ 35 + "movq $__get_kernel_nofault_faulted_%=,%1\n" \ 36 + "jmp _end_%=\n" \ 37 + "__get_kernel_nofault_faulted_%=:\n" \ 38 + "mov $1, %0;" \ 39 + "_end_%=:" \ 40 + : "=r" (_faulted), \ 41 + "=m" (current->thread.segv_continue) :: \ 42 + ) 43 + 32 44 #endif
+3 -14
arch/x86/um/vdso/vma.c
··· 12 12 13 13 static unsigned int __read_mostly vdso_enabled = 1; 14 14 unsigned long um_vdso_addr; 15 + static struct page *um_vdso; 15 16 16 17 extern unsigned long task_size; 17 18 extern char vdso_start[], vdso_end[]; 18 19 19 - static struct page **vdsop; 20 - 21 20 static int __init init_vdso(void) 22 21 { 23 - struct page *um_vdso; 24 - 25 22 BUG_ON(vdso_end - vdso_start > PAGE_SIZE); 26 23 27 24 um_vdso_addr = task_size - PAGE_SIZE; 28 25 29 - vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL); 30 - if (!vdsop) 31 - goto oom; 32 - 33 26 um_vdso = alloc_page(GFP_KERNEL); 34 - if (!um_vdso) { 35 - kfree(vdsop); 36 - 27 + if (!um_vdso) 37 28 goto oom; 38 - } 39 29 40 30 copy_page(page_address(um_vdso), vdso_start); 41 - *vdsop = um_vdso; 42 31 43 32 return 0; 44 33 ··· 45 56 struct mm_struct *mm = current->mm; 46 57 static struct vm_special_mapping vdso_mapping = { 47 58 .name = "[vdso]", 59 + .pages = &um_vdso, 48 60 }; 49 61 50 62 if (!vdso_enabled) ··· 54 64 if (mmap_write_lock_killable(mm)) 55 65 return -EINTR; 56 66 57 - vdso_mapping.pages = vdsop; 58 67 vma = _install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, 59 68 VM_READ|VM_EXEC| 60 69 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+1 -1
fs/hostfs/hostfs.h
··· 60 60 unsigned int uid; 61 61 unsigned int gid; 62 62 unsigned long long size; 63 - struct hostfs_timespec atime, mtime, ctime; 63 + struct hostfs_timespec atime, mtime, ctime, btime; 64 64 unsigned int blksize; 65 65 unsigned long long blocks; 66 66 struct {
+6 -1
fs/hostfs/hostfs_kern.c
··· 33 33 struct inode vfs_inode; 34 34 struct mutex open_mutex; 35 35 dev_t dev; 36 + struct hostfs_timespec btime; 36 37 }; 37 38 38 39 static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) ··· 548 547 } 549 548 550 549 HOSTFS_I(ino)->dev = dev; 550 + HOSTFS_I(ino)->btime = st->btime; 551 551 ino->i_ino = st->ino; 552 552 ino->i_mode = st->mode; 553 553 return hostfs_inode_update(ino, st); ··· 559 557 const struct hostfs_stat *st = data; 560 558 dev_t dev = MKDEV(st->dev.maj, st->dev.min); 561 559 562 - return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev; 560 + return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev && 561 + (inode->i_mode & S_IFMT) == (st->mode & S_IFMT) && 562 + HOSTFS_I(inode)->btime.tv_sec == st->btime.tv_sec && 563 + HOSTFS_I(inode)->btime.tv_nsec == st->btime.tv_nsec; 563 564 } 564 565 565 566 static struct inode *hostfs_iget(struct super_block *sb, char *name)
+34 -25
fs/hostfs/hostfs_user.c
··· 18 18 #include "hostfs.h" 19 19 #include <utime.h> 20 20 21 - static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p) 21 + static void statx_to_hostfs(const struct statx *buf, struct hostfs_stat *p) 22 22 { 23 - p->ino = buf->st_ino; 24 - p->mode = buf->st_mode; 25 - p->nlink = buf->st_nlink; 26 - p->uid = buf->st_uid; 27 - p->gid = buf->st_gid; 28 - p->size = buf->st_size; 29 - p->atime.tv_sec = buf->st_atime; 30 - p->atime.tv_nsec = 0; 31 - p->ctime.tv_sec = buf->st_ctime; 32 - p->ctime.tv_nsec = 0; 33 - p->mtime.tv_sec = buf->st_mtime; 34 - p->mtime.tv_nsec = 0; 35 - p->blksize = buf->st_blksize; 36 - p->blocks = buf->st_blocks; 37 - p->rdev.maj = os_major(buf->st_rdev); 38 - p->rdev.min = os_minor(buf->st_rdev); 39 - p->dev.maj = os_major(buf->st_dev); 40 - p->dev.min = os_minor(buf->st_dev); 23 + p->ino = buf->stx_ino; 24 + p->mode = buf->stx_mode; 25 + p->nlink = buf->stx_nlink; 26 + p->uid = buf->stx_uid; 27 + p->gid = buf->stx_gid; 28 + p->size = buf->stx_size; 29 + p->atime.tv_sec = buf->stx_atime.tv_sec; 30 + p->atime.tv_nsec = buf->stx_atime.tv_nsec; 31 + p->ctime.tv_sec = buf->stx_ctime.tv_sec; 32 + p->ctime.tv_nsec = buf->stx_ctime.tv_nsec; 33 + p->mtime.tv_sec = buf->stx_mtime.tv_sec; 34 + p->mtime.tv_nsec = buf->stx_mtime.tv_nsec; 35 + if (buf->stx_mask & STATX_BTIME) { 36 + p->btime.tv_sec = buf->stx_btime.tv_sec; 37 + p->btime.tv_nsec = buf->stx_btime.tv_nsec; 38 + } else { 39 + memset(&p->btime, 0, sizeof(p->btime)); 40 + } 41 + p->blksize = buf->stx_blksize; 42 + p->blocks = buf->stx_blocks; 43 + p->rdev.maj = buf->stx_rdev_major; 44 + p->rdev.min = buf->stx_rdev_minor; 45 + p->dev.maj = buf->stx_dev_major; 46 + p->dev.min = buf->stx_dev_minor; 41 47 } 42 48 43 49 int stat_file(const char *path, struct hostfs_stat *p, int fd) 44 50 { 45 - struct stat64 buf; 51 + struct statx buf; 52 + int flags = AT_SYMLINK_NOFOLLOW; 46 53 47 54 if (fd >= 0) { 48 - if (fstat64(fd, &buf) < 0) 49 - return -errno; 50 - } else if (lstat64(path, &buf) < 0) { 51 - return -errno; 55 + flags |= AT_EMPTY_PATH; 56 + path = ""; 52 57 } 53 - stat64_to_hostfs(&buf, p); 58 + 59 + if ((statx(fd, path, flags, STATX_BASIC_STATS | STATX_BTIME, &buf)) < 0) 60 + return -errno; 61 + 62 + statx_to_hostfs(&buf, p); 54 63 return 0; 55 64 } 56 65