Skip to content

Commit 8b435e4

Browse files
committed
Merge tag 'usb-6.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are some USB driver and core fixes for 6.4-rc5. Most of these are tiny driver fixes, including: - udc driver bugfix - f_fs gadget driver bugfix - cdns3 driver bugfix - typec bugfixes But the "big" thing in here is a fix yet-again for how the USB buffers are handled from userspace when dealing with DMA issues. The changes were discussed a lot, and tested a lot, on the list, and acked by the relevant mm maintainers and have been in linux-next all this past week with no reported problems" * tag 'usb-6.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: typec: tps6598x: Fix broken polling mode after system suspend/resume mm: page_table_check: Ensure user pages are not slab pages mm: page_table_check: Make it dependent on EXCLUSIVE_SYSTEM_RAM usb: usbfs: Use consistent mmap functions usb: usbfs: Enforce page requirements for mmap dt-bindings: usb: snps,dwc3: Fix "snps,hsphy_interface" type usb: gadget: udc: fix NULL dereference in remove() usb: gadget: f_fs: Add unbind event before functionfs_unbind usb: cdns3: fix NCM gadget RX speed 20x slow than expection at iMX8QM
2 parents b066935 + fcfe842 commit 8b435e4

File tree

12 files changed

+111
-9
lines changed

12 files changed

+111
-9
lines changed

Documentation/devicetree/bindings/usb/snps,dwc3.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ properties:
287287
description:
288288
High-Speed PHY interface selection between UTMI+ and ULPI when the
289289
DWC_USB3_HSPHY_INTERFACE has value 3.
290-
$ref: /schemas/types.yaml#/definitions/uint8
290+
$ref: /schemas/types.yaml#/definitions/string
291291
enum: [utmi, ulpi]
292292

293293
snps,quirk-frame-length-adjustment:

Documentation/mm/page_table_check.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,22 @@ Build kernel with:
5252

5353
Optionally, build kernel with PAGE_TABLE_CHECK_ENFORCED in order to have page
5454
table support without extra kernel parameter.
55+
56+
Implementation notes
57+
====================
58+
59+
We specifically decided not to use VMA information in order to avoid relying on
60+
MM states (except for limited "struct page" info). The page table check is a
61+
separate from Linux-MM state machine that verifies that the user accessible
62+
pages are not falsely shared.
63+
64+
PAGE_TABLE_CHECK depends on EXCLUSIVE_SYSTEM_RAM. The reason is that without
65+
EXCLUSIVE_SYSTEM_RAM, users are allowed to map arbitrary physical memory
66+
regions into the userspace via /dev/mem. At the same time, pages may change
67+
their properties (e.g., from anonymous pages to named pages) while they are
68+
still being mapped in the userspace, leading to "corruption" detected by the
69+
page table check.
70+
71+
Even with EXCLUSIVE_SYSTEM_RAM, I/O pages may be still allowed to be mapped via
72+
/dev/mem. However, these pages are always considered as named pages, so they
73+
won't break the logic used in the page table check.

drivers/usb/cdns3/cdns3-gadget.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,19 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
20972097
else
20982098
priv_ep->trb_burst_size = 16;
20992099

2100+
/*
2101+
* In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs
2102+
* in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the
2103+
* address is not aligned to 128 Bytes (which is a product of the 64-bit AXI
2104+
* and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This
2105+
* results in data corruption when it crosses the 4K border. The corruption
2106+
* specifically occurs from the position (4K - (address & 0x7F)) to 4K.
2107+
*
2108+
* So force trb_burst_size to 16 at such platform.
2109+
*/
2110+
if (priv_dev->dev_ver < DEV_VER_V2)
2111+
priv_ep->trb_burst_size = 16;
2112+
21002113
mult = min_t(u8, mult, EP_CFG_MULT_MAX);
21012114
buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
21022115
maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);

drivers/usb/core/buffer.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,44 @@ void hcd_buffer_free(
172172
}
173173
dma_free_coherent(hcd->self.sysdev, size, addr, dma);
174174
}
175+
176+
void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
177+
size_t size, gfp_t mem_flags, dma_addr_t *dma)
178+
{
179+
if (size == 0)
180+
return NULL;
181+
182+
if (hcd->localmem_pool)
183+
return gen_pool_dma_alloc_align(hcd->localmem_pool,
184+
size, dma, PAGE_SIZE);
185+
186+
/* some USB hosts just use PIO */
187+
if (!hcd_uses_dma(hcd)) {
188+
*dma = DMA_MAPPING_ERROR;
189+
return (void *)__get_free_pages(mem_flags,
190+
get_order(size));
191+
}
192+
193+
return dma_alloc_coherent(hcd->self.sysdev,
194+
size, dma, mem_flags);
195+
}
196+
197+
void hcd_buffer_free_pages(struct usb_hcd *hcd,
198+
size_t size, void *addr, dma_addr_t dma)
199+
{
200+
if (!addr)
201+
return;
202+
203+
if (hcd->localmem_pool) {
204+
gen_pool_free(hcd->localmem_pool,
205+
(unsigned long)addr, size);
206+
return;
207+
}
208+
209+
if (!hcd_uses_dma(hcd)) {
210+
free_pages((unsigned long)addr, get_order(size));
211+
return;
212+
}
213+
214+
dma_free_coherent(hcd->self.sysdev, size, addr, dma);
215+
}

