diff options
author | Stijn Tintel <stijn@linux-ipv6.be> | 2018-11-10 13:03:18 +0200 |
---|---|---|
committer | Stijn Tintel <stijn@linux-ipv6.be> | 2018-12-18 23:19:21 +0200 |
commit | f5919b65d4c671fd5083838c7a445f319f9a13c8 (patch) | |
tree | 2c791d2a5dea5bbbb0b85f86f74afce2647c0726 /target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch | |
parent | 822b4c3b250a254e74407056ccfd5c6aa38da162 (diff) | |
download | upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.tar.gz upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.tar.bz2 upstream-f5919b65d4c671fd5083838c7a445f319f9a13c8.zip |
brcm2708: add kernel 4.14 support
Patch generation process:
- rebase rpi/rpi-4.14.y on v4.14.89 from linux-stable
- git format-patch v4.14.89
Patches skipped during rebase:
- lan78xx: Read MAC address from DT if present
- lan78xx: Enable LEDs and auto-negotiation
- Revert "softirq: Let ksoftirqd do its job"
- sc16is7xx: Fix for multi-channel stall
- lan78xx: Ignore DT MAC address if already valid
- lan78xx: Simple patch to prevent some crashes
- tcp_write_queue_purge clears all the SKBs in the write queue
- Revert "lan78xx: Simple patch to prevent some crashes"
- lan78xx: Connect phy early
- Arm: mm: ftrace: Only set text back to ro after kernel has been marked ro
- Revert "Revert "softirq: Let ksoftirqd do its job""
- ASoC: cs4265: SOC_SINGLE register value error fix
- Revert "ASoC: cs4265: SOC_SINGLE register value error fix"
- Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends"
- Revert "Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends""
Patches dropped after rebase:
- net: Add non-mainline source for rtl8192cu wlan
- net: Fix rtl8192cu build errors on other platforms
- brcm: adds support for BCM43341 wifi
- brcmfmac: Mute expected startup 'errors'
- ARM64: Fix build break for RTL8187/RTL8192CU wifi
- ARM64: Enable RTL8187/RTL8192CU wifi in build config
- This is the driver for Sony CXD2880 DVB-T2/T tuner + demodulator
- brcmfmac: add CLM download support
- brcmfmac: request_firmware_direct is quieter
- Sets the BCDC priority to constant 0
- brcmfmac: Disable ARP offloading when promiscuous
- brcmfmac: Avoid possible out-of-bounds read
- brcmfmac: Delete redundant length check
- net: rtl8192cu: Normalize indentation
- net: rtl8192cu: Fix implicit fallthrough warnings
- Revert "Sets the BCDC priority to constant 0"
- media: cxd2880: Bump to match 4.18.y version
- media: cxd2880-spi: Bump to match 4.18.y version
- Revert "mm: alloc_contig: re-allow CMA to compact FS pages"
- Revert "Revert "mm: alloc_contig: re-allow CMA to compact FS pages""
- cxd2880: CXD2880_SPI_DRV should select DVB_CXD2880 with
MEDIA_SUBDRV_AUTOSELECT
- 950-0421-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch
- 950-0453-Add-hid-bigbenff-to-list-of-have_special_driver-for-.patch
Make I2C built-in instead of modular as in upstream defconfig; also the
easiest way to get MFD_ARIZONA enabled, which is required by
kmod-sound-soc-rpi-cirrus.
Add missing compatible strings from
4.9/960-add-rasbperrypi-compatible.patch, using upstream names for
compute modules.
Add extra patch to enable the LEDs on lan78xx.
Compile-tested: bcm2708, bcm2709, bcm2710 (with CONFIG_ALL_KMODS=y)
Runtime-tested: bcm2708, bcm2710
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Diffstat (limited to 'target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch b/target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch new file mode 100644 index 0000000000..e0d12eb8bc --- /dev/null +++ b/target/linux/brcm2708/patches-4.14/950-0156-vcsm-Revert-to-do-page-table-walk-based-cache-manipu.patch @@ -0,0 +1,235 @@ +From 3e471b58fb766ed5b45ff8b560231da4704c946d Mon Sep 17 00:00:00 2001 +From: Sugizaki Yukimasa <i.can.speak.c.and.basic@gmail.com> +Date: Wed, 10 Jan 2018 06:25:51 +0900 +Subject: [PATCH 156/454] vcsm: Revert to do page-table-walk-based cache + manipulating on some ioctl calls + +On FLUSH, INVALID, CLEAN_INVALID ioctl calls, cache operations based on +page table walk were used in case that the buffer of the cache is not +pinned. So reverted to do page-table-based cache manipulating. + +Signed-off-by: Sugizaki Yukimasa <i.can.speak.c.and.basic@gmail.com> +--- + drivers/char/broadcom/vc_sm/vmcs_sm.c | 141 ++++++++++++++++++++------ + 1 file changed, 110 insertions(+), 31 deletions(-) + +--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c ++++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c +@@ -1256,7 +1256,33 @@ static const struct vm_operations_struct + .fault = vcsm_vma_fault, + }; + +-static int clean_invalid_mem_2d(const void __user *addr, ++/* Converts VCSM_CACHE_OP_* to an operating function. */ ++static void (*cache_op_to_func(const unsigned cache_op)) ++ (const void*, const void*) ++{ ++ switch (cache_op) { ++ case VCSM_CACHE_OP_NOP: ++ return NULL; ++ ++ case VCSM_CACHE_OP_INV: ++ return dmac_inv_range; ++ ++ case VCSM_CACHE_OP_CLEAN: ++ return dmac_clean_range; ++ ++ case VCSM_CACHE_OP_FLUSH: ++ return dmac_flush_range; ++ ++ default: ++ pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); ++ return NULL; ++ } ++} ++ ++/* ++ * Clean/invalid/flush cache of which buffer is already pinned (i.e. accessed). ++ */ ++static int clean_invalid_contiguous_mem_2d(const void __user *addr, + const size_t block_count, const size_t block_size, const size_t stride, + const unsigned cache_op) + { +@@ -1268,22 +1294,9 @@ static int clean_invalid_mem_2d(const vo + return -EINVAL; + } + +- switch (cache_op) { +- case VCSM_CACHE_OP_NOP: +- return 0; +- case VCSM_CACHE_OP_INV: +- op_fn = dmac_inv_range; +- break; +- case VCSM_CACHE_OP_CLEAN: +- op_fn = dmac_clean_range; +- break; +- case VCSM_CACHE_OP_FLUSH: +- op_fn = dmac_flush_range; +- break; +- default: +- pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); ++ op_fn = cache_op_to_func(cache_op); ++ if (op_fn == NULL) + return -EINVAL; +- } + + for (i = 0; i < block_count; i ++, addr += stride) + op_fn(addr, addr + block_size); +@@ -1291,14 +1304,73 @@ static int clean_invalid_mem_2d(const vo + return 0; + } + +-static int clean_invalid_mem(const void __user *addr, const size_t size, ++/* Clean/invalid/flush cache of which buffer may be non-pinned. */ ++/* The caller must lock current->mm->mmap_sem for read. */ ++static int clean_invalid_mem_walk(unsigned long addr, const size_t size, + const unsigned cache_op) + { +- return clean_invalid_mem_2d(addr, 1, size, 0, cache_op); ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *pte; ++ unsigned long pgd_next, pud_next, pmd_next; ++ const unsigned long end = ALIGN(addr + size, PAGE_SIZE); ++ void (*op_fn)(const void*, const void*); ++ ++ addr &= PAGE_MASK; ++ ++ if (addr >= end) ++ return 0; ++ ++ op_fn = cache_op_to_func(cache_op); ++ if (op_fn == NULL) ++ return -EINVAL; ++ ++ /* Walk PGD */ ++ pgd = pgd_offset(current->mm, addr); ++ do { ++ pgd_next = pgd_addr_end(addr, end); ++ ++ if (pgd_none(*pgd) || pgd_bad(*pgd)) ++ continue; ++ ++ /* Walk PUD */ ++ pud = pud_offset(pgd, addr); ++ do { ++ pud_next = pud_addr_end(addr, pgd_next); ++ if (pud_none(*pud) || pud_bad(*pud)) ++ continue; ++ ++ /* Walk PMD */ ++ pmd = pmd_offset(pud, addr); ++ do { ++ pmd_next = pmd_addr_end(addr, pud_next); ++ if (pmd_none(*pmd) || pmd_bad(*pmd)) ++ continue; ++ ++ /* Walk PTE */ ++ pte = pte_offset_map(pmd, addr); ++ do { ++ if (pte_none(*pte) || !pte_present(*pte)) ++ continue; ++ ++ op_fn((const void __user*) addr, ++ (const void __user*) (addr + PAGE_SIZE)); ++ } while (pte++, addr += PAGE_SIZE, addr != pmd_next); ++ pte_unmap(pte); ++ ++ } while (pmd++, addr = pmd_next, addr != pud_next); ++ ++ } while (pud++, addr = pud_next, addr != pgd_next); ++ ++ } while (pgd++, addr = pgd_next, addr != end); ++ ++ return 0; + } + +-static int clean_invalid_resource(const void __user *addr, const size_t size, +- const unsigned cache_op, const int usr_hdl, ++/* Clean/invalid/flush cache of buffer in resource */ ++static int clean_invalid_resource_walk(const void __user *addr, ++ const size_t size, const unsigned cache_op, const int usr_hdl, + struct sm_resource_t *resource) + { + int err; +@@ -1355,7 +1427,10 @@ static int clean_invalid_resource(const + return -EFAULT; + } + +- err = clean_invalid_mem(addr, size, cache_op); ++ down_read(¤t->mm->mmap_sem); ++ err = clean_invalid_mem_walk((unsigned long) addr, size, cache_op); ++ up_read(¤t->mm->mmap_sem); ++ + if (err) + resource->res_stats[stat_failure]++; + +@@ -2004,7 +2079,7 @@ static int vc_sm_ioctl_unlock(struct sm_ + const unsigned long start = map->vma->vm_start; + const unsigned long end = map->vma->vm_end; + +- ret = clean_invalid_mem((void __user*) start, end - start, ++ ret = clean_invalid_mem_walk(start, end - start, + VCSM_CACHE_OP_FLUSH); + if (ret) + goto error; +@@ -2886,7 +2961,7 @@ static long vc_sm_ioctl(struct file *fil + goto out; + } + +- ret = clean_invalid_resource((void __user*) ioparam.addr, ++ ret = clean_invalid_resource_walk((void __user*) ioparam.addr, + ioparam.size, VCSM_CACHE_OP_FLUSH, ioparam.handle, + resource); + vmcs_sm_release_resource(resource, 0); +@@ -2917,7 +2992,7 @@ static long vc_sm_ioctl(struct file *fil + goto out; + } + +- ret = clean_invalid_resource((void __user*) ioparam.addr, ++ ret = clean_invalid_resource_walk((void __user*) ioparam.addr, + ioparam.size, VCSM_CACHE_OP_INV, ioparam.handle, resource); + vmcs_sm_release_resource(resource, 0); + if (ret) +@@ -2951,16 +3026,19 @@ static long vc_sm_ioctl(struct file *fil + goto out; + } + +- ret = clean_invalid_resource((void __user*) ioparam.s[i].addr, +- ioparam.s[i].size, ioparam.s[i].cmd, +- ioparam.s[i].handle, resource); ++ ret = clean_invalid_resource_walk( ++ (void __user*) ioparam.s[i].addr, ioparam.s[i].size, ++ ioparam.s[i].cmd, ioparam.s[i].handle, resource); + vmcs_sm_release_resource(resource, 0); + if (ret) + goto out; + } + } + break; +- /* Flush/Invalidate the cache for a given mapping. */ ++ /* ++ * Flush/Invalidate the cache for a given mapping. ++ * Blocks must be pinned (i.e. accessed) before this call. ++ */ + case VMCS_SM_CMD_CLEAN_INVALID2: + { + int i; +@@ -2993,12 +3071,13 @@ static long vc_sm_ioctl(struct file *fil + for (i = 0; i < ioparam.op_count; i++) { + const struct vmcs_sm_ioctl_clean_invalid_block * const op = block + i; + +- ret = clean_invalid_mem_2d((void __user*) op->start_address, +- op->block_count, op->block_size, +- op->inter_block_stride, op->invalidate_mode); + if (op->invalidate_mode == VCSM_CACHE_OP_NOP) + continue; + ++ ret = clean_invalid_contiguous_mem_2d( ++ (void __user*) op->start_address, op->block_count, ++ op->block_size, op->inter_block_stride, ++ op->invalidate_mode); + if (ret) + break; + } |