diff options
41 files changed, 617 insertions, 516 deletions
diff --git a/Documentation/virt/ne_overview.rst b/Documentation/virt/ne_overview.rst index 39b0c8fe2654..74c2f5919c88 100644 --- a/Documentation/virt/ne_overview.rst +++ b/Documentation/virt/ne_overview.rst @@ -14,12 +14,15 @@ instances [1]. For example, an application that processes sensitive data and runs in a VM, can be separated from other applications running in the same VM. This application then runs in a separate VM than the primary VM, namely an enclave. +It runs alongside the VM that spawned it. This setup matches low latency +applications needs. -An enclave runs alongside the VM that spawned it. This setup matches low latency -applications needs. The resources that are allocated for the enclave, such as -memory and CPUs, are carved out of the primary VM. Each enclave is mapped to a -process running in the primary VM, that communicates with the NE driver via an -ioctl interface. +The current supported architectures for the NE kernel driver, available in the +upstream Linux kernel, are x86 and ARM64. + +The resources that are allocated for the enclave, such as memory and CPUs, are +carved out of the primary VM. Each enclave is mapped to a process running in the +primary VM, that communicates with the NE kernel driver via an ioctl interface. In this sense, there are two components: @@ -43,8 +46,8 @@ for the enclave VM. An enclave does not have persistent storage attached. The memory regions carved out of the primary VM and given to an enclave need to be aligned 2 MiB / 1 GiB physically contiguous memory regions (or multiple of this size e.g. 8 MiB). The memory can be allocated e.g. by using hugetlbfs from -user space [2][3]. The memory size for an enclave needs to be at least 64 MiB. -The enclave memory and CPUs need to be from the same NUMA node. +user space [2][3][7]. The memory size for an enclave needs to be at least +64 MiB. The enclave memory and CPUs need to be from the same NUMA node. An enclave runs on dedicated cores. CPU 0 and its CPU siblings need to remain available for the primary VM. A CPU pool has to be set for NE purposes by an @@ -61,7 +64,7 @@ device is placed in memory below the typical 4 GiB. The application that runs in the enclave needs to be packaged in an enclave image together with the OS ( e.g. kernel, ramdisk, init ) that will run in the enclave VM. The enclave VM has its own kernel and follows the standard Linux -boot protocol [6]. +boot protocol [6][8]. The kernel bzImage, the kernel command line, the ramdisk(s) are part of the Enclave Image Format (EIF); plus an EIF header including metadata such as magic @@ -93,3 +96,5 @@ enclave process can exit. [4] https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html [5] https://man7.org/linux/man-pages/man7/vsock.7.html [6] https://www.kernel.org/doc/html/latest/x86/boot.html +[7] https://www.kernel.org/doc/html/latest/arm64/hugetlbpage.html +[8] https://www.kernel.org/doc/html/latest/arm64/booting.html diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1c596b5cdb27..cc296f0823bd 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -495,6 +495,10 @@ static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter) written += n; if (signal_pending(current)) return written ? written : -ERESTARTSYS; + if (!need_resched()) + continue; + if (iocb->ki_flags & IOCB_NOWAIT) + return written ? written : -EAGAIN; cond_resched(); } return written; @@ -696,11 +700,11 @@ static const struct memdev { #ifdef CONFIG_DEVMEM [DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, #endif - [3] = { "null", 0666, &null_fops, 0 }, + [3] = { "null", 0666, &null_fops, FMODE_NOWAIT }, #ifdef CONFIG_DEVPORT [4] = { "port", 0, &port_fops, 0 }, #endif - [5] = { "zero", 0666, &zero_fops, 0 }, + [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT }, [7] = { "full", 0666, &full_fops, 0 }, [8] = { "random", 0666, &random_fops, 0 }, [9] = { "urandom", 0666, &urandom_fops, 0 }, diff --git a/drivers/char/xillybus/xillybus.h b/drivers/char/xillybus/xillybus.h index c63ffc56637c..51de7cbc579e 100644 --- a/drivers/char/xillybus/xillybus.h +++ b/drivers/char/xillybus/xillybus.h @@ -87,13 +87,8 @@ struct xilly_channel { }; struct xilly_endpoint { - /* - * One of pdev and dev is always NULL, and the other is a valid - * pointer, depending on the type of device - */ - struct pci_dev *pdev; struct device *dev; - struct xilly_endpoint_hardware *ephw; + struct module *owner; int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ __iomem void *registers; @@ -113,25 +108,8 @@ struct xilly_endpoint { unsigned int msg_buf_size; }; -struct xilly_endpoint_hardware { - struct module *owner; - void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *, - dma_addr_t, - size_t, - int); - void (*hw_sync_sgl_for_device)(struct xilly_endpoint *, - dma_addr_t, - size_t, - int); - int (*map_single)(struct xilly_endpoint *, - void *, - size_t, - int, - dma_addr_t *); -}; - struct xilly_mapping { - void *device; + struct device *device; dma_addr_t dma_addr; size_t size; int direction; @@ -139,10 +117,7 @@ struct xilly_mapping { irqreturn_t xillybus_isr(int irq, void *data); -struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, - struct device *dev, - struct xilly_endpoint_hardware - *ephw); +struct xilly_endpoint *xillybus_init_endpoint(struct device *dev); int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint); diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c index 931d0bf4cec6..11b7c4749274 100644 --- a/drivers/char/xillybus/xillybus_core.c +++ b/drivers/char/xillybus/xillybus_core.c @@ -122,10 +122,8 @@ irqreturn_t xillybus_isr(int irq, void *data) buf = ep->msgbuf_addr; buf_size = ep->msg_buf_size/sizeof(u32); - ep->ephw->hw_sync_sgl_for_cpu(ep, - ep->msgbuf_dma_addr, - ep->msg_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(ep->dev, ep->msgbuf_dma_addr, + ep->msg_buf_size, DMA_FROM_DEVICE); for (i = 0; i < buf_size; i += 2) { if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) { @@ -140,11 +138,10 @@ irqreturn_t xillybus_isr(int irq, void *data) dev_err(ep->dev, "Lost sync with interrupt messages. Stopping.\n"); } else { - ep->ephw->hw_sync_sgl_for_device( - ep, - ep->msgbuf_dma_addr, - ep->msg_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_device(ep->dev, + ep->msgbuf_dma_addr, + ep->msg_buf_size, + DMA_FROM_DEVICE); iowrite32(0x01, /* Message NACK */ ep->registers + fpga_msg_ctrl_reg); @@ -275,10 +272,8 @@ irqreturn_t xillybus_isr(int irq, void *data) } } - ep->ephw->hw_sync_sgl_for_device(ep, - ep->msgbuf_dma_addr, - ep->msg_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_device(ep->dev, ep->msgbuf_dma_addr, + ep->msg_buf_size, DMA_FROM_DEVICE); ep->msg_counter = (ep->msg_counter + 1) & 0xf; ep->failed_messages = 0; @@ -304,6 +299,47 @@ struct xilly_alloc_state { u32 regdirection; }; +static void xilly_unmap(void *ptr) +{ + struct xilly_mapping *data = ptr; + + dma_unmap_single(data->device, data->dma_addr, + data->size, data->direction); + + kfree(ptr); +} + +static int xilly_map_single(struct xilly_endpoint *ep, + void *ptr, + size_t size, + int direction, + dma_addr_t *ret_dma_handle + ) +{ + dma_addr_t addr; + struct xilly_mapping *this; + + this = kzalloc(sizeof(*this), GFP_KERNEL); + if (!this) + return -ENOMEM; + + addr = dma_map_single(ep->dev, ptr, size, direction); + + if (dma_mapping_error(ep->dev, addr)) { + kfree(this); + return -ENODEV; + } + + this->device = ep->dev; + this->dma_addr = addr; + this->size = size; + this->direction = direction; + + *ret_dma_handle = addr; + + return devm_add_action_or_reset(ep->dev, xilly_unmap, this); +} + static int xilly_get_dma_buffers(struct xilly_endpoint *ep, struct xilly_alloc_state *s, struct xilly_buffer **buffers, @@ -355,9 +391,9 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, s->left_of_salami = allocsize; } - rc = ep->ephw->map_single(ep, s->salami, - bytebufsize, s->direction, - &dma_addr); + rc = xilly_map_single(ep, s->salami, + bytebufsize, s->direction, + &dma_addr); if (rc) return rc; @@ -620,11 +656,10 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) return -ENODEV; } - endpoint->ephw->hw_sync_sgl_for_cpu( - channel->endpoint, - channel->wr_buffers[0]->dma_addr, - channel->wr_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(channel->endpoint->dev, + channel->wr_buffers[0]->dma_addr, + channel->wr_buf_size, + DMA_FROM_DEVICE); if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) { dev_err(endpoint->dev, @@ -735,11 +770,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, if (!empty) { /* Go on, now without the spinlock */ if (bufpos == 0) /* Position zero means it's virgin */ - channel->endpoint->ephw->hw_sync_sgl_for_cpu( - channel->endpoint, - channel->wr_buffers[bufidx]->dma_addr, - channel->wr_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(channel->endpoint->dev, + channel->wr_buffers[bufidx]->dma_addr, + channel->wr_buf_size, + DMA_FROM_DEVICE); if (copy_to_user( userbuf, @@ -751,11 +785,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, bytes_done += howmany; if (bufferdone) { - channel->endpoint->ephw->hw_sync_sgl_for_device( - channel->endpoint, - channel->wr_buffers[bufidx]->dma_addr, - channel->wr_buf_size, - DMA_FROM_DEVICE); + dma_sync_single_for_device(channel->endpoint->dev, + channel->wr_buffers[bufidx]->dma_addr, + channel->wr_buf_size, + DMA_FROM_DEVICE); /* * Tell FPGA the buffer is done with. It's an @@ -1055,11 +1088,10 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) else channel->rd_host_buf_idx++; - channel->endpoint->ephw->hw_sync_sgl_for_device( - channel->endpoint, - channel->rd_buffers[bufidx]->dma_addr, - channel->rd_buf_size, - DMA_TO_DEVICE); + dma_sync_single_for_device(channel->endpoint->dev, + channel->rd_buffers[bufidx]->dma_addr, + channel->rd_buf_size, + DMA_TO_DEVICE); mutex_lock(&channel->endpoint->register_mutex); @@ -1275,11 +1307,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, if ((bufpos == 0) || /* Zero means it's virgin */ (channel->rd_leftovers[3] != 0)) { - channel->endpoint->ephw->hw_sync_sgl_for_cpu( - channel->endpoint, - channel->rd_buffers[bufidx]->dma_addr, - channel->rd_buf_size, - DMA_TO_DEVICE); + dma_sync_single_for_cpu(channel->endpoint->dev, + channel->rd_buffers[bufidx]->dma_addr, + channel->rd_buf_size, + DMA_TO_DEVICE); /* Virgin, but leftovers are due */ for (i = 0; i < bufpos; i++) @@ -1297,11 +1328,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, bytes_done += howmany; if (bufferdone) { - channel->endpoint->ephw->hw_sync_sgl_for_device( - channel->endpoint, - channel->rd_buffers[bufidx]->dma_addr, - channel->rd_buf_size, - DMA_TO_DEVICE); + dma_sync_single_for_device(channel->endpoint->dev, + channel->rd_buffers[bufidx]->dma_addr, + channel->rd_buf_size, + DMA_TO_DEVICE); mutex_lock(&channel->endpoint->register_mutex); @@ -1772,10 +1802,7 @@ static const struct file_operations xillybus_fops = { .poll = xillybus_poll, }; -struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, - struct device *dev, - struct xilly_endpoint_hardware - *ephw) +struct xilly_endpoint *xillybus_init_endpoint(struct device *dev) { struct xilly_endpoint *endpoint; @@ -1783,9 +1810,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, if (!endpoint) return NULL; - endpoint->pdev = pdev; endpoint->dev = dev; - endpoint->ephw = ephw; endpoint->msg_counter = 0x0b; endpoint->failed_messages = 0; endpoint->fatal_error = 0; @@ -1912,7 +1937,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) goto failed_idt; rc = xillybus_init_chrdev(dev, &xillybus_fops, - endpoint->ephw->owner, endpoint, + endpoint->owner, endpoint, idt_handle.names, idt_handle.names_len, endpoint->num_channels, diff --git a/drivers/char/xillybus/xillybus_of.c b/drivers/char/xillybus/xillybus_of.c index 1a20b286fd1d..e5372e45d211 100644 --- a/drivers/char/xillybus/xillybus_of.c +++ b/drivers/char/xillybus/xillybus_of.c @@ -31,102 +31,22 @@ static const struct of_device_id xillybus_of_match[] = { MODULE_DEVICE_TABLE(of, xillybus_of_match); -static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint *ep, - dma_addr_t dma_handle, - size_t size, - int direction) -{ - dma_sync_single_for_cpu(ep->dev, dma_handle, size, direction); -} - -static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint *ep, - dma_addr_t dma_handle, - size_t size, - int direction) -{ - dma_sync_single_for_device(ep->dev, dma_handle, size, direction); -} - -static void xilly_dma_sync_single_nop(struct xilly_endpoint *ep, - dma_addr_t dma_handle, - size_t size, - int direction) -{ -} - -static void xilly_of_unmap(void *ptr) -{ - struct xilly_mapping *data = ptr; - - dma_unmap_single(data->device, data->dma_addr, - data->size, data->direction); - - kfree(ptr); -} - -static int xilly_map_single_of(struct xilly_endpoint *ep, - void *ptr, - size_t size, - int direction, - dma_addr_t *ret_dma_handle - ) -{ - dma_addr_t addr; - struct xilly_mapping *this; - - this = kzalloc(sizeof(*this), GFP_KERNEL); - if (!this) - return -ENOMEM; - - addr = dma_map_single(ep->dev, ptr, size, direction); - - if (dma_mapping_error(ep->dev, addr)) { - kfree(this); - return -ENODEV; - } - - this->device = ep->dev; - this->dma_addr = addr; - this->size = size; - this->direction = direction; - - *ret_dma_handle = addr; - - return devm_add_action_or_reset(ep->dev, xilly_of_unmap, this); -} - -static struct xilly_endpoint_hardware of_hw = { - .owner = THIS_MODULE, - .hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_of, - .hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_of, - .map_single = xilly_map_single_of, -}; - -static struct xilly_endpoint_hardware of_hw_coherent = { - .owner = THIS_MODULE, - .hw_sync_sgl_for_cpu = xilly_dma_sync_single_nop, - .hw_sync_sgl_for_device = xilly_dma_sync_single_nop, - .map_single = xilly_map_single_of, -}; - static int xilly_drv_probe(struct platform_device *op) { struct device *dev = &op->dev; struct xilly_endpoint *endpoint; int rc; int irq; - struct xilly_endpoint_hardware *ephw = &of_hw; - if (of_property_read_bool(dev->of_node, "dma-coherent")) - ephw = &of_hw_coherent; - - endpoint = xillybus_init_endpoint(NULL, dev, ephw); + endpoint = xillybus_init_endpoint(dev); if (!endpoint) return -ENOMEM; dev_set_drvdata(dev, endpoint); + endpoint->owner = THIS_MODULE; + endpoint->registers = devm_platform_ioremap_resource(op, 0); if (IS_ERR(endpoint->registers)) return PTR_ERR(endpoint->registers); diff --git a/drivers/char/xillybus/xillybus_pcie.c b/drivers/char/xillybus/xillybus_pcie.c index bdf1c366b4fc..9858711e3e79 100644 --- a/drivers/char/xillybus/xillybus_pcie.c +++ b/drivers/char/xillybus/xillybus_pcie.c @@ -32,110 +32,21 @@ static const struct pci_device_id xillyids[] = { { /* End: all zeroes */ } }; -static int xilly_pci_direction(int direction) -{ - switch (direction) { - case DMA_TO_DEVICE: - return PCI_DMA_TODEVICE; - case DMA_FROM_DEVICE: - return PCI_DMA_FROMDEVICE; - default: - return PCI_DMA_BIDIRECTIONAL; - } -} - -static void xilly_dma_sync_single_for_cpu_pci(struct xilly_endpoint *ep, - dma_addr_t dma_handle, - size_t size, - int direction) -{ - pci_dma_sync_single_for_cpu(ep->pdev, - dma_handle, - size, - xilly_pci_direction(direction)); -} - -static void xilly_dma_sync_single_for_device_pci(struct xilly_endpoint *ep, - dma_addr_t dma_handle, - size_t size, - int direction) -{ - pci_dma_sync_single_for_device(ep->pdev, - dma_handle, - size, - xilly_pci_direction(direction)); -} - -static void xilly_pci_unmap(void *ptr) -{ - struct xilly_mapping *data = ptr; - - pci_unmap_single(data->device, data->dma_addr, - data->size, data->direction); - - kfree(ptr); -} - -/* - * Map either through the PCI DMA mapper or the non_PCI one. Behind the - * scenes exactly the same functions are called with the same parameters, - * but that can change. - */ - -static int xilly_map_single_pci(struct xilly_endpoint *ep, - void *ptr, - size_t size, - int direction, - dma_addr_t *ret_dma_handle - ) -{ - int pci_direction; - dma_addr_t addr; - struct xilly_mapping *this; - - this = kzalloc(sizeof(*this), GFP_KERNEL); - if (!this) - return -ENOMEM; - - pci_direction = xilly_pci_direction(direction); - - addr = pci_map_single(ep->pdev, ptr, size, pci_direction); - - if (pci_dma_mapping_error(ep->pdev, addr)) { - kfree(this); - return -ENODEV; - } - - this->device = ep->pdev; - this->dma_addr = addr; - this->size = size; - this->direction = pci_direction; - - *ret_dma_handle = addr; - - return devm_add_action_or_reset(ep->dev, xilly_pci_unmap, this); -} - -static struct xilly_endpoint_hardware pci_hw = { - .owner = THIS_MODULE, - .hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_pci, - .hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_pci, - .map_single = xilly_map_single_pci, -}; - static int xilly_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct xilly_endpoint *endpoint; int rc; - endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw); + endpoint = xillybus_init_endpoint(&pdev->dev); if (!endpoint) return -ENOMEM; pci_set_drvdata(pdev, endpoint); + endpoint->owner = THIS_MODULE; + rc = pcim_enable_device(pdev); if (rc) { dev_err(endpoint->dev, @@ -185,9 +96,9 @@ static int xilly_probe(struct pci_dev *pdev, * So go for the 64-bit mask only when failing is the other option. */ - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { endpoint->dma_using_dac = 0; - } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { endpoint->dma_using_dac = 1; } else { dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n"); diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index c709861198e5..20d2b9ec1227 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -276,7 +276,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, { int res; int i; - struct tty_driver *tty; + struct tty_driver *drv; struct ipoctal_channel *channel; struct ipack_region *region; void __iomem *addr; @@ -359,38 +359,38 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, /* Register the TTY device */ /* Each IP-OCTAL channel is a TTY port */ - tty = tty_alloc_driver(NR_CHANNELS, TTY_DRIVER_REAL_RAW | + drv = tty_alloc_driver(NR_CHANNELS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); - if (IS_ERR(tty)) - return PTR_ERR(tty); + if (IS_ERR(drv)) + return PTR_ERR(drv); /* Fill struct tty_driver with ipoctal data */ - tty->owner = THIS_MODULE; - tty->driver_name = KBUILD_MODNAME; - tty->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); - if (!tty->name) { + drv->owner = THIS_MODULE; + drv->driver_name = KBUILD_MODNAME; + drv->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); + if (!drv->name) { res = -ENOMEM; goto err_put_driver; } - tty->major = 0; - - tty->minor_start = 0; - tty->type = TTY_DRIVER_TYPE_SERIAL; - tty->subtype = SERIAL_TYPE_NORMAL; - tty->init_termios = tty_std_termios; - tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty->init_termios.c_ispeed = 9600; - tty->init_termios.c_ospeed = 9600; - - tty_set_operations(tty, &ipoctal_fops); - res = tty_register_driver(tty); + drv->major = 0; + + drv->minor_start = 0; + drv->type = TTY_DRIVER_TYPE_SERIAL; + drv->subtype = SERIAL_TYPE_NORMAL; + drv->init_termios = tty_std_termios; + drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + drv->init_termios.c_ispeed = 9600; + drv->init_termios.c_ospeed = 9600; + + tty_set_operations(drv, &ipoctal_fops); + res = tty_register_driver(drv); if (res) { dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); goto err_free_name; } /* Save struct tty_driver for use it when uninstalling the device */ - ipoctal->tty_drv = tty; + ipoctal->tty_drv = drv; for (i = 0; i < NR_CHANNELS; i++) { struct device *tty_dev; @@ -407,7 +407,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, spin_lock_init(&channel->lock); channel->pointer_read = 0; channel->pointer_write = 0; - tty_dev = tty_port_register_device_attr(&channel->tty_port, tty, + tty_dev = tty_port_register_device_attr(&channel->tty_port, drv, i, NULL, channel, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); @@ -429,9 +429,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, return 0; err_free_name: - kfree(tty->name); + kfree(drv->name); err_put_driver: - tty_driver_kref_put(tty); + tty_driver_kref_put(drv); return res; } diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index bd869ec5edba..0ee0c6d808c3 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -69,7 +69,8 @@ static int ad_dpot_i2c_probe(struct i2c_client *client, static int ad_dpot_i2c_remove(struct i2c_client *client) { - return ad_dpot_remove(&client->dev); + ad_dpot_remove(&client->dev); + return 0; } static const struct i2c_device_id ad_dpot_id[] = { diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index aea931dd272e..a9e75d80ad36 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -92,7 +92,8 @@ static int ad_dpot_spi_probe(struct spi_device *spi) static int ad_dpot_spi_remove(struct spi_device *spi) { - return ad_dpot_remove(&spi->dev); + ad_dpot_remove(&spi->dev); + return 0; } static const struct spi_device_id ad_dpot_spi_id[] = { diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 5d8f3f6a95f2..756ef6912b5a 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -743,7 +743,7 @@ exit: } EXPORT_SYMBOL(ad_dpot_probe); -int ad_dpot_remove(struct device *dev) +void ad_dpot_remove(struct device *dev) { struct dpot_data *data = dev_get_drvdata(dev); int i; @@ -753,8 +753,6 @@ int ad_dpot_remove(struct device *dev) ad_dpot_remove_files(dev, data->feat, i); kfree(data); - - return 0; } EXPORT_SYMBOL(ad_dpot_remove); diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index ee8dc9f5a45a..72a9d6801937 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -209,6 +209,6 @@ struct ad_dpot_bus_data { int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata, unsigned long devid, const char *name); -int ad_dpot_remove(struct device *dev); +void ad_dpot_remove(struct device *dev); #endif diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index baf83594a01d..8c72eb590f79 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -1536,7 +1536,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, (int)pcidev->revision); - ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); + ret = dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32)); if (ret < 0) return ret; diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index ad6ced454655..3b82d8ebe780 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -24,7 +24,7 @@ #define SDSP_DOMAIN_ID (2) #define CDSP_DOMAIN_ID (3) #define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/ -#define FASTRPC_MAX_SESSIONS 9 /*8 compute, 1 cpz*/ +#define FASTRPC_MAX_SESSIONS 13 /*12 compute, 1 cpz*/ #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 #define FASTRPC_MAX_CRCLIST 64 @@ -892,15 +892,17 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); for (i = inbufs; i < ctx->nbufs; ++i) { - void *src = (void *)(uintptr_t)rpra[i].pv; - void *dst = (void *)(uintptr_t)ctx->args[i].ptr; - u64 len = rpra[i].len; + if (!ctx->maps[i]) { + void *src = (void *)(uintptr_t)rpra[i].pv; + void *dst = (void *)(uintptr_t)ctx->args[i].ptr; + u64 len = rpra[i].len; - if (!kernel) { - if (copy_to_user((void __user *)dst, src, len)) - return -EFAULT; - } else { - memcpy(dst, src, len); + if (!kernel) { + if (copy_to_user((void __user *)dst, src, len)) + return -EFAULT; + } else { + memcpy(dst, src, len); + } } } diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 039b923d1d60..1167463f26fb 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -233,8 +233,8 @@ static void genwqe_unmap_pages(struct genwqe_dev *cd, dma_addr_t *dma_list, struct pci_dev *pci_dev = cd->pci_dev; for (i = 0; (i < num_pages) && (dma_list[i] != 0x0); i++) { - pci_unmap_page(pci_dev, dma_list[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + dma_unmap_page(&pci_dev->dev, dma_list[i], PAGE_SIZE, + DMA_BIDIRECTIONAL); dma_list[i] = 0x0; } } @@ -251,12 +251,12 @@ static int genwqe_map_pages(struct genwqe_dev *cd, dma_addr_t daddr; dma_list[i] = 0x0; - daddr = pci_map_page(pci_dev, page_list[i], + daddr = dma_map_page(&pci_dev->dev, page_list[i], 0, /* map_offs */ PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); /* FIXME rd/rw */ + DMA_BIDIRECTIONAL); /* FIXME rd/rw */ - if (pci_dma_mapping_error(pci_dev, daddr)) { + if (dma_mapping_error(&pci_dev->dev, daddr)) { dev_err(&pci_dev->dev, "[%s] err: no dma addr daddr=%016llx!\n", __func__, (long long)daddr); diff --git a/drivers/misc/hisi_hikey_usb.c b/drivers/misc/hisi_hikey_usb.c index 989d7d129469..2165ec35a343 100644 --- a/drivers/misc/hisi_hikey_usb.c +++ b/drivers/misc/hisi_hikey_usb.c @@ -34,7 +34,6 @@ struct hisi_hikey_usb { struct device *dev; struct gpio_desc *otg_switch; struct gpio_desc *typec_vbus; - struct gpio_desc *hub_vbus; struct gpio_desc *reset; struct regulator *regulator; @@ -54,9 +53,6 @@ static void hub_power_ctrl(struct hisi_hikey_usb *hisi_hikey_usb, int value) { int ret, status; - if (hisi_hikey_usb->hub_vbus) - gpiod_set_value_cansleep(hisi_hikey_usb->hub_vbus, value); - if (!hisi_hikey_usb->regulator) return; @@ -147,75 +143,50 @@ static int hub_usb_role_switch_set(struct usb_role_switch *sw, enum usb_role rol return 0; } -static int hisi_hikey_usb_parse_kirin970(struct platform_device *pdev, +static int hisi_hikey_usb_of_role_switch(struct platform_device *pdev, struct hisi_hikey_usb *hisi_hikey_usb) { - struct regulator *regulator; - - regulator = devm_regulator_get(&pdev->dev, "hub-vdd"); - if (IS_ERR(regulator)) { - if (PTR_ERR(regulator) == -EPROBE_DEFER) { - dev_info(&pdev->dev, - "waiting for hub-vdd-supply to be probed\n"); - return PTR_ERR(regulator); - } - dev_err(&pdev->dev, - "get hub-vdd-supply failed with error %ld\n", - PTR_ERR(regulator)); - return PTR_ERR(regulator); - } - hisi_hikey_usb->regulator = regulator; - - hisi_hikey_usb->reset = devm_gpiod_get(&pdev->dev, "hub_reset_en_gpio", - GPIOD_OUT_HIGH); - return PTR_ERR_OR_ZERO(hisi_hikey_usb->reset); -} - -static int hisi_hikey_usb_probe(struct platform_device *pdev) -{ struct device *dev = &pdev->dev; - struct hisi_hikey_usb *hisi_hikey_usb; struct usb_role_switch_desc hub_role_switch = {NULL}; - int ret; - hisi_hikey_usb = devm_kzalloc(dev, sizeof(*hisi_hikey_usb), GFP_KERNEL); - if (!hisi_hikey_usb) - return -ENOMEM; - - hisi_hikey_usb->dev = &pdev->dev; + if (!device_property_read_bool(dev, "usb-role-switch")) + return 0; hisi_hikey_usb->otg_switch = devm_gpiod_get(dev, "otg-switch", GPIOD_OUT_HIGH); - if (IS_ERR(hisi_hikey_usb->otg_switch)) + if (IS_ERR(hisi_hikey_usb->otg_switch)) { + dev_err(dev, "get otg-switch failed with error %ld\n", + PTR_ERR(hisi_hikey_usb->otg_switch)); return PTR_ERR(hisi_hikey_usb->otg_switch); + } hisi_hikey_usb->typec_vbus = devm_gpiod_get(dev, "typec-vbus", GPIOD_OUT_LOW); - if (IS_ERR(hisi_hikey_usb->typec_vbus)) + if (IS_ERR(hisi_hikey_usb->typec_vbus)) { + dev_err(dev, "get typec-vbus failed with error %ld\n", + PTR_ERR(hisi_hikey_usb->typec_vbus)); return PTR_ERR(hisi_hikey_usb->typec_vbus); + } - /* Parse Kirin 970-specific OF data */ - if (of_device_is_compatible(pdev->dev.of_node, - "hisilicon,kirin970_hikey_usbhub")) { - ret = hisi_hikey_usb_parse_kirin970(pdev, hisi_hikey_usb); - if (ret) - return ret; - } else { - /* hub-vdd33-en is optional */ - hisi_hikey_usb->hub_vbus = devm_gpiod_get_optional(dev, "hub-vdd33-en", - GPIOD_OUT_HIGH); - if (IS_ERR(hisi_hikey_usb->hub_vbus)) - return PTR_ERR(hisi_hikey_usb->hub_vbus); + hisi_hikey_usb->reset = devm_gpiod_get_optional(dev, + "hub-reset-en", + GPIOD_OUT_HIGH); + if (IS_ERR(hisi_hikey_usb->reset)) { + dev_err(dev, "get hub-reset-en failed with error %ld\n", + PTR_ERR(hisi_hikey_usb->reset)); + return PTR_ERR(hisi_hikey_usb->reset); } hisi_hikey_usb->dev_role_sw = usb_role_switch_get(dev); if (!hisi_hikey_usb->dev_role_sw) return -EPROBE_DEFER; - if (IS_ERR(hisi_hikey_usb->dev_role_sw)) + if (IS_ERR(hisi_hikey_usb->dev_role_sw)) { + dev_err(dev, "get device role switch failed with error %ld\n", + PTR_ERR(hisi_hikey_usb->dev_role_sw)); return PTR_ERR(hisi_hikey_usb->dev_role_sw); + } INIT_WORK(&hisi_hikey_usb->work, relay_set_role_switch); - mutex_init(&hisi_hikey_usb->lock); hub_role_switch.fwnode = dev_fwnode(dev); hub_role_switch.set = hub_usb_role_switch_set; @@ -225,10 +196,44 @@ static int hisi_hikey_usb_probe(struct platform_device *pdev) &hub_role_switch); if (IS_ERR(hisi_hikey_usb->hub_role_sw)) { + dev_err(dev, + "failed to register hub role with error %ld\n", + PTR_ERR(hisi_hikey_usb->hub_role_sw)); usb_role_switch_put(hisi_hikey_usb->dev_role_sw); return PTR_ERR(hisi_hikey_usb->hub_role_sw); } + return 0; +} + +static int hisi_hikey_usb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hisi_hikey_usb *hisi_hikey_usb; + int ret; + + hisi_hikey_usb = devm_kzalloc(dev, sizeof(*hisi_hikey_usb), GFP_KERNEL); + if (!hisi_hikey_usb) + return -ENOMEM; + + hisi_hikey_usb->dev = &pdev->dev; + mutex_init(&hisi_hikey_usb->lock); + + hisi_hikey_usb->regulator = devm_regulator_get(dev, "hub-vdd"); + if (IS_ERR(hisi_hikey_usb->regulator)) { + if (PTR_ERR(hisi_hikey_usb->regulator) == -EPROBE_DEFER) { + dev_info(dev, "waiting for hub-vdd-supply\n"); + return PTR_ERR(hisi_hikey_usb->regulator); + } + dev_err(dev, "get hub-vdd-supply failed with error %ld\n", + PTR_ERR(hisi_hikey_usb->regulator)); + return PTR_ERR(hisi_hikey_usb->regulator); + } + + ret = hisi_hikey_usb_of_role_switch(pdev, hisi_hikey_usb); + if (ret) + return ret; + platform_set_drvdata(pdev, hisi_hikey_usb); return 0; @@ -238,18 +243,20 @@ static int hisi_hikey_usb_remove(struct platform_device *pdev) { struct hisi_hikey_usb *hisi_hikey_usb = platform_get_drvdata(pdev); - if (hisi_hikey_usb->hub_role_sw) + if (hisi_hikey_usb->hub_role_sw) { usb_role_switch_unregister(hisi_hikey_usb->hub_role_sw); - if (hisi_hikey_usb->dev_role_sw) - usb_role_switch_put(hisi_hikey_usb->dev_role_sw); + if (hisi_hikey_usb->dev_role_sw) + usb_role_switch_put(hisi_hikey_usb->dev_role_sw); + } else { + hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_OFF); + } return 0; } static const struct of_device_id id_table_hisi_hikey_usb[] = { - { .compatible = "hisilicon,gpio_hubv1" }, - { .compatible = "hisilicon,kirin970_hikey_usbhub" }, + { .compatible = "hisilicon,usbhub" }, {} }; MODULE_DEVICE_TABLE(of, id_table_hisi_hikey_usb); diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 70c5bb1e6f49..3a7808b796b1 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -878,7 +878,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3) return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); } -int lis3lv02d_remove_fs(struct lis3lv02d *lis3) +void lis3lv02d_remove_fs(struct lis3lv02d *lis3) { sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); platform_device_unregister(lis3->pdev); @@ -894,7 +894,6 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) pm_runtime_set_suspended(lis3->pm_dev); } kfree(lis3->reg_cache); - return 0; } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index c394c0b08519..195bd2fd2eb5 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h @@ -312,7 +312,7 @@ int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); void lis3lv02d_poweroff(struct lis3lv02d *lis3); int lis3lv02d_poweron(struct lis3lv02d *lis3); -int lis3lv02d_remove_fs(struct lis3lv02d *lis3); +void lis3lv02d_remove_fs(struct lis3lv02d *lis3); int lis3lv02d_init_dt(struct lis3lv02d *lis3); extern struct lis3lv02d lis3_dev; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index f664ed123730..9e40dfb60742 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -102,7 +102,9 @@ static int lis302dl_spi_remove(struct spi_device *spi) lis3lv02d_joystick_disable(lis3); lis3lv02d_poweroff(lis3); - return lis3lv02d_remove_fs(&lis3_dev); + lis3lv02d_remove_fs(&lis3_dev); + + return 0; } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index aec0483b8e72..fa20d9a27813 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -69,9 +69,9 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto end; } - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { dev_err(&pdev->dev, "No suitable DMA available.\n"); goto end; diff --git a/drivers/misc/pvpanic/pvpanic-mmio.c b/drivers/misc/pvpanic/pvpanic-mmio.c index be4016084979..eb97167c03fb 100644 --- a/drivers/misc/pvpanic/pvpanic-mmio.c +++ b/drivers/misc/pvpanic/pvpanic-mmio.c @@ -24,8 +24,7 @@ MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>"); MODULE_DESCRIPTION("pvpanic-mmio device driver"); MODULE_LICENSE("GPL"); -static ssize_t capability_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pvpanic_instance *pi = dev_get_drvdata(dev); @@ -33,14 +32,14 @@ static ssize_t capability_show(struct device *dev, } static DEVICE_ATTR_RO(capability); -static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pvpanic_instance *pi = dev_get_drvdata(dev); return sysfs_emit(buf, "%x\n", pi->events); } -static ssize_t events_store(struct device *dev, struct device_attribute *attr, +static ssize_t events_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pvpanic_instance *pi = dev_get_drvdata(dev); @@ -100,7 +99,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) pi->base = base; pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; - /* initlize capability by RDPT */ + /* initialize capability by RDPT */ pi->capability &= ioread8(base); pi->events = pi->capability; diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c index 741116b3d995..07eddb5ea30f 100644 --- a/drivers/misc/pvpanic/pvpanic-pci.c +++ b/drivers/misc/pvpanic/pvpanic-pci.c @@ -19,16 +19,10 @@ #define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011 MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>"); -MODULE_DESCRIPTION("pvpanic device driver "); +MODULE_DESCRIPTION("pvpanic device driver"); MODULE_LICENSE("GPL"); -static const struct pci_device_id pvpanic_pci_id_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PVPANIC)}, - {} -}; - -static ssize_t capability_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pvpanic_instance *pi = dev_get_drvdata(dev); @@ -36,14 +30,14 @@ static ssize_t capability_show(struct device *dev, } static DEVICE_ATTR_RO(capability); -static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pvpanic_instance *pi = dev_get_drvdata(dev); return sysfs_emit(buf, "%x\n", pi->events); } -static ssize_t events_store(struct device *dev, struct device_attribute *attr, +static ssize_t events_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pvpanic_instance *pi = dev_get_drvdata(dev); @@ -70,8 +64,7 @@ static struct attribute *pvpanic_pci_dev_attrs[] = { }; ATTRIBUTE_GROUPS(pvpanic_pci_dev); -static int pvpanic_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int pvpanic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct pvpanic_instance *pi; void __iomem *base; @@ -99,6 +92,12 @@ static int pvpanic_pci_probe(struct pci_dev *pdev, return devm_pvpanic_probe(&pdev->dev, pi); } +static const struct pci_device_id pvpanic_pci_id_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PVPANIC)}, + {} +}; +MODULE_DEVICE_TABLE(pci, pvpanic_pci_id_tbl); + static struct pci_driver pvpanic_pci_driver = { .name = "pvpanic-pci", .id_table = pvpanic_pci_id_tbl, @@ -107,7 +106,4 @@ static struct pci_driver pvpanic_pci_driver = { .dev_groups = pvpanic_pci_dev_groups, }, }; - -MODULE_DEVICE_TABLE(pci, pvpanic_pci_id_tbl); - module_pci_driver(pvpanic_pci_driver); diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c index bb7aa6368538..4b8f1c7d726d 100644 --- a/drivers/misc/pvpanic/pvpanic.c +++ b/drivers/misc/pvpanic/pvpanic.c @@ -23,7 +23,7 @@ #include "pvpanic.h" MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>"); -MODULE_DESCRIPTION("pvpanic device driver "); +MODULE_DESCRIPTION("pvpanic device driver"); MODULE_LICENSE("GPL"); static struct list_head pvpanic_list; @@ -43,8 +43,7 @@ pvpanic_send_event(unsigned int event) } static int -pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, - void *unused) +pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, void *unused) { unsigned int event = PVPANIC_PANICKED; @@ -58,7 +57,7 @@ pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, static struct notifier_block pvpanic_panic_nb = { .notifier_call = pvpanic_panic_notify, - .priority = 1, /* let this called before broken drm_fb_helper */ + .priority = 1, /* let this called before broken drm_fb_helper() */ }; static void pvpanic_remove(void *param) @@ -96,18 +95,15 @@ static int pvpanic_init(void) INIT_LIST_HEAD(&pvpanic_list); spin_lock_init(&pvpanic_lock); - atomic_notifier_chain_register(&panic_notifier_list, - &pvpanic_panic_nb); + atomic_notifier_chain_register(&panic_notifier_list, &pvpanic_panic_nb); return 0; } +module_init(pvpanic_init); static void pvpanic_exit(void) { - atomic_notifier_chain_unregister(&panic_notifier_list, - &pvpanic_panic_nb); + atomic_notifier_chain_unregister(&panic_notifier_list, &pvpanic_panic_nb); } - -module_init(pvpanic_init); module_exit(pvpanic_exit); diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 228f2eb1d476..017c2f7d6287 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c @@ -311,7 +311,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev, int pci_dev_busy = 0; int rc; - rc = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); + rc = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); if (rc) return rc; diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 52656fc87e99..a3098fea3bf7 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -176,8 +176,7 @@ struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, { struct tifm_adapter *fm; - fm = kzalloc(sizeof(struct tifm_adapter) - + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); + fm = kzalloc(struct_size(fm, sockets, num_sockets), GFP_KERNEL); if (fm) { fm->dev.class = &tifm_adapter_class; fm->dev.parent = dev; @@ -293,14 +292,15 @@ EXPORT_SYMBOL(tifm_has_ms_pif); int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, int direction) { - return pci_map_sg(to_pci_dev(sock->dev.parent), sg, nents, direction); + return dma_map_sg(&to_pci_dev(sock->dev.parent)->dev, sg, nents, + direction); } EXPORT_SYMBOL(tifm_map_sg); void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, int direction) { - pci_unmap_sg(to_pci_dev(sock->dev.parent), sg, nents, direction); + dma_unmap_sg(&to_pci_dev(sock->dev.parent)->dev, sg, nents, direction); } EXPORT_SYMBOL(tifm_unmap_sg); diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 8976da38b375..e765d3d0542e 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -38,6 +38,7 @@ struct nvmem_device { unsigned int nkeepout; nvmem_reg_read_t reg_read; nvmem_reg_write_t reg_write; + nvmem_cell_post_process_t cell_post_process; struct gpio_desc *wp_gpio; void *priv; }; @@ -45,8 +46,7 @@ struct nvmem_device { #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) #define FLAG_COMPAT BIT(0) - -struct nvmem_cell { +struct nvmem_cell_entry { const char *name; int offset; int bytes; @@ -57,6 +57,11 @@ struct nvmem_cell { struct list_head node; }; +struct nvmem_cell { + struct nvmem_cell_entry *entry; + const char *id; +}; + static DEFINE_MUTEX(nvmem_mutex); static DEFINE_IDA(nvmem_ida); @@ -422,7 +427,7 @@ static struct bus_type nvmem_bus_type = { .name = "nvmem", }; -static void nvmem_cell_drop(struct nvmem_cell *cell) +static void nvmem_cell_entry_drop(struct nvmem_cell_entry *cell) { blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell); mutex_lock(&nvmem_mutex); @@ -435,13 +440,13 @@ static void nvmem_cell_drop(struct nvmem_cell *cell) static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem) { - struct nvmem_cell *cell, *p; + struct nvmem_cell_entry *cell, *p; list_for_each_entry_safe(cell, p, &nvmem->cells, node) - nvmem_cell_drop(cell); + nvmem_cell_entry_drop(cell); } -static void nvmem_cell_add(struct nvmem_cell *cell) +static void nvmem_cell_entry_add(struct nvmem_cell_entry *cell) { mutex_lock(&nvmem_mutex); list_add_tail(&cell->node, &cell->nvmem->cells); @@ -449,9 +454,9 @@ static void nvmem_cell_add(struct nvmem_cell *cell) blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); } -static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info, - struct nvmem_cell *cell) +static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info, + struct nvmem_cell_entry *cell) { cell->nvmem = nvmem; cell->offset = info->offset; @@ -475,13 +480,13 @@ static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, return 0; } -static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info, - struct nvmem_cell *cell) +static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info, + struct nvmem_cell_entry *cell) { int err; - err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell); + err = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, cell); if (err) return err; @@ -505,7 +510,7 @@ static int nvmem_add_cells(struct nvmem_device *nvmem, const struct nvmem_cell_info *info, int ncells) { - struct nvmem_cell **cells; + struct nvmem_cell_entry **cells; int i, rval; cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); @@ -519,13 +524,13 @@ static int nvmem_add_cells(struct nvmem_device *nvmem, goto err; } - rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]); + rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); if (rval) { kfree(cells[i]); goto err; } - nvmem_cell_add(cells[i]); + nvmem_cell_entry_add(cells[i]); } /* remove tmp array */ @@ -534,7 +539,7 @@ static int nvmem_add_cells(struct nvmem_device *nvmem, return 0; err: while (i--) - nvmem_cell_drop(cells[i]); + nvmem_cell_entry_drop(cells[i]); kfree(cells); @@ -571,7 +576,7 @@ static int nvmem_add_cells_from_table(struct nvmem_device *nvmem) { const struct nvmem_cell_info *info; struct nvmem_cell_table *table; - struct nvmem_cell *cell; + struct nvmem_cell_entry *cell; int rval = 0, i; mutex_lock(&nvmem_cell_mutex); @@ -586,15 +591,13 @@ static int nvmem_add_cells_from_table(struct nvmem_device *nvmem) goto out; } - rval = nvmem_cell_info_to_nvmem_cell(nvmem, - info, - cell); + rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); if (rval) { kfree(cell); goto out; } - nvmem_cell_add(cell); + nvmem_cell_entry_add(cell); } } } @@ -604,10 +607,10 @@ out: return rval; } -static struct nvmem_cell * -nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) +static struct nvmem_cell_entry * +nvmem_find_cell_entry_by_name(struct nvmem_device *nvmem, const char *cell_id) { - struct nvmem_cell *iter, *cell = NULL; + struct nvmem_cell_entry *iter, *cell = NULL; mutex_lock(&nvmem_mutex); list_for_each_entry(iter, &nvmem->cells, node) { @@ -678,7 +681,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) { struct device_node *parent, *child; struct device *dev = &nvmem->dev; - struct nvmem_cell *cell; + struct nvmem_cell_entry *cell; const __be32 *addr; int len; @@ -727,7 +730,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) } cell->np = of_node_get(child); - nvmem_cell_add(cell); + nvmem_cell_entry_add(cell); } return 0; @@ -794,6 +797,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->type = config->type; nvmem->reg_read = config->reg_read; nvmem->reg_write = config->reg_write; + nvmem->cell_post_process = config->cell_post_process; nvmem->keepout = config->keepout; nvmem->nkeepout = config->nkeepout; if (config->of_node) @@ -1142,9 +1146,33 @@ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(devm_nvmem_device_get); +static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) +{ + struct nvmem_cell *cell; + const char *name = NULL; + + cell = kzalloc(sizeof(*cell), GFP_KERNEL); + if (!cell) + return ERR_PTR(-ENOMEM); + + if (id) { + name = kstrdup_const(id, GFP_KERNEL); + if (!name) { + kfree(cell); + return ERR_PTR(-ENOMEM); + } + } + + cell->id = name; + cell->entry = entry; + + return cell; +} + static struct nvmem_cell * nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) { + struct nvmem_cell_entry *cell_entry; struct nvmem_cell *cell = ERR_PTR(-ENOENT); struct nvmem_cell_lookup *lookup; struct nvmem_device *nvmem; @@ -1169,11 +1197,15 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) break; } - cell = nvmem_find_cell_by_name(nvmem, - lookup->cell_name); - if (!cell) { + cell_entry = nvmem_find_cell_entry_by_name(nvmem, + lookup->cell_name); + if (!cell_entry) { __nvmem_device_put(nvmem); cell = ERR_PTR(-ENOENT); + } else { + cell = nvmem_create_cell(cell_entry, con_id); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); } break; } @@ -1184,10 +1216,10 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) } #if IS_ENABLED(CONFIG_OF) -static struct nvmem_cell * -nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) +static struct nvmem_cell_entry * +nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) { - struct nvmem_cell *iter, *cell = NULL; + struct nvmem_cell_entry *iter, *cell = NULL; mutex_lock(&nvmem_mutex); list_for_each_entry(iter, &nvmem->cells, node) { @@ -1217,6 +1249,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id) { struct device_node *cell_np, *nvmem_np; struct nvmem_device *nvmem; + struct nvmem_cell_entry *cell_entry; struct nvmem_cell *cell; int index = 0; @@ -1237,12 +1270,16 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id) if (IS_ERR(nvmem)) return ERR_CAST(nvmem); - cell = nvmem_find_cell_by_node(nvmem, cell_np); - if (!cell) { + cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); + if (!cell_entry) { __nvmem_device_put(nvmem); return ERR_PTR(-ENOENT); } + cell = nvmem_create_cell(cell_entry, id); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + return cell; } EXPORT_SYMBOL_GPL(of_nvmem_cell_get); @@ -1348,13 +1385,17 @@ EXPORT_SYMBOL(devm_nvmem_cell_put); */ void nvmem_cell_put(struct nvmem_cell *cell) { - struct nvmem_device *nvmem = cell->nvmem; + struct nvmem_device *nvmem = cell->entry->nvmem; + if (cell->id) + kfree_const(cell->id); + + kfree(cell); __nvmem_device_put(nvmem); } EXPORT_SYMBOL_GPL(nvmem_cell_put); -static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf) +static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf) { u8 *p, *b; int i, extra, bit_offset = cell->bit_offset; @@ -1388,8 +1429,8 @@ static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf) } static int __nvmem_cell_read(struct nvmem_device *nvmem, - struct nvmem_cell *cell, - void *buf, size_t *len) + struct nvmem_cell_entry *cell, + void *buf, size_t *len, const char *id) { int rc; @@ -1402,6 +1443,13 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, if (cell->bit_offset || cell->nbits) nvmem_shift_read_buffer_in_place(cell, buf); + if (nvmem->cell_post_process) { + rc = nvmem->cell_post_process(nvmem->priv, id, + cell->offset, buf, cell->bytes); + if (rc) + return rc; + } + if (len) *len = cell->bytes; @@ -1420,18 +1468,18 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, */ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) { - struct nvmem_device *nvmem = cell->nvmem; + struct nvmem_device *nvmem = cell->entry->nvmem; u8 *buf; int rc; if (!nvmem) return ERR_PTR(-EINVAL); - buf = kzalloc(cell->bytes, GFP_KERNEL); + buf = kzalloc(cell->entry->bytes, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); - rc = __nvmem_cell_read(nvmem, cell, buf, len); + rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); if (rc) { kfree(buf); return ERR_PTR(rc); @@ -1441,7 +1489,7 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) } EXPORT_SYMBOL_GPL(nvmem_cell_read); -static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, +static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell, u8 *_buf, int len) { struct nvmem_device *nvmem = cell->nvmem; @@ -1494,16 +1542,7 @@ err: return ERR_PTR(rc); } -/** - * nvmem_cell_write() - Write to a given nvmem cell - * - * @cell: nvmem cell to be written. - * @buf: Buffer to be written. - * @len: length of buffer to be written to nvmem cell. - * - * Return: length of bytes written or negative on failure. - */ -int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) +static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, size_t len) { struct nvmem_device *nvmem = cell->nvmem; int rc; @@ -1529,6 +1568,21 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) return len; } + +/** + * nvmem_cell_write() - Write to a given nvmem cell + * + * @cell: nvmem cell to be written. + * @buf: Buffer to be written. + * @len: length of buffer to be written to nvmem cell. + * + * Return: length of bytes written or negative on failure. + */ +int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) +{ + return __nvmem_cell_entry_write(cell->entry, buf, len); +} + EXPORT_SYMBOL_GPL(nvmem_cell_write); static int nvmem_cell_read_common(struct device *dev, const char *cell_id, @@ -1631,7 +1685,7 @@ static const void *nvmem_cell_read_variable_common(struct device *dev, if (IS_ERR(cell)) return cell; - nbits = cell->nbits; + nbits = cell->entry->nbits; buf = nvmem_cell_read(cell, len); nvmem_cell_put(cell); if (IS_ERR(buf)) @@ -1727,18 +1781,18 @@ EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u64); ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem, struct nvmem_cell_info *info, void *buf) { - struct nvmem_cell cell; + struct nvmem_cell_entry cell; int rc; ssize_t len; if (!nvmem) return -EINVAL; - rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); + rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); if (rc) return rc; - rc = __nvmem_cell_read(nvmem, &cell, buf, &len); + rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); if (rc) return rc; @@ -1758,17 +1812,17 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read); int nvmem_device_cell_write(struct nvmem_device *nvmem, struct nvmem_cell_info *info, void *buf) { - struct nvmem_cell cell; + struct nvmem_cell_entry cell; int rc; if (!nvmem) return -EINVAL; - rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); + rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); if (rc) return rc; - return nvmem_cell_write(&cell, buf, cell.bytes); + return __nvmem_cell_entry_write(&cell, buf, cell.bytes); } EXPORT_SYMBOL_GPL(nvmem_device_cell_write); diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c index 08f41328cc71..14284e866f26 100644 --- a/drivers/nvmem/imx-ocotp.c +++ b/drivers/nvmem/imx-ocotp.c @@ -97,6 +97,7 @@ struct ocotp_params { unsigned int bank_address_words; void (*set_timing)(struct ocotp_priv *priv); struct ocotp_ctrl_reg ctrl; + bool reverse_mac_address; }; static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) @@ -221,6 +222,25 @@ read_end: return ret; } +static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, + void *data, size_t bytes) +{ + struct ocotp_priv *priv = context; + + /* Deal with some post processing of nvmem cell data */ + if (id && !strcmp(id, "mac-address")) { + if (priv->params->reverse_mac_address) { + u8 *buf = data; + int i; + + for (i = 0; i < bytes/2; i++) + swap(buf[i], buf[bytes - i - 1]); + } + } + + return 0; +} + static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv) { unsigned long clk_rate; @@ -468,6 +488,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = { .stride = 1, .reg_read = imx_ocotp_read, .reg_write = imx_ocotp_write, + .cell_post_process = imx_ocotp_cell_pp, }; static const struct ocotp_params imx6q_params = { @@ -530,6 +551,7 @@ static const struct ocotp_params imx8mq_params = { .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, + .reverse_mac_address = true, }; static const struct ocotp_params imx8mm_params = { @@ -537,6 +559,7 @@ static const struct ocotp_params imx8mm_params = { .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, + .reverse_mac_address = true, }; static const struct ocotp_params imx8mn_params = { @@ -544,6 +567,7 @@ static const struct ocotp_params imx8mn_params = { .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, + .reverse_mac_address = true, }; static const struct ocotp_params imx8mp_params = { @@ -551,6 +575,7 @@ static const struct ocotp_params imx8mp_params = { .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, .ctrl = IMX_OCOTP_BM_CTRL_8MP, + .reverse_mac_address = true, }; static const struct of_device_id imx_ocotp_dt_ids[] = { diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index cc53f725c041..b183967ecfb7 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -349,7 +349,8 @@ static int lis3lv02d_remove(struct platform_device *device) led_classdev_unregister(&hpled_led.led_classdev); flush_work(&hpled_led.work); - return lis3lv02d_remove_fs(&lis3_dev); + lis3lv02d_remove_fs(&lis3_dev); + return 0; } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c index 130e12b8652a..5419794fccf1 100644 --- a/drivers/virt/acrn/hsm.c +++ b/drivers/virt/acrn/hsm.c @@ -114,9 +114,11 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, struct acrn_ptdev_irq *irq_info; struct acrn_ioeventfd ioeventfd; struct acrn_vm_memmap memmap; + struct acrn_mmiodev *mmiodev; struct acrn_msi_entry *msi; struct acrn_pcidev *pcidev; struct acrn_irqfd irqfd; + struct acrn_vdev *vdev; struct page *page; u64 cstate_cmd; int i, ret = 0; @@ -217,6 +219,30 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, ret = acrn_vm_memseg_unmap(vm, &memmap); break; + case ACRN_IOCTL_ASSIGN_MMIODEV: + mmiodev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_mmiodev)); + if (IS_ERR(mmiodev)) + return PTR_ERR(mmiodev); + + ret = hcall_assign_mmiodev(vm->vmid, virt_to_phys(mmiodev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to assign MMIO device!\n"); + kfree(mmiodev); + break; + case ACRN_IOCTL_DEASSIGN_MMIODEV: + mmiodev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_mmiodev)); + if (IS_ERR(mmiodev)) + return PTR_ERR(mmiodev); + + ret = hcall_deassign_mmiodev(vm->vmid, virt_to_phys(mmiodev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to deassign MMIO device!\n"); + kfree(mmiodev); + break; case ACRN_IOCTL_ASSIGN_PCIDEV: pcidev = memdup_user((void __user *)ioctl_param, sizeof(struct acrn_pcidev)); @@ -241,6 +267,29 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, "Failed to deassign pci device!\n"); kfree(pcidev); break; + case ACRN_IOCTL_CREATE_VDEV: + vdev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_vdev)); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + ret = hcall_create_vdev(vm->vmid, virt_to_phys(vdev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to create virtual device!\n"); + kfree(vdev); + break; + case ACRN_IOCTL_DESTROY_VDEV: + vdev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_vdev)); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + ret = hcall_destroy_vdev(vm->vmid, virt_to_phys(vdev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to destroy virtual device!\n"); + kfree(vdev); + break; case ACRN_IOCTL_SET_PTDEV_INTR: irq_info = memdup_user((void __user *)ioctl_param, sizeof(struct acrn_ptdev_irq)); diff --git a/drivers/virt/acrn/hypercall.h b/drivers/virt/acrn/hypercall.h index 0cfad05bd1a9..71d300821a18 100644 --- a/drivers/virt/acrn/hypercall.h +++ b/drivers/virt/acrn/hypercall.h @@ -41,6 +41,10 @@ #define HC_RESET_PTDEV_INTR _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x04) #define HC_ASSIGN_PCIDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x05) #define HC_DEASSIGN_PCIDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x06) +#define HC_ASSIGN_MMIODEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x07) +#define HC_DEASSIGN_MMIODEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x08) +#define HC_CREATE_VDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x09) +#define HC_DESTROY_VDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x0A) #define HC_ID_PM_BASE 0x80UL #define HC_PM_GET_CPU_STATE _HC_ID(HC_ID, HC_ID_PM_BASE + 0x00) @@ -195,6 +199,54 @@ static inline long hcall_set_memory_regions(u64 regions_pa) } /** + * hcall_create_vdev() - Create a virtual device for a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_vdev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_create_vdev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_CREATE_VDEV, vmid, addr); +} + +/** + * hcall_destroy_vdev() - Destroy a virtual device of a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_vdev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_destroy_vdev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_DESTROY_VDEV, vmid, addr); +} + +/** + * hcall_assign_mmiodev() - Assign a MMIO device to a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_mmiodev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_assign_mmiodev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_ASSIGN_MMIODEV, vmid, addr); +} + +/** + * hcall_deassign_mmiodev() - De-assign a PCI device from a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_mmiodev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_deassign_mmiodev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_DEASSIGN_MMIODEV, vmid, addr); +} + +/** * hcall_assign_pcidev() - Assign a PCI device to a User VM * @vmid: User VM ID * @addr: Service VM GPA of the &struct acrn_pcidev diff --git a/drivers/virt/nitro_enclaves/Kconfig b/drivers/virt/nitro_enclaves/Kconfig index 8c9387a232df..f53740b941c0 100644 --- a/drivers/virt/nitro_enclaves/Kconfig +++ b/drivers/virt/nitro_enclaves/Kconfig @@ -1,17 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 # -# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # Amazon Nitro Enclaves (NE) support. # Nitro is a hypervisor that has been developed by Amazon. -# TODO: Add dependency for ARM64 once NE is supported on Arm platforms. For now, -# the NE kernel driver can be built for aarch64 arch. -# depends on (ARM64 || X86) && HOTPLUG_CPU && PCI && SMP - config NITRO_ENCLAVES tristate "Nitro Enclaves Support" - depends on X86 && HOTPLUG_CPU && PCI && SMP + depends on (ARM64 || X86) && HOTPLUG_CPU && PCI && SMP help This driver consists of support for enclave lifetime management for Nitro Enclaves (NE). diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c index e21e1e86ad15..8939612ee0e0 100644 --- a/drivers/virt/nitro_enclaves/ne_misc_dev.c +++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ /** @@ -284,8 +284,8 @@ static int ne_setup_cpu_pool(const char *ne_cpu_list) ne_cpu_pool.nr_parent_vm_cores = nr_cpu_ids / ne_cpu_pool.nr_threads_per_core; ne_cpu_pool.avail_threads_per_core = kcalloc(ne_cpu_pool.nr_parent_vm_cores, - sizeof(*ne_cpu_pool.avail_threads_per_core), - GFP_KERNEL); + sizeof(*ne_cpu_pool.avail_threads_per_core), + GFP_KERNEL); if (!ne_cpu_pool.avail_threads_per_core) { rc = -ENOMEM; @@ -735,7 +735,7 @@ static int ne_add_vcpu_ioctl(struct ne_enclave *ne_enclave, u32 vcpu_id) * * Negative return value on failure. */ static int ne_sanity_check_user_mem_region(struct ne_enclave *ne_enclave, - struct ne_user_memory_region mem_region) + struct ne_user_memory_region mem_region) { struct ne_mem_region *ne_mem_region = NULL; @@ -771,7 +771,7 @@ static int ne_sanity_check_user_mem_region(struct ne_enclave *ne_enclave, u64 userspace_addr = ne_mem_region->userspace_addr; if ((userspace_addr <= mem_region.userspace_addr && - mem_region.userspace_addr < (userspace_addr + memory_size)) || + mem_region.userspace_addr < (userspace_addr + memory_size)) || (mem_region.userspace_addr <= userspace_addr && (mem_region.userspace_addr + mem_region.memory_size) > userspace_addr)) { dev_err_ratelimited(ne_misc_dev.this_device, @@ -836,7 +836,7 @@ static int ne_sanity_check_user_mem_region_page(struct ne_enclave *ne_enclave, * * Negative return value on failure. */ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave, - struct ne_user_memory_region mem_region) + struct ne_user_memory_region mem_region) { long gup_rc = 0; unsigned long i = 0; @@ -1014,7 +1014,7 @@ free_mem_region: * * Negative return value on failure. */ static int ne_start_enclave_ioctl(struct ne_enclave *ne_enclave, - struct ne_enclave_start_info *enclave_start_info) + struct ne_enclave_start_info *enclave_start_info) { struct ne_pci_dev_cmd_reply cmd_reply = {}; unsigned int cpu = 0; @@ -1574,7 +1574,8 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui mutex_unlock(&ne_cpu_pool.mutex); ne_enclave->threads_per_core = kcalloc(ne_enclave->nr_parent_vm_cores, - sizeof(*ne_enclave->threads_per_core), GFP_KERNEL); + sizeof(*ne_enclave->threads_per_core), + GFP_KERNEL); if (!ne_enclave->threads_per_core) { rc = -ENOMEM; diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c b/drivers/virt/nitro_enclaves/ne_pci_dev.c index 143207e9b969..40b49ec8e30b 100644 --- a/drivers/virt/nitro_enclaves/ne_pci_dev.c +++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ /** diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.h b/drivers/virt/nitro_enclaves/ne_pci_dev.h index 8bfbc6607818..6e9f28971a4e 100644 --- a/drivers/virt/nitro_enclaves/ne_pci_dev.h +++ b/drivers/virt/nitro_enclaves/ne_pci_dev.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ #ifndef _NE_PCI_DEV_H_ @@ -84,9 +84,13 @@ */ /** - * NE_SEND_DATA_SIZE / NE_RECV_DATA_SIZE - 240 bytes for send / recv buffer. + * NE_SEND_DATA_SIZE - Size of the send buffer, in bytes. */ #define NE_SEND_DATA_SIZE (240) + +/** + * NE_RECV_DATA_SIZE - Size of the receive buffer, in bytes. + */ #define NE_RECV_DATA_SIZE (240) /** diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 104505e9028f..98efb7b5660d 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, void *val, size_t bytes); typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, void *val, size_t bytes); +/* used for vendor specific post processing of cell data */ +typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, + void *buf, size_t bytes); enum nvmem_type { NVMEM_TYPE_UNKNOWN = 0, @@ -62,6 +65,7 @@ struct nvmem_keepout { * @no_of_node: Device should not use the parent's of_node even if it's !NULL. * @reg_read: Callback to read data. * @reg_write: Callback to write data. + * @cell_post_process: Callback for vendor specific post processing of cell data * @size: Device size. * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. @@ -92,6 +96,7 @@ struct nvmem_config { bool no_of_node; nvmem_reg_read_t reg_read; nvmem_reg_write_t reg_write; + nvmem_cell_post_process_t cell_post_process; int size; int word_size; int stride; diff --git a/include/uapi/linux/acrn.h b/include/uapi/linux/acrn.h index 353b2a2e4536..ccf47ed92500 100644 --- a/include/uapi/linux/acrn.h +++ b/include/uapi/linux/acrn.h @@ -396,6 +396,7 @@ struct acrn_ptdev_irq { /* Type of PCI device assignment */ #define ACRN_PTDEV_QUIRK_ASSIGN (1U << 0) +#define ACRN_MMIODEV_RES_NUM 3 #define ACRN_PCI_NUM_BARS 6 /** * struct acrn_pcidev - Info for assigning or de-assigning a PCI device @@ -418,6 +419,67 @@ struct acrn_pcidev { }; /** + * struct acrn_mmiodev - Info for assigning or de-assigning a MMIO device + * @name: Name of the MMIO device. + * @res[].user_vm_pa: Physical address of User VM of the MMIO region + * for the MMIO device. + * @res[].service_vm_pa: Physical address of Service VM of the MMIO + * region for the MMIO device. + * @res[].size: Size of the MMIO region for the MMIO device. + * @res[].mem_type: Memory type of the MMIO region for the MMIO + * device. + * + * This structure will be passed to hypervisor directly. + */ +struct acrn_mmiodev { + __u8 name[8]; + struct { + __u64 user_vm_pa; + __u64 service_vm_pa; + __u64 size; + __u64 mem_type; + } res[ACRN_MMIODEV_RES_NUM]; +}; + +/** + * struct acrn_vdev - Info for creating or destroying a virtual device + * @id: Union of identifier of the virtual device + * @id.value: Raw data of the identifier + * @id.fields.vendor: Vendor id of the virtual PCI device + * @id.fields.device: Device id of the virtual PCI device + * @id.fields.legacy_id: ID of the virtual device if not a PCI device + * @slot: Virtual Bus/Device/Function of the virtual + * device + * @io_base: IO resource base address of the virtual device + * @io_size: IO resource size of the virtual device + * @args: Arguments for the virtual device creation + * + * The created virtual device can be a PCI device or a legacy device (e.g. + * a virtual UART controller) and it is emulated by the hypervisor. This + * structure will be passed to hypervisor directly. + */ +struct acrn_vdev { + /* + * the identifier of the device, the low 32 bits represent the vendor + * id and device id of PCI device and the high 32 bits represent the + * device number of the legacy device + */ + union { + __u64 value; + struct { + __le16 vendor; + __le16 device; + __le32 legacy_id; + } fields; + } id; + + __u64 slot; + __u32 io_addr[ACRN_PCI_NUM_BARS]; + __u32 io_size[ACRN_PCI_NUM_BARS]; + __u8 args[128]; +}; + +/** * struct acrn_msi_entry - Info for injecting a MSI interrupt to a VM * @msi_addr: MSI addr[19:12] with dest vCPU ID * @msi_data: MSI data[7:0] with vector @@ -568,6 +630,14 @@ struct acrn_irqfd { _IOW(ACRN_IOCTL_TYPE, 0x55, struct acrn_pcidev) #define ACRN_IOCTL_DEASSIGN_PCIDEV \ _IOW(ACRN_IOCTL_TYPE, 0x56, struct acrn_pcidev) +#define ACRN_IOCTL_ASSIGN_MMIODEV \ + _IOW(ACRN_IOCTL_TYPE, 0x57, struct acrn_mmiodev) +#define ACRN_IOCTL_DEASSIGN_MMIODEV \ + _IOW(ACRN_IOCTL_TYPE, 0x58, struct acrn_mmiodev) +#define ACRN_IOCTL_CREATE_VDEV \ + _IOW(ACRN_IOCTL_TYPE, 0x59, struct acrn_vdev) +#define ACRN_IOCTL_DESTROY_VDEV \ + _IOW(ACRN_IOCTL_TYPE, 0x5A, struct acrn_vdev) #define ACRN_IOCTL_PM_GET_CPU_STATE \ _IOWR(ACRN_IOCTL_TYPE, 0x60, __u64) diff --git a/include/uapi/linux/nitro_enclaves.h b/include/uapi/linux/nitro_enclaves.h index b945073fe544..e808f5ba124d 100644 --- a/include/uapi/linux/nitro_enclaves.h +++ b/include/uapi/linux/nitro_enclaves.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ #ifndef _UAPI_LINUX_NITRO_ENCLAVES_H_ @@ -60,7 +60,7 @@ * * Context: Process context. * Return: - * * 0 - Logic succesfully completed. + * * 0 - Logic successfully completed. * * -1 - There was a failure in the ioctl logic. * On failure, errno is set to: * * EFAULT - copy_from_user() / copy_to_user() failure. @@ -95,7 +95,7 @@ * * Context: Process context. * Return: - * * 0 - Logic succesfully completed. + * * 0 - Logic successfully completed. * * -1 - There was a failure in the ioctl logic. * On failure, errno is set to: * * EFAULT - copy_from_user() / copy_to_user() failure. @@ -118,7 +118,7 @@ * * Context: Process context. * Return: - * * 0 - Logic succesfully completed. + * * 0 - Logic successfully completed. * * -1 - There was a failure in the ioctl logic. * On failure, errno is set to: * * EFAULT - copy_from_user() failure. @@ -161,7 +161,7 @@ * * Context: Process context. * Return: - * * 0 - Logic succesfully completed. + * * 0 - Logic successfully completed. * * -1 - There was a failure in the ioctl logic. * On failure, errno is set to: * * EFAULT - copy_from_user() / copy_to_user() failure. diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c index 5a90aa527877..642d0748c169 100644 --- a/samples/kfifo/bytestream-example.c +++ b/samples/kfifo/bytestream-example.c @@ -22,10 +22,10 @@ #define PROC_FIFO "bytestream-fifo" /* lock for procfs read access */ -static DEFINE_MUTEX(read_lock); +static DEFINE_MUTEX(read_access); /* lock for procfs write access */ -static DEFINE_MUTEX(write_lock); +static DEFINE_MUTEX(write_access); /* * define DYNAMIC in this example for a dynamically allocated fifo. @@ -116,12 +116,12 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&write_lock)) + if (mutex_lock_interruptible(&write_access)) return -ERESTARTSYS; ret = kfifo_from_user(&test, buf, count, &copied); - mutex_unlock(&write_lock); + mutex_unlock(&write_access); if (ret) return ret; @@ -134,12 +134,12 @@ static ssize_t fifo_read(struct file *file, char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&read_lock)) + if (mutex_lock_interruptible(&read_access)) return -ERESTARTSYS; ret = kfifo_to_user(&test, buf, count, &copied); - mutex_unlock(&read_lock); + mutex_unlock(&read_access); if (ret) return ret; diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c index e5403d8c971a..c61482ba94f4 100644 --- a/samples/kfifo/inttype-example.c +++ b/samples/kfifo/inttype-example.c @@ -22,10 +22,10 @@ #define PROC_FIFO "int-fifo" /* lock for procfs read access */ -static DEFINE_MUTEX(read_lock); +static DEFINE_MUTEX(read_access); /* lock for procfs write access */ -static DEFINE_MUTEX(write_lock); +static DEFINE_MUTEX(write_access); /* * define DYNAMIC in this example for a dynamically allocated fifo. @@ -109,12 +109,12 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&write_lock)) + if (mutex_lock_interruptible(&write_access)) return -ERESTARTSYS; ret = kfifo_from_user(&test, buf, count, &copied); - mutex_unlock(&write_lock); + mutex_unlock(&write_access); if (ret) return ret; @@ -127,12 +127,12 @@ static ssize_t fifo_read(struct file *file, char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&read_lock)) + if (mutex_lock_interruptible(&read_access)) return -ERESTARTSYS; ret = kfifo_to_user(&test, buf, count, &copied); - mutex_unlock(&read_lock); + mutex_unlock(&read_access); if (ret) return ret; diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c index f64f3d62d6c2..e4087b2d3fc4 100644 --- a/samples/kfifo/record-example.c +++ b/samples/kfifo/record-example.c @@ -22,10 +22,10 @@ #define PROC_FIFO "record-fifo" /* lock for procfs read access */ -static DEFINE_MUTEX(read_lock); +static DEFINE_MUTEX(read_access); /* lock for procfs write access */ -static DEFINE_MUTEX(write_lock); +static DEFINE_MUTEX(write_access); /* * define DYNAMIC in this example for a dynamically allocated fifo. @@ -123,12 +123,12 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&write_lock)) + if (mutex_lock_interruptible(&write_access)) return -ERESTARTSYS; ret = kfifo_from_user(&test, buf, count, &copied); - mutex_unlock(&write_lock); + mutex_unlock(&write_access); if (ret) return ret; @@ -141,12 +141,12 @@ static ssize_t fifo_read(struct file *file, char __user *buf, int ret; unsigned int copied; - if (mutex_lock_interruptible(&read_lock)) + if (mutex_lock_interruptible(&read_access)) return -ERESTARTSYS; ret = kfifo_to_user(&test, buf, count, &copied); - mutex_unlock(&read_lock); + mutex_unlock(&read_access); if (ret) return ret; diff --git a/samples/nitro_enclaves/ne_ioctl_sample.c b/samples/nitro_enclaves/ne_ioctl_sample.c index 480b763142b3..765b131c7319 100644 --- a/samples/nitro_enclaves/ne_ioctl_sample.c +++ b/samples/nitro_enclaves/ne_ioctl_sample.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ /** @@ -185,7 +185,6 @@ static int ne_create_vm(int ne_dev_fd, unsigned long *slot_uid, int *enclave_fd) return 0; } - /** * ne_poll_enclave_fd() - Thread function for polling the enclave fd. * @data: Argument provided for the polling function. @@ -560,8 +559,8 @@ static int ne_add_vcpu(int enclave_fd, unsigned int *vcpu_id) default: printf("Error in add vcpu [%m]\n"); - } + return rc; } @@ -638,7 +637,7 @@ static int ne_start_enclave(int enclave_fd, struct ne_enclave_start_info *encla } /** - * ne_start_enclave_check_booted() - Start the enclave and wait for a hearbeat + * ne_start_enclave_check_booted() - Start the enclave and wait for a heartbeat * from it, on a newly created vsock channel, * to check it has booted. * @enclave_fd : The file descriptor associated with the enclave. diff --git a/scripts/tags.sh b/scripts/tags.sh index db8ba411860a..b24bfaec6290 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -247,6 +247,10 @@ setup_regex() exuberant() { + CTAGS_EXTRA="extra" + if $1 --version 2>&1 | grep -iq universal; then + CTAGS_EXTRA="extras" + fi setup_regex exuberant asm c all_target_sources | xargs $1 -a \ -I __initdata,__exitdata,__initconst,__ro_after_init \ @@ -261,7 +265,7 @@ exuberant() -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \ -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ -I static,const \ - --extra=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \ + --$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \ "${regex[@]}" setup_regex exuberant kconfig |