drivers/usb/core/devio.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static int connected(struct usb_dev_state *ps)
186186
static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count)
187187
{
188188
struct usb_dev_state *ps = usbm->ps;
189+
struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus);
189190
unsigned long flags;
190191

191192
spin_lock_irqsave(&ps->lock, flags);
@@ -194,8 +195,8 @@ static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count)
194195
list_del(&usbm->memlist);
195196
spin_unlock_irqrestore(&ps->lock, flags);
196197

197-
usb_free_coherent(ps->dev, usbm->size, usbm->mem,
198-
usbm->dma_handle);
198+
hcd_buffer_free_pages(hcd, usbm->size,
199+
usbm->mem, usbm->dma_handle);
199200
usbfs_decrease_memory_usage(
200201
usbm->size + sizeof(struct usb_memory));
201202
kfree(usbm);
@@ -234,7 +235,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)
234235
size_t size = vma->vm_end - vma->vm_start;
235236
void *mem;
236237
unsigned long flags;
237-
dma_addr_t dma_handle;
238+
dma_addr_t dma_handle = DMA_MAPPING_ERROR;
238239
int ret;
239240

240241
ret = usbfs_increase_memory_usage(size + sizeof(struct usb_memory));
@@ -247,8 +248,8 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)
247248
goto error_decrease_mem;
248249
}
249250

250-
mem = usb_alloc_coherent(ps->dev, size, GFP_USER | __GFP_NOWARN,
251-
&dma_handle);
251+
mem = hcd_buffer_alloc_pages(hcd,
252+
size, GFP_USER | __GFP_NOWARN, &dma_handle);
252253
if (!mem) {
253254
ret = -ENOMEM;
254255
goto error_free_usbm;
@@ -264,7 +265,14 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma)
264265
usbm->vma_use_count = 1;
265266
INIT_LIST_HEAD(&usbm->memlist);
266267

267-
if (hcd->localmem_pool || !hcd_uses_dma(hcd)) {
268+
/*
269+
* In DMA-unavailable cases, hcd_buffer_alloc_pages allocates
270+
* normal pages and assigns DMA_MAPPING_ERROR to dma_handle. Check
271+
* whether we are in such cases, and then use remap_pfn_range (or
272+
* dma_mmap_coherent) to map normal (or DMA) pages into the user
273+
* space, respectively.
274+
*/
275+
if (dma_handle == DMA_MAPPING_ERROR) {
268276
if (remap_pfn_range(vma, vma->vm_start,
269277
virt_to_phys(usbm->mem) >> PAGE_SHIFT,
270278
size, vma->vm_page_prot) < 0) {

drivers/usb/gadget/function/f_fs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3535,6 +3535,7 @@ static void ffs_func_unbind(struct usb_configuration *c,
35353535
/* Drain any pending AIO completions */
35363536
drain_workqueue(ffs->io_completion_wq);
35373537

3538+
ffs_event_add(ffs, FUNCTIONFS_UNBIND);
35383539
if (!--opts->refcnt)
35393540
functionfs_unbind(ffs);
35403541

@@ -3559,7 +3560,6 @@ static void ffs_func_unbind(struct usb_configuration *c,
35593560
func->function.ssp_descriptors = NULL;
35603561
func->interfaces_nums = NULL;
35613562

3562-
ffs_event_add(ffs, FUNCTIONFS_UNBIND);
35633563
}
35643564

35653565
static struct usb_function *ffs_alloc(struct usb_function_instance *fi)

drivers/usb/gadget/udc/amd5536udc_pci.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ static int udc_pci_probe(
170170
retval = -ENODEV;
171171
goto err_probe;
172172
}
173+
174+
udc = dev;
175+
173176
return 0;
174177

175178
err_probe:

drivers/usb/typec/tipd/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ static int __maybe_unused tps6598x_resume(struct device *dev)
920920
enable_irq(client->irq);
921921
}
922922

923-
if (client->irq)
923+
if (!client->irq)
924924
queue_delayed_work(system_power_efficient_wq, &tps->wq_poll,
925925
msecs_to_jiffies(POLL_INTERVAL));
926926

include/linux/page-flags.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,12 @@ PAGEFLAG_FALSE(VmemmapSelfHosted, vmemmap_self_hosted)
617617
* Please note that, confusingly, "page_mapping" refers to the inode
618618
* address_space which maps the page from disk; whereas "page_mapped"
619619
* refers to user virtual address space into which the page is mapped.
620+
*
621+
* For slab pages, since slab reuses the bits in struct page to store its
622+
* internal states, the page->mapping does not exist as such, nor do these
623+
* flags below. So in order to avoid testing non-existent bits, please
624+
* make sure that PageSlab(page) actually evaluates to false before calling
625+
* the following functions (e.g., PageAnon). See mm/slab.h.
620626
*/
621627
#define PAGE_MAPPING_ANON 0x1
622628
#define PAGE_MAPPING_MOVABLE 0x2

include/linux/usb/hcd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,11 @@ void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
501501
void hcd_buffer_free(struct usb_bus *bus, size_t size,
502502
void *addr, dma_addr_t dma);
503503

504+
void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
505+
size_t size, gfp_t mem_flags, dma_addr_t *dma);
506+
void hcd_buffer_free_pages(struct usb_hcd *hcd,
507+
size_t size, void *addr, dma_addr_t dma);
508+
504509
/* generic bus glue, needed for host controllers that don't use PCI */
505510
extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
506511

0 commit comments

Comments
 (0)