We need the staging/iio fixes in here as well.
Unified · Split
| @@ -288,6 +288,8 @@ Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com> · 287 unmodified lines | ||
| 288 | 288 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com> |
| 289 | 289 | Takashi YOSHII <takashi.yoshii.zj@renesas.com> |
| 290 | 290 | Will Deacon <will@kernel.org> <will.deacon@arm.com> |
| 291 | +Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de> | |
| 292 | +Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de> | |
| 291 | 293 | Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com> |
| 292 | 294 | Yusuke Goda <goda.yusuke@renesas.com> |
| 293 | 295 | Gustavo Padovan <gustavo@las.ic.unicamp.br> |
| @@ -112,6 +112,20 @@ used when printing stack backtraces. The specifier takes into · 111 unmodified lines | ||
| 112 | 112 | consideration the effect of compiler optimisations which may occur |
| 113 | 113 | when tail-calls are used and marked with the noreturn GCC attribute. |
| 114 | 114 | |
| 115 | +Probed Pointers from BPF / tracing | |
| 116 | +---------------------------------- | |
| 117 | + | |
| 118 | +:: | |
| 119 | + | |
| 120 | + %pks kernel string | |
| 121 | + %pus user string | |
| 122 | + | |
| 123 | +The ``k`` and ``u`` specifiers are used for printing prior probed memory from | |
| 124 | +either kernel memory (k) or user memory (u). The subsequent ``s`` specifier | |
| 125 | +results in printing a string. For direct use in regular vsnprintf() the (k) | |
| 126 | +and (u) annotation is ignored, however, when used out of BPF's bpf_trace_printk(), | |
| 127 | +for example, it reads the memory it is pointing to without faulting. | |
| 128 | + | |
| 115 | 129 | Kernel Pointers |
| 116 | 130 | --------------- |
| 117 | 131 | |
| @@ -10,7 +10,8 @@ Required properties: · 9 unmodified lines | ||
| 10 | 10 | - compatible : |
| 11 | 11 | - "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610 SoC |
| 12 | 12 | - "fsl,imx7ulp-edma" for eDMA2 used similar to that on i.mx7ulp |
| 13 | − - "fsl,fsl,ls1028a-edma" for eDMA used similar to that on Vybrid vf610 SoC | |
| 13 | + - "fsl,ls1028a-edma" followed by "fsl,vf610-edma" for eDMA used on the | |
| 14 | + LS1028A SoC. | |
| 14 | 15 | - reg : Specifies base physical address(s) and size of the eDMA registers. |
| 15 | 16 | The 1st region is eDMA control register's address and size. |
| 16 | 17 | The 2nd and the 3rd regions are programmable channel multiplexing |
| @@ -110,6 +110,9 @@ Ethernet switch connected via MDIO to the host, CPU port wired to eth0: · 109 unmodified lines | ||
| 110 | 110 | #size-cells = <0>; |
| 111 | 111 | |
| 112 | 112 | ports { |
| 113 | + #address-cells = <1>; | |
| 114 | + #size-cells = <0>; | |
| 115 | + | |
| 113 | 116 | port0@0 { |
| 114 | 117 | reg = <0>; |
| 115 | 118 | label = "lan1"; |
| @@ -27,9 +27,8 @@ differences are: · 26 unmodified lines | ||
| 27 | 27 | 3. Raw Gadget provides a way to select a UDC device/driver to bind to, |
| 28 | 28 | while GadgetFS currently binds to the first available UDC. |
| 29 | 29 | |
| 30 | −4. Raw Gadget uses predictable endpoint names (handles) across different | |
| 31 | − UDCs (as long as UDCs have enough endpoints of each required transfer | |
| 32 | − type). | |
| 30 | +4. Raw Gadget explicitly exposes information about endpoints addresses and | |
| 31 | + capabilities allowing a user to write UDC-agnostic gadgets. | |
| 33 | 32 | |
| 34 | 33 | 5. Raw Gadget has ioctl-based interface instead of a filesystem-based one. |
| 35 | 34 | |
| @@ -50,12 +49,36 @@ The typical usage of Raw Gadget looks like: · 14 unmodified lines | ||
| 50 | 49 | Raw Gadget and react to those depending on what kind of USB device |
| 51 | 50 | needs to be emulated. |
| 52 | 51 | |
| 52 | +Note, that some UDC drivers have fixed addresses assigned to endpoints, and | |
| 53 | +therefore arbitrary endpoint addresses can't be used in the descriptors. | |
| 54 | +Nevertheles, Raw Gadget provides a UDC-agnostic way to write USB gadgets. | |
| 55 | +Once a USB_RAW_EVENT_CONNECT event is received via USB_RAW_IOCTL_EVENT_FETCH, | |
| 56 | +the USB_RAW_IOCTL_EPS_INFO ioctl can be used to find out information about | |
| 57 | +endpoints that the UDC driver has. Based on that information, the user must | |
| 58 | +chose UDC endpoints that will be used for the gadget being emulated, and | |
| 59 | +properly assign addresses in endpoint descriptors. | |
| 60 | + | |
| 61 | +You can find usage examples (along with a test suite) here: | |
| 62 | + | |
| 63 | +https://github.com/xairy/raw-gadget | |
| 64 | + | |
| 65 | +Internal details | |
| 66 | +~~~~~~~~~~~~~~~~ | |
| 67 | + | |
| 68 | +Currently every endpoint read/write ioctl submits a USB request and waits until | |
| 69 | +its completion. This is the desired mode for coverage-guided fuzzing (as we'd | |
| 70 | +like all USB request processing happen during the lifetime of a syscall), | |
| 71 | +and must be kept in the implementation. (This might be slow for real world | |
| 72 | +applications, thus the O_NONBLOCK improvement suggestion below.) | |
| 73 | + | |
| 53 | 74 | Potential future improvements |
| 54 | 75 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 55 | 76 | |
| 56 | −- Implement ioctl's for setting/clearing halt status on endpoints. | |
| 57 | − | |
| 58 | −- Reporting more events (suspend, resume, etc.) through | |
| 59 | − USB_RAW_IOCTL_EVENT_FETCH. | |
| 77 | +- Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH. | |
| 60 | 78 | |
| 61 | 79 | - Support O_NONBLOCK I/O. |
| 80 | + | |
| 81 | +- Support USB 3 features (accept SS endpoint companion descriptor when | |
| 82 | + enabling endpoints; allow providing stream_id for bulk transfers). | |
| 83 | + | |
| 84 | +- Support ISO transfer features (expose frame_number for completed requests). | |
| @@ -5516,10 +5516,10 @@ F: drivers/gpu/drm/vboxvideo/ · 5515 unmodified lines | ||
| 5516 | 5516 | |
| 5517 | 5517 | DRM DRIVER FOR VMWARE VIRTUAL GPU |
| 5518 | 5518 | M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> |
| 5519 | −M: Thomas Hellstrom <thellstrom@vmware.com> | |
| 5519 | +M: Roland Scheidegger <sroland@vmware.com> | |
| 5520 | 5520 | L: dri-devel@lists.freedesktop.org |
| 5521 | 5521 | S: Supported |
| 5522 | −T: git git://people.freedesktop.org/~thomash/linux | |
| 5522 | +T: git git://people.freedesktop.org/~sroland/linux | |
| 5523 | 5523 | F: drivers/gpu/drm/vmwgfx/ |
| 5524 | 5524 | F: include/uapi/drm/vmwgfx_drm.h |
| 5525 | 5525 | |
| @@ -7839,7 +7839,7 @@ T: git git://linuxtv.org/media_tree.git · 2313 unmodified lines | ||
| 7839 | 7839 | F: drivers/media/platform/sti/hva |
| 7840 | 7840 | |
| 7841 | 7841 | HWPOISON MEMORY FAILURE HANDLING |
| 7842 | −M: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | |
| 7842 | +M: Naoya Horiguchi <naoya.horiguchi@nec.com> | |
| 7843 | 7843 | L: linux-mm@kvack.org |
| 7844 | 7844 | S: Maintained |
| 7845 | 7845 | F: mm/hwpoison-inject.c |
| @@ -7951,7 +7951,7 @@ F: Documentation/i2c/busses/i2c-parport.rst · 105 unmodified lines | ||
| 7951 | 7951 | F: drivers/i2c/busses/i2c-parport.c |
| 7952 | 7952 | |
| 7953 | 7953 | I2C SUBSYSTEM |
| 7954 | −M: Wolfram Sang <wsa@the-dreams.de> | |
| 7954 | +M: Wolfram Sang <wsa@kernel.org> | |
| 7955 | 7955 | L: linux-i2c@vger.kernel.org |
| 7956 | 7956 | S: Maintained |
| 7957 | 7957 | W: https://i2c.wiki.kernel.org/ |
| @@ -9195,6 +9195,11 @@ L: kexec@lists.infradead.org · 1237 unmodified lines | ||
| 9195 | 9195 | S: Maintained |
| 9196 | 9196 | W: http://lse.sourceforge.net/kdump/ |
| 9197 | 9197 | F: Documentation/admin-guide/kdump/ |
| 9198 | +F: fs/proc/vmcore.c | |
| 9199 | +F: include/linux/crash_core.h | |
| 9200 | +F: include/linux/crash_dump.h | |
| 9201 | +F: include/uapi/linux/vmcore.h | |
| 9202 | +F: kernel/crash_*.c | |
| 9198 | 9203 | |
| 9199 | 9204 | KEENE FM RADIO TRANSMITTER DRIVER |
| 9200 | 9205 | M: Hans Verkuil <hverkuil@xs4all.nl> |
| @@ -10672,6 +10677,13 @@ L: netdev@vger.kernel.org · 1471 unmodified lines | ||
| 10672 | 10677 | S: Maintained |
| 10673 | 10678 | F: drivers/net/ethernet/mediatek/ |
| 10674 | 10679 | |
| 10680 | +MEDIATEK I2C CONTROLLER DRIVER | |
| 10681 | +M: Qii Wang <qii.wang@mediatek.com> | |
| 10682 | +L: linux-i2c@vger.kernel.org | |
| 10683 | +S: Maintained | |
| 10684 | +F: Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | |
| 10685 | +F: drivers/i2c/busses/i2c-mt65xx.c | |
| 10686 | + | |
| 10675 | 10687 | MEDIATEK JPEG DRIVER |
| 10676 | 10688 | M: Rick Chang <rick.chang@mediatek.com> |
| 10677 | 10689 | M: Bin Liu <bin.liu@mediatek.com> |
| @@ -11720,8 +11732,9 @@ F: net/core/drop_monitor.c · 1042 unmodified lines | ||
| 11720 | 11732 | |
| 11721 | 11733 | NETWORKING DRIVERS |
| 11722 | 11734 | M: "David S. Miller" <davem@davemloft.net> |
| 11735 | +M: Jakub Kicinski <kuba@kernel.org> | |
| 11723 | 11736 | L: netdev@vger.kernel.org |
| 11724 | −S: Odd Fixes | |
| 11737 | +S: Maintained | |
| 11725 | 11738 | W: http://www.linuxfoundation.org/en/Net |
| 11726 | 11739 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| 11727 | 11740 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| @@ -14644,6 +14657,7 @@ F: drivers/iommu/s390-iommu.c · 2916 unmodified lines | ||
| 14644 | 14657 | |
| 14645 | 14658 | S390 IUCV NETWORK LAYER |
| 14646 | 14659 | M: Julian Wiedmann <jwi@linux.ibm.com> |
| 14660 | +M: Karsten Graul <kgraul@linux.ibm.com> | |
| 14647 | 14661 | M: Ursula Braun <ubraun@linux.ibm.com> |
| 14648 | 14662 | L: linux-s390@vger.kernel.org |
| 14649 | 14663 | S: Supported |
| @@ -14654,6 +14668,7 @@ F: net/iucv/ · 4 unmodified lines | ||
| 14654 | 14668 | |
| 14655 | 14669 | S390 NETWORK DRIVERS |
| 14656 | 14670 | M: Julian Wiedmann <jwi@linux.ibm.com> |
| 14671 | +M: Karsten Graul <kgraul@linux.ibm.com> | |
| 14657 | 14672 | M: Ursula Braun <ubraun@linux.ibm.com> |
| 14658 | 14673 | L: linux-s390@vger.kernel.org |
| 14659 | 14674 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 7 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc5 | |
| 5 | +EXTRAVERSION = -rc7 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -65,6 +65,7 @@ CONFIG_DRM_UDL=y · 64 unmodified lines | ||
| 65 | 65 | CONFIG_DRM_ETNAVIV=y |
| 66 | 66 | CONFIG_FB=y |
| 67 | 67 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 68 | +CONFIG_USB=y | |
| 68 | 69 | CONFIG_USB_EHCI_HCD=y |
| 69 | 70 | CONFIG_USB_EHCI_HCD_PLATFORM=y |
| 70 | 71 | CONFIG_USB_OHCI_HCD=y |
| @@ -15,12 +15,14 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | /* clobbers r5 register */ |
| 17 | 17 | .macro DSP_EARLY_INIT |
| 18 | +#ifdef CONFIG_ISA_ARCV2 | |
| 18 | 19 | lr r5, [ARC_AUX_DSP_BUILD] |
| 19 | 20 | bmsk r5, r5, 7 |
| 20 | 21 | breq r5, 0, 1f |
| 21 | 22 | mov r5, DSP_CTRL_DISABLED_ALL |
| 22 | 23 | sr r5, [ARC_AUX_DSP_CTRL] |
| 23 | 24 | 1: |
| 25 | +#endif | |
| 24 | 26 | .endm |
| 25 | 27 | |
| 26 | 28 | /* clobbers r10, r11 registers pair */ |
| @@ -233,6 +233,8 @@ · 232 unmodified lines | ||
| 233 | 233 | |
| 234 | 234 | #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE |
| 235 | 235 | __RESTORE_REGFILE_HARD |
| 236 | + | |
| 237 | + ; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE | |
| 236 | 238 | add sp, sp, SZ_PT_REGS - 8 |
| 237 | 239 | #else |
| 238 | 240 | add sp, sp, PT_r0 |
| @@ -3,9 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
| 4 | 4 | # |
| 5 | 5 | |
| 6 | −# Pass UTS_MACHINE for user_regset definition | |
| 7 | −CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | |
| 8 | − | |
| 9 | 6 | obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o |
| 10 | 7 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o |
| 11 | 8 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o |
| @@ -253,7 +253,7 @@ static const struct user_regset arc_regsets[] = { · 252 unmodified lines | ||
| 253 | 253 | }; |
| 254 | 254 | |
| 255 | 255 | static const struct user_regset_view user_arc_view = { |
| 256 | − .name = UTS_MACHINE, | |
| 256 | + .name = "arc", | |
| 257 | 257 | .e_machine = EM_ARC_INUSE, |
| 258 | 258 | .regsets = arc_regsets, |
| 259 | 259 | .n = ARRAY_SIZE(arc_regsets) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/clocksource.h> |
| 12 | 12 | #include <linux/console.h> |
| 13 | 13 | #include <linux/module.h> |
| 14 | +#include <linux/sizes.h> | |
| 14 | 15 | #include <linux/cpu.h> |
| 15 | 16 | #include <linux/of_clk.h> |
| 16 | 17 | #include <linux/of_fdt.h> |
| @@ -424,12 +425,12 @@ static void arc_chk_core_config(void) · 407 unmodified lines | ||
| 424 | 425 | if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) |
| 425 | 426 | panic("Linux built with incorrect DCCM Base address\n"); |
| 426 | 427 | |
| 427 | − if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz) | |
| 428 | + if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz) | |
| 428 | 429 | panic("Linux built with incorrect DCCM Size\n"); |
| 429 | 430 | #endif |
| 430 | 431 | |
| 431 | 432 | #ifdef CONFIG_ARC_HAS_ICCM |
| 432 | − if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz) | |
| 433 | + if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz) | |
| 433 | 434 | panic("Linux built with incorrect ICCM Size\n"); |
| 434 | 435 | #endif |
| 435 | 436 | |
| @@ -191,10 +191,9 @@ void show_regs(struct pt_regs *regs) · 190 unmodified lines | ||
| 191 | 191 | if (user_mode(regs)) |
| 192 | 192 | show_faulting_vma(regs->ret); /* faulting code, not data */ |
| 193 | 193 | |
| 194 | − pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n", | |
| 195 | − regs->event, current->thread.fault_address, regs->ret); | |
| 196 | − | |
| 197 | − pr_info("STAT32: 0x%08lx", regs->status32); | |
| 194 | + pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\nSTAT: 0x%08lx", | |
| 195 | + regs->event, current->thread.fault_address, regs->ret, | |
| 196 | + regs->status32); | |
| 198 | 197 | |
| 199 | 198 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" |
| 200 | 199 | |
| @@ -210,11 +209,10 @@ void show_regs(struct pt_regs *regs) · 9 unmodified lines | ||
| 210 | 209 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 211 | 210 | STS_BIT(regs, DE), STS_BIT(regs, AE)); |
| 212 | 211 | #endif |
| 213 | − pr_cont(" BTA: 0x%08lx\n", regs->bta); | |
| 214 | − pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n", | |
| 215 | − (void *)regs->blink, regs->sp, regs->fp); | |
| 212 | + pr_cont(" BTA: 0x%08lx\n SP: 0x%08lx FP: 0x%08lx BLK: %pS\n", | |
| 213 | + regs->bta, regs->sp, regs->fp, (void *)regs->blink); | |
| 216 | 214 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", |
| 217 | − regs->lp_start, regs->lp_end, regs->lp_count); | |
| 215 | + regs->lp_start, regs->lp_end, regs->lp_count); | |
| 218 | 216 | |
| 219 | 217 | /* print regs->r0 thru regs->r12 |
| 220 | 218 | * Sequential printing was generating horrible code |
| @@ -1178,11 +1178,9 @@ int arc_unwind(struct unwind_frame_info *frame) · 1177 unmodified lines | ||
| 1178 | 1178 | #endif |
| 1179 | 1179 | |
| 1180 | 1180 | /* update frame */ |
| 1181 | −#ifndef CONFIG_AS_CFI_SIGNAL_FRAME | |
| 1182 | 1181 | if (frame->call_frame |
| 1183 | 1182 | && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign)) |
| 1184 | 1183 | frame->call_frame = 0; |
| 1185 | −#endif | |
| 1186 | 1184 | cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs; |
| 1187 | 1185 | startLoc = min_t(unsigned long, UNW_SP(frame), cfa); |
| 1188 | 1186 | endLoc = max_t(unsigned long, UNW_SP(frame), cfa); |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | menuconfig ARC_PLAT_EZNPS |
| 8 | 8 | bool "\"EZchip\" ARC dev platform" |
| 9 | + depends on ISA_ARCOMPACT | |
| 9 | 10 | select CPU_BIG_ENDIAN |
| 10 | 11 | select CLKSRC_NPS if !PHYS_ADDR_T_64BIT |
| 11 | 12 | select EZNPS_GIC |
| @@ -12,6 +12,7 @@ config ARM · 11 unmodified lines | ||
| 12 | 12 | select ARCH_HAS_KEEPINITRD |
| 13 | 13 | select ARCH_HAS_KCOV |
| 14 | 14 | select ARCH_HAS_MEMBARRIER_SYNC_CORE |
| 15 | + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 15 | 16 | select ARCH_HAS_PTE_SPECIAL if ARM_LPAE |
| 16 | 17 | select ARCH_HAS_PHYS_TO_DMA |
| 17 | 18 | select ARCH_HAS_SETUP_DMA_OPS |
| @@ -40,3 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | status = "okay"; |
| 41 | 41 | dual_emac; |
| 42 | 42 | }; |
| 43 | + | |
| 44 | +&m_can0 { | |
| 45 | + status = "disabled"; | |
| 46 | +}; | |
| @@ -172,6 +172,7 @@ · 171 unmodified lines | ||
| 172 | 172 | #address-cells = <1>; |
| 173 | 173 | ranges = <0x51000000 0x51000000 0x3000 |
| 174 | 174 | 0x0 0x20000000 0x10000000>; |
| 175 | + dma-ranges; | |
| 175 | 176 | /** |
| 176 | 177 | * To enable PCI endpoint mode, disable the pcie1_rc |
| 177 | 178 | * node and enable pcie1_ep mode. |
| @@ -185,7 +186,6 @@ · 7 unmodified lines | ||
| 185 | 186 | device_type = "pci"; |
| 186 | 187 | ranges = <0x81000000 0 0 0x03000 0 0x00010000 |
| 187 | 188 | 0x82000000 0 0x20013000 0x13000 0 0xffed000>; |
| 188 | − dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>; | |
| 189 | 189 | bus-range = <0x00 0xff>; |
| 190 | 190 | #interrupt-cells = <1>; |
| 191 | 191 | num-lanes = <1>; |
| @@ -230,6 +230,7 @@ · 38 unmodified lines | ||
| 230 | 230 | #address-cells = <1>; |
| 231 | 231 | ranges = <0x51800000 0x51800000 0x3000 |
| 232 | 232 | 0x0 0x30000000 0x10000000>; |
| 233 | + dma-ranges; | |
| 233 | 234 | status = "disabled"; |
| 234 | 235 | pcie2_rc: pcie@51800000 { |
| 235 | 236 | reg = <0x51800000 0x2000>, <0x51802000 0x14c>, <0x1000 0x2000>; |
| @@ -240,7 +241,6 @@ · 4 unmodified lines | ||
| 240 | 241 | device_type = "pci"; |
| 241 | 242 | ranges = <0x81000000 0 0 0x03000 0 0x00010000 |
| 242 | 243 | 0x82000000 0 0x30013000 0x13000 0 0xffed000>; |
| 243 | − dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>; | |
| 244 | 244 | bus-range = <0x00 0xff>; |
| 245 | 245 | #interrupt-cells = <1>; |
| 246 | 246 | num-lanes = <1>; |
| @@ -75,8 +75,8 @@ · 74 unmodified lines | ||
| 75 | 75 | imx27-phycard-s-rdk { |
| 76 | 76 | pinctrl_i2c1: i2c1grp { |
| 77 | 77 | fsl,pins = < |
| 78 | − MX27_PAD_I2C2_SDA__I2C2_SDA 0x0 | |
| 79 | − MX27_PAD_I2C2_SCL__I2C2_SCL 0x0 | |
| 78 | + MX27_PAD_I2C_DATA__I2C_DATA 0x0 | |
| 79 | + MX27_PAD_I2C_CLK__I2C_CLK 0x0 | |
| 80 | 80 | >; |
| 81 | 81 | }; |
| 82 | 82 | |
| @@ -38,7 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | &switch_ports { |
| 41 | − /delete-node/ port@2; | |
| 41 | + /delete-node/ port@3; | |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | 44 | &touchscreen { |
| @@ -72,8 +72,6 @@ · 71 unmodified lines | ||
| 72 | 72 | adi,input-depth = <8>; |
| 73 | 73 | adi,input-colorspace = "rgb"; |
| 74 | 74 | adi,input-clock = "1x"; |
| 75 | − adi,input-style = <1>; | |
| 76 | − adi,input-justification = "evenly"; | |
| 77 | 75 | |
| 78 | 76 | ports { |
| 79 | 77 | #address-cells = <1>; |
| @@ -367,6 +367,8 @@ · 366 unmodified lines | ||
| 367 | 367 | }; |
| 368 | 368 | |
| 369 | 369 | &mmc3 { |
| 370 | + pinctrl-names = "default"; | |
| 371 | + pinctrl-0 = <&mmc3_pins>; | |
| 370 | 372 | vmmc-supply = <&wl12xx_vmmc>; |
| 371 | 373 | /* uart2_tx.sdmmc3_dat1 pad as wakeirq */ |
| 372 | 374 | interrupts-extended = <&wakeupgen GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH |
| @@ -472,6 +474,37 @@ · 99 unmodified lines | ||
| 472 | 474 | >; |
| 473 | 475 | }; |
| 474 | 476 | |
| 477 | + /* | |
| 478 | + * Android uses PIN_OFF_INPUT_PULLDOWN | PIN_INPUT_PULLUP | MUX_MODE3 | |
| 479 | + * for gpio_100, but the internal pull makes wlan flakey on some | |
| 480 | + * devices. Off mode value should be tested if we have off mode working | |
| 481 | + * later on. | |
| 482 | + */ | |
| 483 | + mmc3_pins: pinmux_mmc3_pins { | |
| 484 | + pinctrl-single,pins = < | |
| 485 | + /* 0x4a10008e gpmc_wait2.gpio_100 d23 */ | |
| 486 | + OMAP4_IOPAD(0x08e, PIN_INPUT | MUX_MODE3) | |
| 487 | + | |
| 488 | + /* 0x4a100102 abe_mcbsp1_dx.sdmmc3_dat2 ab25 */ | |
| 489 | + OMAP4_IOPAD(0x102, PIN_INPUT_PULLUP | MUX_MODE1) | |
| 490 | + | |
| 491 | + /* 0x4a100104 abe_mcbsp1_fsx.sdmmc3_dat3 ac27 */ | |
| 492 | + OMAP4_IOPAD(0x104, PIN_INPUT_PULLUP | MUX_MODE1) | |
| 493 | + | |
| 494 | + /* 0x4a100118 uart2_cts.sdmmc3_clk ab26 */ | |
| 495 | + OMAP4_IOPAD(0x118, PIN_INPUT | MUX_MODE1) | |
| 496 | + | |
| 497 | + /* 0x4a10011a uart2_rts.sdmmc3_cmd ab27 */ | |
| 498 | + OMAP4_IOPAD(0x11a, PIN_INPUT_PULLUP | MUX_MODE1) | |
| 499 | + | |
| 500 | + /* 0x4a10011c uart2_rx.sdmmc3_dat0 aa25 */ | |
| 501 | + OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE1) | |
| 502 | + | |
| 503 | + /* 0x4a10011e uart2_tx.sdmmc3_dat1 aa26 */ | |
| 504 | + OMAP4_IOPAD(0x11e, PIN_INPUT_PULLUP | MUX_MODE1) | |
| 505 | + >; | |
| 506 | + }; | |
| 507 | + | |
| 475 | 508 | /* gpmc_ncs0.gpio_50 */ |
| 476 | 509 | poweroff_gpio: pinmux_poweroff_pins { |
| 477 | 510 | pinctrl-single,pins = < |
| @@ -690,14 +723,18 @@ · 212 unmodified lines | ||
| 690 | 723 | }; |
| 691 | 724 | |
| 692 | 725 | /* |
| 693 | − * As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for | |
| 694 | − * uart1 wakeirq. | |
| 726 | + * The uart1 port is wired to mdm6600 with rts and cts. The modem uses gpio_149 | |
| 727 | + * for wake-up events for both the USB PHY and the UART. We can use gpio_149 | |
| 728 | + * pad as the shared wakeirq for the UART rather than the RX or CTS pad as we | |
| 729 | + * have gpio_149 trigger before the UART transfer starts. | |
| 695 | 730 | */ |
| 696 | 731 | &uart1 { |
| 697 | 732 | pinctrl-names = "default"; |
| 698 | 733 | pinctrl-0 = <&uart1_pins>; |
| 699 | 734 | interrupts-extended = <&wakeupgen GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH |
| 700 | − &omap4_pmx_core 0xfc>; | |
| 735 | + &omap4_pmx_core 0x110>; | |
| 736 | + uart-has-rtscts; | |
| 737 | + current-speed = <115200>; | |
| 701 | 738 | }; |
| 702 | 739 | |
| 703 | 740 | &uart3 { |
| @@ -304,7 +304,6 @@ · 303 unmodified lines | ||
| 304 | 304 | reg = <0xe803b000 0x30>; |
| 305 | 305 | interrupts = <GIC_SPI 56 IRQ_TYPE_EDGE_RISING>; |
| 306 | 306 | clocks = <&cpg CPG_MOD 36>; |
| 307 | − clock-names = "ostm0"; | |
| 308 | 307 | power-domains = <&cpg>; |
| 309 | 308 | status = "disabled"; |
| 310 | 309 | }; |
| @@ -314,7 +313,6 @@ · 3 unmodified lines | ||
| 314 | 313 | reg = <0xe803c000 0x30>; |
| 315 | 314 | interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>; |
| 316 | 315 | clocks = <&cpg CPG_MOD 35>; |
| 317 | − clock-names = "ostm1"; | |
| 318 | 316 | power-domains = <&cpg>; |
| 319 | 317 | status = "disabled"; |
| 320 | 318 | }; |
| @@ -324,7 +322,6 @@ · 3 unmodified lines | ||
| 324 | 322 | reg = <0xe803d000 0x30>; |
| 325 | 323 | interrupts = <GIC_SPI 58 IRQ_TYPE_EDGE_RISING>; |
| 326 | 324 | clocks = <&cpg CPG_MOD 34>; |
| 327 | − clock-names = "ostm2"; | |
| 328 | 325 | power-domains = <&cpg>; |
| 329 | 326 | status = "disabled"; |
| 330 | 327 | }; |
| @@ -131,7 +131,14 @@ · 130 unmodified lines | ||
| 131 | 131 | cmt1: timer@e6130000 { |
| 132 | 132 | compatible = "renesas,r8a73a4-cmt1", "renesas,rcar-gen2-cmt1"; |
| 133 | 133 | reg = <0 0xe6130000 0 0x1004>; |
| 134 | − interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; | |
| 134 | + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, | |
| 135 | + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, | |
| 136 | + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, | |
| 137 | + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, | |
| 138 | + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, | |
| 139 | + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, | |
| 140 | + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, | |
| 141 | + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; | |
| 135 | 142 | clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; |
| 136 | 143 | clock-names = "fck"; |
| 137 | 144 | power-domains = <&pd_c5>; |
| @@ -479,7 +479,7 @@ · 478 unmodified lines | ||
| 479 | 479 | cpg_clocks: cpg_clocks@e6150000 { |
| 480 | 480 | compatible = "renesas,r8a7740-cpg-clocks"; |
| 481 | 481 | reg = <0xe6150000 0x10000>; |
| 482 | − clocks = <&extal1_clk>, <&extalr_clk>; | |
| 482 | + clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>; | |
| 483 | 483 | #clock-cells = <1>; |
| 484 | 484 | clock-output-names = "system", "pllc0", "pllc1", |
| 485 | 485 | "pllc2", "r", |
| @@ -84,8 +84,6 @@ · 83 unmodified lines | ||
| 84 | 84 | adi,input-depth = <8>; |
| 85 | 85 | adi,input-colorspace = "rgb"; |
| 86 | 86 | adi,input-clock = "1x"; |
| 87 | − adi,input-style = <1>; | |
| 88 | − adi,input-justification = "evenly"; | |
| 89 | 87 | |
| 90 | 88 | ports { |
| 91 | 89 | #address-cells = <1>; |
| @@ -364,8 +364,6 @@ · 363 unmodified lines | ||
| 364 | 364 | adi,input-depth = <8>; |
| 365 | 365 | adi,input-colorspace = "rgb"; |
| 366 | 366 | adi,input-clock = "1x"; |
| 367 | − adi,input-style = <1>; | |
| 368 | − adi,input-justification = "evenly"; | |
| 369 | 367 | |
| 370 | 368 | ports { |
| 371 | 369 | #address-cells = <1>; |
| @@ -297,8 +297,6 @@ · 296 unmodified lines | ||
| 297 | 297 | adi,input-depth = <8>; |
| 298 | 298 | adi,input-colorspace = "rgb"; |
| 299 | 299 | adi,input-clock = "1x"; |
| 300 | − adi,input-style = <1>; | |
| 301 | − adi,input-justification = "evenly"; | |
| 302 | 300 | |
| 303 | 301 | ports { |
| 304 | 302 | #address-cells = <1>; |
| @@ -387,8 +387,6 @@ · 386 unmodified lines | ||
| 387 | 387 | adi,input-depth = <8>; |
| 388 | 388 | adi,input-colorspace = "rgb"; |
| 389 | 389 | adi,input-clock = "1x"; |
| 390 | − adi,input-style = <1>; | |
| 391 | − adi,input-justification = "evenly"; | |
| 392 | 390 | |
| 393 | 391 | ports { |
| 394 | 392 | #address-cells = <1>; |
| @@ -181,8 +181,6 @@ · 180 unmodified lines | ||
| 181 | 181 | adi,input-depth = <8>; |
| 182 | 182 | adi,input-colorspace = "rgb"; |
| 183 | 183 | adi,input-clock = "1x"; |
| 184 | − adi,input-style = <1>; | |
| 185 | − adi,input-justification = "evenly"; | |
| 186 | 184 | |
| 187 | 185 | ports { |
| 188 | 186 | #address-cells = <1>; |
| @@ -289,8 +289,6 @@ · 288 unmodified lines | ||
| 289 | 289 | adi,input-depth = <8>; |
| 290 | 290 | adi,input-colorspace = "rgb"; |
| 291 | 291 | adi,input-clock = "1x"; |
| 292 | − adi,input-style = <1>; | |
| 293 | − adi,input-justification = "evenly"; | |
| 294 | 292 | |
| 295 | 293 | ports { |
| 296 | 294 | #address-cells = <1>; |
| @@ -249,14 +249,12 @@ · 248 unmodified lines | ||
| 249 | 249 | */ |
| 250 | 250 | hdmi@3d { |
| 251 | 251 | compatible = "adi,adv7513"; |
| 252 | − reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>; | |
| 253 | − reg-names = "main", "cec", "edid", "packet"; | |
| 252 | + reg = <0x3d>, <0x4d>, <0x2d>, <0x5d>; | |
| 253 | + reg-names = "main", "edid", "cec", "packet"; | |
| 254 | 254 | |
| 255 | 255 | adi,input-depth = <8>; |
| 256 | 256 | adi,input-colorspace = "rgb"; |
| 257 | 257 | adi,input-clock = "1x"; |
| 258 | − adi,input-style = <1>; | |
| 259 | − adi,input-justification = "evenly"; | |
| 260 | 258 | |
| 261 | 259 | ports { |
| 262 | 260 | #address-cells = <1>; |
| @@ -280,14 +278,12 @@ · 17 unmodified lines | ||
| 280 | 278 | |
| 281 | 279 | hdmi@39 { |
| 282 | 280 | compatible = "adi,adv7513"; |
| 283 | − reg = <0x39>, <0x29>, <0x49>, <0x59>; | |
| 284 | − reg-names = "main", "cec", "edid", "packet"; | |
| 281 | + reg = <0x39>, <0x49>, <0x29>, <0x59>; | |
| 282 | + reg-names = "main", "edid", "cec", "packet"; | |
| 285 | 283 | |
| 286 | 284 | adi,input-depth = <8>; |
| 287 | 285 | adi,input-colorspace = "rgb"; |
| 288 | 286 | adi,input-clock = "1x"; |
| 289 | − adi,input-style = <1>; | |
| 290 | − adi,input-justification = "evenly"; | |
| 291 | 287 | |
| 292 | 288 | ports { |
| 293 | 289 | #address-cells = <1>; |
| @@ -366,8 +366,6 @@ · 365 unmodified lines | ||
| 366 | 366 | adi,input-depth = <8>; |
| 367 | 367 | adi,input-colorspace = "rgb"; |
| 368 | 368 | adi,input-clock = "1x"; |
| 369 | − adi,input-style = <1>; | |
| 370 | − adi,input-justification = "evenly"; | |
| 371 | 369 | |
| 372 | 370 | ports { |
| 373 | 371 | #address-cells = <1>; |
| @@ -255,8 +255,6 @@ · 254 unmodified lines | ||
| 255 | 255 | adi,input-depth = <8>; |
| 256 | 256 | adi,input-colorspace = "rgb"; |
| 257 | 257 | adi,input-clock = "1x"; |
| 258 | − adi,input-style = <1>; | |
| 259 | − adi,input-justification = "evenly"; | |
| 260 | 258 | |
| 261 | 259 | ports { |
| 262 | 260 | #address-cells = <1>; |
| @@ -128,7 +128,7 @@ · 127 unmodified lines | ||
| 128 | 128 | assigned-clocks = <&cru SCLK_GPU>; |
| 129 | 129 | assigned-clock-rates = <100000000>; |
| 130 | 130 | clocks = <&cru SCLK_GPU>, <&cru SCLK_GPU>; |
| 131 | − clock-names = "core", "bus"; | |
| 131 | + clock-names = "bus", "core"; | |
| 132 | 132 | resets = <&cru SRST_GPU>; |
| 133 | 133 | status = "disabled"; |
| 134 | 134 | }; |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #address-cells = <1>; |
| 47 | 47 | #size-cells = <0>; |
| 48 | 48 | |
| 49 | − phy: phy@0 { | |
| 49 | + phy: ethernet-phy@0 { | |
| 50 | 50 | compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; |
| 51 | 51 | reg = <0>; |
| 52 | 52 | clocks = <&cru SCLK_MAC_PHY>; |
| @@ -150,7 +150,7 @@ · 149 unmodified lines | ||
| 150 | 150 | #address-cells = <1>; |
| 151 | 151 | #size-cells = <0>; |
| 152 | 152 | |
| 153 | − phy: phy@0 { | |
| 153 | + phy: ethernet-phy@0 { | |
| 154 | 154 | compatible = "ethernet-phy-id1234.d400", |
| 155 | 155 | "ethernet-phy-ieee802.3-c22"; |
| 156 | 156 | reg = <0>; |
| @@ -555,7 +555,7 @@ · 554 unmodified lines | ||
| 555 | 555 | "pp1", |
| 556 | 556 | "ppmmu1"; |
| 557 | 557 | clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; |
| 558 | − clock-names = "core", "bus"; | |
| 558 | + clock-names = "bus", "core"; | |
| 559 | 559 | resets = <&cru SRST_GPU_A>; |
| 560 | 560 | status = "disabled"; |
| 561 | 561 | }; |
| @@ -1020,7 +1020,7 @@ · 458 unmodified lines | ||
| 1020 | 1020 | }; |
| 1021 | 1021 | }; |
| 1022 | 1022 | |
| 1023 | − spi-0 { | |
| 1023 | + spi0 { | |
| 1024 | 1024 | spi0_clk: spi0-clk { |
| 1025 | 1025 | rockchip,pins = <0 RK_PB1 2 &pcfg_pull_up>; |
| 1026 | 1026 | }; |
| @@ -1038,7 +1038,7 @@ · 11 unmodified lines | ||
| 1038 | 1038 | }; |
| 1039 | 1039 | }; |
| 1040 | 1040 | |
| 1041 | − spi-1 { | |
| 1041 | + spi1 { | |
| 1042 | 1042 | spi1_clk: spi1-clk { |
| 1043 | 1043 | rockchip,pins = <0 RK_PC7 2 &pcfg_pull_up>; |
| 1044 | 1044 | }; |
| @@ -84,7 +84,7 @@ · 83 unmodified lines | ||
| 84 | 84 | compatible = "arm,mali-400"; |
| 85 | 85 | reg = <0x10090000 0x10000>; |
| 86 | 86 | clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; |
| 87 | − clock-names = "core", "bus"; | |
| 87 | + clock-names = "bus", "core"; | |
| 88 | 88 | assigned-clocks = <&cru ACLK_GPU>; |
| 89 | 89 | assigned-clock-rates = <100000000>; |
| 90 | 90 | resets = <&cru SRST_GPU>; |
| @@ -147,6 +147,7 @@ CONFIG_I2C_DAVINCI=y · 146 unmodified lines | ||
| 147 | 147 | CONFIG_SPI=y |
| 148 | 148 | CONFIG_SPI_DAVINCI=y |
| 149 | 149 | CONFIG_SPI_SPIDEV=y |
| 150 | +CONFIG_PTP_1588_CLOCK=y | |
| 150 | 151 | CONFIG_PINCTRL_SINGLE=y |
| 151 | 152 | CONFIG_GPIOLIB=y |
| 152 | 153 | CONFIG_GPIO_SYSFS=y |
| @@ -274,6 +274,7 @@ CONFIG_SPI_TI_QSPI=m · 273 unmodified lines | ||
| 274 | 274 | CONFIG_HSI=m |
| 275 | 275 | CONFIG_OMAP_SSI=m |
| 276 | 276 | CONFIG_SSI_PROTOCOL=m |
| 277 | +CONFIG_PTP_1588_CLOCK=y | |
| 277 | 278 | CONFIG_PINCTRL_SINGLE=y |
| 278 | 279 | CONFIG_DEBUG_GPIO=y |
| 279 | 280 | CONFIG_GPIO_SYSFS=y |
| @@ -27,7 +27,8 @@ static void __iomem *gic_cpu_ctrl; · 26 unmodified lines | ||
| 27 | 27 | #define GIC_CPU_CTRL 0x00 |
| 28 | 28 | #define GIC_CPU_CTRL_ENABLE 1 |
| 29 | 29 | |
| 30 | −int __init ox820_boot_secondary(unsigned int cpu, struct task_struct *idle) | |
| 30 | +static int __init ox820_boot_secondary(unsigned int cpu, | |
| 31 | + struct task_struct *idle) | |
| 31 | 32 | { |
| 32 | 33 | /* |
| 33 | 34 | * Write the address of secondary startup into the |
| @@ -20,6 +20,7 @@ config ARM64 · 19 unmodified lines | ||
| 20 | 20 | select ARCH_HAS_KCOV |
| 21 | 21 | select ARCH_HAS_KEEPINITRD |
| 22 | 22 | select ARCH_HAS_MEMBARRIER_SYNC_CORE |
| 23 | + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 23 | 24 | select ARCH_HAS_PTE_DEVMAP |
| 24 | 25 | select ARCH_HAS_PTE_SPECIAL |
| 25 | 26 | select ARCH_HAS_SETUP_DMA_OPS |
| @@ -98,7 +98,7 @@ · 97 unmodified lines | ||
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | 100 | &codec_analog { |
| 101 | − hpvcc-supply = <®_eldo1>; | |
| 101 | + cpvdd-supply = <®_eldo1>; | |
| 102 | 102 | status = "okay"; |
| 103 | 103 | }; |
| 104 | 104 | |
| @@ -154,24 +154,6 @@ · 153 unmodified lines | ||
| 154 | 154 | }; |
| 155 | 155 | }; |
| 156 | 156 | |
| 157 | − sound_spdif { | |
| 158 | − compatible = "simple-audio-card"; | |
| 159 | − simple-audio-card,name = "On-board SPDIF"; | |
| 160 | − | |
| 161 | − simple-audio-card,cpu { | |
| 162 | − sound-dai = <&spdif>; | |
| 163 | − }; | |
| 164 | − | |
| 165 | − simple-audio-card,codec { | |
| 166 | − sound-dai = <&spdif_out>; | |
| 167 | − }; | |
| 168 | − }; | |
| 169 | − | |
| 170 | − spdif_out: spdif-out { | |
| 171 | − #sound-dai-cells = <0>; | |
| 172 | − compatible = "linux,spdif-dit"; | |
| 173 | − }; | |
| 174 | − | |
| 175 | 157 | timer { |
| 176 | 158 | compatible = "arm,armv8-timer"; |
| 177 | 159 | allwinner,erratum-unknown1; |
| @@ -2319,7 +2319,7 @@ · 2318 unmodified lines | ||
| 2319 | 2319 | reg = <0x0 0xff400000 0x0 0x40000>; |
| 2320 | 2320 | interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; |
| 2321 | 2321 | clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; |
| 2322 | − clock-names = "ddr"; | |
| 2322 | + clock-names = "otg"; | |
| 2323 | 2323 | phys = <&usb2_phy1>; |
| 2324 | 2324 | phy-names = "usb2-phy"; |
| 2325 | 2325 | dr_mode = "peripheral"; |
| @@ -1,4 +1,3 @@ | ||
| 1 | − | |
| 2 | 1 | // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| 3 | 2 | /* |
| 4 | 3 | * Copyright (c) 2019 BayLibre, SAS |
| @@ -154,6 +154,10 @@ · 153 unmodified lines | ||
| 154 | 154 | clock-latency = <50000>; |
| 155 | 155 | }; |
| 156 | 156 | |
| 157 | +&frddr_a { | |
| 158 | + status = "okay"; | |
| 159 | +}; | |
| 160 | + | |
| 157 | 161 | &frddr_b { |
| 158 | 162 | status = "okay"; |
| 159 | 163 | }; |
| @@ -545,7 +545,7 @@ · 544 unmodified lines | ||
| 545 | 545 | &usb { |
| 546 | 546 | status = "okay"; |
| 547 | 547 | dr_mode = "host"; |
| 548 | − vbus-regulator = <&usb_pwr_en>; | |
| 548 | + vbus-supply = <&usb_pwr_en>; | |
| 549 | 549 | }; |
| 550 | 550 | |
| 551 | 551 | &usb2_phy0 { |
| @@ -447,7 +447,7 @@ · 446 unmodified lines | ||
| 447 | 447 | |
| 448 | 448 | edma0: dma-controller@22c0000 { |
| 449 | 449 | #dma-cells = <2>; |
| 450 | − compatible = "fsl,ls1028a-edma"; | |
| 450 | + compatible = "fsl,ls1028a-edma", "fsl,vf610-edma"; | |
| 451 | 451 | reg = <0x0 0x22c0000 0x0 0x10000>, |
| 452 | 452 | <0x0 0x22d0000 0x0 0x10000>, |
| 453 | 453 | <0x0 0x22e0000 0x0 0x10000>; |
| @@ -264,7 +264,7 @@ · 263 unmodified lines | ||
| 264 | 264 | |
| 265 | 265 | aips1: bus@30000000 { |
| 266 | 266 | compatible = "fsl,aips-bus", "simple-bus"; |
| 267 | − reg = <0x301f0000 0x10000>; | |
| 267 | + reg = <0x30000000 0x400000>; | |
| 268 | 268 | #address-cells = <1>; |
| 269 | 269 | #size-cells = <1>; |
| 270 | 270 | ranges = <0x30000000 0x30000000 0x400000>; |
| @@ -543,7 +543,7 @@ · 272 unmodified lines | ||
| 543 | 543 | |
| 544 | 544 | aips2: bus@30400000 { |
| 545 | 545 | compatible = "fsl,aips-bus", "simple-bus"; |
| 546 | − reg = <0x305f0000 0x10000>; | |
| 546 | + reg = <0x30400000 0x400000>; | |
| 547 | 547 | #address-cells = <1>; |
| 548 | 548 | #size-cells = <1>; |
| 549 | 549 | ranges = <0x30400000 0x30400000 0x400000>; |
| @@ -603,7 +603,7 @@ · 53 unmodified lines | ||
| 603 | 603 | |
| 604 | 604 | aips3: bus@30800000 { |
| 605 | 605 | compatible = "fsl,aips-bus", "simple-bus"; |
| 606 | − reg = <0x309f0000 0x10000>; | |
| 606 | + reg = <0x30800000 0x400000>; | |
| 607 | 607 | #address-cells = <1>; |
| 608 | 608 | #size-cells = <1>; |
| 609 | 609 | ranges = <0x30800000 0x30800000 0x400000>, |
| @@ -863,7 +863,7 @@ · 253 unmodified lines | ||
| 863 | 863 | |
| 864 | 864 | aips4: bus@32c00000 { |
| 865 | 865 | compatible = "fsl,aips-bus", "simple-bus"; |
| 866 | − reg = <0x32df0000 0x10000>; | |
| 866 | + reg = <0x32c00000 0x400000>; | |
| 867 | 867 | #address-cells = <1>; |
| 868 | 868 | #size-cells = <1>; |
| 869 | 869 | ranges = <0x32c00000 0x32c00000 0x400000>; |
| @@ -241,7 +241,7 @@ · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | aips1: bus@30000000 { |
| 243 | 243 | compatible = "fsl,aips-bus", "simple-bus"; |
| 244 | − reg = <0x301f0000 0x10000>; | |
| 244 | + reg = <0x30000000 0x400000>; | |
| 245 | 245 | #address-cells = <1>; |
| 246 | 246 | #size-cells = <1>; |
| 247 | 247 | ranges; |
| @@ -448,7 +448,7 @@ · 200 unmodified lines | ||
| 448 | 448 | |
| 449 | 449 | aips2: bus@30400000 { |
| 450 | 450 | compatible = "fsl,aips-bus", "simple-bus"; |
| 451 | − reg = <0x305f0000 0x10000>; | |
| 451 | + reg = <0x30400000 0x400000>; | |
| 452 | 452 | #address-cells = <1>; |
| 453 | 453 | #size-cells = <1>; |
| 454 | 454 | ranges; |
| @@ -508,7 +508,7 @@ · 53 unmodified lines | ||
| 508 | 508 | |
| 509 | 509 | aips3: bus@30800000 { |
| 510 | 510 | compatible = "fsl,aips-bus", "simple-bus"; |
| 511 | − reg = <0x309f0000 0x10000>; | |
| 511 | + reg = <0x30800000 0x400000>; | |
| 512 | 512 | #address-cells = <1>; |
| 513 | 513 | #size-cells = <1>; |
| 514 | 514 | ranges; |
| @@ -718,7 +718,7 @@ · 203 unmodified lines | ||
| 718 | 718 | reg = <0x30bd0000 0x10000>; |
| 719 | 719 | interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; |
| 720 | 720 | clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>, |
| 721 | − <&clk IMX8MN_CLK_SDMA1_ROOT>; | |
| 721 | + <&clk IMX8MN_CLK_AHB>; | |
| 722 | 722 | clock-names = "ipg", "ahb"; |
| 723 | 723 | #dma-cells = <3>; |
| 724 | 724 | fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; |
| @@ -754,7 +754,7 @@ · 29 unmodified lines | ||
| 754 | 754 | |
| 755 | 755 | aips4: bus@32c00000 { |
| 756 | 756 | compatible = "fsl,aips-bus", "simple-bus"; |
| 757 | − reg = <0x32df0000 0x10000>; | |
| 757 | + reg = <0x32c00000 0x400000>; | |
| 758 | 758 | #address-cells = <1>; |
| 759 | 759 | #size-cells = <1>; |
| 760 | 760 | ranges; |
| @@ -151,26 +151,26 @@ · 150 unmodified lines | ||
| 151 | 151 | #define MX8MP_IOMUXC_ENET_TXC__SIM_M_HADDR22 0x070 0x2D0 0x000 0x7 0x0 |
| 152 | 152 | #define MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x074 0x2D4 0x000 0x0 0x0 |
| 153 | 153 | #define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_SAI7_TX_SYNC 0x074 0x2D4 0x540 0x2 0x0 |
| 154 | −#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_BIT_STREAM03 0x074 0x2D4 0x4CC 0x3 0x0 | |
| 154 | +#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_BIT_STREAM03 0x074 0x2D4 0x4CC 0x3 0x1 | |
| 155 | 155 | #define MX8MP_IOMUXC_ENET_RX_CTL__GPIO1_IO24 0x074 0x2D4 0x000 0x5 0x0 |
| 156 | 156 | #define MX8MP_IOMUXC_ENET_RX_CTL__USDHC3_DATA2 0x074 0x2D4 0x618 0x6 0x0 |
| 157 | 157 | #define MX8MP_IOMUXC_ENET_RX_CTL__SIM_M_HADDR23 0x074 0x2D4 0x000 0x7 0x0 |
| 158 | 158 | #define MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x078 0x2D8 0x000 0x0 0x0 |
| 159 | 159 | #define MX8MP_IOMUXC_ENET_RXC__ENET_QOS_RX_ER 0x078 0x2D8 0x000 0x1 0x0 |
| 160 | 160 | #define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_SAI7_TX_BCLK 0x078 0x2D8 0x53C 0x2 0x0 |
| 161 | −#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_BIT_STREAM02 0x078 0x2D8 0x4C8 0x3 0x0 | |
| 161 | +#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_BIT_STREAM02 0x078 0x2D8 0x4C8 0x3 0x1 | |
| 162 | 162 | #define MX8MP_IOMUXC_ENET_RXC__GPIO1_IO25 0x078 0x2D8 0x000 0x5 0x0 |
| 163 | 163 | #define MX8MP_IOMUXC_ENET_RXC__USDHC3_DATA3 0x078 0x2D8 0x61C 0x6 0x0 |
| 164 | 164 | #define MX8MP_IOMUXC_ENET_RXC__SIM_M_HADDR24 0x078 0x2D8 0x000 0x7 0x0 |
| 165 | 165 | #define MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x07C 0x2DC 0x000 0x0 0x0 |
| 166 | 166 | #define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_SAI7_RX_DATA00 0x07C 0x2DC 0x534 0x2 0x0 |
| 167 | −#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_BIT_STREAM01 0x07C 0x2DC 0x4C4 0x3 0x0 | |
| 167 | +#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_BIT_STREAM01 0x07C 0x2DC 0x4C4 0x3 0x1 | |
| 168 | 168 | #define MX8MP_IOMUXC_ENET_RD0__GPIO1_IO26 0x07C 0x2DC 0x000 0x5 0x0 |
| 169 | 169 | #define MX8MP_IOMUXC_ENET_RD0__USDHC3_DATA4 0x07C 0x2DC 0x620 0x6 0x0 |
| 170 | 170 | #define MX8MP_IOMUXC_ENET_RD0__SIM_M_HADDR25 0x07C 0x2DC 0x000 0x7 0x0 |
| 171 | 171 | #define MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x080 0x2E0 0x000 0x0 0x0 |
| 172 | 172 | #define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_SAI7_RX_SYNC 0x080 0x2E0 0x538 0x2 0x0 |
| 173 | −#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_BIT_STREAM00 0x080 0x2E0 0x4C0 0x3 0x0 | |
| 173 | +#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_BIT_STREAM00 0x080 0x2E0 0x4C0 0x3 0x1 | |
| 174 | 174 | #define MX8MP_IOMUXC_ENET_RD1__GPIO1_IO27 0x080 0x2E0 0x000 0x5 0x0 |
| 175 | 175 | #define MX8MP_IOMUXC_ENET_RD1__USDHC3_RESET_B 0x080 0x2E0 0x000 0x6 0x0 |
| 176 | 176 | #define MX8MP_IOMUXC_ENET_RD1__SIM_M_HADDR26 0x080 0x2E0 0x000 0x7 0x0 |
| @@ -291,7 +291,7 @@ · 114 unmodified lines | ||
| 291 | 291 | #define MX8MP_IOMUXC_SD2_DATA0__I2C4_SDA 0x0C8 0x328 0x5C0 0x2 0x1 |
| 292 | 292 | #define MX8MP_IOMUXC_SD2_DATA0__UART2_DCE_RX 0x0C8 0x328 0x5F0 0x3 0x2 |
| 293 | 293 | #define MX8MP_IOMUXC_SD2_DATA0__UART2_DTE_TX 0x0C8 0x328 0x000 0x3 0x0 |
| 294 | −#define MX8MP_IOMUXC_SD2_DATA0__AUDIOMIX_BIT_STREAM00 0x0C8 0x328 0x4C0 0x4 0x1 | |
| 294 | +#define MX8MP_IOMUXC_SD2_DATA0__AUDIOMIX_BIT_STREAM00 0x0C8 0x328 0x4C0 0x4 0x2 | |
| 295 | 295 | #define MX8MP_IOMUXC_SD2_DATA0__GPIO2_IO15 0x0C8 0x328 0x000 0x5 0x0 |
| 296 | 296 | #define MX8MP_IOMUXC_SD2_DATA0__CCMSRCGPCMIX_OBSERVE2 0x0C8 0x328 0x000 0x6 0x0 |
| 297 | 297 | #define MX8MP_IOMUXC_SD2_DATA0__OBSERVE_MUX_OUT02 0x0C8 0x328 0x000 0x7 0x0 |
| @@ -313,7 +313,7 @@ · 15 unmodified lines | ||
| 313 | 313 | #define MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x0D4 0x334 0x000 0x0 0x0 |
| 314 | 314 | #define MX8MP_IOMUXC_SD2_DATA3__ECSPI2_MISO 0x0D4 0x334 0x56C 0x2 0x0 |
| 315 | 315 | #define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_SPDIF_IN 0x0D4 0x334 0x544 0x3 0x1 |
| 316 | −#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_BIT_STREAM03 0x0D4 0x334 0x4CC 0x4 0x1 | |
| 316 | +#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_BIT_STREAM03 0x0D4 0x334 0x4CC 0x4 0x2 | |
| 317 | 317 | #define MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x0D4 0x334 0x000 0x5 0x0 |
| 318 | 318 | #define MX8MP_IOMUXC_SD2_DATA3__CCMSRCGPCMIX_EARLY_RESET 0x0D4 0x334 0x000 0x6 0x0 |
| 319 | 319 | #define MX8MP_IOMUXC_SD2_RESET_B__USDHC2_RESET_B 0x0D8 0x338 0x000 0x0 0x0 |
| @@ -487,27 +487,27 @@ · 167 unmodified lines | ||
| 487 | 487 | #define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI1_TX_DATA02 0x134 0x394 0x000 0x1 0x0 |
| 488 | 488 | #define MX8MP_IOMUXC_SAI5_RXD0__PWM2_OUT 0x134 0x394 0x000 0x2 0x0 |
| 489 | 489 | #define MX8MP_IOMUXC_SAI5_RXD0__I2C5_SCL 0x134 0x394 0x5C4 0x3 0x1 |
| 490 | −#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_BIT_STREAM00 0x134 0x394 0x4C0 0x4 0x2 | |
| 490 | +#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_BIT_STREAM00 0x134 0x394 0x4C0 0x4 0x3 | |
| 491 | 491 | #define MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x134 0x394 0x000 0x5 0x0 |
| 492 | 492 | #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x138 0x398 0x4FC 0x0 0x0 |
| 493 | 493 | #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_DATA03 0x138 0x398 0x000 0x1 0x0 |
| 494 | 494 | #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_SYNC 0x138 0x398 0x4D8 0x2 0x0 |
| 495 | 495 | #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_TX_SYNC 0x138 0x398 0x510 0x3 0x0 |
| 496 | −#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_BIT_STREAM01 0x138 0x398 0x4C4 0x4 0x2 | |
| 496 | +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_BIT_STREAM01 0x138 0x398 0x4C4 0x4 0x3 | |
| 497 | 497 | #define MX8MP_IOMUXC_SAI5_RXD1__GPIO3_IO22 0x138 0x398 0x000 0x5 0x0 |
| 498 | 498 | #define MX8MP_IOMUXC_SAI5_RXD1__CAN1_TX 0x138 0x398 0x000 0x6 0x0 |
| 499 | 499 | #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x13C 0x39C 0x500 0x0 0x0 |
| 500 | 500 | #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_DATA04 0x13C 0x39C 0x000 0x1 0x0 |
| 501 | 501 | #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_SYNC 0x13C 0x39C 0x4D8 0x2 0x1 |
| 502 | 502 | #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_TX_BCLK 0x13C 0x39C 0x50C 0x3 0x0 |
| 503 | −#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_BIT_STREAM02 0x13C 0x39C 0x4C8 0x4 0x2 | |
| 503 | +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_BIT_STREAM02 0x13C 0x39C 0x4C8 0x4 0x3 | |
| 504 | 504 | #define MX8MP_IOMUXC_SAI5_RXD2__GPIO3_IO23 0x13C 0x39C 0x000 0x5 0x0 |
| 505 | 505 | #define MX8MP_IOMUXC_SAI5_RXD2__CAN1_RX 0x13C 0x39C 0x54C 0x6 0x0 |
| 506 | 506 | #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x140 0x3A0 0x504 0x0 0x0 |
| 507 | 507 | #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_DATA05 0x140 0x3A0 0x000 0x1 0x0 |
| 508 | 508 | #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_SYNC 0x140 0x3A0 0x4D8 0x2 0x2 |
| 509 | 509 | #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_TX_DATA00 0x140 0x3A0 0x000 0x3 0x0 |
| 510 | −#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_BIT_STREAM03 0x140 0x3A0 0x4CC 0x4 0x2 | |
| 510 | +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_BIT_STREAM03 0x140 0x3A0 0x4CC 0x4 0x3 | |
| 511 | 511 | #define MX8MP_IOMUXC_SAI5_RXD3__GPIO3_IO24 0x140 0x3A0 0x000 0x5 0x0 |
| 512 | 512 | #define MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX 0x140 0x3A0 0x000 0x6 0x0 |
| 513 | 513 | #define MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI5_MCLK 0x144 0x3A4 0x4F0 0x0 0x0 |
| @@ -528,22 +528,22 @@ · 14 unmodified lines | ||
| 528 | 528 | #define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_RX_DATA00 0x150 0x3B0 0x000 0x0 0x0 |
| 529 | 529 | #define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x150 0x3B0 0x4F8 0x1 0x1 |
| 530 | 530 | #define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_TX_DATA01 0x150 0x3B0 0x000 0x2 0x0 |
| 531 | −#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_BIT_STREAM00 0x150 0x3B0 0x4C0 0x3 0x3 | |
| 531 | +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_BIT_STREAM00 0x150 0x3B0 0x4C0 0x3 0x4 | |
| 532 | 532 | #define MX8MP_IOMUXC_SAI1_RXD0__ENET1_1588_EVENT1_IN 0x150 0x3B0 0x000 0x4 0x0 |
| 533 | 533 | #define MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x150 0x3B0 0x000 0x5 0x0 |
| 534 | 534 | #define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI1_RX_DATA01 0x154 0x3B4 0x000 0x0 0x0 |
| 535 | 535 | #define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x154 0x3B4 0x4FC 0x1 0x1 |
| 536 | −#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_BIT_STREAM01 0x154 0x3B4 0x4C4 0x3 0x3 | |
| 536 | +#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_BIT_STREAM01 0x154 0x3B4 0x4C4 0x3 0x4 | |
| 537 | 537 | #define MX8MP_IOMUXC_SAI1_RXD1__ENET1_1588_EVENT1_OUT 0x154 0x3B4 0x000 0x4 0x0 |
| 538 | 538 | #define MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03 0x154 0x3B4 0x000 0x5 0x0 |
| 539 | 539 | #define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI1_RX_DATA02 0x158 0x3B8 0x000 0x0 0x0 |
| 540 | 540 | #define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x158 0x3B8 0x500 0x1 0x1 |
| 541 | −#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_BIT_STREAM02 0x158 0x3B8 0x4C8 0x3 0x3 | |
| 541 | +#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_BIT_STREAM02 0x158 0x3B8 0x4C8 0x3 0x4 | |
| 542 | 542 | #define MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x158 0x3B8 0x000 0x4 0x0 |
| 543 | 543 | #define MX8MP_IOMUXC_SAI1_RXD2__GPIO4_IO04 0x158 0x3B8 0x000 0x5 0x0 |
| 544 | 544 | #define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI1_RX_DATA03 0x15C 0x3BC 0x000 0x0 0x0 |
| 545 | 545 | #define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x15C 0x3BC 0x504 0x1 0x1 |
| 546 | −#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_BIT_STREAM03 0x15C 0x3BC 0x4CC 0x3 0x3 | |
| 546 | +#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_BIT_STREAM03 0x15C 0x3BC 0x4CC 0x3 0x4 | |
| 547 | 547 | #define MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x15C 0x3BC 0x57C 0x4 0x1 |
| 548 | 548 | #define MX8MP_IOMUXC_SAI1_RXD3__GPIO4_IO05 0x15C 0x3BC 0x000 0x5 0x0 |
| 549 | 549 | #define MX8MP_IOMUXC_SAI1_RXD4__AUDIOMIX_SAI1_RX_DATA04 0x160 0x3C0 0x000 0x0 0x0 |
| @@ -624,7 +624,7 @@ · 74 unmodified lines | ||
| 624 | 624 | #define MX8MP_IOMUXC_SAI2_RXFS__UART1_DCE_TX 0x19C 0x3FC 0x000 0x4 0x0 |
| 625 | 625 | #define MX8MP_IOMUXC_SAI2_RXFS__UART1_DTE_RX 0x19C 0x3FC 0x5E8 0x4 0x2 |
| 626 | 626 | #define MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x19C 0x3FC 0x000 0x5 0x0 |
| 627 | −#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_BIT_STREAM02 0x19C 0x3FC 0x4C8 0x6 0x4 | |
| 627 | +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_BIT_STREAM02 0x19C 0x3FC 0x4C8 0x6 0x5 | |
| 628 | 628 | #define MX8MP_IOMUXC_SAI2_RXFS__SIM_M_HSIZE00 0x19C 0x3FC 0x000 0x7 0x0 |
| 629 | 629 | #define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI2_RX_BCLK 0x1A0 0x400 0x000 0x0 0x0 |
| 630 | 630 | #define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI5_TX_BCLK 0x1A0 0x400 0x50C 0x1 0x2 |
| @@ -632,7 +632,7 @@ · 1 unmodified line | ||
| 632 | 632 | #define MX8MP_IOMUXC_SAI2_RXC__UART1_DCE_RX 0x1A0 0x400 0x5E8 0x4 0x3 |
| 633 | 633 | #define MX8MP_IOMUXC_SAI2_RXC__UART1_DTE_TX 0x1A0 0x400 0x000 0x4 0x0 |
| 634 | 634 | #define MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x1A0 0x400 0x000 0x5 0x0 |
| 635 | −#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_BIT_STREAM01 0x1A0 0x400 0x4C4 0x6 0x4 | |
| 635 | +#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_BIT_STREAM01 0x1A0 0x400 0x4C4 0x6 0x5 | |
| 636 | 636 | #define MX8MP_IOMUXC_SAI2_RXC__SIM_M_HSIZE01 0x1A0 0x400 0x000 0x7 0x0 |
| 637 | 637 | #define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0x1A4 0x404 0x000 0x0 0x0 |
| 638 | 638 | #define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI5_TX_DATA00 0x1A4 0x404 0x000 0x1 0x0 |
| @@ -641,7 +641,7 @@ · 2 unmodified lines | ||
| 641 | 641 | #define MX8MP_IOMUXC_SAI2_RXD0__UART1_DCE_RTS 0x1A4 0x404 0x5E4 0x4 0x2 |
| 642 | 642 | #define MX8MP_IOMUXC_SAI2_RXD0__UART1_DTE_CTS 0x1A4 0x404 0x000 0x4 0x0 |
| 643 | 643 | #define MX8MP_IOMUXC_SAI2_RXD0__GPIO4_IO23 0x1A4 0x404 0x000 0x5 0x0 |
| 644 | −#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_BIT_STREAM03 0x1A4 0x404 0x4CC 0x6 0x4 | |
| 644 | +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_BIT_STREAM03 0x1A4 0x404 0x4CC 0x6 0x5 | |
| 645 | 645 | #define MX8MP_IOMUXC_SAI2_RXD0__SIM_M_HSIZE02 0x1A4 0x404 0x000 0x7 0x0 |
| 646 | 646 | #define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0x1A8 0x408 0x000 0x0 0x0 |
| 647 | 647 | #define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI5_TX_DATA01 0x1A8 0x408 0x000 0x1 0x0 |
| @@ -650,13 +650,13 @@ · 2 unmodified lines | ||
| 650 | 650 | #define MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS 0x1A8 0x408 0x000 0x4 0x0 |
| 651 | 651 | #define MX8MP_IOMUXC_SAI2_TXFS__UART1_DTE_RTS 0x1A8 0x408 0x5E4 0x4 0x3 |
| 652 | 652 | #define MX8MP_IOMUXC_SAI2_TXFS__GPIO4_IO24 0x1A8 0x408 0x000 0x5 0x0 |
| 653 | −#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_BIT_STREAM02 0x1A8 0x408 0x4C8 0x6 0x5 | |
| 653 | +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_BIT_STREAM02 0x1A8 0x408 0x4C8 0x6 0x6 | |
| 654 | 654 | #define MX8MP_IOMUXC_SAI2_TXFS__SIM_M_HWRITE 0x1A8 0x408 0x000 0x7 0x0 |
| 655 | 655 | #define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0x1AC 0x40C 0x000 0x0 0x0 |
| 656 | 656 | #define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI5_TX_DATA02 0x1AC 0x40C 0x000 0x1 0x0 |
| 657 | 657 | #define MX8MP_IOMUXC_SAI2_TXC__CAN1_RX 0x1AC 0x40C 0x54C 0x3 0x1 |
| 658 | 658 | #define MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x1AC 0x40C 0x000 0x5 0x0 |
| 659 | −#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_BIT_STREAM01 0x1AC 0x40C 0x4C4 0x6 0x5 | |
| 659 | +#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_BIT_STREAM01 0x1AC 0x40C 0x4C4 0x6 0x6 | |
| 660 | 660 | #define MX8MP_IOMUXC_SAI2_TXC__SIM_M_HREADYOUT 0x1AC 0x40C 0x000 0x7 0x0 |
| 661 | 661 | #define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0x1B0 0x410 0x000 0x0 0x0 |
| 662 | 662 | #define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI5_TX_DATA03 0x1B0 0x410 0x000 0x1 0x0 |
| @@ -680,7 +680,7 @@ · 17 unmodified lines | ||
| 680 | 680 | #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_DATA01 0x1B8 0x418 0x000 0x3 0x0 |
| 681 | 681 | #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SPDIF_IN 0x1B8 0x418 0x544 0x4 0x2 |
| 682 | 682 | #define MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x1B8 0x418 0x000 0x5 0x0 |
| 683 | −#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_BIT_STREAM00 0x1B8 0x418 0x4C0 0x6 0x4 | |
| 683 | +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_BIT_STREAM00 0x1B8 0x418 0x4C0 0x6 0x5 | |
| 684 | 684 | #define MX8MP_IOMUXC_SAI3_RXFS__TPSMP_HTRANS00 0x1B8 0x418 0x000 0x7 0x0 |
| 685 | 685 | #define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI3_RX_BCLK 0x1BC 0x41C 0x000 0x0 0x0 |
| 686 | 686 | #define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI2_RX_DATA02 0x1BC 0x41C 0x000 0x1 0x0 |
| @@ -697,7 +697,7 @@ · 10 unmodified lines | ||
| 697 | 697 | #define MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS 0x1C0 0x420 0x5EC 0x4 0x3 |
| 698 | 698 | #define MX8MP_IOMUXC_SAI3_RXD__UART2_DTE_CTS 0x1C0 0x420 0x000 0x4 0x0 |
| 699 | 699 | #define MX8MP_IOMUXC_SAI3_RXD__GPIO4_IO30 0x1C0 0x420 0x000 0x5 0x0 |
| 700 | −#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_BIT_STREAM01 0x1C0 0x420 0x4C4 0x6 0x6 | |
| 700 | +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_BIT_STREAM01 0x1C0 0x420 0x4C4 0x6 0x7 | |
| 701 | 701 | #define MX8MP_IOMUXC_SAI3_RXD__TPSMP_HDATA00 0x1C0 0x420 0x000 0x7 0x0 |
| 702 | 702 | #define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0x1C4 0x424 0x4EC 0x0 0x1 |
| 703 | 703 | #define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI2_TX_DATA01 0x1C4 0x424 0x000 0x1 0x0 |
| @@ -706,7 +706,7 @@ · 2 unmodified lines | ||
| 706 | 706 | #define MX8MP_IOMUXC_SAI3_TXFS__UART2_DCE_RX 0x1C4 0x424 0x5F0 0x4 0x4 |
| 707 | 707 | #define MX8MP_IOMUXC_SAI3_TXFS__UART2_DTE_TX 0x1C4 0x424 0x000 0x4 0x0 |
| 708 | 708 | #define MX8MP_IOMUXC_SAI3_TXFS__GPIO4_IO31 0x1C4 0x424 0x000 0x5 0x0 |
| 709 | −#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_BIT_STREAM03 0x1C4 0x424 0x4CC 0x6 0x5 | |
| 709 | +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_BIT_STREAM03 0x1C4 0x424 0x4CC 0x6 0x6 | |
| 710 | 710 | #define MX8MP_IOMUXC_SAI3_TXFS__TPSMP_HDATA01 0x1C4 0x424 0x000 0x7 0x0 |
| 711 | 711 | #define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0x1C8 0x428 0x4E8 0x0 0x1 |
| 712 | 712 | #define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI2_TX_DATA02 0x1C8 0x428 0x000 0x1 0x0 |
| @@ -715,7 +715,7 @@ · 2 unmodified lines | ||
| 715 | 715 | #define MX8MP_IOMUXC_SAI3_TXC__UART2_DCE_TX 0x1C8 0x428 0x000 0x4 0x0 |
| 716 | 716 | #define MX8MP_IOMUXC_SAI3_TXC__UART2_DTE_RX 0x1C8 0x428 0x5F0 0x4 0x5 |
| 717 | 717 | #define MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x1C8 0x428 0x000 0x5 0x0 |
| 718 | −#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_BIT_STREAM02 0x1C8 0x428 0x4C8 0x6 0x6 | |
| 718 | +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_BIT_STREAM02 0x1C8 0x428 0x4C8 0x6 0x7 | |
| 719 | 719 | #define MX8MP_IOMUXC_SAI3_TXC__TPSMP_HDATA02 0x1C8 0x428 0x000 0x7 0x0 |
| 720 | 720 | #define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0x1CC 0x42C 0x000 0x0 0x0 |
| 721 | 721 | #define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI2_TX_DATA03 0x1CC 0x42C 0x000 0x1 0x0 |
| @@ -145,7 +145,7 @@ · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | aips1: bus@30000000 { |
| 147 | 147 | compatible = "fsl,aips-bus", "simple-bus"; |
| 148 | − reg = <0x301f0000 0x10000>; | |
| 148 | + reg = <0x30000000 0x400000>; | |
| 149 | 149 | #address-cells = <1>; |
| 150 | 150 | #size-cells = <1>; |
| 151 | 151 | ranges; |
| @@ -318,7 +318,7 @@ · 166 unmodified lines | ||
| 318 | 318 | |
| 319 | 319 | aips2: bus@30400000 { |
| 320 | 320 | compatible = "fsl,aips-bus", "simple-bus"; |
| 321 | − reg = <0x305f0000 0x400000>; | |
| 321 | + reg = <0x30400000 0x400000>; | |
| 322 | 322 | #address-cells = <1>; |
| 323 | 323 | #size-cells = <1>; |
| 324 | 324 | ranges; |
| @@ -378,7 +378,7 @@ · 53 unmodified lines | ||
| 378 | 378 | |
| 379 | 379 | aips3: bus@30800000 { |
| 380 | 380 | compatible = "fsl,aips-bus", "simple-bus"; |
| 381 | − reg = <0x309f0000 0x400000>; | |
| 381 | + reg = <0x30800000 0x400000>; | |
| 382 | 382 | #address-cells = <1>; |
| 383 | 383 | #size-cells = <1>; |
| 384 | 384 | ranges; |
| @@ -291,7 +291,7 @@ · 290 unmodified lines | ||
| 291 | 291 | |
| 292 | 292 | bus@30000000 { /* AIPS1 */ |
| 293 | 293 | compatible = "fsl,aips-bus", "simple-bus"; |
| 294 | − reg = <0x301f0000 0x10000>; | |
| 294 | + reg = <0x30000000 0x400000>; | |
| 295 | 295 | #address-cells = <1>; |
| 296 | 296 | #size-cells = <1>; |
| 297 | 297 | ranges = <0x30000000 0x30000000 0x400000>; |
| @@ -696,7 +696,7 @@ · 398 unmodified lines | ||
| 696 | 696 | |
| 697 | 697 | bus@30400000 { /* AIPS2 */ |
| 698 | 698 | compatible = "fsl,aips-bus", "simple-bus"; |
| 699 | − reg = <0x305f0000 0x10000>; | |
| 699 | + reg = <0x30400000 0x400000>; | |
| 700 | 700 | #address-cells = <1>; |
| 701 | 701 | #size-cells = <1>; |
| 702 | 702 | ranges = <0x30400000 0x30400000 0x400000>; |
| @@ -756,7 +756,7 @@ · 53 unmodified lines | ||
| 756 | 756 | |
| 757 | 757 | bus@30800000 { /* AIPS3 */ |
| 758 | 758 | compatible = "fsl,aips-bus", "simple-bus"; |
| 759 | − reg = <0x309f0000 0x10000>; | |
| 759 | + reg = <0x30800000 0x400000>; | |
| 760 | 760 | #address-cells = <1>; |
| 761 | 761 | #size-cells = <1>; |
| 762 | 762 | ranges = <0x30800000 0x30800000 0x400000>, |
| @@ -1029,7 +1029,7 @@ · 266 unmodified lines | ||
| 1029 | 1029 | |
| 1030 | 1030 | bus@32c00000 { /* AIPS4 */ |
| 1031 | 1031 | compatible = "fsl,aips-bus", "simple-bus"; |
| 1032 | − reg = <0x32df0000 0x10000>; | |
| 1032 | + reg = <0x32c00000 0x400000>; | |
| 1033 | 1033 | #address-cells = <1>; |
| 1034 | 1034 | #size-cells = <1>; |
| 1035 | 1035 | ranges = <0x32c00000 0x32c00000 0x400000>; |
| @@ -658,8 +658,8 @@ · 657 unmodified lines | ||
| 658 | 658 | s11 { |
| 659 | 659 | qcom,saw-leader; |
| 660 | 660 | regulator-always-on; |
| 661 | − regulator-min-microvolt = <1230000>; | |
| 662 | − regulator-max-microvolt = <1230000>; | |
| 661 | + regulator-min-microvolt = <980000>; | |
| 662 | + regulator-max-microvolt = <980000>; | |
| 663 | 663 | }; |
| 664 | 664 | }; |
| 665 | 665 | |
| @@ -908,10 +908,27 @@ · 242 unmodified lines | ||
| 908 | 908 | status = "okay"; |
| 909 | 909 | }; |
| 910 | 910 | |
| 911 | +&q6asmdai { | |
| 912 | + dai@0 { | |
| 913 | + reg = <0>; | |
| 914 | + }; | |
| 915 | + | |
| 916 | + dai@1 { | |
| 917 | + reg = <1>; | |
| 918 | + }; | |
| 919 | + | |
| 920 | + dai@2 { | |
| 921 | + reg = <2>; | |
| 922 | + }; | |
| 923 | +}; | |
| 924 | + | |
| 911 | 925 | &sound { |
| 912 | 926 | compatible = "qcom,apq8096-sndcard"; |
| 913 | 927 | model = "DB820c"; |
| 914 | − audio-routing = "RX_BIAS", "MCLK"; | |
| 928 | + audio-routing = "RX_BIAS", "MCLK", | |
| 929 | + "MM_DL1", "MultiMedia1 Playback", | |
| 930 | + "MM_DL2", "MultiMedia2 Playback", | |
| 931 | + "MultiMedia3 Capture", "MM_UL3"; | |
| 915 | 932 | |
| 916 | 933 | mm1-dai-link { |
| 917 | 934 | link-name = "MultiMedia1"; |
| @@ -2066,6 +2066,8 @@ · 2065 unmodified lines | ||
| 2066 | 2066 | reg = <APR_SVC_ASM>; |
| 2067 | 2067 | q6asmdai: dais { |
| 2068 | 2068 | compatible = "qcom,q6asm-dais"; |
| 2069 | + #address-cells = <1>; | |
| 2070 | + #size-cells = <0>; | |
| 2069 | 2071 | #sound-dai-cells = <1>; |
| 2070 | 2072 | iommus = <&lpass_q6_smmu 1>; |
| 2071 | 2073 | }; |
| @@ -442,17 +442,14 @@ · 441 unmodified lines | ||
| 442 | 442 | &q6asmdai { |
| 443 | 443 | dai@0 { |
| 444 | 444 | reg = <0>; |
| 445 | − direction = <2>; | |
| 446 | 445 | }; |
| 447 | 446 | |
| 448 | 447 | dai@1 { |
| 449 | 448 | reg = <1>; |
| 450 | − direction = <2>; | |
| 451 | 449 | }; |
| 452 | 450 | |
| 453 | 451 | dai@2 { |
| 454 | 452 | reg = <2>; |
| 455 | − direction = <1>; | |
| 456 | 453 | }; |
| 457 | 454 | |
| 458 | 455 | dai@3 { |
| @@ -359,12 +359,10 @@ · 358 unmodified lines | ||
| 359 | 359 | &q6asmdai { |
| 360 | 360 | dai@0 { |
| 361 | 361 | reg = <0>; |
| 362 | − direction = <2>; | |
| 363 | 362 | }; |
| 364 | 363 | |
| 365 | 364 | dai@1 { |
| 366 | 365 | reg = <1>; |
| 367 | − direction = <1>; | |
| 368 | 366 | }; |
| 369 | 367 | }; |
| 370 | 368 | |
| @@ -137,8 +137,6 @@ · 136 unmodified lines | ||
| 137 | 137 | adi,input-depth = <8>; |
| 138 | 138 | adi,input-colorspace = "rgb"; |
| 139 | 139 | adi,input-clock = "1x"; |
| 140 | − adi,input-style = <1>; | |
| 141 | − adi,input-justification = "evenly"; | |
| 142 | 140 | |
| 143 | 141 | ports { |
| 144 | 142 | #address-cells = <1>; |
| @@ -150,8 +150,6 @@ · 149 unmodified lines | ||
| 150 | 150 | adi,input-depth = <8>; |
| 151 | 151 | adi,input-colorspace = "rgb"; |
| 152 | 152 | adi,input-clock = "1x"; |
| 153 | − adi,input-style = <1>; | |
| 154 | − adi,input-justification = "evenly"; | |
| 155 | 153 | |
| 156 | 154 | ports { |
| 157 | 155 | #address-cells = <1>; |
| @@ -174,8 +174,6 @@ · 173 unmodified lines | ||
| 174 | 174 | adi,input-depth = <8>; |
| 175 | 175 | adi,input-colorspace = "rgb"; |
| 176 | 176 | adi,input-clock = "1x"; |
| 177 | − adi,input-style = <1>; | |
| 178 | − adi,input-justification = "evenly"; | |
| 179 | 177 | |
| 180 | 178 | ports { |
| 181 | 179 | #address-cells = <1>; |
| @@ -141,8 +141,6 @@ · 140 unmodified lines | ||
| 141 | 141 | adi,input-depth = <8>; |
| 142 | 142 | adi,input-colorspace = "rgb"; |
| 143 | 143 | adi,input-clock = "1x"; |
| 144 | − adi,input-style = <1>; | |
| 145 | − adi,input-justification = "evenly"; | |
| 146 | 144 | |
| 147 | 145 | ports { |
| 148 | 146 | #address-cells = <1>; |
| @@ -1318,6 +1318,7 @@ · 1317 unmodified lines | ||
| 1318 | 1318 | ipmmu_vip0: mmu@e7b00000 { |
| 1319 | 1319 | compatible = "renesas,ipmmu-r8a77980"; |
| 1320 | 1320 | reg = <0 0xe7b00000 0 0x1000>; |
| 1321 | + renesas,ipmmu-main = <&ipmmu_mm 4>; | |
| 1321 | 1322 | power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; |
| 1322 | 1323 | #iommu-cells = <1>; |
| 1323 | 1324 | }; |
| @@ -1325,6 +1326,7 @@ · 1 unmodified line | ||
| 1325 | 1326 | ipmmu_vip1: mmu@e7960000 { |
| 1326 | 1327 | compatible = "renesas,ipmmu-r8a77980"; |
| 1327 | 1328 | reg = <0 0xe7960000 0 0x1000>; |
| 1329 | + renesas,ipmmu-main = <&ipmmu_mm 11>; | |
| 1328 | 1330 | power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; |
| 1329 | 1331 | #iommu-cells = <1>; |
| 1330 | 1332 | }; |
| @@ -360,8 +360,6 @@ · 359 unmodified lines | ||
| 360 | 360 | adi,input-depth = <8>; |
| 361 | 361 | adi,input-colorspace = "rgb"; |
| 362 | 362 | adi,input-clock = "1x"; |
| 363 | − adi,input-style = <1>; | |
| 364 | − adi,input-justification = "evenly"; | |
| 365 | 363 | |
| 366 | 364 | ports { |
| 367 | 365 | #address-cells = <1>; |
| @@ -272,8 +272,8 @@ · 271 unmodified lines | ||
| 272 | 272 | |
| 273 | 273 | hdmi-encoder@39 { |
| 274 | 274 | compatible = "adi,adv7511w"; |
| 275 | − reg = <0x39>, <0x3f>, <0x38>, <0x3c>; | |
| 276 | − reg-names = "main", "edid", "packet", "cec"; | |
| 275 | + reg = <0x39>, <0x3f>, <0x3c>, <0x38>; | |
| 276 | + reg-names = "main", "edid", "cec", "packet"; | |
| 277 | 277 | interrupt-parent = <&gpio1>; |
| 278 | 278 | interrupts = <28 IRQ_TYPE_LEVEL_LOW>; |
| 279 | 279 | |
| @@ -284,8 +284,6 @@ · 4 unmodified lines | ||
| 284 | 284 | adi,input-depth = <8>; |
| 285 | 285 | adi,input-colorspace = "rgb"; |
| 286 | 286 | adi,input-clock = "1x"; |
| 287 | − adi,input-style = <1>; | |
| 288 | − adi,input-justification = "evenly"; | |
| 289 | 287 | |
| 290 | 288 | ports { |
| 291 | 289 | #address-cells = <1>; |
| @@ -143,7 +143,7 @@ · 142 unmodified lines | ||
| 143 | 143 | }; |
| 144 | 144 | |
| 145 | 145 | arm-pmu { |
| 146 | − compatible = "arm,cortex-a53-pmu"; | |
| 146 | + compatible = "arm,cortex-a35-pmu"; | |
| 147 | 147 | interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, |
| 148 | 148 | <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, |
| 149 | 149 | <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, |
| @@ -127,7 +127,7 @@ · 126 unmodified lines | ||
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | 129 | arm-pmu { |
| 130 | − compatible = "arm,cortex-a53-pmu"; | |
| 130 | + compatible = "arm,cortex-a35-pmu"; | |
| 131 | 131 | interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>, |
| 132 | 132 | <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, |
| 133 | 133 | <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, |
| @@ -82,17 +82,16 @@ · 81 unmodified lines | ||
| 82 | 82 | &gmac2phy { |
| 83 | 83 | phy-supply = <&vcc_phy>; |
| 84 | 84 | clock_in_out = "output"; |
| 85 | − assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; | |
| 86 | 85 | assigned-clock-rate = <50000000>; |
| 87 | 86 | assigned-clocks = <&cru SCLK_MAC2PHY>; |
| 88 | 87 | assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; |
| 89 | − | |
| 88 | + status = "okay"; | |
| 90 | 89 | }; |
| 91 | 90 | |
| 92 | 91 | &i2c1 { |
| 93 | 92 | status = "okay"; |
| 94 | 93 | |
| 95 | − rk805: rk805@18 { | |
| 94 | + rk805: pmic@18 { | |
| 96 | 95 | compatible = "rockchip,rk805"; |
| 97 | 96 | reg = <0x18>; |
| 98 | 97 | interrupt-parent = <&gpio2>; |
| @@ -170,7 +170,7 @@ · 169 unmodified lines | ||
| 170 | 170 | &i2c1 { |
| 171 | 171 | status = "okay"; |
| 172 | 172 | |
| 173 | − rk805: rk805@18 { | |
| 173 | + rk805: pmic@18 { | |
| 174 | 174 | compatible = "rockchip,rk805"; |
| 175 | 175 | reg = <0x18>; |
| 176 | 176 | interrupt-parent = <&gpio2>; |
| @@ -299,8 +299,6 @@ · 298 unmodified lines | ||
| 299 | 299 | grf: syscon@ff100000 { |
| 300 | 300 | compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd"; |
| 301 | 301 | reg = <0x0 0xff100000 0x0 0x1000>; |
| 302 | − #address-cells = <1>; | |
| 303 | − #size-cells = <1>; | |
| 304 | 302 | |
| 305 | 303 | io_domains: io-domains { |
| 306 | 304 | compatible = "rockchip,rk3328-io-voltage-domain"; |
| @@ -1794,10 +1792,6 @@ · 1487 unmodified lines | ||
| 1794 | 1792 | }; |
| 1795 | 1793 | |
| 1796 | 1794 | gmac2phy { |
| 1797 | − fephyled_speed100: fephyled-speed100 { | |
| 1798 | − rockchip,pins = <0 RK_PD7 1 &pcfg_pull_none>; | |
| 1799 | − }; | |
| 1800 | − | |
| 1801 | 1795 | fephyled_speed10: fephyled-speed10 { |
| 1802 | 1796 | rockchip,pins = <0 RK_PD6 1 &pcfg_pull_none>; |
| 1803 | 1797 | }; |
| @@ -1806,18 +1800,6 @@ · 2 unmodified lines | ||
| 1806 | 1800 | rockchip,pins = <0 RK_PD6 2 &pcfg_pull_none>; |
| 1807 | 1801 | }; |
| 1808 | 1802 | |
| 1809 | − fephyled_rxm0: fephyled-rxm0 { | |
| 1810 | − rockchip,pins = <0 RK_PD5 1 &pcfg_pull_none>; | |
| 1811 | − }; | |
| 1812 | − | |
| 1813 | − fephyled_txm0: fephyled-txm0 { | |
| 1814 | − rockchip,pins = <0 RK_PD5 2 &pcfg_pull_none>; | |
| 1815 | − }; | |
| 1816 | − | |
| 1817 | − fephyled_linkm0: fephyled-linkm0 { | |
| 1818 | − rockchip,pins = <0 RK_PD4 1 &pcfg_pull_none>; | |
| 1819 | − }; | |
| 1820 | − | |
| 1821 | 1803 | fephyled_rxm1: fephyled-rxm1 { |
| 1822 | 1804 | rockchip,pins = <2 RK_PD1 2 &pcfg_pull_none>; |
| 1823 | 1805 | }; |
| @@ -147,7 +147,7 @@ · 146 unmodified lines | ||
| 147 | 147 | "Speaker", "Speaker Amplifier OUTL", |
| 148 | 148 | "Speaker", "Speaker Amplifier OUTR"; |
| 149 | 149 | |
| 150 | − simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>; | |
| 150 | + simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; | |
| 151 | 151 | simple-audio-card,aux-devs = <&speaker_amp>; |
| 152 | 152 | simple-audio-card,pin-switches = "Speaker"; |
| 153 | 153 | |
| @@ -690,7 +690,8 @@ · 536 unmodified lines | ||
| 690 | 690 | fusb0: fusb30x@22 { |
| 691 | 691 | compatible = "fcs,fusb302"; |
| 692 | 692 | reg = <0x22>; |
| 693 | − fcs,int_n = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; | |
| 693 | + interrupt-parent = <&gpio1>; | |
| 694 | + interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>; | |
| 694 | 695 | pinctrl-names = "default"; |
| 695 | 696 | pinctrl-0 = <&fusb0_int_gpio>; |
| 696 | 697 | vbus-supply = <&vbus_typec>; |
| @@ -788,13 +789,13 @@ · 91 unmodified lines | ||
| 788 | 789 | |
| 789 | 790 | dc-charger { |
| 790 | 791 | dc_det_gpio: dc-det-gpio { |
| 791 | − rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; | |
| 792 | + rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; | |
| 792 | 793 | }; |
| 793 | 794 | }; |
| 794 | 795 | |
| 795 | 796 | es8316 { |
| 796 | 797 | hp_det_gpio: hp-det-gpio { |
| 797 | − rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; | |
| 798 | + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; | |
| 798 | 799 | }; |
| 799 | 800 | }; |
| 800 | 801 | |
| @@ -403,7 +403,7 @@ · 402 unmodified lines | ||
| 403 | 403 | reset-names = "usb3-otg"; |
| 404 | 404 | status = "disabled"; |
| 405 | 405 | |
| 406 | − usbdrd_dwc3_0: dwc3 { | |
| 406 | + usbdrd_dwc3_0: usb@fe800000 { | |
| 407 | 407 | compatible = "snps,dwc3"; |
| 408 | 408 | reg = <0x0 0xfe800000 0x0 0x100000>; |
| 409 | 409 | interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>; |
| @@ -439,7 +439,7 @@ · 29 unmodified lines | ||
| 439 | 439 | reset-names = "usb3-otg"; |
| 440 | 440 | status = "disabled"; |
| 441 | 441 | |
| 442 | − usbdrd_dwc3_1: dwc3 { | |
| 442 | + usbdrd_dwc3_1: usb@fe900000 { | |
| 443 | 443 | compatible = "snps,dwc3"; |
| 444 | 444 | reg = <0x0 0xfe900000 0x0 0x100000>; |
| 445 | 445 | interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>; |
| @@ -1124,8 +1124,6 @@ · 678 unmodified lines | ||
| 1124 | 1124 | pmugrf: syscon@ff320000 { |
| 1125 | 1125 | compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd"; |
| 1126 | 1126 | reg = <0x0 0xff320000 0x0 0x1000>; |
| 1127 | − #address-cells = <1>; | |
| 1128 | − #size-cells = <1>; | |
| 1129 | 1127 | |
| 1130 | 1128 | pmu_io_domains: io-domains { |
| 1131 | 1129 | compatible = "rockchip,rk3399-pmu-io-voltage-domain"; |
| @@ -1883,10 +1881,10 @@ · 751 unmodified lines | ||
| 1883 | 1881 | gpu: gpu@ff9a0000 { |
| 1884 | 1882 | compatible = "rockchip,rk3399-mali", "arm,mali-t860"; |
| 1885 | 1883 | reg = <0x0 0xff9a0000 0x0 0x10000>; |
| 1886 | − interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH 0>, | |
| 1887 | − <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH 0>, | |
| 1888 | − <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH 0>; | |
| 1889 | − interrupt-names = "gpu", "job", "mmu"; | |
| 1884 | + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH 0>, | |
| 1885 | + <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH 0>, | |
| 1886 | + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH 0>; | |
| 1887 | + interrupt-names = "job", "mmu", "gpu"; | |
| 1890 | 1888 | clocks = <&cru ACLK_GPU>; |
| 1891 | 1889 | #cooling-cells = <2>; |
| 1892 | 1890 | power-domains = <&power RK3399_PD_GPU>; |
| @@ -208,7 +208,7 @@ CONFIG_PCIE_QCOM=y · 207 unmodified lines | ||
| 208 | 208 | CONFIG_PCIE_ARMADA_8K=y |
| 209 | 209 | CONFIG_PCIE_KIRIN=y |
| 210 | 210 | CONFIG_PCIE_HISI_STB=y |
| 211 | −CONFIG_PCIE_TEGRA194=m | |
| 211 | +CONFIG_PCIE_TEGRA194_HOST=m | |
| 212 | 212 | CONFIG_DEVTMPFS=y |
| 213 | 213 | CONFIG_DEVTMPFS_MOUNT=y |
| 214 | 214 | CONFIG_FW_LOADER_USER_HELPER=y |
| @@ -567,6 +567,7 @@ CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y · 352 unmodified lines | ||
| 567 | 567 | CONFIG_MEDIA_SDR_SUPPORT=y |
| 568 | 568 | CONFIG_MEDIA_CONTROLLER=y |
| 569 | 569 | CONFIG_VIDEO_V4L2_SUBDEV_API=y |
| 570 | +CONFIG_MEDIA_PLATFORM_SUPPORT=y | |
| 570 | 571 | # CONFIG_DVB_NET is not set |
| 571 | 572 | CONFIG_MEDIA_USB_SUPPORT=y |
| 572 | 573 | CONFIG_USB_VIDEO_CLASS=m |
| @@ -610,8 +611,9 @@ CONFIG_DRM_MSM=m · 37 unmodified lines | ||
| 610 | 611 | CONFIG_DRM_TEGRA=m |
| 611 | 612 | CONFIG_DRM_PANEL_LVDS=m |
| 612 | 613 | CONFIG_DRM_PANEL_SIMPLE=m |
| 613 | −CONFIG_DRM_DUMB_VGA_DAC=m | |
| 614 | +CONFIG_DRM_SIMPLE_BRIDGE=m | |
| 614 | 615 | CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m |
| 616 | +CONFIG_DRM_DISPLAY_CONNECTOR=m | |
| 615 | 617 | CONFIG_DRM_SII902X=m |
| 616 | 618 | CONFIG_DRM_THINE_THC63LVD1024=m |
| 617 | 619 | CONFIG_DRM_TI_SN65DSI86=m |
| @@ -848,7 +850,8 @@ CONFIG_QCOM_APR=m · 230 unmodified lines | ||
| 848 | 850 | CONFIG_ARCH_R8A774A1=y |
| 849 | 851 | CONFIG_ARCH_R8A774B1=y |
| 850 | 852 | CONFIG_ARCH_R8A774C0=y |
| 851 | −CONFIG_ARCH_R8A7795=y | |
| 853 | +CONFIG_ARCH_R8A77950=y | |
| 854 | +CONFIG_ARCH_R8A77951=y | |
| 852 | 855 | CONFIG_ARCH_R8A77960=y |
| 853 | 856 | CONFIG_ARCH_R8A77961=y |
| 854 | 857 | CONFIG_ARCH_R8A77965=y |
| @@ -304,7 +304,7 @@ do { \ · 303 unmodified lines | ||
| 304 | 304 | __p = uaccess_mask_ptr(__p); \ |
| 305 | 305 | __raw_get_user((x), __p, (err)); \ |
| 306 | 306 | } else { \ |
| 307 | − (x) = 0; (err) = -EFAULT; \ | |
| 307 | + (x) = (__force __typeof__(x))0; (err) = -EFAULT; \ | |
| 308 | 308 | } \ |
| 309 | 309 | } while (0) |
| 310 | 310 | |
| @@ -177,6 +177,7 @@ void machine_kexec(struct kimage *kimage) · 176 unmodified lines | ||
| 177 | 177 | * the offline CPUs. Therefore, we must use the __* variant here. |
| 178 | 178 | */ |
| 179 | 179 | __flush_icache_range((uintptr_t)reboot_code_buffer, |
| 180 | + (uintptr_t)reboot_code_buffer + | |
| 180 | 181 | arm64_relocate_new_kernel_size); |
| 181 | 182 | |
| 182 | 183 | /* Flush the kimage list and its buffers. */ |
| @@ -1829,10 +1829,11 @@ static void tracehook_report_syscall(struct pt_regs *regs, · 1828 unmodified lines | ||
| 1829 | 1829 | |
| 1830 | 1830 | int syscall_trace_enter(struct pt_regs *regs) |
| 1831 | 1831 | { |
| 1832 | − if (test_thread_flag(TIF_SYSCALL_TRACE) || | |
| 1833 | − test_thread_flag(TIF_SYSCALL_EMU)) { | |
| 1832 | + unsigned long flags = READ_ONCE(current_thread_info()->flags); | |
| 1833 | + | |
| 1834 | + if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { | |
| 1834 | 1835 | tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); |
| 1835 | − if (!in_syscall(regs) || test_thread_flag(TIF_SYSCALL_EMU)) | |
| 1836 | + if (!in_syscall(regs) || (flags & _TIF_SYSCALL_EMU)) | |
| 1836 | 1837 | return -1; |
| 1837 | 1838 | } |
| 1838 | 1839 | |
| @@ -8,6 +8,7 @@ config CSKY · 7 unmodified lines | ||
| 8 | 8 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE |
| 9 | 9 | select ARCH_USE_BUILTIN_BSWAP |
| 10 | 10 | select ARCH_USE_QUEUED_RWLOCKS if NR_CPUS>2 |
| 11 | + select ARCH_WANT_FRAME_POINTERS if !CPU_CK610 | |
| 11 | 12 | select COMMON_CLK |
| 12 | 13 | select CLKSRC_MMIO |
| 13 | 14 | select CSKY_MPINTC if CPU_CK860 |
| @@ -38,6 +39,7 @@ config CSKY · 24 unmodified lines | ||
| 38 | 39 | select HAVE_ARCH_TRACEHOOK |
| 39 | 40 | select HAVE_ARCH_AUDITSYSCALL |
| 40 | 41 | select HAVE_COPY_THREAD_TLS |
| 42 | + select HAVE_DEBUG_BUGVERBOSE | |
| 41 | 43 | select HAVE_DYNAMIC_FTRACE |
| 42 | 44 | select HAVE_DYNAMIC_FTRACE_WITH_REGS |
| 43 | 45 | select HAVE_FUNCTION_TRACER |
| @@ -47,7 +47,7 @@ ifeq ($(CSKYABI),abiv2) · 46 unmodified lines | ||
| 47 | 47 | KBUILD_CFLAGS += -mno-stack-size |
| 48 | 48 | endif |
| 49 | 49 | |
| 50 | −ifdef CONFIG_STACKTRACE | |
| 50 | +ifdef CONFIG_FRAME_POINTER | |
| 51 | 51 | KBUILD_CFLAGS += -mbacktrace |
| 52 | 52 | endif |
| 53 | 53 | |
| @@ -167,8 +167,8 @@ · 166 unmodified lines | ||
| 167 | 167 | * BA Reserved C D V |
| 168 | 168 | */ |
| 169 | 169 | cprcr r6, cpcr30 |
| 170 | − lsri r6, 28 | |
| 171 | − lsli r6, 28 | |
| 170 | + lsri r6, 29 | |
| 171 | + lsli r6, 29 | |
| 172 | 172 | addi r6, 0xe |
| 173 | 173 | cpwcr r6, cpcr30 |
| 174 | 174 | |
| @@ -285,8 +285,8 @@ · 284 unmodified lines | ||
| 285 | 285 | */ |
| 286 | 286 | mfcr r6, cr<30, 15> /* Get MSA0 */ |
| 287 | 287 | 2: |
| 288 | − lsri r6, 28 | |
| 289 | − lsli r6, 28 | |
| 288 | + lsri r6, 29 | |
| 289 | + lsli r6, 29 | |
| 290 | 290 | addi r6, 0x1ce |
| 291 | 291 | mtcr r6, cr<30, 15> /* Set MSA0 */ |
| 292 | 292 | |
| @@ -103,6 +103,8 @@ ENTRY(_mcount) · 102 unmodified lines | ||
| 103 | 103 | mov a0, lr |
| 104 | 104 | subi a0, 4 |
| 105 | 105 | ldw a1, (sp, 24) |
| 106 | + lrw a2, function_trace_op | |
| 107 | + ldw a2, (a2, 0) | |
| 106 | 108 | |
| 107 | 109 | jsr r26 |
| 108 | 110 | |
| @@ -41,8 +41,7 @@ extern struct cpuinfo_csky cpu_data[]; · 40 unmodified lines | ||
| 41 | 41 | #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) |
| 42 | 42 | |
| 43 | 43 | struct thread_struct { |
| 44 | − unsigned long ksp; /* kernel stack pointer */ | |
| 45 | − unsigned long sr; /* saved status register */ | |
| 44 | + unsigned long sp; /* kernel stack pointer */ | |
| 46 | 45 | unsigned long trap_no; /* saved status register */ |
| 47 | 46 | |
| 48 | 47 | /* FPU regs */ |
| @@ -50,8 +49,7 @@ struct thread_struct { · 1 unmodified line | ||
| 50 | 49 | }; |
| 51 | 50 | |
| 52 | 51 | #define INIT_THREAD { \ |
| 53 | − .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ | |
| 54 | − .sr = DEFAULT_PSR_VALUE, \ | |
| 52 | + .sp = sizeof(init_stack) + (unsigned long) &init_stack, \ | |
| 55 | 53 | } |
| 56 | 54 | |
| 57 | 55 | /* |
| @@ -58,6 +58,16 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) · 57 unmodified lines | ||
| 58 | 58 | return regs->usp; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | +static inline unsigned long frame_pointer(struct pt_regs *regs) | |
| 62 | +{ | |
| 63 | + return regs->regs[4]; | |
| 64 | +} | |
| 65 | +static inline void frame_pointer_set(struct pt_regs *regs, | |
| 66 | + unsigned long val) | |
| 67 | +{ | |
| 68 | + regs->regs[4] = val; | |
| 69 | +} | |
| 70 | + | |
| 61 | 71 | extern int regs_query_register_offset(const char *name); |
| 62 | 72 | extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, |
| 63 | 73 | unsigned int n); |
| @@ -38,7 +38,13 @@ struct thread_info { · 37 unmodified lines | ||
| 38 | 38 | #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) |
| 39 | 39 | |
| 40 | 40 | #define thread_saved_fp(tsk) \ |
| 41 | − ((unsigned long)(((struct switch_stack *)(tsk->thread.ksp))->r8)) | |
| 41 | + ((unsigned long)(((struct switch_stack *)(tsk->thread.sp))->r8)) | |
| 42 | + | |
| 43 | +#define thread_saved_sp(tsk) \ | |
| 44 | + ((unsigned long)(tsk->thread.sp)) | |
| 45 | + | |
| 46 | +#define thread_saved_lr(tsk) \ | |
| 47 | + ((unsigned long)(((struct switch_stack *)(tsk->thread.sp))->r15)) | |
| 42 | 48 | |
| 43 | 49 | static inline struct thread_info *current_thread_info(void) |
| 44 | 50 | { |
| @@ -54,10 +60,10 @@ static inline struct thread_info *current_thread_info(void) · 9 unmodified lines | ||
| 54 | 60 | #define TIF_SIGPENDING 0 /* signal pending */ |
| 55 | 61 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ |
| 56 | 62 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ |
| 57 | −#define TIF_SYSCALL_TRACE 3 /* syscall trace active */ | |
| 58 | −#define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */ | |
| 59 | −#define TIF_SYSCALL_AUDIT 5 /* syscall auditing */ | |
| 60 | −#define TIF_UPROBE 6 /* uprobe breakpoint or singlestep */ | |
| 63 | +#define TIF_UPROBE 3 /* uprobe breakpoint or singlestep */ | |
| 64 | +#define TIF_SYSCALL_TRACE 4 /* syscall trace active */ | |
| 65 | +#define TIF_SYSCALL_TRACEPOINT 5 /* syscall tracepoint instrumentation */ | |
| 66 | +#define TIF_SYSCALL_AUDIT 6 /* syscall auditing */ | |
| 61 | 67 | #define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */ |
| 62 | 68 | #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ |
| 63 | 69 | #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ |
| @@ -253,7 +253,7 @@ do { \ · 252 unmodified lines | ||
| 253 | 253 | |
| 254 | 254 | extern int __get_user_bad(void); |
| 255 | 255 | |
| 256 | −#define __copy_user(to, from, n) \ | |
| 256 | +#define ___copy_to_user(to, from, n) \ | |
| 257 | 257 | do { \ |
| 258 | 258 | int w0, w1, w2, w3; \ |
| 259 | 259 | asm volatile( \ |
| @@ -288,31 +288,34 @@ do { \ · 28 unmodified lines | ||
| 288 | 288 | " subi %0, 4 \n" \ |
| 289 | 289 | " br 3b \n" \ |
| 290 | 290 | "5: cmpnei %0, 0 \n" /* 1B */ \ |
| 291 | − " bf 8f \n" \ | |
| 291 | + " bf 13f \n" \ | |
| 292 | 292 | " ldb %3, (%2, 0) \n" \ |
| 293 | 293 | "6: stb %3, (%1, 0) \n" \ |
| 294 | 294 | " addi %2, 1 \n" \ |
| 295 | 295 | " addi %1, 1 \n" \ |
| 296 | 296 | " subi %0, 1 \n" \ |
| 297 | 297 | " br 5b \n" \ |
| 298 | − "7: br 8f \n" \ | |
| 298 | + "7: subi %0, 4 \n" \ | |
| 299 | + "8: subi %0, 4 \n" \ | |
| 300 | + "12: subi %0, 4 \n" \ | |
| 301 | + " br 13f \n" \ | |
| 299 | 302 | ".section __ex_table, \"a\" \n" \ |
| 300 | 303 | ".align 2 \n" \ |
| 301 | − ".long 2b, 7b \n" \ | |
| 302 | − ".long 9b, 7b \n" \ | |
| 303 | − ".long 10b, 7b \n" \ | |
| 304 | + ".long 2b, 13f \n" \ | |
| 305 | + ".long 4b, 13f \n" \ | |
| 306 | + ".long 6b, 13f \n" \ | |
| 307 | + ".long 9b, 12b \n" \ | |
| 308 | + ".long 10b, 8b \n" \ | |
| 304 | 309 | ".long 11b, 7b \n" \ |
| 305 | − ".long 4b, 7b \n" \ | |
| 306 | − ".long 6b, 7b \n" \ | |
| 307 | 310 | ".previous \n" \ |
| 308 | − "8: \n" \ | |
| 311 | + "13: \n" \ | |
| 309 | 312 | : "=r"(n), "=r"(to), "=r"(from), "=r"(w0), \ |
| 310 | 313 | "=r"(w1), "=r"(w2), "=r"(w3) \ |
| 311 | 314 | : "0"(n), "1"(to), "2"(from) \ |
| 312 | 315 | : "memory"); \ |
| 313 | 316 | } while (0) |
| 314 | 317 | |
| 315 | −#define __copy_user_zeroing(to, from, n) \ | |
| 318 | +#define ___copy_from_user(to, from, n) \ | |
| 316 | 319 | do { \ |
| 317 | 320 | int tmp; \ |
| 318 | 321 | int nsave; \ |
| @@ -355,22 +358,22 @@ do { \ · 36 unmodified lines | ||
| 355 | 358 | " addi %1, 1 \n" \ |
| 356 | 359 | " subi %0, 1 \n" \ |
| 357 | 360 | " br 5b \n" \ |
| 358 | − "8: mov %3, %0 \n" \ | |
| 359 | − " movi %4, 0 \n" \ | |
| 360 | − "9: stb %4, (%1, 0) \n" \ | |
| 361 | − " addi %1, 1 \n" \ | |
| 362 | − " subi %3, 1 \n" \ | |
| 363 | − " cmpnei %3, 0 \n" \ | |
| 364 | − " bt 9b \n" \ | |
| 365 | − " br 7f \n" \ | |
| 361 | + "8: stw %3, (%1, 0) \n" \ | |
| 362 | + " subi %0, 4 \n" \ | |
| 363 | + " bf 7f \n" \ | |
| 364 | + "9: subi %0, 8 \n" \ | |
| 365 | + " bf 7f \n" \ | |
| 366 | + "13: stw %3, (%1, 8) \n" \ | |
| 367 | + " subi %0, 12 \n" \ | |
| 368 | + " bf 7f \n" \ | |
| 366 | 369 | ".section __ex_table, \"a\" \n" \ |
| 367 | 370 | ".align 2 \n" \ |
| 368 | − ".long 2b, 8b \n" \ | |
| 371 | + ".long 2b, 7f \n" \ | |
| 372 | + ".long 4b, 7f \n" \ | |
| 373 | + ".long 6b, 7f \n" \ | |
| 369 | 374 | ".long 10b, 8b \n" \ |
| 370 | − ".long 11b, 8b \n" \ | |
| 371 | − ".long 12b, 8b \n" \ | |
| 372 | − ".long 4b, 8b \n" \ | |
| 373 | − ".long 6b, 8b \n" \ | |
| 375 | + ".long 11b, 9b \n" \ | |
| 376 | + ".long 12b,13b \n" \ | |
| 374 | 377 | ".previous \n" \ |
| 375 | 378 | "7: \n" \ |
| 376 | 379 | : "=r"(n), "=r"(to), "=r"(from), "=r"(nsave), \ |
| @@ -3,7 +3,7 @@ extra-y := head.o vmlinux.lds · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | obj-y += entry.o atomic.o signal.o traps.o irq.o time.o vdso.o |
| 5 | 5 | obj-y += power.o syscall.o syscall_table.o setup.o |
| 6 | −obj-y += process.o cpu-probe.o ptrace.o dumpstack.o | |
| 6 | +obj-y += process.o cpu-probe.o ptrace.o stacktrace.o | |
| 7 | 7 | obj-y += probes/ |
| 8 | 8 | |
| 9 | 9 | obj-$(CONFIG_MODULES) += module.o |
| @@ -18,8 +18,7 @@ int main(void) · 17 unmodified lines | ||
| 18 | 18 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); |
| 19 | 19 | |
| 20 | 20 | /* offsets into the thread struct */ |
| 21 | − DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); | |
| 22 | − DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); | |
| 21 | + DEFINE(THREAD_KSP, offsetof(struct thread_struct, sp)); | |
| 23 | 22 | DEFINE(THREAD_FESR, offsetof(struct thread_struct, user_fp.fesr)); |
| 24 | 23 | DEFINE(THREAD_FCR, offsetof(struct thread_struct, user_fp.fcr)); |
| 25 | 24 | DEFINE(THREAD_FPREG, offsetof(struct thread_struct, user_fp.vr)); |
| @@ -1,49 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 2 | −// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. | |
| 3 | − | |
| 4 | −#include <linux/ptrace.h> | |
| 5 | − | |
| 6 | −int kstack_depth_to_print = 48; | |
| 7 | − | |
| 8 | −void show_trace(unsigned long *stack) | |
| 9 | −{ | |
| 10 | − unsigned long *stack_end; | |
| 11 | − unsigned long *stack_start; | |
| 12 | − unsigned long *fp; | |
| 13 | − unsigned long addr; | |
| 14 | − | |
| 15 | − addr = (unsigned long) stack & THREAD_MASK; | |
| 16 | − stack_start = (unsigned long *) addr; | |
| 17 | − stack_end = (unsigned long *) (addr + THREAD_SIZE); | |
| 18 | − | |
| 19 | − fp = stack; | |
| 20 | − pr_info("\nCall Trace:"); | |
| 21 | − | |
| 22 | − while (fp > stack_start && fp < stack_end) { | |
| 23 | −#ifdef CONFIG_STACKTRACE | |
| 24 | − addr = fp[1]; | |
| 25 | − fp = (unsigned long *) fp[0]; | |
| 26 | −#else | |
| 27 | − addr = *fp++; | |
| 28 | −#endif | |
| 29 | − if (__kernel_text_address(addr)) | |
| 30 | − pr_cont("\n[<%08lx>] %pS", addr, (void *)addr); | |
| 31 | − } | |
| 32 | − pr_cont("\n"); | |
| 33 | −} | |
| 34 | − | |
| 35 | −void show_stack(struct task_struct *task, unsigned long *stack) | |
| 36 | −{ | |
| 37 | − if (!stack) { | |
| 38 | − if (task) | |
| 39 | − stack = (unsigned long *)thread_saved_fp(task); | |
| 40 | − else | |
| 41 | −#ifdef CONFIG_STACKTRACE | |
| 42 | − asm volatile("mov %0, r8\n":"=r"(stack)::"memory"); | |
| 43 | −#else | |
| 44 | − stack = (unsigned long *)&stack; | |
| 45 | −#endif | |
| 46 | − } | |
| 47 | − | |
| 48 | − show_trace(stack); | |
| 49 | −} | |
| @@ -330,11 +330,6 @@ ENTRY(__switch_to) · 329 unmodified lines | ||
| 330 | 330 | lrw a3, TASK_THREAD |
| 331 | 331 | addu a3, a0 |
| 332 | 332 | |
| 333 | − mfcr a2, psr /* Save PSR value */ | |
| 334 | − stw a2, (a3, THREAD_SR) /* Save PSR in task struct */ | |
| 335 | − bclri a2, 6 /* Disable interrupts */ | |
| 336 | − mtcr a2, psr | |
| 337 | − | |
| 338 | 333 | SAVE_SWITCH_STACK |
| 339 | 334 | |
| 340 | 335 | stw sp, (a3, THREAD_KSP) |
| @@ -345,12 +340,9 @@ ENTRY(__switch_to) · 4 unmodified lines | ||
| 345 | 340 | |
| 346 | 341 | ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */ |
| 347 | 342 | |
| 348 | − ldw a2, (a3, THREAD_SR) /* Set next PSR */ | |
| 349 | − mtcr a2, psr | |
| 350 | − | |
| 351 | 343 | #if defined(__CSKYABIV2__) |
| 352 | − addi r7, a1, TASK_THREAD_INFO | |
| 353 | − ldw tls, (r7, TINFO_TP_VALUE) | |
| 344 | + addi a3, a1, TASK_THREAD_INFO | |
| 345 | + ldw tls, (a3, TINFO_TP_VALUE) | |
| 354 | 346 | #endif |
| 355 | 347 | |
| 356 | 348 | RESTORE_SWITCH_STACK |
| @@ -202,6 +202,7 @@ int ftrace_disable_ftrace_graph_caller(void) · 201 unmodified lines | ||
| 202 | 202 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 203 | 203 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
| 204 | 204 | |
| 205 | +#ifdef CONFIG_DYNAMIC_FTRACE | |
| 205 | 206 | #ifndef CONFIG_CPU_HAS_ICACHE_INS |
| 206 | 207 | struct ftrace_modify_param { |
| 207 | 208 | int command; |
| @@ -231,6 +232,7 @@ void arch_ftrace_update_code(int command) · 23 unmodified lines | ||
| 231 | 232 | stop_machine(__ftrace_modify_code, ¶m, cpu_online_mask); |
| 232 | 233 | } |
| 233 | 234 | #endif |
| 235 | +#endif /* CONFIG_DYNAMIC_FTRACE */ | |
| 234 | 236 | |
| 235 | 237 | /* _mcount is defined in abi's mcount.S */ |
| 236 | 238 | EXPORT_SYMBOL(_mcount); |
| @@ -12,12 +12,17 @@ struct stackframe { · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | static int unwind_frame_kernel(struct stackframe *frame) |
| 14 | 14 | { |
| 15 | − if (kstack_end((void *)frame->fp)) | |
| 15 | + unsigned long low = (unsigned long)task_stack_page(current); | |
| 16 | + unsigned long high = low + THREAD_SIZE; | |
| 17 | + | |
| 18 | + if (unlikely(frame->fp < low || frame->fp > high)) | |
| 16 | 19 | return -EPERM; |
| 17 | − if (frame->fp & 0x3 || frame->fp < TASK_SIZE) | |
| 20 | + | |
| 21 | + if (kstack_end((void *)frame->fp) || frame->fp & 0x3) | |
| 18 | 22 | return -EPERM; |
| 19 | 23 | |
| 20 | 24 | *frame = *(struct stackframe *)frame->fp; |
| 25 | + | |
| 21 | 26 | if (__kernel_text_address(frame->lr)) { |
| 22 | 27 | int graph = 0; |
| 23 | 28 | |
| @@ -11,6 +11,11 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #define UPROBE_TRAP_NR UINT_MAX |
| 13 | 13 | |
| 14 | +bool is_swbp_insn(uprobe_opcode_t *insn) | |
| 15 | +{ | |
| 16 | + return (*insn & 0xffff) == UPROBE_SWBP_INSN; | |
| 17 | +} | |
| 18 | + | |
| 14 | 19 | unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) |
| 15 | 20 | { |
| 16 | 21 | return instruction_pointer(regs); |
| @@ -35,7 +35,7 @@ void flush_thread(void){} · 34 unmodified lines | ||
| 35 | 35 | */ |
| 36 | 36 | unsigned long thread_saved_pc(struct task_struct *tsk) |
| 37 | 37 | { |
| 38 | − struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; | |
| 38 | + struct switch_stack *sw = (struct switch_stack *)tsk->thread.sp; | |
| 39 | 39 | |
| 40 | 40 | return sw->r15; |
| 41 | 41 | } |
| @@ -56,8 +56,8 @@ int copy_thread_tls(unsigned long clone_flags, · 14 unmodified lines | ||
| 56 | 56 | childstack = ((struct switch_stack *) childregs) - 1; |
| 57 | 57 | memset(childstack, 0, sizeof(struct switch_stack)); |
| 58 | 58 | |
| 59 | − /* setup ksp for switch_to !!! */ | |
| 60 | − p->thread.ksp = (unsigned long)childstack; | |
| 59 | + /* setup thread.sp for switch_to !!! */ | |
| 60 | + p->thread.sp = (unsigned long)childstack; | |
| 61 | 61 | |
| 62 | 62 | if (unlikely(p->flags & PF_KTHREAD)) { |
| 63 | 63 | memset(childregs, 0, sizeof(struct pt_regs)); |
| @@ -98,37 +98,6 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs) · 34 unmodified lines | ||
| 98 | 98 | return 1; |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | −unsigned long get_wchan(struct task_struct *p) | |
| 102 | −{ | |
| 103 | − unsigned long lr; | |
| 104 | − unsigned long *fp, *stack_start, *stack_end; | |
| 105 | − int count = 0; | |
| 106 | − | |
| 107 | − if (!p || p == current || p->state == TASK_RUNNING) | |
| 108 | − return 0; | |
| 109 | − | |
| 110 | − stack_start = (unsigned long *)end_of_stack(p); | |
| 111 | − stack_end = (unsigned long *)(task_stack_page(p) + THREAD_SIZE); | |
| 112 | − | |
| 113 | − fp = (unsigned long *) thread_saved_fp(p); | |
| 114 | − do { | |
| 115 | − if (fp < stack_start || fp > stack_end) | |
| 116 | − return 0; | |
| 117 | −#ifdef CONFIG_STACKTRACE | |
| 118 | − lr = fp[1]; | |
| 119 | − fp = (unsigned long *)fp[0]; | |
| 120 | −#else | |
| 121 | − lr = *fp++; | |
| 122 | −#endif | |
| 123 | − if (!in_sched_functions(lr) && | |
| 124 | − __kernel_text_address(lr)) | |
| 125 | − return lr; | |
| 126 | − } while (count++ < 16); | |
| 127 | − | |
| 128 | − return 0; | |
| 129 | −} | |
| 130 | −EXPORT_SYMBOL(get_wchan); | |
| 131 | − | |
| 132 | 101 | #ifndef CONFIG_CPU_PM_NONE |
| 133 | 102 | void arch_cpu_idle(void) |
| 134 | 103 | { |
| @@ -41,6 +41,9 @@ static void singlestep_disable(struct task_struct *tsk) · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | regs = task_pt_regs(tsk); |
| 43 | 43 | regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_RUN; |
| 44 | + | |
| 45 | + /* Enable irq */ | |
| 46 | + regs->sr |= BIT(6); | |
| 44 | 47 | } |
| 45 | 48 | |
| 46 | 49 | static void singlestep_enable(struct task_struct *tsk) |
| @@ -49,6 +52,9 @@ static void singlestep_enable(struct task_struct *tsk) · 2 unmodified lines | ||
| 49 | 52 | |
| 50 | 53 | regs = task_pt_regs(tsk); |
| 51 | 54 | regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_SI; |
| 55 | + | |
| 56 | + /* Disable irq */ | |
| 57 | + regs->sr &= ~BIT(6); | |
| 52 | 58 | } |
| 53 | 59 | |
| 54 | 60 | /* |
| @@ -1,57 +1,159 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | −/* Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. */ | |
| 3 | 2 | |
| 4 | 3 | #include <linux/sched/debug.h> |
| 5 | 4 | #include <linux/sched/task_stack.h> |
| 6 | 5 | #include <linux/stacktrace.h> |
| 7 | 6 | #include <linux/ftrace.h> |
| 7 | +#include <linux/ptrace.h> | |
| 8 | 8 | |
| 9 | −void save_stack_trace(struct stack_trace *trace) | |
| 9 | +#ifdef CONFIG_FRAME_POINTER | |
| 10 | + | |
| 11 | +struct stackframe { | |
| 12 | + unsigned long fp; | |
| 13 | + unsigned long ra; | |
| 14 | +}; | |
| 15 | + | |
| 16 | +void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, | |
| 17 | + bool (*fn)(unsigned long, void *), void *arg) | |
| 10 | 18 | { |
| 11 | − save_stack_trace_tsk(current, trace); | |
| 19 | + unsigned long fp, sp, pc; | |
| 20 | + | |
| 21 | + if (regs) { | |
| 22 | + fp = frame_pointer(regs); | |
| 23 | + sp = user_stack_pointer(regs); | |
| 24 | + pc = instruction_pointer(regs); | |
| 25 | + } else if (task == NULL || task == current) { | |
| 26 | + const register unsigned long current_sp __asm__ ("sp"); | |
| 27 | + const register unsigned long current_fp __asm__ ("r8"); | |
| 28 | + fp = current_fp; | |
| 29 | + sp = current_sp; | |
| 30 | + pc = (unsigned long)walk_stackframe; | |
| 31 | + } else { | |
| 32 | + /* task blocked in __switch_to */ | |
| 33 | + fp = thread_saved_fp(task); | |
| 34 | + sp = thread_saved_sp(task); | |
| 35 | + pc = thread_saved_lr(task); | |
| 36 | + } | |
| 37 | + | |
| 38 | + for (;;) { | |
| 39 | + unsigned long low, high; | |
| 40 | + struct stackframe *frame; | |
| 41 | + | |
| 42 | + if (unlikely(!__kernel_text_address(pc) || fn(pc, arg))) | |
| 43 | + break; | |
| 44 | + | |
| 45 | + /* Validate frame pointer */ | |
| 46 | + low = sp; | |
| 47 | + high = ALIGN(sp, THREAD_SIZE); | |
| 48 | + if (unlikely(fp < low || fp > high || fp & 0x3)) | |
| 49 | + break; | |
| 50 | + /* Unwind stack frame */ | |
| 51 | + frame = (struct stackframe *)fp; | |
| 52 | + sp = fp; | |
| 53 | + fp = frame->fp; | |
| 54 | + pc = ftrace_graph_ret_addr(current, NULL, frame->ra, | |
| 55 | + (unsigned long *)(fp - 8)); | |
| 56 | + } | |
| 12 | 57 | } |
| 13 | −EXPORT_SYMBOL_GPL(save_stack_trace); | |
| 14 | 58 | |
| 15 | −void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | |
| 59 | +#else /* !CONFIG_FRAME_POINTER */ | |
| 60 | + | |
| 61 | +static void notrace walk_stackframe(struct task_struct *task, | |
| 62 | + struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) | |
| 16 | 63 | { |
| 17 | − unsigned long *fp, *stack_start, *stack_end; | |
| 18 | − unsigned long addr; | |
| 19 | − int skip = trace->skip; | |
| 20 | − int savesched; | |
| 21 | − int graph_idx = 0; | |
| 64 | + unsigned long sp, pc; | |
| 65 | + unsigned long *ksp; | |
| 22 | 66 | |
| 23 | − if (tsk == current) { | |
| 24 | − asm volatile("mov %0, r8\n":"=r"(fp)); | |
| 25 | − savesched = 1; | |
| 67 | + if (regs) { | |
| 68 | + sp = user_stack_pointer(regs); | |
| 69 | + pc = instruction_pointer(regs); | |
| 70 | + } else if (task == NULL || task == current) { | |
| 71 | + const register unsigned long current_sp __asm__ ("sp"); | |
| 72 | + sp = current_sp; | |
| 73 | + pc = (unsigned long)walk_stackframe; | |
| 26 | 74 | } else { |
| 27 | − fp = (unsigned long *)thread_saved_fp(tsk); | |
| 28 | − savesched = 0; | |
| 75 | + /* task blocked in __switch_to */ | |
| 76 | + sp = thread_saved_sp(task); | |
| 77 | + pc = thread_saved_lr(task); | |
| 29 | 78 | } |
| 30 | 79 | |
| 31 | − addr = (unsigned long) fp & THREAD_MASK; | |
| 32 | − stack_start = (unsigned long *) addr; | |
| 33 | − stack_end = (unsigned long *) (addr + THREAD_SIZE); | |
| 34 | − | |
| 35 | − while (fp > stack_start && fp < stack_end) { | |
| 36 | − unsigned long lpp, fpp; | |
| 80 | + if (unlikely(sp & 0x3)) | |
| 81 | + return; | |
| 37 | 82 | |
| 38 | − fpp = fp[0]; | |
| 39 | − lpp = fp[1]; | |
| 40 | − if (!__kernel_text_address(lpp)) | |
| 83 | + ksp = (unsigned long *)sp; | |
| 84 | + while (!kstack_end(ksp)) { | |
| 85 | + if (__kernel_text_address(pc) && unlikely(fn(pc, arg))) | |
| 41 | 86 | break; |
| 42 | − else | |
| 43 | − lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL); | |
| 44 | − | |
| 45 | − if (savesched || !in_sched_functions(lpp)) { | |
| 46 | − if (skip) { | |
| 47 | − skip--; | |
| 48 | − } else { | |
| 49 | − trace->entries[trace->nr_entries++] = lpp; | |
| 50 | − if (trace->nr_entries >= trace->max_entries) | |
| 51 | − break; | |
| 52 | − } | |
| 53 | − } | |
| 54 | − fp = (unsigned long *)fpp; | |
| 87 | + pc = (*ksp++) - 0x4; | |
| 55 | 88 | } |
| 56 | 89 | } |
| 90 | +#endif /* CONFIG_FRAME_POINTER */ | |
| 91 | + | |
| 92 | +static bool print_trace_address(unsigned long pc, void *arg) | |
| 93 | +{ | |
| 94 | + print_ip_sym(pc); | |
| 95 | + return false; | |
| 96 | +} | |
| 97 | + | |
| 98 | +void show_stack(struct task_struct *task, unsigned long *sp) | |
| 99 | +{ | |
| 100 | + pr_cont("Call Trace:\n"); | |
| 101 | + walk_stackframe(task, NULL, print_trace_address, NULL); | |
| 102 | +} | |
| 103 | + | |
| 104 | +static bool save_wchan(unsigned long pc, void *arg) | |
| 105 | +{ | |
| 106 | + if (!in_sched_functions(pc)) { | |
| 107 | + unsigned long *p = arg; | |
| 108 | + *p = pc; | |
| 109 | + return true; | |
| 110 | + } | |
| 111 | + return false; | |
| 112 | +} | |
| 113 | + | |
| 114 | +unsigned long get_wchan(struct task_struct *task) | |
| 115 | +{ | |
| 116 | + unsigned long pc = 0; | |
| 117 | + | |
| 118 | + if (likely(task && task != current && task->state != TASK_RUNNING)) | |
| 119 | + walk_stackframe(task, NULL, save_wchan, &pc); | |
| 120 | + return pc; | |
| 121 | +} | |
| 122 | + | |
| 123 | +#ifdef CONFIG_STACKTRACE | |
| 124 | +static bool __save_trace(unsigned long pc, void *arg, bool nosched) | |
| 125 | +{ | |
| 126 | + struct stack_trace *trace = arg; | |
| 127 | + | |
| 128 | + if (unlikely(nosched && in_sched_functions(pc))) | |
| 129 | + return false; | |
| 130 | + if (unlikely(trace->skip > 0)) { | |
| 131 | + trace->skip--; | |
| 132 | + return false; | |
| 133 | + } | |
| 134 | + | |
| 135 | + trace->entries[trace->nr_entries++] = pc; | |
| 136 | + return (trace->nr_entries >= trace->max_entries); | |
| 137 | +} | |
| 138 | + | |
| 139 | +static bool save_trace(unsigned long pc, void *arg) | |
| 140 | +{ | |
| 141 | + return __save_trace(pc, arg, false); | |
| 142 | +} | |
| 143 | + | |
| 144 | +/* | |
| 145 | + * Save stack-backtrace addresses into a stack_trace buffer. | |
| 146 | + */ | |
| 147 | +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | |
| 148 | +{ | |
| 149 | + walk_stackframe(tsk, NULL, save_trace, trace); | |
| 150 | +} | |
| 57 | 151 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); |
| 152 | + | |
| 153 | +void save_stack_trace(struct stack_trace *trace) | |
| 154 | +{ | |
| 155 | + save_stack_trace_tsk(NULL, trace); | |
| 156 | +} | |
| 157 | +EXPORT_SYMBOL_GPL(save_stack_trace); | |
| 158 | + | |
| 159 | +#endif /* CONFIG_STACKTRACE */ | |
| @@ -7,10 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | unsigned long raw_copy_from_user(void *to, const void *from, |
| 8 | 8 | unsigned long n) |
| 9 | 9 | { |
| 10 | − if (access_ok(from, n)) | |
| 11 | − __copy_user_zeroing(to, from, n); | |
| 12 | − else | |
| 13 | − memset(to, 0, n); | |
| 10 | + ___copy_from_user(to, from, n); | |
| 14 | 11 | return n; |
| 15 | 12 | } |
| 16 | 13 | EXPORT_SYMBOL(raw_copy_from_user); |
| @@ -18,8 +15,7 @@ EXPORT_SYMBOL(raw_copy_from_user); · 1 unmodified line | ||
| 18 | 15 | unsigned long raw_copy_to_user(void *to, const void *from, |
| 19 | 16 | unsigned long n) |
| 20 | 17 | { |
| 21 | − if (access_ok(to, n)) | |
| 22 | − __copy_user(to, from, n); | |
| 18 | + ___copy_to_user(to, from, n); | |
| 23 | 19 | return n; |
| 24 | 20 | } |
| 25 | 21 | EXPORT_SYMBOL(raw_copy_to_user); |
| @@ -130,7 +130,7 @@ config PPC · 129 unmodified lines | ||
| 130 | 130 | select ARCH_HAS_PTE_SPECIAL |
| 131 | 131 | select ARCH_HAS_MEMBARRIER_CALLBACKS |
| 132 | 132 | select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 |
| 133 | − select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) | |
| 133 | + select ARCH_HAS_STRICT_KERNEL_RWX if (PPC32 && !HIBERNATION) | |
| 134 | 134 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
| 135 | 135 | select ARCH_HAS_UACCESS_FLUSHCACHE |
| 136 | 136 | select ARCH_HAS_UACCESS_MCSAFE if PPC64 |
| @@ -17,9 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | * updating the accessed and modified bits in the page table tree. |
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | −#define _PAGE_USER 0x001 /* usermode access allowed */ | |
| 21 | −#define _PAGE_RW 0x002 /* software: user write access allowed */ | |
| 22 | −#define _PAGE_PRESENT 0x004 /* software: pte contains a translation */ | |
| 20 | +#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ | |
| 21 | +#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */ | |
| 22 | +#define _PAGE_USER 0x004 /* usermode access allowed */ | |
| 23 | 23 | #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ |
| 24 | 24 | #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ |
| 25 | 25 | #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */ |
| @@ -27,7 +27,7 @@ · 1 unmodified line | ||
| 27 | 27 | #define _PAGE_DIRTY 0x080 /* C: page changed */ |
| 28 | 28 | #define _PAGE_ACCESSED 0x100 /* R: page referenced */ |
| 29 | 29 | #define _PAGE_EXEC 0x200 /* software: exec allowed */ |
| 30 | −#define _PAGE_HASHPTE 0x400 /* hash_page has made an HPTE for this pte */ | |
| 30 | +#define _PAGE_RW 0x400 /* software: user write access allowed */ | |
| 31 | 31 | #define _PAGE_SPECIAL 0x800 /* software: Special page */ |
| 32 | 32 | |
| 33 | 33 | #ifdef CONFIG_PTE_64BIT |
| @@ -75,7 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | .macro kuap_check current, gpr |
| 77 | 77 | #ifdef CONFIG_PPC_KUAP_DEBUG |
| 78 | − lwz \gpr2, KUAP(thread) | |
| 78 | + lwz \gpr, KUAP(thread) | |
| 79 | 79 | 999: twnei \gpr, 0 |
| 80 | 80 | EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) |
| 81 | 81 | #endif |
| @@ -250,9 +250,27 @@ static inline bool arch_irqs_disabled(void) · 249 unmodified lines | ||
| 250 | 250 | } \ |
| 251 | 251 | } while(0) |
| 252 | 252 | |
| 253 | +static inline bool __lazy_irq_pending(u8 irq_happened) | |
| 254 | +{ | |
| 255 | + return !!(irq_happened & ~PACA_IRQ_HARD_DIS); | |
| 256 | +} | |
| 257 | + | |
| 258 | +/* | |
| 259 | + * Check if a lazy IRQ is pending. Should be called with IRQs hard disabled. | |
| 260 | + */ | |
| 253 | 261 | static inline bool lazy_irq_pending(void) |
| 254 | 262 | { |
| 255 | − return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS); | |
| 263 | + return __lazy_irq_pending(get_paca()->irq_happened); | |
| 264 | +} | |
| 265 | + | |
| 266 | +/* | |
| 267 | + * Check if a lazy IRQ is pending, with no debugging checks. | |
| 268 | + * Should be called with IRQs hard disabled. | |
| 269 | + * For use in RI disabled code or other constrained situations. | |
| 270 | + */ | |
| 271 | +static inline bool lazy_irq_pending_nocheck(void) | |
| 272 | +{ | |
| 273 | + return __lazy_irq_pending(local_paca->irq_happened); | |
| 256 | 274 | } |
| 257 | 275 | |
| 258 | 276 | /* |
| @@ -166,13 +166,17 @@ do { \ · 165 unmodified lines | ||
| 166 | 166 | ({ \ |
| 167 | 167 | long __pu_err; \ |
| 168 | 168 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ |
| 169 | + __typeof__(*(ptr)) __pu_val = (x); \ | |
| 170 | + __typeof__(size) __pu_size = (size); \ | |
| 171 | + \ | |
| 169 | 172 | if (!is_kernel_addr((unsigned long)__pu_addr)) \ |
| 170 | 173 | might_fault(); \ |
| 171 | − __chk_user_ptr(ptr); \ | |
| 174 | + __chk_user_ptr(__pu_addr); \ | |
| 172 | 175 | if (do_allow) \ |
| 173 | − __put_user_size((x), __pu_addr, (size), __pu_err); \ | |
| 176 | + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ | |
| 174 | 177 | else \ |
| 175 | − __put_user_size_allowed((x), __pu_addr, (size), __pu_err); \ | |
| 178 | + __put_user_size_allowed(__pu_val, __pu_addr, __pu_size, __pu_err); \ | |
| 179 | + \ | |
| 176 | 180 | __pu_err; \ |
| 177 | 181 | }) |
| 178 | 182 | |
| @@ -180,9 +184,13 @@ do { \ · 1 unmodified line | ||
| 180 | 184 | ({ \ |
| 181 | 185 | long __pu_err = -EFAULT; \ |
| 182 | 186 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ |
| 187 | + __typeof__(*(ptr)) __pu_val = (x); \ | |
| 188 | + __typeof__(size) __pu_size = (size); \ | |
| 189 | + \ | |
| 183 | 190 | might_fault(); \ |
| 184 | − if (access_ok(__pu_addr, size)) \ | |
| 185 | − __put_user_size((x), __pu_addr, (size), __pu_err); \ | |
| 191 | + if (access_ok(__pu_addr, __pu_size)) \ | |
| 192 | + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ | |
| 193 | + \ | |
| 186 | 194 | __pu_err; \ |
| 187 | 195 | }) |
| 188 | 196 | |
| @@ -190,8 +198,12 @@ do { \ · 1 unmodified line | ||
| 190 | 198 | ({ \ |
| 191 | 199 | long __pu_err; \ |
| 192 | 200 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ |
| 193 | − __chk_user_ptr(ptr); \ | |
| 194 | − __put_user_size((x), __pu_addr, (size), __pu_err); \ | |
| 201 | + __typeof__(*(ptr)) __pu_val = (x); \ | |
| 202 | + __typeof__(size) __pu_size = (size); \ | |
| 203 | + \ | |
| 204 | + __chk_user_ptr(__pu_addr); \ | |
| 205 | + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ | |
| 206 | + \ | |
| 195 | 207 | __pu_err; \ |
| 196 | 208 | }) |
| 197 | 209 | |
| @@ -283,15 +295,18 @@ do { \ · 85 unmodified lines | ||
| 283 | 295 | long __gu_err; \ |
| 284 | 296 | __long_type(*(ptr)) __gu_val; \ |
| 285 | 297 | __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
| 286 | − __chk_user_ptr(ptr); \ | |
| 298 | + __typeof__(size) __gu_size = (size); \ | |
| 299 | + \ | |
| 300 | + __chk_user_ptr(__gu_addr); \ | |
| 287 | 301 | if (!is_kernel_addr((unsigned long)__gu_addr)) \ |
| 288 | 302 | might_fault(); \ |
| 289 | 303 | barrier_nospec(); \ |
| 290 | 304 | if (do_allow) \ |
| 291 | − __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | |
| 305 | + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ | |
| 292 | 306 | else \ |
| 293 | − __get_user_size_allowed(__gu_val, __gu_addr, (size), __gu_err); \ | |
| 307 | + __get_user_size_allowed(__gu_val, __gu_addr, __gu_size, __gu_err); \ | |
| 294 | 308 | (x) = (__typeof__(*(ptr)))__gu_val; \ |
| 309 | + \ | |
| 295 | 310 | __gu_err; \ |
| 296 | 311 | }) |
| 297 | 312 | |
| @@ -300,12 +315,15 @@ do { \ · 2 unmodified lines | ||
| 300 | 315 | long __gu_err = -EFAULT; \ |
| 301 | 316 | __long_type(*(ptr)) __gu_val = 0; \ |
| 302 | 317 | __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
| 318 | + __typeof__(size) __gu_size = (size); \ | |
| 319 | + \ | |
| 303 | 320 | might_fault(); \ |
| 304 | − if (access_ok(__gu_addr, (size))) { \ | |
| 321 | + if (access_ok(__gu_addr, __gu_size)) { \ | |
| 305 | 322 | barrier_nospec(); \ |
| 306 | − __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | |
| 323 | + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ | |
| 307 | 324 | } \ |
| 308 | 325 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
| 326 | + \ | |
| 309 | 327 | __gu_err; \ |
| 310 | 328 | }) |
| 311 | 329 | |
| @@ -314,10 +332,13 @@ do { \ · 2 unmodified lines | ||
| 314 | 332 | long __gu_err; \ |
| 315 | 333 | __long_type(*(ptr)) __gu_val; \ |
| 316 | 334 | __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
| 317 | − __chk_user_ptr(ptr); \ | |
| 335 | + __typeof__(size) __gu_size = (size); \ | |
| 336 | + \ | |
| 337 | + __chk_user_ptr(__gu_addr); \ | |
| 318 | 338 | barrier_nospec(); \ |
| 319 | − __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | |
| 339 | + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ | |
| 320 | 340 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
| 341 | + \ | |
| 321 | 342 | __gu_err; \ |
| 322 | 343 | }) |
| 323 | 344 | |
| @@ -472,15 +472,17 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) · 471 unmodified lines | ||
| 472 | 472 | #ifdef CONFIG_PPC_BOOK3S |
| 473 | 473 | /* |
| 474 | 474 | * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not |
| 475 | − * touched, AMR not set, no exit work created, then this can be used. | |
| 475 | + * touched, no exit work created, then this can be used. | |
| 476 | 476 | */ |
| 477 | 477 | .balign IFETCH_ALIGN_BYTES |
| 478 | 478 | .globl fast_interrupt_return |
| 479 | 479 | fast_interrupt_return: |
| 480 | 480 | _ASM_NOKPROBE_SYMBOL(fast_interrupt_return) |
| 481 | + kuap_check_amr r3, r4 | |
| 481 | 482 | ld r4,_MSR(r1) |
| 482 | 483 | andi. r0,r4,MSR_PR |
| 483 | 484 | bne .Lfast_user_interrupt_return |
| 485 | + kuap_restore_amr r3 | |
| 484 | 486 | andi. r0,r4,MSR_RI |
| 485 | 487 | li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ |
| 486 | 488 | bne+ .Lfast_kernel_interrupt_return |
| @@ -971,6 +971,7 @@ EXC_COMMON_BEGIN(system_reset_common) · 970 unmodified lines | ||
| 971 | 971 | ld r10,SOFTE(r1) |
| 972 | 972 | stb r10,PACAIRQSOFTMASK(r13) |
| 973 | 973 | |
| 974 | + kuap_restore_amr r10 | |
| 974 | 975 | EXCEPTION_RESTORE_REGS |
| 975 | 976 | RFI_TO_USER_OR_KERNEL |
| 976 | 977 | |
| @@ -348,7 +348,7 @@ BEGIN_MMU_FTR_SECTION · 347 unmodified lines | ||
| 348 | 348 | andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h |
| 349 | 349 | #endif |
| 350 | 350 | bne handle_page_fault_tramp_2 /* if not, try to put a PTE */ |
| 351 | − rlwinm r3, r5, 32 - 24, 30, 30 /* DSISR_STORE -> _PAGE_RW */ | |
| 351 | + rlwinm r3, r5, 32 - 15, 21, 21 /* DSISR_STORE -> _PAGE_RW */ | |
| 352 | 352 | bl hash_page |
| 353 | 353 | b handle_page_fault_tramp_1 |
| 354 | 354 | FTR_SECTION_ELSE |
| @@ -497,6 +497,7 @@ InstructionTLBMiss: · 142 unmodified lines | ||
| 497 | 497 | andc. r1,r1,r0 /* check access & ~permission */ |
| 498 | 498 | bne- InstructionAddressInvalid /* return if access not permitted */ |
| 499 | 499 | /* Convert linux-style PTE to low word of PPC-style PTE */ |
| 500 | + rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ | |
| 500 | 501 | ori r1, r1, 0xe06 /* clear out reserved bits */ |
| 501 | 502 | andc r1, r0, r1 /* PP = user? 1 : 0 */ |
| 502 | 503 | BEGIN_FTR_SECTION |
| @@ -564,8 +565,9 @@ DataLoadTLBMiss: · 61 unmodified lines | ||
| 564 | 565 | * we would need to update the pte atomically with lwarx/stwcx. |
| 565 | 566 | */ |
| 566 | 567 | /* Convert linux-style PTE to low word of PPC-style PTE */ |
| 567 | − rlwinm r1,r0,0,30,30 /* _PAGE_RW -> PP msb */ | |
| 568 | − rlwimi r0,r0,1,30,30 /* _PAGE_USER -> PP msb */ | |
| 568 | + rlwinm r1,r0,32-9,30,30 /* _PAGE_RW -> PP msb */ | |
| 569 | + rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ | |
| 570 | + rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */ | |
| 569 | 571 | ori r1,r1,0xe04 /* clear out reserved bits */ |
| 570 | 572 | andc r1,r0,r1 /* PP = user? rw? 1: 3: 0 */ |
| 571 | 573 | BEGIN_FTR_SECTION |
| @@ -643,6 +645,7 @@ DataStoreTLBMiss: · 71 unmodified lines | ||
| 643 | 645 | * we would need to update the pte atomically with lwarx/stwcx. |
| 644 | 646 | */ |
| 645 | 647 | /* Convert linux-style PTE to low word of PPC-style PTE */ |
| 648 | + rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ | |
| 646 | 649 | li r1,0xe06 /* clear out reserved bits & PP msb */ |
| 647 | 650 | andc r1,r0,r1 /* PP = user? 1: 0 */ |
| 648 | 651 | BEGIN_FTR_SECTION |
| @@ -344,8 +344,9 @@ _ENTRY(saved_ksp_limit) · 343 unmodified lines | ||
| 344 | 344 | /* 0x0C00 - System Call Exception */ |
| 345 | 345 | START_EXCEPTION(0x0C00, SystemCall) |
| 346 | 346 | SYSCALL_ENTRY 0xc00 |
| 347 | +/* Trap_0D is commented out to get more space for system call exception */ | |
| 347 | 348 | |
| 348 | − EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) | |
| 349 | +/* EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) */ | |
| 349 | 350 | EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_STD) |
| 350 | 351 | EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_STD) |
| 351 | 352 | |
| @@ -19,12 +19,12 @@ bool arch_ima_get_secureboot(void) · 18 unmodified lines | ||
| 19 | 19 | * to be stored as an xattr or as an appended signature. |
| 20 | 20 | * |
| 21 | 21 | * To avoid duplicate signature verification as much as possible, the IMA |
| 22 | − * policy rule for module appraisal is added only if CONFIG_MODULE_SIG_FORCE | |
| 22 | + * policy rule for module appraisal is added only if CONFIG_MODULE_SIG | |
| 23 | 23 | * is not enabled. |
| 24 | 24 | */ |
| 25 | 25 | static const char *const secure_rules[] = { |
| 26 | 26 | "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", |
| 27 | −#ifndef CONFIG_MODULE_SIG_FORCE | |
| 27 | +#ifndef CONFIG_MODULE_SIG | |
| 28 | 28 | "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", |
| 29 | 29 | #endif |
| 30 | 30 | NULL |
| @@ -50,7 +50,7 @@ static const char *const secure_and_trusted_rules[] = { · 19 unmodified lines | ||
| 50 | 50 | "measure func=KEXEC_KERNEL_CHECK template=ima-modsig", |
| 51 | 51 | "measure func=MODULE_CHECK template=ima-modsig", |
| 52 | 52 | "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", |
| 53 | −#ifndef CONFIG_MODULE_SIG_FORCE | |
| 53 | +#ifndef CONFIG_MODULE_SIG | |
| 54 | 54 | "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", |
| 55 | 55 | #endif |
| 56 | 56 | NULL |
| @@ -35,6 +35,8 @@ notrace long system_call_exception(long r3, long r4, long r5, · 34 unmodified lines | ||
| 35 | 35 | BUG_ON(!FULL_REGS(regs)); |
| 36 | 36 | BUG_ON(regs->softe != IRQS_ENABLED); |
| 37 | 37 | |
| 38 | + kuap_check_amr(); | |
| 39 | + | |
| 38 | 40 | account_cpu_user_entry(); |
| 39 | 41 | |
| 40 | 42 | #ifdef CONFIG_PPC_SPLPAR |
| @@ -47,8 +49,6 @@ notrace long system_call_exception(long r3, long r4, long r5, · 6 unmodified lines | ||
| 47 | 49 | } |
| 48 | 50 | #endif |
| 49 | 51 | |
| 50 | − kuap_check_amr(); | |
| 51 | − | |
| 52 | 52 | /* |
| 53 | 53 | * This is not required for the syscall exit path, but makes the |
| 54 | 54 | * stack frame look nicer. If this was initialised in the first stack |
| @@ -117,6 +117,8 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, · 62 unmodified lines | ||
| 117 | 117 | unsigned long ti_flags; |
| 118 | 118 | unsigned long ret = 0; |
| 119 | 119 | |
| 120 | + kuap_check_amr(); | |
| 121 | + | |
| 120 | 122 | regs->result = r3; |
| 121 | 123 | |
| 122 | 124 | /* Check whether the syscall is issued inside a restartable sequence */ |
| @@ -189,7 +191,7 @@ again: · 66 unmodified lines | ||
| 189 | 191 | |
| 190 | 192 | /* This pattern matches prep_irq_for_idle */ |
| 191 | 193 | __hard_EE_RI_disable(); |
| 192 | − if (unlikely(lazy_irq_pending())) { | |
| 194 | + if (unlikely(lazy_irq_pending_nocheck())) { | |
| 193 | 195 | __hard_RI_enable(); |
| 194 | 196 | trace_hardirqs_off(); |
| 195 | 197 | local_paca->irq_happened |= PACA_IRQ_HARD_DIS; |
| @@ -204,8 +206,6 @@ again: · 8 unmodified lines | ||
| 204 | 206 | local_paca->tm_scratch = regs->msr; |
| 205 | 207 | #endif |
| 206 | 208 | |
| 207 | − kuap_check_amr(); | |
| 208 | − | |
| 209 | 209 | account_cpu_user_exit(); |
| 210 | 210 | |
| 211 | 211 | return ret; |
| @@ -228,6 +228,8 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned · 16 unmodified lines | ||
| 228 | 228 | BUG_ON(!FULL_REGS(regs)); |
| 229 | 229 | BUG_ON(regs->softe != IRQS_ENABLED); |
| 230 | 230 | |
| 231 | + kuap_check_amr(); | |
| 232 | + | |
| 231 | 233 | local_irq_save(flags); |
| 232 | 234 | |
| 233 | 235 | again: |
| @@ -264,7 +266,7 @@ again: · 30 unmodified lines | ||
| 264 | 266 | |
| 265 | 267 | trace_hardirqs_on(); |
| 266 | 268 | __hard_EE_RI_disable(); |
| 267 | − if (unlikely(lazy_irq_pending())) { | |
| 269 | + if (unlikely(lazy_irq_pending_nocheck())) { | |
| 268 | 270 | __hard_RI_enable(); |
| 269 | 271 | trace_hardirqs_off(); |
| 270 | 272 | local_paca->irq_happened |= PACA_IRQ_HARD_DIS; |
| @@ -292,8 +294,6 @@ again: · 21 unmodified lines | ||
| 292 | 294 | local_paca->tm_scratch = regs->msr; |
| 293 | 295 | #endif |
| 294 | 296 | |
| 295 | − kuap_check_amr(); | |
| 296 | − | |
| 297 | 297 | account_cpu_user_exit(); |
| 298 | 298 | |
| 299 | 299 | return ret; |
| @@ -313,6 +313,8 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign · 13 unmodified lines | ||
| 313 | 313 | BUG_ON(regs->msr & MSR_PR); |
| 314 | 314 | BUG_ON(!FULL_REGS(regs)); |
| 315 | 315 | |
| 316 | + kuap_check_amr(); | |
| 317 | + | |
| 316 | 318 | if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { |
| 317 | 319 | clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); |
| 318 | 320 | ret = 1; |
| @@ -334,7 +336,7 @@ again: · 15 unmodified lines | ||
| 334 | 336 | |
| 335 | 337 | trace_hardirqs_on(); |
| 336 | 338 | __hard_EE_RI_disable(); |
| 337 | − if (unlikely(lazy_irq_pending())) { | |
| 339 | + if (unlikely(lazy_irq_pending_nocheck())) { | |
| 338 | 340 | __hard_RI_enable(); |
| 339 | 341 | irq_soft_mask_set(IRQS_ALL_DISABLED); |
| 340 | 342 | trace_hardirqs_off(); |
| @@ -218,11 +218,11 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) · 217 unmodified lines | ||
| 218 | 218 | blr |
| 219 | 219 | |
| 220 | 220 | /* |
| 221 | − * invalid clock | |
| 221 | + * syscall fallback | |
| 222 | 222 | */ |
| 223 | 223 | 99: |
| 224 | − li r3, EINVAL | |
| 225 | − crset so | |
| 224 | + li r0,__NR_clock_getres | |
| 225 | + sc | |
| 226 | 226 | blr |
| 227 | 227 | .cfi_endproc |
| 228 | 228 | V_FUNCTION_END(__kernel_clock_getres) |
| @@ -35,7 +35,7 @@ mmu_hash_lock: · 34 unmodified lines | ||
| 35 | 35 | /* |
| 36 | 36 | * Load a PTE into the hash table, if possible. |
| 37 | 37 | * The address is in r4, and r3 contains an access flag: |
| 38 | − * _PAGE_RW (0x002) if a write. | |
| 38 | + * _PAGE_RW (0x400) if a write. | |
| 39 | 39 | * r9 contains the SRR1 value, from which we use the MSR_PR bit. |
| 40 | 40 | * SPRG_THREAD contains the physical address of the current task's thread. |
| 41 | 41 | * |
| @@ -69,7 +69,7 @@ _GLOBAL(hash_page) · 27 unmodified lines | ||
| 69 | 69 | blt+ 112f /* assume user more likely */ |
| 70 | 70 | lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 71 | 71 | addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ |
| 72 | − rlwimi r3,r9,32-14,31,31 /* MSR_PR -> _PAGE_USER */ | |
| 72 | + rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ | |
| 73 | 73 | 112: |
| 74 | 74 | #ifndef CONFIG_PTE_64BIT |
| 75 | 75 | rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ |
| @@ -94,7 +94,7 @@ _GLOBAL(hash_page) · 18 unmodified lines | ||
| 94 | 94 | #else |
| 95 | 95 | rlwimi r8,r4,23,20,28 /* compute pte address */ |
| 96 | 96 | #endif |
| 97 | − rlwinm r0,r3,6,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ | |
| 97 | + rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ | |
| 98 | 98 | ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE |
| 99 | 99 | |
| 100 | 100 | /* |
| @@ -310,9 +310,11 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) · 209 unmodified lines | ||
| 310 | 310 | |
| 311 | 311 | _GLOBAL(create_hpte) |
| 312 | 312 | /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */ |
| 313 | + rlwinm r8,r5,32-9,30,30 /* _PAGE_RW -> PP msb */ | |
| 313 | 314 | rlwinm r0,r5,32-6,30,30 /* _PAGE_DIRTY -> PP msb */ |
| 314 | − and r8,r5,r0 /* writable if _RW & _DIRTY */ | |
| 315 | − rlwimi r5,r5,1,30,30 /* _PAGE_USER -> PP msb */ | |
| 315 | + and r8,r8,r0 /* writable if _RW & _DIRTY */ | |
| 316 | + rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ | |
| 317 | + rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ | |
| 316 | 318 | ori r8,r8,0xe04 /* clear out reserved bits */ |
| 317 | 319 | andc r8,r5,r8 /* PP = user? (rw&dirty? 1: 3): 0 */ |
| 318 | 320 | BEGIN_FTR_SECTION |
| @@ -564,7 +566,7 @@ _GLOBAL(flush_hash_pages) · 245 unmodified lines | ||
| 564 | 566 | 33: lwarx r8,0,r5 /* fetch the pte flags word */ |
| 565 | 567 | andi. r0,r8,_PAGE_HASHPTE |
| 566 | 568 | beq 8f /* done if HASHPTE is already clear */ |
| 567 | − rlwinm r8,r8,0,~_PAGE_HASHPTE /* clear HASHPTE bit */ | |
| 569 | + rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ | |
| 568 | 570 | stwcx. r8,0,r5 /* update the pte */ |
| 569 | 571 | bne- 33b |
| 570 | 572 | |
| @@ -54,7 +54,7 @@ config RISCV · 53 unmodified lines | ||
| 54 | 54 | select GENERIC_ARCH_TOPOLOGY if SMP |
| 55 | 55 | select ARCH_HAS_PTE_SPECIAL |
| 56 | 56 | select ARCH_HAS_MMIOWB |
| 57 | − select ARCH_HAS_DEBUG_VIRTUAL | |
| 57 | + select ARCH_HAS_DEBUG_VIRTUAL if MMU | |
| 58 | 58 | select HAVE_EBPF_JIT if MMU |
| 59 | 59 | select EDAC_SUPPORT |
| 60 | 60 | select ARCH_HAS_GIGANTIC_PAGE |
| @@ -136,6 +136,7 @@ config ARCH_SUPPORTS_DEBUG_PAGEALLOC · 75 unmodified lines | ||
| 136 | 136 | def_bool y |
| 137 | 137 | |
| 138 | 138 | config SYS_SUPPORTS_HUGETLBFS |
| 139 | + depends on MMU | |
| 139 | 140 | def_bool y |
| 140 | 141 | |
| 141 | 142 | config STACKTRACE_SUPPORT |
| @@ -11,14 +11,15 @@ config SOC_SIFIVE · 10 unmodified lines | ||
| 11 | 11 | This enables support for SiFive SoC platform hardware. |
| 12 | 12 | |
| 13 | 13 | config SOC_VIRT |
| 14 | − bool "QEMU Virt Machine" | |
| 15 | − select POWER_RESET_SYSCON | |
| 16 | − select POWER_RESET_SYSCON_POWEROFF | |
| 17 | − select GOLDFISH | |
| 18 | − select RTC_DRV_GOLDFISH | |
| 19 | − select SIFIVE_PLIC | |
| 20 | − help | |
| 21 | − This enables support for QEMU Virt Machine. | |
| 14 | + bool "QEMU Virt Machine" | |
| 15 | + select POWER_RESET | |
| 16 | + select POWER_RESET_SYSCON | |
| 17 | + select POWER_RESET_SYSCON_POWEROFF | |
| 18 | + select GOLDFISH | |
| 19 | + select RTC_DRV_GOLDFISH if RTC_CLASS | |
| 20 | + select SIFIVE_PLIC | |
| 21 | + help | |
| 22 | + This enables support for QEMU Virt Machine. | |
| 22 | 23 | |
| 23 | 24 | config SOC_KENDRYTE |
| 24 | 25 | bool "Kendryte K210 SoC" |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #ifndef CONFIG_MMU |
| 18 | 18 | #define pgprot_noncached(x) (x) |
| 19 | +#define pgprot_writecombine(x) (x) | |
| 20 | +#define pgprot_device(x) (x) | |
| 19 | 21 | #endif /* CONFIG_MMU */ |
| 20 | 22 | |
| 21 | 23 | /* Generic IO read/write. These perform native-endian accesses. */ |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | */ |
| 10 | 10 | #define mmiowb() __asm__ __volatile__ ("fence o,w" : : : "memory"); |
| 11 | 11 | |
| 12 | +#include <linux/smp.h> | |
| 12 | 13 | #include <asm-generic/mmiowb.h> |
| 13 | 14 | |
| 14 | 15 | #endif /* _ASM_RISCV_MMIOWB_H */ |
| @@ -12,19 +12,14 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/ptrace.h> |
| 13 | 13 | #include <linux/interrupt.h> |
| 14 | 14 | |
| 15 | +#ifdef CONFIG_RISCV_BASE_PMU | |
| 15 | 16 | #define RISCV_BASE_COUNTERS 2 |
| 16 | 17 | |
| 17 | 18 | /* |
| 18 | 19 | * The RISCV_MAX_COUNTERS parameter should be specified. |
| 19 | 20 | */ |
| 20 | 21 | |
| 21 | −#ifdef CONFIG_RISCV_BASE_PMU | |
| 22 | 22 | #define RISCV_MAX_COUNTERS 2 |
| 23 | −#endif | |
| 24 | − | |
| 25 | −#ifndef RISCV_MAX_COUNTERS | |
| 26 | −#error "Please provide a valid RISCV_MAX_COUNTERS for the PMU." | |
| 27 | −#endif | |
| 28 | 23 | |
| 29 | 24 | /* |
| 30 | 25 | * These are the indexes of bits in counteren register *minus* 1, |
| @@ -82,6 +77,7 @@ struct riscv_pmu { · 51 unmodified lines | ||
| 82 | 77 | int irq; |
| 83 | 78 | }; |
| 84 | 79 | |
| 80 | +#endif | |
| 85 | 81 | #ifdef CONFIG_PERF_EVENTS |
| 86 | 82 | #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs |
| 87 | 83 | #endif |
| @@ -470,12 +470,15 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, · 469 unmodified lines | ||
| 470 | 470 | |
| 471 | 471 | #else /* CONFIG_MMU */ |
| 472 | 472 | |
| 473 | +#define PAGE_SHARED __pgprot(0) | |
| 473 | 474 | #define PAGE_KERNEL __pgprot(0) |
| 474 | 475 | #define swapper_pg_dir NULL |
| 475 | 476 | #define VMALLOC_START 0 |
| 476 | 477 | |
| 477 | 478 | #define TASK_SIZE 0xffffffffUL |
| 478 | 479 | |
| 480 | +static inline void __kernel_map_pages(struct page *page, int numpages, int enable) {} | |
| 481 | + | |
| 479 | 482 | #endif /* !CONFIG_MMU */ |
| 480 | 483 | |
| 481 | 484 | #define kern_addr_valid(addr) (1) /* FIXME */ |
| @@ -43,7 +43,7 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o · 42 unmodified lines | ||
| 43 | 43 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o |
| 44 | 44 | obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o |
| 45 | 45 | |
| 46 | −obj-$(CONFIG_PERF_EVENTS) += perf_event.o | |
| 46 | +obj-$(CONFIG_RISCV_BASE_PMU) += perf_event.o | |
| 47 | 47 | obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o |
| 48 | 48 | obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o |
| 49 | 49 | obj-$(CONFIG_RISCV_SBI) += sbi.o |
| @@ -147,7 +147,7 @@ static int riscv_map_hw_event(u64 config) · 146 unmodified lines | ||
| 147 | 147 | return riscv_pmu->hw_events[config]; |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | −int riscv_map_cache_decode(u64 config, unsigned int *type, | |
| 150 | +static int riscv_map_cache_decode(u64 config, unsigned int *type, | |
| 151 | 151 | unsigned int *op, unsigned int *result) |
| 152 | 152 | { |
| 153 | 153 | return -ENOENT; |
| @@ -342,7 +342,7 @@ static void riscv_pmu_del(struct perf_event *event, int flags) · 188 unmodified lines | ||
| 342 | 342 | |
| 343 | 343 | static DEFINE_MUTEX(pmc_reserve_mutex); |
| 344 | 344 | |
| 345 | −irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev) | |
| 345 | +static irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev) | |
| 346 | 346 | { |
| 347 | 347 | return IRQ_NONE; |
| 348 | 348 | } |
| @@ -361,7 +361,7 @@ static int reserve_pmc_hardware(void) · 12 unmodified lines | ||
| 361 | 361 | return err; |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | −void release_pmc_hardware(void) | |
| 364 | +static void release_pmc_hardware(void) | |
| 365 | 365 | { |
| 366 | 366 | mutex_lock(&pmc_reserve_mutex); |
| 367 | 367 | if (riscv_pmu->irq >= 0) |
| @@ -464,7 +464,7 @@ static const struct of_device_id riscv_pmu_of_ids[] = { · 96 unmodified lines | ||
| 464 | 464 | { /* sentinel value */ } |
| 465 | 465 | }; |
| 466 | 466 | |
| 467 | −int __init init_hw_perf_events(void) | |
| 467 | +static int __init init_hw_perf_events(void) | |
| 468 | 468 | { |
| 469 | 469 | struct device_node *node = of_find_node_by_type(NULL, "pmu"); |
| 470 | 470 | const struct of_device_id *of_id; |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <asm/switch_to.h> |
| 23 | 23 | #include <asm/thread_info.h> |
| 24 | 24 | |
| 25 | −unsigned long gp_in_global __asm__("gp"); | |
| 25 | +register unsigned long gp_in_global __asm__("gp"); | |
| 26 | 26 | |
| 27 | 27 | extern asmlinkage void ret_from_fork(void); |
| 28 | 28 | extern asmlinkage void ret_from_kernel_thread(void); |
| @@ -65,7 +65,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, · 64 unmodified lines | ||
| 65 | 65 | |
| 66 | 66 | #else /* !CONFIG_FRAME_POINTER */ |
| 67 | 67 | |
| 68 | −static void notrace walk_stackframe(struct task_struct *task, | |
| 68 | +void notrace walk_stackframe(struct task_struct *task, | |
| 69 | 69 | struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) |
| 70 | 70 | { |
| 71 | 71 | unsigned long sp, pc; |
| @@ -47,7 +47,7 @@ static void setup_zero_page(void) · 46 unmodified lines | ||
| 47 | 47 | memset((void *)empty_zero_page, 0, PAGE_SIZE); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | −#ifdef CONFIG_DEBUG_VM | |
| 50 | +#if defined(CONFIG_MMU) && defined(CONFIG_DEBUG_VM) | |
| 51 | 51 | static inline void print_mlk(char *name, unsigned long b, unsigned long t) |
| 52 | 52 | { |
| 53 | 53 | pr_notice("%12s : 0x%08lx - 0x%08lx (%4ld kB)\n", name, b, t, |
| @@ -8,6 +8,10 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/slab.h> |
| 9 | 9 | #include <asm/pci_insn.h> |
| 10 | 10 | |
| 11 | +/* I/O size constraints */ | |
| 12 | +#define ZPCI_MAX_READ_SIZE 8 | |
| 13 | +#define ZPCI_MAX_WRITE_SIZE 128 | |
| 14 | + | |
| 11 | 15 | /* I/O Map */ |
| 12 | 16 | #define ZPCI_IOMAP_SHIFT 48 |
| 13 | 17 | #define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL |
| @@ -140,7 +144,8 @@ static inline int zpci_memcpy_fromio(void *dst, · 126 unmodified lines | ||
| 140 | 144 | |
| 141 | 145 | while (n > 0) { |
| 142 | 146 | size = zpci_get_max_write_size((u64 __force) src, |
| 143 | − (u64) dst, n, 8); | |
| 147 | + (u64) dst, n, | |
| 148 | + ZPCI_MAX_READ_SIZE); | |
| 144 | 149 | rc = zpci_read_single(dst, src, size); |
| 145 | 150 | if (rc) |
| 146 | 151 | break; |
| @@ -161,7 +166,8 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst, · 14 unmodified lines | ||
| 161 | 166 | |
| 162 | 167 | while (n > 0) { |
| 163 | 168 | size = zpci_get_max_write_size((u64 __force) dst, |
| 164 | − (u64) src, n, 128); | |
| 169 | + (u64) src, n, | |
| 170 | + ZPCI_MAX_WRITE_SIZE); | |
| 165 | 171 | if (size > 8) /* main path */ |
| 166 | 172 | rc = zpci_write_block(dst, src, size); |
| 167 | 173 | else |
| @@ -151,7 +151,7 @@ static int kexec_file_add_initrd(struct kimage *image, · 150 unmodified lines | ||
| 151 | 151 | buf.mem += crashk_res.start; |
| 152 | 152 | buf.memsz = buf.bufsz; |
| 153 | 153 | |
| 154 | − data->parm->initrd_start = buf.mem; | |
| 154 | + data->parm->initrd_start = data->memsz; | |
| 155 | 155 | data->parm->initrd_size = buf.memsz; |
| 156 | 156 | data->memsz += buf.memsz; |
| 157 | 157 | |
| @@ -28,6 +28,7 @@ int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, · 27 unmodified lines | ||
| 28 | 28 | break; |
| 29 | 29 | case R_390_64: /* Direct 64 bit. */ |
| 30 | 30 | case R_390_GLOB_DAT: |
| 31 | + case R_390_JMP_SLOT: | |
| 31 | 32 | *(u64 *)loc = val; |
| 32 | 33 | break; |
| 33 | 34 | case R_390_PC16: /* PC relative 16 bit. */ |
| @@ -159,10 +159,13 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 158 unmodified lines | ||
| 159 | 159 | rste &= ~_SEGMENT_ENTRY_NOEXEC; |
| 160 | 160 | |
| 161 | 161 | /* Set correct table type for 2G hugepages */ |
| 162 | − if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) | |
| 163 | − rste |= _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE; | |
| 164 | − else | |
| 162 | + if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) { | |
| 163 | + if (likely(pte_present(pte))) | |
| 164 | + rste |= _REGION3_ENTRY_LARGE; | |
| 165 | + rste |= _REGION_ENTRY_TYPE_R3; | |
| 166 | + } else if (likely(pte_present(pte))) | |
| 165 | 167 | rste |= _SEGMENT_ENTRY_LARGE; |
| 168 | + | |
| 166 | 169 | clear_huge_pte_skeys(mm, rste); |
| 167 | 170 | pte_val(*ptep) = rste; |
| 168 | 171 | } |
| @@ -11,6 +11,113 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/mm.h> |
| 12 | 12 | #include <linux/errno.h> |
| 13 | 13 | #include <linux/pci.h> |
| 14 | +#include <asm/pci_io.h> | |
| 15 | +#include <asm/pci_debug.h> | |
| 16 | + | |
| 17 | +static inline void zpci_err_mmio(u8 cc, u8 status, u64 offset) | |
| 18 | +{ | |
| 19 | + struct { | |
| 20 | + u64 offset; | |
| 21 | + u8 cc; | |
| 22 | + u8 status; | |
| 23 | + } data = {offset, cc, status}; | |
| 24 | + | |
| 25 | + zpci_err_hex(&data, sizeof(data)); | |
| 26 | +} | |
| 27 | + | |
| 28 | +static inline int __pcistb_mio_inuser( | |
| 29 | + void __iomem *ioaddr, const void __user *src, | |
| 30 | + u64 len, u8 *status) | |
| 31 | +{ | |
| 32 | + int cc = -ENXIO; | |
| 33 | + | |
| 34 | + asm volatile ( | |
| 35 | + " sacf 256\n" | |
| 36 | + "0: .insn rsy,0xeb00000000d4,%[len],%[ioaddr],%[src]\n" | |
| 37 | + "1: ipm %[cc]\n" | |
| 38 | + " srl %[cc],28\n" | |
| 39 | + "2: sacf 768\n" | |
| 40 | + EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | |
| 41 | + : [cc] "+d" (cc), [len] "+d" (len) | |
| 42 | + : [ioaddr] "a" (ioaddr), [src] "Q" (*((u8 __force *)src)) | |
| 43 | + : "cc", "memory"); | |
| 44 | + *status = len >> 24 & 0xff; | |
| 45 | + return cc; | |
| 46 | +} | |
| 47 | + | |
| 48 | +static inline int __pcistg_mio_inuser( | |
| 49 | + void __iomem *ioaddr, const void __user *src, | |
| 50 | + u64 ulen, u8 *status) | |
| 51 | +{ | |
| 52 | + register u64 addr asm("2") = (u64 __force) ioaddr; | |
| 53 | + register u64 len asm("3") = ulen; | |
| 54 | + int cc = -ENXIO; | |
| 55 | + u64 val = 0; | |
| 56 | + u64 cnt = ulen; | |
| 57 | + u8 tmp; | |
| 58 | + | |
| 59 | + /* | |
| 60 | + * copy 0 < @len <= 8 bytes from @src into the right most bytes of | |
| 61 | + * a register, then store it to PCI at @ioaddr while in secondary | |
| 62 | + * address space. pcistg then uses the user mappings. | |
| 63 | + */ | |
| 64 | + asm volatile ( | |
| 65 | + " sacf 256\n" | |
| 66 | + "0: llgc %[tmp],0(%[src])\n" | |
| 67 | + " sllg %[val],%[val],8\n" | |
| 68 | + " aghi %[src],1\n" | |
| 69 | + " ogr %[val],%[tmp]\n" | |
| 70 | + " brctg %[cnt],0b\n" | |
| 71 | + "1: .insn rre,0xb9d40000,%[val],%[ioaddr]\n" | |
| 72 | + "2: ipm %[cc]\n" | |
| 73 | + " srl %[cc],28\n" | |
| 74 | + "3: sacf 768\n" | |
| 75 | + EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b) | |
| 76 | + : | |
| 77 | + [src] "+a" (src), [cnt] "+d" (cnt), | |
| 78 | + [val] "+d" (val), [tmp] "=d" (tmp), | |
| 79 | + [len] "+d" (len), [cc] "+d" (cc), | |
| 80 | + [ioaddr] "+a" (addr) | |
| 81 | + :: "cc", "memory"); | |
| 82 | + *status = len >> 24 & 0xff; | |
| 83 | + | |
| 84 | + /* did we read everything from user memory? */ | |
| 85 | + if (!cc && cnt != 0) | |
| 86 | + cc = -EFAULT; | |
| 87 | + | |
| 88 | + return cc; | |
| 89 | +} | |
| 90 | + | |
| 91 | +static inline int __memcpy_toio_inuser(void __iomem *dst, | |
| 92 | + const void __user *src, size_t n) | |
| 93 | +{ | |
| 94 | + int size, rc = 0; | |
| 95 | + u8 status = 0; | |
| 96 | + mm_segment_t old_fs; | |
| 97 | + | |
| 98 | + if (!src) | |
| 99 | + return -EINVAL; | |
| 100 | + | |
| 101 | + old_fs = enable_sacf_uaccess(); | |
| 102 | + while (n > 0) { | |
| 103 | + size = zpci_get_max_write_size((u64 __force) dst, | |
| 104 | + (u64 __force) src, n, | |
| 105 | + ZPCI_MAX_WRITE_SIZE); | |
| 106 | + if (size > 8) /* main path */ | |
| 107 | + rc = __pcistb_mio_inuser(dst, src, size, &status); | |
| 108 | + else | |
| 109 | + rc = __pcistg_mio_inuser(dst, src, size, &status); | |
| 110 | + if (rc) | |
| 111 | + break; | |
| 112 | + src += size; | |
| 113 | + dst += size; | |
| 114 | + n -= size; | |
| 115 | + } | |
| 116 | + disable_sacf_uaccess(old_fs); | |
| 117 | + if (rc) | |
| 118 | + zpci_err_mmio(rc, status, (__force u64) dst); | |
| 119 | + return rc; | |
| 120 | +} | |
| 14 | 121 | |
| 15 | 122 | static long get_pfn(unsigned long user_addr, unsigned long access, |
| 16 | 123 | unsigned long *pfn) |
| @@ -46,6 +153,20 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, · 29 unmodified lines | ||
| 46 | 153 | |
| 47 | 154 | if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) |
| 48 | 155 | return -EINVAL; |
| 156 | + | |
| 157 | + /* | |
| 158 | + * Only support read access to MIO capable devices on a MIO enabled | |
| 159 | + * system. Otherwise we would have to check for every address if it is | |
| 160 | + * a special ZPCI_ADDR and we would have to do a get_pfn() which we | |
| 161 | + * don't need for MIO capable devices. | |
| 162 | + */ | |
| 163 | + if (static_branch_likely(&have_mio)) { | |
| 164 | + ret = __memcpy_toio_inuser((void __iomem *) mmio_addr, | |
| 165 | + user_buffer, | |
| 166 | + length); | |
| 167 | + return ret; | |
| 168 | + } | |
| 169 | + | |
| 49 | 170 | if (length > 64) { |
| 50 | 171 | buf = kmalloc(length, GFP_KERNEL); |
| 51 | 172 | if (!buf) |
| @@ -56,7 +177,8 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, · 4 unmodified lines | ||
| 56 | 177 | ret = get_pfn(mmio_addr, VM_WRITE, &pfn); |
| 57 | 178 | if (ret) |
| 58 | 179 | goto out; |
| 59 | − io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); | |
| 180 | + io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | | |
| 181 | + (mmio_addr & ~PAGE_MASK)); | |
| 60 | 182 | |
| 61 | 183 | ret = -EFAULT; |
| 62 | 184 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) |
| @@ -72,6 +194,78 @@ out: · 9 unmodified lines | ||
| 72 | 194 | return ret; |
| 73 | 195 | } |
| 74 | 196 | |
| 197 | +static inline int __pcilg_mio_inuser( | |
| 198 | + void __user *dst, const void __iomem *ioaddr, | |
| 199 | + u64 ulen, u8 *status) | |
| 200 | +{ | |
| 201 | + register u64 addr asm("2") = (u64 __force) ioaddr; | |
| 202 | + register u64 len asm("3") = ulen; | |
| 203 | + u64 cnt = ulen; | |
| 204 | + int shift = ulen * 8; | |
| 205 | + int cc = -ENXIO; | |
| 206 | + u64 val, tmp; | |
| 207 | + | |
| 208 | + /* | |
| 209 | + * read 0 < @len <= 8 bytes from the PCI memory mapped at @ioaddr (in | |
| 210 | + * user space) into a register using pcilg then store these bytes at | |
| 211 | + * user address @dst | |
| 212 | + */ | |
| 213 | + asm volatile ( | |
| 214 | + " sacf 256\n" | |
| 215 | + "0: .insn rre,0xb9d60000,%[val],%[ioaddr]\n" | |
| 216 | + "1: ipm %[cc]\n" | |
| 217 | + " srl %[cc],28\n" | |
| 218 | + " ltr %[cc],%[cc]\n" | |
| 219 | + " jne 4f\n" | |
| 220 | + "2: ahi %[shift],-8\n" | |
| 221 | + " srlg %[tmp],%[val],0(%[shift])\n" | |
| 222 | + "3: stc %[tmp],0(%[dst])\n" | |
| 223 | + " aghi %[dst],1\n" | |
| 224 | + " brctg %[cnt],2b\n" | |
| 225 | + "4: sacf 768\n" | |
| 226 | + EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) | |
| 227 | + : | |
| 228 | + [cc] "+d" (cc), [val] "=d" (val), [len] "+d" (len), | |
| 229 | + [dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp), | |
| 230 | + [shift] "+d" (shift) | |
| 231 | + : | |
| 232 | + [ioaddr] "a" (addr) | |
| 233 | + : "cc", "memory"); | |
| 234 | + | |
| 235 | + /* did we write everything to the user space buffer? */ | |
| 236 | + if (!cc && cnt != 0) | |
| 237 | + cc = -EFAULT; | |
| 238 | + | |
| 239 | + *status = len >> 24 & 0xff; | |
| 240 | + return cc; | |
| 241 | +} | |
| 242 | + | |
| 243 | +static inline int __memcpy_fromio_inuser(void __user *dst, | |
| 244 | + const void __iomem *src, | |
| 245 | + unsigned long n) | |
| 246 | +{ | |
| 247 | + int size, rc = 0; | |
| 248 | + u8 status; | |
| 249 | + mm_segment_t old_fs; | |
| 250 | + | |
| 251 | + old_fs = enable_sacf_uaccess(); | |
| 252 | + while (n > 0) { | |
| 253 | + size = zpci_get_max_write_size((u64 __force) src, | |
| 254 | + (u64 __force) dst, n, | |
| 255 | + ZPCI_MAX_READ_SIZE); | |
| 256 | + rc = __pcilg_mio_inuser(dst, src, size, &status); | |
| 257 | + if (rc) | |
| 258 | + break; | |
| 259 | + src += size; | |
| 260 | + dst += size; | |
| 261 | + n -= size; | |
| 262 | + } | |
| 263 | + disable_sacf_uaccess(old_fs); | |
| 264 | + if (rc) | |
| 265 | + zpci_err_mmio(rc, status, (__force u64) dst); | |
| 266 | + return rc; | |
| 267 | +} | |
| 268 | + | |
| 75 | 269 | SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, |
| 76 | 270 | void __user *, user_buffer, size_t, length) |
| 77 | 271 | { |
| @@ -86,12 +280,27 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, · 8 unmodified lines | ||
| 86 | 280 | |
| 87 | 281 | if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) |
| 88 | 282 | return -EINVAL; |
| 283 | + | |
| 284 | + /* | |
| 285 | + * Only support write access to MIO capable devices on a MIO enabled | |
| 286 | + * system. Otherwise we would have to check for every address if it is | |
| 287 | + * a special ZPCI_ADDR and we would have to do a get_pfn() which we | |
| 288 | + * don't need for MIO capable devices. | |
| 289 | + */ | |
| 290 | + if (static_branch_likely(&have_mio)) { | |
| 291 | + ret = __memcpy_fromio_inuser( | |
| 292 | + user_buffer, (const void __iomem *)mmio_addr, | |
| 293 | + length); | |
| 294 | + return ret; | |
| 295 | + } | |
| 296 | + | |
| 89 | 297 | if (length > 64) { |
| 90 | 298 | buf = kmalloc(length, GFP_KERNEL); |
| 91 | 299 | if (!buf) |
| 92 | 300 | return -ENOMEM; |
| 93 | − } else | |
| 301 | + } else { | |
| 94 | 302 | buf = local_buf; |
| 303 | + } | |
| 95 | 304 | |
| 96 | 305 | ret = get_pfn(mmio_addr, VM_READ, &pfn); |
| 97 | 306 | if (ret) |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __ASM_SH_SOCKIOS_H |
| 3 | 3 | #define __ASM_SH_SOCKIOS_H |
| 4 | 4 | |
| 5 | +#include <linux/time_types.h> | |
| 6 | + | |
| 5 | 7 | /* Socket-level I/O control calls. */ |
| 6 | 8 | #define FIOGETOWN _IOR('f', 123, int) |
| 7 | 9 | #define FIOSETOWN _IOW('f', 124, int) |
| @@ -331,9 +331,9 @@ static void __init srmmu_nocache_init(void) · 330 unmodified lines | ||
| 331 | 331 | |
| 332 | 332 | while (vaddr < srmmu_nocache_end) { |
| 333 | 333 | pgd = pgd_offset_k(vaddr); |
| 334 | − p4d = p4d_offset(__nocache_fix(pgd), vaddr); | |
| 335 | − pud = pud_offset(__nocache_fix(p4d), vaddr); | |
| 336 | − pmd = pmd_offset(__nocache_fix(pgd), vaddr); | |
| 334 | + p4d = p4d_offset(pgd, vaddr); | |
| 335 | + pud = pud_offset(p4d, vaddr); | |
| 336 | + pmd = pmd_offset(__nocache_fix(pud), vaddr); | |
| 337 | 337 | pte = pte_offset_kernel(__nocache_fix(pmd), vaddr); |
| 338 | 338 | |
| 339 | 339 | pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV); |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #define TRANS_TAP_LEN strlen(TRANS_TAP) |
| 18 | 18 | |
| 19 | 19 | #define TRANS_GRE "gre" |
| 20 | −#define TRANS_GRE_LEN strlen(TRANS_RAW) | |
| 20 | +#define TRANS_GRE_LEN strlen(TRANS_GRE) | |
| 21 | 21 | |
| 22 | 22 | #define TRANS_L2TPV3 "l2tpv3" |
| 23 | 23 | #define TRANS_L2TPV3_LEN strlen(TRANS_L2TPV3) |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | #include <asm-generic/xor.h> |
| 3 | −#include <shared/timer-internal.h> | |
| 3 | +#include <linux/time-internal.h> | |
| 4 | 4 | |
| 5 | 5 | /* pick an arbitrary one - measuring isn't possible with inf-cpu */ |
| 6 | 6 | #define XOR_SELECT_TEMPLATE(x) \ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <sysdep/ptrace_user.h> |
| 12 | 12 | #include <sysdep/syscalls.h> |
| 13 | 13 | #include <linux/time-internal.h> |
| 14 | +#include <asm/unistd.h> | |
| 14 | 15 | |
| 15 | 16 | void handle_syscall(struct uml_pt_regs *r) |
| 16 | 17 | { |
| @@ -68,6 +68,7 @@ config X86 · 67 unmodified lines | ||
| 68 | 68 | select ARCH_HAS_KCOV if X86_64 |
| 69 | 69 | select ARCH_HAS_MEM_ENCRYPT |
| 70 | 70 | select ARCH_HAS_MEMBARRIER_SYNC_CORE |
| 71 | + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 71 | 72 | select ARCH_HAS_PMEM_API if X86_64 |
| 72 | 73 | select ARCH_HAS_PTE_DEVMAP if X86_64 |
| 73 | 74 | select ARCH_HAS_PTE_SPECIAL |
| @@ -59,14 +59,14 @@ u8 buf[SETUP_SECT_MAX*512]; · 58 unmodified lines | ||
| 59 | 59 | #define PECOFF_COMPAT_RESERVE 0x0 |
| 60 | 60 | #endif |
| 61 | 61 | |
| 62 | −unsigned long efi32_stub_entry; | |
| 63 | −unsigned long efi64_stub_entry; | |
| 64 | −unsigned long efi_pe_entry; | |
| 65 | −unsigned long efi32_pe_entry; | |
| 66 | −unsigned long kernel_info; | |
| 67 | −unsigned long startup_64; | |
| 68 | −unsigned long _ehead; | |
| 69 | −unsigned long _end; | |
| 62 | +static unsigned long efi32_stub_entry; | |
| 63 | +static unsigned long efi64_stub_entry; | |
| 64 | +static unsigned long efi_pe_entry; | |
| 65 | +static unsigned long efi32_pe_entry; | |
| 66 | +static unsigned long kernel_info; | |
| 67 | +static unsigned long startup_64; | |
| 68 | +static unsigned long _ehead; | |
| 69 | +static unsigned long _end; | |
| 70 | 70 | |
| 71 | 71 | /*----------------------------------------------------------------------*/ |
| 72 | 72 | |
| @@ -226,10 +226,18 @@ static int hv_cpu_die(unsigned int cpu) · 225 unmodified lines | ||
| 226 | 226 | |
| 227 | 227 | rdmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); |
| 228 | 228 | if (re_ctrl.target_vp == hv_vp_index[cpu]) { |
| 229 | − /* Reassign to some other online CPU */ | |
| 229 | + /* | |
| 230 | + * Reassign reenlightenment notifications to some other online | |
| 231 | + * CPU or just disable the feature if there are no online CPUs | |
| 232 | + * left (happens on hibernation). | |
| 233 | + */ | |
| 230 | 234 | new_cpu = cpumask_any_but(cpu_online_mask, cpu); |
| 231 | 235 | |
| 232 | − re_ctrl.target_vp = hv_vp_index[new_cpu]; | |
| 236 | + if (new_cpu < nr_cpu_ids) | |
| 237 | + re_ctrl.target_vp = hv_vp_index[new_cpu]; | |
| 238 | + else | |
| 239 | + re_ctrl.enabled = 0; | |
| 240 | + | |
| 233 | 241 | wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); |
| 234 | 242 | } |
| 235 | 243 | |
| @@ -293,6 +301,13 @@ static void hv_resume(void) · 57 unmodified lines | ||
| 293 | 301 | |
| 294 | 302 | hv_hypercall_pg = hv_hypercall_pg_saved; |
| 295 | 303 | hv_hypercall_pg_saved = NULL; |
| 304 | + | |
| 305 | + /* | |
| 306 | + * Reenlightenment notifications are disabled by hv_cpu_die(0), | |
| 307 | + * reenable them here if hv_reenlightenment_cb was previously set. | |
| 308 | + */ | |
| 309 | + if (hv_reenlightenment_cb) | |
| 310 | + set_hv_tscchange_cb(hv_reenlightenment_cb); | |
| 296 | 311 | } |
| 297 | 312 | |
| 298 | 313 | /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ |
| @@ -52,9 +52,9 @@ static __always_inline void · 51 unmodified lines | ||
| 52 | 52 | arch_set_bit(long nr, volatile unsigned long *addr) |
| 53 | 53 | { |
| 54 | 54 | if (__builtin_constant_p(nr)) { |
| 55 | − asm volatile(LOCK_PREFIX "orb %1,%0" | |
| 55 | + asm volatile(LOCK_PREFIX "orb %b1,%0" | |
| 56 | 56 | : CONST_MASK_ADDR(nr, addr) |
| 57 | − : "iq" (CONST_MASK(nr) & 0xff) | |
| 57 | + : "iq" (CONST_MASK(nr)) | |
| 58 | 58 | : "memory"); |
| 59 | 59 | } else { |
| 60 | 60 | asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0" |
| @@ -72,9 +72,9 @@ static __always_inline void · 11 unmodified lines | ||
| 72 | 72 | arch_clear_bit(long nr, volatile unsigned long *addr) |
| 73 | 73 | { |
| 74 | 74 | if (__builtin_constant_p(nr)) { |
| 75 | − asm volatile(LOCK_PREFIX "andb %1,%0" | |
| 75 | + asm volatile(LOCK_PREFIX "andb %b1,%0" | |
| 76 | 76 | : CONST_MASK_ADDR(nr, addr) |
| 77 | − : "iq" (CONST_MASK(nr) ^ 0xff)); | |
| 77 | + : "iq" (~CONST_MASK(nr))); | |
| 78 | 78 | } else { |
| 79 | 79 | asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0" |
| 80 | 80 | : : RLONG_ADDR(addr), "Ir" (nr) : "memory"); |
| @@ -123,9 +123,9 @@ static __always_inline void · 42 unmodified lines | ||
| 123 | 123 | arch_change_bit(long nr, volatile unsigned long *addr) |
| 124 | 124 | { |
| 125 | 125 | if (__builtin_constant_p(nr)) { |
| 126 | − asm volatile(LOCK_PREFIX "xorb %1,%0" | |
| 126 | + asm volatile(LOCK_PREFIX "xorb %b1,%0" | |
| 127 | 127 | : CONST_MASK_ADDR(nr, addr) |
| 128 | − : "iq" ((u8)CONST_MASK(nr))); | |
| 128 | + : "iq" (CONST_MASK(nr))); | |
| 129 | 129 | } else { |
| 130 | 130 | asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0" |
| 131 | 131 | : : RLONG_ADDR(addr), "Ir" (nr) : "memory"); |
| @@ -56,6 +56,12 @@ struct dyn_arch_ftrace { · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | #ifndef __ASSEMBLY__ |
| 58 | 58 | |
| 59 | +#if defined(CONFIG_FUNCTION_TRACER) && defined(CONFIG_DYNAMIC_FTRACE) | |
| 60 | +extern void set_ftrace_ops_ro(void); | |
| 61 | +#else | |
| 62 | +static inline void set_ftrace_ops_ro(void) { } | |
| 63 | +#endif | |
| 64 | + | |
| 59 | 65 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME |
| 60 | 66 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) |
| 61 | 67 | { |
| @@ -578,6 +578,7 @@ struct kvm_vcpu_arch { · 577 unmodified lines | ||
| 578 | 578 | unsigned long cr4; |
| 579 | 579 | unsigned long cr4_guest_owned_bits; |
| 580 | 580 | unsigned long cr8; |
| 581 | + u32 host_pkru; | |
| 581 | 582 | u32 pkru; |
| 582 | 583 | u32 hflags; |
| 583 | 584 | u64 efer; |
| @@ -1093,8 +1094,6 @@ struct kvm_x86_ops { · 509 unmodified lines | ||
| 1093 | 1094 | void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
| 1094 | 1095 | void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
| 1095 | 1096 | void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
| 1096 | − u64 (*get_dr6)(struct kvm_vcpu *vcpu); | |
| 1097 | − void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value); | |
| 1098 | 1097 | void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu); |
| 1099 | 1098 | void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); |
| 1100 | 1099 | void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); |
| @@ -1449,6 +1448,7 @@ bool kvm_rdpmc(struct kvm_vcpu *vcpu); · 348 unmodified lines | ||
| 1449 | 1448 | |
| 1450 | 1449 | void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); |
| 1451 | 1450 | void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); |
| 1451 | +void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); | |
| 1452 | 1452 | void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); |
| 1453 | 1453 | void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); |
| 1454 | 1454 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); |
| @@ -55,8 +55,13 @@ · 54 unmodified lines | ||
| 55 | 55 | /* |
| 56 | 56 | * Initialize the stackprotector canary value. |
| 57 | 57 | * |
| 58 | − * NOTE: this must only be called from functions that never return, | |
| 58 | + * NOTE: this must only be called from functions that never return | |
| 59 | 59 | * and it must always be inlined. |
| 60 | + * | |
| 61 | + * In addition, it should be called from a compilation unit for which | |
| 62 | + * stack protector is disabled. Alternatively, the caller should not end | |
| 63 | + * with a function call which gets tail-call optimized as that would | |
| 64 | + * lead to checking a modified canary value. | |
| 60 | 65 | */ |
| 61 | 66 | static __always_inline void boot_init_stack_canary(void) |
| 62 | 67 | { |
| @@ -407,7 +407,8 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | set_vm_flush_reset_perms(trampoline); |
| 409 | 409 | |
| 410 | − set_memory_ro((unsigned long)trampoline, npages); | |
| 410 | + if (likely(system_state != SYSTEM_BOOTING)) | |
| 411 | + set_memory_ro((unsigned long)trampoline, npages); | |
| 411 | 412 | set_memory_x((unsigned long)trampoline, npages); |
| 412 | 413 | return (unsigned long)trampoline; |
| 413 | 414 | fail: |
| @@ -415,6 +416,32 @@ fail: · 1 unmodified line | ||
| 415 | 416 | return 0; |
| 416 | 417 | } |
| 417 | 418 | |
| 419 | +void set_ftrace_ops_ro(void) | |
| 420 | +{ | |
| 421 | + struct ftrace_ops *ops; | |
| 422 | + unsigned long start_offset; | |
| 423 | + unsigned long end_offset; | |
| 424 | + unsigned long npages; | |
| 425 | + unsigned long size; | |
| 426 | + | |
| 427 | + do_for_each_ftrace_op(ops, ftrace_ops_list) { | |
| 428 | + if (!(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP)) | |
| 429 | + continue; | |
| 430 | + | |
| 431 | + if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { | |
| 432 | + start_offset = (unsigned long)ftrace_regs_caller; | |
| 433 | + end_offset = (unsigned long)ftrace_regs_caller_end; | |
| 434 | + } else { | |
| 435 | + start_offset = (unsigned long)ftrace_caller; | |
| 436 | + end_offset = (unsigned long)ftrace_epilogue; | |
| 437 | + } | |
| 438 | + size = end_offset - start_offset; | |
| 439 | + size = size + RET_SIZE + sizeof(void *); | |
| 440 | + npages = DIV_ROUND_UP(size, PAGE_SIZE); | |
| 441 | + set_memory_ro((unsigned long)ops->trampoline, npages); | |
| 442 | + } while_for_each_ftrace_op(ops); | |
| 443 | +} | |
| 444 | + | |
| 418 | 445 | static unsigned long calc_trampoline_call_offset(bool save_regs) |
| 419 | 446 | { |
| 420 | 447 | unsigned long start_offset; |
| @@ -266,6 +266,14 @@ static void notrace start_secondary(void *unused) · 265 unmodified lines | ||
| 266 | 266 | |
| 267 | 267 | wmb(); |
| 268 | 268 | cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); |
| 269 | + | |
| 270 | + /* | |
| 271 | + * Prevent tail call to cpu_startup_entry() because the stack protector | |
| 272 | + * guard has been changed a couple of function calls up, in | |
| 273 | + * boot_init_stack_canary() and must not be checked before tail calling | |
| 274 | + * another function. | |
| 275 | + */ | |
| 276 | + prevent_tail_call_optimization(); | |
| 269 | 277 | } |
| 270 | 278 | |
| 271 | 279 | /** |
| @@ -320,12 +320,19 @@ EXPORT_SYMBOL_GPL(unwind_get_return_address); · 319 unmodified lines | ||
| 320 | 320 | |
| 321 | 321 | unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) |
| 322 | 322 | { |
| 323 | + struct task_struct *task = state->task; | |
| 324 | + | |
| 323 | 325 | if (unwind_done(state)) |
| 324 | 326 | return NULL; |
| 325 | 327 | |
| 326 | 328 | if (state->regs) |
| 327 | 329 | return &state->regs->ip; |
| 328 | 330 | |
| 331 | + if (task != current && state->sp == task->thread.sp) { | |
| 332 | + struct inactive_task_frame *frame = (void *)task->thread.sp; | |
| 333 | + return &frame->ret_addr; | |
| 334 | + } | |
| 335 | + | |
| 329 | 336 | if (state->sp) |
| 330 | 337 | return (unsigned long *)state->sp - 1; |
| 331 | 338 | |
| @@ -617,23 +624,23 @@ EXPORT_SYMBOL_GPL(unwind_next_frame); · 285 unmodified lines | ||
| 617 | 624 | void __unwind_start(struct unwind_state *state, struct task_struct *task, |
| 618 | 625 | struct pt_regs *regs, unsigned long *first_frame) |
| 619 | 626 | { |
| 620 | − if (!orc_init) | |
| 621 | − goto done; | |
| 622 | − | |
| 623 | 627 | memset(state, 0, sizeof(*state)); |
| 624 | 628 | state->task = task; |
| 625 | 629 | |
| 630 | + if (!orc_init) | |
| 631 | + goto err; | |
| 632 | + | |
| 626 | 633 | /* |
| 627 | 634 | * Refuse to unwind the stack of a task while it's executing on another |
| 628 | 635 | * CPU. This check is racy, but that's ok: the unwinder has other |
| 629 | 636 | * checks to prevent it from going off the rails. |
| 630 | 637 | */ |
| 631 | 638 | if (task_on_another_cpu(task)) |
| 632 | − goto done; | |
| 639 | + goto err; | |
| 633 | 640 | |
| 634 | 641 | if (regs) { |
| 635 | 642 | if (user_mode(regs)) |
| 636 | − goto done; | |
| 643 | + goto the_end; | |
| 637 | 644 | |
| 638 | 645 | state->ip = regs->ip; |
| 639 | 646 | state->sp = regs->sp; |
| @@ -666,6 +673,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 26 unmodified lines | ||
| 666 | 673 | * generate some kind of backtrace if this happens. |
| 667 | 674 | */ |
| 668 | 675 | void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp); |
| 676 | + state->error = true; | |
| 669 | 677 | if (get_stack_info(next_page, state->task, &state->stack_info, |
| 670 | 678 | &state->stack_mask)) |
| 671 | 679 | return; |
| @@ -691,8 +699,9 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 19 unmodified lines | ||
| 691 | 699 | |
| 692 | 700 | return; |
| 693 | 701 | |
| 694 | −done: | |
| 702 | +err: | |
| 703 | + state->error = true; | |
| 704 | +the_end: | |
| 695 | 705 | state->stack_info.type = STACK_TYPE_UNKNOWN; |
| 696 | − return; | |
| 697 | 706 | } |
| 698 | 707 | EXPORT_SYMBOL_GPL(__unwind_start); |
| @@ -1427,7 +1427,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *current_vcpu, u64 ingpa, · 1426 unmodified lines | ||
| 1427 | 1427 | */ |
| 1428 | 1428 | kvm_make_vcpus_request_mask(kvm, |
| 1429 | 1429 | KVM_REQ_TLB_FLUSH | KVM_REQUEST_NO_WAKEUP, |
| 1430 | − vcpu_mask, &hv_vcpu->tlb_flush); | |
| 1430 | + NULL, vcpu_mask, &hv_vcpu->tlb_flush); | |
| 1431 | 1431 | |
| 1432 | 1432 | ret_success: |
| 1433 | 1433 | /* We always do full TLB flush, set rep_done = rep_cnt. */ |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/kernel.h> |
| 20 | 20 | |
| 21 | 21 | #include <asm/msr-index.h> |
| 22 | +#include <asm/debugreg.h> | |
| 22 | 23 | |
| 23 | 24 | #include "kvm_emulate.h" |
| 24 | 25 | #include "trace.h" |
| @@ -267,7 +268,7 @@ void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, · 242 unmodified lines | ||
| 267 | 268 | svm->vmcb->save.rsp = nested_vmcb->save.rsp; |
| 268 | 269 | svm->vmcb->save.rip = nested_vmcb->save.rip; |
| 269 | 270 | svm->vmcb->save.dr7 = nested_vmcb->save.dr7; |
| 270 | − svm->vmcb->save.dr6 = nested_vmcb->save.dr6; | |
| 271 | + svm->vcpu.arch.dr6 = nested_vmcb->save.dr6; | |
| 271 | 272 | svm->vmcb->save.cpl = nested_vmcb->save.cpl; |
| 272 | 273 | |
| 273 | 274 | svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa & ~0x0fffULL; |
| @@ -482,7 +483,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 208 unmodified lines | ||
| 482 | 483 | nested_vmcb->save.rsp = vmcb->save.rsp; |
| 483 | 484 | nested_vmcb->save.rax = vmcb->save.rax; |
| 484 | 485 | nested_vmcb->save.dr7 = vmcb->save.dr7; |
| 485 | − nested_vmcb->save.dr6 = vmcb->save.dr6; | |
| 486 | + nested_vmcb->save.dr6 = svm->vcpu.arch.dr6; | |
| 486 | 487 | nested_vmcb->save.cpl = vmcb->save.cpl; |
| 487 | 488 | |
| 488 | 489 | nested_vmcb->control.int_ctl = vmcb->control.int_ctl; |
| @@ -606,26 +607,45 @@ static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) · 117 unmodified lines | ||
| 606 | 607 | /* DB exceptions for our internal use must not cause vmexit */ |
| 607 | 608 | static int nested_svm_intercept_db(struct vcpu_svm *svm) |
| 608 | 609 | { |
| 609 | − unsigned long dr6; | |
| 610 | + unsigned long dr6 = svm->vmcb->save.dr6; | |
| 611 | + | |
| 612 | + /* Always catch it and pass it to userspace if debugging. */ | |
| 613 | + if (svm->vcpu.guest_debug & | |
| 614 | + (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | |
| 615 | + return NESTED_EXIT_HOST; | |
| 610 | 616 | |
| 611 | 617 | /* if we're not singlestepping, it's not ours */ |
| 612 | 618 | if (!svm->nmi_singlestep) |
| 613 | − return NESTED_EXIT_DONE; | |
| 619 | + goto reflected_db; | |
| 614 | 620 | |
| 615 | 621 | /* if it's not a singlestep exception, it's not ours */ |
| 616 | − if (kvm_get_dr(&svm->vcpu, 6, &dr6)) | |
| 617 | − return NESTED_EXIT_DONE; | |
| 618 | 622 | if (!(dr6 & DR6_BS)) |
| 619 | − return NESTED_EXIT_DONE; | |
| 623 | + goto reflected_db; | |
| 620 | 624 | |
| 621 | 625 | /* if the guest is singlestepping, it should get the vmexit */ |
| 622 | 626 | if (svm->nmi_singlestep_guest_rflags & X86_EFLAGS_TF) { |
| 623 | 627 | disable_nmi_singlestep(svm); |
| 624 | − return NESTED_EXIT_DONE; | |
| 628 | + goto reflected_db; | |
| 625 | 629 | } |
| 626 | 630 | |
| 627 | 631 | /* it's ours, the nested hypervisor must not see this one */ |
| 628 | 632 | return NESTED_EXIT_HOST; |
| 633 | + | |
| 634 | +reflected_db: | |
| 635 | + /* | |
| 636 | + * Synchronize guest DR6 here just like in kvm_deliver_exception_payload; | |
| 637 | + * it will be moved into the nested VMCB by nested_svm_vmexit. Once | |
| 638 | + * exceptions will be moved to svm_check_nested_events, all this stuff | |
| 639 | + * will just go away and we could just return NESTED_EXIT_HOST | |
| 640 | + * unconditionally. db_interception will queue the exception, which | |
| 641 | + * will be processed by svm_check_nested_events if a nested vmexit is | |
| 642 | + * required, and we will just use kvm_deliver_exception_payload to copy | |
| 643 | + * the payload to DR6 before vmexit. | |
| 644 | + */ | |
| 645 | + WARN_ON(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT); | |
| 646 | + svm->vcpu.arch.dr6 &= ~(DR_TRAP_BITS | DR6_RTM); | |
| 647 | + svm->vcpu.arch.dr6 |= dr6 & ~DR6_FIXED_1; | |
| 648 | + return NESTED_EXIT_DONE; | |
| 629 | 649 | } |
| 630 | 650 | |
| 631 | 651 | static int nested_svm_intercept_ioio(struct vcpu_svm *svm) |
| @@ -682,6 +702,9 @@ static int nested_svm_intercept(struct vcpu_svm *svm) · 50 unmodified lines | ||
| 682 | 702 | if (svm->nested.intercept_exceptions & excp_bits) { |
| 683 | 703 | if (exit_code == SVM_EXIT_EXCP_BASE + DB_VECTOR) |
| 684 | 704 | vmexit = nested_svm_intercept_db(svm); |
| 705 | + else if (exit_code == SVM_EXIT_EXCP_BASE + BP_VECTOR && | |
| 706 | + svm->vcpu.guest_debug & KVM_GUESTDBG_USE_SW_BP) | |
| 707 | + vmexit = NESTED_EXIT_HOST; | |
| 685 | 708 | else |
| 686 | 709 | vmexit = NESTED_EXIT_DONE; |
| 687 | 710 | } |
| @@ -1672,17 +1672,14 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) · 1671 unmodified lines | ||
| 1672 | 1672 | mark_dirty(svm->vmcb, VMCB_ASID); |
| 1673 | 1673 | } |
| 1674 | 1674 | |
| 1675 | −static u64 svm_get_dr6(struct kvm_vcpu *vcpu) | |
| 1675 | +static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value) | |
| 1676 | 1676 | { |
| 1677 | − return to_svm(vcpu)->vmcb->save.dr6; | |
| 1678 | −} | |
| 1679 | − | |
| 1680 | −static void svm_set_dr6(struct kvm_vcpu *vcpu, unsigned long value) | |
| 1681 | −{ | |
| 1682 | − struct vcpu_svm *svm = to_svm(vcpu); | |
| 1677 | + struct vmcb *vmcb = svm->vmcb; | |
| 1683 | 1678 | |
| 1684 | − svm->vmcb->save.dr6 = value; | |
| 1685 | − mark_dirty(svm->vmcb, VMCB_DR); | |
| 1679 | + if (unlikely(value != vmcb->save.dr6)) { | |
| 1680 | + vmcb->save.dr6 = value; | |
| 1681 | + mark_dirty(vmcb, VMCB_DR); | |
| 1682 | + } | |
| 1686 | 1683 | } |
| 1687 | 1684 | |
| 1688 | 1685 | static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) |
| @@ -1693,9 +1690,12 @@ static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) · 4 unmodified lines | ||
| 1693 | 1690 | get_debugreg(vcpu->arch.db[1], 1); |
| 1694 | 1691 | get_debugreg(vcpu->arch.db[2], 2); |
| 1695 | 1692 | get_debugreg(vcpu->arch.db[3], 3); |
| 1696 | − vcpu->arch.dr6 = svm_get_dr6(vcpu); | |
| 1693 | + /* | |
| 1694 | + * We cannot reset svm->vmcb->save.dr6 to DR6_FIXED_1|DR6_RTM here, | |
| 1695 | + * because db_interception might need it. We can do it before vmentry. | |
| 1696 | + */ | |
| 1697 | + vcpu->arch.dr6 = svm->vmcb->save.dr6; | |
| 1697 | 1698 | vcpu->arch.dr7 = svm->vmcb->save.dr7; |
| 1698 | − | |
| 1699 | 1699 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT; |
| 1700 | 1700 | set_dr_intercepts(svm); |
| 1701 | 1701 | } |
| @@ -1739,7 +1739,8 @@ static int db_interception(struct vcpu_svm *svm) · 37 unmodified lines | ||
| 1739 | 1739 | if (!(svm->vcpu.guest_debug & |
| 1740 | 1740 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) && |
| 1741 | 1741 | !svm->nmi_singlestep) { |
| 1742 | − kvm_queue_exception(&svm->vcpu, DB_VECTOR); | |
| 1742 | + u32 payload = (svm->vmcb->save.dr6 ^ DR6_RTM) & ~DR6_FIXED_1; | |
| 1743 | + kvm_queue_exception_p(&svm->vcpu, DB_VECTOR, payload); | |
| 1743 | 1744 | return 1; |
| 1744 | 1745 | } |
| 1745 | 1746 | |
| @@ -3317,6 +3318,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) · 1571 unmodified lines | ||
| 3317 | 3318 | |
| 3318 | 3319 | svm->vmcb->save.cr2 = vcpu->arch.cr2; |
| 3319 | 3320 | |
| 3321 | + /* | |
| 3322 | + * Run with all-zero DR6 unless needed, so that we can get the exact cause | |
| 3323 | + * of a #DB. | |
| 3324 | + */ | |
| 3325 | + if (unlikely(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) | |
| 3326 | + svm_set_dr6(svm, vcpu->arch.dr6); | |
| 3327 | + else | |
| 3328 | + svm_set_dr6(svm, DR6_FIXED_1 | DR6_RTM); | |
| 3329 | + | |
| 3320 | 3330 | clgi(); |
| 3321 | 3331 | kvm_load_guest_xsave_state(vcpu); |
| 3322 | 3332 | |
| @@ -3931,8 +3941,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 608 unmodified lines | ||
| 3931 | 3941 | .set_idt = svm_set_idt, |
| 3932 | 3942 | .get_gdt = svm_get_gdt, |
| 3933 | 3943 | .set_gdt = svm_set_gdt, |
| 3934 | − .get_dr6 = svm_get_dr6, | |
| 3935 | − .set_dr6 = svm_set_dr6, | |
| 3936 | 3944 | .set_dr7 = svm_set_dr7, |
| 3937 | 3945 | .sync_dirty_debug_regs = svm_sync_dirty_debug_regs, |
| 3938 | 3946 | .cache_reg = svm_cache_reg, |
| @@ -1372,7 +1372,6 @@ void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 1371 unmodified lines | ||
| 1372 | 1372 | |
| 1373 | 1373 | vmx_vcpu_pi_load(vcpu, cpu); |
| 1374 | 1374 | |
| 1375 | − vmx->host_pkru = read_pkru(); | |
| 1376 | 1375 | vmx->host_debugctlmsr = get_debugctlmsr(); |
| 1377 | 1376 | } |
| 1378 | 1377 | |
| @@ -4677,15 +4676,13 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) · 3298 unmodified lines | ||
| 4677 | 4676 | dr6 = vmcs_readl(EXIT_QUALIFICATION); |
| 4678 | 4677 | if (!(vcpu->guest_debug & |
| 4679 | 4678 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { |
| 4680 | − vcpu->arch.dr6 &= ~DR_TRAP_BITS; | |
| 4681 | − vcpu->arch.dr6 |= dr6 | DR6_RTM; | |
| 4682 | 4679 | if (is_icebp(intr_info)) |
| 4683 | 4680 | WARN_ON(!skip_emulated_instruction(vcpu)); |
| 4684 | 4681 | |
| 4685 | − kvm_queue_exception(vcpu, DB_VECTOR); | |
| 4682 | + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); | |
| 4686 | 4683 | return 1; |
| 4687 | 4684 | } |
| 4688 | − kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1; | |
| 4685 | + kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; | |
| 4689 | 4686 | kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7); |
| 4690 | 4687 | /* fall through */ |
| 4691 | 4688 | case BP_VECTOR: |
| @@ -4929,16 +4926,14 @@ static int handle_dr(struct kvm_vcpu *vcpu) · 237 unmodified lines | ||
| 4929 | 4926 | * guest debugging itself. |
| 4930 | 4927 | */ |
| 4931 | 4928 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { |
| 4932 | − vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; | |
| 4929 | + vcpu->run->debug.arch.dr6 = DR6_BD | DR6_RTM | DR6_FIXED_1; | |
| 4933 | 4930 | vcpu->run->debug.arch.dr7 = dr7; |
| 4934 | 4931 | vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu); |
| 4935 | 4932 | vcpu->run->debug.arch.exception = DB_VECTOR; |
| 4936 | 4933 | vcpu->run->exit_reason = KVM_EXIT_DEBUG; |
| 4937 | 4934 | return 0; |
| 4938 | 4935 | } else { |
| 4939 | − vcpu->arch.dr6 &= ~DR_TRAP_BITS; | |
| 4940 | − vcpu->arch.dr6 |= DR6_BD | DR6_RTM; | |
| 4941 | − kvm_queue_exception(vcpu, DB_VECTOR); | |
| 4936 | + kvm_queue_exception_p(vcpu, DB_VECTOR, DR6_BD); | |
| 4942 | 4937 | return 1; |
| 4943 | 4938 | } |
| 4944 | 4939 | } |
| @@ -4969,15 +4964,6 @@ static int handle_dr(struct kvm_vcpu *vcpu) · 24 unmodified lines | ||
| 4969 | 4964 | return kvm_skip_emulated_instruction(vcpu); |
| 4970 | 4965 | } |
| 4971 | 4966 | |
| 4972 | −static u64 vmx_get_dr6(struct kvm_vcpu *vcpu) | |
| 4973 | −{ | |
| 4974 | − return vcpu->arch.dr6; | |
| 4975 | −} | |
| 4976 | − | |
| 4977 | −static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) | |
| 4978 | −{ | |
| 4979 | −} | |
| 4980 | − | |
| 4981 | 4967 | static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) |
| 4982 | 4968 | { |
| 4983 | 4969 | get_debugreg(vcpu->arch.db[0], 0); |
| @@ -6577,11 +6563,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) · 1593 unmodified lines | ||
| 6577 | 6563 | |
| 6578 | 6564 | kvm_load_guest_xsave_state(vcpu); |
| 6579 | 6565 | |
| 6580 | − if (static_cpu_has(X86_FEATURE_PKU) && | |
| 6581 | − kvm_read_cr4_bits(vcpu, X86_CR4_PKE) && | |
| 6582 | − vcpu->arch.pkru != vmx->host_pkru) | |
| 6583 | − __write_pkru(vcpu->arch.pkru); | |
| 6584 | − | |
| 6585 | 6566 | pt_guest_enter(vmx); |
| 6586 | 6567 | |
| 6587 | 6568 | if (vcpu_to_pmu(vcpu)->version) |
| @@ -6671,18 +6652,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) · 83 unmodified lines | ||
| 6671 | 6652 | |
| 6672 | 6653 | pt_guest_exit(vmx); |
| 6673 | 6654 | |
| 6674 | − /* | |
| 6675 | − * eager fpu is enabled if PKEY is supported and CR4 is switched | |
| 6676 | − * back on host, so it is safe to read guest PKRU from current | |
| 6677 | − * XSAVE. | |
| 6678 | − */ | |
| 6679 | − if (static_cpu_has(X86_FEATURE_PKU) && | |
| 6680 | − kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) { | |
| 6681 | − vcpu->arch.pkru = rdpkru(); | |
| 6682 | − if (vcpu->arch.pkru != vmx->host_pkru) | |
| 6683 | − __write_pkru(vmx->host_pkru); | |
| 6684 | − } | |
| 6685 | − | |
| 6686 | 6655 | kvm_load_host_xsave_state(vcpu); |
| 6687 | 6656 | |
| 6688 | 6657 | vmx->nested.nested_run_pending = 0; |
| @@ -7740,8 +7709,6 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 1051 unmodified lines | ||
| 7740 | 7709 | .set_idt = vmx_set_idt, |
| 7741 | 7710 | .get_gdt = vmx_get_gdt, |
| 7742 | 7711 | .set_gdt = vmx_set_gdt, |
| 7743 | − .get_dr6 = vmx_get_dr6, | |
| 7744 | − .set_dr6 = vmx_set_dr6, | |
| 7745 | 7712 | .set_dr7 = vmx_set_dr7, |
| 7746 | 7713 | .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs, |
| 7747 | 7714 | .cache_reg = vmx_cache_reg, |
| @@ -572,11 +572,12 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) · 571 unmodified lines | ||
| 572 | 572 | } |
| 573 | 573 | EXPORT_SYMBOL_GPL(kvm_requeue_exception); |
| 574 | 574 | |
| 575 | −static void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, | |
| 576 | − unsigned long payload) | |
| 575 | +void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, | |
| 576 | + unsigned long payload) | |
| 577 | 577 | { |
| 578 | 578 | kvm_multiple_exception(vcpu, nr, false, 0, true, payload, false); |
| 579 | 579 | } |
| 580 | +EXPORT_SYMBOL_GPL(kvm_queue_exception_p); | |
| 580 | 581 | |
| 581 | 582 | static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, |
| 582 | 583 | u32 error_code, unsigned long payload) |
| @@ -836,11 +837,25 @@ void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu) · 253 unmodified lines | ||
| 836 | 837 | vcpu->arch.ia32_xss != host_xss) |
| 837 | 838 | wrmsrl(MSR_IA32_XSS, vcpu->arch.ia32_xss); |
| 838 | 839 | } |
| 840 | + | |
| 841 | + if (static_cpu_has(X86_FEATURE_PKU) && | |
| 842 | + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || | |
| 843 | + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) && | |
| 844 | + vcpu->arch.pkru != vcpu->arch.host_pkru) | |
| 845 | + __write_pkru(vcpu->arch.pkru); | |
| 839 | 846 | } |
| 840 | 847 | EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state); |
| 841 | 848 | |
| 842 | 849 | void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) |
| 843 | 850 | { |
| 851 | + if (static_cpu_has(X86_FEATURE_PKU) && | |
| 852 | + (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || | |
| 853 | + (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) { | |
| 854 | + vcpu->arch.pkru = rdpkru(); | |
| 855 | + if (vcpu->arch.pkru != vcpu->arch.host_pkru) | |
| 856 | + __write_pkru(vcpu->arch.host_pkru); | |
| 857 | + } | |
| 858 | + | |
| 844 | 859 | if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) { |
| 845 | 860 | |
| 846 | 861 | if (vcpu->arch.xcr0 != host_xcr0) |
| @@ -1045,12 +1060,6 @@ static void kvm_update_dr0123(struct kvm_vcpu *vcpu) · 198 unmodified lines | ||
| 1045 | 1060 | } |
| 1046 | 1061 | } |
| 1047 | 1062 | |
| 1048 | −static void kvm_update_dr6(struct kvm_vcpu *vcpu) | |
| 1049 | −{ | |
| 1050 | − if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | |
| 1051 | − kvm_x86_ops.set_dr6(vcpu, vcpu->arch.dr6); | |
| 1052 | −} | |
| 1053 | − | |
| 1054 | 1063 | static void kvm_update_dr7(struct kvm_vcpu *vcpu) |
| 1055 | 1064 | { |
| 1056 | 1065 | unsigned long dr7; |
| @@ -1090,7 +1099,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) · 33 unmodified lines | ||
| 1090 | 1099 | if (val & 0xffffffff00000000ULL) |
| 1091 | 1100 | return -1; /* #GP */ |
| 1092 | 1101 | vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu); |
| 1093 | − kvm_update_dr6(vcpu); | |
| 1094 | 1102 | break; |
| 1095 | 1103 | case 5: |
| 1096 | 1104 | /* fall through */ |
| @@ -1126,10 +1134,7 @@ int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) · 29 unmodified lines | ||
| 1126 | 1134 | case 4: |
| 1127 | 1135 | /* fall through */ |
| 1128 | 1136 | case 6: |
| 1129 | − if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | |
| 1130 | − *val = vcpu->arch.dr6; | |
| 1131 | − else | |
| 1132 | − *val = kvm_x86_ops.get_dr6(vcpu); | |
| 1137 | + *val = vcpu->arch.dr6; | |
| 1133 | 1138 | break; |
| 1134 | 1139 | case 5: |
| 1135 | 1140 | /* fall through */ |
| @@ -3558,6 +3563,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 2422 unmodified lines | ||
| 3558 | 3563 | |
| 3559 | 3564 | kvm_x86_ops.vcpu_load(vcpu, cpu); |
| 3560 | 3565 | |
| 3566 | + /* Save host pkru register if supported */ | |
| 3567 | + vcpu->arch.host_pkru = read_pkru(); | |
| 3568 | + | |
| 3561 | 3569 | /* Apply any externally detected TSC adjustments (due to suspend) */ |
| 3562 | 3570 | if (unlikely(vcpu->arch.tsc_offset_adjustment)) { |
| 3563 | 3571 | adjust_tsc_offset_host(vcpu, vcpu->arch.tsc_offset_adjustment); |
| @@ -3751,7 +3759,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, · 187 unmodified lines | ||
| 3751 | 3759 | unsigned bank_num = mcg_cap & 0xff, bank; |
| 3752 | 3760 | |
| 3753 | 3761 | r = -EINVAL; |
| 3754 | − if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) | |
| 3762 | + if (!bank_num || bank_num > KVM_MAX_MCE_BANKS) | |
| 3755 | 3763 | goto out; |
| 3756 | 3764 | if (mcg_cap & ~(kvm_mce_cap_supported | 0xff | 0xff0000)) |
| 3757 | 3765 | goto out; |
| @@ -4009,7 +4017,6 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, · 251 unmodified lines | ||
| 4009 | 4017 | memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); |
| 4010 | 4018 | kvm_update_dr0123(vcpu); |
| 4011 | 4019 | vcpu->arch.dr6 = dbgregs->dr6; |
| 4012 | − kvm_update_dr6(vcpu); | |
| 4013 | 4020 | vcpu->arch.dr7 = dbgregs->dr7; |
| 4014 | 4021 | kvm_update_dr7(vcpu); |
| 4015 | 4022 | |
| @@ -6659,7 +6666,7 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu) · 2643 unmodified lines | ||
| 6659 | 6666 | |
| 6660 | 6667 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { |
| 6661 | 6668 | kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM; |
| 6662 | − kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; | |
| 6669 | + kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu); | |
| 6663 | 6670 | kvm_run->debug.arch.exception = DB_VECTOR; |
| 6664 | 6671 | kvm_run->exit_reason = KVM_EXIT_DEBUG; |
| 6665 | 6672 | return 0; |
| @@ -6719,9 +6726,7 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) · 53 unmodified lines | ||
| 6719 | 6726 | vcpu->arch.db); |
| 6720 | 6727 | |
| 6721 | 6728 | if (dr6 != 0) { |
| 6722 | − vcpu->arch.dr6 &= ~DR_TRAP_BITS; | |
| 6723 | − vcpu->arch.dr6 |= dr6 | DR6_RTM; | |
| 6724 | − kvm_queue_exception(vcpu, DB_VECTOR); | |
| 6729 | + kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); | |
| 6725 | 6730 | *r = 1; |
| 6726 | 6731 | return true; |
| 6727 | 6732 | } |
| @@ -8042,7 +8047,7 @@ void kvm_make_scan_ioapic_request_mask(struct kvm *kvm, · 1314 unmodified lines | ||
| 8042 | 8047 | zalloc_cpumask_var(&cpus, GFP_ATOMIC); |
| 8043 | 8048 | |
| 8044 | 8049 | kvm_make_vcpus_request_mask(kvm, KVM_REQ_SCAN_IOAPIC, |
| 8045 | − vcpu_bitmap, cpus); | |
| 8050 | + NULL, vcpu_bitmap, cpus); | |
| 8046 | 8051 | |
| 8047 | 8052 | free_cpumask_var(cpus); |
| 8048 | 8053 | } |
| @@ -8072,6 +8077,7 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); · 23 unmodified lines | ||
| 8072 | 8077 | */ |
| 8073 | 8078 | void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) |
| 8074 | 8079 | { |
| 8080 | + struct kvm_vcpu *except; | |
| 8075 | 8081 | unsigned long old, new, expected; |
| 8076 | 8082 | |
| 8077 | 8083 | if (!kvm_x86_ops.check_apicv_inhibit_reasons || |
| @@ -8096,7 +8102,17 @@ void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) · 18 unmodified lines | ||
| 8096 | 8102 | trace_kvm_apicv_update_request(activate, bit); |
| 8097 | 8103 | if (kvm_x86_ops.pre_update_apicv_exec_ctrl) |
| 8098 | 8104 | kvm_x86_ops.pre_update_apicv_exec_ctrl(kvm, activate); |
| 8099 | − kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); | |
| 8105 | + | |
| 8106 | + /* | |
| 8107 | + * Sending request to update APICV for all other vcpus, | |
| 8108 | + * while update the calling vcpu immediately instead of | |
| 8109 | + * waiting for another #VMEXIT to handle the request. | |
| 8110 | + */ | |
| 8111 | + except = kvm_get_running_vcpu(); | |
| 8112 | + kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, | |
| 8113 | + except); | |
| 8114 | + if (except) | |
| 8115 | + kvm_vcpu_update_apicv(except); | |
| 8100 | 8116 | } |
| 8101 | 8117 | EXPORT_SYMBOL_GPL(kvm_request_apicv_update); |
| 8102 | 8118 | |
| @@ -8420,7 +8436,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 317 unmodified lines | ||
| 8420 | 8436 | WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); |
| 8421 | 8437 | kvm_x86_ops.sync_dirty_debug_regs(vcpu); |
| 8422 | 8438 | kvm_update_dr0123(vcpu); |
| 8423 | − kvm_update_dr6(vcpu); | |
| 8424 | 8439 | kvm_update_dr7(vcpu); |
| 8425 | 8440 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; |
| 8426 | 8441 | } |
| @@ -9481,7 +9496,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 1054 unmodified lines | ||
| 9481 | 9496 | memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); |
| 9482 | 9497 | kvm_update_dr0123(vcpu); |
| 9483 | 9498 | vcpu->arch.dr6 = DR6_INIT; |
| 9484 | − kvm_update_dr6(vcpu); | |
| 9485 | 9499 | vcpu->arch.dr7 = DR7_FIXED_1; |
| 9486 | 9500 | kvm_update_dr7(vcpu); |
| 9487 | 9501 | |
| @@ -54,6 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | #include <asm/init.h> |
| 55 | 55 | #include <asm/uv/uv.h> |
| 56 | 56 | #include <asm/setup.h> |
| 57 | +#include <asm/ftrace.h> | |
| 57 | 58 | |
| 58 | 59 | #include "mm_internal.h" |
| 59 | 60 | |
| @@ -1291,6 +1292,8 @@ void mark_rodata_ro(void) · 1231 unmodified lines | ||
| 1291 | 1292 | all_end = roundup((unsigned long)_brk_end, PMD_SIZE); |
| 1292 | 1293 | set_memory_nx(text_end, (all_end - text_end) >> PAGE_SHIFT); |
| 1293 | 1294 | |
| 1295 | + set_ftrace_ops_ro(); | |
| 1296 | + | |
| 1294 | 1297 | #ifdef CONFIG_CPA_DEBUG |
| 1295 | 1298 | printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, end); |
| 1296 | 1299 | set_memory_rw(start, (end-start) >> PAGE_SHIFT); |
| @@ -372,7 +372,7 @@ static void enter_uniprocessor(void) · 371 unmodified lines | ||
| 372 | 372 | int cpu; |
| 373 | 373 | int err; |
| 374 | 374 | |
| 375 | − if (downed_cpus == NULL && | |
| 375 | + if (!cpumask_available(downed_cpus) && | |
| 376 | 376 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { |
| 377 | 377 | pr_notice("Failed to allocate mask\n"); |
| 378 | 378 | goto out; |
| @@ -402,7 +402,7 @@ static void leave_uniprocessor(void) · 23 unmodified lines | ||
| 402 | 402 | int cpu; |
| 403 | 403 | int err; |
| 404 | 404 | |
| 405 | − if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) | |
| 405 | + if (!cpumask_available(downed_cpus) || cpumask_weight(downed_cpus) == 0) | |
| 406 | 406 | return; |
| 407 | 407 | pr_notice("Re-enabling CPUs...\n"); |
| 408 | 408 | for_each_cpu(cpu, downed_cpus) { |
| @@ -93,6 +93,7 @@ asmlinkage __visible void cpu_bringup_and_idle(void) · 92 unmodified lines | ||
| 93 | 93 | cpu_bringup(); |
| 94 | 94 | boot_init_stack_canary(); |
| 95 | 95 | cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); |
| 96 | + prevent_tail_call_optimization(); | |
| 96 | 97 | } |
| 97 | 98 | |
| 98 | 99 | void xen_smp_intr_free_pv(unsigned int cpu) |
| @@ -1994,23 +1994,35 @@ void acpi_ec_set_gpe_wake_mask(u8 action) · 1993 unmodified lines | ||
| 1994 | 1994 | acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action); |
| 1995 | 1995 | } |
| 1996 | 1996 | |
| 1997 | −bool acpi_ec_other_gpes_active(void) | |
| 1998 | −{ | |
| 1999 | − return acpi_any_gpe_status_set(first_ec ? first_ec->gpe : U32_MAX); | |
| 2000 | −} | |
| 2001 | − | |
| 2002 | 1997 | bool acpi_ec_dispatch_gpe(void) |
| 2003 | 1998 | { |
| 2004 | 1999 | u32 ret; |
| 2005 | 2000 | |
| 2006 | 2001 | if (!first_ec) |
| 2002 | + return acpi_any_gpe_status_set(U32_MAX); | |
| 2003 | + | |
| 2004 | + /* | |
| 2005 | + * Report wakeup if the status bit is set for any enabled GPE other | |
| 2006 | + * than the EC one. | |
| 2007 | + */ | |
| 2008 | + if (acpi_any_gpe_status_set(first_ec->gpe)) | |
| 2009 | + return true; | |
| 2010 | + | |
| 2011 | + if (ec_no_wakeup) | |
| 2007 | 2012 | return false; |
| 2008 | 2013 | |
| 2014 | + /* | |
| 2015 | + * Dispatch the EC GPE in-band, but do not report wakeup in any case | |
| 2016 | + * to allow the caller to process events properly after that. | |
| 2017 | + */ | |
| 2009 | 2018 | ret = acpi_dispatch_gpe(NULL, first_ec->gpe); |
| 2010 | 2019 | if (ret == ACPI_INTERRUPT_HANDLED) { |
| 2011 | 2020 | pm_pr_dbg("EC GPE dispatched\n"); |
| 2012 | − return true; | |
| 2021 | + | |
| 2022 | + /* Flush the event and query workqueues. */ | |
| 2023 | + acpi_ec_flush_work(); | |
| 2013 | 2024 | } |
| 2025 | + | |
| 2014 | 2026 | return false; |
| 2015 | 2027 | } |
| 2016 | 2028 | #endif /* CONFIG_PM_SLEEP */ |
| @@ -202,7 +202,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); · 201 unmodified lines | ||
| 202 | 202 | |
| 203 | 203 | #ifdef CONFIG_PM_SLEEP |
| 204 | 204 | void acpi_ec_flush_work(void); |
| 205 | −bool acpi_ec_other_gpes_active(void); | |
| 206 | 205 | bool acpi_ec_dispatch_gpe(void); |
| 207 | 206 | #endif |
| 208 | 207 | |
| @@ -980,13 +980,6 @@ static int acpi_s2idle_prepare_late(void) · 979 unmodified lines | ||
| 980 | 980 | return 0; |
| 981 | 981 | } |
| 982 | 982 | |
| 983 | −static void acpi_s2idle_sync(void) | |
| 984 | −{ | |
| 985 | − /* The EC driver uses special workqueues that need to be flushed. */ | |
| 986 | − acpi_ec_flush_work(); | |
| 987 | − acpi_os_wait_events_complete(); /* synchronize Notify handling */ | |
| 988 | −} | |
| 989 | − | |
| 990 | 983 | static bool acpi_s2idle_wake(void) |
| 991 | 984 | { |
| 992 | 985 | if (!acpi_sci_irq_valid()) |
| @@ -1013,22 +1006,12 @@ static bool acpi_s2idle_wake(void) · 20 unmodified lines | ||
| 1013 | 1006 | if (acpi_check_wakeup_handlers()) |
| 1014 | 1007 | return true; |
| 1015 | 1008 | |
| 1016 | − /* | |
| 1017 | − * If the status bit is set for any enabled GPE other than the | |
| 1018 | − * EC one, the wakeup is regarded as a genuine one. | |
| 1019 | − */ | |
| 1020 | − if (acpi_ec_other_gpes_active()) | |
| 1009 | + /* Check non-EC GPE wakeups and dispatch the EC GPE. */ | |
| 1010 | + if (acpi_ec_dispatch_gpe()) | |
| 1021 | 1011 | return true; |
| 1022 | 1012 | |
| 1023 | 1013 | /* |
| 1024 | − * If the EC GPE status bit has not been set, the wakeup is | |
| 1025 | − * regarded as a spurious one. | |
| 1026 | − */ | |
| 1027 | − if (!acpi_ec_dispatch_gpe()) | |
| 1028 | − return false; | |
| 1029 | − | |
| 1030 | − /* | |
| 1031 | − * Cancel the wakeup and process all pending events in case | |
| 1014 | + * Cancel the SCI wakeup and process all pending events in case | |
| 1032 | 1015 | * there are any wakeup ones in there. |
| 1033 | 1016 | * |
| 1034 | 1017 | * Note that if any non-EC GPEs are active at this point, the |
| @@ -1036,8 +1019,7 @@ static bool acpi_s2idle_wake(void) · 1 unmodified line | ||
| 1036 | 1019 | * should be missed by canceling the wakeup here. |
| 1037 | 1020 | */ |
| 1038 | 1021 | pm_system_cancel_wakeup(); |
| 1039 | − | |
| 1040 | − acpi_s2idle_sync(); | |
| 1022 | + acpi_os_wait_events_complete(); | |
| 1041 | 1023 | |
| 1042 | 1024 | /* |
| 1043 | 1025 | * The SCI is in the "suspended" state now and it cannot produce |
| @@ -1070,7 +1052,8 @@ static void acpi_s2idle_restore(void) · 26 unmodified lines | ||
| 1070 | 1052 | * of GPEs. |
| 1071 | 1053 | */ |
| 1072 | 1054 | acpi_os_wait_events_complete(); /* synchronize GPE processing */ |
| 1073 | − acpi_s2idle_sync(); | |
| 1055 | + acpi_ec_flush_work(); /* flush the EC driver's workqueues */ | |
| 1056 | + acpi_os_wait_events_complete(); /* synchronize Notify handling */ | |
| 1074 | 1057 | |
| 1075 | 1058 | s2idle_wakeup = false; |
| 1076 | 1059 | |
| @@ -365,6 +365,7 @@ struct device_link *device_link_add(struct device *consumer, · 364 unmodified lines | ||
| 365 | 365 | link->flags |= DL_FLAG_STATELESS; |
| 366 | 366 | goto reorder; |
| 367 | 367 | } else { |
| 368 | + link->flags |= DL_FLAG_STATELESS; | |
| 368 | 369 | goto out; |
| 369 | 370 | } |
| 370 | 371 | } |
| @@ -433,12 +434,16 @@ struct device_link *device_link_add(struct device *consumer, · 62 unmodified lines | ||
| 433 | 434 | flags & DL_FLAG_PM_RUNTIME) |
| 434 | 435 | pm_runtime_resume(supplier); |
| 435 | 436 | |
| 437 | + list_add_tail_rcu(&link->s_node, &supplier->links.consumers); | |
| 438 | + list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); | |
| 439 | + | |
| 436 | 440 | if (flags & DL_FLAG_SYNC_STATE_ONLY) { |
| 437 | 441 | dev_dbg(consumer, |
| 438 | 442 | "Linked as a sync state only consumer to %s\n", |
| 439 | 443 | dev_name(supplier)); |
| 440 | 444 | goto out; |
| 441 | 445 | } |
| 446 | + | |
| 442 | 447 | reorder: |
| 443 | 448 | /* |
| 444 | 449 | * Move the consumer and all of the devices depending on it to the end |
| @@ -449,12 +454,9 @@ reorder: · 4 unmodified lines | ||
| 449 | 454 | */ |
| 450 | 455 | device_reorder_to_tail(consumer, NULL); |
| 451 | 456 | |
| 452 | − list_add_tail_rcu(&link->s_node, &supplier->links.consumers); | |
| 453 | − list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); | |
| 454 | − | |
| 455 | 457 | dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); |
| 456 | 458 | |
| 457 | − out: | |
| 459 | +out: | |
| 458 | 460 | device_pm_unlock(); |
| 459 | 461 | device_links_write_unlock(); |
| 460 | 462 | |
| @@ -829,6 +831,13 @@ static void __device_links_supplier_defer_sync(struct device *sup) · 368 unmodified lines | ||
| 829 | 831 | list_add_tail(&sup->links.defer_sync, &deferred_sync); |
| 830 | 832 | } |
| 831 | 833 | |
| 834 | +static void device_link_drop_managed(struct device_link *link) | |
| 835 | +{ | |
| 836 | + link->flags &= ~DL_FLAG_MANAGED; | |
| 837 | + WRITE_ONCE(link->status, DL_STATE_NONE); | |
| 838 | + kref_put(&link->kref, __device_link_del); | |
| 839 | +} | |
| 840 | + | |
| 832 | 841 | /** |
| 833 | 842 | * device_links_driver_bound - Update device links after probing its driver. |
| 834 | 843 | * @dev: Device to update the links for. |
| @@ -842,7 +851,7 @@ static void __device_links_supplier_defer_sync(struct device *sup) · 7 unmodified lines | ||
| 842 | 851 | */ |
| 843 | 852 | void device_links_driver_bound(struct device *dev) |
| 844 | 853 | { |
| 845 | − struct device_link *link; | |
| 854 | + struct device_link *link, *ln; | |
| 846 | 855 | LIST_HEAD(sync_list); |
| 847 | 856 | |
| 848 | 857 | /* |
| @@ -882,18 +891,35 @@ void device_links_driver_bound(struct device *dev) · 33 unmodified lines | ||
| 882 | 891 | else |
| 883 | 892 | __device_links_queue_sync_state(dev, &sync_list); |
| 884 | 893 | |
| 885 | − list_for_each_entry(link, &dev->links.suppliers, c_node) { | |
| 894 | + list_for_each_entry_safe(link, ln, &dev->links.suppliers, c_node) { | |
| 895 | + struct device *supplier; | |
| 896 | + | |
| 886 | 897 | if (!(link->flags & DL_FLAG_MANAGED)) |
| 887 | 898 | continue; |
| 888 | 899 | |
| 889 | − WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); | |
| 890 | − WRITE_ONCE(link->status, DL_STATE_ACTIVE); | |
| 900 | + supplier = link->supplier; | |
| 901 | + if (link->flags & DL_FLAG_SYNC_STATE_ONLY) { | |
| 902 | + /* | |
| 903 | + * When DL_FLAG_SYNC_STATE_ONLY is set, it means no | |
| 904 | + * other DL_MANAGED_LINK_FLAGS have been set. So, it's | |
| 905 | + * save to drop the managed link completely. | |
| 906 | + */ | |
| 907 | + device_link_drop_managed(link); | |
| 908 | + } else { | |
| 909 | + WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); | |
| 910 | + WRITE_ONCE(link->status, DL_STATE_ACTIVE); | |
| 911 | + } | |
| 891 | 912 | |
| 913 | + /* | |
| 914 | + * This needs to be done even for the deleted | |
| 915 | + * DL_FLAG_SYNC_STATE_ONLY device link in case it was the last | |
| 916 | + * device link that was preventing the supplier from getting a | |
| 917 | + * sync_state() call. | |
| 918 | + */ | |
| 892 | 919 | if (defer_sync_state_count) |
| 893 | − __device_links_supplier_defer_sync(link->supplier); | |
| 920 | + __device_links_supplier_defer_sync(supplier); | |
| 894 | 921 | else |
| 895 | − __device_links_queue_sync_state(link->supplier, | |
| 896 | − &sync_list); | |
| 922 | + __device_links_queue_sync_state(supplier, &sync_list); | |
| 897 | 923 | } |
| 898 | 924 | |
| 899 | 925 | dev->links.status = DL_DEV_DRIVER_BOUND; |
| @@ -903,13 +929,6 @@ void device_links_driver_bound(struct device *dev) · 3 unmodified lines | ||
| 903 | 929 | device_links_flush_sync_list(&sync_list, dev); |
| 904 | 930 | } |
| 905 | 931 | |
| 906 | −static void device_link_drop_managed(struct device_link *link) | |
| 907 | −{ | |
| 908 | − link->flags &= ~DL_FLAG_MANAGED; | |
| 909 | − WRITE_ONCE(link->status, DL_STATE_NONE); | |
| 910 | − kref_put(&link->kref, __device_link_del); | |
| 911 | −} | |
| 912 | − | |
| 913 | 932 | /** |
| 914 | 933 | * __device_links_no_driver - Update links of a device without a driver. |
| 915 | 934 | * @dev: Device without a drvier. |
| @@ -1535,6 +1535,13 @@ static void null_config_discard(struct nullb *nullb) · 1534 unmodified lines | ||
| 1535 | 1535 | { |
| 1536 | 1536 | if (nullb->dev->discard == false) |
| 1537 | 1537 | return; |
| 1538 | + | |
| 1539 | + if (nullb->dev->zoned) { | |
| 1540 | + nullb->dev->discard = false; | |
| 1541 | + pr_info("discard option is ignored in zoned mode\n"); | |
| 1542 | + return; | |
| 1543 | + } | |
| 1544 | + | |
| 1538 | 1545 | nullb->q->limits.discard_granularity = nullb->dev->blocksize; |
| 1539 | 1546 | nullb->q->limits.discard_alignment = nullb->dev->blocksize; |
| 1540 | 1547 | blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9); |
| @@ -23,6 +23,10 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) · 22 unmodified lines | ||
| 23 | 23 | pr_err("zone_size must be power-of-two\n"); |
| 24 | 24 | return -EINVAL; |
| 25 | 25 | } |
| 26 | + if (dev->zone_size > dev->size) { | |
| 27 | + pr_err("Zone size larger than device capacity\n"); | |
| 28 | + return -EINVAL; | |
| 29 | + } | |
| 26 | 30 | |
| 27 | 31 | dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT; |
| 28 | 32 | dev->nr_zones = dev_size >> |
| @@ -291,6 +291,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) · 290 unmodified lines | ||
| 291 | 291 | } |
| 292 | 292 | |
| 293 | 293 | /* Setup cmd context */ |
| 294 | + ret = -ENOMEM; | |
| 294 | 295 | mhi_ctxt->cmd_ctxt = mhi_alloc_coherent(mhi_cntrl, |
| 295 | 296 | sizeof(*mhi_ctxt->cmd_ctxt) * |
| 296 | 297 | NR_OF_CMD_RINGS, |
| @@ -1100,6 +1101,7 @@ static int mhi_driver_probe(struct device *dev) · 803 unmodified lines | ||
| 1100 | 1101 | } |
| 1101 | 1102 | } |
| 1102 | 1103 | |
| 1104 | + ret = -EINVAL; | |
| 1103 | 1105 | if (dl_chan) { |
| 1104 | 1106 | /* |
| 1105 | 1107 | * If channel supports LPM notifications then status_cb should |
| @@ -1947,8 +1947,8 @@ static int ssif_adapter_handler(struct device *adev, void *opaque) · 1946 unmodified lines | ||
| 1947 | 1947 | if (adev->type != &i2c_adapter_type) |
| 1948 | 1948 | return 0; |
| 1949 | 1949 | |
| 1950 | − addr_info->added_client = i2c_new_device(to_i2c_adapter(adev), | |
| 1951 | − &addr_info->binfo); | |
| 1950 | + addr_info->added_client = i2c_new_client_device(to_i2c_adapter(adev), | |
| 1951 | + &addr_info->binfo); | |
| 1952 | 1952 | |
| 1953 | 1953 | if (!addr_info->adapter_name) |
| 1954 | 1954 | return 1; /* Only try the first I2C adapter by default. */ |
| @@ -3519,6 +3519,9 @@ static int __clk_core_init(struct clk_core *core) · 3518 unmodified lines | ||
| 3519 | 3519 | out: |
| 3520 | 3520 | clk_pm_runtime_put(core); |
| 3521 | 3521 | unlock: |
| 3522 | + if (ret) | |
| 3523 | + hlist_del_init(&core->child_node); | |
| 3524 | + | |
| 3522 | 3525 | clk_prepare_unlock(); |
| 3523 | 3526 | |
| 3524 | 3527 | if (!ret) |
| @@ -156,8 +156,6 @@ PNAME(mux_i2s_out_p) = { "i2s1_pre", "xin12m" }; · 155 unmodified lines | ||
| 156 | 156 | PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" }; |
| 157 | 157 | PNAME(mux_sclk_spdif_p) = { "sclk_spdif_src", "spdif_frac", "xin12m" }; |
| 158 | 158 | |
| 159 | −PNAME(mux_aclk_gpu_pre_p) = { "cpll_gpu", "gpll_gpu", "hdmiphy_gpu", "usb480m_gpu" }; | |
| 160 | − | |
| 161 | 159 | PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; |
| 162 | 160 | PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; |
| 163 | 161 | PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; |
| @@ -468,16 +466,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { · 304 unmodified lines | ||
| 468 | 466 | RK2928_CLKSEL_CON(24), 6, 10, DFLAGS, |
| 469 | 467 | RK2928_CLKGATE_CON(2), 8, GFLAGS), |
| 470 | 468 | |
| 471 | − GATE(0, "cpll_gpu", "cpll", 0, | |
| 472 | − RK2928_CLKGATE_CON(3), 13, GFLAGS), | |
| 473 | − GATE(0, "gpll_gpu", "gpll", 0, | |
| 474 | − RK2928_CLKGATE_CON(3), 13, GFLAGS), | |
| 475 | − GATE(0, "hdmiphy_gpu", "hdmiphy", 0, | |
| 476 | − RK2928_CLKGATE_CON(3), 13, GFLAGS), | |
| 477 | − GATE(0, "usb480m_gpu", "usb480m", 0, | |
| 469 | + COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_4plls_p, 0, | |
| 470 | + RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS, | |
| 478 | 471 | RK2928_CLKGATE_CON(3), 13, GFLAGS), |
| 479 | − COMPOSITE_NOGATE(0, "aclk_gpu_pre", mux_aclk_gpu_pre_p, 0, | |
| 480 | − RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS), | |
| 481 | 472 | |
| 482 | 473 | COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_2plls_p, 0, |
| 483 | 474 | RK2928_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS, |
| @@ -582,8 +573,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { · 98 unmodified lines | ||
| 582 | 573 | GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS), |
| 583 | 574 | |
| 584 | 575 | /* PD_GPU */ |
| 585 | − GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), | |
| 586 | − GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS), | |
| 576 | + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), | |
| 577 | + GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), | |
| 587 | 578 | |
| 588 | 579 | /* PD_BUS */ |
| 589 | 580 | GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), |
| @@ -1292,7 +1292,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { · 1291 unmodified lines | ||
| 1292 | 1292 | { TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
| 1293 | 1293 | { TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
| 1294 | 1294 | { TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
| 1295 | − { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 0 }, | |
| 1295 | + { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 282240000, 0 }, | |
| 1296 | 1296 | { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 0 }, |
| 1297 | 1297 | { TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
| 1298 | 1298 | { TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
| @@ -212,7 +212,7 @@ static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = { · 211 unmodified lines | ||
| 212 | 212 | }; |
| 213 | 213 | |
| 214 | 214 | static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = { |
| 215 | − { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, | |
| 215 | + { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk-24mhz-clkctrl:0000:0" }, | |
| 216 | 216 | { 0 }, |
| 217 | 217 | }; |
| 218 | 218 | |
| @@ -255,24 +255,53 @@ static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec, · 254 unmodified lines | ||
| 255 | 255 | return entry->clk; |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | +/* Get clkctrl clock base name based on clkctrl_name or dts node */ | |
| 259 | +static const char * __init clkctrl_get_clock_name(struct device_node *np, | |
| 260 | + const char *clkctrl_name, | |
| 261 | + int offset, int index, | |
| 262 | + bool legacy_naming) | |
| 263 | +{ | |
| 264 | + char *clock_name; | |
| 265 | + | |
| 266 | + /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */ | |
| 267 | + if (clkctrl_name && !legacy_naming) { | |
| 268 | + clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", | |
| 269 | + clkctrl_name, offset, index); | |
| 270 | + strreplace(clock_name, '_', '-'); | |
| 271 | + | |
| 272 | + return clock_name; | |
| 273 | + } | |
| 274 | + | |
| 275 | + /* l4per:1234:0 old style naming based on clkctrl_name */ | |
| 276 | + if (clkctrl_name) | |
| 277 | + return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d", | |
| 278 | + clkctrl_name, offset, index); | |
| 279 | + | |
| 280 | + /* l4per_cm:1234:0 old style naming based on parent node name */ | |
| 281 | + if (legacy_naming) | |
| 282 | + return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d", | |
| 283 | + np->parent, offset, index); | |
| 284 | + | |
| 285 | + /* l4per-clkctrl:1234:0 style naming based on node name */ | |
| 286 | + return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index); | |
| 287 | +} | |
| 288 | + | |
| 258 | 289 | static int __init |
| 259 | 290 | _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, |
| 260 | 291 | struct device_node *node, struct clk_hw *clk_hw, |
| 261 | 292 | u16 offset, u8 bit, const char * const *parents, |
| 262 | − int num_parents, const struct clk_ops *ops) | |
| 293 | + int num_parents, const struct clk_ops *ops, | |
| 294 | + const char *clkctrl_name) | |
| 263 | 295 | { |
| 264 | 296 | struct clk_init_data init = { NULL }; |
| 265 | 297 | struct clk *clk; |
| 266 | 298 | struct omap_clkctrl_clk *clkctrl_clk; |
| 267 | 299 | int ret = 0; |
| 268 | 300 | |
| 269 | − if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) | |
| 270 | − init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d", | |
| 271 | − node->parent, node, offset, | |
| 272 | − bit); | |
| 273 | − else | |
| 274 | − init.name = kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", node, | |
| 275 | − offset, bit); | |
| 301 | + init.name = clkctrl_get_clock_name(node, clkctrl_name, offset, bit, | |
| 302 | + ti_clk_get_features()->flags & | |
| 303 | + TI_CLK_CLKCTRL_COMPAT); | |
| 304 | + | |
| 276 | 305 | clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); |
| 277 | 306 | if (!init.name || !clkctrl_clk) { |
| 278 | 307 | ret = -ENOMEM; |
| @@ -309,7 +338,7 @@ static void __init · 30 unmodified lines | ||
| 309 | 338 | _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider, |
| 310 | 339 | struct device_node *node, u16 offset, |
| 311 | 340 | const struct omap_clkctrl_bit_data *data, |
| 312 | − void __iomem *reg) | |
| 341 | + void __iomem *reg, const char *clkctrl_name) | |
| 313 | 342 | { |
| 314 | 343 | struct clk_hw_omap *clk_hw; |
| 315 | 344 | |
| @@ -322,7 +351,7 @@ _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider, · 6 unmodified lines | ||
| 322 | 351 | |
| 323 | 352 | if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset, |
| 324 | 353 | data->bit, data->parents, 1, |
| 325 | − &omap_gate_clk_ops)) | |
| 354 | + &omap_gate_clk_ops, clkctrl_name)) | |
| 326 | 355 | kfree(clk_hw); |
| 327 | 356 | } |
| 328 | 357 | |
| @@ -330,7 +359,7 @@ static void __init · 1 unmodified line | ||
| 330 | 359 | _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider, |
| 331 | 360 | struct device_node *node, u16 offset, |
| 332 | 361 | const struct omap_clkctrl_bit_data *data, |
| 333 | − void __iomem *reg) | |
| 362 | + void __iomem *reg, const char *clkctrl_name) | |
| 334 | 363 | { |
| 335 | 364 | struct clk_omap_mux *mux; |
| 336 | 365 | int num_parents = 0; |
| @@ -357,7 +386,7 @@ _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider, · 20 unmodified lines | ||
| 357 | 386 | |
| 358 | 387 | if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset, |
| 359 | 388 | data->bit, data->parents, num_parents, |
| 360 | − &ti_clk_mux_ops)) | |
| 389 | + &ti_clk_mux_ops, clkctrl_name)) | |
| 361 | 390 | kfree(mux); |
| 362 | 391 | } |
| 363 | 392 | |
| @@ -365,7 +394,7 @@ static void __init · 1 unmodified line | ||
| 365 | 394 | _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, |
| 366 | 395 | struct device_node *node, u16 offset, |
| 367 | 396 | const struct omap_clkctrl_bit_data *data, |
| 368 | − void __iomem *reg) | |
| 397 | + void __iomem *reg, const char *clkctrl_name) | |
| 369 | 398 | { |
| 370 | 399 | struct clk_omap_divider *div; |
| 371 | 400 | const struct omap_clkctrl_div_data *div_data = data->data; |
| @@ -393,7 +422,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, · 21 unmodified lines | ||
| 393 | 422 | |
| 394 | 423 | if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset, |
| 395 | 424 | data->bit, data->parents, 1, |
| 396 | − &ti_clk_divider_ops)) | |
| 425 | + &ti_clk_divider_ops, clkctrl_name)) | |
| 397 | 426 | kfree(div); |
| 398 | 427 | } |
| 399 | 428 | |
| @@ -401,7 +430,7 @@ static void __init · 1 unmodified line | ||
| 401 | 430 | _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider, |
| 402 | 431 | struct device_node *node, |
| 403 | 432 | const struct omap_clkctrl_reg_data *data, |
| 404 | − void __iomem *reg) | |
| 433 | + void __iomem *reg, const char *clkctrl_name) | |
| 405 | 434 | { |
| 406 | 435 | const struct omap_clkctrl_bit_data *bits = data->bit_data; |
| 407 | 436 | |
| @@ -412,17 +441,17 @@ _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider, · 4 unmodified lines | ||
| 412 | 441 | switch (bits->type) { |
| 413 | 442 | case TI_CLK_GATE: |
| 414 | 443 | _ti_clkctrl_setup_gate(provider, node, data->offset, |
| 415 | − bits, reg); | |
| 444 | + bits, reg, clkctrl_name); | |
| 416 | 445 | break; |
| 417 | 446 | |
| 418 | 447 | case TI_CLK_DIVIDER: |
| 419 | 448 | _ti_clkctrl_setup_div(provider, node, data->offset, |
| 420 | − bits, reg); | |
| 449 | + bits, reg, clkctrl_name); | |
| 421 | 450 | break; |
| 422 | 451 | |
| 423 | 452 | case TI_CLK_MUX: |
| 424 | 453 | _ti_clkctrl_setup_mux(provider, node, data->offset, |
| 425 | − bits, reg); | |
| 454 | + bits, reg, clkctrl_name); | |
| 426 | 455 | break; |
| 427 | 456 | |
| 428 | 457 | default: |
| @@ -461,42 +490,10 @@ static char * __init clkctrl_get_name(struct device_node *np) · 32 unmodified lines | ||
| 461 | 490 | return name; |
| 462 | 491 | } |
| 463 | 492 | } |
| 464 | − of_node_put(np); | |
| 465 | 493 | |
| 466 | 494 | return NULL; |
| 467 | 495 | } |
| 468 | 496 | |
| 469 | −/* Get clkctrl clock base name based on clkctrl_name or dts node */ | |
| 470 | −static const char * __init clkctrl_get_clock_name(struct device_node *np, | |
| 471 | − const char *clkctrl_name, | |
| 472 | − int offset, int index, | |
| 473 | − bool legacy_naming) | |
| 474 | −{ | |
| 475 | − char *clock_name; | |
| 476 | − | |
| 477 | − /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */ | |
| 478 | − if (clkctrl_name && !legacy_naming) { | |
| 479 | − clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", | |
| 480 | − clkctrl_name, offset, index); | |
| 481 | − strreplace(clock_name, '_', '-'); | |
| 482 | − | |
| 483 | − return clock_name; | |
| 484 | − } | |
| 485 | − | |
| 486 | − /* l4per:1234:0 old style naming based on clkctrl_name */ | |
| 487 | − if (clkctrl_name) | |
| 488 | − return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d", | |
| 489 | − clkctrl_name, offset, index); | |
| 490 | − | |
| 491 | − /* l4per_cm:1234:0 old style naming based on parent node name */ | |
| 492 | − if (legacy_naming) | |
| 493 | − return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d", | |
| 494 | − np->parent, offset, index); | |
| 495 | − | |
| 496 | − /* l4per-clkctrl:1234:0 style naming based on node name */ | |
| 497 | − return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index); | |
| 498 | −} | |
| 499 | − | |
| 500 | 497 | static void __init _ti_omap4_clkctrl_setup(struct device_node *node) |
| 501 | 498 | { |
| 502 | 499 | struct omap_clkctrl_provider *provider; |
| @@ -664,7 +661,7 @@ clkdm_found: · 161 unmodified lines | ||
| 664 | 661 | hw->enable_reg.ptr = provider->base + reg_data->offset; |
| 665 | 662 | |
| 666 | 663 | _ti_clkctrl_setup_subclks(provider, node, reg_data, |
| 667 | − hw->enable_reg.ptr); | |
| 664 | + hw->enable_reg.ptr, clkctrl_name); | |
| 668 | 665 | |
| 669 | 666 | if (reg_data->flags & CLKF_SW_SUP) |
| 670 | 667 | hw->enable_bit = MODULEMODE_SWCTRL; |
| @@ -206,6 +206,7 @@ static int integrator_impd1_clk_spawn(struct device *dev, · 205 unmodified lines | ||
| 206 | 206 | return -ENODEV; |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | + of_property_read_string(np, "clock-output-names", &name); | |
| 209 | 210 | parent_name = of_clk_get_parent_name(np, 0); |
| 210 | 211 | clk = icst_clk_setup(NULL, desc, name, parent_name, map, |
| 211 | 212 | ICST_INTEGRATOR_IM_PD1); |
| @@ -22,6 +22,7 @@ int dev_dax_kmem_probe(struct device *dev) · 21 unmodified lines | ||
| 22 | 22 | resource_size_t kmem_size; |
| 23 | 23 | resource_size_t kmem_end; |
| 24 | 24 | struct resource *new_res; |
| 25 | + const char *new_res_name; | |
| 25 | 26 | int numa_node; |
| 26 | 27 | int rc; |
| 27 | 28 | |
| @@ -48,11 +49,16 @@ int dev_dax_kmem_probe(struct device *dev) · 20 unmodified lines | ||
| 48 | 49 | kmem_size &= ~(memory_block_size_bytes() - 1); |
| 49 | 50 | kmem_end = kmem_start + kmem_size; |
| 50 | 51 | |
| 51 | − /* Region is permanently reserved. Hot-remove not yet implemented. */ | |
| 52 | − new_res = request_mem_region(kmem_start, kmem_size, dev_name(dev)); | |
| 52 | + new_res_name = kstrdup(dev_name(dev), GFP_KERNEL); | |
| 53 | + if (!new_res_name) | |
| 54 | + return -ENOMEM; | |
| 55 | + | |
| 56 | + /* Region is permanently reserved if hotremove fails. */ | |
| 57 | + new_res = request_mem_region(kmem_start, kmem_size, new_res_name); | |
| 53 | 58 | if (!new_res) { |
| 54 | 59 | dev_warn(dev, "could not reserve region [%pa-%pa]\n", |
| 55 | 60 | &kmem_start, &kmem_end); |
| 61 | + kfree(new_res_name); | |
| 56 | 62 | return -EBUSY; |
| 57 | 63 | } |
| 58 | 64 | |
| @@ -63,12 +69,12 @@ int dev_dax_kmem_probe(struct device *dev) · 4 unmodified lines | ||
| 63 | 69 | * unknown to us that will break add_memory() below. |
| 64 | 70 | */ |
| 65 | 71 | new_res->flags = IORESOURCE_SYSTEM_RAM; |
| 66 | − new_res->name = dev_name(dev); | |
| 67 | 72 | |
| 68 | 73 | rc = add_memory(numa_node, new_res->start, resource_size(new_res)); |
| 69 | 74 | if (rc) { |
| 70 | 75 | release_resource(new_res); |
| 71 | 76 | kfree(new_res); |
| 77 | + kfree(new_res_name); | |
| 72 | 78 | return rc; |
| 73 | 79 | } |
| 74 | 80 | dev_dax->dax_kmem_res = new_res; |
| @@ -83,6 +89,7 @@ static int dev_dax_kmem_remove(struct device *dev) · 8 unmodified lines | ||
| 83 | 89 | struct resource *res = dev_dax->dax_kmem_res; |
| 84 | 90 | resource_size_t kmem_start = res->start; |
| 85 | 91 | resource_size_t kmem_size = resource_size(res); |
| 92 | + const char *res_name = res->name; | |
| 86 | 93 | int rc; |
| 87 | 94 | |
| 88 | 95 | /* |
| @@ -102,6 +109,7 @@ static int dev_dax_kmem_remove(struct device *dev) · 13 unmodified lines | ||
| 102 | 109 | /* Release and free dax resources */ |
| 103 | 110 | release_resource(res); |
| 104 | 111 | kfree(res); |
| 112 | + kfree(res_name); | |
| 105 | 113 | dev_dax->dax_kmem_res = NULL; |
| 106 | 114 | |
| 107 | 115 | return 0; |
| @@ -1166,10 +1166,11 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp) · 1165 unmodified lines | ||
| 1166 | 1166 | mutex_unlock(&info->lock); |
| 1167 | 1167 | return ret; |
| 1168 | 1168 | } else if (dmatest_run) { |
| 1169 | − if (is_threaded_test_pending(info)) | |
| 1170 | − start_threaded_tests(info); | |
| 1171 | − else | |
| 1172 | − pr_info("Could not start test, no channels configured\n"); | |
| 1169 | + if (!is_threaded_test_pending(info)) { | |
| 1170 | + pr_info("No channels configured, continue with any\n"); | |
| 1171 | + add_threaded_test(info); | |
| 1172 | + } | |
| 1173 | + start_threaded_tests(info); | |
| 1173 | 1174 | } else { |
| 1174 | 1175 | stop_threaded_test(info); |
| 1175 | 1176 | } |
| @@ -62,6 +62,13 @@ int idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id) · 61 unmodified lines | ||
| 62 | 62 | perm.ignore = 0; |
| 63 | 63 | iowrite32(perm.bits, idxd->reg_base + offset); |
| 64 | 64 | |
| 65 | + /* | |
| 66 | + * A readback from the device ensures that any previously generated | |
| 67 | + * completion record writes are visible to software based on PCI | |
| 68 | + * ordering rules. | |
| 69 | + */ | |
| 70 | + perm.bits = ioread32(idxd->reg_base + offset); | |
| 71 | + | |
| 65 | 72 | return 0; |
| 66 | 73 | } |
| 67 | 74 | |
| @@ -173,6 +173,7 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, · 172 unmodified lines | ||
| 173 | 173 | struct llist_node *head; |
| 174 | 174 | int queued = 0; |
| 175 | 175 | |
| 176 | + *processed = 0; | |
| 176 | 177 | head = llist_del_all(&irq_entry->pending_llist); |
| 177 | 178 | if (!head) |
| 178 | 179 | return 0; |
| @@ -197,6 +198,7 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, · 18 unmodified lines | ||
| 197 | 198 | struct list_head *node, *next; |
| 198 | 199 | int queued = 0; |
| 199 | 200 | |
| 201 | + *processed = 0; | |
| 200 | 202 | if (list_empty(&irq_entry->work_list)) |
| 201 | 203 | return 0; |
| 202 | 204 | |
| @@ -218,10 +220,9 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, · 15 unmodified lines | ||
| 218 | 220 | return queued; |
| 219 | 221 | } |
| 220 | 222 | |
| 221 | −irqreturn_t idxd_wq_thread(int irq, void *data) | |
| 223 | +static int idxd_desc_process(struct idxd_irq_entry *irq_entry) | |
| 222 | 224 | { |
| 223 | − struct idxd_irq_entry *irq_entry = data; | |
| 224 | − int rc, processed = 0, retry = 0; | |
| 225 | + int rc, processed, total = 0; | |
| 225 | 226 | |
| 226 | 227 | /* |
| 227 | 228 | * There are two lists we are processing. The pending_llist is where |
| @@ -244,15 +245,26 @@ irqreturn_t idxd_wq_thread(int irq, void *data) · 16 unmodified lines | ||
| 244 | 245 | */ |
| 245 | 246 | do { |
| 246 | 247 | rc = irq_process_work_list(irq_entry, &processed); |
| 247 | − if (rc != 0) { | |
| 248 | − retry++; | |
| 248 | + total += processed; | |
| 249 | + if (rc != 0) | |
| 249 | 250 | continue; |
| 250 | − } | |
| 251 | 251 | |
| 252 | 252 | rc = irq_process_pending_llist(irq_entry, &processed); |
| 253 | − } while (rc != 0 && retry != 10); | |
| 253 | + total += processed; | |
| 254 | + } while (rc != 0); | |
| 255 | + | |
| 256 | + return total; | |
| 257 | +} | |
| 258 | + | |
| 259 | +irqreturn_t idxd_wq_thread(int irq, void *data) | |
| 260 | +{ | |
| 261 | + struct idxd_irq_entry *irq_entry = data; | |
| 262 | + int processed; | |
| 254 | 263 | |
| 264 | + processed = idxd_desc_process(irq_entry); | |
| 255 | 265 | idxd_unmask_msix_vector(irq_entry->idxd, irq_entry->id); |
| 266 | + /* catch anything unprocessed after unmasking */ | |
| 267 | + processed += idxd_desc_process(irq_entry); | |
| 256 | 268 | |
| 257 | 269 | if (processed == 0) |
| 258 | 270 | return IRQ_NONE; |
| @@ -175,13 +175,11 @@ struct owl_dma_txd { · 174 unmodified lines | ||
| 175 | 175 | * @id: physical index to this channel |
| 176 | 176 | * @base: virtual memory base for the dma channel |
| 177 | 177 | * @vchan: the virtual channel currently being served by this physical channel |
| 178 | − * @lock: a lock to use when altering an instance of this struct | |
| 179 | 178 | */ |
| 180 | 179 | struct owl_dma_pchan { |
| 181 | 180 | u32 id; |
| 182 | 181 | void __iomem *base; |
| 183 | 182 | struct owl_dma_vchan *vchan; |
| 184 | − spinlock_t lock; | |
| 185 | 183 | }; |
| 186 | 184 | |
| 187 | 185 | /** |
| @@ -437,14 +435,14 @@ static struct owl_dma_pchan *owl_dma_get_pchan(struct owl_dma *od, · 249 unmodified lines | ||
| 437 | 435 | for (i = 0; i < od->nr_pchans; i++) { |
| 438 | 436 | pchan = &od->pchans[i]; |
| 439 | 437 | |
| 440 | − spin_lock_irqsave(&pchan->lock, flags); | |
| 438 | + spin_lock_irqsave(&od->lock, flags); | |
| 441 | 439 | if (!pchan->vchan) { |
| 442 | 440 | pchan->vchan = vchan; |
| 443 | − spin_unlock_irqrestore(&pchan->lock, flags); | |
| 441 | + spin_unlock_irqrestore(&od->lock, flags); | |
| 444 | 442 | break; |
| 445 | 443 | } |
| 446 | 444 | |
| 447 | − spin_unlock_irqrestore(&pchan->lock, flags); | |
| 445 | + spin_unlock_irqrestore(&od->lock, flags); | |
| 448 | 446 | } |
| 449 | 447 | |
| 450 | 448 | return pchan; |
| @@ -900,7 +900,7 @@ static int tegra_adma_probe(struct platform_device *pdev) · 899 unmodified lines | ||
| 900 | 900 | ret = dma_async_device_register(&tdma->dma_dev); |
| 901 | 901 | if (ret < 0) { |
| 902 | 902 | dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret); |
| 903 | − goto irq_dispose; | |
| 903 | + goto rpm_put; | |
| 904 | 904 | } |
| 905 | 905 | |
| 906 | 906 | ret = of_dma_controller_register(pdev->dev.of_node, |
| @@ -2156,7 +2156,8 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, · 2155 unmodified lines | ||
| 2156 | 2156 | d->residue += sg_dma_len(sgent); |
| 2157 | 2157 | } |
| 2158 | 2158 | |
| 2159 | − cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, CPPI5_TR_CSF_EOP); | |
| 2159 | + cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, | |
| 2160 | + CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); | |
| 2160 | 2161 | |
| 2161 | 2162 | return d; |
| 2162 | 2163 | } |
| @@ -2733,7 +2734,8 @@ udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, · 570 unmodified lines | ||
| 2733 | 2734 | tr_req[1].dicnt3 = 1; |
| 2734 | 2735 | } |
| 2735 | 2736 | |
| 2736 | − cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, CPPI5_TR_CSF_EOP); | |
| 2737 | + cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, | |
| 2738 | + CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); | |
| 2737 | 2739 | |
| 2738 | 2740 | if (uc->config.metadata_size) |
| 2739 | 2741 | d->vd.tx.metadata_ops = &metadata_ops; |
| @@ -434,6 +434,7 @@ static void zynqmp_dma_free_descriptor(struct zynqmp_dma_chan *chan, · 433 unmodified lines | ||
| 434 | 434 | struct zynqmp_dma_desc_sw *child, *next; |
| 435 | 435 | |
| 436 | 436 | chan->desc_free_cnt++; |
| 437 | + list_del(&sdesc->node); | |
| 437 | 438 | list_add_tail(&sdesc->node, &chan->free_list); |
| 438 | 439 | list_for_each_entry_safe(child, next, &sdesc->tx_list, node) { |
| 439 | 440 | chan->desc_free_cnt++; |
| @@ -608,8 +609,6 @@ static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan) · 168 unmodified lines | ||
| 608 | 609 | dma_async_tx_callback callback; |
| 609 | 610 | void *callback_param; |
| 610 | 611 | |
| 611 | − list_del(&desc->node); | |
| 612 | − | |
| 613 | 612 | callback = desc->async_tx.callback; |
| 614 | 613 | callback_param = desc->async_tx.callback_param; |
| 615 | 614 | if (callback) { |
| @@ -407,6 +407,58 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, · 406 unmodified lines | ||
| 407 | 407 | } |
| 408 | 408 | } |
| 409 | 409 | |
| 410 | +static const char * const fw_err_rec_type_strs[] = { | |
| 411 | + "IPF SAL Error Record", | |
| 412 | + "SOC Firmware Error Record Type1 (Legacy CrashLog Support)", | |
| 413 | + "SOC Firmware Error Record Type2", | |
| 414 | +}; | |
| 415 | + | |
| 416 | +static void cper_print_fw_err(const char *pfx, | |
| 417 | + struct acpi_hest_generic_data *gdata, | |
| 418 | + const struct cper_sec_fw_err_rec_ref *fw_err) | |
| 419 | +{ | |
| 420 | + void *buf = acpi_hest_get_payload(gdata); | |
| 421 | + u32 offset, length = gdata->error_data_length; | |
| 422 | + | |
| 423 | + printk("%s""Firmware Error Record Type: %s\n", pfx, | |
| 424 | + fw_err->record_type < ARRAY_SIZE(fw_err_rec_type_strs) ? | |
| 425 | + fw_err_rec_type_strs[fw_err->record_type] : "unknown"); | |
| 426 | + printk("%s""Revision: %d\n", pfx, fw_err->revision); | |
| 427 | + | |
| 428 | + /* Record Type based on UEFI 2.7 */ | |
| 429 | + if (fw_err->revision == 0) { | |
| 430 | + printk("%s""Record Identifier: %08llx\n", pfx, | |
| 431 | + fw_err->record_identifier); | |
| 432 | + } else if (fw_err->revision == 2) { | |
| 433 | + printk("%s""Record Identifier: %pUl\n", pfx, | |
| 434 | + &fw_err->record_identifier_guid); | |
| 435 | + } | |
| 436 | + | |
| 437 | + /* | |
| 438 | + * The FW error record may contain trailing data beyond the | |
| 439 | + * structure defined by the specification. As the fields | |
| 440 | + * defined (and hence the offset of any trailing data) vary | |
| 441 | + * with the revision, set the offset to account for this | |
| 442 | + * variation. | |
| 443 | + */ | |
| 444 | + if (fw_err->revision == 0) { | |
| 445 | + /* record_identifier_guid not defined */ | |
| 446 | + offset = offsetof(struct cper_sec_fw_err_rec_ref, | |
| 447 | + record_identifier_guid); | |
| 448 | + } else if (fw_err->revision == 1) { | |
| 449 | + /* record_identifier not defined */ | |
| 450 | + offset = offsetof(struct cper_sec_fw_err_rec_ref, | |
| 451 | + record_identifier); | |
| 452 | + } else { | |
| 453 | + offset = sizeof(*fw_err); | |
| 454 | + } | |
| 455 | + | |
| 456 | + buf += offset; | |
| 457 | + length -= offset; | |
| 458 | + | |
| 459 | + print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, buf, length, true); | |
| 460 | +} | |
| 461 | + | |
| 410 | 462 | static void cper_print_tstamp(const char *pfx, |
| 411 | 463 | struct acpi_hest_generic_data_v300 *gdata) |
| 412 | 464 | { |
| @@ -494,6 +546,16 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata · 81 unmodified lines | ||
| 494 | 546 | else |
| 495 | 547 | goto err_section_too_small; |
| 496 | 548 | #endif |
| 549 | + } else if (guid_equal(sec_type, &CPER_SEC_FW_ERR_REC_REF)) { | |
| 550 | + struct cper_sec_fw_err_rec_ref *fw_err = acpi_hest_get_payload(gdata); | |
| 551 | + | |
| 552 | + printk("%ssection_type: Firmware Error Record Reference\n", | |
| 553 | + newpfx); | |
| 554 | + /* The minimal FW Error Record contains 16 bytes */ | |
| 555 | + if (gdata->error_data_length >= SZ_16) | |
| 556 | + cper_print_fw_err(newpfx, gdata, fw_err); | |
| 557 | + else | |
| 558 | + goto err_section_too_small; | |
| 497 | 559 | } else { |
| 498 | 560 | const void *err = acpi_hest_get_payload(gdata); |
| 499 | 561 | |
| @@ -114,14 +114,16 @@ static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h) · 113 unmodified lines | ||
| 114 | 114 | const u32 color_black = 0x00000000; |
| 115 | 115 | const u32 color_white = 0x00ffffff; |
| 116 | 116 | const u8 *src; |
| 117 | − u8 s8; | |
| 118 | − int m; | |
| 117 | + int m, n, bytes; | |
| 118 | + u8 x; | |
| 119 | 119 | |
| 120 | − src = font->data + c * font->height; | |
| 121 | − s8 = *(src + h); | |
| 120 | + bytes = BITS_TO_BYTES(font->width); | |
| 121 | + src = font->data + c * font->height * bytes + h * bytes; | |
| 122 | 122 | |
| 123 | − for (m = 0; m < 8; m++) { | |
| 124 | − if ((s8 >> (7 - m)) & 1) | |
| 123 | + for (m = 0; m < font->width; m++) { | |
| 124 | + n = m % 8; | |
| 125 | + x = *(src + m / 8); | |
| 126 | + if ((x >> (7 - n)) & 1) | |
| 125 | 127 | *dst = color_white; |
| 126 | 128 | else |
| 127 | 129 | *dst = color_black; |
| @@ -130,11 +130,8 @@ static ssize_t systab_show(struct kobject *kobj, · 129 unmodified lines | ||
| 130 | 130 | if (efi.smbios != EFI_INVALID_TABLE_ADDR) |
| 131 | 131 | str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios); |
| 132 | 132 | |
| 133 | − if (IS_ENABLED(CONFIG_IA64) || IS_ENABLED(CONFIG_X86)) { | |
| 134 | − extern char *efi_systab_show_arch(char *str); | |
| 135 | − | |
| 133 | + if (IS_ENABLED(CONFIG_IA64) || IS_ENABLED(CONFIG_X86)) | |
| 136 | 134 | str = efi_systab_show_arch(str); |
| 137 | − } | |
| 138 | 135 | |
| 139 | 136 | return str - buf; |
| 140 | 137 | } |
| @@ -60,7 +60,11 @@ static struct screen_info *setup_graphics(void) · 59 unmodified lines | ||
| 60 | 60 | si = alloc_screen_info(); |
| 61 | 61 | if (!si) |
| 62 | 62 | return NULL; |
| 63 | − efi_setup_gop(si, &gop_proto, size); | |
| 63 | + status = efi_setup_gop(si, &gop_proto, size); | |
| 64 | + if (status != EFI_SUCCESS) { | |
| 65 | + free_screen_info(si); | |
| 66 | + return NULL; | |
| 67 | + } | |
| 64 | 68 | } |
| 65 | 69 | return si; |
| 66 | 70 | } |
| @@ -92,6 +92,19 @@ extern __pure efi_system_table_t *efi_system_table(void); · 91 unmodified lines | ||
| 92 | 92 | #define EFI_LOCATE_BY_REGISTER_NOTIFY 1 |
| 93 | 93 | #define EFI_LOCATE_BY_PROTOCOL 2 |
| 94 | 94 | |
| 95 | +/* | |
| 96 | + * An efi_boot_memmap is used by efi_get_memory_map() to return the | |
| 97 | + * EFI memory map in a dynamically allocated buffer. | |
| 98 | + * | |
| 99 | + * The buffer allocated for the EFI memory map includes extra room for | |
| 100 | + * a minimum of EFI_MMAP_NR_SLACK_SLOTS additional EFI memory descriptors. | |
| 101 | + * This facilitates the reuse of the EFI memory map buffer when a second | |
| 102 | + * call to ExitBootServices() is needed because of intervening changes to | |
| 103 | + * the EFI memory map. Other related structures, e.g. x86 e820ext, need | |
| 104 | + * to factor in this headroom requirement as well. | |
| 105 | + */ | |
| 106 | +#define EFI_MMAP_NR_SLACK_SLOTS 8 | |
| 107 | + | |
| 95 | 108 | struct efi_boot_memmap { |
| 96 | 109 | efi_memory_desc_t **map; |
| 97 | 110 | unsigned long *map_size; |
| @@ -5,8 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include "efistub.h" |
| 7 | 7 | |
| 8 | −#define EFI_MMAP_NR_SLACK_SLOTS 8 | |
| 9 | − | |
| 10 | 8 | static inline bool mmap_has_headroom(unsigned long buff_size, |
| 11 | 9 | unsigned long map_size, |
| 12 | 10 | unsigned long desc_size) |
| @@ -54,7 +54,7 @@ void efi_retrieve_tpm2_eventlog(void) · 53 unmodified lines | ||
| 54 | 54 | efi_status_t status; |
| 55 | 55 | efi_physical_addr_t log_location = 0, log_last_entry = 0; |
| 56 | 56 | struct linux_efi_tpm_eventlog *log_tbl = NULL; |
| 57 | − struct efi_tcg2_final_events_table *final_events_table; | |
| 57 | + struct efi_tcg2_final_events_table *final_events_table = NULL; | |
| 58 | 58 | unsigned long first_entry_addr, last_entry_addr; |
| 59 | 59 | size_t log_size, last_entry_size; |
| 60 | 60 | efi_bool_t truncated; |
| @@ -127,7 +127,8 @@ void efi_retrieve_tpm2_eventlog(void) · 66 unmodified lines | ||
| 127 | 127 | * Figure out whether any events have already been logged to the |
| 128 | 128 | * final events structure, and if so how much space they take up |
| 129 | 129 | */ |
| 130 | − final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); | |
| 130 | + if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) | |
| 131 | + final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); | |
| 131 | 132 | if (final_events_table && final_events_table->nr_events) { |
| 132 | 133 | struct tcg_pcr_event2_head *header; |
| 133 | 134 | int offset; |
| @@ -606,24 +606,18 @@ static efi_status_t allocate_e820(struct boot_params *params, · 605 unmodified lines | ||
| 606 | 606 | struct setup_data **e820ext, |
| 607 | 607 | u32 *e820ext_size) |
| 608 | 608 | { |
| 609 | − unsigned long map_size, desc_size, buff_size; | |
| 610 | − struct efi_boot_memmap boot_map; | |
| 611 | − efi_memory_desc_t *map; | |
| 609 | + unsigned long map_size, desc_size, map_key; | |
| 612 | 610 | efi_status_t status; |
| 613 | − __u32 nr_desc; | |
| 611 | + __u32 nr_desc, desc_version; | |
| 614 | 612 | |
| 615 | − boot_map.map = ↦ | |
| 616 | − boot_map.map_size = &map_size; | |
| 617 | − boot_map.desc_size = &desc_size; | |
| 618 | − boot_map.desc_ver = NULL; | |
| 619 | − boot_map.key_ptr = NULL; | |
| 620 | − boot_map.buff_size = &buff_size; | |
| 613 | + /* Only need the size of the mem map and size of each mem descriptor */ | |
| 614 | + map_size = 0; | |
| 615 | + status = efi_bs_call(get_memory_map, &map_size, NULL, &map_key, | |
| 616 | + &desc_size, &desc_version); | |
| 617 | + if (status != EFI_BUFFER_TOO_SMALL) | |
| 618 | + return (status != EFI_SUCCESS) ? status : EFI_UNSUPPORTED; | |
| 621 | 619 | |
| 622 | − status = efi_get_memory_map(&boot_map); | |
| 623 | − if (status != EFI_SUCCESS) | |
| 624 | − return status; | |
| 625 | − | |
| 626 | − nr_desc = buff_size / desc_size; | |
| 620 | + nr_desc = map_size / desc_size + EFI_MMAP_NR_SLACK_SLOTS; | |
| 627 | 621 | |
| 628 | 622 | if (nr_desc > ARRAY_SIZE(params->e820_table)) { |
| 629 | 623 | u32 nr_e820ext = nr_desc - ARRAY_SIZE(params->e820_table); |
| @@ -62,8 +62,11 @@ int __init efi_tpm_eventlog_init(void) · 61 unmodified lines | ||
| 62 | 62 | tbl_size = sizeof(*log_tbl) + log_tbl->size; |
| 63 | 63 | memblock_reserve(efi.tpm_log, tbl_size); |
| 64 | 64 | |
| 65 | − if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) | |
| 65 | + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || | |
| 66 | + log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { | |
| 67 | + pr_warn(FW_BUG "TPM Final Events table missing or invalid\n"); | |
| 66 | 68 | goto out; |
| 69 | + } | |
| 67 | 70 | |
| 68 | 71 | final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl)); |
| 69 | 72 | |
| @@ -531,7 +531,7 @@ static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset, · 530 unmodified lines | ||
| 531 | 531 | { |
| 532 | 532 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 533 | 533 | |
| 534 | − switch (config) { | |
| 534 | + switch (pinconf_to_config_param(config)) { | |
| 535 | 535 | case PIN_CONFIG_BIAS_PULL_UP: |
| 536 | 536 | case PIN_CONFIG_BIAS_PULL_DOWN: |
| 537 | 537 | return pca953x_gpio_set_pull_up_down(chip, offset, config); |
| @@ -368,6 +368,7 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d) · 367 unmodified lines | ||
| 368 | 368 | struct tegra_gpio_info *tgi = bank->tgi; |
| 369 | 369 | unsigned int gpio = d->hwirq; |
| 370 | 370 | |
| 371 | + tegra_gpio_irq_mask(d); | |
| 371 | 372 | gpiochip_unlock_as_irq(&tgi->gc, gpio); |
| 372 | 373 | } |
| 373 | 374 | |
| @@ -1158,8 +1158,19 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, · 1157 unmodified lines | ||
| 1158 | 1158 | struct gpioline_info *info) |
| 1159 | 1159 | { |
| 1160 | 1160 | struct gpio_chip *gc = desc->gdev->chip; |
| 1161 | + bool ok_for_pinctrl; | |
| 1161 | 1162 | unsigned long flags; |
| 1162 | 1163 | |
| 1164 | + /* | |
| 1165 | + * This function takes a mutex so we must check this before taking | |
| 1166 | + * the spinlock. | |
| 1167 | + * | |
| 1168 | + * FIXME: find a non-racy way to retrieve this information. Maybe a | |
| 1169 | + * lock common to both frameworks? | |
| 1170 | + */ | |
| 1171 | + ok_for_pinctrl = | |
| 1172 | + pinctrl_gpio_can_use_line(gc->base + info->line_offset); | |
| 1173 | + | |
| 1163 | 1174 | spin_lock_irqsave(&gpio_lock, flags); |
| 1164 | 1175 | |
| 1165 | 1176 | if (desc->name) { |
| @@ -1186,7 +1197,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, · 20 unmodified lines | ||
| 1186 | 1197 | test_bit(FLAG_USED_AS_IRQ, &desc->flags) || |
| 1187 | 1198 | test_bit(FLAG_EXPORT, &desc->flags) || |
| 1188 | 1199 | test_bit(FLAG_SYSFS, &desc->flags) || |
| 1189 | − !pinctrl_gpio_can_use_line(gc->base + info->line_offset)) | |
| 1200 | + !ok_for_pinctrl) | |
| 1190 | 1201 | info->flags |= GPIOLINE_FLAG_KERNEL; |
| 1191 | 1202 | if (test_bit(FLAG_IS_OUT, &desc->flags)) |
| 1192 | 1203 | info->flags |= GPIOLINE_FLAG_IS_OUT; |
| @@ -1227,6 +1238,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 34 unmodified lines | ||
| 1227 | 1238 | void __user *ip = (void __user *)arg; |
| 1228 | 1239 | struct gpio_desc *desc; |
| 1229 | 1240 | __u32 offset; |
| 1241 | + int hwgpio; | |
| 1230 | 1242 | |
| 1231 | 1243 | /* We fail any subsequent ioctl():s when the chip is gone */ |
| 1232 | 1244 | if (!gc) |
| @@ -1259,13 +1271,19 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 26 unmodified lines | ||
| 1259 | 1271 | if (IS_ERR(desc)) |
| 1260 | 1272 | return PTR_ERR(desc); |
| 1261 | 1273 | |
| 1274 | + hwgpio = gpio_chip_hwgpio(desc); | |
| 1275 | + | |
| 1276 | + if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL && | |
| 1277 | + test_bit(hwgpio, priv->watched_lines)) | |
| 1278 | + return -EBUSY; | |
| 1279 | + | |
| 1262 | 1280 | gpio_desc_to_lineinfo(desc, &lineinfo); |
| 1263 | 1281 | |
| 1264 | 1282 | if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) |
| 1265 | 1283 | return -EFAULT; |
| 1266 | 1284 | |
| 1267 | 1285 | if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) |
| 1268 | − set_bit(gpio_chip_hwgpio(desc), priv->watched_lines); | |
| 1286 | + set_bit(hwgpio, priv->watched_lines); | |
| 1269 | 1287 | |
| 1270 | 1288 | return 0; |
| 1271 | 1289 | } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { |
| @@ -1280,7 +1298,12 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 8 unmodified lines | ||
| 1280 | 1298 | if (IS_ERR(desc)) |
| 1281 | 1299 | return PTR_ERR(desc); |
| 1282 | 1300 | |
| 1283 | − clear_bit(gpio_chip_hwgpio(desc), priv->watched_lines); | |
| 1301 | + hwgpio = gpio_chip_hwgpio(desc); | |
| 1302 | + | |
| 1303 | + if (!test_bit(hwgpio, priv->watched_lines)) | |
| 1304 | + return -EBUSY; | |
| 1305 | + | |
| 1306 | + clear_bit(hwgpio, priv->watched_lines); | |
| 1284 | 1307 | return 0; |
| 1285 | 1308 | } |
| 1286 | 1309 | return -EINVAL; |
| @@ -5289,8 +5312,9 @@ static int __init gpiolib_dev_init(void) · 4002 unmodified lines | ||
| 5289 | 5312 | gpiolib_initialized = true; |
| 5290 | 5313 | gpiochip_setup_devs(); |
| 5291 | 5314 | |
| 5292 | − if (IS_ENABLED(CONFIG_OF_DYNAMIC)) | |
| 5293 | − WARN_ON(of_reconfig_notifier_register(&gpio_of_notifier)); | |
| 5315 | +#if IS_ENABLED(CONFIG_OF_DYNAMIC) && IS_ENABLED(CONFIG_OF_GPIO) | |
| 5316 | + WARN_ON(of_reconfig_notifier_register(&gpio_of_notifier)); | |
| 5317 | +#endif /* CONFIG_OF_DYNAMIC && CONFIG_OF_GPIO */ | |
| 5294 | 5318 | |
| 5295 | 5319 | return ret; |
| 5296 | 5320 | } |
| @@ -945,6 +945,7 @@ struct amdgpu_device { · 944 unmodified lines | ||
| 945 | 945 | |
| 946 | 946 | /* s3/s4 mask */ |
| 947 | 947 | bool in_suspend; |
| 948 | + bool in_hibernate; | |
| 948 | 949 | |
| 949 | 950 | /* record last mm index being written through WREG32*/ |
| 950 | 951 | unsigned long last_mm_index; |
| @@ -1343,7 +1343,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( · 1342 unmodified lines | ||
| 1343 | 1343 | } |
| 1344 | 1344 | |
| 1345 | 1345 | /* Free the BO*/ |
| 1346 | − amdgpu_bo_unref(&mem->bo); | |
| 1346 | + drm_gem_object_put_unlocked(&mem->bo->tbo.base); | |
| 1347 | 1347 | mutex_destroy(&mem->lock); |
| 1348 | 1348 | kfree(mem); |
| 1349 | 1349 | |
| @@ -1688,7 +1688,8 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd, · 338 unmodified lines | ||
| 1688 | 1688 | | KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE |
| 1689 | 1689 | | KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; |
| 1690 | 1690 | |
| 1691 | − (*mem)->bo = amdgpu_bo_ref(bo); | |
| 1691 | + drm_gem_object_get(&bo->tbo.base); | |
| 1692 | + (*mem)->bo = bo; | |
| 1692 | 1693 | (*mem)->va = va; |
| 1693 | 1694 | (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? |
| 1694 | 1695 | AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT; |
| @@ -1181,7 +1181,9 @@ static int amdgpu_pmops_freeze(struct device *dev) · 1180 unmodified lines | ||
| 1181 | 1181 | struct amdgpu_device *adev = drm_dev->dev_private; |
| 1182 | 1182 | int r; |
| 1183 | 1183 | |
| 1184 | + adev->in_hibernate = true; | |
| 1184 | 1185 | r = amdgpu_device_suspend(drm_dev, true); |
| 1186 | + adev->in_hibernate = false; | |
| 1185 | 1187 | if (r) |
| 1186 | 1188 | return r; |
| 1187 | 1189 | return amdgpu_asic_reset(adev); |
| @@ -133,8 +133,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, · 132 unmodified lines | ||
| 133 | 133 | u32 cpp; |
| 134 | 134 | u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | |
| 135 | 135 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | |
| 136 | − AMDGPU_GEM_CREATE_VRAM_CLEARED | | |
| 137 | − AMDGPU_GEM_CREATE_CPU_GTT_USWC; | |
| 136 | + AMDGPU_GEM_CREATE_VRAM_CLEARED; | |
| 138 | 137 | |
| 139 | 138 | info = drm_get_format_info(adev->ddev, mode_cmd); |
| 140 | 139 | cpp = info->cpp[0]; |
| @@ -4273,7 +4273,7 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, · 4272 unmodified lines | ||
| 4273 | 4273 | /* === CGCG /CGLS for GFX 3D Only === */ |
| 4274 | 4274 | gfx_v10_0_update_3d_clock_gating(adev, enable); |
| 4275 | 4275 | /* === MGCG + MGLS === */ |
| 4276 | − /* gfx_v10_0_update_medium_grain_clock_gating(adev, enable); */ | |
| 4276 | + gfx_v10_0_update_medium_grain_clock_gating(adev, enable); | |
| 4277 | 4277 | } |
| 4278 | 4278 | |
| 4279 | 4279 | if (adev->cg_flags & |
| @@ -4353,11 +4353,7 @@ static int gfx_v10_0_set_powergating_state(void *handle, · 73 unmodified lines | ||
| 4353 | 4353 | switch (adev->asic_type) { |
| 4354 | 4354 | case CHIP_NAVI10: |
| 4355 | 4355 | case CHIP_NAVI14: |
| 4356 | − if (!enable) { | |
| 4357 | − amdgpu_gfx_off_ctrl(adev, false); | |
| 4358 | − cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); | |
| 4359 | − } else | |
| 4360 | − amdgpu_gfx_off_ctrl(adev, true); | |
| 4356 | + amdgpu_gfx_off_ctrl(adev, enable); | |
| 4361 | 4357 | break; |
| 4362 | 4358 | default: |
| 4363 | 4359 | break; |
| @@ -4918,6 +4914,19 @@ static void gfx_v10_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring, · 554 unmodified lines | ||
| 4918 | 4914 | ref, mask); |
| 4919 | 4915 | } |
| 4920 | 4916 | |
| 4917 | +static void gfx_v10_0_ring_soft_recovery(struct amdgpu_ring *ring, | |
| 4918 | + unsigned vmid) | |
| 4919 | +{ | |
| 4920 | + struct amdgpu_device *adev = ring->adev; | |
| 4921 | + uint32_t value = 0; | |
| 4922 | + | |
| 4923 | + value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03); | |
| 4924 | + value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01); | |
| 4925 | + value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1); | |
| 4926 | + value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid); | |
| 4927 | + WREG32_SOC15(GC, 0, mmSQ_CMD, value); | |
| 4928 | +} | |
| 4929 | + | |
| 4921 | 4930 | static void |
| 4922 | 4931 | gfx_v10_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, |
| 4923 | 4932 | uint32_t me, uint32_t pipe, |
| @@ -5309,6 +5318,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = { · 385 unmodified lines | ||
| 5309 | 5318 | .emit_wreg = gfx_v10_0_ring_emit_wreg, |
| 5310 | 5319 | .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait, |
| 5311 | 5320 | .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait, |
| 5321 | + .soft_recovery = gfx_v10_0_ring_soft_recovery, | |
| 5312 | 5322 | }; |
| 5313 | 5323 | |
| 5314 | 5324 | static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = { |
| @@ -1236,6 +1236,8 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = { · 1235 unmodified lines | ||
| 1236 | 1236 | { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 }, |
| 1237 | 1237 | /* https://bugzilla.kernel.org/show_bug.cgi?id=207171 */ |
| 1238 | 1238 | { 0x1002, 0x15dd, 0x103c, 0x83e7, 0xd3 }, |
| 1239 | + /* GFXOFF is unstable on C6 parts with a VBIOS 113-RAVEN-114 */ | |
| 1240 | + { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 }, | |
| 1239 | 1241 | { 0, 0, 0, 0, 0 }, |
| 1240 | 1242 | }; |
| 1241 | 1243 | |
| @@ -5025,10 +5027,9 @@ static int gfx_v9_0_set_powergating_state(void *handle, · 3783 unmodified lines | ||
| 5025 | 5027 | switch (adev->asic_type) { |
| 5026 | 5028 | case CHIP_RAVEN: |
| 5027 | 5029 | case CHIP_RENOIR: |
| 5028 | − if (!enable) { | |
| 5030 | + if (!enable) | |
| 5029 | 5031 | amdgpu_gfx_off_ctrl(adev, false); |
| 5030 | − cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); | |
| 5031 | − } | |
| 5032 | + | |
| 5032 | 5033 | if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) { |
| 5033 | 5034 | gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true); |
| 5034 | 5035 | gfx_v9_0_enable_sck_slow_down_on_power_down(adev, true); |
| @@ -5052,12 +5053,7 @@ static int gfx_v9_0_set_powergating_state(void *handle, · 17 unmodified lines | ||
| 5052 | 5053 | amdgpu_gfx_off_ctrl(adev, true); |
| 5053 | 5054 | break; |
| 5054 | 5055 | case CHIP_VEGA12: |
| 5055 | − if (!enable) { | |
| 5056 | − amdgpu_gfx_off_ctrl(adev, false); | |
| 5057 | − cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); | |
| 5058 | − } else { | |
| 5059 | − amdgpu_gfx_off_ctrl(adev, true); | |
| 5060 | − } | |
| 5056 | + amdgpu_gfx_off_ctrl(adev, enable); | |
| 5061 | 5057 | break; |
| 5062 | 5058 | default: |
| 5063 | 5059 | break; |
| @@ -441,7 +441,7 @@ static void dm_vupdate_high_irq(void *interrupt_params) · 440 unmodified lines | ||
| 441 | 441 | |
| 442 | 442 | /** |
| 443 | 443 | * dm_crtc_high_irq() - Handles CRTC interrupt |
| 444 | − * @interrupt_params: ignored | |
| 444 | + * @interrupt_params: used for determining the CRTC instance | |
| 445 | 445 | * |
| 446 | 446 | * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK |
| 447 | 447 | * event handler. |
| @@ -455,70 +455,6 @@ static void dm_crtc_high_irq(void *interrupt_params) · 7 unmodified lines | ||
| 455 | 455 | unsigned long flags; |
| 456 | 456 | |
| 457 | 457 | acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); |
| 458 | − | |
| 459 | − if (acrtc) { | |
| 460 | − acrtc_state = to_dm_crtc_state(acrtc->base.state); | |
| 461 | − | |
| 462 | − DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d\n", | |
| 463 | − acrtc->crtc_id, | |
| 464 | − amdgpu_dm_vrr_active(acrtc_state)); | |
| 465 | − | |
| 466 | − /* Core vblank handling at start of front-porch is only possible | |
| 467 | − * in non-vrr mode, as only there vblank timestamping will give | |
| 468 | − * valid results while done in front-porch. Otherwise defer it | |
| 469 | − * to dm_vupdate_high_irq after end of front-porch. | |
| 470 | − */ | |
| 471 | − if (!amdgpu_dm_vrr_active(acrtc_state)) | |
| 472 | − drm_crtc_handle_vblank(&acrtc->base); | |
| 473 | − | |
| 474 | − /* Following stuff must happen at start of vblank, for crc | |
| 475 | − * computation and below-the-range btr support in vrr mode. | |
| 476 | − */ | |
| 477 | − amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); | |
| 478 | − | |
| 479 | − if (acrtc_state->stream && adev->family >= AMDGPU_FAMILY_AI && | |
| 480 | − acrtc_state->vrr_params.supported && | |
| 481 | − acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { | |
| 482 | − spin_lock_irqsave(&adev->ddev->event_lock, flags); | |
| 483 | − mod_freesync_handle_v_update( | |
| 484 | − adev->dm.freesync_module, | |
| 485 | − acrtc_state->stream, | |
| 486 | − &acrtc_state->vrr_params); | |
| 487 | − | |
| 488 | − dc_stream_adjust_vmin_vmax( | |
| 489 | − adev->dm.dc, | |
| 490 | − acrtc_state->stream, | |
| 491 | − &acrtc_state->vrr_params.adjust); | |
| 492 | − spin_unlock_irqrestore(&adev->ddev->event_lock, flags); | |
| 493 | − } | |
| 494 | − } | |
| 495 | −} | |
| 496 | − | |
| 497 | −#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 498 | −/** | |
| 499 | − * dm_dcn_crtc_high_irq() - Handles VStartup interrupt for DCN generation ASICs | |
| 500 | − * @interrupt params - interrupt parameters | |
| 501 | − * | |
| 502 | − * Notify DRM's vblank event handler at VSTARTUP | |
| 503 | − * | |
| 504 | − * Unlike DCE hardware, we trigger the handler at VSTARTUP. at which: | |
| 505 | − * * We are close enough to VUPDATE - the point of no return for hw | |
| 506 | − * * We are in the fixed portion of variable front porch when vrr is enabled | |
| 507 | − * * We are before VUPDATE, where double-buffered vrr registers are swapped | |
| 508 | − * | |
| 509 | − * It is therefore the correct place to signal vblank, send user flip events, | |
| 510 | − * and update VRR. | |
| 511 | − */ | |
| 512 | −static void dm_dcn_crtc_high_irq(void *interrupt_params) | |
| 513 | −{ | |
| 514 | − struct common_irq_params *irq_params = interrupt_params; | |
| 515 | − struct amdgpu_device *adev = irq_params->adev; | |
| 516 | − struct amdgpu_crtc *acrtc; | |
| 517 | − struct dm_crtc_state *acrtc_state; | |
| 518 | − unsigned long flags; | |
| 519 | − | |
| 520 | − acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); | |
| 521 | − | |
| 522 | 458 | if (!acrtc) |
| 523 | 459 | return; |
| 524 | 460 | |
| @@ -528,22 +464,35 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 3 unmodified lines | ||
| 528 | 464 | amdgpu_dm_vrr_active(acrtc_state), |
| 529 | 465 | acrtc_state->active_planes); |
| 530 | 466 | |
| 467 | + /** | |
| 468 | + * Core vblank handling at start of front-porch is only possible | |
| 469 | + * in non-vrr mode, as only there vblank timestamping will give | |
| 470 | + * valid results while done in front-porch. Otherwise defer it | |
| 471 | + * to dm_vupdate_high_irq after end of front-porch. | |
| 472 | + */ | |
| 473 | + if (!amdgpu_dm_vrr_active(acrtc_state)) | |
| 474 | + drm_crtc_handle_vblank(&acrtc->base); | |
| 475 | + | |
| 476 | + /** | |
| 477 | + * Following stuff must happen at start of vblank, for crc | |
| 478 | + * computation and below-the-range btr support in vrr mode. | |
| 479 | + */ | |
| 531 | 480 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); |
| 532 | − drm_crtc_handle_vblank(&acrtc->base); | |
| 481 | + | |
| 482 | + /* BTR updates need to happen before VUPDATE on Vega and above. */ | |
| 483 | + if (adev->family < AMDGPU_FAMILY_AI) | |
| 484 | + return; | |
| 533 | 485 | |
| 534 | 486 | spin_lock_irqsave(&adev->ddev->event_lock, flags); |
| 535 | 487 | |
| 536 | − if (acrtc_state->vrr_params.supported && | |
| 488 | + if (acrtc_state->stream && acrtc_state->vrr_params.supported && | |
| 537 | 489 | acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { |
| 538 | − mod_freesync_handle_v_update( | |
| 539 | − adev->dm.freesync_module, | |
| 540 | − acrtc_state->stream, | |
| 541 | − &acrtc_state->vrr_params); | |
| 490 | + mod_freesync_handle_v_update(adev->dm.freesync_module, | |
| 491 | + acrtc_state->stream, | |
| 492 | + &acrtc_state->vrr_params); | |
| 542 | 493 | |
| 543 | − dc_stream_adjust_vmin_vmax( | |
| 544 | − adev->dm.dc, | |
| 545 | − acrtc_state->stream, | |
| 546 | − &acrtc_state->vrr_params.adjust); | |
| 494 | + dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc_state->stream, | |
| 495 | + &acrtc_state->vrr_params.adjust); | |
| 547 | 496 | } |
| 548 | 497 | |
| 549 | 498 | /* |
| @@ -556,7 +505,8 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 6 unmodified lines | ||
| 556 | 505 | * avoid race conditions between flip programming and completion, |
| 557 | 506 | * which could cause too early flip completion events. |
| 558 | 507 | */ |
| 559 | − if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && | |
| 508 | + if (adev->family >= AMDGPU_FAMILY_RV && | |
| 509 | + acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && | |
| 560 | 510 | acrtc_state->active_planes == 0) { |
| 561 | 511 | if (acrtc->event) { |
| 562 | 512 | drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); |
| @@ -568,7 +518,6 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 5 unmodified lines | ||
| 568 | 518 | |
| 569 | 519 | spin_unlock_irqrestore(&adev->ddev->event_lock, flags); |
| 570 | 520 | } |
| 571 | −#endif | |
| 572 | 521 | |
| 573 | 522 | static int dm_set_clockgating_state(void *handle, |
| 574 | 523 | enum amd_clockgating_state state) |
| @@ -2445,8 +2394,36 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) · 1870 unmodified lines | ||
| 2445 | 2394 | c_irq_params->adev = adev; |
| 2446 | 2395 | c_irq_params->irq_src = int_params.irq_source; |
| 2447 | 2396 | |
| 2397 | + amdgpu_dm_irq_register_interrupt( | |
| 2398 | + adev, &int_params, dm_crtc_high_irq, c_irq_params); | |
| 2399 | + } | |
| 2400 | + | |
| 2401 | + /* Use VUPDATE_NO_LOCK interrupt on DCN, which seems to correspond to | |
| 2402 | + * the regular VUPDATE interrupt on DCE. We want DC_IRQ_SOURCE_VUPDATEx | |
| 2403 | + * to trigger at end of each vblank, regardless of state of the lock, | |
| 2404 | + * matching DCE behaviour. | |
| 2405 | + */ | |
| 2406 | + for (i = DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT; | |
| 2407 | + i <= DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT + adev->mode_info.num_crtc - 1; | |
| 2408 | + i++) { | |
| 2409 | + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->vupdate_irq); | |
| 2410 | + | |
| 2411 | + if (r) { | |
| 2412 | + DRM_ERROR("Failed to add vupdate irq id!\n"); | |
| 2413 | + return r; | |
| 2414 | + } | |
| 2415 | + | |
| 2416 | + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; | |
| 2417 | + int_params.irq_source = | |
| 2418 | + dc_interrupt_to_irq_source(dc, i, 0); | |
| 2419 | + | |
| 2420 | + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; | |
| 2421 | + | |
| 2422 | + c_irq_params->adev = adev; | |
| 2423 | + c_irq_params->irq_src = int_params.irq_source; | |
| 2424 | + | |
| 2448 | 2425 | amdgpu_dm_irq_register_interrupt(adev, &int_params, |
| 2449 | − dm_dcn_crtc_high_irq, c_irq_params); | |
| 2426 | + dm_vupdate_high_irq, c_irq_params); | |
| 2450 | 2427 | } |
| 2451 | 2428 | |
| 2452 | 2429 | /* Use GRPH_PFLIP interrupt */ |
| @@ -4453,10 +4430,6 @@ static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) · 2000 unmodified lines | ||
| 4453 | 4430 | struct amdgpu_device *adev = crtc->dev->dev_private; |
| 4454 | 4431 | int rc; |
| 4455 | 4432 | |
| 4456 | − /* Do not set vupdate for DCN hardware */ | |
| 4457 | − if (adev->family > AMDGPU_FAMILY_AI) | |
| 4458 | − return 0; | |
| 4459 | − | |
| 4460 | 4433 | irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst; |
| 4461 | 4434 | |
| 4462 | 4435 | rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; |
| @@ -7882,6 +7855,7 @@ static int dm_update_plane_state(struct dc *dc, · 3419 unmodified lines | ||
| 7882 | 7855 | struct drm_crtc_state *old_crtc_state, *new_crtc_state; |
| 7883 | 7856 | struct dm_crtc_state *dm_new_crtc_state, *dm_old_crtc_state; |
| 7884 | 7857 | struct dm_plane_state *dm_new_plane_state, *dm_old_plane_state; |
| 7858 | + struct amdgpu_crtc *new_acrtc; | |
| 7885 | 7859 | bool needs_reset; |
| 7886 | 7860 | int ret = 0; |
| 7887 | 7861 | |
| @@ -7891,9 +7865,30 @@ static int dm_update_plane_state(struct dc *dc, · 3 unmodified lines | ||
| 7891 | 7865 | dm_new_plane_state = to_dm_plane_state(new_plane_state); |
| 7892 | 7866 | dm_old_plane_state = to_dm_plane_state(old_plane_state); |
| 7893 | 7867 | |
| 7894 | − /*TODO Implement atomic check for cursor plane */ | |
| 7895 | − if (plane->type == DRM_PLANE_TYPE_CURSOR) | |
| 7868 | + /*TODO Implement better atomic check for cursor plane */ | |
| 7869 | + if (plane->type == DRM_PLANE_TYPE_CURSOR) { | |
| 7870 | + if (!enable || !new_plane_crtc || | |
| 7871 | + drm_atomic_plane_disabling(plane->state, new_plane_state)) | |
| 7872 | + return 0; | |
| 7873 | + | |
| 7874 | + new_acrtc = to_amdgpu_crtc(new_plane_crtc); | |
| 7875 | + | |
| 7876 | + if ((new_plane_state->crtc_w > new_acrtc->max_cursor_width) || | |
| 7877 | + (new_plane_state->crtc_h > new_acrtc->max_cursor_height)) { | |
| 7878 | + DRM_DEBUG_ATOMIC("Bad cursor size %d x %d\n", | |
| 7879 | + new_plane_state->crtc_w, new_plane_state->crtc_h); | |
| 7880 | + return -EINVAL; | |
| 7881 | + } | |
| 7882 | + | |
| 7883 | + if (new_plane_state->crtc_x <= -new_acrtc->max_cursor_width || | |
| 7884 | + new_plane_state->crtc_y <= -new_acrtc->max_cursor_height) { | |
| 7885 | + DRM_DEBUG_ATOMIC("Bad cursor position %d, %d\n", | |
| 7886 | + new_plane_state->crtc_x, new_plane_state->crtc_y); | |
| 7887 | + return -EINVAL; | |
| 7888 | + } | |
| 7889 | + | |
| 7896 | 7890 | return 0; |
| 7891 | + } | |
| 7897 | 7892 | |
| 7898 | 7893 | needs_reset = should_reset_plane(state, plane, old_plane_state, |
| 7899 | 7894 | new_plane_state); |
| @@ -398,15 +398,15 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) · 397 unmodified lines | ||
| 398 | 398 | struct mod_hdcp_display *display = &hdcp_work[link_index].display; |
| 399 | 399 | struct mod_hdcp_link *link = &hdcp_work[link_index].link; |
| 400 | 400 | |
| 401 | − memset(display, 0, sizeof(*display)); | |
| 402 | − memset(link, 0, sizeof(*link)); | |
| 403 | − | |
| 404 | − display->index = aconnector->base.index; | |
| 405 | − | |
| 406 | 401 | if (config->dpms_off) { |
| 407 | 402 | hdcp_remove_display(hdcp_work, link_index, aconnector); |
| 408 | 403 | return; |
| 409 | 404 | } |
| 405 | + | |
| 406 | + memset(display, 0, sizeof(*display)); | |
| 407 | + memset(link, 0, sizeof(*link)); | |
| 408 | + | |
| 409 | + display->index = aconnector->base.index; | |
| 410 | 410 | display->state = MOD_HDCP_DISPLAY_ACTIVE; |
| 411 | 411 | |
| 412 | 412 | if (aconnector->dc_sink != NULL) |
| @@ -220,6 +220,30 @@ static enum dpcd_training_patterns · 219 unmodified lines | ||
| 220 | 220 | return dpcd_tr_pattern; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | +static uint8_t dc_dp_initialize_scrambling_data_symbols( | |
| 224 | + struct dc_link *link, | |
| 225 | + enum dc_dp_training_pattern pattern) | |
| 226 | +{ | |
| 227 | + uint8_t disable_scrabled_data_symbols = 0; | |
| 228 | + | |
| 229 | + switch (pattern) { | |
| 230 | + case DP_TRAINING_PATTERN_SEQUENCE_1: | |
| 231 | + case DP_TRAINING_PATTERN_SEQUENCE_2: | |
| 232 | + case DP_TRAINING_PATTERN_SEQUENCE_3: | |
| 233 | + disable_scrabled_data_symbols = 1; | |
| 234 | + break; | |
| 235 | + case DP_TRAINING_PATTERN_SEQUENCE_4: | |
| 236 | + disable_scrabled_data_symbols = 0; | |
| 237 | + break; | |
| 238 | + default: | |
| 239 | + ASSERT(0); | |
| 240 | + DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n", | |
| 241 | + __func__, pattern); | |
| 242 | + break; | |
| 243 | + } | |
| 244 | + return disable_scrabled_data_symbols; | |
| 245 | +} | |
| 246 | + | |
| 223 | 247 | static inline bool is_repeater(struct dc_link *link, uint32_t offset) |
| 224 | 248 | { |
| 225 | 249 | return (!link->is_lttpr_mode_transparent && offset != 0); |
| @@ -252,6 +276,9 @@ static void dpcd_set_lt_pattern_and_lane_settings( · 26 unmodified lines | ||
| 252 | 276 | dpcd_pattern.v1_4.TRAINING_PATTERN_SET = |
| 253 | 277 | dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern); |
| 254 | 278 | |
| 279 | + dpcd_pattern.v1_4.SCRAMBLING_DISABLE = | |
| 280 | + dc_dp_initialize_scrambling_data_symbols(link, pattern); | |
| 281 | + | |
| 255 | 282 | dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET] |
| 256 | 283 | = dpcd_pattern.raw; |
| 257 | 284 | |
| @@ -1625,12 +1625,79 @@ void dcn10_pipe_control_lock( · 1624 unmodified lines | ||
| 1625 | 1625 | hws->funcs.verify_allow_pstate_change_high(dc); |
| 1626 | 1626 | } |
| 1627 | 1627 | |
| 1628 | +/** | |
| 1629 | + * delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE. | |
| 1630 | + * | |
| 1631 | + * Software keepout workaround to prevent cursor update locking from stalling | |
| 1632 | + * out cursor updates indefinitely or from old values from being retained in | |
| 1633 | + * the case where the viewport changes in the same frame as the cursor. | |
| 1634 | + * | |
| 1635 | + * The idea is to calculate the remaining time from VPOS to VUPDATE. If it's | |
| 1636 | + * too close to VUPDATE, then stall out until VUPDATE finishes. | |
| 1637 | + * | |
| 1638 | + * TODO: Optimize cursor programming to be once per frame before VUPDATE | |
| 1639 | + * to avoid the need for this workaround. | |
| 1640 | + */ | |
| 1641 | +static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx) | |
| 1642 | +{ | |
| 1643 | + struct dc_stream_state *stream = pipe_ctx->stream; | |
| 1644 | + struct crtc_position position; | |
| 1645 | + uint32_t vupdate_start, vupdate_end; | |
| 1646 | + unsigned int lines_to_vupdate, us_to_vupdate, vpos; | |
| 1647 | + unsigned int us_per_line, us_vupdate; | |
| 1648 | + | |
| 1649 | + if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position) | |
| 1650 | + return; | |
| 1651 | + | |
| 1652 | + if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg) | |
| 1653 | + return; | |
| 1654 | + | |
| 1655 | + dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start, | |
| 1656 | + &vupdate_end); | |
| 1657 | + | |
| 1658 | + dc->hwss.get_position(&pipe_ctx, 1, &position); | |
| 1659 | + vpos = position.vertical_count; | |
| 1660 | + | |
| 1661 | + /* Avoid wraparound calculation issues */ | |
| 1662 | + vupdate_start += stream->timing.v_total; | |
| 1663 | + vupdate_end += stream->timing.v_total; | |
| 1664 | + vpos += stream->timing.v_total; | |
| 1665 | + | |
| 1666 | + if (vpos <= vupdate_start) { | |
| 1667 | + /* VPOS is in VACTIVE or back porch. */ | |
| 1668 | + lines_to_vupdate = vupdate_start - vpos; | |
| 1669 | + } else if (vpos > vupdate_end) { | |
| 1670 | + /* VPOS is in the front porch. */ | |
| 1671 | + return; | |
| 1672 | + } else { | |
| 1673 | + /* VPOS is in VUPDATE. */ | |
| 1674 | + lines_to_vupdate = 0; | |
| 1675 | + } | |
| 1676 | + | |
| 1677 | + /* Calculate time until VUPDATE in microseconds. */ | |
| 1678 | + us_per_line = | |
| 1679 | + stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz; | |
| 1680 | + us_to_vupdate = lines_to_vupdate * us_per_line; | |
| 1681 | + | |
| 1682 | + /* 70 us is a conservative estimate of cursor update time*/ | |
| 1683 | + if (us_to_vupdate > 70) | |
| 1684 | + return; | |
| 1685 | + | |
| 1686 | + /* Stall out until the cursor update completes. */ | |
| 1687 | + us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line; | |
| 1688 | + udelay(us_to_vupdate + us_vupdate); | |
| 1689 | +} | |
| 1690 | + | |
| 1628 | 1691 | void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) |
| 1629 | 1692 | { |
| 1630 | 1693 | /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ |
| 1631 | 1694 | if (!pipe || pipe->top_pipe) |
| 1632 | 1695 | return; |
| 1633 | 1696 | |
| 1697 | + /* Prevent cursor lock from stalling out cursor updates. */ | |
| 1698 | + if (lock) | |
| 1699 | + delay_cursor_until_vupdate(dc, pipe); | |
| 1700 | + | |
| 1634 | 1701 | dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, |
| 1635 | 1702 | pipe->stream_res.opp->inst, lock); |
| 1636 | 1703 | } |
| @@ -3236,7 +3303,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) · 1599 unmodified lines | ||
| 3236 | 3303 | return vertical_line_start; |
| 3237 | 3304 | } |
| 3238 | 3305 | |
| 3239 | −static void dcn10_calc_vupdate_position( | |
| 3306 | +void dcn10_calc_vupdate_position( | |
| 3240 | 3307 | struct dc *dc, |
| 3241 | 3308 | struct pipe_ctx *pipe_ctx, |
| 3242 | 3309 | uint32_t *start_line, |
| @@ -34,6 +34,11 @@ struct dc; · 33 unmodified lines | ||
| 34 | 34 | void dcn10_hw_sequencer_construct(struct dc *dc); |
| 35 | 35 | |
| 36 | 36 | int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx); |
| 37 | +void dcn10_calc_vupdate_position( | |
| 38 | + struct dc *dc, | |
| 39 | + struct pipe_ctx *pipe_ctx, | |
| 40 | + uint32_t *start_line, | |
| 41 | + uint32_t *end_line); | |
| 37 | 42 | void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); |
| 38 | 43 | enum dc_status dcn10_enable_stream_timing( |
| 39 | 44 | struct pipe_ctx *pipe_ctx, |
| @@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 71 unmodified lines | ||
| 72 | 72 | .set_clock = dcn10_set_clock, |
| 73 | 73 | .get_clock = dcn10_get_clock, |
| 74 | 74 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 75 | + .calc_vupdate_position = dcn10_calc_vupdate_position, | |
| 75 | 76 | }; |
| 76 | 77 | |
| 77 | 78 | static const struct hwseq_private_funcs dcn10_private_funcs = { |
| @@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 82 unmodified lines | ||
| 83 | 83 | .init_vm_ctx = dcn20_init_vm_ctx, |
| 84 | 84 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, |
| 85 | 85 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 86 | + .calc_vupdate_position = dcn10_calc_vupdate_position, | |
| 86 | 87 | }; |
| 87 | 88 | |
| 88 | 89 | static const struct hwseq_private_funcs dcn20_private_funcs = { |
| @@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 85 unmodified lines | ||
| 86 | 86 | .optimize_pwr_state = dcn21_optimize_pwr_state, |
| 87 | 87 | .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, |
| 88 | 88 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 89 | + .calc_vupdate_position = dcn10_calc_vupdate_position, | |
| 89 | 90 | .set_cursor_position = dcn10_set_cursor_position, |
| 90 | 91 | .set_cursor_attribute = dcn10_set_cursor_attribute, |
| 91 | 92 | .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, |
| @@ -63,10 +63,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) · 62 unmodified lines | ||
| 63 | 63 | endif |
| 64 | 64 | CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags) |
| 65 | 65 | CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags) |
| 66 | −CFLAGS_$(AMDDALPATH)/dc/dml/dml_common_defs.o := $(dml_ccflags) | |
| 67 | 66 | |
| 68 | 67 | DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ |
| 69 | − dml_common_defs.o | |
| 70 | 68 | |
| 71 | 69 | ifdef CONFIG_DRM_AMD_DC_DCN |
| 72 | 70 | DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DML20_DISPLAY_RQ_DLG_CALC_H__ |
| 27 | 27 | #define __DML20_DISPLAY_RQ_DLG_CALC_H__ |
| 28 | 28 | |
| 29 | −#include "../dml_common_defs.h" | |
| 30 | 29 | #include "../display_rq_dlg_helpers.h" |
| 31 | 30 | |
| 32 | 31 | struct display_mode_lib; |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DML20V2_DISPLAY_RQ_DLG_CALC_H__ |
| 27 | 27 | #define __DML20V2_DISPLAY_RQ_DLG_CALC_H__ |
| 28 | 28 | |
| 29 | −#include "../dml_common_defs.h" | |
| 30 | 29 | #include "../display_rq_dlg_helpers.h" |
| 31 | 30 | |
| 32 | 31 | struct display_mode_lib; |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DML21_DISPLAY_RQ_DLG_CALC_H__ |
| 27 | 27 | #define __DML21_DISPLAY_RQ_DLG_CALC_H__ |
| 28 | 28 | |
| 29 | −#include "../dml_common_defs.h" | |
| 29 | +#include "dm_services.h" | |
| 30 | 30 | #include "../display_rq_dlg_helpers.h" |
| 31 | 31 | |
| 32 | 32 | struct display_mode_lib; |
| @@ -25,8 +25,10 @@ · 24 unmodified lines | ||
| 25 | 25 | #ifndef __DISPLAY_MODE_LIB_H__ |
| 26 | 26 | #define __DISPLAY_MODE_LIB_H__ |
| 27 | 27 | |
| 28 | − | |
| 29 | −#include "dml_common_defs.h" | |
| 28 | +#include "dm_services.h" | |
| 29 | +#include "dc_features.h" | |
| 30 | +#include "display_mode_structs.h" | |
| 31 | +#include "display_mode_enums.h" | |
| 30 | 32 | #include "display_mode_vba.h" |
| 31 | 33 | |
| 32 | 34 | enum dml_project { |
| @@ -27,8 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #ifndef __DML2_DISPLAY_MODE_VBA_H__ |
| 28 | 28 | #define __DML2_DISPLAY_MODE_VBA_H__ |
| 29 | 29 | |
| 30 | −#include "dml_common_defs.h" | |
| 31 | − | |
| 32 | 30 | struct display_mode_lib; |
| 33 | 31 | |
| 34 | 32 | void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib); |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DISPLAY_RQ_DLG_HELPERS_H__ |
| 27 | 27 | #define __DISPLAY_RQ_DLG_HELPERS_H__ |
| 28 | 28 | |
| 29 | −#include "dml_common_defs.h" | |
| 30 | 29 | #include "display_mode_lib.h" |
| 31 | 30 | |
| 32 | 31 | /* Function: Printer functions |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DISPLAY_RQ_DLG_CALC_H__ |
| 27 | 27 | #define __DISPLAY_RQ_DLG_CALC_H__ |
| 28 | 28 | |
| 29 | −#include "dml_common_defs.h" | |
| 30 | − | |
| 31 | 29 | struct display_mode_lib; |
| 32 | 30 | |
| 33 | 31 | #include "display_rq_dlg_helpers.h" |
| @@ -1,43 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright 2017 Advanced Micro Devices, Inc. | |
| 3 | − * | |
| 4 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | − * copy of this software and associated documentation files (the "Software"), | |
| 6 | − * to deal in the Software without restriction, including without limitation | |
| 7 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | − * Software is furnished to do so, subject to the following conditions: | |
| 10 | − * | |
| 11 | − * The above copyright notice and this permission notice shall be included in | |
| 12 | − * all copies or substantial portions of the Software. | |
| 13 | − * | |
| 14 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | − * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | − * | |
| 22 | − * Authors: AMD | |
| 23 | − * | |
| 24 | − */ | |
| 25 | − | |
| 26 | −#include "dml_common_defs.h" | |
| 27 | −#include "dcn_calc_math.h" | |
| 28 | − | |
| 29 | −#include "dml_inline_defs.h" | |
| 30 | − | |
| 31 | −double dml_round(double a) | |
| 32 | −{ | |
| 33 | − double round_pt = 0.5; | |
| 34 | − double ceil = dml_ceil(a, 1); | |
| 35 | − double floor = dml_floor(a, 1); | |
| 36 | − | |
| 37 | − if (a - floor >= round_pt) | |
| 38 | − return ceil; | |
| 39 | − else | |
| 40 | − return floor; | |
| 41 | −} | |
| 42 | − | |
| 43 | − | |
| @@ -1,37 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright 2017 Advanced Micro Devices, Inc. | |
| 3 | − * | |
| 4 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | − * copy of this software and associated documentation files (the "Software"), | |
| 6 | − * to deal in the Software without restriction, including without limitation | |
| 7 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | − * Software is furnished to do so, subject to the following conditions: | |
| 10 | − * | |
| 11 | − * The above copyright notice and this permission notice shall be included in | |
| 12 | − * all copies or substantial portions of the Software. | |
| 13 | − * | |
| 14 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | − * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | − * | |
| 22 | − * Authors: AMD | |
| 23 | − * | |
| 24 | − */ | |
| 25 | − | |
| 26 | −#ifndef __DC_COMMON_DEFS_H__ | |
| 27 | −#define __DC_COMMON_DEFS_H__ | |
| 28 | − | |
| 29 | −#include "dm_services.h" | |
| 30 | −#include "dc_features.h" | |
| 31 | −#include "display_mode_structs.h" | |
| 32 | −#include "display_mode_enums.h" | |
| 33 | − | |
| 34 | − | |
| 35 | −double dml_round(double a); | |
| 36 | − | |
| 37 | −#endif /* __DC_COMMON_DEFS_H__ */ | |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifndef __DML_INLINE_DEFS_H__ |
| 27 | 27 | #define __DML_INLINE_DEFS_H__ |
| 28 | 28 | |
| 29 | −#include "dml_common_defs.h" | |
| 30 | 29 | #include "dcn_calc_math.h" |
| 31 | 30 | #include "dml_logger.h" |
| 32 | 31 | |
| @@ -75,6 +74,18 @@ static inline double dml_floor(double a, double granularity) · 42 unmodified lines | ||
| 75 | 74 | return (double) dcn_bw_floor2(a, granularity); |
| 76 | 75 | } |
| 77 | 76 | |
| 77 | +static inline double dml_round(double a) | |
| 78 | +{ | |
| 79 | + double round_pt = 0.5; | |
| 80 | + double ceil = dml_ceil(a, 1); | |
| 81 | + double floor = dml_floor(a, 1); | |
| 82 | + | |
| 83 | + if (a - floor >= round_pt) | |
| 84 | + return ceil; | |
| 85 | + else | |
| 86 | + return floor; | |
| 87 | +} | |
| 88 | + | |
| 78 | 89 | static inline int dml_log2(double x) |
| 79 | 90 | { |
| 80 | 91 | return dml_round((double)dcn_bw_log(x, 2)); |
| @@ -112,7 +123,7 @@ static inline double dml_log(double x, double base) · 31 unmodified lines | ||
| 112 | 123 | |
| 113 | 124 | static inline unsigned int dml_round_to_multiple(unsigned int num, |
| 114 | 125 | unsigned int multiple, |
| 115 | − bool up) | |
| 126 | + unsigned char up) | |
| 116 | 127 | { |
| 117 | 128 | unsigned int remainder; |
| 118 | 129 | |
| @@ -92,6 +92,11 @@ struct hw_sequencer_funcs { · 91 unmodified lines | ||
| 92 | 92 | void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, |
| 93 | 93 | struct crtc_position *position); |
| 94 | 94 | int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx); |
| 95 | + void (*calc_vupdate_position)( | |
| 96 | + struct dc *dc, | |
| 97 | + struct pipe_ctx *pipe_ctx, | |
| 98 | + uint32_t *start_line, | |
| 99 | + uint32_t *end_line); | |
| 95 | 100 | void (*enable_per_frame_crtc_position_reset)(struct dc *dc, |
| 96 | 101 | int group_size, struct pipe_ctx *grouped_pipes[]); |
| 97 | 102 | void (*enable_timing_synchronization)(struct dc *dc, |
| @@ -319,12 +319,12 @@ static void pp_dpm_en_umd_pstate(struct pp_hwmgr *hwmgr, · 318 unmodified lines | ||
| 319 | 319 | if (*level & profile_mode_mask) { |
| 320 | 320 | hwmgr->saved_dpm_level = hwmgr->dpm_level; |
| 321 | 321 | hwmgr->en_umd_pstate = true; |
| 322 | − amdgpu_device_ip_set_clockgating_state(hwmgr->adev, | |
| 323 | − AMD_IP_BLOCK_TYPE_GFX, | |
| 324 | − AMD_CG_STATE_UNGATE); | |
| 325 | 322 | amdgpu_device_ip_set_powergating_state(hwmgr->adev, |
| 326 | 323 | AMD_IP_BLOCK_TYPE_GFX, |
| 327 | 324 | AMD_PG_STATE_UNGATE); |
| 325 | + amdgpu_device_ip_set_clockgating_state(hwmgr->adev, | |
| 326 | + AMD_IP_BLOCK_TYPE_GFX, | |
| 327 | + AMD_CG_STATE_UNGATE); | |
| 328 | 328 | } |
| 329 | 329 | } else { |
| 330 | 330 | /* exit umd pstate, restore level, enable gfx cg*/ |
| @@ -1476,7 +1476,7 @@ static int smu_disable_dpm(struct smu_context *smu) · 1475 unmodified lines | ||
| 1476 | 1476 | bool use_baco = !smu->is_apu && |
| 1477 | 1477 | ((adev->in_gpu_reset && |
| 1478 | 1478 | (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || |
| 1479 | − (adev->in_runpm && amdgpu_asic_supports_baco(adev))); | |
| 1479 | + ((adev->in_runpm || adev->in_hibernate) && amdgpu_asic_supports_baco(adev))); | |
| 1480 | 1480 | |
| 1481 | 1481 | ret = smu_get_smc_version(smu, NULL, &smu_version); |
| 1482 | 1482 | if (ret) { |
| @@ -1744,12 +1744,12 @@ static int smu_enable_umd_pstate(void *handle, · 261 unmodified lines | ||
| 1744 | 1744 | if (*level & profile_mode_mask) { |
| 1745 | 1745 | smu_dpm_ctx->saved_dpm_level = smu_dpm_ctx->dpm_level; |
| 1746 | 1746 | smu_dpm_ctx->enable_umd_pstate = true; |
| 1747 | − amdgpu_device_ip_set_clockgating_state(smu->adev, | |
| 1748 | − AMD_IP_BLOCK_TYPE_GFX, | |
| 1749 | − AMD_CG_STATE_UNGATE); | |
| 1750 | 1747 | amdgpu_device_ip_set_powergating_state(smu->adev, |
| 1751 | 1748 | AMD_IP_BLOCK_TYPE_GFX, |
| 1752 | 1749 | AMD_PG_STATE_UNGATE); |
| 1750 | + amdgpu_device_ip_set_clockgating_state(smu->adev, | |
| 1751 | + AMD_IP_BLOCK_TYPE_GFX, | |
| 1752 | + AMD_CG_STATE_UNGATE); | |
| 1753 | 1753 | } |
| 1754 | 1754 | } else { |
| 1755 | 1755 | /* exit umd pstate, restore level, enable gfx cg*/ |
| @@ -191,10 +191,11 @@ static const struct edid_quirk { · 190 unmodified lines | ||
| 191 | 191 | { "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP }, |
| 192 | 192 | { "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP }, |
| 193 | 193 | |
| 194 | − /* Oculus Rift DK1, DK2, and CV1 VR Headsets */ | |
| 194 | + /* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */ | |
| 195 | 195 | { "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP }, |
| 196 | 196 | { "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP }, |
| 197 | 197 | { "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP }, |
| 198 | + { "OVR", 0x0012, EDID_QUIRK_NON_DESKTOP }, | |
| 198 | 199 | |
| 199 | 200 | /* Windows Mixed Reality Headsets */ |
| 200 | 201 | { "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP }, |
| @@ -238,8 +238,10 @@ static int submit_pin_objects(struct etnaviv_gem_submit *submit) · 237 unmodified lines | ||
| 238 | 238 | } |
| 239 | 239 | |
| 240 | 240 | if ((submit->flags & ETNA_SUBMIT_SOFTPIN) && |
| 241 | − submit->bos[i].va != mapping->iova) | |
| 241 | + submit->bos[i].va != mapping->iova) { | |
| 242 | + etnaviv_gem_mapping_unreference(mapping); | |
| 242 | 243 | return -EINVAL; |
| 244 | + } | |
| 243 | 245 | |
| 244 | 246 | atomic_inc(&etnaviv_obj->gpu_active); |
| 245 | 247 | |
| @@ -453,7 +453,7 @@ static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu, · 452 unmodified lines | ||
| 453 | 453 | if (!(gpu->identity.features & meta->feature)) |
| 454 | 454 | continue; |
| 455 | 455 | |
| 456 | − if (meta->nr_domains < (index - offset)) { | |
| 456 | + if (index - offset >= meta->nr_domains) { | |
| 457 | 457 | offset += meta->nr_domains; |
| 458 | 458 | continue; |
| 459 | 459 | } |
| @@ -485,8 +485,7 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, · 484 unmodified lines | ||
| 485 | 485 | if (!ret) |
| 486 | 486 | goto err_llb; |
| 487 | 487 | else if (ret > 1) { |
| 488 | − DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); | |
| 489 | − | |
| 488 | + DRM_INFO_ONCE("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); | |
| 490 | 489 | } |
| 491 | 490 | |
| 492 | 491 | fbc->threshold = ret; |
| @@ -368,7 +368,6 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) · 367 unmodified lines | ||
| 368 | 368 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 369 | 369 | struct i915_vma *vma; |
| 370 | 370 | |
| 371 | − GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); | |
| 372 | 371 | if (!atomic_read(&obj->bind_count)) |
| 373 | 372 | return; |
| 374 | 373 | |
| @@ -400,12 +399,8 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) · 25 unmodified lines | ||
| 400 | 399 | void |
| 401 | 400 | i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) |
| 402 | 401 | { |
| 403 | − struct drm_i915_gem_object *obj = vma->obj; | |
| 404 | − | |
| 405 | − assert_object_held(obj); | |
| 406 | − | |
| 407 | 402 | /* Bump the LRU to try and avoid premature eviction whilst flipping */ |
| 408 | − i915_gem_object_bump_inactive_ggtt(obj); | |
| 403 | + i915_gem_object_bump_inactive_ggtt(vma->obj); | |
| 409 | 404 | |
| 410 | 405 | i915_vma_unpin(vma); |
| 411 | 406 | } |
| @@ -69,7 +69,13 @@ struct intel_context { · 68 unmodified lines | ||
| 69 | 69 | #define CONTEXT_NOPREEMPT 7 |
| 70 | 70 | |
| 71 | 71 | u32 *lrc_reg_state; |
| 72 | − u64 lrc_desc; | |
| 72 | + union { | |
| 73 | + struct { | |
| 74 | + u32 lrca; | |
| 75 | + u32 ccid; | |
| 76 | + }; | |
| 77 | + u64 desc; | |
| 78 | + } lrc; | |
| 73 | 79 | u32 tag; /* cookie passed to HW to track this context on submission */ |
| 74 | 80 | |
| 75 | 81 | /* Time on GPU as tracked by the hw. */ |
| @@ -333,13 +333,4 @@ intel_engine_has_preempt_reset(const struct intel_engine_cs *engine) · 332 unmodified lines | ||
| 333 | 333 | return intel_engine_has_preemption(engine); |
| 334 | 334 | } |
| 335 | 335 | |
| 336 | −static inline bool | |
| 337 | −intel_engine_has_timeslices(const struct intel_engine_cs *engine) | |
| 338 | −{ | |
| 339 | − if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) | |
| 340 | − return false; | |
| 341 | − | |
| 342 | − return intel_engine_has_semaphores(engine); | |
| 343 | −} | |
| 344 | − | |
| 345 | 336 | #endif /* _INTEL_RINGBUFFER_H_ */ |
| @@ -1295,6 +1295,12 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, · 1294 unmodified lines | ||
| 1295 | 1295 | |
| 1296 | 1296 | if (engine->id == RENDER_CLASS && IS_GEN_RANGE(dev_priv, 4, 7)) |
| 1297 | 1297 | drm_printf(m, "\tCCID: 0x%08x\n", ENGINE_READ(engine, CCID)); |
| 1298 | + if (HAS_EXECLISTS(dev_priv)) { | |
| 1299 | + drm_printf(m, "\tEL_STAT_HI: 0x%08x\n", | |
| 1300 | + ENGINE_READ(engine, RING_EXECLIST_STATUS_HI)); | |
| 1301 | + drm_printf(m, "\tEL_STAT_LO: 0x%08x\n", | |
| 1302 | + ENGINE_READ(engine, RING_EXECLIST_STATUS_LO)); | |
| 1303 | + } | |
| 1298 | 1304 | drm_printf(m, "\tRING_START: 0x%08x\n", |
| 1299 | 1305 | ENGINE_READ(engine, RING_START)); |
| 1300 | 1306 | drm_printf(m, "\tRING_HEAD: 0x%08x\n", |
| @@ -156,6 +156,20 @@ struct intel_engine_execlists { · 155 unmodified lines | ||
| 156 | 156 | */ |
| 157 | 157 | struct i915_priolist default_priolist; |
| 158 | 158 | |
| 159 | + /** | |
| 160 | + * @ccid: identifier for contexts submitted to this engine | |
| 161 | + */ | |
| 162 | + u32 ccid; | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * @yield: CCID at the time of the last semaphore-wait interrupt. | |
| 166 | + * | |
| 167 | + * Instead of leaving a semaphore busy-spinning on an engine, we would | |
| 168 | + * like to switch to another ready context, i.e. yielding the semaphore | |
| 169 | + * timeslice. | |
| 170 | + */ | |
| 171 | + u32 yield; | |
| 172 | + | |
| 159 | 173 | /** |
| 160 | 174 | * @error_interrupt: CS Master EIR |
| 161 | 175 | * |
| @@ -295,8 +309,7 @@ struct intel_engine_cs { · 133 unmodified lines | ||
| 295 | 309 | u32 context_size; |
| 296 | 310 | u32 mmio_base; |
| 297 | 311 | |
| 298 | − unsigned int context_tag; | |
| 299 | −#define NUM_CONTEXT_TAG roundup_pow_of_two(2 * EXECLIST_MAX_PORTS) | |
| 312 | + unsigned long context_tag; | |
| 300 | 313 | |
| 301 | 314 | struct rb_node uabi_node; |
| 302 | 315 | |
| @@ -483,10 +496,11 @@ struct intel_engine_cs { · 180 unmodified lines | ||
| 483 | 496 | #define I915_ENGINE_SUPPORTS_STATS BIT(1) |
| 484 | 497 | #define I915_ENGINE_HAS_PREEMPTION BIT(2) |
| 485 | 498 | #define I915_ENGINE_HAS_SEMAPHORES BIT(3) |
| 486 | −#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4) | |
| 487 | −#define I915_ENGINE_IS_VIRTUAL BIT(5) | |
| 488 | −#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6) | |
| 489 | −#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7) | |
| 499 | +#define I915_ENGINE_HAS_TIMESLICES BIT(4) | |
| 500 | +#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5) | |
| 501 | +#define I915_ENGINE_IS_VIRTUAL BIT(6) | |
| 502 | +#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7) | |
| 503 | +#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8) | |
| 490 | 504 | unsigned int flags; |
| 491 | 505 | |
| 492 | 506 | /* |
| @@ -584,6 +598,15 @@ intel_engine_has_semaphores(const struct intel_engine_cs *engine) · 91 unmodified lines | ||
| 584 | 598 | return engine->flags & I915_ENGINE_HAS_SEMAPHORES; |
| 585 | 599 | } |
| 586 | 600 | |
| 601 | +static inline bool | |
| 602 | +intel_engine_has_timeslices(const struct intel_engine_cs *engine) | |
| 603 | +{ | |
| 604 | + if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) | |
| 605 | + return false; | |
| 606 | + | |
| 607 | + return engine->flags & I915_ENGINE_HAS_TIMESLICES; | |
| 608 | +} | |
| 609 | + | |
| 587 | 610 | static inline bool |
| 588 | 611 | intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine) |
| 589 | 612 | { |
| @@ -39,6 +39,15 @@ cs_irq_handler(struct intel_engine_cs *engine, u32 iir) · 38 unmodified lines | ||
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | + if (iir & GT_WAIT_SEMAPHORE_INTERRUPT) { | |
| 43 | + WRITE_ONCE(engine->execlists.yield, | |
| 44 | + ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI)); | |
| 45 | + ENGINE_TRACE(engine, "semaphore yield: %08x\n", | |
| 46 | + engine->execlists.yield); | |
| 47 | + if (del_timer(&engine->execlists.timer)) | |
| 48 | + tasklet = true; | |
| 49 | + } | |
| 50 | + | |
| 42 | 51 | if (iir & GT_CONTEXT_SWITCH_INTERRUPT) |
| 43 | 52 | tasklet = true; |
| 44 | 53 | |
| @@ -228,7 +237,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt) · 183 unmodified lines | ||
| 228 | 237 | const u32 irqs = |
| 229 | 238 | GT_CS_MASTER_ERROR_INTERRUPT | |
| 230 | 239 | GT_RENDER_USER_INTERRUPT | |
| 231 | − GT_CONTEXT_SWITCH_INTERRUPT; | |
| 240 | + GT_CONTEXT_SWITCH_INTERRUPT | | |
| 241 | + GT_WAIT_SEMAPHORE_INTERRUPT; | |
| 232 | 242 | struct intel_uncore *uncore = gt->uncore; |
| 233 | 243 | const u32 dmask = irqs << 16 | irqs; |
| 234 | 244 | const u32 smask = irqs << 16; |
| @@ -366,7 +376,8 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt) · 131 unmodified lines | ||
| 366 | 376 | const u32 irqs = |
| 367 | 377 | GT_CS_MASTER_ERROR_INTERRUPT | |
| 368 | 378 | GT_RENDER_USER_INTERRUPT | |
| 369 | − GT_CONTEXT_SWITCH_INTERRUPT; | |
| 379 | + GT_CONTEXT_SWITCH_INTERRUPT | | |
| 380 | + GT_WAIT_SEMAPHORE_INTERRUPT; | |
| 370 | 381 | const u32 gt_interrupts[] = { |
| 371 | 382 | irqs << GEN8_RCS_IRQ_SHIFT | irqs << GEN8_BCS_IRQ_SHIFT, |
| 372 | 383 | irqs << GEN8_VCS0_IRQ_SHIFT | irqs << GEN8_VCS1_IRQ_SHIFT, |
| @@ -456,10 +456,10 @@ assert_priority_queue(const struct i915_request *prev, · 455 unmodified lines | ||
| 456 | 456 | * engine info, SW context ID and SW counter need to form a unique number |
| 457 | 457 | * (Context ID) per lrc. |
| 458 | 458 | */ |
| 459 | −static u64 | |
| 459 | +static u32 | |
| 460 | 460 | lrc_descriptor(struct intel_context *ce, struct intel_engine_cs *engine) |
| 461 | 461 | { |
| 462 | − u64 desc; | |
| 462 | + u32 desc; | |
| 463 | 463 | |
| 464 | 464 | desc = INTEL_LEGACY_32B_CONTEXT; |
| 465 | 465 | if (i915_vm_is_4lvl(ce->vm)) |
| @@ -470,21 +470,7 @@ lrc_descriptor(struct intel_context *ce, struct intel_engine_cs *engine) · 4 unmodified lines | ||
| 470 | 470 | if (IS_GEN(engine->i915, 8)) |
| 471 | 471 | desc |= GEN8_CTX_L3LLC_COHERENT; |
| 472 | 472 | |
| 473 | − desc |= i915_ggtt_offset(ce->state); /* bits 12-31 */ | |
| 474 | − /* | |
| 475 | − * The following 32bits are copied into the OA reports (dword 2). | |
| 476 | − * Consider updating oa_get_render_ctx_id in i915_perf.c when changing | |
| 477 | − * anything below. | |
| 478 | − */ | |
| 479 | − if (INTEL_GEN(engine->i915) >= 11) { | |
| 480 | − desc |= (u64)engine->instance << GEN11_ENGINE_INSTANCE_SHIFT; | |
| 481 | − /* bits 48-53 */ | |
| 482 | − | |
| 483 | − desc |= (u64)engine->class << GEN11_ENGINE_CLASS_SHIFT; | |
| 484 | − /* bits 61-63 */ | |
| 485 | − } | |
| 486 | − | |
| 487 | − return desc; | |
| 473 | + return i915_ggtt_offset(ce->state) | desc; | |
| 488 | 474 | } |
| 489 | 475 | |
| 490 | 476 | static inline unsigned int dword_in_page(void *addr) |
| @@ -1192,7 +1178,7 @@ static void reset_active(struct i915_request *rq, · 701 unmodified lines | ||
| 1192 | 1178 | __execlists_update_reg_state(ce, engine, head); |
| 1193 | 1179 | |
| 1194 | 1180 | /* We've switched away, so this should be a no-op, but intent matters */ |
| 1195 | − ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; | |
| 1181 | + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; | |
| 1196 | 1182 | } |
| 1197 | 1183 | |
| 1198 | 1184 | static u32 intel_context_get_runtime(const struct intel_context *ce) |
| @@ -1251,18 +1237,23 @@ __execlists_schedule_in(struct i915_request *rq) · 52 unmodified lines | ||
| 1251 | 1237 | if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) |
| 1252 | 1238 | execlists_check_context(ce, engine); |
| 1253 | 1239 | |
| 1254 | − ce->lrc_desc &= ~GENMASK_ULL(47, 37); | |
| 1255 | 1240 | if (ce->tag) { |
| 1256 | 1241 | /* Use a fixed tag for OA and friends */ |
| 1257 | − ce->lrc_desc |= (u64)ce->tag << 32; | |
| 1242 | + GEM_BUG_ON(ce->tag <= BITS_PER_LONG); | |
| 1243 | + ce->lrc.ccid = ce->tag; | |
| 1258 | 1244 | } else { |
| 1259 | 1245 | /* We don't need a strict matching tag, just different values */ |
| 1260 | − ce->lrc_desc |= | |
| 1261 | − (u64)(++engine->context_tag % NUM_CONTEXT_TAG) << | |
| 1262 | − GEN11_SW_CTX_ID_SHIFT; | |
| 1263 | − BUILD_BUG_ON(NUM_CONTEXT_TAG > GEN12_MAX_CONTEXT_HW_ID); | |
| 1246 | + unsigned int tag = ffs(engine->context_tag); | |
| 1247 | + | |
| 1248 | + GEM_BUG_ON(tag == 0 || tag >= BITS_PER_LONG); | |
| 1249 | + clear_bit(tag - 1, &engine->context_tag); | |
| 1250 | + ce->lrc.ccid = tag << (GEN11_SW_CTX_ID_SHIFT - 32); | |
| 1251 | + | |
| 1252 | + BUILD_BUG_ON(BITS_PER_LONG > GEN12_MAX_CONTEXT_HW_ID); | |
| 1264 | 1253 | } |
| 1265 | 1254 | |
| 1255 | + ce->lrc.ccid |= engine->execlists.ccid; | |
| 1256 | + | |
| 1266 | 1257 | __intel_gt_pm_get(engine->gt); |
| 1267 | 1258 | execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN); |
| 1268 | 1259 | intel_engine_context_in(engine); |
| @@ -1302,7 +1293,8 @@ static void kick_siblings(struct i915_request *rq, struct intel_context *ce) · 33 unmodified lines | ||
| 1302 | 1293 | |
| 1303 | 1294 | static inline void |
| 1304 | 1295 | __execlists_schedule_out(struct i915_request *rq, |
| 1305 | − struct intel_engine_cs * const engine) | |
| 1296 | + struct intel_engine_cs * const engine, | |
| 1297 | + unsigned int ccid) | |
| 1306 | 1298 | { |
| 1307 | 1299 | struct intel_context * const ce = rq->context; |
| 1308 | 1300 | |
| @@ -1320,6 +1312,14 @@ __execlists_schedule_out(struct i915_request *rq, · 11 unmodified lines | ||
| 1320 | 1312 | i915_request_completed(rq)) |
| 1321 | 1313 | intel_engine_add_retire(engine, ce->timeline); |
| 1322 | 1314 | |
| 1315 | + ccid >>= GEN11_SW_CTX_ID_SHIFT - 32; | |
| 1316 | + ccid &= GEN12_MAX_CONTEXT_HW_ID; | |
| 1317 | + if (ccid < BITS_PER_LONG) { | |
| 1318 | + GEM_BUG_ON(ccid == 0); | |
| 1319 | + GEM_BUG_ON(test_bit(ccid - 1, &engine->context_tag)); | |
| 1320 | + set_bit(ccid - 1, &engine->context_tag); | |
| 1321 | + } | |
| 1322 | + | |
| 1323 | 1323 | intel_context_update_runtime(ce); |
| 1324 | 1324 | intel_engine_context_out(engine); |
| 1325 | 1325 | execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); |
| @@ -1345,15 +1345,17 @@ execlists_schedule_out(struct i915_request *rq) · 19 unmodified lines | ||
| 1345 | 1345 | { |
| 1346 | 1346 | struct intel_context * const ce = rq->context; |
| 1347 | 1347 | struct intel_engine_cs *cur, *old; |
| 1348 | + u32 ccid; | |
| 1348 | 1349 | |
| 1349 | 1350 | trace_i915_request_out(rq); |
| 1350 | 1351 | |
| 1352 | + ccid = rq->context->lrc.ccid; | |
| 1351 | 1353 | old = READ_ONCE(ce->inflight); |
| 1352 | 1354 | do |
| 1353 | 1355 | cur = ptr_unmask_bits(old, 2) ? ptr_dec(old) : NULL; |
| 1354 | 1356 | while (!try_cmpxchg(&ce->inflight, &old, cur)); |
| 1355 | 1357 | if (!cur) |
| 1356 | − __execlists_schedule_out(rq, old); | |
| 1358 | + __execlists_schedule_out(rq, old, ccid); | |
| 1357 | 1359 | |
| 1358 | 1360 | i915_request_put(rq); |
| 1359 | 1361 | } |
| @@ -1361,7 +1363,7 @@ execlists_schedule_out(struct i915_request *rq) · 1 unmodified line | ||
| 1361 | 1363 | static u64 execlists_update_context(struct i915_request *rq) |
| 1362 | 1364 | { |
| 1363 | 1365 | struct intel_context *ce = rq->context; |
| 1364 | − u64 desc = ce->lrc_desc; | |
| 1366 | + u64 desc = ce->lrc.desc; | |
| 1365 | 1367 | u32 tail, prev; |
| 1366 | 1368 | |
| 1367 | 1369 | /* |
| @@ -1400,7 +1402,7 @@ static u64 execlists_update_context(struct i915_request *rq) · 32 unmodified lines | ||
| 1400 | 1402 | */ |
| 1401 | 1403 | wmb(); |
| 1402 | 1404 | |
| 1403 | − ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE; | |
| 1405 | + ce->lrc.desc &= ~CTX_DESC_FORCE_RESTORE; | |
| 1404 | 1406 | return desc; |
| 1405 | 1407 | } |
| 1406 | 1408 | |
| @@ -1719,6 +1721,9 @@ static void defer_request(struct i915_request *rq, struct list_head * const pl) · 312 unmodified lines | ||
| 1719 | 1721 | struct i915_request *w = |
| 1720 | 1722 | container_of(p->waiter, typeof(*w), sched); |
| 1721 | 1723 | |
| 1724 | + if (p->flags & I915_DEPENDENCY_WEAK) | |
| 1725 | + continue; | |
| 1726 | + | |
| 1722 | 1727 | /* Leave semaphores spinning on the other engines */ |
| 1723 | 1728 | if (w->engine != rq->engine) |
| 1724 | 1729 | continue; |
| @@ -1754,7 +1759,8 @@ static void defer_active(struct intel_engine_cs *engine) · 29 unmodified lines | ||
| 1754 | 1759 | } |
| 1755 | 1760 | |
| 1756 | 1761 | static bool |
| 1757 | −need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq) | |
| 1762 | +need_timeslice(const struct intel_engine_cs *engine, | |
| 1763 | + const struct i915_request *rq) | |
| 1758 | 1764 | { |
| 1759 | 1765 | int hint; |
| 1760 | 1766 | |
| @@ -1768,6 +1774,32 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq) · 7 unmodified lines | ||
| 1768 | 1774 | return hint >= effective_prio(rq); |
| 1769 | 1775 | } |
| 1770 | 1776 | |
| 1777 | +static bool | |
| 1778 | +timeslice_yield(const struct intel_engine_execlists *el, | |
| 1779 | + const struct i915_request *rq) | |
| 1780 | +{ | |
| 1781 | + /* | |
| 1782 | + * Once bitten, forever smitten! | |
| 1783 | + * | |
| 1784 | + * If the active context ever busy-waited on a semaphore, | |
| 1785 | + * it will be treated as a hog until the end of its timeslice (i.e. | |
| 1786 | + * until it is scheduled out and replaced by a new submission, | |
| 1787 | + * possibly even its own lite-restore). The HW only sends an interrupt | |
| 1788 | + * on the first miss, and we do know if that semaphore has been | |
| 1789 | + * signaled, or even if it is now stuck on another semaphore. Play | |
| 1790 | + * safe, yield if it might be stuck -- it will be given a fresh | |
| 1791 | + * timeslice in the near future. | |
| 1792 | + */ | |
| 1793 | + return rq->context->lrc.ccid == READ_ONCE(el->yield); | |
| 1794 | +} | |
| 1795 | + | |
| 1796 | +static bool | |
| 1797 | +timeslice_expired(const struct intel_engine_execlists *el, | |
| 1798 | + const struct i915_request *rq) | |
| 1799 | +{ | |
| 1800 | + return timer_expired(&el->timer) || timeslice_yield(el, rq); | |
| 1801 | +} | |
| 1802 | + | |
| 1771 | 1803 | static int |
| 1772 | 1804 | switch_prio(struct intel_engine_cs *engine, const struct i915_request *rq) |
| 1773 | 1805 | { |
| @@ -1783,8 +1815,7 @@ timeslice(const struct intel_engine_cs *engine) · 9 unmodified lines | ||
| 1783 | 1815 | return READ_ONCE(engine->props.timeslice_duration_ms); |
| 1784 | 1816 | } |
| 1785 | 1817 | |
| 1786 | −static unsigned long | |
| 1787 | −active_timeslice(const struct intel_engine_cs *engine) | |
| 1818 | +static unsigned long active_timeslice(const struct intel_engine_cs *engine) | |
| 1788 | 1819 | { |
| 1789 | 1820 | const struct intel_engine_execlists *execlists = &engine->execlists; |
| 1790 | 1821 | const struct i915_request *rq = *execlists->active; |
| @@ -1946,13 +1977,14 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 155 unmodified lines | ||
| 1946 | 1977 | |
| 1947 | 1978 | last = NULL; |
| 1948 | 1979 | } else if (need_timeslice(engine, last) && |
| 1949 | − timer_expired(&engine->execlists.timer)) { | |
| 1980 | + timeslice_expired(execlists, last)) { | |
| 1950 | 1981 | ENGINE_TRACE(engine, |
| 1951 | − "expired last=%llx:%lld, prio=%d, hint=%d\n", | |
| 1982 | + "expired last=%llx:%lld, prio=%d, hint=%d, yield?=%s\n", | |
| 1952 | 1983 | last->fence.context, |
| 1953 | 1984 | last->fence.seqno, |
| 1954 | 1985 | last->sched.attr.priority, |
| 1955 | − execlists->queue_priority_hint); | |
| 1986 | + execlists->queue_priority_hint, | |
| 1987 | + yesno(timeslice_yield(execlists, last))); | |
| 1956 | 1988 | |
| 1957 | 1989 | ring_set_paused(engine, 1); |
| 1958 | 1990 | defer_active(engine); |
| @@ -2213,6 +2245,7 @@ done: · 254 unmodified lines | ||
| 2213 | 2245 | } |
| 2214 | 2246 | clear_ports(port + 1, last_port - port); |
| 2215 | 2247 | |
| 2248 | + WRITE_ONCE(execlists->yield, -1); | |
| 2216 | 2249 | execlists_submit_ports(engine); |
| 2217 | 2250 | set_preempt_timeout(engine, *active); |
| 2218 | 2251 | } else { |
| @@ -3043,7 +3076,7 @@ __execlists_context_pin(struct intel_context *ce, · 824 unmodified lines | ||
| 3043 | 3076 | if (IS_ERR(vaddr)) |
| 3044 | 3077 | return PTR_ERR(vaddr); |
| 3045 | 3078 | |
| 3046 | − ce->lrc_desc = lrc_descriptor(ce, engine) | CTX_DESC_FORCE_RESTORE; | |
| 3079 | + ce->lrc.lrca = lrc_descriptor(ce, engine) | CTX_DESC_FORCE_RESTORE; | |
| 3047 | 3080 | ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; |
| 3048 | 3081 | __execlists_update_reg_state(ce, engine, ce->ring->tail); |
| 3049 | 3082 | |
| @@ -3072,7 +3105,7 @@ static void execlists_context_reset(struct intel_context *ce) · 22 unmodified lines | ||
| 3072 | 3105 | ce, ce->engine, ce->ring, true); |
| 3073 | 3106 | __execlists_update_reg_state(ce, ce->engine, ce->ring->tail); |
| 3074 | 3107 | |
| 3075 | − ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; | |
| 3108 | + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; | |
| 3076 | 3109 | } |
| 3077 | 3110 | |
| 3078 | 3111 | static const struct intel_context_ops execlists_context_ops = { |
| @@ -3541,7 +3574,7 @@ static void enable_execlists(struct intel_engine_cs *engine) · 462 unmodified lines | ||
| 3541 | 3574 | |
| 3542 | 3575 | enable_error_interrupt(engine); |
| 3543 | 3576 | |
| 3544 | − engine->context_tag = 0; | |
| 3577 | + engine->context_tag = GENMASK(BITS_PER_LONG - 2, 0); | |
| 3545 | 3578 | } |
| 3546 | 3579 | |
| 3547 | 3580 | static bool unexpected_starting_state(struct intel_engine_cs *engine) |
| @@ -3753,7 +3786,7 @@ out_replay: · 205 unmodified lines | ||
| 3753 | 3786 | head, ce->ring->tail); |
| 3754 | 3787 | __execlists_reset_reg_state(ce, engine); |
| 3755 | 3788 | __execlists_update_reg_state(ce, engine, head); |
| 3756 | − ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; /* paranoid: GPU was reset! */ | |
| 3789 | + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; /* paranoid: GPU was reset! */ | |
| 3757 | 3790 | |
| 3758 | 3791 | unwind: |
| 3759 | 3792 | /* Push back any incomplete requests for replay after the reset. */ |
| @@ -4369,8 +4402,11 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine) · 609 unmodified lines | ||
| 4369 | 4402 | engine->flags |= I915_ENGINE_SUPPORTS_STATS; |
| 4370 | 4403 | if (!intel_vgpu_active(engine->i915)) { |
| 4371 | 4404 | engine->flags |= I915_ENGINE_HAS_SEMAPHORES; |
| 4372 | − if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) | |
| 4405 | + if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) { | |
| 4373 | 4406 | engine->flags |= I915_ENGINE_HAS_PREEMPTION; |
| 4407 | + if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) | |
| 4408 | + engine->flags |= I915_ENGINE_HAS_TIMESLICES; | |
| 4409 | + } | |
| 4374 | 4410 | } |
| 4375 | 4411 | |
| 4376 | 4412 | if (INTEL_GEN(engine->i915) >= 12) |
| @@ -4449,6 +4485,7 @@ logical_ring_default_irqs(struct intel_engine_cs *engine) · 72 unmodified lines | ||
| 4449 | 4485 | engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; |
| 4450 | 4486 | engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; |
| 4451 | 4487 | engine->irq_keep_mask |= GT_CS_MASTER_ERROR_INTERRUPT << shift; |
| 4488 | + engine->irq_keep_mask |= GT_WAIT_SEMAPHORE_INTERRUPT << shift; | |
| 4452 | 4489 | } |
| 4453 | 4490 | |
| 4454 | 4491 | static void rcs_submission_override(struct intel_engine_cs *engine) |
| @@ -4516,6 +4553,11 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine) · 61 unmodified lines | ||
| 4516 | 4553 | else |
| 4517 | 4554 | execlists->csb_size = GEN11_CSB_ENTRIES; |
| 4518 | 4555 | |
| 4556 | + if (INTEL_GEN(engine->i915) >= 11) { | |
| 4557 | + execlists->ccid |= engine->instance << (GEN11_ENGINE_INSTANCE_SHIFT - 32); | |
| 4558 | + execlists->ccid |= engine->class << (GEN11_ENGINE_CLASS_SHIFT - 32); | |
| 4559 | + } | |
| 4560 | + | |
| 4519 | 4561 | reset_csb_pointers(engine); |
| 4520 | 4562 | |
| 4521 | 4563 | /* Finally, take ownership and responsibility for cleanup! */ |
| @@ -929,7 +929,7 @@ create_rewinder(struct intel_context *ce, · 928 unmodified lines | ||
| 929 | 929 | goto err; |
| 930 | 930 | } |
| 931 | 931 | |
| 932 | − cs = intel_ring_begin(rq, 10); | |
| 932 | + cs = intel_ring_begin(rq, 14); | |
| 933 | 933 | if (IS_ERR(cs)) { |
| 934 | 934 | err = PTR_ERR(cs); |
| 935 | 935 | goto err; |
| @@ -941,8 +941,8 @@ create_rewinder(struct intel_context *ce, · 5 unmodified lines | ||
| 941 | 941 | *cs++ = MI_SEMAPHORE_WAIT | |
| 942 | 942 | MI_SEMAPHORE_GLOBAL_GTT | |
| 943 | 943 | MI_SEMAPHORE_POLL | |
| 944 | − MI_SEMAPHORE_SAD_NEQ_SDD; | |
| 945 | − *cs++ = 0; | |
| 944 | + MI_SEMAPHORE_SAD_GTE_SDD; | |
| 945 | + *cs++ = idx; | |
| 946 | 946 | *cs++ = offset; |
| 947 | 947 | *cs++ = 0; |
| 948 | 948 | |
| @@ -951,6 +951,11 @@ create_rewinder(struct intel_context *ce, · 2 unmodified lines | ||
| 951 | 951 | *cs++ = offset + idx * sizeof(u32); |
| 952 | 952 | *cs++ = 0; |
| 953 | 953 | |
| 954 | + *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; | |
| 955 | + *cs++ = offset; | |
| 956 | + *cs++ = 0; | |
| 957 | + *cs++ = idx + 1; | |
| 958 | + | |
| 954 | 959 | intel_ring_advance(rq, cs); |
| 955 | 960 | |
| 956 | 961 | rq->sched.attr.priority = I915_PRIORITY_MASK; |
| @@ -984,7 +989,7 @@ static int live_timeslice_rewind(void *arg) · 27 unmodified lines | ||
| 984 | 989 | |
| 985 | 990 | for_each_engine(engine, gt, id) { |
| 986 | 991 | enum { A1, A2, B1 }; |
| 987 | − enum { X = 1, Y, Z }; | |
| 992 | + enum { X = 1, Z, Y }; | |
| 988 | 993 | struct i915_request *rq[3] = {}; |
| 989 | 994 | struct intel_context *ce; |
| 990 | 995 | unsigned long heartbeat; |
| @@ -1017,13 +1022,13 @@ static int live_timeslice_rewind(void *arg) · 26 unmodified lines | ||
| 1017 | 1022 | goto err; |
| 1018 | 1023 | } |
| 1019 | 1024 | |
| 1020 | − rq[0] = create_rewinder(ce, NULL, slot, 1); | |
| 1025 | + rq[0] = create_rewinder(ce, NULL, slot, X); | |
| 1021 | 1026 | if (IS_ERR(rq[0])) { |
| 1022 | 1027 | intel_context_put(ce); |
| 1023 | 1028 | goto err; |
| 1024 | 1029 | } |
| 1025 | 1030 | |
| 1026 | − rq[1] = create_rewinder(ce, NULL, slot, 2); | |
| 1031 | + rq[1] = create_rewinder(ce, NULL, slot, Y); | |
| 1027 | 1032 | intel_context_put(ce); |
| 1028 | 1033 | if (IS_ERR(rq[1])) |
| 1029 | 1034 | goto err; |
| @@ -1041,7 +1046,7 @@ static int live_timeslice_rewind(void *arg) · 11 unmodified lines | ||
| 1041 | 1046 | goto err; |
| 1042 | 1047 | } |
| 1043 | 1048 | |
| 1044 | − rq[2] = create_rewinder(ce, rq[0], slot, 3); | |
| 1049 | + rq[2] = create_rewinder(ce, rq[0], slot, Z); | |
| 1045 | 1050 | intel_context_put(ce); |
| 1046 | 1051 | if (IS_ERR(rq[2])) |
| 1047 | 1052 | goto err; |
| @@ -1055,15 +1060,12 @@ static int live_timeslice_rewind(void *arg) · 7 unmodified lines | ||
| 1055 | 1060 | GEM_BUG_ON(!timer_pending(&engine->execlists.timer)); |
| 1056 | 1061 | |
| 1057 | 1062 | /* ELSP[] = { { A:rq1, A:rq2 }, { B:rq1 } } */ |
| 1058 | − GEM_BUG_ON(!i915_request_is_active(rq[A1])); | |
| 1059 | − GEM_BUG_ON(!i915_request_is_active(rq[A2])); | |
| 1060 | − GEM_BUG_ON(!i915_request_is_active(rq[B1])); | |
| 1061 | − | |
| 1062 | − /* Wait for the timeslice to kick in */ | |
| 1063 | − del_timer(&engine->execlists.timer); | |
| 1064 | − tasklet_hi_schedule(&engine->execlists.tasklet); | |
| 1065 | − intel_engine_flush_submission(engine); | |
| 1066 | − | |
| 1063 | + if (i915_request_is_active(rq[A2])) { /* semaphore yielded! */ | |
| 1064 | + /* Wait for the timeslice to kick in */ | |
| 1065 | + del_timer(&engine->execlists.timer); | |
| 1066 | + tasklet_hi_schedule(&engine->execlists.tasklet); | |
| 1067 | + intel_engine_flush_submission(engine); | |
| 1068 | + } | |
| 1067 | 1069 | /* -> ELSP[] = { { A:rq1 }, { B:rq1 } } */ |
| 1068 | 1070 | GEM_BUG_ON(!i915_request_is_active(rq[A1])); |
| 1069 | 1071 | GEM_BUG_ON(!i915_request_is_active(rq[B1])); |
| @@ -217,7 +217,7 @@ static void guc_wq_item_append(struct intel_guc *guc, · 216 unmodified lines | ||
| 217 | 217 | static void guc_add_request(struct intel_guc *guc, struct i915_request *rq) |
| 218 | 218 | { |
| 219 | 219 | struct intel_engine_cs *engine = rq->engine; |
| 220 | − u32 ctx_desc = lower_32_bits(rq->context->lrc_desc); | |
| 220 | + u32 ctx_desc = rq->context->lrc.ccid; | |
| 221 | 221 | u32 ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); |
| 222 | 222 | |
| 223 | 223 | guc_wq_item_append(guc, engine->guc_id, ctx_desc, |
| @@ -208,14 +208,41 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 207 unmodified lines | ||
| 208 | 208 | SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | |
| 209 | 209 | SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | |
| 210 | 210 | SKL_FUSE_PG_DIST_STATUS(SKL_PG2); |
| 211 | − vgpu_vreg_t(vgpu, LCPLL1_CTL) |= | |
| 212 | − LCPLL_PLL_ENABLE | | |
| 213 | − LCPLL_PLL_LOCK; | |
| 214 | − vgpu_vreg_t(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE; | |
| 215 | − | |
| 211 | + /* | |
| 212 | + * Only 1 PIPE enabled in current vGPU display and PIPE_A is | |
| 213 | + * tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A, | |
| 214 | + * TRANSCODER_A can be enabled. PORT_x depends on the input of | |
| 215 | + * setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x | |
| 216 | + * so we fixed to DPLL0 here. | |
| 217 | + * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode | |
| 218 | + */ | |
| 219 | + vgpu_vreg_t(vgpu, DPLL_CTRL1) = | |
| 220 | + DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0); | |
| 221 | + vgpu_vreg_t(vgpu, DPLL_CTRL1) |= | |
| 222 | + DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0); | |
| 223 | + vgpu_vreg_t(vgpu, LCPLL1_CTL) = | |
| 224 | + LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK; | |
| 225 | + vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0); | |
| 226 | + /* | |
| 227 | + * Golden M/N are calculated based on: | |
| 228 | + * 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID), | |
| 229 | + * DP link clk 1620 MHz and non-constant_n. | |
| 230 | + * TODO: calculate DP link symbol clk and stream clk m/n. | |
| 231 | + */ | |
| 232 | + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT; | |
| 233 | + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e; | |
| 234 | + vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000; | |
| 235 | + vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e; | |
| 236 | + vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000; | |
| 216 | 237 | } |
| 217 | 238 | |
| 218 | 239 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { |
| 240 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= | |
| 241 | + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_B); | |
| 242 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 243 | + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B); | |
| 244 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 245 | + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B); | |
| 219 | 246 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED; |
| 220 | 247 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= |
| 221 | 248 | ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | |
| @@ -236,6 +263,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 14 unmodified lines | ||
| 236 | 263 | } |
| 237 | 264 | |
| 238 | 265 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { |
| 266 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= | |
| 267 | + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_C); | |
| 268 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 269 | + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C); | |
| 270 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 271 | + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C); | |
| 239 | 272 | vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT; |
| 240 | 273 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= |
| 241 | 274 | ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | |
| @@ -256,6 +289,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 14 unmodified lines | ||
| 256 | 289 | } |
| 257 | 290 | |
| 258 | 291 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) { |
| 292 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= | |
| 293 | + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_D); | |
| 294 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 295 | + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D); | |
| 296 | + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= | |
| 297 | + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D); | |
| 259 | 298 | vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT; |
| 260 | 299 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= |
| 261 | 300 | ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | |
| @@ -290,7 +290,7 @@ static void · 289 unmodified lines | ||
| 290 | 290 | shadow_context_descriptor_update(struct intel_context *ce, |
| 291 | 291 | struct intel_vgpu_workload *workload) |
| 292 | 292 | { |
| 293 | − u64 desc = ce->lrc_desc; | |
| 293 | + u64 desc = ce->lrc.desc; | |
| 294 | 294 | |
| 295 | 295 | /* |
| 296 | 296 | * Update bits 0-11 of the context descriptor which includes flags |
| @@ -300,7 +300,7 @@ shadow_context_descriptor_update(struct intel_context *ce, · 3 unmodified lines | ||
| 300 | 300 | desc |= (u64)workload->ctx_desc.addressing_mode << |
| 301 | 301 | GEN8_CTX_ADDRESSING_MODE_SHIFT; |
| 302 | 302 | |
| 303 | − ce->lrc_desc = desc; | |
| 303 | + ce->lrc.desc = desc; | |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | 306 | static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) |
| @@ -379,7 +379,11 @@ static void set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload, · 72 unmodified lines | ||
| 379 | 379 | for (i = 0; i < GVT_RING_CTX_NR_PDPS; i++) { |
| 380 | 380 | struct i915_page_directory * const pd = |
| 381 | 381 | i915_pd_entry(ppgtt->pd, i); |
| 382 | − | |
| 382 | + /* skip now as current i915 ppgtt alloc won't allocate | |
| 383 | + top level pdp for non 4-level table, won't impact | |
| 384 | + shadow ppgtt. */ | |
| 385 | + if (!pd) | |
| 386 | + break; | |
| 383 | 387 | px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i]; |
| 384 | 388 | } |
| 385 | 389 | } |
| @@ -128,6 +128,13 @@ search_again: · 127 unmodified lines | ||
| 128 | 128 | active = NULL; |
| 129 | 129 | INIT_LIST_HEAD(&eviction_list); |
| 130 | 130 | list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) { |
| 131 | + if (vma == active) { /* now seen this vma twice */ | |
| 132 | + if (flags & PIN_NONBLOCK) | |
| 133 | + break; | |
| 134 | + | |
| 135 | + active = ERR_PTR(-EAGAIN); | |
| 136 | + } | |
| 137 | + | |
| 131 | 138 | /* |
| 132 | 139 | * We keep this list in a rough least-recently scanned order |
| 133 | 140 | * of active elements (inactive elements are cheap to reap). |
| @@ -143,21 +150,12 @@ search_again: · 9 unmodified lines | ||
| 143 | 150 | * To notice when we complete one full cycle, we record the |
| 144 | 151 | * first active element seen, before moving it to the tail. |
| 145 | 152 | */ |
| 146 | − if (i915_vma_is_active(vma)) { | |
| 147 | − if (vma == active) { | |
| 148 | − if (flags & PIN_NONBLOCK) | |
| 149 | − break; | |
| 150 | − | |
| 151 | − active = ERR_PTR(-EAGAIN); | |
| 152 | − } | |
| 153 | − | |
| 154 | − if (active != ERR_PTR(-EAGAIN)) { | |
| 155 | − if (!active) | |
| 156 | − active = vma; | |
| 153 | + if (active != ERR_PTR(-EAGAIN) && i915_vma_is_active(vma)) { | |
| 154 | + if (!active) | |
| 155 | + active = vma; | |
| 157 | 156 | |
| 158 | − list_move_tail(&vma->vm_link, &vm->bound_list); | |
| 159 | − continue; | |
| 160 | − } | |
| 157 | + list_move_tail(&vma->vm_link, &vm->bound_list); | |
| 158 | + continue; | |
| 161 | 159 | } |
| 162 | 160 | |
| 163 | 161 | if (mark_free(&scan, vma, flags, &eviction_list)) |
| @@ -1207,8 +1207,6 @@ static void engine_record_registers(struct intel_engine_coredump *ee) · 1206 unmodified lines | ||
| 1207 | 1207 | static void record_request(const struct i915_request *request, |
| 1208 | 1208 | struct i915_request_coredump *erq) |
| 1209 | 1209 | { |
| 1210 | − const struct i915_gem_context *ctx; | |
| 1211 | − | |
| 1212 | 1210 | erq->flags = request->fence.flags; |
| 1213 | 1211 | erq->context = request->fence.context; |
| 1214 | 1212 | erq->seqno = request->fence.seqno; |
| @@ -1219,9 +1217,13 @@ static void record_request(const struct i915_request *request, · 4 unmodified lines | ||
| 1219 | 1217 | |
| 1220 | 1218 | erq->pid = 0; |
| 1221 | 1219 | rcu_read_lock(); |
| 1222 | − ctx = rcu_dereference(request->context->gem_context); | |
| 1223 | − if (ctx) | |
| 1224 | − erq->pid = pid_nr(ctx->pid); | |
| 1220 | + if (!intel_context_is_closed(request->context)) { | |
| 1221 | + const struct i915_gem_context *ctx; | |
| 1222 | + | |
| 1223 | + ctx = rcu_dereference(request->context->gem_context); | |
| 1224 | + if (ctx) | |
| 1225 | + erq->pid = pid_nr(ctx->pid); | |
| 1226 | + } | |
| 1225 | 1227 | rcu_read_unlock(); |
| 1226 | 1228 | } |
| 1227 | 1229 | |
| @@ -3361,7 +3361,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 3360 unmodified lines | ||
| 3361 | 3361 | u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | |
| 3362 | 3362 | GEN8_PIPE_CDCLK_CRC_DONE; |
| 3363 | 3363 | u32 de_pipe_enables; |
| 3364 | − u32 de_port_masked = GEN8_AUX_CHANNEL_A; | |
| 3364 | + u32 de_port_masked = gen8_de_port_aux_mask(dev_priv); | |
| 3365 | 3365 | u32 de_port_enables; |
| 3366 | 3366 | u32 de_misc_masked = GEN8_DE_EDP_PSR; |
| 3367 | 3367 | enum pipe pipe; |
| @@ -3369,18 +3369,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 1 unmodified line | ||
| 3369 | 3369 | if (INTEL_GEN(dev_priv) <= 10) |
| 3370 | 3370 | de_misc_masked |= GEN8_DE_MISC_GSE; |
| 3371 | 3371 | |
| 3372 | − if (INTEL_GEN(dev_priv) >= 9) { | |
| 3373 | − de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | | |
| 3374 | − GEN9_AUX_CHANNEL_D; | |
| 3375 | − if (IS_GEN9_LP(dev_priv)) | |
| 3376 | − de_port_masked |= BXT_DE_PORT_GMBUS; | |
| 3377 | − } | |
| 3378 | − | |
| 3379 | − if (INTEL_GEN(dev_priv) >= 11) | |
| 3380 | − de_port_masked |= ICL_AUX_CHANNEL_E; | |
| 3381 | − | |
| 3382 | − if (IS_CNL_WITH_PORT_F(dev_priv) || INTEL_GEN(dev_priv) >= 11) | |
| 3383 | − de_port_masked |= CNL_AUX_CHANNEL_F; | |
| 3372 | + if (IS_GEN9_LP(dev_priv)) | |
| 3373 | + de_port_masked |= BXT_DE_PORT_GMBUS; | |
| 3384 | 3374 | |
| 3385 | 3375 | de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | |
| 3386 | 3376 | GEN8_PIPE_FIFO_UNDERRUN; |
| @@ -1310,8 +1310,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) · 1309 unmodified lines | ||
| 1310 | 1310 | * dropped by GuC. They won't be part of the context |
| 1311 | 1311 | * ID in the OA reports, so squash those lower bits. |
| 1312 | 1312 | */ |
| 1313 | − stream->specific_ctx_id = | |
| 1314 | − lower_32_bits(ce->lrc_desc) >> 12; | |
| 1313 | + stream->specific_ctx_id = ce->lrc.lrca >> 12; | |
| 1315 | 1314 | |
| 1316 | 1315 | /* |
| 1317 | 1316 | * GuC uses the top bit to signal proxy submission, so |
| @@ -1328,11 +1327,10 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) · 10 unmodified lines | ||
| 1328 | 1327 | ((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32); |
| 1329 | 1328 | /* |
| 1330 | 1329 | * Pick an unused context id |
| 1331 | − * 0 - (NUM_CONTEXT_TAG - 1) are used by other contexts | |
| 1330 | + * 0 - BITS_PER_LONG are used by other contexts | |
| 1332 | 1331 | * GEN12_MAX_CONTEXT_HW_ID (0x7ff) is used by idle context |
| 1333 | 1332 | */ |
| 1334 | 1333 | stream->specific_ctx_id = (GEN12_MAX_CONTEXT_HW_ID - 1) << (GEN11_SW_CTX_ID_SHIFT - 32); |
| 1335 | − BUILD_BUG_ON((GEN12_MAX_CONTEXT_HW_ID - 1) < NUM_CONTEXT_TAG); | |
| 1336 | 1334 | break; |
| 1337 | 1335 | } |
| 1338 | 1336 | |
| @@ -3094,6 +3094,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 3093 unmodified lines | ||
| 3094 | 3094 | #define GT_BSD_CS_ERROR_INTERRUPT (1 << 15) |
| 3095 | 3095 | #define GT_BSD_USER_INTERRUPT (1 << 12) |
| 3096 | 3096 | #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */ |
| 3097 | +#define GT_WAIT_SEMAPHORE_INTERRUPT REG_BIT(11) /* bdw+ */ | |
| 3097 | 3098 | #define GT_CONTEXT_SWITCH_INTERRUPT (1 << 8) |
| 3098 | 3099 | #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */ |
| 3099 | 3100 | #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4) |
| @@ -1017,11 +1017,15 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) · 1016 unmodified lines | ||
| 1017 | 1017 | GEM_BUG_ON(to == from); |
| 1018 | 1018 | GEM_BUG_ON(to->timeline == from->timeline); |
| 1019 | 1019 | |
| 1020 | − if (i915_request_completed(from)) | |
| 1020 | + if (i915_request_completed(from)) { | |
| 1021 | + i915_sw_fence_set_error_once(&to->submit, from->fence.error); | |
| 1021 | 1022 | return 0; |
| 1023 | + } | |
| 1022 | 1024 | |
| 1023 | 1025 | if (to->engine->schedule) { |
| 1024 | − ret = i915_sched_node_add_dependency(&to->sched, &from->sched); | |
| 1026 | + ret = i915_sched_node_add_dependency(&to->sched, | |
| 1027 | + &from->sched, | |
| 1028 | + I915_DEPENDENCY_EXTERNAL); | |
| 1025 | 1029 | if (ret < 0) |
| 1026 | 1030 | return ret; |
| 1027 | 1031 | } |
| @@ -1183,7 +1187,9 @@ __i915_request_await_execution(struct i915_request *to, · 155 unmodified lines | ||
| 1183 | 1187 | |
| 1184 | 1188 | /* Couple the dependency tree for PI on this exposed to->fence */ |
| 1185 | 1189 | if (to->engine->schedule) { |
| 1186 | − err = i915_sched_node_add_dependency(&to->sched, &from->sched); | |
| 1190 | + err = i915_sched_node_add_dependency(&to->sched, | |
| 1191 | + &from->sched, | |
| 1192 | + I915_DEPENDENCY_WEAK); | |
| 1187 | 1193 | if (err < 0) |
| 1188 | 1194 | return err; |
| 1189 | 1195 | } |
| @@ -456,7 +456,8 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node, · 455 unmodified lines | ||
| 456 | 456 | } |
| 457 | 457 | |
| 458 | 458 | int i915_sched_node_add_dependency(struct i915_sched_node *node, |
| 459 | − struct i915_sched_node *signal) | |
| 459 | + struct i915_sched_node *signal, | |
| 460 | + unsigned long flags) | |
| 460 | 461 | { |
| 461 | 462 | struct i915_dependency *dep; |
| 462 | 463 | |
| @@ -465,8 +466,7 @@ int i915_sched_node_add_dependency(struct i915_sched_node *node, · 2 unmodified lines | ||
| 465 | 466 | return -ENOMEM; |
| 466 | 467 | |
| 467 | 468 | if (!__i915_sched_node_add_dependency(node, signal, dep, |
| 468 | − I915_DEPENDENCY_EXTERNAL | | |
| 469 | − I915_DEPENDENCY_ALLOC)) | |
| 469 | + flags | I915_DEPENDENCY_ALLOC)) | |
| 470 | 470 | i915_dependency_free(dep); |
| 471 | 471 | |
| 472 | 472 | return 0; |
| @@ -34,7 +34,8 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node, · 33 unmodified lines | ||
| 34 | 34 | unsigned long flags); |
| 35 | 35 | |
| 36 | 36 | int i915_sched_node_add_dependency(struct i915_sched_node *node, |
| 37 | − struct i915_sched_node *signal); | |
| 37 | + struct i915_sched_node *signal, | |
| 38 | + unsigned long flags); | |
| 38 | 39 | |
| 39 | 40 | void i915_sched_node_fini(struct i915_sched_node *node); |
| 40 | 41 | |
| @@ -78,6 +78,7 @@ struct i915_dependency { · 77 unmodified lines | ||
| 78 | 78 | unsigned long flags; |
| 79 | 79 | #define I915_DEPENDENCY_ALLOC BIT(0) |
| 80 | 80 | #define I915_DEPENDENCY_EXTERNAL BIT(1) |
| 81 | +#define I915_DEPENDENCY_WEAK BIT(2) | |
| 81 | 82 | }; |
| 82 | 83 | |
| 83 | 84 | #endif /* _I915_SCHEDULER_TYPES_H_ */ |
| @@ -1228,18 +1228,6 @@ int __i915_vma_unbind(struct i915_vma *vma) · 1227 unmodified lines | ||
| 1228 | 1228 | |
| 1229 | 1229 | lockdep_assert_held(&vma->vm->mutex); |
| 1230 | 1230 | |
| 1231 | − /* | |
| 1232 | − * First wait upon any activity as retiring the request may | |
| 1233 | − * have side-effects such as unpinning or even unbinding this vma. | |
| 1234 | − * | |
| 1235 | − * XXX Actually waiting under the vm->mutex is a hinderance and | |
| 1236 | − * should be pipelined wherever possible. In cases where that is | |
| 1237 | − * unavoidable, we should lift the wait to before the mutex. | |
| 1238 | − */ | |
| 1239 | − ret = i915_vma_sync(vma); | |
| 1240 | − if (ret) | |
| 1241 | − return ret; | |
| 1242 | − | |
| 1243 | 1231 | if (i915_vma_is_pinned(vma)) { |
| 1244 | 1232 | vma_print_allocator(vma, "is pinned"); |
| 1245 | 1233 | return -EAGAIN; |
| @@ -1313,15 +1301,20 @@ int i915_vma_unbind(struct i915_vma *vma) · 67 unmodified lines | ||
| 1313 | 1301 | if (!drm_mm_node_allocated(&vma->node)) |
| 1314 | 1302 | return 0; |
| 1315 | 1303 | |
| 1316 | − if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) | |
| 1317 | − /* XXX not always required: nop_clear_range */ | |
| 1318 | − wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm); | |
| 1319 | − | |
| 1320 | 1304 | /* Optimistic wait before taking the mutex */ |
| 1321 | 1305 | err = i915_vma_sync(vma); |
| 1322 | 1306 | if (err) |
| 1323 | 1307 | goto out_rpm; |
| 1324 | 1308 | |
| 1309 | + if (i915_vma_is_pinned(vma)) { | |
| 1310 | + vma_print_allocator(vma, "is pinned"); | |
| 1311 | + return -EAGAIN; | |
| 1312 | + } | |
| 1313 | + | |
| 1314 | + if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) | |
| 1315 | + /* XXX not always required: nop_clear_range */ | |
| 1316 | + wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm); | |
| 1317 | + | |
| 1325 | 1318 | err = mutex_lock_interruptible(&vm->mutex); |
| 1326 | 1319 | if (err) |
| 1327 | 1320 | goto out_rpm; |
| @@ -4992,7 +4992,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, · 4991 unmodified lines | ||
| 4992 | 4992 | * WaIncreaseLatencyIPCEnabled: kbl,cfl |
| 4993 | 4993 | * Display WA #1141: kbl,cfl |
| 4994 | 4994 | */ |
| 4995 | − if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) || | |
| 4995 | + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && | |
| 4996 | 4996 | dev_priv->ipc_enabled) |
| 4997 | 4997 | latency += 4; |
| 4998 | 4998 | |
| @@ -173,7 +173,7 @@ static int igt_vma_create(void *arg) · 172 unmodified lines | ||
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | nc = 0; |
| 176 | − for_each_prime_number(num_ctx, 2 * NUM_CONTEXT_TAG) { | |
| 176 | + for_each_prime_number(num_ctx, 2 * BITS_PER_LONG) { | |
| 177 | 177 | for (; nc < num_ctx; nc++) { |
| 178 | 178 | ctx = mock_context(i915, "mock"); |
| 179 | 179 | if (!ctx) |
| @@ -412,9 +412,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev) · 411 unmodified lines | ||
| 412 | 412 | if (priv->afbcd.ops) |
| 413 | 413 | priv->afbcd.ops->init(priv); |
| 414 | 414 | |
| 415 | − drm_mode_config_helper_resume(priv->drm); | |
| 416 | − | |
| 417 | − return 0; | |
| 415 | + return drm_mode_config_helper_resume(priv->drm); | |
| 418 | 416 | } |
| 419 | 417 | |
| 420 | 418 | static int compare_of(struct device *dev, void *data) |
| @@ -1039,6 +1039,7 @@ void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt, · 1038 unmodified lines | ||
| 1039 | 1039 | |
| 1040 | 1040 | static bool host1x_drm_wants_iommu(struct host1x_device *dev) |
| 1041 | 1041 | { |
| 1042 | + struct host1x *host1x = dev_get_drvdata(dev->dev.parent); | |
| 1042 | 1043 | struct iommu_domain *domain; |
| 1043 | 1044 | |
| 1044 | 1045 | /* |
| @@ -1076,7 +1077,7 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev) · 31 unmodified lines | ||
| 1076 | 1077 | * sufficient and whether or not the host1x is attached to an IOMMU |
| 1077 | 1078 | * doesn't matter. |
| 1078 | 1079 | */ |
| 1079 | − if (!domain && dma_get_mask(dev->dev.parent) <= DMA_BIT_MASK(32)) | |
| 1080 | + if (!domain && host1x_get_dma_mask(host1x) <= DMA_BIT_MASK(32)) | |
| 1080 | 1081 | return true; |
| 1081 | 1082 | |
| 1082 | 1083 | return domain != NULL; |
| @@ -850,7 +850,7 @@ extern void vmw_bo_bo_free(struct ttm_buffer_object *bo); · 849 unmodified lines | ||
| 850 | 850 | extern int vmw_bo_init(struct vmw_private *dev_priv, |
| 851 | 851 | struct vmw_buffer_object *vmw_bo, |
| 852 | 852 | size_t size, struct ttm_placement *placement, |
| 853 | − bool interuptable, | |
| 853 | + bool interruptible, | |
| 854 | 854 | void (*bo_free)(struct ttm_buffer_object *bo)); |
| 855 | 855 | extern int vmw_user_bo_verify_access(struct ttm_buffer_object *bo, |
| 856 | 856 | struct ttm_object_file *tfile); |
| @@ -515,7 +515,7 @@ bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence) · 514 unmodified lines | ||
| 515 | 515 | struct vmw_fence_manager *fman = fman_from_fence(fence); |
| 516 | 516 | |
| 517 | 517 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) |
| 518 | − return 1; | |
| 518 | + return true; | |
| 519 | 519 | |
| 520 | 520 | vmw_fences_update(fman); |
| 521 | 521 | |
| @@ -1651,7 +1651,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, · 1650 unmodified lines | ||
| 1651 | 1651 | struct vmw_surface_metadata *metadata; |
| 1652 | 1652 | struct ttm_base_object *base; |
| 1653 | 1653 | uint32_t backup_handle; |
| 1654 | − int ret = -EINVAL; | |
| 1654 | + int ret; | |
| 1655 | 1655 | |
| 1656 | 1656 | ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid, |
| 1657 | 1657 | req->handle_type, &base); |
| @@ -192,17 +192,55 @@ static void host1x_setup_sid_table(struct host1x *host) · 191 unmodified lines | ||
| 192 | 192 | } |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | +static bool host1x_wants_iommu(struct host1x *host1x) | |
| 196 | +{ | |
| 197 | + /* | |
| 198 | + * If we support addressing a maximum of 32 bits of physical memory | |
| 199 | + * and if the host1x firewall is enabled, there's no need to enable | |
| 200 | + * IOMMU support. This can happen for example on Tegra20, Tegra30 | |
| 201 | + * and Tegra114. | |
| 202 | + * | |
| 203 | + * Tegra124 and later can address up to 34 bits of physical memory and | |
| 204 | + * many platforms come equipped with more than 2 GiB of system memory, | |
| 205 | + * which requires crossing the 4 GiB boundary. But there's a catch: on | |
| 206 | + * SoCs before Tegra186 (i.e. Tegra124 and Tegra210), the host1x can | |
| 207 | + * only address up to 32 bits of memory in GATHER opcodes, which means | |
| 208 | + * that command buffers need to either be in the first 2 GiB of system | |
| 209 | + * memory (which could quickly lead to memory exhaustion), or command | |
| 210 | + * buffers need to be treated differently from other buffers (which is | |
| 211 | + * not possible with the current ABI). | |
| 212 | + * | |
| 213 | + * A third option is to use the IOMMU in these cases to make sure all | |
| 214 | + * buffers will be mapped into a 32-bit IOVA space that host1x can | |
| 215 | + * address. This allows all of the system memory to be used and works | |
| 216 | + * within the limitations of the host1x on these SoCs. | |
| 217 | + * | |
| 218 | + * In summary, default to enable IOMMU on Tegra124 and later. For any | |
| 219 | + * of the earlier SoCs, only use the IOMMU for additional safety when | |
| 220 | + * the host1x firewall is disabled. | |
| 221 | + */ | |
| 222 | + if (host1x->info->dma_mask <= DMA_BIT_MASK(32)) { | |
| 223 | + if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) | |
| 224 | + return false; | |
| 225 | + } | |
| 226 | + | |
| 227 | + return true; | |
| 228 | +} | |
| 229 | + | |
| 195 | 230 | static struct iommu_domain *host1x_iommu_attach(struct host1x *host) |
| 196 | 231 | { |
| 197 | 232 | struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); |
| 198 | 233 | int err; |
| 199 | 234 | |
| 200 | 235 | /* |
| 201 | − * If the host1x firewall is enabled, there's no need to enable IOMMU | |
| 202 | − * support. Similarly, if host1x is already attached to an IOMMU (via | |
| 203 | − * the DMA API), don't try to attach again. | |
| 236 | + * We may not always want to enable IOMMU support (for example if the | |
| 237 | + * host1x firewall is already enabled and we don't support addressing | |
| 238 | + * more than 32 bits of physical memory), so check for that first. | |
| 239 | + * | |
| 240 | + * Similarly, if host1x is already attached to an IOMMU (via the DMA | |
| 241 | + * API), don't try to attach again. | |
| 204 | 242 | */ |
| 205 | − if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) || domain) | |
| 243 | + if (!host1x_wants_iommu(host) || domain) | |
| 206 | 244 | return domain; |
| 207 | 245 | |
| 208 | 246 | host->group = iommu_group_get(host->dev); |
| @@ -502,6 +540,19 @@ static void __exit tegra_host1x_exit(void) · 293 unmodified lines | ||
| 502 | 540 | } |
| 503 | 541 | module_exit(tegra_host1x_exit); |
| 504 | 542 | |
| 543 | +/** | |
| 544 | + * host1x_get_dma_mask() - query the supported DMA mask for host1x | |
| 545 | + * @host1x: host1x instance | |
| 546 | + * | |
| 547 | + * Note that this returns the supported DMA mask for host1x, which can be | |
| 548 | + * different from the applicable DMA mask under certain circumstances. | |
| 549 | + */ | |
| 550 | +u64 host1x_get_dma_mask(struct host1x *host1x) | |
| 551 | +{ | |
| 552 | + return host1x->info->dma_mask; | |
| 553 | +} | |
| 554 | +EXPORT_SYMBOL(host1x_get_dma_mask); | |
| 555 | + | |
| 505 | 556 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); |
| 506 | 557 | MODULE_AUTHOR("Terje Bergstrom <tbergstrom@nvidia.com>"); |
| 507 | 558 | MODULE_DESCRIPTION("Host1x driver for Tegra products"); |
| @@ -244,9 +244,9 @@ static ssize_t da9052_tsi_show(struct device *dev, · 243 unmodified lines | ||
| 244 | 244 | int channel = to_sensor_dev_attr(devattr)->index; |
| 245 | 245 | int ret; |
| 246 | 246 | |
| 247 | − mutex_lock(&hwmon->hwmon_lock); | |
| 247 | + mutex_lock(&hwmon->da9052->auxadc_lock); | |
| 248 | 248 | ret = __da9052_read_tsi(dev, channel); |
| 249 | − mutex_unlock(&hwmon->hwmon_lock); | |
| 249 | + mutex_unlock(&hwmon->da9052->auxadc_lock); | |
| 250 | 250 | |
| 251 | 251 | if (ret < 0) |
| 252 | 252 | return ret; |
| @@ -346,7 +346,7 @@ static int drivetemp_identify_sata(struct drivetemp_data *st) · 345 unmodified lines | ||
| 346 | 346 | st->have_temp_highest = temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]); |
| 347 | 347 | |
| 348 | 348 | if (!have_sct_data_table) |
| 349 | − goto skip_sct; | |
| 349 | + goto skip_sct_data; | |
| 350 | 350 | |
| 351 | 351 | /* Request and read temperature history table */ |
| 352 | 352 | memset(buf, '\0', sizeof(st->smartdata)); |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #define FANCTL_MAX 4 /* Counted from 1 */ |
| 42 | 42 | #define TCPU_MAX 8 /* Counted from 1 */ |
| 43 | 43 | #define TEMP_MAX 4 /* Counted from 1 */ |
| 44 | +#define SMI_STS_MAX 10 /* Counted from 1 */ | |
| 44 | 45 | |
| 45 | 46 | #define VT_ADC_CTRL0_REG 0x20 /* Bank 0 */ |
| 46 | 47 | #define VT_ADC_CTRL1_REG 0x21 /* Bank 0 */ |
| @@ -361,6 +362,7 @@ static int nct7904_read_temp(struct device *dev, u32 attr, int channel, · 314 unmodified lines | ||
| 361 | 362 | struct nct7904_data *data = dev_get_drvdata(dev); |
| 362 | 363 | int ret, temp; |
| 363 | 364 | unsigned int reg1, reg2, reg3; |
| 365 | + s8 temps; | |
| 364 | 366 | |
| 365 | 367 | switch (attr) { |
| 366 | 368 | case hwmon_temp_input: |
| @@ -466,7 +468,8 @@ static int nct7904_read_temp(struct device *dev, u32 attr, int channel, · 99 unmodified lines | ||
| 466 | 468 | |
| 467 | 469 | if (ret < 0) |
| 468 | 470 | return ret; |
| 469 | − *val = ret * 1000; | |
| 471 | + temps = ret; | |
| 472 | + *val = temps * 1000; | |
| 470 | 473 | return 0; |
| 471 | 474 | } |
| 472 | 475 | |
| @@ -1009,6 +1012,13 @@ static int nct7904_probe(struct i2c_client *client, · 536 unmodified lines | ||
| 1009 | 1012 | data->fan_mode[i] = ret; |
| 1010 | 1013 | } |
| 1011 | 1014 | |
| 1015 | + /* Read all of SMI status register to clear alarms */ | |
| 1016 | + for (i = 0; i < SMI_STS_MAX; i++) { | |
| 1017 | + ret = nct7904_read_reg(data, BANK_0, SMI_STS1_REG + i); | |
| 1018 | + if (ret < 0) | |
| 1019 | + return ret; | |
| 1020 | + } | |
| 1021 | + | |
| 1012 | 1022 | hwmon_dev = |
| 1013 | 1023 | devm_hwmon_device_register_with_info(dev, client->name, data, |
| 1014 | 1024 | &nct7904_chip_info, NULL); |
| @@ -120,7 +120,7 @@ static int cti_plat_create_v8_etm_connection(struct device *dev, · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | /* Can optionally have an etm node - return if not */ |
| 122 | 122 | cs_fwnode = fwnode_find_reference(root_fwnode, CTI_DT_CSDEV_ASSOC, 0); |
| 123 | − if (IS_ERR_OR_NULL(cs_fwnode)) | |
| 123 | + if (IS_ERR(cs_fwnode)) | |
| 124 | 124 | return 0; |
| 125 | 125 | |
| 126 | 126 | /* allocate memory */ |
| @@ -393,7 +393,7 @@ static int cti_plat_create_connection(struct device *dev, · 266 unmodified lines | ||
| 393 | 393 | /* associated device ? */ |
| 394 | 394 | cs_fwnode = fwnode_find_reference(fwnode, |
| 395 | 395 | CTI_DT_CSDEV_ASSOC, 0); |
| 396 | − if (!IS_ERR_OR_NULL(cs_fwnode)) { | |
| 396 | + if (!IS_ERR(cs_fwnode)) { | |
| 397 | 397 | assoc_name = cti_plat_get_csdev_or_node_name(cs_fwnode, |
| 398 | 398 | &csdev); |
| 399 | 399 | fwnode_handle_put(cs_fwnode); |
| @@ -542,7 +542,7 @@ int i2c_pca_add_numbered_bus(struct i2c_adapter *adap) · 541 unmodified lines | ||
| 542 | 542 | EXPORT_SYMBOL(i2c_pca_add_numbered_bus); |
| 543 | 543 | |
| 544 | 544 | MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " |
| 545 | − "Wolfram Sang <w.sang@pengutronix.de>"); | |
| 545 | + "Wolfram Sang <kernel@pengutronix.de>"); | |
| 546 | 546 | MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); |
| 547 | 547 | MODULE_LICENSE("GPL"); |
| 548 | 548 | |
| @@ -70,6 +70,7 @@ · 69 unmodified lines | ||
| 70 | 70 | * @isr_mask: cached copy of local ISR enables. |
| 71 | 71 | * @isr_status: cached copy of local ISR status. |
| 72 | 72 | * @lock: spinlock for IRQ synchronization. |
| 73 | + * @isr_mutex: mutex for IRQ thread. | |
| 73 | 74 | */ |
| 74 | 75 | struct altr_i2c_dev { |
| 75 | 76 | void __iomem *base; |
| @@ -86,6 +87,7 @@ struct altr_i2c_dev { · 10 unmodified lines | ||
| 86 | 87 | u32 isr_mask; |
| 87 | 88 | u32 isr_status; |
| 88 | 89 | spinlock_t lock; /* IRQ synchronization */ |
| 90 | + struct mutex isr_mutex; | |
| 89 | 91 | }; |
| 90 | 92 | |
| 91 | 93 | static void |
| @@ -245,10 +247,11 @@ static irqreturn_t altr_i2c_isr(int irq, void *_dev) · 153 unmodified lines | ||
| 245 | 247 | struct altr_i2c_dev *idev = _dev; |
| 246 | 248 | u32 status = idev->isr_status; |
| 247 | 249 | |
| 250 | + mutex_lock(&idev->isr_mutex); | |
| 248 | 251 | if (!idev->msg) { |
| 249 | 252 | dev_warn(idev->dev, "unexpected interrupt\n"); |
| 250 | 253 | altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ); |
| 251 | − return IRQ_HANDLED; | |
| 254 | + goto out; | |
| 252 | 255 | } |
| 253 | 256 | read = (idev->msg->flags & I2C_M_RD) != 0; |
| 254 | 257 | |
| @@ -301,6 +304,8 @@ static irqreturn_t altr_i2c_isr(int irq, void *_dev) · 46 unmodified lines | ||
| 301 | 304 | complete(&idev->msg_complete); |
| 302 | 305 | dev_dbg(idev->dev, "Message Complete\n"); |
| 303 | 306 | } |
| 307 | +out: | |
| 308 | + mutex_unlock(&idev->isr_mutex); | |
| 304 | 309 | |
| 305 | 310 | return IRQ_HANDLED; |
| 306 | 311 | } |
| @@ -312,6 +317,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg) · 5 unmodified lines | ||
| 312 | 317 | u32 value; |
| 313 | 318 | u8 addr = i2c_8bit_addr_from_msg(msg); |
| 314 | 319 | |
| 320 | + mutex_lock(&idev->isr_mutex); | |
| 315 | 321 | idev->msg = msg; |
| 316 | 322 | idev->msg_len = msg->len; |
| 317 | 323 | idev->buf = msg->buf; |
| @@ -336,6 +342,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg) · 18 unmodified lines | ||
| 336 | 342 | altr_i2c_int_enable(idev, imask, true); |
| 337 | 343 | altr_i2c_fill_tx_fifo(idev); |
| 338 | 344 | } |
| 345 | + mutex_unlock(&idev->isr_mutex); | |
| 339 | 346 | |
| 340 | 347 | time_left = wait_for_completion_timeout(&idev->msg_complete, |
| 341 | 348 | ALTR_I2C_XFER_TIMEOUT); |
| @@ -409,6 +416,7 @@ static int altr_i2c_probe(struct platform_device *pdev) · 67 unmodified lines | ||
| 409 | 416 | idev->dev = &pdev->dev; |
| 410 | 417 | init_completion(&idev->msg_complete); |
| 411 | 418 | spin_lock_init(&idev->lock); |
| 419 | + mutex_init(&idev->isr_mutex); | |
| 412 | 420 | |
| 413 | 421 | ret = device_property_read_u32(idev->dev, "fifo-size", |
| 414 | 422 | &idev->fifo_size); |
| @@ -845,6 +845,18 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev, · 844 unmodified lines | ||
| 845 | 845 | PINCTRL_STATE_DEFAULT); |
| 846 | 846 | dev->pinctrl_pins_gpio = pinctrl_lookup_state(dev->pinctrl, |
| 847 | 847 | "gpio"); |
| 848 | + if (IS_ERR(dev->pinctrl_pins_default) || | |
| 849 | + IS_ERR(dev->pinctrl_pins_gpio)) { | |
| 850 | + dev_info(&pdev->dev, "pinctrl states incomplete for recovery\n"); | |
| 851 | + return -EINVAL; | |
| 852 | + } | |
| 853 | + | |
| 854 | + /* | |
| 855 | + * pins will be taken as GPIO, so we might as well inform pinctrl about | |
| 856 | + * this and move the state to GPIO | |
| 857 | + */ | |
| 858 | + pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio); | |
| 859 | + | |
| 848 | 860 | rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN); |
| 849 | 861 | if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER) |
| 850 | 862 | return -EPROBE_DEFER; |
| @@ -855,9 +867,7 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev, · 4 unmodified lines | ||
| 855 | 867 | return -EPROBE_DEFER; |
| 856 | 868 | |
| 857 | 869 | if (IS_ERR(rinfo->sda_gpiod) || |
| 858 | − IS_ERR(rinfo->scl_gpiod) || | |
| 859 | − IS_ERR(dev->pinctrl_pins_default) || | |
| 860 | − IS_ERR(dev->pinctrl_pins_gpio)) { | |
| 870 | + IS_ERR(rinfo->scl_gpiod)) { | |
| 861 | 871 | dev_info(&pdev->dev, "recovery information incomplete\n"); |
| 862 | 872 | if (!IS_ERR(rinfo->sda_gpiod)) { |
| 863 | 873 | gpiod_put(rinfo->sda_gpiod); |
| @@ -867,9 +877,13 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev, · 3 unmodified lines | ||
| 867 | 877 | gpiod_put(rinfo->scl_gpiod); |
| 868 | 878 | rinfo->scl_gpiod = NULL; |
| 869 | 879 | } |
| 880 | + pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default); | |
| 870 | 881 | return -EINVAL; |
| 871 | 882 | } |
| 872 | 883 | |
| 884 | + /* change the state of the pins back to their default state */ | |
| 885 | + pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default); | |
| 886 | + | |
| 873 | 887 | dev_info(&pdev->dev, "using scl, sda for recovery\n"); |
| 874 | 888 | |
| 875 | 889 | rinfo->prepare_recovery = at91_prepare_twi_recovery; |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Mux support by Rodolfo Giometti <giometti@enneenne.com> and |
| 8 | 8 | * Michael Lawnick <michael.lawnick.ext@nsn.com> |
| 9 | 9 | * |
| 10 | − * Copyright (C) 2013-2017 Wolfram Sang <wsa@the-dreams.de> | |
| 10 | + * Copyright (C) 2013-2017 Wolfram Sang <wsa@kernel.org> | |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | 13 | #define pr_fmt(fmt) "i2c-core: " fmt |
| @@ -338,8 +338,10 @@ static int i2c_device_probe(struct device *dev) · 324 unmodified lines | ||
| 338 | 338 | } else if (ACPI_COMPANION(dev)) { |
| 339 | 339 | irq = i2c_acpi_get_irq(client); |
| 340 | 340 | } |
| 341 | − if (irq == -EPROBE_DEFER) | |
| 342 | − return irq; | |
| 341 | + if (irq == -EPROBE_DEFER) { | |
| 342 | + status = irq; | |
| 343 | + goto put_sync_adapter; | |
| 344 | + } | |
| 343 | 345 | |
| 344 | 346 | if (irq < 0) |
| 345 | 347 | irq = 0; |
| @@ -353,15 +355,19 @@ static int i2c_device_probe(struct device *dev) · 7 unmodified lines | ||
| 353 | 355 | */ |
| 354 | 356 | if (!driver->id_table && |
| 355 | 357 | !i2c_acpi_match_device(dev->driver->acpi_match_table, client) && |
| 356 | − !i2c_of_match_device(dev->driver->of_match_table, client)) | |
| 357 | − return -ENODEV; | |
| 358 | + !i2c_of_match_device(dev->driver->of_match_table, client)) { | |
| 359 | + status = -ENODEV; | |
| 360 | + goto put_sync_adapter; | |
| 361 | + } | |
| 358 | 362 | |
| 359 | 363 | if (client->flags & I2C_CLIENT_WAKE) { |
| 360 | 364 | int wakeirq; |
| 361 | 365 | |
| 362 | 366 | wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); |
| 363 | − if (wakeirq == -EPROBE_DEFER) | |
| 364 | − return wakeirq; | |
| 367 | + if (wakeirq == -EPROBE_DEFER) { | |
| 368 | + status = wakeirq; | |
| 369 | + goto put_sync_adapter; | |
| 370 | + } | |
| 365 | 371 | |
| 366 | 372 | device_init_wakeup(&client->dev, true); |
| 367 | 373 | |
| @@ -408,6 +414,10 @@ err_detach_pm_domain: · 40 unmodified lines | ||
| 408 | 414 | err_clear_wakeup_irq: |
| 409 | 415 | dev_pm_clear_wake_irq(&client->dev); |
| 410 | 416 | device_init_wakeup(&client->dev, false); |
| 417 | +put_sync_adapter: | |
| 418 | + if (client->flags & I2C_CLIENT_HOST_NOTIFY) | |
| 419 | + pm_runtime_put_sync(&client->adapter->dev); | |
| 420 | + | |
| 411 | 421 | return status; |
| 412 | 422 | } |
| 413 | 423 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (C) 2008 Jochen Friedrich <jochen@scram.de> |
| 6 | 6 | * based on a previous patch from Jon Smirl <jonsmirl@gmail.com> |
| 7 | 7 | * |
| 8 | − * Copyright (C) 2013, 2018 Wolfram Sang <wsa@the-dreams.de> | |
| 8 | + * Copyright (C) 2013, 2018 Wolfram Sang <wsa@kernel.org> | |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #include <dt-bindings/i2c/i2c.h> |
| @@ -272,6 +272,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) · 271 unmodified lines | ||
| 272 | 272 | err_rollback_available: |
| 273 | 273 | device_remove_file(&pdev->dev, &dev_attr_available_masters); |
| 274 | 274 | err_rollback: |
| 275 | + i2c_demux_deactivate_master(priv); | |
| 275 | 276 | for (j = 0; j < i; j++) { |
| 276 | 277 | of_node_put(priv->chan[j].parent_np); |
| 277 | 278 | of_changeset_destroy(&priv->chan[j].chgset); |
| @@ -980,7 +980,7 @@ static int sca3000_read_data(struct sca3000_state *st, · 979 unmodified lines | ||
| 980 | 980 | st->tx[0] = SCA3000_READ_REG(reg_address_high); |
| 981 | 981 | ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer)); |
| 982 | 982 | if (ret) { |
| 983 | − dev_err(get_device(&st->us->dev), "problem reading register"); | |
| 983 | + dev_err(&st->us->dev, "problem reading register\n"); | |
| 984 | 984 | return ret; |
| 985 | 985 | } |
| 986 | 986 | |
| @@ -1812,18 +1812,18 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) · 1811 unmodified lines | ||
| 1812 | 1812 | return 0; |
| 1813 | 1813 | } |
| 1814 | 1814 | |
| 1815 | −static int stm32_adc_dma_request(struct iio_dev *indio_dev) | |
| 1815 | +static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) | |
| 1816 | 1816 | { |
| 1817 | 1817 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1818 | 1818 | struct dma_slave_config config; |
| 1819 | 1819 | int ret; |
| 1820 | 1820 | |
| 1821 | − adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx"); | |
| 1821 | + adc->dma_chan = dma_request_chan(dev, "rx"); | |
| 1822 | 1822 | if (IS_ERR(adc->dma_chan)) { |
| 1823 | 1823 | ret = PTR_ERR(adc->dma_chan); |
| 1824 | 1824 | if (ret != -ENODEV) { |
| 1825 | 1825 | if (ret != -EPROBE_DEFER) |
| 1826 | − dev_err(&indio_dev->dev, | |
| 1826 | + dev_err(dev, | |
| 1827 | 1827 | "DMA channel request failed with %d\n", |
| 1828 | 1828 | ret); |
| 1829 | 1829 | return ret; |
| @@ -1930,7 +1930,7 @@ static int stm32_adc_probe(struct platform_device *pdev) · 100 unmodified lines | ||
| 1930 | 1930 | if (ret < 0) |
| 1931 | 1931 | return ret; |
| 1932 | 1932 | |
| 1933 | − ret = stm32_adc_dma_request(indio_dev); | |
| 1933 | + ret = stm32_adc_dma_request(dev, indio_dev); | |
| 1934 | 1934 | if (ret < 0) |
| 1935 | 1935 | return ret; |
| 1936 | 1936 | |
| @@ -62,7 +62,7 @@ enum sd_converter_type { · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | struct stm32_dfsdm_dev_data { |
| 64 | 64 | int type; |
| 65 | − int (*init)(struct iio_dev *indio_dev); | |
| 65 | + int (*init)(struct device *dev, struct iio_dev *indio_dev); | |
| 66 | 66 | unsigned int num_channels; |
| 67 | 67 | const struct regmap_config *regmap_cfg; |
| 68 | 68 | }; |
| @@ -1365,11 +1365,12 @@ static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev) · 1296 unmodified lines | ||
| 1365 | 1365 | } |
| 1366 | 1366 | } |
| 1367 | 1367 | |
| 1368 | −static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev) | |
| 1368 | +static int stm32_dfsdm_dma_request(struct device *dev, | |
| 1369 | + struct iio_dev *indio_dev) | |
| 1369 | 1370 | { |
| 1370 | 1371 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| 1371 | 1372 | |
| 1372 | − adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx"); | |
| 1373 | + adc->dma_chan = dma_request_chan(dev, "rx"); | |
| 1373 | 1374 | if (IS_ERR(adc->dma_chan)) { |
| 1374 | 1375 | int ret = PTR_ERR(adc->dma_chan); |
| 1375 | 1376 | |
| @@ -1425,7 +1426,7 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, · 49 unmodified lines | ||
| 1425 | 1426 | &adc->dfsdm->ch_list[ch->channel]); |
| 1426 | 1427 | } |
| 1427 | 1428 | |
| 1428 | −static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) | |
| 1429 | +static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev) | |
| 1429 | 1430 | { |
| 1430 | 1431 | struct iio_chan_spec *ch; |
| 1431 | 1432 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| @@ -1452,10 +1453,10 @@ static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) · 20 unmodified lines | ||
| 1452 | 1453 | indio_dev->num_channels = 1; |
| 1453 | 1454 | indio_dev->channels = ch; |
| 1454 | 1455 | |
| 1455 | − return stm32_dfsdm_dma_request(indio_dev); | |
| 1456 | + return stm32_dfsdm_dma_request(dev, indio_dev); | |
| 1456 | 1457 | } |
| 1457 | 1458 | |
| 1458 | −static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) | |
| 1459 | +static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) | |
| 1459 | 1460 | { |
| 1460 | 1461 | struct iio_chan_spec *ch; |
| 1461 | 1462 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| @@ -1499,17 +1500,17 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) · 37 unmodified lines | ||
| 1499 | 1500 | init_completion(&adc->completion); |
| 1500 | 1501 | |
| 1501 | 1502 | /* Optionally request DMA */ |
| 1502 | − ret = stm32_dfsdm_dma_request(indio_dev); | |
| 1503 | + ret = stm32_dfsdm_dma_request(dev, indio_dev); | |
| 1503 | 1504 | if (ret) { |
| 1504 | 1505 | if (ret != -ENODEV) { |
| 1505 | 1506 | if (ret != -EPROBE_DEFER) |
| 1506 | − dev_err(&indio_dev->dev, | |
| 1507 | + dev_err(dev, | |
| 1507 | 1508 | "DMA channel request failed with %d\n", |
| 1508 | 1509 | ret); |
| 1509 | 1510 | return ret; |
| 1510 | 1511 | } |
| 1511 | 1512 | |
| 1512 | − dev_dbg(&indio_dev->dev, "No DMA support\n"); | |
| 1513 | + dev_dbg(dev, "No DMA support\n"); | |
| 1513 | 1514 | return 0; |
| 1514 | 1515 | } |
| 1515 | 1516 | |
| @@ -1622,7 +1623,7 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev) · 106 unmodified lines | ||
| 1622 | 1623 | adc->dfsdm->fl_list[adc->fl_id].sync_mode = val; |
| 1623 | 1624 | |
| 1624 | 1625 | adc->dev_data = dev_data; |
| 1625 | − ret = dev_data->init(iio); | |
| 1626 | + ret = dev_data->init(dev, iio); | |
| 1626 | 1627 | if (ret < 0) |
| 1627 | 1628 | return ret; |
| 1628 | 1629 | |
| @@ -32,16 +32,17 @@ struct ads8344 { · 31 unmodified lines | ||
| 32 | 32 | u8 rx_buf[3]; |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | −#define ADS8344_VOLTAGE_CHANNEL(chan, si) \ | |
| 35 | +#define ADS8344_VOLTAGE_CHANNEL(chan, addr) \ | |
| 36 | 36 | { \ |
| 37 | 37 | .type = IIO_VOLTAGE, \ |
| 38 | 38 | .indexed = 1, \ |
| 39 | 39 | .channel = chan, \ |
| 40 | 40 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
| 41 | 41 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
| 42 | + .address = addr, \ | |
| 42 | 43 | } |
| 43 | 44 | |
| 44 | −#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \ | |
| 45 | +#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, addr) \ | |
| 45 | 46 | { \ |
| 46 | 47 | .type = IIO_VOLTAGE, \ |
| 47 | 48 | .indexed = 1, \ |
| @@ -50,6 +51,7 @@ struct ads8344 { · 2 unmodified lines | ||
| 50 | 51 | .differential = 1, \ |
| 51 | 52 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
| 52 | 53 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
| 54 | + .address = addr, \ | |
| 53 | 55 | } |
| 54 | 56 | |
| 55 | 57 | static const struct iio_chan_spec ads8344_channels[] = { |
| @@ -105,7 +107,7 @@ static int ads8344_read_raw(struct iio_dev *iio, · 49 unmodified lines | ||
| 105 | 107 | switch (mask) { |
| 106 | 108 | case IIO_CHAN_INFO_RAW: |
| 107 | 109 | mutex_lock(&adc->lock); |
| 108 | − *value = ads8344_adc_conversion(adc, channel->scan_index, | |
| 110 | + *value = ads8344_adc_conversion(adc, channel->address, | |
| 109 | 111 | channel->differential); |
| 110 | 112 | mutex_unlock(&adc->lock); |
| 111 | 113 | if (*value < 0) |
| @@ -198,7 +198,19 @@ static const struct iio_chan_spec atlas_orp_channels[] = { · 197 unmodified lines | ||
| 198 | 198 | }; |
| 199 | 199 | |
| 200 | 200 | static const struct iio_chan_spec atlas_do_channels[] = { |
| 201 | − ATLAS_CONCENTRATION_CHANNEL(0, ATLAS_REG_DO_DATA), | |
| 201 | + { | |
| 202 | + .type = IIO_CONCENTRATION, | |
| 203 | + .address = ATLAS_REG_DO_DATA, | |
| 204 | + .info_mask_separate = | |
| 205 | + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | |
| 206 | + .scan_index = 0, | |
| 207 | + .scan_type = { | |
| 208 | + .sign = 'u', | |
| 209 | + .realbits = 32, | |
| 210 | + .storagebits = 32, | |
| 211 | + .endianness = IIO_BE, | |
| 212 | + }, | |
| 213 | + }, | |
| 202 | 214 | IIO_CHAN_SOFT_TIMESTAMP(1), |
| 203 | 215 | { |
| 204 | 216 | .type = IIO_TEMP, |
| @@ -226,6 +226,7 @@ static int vf610_dac_probe(struct platform_device *pdev) · 225 unmodified lines | ||
| 226 | 226 | return 0; |
| 227 | 227 | |
| 228 | 228 | error_iio_device_register: |
| 229 | + vf610_dac_exit(info); | |
| 229 | 230 | clk_disable_unprepare(info->clk); |
| 230 | 231 | |
| 231 | 232 | return ret; |
| @@ -637,8 +637,10 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev, · 636 unmodified lines | ||
| 637 | 637 | |
| 638 | 638 | ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); |
| 639 | 639 | odr = st_lsm6dsx_check_odr(ref_sensor, val, &odr_val); |
| 640 | − if (odr < 0) | |
| 641 | − return odr; | |
| 640 | + if (odr < 0) { | |
| 641 | + err = odr; | |
| 642 | + goto release; | |
| 643 | + } | |
| 642 | 644 | |
| 643 | 645 | sensor->ext_info.slv_odr = val; |
| 644 | 646 | sensor->odr = odr; |
| @@ -653,6 +655,7 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev, · 8 unmodified lines | ||
| 653 | 655 | break; |
| 654 | 656 | } |
| 655 | 657 | |
| 658 | +release: | |
| 656 | 659 | iio_device_release_direct_mode(iio_dev); |
| 657 | 660 | |
| 658 | 661 | return err; |
| @@ -1553,8 +1553,11 @@ int ib_cache_setup_one(struct ib_device *device) · 1552 unmodified lines | ||
| 1553 | 1553 | if (err) |
| 1554 | 1554 | return err; |
| 1555 | 1555 | |
| 1556 | − rdma_for_each_port (device, p) | |
| 1557 | − ib_cache_update(device, p, true); | |
| 1556 | + rdma_for_each_port (device, p) { | |
| 1557 | + err = ib_cache_update(device, p, true); | |
| 1558 | + if (err) | |
| 1559 | + return err; | |
| 1560 | + } | |
| 1558 | 1561 | |
| 1559 | 1562 | return 0; |
| 1560 | 1563 | } |
| @@ -1292,11 +1292,10 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 1291 unmodified lines | ||
| 1292 | 1292 | has_cap_net_admin = netlink_capable(skb, CAP_NET_ADMIN); |
| 1293 | 1293 | |
| 1294 | 1294 | ret = fill_func(msg, has_cap_net_admin, res, port); |
| 1295 | − | |
| 1296 | − rdma_restrack_put(res); | |
| 1297 | 1295 | if (ret) |
| 1298 | 1296 | goto err_free; |
| 1299 | 1297 | |
| 1298 | + rdma_restrack_put(res); | |
| 1300 | 1299 | nlmsg_end(msg, nlh); |
| 1301 | 1300 | ib_device_put(device); |
| 1302 | 1301 | return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid); |
| @@ -459,7 +459,8 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj, · 458 unmodified lines | ||
| 459 | 459 | struct ib_uobject *uobj; |
| 460 | 460 | struct file *filp; |
| 461 | 461 | |
| 462 | − if (WARN_ON(fd_type->fops->release != &uverbs_uobject_fd_release)) | |
| 462 | + if (WARN_ON(fd_type->fops->release != &uverbs_uobject_fd_release && | |
| 463 | + fd_type->fops->release != &uverbs_async_event_release)) | |
| 463 | 464 | return ERR_PTR(-EINVAL); |
| 464 | 465 | |
| 465 | 466 | new_fd = get_unused_fd_flags(O_CLOEXEC); |
| @@ -219,6 +219,7 @@ void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue); · 218 unmodified lines | ||
| 219 | 219 | void ib_uverbs_init_async_event_file(struct ib_uverbs_async_event_file *ev_file); |
| 220 | 220 | void ib_uverbs_free_event_queue(struct ib_uverbs_event_queue *event_queue); |
| 221 | 221 | void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res); |
| 222 | +int uverbs_async_event_release(struct inode *inode, struct file *filp); | |
| 222 | 223 | |
| 223 | 224 | int ib_alloc_ucontext(struct uverbs_attr_bundle *attrs); |
| 224 | 225 | int ib_init_ucontext(struct uverbs_attr_bundle *attrs); |
| @@ -227,6 +228,9 @@ void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file, · 2 unmodified lines | ||
| 227 | 228 | struct ib_ucq_object *uobj); |
| 228 | 229 | void ib_uverbs_release_uevent(struct ib_uevent_object *uobj); |
| 229 | 230 | void ib_uverbs_release_file(struct kref *ref); |
| 231 | +void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, | |
| 232 | + __u64 element, __u64 event, | |
| 233 | + struct list_head *obj_list, u32 *counter); | |
| 230 | 234 | |
| 231 | 235 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); |
| 232 | 236 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); |
| @@ -346,7 +346,7 @@ const struct file_operations uverbs_async_event_fops = { · 345 unmodified lines | ||
| 346 | 346 | .owner = THIS_MODULE, |
| 347 | 347 | .read = ib_uverbs_async_event_read, |
| 348 | 348 | .poll = ib_uverbs_async_event_poll, |
| 349 | − .release = uverbs_uobject_fd_release, | |
| 349 | + .release = uverbs_async_event_release, | |
| 350 | 350 | .fasync = ib_uverbs_async_event_fasync, |
| 351 | 351 | .llseek = no_llseek, |
| 352 | 352 | }; |
| @@ -386,10 +386,9 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) · 33 unmodified lines | ||
| 386 | 386 | kill_fasync(&ev_queue->async_queue, SIGIO, POLL_IN); |
| 387 | 387 | } |
| 388 | 388 | |
| 389 | −static void | |
| 390 | −ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, | |
| 391 | − __u64 element, __u64 event, struct list_head *obj_list, | |
| 392 | − u32 *counter) | |
| 389 | +void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, | |
| 390 | + __u64 element, __u64 event, | |
| 391 | + struct list_head *obj_list, u32 *counter) | |
| 393 | 392 | { |
| 394 | 393 | struct ib_uverbs_event *entry; |
| 395 | 394 | unsigned long flags; |
| @@ -1187,9 +1186,6 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev, · 791 unmodified lines | ||
| 1187 | 1186 | */ |
| 1188 | 1187 | mutex_unlock(&uverbs_dev->lists_mutex); |
| 1189 | 1188 | |
| 1190 | − ib_uverbs_async_handler(READ_ONCE(file->async_file), 0, | |
| 1191 | − IB_EVENT_DEVICE_FATAL, NULL, NULL); | |
| 1192 | − | |
| 1193 | 1189 | uverbs_destroy_ufile_hw(file, RDMA_REMOVE_DRIVER_REMOVE); |
| 1194 | 1190 | kref_put(&file->ref, ib_uverbs_release_file); |
| 1195 | 1191 | |
| @@ -26,10 +26,38 @@ static int uverbs_async_event_destroy_uobj(struct ib_uobject *uobj, · 25 unmodified lines | ||
| 26 | 26 | container_of(uobj, struct ib_uverbs_async_event_file, uobj); |
| 27 | 27 | |
| 28 | 28 | ib_unregister_event_handler(&event_file->event_handler); |
| 29 | − ib_uverbs_free_event_queue(&event_file->ev_queue); | |
| 29 | + | |
| 30 | + if (why == RDMA_REMOVE_DRIVER_REMOVE) | |
| 31 | + ib_uverbs_async_handler(event_file, 0, IB_EVENT_DEVICE_FATAL, | |
| 32 | + NULL, NULL); | |
| 30 | 33 | return 0; |
| 31 | 34 | } |
| 32 | 35 | |
| 36 | +int uverbs_async_event_release(struct inode *inode, struct file *filp) | |
| 37 | +{ | |
| 38 | + struct ib_uverbs_async_event_file *event_file; | |
| 39 | + struct ib_uobject *uobj = filp->private_data; | |
| 40 | + int ret; | |
| 41 | + | |
| 42 | + if (!uobj) | |
| 43 | + return uverbs_uobject_fd_release(inode, filp); | |
| 44 | + | |
| 45 | + event_file = | |
| 46 | + container_of(uobj, struct ib_uverbs_async_event_file, uobj); | |
| 47 | + | |
| 48 | + /* | |
| 49 | + * The async event FD has to deliver IB_EVENT_DEVICE_FATAL even after | |
| 50 | + * disassociation, so cleaning the event list must only happen after | |
| 51 | + * release. The user knows it has reached the end of the event stream | |
| 52 | + * when it sees IB_EVENT_DEVICE_FATAL. | |
| 53 | + */ | |
| 54 | + uverbs_uobject_get(uobj); | |
| 55 | + ret = uverbs_uobject_fd_release(inode, filp); | |
| 56 | + ib_uverbs_free_event_queue(&event_file->ev_queue); | |
| 57 | + uverbs_uobject_put(uobj); | |
| 58 | + return ret; | |
| 59 | +} | |
| 60 | + | |
| 33 | 61 | DECLARE_UVERBS_NAMED_METHOD( |
| 34 | 62 | UVERBS_METHOD_ASYNC_EVENT_ALLOC, |
| 35 | 63 | UVERBS_ATTR_FD(UVERBS_ATTR_ASYNC_EVENT_ALLOC_FD_HANDLE, |
| @@ -2891,8 +2891,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) · 2890 unmodified lines | ||
| 2891 | 2891 | srqidx = ABORT_RSS_SRQIDX_G( |
| 2892 | 2892 | be32_to_cpu(req->srqidx_status)); |
| 2893 | 2893 | if (srqidx) { |
| 2894 | − complete_cached_srq_buffers(ep, | |
| 2895 | − req->srqidx_status); | |
| 2894 | + complete_cached_srq_buffers(ep, srqidx); | |
| 2896 | 2895 | } else { |
| 2897 | 2896 | /* Hold ep ref until finish_peer_abort() */ |
| 2898 | 2897 | c4iw_get_ep(&ep->com); |
| @@ -3878,8 +3877,8 @@ static int read_tcb_rpl(struct c4iw_dev *dev, struct sk_buff *skb) · 979 unmodified lines | ||
| 3878 | 3877 | return 0; |
| 3879 | 3878 | } |
| 3880 | 3879 | |
| 3881 | − ep->srqe_idx = t4_tcb_get_field32(tcb, TCB_RQ_START_W, TCB_RQ_START_W, | |
| 3882 | − TCB_RQ_START_S); | |
| 3880 | + ep->srqe_idx = t4_tcb_get_field32(tcb, TCB_RQ_START_W, TCB_RQ_START_M, | |
| 3881 | + TCB_RQ_START_S); | |
| 3883 | 3882 | cleanup: |
| 3884 | 3883 | pr_debug("ep %p tid %u %016x\n", ep, ep->hwtid, ep->srqe_idx); |
| 3885 | 3884 | |
| @@ -589,10 +589,6 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, · 588 unmodified lines | ||
| 589 | 589 | |
| 590 | 590 | set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); |
| 591 | 591 | pq->state = SDMA_PKT_Q_ACTIVE; |
| 592 | − /* Send the first N packets in the request to buy us some time */ | |
| 593 | − ret = user_sdma_send_pkts(req, pcount); | |
| 594 | − if (unlikely(ret < 0 && ret != -EBUSY)) | |
| 595 | − goto free_req; | |
| 596 | 592 | |
| 597 | 593 | /* |
| 598 | 594 | * This is a somewhat blocking send implementation. |
| @@ -1987,7 +1987,6 @@ static int i40iw_addr_resolve_neigh(struct i40iw_device *iwdev, · 1986 unmodified lines | ||
| 1987 | 1987 | struct rtable *rt; |
| 1988 | 1988 | struct neighbour *neigh; |
| 1989 | 1989 | int rc = arpindex; |
| 1990 | − struct net_device *netdev = iwdev->netdev; | |
| 1991 | 1990 | __be32 dst_ipaddr = htonl(dst_ip); |
| 1992 | 1991 | __be32 src_ipaddr = htonl(src_ip); |
| 1993 | 1992 | |
| @@ -1997,9 +1996,6 @@ static int i40iw_addr_resolve_neigh(struct i40iw_device *iwdev, · 3 unmodified lines | ||
| 1997 | 1996 | return rc; |
| 1998 | 1997 | } |
| 1999 | 1998 | |
| 2000 | − if (netif_is_bond_slave(netdev)) | |
| 2001 | − netdev = netdev_master_upper_dev_get(netdev); | |
| 2002 | − | |
| 2003 | 1999 | neigh = dst_neigh_lookup(&rt->dst, &dst_ipaddr); |
| 2004 | 2000 | |
| 2005 | 2001 | rcu_read_lock(); |
| @@ -2065,7 +2061,6 @@ static int i40iw_addr_resolve_neigh_ipv6(struct i40iw_device *iwdev, · 59 unmodified lines | ||
| 2065 | 2061 | { |
| 2066 | 2062 | struct neighbour *neigh; |
| 2067 | 2063 | int rc = arpindex; |
| 2068 | − struct net_device *netdev = iwdev->netdev; | |
| 2069 | 2064 | struct dst_entry *dst; |
| 2070 | 2065 | struct sockaddr_in6 dst_addr; |
| 2071 | 2066 | struct sockaddr_in6 src_addr; |
| @@ -2086,9 +2081,6 @@ static int i40iw_addr_resolve_neigh_ipv6(struct i40iw_device *iwdev, · 14 unmodified lines | ||
| 2086 | 2081 | return rc; |
| 2087 | 2082 | } |
| 2088 | 2083 | |
| 2089 | − if (netif_is_bond_slave(netdev)) | |
| 2090 | − netdev = netdev_master_upper_dev_get(netdev); | |
| 2091 | − | |
| 2092 | 2084 | neigh = dst_neigh_lookup(dst, dst_addr.sin6_addr.in6_u.u6_addr32); |
| 2093 | 2085 | |
| 2094 | 2086 | rcu_read_lock(); |
| @@ -534,7 +534,7 @@ void i40iw_manage_arp_cache(struct i40iw_device *iwdev, · 533 unmodified lines | ||
| 534 | 534 | int arp_index; |
| 535 | 535 | |
| 536 | 536 | arp_index = i40iw_arp_table(iwdev, ip_addr, ipv4, mac_addr, action); |
| 537 | − if (arp_index == -1) | |
| 537 | + if (arp_index < 0) | |
| 538 | 538 | return; |
| 539 | 539 | cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false); |
| 540 | 540 | if (!cqp_request) |
| @@ -2891,6 +2891,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, · 2890 unmodified lines | ||
| 2891 | 2891 | int send_size; |
| 2892 | 2892 | int header_size; |
| 2893 | 2893 | int spc; |
| 2894 | + int err; | |
| 2894 | 2895 | int i; |
| 2895 | 2896 | |
| 2896 | 2897 | if (wr->wr.opcode != IB_WR_SEND) |
| @@ -2925,7 +2926,9 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, · 28 unmodified lines | ||
| 2925 | 2926 | |
| 2926 | 2927 | sqp->ud_header.lrh.virtual_lane = 0; |
| 2927 | 2928 | sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); |
| 2928 | − ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); | |
| 2929 | + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); | |
| 2930 | + if (err) | |
| 2931 | + return err; | |
| 2929 | 2932 | sqp->ud_header.bth.pkey = cpu_to_be16(pkey); |
| 2930 | 2933 | if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_TUN_SMI_OWNER) |
| 2931 | 2934 | sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); |
| @@ -3212,9 +3215,14 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr, · 280 unmodified lines | ||
| 3212 | 3215 | } |
| 3213 | 3216 | sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); |
| 3214 | 3217 | if (!sqp->qp.ibqp.qp_num) |
| 3215 | − ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, &pkey); | |
| 3218 | + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, | |
| 3219 | + &pkey); | |
| 3216 | 3220 | else |
| 3217 | − ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, &pkey); | |
| 3221 | + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, | |
| 3222 | + &pkey); | |
| 3223 | + if (err) | |
| 3224 | + return err; | |
| 3225 | + | |
| 3218 | 3226 | sqp->ud_header.bth.pkey = cpu_to_be16(pkey); |
| 3219 | 3227 | sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); |
| 3220 | 3228 | sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); |
| @@ -151,7 +151,7 @@ struct rxe_mmap_info *rxe_create_mmap_info(struct rxe_dev *rxe, u32 size, · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | ip = kmalloc(sizeof(*ip), GFP_KERNEL); |
| 153 | 153 | if (!ip) |
| 154 | − return NULL; | |
| 154 | + return ERR_PTR(-ENOMEM); | |
| 155 | 155 | |
| 156 | 156 | size = PAGE_ALIGN(size); |
| 157 | 157 | |
| @@ -45,12 +45,15 @@ int do_mmap_info(struct rxe_dev *rxe, struct mminfo __user *outbuf, · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | if (outbuf) { |
| 47 | 47 | ip = rxe_create_mmap_info(rxe, buf_size, udata, buf); |
| 48 | − if (!ip) | |
| 48 | + if (IS_ERR(ip)) { | |
| 49 | + err = PTR_ERR(ip); | |
| 49 | 50 | goto err1; |
| 51 | + } | |
| 50 | 52 | |
| 51 | − err = copy_to_user(outbuf, &ip->info, sizeof(ip->info)); | |
| 52 | − if (err) | |
| 53 | + if (copy_to_user(outbuf, &ip->info, sizeof(ip->info))) { | |
| 54 | + err = -EFAULT; | |
| 53 | 55 | goto err2; |
| 56 | + } | |
| 54 | 57 | |
| 55 | 58 | spin_lock_bh(&rxe->pending_lock); |
| 56 | 59 | list_add(&ip->pending_mmaps, &rxe->pending_mmaps); |
| @@ -64,7 +67,7 @@ int do_mmap_info(struct rxe_dev *rxe, struct mminfo __user *outbuf, · 7 unmodified lines | ||
| 64 | 67 | err2: |
| 65 | 68 | kfree(ip); |
| 66 | 69 | err1: |
| 67 | − return -EINVAL; | |
| 70 | + return err; | |
| 68 | 71 | } |
| 69 | 72 | |
| 70 | 73 | inline void rxe_queue_reset(struct rxe_queue *q) |
| @@ -127,7 +127,8 @@ static inline int get_acpihid_device_id(struct device *dev, · 126 unmodified lines | ||
| 127 | 127 | return -ENODEV; |
| 128 | 128 | |
| 129 | 129 | list_for_each_entry(p, &acpihid_map, list) { |
| 130 | − if (acpi_dev_hid_uid_match(adev, p->hid, p->uid)) { | |
| 130 | + if (acpi_dev_hid_uid_match(adev, p->hid, | |
| 131 | + p->uid[0] ? p->uid : NULL)) { | |
| 131 | 132 | if (entry) |
| 132 | 133 | *entry = p; |
| 133 | 134 | return p->devid; |
| @@ -1329,8 +1329,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, · 1328 unmodified lines | ||
| 1329 | 1329 | } |
| 1330 | 1330 | case IVHD_DEV_ACPI_HID: { |
| 1331 | 1331 | u16 devid; |
| 1332 | − u8 hid[ACPIHID_HID_LEN] = {0}; | |
| 1333 | − u8 uid[ACPIHID_UID_LEN] = {0}; | |
| 1332 | + u8 hid[ACPIHID_HID_LEN]; | |
| 1333 | + u8 uid[ACPIHID_UID_LEN]; | |
| 1334 | 1334 | int ret; |
| 1335 | 1335 | |
| 1336 | 1336 | if (h->type != 0x40) { |
| @@ -1347,6 +1347,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, · 10 unmodified lines | ||
| 1347 | 1347 | break; |
| 1348 | 1348 | } |
| 1349 | 1349 | |
| 1350 | + uid[0] = '\0'; | |
| 1350 | 1351 | switch (e->uidf) { |
| 1351 | 1352 | case UID_NOT_PRESENT: |
| 1352 | 1353 | |
| @@ -1361,8 +1362,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, · 8 unmodified lines | ||
| 1361 | 1362 | break; |
| 1362 | 1363 | case UID_IS_CHARACTER: |
| 1363 | 1364 | |
| 1364 | − memcpy(uid, (u8 *)(&e->uid), ACPIHID_UID_LEN - 1); | |
| 1365 | − uid[ACPIHID_UID_LEN - 1] = '\0'; | |
| 1365 | + memcpy(uid, &e->uid, e->uidl); | |
| 1366 | + uid[e->uidl] = '\0'; | |
| 1366 | 1367 | |
| 1367 | 1368 | break; |
| 1368 | 1369 | default: |
| @@ -693,6 +693,15 @@ out: · 692 unmodified lines | ||
| 693 | 693 | return ret; |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | +static bool iommu_is_attach_deferred(struct iommu_domain *domain, | |
| 697 | + struct device *dev) | |
| 698 | +{ | |
| 699 | + if (domain->ops->is_attach_deferred) | |
| 700 | + return domain->ops->is_attach_deferred(domain, dev); | |
| 701 | + | |
| 702 | + return false; | |
| 703 | +} | |
| 704 | + | |
| 696 | 705 | /** |
| 697 | 706 | * iommu_group_add_device - add a device to an iommu group |
| 698 | 707 | * @group: the group into which to add the device (reference should be held) |
| @@ -747,7 +756,7 @@ rename: · 48 unmodified lines | ||
| 747 | 756 | |
| 748 | 757 | mutex_lock(&group->mutex); |
| 749 | 758 | list_add_tail(&device->list, &group->devices); |
| 750 | − if (group->domain) | |
| 759 | + if (group->domain && !iommu_is_attach_deferred(group->domain, dev)) | |
| 751 | 760 | ret = __iommu_attach_device(group->domain, dev); |
| 752 | 761 | mutex_unlock(&group->mutex); |
| 753 | 762 | if (ret) |
| @@ -1653,9 +1662,6 @@ static int __iommu_attach_device(struct iommu_domain *domain, · 899 unmodified lines | ||
| 1653 | 1662 | struct device *dev) |
| 1654 | 1663 | { |
| 1655 | 1664 | int ret; |
| 1656 | − if ((domain->ops->is_attach_deferred != NULL) && | |
| 1657 | − domain->ops->is_attach_deferred(domain, dev)) | |
| 1658 | − return 0; | |
| 1659 | 1665 | |
| 1660 | 1666 | if (unlikely(domain->ops->attach_dev == NULL)) |
| 1661 | 1667 | return -ENODEV; |
| @@ -1727,8 +1733,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_unbind_gpasid); · 65 unmodified lines | ||
| 1727 | 1733 | static void __iommu_detach_device(struct iommu_domain *domain, |
| 1728 | 1734 | struct device *dev) |
| 1729 | 1735 | { |
| 1730 | − if ((domain->ops->is_attach_deferred != NULL) && | |
| 1731 | − domain->ops->is_attach_deferred(domain, dev)) | |
| 1736 | + if (iommu_is_attach_deferred(domain, dev)) | |
| 1732 | 1737 | return; |
| 1733 | 1738 | |
| 1734 | 1739 | if (unlikely(domain->ops->detach_dev == NULL)) |
| @@ -306,6 +306,7 @@ static int tpci200_register(struct tpci200_board *tpci200) · 305 unmodified lines | ||
| 306 | 306 | "(bn 0x%X, sn 0x%X) failed to map driver user space!", |
| 307 | 307 | tpci200->info->pdev->bus->number, |
| 308 | 308 | tpci200->info->pdev->devfn); |
| 309 | + res = -ENOMEM; | |
| 309 | 310 | goto out_release_mem8_space; |
| 310 | 311 | } |
| 311 | 312 | |
| @@ -142,6 +142,9 @@ static void rtsx_comm_pm_full_on(struct rtsx_pcr *pcr) · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | rtsx_disable_aspm(pcr); |
| 144 | 144 | |
| 145 | + /* Fixes DMA transfer timout issue after disabling ASPM on RTS5260 */ | |
| 146 | + msleep(1); | |
| 147 | + | |
| 145 | 148 | if (option->ltr_enabled) |
| 146 | 149 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 147 | 150 | |
| @@ -266,6 +266,7 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid) · 265 unmodified lines | ||
| 266 | 266 | down_write(&dev->me_clients_rwsem); |
| 267 | 267 | me_cl = __mei_me_cl_by_uuid(dev, uuid); |
| 268 | 268 | __mei_me_cl_del(dev, me_cl); |
| 269 | + mei_me_cl_put(me_cl); | |
| 269 | 270 | up_write(&dev->me_clients_rwsem); |
| 270 | 271 | } |
| 271 | 272 | |
| @@ -287,6 +288,7 @@ void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id) · 15 unmodified lines | ||
| 287 | 288 | down_write(&dev->me_clients_rwsem); |
| 288 | 289 | me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id); |
| 289 | 290 | __mei_me_cl_del(dev, me_cl); |
| 291 | + mei_me_cl_put(me_cl); | |
| 290 | 292 | up_write(&dev->me_clients_rwsem); |
| 291 | 293 | } |
| 292 | 294 | |
| @@ -1370,6 +1370,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) · 1369 unmodified lines | ||
| 1370 | 1370 | struct mmc_request *mrq = &mqrq->brq.mrq; |
| 1371 | 1371 | struct request_queue *q = req->q; |
| 1372 | 1372 | struct mmc_host *host = mq->card->host; |
| 1373 | + enum mmc_issue_type issue_type = mmc_issue_type(mq, req); | |
| 1373 | 1374 | unsigned long flags; |
| 1374 | 1375 | bool put_card; |
| 1375 | 1376 | int err; |
| @@ -1399,7 +1400,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) · 23 unmodified lines | ||
| 1399 | 1400 | |
| 1400 | 1401 | spin_lock_irqsave(&mq->lock, flags); |
| 1401 | 1402 | |
| 1402 | − mq->in_flight[mmc_issue_type(mq, req)] -= 1; | |
| 1403 | + mq->in_flight[issue_type] -= 1; | |
| 1403 | 1404 | |
| 1404 | 1405 | put_card = (mmc_tot_in_flight(mq) == 0); |
| 1405 | 1406 | |
| @@ -107,11 +107,10 @@ static enum blk_eh_timer_return mmc_cqe_timed_out(struct request *req) · 106 unmodified lines | ||
| 107 | 107 | case MMC_ISSUE_DCMD: |
| 108 | 108 | if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) { |
| 109 | 109 | if (recovery_needed) |
| 110 | − __mmc_cqe_recovery_notifier(mq); | |
| 110 | + mmc_cqe_recovery_notifier(mrq); | |
| 111 | 111 | return BLK_EH_RESET_TIMER; |
| 112 | 112 | } |
| 113 | − /* No timeout (XXX: huh? comment doesn't make much sense) */ | |
| 114 | − blk_mq_complete_request(req); | |
| 113 | + /* The request has gone already */ | |
| 115 | 114 | return BLK_EH_DONE; |
| 116 | 115 | default: |
| 117 | 116 | /* Timeout is handled by mmc core */ |
| @@ -127,18 +126,13 @@ static enum blk_eh_timer_return mmc_mq_timed_out(struct request *req, · 9 unmodified lines | ||
| 127 | 126 | struct mmc_card *card = mq->card; |
| 128 | 127 | struct mmc_host *host = card->host; |
| 129 | 128 | unsigned long flags; |
| 130 | − int ret; | |
| 129 | + bool ignore_tout; | |
| 131 | 130 | |
| 132 | 131 | spin_lock_irqsave(&mq->lock, flags); |
| 133 | − | |
| 134 | − if (mq->recovery_needed || !mq->use_cqe || host->hsq_enabled) | |
| 135 | − ret = BLK_EH_RESET_TIMER; | |
| 136 | − else | |
| 137 | − ret = mmc_cqe_timed_out(req); | |
| 138 | − | |
| 132 | + ignore_tout = mq->recovery_needed || !mq->use_cqe || host->hsq_enabled; | |
| 139 | 133 | spin_unlock_irqrestore(&mq->lock, flags); |
| 140 | 134 | |
| 141 | − return ret; | |
| 135 | + return ignore_tout ? BLK_EH_RESET_TIMER : mmc_cqe_timed_out(req); | |
| 142 | 136 | } |
| 143 | 137 | |
| 144 | 138 | static void mmc_mq_recovery_handler(struct work_struct *work) |
| @@ -1104,7 +1104,7 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) · 1103 unmodified lines | ||
| 1104 | 1104 | |
| 1105 | 1105 | if (ret) { |
| 1106 | 1106 | dev_err(&pdev->dev, "Failed to get irq for data line\n"); |
| 1107 | − return ret; | |
| 1107 | + goto free_host; | |
| 1108 | 1108 | } |
| 1109 | 1109 | |
| 1110 | 1110 | mutex_init(&host->cmd_mutex); |
| @@ -1116,6 +1116,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 1116 | 1116 | dev_set_drvdata(&pdev->dev, host); |
| 1117 | 1117 | mmc_add_host(mmc); |
| 1118 | 1118 | return 0; |
| 1119 | + | |
| 1120 | +free_host: | |
| 1121 | + mmc_free_host(mmc); | |
| 1122 | + return ret; | |
| 1119 | 1123 | } |
| 1120 | 1124 | |
| 1121 | 1125 | static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev) |
| @@ -605,10 +605,12 @@ static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev, · 604 unmodified lines | ||
| 605 | 605 | } |
| 606 | 606 | |
| 607 | 607 | static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = { |
| 608 | − .chip = &sdhci_acpi_chip_amd, | |
| 609 | − .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, | |
| 610 | − .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | | |
| 611 | − SDHCI_QUIRK_32BIT_ADMA_SIZE, | |
| 608 | + .chip = &sdhci_acpi_chip_amd, | |
| 609 | + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, | |
| 610 | + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | | |
| 611 | + SDHCI_QUIRK_32BIT_DMA_SIZE | | |
| 612 | + SDHCI_QUIRK_32BIT_ADMA_SIZE, | |
| 613 | + .quirks2 = SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | |
| 612 | 614 | .probe_slot = sdhci_acpi_emmc_amd_probe_slot, |
| 613 | 615 | }; |
| 614 | 616 | |
| @@ -26,6 +26,9 @@ · 25 unmodified lines | ||
| 26 | 26 | #define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26) |
| 27 | 27 | #define GLI_9750_DRIVING_1_VALUE 0xFFF |
| 28 | 28 | #define GLI_9750_DRIVING_2_VALUE 0x3 |
| 29 | +#define SDHCI_GLI_9750_SEL_1 BIT(29) | |
| 30 | +#define SDHCI_GLI_9750_SEL_2 BIT(31) | |
| 31 | +#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30)) | |
| 29 | 32 | |
| 30 | 33 | #define SDHCI_GLI_9750_PLL 0x864 |
| 31 | 34 | #define SDHCI_GLI_9750_PLL_TX2_INV BIT(23) |
| @@ -122,6 +125,8 @@ static void gli_set_9750(struct sdhci_host *host) · 90 unmodified lines | ||
| 122 | 125 | GLI_9750_DRIVING_1_VALUE); |
| 123 | 126 | driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2, |
| 124 | 127 | GLI_9750_DRIVING_2_VALUE); |
| 128 | + driving_value &= ~(SDHCI_GLI_9750_SEL_1|SDHCI_GLI_9750_SEL_2|SDHCI_GLI_9750_ALL_RST); | |
| 129 | + driving_value |= SDHCI_GLI_9750_SEL_2; | |
| 125 | 130 | sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING); |
| 126 | 131 | |
| 127 | 132 | sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4; |
| @@ -334,6 +339,18 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) · 206 unmodified lines | ||
| 334 | 339 | return value; |
| 335 | 340 | } |
| 336 | 341 | |
| 342 | +#ifdef CONFIG_PM_SLEEP | |
| 343 | +static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) | |
| 344 | +{ | |
| 345 | + struct sdhci_pci_slot *slot = chip->slots[0]; | |
| 346 | + | |
| 347 | + pci_free_irq_vectors(slot->chip->pdev); | |
| 348 | + gli_pcie_enable_msi(slot); | |
| 349 | + | |
| 350 | + return sdhci_pci_resume_host(chip); | |
| 351 | +} | |
| 352 | +#endif | |
| 353 | + | |
| 337 | 354 | static const struct sdhci_ops sdhci_gl9755_ops = { |
| 338 | 355 | .set_clock = sdhci_set_clock, |
| 339 | 356 | .enable_dma = sdhci_pci_enable_dma, |
| @@ -348,6 +365,9 @@ const struct sdhci_pci_fixes sdhci_gl9755 = { · 8 unmodified lines | ||
| 348 | 365 | .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, |
| 349 | 366 | .probe_slot = gli_probe_slot_gl9755, |
| 350 | 367 | .ops = &sdhci_gl9755_ops, |
| 368 | +#ifdef CONFIG_PM_SLEEP | |
| 369 | + .resume = sdhci_pci_gli_resume, | |
| 370 | +#endif | |
| 351 | 371 | }; |
| 352 | 372 | |
| 353 | 373 | static const struct sdhci_ops sdhci_gl9750_ops = { |
| @@ -366,4 +386,7 @@ const struct sdhci_pci_fixes sdhci_gl9750 = { · 12 unmodified lines | ||
| 366 | 386 | .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, |
| 367 | 387 | .probe_slot = gli_probe_slot_gl9750, |
| 368 | 388 | .ops = &sdhci_gl9750_ops, |
| 389 | +#ifdef CONFIG_PM_SLEEP | |
| 390 | + .resume = sdhci_pci_gli_resume, | |
| 391 | +#endif | |
| 369 | 392 | }; |
| @@ -555,7 +555,7 @@ static int mtd_nvmem_add(struct mtd_info *mtd) · 554 unmodified lines | ||
| 555 | 555 | |
| 556 | 556 | config.id = -1; |
| 557 | 557 | config.dev = &mtd->dev; |
| 558 | − config.name = mtd->name; | |
| 558 | + config.name = dev_name(&mtd->dev); | |
| 559 | 559 | config.owner = THIS_MODULE; |
| 560 | 560 | config.reg_read = mtd_nvmem_reg_read; |
| 561 | 561 | config.size = mtd->size; |
| @@ -2728,9 +2728,8 @@ static int brcmnand_resume(struct device *dev) · 2727 unmodified lines | ||
| 2728 | 2728 | flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); |
| 2729 | 2729 | } |
| 2730 | 2730 | |
| 2731 | − if (has_edu(ctrl)) | |
| 2731 | + if (has_edu(ctrl)) { | |
| 2732 | 2732 | ctrl->edu_config = edu_readl(ctrl, EDU_CONFIG); |
| 2733 | − else { | |
| 2734 | 2733 | edu_writel(ctrl, EDU_CONFIG, ctrl->edu_config); |
| 2735 | 2734 | edu_readl(ctrl, EDU_CONFIG); |
| 2736 | 2735 | brcmnand_edu_init(ctrl); |
| @@ -1089,6 +1089,10 @@ static int spinand_init(struct spinand_device *spinand) · 1088 unmodified lines | ||
| 1089 | 1089 | |
| 1090 | 1090 | mtd->oobavail = ret; |
| 1091 | 1091 | |
| 1092 | + /* Propagate ECC information to mtd_info */ | |
| 1093 | + mtd->ecc_strength = nand->eccreq.strength; | |
| 1094 | + mtd->ecc_step_size = nand->eccreq.step_size; | |
| 1095 | + | |
| 1092 | 1096 | return 0; |
| 1093 | 1097 | |
| 1094 | 1098 | err_cleanup_nanddev: |
| @@ -393,9 +393,6 @@ static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos) · 392 unmodified lines | ||
| 393 | 393 | { |
| 394 | 394 | struct ubi_device *ubi = s->private; |
| 395 | 395 | |
| 396 | − if (*pos == 0) | |
| 397 | − return SEQ_START_TOKEN; | |
| 398 | − | |
| 399 | 396 | if (*pos < ubi->peb_count) |
| 400 | 397 | return pos; |
| 401 | 398 | |
| @@ -409,8 +406,6 @@ static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos) · 7 unmodified lines | ||
| 409 | 406 | { |
| 410 | 407 | struct ubi_device *ubi = s->private; |
| 411 | 408 | |
| 412 | − if (v == SEQ_START_TOKEN) | |
| 413 | − return pos; | |
| 414 | 409 | (*pos)++; |
| 415 | 410 | |
| 416 | 411 | if (*pos < ubi->peb_count) |
| @@ -432,11 +427,8 @@ static int eraseblk_count_seq_show(struct seq_file *s, void *iter) · 15 unmodified lines | ||
| 432 | 427 | int err; |
| 433 | 428 | |
| 434 | 429 | /* If this is the start, print a header */ |
| 435 | − if (iter == SEQ_START_TOKEN) { | |
| 436 | − seq_puts(s, | |
| 437 | − "physical_block_number\terase_count\tblock_status\tread_status\n"); | |
| 438 | − return 0; | |
| 439 | − } | |
| 430 | + if (*block_number == 0) | |
| 431 | + seq_puts(s, "physical_block_number\terase_count\n"); | |
| 440 | 432 | |
| 441 | 433 | err = ubi_io_is_bad(ubi, *block_number); |
| 442 | 434 | if (err) |
| @@ -136,25 +136,21 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 135 unmodified lines | ||
| 136 | 136 | oiph = skb_network_header(skb); |
| 137 | 137 | skb_reset_network_header(skb); |
| 138 | 138 | |
| 139 | − if (family == AF_INET) | |
| 139 | + if (!IS_ENABLED(CONFIG_IPV6) || family == AF_INET) | |
| 140 | 140 | err = IP_ECN_decapsulate(oiph, skb); |
| 141 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 142 | 141 | else |
| 143 | 142 | err = IP6_ECN_decapsulate(oiph, skb); |
| 144 | −#endif | |
| 145 | 143 | |
| 146 | 144 | if (unlikely(err)) { |
| 147 | 145 | if (log_ecn_error) { |
| 148 | − if (family == AF_INET) | |
| 146 | + if (!IS_ENABLED(CONFIG_IPV6) || family == AF_INET) | |
| 149 | 147 | net_info_ratelimited("non-ECT from %pI4 " |
| 150 | 148 | "with TOS=%#x\n", |
| 151 | 149 | &((struct iphdr *)oiph)->saddr, |
| 152 | 150 | ((struct iphdr *)oiph)->tos); |
| 153 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 154 | 151 | else |
| 155 | 152 | net_info_ratelimited("non-ECT from %pI6\n", |
| 156 | 153 | &((struct ipv6hdr *)oiph)->saddr); |
| 157 | −#endif | |
| 158 | 154 | } |
| 159 | 155 | if (err > 1) { |
| 160 | 156 | ++bareudp->dev->stats.rx_frame_errors; |
| @@ -350,7 +346,6 @@ free_dst: · 189 unmodified lines | ||
| 350 | 346 | return err; |
| 351 | 347 | } |
| 352 | 348 | |
| 353 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 354 | 349 | static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
| 355 | 350 | struct bareudp_dev *bareudp, |
| 356 | 351 | const struct ip_tunnel_info *info) |
| @@ -411,7 +406,6 @@ free_dst: · 54 unmodified lines | ||
| 411 | 406 | dst_release(dst); |
| 412 | 407 | return err; |
| 413 | 408 | } |
| 414 | −#endif | |
| 415 | 409 | |
| 416 | 410 | static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev) |
| 417 | 411 | { |
| @@ -435,11 +429,9 @@ static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev) · 17 unmodified lines | ||
| 435 | 429 | } |
| 436 | 430 | |
| 437 | 431 | rcu_read_lock(); |
| 438 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 439 | − if (info->mode & IP_TUNNEL_INFO_IPV6) | |
| 432 | + if (IS_ENABLED(CONFIG_IPV6) && info->mode & IP_TUNNEL_INFO_IPV6) | |
| 440 | 433 | err = bareudp6_xmit_skb(skb, dev, bareudp, info); |
| 441 | 434 | else |
| 442 | −#endif | |
| 443 | 435 | err = bareudp_xmit_skb(skb, dev, bareudp, info); |
| 444 | 436 | |
| 445 | 437 | rcu_read_unlock(); |
| @@ -467,7 +459,7 @@ static int bareudp_fill_metadata_dst(struct net_device *dev, · 21 unmodified lines | ||
| 467 | 459 | |
| 468 | 460 | use_cache = ip_tunnel_dst_cache_usable(skb, info); |
| 469 | 461 | |
| 470 | − if (ip_tunnel_info_af(info) == AF_INET) { | |
| 462 | + if (!IS_ENABLED(CONFIG_IPV6) || ip_tunnel_info_af(info) == AF_INET) { | |
| 471 | 463 | struct rtable *rt; |
| 472 | 464 | __be32 saddr; |
| 473 | 465 | |
| @@ -478,7 +470,6 @@ static int bareudp_fill_metadata_dst(struct net_device *dev, · 4 unmodified lines | ||
| 478 | 470 | |
| 479 | 471 | ip_rt_put(rt); |
| 480 | 472 | info->key.u.ipv4.src = saddr; |
| 481 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 482 | 473 | } else if (ip_tunnel_info_af(info) == AF_INET6) { |
| 483 | 474 | struct dst_entry *dst; |
| 484 | 475 | struct in6_addr saddr; |
| @@ -492,7 +483,6 @@ static int bareudp_fill_metadata_dst(struct net_device *dev, · 7 unmodified lines | ||
| 492 | 483 | |
| 493 | 484 | dst_release(dst); |
| 494 | 485 | info->key.u.ipv6.src = saddr; |
| 495 | −#endif | |
| 496 | 486 | } else { |
| 497 | 487 | return -EINVAL; |
| 498 | 488 | } |
| @@ -947,8 +947,11 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) · 946 unmodified lines | ||
| 947 | 947 | u32 id, rev; |
| 948 | 948 | |
| 949 | 949 | addr = devm_platform_ioremap_resource(pdev, 0); |
| 950 | + if (IS_ERR(addr)) | |
| 951 | + return PTR_ERR(addr); | |
| 952 | + | |
| 950 | 953 | irq = platform_get_irq(pdev, 0); |
| 951 | − if (IS_ERR(addr) || irq < 0) | |
| 954 | + if (irq < 0) | |
| 952 | 955 | return -EINVAL; |
| 953 | 956 | |
| 954 | 957 | id = readl(addr + IFI_CANFD_IP_ID); |
| @@ -792,7 +792,7 @@ static int sun4ican_probe(struct platform_device *pdev) · 791 unmodified lines | ||
| 792 | 792 | |
| 793 | 793 | addr = devm_platform_ioremap_resource(pdev, 0); |
| 794 | 794 | if (IS_ERR(addr)) { |
| 795 | − err = -EBUSY; | |
| 795 | + err = PTR_ERR(addr); | |
| 796 | 796 | goto exit; |
| 797 | 797 | } |
| 798 | 798 | |
| @@ -609,7 +609,7 @@ static int b53_srab_probe(struct platform_device *pdev) · 608 unmodified lines | ||
| 609 | 609 | |
| 610 | 610 | priv->regs = devm_platform_ioremap_resource(pdev, 0); |
| 611 | 611 | if (IS_ERR(priv->regs)) |
| 612 | − return -ENOMEM; | |
| 612 | + return PTR_ERR(priv->regs); | |
| 613 | 613 | |
| 614 | 614 | dev = b53_switch_alloc(&pdev->dev, &b53_srab_ops, priv); |
| 615 | 615 | if (!dev) |
| @@ -360,6 +360,7 @@ static void __exit dsa_loop_exit(void) · 359 unmodified lines | ||
| 360 | 360 | } |
| 361 | 361 | module_exit(dsa_loop_exit); |
| 362 | 362 | |
| 363 | +MODULE_SOFTDEP("pre: dsa_loop_bdinfo"); | |
| 363 | 364 | MODULE_LICENSE("GPL"); |
| 364 | 365 | MODULE_AUTHOR("Florian Fainelli"); |
| 365 | 366 | MODULE_DESCRIPTION("DSA loopback driver"); |
| @@ -628,11 +628,8 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, · 627 unmodified lines | ||
| 628 | 628 | mt7530_write(priv, MT7530_PVC_P(port), |
| 629 | 629 | PORT_SPEC_TAG); |
| 630 | 630 | |
| 631 | − /* Disable auto learning on the cpu port */ | |
| 632 | − mt7530_set(priv, MT7530_PSC_P(port), SA_DIS); | |
| 633 | − | |
| 634 | − /* Unknown unicast frame fordwarding to the cpu port */ | |
| 635 | − mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port))); | |
| 631 | + /* Unknown multicast frame forwarding to the cpu port */ | |
| 632 | + mt7530_rmw(priv, MT7530_MFC, UNM_FFP_MASK, UNM_FFP(BIT(port))); | |
| 636 | 633 | |
| 637 | 634 | /* Set CPU port number */ |
| 638 | 635 | if (priv->id == ID_MT7621) |
| @@ -1294,8 +1291,6 @@ mt7530_setup(struct dsa_switch *ds) · 655 unmodified lines | ||
| 1294 | 1291 | /* Enable and reset MIB counters */ |
| 1295 | 1292 | mt7530_mib_reset(ds); |
| 1296 | 1293 | |
| 1297 | − mt7530_clear(priv, MT7530_MFC, UNU_FFP_MASK); | |
| 1298 | − | |
| 1299 | 1294 | for (i = 0; i < MT7530_NUM_PORTS; i++) { |
| 1300 | 1295 | /* Disable forwarding by default on all ports */ |
| 1301 | 1296 | mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, |
| @@ -31,6 +31,7 @@ enum { · 30 unmodified lines | ||
| 31 | 31 | #define MT7530_MFC 0x10 |
| 32 | 32 | #define BC_FFP(x) (((x) & 0xff) << 24) |
| 33 | 33 | #define UNM_FFP(x) (((x) & 0xff) << 16) |
| 34 | +#define UNM_FFP_MASK UNM_FFP(~0) | |
| 34 | 35 | #define UNU_FFP(x) (((x) & 0xff) << 8) |
| 35 | 36 | #define UNU_FFP_MASK UNU_FFP(~0) |
| 36 | 37 | #define CPU_EN BIT(7) |
| @@ -388,6 +388,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) · 387 unmodified lines | ||
| 388 | 388 | struct ocelot *ocelot = &felix->ocelot; |
| 389 | 389 | phy_interface_t *port_phy_modes; |
| 390 | 390 | resource_size_t switch_base; |
| 391 | + struct resource res; | |
| 391 | 392 | int port, i, err; |
| 392 | 393 | |
| 393 | 394 | ocelot->num_phys_ports = num_phys_ports; |
| @@ -422,17 +423,16 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) · 28 unmodified lines | ||
| 422 | 423 | |
| 423 | 424 | for (i = 0; i < TARGET_MAX; i++) { |
| 424 | 425 | struct regmap *target; |
| 425 | − struct resource *res; | |
| 426 | 426 | |
| 427 | 427 | if (!felix->info->target_io_res[i].name) |
| 428 | 428 | continue; |
| 429 | 429 | |
| 430 | − res = &felix->info->target_io_res[i]; | |
| 431 | − res->flags = IORESOURCE_MEM; | |
| 432 | − res->start += switch_base; | |
| 433 | − res->end += switch_base; | |
| 430 | + memcpy(&res, &felix->info->target_io_res[i], sizeof(res)); | |
| 431 | + res.flags = IORESOURCE_MEM; | |
| 432 | + res.start += switch_base; | |
| 433 | + res.end += switch_base; | |
| 434 | 434 | |
| 435 | − target = ocelot_regmap_init(ocelot, res); | |
| 435 | + target = ocelot_regmap_init(ocelot, &res); | |
| 436 | 436 | if (IS_ERR(target)) { |
| 437 | 437 | dev_err(ocelot->dev, |
| 438 | 438 | "Failed to map device memory space\n"); |
| @@ -453,7 +453,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) · 14 unmodified lines | ||
| 453 | 453 | for (port = 0; port < num_phys_ports; port++) { |
| 454 | 454 | struct ocelot_port *ocelot_port; |
| 455 | 455 | void __iomem *port_regs; |
| 456 | − struct resource *res; | |
| 457 | 456 | |
| 458 | 457 | ocelot_port = devm_kzalloc(ocelot->dev, |
| 459 | 458 | sizeof(struct ocelot_port), |
| @@ -465,12 +464,12 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) · 5 unmodified lines | ||
| 465 | 464 | return -ENOMEM; |
| 466 | 465 | } |
| 467 | 466 | |
| 468 | − res = &felix->info->port_io_res[port]; | |
| 469 | − res->flags = IORESOURCE_MEM; | |
| 470 | − res->start += switch_base; | |
| 471 | − res->end += switch_base; | |
| 467 | + memcpy(&res, &felix->info->port_io_res[port], sizeof(res)); | |
| 468 | + res.flags = IORESOURCE_MEM; | |
| 469 | + res.start += switch_base; | |
| 470 | + res.end += switch_base; | |
| 472 | 471 | |
| 473 | − port_regs = devm_ioremap_resource(ocelot->dev, res); | |
| 472 | + port_regs = devm_ioremap_resource(ocelot->dev, &res); | |
| 474 | 473 | if (IS_ERR(port_regs)) { |
| 475 | 474 | dev_err(ocelot->dev, |
| 476 | 475 | "failed to map registers for port %d\n", port); |
| @@ -8,9 +8,9 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | /* Platform-specific information */ |
| 10 | 10 | struct felix_info { |
| 11 | − struct resource *target_io_res; | |
| 12 | − struct resource *port_io_res; | |
| 13 | − struct resource *imdio_res; | |
| 11 | + const struct resource *target_io_res; | |
| 12 | + const struct resource *port_io_res; | |
| 13 | + const struct resource *imdio_res; | |
| 14 | 14 | const struct reg_field *regfields; |
| 15 | 15 | const u32 *const *map; |
| 16 | 16 | const struct ocelot_ops *ops; |
| @@ -333,10 +333,8 @@ static const u32 *vsc9959_regmap[] = { · 332 unmodified lines | ||
| 333 | 333 | [GCB] = vsc9959_gcb_regmap, |
| 334 | 334 | }; |
| 335 | 335 | |
| 336 | −/* Addresses are relative to the PCI device's base address and | |
| 337 | − * will be fixed up at ioremap time. | |
| 338 | − */ | |
| 339 | −static struct resource vsc9959_target_io_res[] = { | |
| 336 | +/* Addresses are relative to the PCI device's base address */ | |
| 337 | +static const struct resource vsc9959_target_io_res[] = { | |
| 340 | 338 | [ANA] = { |
| 341 | 339 | .start = 0x0280000, |
| 342 | 340 | .end = 0x028ffff, |
| @@ -379,7 +377,7 @@ static struct resource vsc9959_target_io_res[] = { · 36 unmodified lines | ||
| 379 | 377 | }, |
| 380 | 378 | }; |
| 381 | 379 | |
| 382 | −static struct resource vsc9959_port_io_res[] = { | |
| 380 | +static const struct resource vsc9959_port_io_res[] = { | |
| 383 | 381 | { |
| 384 | 382 | .start = 0x0100000, |
| 385 | 383 | .end = 0x010ffff, |
| @@ -415,7 +413,7 @@ static struct resource vsc9959_port_io_res[] = { · 29 unmodified lines | ||
| 415 | 413 | /* Port MAC 0 Internal MDIO bus through which the SerDes acting as an |
| 416 | 414 | * SGMII/QSGMII MAC PCS can be found. |
| 417 | 415 | */ |
| 418 | −static struct resource vsc9959_imdio_res = { | |
| 416 | +static const struct resource vsc9959_imdio_res = { | |
| 419 | 417 | .start = 0x8030, |
| 420 | 418 | .end = 0x8040, |
| 421 | 419 | .name = "imdio", |
| @@ -1111,7 +1109,7 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) · 689 unmodified lines | ||
| 1111 | 1109 | struct device *dev = ocelot->dev; |
| 1112 | 1110 | resource_size_t imdio_base; |
| 1113 | 1111 | void __iomem *imdio_regs; |
| 1114 | − struct resource *res; | |
| 1112 | + struct resource res; | |
| 1115 | 1113 | struct enetc_hw *hw; |
| 1116 | 1114 | struct mii_bus *bus; |
| 1117 | 1115 | int port; |
| @@ -1128,12 +1126,12 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) · 10 unmodified lines | ||
| 1128 | 1126 | imdio_base = pci_resource_start(felix->pdev, |
| 1129 | 1127 | felix->info->imdio_pci_bar); |
| 1130 | 1128 | |
| 1131 | − res = felix->info->imdio_res; | |
| 1132 | − res->flags = IORESOURCE_MEM; | |
| 1133 | − res->start += imdio_base; | |
| 1134 | − res->end += imdio_base; | |
| 1129 | + memcpy(&res, felix->info->imdio_res, sizeof(res)); | |
| 1130 | + res.flags = IORESOURCE_MEM; | |
| 1131 | + res.start += imdio_base; | |
| 1132 | + res.end += imdio_base; | |
| 1135 | 1133 | |
| 1136 | − imdio_regs = devm_ioremap_resource(dev, res); | |
| 1134 | + imdio_regs = devm_ioremap_resource(dev, &res); | |
| 1137 | 1135 | if (IS_ERR(imdio_regs)) { |
| 1138 | 1136 | dev_err(dev, "failed to map internal MDIO registers\n"); |
| 1139 | 1137 | return PTR_ERR(imdio_regs); |
| @@ -1182,7 +1182,7 @@ bmac_get_station_address(struct net_device *dev, unsigned char *ea) · 1181 unmodified lines | ||
| 1182 | 1182 | int i; |
| 1183 | 1183 | unsigned short data; |
| 1184 | 1184 | |
| 1185 | − for (i = 0; i < 6; i++) | |
| 1185 | + for (i = 0; i < 3; i++) | |
| 1186 | 1186 | { |
| 1187 | 1187 | reset_and_select_srom(dev); |
| 1188 | 1188 | data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits); |
| @@ -69,6 +69,7 @@ config BCMGENET · 68 unmodified lines | ||
| 69 | 69 | select BCM7XXX_PHY |
| 70 | 70 | select MDIO_BCM_UNIMAC |
| 71 | 71 | select DIMLIB |
| 72 | + select BROADCOM_PHY if ARCH_BCM2835 | |
| 72 | 73 | help |
| 73 | 74 | This driver supports the built-in Ethernet MACs found in the |
| 74 | 75 | Broadcom BCM7xxx Set Top Box family chipset. |
| @@ -77,6 +77,7 @@ config UCC_GETH · 76 unmodified lines | ||
| 77 | 77 | depends on QUICC_ENGINE && PPC32 |
| 78 | 78 | select FSL_PQ_MDIO |
| 79 | 79 | select PHYLIB |
| 80 | + select FIXED_PHY | |
| 80 | 81 | ---help--- |
| 81 | 82 | This driver supports the Gigabit Ethernet mode of the QUICC Engine, |
| 82 | 83 | which is available on some Freescale SOCs. |
| @@ -90,6 +91,7 @@ config GIANFAR · 7 unmodified lines | ||
| 90 | 91 | depends on HAS_DMA |
| 91 | 92 | select FSL_PQ_MDIO |
| 92 | 93 | select PHYLIB |
| 94 | + select FIXED_PHY | |
| 93 | 95 | select CRC32 |
| 94 | 96 | ---help--- |
| 95 | 97 | This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, |
| @@ -3,6 +3,7 @@ menuconfig FSL_DPAA_ETH · 2 unmodified lines | ||
| 3 | 3 | tristate "DPAA Ethernet" |
| 4 | 4 | depends on FSL_DPAA && FSL_FMAN |
| 5 | 5 | select PHYLIB |
| 6 | + select FIXED_PHY | |
| 6 | 7 | select FSL_FMAN_MAC |
| 7 | 8 | ---help--- |
| 8 | 9 | Data Path Acceleration Architecture Ethernet driver, |
| @@ -86,7 +86,7 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv, · 85 unmodified lines | ||
| 86 | 86 | for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) { |
| 87 | 87 | addr = dpaa2_sg_get_addr(&sgt[i]); |
| 88 | 88 | sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); |
| 89 | − dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 89 | + dma_unmap_page(dev, addr, priv->rx_buf_size, | |
| 90 | 90 | DMA_BIDIRECTIONAL); |
| 91 | 91 | |
| 92 | 92 | free_pages((unsigned long)sg_vaddr, 0); |
| @@ -144,7 +144,7 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, · 51 unmodified lines | ||
| 144 | 144 | /* Get the address and length from the S/G entry */ |
| 145 | 145 | sg_addr = dpaa2_sg_get_addr(sge); |
| 146 | 146 | sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr); |
| 147 | − dma_unmap_page(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 147 | + dma_unmap_page(dev, sg_addr, priv->rx_buf_size, | |
| 148 | 148 | DMA_BIDIRECTIONAL); |
| 149 | 149 | |
| 150 | 150 | sg_length = dpaa2_sg_get_len(sge); |
| @@ -185,7 +185,7 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, · 34 unmodified lines | ||
| 185 | 185 | (page_address(page) - page_address(head_page)); |
| 186 | 186 | |
| 187 | 187 | skb_add_rx_frag(skb, i - 1, head_page, page_offset, |
| 188 | − sg_length, DPAA2_ETH_RX_BUF_SIZE); | |
| 188 | + sg_length, priv->rx_buf_size); | |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | if (dpaa2_sg_is_final(sge)) |
| @@ -211,7 +211,7 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count) · 19 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | for (i = 0; i < count; i++) { |
| 213 | 213 | vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]); |
| 214 | − dma_unmap_page(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE, | |
| 214 | + dma_unmap_page(dev, buf_array[i], priv->rx_buf_size, | |
| 215 | 215 | DMA_BIDIRECTIONAL); |
| 216 | 216 | free_pages((unsigned long)vaddr, 0); |
| 217 | 217 | } |
| @@ -335,7 +335,7 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv, · 117 unmodified lines | ||
| 335 | 335 | break; |
| 336 | 336 | case XDP_REDIRECT: |
| 337 | 337 | dma_unmap_page(priv->net_dev->dev.parent, addr, |
| 338 | − DPAA2_ETH_RX_BUF_SIZE, DMA_BIDIRECTIONAL); | |
| 338 | + priv->rx_buf_size, DMA_BIDIRECTIONAL); | |
| 339 | 339 | ch->buf_count--; |
| 340 | 340 | xdp.data_hard_start = vaddr; |
| 341 | 341 | err = xdp_do_redirect(priv->net_dev, &xdp, xdp_prog); |
| @@ -374,7 +374,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, · 32 unmodified lines | ||
| 374 | 374 | trace_dpaa2_rx_fd(priv->net_dev, fd); |
| 375 | 375 | |
| 376 | 376 | vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); |
| 377 | − dma_sync_single_for_cpu(dev, addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 377 | + dma_sync_single_for_cpu(dev, addr, priv->rx_buf_size, | |
| 378 | 378 | DMA_BIDIRECTIONAL); |
| 379 | 379 | |
| 380 | 380 | fas = dpaa2_get_fas(vaddr, false); |
| @@ -393,13 +393,13 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, · 12 unmodified lines | ||
| 393 | 393 | return; |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | − dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 396 | + dma_unmap_page(dev, addr, priv->rx_buf_size, | |
| 397 | 397 | DMA_BIDIRECTIONAL); |
| 398 | 398 | skb = build_linear_skb(ch, fd, vaddr); |
| 399 | 399 | } else if (fd_format == dpaa2_fd_sg) { |
| 400 | 400 | WARN_ON(priv->xdp_prog); |
| 401 | 401 | |
| 402 | − dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 402 | + dma_unmap_page(dev, addr, priv->rx_buf_size, | |
| 403 | 403 | DMA_BIDIRECTIONAL); |
| 404 | 404 | skb = build_frag_skb(priv, ch, buf_data); |
| 405 | 405 | free_pages((unsigned long)vaddr, 0); |
| @@ -974,7 +974,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, · 568 unmodified lines | ||
| 974 | 974 | if (!page) |
| 975 | 975 | goto err_alloc; |
| 976 | 976 | |
| 977 | − addr = dma_map_page(dev, page, 0, DPAA2_ETH_RX_BUF_SIZE, | |
| 977 | + addr = dma_map_page(dev, page, 0, priv->rx_buf_size, | |
| 978 | 978 | DMA_BIDIRECTIONAL); |
| 979 | 979 | if (unlikely(dma_mapping_error(dev, addr))) |
| 980 | 980 | goto err_map; |
| @@ -984,7 +984,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, · 3 unmodified lines | ||
| 984 | 984 | /* tracing point */ |
| 985 | 985 | trace_dpaa2_eth_buf_seed(priv->net_dev, |
| 986 | 986 | page, DPAA2_ETH_RX_BUF_RAW_SIZE, |
| 987 | − addr, DPAA2_ETH_RX_BUF_SIZE, | |
| 987 | + addr, priv->rx_buf_size, | |
| 988 | 988 | bpid); |
| 989 | 989 | } |
| 990 | 990 | |
| @@ -1720,7 +1720,7 @@ static bool xdp_mtu_valid(struct dpaa2_eth_priv *priv, int mtu) · 729 unmodified lines | ||
| 1720 | 1720 | int mfl, linear_mfl; |
| 1721 | 1721 | |
| 1722 | 1722 | mfl = DPAA2_ETH_L2_MAX_FRM(mtu); |
| 1723 | − linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE - | |
| 1723 | + linear_mfl = priv->rx_buf_size - DPAA2_ETH_RX_HWA_SIZE - | |
| 1724 | 1724 | dpaa2_eth_rx_head_room(priv) - XDP_PACKET_HEADROOM; |
| 1725 | 1725 | |
| 1726 | 1726 | if (mfl > linear_mfl) { |
| @@ -2462,6 +2462,11 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) · 735 unmodified lines | ||
| 2462 | 2462 | else |
| 2463 | 2463 | rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; |
| 2464 | 2464 | |
| 2465 | + /* We need to ensure that the buffer size seen by WRIOP is a multiple | |
| 2466 | + * of 64 or 256 bytes depending on the WRIOP version. | |
| 2467 | + */ | |
| 2468 | + priv->rx_buf_size = ALIGN_DOWN(DPAA2_ETH_RX_BUF_SIZE, rx_buf_align); | |
| 2469 | + | |
| 2465 | 2470 | /* tx buffer */ |
| 2466 | 2471 | buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; |
| 2467 | 2472 | buf_layout.pass_timestamp = true; |
| @@ -3126,7 +3131,7 @@ static int bind_dpni(struct dpaa2_eth_priv *priv) · 658 unmodified lines | ||
| 3126 | 3131 | pools_params.num_dpbp = 1; |
| 3127 | 3132 | pools_params.pools[0].dpbp_id = priv->dpbp_dev->obj_desc.id; |
| 3128 | 3133 | pools_params.pools[0].backup_pool = 0; |
| 3129 | − pools_params.pools[0].buffer_size = DPAA2_ETH_RX_BUF_SIZE; | |
| 3134 | + pools_params.pools[0].buffer_size = priv->rx_buf_size; | |
| 3130 | 3135 | err = dpni_set_pools(priv->mc_io, 0, priv->mc_token, &pools_params); |
| 3131 | 3136 | if (err) { |
| 3132 | 3137 | dev_err(dev, "dpni_set_pools() failed\n"); |
| @@ -382,6 +382,7 @@ struct dpaa2_eth_priv { · 381 unmodified lines | ||
| 382 | 382 | u16 tx_data_offset; |
| 383 | 383 | |
| 384 | 384 | struct fsl_mc_device *dpbp_dev; |
| 385 | + u16 rx_buf_size; | |
| 385 | 386 | u16 bpid; |
| 386 | 387 | struct iommu_domain *iommu_domain; |
| 387 | 388 | |
| @@ -635,7 +635,7 @@ static int num_rules(struct dpaa2_eth_priv *priv) · 634 unmodified lines | ||
| 635 | 635 | |
| 636 | 636 | static int update_cls_rule(struct net_device *net_dev, |
| 637 | 637 | struct ethtool_rx_flow_spec *new_fs, |
| 638 | − int location) | |
| 638 | + unsigned int location) | |
| 639 | 639 | { |
| 640 | 640 | struct dpaa2_eth_priv *priv = netdev_priv(net_dev); |
| 641 | 641 | struct dpaa2_eth_cls_rule *rule; |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <soc/fsl/qe/ucc.h> |
| 43 | 43 | #include <soc/fsl/qe/ucc_fast.h> |
| 44 | 44 | #include <asm/machdep.h> |
| 45 | +#include <net/sch_generic.h> | |
| 45 | 46 | |
| 46 | 47 | #include "ucc_geth.h" |
| 47 | 48 | |
| @@ -1548,11 +1549,8 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) · 1500 unmodified lines | ||
| 1548 | 1549 | |
| 1549 | 1550 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) |
| 1550 | 1551 | { |
| 1551 | − /* Prevent any further xmits, plus detach the device. */ | |
| 1552 | − netif_device_detach(ugeth->ndev); | |
| 1553 | − | |
| 1554 | − /* Wait for any current xmits to finish. */ | |
| 1555 | − netif_tx_disable(ugeth->ndev); | |
| 1552 | + /* Prevent any further xmits */ | |
| 1553 | + netif_tx_stop_all_queues(ugeth->ndev); | |
| 1556 | 1554 | |
| 1557 | 1555 | /* Disable the interrupt to avoid NAPI rescheduling. */ |
| 1558 | 1556 | disable_irq(ugeth->ug_info->uf_info.irq); |
| @@ -1565,7 +1563,10 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) · 6 unmodified lines | ||
| 1565 | 1563 | { |
| 1566 | 1564 | napi_enable(&ugeth->napi); |
| 1567 | 1565 | enable_irq(ugeth->ug_info->uf_info.irq); |
| 1568 | − netif_device_attach(ugeth->ndev); | |
| 1566 | + | |
| 1567 | + /* allow to xmit again */ | |
| 1568 | + netif_tx_wake_all_queues(ugeth->ndev); | |
| 1569 | + __netdev_watchdog_up(ugeth->ndev); | |
| 1569 | 1570 | } |
| 1570 | 1571 | |
| 1571 | 1572 | /* Called every time the controller might need to be made |
| @@ -64,7 +64,7 @@ config HNS_MDIO · 63 unmodified lines | ||
| 64 | 64 | the PHY |
| 65 | 65 | |
| 66 | 66 | config HNS |
| 67 | − tristate "Hisilicon Network Subsystem Support (Framework)" | |
| 67 | + tristate | |
| 68 | 68 | ---help--- |
| 69 | 69 | This selects the framework support for Hisilicon Network Subsystem. It |
| 70 | 70 | is needed by any driver which provides HNS acceleration engine or make |
| @@ -45,6 +45,8 @@ · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | #define MGMT_MSG_TIMEOUT 5000 |
| 47 | 47 | |
| 48 | +#define SET_FUNC_PORT_MGMT_TIMEOUT 25000 | |
| 49 | + | |
| 48 | 50 | #define mgmt_to_pfhwdev(pf_mgmt) \ |
| 49 | 51 | container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt) |
| 50 | 52 | |
| @@ -238,12 +240,13 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt, · 187 unmodified lines | ||
| 238 | 240 | u8 *buf_in, u16 in_size, |
| 239 | 241 | u8 *buf_out, u16 *out_size, |
| 240 | 242 | enum mgmt_direction_type direction, |
| 241 | − u16 resp_msg_id) | |
| 243 | + u16 resp_msg_id, u32 timeout) | |
| 242 | 244 | { |
| 243 | 245 | struct hinic_hwif *hwif = pf_to_mgmt->hwif; |
| 244 | 246 | struct pci_dev *pdev = hwif->pdev; |
| 245 | 247 | struct hinic_recv_msg *recv_msg; |
| 246 | 248 | struct completion *recv_done; |
| 249 | + unsigned long timeo; | |
| 247 | 250 | u16 msg_id; |
| 248 | 251 | int err; |
| 249 | 252 | |
| @@ -267,8 +270,9 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt, · 17 unmodified lines | ||
| 267 | 270 | goto unlock_sync_msg; |
| 268 | 271 | } |
| 269 | 272 | |
| 270 | − if (!wait_for_completion_timeout(recv_done, | |
| 271 | − msecs_to_jiffies(MGMT_MSG_TIMEOUT))) { | |
| 273 | + timeo = msecs_to_jiffies(timeout ? timeout : MGMT_MSG_TIMEOUT); | |
| 274 | + | |
| 275 | + if (!wait_for_completion_timeout(recv_done, timeo)) { | |
| 272 | 276 | dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id); |
| 273 | 277 | err = -ETIMEDOUT; |
| 274 | 278 | goto unlock_sync_msg; |
| @@ -342,6 +346,7 @@ int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt, · 67 unmodified lines | ||
| 342 | 346 | { |
| 343 | 347 | struct hinic_hwif *hwif = pf_to_mgmt->hwif; |
| 344 | 348 | struct pci_dev *pdev = hwif->pdev; |
| 349 | + u32 timeout = 0; | |
| 345 | 350 | |
| 346 | 351 | if (sync != HINIC_MGMT_MSG_SYNC) { |
| 347 | 352 | dev_err(&pdev->dev, "Invalid MGMT msg type\n"); |
| @@ -353,9 +358,12 @@ int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt, · 5 unmodified lines | ||
| 353 | 358 | return -EINVAL; |
| 354 | 359 | } |
| 355 | 360 | |
| 361 | + if (cmd == HINIC_PORT_CMD_SET_FUNC_STATE) | |
| 362 | + timeout = SET_FUNC_PORT_MGMT_TIMEOUT; | |
| 363 | + | |
| 356 | 364 | return msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size, |
| 357 | 365 | buf_out, out_size, MGMT_DIRECT_SEND, |
| 358 | − MSG_NOT_RESP); | |
| 366 | + MSG_NOT_RESP, timeout); | |
| 359 | 367 | } |
| 360 | 368 | |
| 361 | 369 | /** |
| @@ -483,7 +483,6 @@ static int hinic_close(struct net_device *netdev) · 482 unmodified lines | ||
| 483 | 483 | { |
| 484 | 484 | struct hinic_dev *nic_dev = netdev_priv(netdev); |
| 485 | 485 | unsigned int flags; |
| 486 | − int err; | |
| 487 | 486 | |
| 488 | 487 | down(&nic_dev->mgmt_lock); |
| 489 | 488 | |
| @@ -497,20 +496,9 @@ static int hinic_close(struct net_device *netdev) · 7 unmodified lines | ||
| 497 | 496 | |
| 498 | 497 | up(&nic_dev->mgmt_lock); |
| 499 | 498 | |
| 500 | − err = hinic_port_set_func_state(nic_dev, HINIC_FUNC_PORT_DISABLE); | |
| 501 | − if (err) { | |
| 502 | − netif_err(nic_dev, drv, netdev, | |
| 503 | − "Failed to set func port state\n"); | |
| 504 | − nic_dev->flags |= (flags & HINIC_INTF_UP); | |
| 505 | − return err; | |
| 506 | − } | |
| 499 | + hinic_port_set_state(nic_dev, HINIC_PORT_DISABLE); | |
| 507 | 500 | |
| 508 | − err = hinic_port_set_state(nic_dev, HINIC_PORT_DISABLE); | |
| 509 | − if (err) { | |
| 510 | − netif_err(nic_dev, drv, netdev, "Failed to set port state\n"); | |
| 511 | − nic_dev->flags |= (flags & HINIC_INTF_UP); | |
| 512 | − return err; | |
| 513 | − } | |
| 501 | + hinic_port_set_func_state(nic_dev, HINIC_FUNC_PORT_DISABLE); | |
| 514 | 502 | |
| 515 | 503 | if (nic_dev->flags & HINIC_RSS_ENABLE) { |
| 516 | 504 | hinic_rss_deinit(nic_dev); |
| @@ -1070,7 +1070,7 @@ void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port) · 1069 unmodified lines | ||
| 1070 | 1070 | (port->first_rxq >> MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS)); |
| 1071 | 1071 | |
| 1072 | 1072 | val = mvpp2_read(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG); |
| 1073 | − val |= MVPP2_CLS_SWFWD_PCTRL_MASK(port->id); | |
| 1073 | + val &= ~MVPP2_CLS_SWFWD_PCTRL_MASK(port->id); | |
| 1074 | 1074 | mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val); |
| 1075 | 1075 | } |
| 1076 | 1076 | |
| @@ -497,13 +497,17 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 496 unmodified lines | ||
| 497 | 497 | |
| 498 | 498 | hw->irq_name = devm_kmalloc_array(&hw->pdev->dev, num_vec, NAME_SIZE, |
| 499 | 499 | GFP_KERNEL); |
| 500 | − if (!hw->irq_name) | |
| 500 | + if (!hw->irq_name) { | |
| 501 | + err = -ENOMEM; | |
| 501 | 502 | goto err_free_netdev; |
| 503 | + } | |
| 502 | 504 | |
| 503 | 505 | hw->affinity_mask = devm_kcalloc(&hw->pdev->dev, num_vec, |
| 504 | 506 | sizeof(cpumask_var_t), GFP_KERNEL); |
| 505 | − if (!hw->affinity_mask) | |
| 507 | + if (!hw->affinity_mask) { | |
| 508 | + err = -ENOMEM; | |
| 506 | 509 | goto err_free_netdev; |
| 510 | + } | |
| 507 | 511 | |
| 508 | 512 | err = pci_alloc_irq_vectors(hw->pdev, num_vec, num_vec, PCI_IRQ_MSIX); |
| 509 | 513 | if (err < 0) { |
| @@ -1418,7 +1418,7 @@ static int pxa168_eth_probe(struct platform_device *pdev) · 1417 unmodified lines | ||
| 1418 | 1418 | |
| 1419 | 1419 | pep->base = devm_platform_ioremap_resource(pdev, 0); |
| 1420 | 1420 | if (IS_ERR(pep->base)) { |
| 1421 | − err = -ENOMEM; | |
| 1421 | + err = PTR_ERR(pep->base); | |
| 1422 | 1422 | goto err_netdev; |
| 1423 | 1423 | } |
| 1424 | 1424 | |
| @@ -2734,7 +2734,7 @@ void mlx4_opreq_action(struct work_struct *work) · 2733 unmodified lines | ||
| 2734 | 2734 | if (err) { |
| 2735 | 2735 | mlx4_err(dev, "Failed to retrieve required operation: %d\n", |
| 2736 | 2736 | err); |
| 2737 | − return; | |
| 2737 | + goto out; | |
| 2738 | 2738 | } |
| 2739 | 2739 | MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET); |
| 2740 | 2740 | MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET); |
| @@ -848,6 +848,14 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg); · 847 unmodified lines | ||
| 848 | 848 | static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev, |
| 849 | 849 | struct mlx5_cmd_msg *msg); |
| 850 | 850 | |
| 851 | +static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode) | |
| 852 | +{ | |
| 853 | + if (cmd->allowed_opcode == CMD_ALLOWED_OPCODE_ALL) | |
| 854 | + return true; | |
| 855 | + | |
| 856 | + return cmd->allowed_opcode == opcode; | |
| 857 | +} | |
| 858 | + | |
| 851 | 859 | static void cmd_work_handler(struct work_struct *work) |
| 852 | 860 | { |
| 853 | 861 | struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work); |
| @@ -861,6 +869,7 @@ static void cmd_work_handler(struct work_struct *work) · 7 unmodified lines | ||
| 861 | 869 | int alloc_ret; |
| 862 | 870 | int cmd_mode; |
| 863 | 871 | |
| 872 | + complete(&ent->handling); | |
| 864 | 873 | sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; |
| 865 | 874 | down(sem); |
| 866 | 875 | if (!ent->page_queue) { |
| @@ -913,7 +922,9 @@ static void cmd_work_handler(struct work_struct *work) · 46 unmodified lines | ||
| 913 | 922 | |
| 914 | 923 | /* Skip sending command to fw if internal error */ |
| 915 | 924 | if (pci_channel_offline(dev->pdev) || |
| 916 | − dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { | |
| 925 | + dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR || | |
| 926 | + cmd->state != MLX5_CMDIF_STATE_UP || | |
| 927 | + !opcode_allowed(&dev->cmd, ent->op)) { | |
| 917 | 928 | u8 status = 0; |
| 918 | 929 | u32 drv_synd; |
| 919 | 930 | |
| @@ -978,6 +989,11 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) · 58 unmodified lines | ||
| 978 | 989 | struct mlx5_cmd *cmd = &dev->cmd; |
| 979 | 990 | int err; |
| 980 | 991 | |
| 992 | + if (!wait_for_completion_timeout(&ent->handling, timeout) && | |
| 993 | + cancel_work_sync(&ent->work)) { | |
| 994 | + ent->ret = -ECANCELED; | |
| 995 | + goto out_err; | |
| 996 | + } | |
| 981 | 997 | if (cmd->mode == CMD_MODE_POLLING || ent->polling) { |
| 982 | 998 | wait_for_completion(&ent->done); |
| 983 | 999 | } else if (!wait_for_completion_timeout(&ent->done, timeout)) { |
| @@ -985,12 +1001,17 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) · 1 unmodified line | ||
| 985 | 1001 | mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); |
| 986 | 1002 | } |
| 987 | 1003 | |
| 1004 | +out_err: | |
| 988 | 1005 | err = ent->ret; |
| 989 | 1006 | |
| 990 | 1007 | if (err == -ETIMEDOUT) { |
| 991 | 1008 | mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", |
| 992 | 1009 | mlx5_command_str(msg_to_opcode(ent->in)), |
| 993 | 1010 | msg_to_opcode(ent->in)); |
| 1011 | + } else if (err == -ECANCELED) { | |
| 1012 | + mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n", | |
| 1013 | + mlx5_command_str(msg_to_opcode(ent->in)), | |
| 1014 | + msg_to_opcode(ent->in)); | |
| 994 | 1015 | } |
| 995 | 1016 | mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", |
| 996 | 1017 | err, deliv_status_to_str(ent->status), ent->status); |
| @@ -1026,6 +1047,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, · 29 unmodified lines | ||
| 1026 | 1047 | ent->token = token; |
| 1027 | 1048 | ent->polling = force_polling; |
| 1028 | 1049 | |
| 1050 | + init_completion(&ent->handling); | |
| 1029 | 1051 | if (!callback) |
| 1030 | 1052 | init_completion(&ent->done); |
| 1031 | 1053 | |
| @@ -1045,6 +1067,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, · 13 unmodified lines | ||
| 1045 | 1067 | err = wait_func(dev, ent); |
| 1046 | 1068 | if (err == -ETIMEDOUT) |
| 1047 | 1069 | goto out; |
| 1070 | + if (err == -ECANCELED) | |
| 1071 | + goto out_free; | |
| 1048 | 1072 | |
| 1049 | 1073 | ds = ent->ts2 - ent->ts1; |
| 1050 | 1074 | op = MLX5_GET(mbox_in, in->first.data, opcode); |
| @@ -1391,6 +1415,22 @@ static void create_debugfs_files(struct mlx5_core_dev *dev) · 340 unmodified lines | ||
| 1391 | 1415 | mlx5_cmdif_debugfs_init(dev); |
| 1392 | 1416 | } |
| 1393 | 1417 | |
| 1418 | +void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode) | |
| 1419 | +{ | |
| 1420 | + struct mlx5_cmd *cmd = &dev->cmd; | |
| 1421 | + int i; | |
| 1422 | + | |
| 1423 | + for (i = 0; i < cmd->max_reg_cmds; i++) | |
| 1424 | + down(&cmd->sem); | |
| 1425 | + down(&cmd->pages_sem); | |
| 1426 | + | |
| 1427 | + cmd->allowed_opcode = opcode; | |
| 1428 | + | |
| 1429 | + up(&cmd->pages_sem); | |
| 1430 | + for (i = 0; i < cmd->max_reg_cmds; i++) | |
| 1431 | + up(&cmd->sem); | |
| 1432 | +} | |
| 1433 | + | |
| 1394 | 1434 | static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode) |
| 1395 | 1435 | { |
| 1396 | 1436 | struct mlx5_cmd *cmd = &dev->cmd; |
| @@ -1667,12 +1707,14 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, · 270 unmodified lines | ||
| 1667 | 1707 | int err; |
| 1668 | 1708 | u8 status = 0; |
| 1669 | 1709 | u32 drv_synd; |
| 1710 | + u16 opcode; | |
| 1670 | 1711 | u8 token; |
| 1671 | 1712 | |
| 1713 | + opcode = MLX5_GET(mbox_in, in, opcode); | |
| 1672 | 1714 | if (pci_channel_offline(dev->pdev) || |
| 1673 | − dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { | |
| 1674 | − u16 opcode = MLX5_GET(mbox_in, in, opcode); | |
| 1675 | − | |
| 1715 | + dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR || | |
| 1716 | + dev->cmd.state != MLX5_CMDIF_STATE_UP || | |
| 1717 | + !opcode_allowed(&dev->cmd, opcode)) { | |
| 1676 | 1718 | err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status); |
| 1677 | 1719 | MLX5_SET(mbox_out, out, status, status); |
| 1678 | 1720 | MLX5_SET(mbox_out, out, syndrome, drv_synd); |
| @@ -1937,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) · 258 unmodified lines | ||
| 1937 | 1979 | goto err_free_page; |
| 1938 | 1980 | } |
| 1939 | 1981 | |
| 1982 | + cmd->state = MLX5_CMDIF_STATE_DOWN; | |
| 1940 | 1983 | cmd->checksum_disabled = 1; |
| 1941 | 1984 | cmd->max_reg_cmds = (1 << cmd->log_sz) - 1; |
| 1942 | 1985 | cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1; |
| @@ -1974,6 +2017,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) · 31 unmodified lines | ||
| 1974 | 2017 | mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma)); |
| 1975 | 2018 | |
| 1976 | 2019 | cmd->mode = CMD_MODE_POLLING; |
| 2020 | + cmd->allowed_opcode = CMD_ALLOWED_OPCODE_ALL; | |
| 1977 | 2021 | |
| 1978 | 2022 | create_msg_cache(dev); |
| 1979 | 2023 | |
| @@ -2013,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev) · 33 unmodified lines | ||
| 2013 | 2057 | dma_pool_destroy(cmd->pool); |
| 2014 | 2058 | } |
| 2015 | 2059 | EXPORT_SYMBOL(mlx5_cmd_cleanup); |
| 2060 | + | |
| 2061 | +void mlx5_cmd_set_state(struct mlx5_core_dev *dev, | |
| 2062 | + enum mlx5_cmdif_state cmdif_state) | |
| 2063 | +{ | |
| 2064 | + dev->cmd.state = cmdif_state; | |
| 2065 | +} | |
| 2066 | +EXPORT_SYMBOL(mlx5_cmd_set_state); | |
| @@ -1121,7 +1121,7 @@ void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq); · 1120 unmodified lines | ||
| 1121 | 1121 | int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv); |
| 1122 | 1122 | |
| 1123 | 1123 | int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc); |
| 1124 | −void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc); | |
| 1124 | +void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv); | |
| 1125 | 1125 | |
| 1126 | 1126 | int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs); |
| 1127 | 1127 | void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs); |
| @@ -699,6 +699,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, · 698 unmodified lines | ||
| 699 | 699 | struct netlink_ext_ack *extack) |
| 700 | 700 | { |
| 701 | 701 | struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv); |
| 702 | + struct flow_rule *rule = flow_cls_offload_flow_rule(f); | |
| 702 | 703 | struct flow_dissector_key_ct *mask, *key; |
| 703 | 704 | bool trk, est, untrk, unest, new; |
| 704 | 705 | u32 ctstate = 0, ctstate_mask = 0; |
| @@ -706,7 +707,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, · 1 unmodified line | ||
| 706 | 707 | u16 ct_state, ct_state_mask; |
| 707 | 708 | struct flow_match_ct match; |
| 708 | 709 | |
| 709 | − if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT)) | |
| 710 | + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT)) | |
| 710 | 711 | return 0; |
| 711 | 712 | |
| 712 | 713 | if (!ct_priv) { |
| @@ -715,7 +716,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, · 2 unmodified lines | ||
| 715 | 716 | return -EOPNOTSUPP; |
| 716 | 717 | } |
| 717 | 718 | |
| 718 | − flow_rule_match_ct(f->rule, &match); | |
| 719 | + flow_rule_match_ct(rule, &match); | |
| 719 | 720 | |
| 720 | 721 | key = match.key; |
| 721 | 722 | mask = match.mask; |
| @@ -130,7 +130,9 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, · 129 unmodified lines | ||
| 130 | 130 | struct flow_cls_offload *f, |
| 131 | 131 | struct netlink_ext_ack *extack) |
| 132 | 132 | { |
| 133 | − if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT)) | |
| 133 | + struct flow_rule *rule = flow_cls_offload_flow_rule(f); | |
| 134 | + | |
| 135 | + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT)) | |
| 134 | 136 | return 0; |
| 135 | 137 | |
| 136 | 138 | NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled."); |
| @@ -69,8 +69,8 @@ static void mlx5e_ktls_del(struct net_device *netdev, · 68 unmodified lines | ||
| 69 | 69 | struct mlx5e_ktls_offload_context_tx *tx_priv = |
| 70 | 70 | mlx5e_get_ktls_tx_priv_ctx(tls_ctx); |
| 71 | 71 | |
| 72 | − mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id); | |
| 73 | 72 | mlx5e_destroy_tis(priv->mdev, tx_priv->tisn); |
| 73 | + mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id); | |
| 74 | 74 | kvfree(tx_priv); |
| 75 | 75 | } |
| 76 | 76 | |
| @@ -2717,7 +2717,8 @@ void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen) · 2716 unmodified lines | ||
| 2717 | 2717 | mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen); |
| 2718 | 2718 | } |
| 2719 | 2719 | |
| 2720 | − if (!mlx5e_tunnel_inner_ft_supported(priv->mdev)) | |
| 2720 | + /* Verify inner tirs resources allocated */ | |
| 2721 | + if (!priv->inner_indir_tir[0].tirn) | |
| 2721 | 2722 | return; |
| 2722 | 2723 | |
| 2723 | 2724 | for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { |
| @@ -3408,14 +3409,15 @@ out: · 684 unmodified lines | ||
| 3408 | 3409 | return err; |
| 3409 | 3410 | } |
| 3410 | 3411 | |
| 3411 | −void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc) | |
| 3412 | +void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv) | |
| 3412 | 3413 | { |
| 3413 | 3414 | int i; |
| 3414 | 3415 | |
| 3415 | 3416 | for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) |
| 3416 | 3417 | mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]); |
| 3417 | 3418 | |
| 3418 | − if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev)) | |
| 3419 | + /* Verify inner tirs resources allocated */ | |
| 3420 | + if (!priv->inner_indir_tir[0].tirn) | |
| 3419 | 3421 | return; |
| 3420 | 3422 | |
| 3421 | 3423 | for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) |
| @@ -5123,7 +5125,7 @@ err_destroy_xsk_rqts: · 1701 unmodified lines | ||
| 5123 | 5125 | err_destroy_direct_tirs: |
| 5124 | 5126 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 5125 | 5127 | err_destroy_indirect_tirs: |
| 5126 | − mlx5e_destroy_indirect_tirs(priv, true); | |
| 5128 | + mlx5e_destroy_indirect_tirs(priv); | |
| 5127 | 5129 | err_destroy_direct_rqts: |
| 5128 | 5130 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 5129 | 5131 | err_destroy_indirect_rqts: |
| @@ -5142,7 +5144,7 @@ static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv) · 12 unmodified lines | ||
| 5142 | 5144 | mlx5e_destroy_direct_tirs(priv, priv->xsk_tir); |
| 5143 | 5145 | mlx5e_destroy_direct_rqts(priv, priv->xsk_tir); |
| 5144 | 5146 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 5145 | − mlx5e_destroy_indirect_tirs(priv, true); | |
| 5147 | + mlx5e_destroy_indirect_tirs(priv); | |
| 5146 | 5148 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 5147 | 5149 | mlx5e_destroy_rqt(priv, &priv->indir_rqt); |
| 5148 | 5150 | mlx5e_close_drop_rq(&priv->drop_rq); |
| @@ -1484,13 +1484,9 @@ bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) · 1483 unmodified lines | ||
| 1484 | 1484 | return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; |
| 1485 | 1485 | } |
| 1486 | 1486 | |
| 1487 | −bool mlx5e_eswitch_rep(struct net_device *netdev) | |
| 1487 | +bool mlx5e_eswitch_vf_rep(struct net_device *netdev) | |
| 1488 | 1488 | { |
| 1489 | − if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || | |
| 1490 | − netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep) | |
| 1491 | − return true; | |
| 1492 | − | |
| 1493 | − return false; | |
| 1489 | + return netdev->netdev_ops == &mlx5e_netdev_ops_rep; | |
| 1494 | 1490 | } |
| 1495 | 1491 | |
| 1496 | 1492 | static void mlx5e_build_rep_params(struct net_device *netdev) |
| @@ -1747,7 +1743,7 @@ err_destroy_ttc_table: · 250 unmodified lines | ||
| 1747 | 1743 | err_destroy_direct_tirs: |
| 1748 | 1744 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 1749 | 1745 | err_destroy_indirect_tirs: |
| 1750 | − mlx5e_destroy_indirect_tirs(priv, false); | |
| 1746 | + mlx5e_destroy_indirect_tirs(priv); | |
| 1751 | 1747 | err_destroy_direct_rqts: |
| 1752 | 1748 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 1753 | 1749 | err_destroy_indirect_rqts: |
| @@ -1765,7 +1761,7 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv) · 11 unmodified lines | ||
| 1765 | 1761 | mlx5e_destroy_rep_root_ft(priv); |
| 1766 | 1762 | mlx5e_destroy_ttc_table(priv, &priv->fs.ttc); |
| 1767 | 1763 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 1768 | − mlx5e_destroy_indirect_tirs(priv, false); | |
| 1764 | + mlx5e_destroy_indirect_tirs(priv); | |
| 1769 | 1765 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 1770 | 1766 | mlx5e_destroy_rqt(priv, &priv->indir_rqt); |
| 1771 | 1767 | mlx5e_close_drop_rq(&priv->drop_rq); |
| @@ -210,8 +210,13 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, · 209 unmodified lines | ||
| 210 | 210 | |
| 211 | 211 | void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); |
| 212 | 212 | |
| 213 | −bool mlx5e_eswitch_rep(struct net_device *netdev); | |
| 213 | +bool mlx5e_eswitch_vf_rep(struct net_device *netdev); | |
| 214 | 214 | bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); |
| 215 | +static inline bool mlx5e_eswitch_rep(struct net_device *netdev) | |
| 216 | +{ | |
| 217 | + return mlx5e_eswitch_vf_rep(netdev) || | |
| 218 | + mlx5e_eswitch_uplink_rep(netdev); | |
| 219 | +} | |
| 215 | 220 | |
| 216 | 221 | #else /* CONFIG_MLX5_ESWITCH */ |
| 217 | 222 | static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } |
| @@ -3073,6 +3073,11 @@ static bool actions_match_supported(struct mlx5e_priv *priv, · 3072 unmodified lines | ||
| 3073 | 3073 | return true; |
| 3074 | 3074 | } |
| 3075 | 3075 | |
| 3076 | +static bool same_port_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv) | |
| 3077 | +{ | |
| 3078 | + return priv->mdev == peer_priv->mdev; | |
| 3079 | +} | |
| 3080 | + | |
| 3076 | 3081 | static bool same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv) |
| 3077 | 3082 | { |
| 3078 | 3083 | struct mlx5_core_dev *fmdev, *pmdev; |
| @@ -3291,7 +3296,7 @@ static inline int hash_encap_info(struct encap_key *key) · 212 unmodified lines | ||
| 3291 | 3296 | } |
| 3292 | 3297 | |
| 3293 | 3298 | |
| 3294 | −static bool is_merged_eswitch_dev(struct mlx5e_priv *priv, | |
| 3299 | +static bool is_merged_eswitch_vfs(struct mlx5e_priv *priv, | |
| 3295 | 3300 | struct net_device *peer_netdev) |
| 3296 | 3301 | { |
| 3297 | 3302 | struct mlx5e_priv *peer_priv; |
| @@ -3299,13 +3304,11 @@ static bool is_merged_eswitch_dev(struct mlx5e_priv *priv, · 1 unmodified line | ||
| 3299 | 3304 | peer_priv = netdev_priv(peer_netdev); |
| 3300 | 3305 | |
| 3301 | 3306 | return (MLX5_CAP_ESW(priv->mdev, merged_eswitch) && |
| 3302 | − mlx5e_eswitch_rep(priv->netdev) && | |
| 3303 | − mlx5e_eswitch_rep(peer_netdev) && | |
| 3307 | + mlx5e_eswitch_vf_rep(priv->netdev) && | |
| 3308 | + mlx5e_eswitch_vf_rep(peer_netdev) && | |
| 3304 | 3309 | same_hw_devs(priv, peer_priv)); |
| 3305 | 3310 | } |
| 3306 | 3311 | |
| 3307 | − | |
| 3308 | − | |
| 3309 | 3312 | bool mlx5e_encap_take(struct mlx5e_encap_entry *e) |
| 3310 | 3313 | { |
| 3311 | 3314 | return refcount_inc_not_zero(&e->refcnt); |
| @@ -3575,14 +3578,37 @@ static int add_vlan_pop_action(struct mlx5e_priv *priv, · 263 unmodified lines | ||
| 3575 | 3578 | return err; |
| 3576 | 3579 | } |
| 3577 | 3580 | |
| 3581 | +static bool same_hw_reps(struct mlx5e_priv *priv, | |
| 3582 | + struct net_device *peer_netdev) | |
| 3583 | +{ | |
| 3584 | + struct mlx5e_priv *peer_priv; | |
| 3585 | + | |
| 3586 | + peer_priv = netdev_priv(peer_netdev); | |
| 3587 | + | |
| 3588 | + return mlx5e_eswitch_rep(priv->netdev) && | |
| 3589 | + mlx5e_eswitch_rep(peer_netdev) && | |
| 3590 | + same_hw_devs(priv, peer_priv); | |
| 3591 | +} | |
| 3592 | + | |
| 3593 | +static bool is_lag_dev(struct mlx5e_priv *priv, | |
| 3594 | + struct net_device *peer_netdev) | |
| 3595 | +{ | |
| 3596 | + return ((mlx5_lag_is_sriov(priv->mdev) || | |
| 3597 | + mlx5_lag_is_multipath(priv->mdev)) && | |
| 3598 | + same_hw_reps(priv, peer_netdev)); | |
| 3599 | +} | |
| 3600 | + | |
| 3578 | 3601 | bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv, |
| 3579 | 3602 | struct net_device *out_dev) |
| 3580 | 3603 | { |
| 3581 | − if (is_merged_eswitch_dev(priv, out_dev)) | |
| 3604 | + if (is_merged_eswitch_vfs(priv, out_dev)) | |
| 3605 | + return true; | |
| 3606 | + | |
| 3607 | + if (is_lag_dev(priv, out_dev)) | |
| 3582 | 3608 | return true; |
| 3583 | 3609 | |
| 3584 | 3610 | return mlx5e_eswitch_rep(out_dev) && |
| 3585 | − same_hw_devs(priv, netdev_priv(out_dev)); | |
| 3611 | + same_port_devs(priv, netdev_priv(out_dev)); | |
| 3586 | 3612 | } |
| 3587 | 3613 | |
| 3588 | 3614 | static bool is_duplicated_output_device(struct net_device *dev, |
| @@ -537,10 +537,9 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) · 536 unmodified lines | ||
| 537 | 537 | void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq) |
| 538 | 538 | { |
| 539 | 539 | struct mlx5e_tx_wqe_info *wi; |
| 540 | + u32 dma_fifo_cc, nbytes = 0; | |
| 541 | + u16 ci, sqcc, npkts = 0; | |
| 540 | 542 | struct sk_buff *skb; |
| 541 | − u32 dma_fifo_cc; | |
| 542 | − u16 sqcc; | |
| 543 | − u16 ci; | |
| 544 | 543 | int i; |
| 545 | 544 | |
| 546 | 545 | sqcc = sq->cc; |
| @@ -565,11 +564,15 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq) · 18 unmodified lines | ||
| 565 | 564 | } |
| 566 | 565 | |
| 567 | 566 | dev_kfree_skb_any(skb); |
| 567 | + npkts++; | |
| 568 | + nbytes += wi->num_bytes; | |
| 568 | 569 | sqcc += wi->num_wqebbs; |
| 569 | 570 | } |
| 570 | 571 | |
| 571 | 572 | sq->dma_fifo_cc = dma_fifo_cc; |
| 572 | 573 | sq->cc = sqcc; |
| 574 | + | |
| 575 | + netdev_tx_completed_queue(sq->txq, npkts, nbytes); | |
| 573 | 576 | } |
| 574 | 577 | |
| 575 | 578 | #ifdef CONFIG_MLX5_CORE_IPOIB |
| @@ -611,11 +611,13 @@ static int create_async_eqs(struct mlx5_core_dev *dev) · 610 unmodified lines | ||
| 611 | 611 | .nent = MLX5_NUM_CMD_EQE, |
| 612 | 612 | .mask[0] = 1ull << MLX5_EVENT_TYPE_CMD, |
| 613 | 613 | }; |
| 614 | + mlx5_cmd_allowed_opcode(dev, MLX5_CMD_OP_CREATE_EQ); | |
| 614 | 615 | err = setup_async_eq(dev, &table->cmd_eq, ¶m, "cmd"); |
| 615 | 616 | if (err) |
| 616 | 617 | goto err1; |
| 617 | 618 | |
| 618 | 619 | mlx5_cmd_use_events(dev); |
| 620 | + mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL); | |
| 619 | 621 | |
| 620 | 622 | param = (struct mlx5_eq_param) { |
| 621 | 623 | .irq_index = 0, |
| @@ -645,6 +647,7 @@ err2: · 23 unmodified lines | ||
| 645 | 647 | mlx5_cmd_use_polling(dev); |
| 646 | 648 | cleanup_async_eq(dev, &table->cmd_eq, "cmd"); |
| 647 | 649 | err1: |
| 650 | + mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL); | |
| 648 | 651 | mlx5_eq_notifier_unregister(dev, &table->cq_err_nb); |
| 649 | 652 | return err; |
| 650 | 653 | } |
| @@ -346,8 +346,10 @@ int mlx5_events_init(struct mlx5_core_dev *dev) · 345 unmodified lines | ||
| 346 | 346 | events->dev = dev; |
| 347 | 347 | dev->priv.events = events; |
| 348 | 348 | events->wq = create_singlethread_workqueue("mlx5_events"); |
| 349 | − if (!events->wq) | |
| 349 | + if (!events->wq) { | |
| 350 | + kfree(events); | |
| 350 | 351 | return -ENOMEM; |
| 352 | + } | |
| 351 | 353 | INIT_WORK(&events->pcie_core_work, mlx5_pcie_event); |
| 352 | 354 | |
| 353 | 355 | return 0; |
| @@ -344,17 +344,12 @@ static void tree_put_node(struct fs_node *node, bool locked) · 343 unmodified lines | ||
| 344 | 344 | if (node->del_hw_func) |
| 345 | 345 | node->del_hw_func(node); |
| 346 | 346 | if (parent_node) { |
| 347 | − /* Only root namespace doesn't have parent and we just | |
| 348 | − * need to free its node. | |
| 349 | − */ | |
| 350 | 347 | down_write_ref_node(parent_node, locked); |
| 351 | 348 | list_del_init(&node->list); |
| 352 | − if (node->del_sw_func) | |
| 353 | − node->del_sw_func(node); | |
| 354 | − up_write_ref_node(parent_node, locked); | |
| 355 | − } else { | |
| 356 | − kfree(node); | |
| 357 | 349 | } |
| 350 | + node->del_sw_func(node); | |
| 351 | + if (parent_node) | |
| 352 | + up_write_ref_node(parent_node, locked); | |
| 358 | 353 | node = NULL; |
| 359 | 354 | } |
| 360 | 355 | if (!node && parent_node) |
| @@ -468,8 +463,10 @@ static void del_sw_flow_table(struct fs_node *node) · 107 unmodified lines | ||
| 468 | 463 | fs_get_obj(ft, node); |
| 469 | 464 | |
| 470 | 465 | rhltable_destroy(&ft->fgs_hash); |
| 471 | − fs_get_obj(prio, ft->node.parent); | |
| 472 | − prio->num_ft--; | |
| 466 | + if (ft->node.parent) { | |
| 467 | + fs_get_obj(prio, ft->node.parent); | |
| 468 | + prio->num_ft--; | |
| 469 | + } | |
| 473 | 470 | kfree(ft); |
| 474 | 471 | } |
| 475 | 472 | |
| @@ -2351,6 +2348,17 @@ static int init_root_tree(struct mlx5_flow_steering *steering, · 1875 unmodified lines | ||
| 2351 | 2348 | return 0; |
| 2352 | 2349 | } |
| 2353 | 2350 | |
| 2351 | +static void del_sw_root_ns(struct fs_node *node) | |
| 2352 | +{ | |
| 2353 | + struct mlx5_flow_root_namespace *root_ns; | |
| 2354 | + struct mlx5_flow_namespace *ns; | |
| 2355 | + | |
| 2356 | + fs_get_obj(ns, node); | |
| 2357 | + root_ns = container_of(ns, struct mlx5_flow_root_namespace, ns); | |
| 2358 | + mutex_destroy(&root_ns->chain_lock); | |
| 2359 | + kfree(node); | |
| 2360 | +} | |
| 2361 | + | |
| 2354 | 2362 | static struct mlx5_flow_root_namespace |
| 2355 | 2363 | *create_root_ns(struct mlx5_flow_steering *steering, |
| 2356 | 2364 | enum fs_flow_table_type table_type) |
| @@ -2377,7 +2385,7 @@ static struct mlx5_flow_root_namespace · 20 unmodified lines | ||
| 2377 | 2385 | ns = &root_ns->ns; |
| 2378 | 2386 | fs_init_namespace(ns); |
| 2379 | 2387 | mutex_init(&root_ns->chain_lock); |
| 2380 | − tree_init_node(&ns->node, NULL, NULL); | |
| 2388 | + tree_init_node(&ns->node, NULL, del_sw_root_ns); | |
| 2381 | 2389 | tree_add_node(&ns->node, NULL); |
| 2382 | 2390 | |
| 2383 | 2391 | return root_ns; |
| @@ -396,7 +396,7 @@ static int mlx5i_init_rx(struct mlx5e_priv *priv) · 395 unmodified lines | ||
| 396 | 396 | err_destroy_direct_tirs: |
| 397 | 397 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 398 | 398 | err_destroy_indirect_tirs: |
| 399 | − mlx5e_destroy_indirect_tirs(priv, true); | |
| 399 | + mlx5e_destroy_indirect_tirs(priv); | |
| 400 | 400 | err_destroy_direct_rqts: |
| 401 | 401 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 402 | 402 | err_destroy_indirect_rqts: |
| @@ -412,7 +412,7 @@ static void mlx5i_cleanup_rx(struct mlx5e_priv *priv) · 9 unmodified lines | ||
| 412 | 412 | { |
| 413 | 413 | mlx5i_destroy_flow_steering(priv); |
| 414 | 414 | mlx5e_destroy_direct_tirs(priv, priv->direct_tir); |
| 415 | − mlx5e_destroy_indirect_tirs(priv, true); | |
| 415 | + mlx5e_destroy_indirect_tirs(priv); | |
| 416 | 416 | mlx5e_destroy_direct_rqts(priv, priv->direct_tir); |
| 417 | 417 | mlx5e_destroy_rqt(priv, &priv->indir_rqt); |
| 418 | 418 | mlx5e_close_drop_rq(&priv->drop_rq); |
| @@ -965,6 +965,8 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) · 964 unmodified lines | ||
| 965 | 965 | goto err_cmd_cleanup; |
| 966 | 966 | } |
| 967 | 967 | |
| 968 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP); | |
| 969 | + | |
| 968 | 970 | err = mlx5_core_enable_hca(dev, 0); |
| 969 | 971 | if (err) { |
| 970 | 972 | mlx5_core_err(dev, "enable hca failed\n"); |
| @@ -1026,6 +1028,7 @@ reclaim_boot_pages: · 55 unmodified lines | ||
| 1026 | 1028 | err_disable_hca: |
| 1027 | 1029 | mlx5_core_disable_hca(dev, 0); |
| 1028 | 1030 | err_cmd_cleanup: |
| 1031 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); | |
| 1029 | 1032 | mlx5_cmd_cleanup(dev); |
| 1030 | 1033 | |
| 1031 | 1034 | return err; |
| @@ -1043,6 +1046,7 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) · 11 unmodified lines | ||
| 1043 | 1046 | } |
| 1044 | 1047 | mlx5_reclaim_startup_pages(dev); |
| 1045 | 1048 | mlx5_core_disable_hca(dev, 0); |
| 1049 | + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); | |
| 1046 | 1050 | mlx5_cmd_cleanup(dev); |
| 1047 | 1051 | |
| 1048 | 1052 | return 0; |
| @@ -1191,7 +1195,7 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool boot) · 142 unmodified lines | ||
| 1191 | 1195 | |
| 1192 | 1196 | err = mlx5_function_setup(dev, boot); |
| 1193 | 1197 | if (err) |
| 1194 | − goto out; | |
| 1198 | + goto err_function; | |
| 1195 | 1199 | |
| 1196 | 1200 | if (boot) { |
| 1197 | 1201 | err = mlx5_init_once(dev); |
| @@ -1229,6 +1233,7 @@ err_load: · 31 unmodified lines | ||
| 1229 | 1233 | mlx5_cleanup_once(dev); |
| 1230 | 1234 | function_teardown: |
| 1231 | 1235 | mlx5_function_teardown(dev, boot); |
| 1236 | +err_function: | |
| 1232 | 1237 | dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; |
| 1233 | 1238 | mutex_unlock(&dev->intf_state_mutex); |
| 1234 | 1239 | |
| @@ -3986,6 +3986,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp) · 3985 unmodified lines | ||
| 3986 | 3986 | mlxsw_sp_port_remove(mlxsw_sp, i); |
| 3987 | 3987 | mlxsw_sp_cpu_port_remove(mlxsw_sp); |
| 3988 | 3988 | kfree(mlxsw_sp->ports); |
| 3989 | + mlxsw_sp->ports = NULL; | |
| 3989 | 3990 | } |
| 3990 | 3991 | |
| 3991 | 3992 | static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) |
| @@ -4022,6 +4023,7 @@ err_port_create: · 30 unmodified lines | ||
| 4022 | 4023 | mlxsw_sp_cpu_port_remove(mlxsw_sp); |
| 4023 | 4024 | err_cpu_port_create: |
| 4024 | 4025 | kfree(mlxsw_sp->ports); |
| 4026 | + mlxsw_sp->ports = NULL; | |
| 4025 | 4027 | return err; |
| 4026 | 4028 | } |
| 4027 | 4029 | |
| @@ -4143,6 +4145,14 @@ static int mlxsw_sp_local_ports_offset(struct mlxsw_core *mlxsw_core, · 115 unmodified lines | ||
| 4143 | 4145 | return mlxsw_core_res_get(mlxsw_core, local_ports_in_x_res_id); |
| 4144 | 4146 | } |
| 4145 | 4147 | |
| 4148 | +static struct mlxsw_sp_port * | |
| 4149 | +mlxsw_sp_port_get_by_local_port(struct mlxsw_sp *mlxsw_sp, u8 local_port) | |
| 4150 | +{ | |
| 4151 | + if (mlxsw_sp->ports && mlxsw_sp->ports[local_port]) | |
| 4152 | + return mlxsw_sp->ports[local_port]; | |
| 4153 | + return NULL; | |
| 4154 | +} | |
| 4155 | + | |
| 4146 | 4156 | static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, |
| 4147 | 4157 | unsigned int count, |
| 4148 | 4158 | struct netlink_ext_ack *extack) |
| @@ -4156,7 +4166,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, · 7 unmodified lines | ||
| 4156 | 4166 | int i; |
| 4157 | 4167 | int err; |
| 4158 | 4168 | |
| 4159 | − mlxsw_sp_port = mlxsw_sp->ports[local_port]; | |
| 4169 | + mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port); | |
| 4160 | 4170 | if (!mlxsw_sp_port) { |
| 4161 | 4171 | dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", |
| 4162 | 4172 | local_port); |
| @@ -4251,7 +4261,7 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port, · 88 unmodified lines | ||
| 4251 | 4261 | int offset; |
| 4252 | 4262 | int i; |
| 4253 | 4263 | |
| 4254 | − mlxsw_sp_port = mlxsw_sp->ports[local_port]; | |
| 4264 | + mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port); | |
| 4255 | 4265 | if (!mlxsw_sp_port) { |
| 4256 | 4266 | dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", |
| 4257 | 4267 | local_port); |
| @@ -1259,6 +1259,7 @@ static void mlxsw_sx_ports_remove(struct mlxsw_sx *mlxsw_sx) · 1258 unmodified lines | ||
| 1259 | 1259 | if (mlxsw_sx_port_created(mlxsw_sx, i)) |
| 1260 | 1260 | mlxsw_sx_port_remove(mlxsw_sx, i); |
| 1261 | 1261 | kfree(mlxsw_sx->ports); |
| 1262 | + mlxsw_sx->ports = NULL; | |
| 1262 | 1263 | } |
| 1263 | 1264 | |
| 1264 | 1265 | static int mlxsw_sx_ports_create(struct mlxsw_sx *mlxsw_sx) |
| @@ -1293,6 +1294,7 @@ err_port_module_info_get: · 28 unmodified lines | ||
| 1293 | 1294 | if (mlxsw_sx_port_created(mlxsw_sx, i)) |
| 1294 | 1295 | mlxsw_sx_port_remove(mlxsw_sx, i); |
| 1295 | 1296 | kfree(mlxsw_sx->ports); |
| 1297 | + mlxsw_sx->ports = NULL; | |
| 1296 | 1298 | return err; |
| 1297 | 1299 | } |
| 1298 | 1300 | |
| @@ -1376,6 +1378,12 @@ static int mlxsw_sx_port_type_set(struct mlxsw_core *mlxsw_core, u8 local_port, · 77 unmodified lines | ||
| 1376 | 1378 | u8 module, width; |
| 1377 | 1379 | int err; |
| 1378 | 1380 | |
| 1381 | + if (!mlxsw_sx->ports || !mlxsw_sx->ports[local_port]) { | |
| 1382 | + dev_err(mlxsw_sx->bus_info->dev, "Port number \"%d\" does not exist\n", | |
| 1383 | + local_port); | |
| 1384 | + return -EINVAL; | |
| 1385 | + } | |
| 1386 | + | |
| 1379 | 1387 | if (new_type == DEVLINK_PORT_TYPE_AUTO) |
| 1380 | 1388 | return -EOPNOTSUPP; |
| 1381 | 1389 | |
| @@ -1070,7 +1070,7 @@ static int encx24j600_spi_probe(struct spi_device *spi) · 1069 unmodified lines | ||
| 1070 | 1070 | if (unlikely(ret)) { |
| 1071 | 1071 | netif_err(priv, probe, ndev, "Error %d initializing card encx24j600 card\n", |
| 1072 | 1072 | ret); |
| 1073 | − goto out_free; | |
| 1073 | + goto out_stop; | |
| 1074 | 1074 | } |
| 1075 | 1075 | |
| 1076 | 1076 | eidled = encx24j600_read_reg(priv, EIDLED); |
| @@ -1088,6 +1088,8 @@ static int encx24j600_spi_probe(struct spi_device *spi) · 11 unmodified lines | ||
| 1088 | 1088 | |
| 1089 | 1089 | out_unregister: |
| 1090 | 1090 | unregister_netdev(priv->ndev); |
| 1091 | +out_stop: | |
| 1092 | + kthread_stop(priv->kworker_task); | |
| 1091 | 1093 | out_free: |
| 1092 | 1094 | free_netdev(ndev); |
| 1093 | 1095 | |
| @@ -1100,6 +1102,7 @@ static int encx24j600_spi_remove(struct spi_device *spi) · 6 unmodified lines | ||
| 1100 | 1102 | struct encx24j600_priv *priv = dev_get_drvdata(&spi->dev); |
| 1101 | 1103 | |
| 1102 | 1104 | unregister_netdev(priv->ndev); |
| 1105 | + kthread_stop(priv->kworker_task); | |
| 1103 | 1106 | |
| 1104 | 1107 | free_netdev(priv->ndev); |
| 1105 | 1108 | |
| @@ -1467,7 +1467,7 @@ static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port, · 1466 unmodified lines | ||
| 1467 | 1467 | unsigned long ageing_clock_t) |
| 1468 | 1468 | { |
| 1469 | 1469 | unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t); |
| 1470 | − u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000; | |
| 1470 | + u32 ageing_time = jiffies_to_msecs(ageing_jiffies); | |
| 1471 | 1471 | |
| 1472 | 1472 | ocelot_set_ageing_time(ocelot, ageing_time); |
| 1473 | 1473 | } |
| @@ -333,8 +333,10 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) · 332 unmodified lines | ||
| 333 | 333 | goto err_free_alink; |
| 334 | 334 | |
| 335 | 335 | alink->prio_map = kzalloc(abm->prio_map_len, GFP_KERNEL); |
| 336 | − if (!alink->prio_map) | |
| 336 | + if (!alink->prio_map) { | |
| 337 | + err = -ENOMEM; | |
| 337 | 338 | goto err_free_alink; |
| 339 | + } | |
| 338 | 340 | |
| 339 | 341 | /* This is a multi-host app, make sure MAC/PHY is up, but don't |
| 340 | 342 | * make the MAC/PHY state follow the state of any of the ports. |
| @@ -2118,6 +2118,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) · 2117 unmodified lines | ||
| 2118 | 2118 | dev_info(ionic->dev, "FW Up: restarting LIFs\n"); |
| 2119 | 2119 | |
| 2120 | 2120 | ionic_init_devinfo(ionic); |
| 2121 | + ionic_port_init(ionic); | |
| 2121 | 2122 | err = ionic_qcqs_alloc(lif); |
| 2122 | 2123 | if (err) |
| 2123 | 2124 | goto err_out; |
| @@ -2348,7 +2349,17 @@ static int ionic_station_set(struct ionic_lif *lif) · 224 unmodified lines | ||
| 2348 | 2349 | if (is_zero_ether_addr(ctx.comp.lif_getattr.mac)) |
| 2349 | 2350 | return 0; |
| 2350 | 2351 | |
| 2351 | − if (!ether_addr_equal(ctx.comp.lif_getattr.mac, netdev->dev_addr)) { | |
| 2352 | + if (!is_zero_ether_addr(netdev->dev_addr)) { | |
| 2353 | + /* If the netdev mac is non-zero and doesn't match the default | |
| 2354 | + * device address, it was set by something earlier and we're | |
| 2355 | + * likely here again after a fw-upgrade reset. We need to be | |
| 2356 | + * sure the netdev mac is in our filter list. | |
| 2357 | + */ | |
| 2358 | + if (!ether_addr_equal(ctx.comp.lif_getattr.mac, | |
| 2359 | + netdev->dev_addr)) | |
| 2360 | + ionic_lif_addr(lif, netdev->dev_addr, true); | |
| 2361 | + } else { | |
| 2362 | + /* Update the netdev mac with the device's mac */ | |
| 2352 | 2363 | memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); |
| 2353 | 2364 | addr.sa_family = AF_INET; |
| 2354 | 2365 | err = eth_prepare_mac_addr_change(netdev, &addr); |
| @@ -2358,12 +2369,6 @@ static int ionic_station_set(struct ionic_lif *lif) · 3 unmodified lines | ||
| 2358 | 2369 | return 0; |
| 2359 | 2370 | } |
| 2360 | 2371 | |
| 2361 | − if (!is_zero_ether_addr(netdev->dev_addr)) { | |
| 2362 | − netdev_dbg(lif->netdev, "deleting station MAC addr %pM\n", | |
| 2363 | − netdev->dev_addr); | |
| 2364 | − ionic_lif_addr(lif, netdev->dev_addr, false); | |
| 2365 | − } | |
| 2366 | − | |
| 2367 | 2372 | eth_commit_mac_addr_change(netdev, &addr); |
| 2368 | 2373 | } |
| 2369 | 2374 | |
| @@ -509,16 +509,16 @@ int ionic_port_init(struct ionic *ionic) · 508 unmodified lines | ||
| 509 | 509 | size_t sz; |
| 510 | 510 | int err; |
| 511 | 511 | |
| 512 | − if (idev->port_info) | |
| 513 | − return 0; | |
| 514 | − | |
| 515 | − idev->port_info_sz = ALIGN(sizeof(*idev->port_info), PAGE_SIZE); | |
| 516 | − idev->port_info = dma_alloc_coherent(ionic->dev, idev->port_info_sz, | |
| 517 | − &idev->port_info_pa, | |
| 518 | − GFP_KERNEL); | |
| 519 | 512 | if (!idev->port_info) { |
| 520 | − dev_err(ionic->dev, "Failed to allocate port info, aborting\n"); | |
| 521 | − return -ENOMEM; | |
| 513 | + idev->port_info_sz = ALIGN(sizeof(*idev->port_info), PAGE_SIZE); | |
| 514 | + idev->port_info = dma_alloc_coherent(ionic->dev, | |
| 515 | + idev->port_info_sz, | |
| 516 | + &idev->port_info_pa, | |
| 517 | + GFP_KERNEL); | |
| 518 | + if (!idev->port_info) { | |
| 519 | + dev_err(ionic->dev, "Failed to allocate port info\n"); | |
| 520 | + return -ENOMEM; | |
| 521 | + } | |
| 522 | 522 | } |
| 523 | 523 | |
| 524 | 524 | sz = min(sizeof(ident->port.config), sizeof(idev->dev_cmd_regs->data)); |
| @@ -1050,6 +1050,13 @@ static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) · 1049 unmodified lines | ||
| 1050 | 1050 | RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; |
| 1051 | 1051 | } |
| 1052 | 1052 | |
| 1053 | +static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) | |
| 1054 | +{ | |
| 1055 | + /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ | |
| 1056 | + if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) | |
| 1057 | + *cmd |= 0x7f0 << 18; | |
| 1058 | +} | |
| 1059 | + | |
| 1053 | 1060 | DECLARE_RTL_COND(rtl_eriar_cond) |
| 1054 | 1061 | { |
| 1055 | 1062 | return RTL_R32(tp, ERIAR) & ERIAR_FLAG; |
| @@ -1058,9 +1065,12 @@ DECLARE_RTL_COND(rtl_eriar_cond) · 2 unmodified lines | ||
| 1058 | 1065 | static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, |
| 1059 | 1066 | u32 val, int type) |
| 1060 | 1067 | { |
| 1068 | + u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; | |
| 1069 | + | |
| 1061 | 1070 | BUG_ON((addr & 3) || (mask == 0)); |
| 1062 | 1071 | RTL_W32(tp, ERIDR, val); |
| 1063 | − RTL_W32(tp, ERIAR, ERIAR_WRITE_CMD | type | mask | addr); | |
| 1072 | + r8168fp_adjust_ocp_cmd(tp, &cmd, type); | |
| 1073 | + RTL_W32(tp, ERIAR, cmd); | |
| 1064 | 1074 | |
| 1065 | 1075 | rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); |
| 1066 | 1076 | } |
| @@ -1073,7 +1083,10 @@ static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, · 6 unmodified lines | ||
| 1073 | 1083 | |
| 1074 | 1084 | static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) |
| 1075 | 1085 | { |
| 1076 | − RTL_W32(tp, ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); | |
| 1086 | + u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; | |
| 1087 | + | |
| 1088 | + r8168fp_adjust_ocp_cmd(tp, &cmd, type); | |
| 1089 | + RTL_W32(tp, ERIAR, cmd); | |
| 1077 | 1090 | |
| 1078 | 1091 | return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? |
| 1079 | 1092 | RTL_R32(tp, ERIDR) : ~0; |
| @@ -2127,6 +2140,8 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) · 1047 unmodified lines | ||
| 2127 | 2140 | { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, |
| 2128 | 2141 | { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, |
| 2129 | 2142 | { 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 }, |
| 2143 | + /* RTL8401, reportedly works if treated as RTL8101e */ | |
| 2144 | + { 0x7cf, 0x240, RTL_GIGA_MAC_VER_13 }, | |
| 2130 | 2145 | { 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 }, |
| 2131 | 2146 | { 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 }, |
| 2132 | 2147 | { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, |
| @@ -848,14 +848,14 @@ static int ioc3eth_probe(struct platform_device *pdev) · 847 unmodified lines | ||
| 848 | 848 | ip = netdev_priv(dev); |
| 849 | 849 | ip->dma_dev = pdev->dev.parent; |
| 850 | 850 | ip->regs = devm_platform_ioremap_resource(pdev, 0); |
| 851 | − if (!ip->regs) { | |
| 852 | − err = -ENOMEM; | |
| 851 | + if (IS_ERR(ip->regs)) { | |
| 852 | + err = PTR_ERR(ip->regs); | |
| 853 | 853 | goto out_free; |
| 854 | 854 | } |
| 855 | 855 | |
| 856 | 856 | ip->ssram = devm_platform_ioremap_resource(pdev, 1); |
| 857 | − if (!ip->ssram) { | |
| 858 | − err = -ENOMEM; | |
| 857 | + if (IS_ERR(ip->ssram)) { | |
| 858 | + err = PTR_ERR(ip->ssram); | |
| 859 | 859 | goto out_free; |
| 860 | 860 | } |
| 861 | 861 | |
| @@ -2493,20 +2493,20 @@ static int smsc911x_drv_probe(struct platform_device *pdev) · 2492 unmodified lines | ||
| 2493 | 2493 | |
| 2494 | 2494 | retval = smsc911x_init(dev); |
| 2495 | 2495 | if (retval < 0) |
| 2496 | − goto out_disable_resources; | |
| 2496 | + goto out_init_fail; | |
| 2497 | 2497 | |
| 2498 | 2498 | netif_carrier_off(dev); |
| 2499 | 2499 | |
| 2500 | 2500 | retval = smsc911x_mii_init(pdev, dev); |
| 2501 | 2501 | if (retval) { |
| 2502 | 2502 | SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); |
| 2503 | − goto out_disable_resources; | |
| 2503 | + goto out_init_fail; | |
| 2504 | 2504 | } |
| 2505 | 2505 | |
| 2506 | 2506 | retval = register_netdev(dev); |
| 2507 | 2507 | if (retval) { |
| 2508 | 2508 | SMSC_WARN(pdata, probe, "Error %i registering device", retval); |
| 2509 | − goto out_disable_resources; | |
| 2509 | + goto out_init_fail; | |
| 2510 | 2510 | } else { |
| 2511 | 2511 | SMSC_TRACE(pdata, probe, |
| 2512 | 2512 | "Network interface: \"%s\"", dev->name); |
| @@ -2547,9 +2547,10 @@ static int smsc911x_drv_probe(struct platform_device *pdev) · 34 unmodified lines | ||
| 2547 | 2547 | |
| 2548 | 2548 | return 0; |
| 2549 | 2549 | |
| 2550 | −out_disable_resources: | |
| 2550 | +out_init_fail: | |
| 2551 | 2551 | pm_runtime_put(&pdev->dev); |
| 2552 | 2552 | pm_runtime_disable(&pdev->dev); |
| 2553 | +out_disable_resources: | |
| 2553 | 2554 | (void)smsc911x_disable_resources(pdev); |
| 2554 | 2555 | out_enable_resources_fail: |
| 2555 | 2556 | smsc911x_free_resources(pdev); |
| @@ -319,6 +319,19 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) · 318 unmodified lines | ||
| 319 | 319 | /* Enable PTP clock */ |
| 320 | 320 | regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); |
| 321 | 321 | val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id); |
| 322 | + switch (gmac->phy_mode) { | |
| 323 | + case PHY_INTERFACE_MODE_RGMII: | |
| 324 | + val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) | | |
| 325 | + NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id); | |
| 326 | + break; | |
| 327 | + case PHY_INTERFACE_MODE_SGMII: | |
| 328 | + val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) | | |
| 329 | + NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id); | |
| 330 | + break; | |
| 331 | + default: | |
| 332 | + /* We don't get here; the switch above will have errored out */ | |
| 333 | + unreachable(); | |
| 334 | + } | |
| 322 | 335 | regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); |
| 323 | 336 | |
| 324 | 337 | if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) { |
| @@ -75,6 +75,11 @@ struct ethqos_emac_por { · 74 unmodified lines | ||
| 75 | 75 | unsigned int value; |
| 76 | 76 | }; |
| 77 | 77 | |
| 78 | +struct ethqos_emac_driver_data { | |
| 79 | + const struct ethqos_emac_por *por; | |
| 80 | + unsigned int num_por; | |
| 81 | +}; | |
| 82 | + | |
| 78 | 83 | struct qcom_ethqos { |
| 79 | 84 | struct platform_device *pdev; |
| 80 | 85 | void __iomem *rgmii_base; |
| @@ -171,6 +176,11 @@ static const struct ethqos_emac_por emac_v2_3_0_por[] = { · 90 unmodified lines | ||
| 171 | 176 | { .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 }, |
| 172 | 177 | }; |
| 173 | 178 | |
| 179 | +static const struct ethqos_emac_driver_data emac_v2_3_0_data = { | |
| 180 | + .por = emac_v2_3_0_por, | |
| 181 | + .num_por = ARRAY_SIZE(emac_v2_3_0_por), | |
| 182 | +}; | |
| 183 | + | |
| 174 | 184 | static int ethqos_dll_configure(struct qcom_ethqos *ethqos) |
| 175 | 185 | { |
| 176 | 186 | unsigned int val; |
| @@ -442,6 +452,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) · 265 unmodified lines | ||
| 442 | 452 | struct device_node *np = pdev->dev.of_node; |
| 443 | 453 | struct plat_stmmacenet_data *plat_dat; |
| 444 | 454 | struct stmmac_resources stmmac_res; |
| 455 | + const struct ethqos_emac_driver_data *data; | |
| 445 | 456 | struct qcom_ethqos *ethqos; |
| 446 | 457 | struct resource *res; |
| 447 | 458 | int ret; |
| @@ -471,7 +482,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev) · 23 unmodified lines | ||
| 471 | 482 | goto err_mem; |
| 472 | 483 | } |
| 473 | 484 | |
| 474 | − ethqos->por = of_device_get_match_data(&pdev->dev); | |
| 485 | + data = of_device_get_match_data(&pdev->dev); | |
| 486 | + ethqos->por = data->por; | |
| 487 | + ethqos->num_por = data->num_por; | |
| 475 | 488 | |
| 476 | 489 | ethqos->rgmii_clk = devm_clk_get(&pdev->dev, "rgmii"); |
| 477 | 490 | if (IS_ERR(ethqos->rgmii_clk)) { |
| @@ -526,7 +539,7 @@ static int qcom_ethqos_remove(struct platform_device *pdev) · 48 unmodified lines | ||
| 526 | 539 | } |
| 527 | 540 | |
| 528 | 541 | static const struct of_device_id qcom_ethqos_match[] = { |
| 529 | − { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_por}, | |
| 542 | + { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data}, | |
| 530 | 543 | { } |
| 531 | 544 | }; |
| 532 | 545 | MODULE_DEVICE_TABLE(of, qcom_ethqos_match); |
| @@ -5190,8 +5190,6 @@ int stmmac_resume(struct device *dev) · 5189 unmodified lines | ||
| 5190 | 5190 | return ret; |
| 5191 | 5191 | } |
| 5192 | 5192 | |
| 5193 | − netif_device_attach(ndev); | |
| 5194 | − | |
| 5195 | 5193 | mutex_lock(&priv->lock); |
| 5196 | 5194 | |
| 5197 | 5195 | stmmac_reset_queues_param(priv); |
| @@ -5218,6 +5216,8 @@ int stmmac_resume(struct device *dev) · 20 unmodified lines | ||
| 5218 | 5216 | |
| 5219 | 5217 | phylink_mac_change(priv->phylink, true); |
| 5220 | 5218 | |
| 5219 | + netif_device_attach(ndev); | |
| 5220 | + | |
| 5221 | 5221 | return 0; |
| 5222 | 5222 | } |
| 5223 | 5223 | EXPORT_SYMBOL_GPL(stmmac_resume); |
| @@ -4963,7 +4963,7 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 4962 unmodified lines | ||
| 4963 | 4963 | cas_cacheline_size)) { |
| 4964 | 4964 | dev_err(&pdev->dev, "Could not set PCI cache " |
| 4965 | 4965 | "line size\n"); |
| 4966 | − goto err_write_cacheline; | |
| 4966 | + goto err_out_free_res; | |
| 4967 | 4967 | } |
| 4968 | 4968 | } |
| 4969 | 4969 | #endif |
| @@ -5136,7 +5136,6 @@ err_out_iounmap: · 166 unmodified lines | ||
| 5136 | 5136 | err_out_free_res: |
| 5137 | 5137 | pci_release_regions(pdev); |
| 5138 | 5138 | |
| 5139 | −err_write_cacheline: | |
| 5140 | 5139 | /* Try to restore it in case the error occurred after we |
| 5141 | 5140 | * set it. |
| 5142 | 5141 | */ |
| @@ -49,6 +49,7 @@ config TI_CPSW_PHY_SEL · 48 unmodified lines | ||
| 49 | 49 | config TI_CPSW |
| 50 | 50 | tristate "TI CPSW Switch Support" |
| 51 | 51 | depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST |
| 52 | + depends on TI_CPTS || !TI_CPTS | |
| 52 | 53 | select TI_DAVINCI_MDIO |
| 53 | 54 | select MFD_SYSCON |
| 54 | 55 | select PAGE_POOL |
| @@ -64,6 +65,7 @@ config TI_CPSW_SWITCHDEV · 9 unmodified lines | ||
| 64 | 65 | tristate "TI CPSW Switch Support with switchdev" |
| 65 | 66 | depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST |
| 66 | 67 | depends on NET_SWITCHDEV |
| 68 | + depends on TI_CPTS || !TI_CPTS | |
| 67 | 69 | select PAGE_POOL |
| 68 | 70 | select TI_DAVINCI_MDIO |
| 69 | 71 | select MFD_SYSCON |
| @@ -77,23 +79,16 @@ config TI_CPSW_SWITCHDEV · 7 unmodified lines | ||
| 77 | 79 | will be called cpsw_new. |
| 78 | 80 | |
| 79 | 81 | config TI_CPTS |
| 80 | − bool "TI Common Platform Time Sync (CPTS) Support" | |
| 81 | − depends on TI_CPSW || TI_KEYSTONE_NETCP || TI_CPSW_SWITCHDEV || COMPILE_TEST | |
| 82 | + tristate "TI Common Platform Time Sync (CPTS) Support" | |
| 83 | + depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST | |
| 82 | 84 | depends on COMMON_CLK |
| 83 | − depends on POSIX_TIMERS | |
| 85 | + depends on PTP_1588_CLOCK | |
| 84 | 86 | ---help--- |
| 85 | 87 | This driver supports the Common Platform Time Sync unit of |
| 86 | 88 | the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem. |
| 87 | 89 | The unit can time stamp PTP UDP/IPv4 and Layer 2 packets, and the |
| 88 | 90 | driver offers a PTP Hardware Clock. |
| 89 | 91 | |
| 90 | −config TI_CPTS_MOD | |
| 91 | − tristate | |
| 92 | − depends on TI_CPTS | |
| 93 | − depends on PTP_1588_CLOCK | |
| 94 | − default y if TI_CPSW=y || TI_KEYSTONE_NETCP=y || TI_CPSW_SWITCHDEV=y | |
| 95 | − default m | |
| 96 | − | |
| 97 | 92 | config TI_K3_AM65_CPSW_NUSS |
| 98 | 93 | tristate "TI K3 AM654x/J721E CPSW Ethernet driver" |
| 99 | 94 | depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER |
| @@ -114,6 +109,7 @@ config TI_KEYSTONE_NETCP · 14 unmodified lines | ||
| 114 | 109 | select TI_DAVINCI_MDIO |
| 115 | 110 | depends on OF |
| 116 | 111 | depends on KEYSTONE_NAVIGATOR_DMA && KEYSTONE_NAVIGATOR_QMSS |
| 112 | + depends on TI_CPTS || !TI_CPTS | |
| 117 | 113 | ---help--- |
| 118 | 114 | This driver supports TI's Keystone NETCP Core. |
| 119 | 115 | |
| @@ -13,7 +13,7 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += ti_davinci_emac.o · 12 unmodified lines | ||
| 13 | 13 | ti_davinci_emac-y := davinci_emac.o davinci_cpdma.o |
| 14 | 14 | obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o |
| 15 | 15 | obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o |
| 16 | −obj-$(CONFIG_TI_CPTS_MOD) += cpts.o | |
| 16 | +obj-$(CONFIG_TI_CPTS) += cpts.o | |
| 17 | 17 | obj-$(CONFIG_TI_CPSW) += ti_cpsw.o |
| 18 | 18 | ti_cpsw-y := cpsw.o davinci_cpdma.o cpsw_ale.o cpsw_priv.o cpsw_sl.o cpsw_ethtool.o |
| 19 | 19 | obj-$(CONFIG_TI_CPSW_SWITCHDEV) += ti_cpsw_new.o |
| @@ -1895,8 +1895,9 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) · 1894 unmodified lines | ||
| 1895 | 1895 | ale_params.nu_switch_ale = true; |
| 1896 | 1896 | |
| 1897 | 1897 | common->ale = cpsw_ale_create(&ale_params); |
| 1898 | − if (!common->ale) { | |
| 1898 | + if (IS_ERR(common->ale)) { | |
| 1899 | 1899 | dev_err(dev, "error initializing ale engine\n"); |
| 1900 | + ret = PTR_ERR(common->ale); | |
| 1900 | 1901 | goto err_of_clear; |
| 1901 | 1902 | } |
| 1902 | 1903 | |
| @@ -1753,11 +1753,15 @@ static int cpsw_suspend(struct device *dev) · 1752 unmodified lines | ||
| 1753 | 1753 | struct cpsw_common *cpsw = dev_get_drvdata(dev); |
| 1754 | 1754 | int i; |
| 1755 | 1755 | |
| 1756 | + rtnl_lock(); | |
| 1757 | + | |
| 1756 | 1758 | for (i = 0; i < cpsw->data.slaves; i++) |
| 1757 | 1759 | if (cpsw->slaves[i].ndev) |
| 1758 | 1760 | if (netif_running(cpsw->slaves[i].ndev)) |
| 1759 | 1761 | cpsw_ndo_stop(cpsw->slaves[i].ndev); |
| 1760 | 1762 | |
| 1763 | + rtnl_unlock(); | |
| 1764 | + | |
| 1761 | 1765 | /* Select sleep pin state */ |
| 1762 | 1766 | pinctrl_pm_select_sleep_state(dev); |
| 1763 | 1767 | |
| @@ -955,7 +955,7 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) · 954 unmodified lines | ||
| 955 | 955 | |
| 956 | 956 | ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); |
| 957 | 957 | if (!ale) |
| 958 | − return NULL; | |
| 958 | + return ERR_PTR(-ENOMEM); | |
| 959 | 959 | |
| 960 | 960 | ale->p0_untag_vid_mask = |
| 961 | 961 | devm_kmalloc_array(params->dev, BITS_TO_LONGS(VLAN_N_VID), |
| @@ -490,9 +490,9 @@ int cpsw_init_common(struct cpsw_common *cpsw, void __iomem *ss_regs, · 489 unmodified lines | ||
| 490 | 490 | ale_params.ale_ports = CPSW_ALE_PORTS_NUM; |
| 491 | 491 | |
| 492 | 492 | cpsw->ale = cpsw_ale_create(&ale_params); |
| 493 | − if (!cpsw->ale) { | |
| 493 | + if (IS_ERR(cpsw->ale)) { | |
| 494 | 494 | dev_err(dev, "error initializing ale engine\n"); |
| 495 | − return -ENODEV; | |
| 495 | + return PTR_ERR(cpsw->ale); | |
| 496 | 496 | } |
| 497 | 497 | |
| 498 | 498 | dma_params.dev = dev; |
| @@ -3704,9 +3704,9 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, · 3703 unmodified lines | ||
| 3704 | 3704 | ale_params.nu_switch_ale = true; |
| 3705 | 3705 | } |
| 3706 | 3706 | gbe_dev->ale = cpsw_ale_create(&ale_params); |
| 3707 | − if (!gbe_dev->ale) { | |
| 3707 | + if (IS_ERR(gbe_dev->ale)) { | |
| 3708 | 3708 | dev_err(gbe_dev->dev, "error initializing ale engine\n"); |
| 3709 | − ret = -ENODEV; | |
| 3709 | + ret = PTR_ERR(gbe_dev->ale); | |
| 3710 | 3710 | goto free_sec_ports; |
| 3711 | 3711 | } else { |
| 3712 | 3712 | dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); |
| @@ -127,7 +127,8 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev) · 126 unmodified lines | ||
| 127 | 127 | { |
| 128 | 128 | struct bpqdev *bpq; |
| 129 | 129 | |
| 130 | − list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) { | |
| 130 | + list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list, | |
| 131 | + lockdep_rtnl_is_held()) { | |
| 131 | 132 | if (bpq->ethdev == dev) |
| 132 | 133 | return bpq->axdev; |
| 133 | 134 | } |
| @@ -1392,6 +1392,7 @@ static int gsi_channel_poll(struct napi_struct *napi, int budget) · 1391 unmodified lines | ||
| 1392 | 1392 | while (count < budget) { |
| 1393 | 1393 | struct gsi_trans *trans; |
| 1394 | 1394 | |
| 1395 | + count++; | |
| 1395 | 1396 | trans = gsi_channel_poll_one(channel); |
| 1396 | 1397 | if (!trans) |
| 1397 | 1398 | break; |
| @@ -399,13 +399,14 @@ void gsi_trans_cmd_add(struct gsi_trans *trans, void *buf, u32 size, · 398 unmodified lines | ||
| 399 | 399 | /* assert(which < trans->tre_count); */ |
| 400 | 400 | |
| 401 | 401 | /* Set the page information for the buffer. We also need to fill in |
| 402 | − * the DMA address for the buffer (something dma_map_sg() normally | |
| 403 | − * does). | |
| 402 | + * the DMA address and length for the buffer (something dma_map_sg() | |
| 403 | + * normally does). | |
| 404 | 404 | */ |
| 405 | 405 | sg = &trans->sgl[which]; |
| 406 | 406 | |
| 407 | 407 | sg_set_buf(sg, buf, size); |
| 408 | 408 | sg_dma_address(sg) = addr; |
| 409 | + sg_dma_len(sg) = sg->length; | |
| 409 | 410 | |
| 410 | 411 | info = &trans->info[which]; |
| 411 | 412 | info->opcode = opcode; |
| @@ -628,23 +628,15 @@ static void ipa_cmd_transfer_add(struct gsi_trans *trans, u16 size) · 627 unmodified lines | ||
| 628 | 628 | |
| 629 | 629 | void ipa_cmd_tag_process_add(struct gsi_trans *trans) |
| 630 | 630 | { |
| 631 | − ipa_cmd_register_write_add(trans, 0, 0, 0, true); | |
| 632 | −#if 1 | |
| 633 | − /* Reference these functions to avoid a compile error */ | |
| 634 | − (void)ipa_cmd_ip_packet_init_add; | |
| 635 | − (void)ipa_cmd_ip_tag_status_add; | |
| 636 | − (void) ipa_cmd_transfer_add; | |
| 637 | −#else | |
| 638 | 631 | struct ipa *ipa = container_of(trans->gsi, struct ipa, gsi); |
| 639 | − struct gsi_endpoint *endpoint; | |
| 632 | + struct ipa_endpoint *endpoint; | |
| 640 | 633 | |
| 641 | 634 | endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; |
| 642 | − ipa_cmd_ip_packet_init_add(trans, endpoint->endpoint_id); | |
| 643 | 635 | |
| 636 | + ipa_cmd_register_write_add(trans, 0, 0, 0, true); | |
| 637 | + ipa_cmd_ip_packet_init_add(trans, endpoint->endpoint_id); | |
| 644 | 638 | ipa_cmd_ip_tag_status_add(trans, 0xcba987654321); |
| 645 | − | |
| 646 | 639 | ipa_cmd_transfer_add(trans, 4); |
| 647 | −#endif | |
| 648 | 640 | } |
| 649 | 641 | |
| 650 | 642 | /* Returns the number of commands required for the tag process */ |
| @@ -53,7 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | * @clock_on: Whether IPA clock is on |
| 54 | 54 | * @notified: Whether modem has been notified of clock state |
| 55 | 55 | * @disabled: Whether setup ready interrupt handling is disabled |
| 56 | − * @mutex mutex: Motex protecting ready interrupt/shutdown interlock | |
| 56 | + * @mutex: Mutex protecting ready-interrupt/shutdown interlock | |
| 57 | 57 | * @panic_notifier: Panic notifier structure |
| 58 | 58 | */ |
| 59 | 59 | struct ipa_smp2p { |
| @@ -858,8 +858,7 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink, · 857 unmodified lines | ||
| 858 | 858 | return -EINVAL; |
| 859 | 859 | |
| 860 | 860 | cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1]; |
| 861 | − *p_drops = *cnt; | |
| 862 | − *cnt += jiffies % 64; | |
| 861 | + *p_drops = (*cnt)++; | |
| 863 | 862 | |
| 864 | 863 | return 0; |
| 865 | 864 | } |
| @@ -225,8 +225,12 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) · 224 unmodified lines | ||
| 225 | 225 | else |
| 226 | 226 | val |= BCM54XX_SHD_SCR3_DLLAPD_DIS; |
| 227 | 227 | |
| 228 | − if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) | |
| 229 | − val |= BCM54XX_SHD_SCR3_TRDDAPD; | |
| 228 | + if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) { | |
| 229 | + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) | |
| 230 | + val |= BCM54810_SHD_SCR3_TRDDAPD; | |
| 231 | + else | |
| 232 | + val |= BCM54XX_SHD_SCR3_TRDDAPD; | |
| 233 | + } | |
| 230 | 234 | |
| 231 | 235 | if (orig != val) |
| 232 | 236 | bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val); |
| @@ -354,6 +354,8 @@ struct vsc8531_private { · 353 unmodified lines | ||
| 354 | 354 | u64 *stats; |
| 355 | 355 | int nstats; |
| 356 | 356 | bool pkg_init; |
| 357 | + /* PHY address within the package. */ | |
| 358 | + u8 addr; | |
| 357 | 359 | /* For multiple port PHYs; the MDIO address of the base PHY in the |
| 358 | 360 | * package. |
| 359 | 361 | */ |
| @@ -152,8 +152,8 @@ · 151 unmodified lines | ||
| 152 | 152 | #define MSCC_MAC_PAUSE_CFG_STATE_PAUSE_STATE BIT(0) |
| 153 | 153 | #define MSCC_MAC_PAUSE_CFG_STATE_MAC_TX_PAUSE_GEN BIT(4) |
| 154 | 154 | |
| 155 | −#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL 0x2 | |
| 156 | −#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(x) (x) | |
| 157 | −#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M GENMASK(2, 0) | |
| 155 | +#define MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL 0x2 | |
| 156 | +#define MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(x) (x) | |
| 157 | +#define MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M GENMASK(2, 0) | |
| 158 | 158 | |
| 159 | 159 | #endif /* _MSCC_PHY_LINE_MAC_H_ */ |
| @@ -316,6 +316,8 @@ static void vsc8584_macsec_mac_init(struct phy_device *phydev, · 315 unmodified lines | ||
| 316 | 316 | /* Must be called with mdio_lock taken */ |
| 317 | 317 | static int __vsc8584_macsec_init(struct phy_device *phydev) |
| 318 | 318 | { |
| 319 | + struct vsc8531_private *priv = phydev->priv; | |
| 320 | + enum macsec_bank proc_bank; | |
| 319 | 321 | u32 val; |
| 320 | 322 | |
| 321 | 323 | vsc8584_macsec_block_init(phydev, MACSEC_INGR); |
| @@ -351,12 +353,14 @@ static int __vsc8584_macsec_init(struct phy_device *phydev) · 29 unmodified lines | ||
| 351 | 353 | val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA; |
| 352 | 354 | vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val); |
| 353 | 355 | |
| 354 | − val = vsc8584_macsec_phy_read(phydev, IP_1588, | |
| 355 | − MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL); | |
| 356 | − val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M; | |
| 357 | − val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4); | |
| 358 | − vsc8584_macsec_phy_write(phydev, IP_1588, | |
| 359 | − MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val); | |
| 356 | + proc_bank = (priv->addr < 2) ? PROC_0 : PROC_2; | |
| 357 | + | |
| 358 | + val = vsc8584_macsec_phy_read(phydev, proc_bank, | |
| 359 | + MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL); | |
| 360 | + val &= ~MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M; | |
| 361 | + val |= MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4); | |
| 362 | + vsc8584_macsec_phy_write(phydev, proc_bank, | |
| 363 | + MSCC_PROC_IP_1588_TOP_CFG_STAT_MODE_CTL, val); | |
| 360 | 364 | |
| 361 | 365 | return 0; |
| 362 | 366 | } |
| @@ -64,7 +64,8 @@ enum macsec_bank { · 63 unmodified lines | ||
| 64 | 64 | FC_BUFFER = 0x04, |
| 65 | 65 | HOST_MAC = 0x05, |
| 66 | 66 | LINE_MAC = 0x06, |
| 67 | − IP_1588 = 0x0e, | |
| 67 | + PROC_0 = 0x0e, | |
| 68 | + PROC_2 = 0x0f, | |
| 68 | 69 | MACSEC_INGR = 0x38, |
| 69 | 70 | MACSEC_EGR = 0x3c, |
| 70 | 71 | }; |
| @@ -1347,6 +1347,8 @@ static int vsc8584_config_init(struct phy_device *phydev) · 1346 unmodified lines | ||
| 1347 | 1347 | else |
| 1348 | 1348 | vsc8531->base_addr = phydev->mdio.addr - addr; |
| 1349 | 1349 | |
| 1350 | + vsc8531->addr = addr; | |
| 1351 | + | |
| 1350 | 1352 | /* Some parts of the init sequence are identical for every PHY in the |
| 1351 | 1353 | * package. Some parts are modifying the GPIO register bank which is a |
| 1352 | 1354 | * set of registers that are affecting all PHYs, a few resetting the |
| @@ -1771,6 +1773,8 @@ static int vsc8514_config_init(struct phy_device *phydev) · 418 unmodified lines | ||
| 1771 | 1773 | else |
| 1772 | 1774 | vsc8531->base_addr = phydev->mdio.addr - addr; |
| 1773 | 1775 | |
| 1776 | + vsc8531->addr = addr; | |
| 1777 | + | |
| 1774 | 1778 | /* Some parts of the init sequence are identical for every PHY in the |
| 1775 | 1779 | * package. Some parts are modifying the GPIO register bank which is a |
| 1776 | 1780 | * set of registers that are affecting all PHYs, a few resetting the |
| @@ -1132,9 +1132,11 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) · 1131 unmodified lines | ||
| 1132 | 1132 | /* Restart autonegotiation so the new modes get sent to the |
| 1133 | 1133 | * link partner. |
| 1134 | 1134 | */ |
| 1135 | − ret = phy_restart_aneg(phydev); | |
| 1136 | − if (ret < 0) | |
| 1137 | − return ret; | |
| 1135 | + if (phydev->autoneg == AUTONEG_ENABLE) { | |
| 1136 | + ret = phy_restart_aneg(phydev); | |
| 1137 | + if (ret < 0) | |
| 1138 | + return ret; | |
| 1139 | + } | |
| 1138 | 1140 | } |
| 1139 | 1141 | |
| 1140 | 1142 | return 0; |
| @@ -1233,7 +1233,7 @@ int phy_sfp_probe(struct phy_device *phydev, · 1232 unmodified lines | ||
| 1233 | 1233 | const struct sfp_upstream_ops *ops) |
| 1234 | 1234 | { |
| 1235 | 1235 | struct sfp_bus *bus; |
| 1236 | − int ret; | |
| 1236 | + int ret = 0; | |
| 1237 | 1237 | |
| 1238 | 1238 | if (phydev->mdio.dev.fwnode) { |
| 1239 | 1239 | bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode); |
| @@ -1245,7 +1245,7 @@ int phy_sfp_probe(struct phy_device *phydev, · 5 unmodified lines | ||
| 1245 | 1245 | ret = sfp_bus_add_upstream(bus, phydev, ops); |
| 1246 | 1246 | sfp_bus_put(bus); |
| 1247 | 1247 | } |
| 1248 | − return 0; | |
| 1248 | + return ret; | |
| 1249 | 1249 | } |
| 1250 | 1250 | EXPORT_SYMBOL(phy_sfp_probe); |
| 1251 | 1251 | |
| @@ -490,6 +490,9 @@ static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev, · 489 unmodified lines | ||
| 490 | 490 | if (!skb) |
| 491 | 491 | goto out; |
| 492 | 492 | |
| 493 | + if (skb->pkt_type != PACKET_HOST) | |
| 494 | + goto abort; | |
| 495 | + | |
| 493 | 496 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) |
| 494 | 497 | goto abort; |
| 495 | 498 | |
| @@ -815,14 +815,21 @@ static const struct usb_device_id products[] = { · 814 unmodified lines | ||
| 815 | 815 | .driver_info = 0, |
| 816 | 816 | }, |
| 817 | 817 | |
| 818 | −/* Microsoft Surface 3 dock (based on Realtek RTL8153) */ | |
| 818 | +/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */ | |
| 819 | 819 | { |
| 820 | 820 | USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM, |
| 821 | 821 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
| 822 | 822 | .driver_info = 0, |
| 823 | 823 | }, |
| 824 | 824 | |
| 825 | − /* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ | |
| 825 | +/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */ | |
| 826 | +{ | |
| 827 | + USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM, | |
| 828 | + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | |
| 829 | + .driver_info = 0, | |
| 830 | +}, | |
| 831 | + | |
| 832 | +/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ | |
| 826 | 833 | { |
| 827 | 834 | USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, |
| 828 | 835 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
| @@ -2659,7 +2659,7 @@ static struct hso_device *hso_create_bulk_serial_device( · 2658 unmodified lines | ||
| 2659 | 2659 | if (! |
| 2660 | 2660 | (serial->out_endp = |
| 2661 | 2661 | hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) { |
| 2662 | − dev_err(&interface->dev, "Failed to find BULK IN ep\n"); | |
| 2662 | + dev_err(&interface->dev, "Failed to find BULK OUT ep\n"); | |
| 2663 | 2663 | goto exit2; |
| 2664 | 2664 | } |
| 2665 | 2665 | |
| @@ -6880,6 +6880,7 @@ static const struct usb_device_id rtl8152_table[] = { · 6879 unmodified lines | ||
| 6880 | 6880 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, |
| 6881 | 6881 | {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)}, |
| 6882 | 6882 | {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6)}, |
| 6883 | + {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927)}, | |
| 6883 | 6884 | {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, |
| 6884 | 6885 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, |
| 6885 | 6886 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, |
| @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq, · 1242 unmodified lines | ||
| 1243 | 1243 | break; |
| 1244 | 1244 | } while (rq->vq->num_free); |
| 1245 | 1245 | if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) { |
| 1246 | − u64_stats_update_begin(&rq->stats.syncp); | |
| 1246 | + unsigned long flags; | |
| 1247 | + | |
| 1248 | + flags = u64_stats_update_begin_irqsave(&rq->stats.syncp); | |
| 1247 | 1249 | rq->stats.kicks++; |
| 1248 | − u64_stats_update_end(&rq->stats.syncp); | |
| 1250 | + u64_stats_update_end_irqrestore(&rq->stats.syncp, flags); | |
| 1249 | 1251 | } |
| 1250 | 1252 | |
| 1251 | 1253 | return !oom; |
| @@ -32,7 +32,7 @@ enum cookie_values { · 31 unmodified lines | ||
| 32 | 32 | }; |
| 33 | 33 | |
| 34 | 34 | enum counter_values { |
| 35 | − COUNTER_BITS_TOTAL = 2048, | |
| 35 | + COUNTER_BITS_TOTAL = 8192, | |
| 36 | 36 | COUNTER_REDUNDANT_BITS = BITS_PER_LONG, |
| 37 | 37 | COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS |
| 38 | 38 | }; |
| @@ -104,6 +104,7 @@ static struct noise_keypair *keypair_create(struct wg_peer *peer) · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | if (unlikely(!keypair)) |
| 106 | 106 | return NULL; |
| 107 | + spin_lock_init(&keypair->receiving_counter.lock); | |
| 107 | 108 | keypair->internal_id = atomic64_inc_return(&keypair_counter); |
| 108 | 109 | keypair->entry.type = INDEX_HASHTABLE_KEYPAIR; |
| 109 | 110 | keypair->entry.peer = peer; |
| @@ -358,25 +359,16 @@ out: · 248 unmodified lines | ||
| 358 | 359 | memzero_explicit(output, BLAKE2S_HASH_SIZE + 1); |
| 359 | 360 | } |
| 360 | 361 | |
| 361 | −static void symmetric_key_init(struct noise_symmetric_key *key) | |
| 362 | −{ | |
| 363 | − spin_lock_init(&key->counter.receive.lock); | |
| 364 | − atomic64_set(&key->counter.counter, 0); | |
| 365 | − memset(key->counter.receive.backtrack, 0, | |
| 366 | − sizeof(key->counter.receive.backtrack)); | |
| 367 | − key->birthdate = ktime_get_coarse_boottime_ns(); | |
| 368 | − key->is_valid = true; | |
| 369 | −} | |
| 370 | − | |
| 371 | 362 | static void derive_keys(struct noise_symmetric_key *first_dst, |
| 372 | 363 | struct noise_symmetric_key *second_dst, |
| 373 | 364 | const u8 chaining_key[NOISE_HASH_LEN]) |
| 374 | 365 | { |
| 366 | + u64 birthdate = ktime_get_coarse_boottime_ns(); | |
| 375 | 367 | kdf(first_dst->key, second_dst->key, NULL, NULL, |
| 376 | 368 | NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0, |
| 377 | 369 | chaining_key); |
| 378 | − symmetric_key_init(first_dst); | |
| 379 | − symmetric_key_init(second_dst); | |
| 370 | + first_dst->birthdate = second_dst->birthdate = birthdate; | |
| 371 | + first_dst->is_valid = second_dst->is_valid = true; | |
| 380 | 372 | } |
| 381 | 373 | |
| 382 | 374 | static bool __must_check mix_dh(u8 chaining_key[NOISE_HASH_LEN], |
| @@ -715,6 +707,7 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src, · 332 unmodified lines | ||
| 715 | 707 | u8 e[NOISE_PUBLIC_KEY_LEN]; |
| 716 | 708 | u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN]; |
| 717 | 709 | u8 static_private[NOISE_PUBLIC_KEY_LEN]; |
| 710 | + u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]; | |
| 718 | 711 | |
| 719 | 712 | down_read(&wg->static_identity.lock); |
| 720 | 713 | |
| @@ -733,6 +726,8 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src, · 12 unmodified lines | ||
| 733 | 726 | memcpy(chaining_key, handshake->chaining_key, NOISE_HASH_LEN); |
| 734 | 727 | memcpy(ephemeral_private, handshake->ephemeral_private, |
| 735 | 728 | NOISE_PUBLIC_KEY_LEN); |
| 729 | + memcpy(preshared_key, handshake->preshared_key, | |
| 730 | + NOISE_SYMMETRIC_KEY_LEN); | |
| 736 | 731 | up_read(&handshake->lock); |
| 737 | 732 | |
| 738 | 733 | if (state != HANDSHAKE_CREATED_INITIATION) |
| @@ -750,7 +745,7 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src, · 11 unmodified lines | ||
| 750 | 745 | goto fail; |
| 751 | 746 | |
| 752 | 747 | /* psk */ |
| 753 | − mix_psk(chaining_key, hash, key, handshake->preshared_key); | |
| 748 | + mix_psk(chaining_key, hash, key, preshared_key); | |
| 754 | 749 | |
| 755 | 750 | /* {} */ |
| 756 | 751 | if (!message_decrypt(NULL, src->encrypted_nothing, |
| @@ -783,6 +778,7 @@ out: · 26 unmodified lines | ||
| 783 | 778 | memzero_explicit(chaining_key, NOISE_HASH_LEN); |
| 784 | 779 | memzero_explicit(ephemeral_private, NOISE_PUBLIC_KEY_LEN); |
| 785 | 780 | memzero_explicit(static_private, NOISE_PUBLIC_KEY_LEN); |
| 781 | + memzero_explicit(preshared_key, NOISE_SYMMETRIC_KEY_LEN); | |
| 786 | 782 | up_read(&wg->static_identity.lock); |
| 787 | 783 | return ret_peer; |
| 788 | 784 | } |
| @@ -15,18 +15,14 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/mutex.h> |
| 16 | 16 | #include <linux/kref.h> |
| 17 | 17 | |
| 18 | −union noise_counter { | |
| 19 | − struct { | |
| 20 | − u64 counter; | |
| 21 | − unsigned long backtrack[COUNTER_BITS_TOTAL / BITS_PER_LONG]; | |
| 22 | − spinlock_t lock; | |
| 23 | − } receive; | |
| 24 | − atomic64_t counter; | |
| 18 | +struct noise_replay_counter { | |
| 19 | + u64 counter; | |
| 20 | + spinlock_t lock; | |
| 21 | + unsigned long backtrack[COUNTER_BITS_TOTAL / BITS_PER_LONG]; | |
| 25 | 22 | }; |
| 26 | 23 | |
| 27 | 24 | struct noise_symmetric_key { |
| 28 | 25 | u8 key[NOISE_SYMMETRIC_KEY_LEN]; |
| 29 | − union noise_counter counter; | |
| 30 | 26 | u64 birthdate; |
| 31 | 27 | bool is_valid; |
| 32 | 28 | }; |
| @@ -34,7 +30,9 @@ struct noise_symmetric_key { · 1 unmodified line | ||
| 34 | 30 | struct noise_keypair { |
| 35 | 31 | struct index_hashtable_entry entry; |
| 36 | 32 | struct noise_symmetric_key sending; |
| 33 | + atomic64_t sending_counter; | |
| 37 | 34 | struct noise_symmetric_key receiving; |
| 35 | + struct noise_replay_counter receiving_counter; | |
| 38 | 36 | __le32 remote_index; |
| 39 | 37 | bool i_am_the_initiator; |
| 40 | 38 | struct kref refcount; |
| @@ -87,12 +87,20 @@ static inline bool wg_check_packet_protocol(struct sk_buff *skb) · 86 unmodified lines | ||
| 87 | 87 | return real_protocol && skb->protocol == real_protocol; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | −static inline void wg_reset_packet(struct sk_buff *skb) | |
| 90 | +static inline void wg_reset_packet(struct sk_buff *skb, bool encapsulating) | |
| 91 | 91 | { |
| 92 | + u8 l4_hash = skb->l4_hash; | |
| 93 | + u8 sw_hash = skb->sw_hash; | |
| 94 | + u32 hash = skb->hash; | |
| 92 | 95 | skb_scrub_packet(skb, true); |
| 93 | 96 | memset(&skb->headers_start, 0, |
| 94 | 97 | offsetof(struct sk_buff, headers_end) - |
| 95 | 98 | offsetof(struct sk_buff, headers_start)); |
| 99 | + if (encapsulating) { | |
| 100 | + skb->l4_hash = l4_hash; | |
| 101 | + skb->sw_hash = sw_hash; | |
| 102 | + skb->hash = hash; | |
| 103 | + } | |
| 96 | 104 | skb->queue_mapping = 0; |
| 97 | 105 | skb->nohdr = 0; |
| 98 | 106 | skb->peeked = 0; |
| @@ -245,20 +245,20 @@ static void keep_key_fresh(struct wg_peer *peer) · 244 unmodified lines | ||
| 245 | 245 | } |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | −static bool decrypt_packet(struct sk_buff *skb, struct noise_symmetric_key *key) | |
| 248 | +static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) | |
| 249 | 249 | { |
| 250 | 250 | struct scatterlist sg[MAX_SKB_FRAGS + 8]; |
| 251 | 251 | struct sk_buff *trailer; |
| 252 | 252 | unsigned int offset; |
| 253 | 253 | int num_frags; |
| 254 | 254 | |
| 255 | − if (unlikely(!key)) | |
| 255 | + if (unlikely(!keypair)) | |
| 256 | 256 | return false; |
| 257 | 257 | |
| 258 | − if (unlikely(!READ_ONCE(key->is_valid) || | |
| 259 | − wg_birthdate_has_expired(key->birthdate, REJECT_AFTER_TIME) || | |
| 260 | − key->counter.receive.counter >= REJECT_AFTER_MESSAGES)) { | |
| 261 | − WRITE_ONCE(key->is_valid, false); | |
| 258 | + if (unlikely(!READ_ONCE(keypair->receiving.is_valid) || | |
| 259 | + wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) || | |
| 260 | + keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) { | |
| 261 | + WRITE_ONCE(keypair->receiving.is_valid, false); | |
| 262 | 262 | return false; |
| 263 | 263 | } |
| 264 | 264 | |
| @@ -283,7 +283,7 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_symmetric_key *key) · 18 unmodified lines | ||
| 283 | 283 | |
| 284 | 284 | if (!chacha20poly1305_decrypt_sg_inplace(sg, skb->len, NULL, 0, |
| 285 | 285 | PACKET_CB(skb)->nonce, |
| 286 | − key->key)) | |
| 286 | + keypair->receiving.key)) | |
| 287 | 287 | return false; |
| 288 | 288 | |
| 289 | 289 | /* Another ugly situation of pushing and pulling the header so as to |
| @@ -298,41 +298,41 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_symmetric_key *key) · 8 unmodified lines | ||
| 298 | 298 | } |
| 299 | 299 | |
| 300 | 300 | /* This is RFC6479, a replay detection bitmap algorithm that avoids bitshifts */ |
| 301 | −static bool counter_validate(union noise_counter *counter, u64 their_counter) | |
| 301 | +static bool counter_validate(struct noise_replay_counter *counter, u64 their_counter) | |
| 302 | 302 | { |
| 303 | 303 | unsigned long index, index_current, top, i; |
| 304 | 304 | bool ret = false; |
| 305 | 305 | |
| 306 | − spin_lock_bh(&counter->receive.lock); | |
| 306 | + spin_lock_bh(&counter->lock); | |
| 307 | 307 | |
| 308 | − if (unlikely(counter->receive.counter >= REJECT_AFTER_MESSAGES + 1 || | |
| 308 | + if (unlikely(counter->counter >= REJECT_AFTER_MESSAGES + 1 || | |
| 309 | 309 | their_counter >= REJECT_AFTER_MESSAGES)) |
| 310 | 310 | goto out; |
| 311 | 311 | |
| 312 | 312 | ++their_counter; |
| 313 | 313 | |
| 314 | 314 | if (unlikely((COUNTER_WINDOW_SIZE + their_counter) < |
| 315 | − counter->receive.counter)) | |
| 315 | + counter->counter)) | |
| 316 | 316 | goto out; |
| 317 | 317 | |
| 318 | 318 | index = their_counter >> ilog2(BITS_PER_LONG); |
| 319 | 319 | |
| 320 | − if (likely(their_counter > counter->receive.counter)) { | |
| 321 | − index_current = counter->receive.counter >> ilog2(BITS_PER_LONG); | |
| 320 | + if (likely(their_counter > counter->counter)) { | |
| 321 | + index_current = counter->counter >> ilog2(BITS_PER_LONG); | |
| 322 | 322 | top = min_t(unsigned long, index - index_current, |
| 323 | 323 | COUNTER_BITS_TOTAL / BITS_PER_LONG); |
| 324 | 324 | for (i = 1; i <= top; ++i) |
| 325 | − counter->receive.backtrack[(i + index_current) & | |
| 325 | + counter->backtrack[(i + index_current) & | |
| 326 | 326 | ((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0; |
| 327 | − counter->receive.counter = their_counter; | |
| 327 | + counter->counter = their_counter; | |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | 330 | index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1; |
| 331 | 331 | ret = !test_and_set_bit(their_counter & (BITS_PER_LONG - 1), |
| 332 | − &counter->receive.backtrack[index]); | |
| 332 | + &counter->backtrack[index]); | |
| 333 | 333 | |
| 334 | 334 | out: |
| 335 | − spin_unlock_bh(&counter->receive.lock); | |
| 335 | + spin_unlock_bh(&counter->lock); | |
| 336 | 336 | return ret; |
| 337 | 337 | } |
| 338 | 338 | |
| @@ -472,19 +472,19 @@ int wg_packet_rx_poll(struct napi_struct *napi, int budget) · 133 unmodified lines | ||
| 472 | 472 | if (unlikely(state != PACKET_STATE_CRYPTED)) |
| 473 | 473 | goto next; |
| 474 | 474 | |
| 475 | − if (unlikely(!counter_validate(&keypair->receiving.counter, | |
| 475 | + if (unlikely(!counter_validate(&keypair->receiving_counter, | |
| 476 | 476 | PACKET_CB(skb)->nonce))) { |
| 477 | 477 | net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n", |
| 478 | 478 | peer->device->dev->name, |
| 479 | 479 | PACKET_CB(skb)->nonce, |
| 480 | − keypair->receiving.counter.receive.counter); | |
| 480 | + keypair->receiving_counter.counter); | |
| 481 | 481 | goto next; |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | 484 | if (unlikely(wg_socket_endpoint_from_skb(&endpoint, skb))) |
| 485 | 485 | goto next; |
| 486 | 486 | |
| 487 | − wg_reset_packet(skb); | |
| 487 | + wg_reset_packet(skb, false); | |
| 488 | 488 | wg_packet_consume_data_done(peer, skb, &endpoint); |
| 489 | 489 | free = false; |
| 490 | 490 | |
| @@ -511,8 +511,8 @@ void wg_packet_decrypt_worker(struct work_struct *work) · 20 unmodified lines | ||
| 511 | 511 | struct sk_buff *skb; |
| 512 | 512 | |
| 513 | 513 | while ((skb = ptr_ring_consume_bh(&queue->ring)) != NULL) { |
| 514 | − enum packet_state state = likely(decrypt_packet(skb, | |
| 515 | − &PACKET_CB(skb)->keypair->receiving)) ? | |
| 514 | + enum packet_state state = | |
| 515 | + likely(decrypt_packet(skb, PACKET_CB(skb)->keypair)) ? | |
| 516 | 516 | PACKET_STATE_CRYPTED : PACKET_STATE_DEAD; |
| 517 | 517 | wg_queue_enqueue_per_peer_napi(skb, state); |
| 518 | 518 | if (need_resched()) |
| @@ -6,18 +6,24 @@ · 5 unmodified lines | ||
| 6 | 6 | #ifdef DEBUG |
| 7 | 7 | bool __init wg_packet_counter_selftest(void) |
| 8 | 8 | { |
| 9 | + struct noise_replay_counter *counter; | |
| 9 | 10 | unsigned int test_num = 0, i; |
| 10 | − union noise_counter counter; | |
| 11 | 11 | bool success = true; |
| 12 | 12 | |
| 13 | −#define T_INIT do { \ | |
| 14 | − memset(&counter, 0, sizeof(union noise_counter)); \ | |
| 15 | − spin_lock_init(&counter.receive.lock); \ | |
| 13 | + counter = kmalloc(sizeof(*counter), GFP_KERNEL); | |
| 14 | + if (unlikely(!counter)) { | |
| 15 | + pr_err("nonce counter self-test malloc: FAIL\n"); | |
| 16 | + return false; | |
| 17 | + } | |
| 18 | + | |
| 19 | +#define T_INIT do { \ | |
| 20 | + memset(counter, 0, sizeof(*counter)); \ | |
| 21 | + spin_lock_init(&counter->lock); \ | |
| 16 | 22 | } while (0) |
| 17 | 23 | #define T_LIM (COUNTER_WINDOW_SIZE + 1) |
| 18 | 24 | #define T(n, v) do { \ |
| 19 | 25 | ++test_num; \ |
| 20 | − if (counter_validate(&counter, n) != (v)) { \ | |
| 26 | + if (counter_validate(counter, n) != (v)) { \ | |
| 21 | 27 | pr_err("nonce counter self-test %u: FAIL\n", \ |
| 22 | 28 | test_num); \ |
| 23 | 29 | success = false; \ |
| @@ -99,6 +105,7 @@ bool __init wg_packet_counter_selftest(void) · 75 unmodified lines | ||
| 99 | 105 | |
| 100 | 106 | if (success) |
| 101 | 107 | pr_info("nonce counter self-tests: pass\n"); |
| 108 | + kfree(counter); | |
| 102 | 109 | return success; |
| 103 | 110 | } |
| 104 | 111 | #endif |
| @@ -129,7 +129,7 @@ static void keep_key_fresh(struct wg_peer *peer) · 128 unmodified lines | ||
| 129 | 129 | rcu_read_lock_bh(); |
| 130 | 130 | keypair = rcu_dereference_bh(peer->keypairs.current_keypair); |
| 131 | 131 | send = keypair && READ_ONCE(keypair->sending.is_valid) && |
| 132 | − (atomic64_read(&keypair->sending.counter.counter) > REKEY_AFTER_MESSAGES || | |
| 132 | + (atomic64_read(&keypair->sending_counter) > REKEY_AFTER_MESSAGES || | |
| 133 | 133 | (keypair->i_am_the_initiator && |
| 134 | 134 | wg_birthdate_has_expired(keypair->sending.birthdate, REKEY_AFTER_TIME))); |
| 135 | 135 | rcu_read_unlock_bh(); |
| @@ -167,6 +167,11 @@ static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) · 31 unmodified lines | ||
| 167 | 167 | struct sk_buff *trailer; |
| 168 | 168 | int num_frags; |
| 169 | 169 | |
| 170 | + /* Force hash calculation before encryption so that flow analysis is | |
| 171 | + * consistent over the inner packet. | |
| 172 | + */ | |
| 173 | + skb_get_hash(skb); | |
| 174 | + | |
| 170 | 175 | /* Calculate lengths. */ |
| 171 | 176 | padding_len = calculate_skb_padding(skb); |
| 172 | 177 | trailer_len = padding_len + noise_encrypted_len(0); |
| @@ -295,7 +300,7 @@ void wg_packet_encrypt_worker(struct work_struct *work) · 122 unmodified lines | ||
| 295 | 300 | skb_list_walk_safe(first, skb, next) { |
| 296 | 301 | if (likely(encrypt_packet(skb, |
| 297 | 302 | PACKET_CB(first)->keypair))) { |
| 298 | − wg_reset_packet(skb); | |
| 303 | + wg_reset_packet(skb, true); | |
| 299 | 304 | } else { |
| 300 | 305 | state = PACKET_STATE_DEAD; |
| 301 | 306 | break; |
| @@ -344,7 +349,6 @@ void wg_packet_purge_staged_packets(struct wg_peer *peer) · 42 unmodified lines | ||
| 344 | 349 | |
| 345 | 350 | void wg_packet_send_staged_packets(struct wg_peer *peer) |
| 346 | 351 | { |
| 347 | − struct noise_symmetric_key *key; | |
| 348 | 352 | struct noise_keypair *keypair; |
| 349 | 353 | struct sk_buff_head packets; |
| 350 | 354 | struct sk_buff *skb; |
| @@ -364,10 +368,9 @@ void wg_packet_send_staged_packets(struct wg_peer *peer) · 13 unmodified lines | ||
| 364 | 368 | rcu_read_unlock_bh(); |
| 365 | 369 | if (unlikely(!keypair)) |
| 366 | 370 | goto out_nokey; |
| 367 | − key = &keypair->sending; | |
| 368 | − if (unlikely(!READ_ONCE(key->is_valid))) | |
| 371 | + if (unlikely(!READ_ONCE(keypair->sending.is_valid))) | |
| 369 | 372 | goto out_nokey; |
| 370 | − if (unlikely(wg_birthdate_has_expired(key->birthdate, | |
| 373 | + if (unlikely(wg_birthdate_has_expired(keypair->sending.birthdate, | |
| 371 | 374 | REJECT_AFTER_TIME))) |
| 372 | 375 | goto out_invalid; |
| 373 | 376 | |
| @@ -382,7 +385,7 @@ void wg_packet_send_staged_packets(struct wg_peer *peer) · 8 unmodified lines | ||
| 382 | 385 | */ |
| 383 | 386 | PACKET_CB(skb)->ds = ip_tunnel_ecn_encap(0, ip_hdr(skb), skb); |
| 384 | 387 | PACKET_CB(skb)->nonce = |
| 385 | − atomic64_inc_return(&key->counter.counter) - 1; | |
| 388 | + atomic64_inc_return(&keypair->sending_counter) - 1; | |
| 386 | 389 | if (unlikely(PACKET_CB(skb)->nonce >= REJECT_AFTER_MESSAGES)) |
| 387 | 390 | goto out_invalid; |
| 388 | 391 | } |
| @@ -394,7 +397,7 @@ void wg_packet_send_staged_packets(struct wg_peer *peer) · 5 unmodified lines | ||
| 394 | 397 | return; |
| 395 | 398 | |
| 396 | 399 | out_invalid: |
| 397 | − WRITE_ONCE(key->is_valid, false); | |
| 400 | + WRITE_ONCE(keypair->sending.is_valid, false); | |
| 398 | 401 | out_nokey: |
| 399 | 402 | wg_noise_keypair_put(keypair, false); |
| 400 | 403 | |
| @@ -1092,6 +1092,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1091 unmodified lines | ||
| 1092 | 1092 | iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; |
| 1093 | 1093 | else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) |
| 1094 | 1094 | iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; |
| 1095 | + else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) | |
| 1096 | + iwl_trans->cfg = &iwl_ax1650s_cfg_quz_hr; | |
| 1097 | + else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) | |
| 1098 | + iwl_trans->cfg = &iwl_ax1650i_cfg_quz_hr; | |
| 1095 | 1099 | } |
| 1096 | 1100 | |
| 1097 | 1101 | #endif |
| @@ -989,6 +989,11 @@ static inline int nvme_process_cq(struct nvme_queue *nvmeq) · 988 unmodified lines | ||
| 989 | 989 | |
| 990 | 990 | while (nvme_cqe_pending(nvmeq)) { |
| 991 | 991 | found++; |
| 992 | + /* | |
| 993 | + * load-load control dependency between phase and the rest of | |
| 994 | + * the cqe requires a full read memory barrier | |
| 995 | + */ | |
| 996 | + dma_rmb(); | |
| 992 | 997 | nvme_handle_cqe(nvmeq, nvmeq->cq_head); |
| 993 | 998 | nvme_update_cq_head(nvmeq); |
| 994 | 999 | } |
| @@ -1435,7 +1435,7 @@ static const char * const sd2_groups[] = { · 1434 unmodified lines | ||
| 1435 | 1435 | static const char * const i2c0_groups[] = { |
| 1436 | 1436 | "uart0_rx_mfp", |
| 1437 | 1437 | "uart0_tx_mfp", |
| 1438 | − "i2c0_mfp_mfp", | |
| 1438 | + "i2c0_mfp", | |
| 1439 | 1439 | }; |
| 1440 | 1440 | |
| 1441 | 1441 | static const char * const i2c1_groups[] = { |
| @@ -1286,6 +1286,7 @@ static const struct gpio_chip byt_gpio_chip = { · 1285 unmodified lines | ||
| 1286 | 1286 | .direction_output = byt_gpio_direction_output, |
| 1287 | 1287 | .get = byt_gpio_get, |
| 1288 | 1288 | .set = byt_gpio_set, |
| 1289 | + .set_config = gpiochip_generic_config, | |
| 1289 | 1290 | .dbg_show = byt_gpio_dbg_show, |
| 1290 | 1291 | }; |
| 1291 | 1292 | |
| @@ -1479,11 +1479,15 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) · 1478 unmodified lines | ||
| 1479 | 1479 | struct chv_pinctrl *pctrl = gpiochip_get_data(gc); |
| 1480 | 1480 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 1481 | 1481 | unsigned long pending; |
| 1482 | + unsigned long flags; | |
| 1482 | 1483 | u32 intr_line; |
| 1483 | 1484 | |
| 1484 | 1485 | chained_irq_enter(chip, desc); |
| 1485 | 1486 | |
| 1487 | + raw_spin_lock_irqsave(&chv_lock, flags); | |
| 1486 | 1488 | pending = readl(pctrl->regs + CHV_INTSTAT); |
| 1489 | + raw_spin_unlock_irqrestore(&chv_lock, flags); | |
| 1490 | + | |
| 1487 | 1491 | for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { |
| 1488 | 1492 | unsigned int irq, offset; |
| 1489 | 1493 | |
| @@ -15,17 +15,18 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include "pinctrl-intel.h" |
| 17 | 17 | |
| 18 | −#define SPT_PAD_OWN 0x020 | |
| 19 | −#define SPT_PADCFGLOCK 0x0a0 | |
| 20 | −#define SPT_HOSTSW_OWN 0x0d0 | |
| 21 | −#define SPT_GPI_IS 0x100 | |
| 22 | −#define SPT_GPI_IE 0x120 | |
| 18 | +#define SPT_PAD_OWN 0x020 | |
| 19 | +#define SPT_H_PADCFGLOCK 0x090 | |
| 20 | +#define SPT_LP_PADCFGLOCK 0x0a0 | |
| 21 | +#define SPT_HOSTSW_OWN 0x0d0 | |
| 22 | +#define SPT_GPI_IS 0x100 | |
| 23 | +#define SPT_GPI_IE 0x120 | |
| 23 | 24 | |
| 24 | 25 | #define SPT_COMMUNITY(b, s, e) \ |
| 25 | 26 | { \ |
| 26 | 27 | .barno = (b), \ |
| 27 | 28 | .padown_offset = SPT_PAD_OWN, \ |
| 28 | − .padcfglock_offset = SPT_PADCFGLOCK, \ | |
| 29 | + .padcfglock_offset = SPT_LP_PADCFGLOCK, \ | |
| 29 | 30 | .hostown_offset = SPT_HOSTSW_OWN, \ |
| 30 | 31 | .is_offset = SPT_GPI_IS, \ |
| 31 | 32 | .ie_offset = SPT_GPI_IE, \ |
| @@ -47,7 +48,7 @@ · 15 unmodified lines | ||
| 47 | 48 | { \ |
| 48 | 49 | .barno = (b), \ |
| 49 | 50 | .padown_offset = SPT_PAD_OWN, \ |
| 50 | − .padcfglock_offset = SPT_PADCFGLOCK, \ | |
| 51 | + .padcfglock_offset = SPT_H_PADCFGLOCK, \ | |
| 51 | 52 | .hostown_offset = SPT_HOSTSW_OWN, \ |
| 52 | 53 | .is_offset = SPT_GPI_IS, \ |
| 53 | 54 | .ie_offset = SPT_GPI_IE, \ |
| @@ -164,8 +164,6 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, · 163 unmodified lines | ||
| 164 | 164 | case MTK_PIN_CONFIG_PU_ADV: |
| 165 | 165 | case MTK_PIN_CONFIG_PD_ADV: |
| 166 | 166 | if (hw->soc->adv_pull_get) { |
| 167 | − bool pullup; | |
| 168 | − | |
| 169 | 167 | pullup = param == MTK_PIN_CONFIG_PU_ADV; |
| 170 | 168 | err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); |
| 171 | 169 | } else |
| @@ -697,7 +697,7 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl, · 696 unmodified lines | ||
| 697 | 697 | |
| 698 | 698 | pol = msm_readl_intr_cfg(pctrl, g); |
| 699 | 699 | pol ^= BIT(g->intr_polarity_bit); |
| 700 | − msm_writel_intr_cfg(val, pctrl, g); | |
| 700 | + msm_writel_intr_cfg(pol, pctrl, g); | |
| 701 | 701 | |
| 702 | 702 | val2 = msm_readl_io(pctrl, g) & BIT(g->in_bit); |
| 703 | 703 | intstat = msm_readl_intr_status(pctrl, g); |
| @@ -1034,6 +1034,29 @@ static void msm_gpio_irq_relres(struct irq_data *d) · 330 unmodified lines | ||
| 1034 | 1034 | module_put(gc->owner); |
| 1035 | 1035 | } |
| 1036 | 1036 | |
| 1037 | +static int msm_gpio_irq_set_affinity(struct irq_data *d, | |
| 1038 | + const struct cpumask *dest, bool force) | |
| 1039 | +{ | |
| 1040 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 1041 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); | |
| 1042 | + | |
| 1043 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) | |
| 1044 | + return irq_chip_set_affinity_parent(d, dest, force); | |
| 1045 | + | |
| 1046 | + return 0; | |
| 1047 | +} | |
| 1048 | + | |
| 1049 | +static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) | |
| 1050 | +{ | |
| 1051 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 1052 | + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); | |
| 1053 | + | |
| 1054 | + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) | |
| 1055 | + return irq_chip_set_vcpu_affinity_parent(d, vcpu_info); | |
| 1056 | + | |
| 1057 | + return 0; | |
| 1058 | +} | |
| 1059 | + | |
| 1037 | 1060 | static void msm_gpio_irq_handler(struct irq_desc *desc) |
| 1038 | 1061 | { |
| 1039 | 1062 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| @@ -1132,6 +1155,8 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 92 unmodified lines | ||
| 1132 | 1155 | pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake; |
| 1133 | 1156 | pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres; |
| 1134 | 1157 | pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres; |
| 1158 | + pctrl->irq_chip.irq_set_affinity = msm_gpio_irq_set_affinity; | |
| 1159 | + pctrl->irq_chip.irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity; | |
| 1135 | 1160 | |
| 1136 | 1161 | np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0); |
| 1137 | 1162 | if (np) { |
| @@ -877,6 +877,11 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, · 876 unmodified lines | ||
| 877 | 877 | rmcd_error("pinned %ld out of %ld pages", |
| 878 | 878 | pinned, nr_pages); |
| 879 | 879 | ret = -EFAULT; |
| 880 | + /* | |
| 881 | + * Set nr_pages up to mean "how many pages to unpin, in | |
| 882 | + * the error handler: | |
| 883 | + */ | |
| 884 | + nr_pages = pinned; | |
| 880 | 885 | goto err_pg; |
| 881 | 886 | } |
| 882 | 887 | |
| @@ -521,8 +521,10 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 520 unmodified lines | ||
| 521 | 521 | |
| 522 | 522 | ism->smcd = smcd_alloc_dev(&pdev->dev, dev_name(&pdev->dev), &ism_ops, |
| 523 | 523 | ISM_NR_DMBS); |
| 524 | − if (!ism->smcd) | |
| 524 | + if (!ism->smcd) { | |
| 525 | + ret = -ENOMEM; | |
| 525 | 526 | goto err_resource; |
| 527 | + } | |
| 526 | 528 | |
| 527 | 529 | ism->smcd->priv = ism; |
| 528 | 530 | ret = ism_dev_init(ism); |
| @@ -1850,9 +1850,6 @@ qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, · 1849 unmodified lines | ||
| 1850 | 1850 | return -EINVAL; |
| 1851 | 1851 | } |
| 1852 | 1852 | |
| 1853 | − ql_log(ql_log_info, vha, 0x70d6, | |
| 1854 | − "port speed:%d\n", ha->link_data_rate); | |
| 1855 | − | |
| 1856 | 1853 | return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); |
| 1857 | 1854 | } |
| 1858 | 1855 | |
| @@ -80,6 +80,10 @@ static int scsi_dev_type_resume(struct device *dev, · 79 unmodified lines | ||
| 80 | 80 | dev_dbg(dev, "scsi resume: %d\n", err); |
| 81 | 81 | |
| 82 | 82 | if (err == 0) { |
| 83 | + bool was_runtime_suspended; | |
| 84 | + | |
| 85 | + was_runtime_suspended = pm_runtime_suspended(dev); | |
| 86 | + | |
| 83 | 87 | pm_runtime_disable(dev); |
| 84 | 88 | err = pm_runtime_set_active(dev); |
| 85 | 89 | pm_runtime_enable(dev); |
| @@ -93,8 +97,10 @@ static int scsi_dev_type_resume(struct device *dev, · 7 unmodified lines | ||
| 93 | 97 | */ |
| 94 | 98 | if (!err && scsi_is_sdev_device(dev)) { |
| 95 | 99 | struct scsi_device *sdev = to_scsi_device(dev); |
| 96 | − | |
| 97 | − blk_set_runtime_active(sdev->request_queue); | |
| 100 | + if (was_runtime_suspended) | |
| 101 | + blk_post_runtime_resume(sdev->request_queue, 0); | |
| 102 | + else | |
| 103 | + blk_set_runtime_active(sdev->request_queue); | |
| 98 | 104 | } |
| 99 | 105 | } |
| 100 | 106 | |
| @@ -526,9 +526,9 @@ static void gb_tty_set_termios(struct tty_struct *tty, · 525 unmodified lines | ||
| 526 | 526 | } |
| 527 | 527 | |
| 528 | 528 | if (C_CRTSCTS(tty) && C_BAUD(tty) != B0) |
| 529 | − newline.flow_control |= GB_SERIAL_AUTO_RTSCTS_EN; | |
| 529 | + newline.flow_control = GB_SERIAL_AUTO_RTSCTS_EN; | |
| 530 | 530 | else |
| 531 | − newline.flow_control &= ~GB_SERIAL_AUTO_RTSCTS_EN; | |
| 531 | + newline.flow_control = 0; | |
| 532 | 532 | |
| 533 | 533 | if (memcmp(&gb_tty->line_coding, &newline, sizeof(newline))) { |
| 534 | 534 | memcpy(&gb_tty->line_coding, &newline, sizeof(newline)); |
| @@ -130,17 +130,24 @@ static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data) · 129 unmodified lines | ||
| 130 | 130 | static int ad2s1210_config_read(struct ad2s1210_state *st, |
| 131 | 131 | unsigned char address) |
| 132 | 132 | { |
| 133 | − struct spi_transfer xfer = { | |
| 134 | − .len = 2, | |
| 135 | − .rx_buf = st->rx, | |
| 136 | − .tx_buf = st->tx, | |
| 133 | + struct spi_transfer xfers[] = { | |
| 134 | + { | |
| 135 | + .len = 1, | |
| 136 | + .rx_buf = &st->rx[0], | |
| 137 | + .tx_buf = &st->tx[0], | |
| 138 | + .cs_change = 1, | |
| 139 | + }, { | |
| 140 | + .len = 1, | |
| 141 | + .rx_buf = &st->rx[1], | |
| 142 | + .tx_buf = &st->tx[1], | |
| 143 | + }, | |
| 137 | 144 | }; |
| 138 | 145 | int ret = 0; |
| 139 | 146 | |
| 140 | 147 | ad2s1210_set_mode(MOD_CONFIG, st); |
| 141 | 148 | st->tx[0] = address | AD2S1210_MSB_IS_HIGH; |
| 142 | 149 | st->tx[1] = AD2S1210_REG_FAULT; |
| 143 | − ret = spi_sync_transfer(st->sdev, &xfer, 1); | |
| 150 | + ret = spi_sync_transfer(st->sdev, xfers, 2); | |
| 144 | 151 | if (ret < 0) |
| 145 | 152 | return ret; |
| 146 | 153 | |
| @@ -298,7 +298,6 @@ static int kp2000_pcie_probe(struct pci_dev *pdev, · 297 unmodified lines | ||
| 298 | 298 | { |
| 299 | 299 | int err = 0; |
| 300 | 300 | struct kp2000_device *pcard; |
| 301 | − int rv; | |
| 302 | 301 | unsigned long reg_bar_phys_addr; |
| 303 | 302 | unsigned long reg_bar_phys_len; |
| 304 | 303 | unsigned long dma_bar_phys_addr; |
| @@ -445,11 +444,11 @@ static int kp2000_pcie_probe(struct pci_dev *pdev, · 140 unmodified lines | ||
| 445 | 444 | if (err < 0) |
| 446 | 445 | goto err_release_dma; |
| 447 | 446 | |
| 448 | − rv = request_irq(pcard->pdev->irq, kp2000_irq_handler, IRQF_SHARED, | |
| 449 | − pcard->name, pcard); | |
| 450 | − if (rv) { | |
| 447 | + err = request_irq(pcard->pdev->irq, kp2000_irq_handler, IRQF_SHARED, | |
| 448 | + pcard->name, pcard); | |
| 449 | + if (err) { | |
| 451 | 450 | dev_err(&pcard->pdev->dev, |
| 452 | − "%s: failed to request_irq: %d\n", __func__, rv); | |
| 451 | + "%s: failed to request_irq: %d\n", __func__, err); | |
| 453 | 452 | goto err_disable_msi; |
| 454 | 453 | } |
| 455 | 454 | |
| @@ -57,8 +57,10 @@ static int send_scan_req(struct wfx_vif *wvif, · 56 unmodified lines | ||
| 57 | 57 | wvif->scan_abort = false; |
| 58 | 58 | reinit_completion(&wvif->scan_complete); |
| 59 | 59 | timeout = hif_scan(wvif, req, start_idx, i - start_idx); |
| 60 | − if (timeout < 0) | |
| 60 | + if (timeout < 0) { | |
| 61 | + wfx_tx_unlock(wvif->wdev); | |
| 61 | 62 | return timeout; |
| 63 | + } | |
| 62 | 64 | ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); |
| 63 | 65 | if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) |
| 64 | 66 | hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); |
| @@ -3350,6 +3350,7 @@ static void target_tmr_work(struct work_struct *work) · 3349 unmodified lines | ||
| 3350 | 3350 | |
| 3351 | 3351 | cmd->se_tfo->queue_tm_rsp(cmd); |
| 3352 | 3352 | |
| 3353 | + transport_lun_remove_cmd(cmd); | |
| 3353 | 3354 | transport_cmd_check_stop_to_fabric(cmd); |
| 3354 | 3355 | return; |
| 3355 | 3356 | |
| @@ -883,6 +883,7 @@ console_initcall(sifive_console_init); · 882 unmodified lines | ||
| 883 | 883 | |
| 884 | 884 | static void __ssp_add_console_port(struct sifive_serial_port *ssp) |
| 885 | 885 | { |
| 886 | + spin_lock_init(&ssp->port.lock); | |
| 886 | 887 | sifive_serial_console_ports[ssp->port.line] = ssp; |
| 887 | 888 | } |
| 888 | 889 | |
| @@ -82,7 +82,7 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep, · 81 unmodified lines | ||
| 82 | 82 | * @ptr: address of device controller register to be read and changed |
| 83 | 83 | * @mask: bits requested to clar |
| 84 | 84 | */ |
| 85 | −void cdns3_clear_register_bit(void __iomem *ptr, u32 mask) | |
| 85 | +static void cdns3_clear_register_bit(void __iomem *ptr, u32 mask) | |
| 86 | 86 | { |
| 87 | 87 | mask = readl(ptr) & ~mask; |
| 88 | 88 | writel(mask, ptr); |
| @@ -137,7 +137,7 @@ struct usb_request *cdns3_next_request(struct list_head *list) · 48 unmodified lines | ||
| 137 | 137 | * |
| 138 | 138 | * Returns buffer or NULL if no buffers in list |
| 139 | 139 | */ |
| 140 | −struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list) | |
| 140 | +static struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list) | |
| 141 | 141 | { |
| 142 | 142 | return list_first_entry_or_null(list, struct cdns3_aligned_buf, list); |
| 143 | 143 | } |
| @@ -148,7 +148,7 @@ struct cdns3_aligned_buf *cdns3_next_align_buf(struct list_head *list) · 4 unmodified lines | ||
| 148 | 148 | * |
| 149 | 149 | * Returns request or NULL if no requests in list |
| 150 | 150 | */ |
| 151 | −struct cdns3_request *cdns3_next_priv_request(struct list_head *list) | |
| 151 | +static struct cdns3_request *cdns3_next_priv_request(struct list_head *list) | |
| 152 | 152 | { |
| 153 | 153 | return list_first_entry_or_null(list, struct cdns3_request, list); |
| 154 | 154 | } |
| @@ -190,7 +190,7 @@ dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep, · 35 unmodified lines | ||
| 190 | 190 | return priv_ep->trb_pool_dma + offset; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | −int cdns3_ring_size(struct cdns3_endpoint *priv_ep) | |
| 193 | +static int cdns3_ring_size(struct cdns3_endpoint *priv_ep) | |
| 194 | 194 | { |
| 195 | 195 | switch (priv_ep->type) { |
| 196 | 196 | case USB_ENDPOINT_XFER_ISOC: |
| @@ -345,7 +345,7 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep) · 148 unmodified lines | ||
| 345 | 345 | cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); |
| 346 | 346 | } |
| 347 | 347 | |
| 348 | −void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req) | |
| 348 | +static void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req) | |
| 349 | 349 | { |
| 350 | 350 | struct cdns3_endpoint *priv_ep = priv_req->priv_ep; |
| 351 | 351 | int current_trb = priv_req->start_trb; |
| @@ -511,7 +511,7 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep, · 159 unmodified lines | ||
| 511 | 511 | } |
| 512 | 512 | } |
| 513 | 513 | |
| 514 | −struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev, | |
| 514 | +static struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev, | |
| 515 | 515 | struct cdns3_endpoint *priv_ep, |
| 516 | 516 | struct cdns3_request *priv_req) |
| 517 | 517 | { |
| @@ -551,7 +551,7 @@ struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev, · 33 unmodified lines | ||
| 551 | 551 | return &priv_req->request; |
| 552 | 552 | } |
| 553 | 553 | |
| 554 | −int cdns3_wa2_gadget_ep_queue(struct cdns3_device *priv_dev, | |
| 554 | +static int cdns3_wa2_gadget_ep_queue(struct cdns3_device *priv_dev, | |
| 555 | 555 | struct cdns3_endpoint *priv_ep, |
| 556 | 556 | struct cdns3_request *priv_req) |
| 557 | 557 | { |
| @@ -836,7 +836,7 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, · 278 unmodified lines | ||
| 836 | 836 | cdns3_gadget_ep_free_request(&priv_ep->endpoint, request); |
| 837 | 837 | } |
| 838 | 838 | |
| 839 | −void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep) | |
| 839 | +static void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep) | |
| 840 | 840 | { |
| 841 | 841 | /* Work around for stale data address in TRB*/ |
| 842 | 842 | if (priv_ep->wa1_set) { |
| @@ -1904,7 +1904,7 @@ static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev, · 1061 unmodified lines | ||
| 1904 | 1904 | return 0; |
| 1905 | 1905 | } |
| 1906 | 1906 | |
| 1907 | −void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev, | |
| 1907 | +static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev, | |
| 1908 | 1908 | struct cdns3_endpoint *priv_ep) |
| 1909 | 1909 | { |
| 1910 | 1910 | if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER) |
| @@ -1925,7 +1925,7 @@ void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev, · 14 unmodified lines | ||
| 1925 | 1925 | EP_CFG_TDL_CHK | EP_CFG_SID_CHK); |
| 1926 | 1926 | } |
| 1927 | 1927 | |
| 1928 | −void cdns3_configure_dmult(struct cdns3_device *priv_dev, | |
| 1928 | +static void cdns3_configure_dmult(struct cdns3_device *priv_dev, | |
| 1929 | 1929 | struct cdns3_endpoint *priv_ep) |
| 1930 | 1930 | { |
| 1931 | 1931 | struct cdns3_usb_regs __iomem *regs = priv_dev->regs; |
| @@ -2548,7 +2548,7 @@ found: · 616 unmodified lines | ||
| 2548 | 2548 | link_trb = priv_req->trb; |
| 2549 | 2549 | |
| 2550 | 2550 | /* Update ring only if removed request is on pending_req_list list */ |
| 2551 | − if (req_on_hw_ring) { | |
| 2551 | + if (req_on_hw_ring && link_trb) { | |
| 2552 | 2552 | link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + |
| 2553 | 2553 | ((priv_req->end_trb + 1) * TRB_SIZE)); |
| 2554 | 2554 | link_trb->control = (link_trb->control & TRB_CYCLE) | |
| @@ -251,9 +251,19 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) · 250 unmodified lines | ||
| 251 | 251 | usbm->vma_use_count = 1; |
| 252 | 252 | INIT_LIST_HEAD(&usbm->memlist); |
| 253 | 253 | |
| 254 | − if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { | |
| 255 | − dec_usb_memory_use_count(usbm, &usbm->vma_use_count); | |
| 256 | − return -EAGAIN; | |
| 254 | + if (hcd->localmem_pool || !hcd_uses_dma(hcd)) { | |
| 255 | + if (remap_pfn_range(vma, vma->vm_start, | |
| 256 | + virt_to_phys(usbm->mem) >> PAGE_SHIFT, | |
| 257 | + size, vma->vm_page_prot) < 0) { | |
| 258 | + dec_usb_memory_use_count(usbm, &usbm->vma_use_count); | |
| 259 | + return -EAGAIN; | |
| 260 | + } | |
| 261 | + } else { | |
| 262 | + if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, | |
| 263 | + size)) { | |
| 264 | + dec_usb_memory_use_count(usbm, &usbm->vma_use_count); | |
| 265 | + return -EAGAIN; | |
| 266 | + } | |
| 257 | 267 | } |
| 258 | 268 | |
| 259 | 269 | vma->vm_flags |= VM_IO; |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define USB_VENDOR_GENESYS_LOGIC 0x05e3 |
| 41 | 41 | #define USB_VENDOR_SMSC 0x0424 |
| 42 | +#define USB_PRODUCT_USB5534B 0x5534 | |
| 42 | 43 | #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 |
| 43 | 44 | #define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 |
| 44 | 45 | |
| @@ -5621,8 +5622,11 @@ out_hdev_lock: · 5576 unmodified lines | ||
| 5621 | 5622 | } |
| 5622 | 5623 | |
| 5623 | 5624 | static const struct usb_device_id hub_id_table[] = { |
| 5624 | − { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, | |
| 5625 | + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | |
| 5626 | + | USB_DEVICE_ID_MATCH_PRODUCT | |
| 5627 | + | USB_DEVICE_ID_MATCH_INT_CLASS, | |
| 5625 | 5628 | .idVendor = USB_VENDOR_SMSC, |
| 5629 | + .idProduct = USB_PRODUCT_USB5534B, | |
| 5626 | 5630 | .bInterfaceClass = USB_CLASS_HUB, |
| 5627 | 5631 | .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, |
| 5628 | 5632 | { .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
| @@ -4,6 +4,7 @@ config USB_DWC3 · 3 unmodified lines | ||
| 4 | 4 | tristate "DesignWare USB3 DRD Core Support" |
| 5 | 5 | depends on (USB || USB_GADGET) && HAS_DMA |
| 6 | 6 | select USB_XHCI_PLATFORM if USB_XHCI_HCD |
| 7 | + select USB_ROLE_SWITCH if USB_DWC3_DUAL_ROLE | |
| 7 | 8 | help |
| 8 | 9 | Say Y or M here if your system has a Dual Role SuperSpeed |
| 9 | 10 | USB controller based on the DesignWare USB3 IP Core. |
| @@ -114,6 +114,7 @@ static const struct property_entry dwc3_pci_intel_properties[] = { · 113 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | static const struct property_entry dwc3_pci_mrfld_properties[] = { |
| 116 | 116 | PROPERTY_ENTRY_STRING("dr_mode", "otg"), |
| 117 | + PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), | |
| 117 | 118 | PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), |
| 118 | 119 | {} |
| 119 | 120 | }; |
| @@ -2483,9 +2483,6 @@ static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep, · 2482 unmodified lines | ||
| 2483 | 2483 | for_each_sg(sg, s, pending, i) { |
| 2484 | 2484 | trb = &dep->trb_pool[dep->trb_dequeue]; |
| 2485 | 2485 | |
| 2486 | − if (trb->ctrl & DWC3_TRB_CTRL_HWO) | |
| 2487 | − break; | |
| 2488 | − | |
| 2489 | 2486 | req->sg = sg_next(s); |
| 2490 | 2487 | req->num_pending_sgs--; |
| 2491 | 2488 | |
| @@ -260,6 +260,9 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, · 259 unmodified lines | ||
| 260 | 260 | char *name; |
| 261 | 261 | int ret; |
| 262 | 262 | |
| 263 | + if (strlen(page) < len) | |
| 264 | + return -EOVERFLOW; | |
| 265 | + | |
| 263 | 266 | name = kstrdup(page, GFP_KERNEL); |
| 264 | 267 | if (!name) |
| 265 | 268 | return -ENOMEM; |
| @@ -300,8 +300,10 @@ static int audio_bind(struct usb_composite_dev *cdev) · 299 unmodified lines | ||
| 300 | 300 | struct usb_descriptor_header *usb_desc; |
| 301 | 301 | |
| 302 | 302 | usb_desc = usb_otg_descriptor_alloc(cdev->gadget); |
| 303 | − if (!usb_desc) | |
| 303 | + if (!usb_desc) { | |
| 304 | + status = -ENOMEM; | |
| 304 | 305 | goto fail; |
| 306 | + } | |
| 305 | 307 | usb_otg_descriptor_init(cdev->gadget, usb_desc); |
| 306 | 308 | otg_desc[0] = usb_desc; |
| 307 | 309 | otg_desc[1] = NULL; |
| @@ -179,8 +179,10 @@ static int cdc_bind(struct usb_composite_dev *cdev) · 178 unmodified lines | ||
| 179 | 179 | struct usb_descriptor_header *usb_desc; |
| 180 | 180 | |
| 181 | 181 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 182 | − if (!usb_desc) | |
| 182 | + if (!usb_desc) { | |
| 183 | + status = -ENOMEM; | |
| 183 | 184 | goto fail1; |
| 185 | + } | |
| 184 | 186 | usb_otg_descriptor_init(gadget, usb_desc); |
| 185 | 187 | otg_desc[0] = usb_desc; |
| 186 | 188 | otg_desc[1] = NULL; |
| @@ -1361,7 +1361,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) · 1360 unmodified lines | ||
| 1361 | 1361 | |
| 1362 | 1362 | req->buf = dev->rbuf; |
| 1363 | 1363 | req->context = NULL; |
| 1364 | − value = -EOPNOTSUPP; | |
| 1365 | 1364 | switch (ctrl->bRequest) { |
| 1366 | 1365 | |
| 1367 | 1366 | case USB_REQ_GET_DESCRIPTOR: |
| @@ -1784,7 +1783,7 @@ static ssize_t · 416 unmodified lines | ||
| 1784 | 1783 | dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) |
| 1785 | 1784 | { |
| 1786 | 1785 | struct dev_data *dev = fd->private_data; |
| 1787 | − ssize_t value = len, length = len; | |
| 1786 | + ssize_t value, length = len; | |
| 1788 | 1787 | unsigned total; |
| 1789 | 1788 | u32 tag; |
| 1790 | 1789 | char *kbuf; |
| @@ -156,8 +156,10 @@ static int gncm_bind(struct usb_composite_dev *cdev) · 155 unmodified lines | ||
| 156 | 156 | struct usb_descriptor_header *usb_desc; |
| 157 | 157 | |
| 158 | 158 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 159 | − if (!usb_desc) | |
| 159 | + if (!usb_desc) { | |
| 160 | + status = -ENOMEM; | |
| 160 | 161 | goto fail; |
| 162 | + } | |
| 161 | 163 | usb_otg_descriptor_init(gadget, usb_desc); |
| 162 | 164 | otg_desc[0] = usb_desc; |
| 163 | 165 | otg_desc[1] = NULL; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/compiler.h> |
| 10 | +#include <linux/ctype.h> | |
| 10 | 11 | #include <linux/debugfs.h> |
| 11 | 12 | #include <linux/delay.h> |
| 12 | 13 | #include <linux/kref.h> |
| @@ -123,8 +124,6 @@ static void raw_event_queue_destroy(struct raw_event_queue *queue) · 110 unmodified lines | ||
| 123 | 124 | |
| 124 | 125 | struct raw_dev; |
| 125 | 126 | |
| 126 | −#define USB_RAW_MAX_ENDPOINTS 32 | |
| 127 | − | |
| 128 | 127 | enum ep_state { |
| 129 | 128 | STATE_EP_DISABLED, |
| 130 | 129 | STATE_EP_ENABLED, |
| @@ -134,6 +133,7 @@ struct raw_ep { · 3 unmodified lines | ||
| 134 | 133 | struct raw_dev *dev; |
| 135 | 134 | enum ep_state state; |
| 136 | 135 | struct usb_ep *ep; |
| 136 | + u8 addr; | |
| 137 | 137 | struct usb_request *req; |
| 138 | 138 | bool urb_queued; |
| 139 | 139 | bool disabling; |
| @@ -168,7 +168,8 @@ struct raw_dev { · 28 unmodified lines | ||
| 168 | 168 | bool ep0_out_pending; |
| 169 | 169 | bool ep0_urb_queued; |
| 170 | 170 | ssize_t ep0_status; |
| 171 | − struct raw_ep eps[USB_RAW_MAX_ENDPOINTS]; | |
| 171 | + struct raw_ep eps[USB_RAW_EPS_NUM_MAX]; | |
| 172 | + int eps_num; | |
| 172 | 173 | |
| 173 | 174 | struct completion ep0_done; |
| 174 | 175 | struct raw_event_queue queue; |
| @@ -202,8 +203,8 @@ static void dev_free(struct kref *kref) · 27 unmodified lines | ||
| 202 | 203 | usb_ep_free_request(dev->gadget->ep0, dev->req); |
| 203 | 204 | } |
| 204 | 205 | raw_event_queue_destroy(&dev->queue); |
| 205 | − for (i = 0; i < USB_RAW_MAX_ENDPOINTS; i++) { | |
| 206 | − if (dev->eps[i].state != STATE_EP_ENABLED) | |
| 206 | + for (i = 0; i < dev->eps_num; i++) { | |
| 207 | + if (dev->eps[i].state == STATE_EP_DISABLED) | |
| 207 | 208 | continue; |
| 208 | 209 | usb_ep_disable(dev->eps[i].ep); |
| 209 | 210 | usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req); |
| @@ -249,12 +250,26 @@ static void gadget_ep0_complete(struct usb_ep *ep, struct usb_request *req) · 39 unmodified lines | ||
| 249 | 250 | complete(&dev->ep0_done); |
| 250 | 251 | } |
| 251 | 252 | |
| 253 | +static u8 get_ep_addr(const char *name) | |
| 254 | +{ | |
| 255 | + /* If the endpoint has fixed function (named as e.g. "ep12out-bulk"), | |
| 256 | + * parse the endpoint address from its name. We deliberately use | |
| 257 | + * deprecated simple_strtoul() function here, as the number isn't | |
| 258 | + * followed by '\0' nor '\n'. | |
| 259 | + */ | |
| 260 | + if (isdigit(name[2])) | |
| 261 | + return simple_strtoul(&name[2], NULL, 10); | |
| 262 | + /* Otherwise the endpoint is configurable (named as e.g. "ep-a"). */ | |
| 263 | + return USB_RAW_EP_ADDR_ANY; | |
| 264 | +} | |
| 265 | + | |
| 252 | 266 | static int gadget_bind(struct usb_gadget *gadget, |
| 253 | 267 | struct usb_gadget_driver *driver) |
| 254 | 268 | { |
| 255 | − int ret = 0; | |
| 269 | + int ret = 0, i = 0; | |
| 256 | 270 | struct raw_dev *dev = container_of(driver, struct raw_dev, driver); |
| 257 | 271 | struct usb_request *req; |
| 272 | + struct usb_ep *ep; | |
| 258 | 273 | unsigned long flags; |
| 259 | 274 | |
| 260 | 275 | if (strcmp(gadget->name, dev->udc_name) != 0) |
| @@ -273,6 +288,13 @@ static int gadget_bind(struct usb_gadget *gadget, · 12 unmodified lines | ||
| 273 | 288 | dev->req->context = dev; |
| 274 | 289 | dev->req->complete = gadget_ep0_complete; |
| 275 | 290 | dev->gadget = gadget; |
| 291 | + gadget_for_each_ep(ep, dev->gadget) { | |
| 292 | + dev->eps[i].ep = ep; | |
| 293 | + dev->eps[i].addr = get_ep_addr(ep->name); | |
| 294 | + dev->eps[i].state = STATE_EP_DISABLED; | |
| 295 | + i++; | |
| 296 | + } | |
| 297 | + dev->eps_num = i; | |
| 276 | 298 | spin_unlock_irqrestore(&dev->lock, flags); |
| 277 | 299 | |
| 278 | 300 | /* Matches kref_put() in gadget_unbind(). */ |
| @@ -555,7 +577,7 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, · 276 unmodified lines | ||
| 555 | 577 | |
| 556 | 578 | if (copy_from_user(io, ptr, sizeof(*io))) |
| 557 | 579 | return ERR_PTR(-EFAULT); |
| 558 | − if (io->ep >= USB_RAW_MAX_ENDPOINTS) | |
| 580 | + if (io->ep >= USB_RAW_EPS_NUM_MAX) | |
| 559 | 581 | return ERR_PTR(-EINVAL); |
| 560 | 582 | if (!usb_raw_io_flags_valid(io->flags)) |
| 561 | 583 | return ERR_PTR(-EINVAL); |
| @@ -669,43 +691,61 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value) · 107 unmodified lines | ||
| 669 | 691 | if (IS_ERR(data)) |
| 670 | 692 | return PTR_ERR(data); |
| 671 | 693 | ret = raw_process_ep0_io(dev, &io, data, false); |
| 672 | − if (ret) | |
| 694 | + if (ret < 0) | |
| 673 | 695 | goto free; |
| 674 | 696 | |
| 675 | 697 | length = min(io.length, (unsigned int)ret); |
| 676 | 698 | if (copy_to_user((void __user *)(value + sizeof(io)), data, length)) |
| 677 | 699 | ret = -EFAULT; |
| 700 | + else | |
| 701 | + ret = length; | |
| 678 | 702 | free: |
| 679 | 703 | kfree(data); |
| 680 | 704 | return ret; |
| 681 | 705 | } |
| 682 | 706 | |
| 683 | −static bool check_ep_caps(struct usb_ep *ep, | |
| 684 | − struct usb_endpoint_descriptor *desc) | |
| 707 | +static int raw_ioctl_ep0_stall(struct raw_dev *dev, unsigned long value) | |
| 685 | 708 | { |
| 686 | − switch (usb_endpoint_type(desc)) { | |
| 687 | − case USB_ENDPOINT_XFER_ISOC: | |
| 688 | − if (!ep->caps.type_iso) | |
| 689 | − return false; | |
| 690 | − break; | |
| 691 | − case USB_ENDPOINT_XFER_BULK: | |
| 692 | − if (!ep->caps.type_bulk) | |
| 693 | − return false; | |
| 694 | − break; | |
| 695 | − case USB_ENDPOINT_XFER_INT: | |
| 696 | − if (!ep->caps.type_int) | |
| 697 | − return false; | |
| 698 | − break; | |
| 699 | − default: | |
| 700 | − return false; | |
| 709 | + int ret = 0; | |
| 710 | + unsigned long flags; | |
| 711 | + | |
| 712 | + if (value) | |
| 713 | + return -EINVAL; | |
| 714 | + spin_lock_irqsave(&dev->lock, flags); | |
| 715 | + if (dev->state != STATE_DEV_RUNNING) { | |
| 716 | + dev_dbg(dev->dev, "fail, device is not running\n"); | |
| 717 | + ret = -EINVAL; | |
| 718 | + goto out_unlock; | |
| 719 | + } | |
| 720 | + if (!dev->gadget) { | |
| 721 | + dev_dbg(dev->dev, "fail, gadget is not bound\n"); | |
| 722 | + ret = -EBUSY; | |
| 723 | + goto out_unlock; | |
| 724 | + } | |
| 725 | + if (dev->ep0_urb_queued) { | |
| 726 | + dev_dbg(&dev->gadget->dev, "fail, urb already queued\n"); | |
| 727 | + ret = -EBUSY; | |
| 728 | + goto out_unlock; | |
| 729 | + } | |
| 730 | + if (!dev->ep0_in_pending && !dev->ep0_out_pending) { | |
| 731 | + dev_dbg(&dev->gadget->dev, "fail, no request pending\n"); | |
| 732 | + ret = -EBUSY; | |
| 733 | + goto out_unlock; | |
| 701 | 734 | } |
| 702 | 735 | |
| 703 | − if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in) | |
| 704 | − return false; | |
| 705 | − if (usb_endpoint_dir_out(desc) && !ep->caps.dir_out) | |
| 706 | − return false; | |
| 736 | + ret = usb_ep_set_halt(dev->gadget->ep0); | |
| 737 | + if (ret < 0) | |
| 738 | + dev_err(&dev->gadget->dev, | |
| 739 | + "fail, usb_ep_set_halt returned %d\n", ret); | |
| 740 | + | |
| 741 | + if (dev->ep0_in_pending) | |
| 742 | + dev->ep0_in_pending = false; | |
| 743 | + else | |
| 744 | + dev->ep0_out_pending = false; | |
| 707 | 745 | |
| 708 | − return true; | |
| 746 | +out_unlock: | |
| 747 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 748 | + return ret; | |
| 709 | 749 | } |
| 710 | 750 | |
| 711 | 751 | static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value) |
| @@ -713,7 +753,7 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value) · 1 unmodified line | ||
| 713 | 753 | int ret = 0, i; |
| 714 | 754 | unsigned long flags; |
| 715 | 755 | struct usb_endpoint_descriptor *desc; |
| 716 | − struct usb_ep *ep = NULL; | |
| 756 | + struct raw_ep *ep; | |
| 717 | 757 | |
| 718 | 758 | desc = memdup_user((void __user *)value, sizeof(*desc)); |
| 719 | 759 | if (IS_ERR(desc)) |
| @@ -741,41 +781,32 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value) · 21 unmodified lines | ||
| 741 | 781 | goto out_free; |
| 742 | 782 | } |
| 743 | 783 | |
| 744 | − for (i = 0; i < USB_RAW_MAX_ENDPOINTS; i++) { | |
| 745 | − if (dev->eps[i].state == STATE_EP_ENABLED) | |
| 784 | + for (i = 0; i < dev->eps_num; i++) { | |
| 785 | + ep = &dev->eps[i]; | |
| 786 | + if (ep->state != STATE_EP_DISABLED) | |
| 746 | 787 | continue; |
| 747 | − break; | |
| 748 | − } | |
| 749 | − if (i == USB_RAW_MAX_ENDPOINTS) { | |
| 750 | − dev_dbg(&dev->gadget->dev, | |
| 751 | − "fail, no device endpoints available\n"); | |
| 752 | − ret = -EBUSY; | |
| 753 | − goto out_free; | |
| 754 | − } | |
| 755 | − | |
| 756 | − gadget_for_each_ep(ep, dev->gadget) { | |
| 757 | − if (ep->enabled) | |
| 788 | + if (ep->addr != usb_endpoint_num(desc) && | |
| 789 | + ep->addr != USB_RAW_EP_ADDR_ANY) | |
| 758 | 790 | continue; |
| 759 | − if (!check_ep_caps(ep, desc)) | |
| 791 | + if (!usb_gadget_ep_match_desc(dev->gadget, ep->ep, desc, NULL)) | |
| 760 | 792 | continue; |
| 761 | − ep->desc = desc; | |
| 762 | − ret = usb_ep_enable(ep); | |
| 793 | + ep->ep->desc = desc; | |
| 794 | + ret = usb_ep_enable(ep->ep); | |
| 763 | 795 | if (ret < 0) { |
| 764 | 796 | dev_err(&dev->gadget->dev, |
| 765 | 797 | "fail, usb_ep_enable returned %d\n", ret); |
| 766 | 798 | goto out_free; |
| 767 | 799 | } |
| 768 | − dev->eps[i].req = usb_ep_alloc_request(ep, GFP_ATOMIC); | |
| 769 | − if (!dev->eps[i].req) { | |
| 800 | + ep->req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC); | |
| 801 | + if (!ep->req) { | |
| 770 | 802 | dev_err(&dev->gadget->dev, |
| 771 | 803 | "fail, usb_ep_alloc_request failed\n"); |
| 772 | − usb_ep_disable(ep); | |
| 804 | + usb_ep_disable(ep->ep); | |
| 773 | 805 | ret = -ENOMEM; |
| 774 | 806 | goto out_free; |
| 775 | 807 | } |
| 776 | − dev->eps[i].ep = ep; | |
| 777 | − dev->eps[i].state = STATE_EP_ENABLED; | |
| 778 | − ep->driver_data = &dev->eps[i]; | |
| 808 | + ep->state = STATE_EP_ENABLED; | |
| 809 | + ep->ep->driver_data = ep; | |
| 779 | 810 | ret = i; |
| 780 | 811 | goto out_unlock; |
| 781 | 812 | } |
| @@ -794,10 +825,6 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 12 unmodified lines | ||
| 794 | 825 | { |
| 795 | 826 | int ret = 0, i = value; |
| 796 | 827 | unsigned long flags; |
| 797 | − const void *desc; | |
| 798 | − | |
| 799 | − if (i < 0 || i >= USB_RAW_MAX_ENDPOINTS) | |
| 800 | − return -EINVAL; | |
| 801 | 828 | |
| 802 | 829 | spin_lock_irqsave(&dev->lock, flags); |
| 803 | 830 | if (dev->state != STATE_DEV_RUNNING) { |
| @@ -810,7 +837,12 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 6 unmodified lines | ||
| 810 | 837 | ret = -EBUSY; |
| 811 | 838 | goto out_unlock; |
| 812 | 839 | } |
| 813 | − if (dev->eps[i].state != STATE_EP_ENABLED) { | |
| 840 | + if (i < 0 || i >= dev->eps_num) { | |
| 841 | + dev_dbg(dev->dev, "fail, invalid endpoint\n"); | |
| 842 | + ret = -EBUSY; | |
| 843 | + goto out_unlock; | |
| 844 | + } | |
| 845 | + if (dev->eps[i].state == STATE_EP_DISABLED) { | |
| 814 | 846 | dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n"); |
| 815 | 847 | ret = -EINVAL; |
| 816 | 848 | goto out_unlock; |
| @@ -834,10 +866,8 @@ static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) · 17 unmodified lines | ||
| 834 | 866 | |
| 835 | 867 | spin_lock_irqsave(&dev->lock, flags); |
| 836 | 868 | usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req); |
| 837 | − desc = dev->eps[i].ep->desc; | |
| 838 | − dev->eps[i].ep = NULL; | |
| 869 | + kfree(dev->eps[i].ep->desc); | |
| 839 | 870 | dev->eps[i].state = STATE_EP_DISABLED; |
| 840 | − kfree(desc); | |
| 841 | 871 | dev->eps[i].disabling = false; |
| 842 | 872 | |
| 843 | 873 | out_unlock: |
| @@ -845,6 +875,74 @@ out_unlock: · 1 unmodified line | ||
| 845 | 875 | return ret; |
| 846 | 876 | } |
| 847 | 877 | |
| 878 | +static int raw_ioctl_ep_set_clear_halt_wedge(struct raw_dev *dev, | |
| 879 | + unsigned long value, bool set, bool halt) | |
| 880 | +{ | |
| 881 | + int ret = 0, i = value; | |
| 882 | + unsigned long flags; | |
| 883 | + | |
| 884 | + spin_lock_irqsave(&dev->lock, flags); | |
| 885 | + if (dev->state != STATE_DEV_RUNNING) { | |
| 886 | + dev_dbg(dev->dev, "fail, device is not running\n"); | |
| 887 | + ret = -EINVAL; | |
| 888 | + goto out_unlock; | |
| 889 | + } | |
| 890 | + if (!dev->gadget) { | |
| 891 | + dev_dbg(dev->dev, "fail, gadget is not bound\n"); | |
| 892 | + ret = -EBUSY; | |
| 893 | + goto out_unlock; | |
| 894 | + } | |
| 895 | + if (i < 0 || i >= dev->eps_num) { | |
| 896 | + dev_dbg(dev->dev, "fail, invalid endpoint\n"); | |
| 897 | + ret = -EBUSY; | |
| 898 | + goto out_unlock; | |
| 899 | + } | |
| 900 | + if (dev->eps[i].state == STATE_EP_DISABLED) { | |
| 901 | + dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n"); | |
| 902 | + ret = -EINVAL; | |
| 903 | + goto out_unlock; | |
| 904 | + } | |
| 905 | + if (dev->eps[i].disabling) { | |
| 906 | + dev_dbg(&dev->gadget->dev, | |
| 907 | + "fail, disable is in progress\n"); | |
| 908 | + ret = -EINVAL; | |
| 909 | + goto out_unlock; | |
| 910 | + } | |
| 911 | + if (dev->eps[i].urb_queued) { | |
| 912 | + dev_dbg(&dev->gadget->dev, | |
| 913 | + "fail, waiting for urb completion\n"); | |
| 914 | + ret = -EINVAL; | |
| 915 | + goto out_unlock; | |
| 916 | + } | |
| 917 | + if (usb_endpoint_xfer_isoc(dev->eps[i].ep->desc)) { | |
| 918 | + dev_dbg(&dev->gadget->dev, | |
| 919 | + "fail, can't halt/wedge ISO endpoint\n"); | |
| 920 | + ret = -EINVAL; | |
| 921 | + goto out_unlock; | |
| 922 | + } | |
| 923 | + | |
| 924 | + if (set && halt) { | |
| 925 | + ret = usb_ep_set_halt(dev->eps[i].ep); | |
| 926 | + if (ret < 0) | |
| 927 | + dev_err(&dev->gadget->dev, | |
| 928 | + "fail, usb_ep_set_halt returned %d\n", ret); | |
| 929 | + } else if (!set && halt) { | |
| 930 | + ret = usb_ep_clear_halt(dev->eps[i].ep); | |
| 931 | + if (ret < 0) | |
| 932 | + dev_err(&dev->gadget->dev, | |
| 933 | + "fail, usb_ep_clear_halt returned %d\n", ret); | |
| 934 | + } else if (set && !halt) { | |
| 935 | + ret = usb_ep_set_wedge(dev->eps[i].ep); | |
| 936 | + if (ret < 0) | |
| 937 | + dev_err(&dev->gadget->dev, | |
| 938 | + "fail, usb_ep_set_wedge returned %d\n", ret); | |
| 939 | + } | |
| 940 | + | |
| 941 | +out_unlock: | |
| 942 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 943 | + return ret; | |
| 944 | +} | |
| 945 | + | |
| 848 | 946 | static void gadget_ep_complete(struct usb_ep *ep, struct usb_request *req) |
| 849 | 947 | { |
| 850 | 948 | struct raw_ep *r_ep = (struct raw_ep *)ep->driver_data; |
| @@ -866,7 +964,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, · 15 unmodified lines | ||
| 866 | 964 | { |
| 867 | 965 | int ret = 0; |
| 868 | 966 | unsigned long flags; |
| 869 | − struct raw_ep *ep = &dev->eps[io->ep]; | |
| 967 | + struct raw_ep *ep; | |
| 870 | 968 | DECLARE_COMPLETION_ONSTACK(done); |
| 871 | 969 | |
| 872 | 970 | spin_lock_irqsave(&dev->lock, flags); |
| @@ -880,6 +978,12 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, · 7 unmodified lines | ||
| 880 | 978 | ret = -EBUSY; |
| 881 | 979 | goto out_unlock; |
| 882 | 980 | } |
| 981 | + if (io->ep >= dev->eps_num) { | |
| 982 | + dev_dbg(&dev->gadget->dev, "fail, invalid endpoint\n"); | |
| 983 | + ret = -EINVAL; | |
| 984 | + goto out_unlock; | |
| 985 | + } | |
| 986 | + ep = &dev->eps[io->ep]; | |
| 883 | 987 | if (ep->state != STATE_EP_ENABLED) { |
| 884 | 988 | dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n"); |
| 885 | 989 | ret = -EBUSY; |
| @@ -964,12 +1068,14 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value) · 78 unmodified lines | ||
| 964 | 1068 | if (IS_ERR(data)) |
| 965 | 1069 | return PTR_ERR(data); |
| 966 | 1070 | ret = raw_process_ep_io(dev, &io, data, false); |
| 967 | − if (ret) | |
| 1071 | + if (ret < 0) | |
| 968 | 1072 | goto free; |
| 969 | 1073 | |
| 970 | 1074 | length = min(io.length, (unsigned int)ret); |
| 971 | 1075 | if (copy_to_user((void __user *)(value + sizeof(io)), data, length)) |
| 972 | 1076 | ret = -EFAULT; |
| 1077 | + else | |
| 1078 | + ret = length; | |
| 973 | 1079 | free: |
| 974 | 1080 | kfree(data); |
| 975 | 1081 | return ret; |
| @@ -1023,6 +1129,71 @@ out_unlock: · 47 unmodified lines | ||
| 1023 | 1129 | return ret; |
| 1024 | 1130 | } |
| 1025 | 1131 | |
| 1132 | +static void fill_ep_caps(struct usb_ep_caps *caps, | |
| 1133 | + struct usb_raw_ep_caps *raw_caps) | |
| 1134 | +{ | |
| 1135 | + raw_caps->type_control = caps->type_control; | |
| 1136 | + raw_caps->type_iso = caps->type_iso; | |
| 1137 | + raw_caps->type_bulk = caps->type_bulk; | |
| 1138 | + raw_caps->type_int = caps->type_int; | |
| 1139 | + raw_caps->dir_in = caps->dir_in; | |
| 1140 | + raw_caps->dir_out = caps->dir_out; | |
| 1141 | +} | |
| 1142 | + | |
| 1143 | +static void fill_ep_limits(struct usb_ep *ep, struct usb_raw_ep_limits *limits) | |
| 1144 | +{ | |
| 1145 | + limits->maxpacket_limit = ep->maxpacket_limit; | |
| 1146 | + limits->max_streams = ep->max_streams; | |
| 1147 | +} | |
| 1148 | + | |
| 1149 | +static int raw_ioctl_eps_info(struct raw_dev *dev, unsigned long value) | |
| 1150 | +{ | |
| 1151 | + int ret = 0, i; | |
| 1152 | + unsigned long flags; | |
| 1153 | + struct usb_raw_eps_info *info; | |
| 1154 | + struct raw_ep *ep; | |
| 1155 | + | |
| 1156 | + info = kmalloc(sizeof(*info), GFP_KERNEL); | |
| 1157 | + if (!info) { | |
| 1158 | + ret = -ENOMEM; | |
| 1159 | + goto out; | |
| 1160 | + } | |
| 1161 | + | |
| 1162 | + spin_lock_irqsave(&dev->lock, flags); | |
| 1163 | + if (dev->state != STATE_DEV_RUNNING) { | |
| 1164 | + dev_dbg(dev->dev, "fail, device is not running\n"); | |
| 1165 | + ret = -EINVAL; | |
| 1166 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 1167 | + goto out_free; | |
| 1168 | + } | |
| 1169 | + if (!dev->gadget) { | |
| 1170 | + dev_dbg(dev->dev, "fail, gadget is not bound\n"); | |
| 1171 | + ret = -EBUSY; | |
| 1172 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 1173 | + goto out_free; | |
| 1174 | + } | |
| 1175 | + | |
| 1176 | + memset(info, 0, sizeof(*info)); | |
| 1177 | + for (i = 0; i < dev->eps_num; i++) { | |
| 1178 | + ep = &dev->eps[i]; | |
| 1179 | + strscpy(&info->eps[i].name[0], ep->ep->name, | |
| 1180 | + USB_RAW_EP_NAME_MAX); | |
| 1181 | + info->eps[i].addr = ep->addr; | |
| 1182 | + fill_ep_caps(&ep->ep->caps, &info->eps[i].caps); | |
| 1183 | + fill_ep_limits(ep->ep, &info->eps[i].limits); | |
| 1184 | + } | |
| 1185 | + ret = dev->eps_num; | |
| 1186 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 1187 | + | |
| 1188 | + if (copy_to_user((void __user *)value, info, sizeof(*info))) | |
| 1189 | + ret = -EFAULT; | |
| 1190 | + | |
| 1191 | +out_free: | |
| 1192 | + kfree(info); | |
| 1193 | +out: | |
| 1194 | + return ret; | |
| 1195 | +} | |
| 1196 | + | |
| 1026 | 1197 | static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value) |
| 1027 | 1198 | { |
| 1028 | 1199 | struct raw_dev *dev = fd->private_data; |
| @@ -1065,6 +1236,24 @@ static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value) · 36 unmodified lines | ||
| 1065 | 1236 | case USB_RAW_IOCTL_VBUS_DRAW: |
| 1066 | 1237 | ret = raw_ioctl_vbus_draw(dev, value); |
| 1067 | 1238 | break; |
| 1239 | + case USB_RAW_IOCTL_EPS_INFO: | |
| 1240 | + ret = raw_ioctl_eps_info(dev, value); | |
| 1241 | + break; | |
| 1242 | + case USB_RAW_IOCTL_EP0_STALL: | |
| 1243 | + ret = raw_ioctl_ep0_stall(dev, value); | |
| 1244 | + break; | |
| 1245 | + case USB_RAW_IOCTL_EP_SET_HALT: | |
| 1246 | + ret = raw_ioctl_ep_set_clear_halt_wedge( | |
| 1247 | + dev, value, true, true); | |
| 1248 | + break; | |
| 1249 | + case USB_RAW_IOCTL_EP_CLEAR_HALT: | |
| 1250 | + ret = raw_ioctl_ep_set_clear_halt_wedge( | |
| 1251 | + dev, value, false, true); | |
| 1252 | + break; | |
| 1253 | + case USB_RAW_IOCTL_EP_SET_WEDGE: | |
| 1254 | + ret = raw_ioctl_ep_set_clear_halt_wedge( | |
| 1255 | + dev, value, true, false); | |
| 1256 | + break; | |
| 1068 | 1257 | default: |
| 1069 | 1258 | ret = -EINVAL; |
| 1070 | 1259 | } |
| @@ -185,7 +185,7 @@ static int regs_dbg_release(struct inode *inode, struct file *file) · 184 unmodified lines | ||
| 185 | 185 | return 0; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | −const struct file_operations queue_dbg_fops = { | |
| 188 | +static const struct file_operations queue_dbg_fops = { | |
| 189 | 189 | .owner = THIS_MODULE, |
| 190 | 190 | .open = queue_dbg_open, |
| 191 | 191 | .llseek = no_llseek, |
| @@ -193,7 +193,7 @@ const struct file_operations queue_dbg_fops = { · 1 unmodified line | ||
| 193 | 193 | .release = queue_dbg_release, |
| 194 | 194 | }; |
| 195 | 195 | |
| 196 | −const struct file_operations regs_dbg_fops = { | |
| 196 | +static const struct file_operations regs_dbg_fops = { | |
| 197 | 197 | .owner = THIS_MODULE, |
| 198 | 198 | .open = regs_dbg_open, |
| 199 | 199 | .llseek = generic_file_llseek, |
| @@ -2647,6 +2647,8 @@ net2272_plat_probe(struct platform_device *pdev) · 2646 unmodified lines | ||
| 2647 | 2647 | err_req: |
| 2648 | 2648 | release_mem_region(base, len); |
| 2649 | 2649 | err: |
| 2650 | + kfree(dev); | |
| 2651 | + | |
| 2650 | 2652 | return ret; |
| 2651 | 2653 | } |
| 2652 | 2654 | |
| @@ -3840,11 +3840,11 @@ static int __maybe_unused tegra_xudc_suspend(struct device *dev) · 3839 unmodified lines | ||
| 3840 | 3840 | |
| 3841 | 3841 | flush_work(&xudc->usb_role_sw_work); |
| 3842 | 3842 | |
| 3843 | − /* Forcibly disconnect before powergating. */ | |
| 3844 | − tegra_xudc_device_mode_off(xudc); | |
| 3845 | − | |
| 3846 | − if (!pm_runtime_status_suspended(dev)) | |
| 3843 | + if (!pm_runtime_status_suspended(dev)) { | |
| 3844 | + /* Forcibly disconnect before powergating. */ | |
| 3845 | + tegra_xudc_device_mode_off(xudc); | |
| 3847 | 3846 | tegra_xudc_powergate(xudc); |
| 3847 | + } | |
| 3848 | 3848 | |
| 3849 | 3849 | pm_runtime_disable(dev); |
| 3850 | 3850 | |
| @@ -362,6 +362,7 @@ static int xhci_plat_remove(struct platform_device *dev) · 361 unmodified lines | ||
| 362 | 362 | struct clk *reg_clk = xhci->reg_clk; |
| 363 | 363 | struct usb_hcd *shared_hcd = xhci->shared_hcd; |
| 364 | 364 | |
| 365 | + pm_runtime_get_sync(&dev->dev); | |
| 365 | 366 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
| 366 | 367 | |
| 367 | 368 | usb_remove_hcd(shared_hcd); |
| @@ -375,8 +376,9 @@ static int xhci_plat_remove(struct platform_device *dev) · 7 unmodified lines | ||
| 375 | 376 | clk_disable_unprepare(reg_clk); |
| 376 | 377 | usb_put_hcd(hcd); |
| 377 | 378 | |
| 378 | − pm_runtime_set_suspended(&dev->dev); | |
| 379 | 379 | pm_runtime_disable(&dev->dev); |
| 380 | + pm_runtime_put_noidle(&dev->dev); | |
| 381 | + pm_runtime_set_suspended(&dev->dev); | |
| 380 | 382 | |
| 381 | 383 | return 0; |
| 382 | 384 | } |
| @@ -3433,8 +3433,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, · 3432 unmodified lines | ||
| 3433 | 3433 | /* New sg entry */ |
| 3434 | 3434 | --num_sgs; |
| 3435 | 3435 | sent_len -= block_len; |
| 3436 | − if (num_sgs != 0) { | |
| 3437 | − sg = sg_next(sg); | |
| 3436 | + sg = sg_next(sg); | |
| 3437 | + if (num_sgs != 0 && sg) { | |
| 3438 | 3438 | block_len = sg_dma_len(sg); |
| 3439 | 3439 | addr = (u64) sg_dma_address(sg); |
| 3440 | 3440 | addr += sent_len; |
| @@ -276,7 +276,7 @@ static const struct file_operations mtu3_ep_fops = { · 275 unmodified lines | ||
| 276 | 276 | .release = single_release, |
| 277 | 277 | }; |
| 278 | 278 | |
| 279 | −static struct debugfs_reg32 mtu3_prb_regs[] = { | |
| 279 | +static const struct debugfs_reg32 mtu3_prb_regs[] = { | |
| 280 | 280 | dump_prb_reg("enable", U3D_SSUSB_PRB_CTRL0), |
| 281 | 281 | dump_prb_reg("byte-sell", U3D_SSUSB_PRB_CTRL1), |
| 282 | 282 | dump_prb_reg("byte-selh", U3D_SSUSB_PRB_CTRL2), |
| @@ -349,7 +349,7 @@ static const struct file_operations mtu3_probe_fops = { · 66 unmodified lines | ||
| 349 | 349 | static void mtu3_debugfs_create_prb_files(struct mtu3 *mtu) |
| 350 | 350 | { |
| 351 | 351 | struct ssusb_mtk *ssusb = mtu->ssusb; |
| 352 | − struct debugfs_reg32 *regs; | |
| 352 | + const struct debugfs_reg32 *regs; | |
| 353 | 353 | struct dentry *dir_prb; |
| 354 | 354 | int i; |
| 355 | 355 | |
| @@ -377,7 +377,7 @@ static int twl6030_usb_probe(struct platform_device *pdev) · 376 unmodified lines | ||
| 377 | 377 | if (status < 0) { |
| 378 | 378 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", |
| 379 | 379 | twl->irq1, status); |
| 380 | − return status; | |
| 380 | + goto err_put_regulator; | |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | 383 | status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, |
| @@ -386,8 +386,7 @@ static int twl6030_usb_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 386 | 386 | if (status < 0) { |
| 387 | 387 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", |
| 388 | 388 | twl->irq2, status); |
| 389 | − free_irq(twl->irq1, twl); | |
| 390 | − return status; | |
| 389 | + goto err_free_irq1; | |
| 391 | 390 | } |
| 392 | 391 | |
| 393 | 392 | twl->asleep = 0; |
| @@ -396,6 +395,13 @@ static int twl6030_usb_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 396 | 395 | dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); |
| 397 | 396 | |
| 398 | 397 | return 0; |
| 398 | + | |
| 399 | +err_free_irq1: | |
| 400 | + free_irq(twl->irq1, twl); | |
| 401 | +err_put_regulator: | |
| 402 | + regulator_put(twl->usb3v3); | |
| 403 | + | |
| 404 | + return status; | |
| 399 | 405 | } |
| 400 | 406 | |
| 401 | 407 | static int twl6030_usb_remove(struct platform_device *pdev) |
| @@ -63,6 +63,7 @@ enum { · 62 unmodified lines | ||
| 63 | 63 | #define PMC_USB_ALTMODE_DP_MODE_SHIFT 8 |
| 64 | 64 | |
| 65 | 65 | /* TBT specific Mode Data bits */ |
| 66 | +#define PMC_USB_ALTMODE_HPD_HIGH BIT(14) | |
| 66 | 67 | #define PMC_USB_ALTMODE_TBT_TYPE BIT(17) |
| 67 | 68 | #define PMC_USB_ALTMODE_CABLE_TYPE BIT(18) |
| 68 | 69 | #define PMC_USB_ALTMODE_ACTIVE_LINK BIT(20) |
| @@ -74,8 +75,8 @@ enum { · 5 unmodified lines | ||
| 74 | 75 | #define PMC_USB_ALTMODE_TBT_GEN(_g_) (((_g_) & GENMASK(1, 0)) << 28) |
| 75 | 76 | |
| 76 | 77 | /* Display HPD Request bits */ |
| 78 | +#define PMC_USB_DP_HPD_LVL BIT(4) | |
| 77 | 79 | #define PMC_USB_DP_HPD_IRQ BIT(5) |
| 78 | −#define PMC_USB_DP_HPD_LVL BIT(6) | |
| 79 | 80 | |
| 80 | 81 | struct pmc_usb; |
| 81 | 82 | |
| @@ -158,8 +159,7 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state) · 76 unmodified lines | ||
| 158 | 159 | PMC_USB_ALTMODE_DP_MODE_SHIFT; |
| 159 | 160 | |
| 160 | 161 | if (data->status & DP_STATUS_HPD_STATE) |
| 161 | − req.mode_data |= PMC_USB_DP_HPD_LVL << | |
| 162 | − PMC_USB_ALTMODE_DP_MODE_SHIFT; | |
| 162 | + req.mode_data |= PMC_USB_ALTMODE_HPD_HIGH; | |
| 163 | 163 | |
| 164 | 164 | return pmc_usb_command(port, (void *)&req, sizeof(req)); |
| 165 | 165 | } |
| @@ -89,15 +89,14 @@ static struct vdpasim *dev_to_sim(struct device *dev) · 88 unmodified lines | ||
| 89 | 89 | static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx) |
| 90 | 90 | { |
| 91 | 91 | struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; |
| 92 | − int ret; | |
| 93 | 92 | |
| 94 | − ret = vringh_init_iotlb(&vq->vring, vdpasim_features, | |
| 95 | − VDPASIM_QUEUE_MAX, false, | |
| 96 | − (struct vring_desc *)(uintptr_t)vq->desc_addr, | |
| 97 | − (struct vring_avail *) | |
| 98 | − (uintptr_t)vq->driver_addr, | |
| 99 | − (struct vring_used *) | |
| 100 | − (uintptr_t)vq->device_addr); | |
| 93 | + vringh_init_iotlb(&vq->vring, vdpasim_features, | |
| 94 | + VDPASIM_QUEUE_MAX, false, | |
| 95 | + (struct vring_desc *)(uintptr_t)vq->desc_addr, | |
| 96 | + (struct vring_avail *) | |
| 97 | + (uintptr_t)vq->driver_addr, | |
| 98 | + (struct vring_used *) | |
| 99 | + (uintptr_t)vq->device_addr); | |
| 101 | 100 | } |
| 102 | 101 | |
| 103 | 102 | static void vdpasim_vq_reset(struct vdpasim_virtqueue *vq) |
| @@ -730,7 +730,7 @@ static inline void __user *vhost_vq_meta_fetch(struct vhost_virtqueue *vq, · 729 unmodified lines | ||
| 730 | 730 | if (!map) |
| 731 | 731 | return NULL; |
| 732 | 732 | |
| 733 | − return (void *)(uintptr_t)(map->addr + addr - map->start); | |
| 733 | + return (void __user *)(uintptr_t)(map->addr + addr - map->start); | |
| 734 | 734 | } |
| 735 | 735 | |
| 736 | 736 | /* Can we switch to this memory table? */ |
| @@ -869,7 +869,7 @@ static void __user *__vhost_get_user_slow(struct vhost_virtqueue *vq, · 132 unmodified lines | ||
| 869 | 869 | * not happen in this case. |
| 870 | 870 | */ |
| 871 | 871 | static inline void __user *__vhost_get_user(struct vhost_virtqueue *vq, |
| 872 | − void *addr, unsigned int size, | |
| 872 | + void __user *addr, unsigned int size, | |
| 873 | 873 | int type) |
| 874 | 874 | { |
| 875 | 875 | void __user *uaddr = vhost_vq_meta_fetch(vq, |
| @@ -32,9 +32,8 @@ void afs_fileserver_probe_result(struct afs_call *call) · 31 unmodified lines | ||
| 32 | 32 | struct afs_server *server = call->server; |
| 33 | 33 | unsigned int server_index = call->server_index; |
| 34 | 34 | unsigned int index = call->addr_ix; |
| 35 | − unsigned int rtt = UINT_MAX; | |
| 35 | + unsigned int rtt_us = 0; | |
| 36 | 36 | bool have_result = false; |
| 37 | − u64 _rtt; | |
| 38 | 37 | int ret = call->error; |
| 39 | 38 | |
| 40 | 39 | _enter("%pU,%u", &server->uuid, index); |
| @@ -93,15 +92,9 @@ responded: · 52 unmodified lines | ||
| 93 | 92 | } |
| 94 | 93 | } |
| 95 | 94 | |
| 96 | − /* Get the RTT and scale it to fit into a 32-bit value that represents | |
| 97 | − * over a minute of time so that we can access it with one instruction | |
| 98 | − * on a 32-bit system. | |
| 99 | − */ | |
| 100 | − _rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); | |
| 101 | − _rtt /= 64; | |
| 102 | − rtt = (_rtt > UINT_MAX) ? UINT_MAX : _rtt; | |
| 103 | − if (rtt < server->probe.rtt) { | |
| 104 | − server->probe.rtt = rtt; | |
| 95 | + rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall); | |
| 96 | + if (rtt_us < server->probe.rtt) { | |
| 97 | + server->probe.rtt = rtt_us; | |
| 105 | 98 | alist->preferred = index; |
| 106 | 99 | have_result = true; |
| 107 | 100 | } |
| @@ -113,8 +106,7 @@ out: · 5 unmodified lines | ||
| 113 | 106 | spin_unlock(&server->probe_lock); |
| 114 | 107 | |
| 115 | 108 | _debug("probe [%u][%u] %pISpc rtt=%u ret=%d", |
| 116 | − server_index, index, &alist->addrs[index].transport, | |
| 117 | − (unsigned int)rtt, ret); | |
| 109 | + server_index, index, &alist->addrs[index].transport, rtt_us, ret); | |
| 118 | 110 | |
| 119 | 111 | have_result |= afs_fs_probe_done(server); |
| 120 | 112 | if (have_result) |
| @@ -385,8 +385,6 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) · 384 unmodified lines | ||
| 385 | 385 | ASSERTCMP(req->offset, <=, PAGE_SIZE); |
| 386 | 386 | if (req->offset == PAGE_SIZE) { |
| 387 | 387 | req->offset = 0; |
| 388 | − if (req->page_done) | |
| 389 | − req->page_done(req); | |
| 390 | 388 | req->index++; |
| 391 | 389 | if (req->remain > 0) |
| 392 | 390 | goto begin_page; |
| @@ -440,11 +438,13 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) · 47 unmodified lines | ||
| 440 | 438 | if (req->offset < PAGE_SIZE) |
| 441 | 439 | zero_user_segment(req->pages[req->index], |
| 442 | 440 | req->offset, PAGE_SIZE); |
| 443 | − if (req->page_done) | |
| 444 | − req->page_done(req); | |
| 445 | 441 | req->offset = 0; |
| 446 | 442 | } |
| 447 | 443 | |
| 444 | + if (req->page_done) | |
| 445 | + for (req->index = 0; req->index < req->nr_pages; req->index++) | |
| 446 | + req->page_done(req); | |
| 447 | + | |
| 448 | 448 | _leave(" = 0 [done]"); |
| 449 | 449 | return 0; |
| 450 | 450 | } |
| @@ -31,10 +31,9 @@ void afs_vlserver_probe_result(struct afs_call *call) · 30 unmodified lines | ||
| 31 | 31 | struct afs_addr_list *alist = call->alist; |
| 32 | 32 | struct afs_vlserver *server = call->vlserver; |
| 33 | 33 | unsigned int server_index = call->server_index; |
| 34 | + unsigned int rtt_us = 0; | |
| 34 | 35 | unsigned int index = call->addr_ix; |
| 35 | − unsigned int rtt = UINT_MAX; | |
| 36 | 36 | bool have_result = false; |
| 37 | − u64 _rtt; | |
| 38 | 37 | int ret = call->error; |
| 39 | 38 | |
| 40 | 39 | _enter("%s,%u,%u,%d,%d", server->name, server_index, index, ret, call->abort_code); |
| @@ -93,15 +92,9 @@ responded: · 52 unmodified lines | ||
| 93 | 92 | } |
| 94 | 93 | } |
| 95 | 94 | |
| 96 | − /* Get the RTT and scale it to fit into a 32-bit value that represents | |
| 97 | − * over a minute of time so that we can access it with one instruction | |
| 98 | − * on a 32-bit system. | |
| 99 | − */ | |
| 100 | − _rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); | |
| 101 | − _rtt /= 64; | |
| 102 | − rtt = (_rtt > UINT_MAX) ? UINT_MAX : _rtt; | |
| 103 | − if (rtt < server->probe.rtt) { | |
| 104 | − server->probe.rtt = rtt; | |
| 95 | + rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall); | |
| 96 | + if (rtt_us < server->probe.rtt) { | |
| 97 | + server->probe.rtt = rtt_us; | |
| 105 | 98 | alist->preferred = index; |
| 106 | 99 | have_result = true; |
| 107 | 100 | } |
| @@ -113,8 +106,7 @@ out: · 5 unmodified lines | ||
| 113 | 106 | spin_unlock(&server->probe_lock); |
| 114 | 107 | |
| 115 | 108 | _debug("probe [%u][%u] %pISpc rtt=%u ret=%d", |
| 116 | − server_index, index, &alist->addrs[index].transport, | |
| 117 | − (unsigned int)rtt, ret); | |
| 109 | + server_index, index, &alist->addrs[index].transport, rtt_us, ret); | |
| 118 | 110 | |
| 119 | 111 | have_result |= afs_vl_probe_done(server); |
| 120 | 112 | if (have_result) { |
| @@ -497,8 +497,6 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) · 496 unmodified lines | ||
| 497 | 497 | ASSERTCMP(req->offset, <=, PAGE_SIZE); |
| 498 | 498 | if (req->offset == PAGE_SIZE) { |
| 499 | 499 | req->offset = 0; |
| 500 | − if (req->page_done) | |
| 501 | − req->page_done(req); | |
| 502 | 500 | req->index++; |
| 503 | 501 | if (req->remain > 0) |
| 504 | 502 | goto begin_page; |
| @@ -556,11 +554,13 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) · 51 unmodified lines | ||
| 556 | 554 | if (req->offset < PAGE_SIZE) |
| 557 | 555 | zero_user_segment(req->pages[req->index], |
| 558 | 556 | req->offset, PAGE_SIZE); |
| 559 | − if (req->page_done) | |
| 560 | − req->page_done(req); | |
| 561 | 557 | req->offset = 0; |
| 562 | 558 | } |
| 563 | 559 | |
| 560 | + if (req->page_done) | |
| 561 | + for (req->index = 0; req->index < req->nr_pages; req->index++) | |
| 562 | + req->page_done(req); | |
| 563 | + | |
| 564 | 564 | _leave(" = 0 [done]"); |
| 565 | 565 | return 0; |
| 566 | 566 | } |
| @@ -60,9 +60,9 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode, · 59 unmodified lines | ||
| 60 | 60 | object = container_of(op->op.object, struct cachefiles_object, fscache); |
| 61 | 61 | spin_lock(&object->work_lock); |
| 62 | 62 | list_add_tail(&monitor->op_link, &op->to_do); |
| 63 | + fscache_enqueue_retrieval(op); | |
| 63 | 64 | spin_unlock(&object->work_lock); |
| 64 | 65 | |
| 65 | − fscache_enqueue_retrieval(op); | |
| 66 | 66 | fscache_put_retrieval(op); |
| 67 | 67 | return 0; |
| 68 | 68 | } |
| @@ -398,7 +398,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, · 329 unmodified lines | ||
| 398 | 398 | struct inode *inode; |
| 399 | 399 | sector_t block; |
| 400 | 400 | unsigned shift; |
| 401 | − int ret; | |
| 401 | + int ret, ret2; | |
| 402 | 402 | |
| 403 | 403 | object = container_of(op->op.object, |
| 404 | 404 | struct cachefiles_object, fscache); |
| @@ -430,8 +430,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, · 25 unmodified lines | ||
| 430 | 430 | block = page->index; |
| 431 | 431 | block <<= shift; |
| 432 | 432 | |
| 433 | − ret = bmap(inode, &block); | |
| 434 | − ASSERT(ret < 0); | |
| 433 | + ret2 = bmap(inode, &block); | |
| 434 | + ASSERT(ret2 == 0); | |
| 435 | 435 | |
| 436 | 436 | _debug("%llx -> %llx", |
| 437 | 437 | (unsigned long long) (page->index << shift), |
| @@ -739,8 +739,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, · 301 unmodified lines | ||
| 739 | 739 | block = page->index; |
| 740 | 740 | block <<= shift; |
| 741 | 741 | |
| 742 | − ret = bmap(inode, &block); | |
| 743 | − ASSERT(!ret); | |
| 742 | + ret2 = bmap(inode, &block); | |
| 743 | + ASSERT(ret2 == 0); | |
| 744 | 744 | |
| 745 | 745 | _debug("%llx -> %llx", |
| 746 | 746 | (unsigned long long) (page->index << shift), |
| @@ -2152,8 +2152,8 @@ cifs_writev_requeue(struct cifs_writedata *wdata) · 2151 unmodified lines | ||
| 2152 | 2152 | } |
| 2153 | 2153 | } |
| 2154 | 2154 | |
| 2155 | + kref_put(&wdata2->refcount, cifs_writedata_release); | |
| 2155 | 2156 | if (rc) { |
| 2156 | − kref_put(&wdata2->refcount, cifs_writedata_release); | |
| 2157 | 2157 | if (is_retryable_error(rc)) |
| 2158 | 2158 | continue; |
| 2159 | 2159 | i += nr_pages; |
| @@ -4060,7 +4060,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) · 4059 unmodified lines | ||
| 4060 | 4060 | * than it negotiated since it will refuse the read |
| 4061 | 4061 | * then. |
| 4062 | 4062 | */ |
| 4063 | − if ((tcon->ses) && !(tcon->ses->capabilities & | |
| 4063 | + if (!(tcon->ses->capabilities & | |
| 4064 | 4064 | tcon->ses->server->vals->cap_large_files)) { |
| 4065 | 4065 | current_read_size = min_t(uint, |
| 4066 | 4066 | current_read_size, CIFSMaxBufSize); |
| @@ -730,7 +730,7 @@ static __u64 simple_hashstr(const char *str) · 729 unmodified lines | ||
| 730 | 730 | * cifs_backup_query_path_info - SMB1 fallback code to get ino |
| 731 | 731 | * |
| 732 | 732 | * Fallback code to get file metadata when we don't have access to |
| 733 | − * @full_path (EACCESS) and have backup creds. | |
| 733 | + * @full_path (EACCES) and have backup creds. | |
| 734 | 734 | * |
| 735 | 735 | * @data will be set to search info result buffer |
| 736 | 736 | * @resp_buf will be set to cifs resp buf and needs to be freed with |
| @@ -1879,34 +1879,33 @@ fetch_events: · 1878 unmodified lines | ||
| 1879 | 1879 | * event delivery. |
| 1880 | 1880 | */ |
| 1881 | 1881 | init_wait(&wait); |
| 1882 | − write_lock_irq(&ep->lock); | |
| 1883 | − __add_wait_queue_exclusive(&ep->wq, &wait); | |
| 1884 | − write_unlock_irq(&ep->lock); | |
| 1885 | 1882 | |
| 1883 | + write_lock_irq(&ep->lock); | |
| 1886 | 1884 | /* |
| 1887 | − * We don't want to sleep if the ep_poll_callback() sends us | |
| 1888 | − * a wakeup in between. That's why we set the task state | |
| 1889 | − * to TASK_INTERRUPTIBLE before doing the checks. | |
| 1885 | + * Barrierless variant, waitqueue_active() is called under | |
| 1886 | + * the same lock on wakeup ep_poll_callback() side, so it | |
| 1887 | + * is safe to avoid an explicit barrier. | |
| 1890 | 1888 | */ |
| 1891 | − set_current_state(TASK_INTERRUPTIBLE); | |
| 1889 | + __set_current_state(TASK_INTERRUPTIBLE); | |
| 1890 | + | |
| 1892 | 1891 | /* |
| 1893 | − * Always short-circuit for fatal signals to allow | |
| 1894 | − * threads to make a timely exit without the chance of | |
| 1895 | − * finding more events available and fetching | |
| 1896 | − * repeatedly. | |
| 1892 | + * Do the final check under the lock. ep_scan_ready_list() | |
| 1893 | + * plays with two lists (->rdllist and ->ovflist) and there | |
| 1894 | + * is always a race when both lists are empty for short | |
| 1895 | + * period of time although events are pending, so lock is | |
| 1896 | + * important. | |
| 1897 | 1897 | */ |
| 1898 | − if (fatal_signal_pending(current)) { | |
| 1899 | − res = -EINTR; | |
| 1900 | − break; | |
| 1898 | + eavail = ep_events_available(ep); | |
| 1899 | + if (!eavail) { | |
| 1900 | + if (signal_pending(current)) | |
| 1901 | + res = -EINTR; | |
| 1902 | + else | |
| 1903 | + __add_wait_queue_exclusive(&ep->wq, &wait); | |
| 1901 | 1904 | } |
| 1905 | + write_unlock_irq(&ep->lock); | |
| 1902 | 1906 | |
| 1903 | − eavail = ep_events_available(ep); | |
| 1904 | − if (eavail) | |
| 1905 | − break; | |
| 1906 | − if (signal_pending(current)) { | |
| 1907 | − res = -EINTR; | |
| 1907 | + if (eavail || res) | |
| 1908 | 1908 | break; |
| 1909 | − } | |
| 1910 | 1909 | |
| 1911 | 1910 | if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) { |
| 1912 | 1911 | timed_out = 1; |
| @@ -1927,6 +1926,15 @@ fetch_events: · 14 unmodified lines | ||
| 1927 | 1926 | } |
| 1928 | 1927 | |
| 1929 | 1928 | send_events: |
| 1929 | + if (fatal_signal_pending(current)) { | |
| 1930 | + /* | |
| 1931 | + * Always short-circuit for fatal signals to allow | |
| 1932 | + * threads to make a timely exit without the chance of | |
| 1933 | + * finding more events available and fetching | |
| 1934 | + * repeatedly. | |
| 1935 | + */ | |
| 1936 | + res = -EINTR; | |
| 1937 | + } | |
| 1930 | 1938 | /* |
| 1931 | 1939 | * Try to transfer events to user space. In case we get 0 events and |
| 1932 | 1940 | * there's still timeout left over, we go trying again in search of |
| @@ -1317,6 +1317,8 @@ int flush_old_exec(struct linux_binprm * bprm) · 1316 unmodified lines | ||
| 1317 | 1317 | */ |
| 1318 | 1318 | set_mm_exe_file(bprm->mm, bprm->file); |
| 1319 | 1319 | |
| 1320 | + would_dump(bprm, bprm->file); | |
| 1321 | + | |
| 1320 | 1322 | /* |
| 1321 | 1323 | * Release all of the old mmap stuff |
| 1322 | 1324 | */ |
| @@ -1876,8 +1878,6 @@ static int __do_execve_file(int fd, struct filename *filename, · 553 unmodified lines | ||
| 1876 | 1878 | if (retval < 0) |
| 1877 | 1879 | goto out; |
| 1878 | 1880 | |
| 1879 | − would_dump(bprm, bprm->file); | |
| 1880 | − | |
| 1881 | 1881 | retval = exec_binprm(bprm); |
| 1882 | 1882 | if (retval < 0) |
| 1883 | 1883 | goto out; |
| @@ -348,12 +348,13 @@ out: · 347 unmodified lines | ||
| 348 | 348 | } |
| 349 | 349 | |
| 350 | 350 | const struct file_operations exfat_file_operations = { |
| 351 | − .llseek = generic_file_llseek, | |
| 352 | − .read_iter = generic_file_read_iter, | |
| 353 | − .write_iter = generic_file_write_iter, | |
| 354 | − .mmap = generic_file_mmap, | |
| 355 | − .fsync = generic_file_fsync, | |
| 356 | − .splice_read = generic_file_splice_read, | |
| 351 | + .llseek = generic_file_llseek, | |
| 352 | + .read_iter = generic_file_read_iter, | |
| 353 | + .write_iter = generic_file_write_iter, | |
| 354 | + .mmap = generic_file_mmap, | |
| 355 | + .fsync = generic_file_fsync, | |
| 356 | + .splice_read = generic_file_splice_read, | |
| 357 | + .splice_write = iter_file_splice_write, | |
| 357 | 358 | }; |
| 358 | 359 | |
| 359 | 360 | const struct inode_operations exfat_file_inode_operations = { |
| @@ -692,6 +692,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, · 691 unmodified lines | ||
| 692 | 692 | exfat_fs_error(sb, |
| 693 | 693 | "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)", |
| 694 | 694 | i_size_read(dir), ei->dir.dir, ei->entry); |
| 695 | + kfree(es); | |
| 695 | 696 | return -EIO; |
| 696 | 697 | } |
| 697 | 698 | |
| @@ -203,6 +203,12 @@ enum { · 202 unmodified lines | ||
| 203 | 203 | Opt_errors, |
| 204 | 204 | Opt_discard, |
| 205 | 205 | Opt_time_offset, |
| 206 | + | |
| 207 | + /* Deprecated options */ | |
| 208 | + Opt_utf8, | |
| 209 | + Opt_debug, | |
| 210 | + Opt_namecase, | |
| 211 | + Opt_codepage, | |
| 206 | 212 | }; |
| 207 | 213 | |
| 208 | 214 | static const struct constant_table exfat_param_enums[] = { |
| @@ -223,6 +229,14 @@ static const struct fs_parameter_spec exfat_parameters[] = { · 14 unmodified lines | ||
| 223 | 229 | fsparam_enum("errors", Opt_errors, exfat_param_enums), |
| 224 | 230 | fsparam_flag("discard", Opt_discard), |
| 225 | 231 | fsparam_s32("time_offset", Opt_time_offset), |
| 232 | + __fsparam(NULL, "utf8", Opt_utf8, fs_param_deprecated, | |
| 233 | + NULL), | |
| 234 | + __fsparam(NULL, "debug", Opt_debug, fs_param_deprecated, | |
| 235 | + NULL), | |
| 236 | + __fsparam(fs_param_is_u32, "namecase", Opt_namecase, | |
| 237 | + fs_param_deprecated, NULL), | |
| 238 | + __fsparam(fs_param_is_u32, "codepage", Opt_codepage, | |
| 239 | + fs_param_deprecated, NULL), | |
| 226 | 240 | {} |
| 227 | 241 | }; |
| 228 | 242 | |
| @@ -278,6 +292,11 @@ static int exfat_parse_param(struct fs_context *fc, struct fs_parameter *param) · 49 unmodified lines | ||
| 278 | 292 | return -EINVAL; |
| 279 | 293 | opts->time_offset = result.int_32; |
| 280 | 294 | break; |
| 295 | + case Opt_utf8: | |
| 296 | + case Opt_debug: | |
| 297 | + case Opt_namecase: | |
| 298 | + case Opt_codepage: | |
| 299 | + break; | |
| 281 | 300 | default: |
| 282 | 301 | return -EINVAL; |
| 283 | 302 | } |
| @@ -722,7 +722,7 @@ enum { · 721 unmodified lines | ||
| 722 | 722 | #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF |
| 723 | 723 | |
| 724 | 724 | /* Max logical block we can support */ |
| 725 | −#define EXT4_MAX_LOGICAL_BLOCK 0xFFFFFFFF | |
| 725 | +#define EXT4_MAX_LOGICAL_BLOCK 0xFFFFFFFE | |
| 726 | 726 | |
| 727 | 727 | /* |
| 728 | 728 | * Structure of an inode on the disk |
| @@ -4832,6 +4832,28 @@ static const struct iomap_ops ext4_iomap_xattr_ops = { · 4831 unmodified lines | ||
| 4832 | 4832 | .iomap_begin = ext4_iomap_xattr_begin, |
| 4833 | 4833 | }; |
| 4834 | 4834 | |
| 4835 | +static int ext4_fiemap_check_ranges(struct inode *inode, u64 start, u64 *len) | |
| 4836 | +{ | |
| 4837 | + u64 maxbytes; | |
| 4838 | + | |
| 4839 | + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | |
| 4840 | + maxbytes = inode->i_sb->s_maxbytes; | |
| 4841 | + else | |
| 4842 | + maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes; | |
| 4843 | + | |
| 4844 | + if (*len == 0) | |
| 4845 | + return -EINVAL; | |
| 4846 | + if (start > maxbytes) | |
| 4847 | + return -EFBIG; | |
| 4848 | + | |
| 4849 | + /* | |
| 4850 | + * Shrink request scope to what the fs can actually handle. | |
| 4851 | + */ | |
| 4852 | + if (*len > maxbytes || (maxbytes - *len) < start) | |
| 4853 | + *len = maxbytes - start; | |
| 4854 | + return 0; | |
| 4855 | +} | |
| 4856 | + | |
| 4835 | 4857 | static int _ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 4836 | 4858 | __u64 start, __u64 len, bool from_es_cache) |
| 4837 | 4859 | { |
| @@ -4852,6 +4874,15 @@ static int _ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, · 14 unmodified lines | ||
| 4852 | 4874 | if (fiemap_check_flags(fieinfo, ext4_fiemap_flags)) |
| 4853 | 4875 | return -EBADR; |
| 4854 | 4876 | |
| 4877 | + /* | |
| 4878 | + * For bitmap files the maximum size limit could be smaller than | |
| 4879 | + * s_maxbytes, so check len here manually instead of just relying on the | |
| 4880 | + * generic check. | |
| 4881 | + */ | |
| 4882 | + error = ext4_fiemap_check_ranges(inode, start, &len); | |
| 4883 | + if (error) | |
| 4884 | + return error; | |
| 4885 | + | |
| 4855 | 4886 | if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { |
| 4856 | 4887 | fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR; |
| 4857 | 4888 | error = iomap_fiemap(inode, fieinfo, start, len, |
| @@ -733,29 +733,6 @@ static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa) · 732 unmodified lines | ||
| 733 | 733 | fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); |
| 734 | 734 | } |
| 735 | 735 | |
| 736 | −/* copied from fs/ioctl.c */ | |
| 737 | −static int fiemap_check_ranges(struct super_block *sb, | |
| 738 | − u64 start, u64 len, u64 *new_len) | |
| 739 | −{ | |
| 740 | − u64 maxbytes = (u64) sb->s_maxbytes; | |
| 741 | − | |
| 742 | − *new_len = len; | |
| 743 | − | |
| 744 | − if (len == 0) | |
| 745 | − return -EINVAL; | |
| 746 | − | |
| 747 | − if (start > maxbytes) | |
| 748 | − return -EFBIG; | |
| 749 | − | |
| 750 | − /* | |
| 751 | − * Shrink request scope to what the fs can actually handle. | |
| 752 | − */ | |
| 753 | − if (len > maxbytes || (maxbytes - len) < start) | |
| 754 | − *new_len = maxbytes - start; | |
| 755 | − | |
| 756 | − return 0; | |
| 757 | −} | |
| 758 | − | |
| 759 | 736 | /* So that the fiemap access checks can't overflow on 32 bit machines. */ |
| 760 | 737 | #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent)) |
| 761 | 738 | |
| @@ -765,8 +742,6 @@ static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) · 3 unmodified lines | ||
| 765 | 742 | struct fiemap __user *ufiemap = (struct fiemap __user *) arg; |
| 766 | 743 | struct fiemap_extent_info fieinfo = { 0, }; |
| 767 | 744 | struct inode *inode = file_inode(filp); |
| 768 | − struct super_block *sb = inode->i_sb; | |
| 769 | − u64 len; | |
| 770 | 745 | int error; |
| 771 | 746 | |
| 772 | 747 | if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap))) |
| @@ -775,11 +750,6 @@ static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) · 2 unmodified lines | ||
| 775 | 750 | if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS) |
| 776 | 751 | return -EINVAL; |
| 777 | 752 | |
| 778 | − error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length, | |
| 779 | − &len); | |
| 780 | − if (error) | |
| 781 | − return error; | |
| 782 | − | |
| 783 | 753 | fieinfo.fi_flags = fiemap.fm_flags; |
| 784 | 754 | fieinfo.fi_extents_max = fiemap.fm_extent_count; |
| 785 | 755 | fieinfo.fi_extents_start = ufiemap->fm_extents; |
| @@ -792,7 +762,8 @@ static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) · 6 unmodified lines | ||
| 792 | 762 | if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC) |
| 793 | 763 | filemap_write_and_wait(inode->i_mapping); |
| 794 | 764 | |
| 795 | − error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start, len); | |
| 765 | + error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start, | |
| 766 | + fiemap.fm_length); | |
| 796 | 767 | fiemap.fm_flags = fieinfo.fi_flags; |
| 797 | 768 | fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped; |
| 798 | 769 | if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap))) |
| @@ -70,7 +70,7 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt, · 69 unmodified lines | ||
| 70 | 70 | */ |
| 71 | 71 | static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) |
| 72 | 72 | { |
| 73 | − unsigned int cpy, set; | |
| 73 | + size_t cpy, set; | |
| 74 | 74 | |
| 75 | 75 | BUG_ON(nfdt->max_fds < ofdt->max_fds); |
| 76 | 76 | |
| @@ -528,10 +528,12 @@ lower_metapath: · 527 unmodified lines | ||
| 528 | 528 | |
| 529 | 529 | /* Advance in metadata tree. */ |
| 530 | 530 | (mp->mp_list[hgt])++; |
| 531 | − if (mp->mp_list[hgt] >= sdp->sd_inptrs) { | |
| 532 | − if (!hgt) | |
| 531 | + if (hgt) { | |
| 532 | + if (mp->mp_list[hgt] >= sdp->sd_inptrs) | |
| 533 | + goto lower_metapath; | |
| 534 | + } else { | |
| 535 | + if (mp->mp_list[hgt] >= sdp->sd_diptrs) | |
| 533 | 536 | break; |
| 534 | − goto lower_metapath; | |
| 535 | 537 | } |
| 536 | 538 | |
| 537 | 539 | fill_up_metapath: |
| @@ -876,10 +878,9 @@ static int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length, · 338 unmodified lines | ||
| 876 | 878 | ret = -ENOENT; |
| 877 | 879 | goto unlock; |
| 878 | 880 | } else { |
| 879 | − /* report a hole */ | |
| 880 | 881 | iomap->offset = pos; |
| 881 | 882 | iomap->length = length; |
| 882 | − goto do_alloc; | |
| 883 | + goto hole_found; | |
| 883 | 884 | } |
| 884 | 885 | } |
| 885 | 886 | iomap->length = size; |
| @@ -933,8 +934,6 @@ unlock: · 47 unmodified lines | ||
| 933 | 934 | return ret; |
| 934 | 935 | |
| 935 | 936 | do_alloc: |
| 936 | − iomap->addr = IOMAP_NULL_ADDR; | |
| 937 | − iomap->type = IOMAP_HOLE; | |
| 938 | 937 | if (flags & IOMAP_REPORT) { |
| 939 | 938 | if (pos >= size) |
| 940 | 939 | ret = -ENOENT; |
| @@ -956,6 +955,9 @@ do_alloc: · 15 unmodified lines | ||
| 956 | 955 | if (pos < size && height == ip->i_height) |
| 957 | 956 | ret = gfs2_hole_size(inode, lblock, len, mp, iomap); |
| 958 | 957 | } |
| 958 | +hole_found: | |
| 959 | + iomap->addr = IOMAP_NULL_ADDR; | |
| 960 | + iomap->type = IOMAP_HOLE; | |
| 959 | 961 | goto out; |
| 960 | 962 | } |
| 961 | 963 | |
| @@ -613,7 +613,7 @@ __acquires(&gl->gl_lockref.lock) · 612 unmodified lines | ||
| 613 | 613 | fs_err(sdp, "Error %d syncing glock \n", ret); |
| 614 | 614 | gfs2_dump_glock(NULL, gl, true); |
| 615 | 615 | } |
| 616 | − return; | |
| 616 | + goto skip_inval; | |
| 617 | 617 | } |
| 618 | 618 | } |
| 619 | 619 | if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags)) { |
| @@ -633,6 +633,7 @@ __acquires(&gl->gl_lockref.lock) · 13 unmodified lines | ||
| 633 | 633 | clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | +skip_inval: | |
| 636 | 637 | gfs2_glock_hold(gl); |
| 637 | 638 | /* |
| 638 | 639 | * Check for an error encountered since we called go_sync and go_inval. |
| @@ -722,9 +723,6 @@ __acquires(&gl->gl_lockref.lock) · 83 unmodified lines | ||
| 722 | 723 | goto out_unlock; |
| 723 | 724 | if (nonblock) |
| 724 | 725 | goto out_sched; |
| 725 | − smp_mb(); | |
| 726 | − if (atomic_read(&gl->gl_revokes) != 0) | |
| 727 | − goto out_sched; | |
| 728 | 726 | set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); |
| 729 | 727 | GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE); |
| 730 | 728 | gl->gl_target = gl->gl_demote_state; |
| @@ -622,7 +622,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, · 621 unmodified lines | ||
| 622 | 622 | error = finish_no_open(file, NULL); |
| 623 | 623 | } |
| 624 | 624 | gfs2_glock_dq_uninit(ghs); |
| 625 | − return error; | |
| 625 | + goto fail; | |
| 626 | 626 | } else if (error != -ENOENT) { |
| 627 | 627 | goto fail_gunlock; |
| 628 | 628 | } |
| @@ -764,9 +764,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, · 135 unmodified lines | ||
| 764 | 764 | error = finish_open(file, dentry, gfs2_open_common); |
| 765 | 765 | } |
| 766 | 766 | gfs2_glock_dq_uninit(ghs); |
| 767 | + gfs2_qa_put(ip); | |
| 767 | 768 | gfs2_glock_dq_uninit(ghs + 1); |
| 768 | 769 | clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); |
| 769 | 770 | gfs2_glock_put(io_gl); |
| 771 | + gfs2_qa_put(dip); | |
| 770 | 772 | return error; |
| 771 | 773 | |
| 772 | 774 | fail_gunlock3: |
| @@ -776,7 +778,6 @@ fail_gunlock2: · 3 unmodified lines | ||
| 776 | 778 | clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); |
| 777 | 779 | gfs2_glock_put(io_gl); |
| 778 | 780 | fail_free_inode: |
| 779 | − gfs2_qa_put(ip); | |
| 780 | 781 | if (ip->i_gl) { |
| 781 | 782 | glock_clear_object(ip->i_gl, ip); |
| 782 | 783 | gfs2_glock_put(ip->i_gl); |
| @@ -1005,7 +1006,7 @@ out_gunlock: · 222 unmodified lines | ||
| 1005 | 1006 | out_child: |
| 1006 | 1007 | gfs2_glock_dq(ghs); |
| 1007 | 1008 | out_parent: |
| 1008 | − gfs2_qa_put(ip); | |
| 1009 | + gfs2_qa_put(dip); | |
| 1009 | 1010 | gfs2_holder_uninit(ghs); |
| 1010 | 1011 | gfs2_holder_uninit(ghs + 1); |
| 1011 | 1012 | return error; |
| @@ -669,13 +669,13 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 668 unmodified lines | ||
| 669 | 669 | struct buffer_head *bh = bd->bd_bh; |
| 670 | 670 | struct gfs2_glock *gl = bd->bd_gl; |
| 671 | 671 | |
| 672 | + sdp->sd_log_num_revoke++; | |
| 673 | + if (atomic_inc_return(&gl->gl_revokes) == 1) | |
| 674 | + gfs2_glock_hold(gl); | |
| 672 | 675 | bh->b_private = NULL; |
| 673 | 676 | bd->bd_blkno = bh->b_blocknr; |
| 674 | 677 | gfs2_remove_from_ail(bd); /* drops ref on bh */ |
| 675 | 678 | bd->bd_bh = NULL; |
| 676 | − sdp->sd_log_num_revoke++; | |
| 677 | − if (atomic_inc_return(&gl->gl_revokes) == 1) | |
| 678 | − gfs2_glock_hold(gl); | |
| 679 | 679 | set_bit(GLF_LFLUSH, &gl->gl_flags); |
| 680 | 680 | list_add(&bd->bd_list, &sdp->sd_log_revokes); |
| 681 | 681 | } |
| @@ -1131,6 +1131,10 @@ int gfs2_logd(void *data) · 449 unmodified lines | ||
| 1131 | 1131 | |
| 1132 | 1132 | while (!kthread_should_stop()) { |
| 1133 | 1133 | |
| 1134 | + if (gfs2_withdrawn(sdp)) { | |
| 1135 | + msleep_interruptible(HZ); | |
| 1136 | + continue; | |
| 1137 | + } | |
| 1134 | 1138 | /* Check for errors writing to the journal */ |
| 1135 | 1139 | if (sdp->sd_log_error) { |
| 1136 | 1140 | gfs2_lm(sdp, |
| @@ -1139,6 +1143,7 @@ int gfs2_logd(void *data) · 2 unmodified lines | ||
| 1139 | 1143 | "prevent further damage.\n", |
| 1140 | 1144 | sdp->sd_fsname, sdp->sd_log_error); |
| 1141 | 1145 | gfs2_withdraw(sdp); |
| 1146 | + continue; | |
| 1142 | 1147 | } |
| 1143 | 1148 | |
| 1144 | 1149 | did_flush = false; |
| @@ -263,7 +263,7 @@ static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno, · 262 unmodified lines | ||
| 263 | 263 | struct super_block *sb = sdp->sd_vfs; |
| 264 | 264 | struct bio *bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); |
| 265 | 265 | |
| 266 | − bio->bi_iter.bi_sector = blkno << (sb->s_blocksize_bits - 9); | |
| 266 | + bio->bi_iter.bi_sector = blkno << sdp->sd_fsb2bb_shift; | |
| 267 | 267 | bio_set_dev(bio, sb->s_bdev); |
| 268 | 268 | bio->bi_end_io = end_io; |
| 269 | 269 | bio->bi_private = sdp; |
| @@ -509,7 +509,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head, · 239 unmodified lines | ||
| 509 | 509 | unsigned int bsize = sdp->sd_sb.sb_bsize, off; |
| 510 | 510 | unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift; |
| 511 | 511 | unsigned int shift = PAGE_SHIFT - bsize_shift; |
| 512 | − unsigned int readahead_blocks = BIO_MAX_PAGES << shift; | |
| 512 | + unsigned int max_bio_size = 2 * 1024 * 1024; | |
| 513 | 513 | struct gfs2_journal_extent *je; |
| 514 | 514 | int sz, ret = 0; |
| 515 | 515 | struct bio *bio = NULL; |
| @@ -537,12 +537,17 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head, · 21 unmodified lines | ||
| 537 | 537 | off = 0; |
| 538 | 538 | } |
| 539 | 539 | |
| 540 | − if (!bio || (bio_chained && !off)) { | |
| 540 | + if (!bio || (bio_chained && !off) || | |
| 541 | + bio->bi_iter.bi_size >= max_bio_size) { | |
| 541 | 542 | /* start new bio */ |
| 542 | 543 | } else { |
| 543 | − sz = bio_add_page(bio, page, bsize, off); | |
| 544 | − if (sz == bsize) | |
| 545 | − goto block_added; | |
| 544 | + sector_t sector = dblock << sdp->sd_fsb2bb_shift; | |
| 545 | + | |
| 546 | + if (bio_end_sector(bio) == sector) { | |
| 547 | + sz = bio_add_page(bio, page, bsize, off); | |
| 548 | + if (sz == bsize) | |
| 549 | + goto block_added; | |
| 550 | + } | |
| 546 | 551 | if (off) { |
| 547 | 552 | unsigned int blocks = |
| 548 | 553 | (PAGE_SIZE - off) >> bsize_shift; |
| @@ -568,7 +573,7 @@ block_added: · 19 unmodified lines | ||
| 568 | 573 | off += bsize; |
| 569 | 574 | if (off == PAGE_SIZE) |
| 570 | 575 | page = NULL; |
| 571 | − if (blocks_submitted < blocks_read + readahead_blocks) { | |
| 576 | + if (blocks_submitted < 2 * max_bio_size >> bsize_shift) { | |
| 572 | 577 | /* Keep at least one bio in flight */ |
| 573 | 578 | continue; |
| 574 | 579 | } |
| @@ -252,7 +252,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, · 251 unmodified lines | ||
| 252 | 252 | int num = 0; |
| 253 | 253 | |
| 254 | 254 | if (unlikely(gfs2_withdrawn(sdp)) && |
| 255 | − (!sdp->sd_jdesc || (blkno != sdp->sd_jdesc->jd_no_addr))) { | |
| 255 | + (!sdp->sd_jdesc || gl != sdp->sd_jinode_gl)) { | |
| 256 | 256 | *bhp = NULL; |
| 257 | 257 | return -EIO; |
| 258 | 258 | } |
| @@ -1051,8 +1051,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) · 1050 unmodified lines | ||
| 1051 | 1051 | u32 x; |
| 1052 | 1052 | int error = 0; |
| 1053 | 1053 | |
| 1054 | − if (capable(CAP_SYS_RESOURCE) || | |
| 1055 | − sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | |
| 1054 | + if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | |
| 1056 | 1055 | return 0; |
| 1057 | 1056 | |
| 1058 | 1057 | error = gfs2_quota_hold(ip, uid, gid); |
| @@ -1125,7 +1124,7 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) · 66 unmodified lines | ||
| 1125 | 1124 | int found; |
| 1126 | 1125 | |
| 1127 | 1126 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) |
| 1128 | − goto out; | |
| 1127 | + return; | |
| 1129 | 1128 | |
| 1130 | 1129 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
| 1131 | 1130 | struct gfs2_quota_data *qd; |
| @@ -1162,7 +1161,6 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) · 30 unmodified lines | ||
| 1162 | 1161 | qd_unlock(qda[x]); |
| 1163 | 1162 | } |
| 1164 | 1163 | |
| 1165 | −out: | |
| 1166 | 1164 | gfs2_quota_unhold(ip); |
| 1167 | 1165 | } |
| 1168 | 1166 | |
| @@ -1210,9 +1208,6 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, · 41 unmodified lines | ||
| 1210 | 1208 | if (!test_bit(GIF_QD_LOCKED, &ip->i_flags)) |
| 1211 | 1209 | return 0; |
| 1212 | 1210 | |
| 1213 | − if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | |
| 1214 | − return 0; | |
| 1215 | − | |
| 1216 | 1211 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
| 1217 | 1212 | qd = ip->i_qadata->qa_qd[x]; |
| 1218 | 1213 | |
| @@ -1270,7 +1265,9 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, · 51 unmodified lines | ||
| 1270 | 1265 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
| 1271 | 1266 | return; |
| 1272 | 1267 | |
| 1273 | − BUG_ON(ip->i_qadata->qa_ref <= 0); | |
| 1268 | + if (gfs2_assert_withdraw(sdp, ip->i_qadata && | |
| 1269 | + ip->i_qadata->qa_ref > 0)) | |
| 1270 | + return; | |
| 1274 | 1271 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
| 1275 | 1272 | qd = ip->i_qadata->qa_qd[x]; |
| 1276 | 1273 | |
| @@ -44,7 +44,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip, · 43 unmodified lines | ||
| 44 | 44 | int ret; |
| 45 | 45 | |
| 46 | 46 | ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ |
| 47 | − if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | |
| 47 | + if (capable(CAP_SYS_RESOURCE) || | |
| 48 | + sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | |
| 48 | 49 | return 0; |
| 49 | 50 | ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
| 50 | 51 | if (ret) |
| @@ -1404,7 +1404,6 @@ out: · 1403 unmodified lines | ||
| 1404 | 1404 | if (ip->i_qadata) |
| 1405 | 1405 | gfs2_assert_warn(sdp, ip->i_qadata->qa_ref == 0); |
| 1406 | 1406 | gfs2_rs_delete(ip, NULL); |
| 1407 | − gfs2_qa_put(ip); | |
| 1408 | 1407 | gfs2_ordered_del_inode(ip); |
| 1409 | 1408 | clear_inode(inode); |
| 1410 | 1409 | gfs2_dir_hash_inval(ip); |
| @@ -119,6 +119,12 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) · 118 unmodified lines | ||
| 119 | 119 | if (!sb_rdonly(sdp->sd_vfs)) |
| 120 | 120 | ret = gfs2_make_fs_ro(sdp); |
| 121 | 121 | |
| 122 | + if (sdp->sd_lockstruct.ls_ops->lm_lock == NULL) { /* lock_nolock */ | |
| 123 | + if (!ret) | |
| 124 | + ret = -EIO; | |
| 125 | + clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); | |
| 126 | + goto skip_recovery; | |
| 127 | + } | |
| 122 | 128 | /* |
| 123 | 129 | * Drop the glock for our journal so another node can recover it. |
| 124 | 130 | */ |
| @@ -159,10 +165,6 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) · 34 unmodified lines | ||
| 159 | 165 | wait_on_bit(&gl->gl_flags, GLF_FREEING, TASK_UNINTERRUPTIBLE); |
| 160 | 166 | } |
| 161 | 167 | |
| 162 | − if (sdp->sd_lockstruct.ls_ops->lm_lock == NULL) { /* lock_nolock */ | |
| 163 | − clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); | |
| 164 | − goto skip_recovery; | |
| 165 | − } | |
| 166 | 168 | /* |
| 167 | 169 | * Dequeue the "live" glock, but keep a reference so it's never freed. |
| 168 | 170 | */ |
| @@ -619,6 +619,8 @@ struct io_kiocb { · 618 unmodified lines | ||
| 619 | 619 | bool needs_fixed_file; |
| 620 | 620 | u8 opcode; |
| 621 | 621 | |
| 622 | + u16 buf_index; | |
| 623 | + | |
| 622 | 624 | struct io_ring_ctx *ctx; |
| 623 | 625 | struct list_head list; |
| 624 | 626 | unsigned int flags; |
| @@ -924,6 +926,7 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) · 299 unmodified lines | ||
| 924 | 926 | goto err; |
| 925 | 927 | |
| 926 | 928 | ctx->flags = p->flags; |
| 929 | + init_waitqueue_head(&ctx->sqo_wait); | |
| 927 | 930 | init_waitqueue_head(&ctx->cq_wait); |
| 928 | 931 | INIT_LIST_HEAD(&ctx->cq_overflow_list); |
| 929 | 932 | init_completion(&ctx->completions[0]); |
| @@ -1394,10 +1397,6 @@ static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb) · 464 unmodified lines | ||
| 1394 | 1397 | for (i = 0; i < rb->to_free; i++) { |
| 1395 | 1398 | struct io_kiocb *req = rb->reqs[i]; |
| 1396 | 1399 | |
| 1397 | − if (req->flags & REQ_F_FIXED_FILE) { | |
| 1398 | − req->file = NULL; | |
| 1399 | − percpu_ref_put(req->fixed_file_refs); | |
| 1400 | − } | |
| 1401 | 1400 | if (req->flags & REQ_F_INFLIGHT) |
| 1402 | 1401 | inflight++; |
| 1403 | 1402 | __io_req_aux_free(req); |
| @@ -1670,7 +1669,7 @@ static inline bool io_req_multi_free(struct req_batch *rb, struct io_kiocb *req) · 266 unmodified lines | ||
| 1670 | 1669 | if ((req->flags & REQ_F_LINK_HEAD) || io_is_fallback_req(req)) |
| 1671 | 1670 | return false; |
| 1672 | 1671 | |
| 1673 | − if (!(req->flags & REQ_F_FIXED_FILE) || req->io) | |
| 1672 | + if (req->file || req->io) | |
| 1674 | 1673 | rb->need_iter++; |
| 1675 | 1674 | |
| 1676 | 1675 | rb->reqs[rb->to_free++] = req; |
| @@ -2104,9 +2103,7 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 427 unmodified lines | ||
| 2104 | 2103 | |
| 2105 | 2104 | req->rw.addr = READ_ONCE(sqe->addr); |
| 2106 | 2105 | req->rw.len = READ_ONCE(sqe->len); |
| 2107 | − /* we own ->private, reuse it for the buffer index / buffer ID */ | |
| 2108 | − req->rw.kiocb.private = (void *) (unsigned long) | |
| 2109 | − READ_ONCE(sqe->buf_index); | |
| 2106 | + req->buf_index = READ_ONCE(sqe->buf_index); | |
| 2110 | 2107 | return 0; |
| 2111 | 2108 | } |
| 2112 | 2109 | |
| @@ -2149,7 +2146,7 @@ static ssize_t io_import_fixed(struct io_kiocb *req, int rw, · 36 unmodified lines | ||
| 2149 | 2146 | struct io_ring_ctx *ctx = req->ctx; |
| 2150 | 2147 | size_t len = req->rw.len; |
| 2151 | 2148 | struct io_mapped_ubuf *imu; |
| 2152 | − unsigned index, buf_index; | |
| 2149 | + u16 index, buf_index; | |
| 2153 | 2150 | size_t offset; |
| 2154 | 2151 | u64 buf_addr; |
| 2155 | 2152 | |
| @@ -2157,7 +2154,7 @@ static ssize_t io_import_fixed(struct io_kiocb *req, int rw, · 1 unmodified line | ||
| 2157 | 2154 | if (unlikely(!ctx->user_bufs)) |
| 2158 | 2155 | return -EFAULT; |
| 2159 | 2156 | |
| 2160 | − buf_index = (unsigned long) req->rw.kiocb.private; | |
| 2157 | + buf_index = req->buf_index; | |
| 2161 | 2158 | if (unlikely(buf_index >= ctx->nr_user_bufs)) |
| 2162 | 2159 | return -EFAULT; |
| 2163 | 2160 | |
| @@ -2273,10 +2270,10 @@ static void __user *io_rw_buffer_select(struct io_kiocb *req, size_t *len, · 109 unmodified lines | ||
| 2273 | 2270 | bool needs_lock) |
| 2274 | 2271 | { |
| 2275 | 2272 | struct io_buffer *kbuf; |
| 2276 | − int bgid; | |
| 2273 | + u16 bgid; | |
| 2277 | 2274 | |
| 2278 | 2275 | kbuf = (struct io_buffer *) (unsigned long) req->rw.addr; |
| 2279 | − bgid = (int) (unsigned long) req->rw.kiocb.private; | |
| 2276 | + bgid = req->buf_index; | |
| 2280 | 2277 | kbuf = io_buffer_select(req, len, bgid, kbuf, needs_lock); |
| 2281 | 2278 | if (IS_ERR(kbuf)) |
| 2282 | 2279 | return kbuf; |
| @@ -2367,7 +2364,7 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req, · 84 unmodified lines | ||
| 2367 | 2364 | } |
| 2368 | 2365 | |
| 2369 | 2366 | /* buffer index only valid with fixed read/write, or buffer select */ |
| 2370 | − if (req->rw.kiocb.private && !(req->flags & REQ_F_BUFFER_SELECT)) | |
| 2367 | + if (req->buf_index && !(req->flags & REQ_F_BUFFER_SELECT)) | |
| 2371 | 2368 | return -EINVAL; |
| 2372 | 2369 | |
| 2373 | 2370 | if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE) { |
| @@ -2767,16 +2764,16 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock) · 393 unmodified lines | ||
| 2767 | 2764 | struct file *out = sp->file_out; |
| 2768 | 2765 | unsigned int flags = sp->flags & ~SPLICE_F_FD_IN_FIXED; |
| 2769 | 2766 | loff_t *poff_in, *poff_out; |
| 2770 | − long ret; | |
| 2767 | + long ret = 0; | |
| 2771 | 2768 | |
| 2772 | 2769 | if (force_nonblock) |
| 2773 | 2770 | return -EAGAIN; |
| 2774 | 2771 | |
| 2775 | 2772 | poff_in = (sp->off_in == -1) ? NULL : &sp->off_in; |
| 2776 | 2773 | poff_out = (sp->off_out == -1) ? NULL : &sp->off_out; |
| 2777 | − ret = do_splice(in, poff_in, out, poff_out, sp->len, flags); | |
| 2778 | − if (force_nonblock && ret == -EAGAIN) | |
| 2779 | − return -EAGAIN; | |
| 2774 | + | |
| 2775 | + if (sp->len) | |
| 2776 | + ret = do_splice(in, poff_in, out, poff_out, sp->len, flags); | |
| 2780 | 2777 | |
| 2781 | 2778 | io_put_file(req, in, (sp->flags & SPLICE_F_FD_IN_FIXED)); |
| 2782 | 2779 | req->flags &= ~REQ_F_NEED_CLEANUP; |
| @@ -4138,12 +4135,14 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll, · 1355 unmodified lines | ||
| 4138 | 4135 | req->result = mask; |
| 4139 | 4136 | init_task_work(&req->task_work, func); |
| 4140 | 4137 | /* |
| 4141 | − * If this fails, then the task is exiting. Punt to one of the io-wq | |
| 4142 | − * threads to ensure the work gets run, we can't always rely on exit | |
| 4143 | − * cancelation taking care of this. | |
| 4138 | + * If this fails, then the task is exiting. When a task exits, the | |
| 4139 | + * work gets canceled, so just cancel this request as well instead | |
| 4140 | + * of executing it. We can't safely execute it anyway, as we may not | |
| 4141 | + * have the needed state needed for it anyway. | |
| 4144 | 4142 | */ |
| 4145 | 4143 | ret = task_work_add(tsk, &req->task_work, true); |
| 4146 | 4144 | if (unlikely(ret)) { |
| 4145 | + WRITE_ONCE(poll->canceled, true); | |
| 4147 | 4146 | tsk = io_wq_get_task(req->ctx->io_wq); |
| 4148 | 4147 | task_work_add(tsk, &req->task_work, true); |
| 4149 | 4148 | } |
| @@ -5014,12 +5013,13 @@ static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 864 unmodified lines | ||
| 5014 | 5013 | if (!req_need_defer(req) && list_empty_careful(&ctx->defer_list)) |
| 5015 | 5014 | return 0; |
| 5016 | 5015 | |
| 5017 | − if (!req->io && io_alloc_async_ctx(req)) | |
| 5018 | − return -EAGAIN; | |
| 5019 | − | |
| 5020 | − ret = io_req_defer_prep(req, sqe); | |
| 5021 | − if (ret < 0) | |
| 5022 | − return ret; | |
| 5016 | + if (!req->io) { | |
| 5017 | + if (io_alloc_async_ctx(req)) | |
| 5018 | + return -EAGAIN; | |
| 5019 | + ret = io_req_defer_prep(req, sqe); | |
| 5020 | + if (ret < 0) | |
| 5021 | + return ret; | |
| 5022 | + } | |
| 5023 | 5023 | |
| 5024 | 5024 | spin_lock_irq(&ctx->completion_lock); |
| 5025 | 5025 | if (!req_need_defer(req) && list_empty(&ctx->defer_list)) { |
| @@ -5306,7 +5306,8 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 280 unmodified lines | ||
| 5306 | 5306 | if (ret) |
| 5307 | 5307 | return ret; |
| 5308 | 5308 | |
| 5309 | − if (ctx->flags & IORING_SETUP_IOPOLL) { | |
| 5309 | + /* If the op doesn't have a file, we're not polling for it */ | |
| 5310 | + if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) { | |
| 5310 | 5311 | const bool in_async = io_wq_current_is_worker(); |
| 5311 | 5312 | |
| 5312 | 5313 | if (req->result == -EAGAIN) |
| @@ -5607,9 +5608,15 @@ fail_req: · 294 unmodified lines | ||
| 5607 | 5608 | io_double_put_req(req); |
| 5608 | 5609 | } |
| 5609 | 5610 | } else if (req->flags & REQ_F_FORCE_ASYNC) { |
| 5610 | − ret = io_req_defer_prep(req, sqe); | |
| 5611 | − if (unlikely(ret < 0)) | |
| 5612 | − goto fail_req; | |
| 5611 | + if (!req->io) { | |
| 5612 | + ret = -EAGAIN; | |
| 5613 | + if (io_alloc_async_ctx(req)) | |
| 5614 | + goto fail_req; | |
| 5615 | + ret = io_req_defer_prep(req, sqe); | |
| 5616 | + if (unlikely(ret < 0)) | |
| 5617 | + goto fail_req; | |
| 5618 | + } | |
| 5619 | + | |
| 5613 | 5620 | /* |
| 5614 | 5621 | * Never try inline submit of IOSQE_ASYNC is set, go straight |
| 5615 | 5622 | * to async execution. |
| @@ -6025,6 +6032,7 @@ static int io_sq_thread(void *data) · 409 unmodified lines | ||
| 6025 | 6032 | finish_wait(&ctx->sqo_wait, &wait); |
| 6026 | 6033 | |
| 6027 | 6034 | ctx->rings->sq_flags &= ~IORING_SQ_NEED_WAKEUP; |
| 6035 | + ret = 0; | |
| 6028 | 6036 | continue; |
| 6029 | 6037 | } |
| 6030 | 6038 | finish_wait(&ctx->sqo_wait, &wait); |
| @@ -6838,7 +6846,6 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, · 807 unmodified lines | ||
| 6838 | 6846 | { |
| 6839 | 6847 | int ret; |
| 6840 | 6848 | |
| 6841 | − init_waitqueue_head(&ctx->sqo_wait); | |
| 6842 | 6849 | mmgrab(current->mm); |
| 6843 | 6850 | ctx->sqo_mm = current->mm; |
| 6844 | 6851 | |
| @@ -118,8 +118,6 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int · 117 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | nfss->fscache_key = NULL; |
| 120 | 120 | nfss->fscache = NULL; |
| 121 | − if (!(nfss->options & NFS_OPTION_FSCACHE)) | |
| 122 | − return; | |
| 123 | 121 | if (!uniq) { |
| 124 | 122 | uniq = ""; |
| 125 | 123 | ulen = 1; |
| @@ -188,7 +186,8 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int · 62 unmodified lines | ||
| 188 | 186 | /* create a cache index for looking up filehandles */ |
| 189 | 187 | nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, |
| 190 | 188 | &nfs_fscache_super_index_def, |
| 191 | − key, sizeof(*key) + ulen, | |
| 189 | + &key->key, | |
| 190 | + sizeof(key->key) + ulen, | |
| 192 | 191 | NULL, 0, |
| 193 | 192 | nfss, 0, true); |
| 194 | 193 | dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", |
| @@ -226,6 +225,19 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) · 31 unmodified lines | ||
| 226 | 225 | } |
| 227 | 226 | } |
| 228 | 227 | |
| 228 | +static void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata, | |
| 229 | + struct nfs_inode *nfsi) | |
| 230 | +{ | |
| 231 | + memset(auxdata, 0, sizeof(*auxdata)); | |
| 232 | + auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; | |
| 233 | + auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; | |
| 234 | + auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; | |
| 235 | + auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; | |
| 236 | + | |
| 237 | + if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) | |
| 238 | + auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); | |
| 239 | +} | |
| 240 | + | |
| 229 | 241 | /* |
| 230 | 242 | * Initialise the per-inode cache cookie pointer for an NFS inode. |
| 231 | 243 | */ |
| @@ -239,14 +251,7 @@ void nfs_fscache_init_inode(struct inode *inode) · 7 unmodified lines | ||
| 239 | 251 | if (!(nfss->fscache && S_ISREG(inode->i_mode))) |
| 240 | 252 | return; |
| 241 | 253 | |
| 242 | − memset(&auxdata, 0, sizeof(auxdata)); | |
| 243 | − auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; | |
| 244 | − auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; | |
| 245 | − auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; | |
| 246 | − auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; | |
| 247 | − | |
| 248 | − if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) | |
| 249 | − auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); | |
| 254 | + nfs_fscache_update_auxdata(&auxdata, nfsi); | |
| 250 | 255 | |
| 251 | 256 | nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, |
| 252 | 257 | &nfs_fscache_inode_object_def, |
| @@ -266,11 +271,7 @@ void nfs_fscache_clear_inode(struct inode *inode) · 13 unmodified lines | ||
| 266 | 271 | |
| 267 | 272 | dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); |
| 268 | 273 | |
| 269 | − memset(&auxdata, 0, sizeof(auxdata)); | |
| 270 | − auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; | |
| 271 | − auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; | |
| 272 | − auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; | |
| 273 | − auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; | |
| 274 | + nfs_fscache_update_auxdata(&auxdata, nfsi); | |
| 274 | 275 | fscache_relinquish_cookie(cookie, &auxdata, false); |
| 275 | 276 | nfsi->fscache = NULL; |
| 276 | 277 | } |
| @@ -310,11 +311,7 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp) · 33 unmodified lines | ||
| 310 | 311 | if (!fscache_cookie_valid(cookie)) |
| 311 | 312 | return; |
| 312 | 313 | |
| 313 | − memset(&auxdata, 0, sizeof(auxdata)); | |
| 314 | − auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; | |
| 315 | − auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; | |
| 316 | − auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; | |
| 317 | − auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; | |
| 314 | + nfs_fscache_update_auxdata(&auxdata, nfsi); | |
| 318 | 315 | |
| 319 | 316 | if (inode_is_open_for_write(inode)) { |
| 320 | 317 | dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) |
| 31 | 31 | #define MNT_status_sz (1) |
| 32 | 32 | #define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE) |
| 33 | +#define MNT_fhandlev3_sz XDR_QUADLEN(NFS3_FHSIZE) | |
| 33 | 34 | #define MNT_authflav3_sz (1 + NFS_MAX_SECFLAVORS) |
| 34 | 35 | |
| 35 | 36 | /* |
| @@ -37,7 +38,7 @@ · 1 unmodified line | ||
| 37 | 38 | */ |
| 38 | 39 | #define MNT_enc_dirpath_sz encode_dirpath_sz |
| 39 | 40 | #define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz) |
| 40 | −#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandle_sz + \ | |
| 41 | +#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandlev3_sz + \ | |
| 41 | 42 | MNT_authflav3_sz) |
| 42 | 43 | |
| 43 | 44 | /* |
| @@ -6347,7 +6347,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, · 6346 unmodified lines | ||
| 6347 | 6347 | .rpc_client = server->client, |
| 6348 | 6348 | .rpc_message = &msg, |
| 6349 | 6349 | .callback_ops = &nfs4_delegreturn_ops, |
| 6350 | − .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | RPC_TASK_TIMEOUT, | |
| 6350 | + .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT, | |
| 6351 | 6351 | }; |
| 6352 | 6352 | int status = 0; |
| 6353 | 6353 | |
| @@ -734,9 +734,9 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) · 733 unmodified lines | ||
| 734 | 734 | state = new; |
| 735 | 735 | state->owner = owner; |
| 736 | 736 | atomic_inc(&owner->so_count); |
| 737 | − list_add_rcu(&state->inode_states, &nfsi->open_states); | |
| 738 | 737 | ihold(inode); |
| 739 | 738 | state->inode = inode; |
| 739 | + list_add_rcu(&state->inode_states, &nfsi->open_states); | |
| 740 | 740 | spin_unlock(&inode->i_lock); |
| 741 | 741 | /* Note: The reclaim code dictates that we add stateless |
| 742 | 742 | * and read-only stateids to the end of the list */ |
| @@ -752,7 +752,7 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr, · 751 unmodified lines | ||
| 752 | 752 | .callback_ops = call_ops, |
| 753 | 753 | .callback_data = hdr, |
| 754 | 754 | .workqueue = nfsiod_workqueue, |
| 755 | − .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | flags, | |
| 755 | + .flags = RPC_TASK_ASYNC | flags, | |
| 756 | 756 | }; |
| 757 | 757 | |
| 758 | 758 | hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how); |
| @@ -950,7 +950,8 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) · 191 unmodified lines | ||
| 950 | 950 | hdr->cred, |
| 951 | 951 | NFS_PROTO(hdr->inode), |
| 952 | 952 | desc->pg_rpc_callops, |
| 953 | − desc->pg_ioflags, 0); | |
| 953 | + desc->pg_ioflags, | |
| 954 | + RPC_TASK_CRED_NOREF); | |
| 954 | 955 | return ret; |
| 955 | 956 | } |
| 956 | 957 | |
| @@ -536,7 +536,8 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages, · 535 unmodified lines | ||
| 536 | 536 | nfs_init_commit(data, NULL, NULL, cinfo); |
| 537 | 537 | nfs_initiate_commit(NFS_CLIENT(inode), data, |
| 538 | 538 | NFS_PROTO(data->inode), |
| 539 | − data->mds_ops, how, 0); | |
| 539 | + data->mds_ops, how, | |
| 540 | + RPC_TASK_CRED_NOREF); | |
| 540 | 541 | } else { |
| 541 | 542 | nfs_init_commit(data, NULL, data->lseg, cinfo); |
| 542 | 543 | initiate_commit(data, how); |
| @@ -1189,7 +1189,6 @@ static void nfs_get_cache_cookie(struct super_block *sb, · 1188 unmodified lines | ||
| 1189 | 1189 | uniq = ctx->fscache_uniq; |
| 1190 | 1190 | ulen = strlen(ctx->fscache_uniq); |
| 1191 | 1191 | } |
| 1192 | − return; | |
| 1193 | 1192 | } |
| 1194 | 1193 | |
| 1195 | 1194 | nfs_fscache_get_super_cookie(sb, uniq, ulen); |
| @@ -1695,7 +1695,7 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, · 1694 unmodified lines | ||
| 1695 | 1695 | .callback_ops = call_ops, |
| 1696 | 1696 | .callback_data = data, |
| 1697 | 1697 | .workqueue = nfsiod_workqueue, |
| 1698 | − .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF | flags, | |
| 1698 | + .flags = RPC_TASK_ASYNC | flags, | |
| 1699 | 1699 | .priority = priority, |
| 1700 | 1700 | }; |
| 1701 | 1701 | /* Set up the initial task struct. */ |
| @@ -1813,7 +1813,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, · 111 unmodified lines | ||
| 1813 | 1813 | nfs_init_commit(data, head, NULL, cinfo); |
| 1814 | 1814 | atomic_inc(&cinfo->mds->rpcs_out); |
| 1815 | 1815 | return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode), |
| 1816 | − data->mds_ops, how, 0); | |
| 1816 | + data->mds_ops, how, RPC_TASK_CRED_NOREF); | |
| 1817 | 1817 | } |
| 1818 | 1818 | |
| 1819 | 1819 | /* |
| @@ -783,6 +783,9 @@ static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type) · 782 unmodified lines | ||
| 783 | 783 | if (fh_type != OVL_FILEID_V0) |
| 784 | 784 | return ERR_PTR(-EINVAL); |
| 785 | 785 | |
| 786 | + if (buflen <= OVL_FH_WIRE_OFFSET) | |
| 787 | + return ERR_PTR(-EINVAL); | |
| 788 | + | |
| 786 | 789 | fh = kzalloc(buflen, GFP_KERNEL); |
| 787 | 790 | if (!fh) |
| 788 | 791 | return ERR_PTR(-ENOMEM); |
| @@ -58,6 +58,24 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) · 57 unmodified lines | ||
| 58 | 58 | if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) |
| 59 | 59 | attr->ia_valid &= ~ATTR_MODE; |
| 60 | 60 | |
| 61 | + /* | |
| 62 | + * We might have to translate ovl file into real file object | |
| 63 | + * once use cases emerge. For now, simply don't let underlying | |
| 64 | + * filesystem rely on attr->ia_file | |
| 65 | + */ | |
| 66 | + attr->ia_valid &= ~ATTR_FILE; | |
| 67 | + | |
| 68 | + /* | |
| 69 | + * If open(O_TRUNC) is done, VFS calls ->setattr with ATTR_OPEN | |
| 70 | + * set. Overlayfs does not pass O_TRUNC flag to underlying | |
| 71 | + * filesystem during open -> do not pass ATTR_OPEN. This | |
| 72 | + * disables optimization in fuse which assumes open(O_TRUNC) | |
| 73 | + * already set file size to 0. But we never passed O_TRUNC to | |
| 74 | + * fuse. So by clearing ATTR_OPEN, fuse will be forced to send | |
| 75 | + * setattr request to server. | |
| 76 | + */ | |
| 77 | + attr->ia_valid &= ~ATTR_OPEN; | |
| 78 | + | |
| 61 | 79 | inode_lock(upperdentry->d_inode); |
| 62 | 80 | old_cred = ovl_override_creds(dentry->d_sb); |
| 63 | 81 | err = notify_change(upperdentry, attr, NULL); |
| @@ -1494,7 +1494,7 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) · 1493 unmodified lines | ||
| 1494 | 1494 | * Check pipe occupancy without the inode lock first. This function |
| 1495 | 1495 | * is speculative anyways, so missing one is ok. |
| 1496 | 1496 | */ |
| 1497 | − if (pipe_full(pipe->head, pipe->tail, pipe->max_usage)) | |
| 1497 | + if (!pipe_full(pipe->head, pipe->tail, pipe->max_usage)) | |
| 1498 | 1498 | return 0; |
| 1499 | 1499 | |
| 1500 | 1500 | ret = 0; |
| @@ -79,13 +79,9 @@ int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, · 78 unmodified lines | ||
| 79 | 79 | struct shash_desc *inhash) |
| 80 | 80 | { |
| 81 | 81 | struct ubifs_auth_node *auth = node; |
| 82 | − u8 *hash; | |
| 82 | + u8 hash[UBIFS_HASH_ARR_SZ]; | |
| 83 | 83 | int err; |
| 84 | 84 | |
| 85 | − hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS); | |
| 86 | − if (!hash) | |
| 87 | − return -ENOMEM; | |
| 88 | − | |
| 89 | 85 | { |
| 90 | 86 | SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); |
| 91 | 87 | |
| @@ -94,21 +90,16 @@ int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, · 2 unmodified lines | ||
| 94 | 90 | |
| 95 | 91 | err = crypto_shash_final(hash_desc, hash); |
| 96 | 92 | if (err) |
| 97 | − goto out; | |
| 93 | + return err; | |
| 98 | 94 | } |
| 99 | 95 | |
| 100 | 96 | err = ubifs_hash_calc_hmac(c, hash, auth->hmac); |
| 101 | 97 | if (err) |
| 102 | − goto out; | |
| 98 | + return err; | |
| 103 | 99 | |
| 104 | 100 | auth->ch.node_type = UBIFS_AUTH_NODE; |
| 105 | 101 | ubifs_prepare_node(c, auth, ubifs_auth_node_sz(c), 0); |
| 106 | − | |
| 107 | − err = 0; | |
| 108 | −out: | |
| 109 | − kfree(hash); | |
| 110 | − | |
| 111 | − return err; | |
| 102 | + return 0; | |
| 112 | 103 | } |
| 113 | 104 | |
| 114 | 105 | static struct shash_desc *ubifs_get_desc(const struct ubifs_info *c, |
| @@ -1375,7 +1375,6 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time, · 1374 unmodified lines | ||
| 1375 | 1375 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
| 1376 | 1376 | struct ubifs_budget_req req = { .dirtied_ino = 1, |
| 1377 | 1377 | .dirtied_ino_d = ALIGN(ui->data_len, 8) }; |
| 1378 | − int iflags = I_DIRTY_TIME; | |
| 1379 | 1378 | int err, release; |
| 1380 | 1379 | |
| 1381 | 1380 | if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
| @@ -1393,11 +1392,8 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time, · 11 unmodified lines | ||
| 1393 | 1392 | if (flags & S_MTIME) |
| 1394 | 1393 | inode->i_mtime = *time; |
| 1395 | 1394 | |
| 1396 | − if (!(inode->i_sb->s_flags & SB_LAZYTIME)) | |
| 1397 | − iflags |= I_DIRTY_SYNC; | |
| 1398 | − | |
| 1399 | 1395 | release = ui->dirty; |
| 1400 | − __mark_inode_dirty(inode, iflags); | |
| 1396 | + __mark_inode_dirty(inode, I_DIRTY_SYNC); | |
| 1401 | 1397 | mutex_unlock(&ui->ui_mutex); |
| 1402 | 1398 | if (release) |
| 1403 | 1399 | ubifs_release_budget(c, &req); |
| @@ -601,18 +601,12 @@ static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, · 600 unmodified lines | ||
| 601 | 601 | struct ubifs_scan_node *snod; |
| 602 | 602 | int n_nodes = 0; |
| 603 | 603 | int err; |
| 604 | − u8 *hash, *hmac; | |
| 604 | + u8 hash[UBIFS_HASH_ARR_SZ]; | |
| 605 | + u8 hmac[UBIFS_HMAC_ARR_SZ]; | |
| 605 | 606 | |
| 606 | 607 | if (!ubifs_authenticated(c)) |
| 607 | 608 | return sleb->nodes_cnt; |
| 608 | 609 | |
| 609 | − hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS); | |
| 610 | − hmac = kmalloc(c->hmac_desc_len, GFP_NOFS); | |
| 611 | − if (!hash || !hmac) { | |
| 612 | − err = -ENOMEM; | |
| 613 | − goto out; | |
| 614 | − } | |
| 615 | − | |
| 616 | 610 | list_for_each_entry(snod, &sleb->nodes, list) { |
| 617 | 611 | |
| 618 | 612 | n_nodes++; |
| @@ -662,9 +656,6 @@ static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, · 43 unmodified lines | ||
| 662 | 656 | err = 0; |
| 663 | 657 | } |
| 664 | 658 | out: |
| 665 | − kfree(hash); | |
| 666 | − kfree(hmac); | |
| 667 | − | |
| 668 | 659 | return err ? err : n_nodes - n_not_auth; |
| 669 | 660 | } |
| 670 | 661 | |
| @@ -48,7 +48,7 @@ struct videomode; · 47 unmodified lines | ||
| 48 | 48 | * @MODE_HSYNC: hsync out of range |
| 49 | 49 | * @MODE_VSYNC: vsync out of range |
| 50 | 50 | * @MODE_H_ILLEGAL: mode has illegal horizontal timings |
| 51 | − * @MODE_V_ILLEGAL: mode has illegal horizontal timings | |
| 51 | + * @MODE_V_ILLEGAL: mode has illegal vertical timings | |
| 52 | 52 | * @MODE_BAD_WIDTH: requires an unsupported linepitch |
| 53 | 53 | * @MODE_NOMODE: no mode with a matching name |
| 54 | 54 | * @MODE_NO_INTERLACE: interlaced mode not supported |
| @@ -245,6 +245,7 @@ · 244 unmodified lines | ||
| 245 | 245 | #define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN (1 << 0) |
| 246 | 246 | #define BCM54810_SHD_CLK_CTL 0x3 |
| 247 | 247 | #define BCM54810_SHD_CLK_CTL_GTXCLK_EN (1 << 9) |
| 248 | +#define BCM54810_SHD_SCR3_TRDDAPD 0x0100 | |
| 248 | 249 | |
| 249 | 250 | /* BCM54612E Registers */ |
| 250 | 251 | #define BCM54612E_EXP_SPARE0 (MII_BCM54XX_EXP_SEL_ETC + 0x34) |
| @@ -356,4 +356,10 @@ static inline void *offset_to_ptr(const int *off) · 355 unmodified lines | ||
| 356 | 356 | /* &a[0] degrades to a pointer: a different type from an array */ |
| 357 | 357 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) |
| 358 | 358 | |
| 359 | +/* | |
| 360 | + * This is needed in functions which generate the stack canary, see | |
| 361 | + * arch/x86/kernel/smpboot.c::start_secondary() for an example. | |
| 362 | + */ | |
| 363 | +#define prevent_tail_call_optimization() mb() | |
| 364 | + | |
| 359 | 365 | #endif /* __LINUX_COMPILER_H */ |
| @@ -521,6 +521,15 @@ struct cper_sec_pcie { · 520 unmodified lines | ||
| 521 | 521 | u8 aer_info[96]; |
| 522 | 522 | }; |
| 523 | 523 | |
| 524 | +/* Firmware Error Record Reference, UEFI v2.7 sec N.2.10 */ | |
| 525 | +struct cper_sec_fw_err_rec_ref { | |
| 526 | + u8 record_type; | |
| 527 | + u8 revision; | |
| 528 | + u8 reserved[6]; | |
| 529 | + u64 record_identifier; | |
| 530 | + guid_t record_identifier_guid; | |
| 531 | +}; | |
| 532 | + | |
| 524 | 533 | /* Reset to default packing */ |
| 525 | 534 | #pragma pack() |
| 526 | 535 | |
| @@ -1245,4 +1245,6 @@ struct linux_efi_memreserve { · 1244 unmodified lines | ||
| 1245 | 1245 | |
| 1246 | 1246 | void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); |
| 1247 | 1247 | |
| 1248 | +char *efi_systab_show_arch(char *str); | |
| 1249 | + | |
| 1248 | 1250 | #endif /* _LINUX_EFI_H */ |
| @@ -210,6 +210,29 @@ struct ftrace_ops { · 209 unmodified lines | ||
| 210 | 210 | #endif |
| 211 | 211 | }; |
| 212 | 212 | |
| 213 | +extern struct ftrace_ops __rcu *ftrace_ops_list; | |
| 214 | +extern struct ftrace_ops ftrace_list_end; | |
| 215 | + | |
| 216 | +/* | |
| 217 | + * Traverse the ftrace_global_list, invoking all entries. The reason that we | |
| 218 | + * can use rcu_dereference_raw_check() is that elements removed from this list | |
| 219 | + * are simply leaked, so there is no need to interact with a grace-period | |
| 220 | + * mechanism. The rcu_dereference_raw_check() calls are needed to handle | |
| 221 | + * concurrent insertions into the ftrace_global_list. | |
| 222 | + * | |
| 223 | + * Silly Alpha and silly pointer-speculation compiler optimizations! | |
| 224 | + */ | |
| 225 | +#define do_for_each_ftrace_op(op, list) \ | |
| 226 | + op = rcu_dereference_raw_check(list); \ | |
| 227 | + do | |
| 228 | + | |
| 229 | +/* | |
| 230 | + * Optimized for just a single item in the list (as that is the normal case). | |
| 231 | + */ | |
| 232 | +#define while_for_each_ftrace_op(op) \ | |
| 233 | + while (likely(op = rcu_dereference_raw_check((op)->next)) && \ | |
| 234 | + unlikely((op) != &ftrace_list_end)) | |
| 235 | + | |
| 213 | 236 | /* |
| 214 | 237 | * Type of the current tracing. |
| 215 | 238 | */ |
| @@ -17,9 +17,12 @@ enum host1x_class { · 16 unmodified lines | ||
| 17 | 17 | HOST1X_CLASS_GR3D = 0x60, |
| 18 | 18 | }; |
| 19 | 19 | |
| 20 | +struct host1x; | |
| 20 | 21 | struct host1x_client; |
| 21 | 22 | struct iommu_group; |
| 22 | 23 | |
| 24 | +u64 host1x_get_dma_mask(struct host1x *host1x); | |
| 25 | + | |
| 23 | 26 | /** |
| 24 | 27 | * struct host1x_client_ops - host1x client operations |
| 25 | 28 | * @init: host1x client initialization code |
| @@ -29,7 +29,7 @@ struct i2c_mux_core { · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | int num_adapters; |
| 31 | 31 | int max_adapters; |
| 32 | − struct i2c_adapter *adapter[0]; | |
| 32 | + struct i2c_adapter *adapter[]; | |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | 35 | struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent, |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * i2c.h - definitions for the Linux i2c bus interface |
| 4 | 4 | * Copyright (C) 1995-2000 Simon G. Vogl |
| 5 | − * Copyright (C) 2013-2019 Wolfram Sang <wsa@the-dreams.de> | |
| 5 | + * Copyright (C) 2013-2019 Wolfram Sang <wsa@kernel.org> | |
| 6 | 6 | * |
| 7 | 7 | * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and |
| 8 | 8 | * Frodo Looijaard <frodol@dds.nl> |
| @@ -813,8 +813,11 @@ void kvm_flush_remote_tlbs(struct kvm *kvm); · 812 unmodified lines | ||
| 813 | 813 | void kvm_reload_remote_mmus(struct kvm *kvm); |
| 814 | 814 | |
| 815 | 815 | bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, |
| 816 | + struct kvm_vcpu *except, | |
| 816 | 817 | unsigned long *vcpu_bitmap, cpumask_var_t tmp); |
| 817 | 818 | bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); |
| 819 | +bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, | |
| 820 | + struct kvm_vcpu *except); | |
| 818 | 821 | bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req, |
| 819 | 822 | unsigned long *vcpu_bitmap); |
| 820 | 823 | |
| @@ -243,7 +243,7 @@ LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, char *name, · 242 unmodified lines | ||
| 243 | 243 | char **value) |
| 244 | 244 | LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) |
| 245 | 245 | LSM_HOOK(int, 0, ismaclabel, const char *name) |
| 246 | −LSM_HOOK(int, 0, secid_to_secctx, u32 secid, char **secdata, | |
| 246 | +LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata, | |
| 247 | 247 | u32 *seclen) |
| 248 | 248 | LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid) |
| 249 | 249 | LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen) |
| @@ -783,6 +783,8 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg, · 782 unmodified lines | ||
| 783 | 783 | atomic_long_inc(&memcg->memory_events[event]); |
| 784 | 784 | cgroup_file_notify(&memcg->events_file); |
| 785 | 785 | |
| 786 | + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) | |
| 787 | + break; | |
| 786 | 788 | if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS) |
| 787 | 789 | break; |
| 788 | 790 | } while ((memcg = parent_mem_cgroup(memcg)) && |
| @@ -213,6 +213,12 @@ enum mlx5_port_status { · 212 unmodified lines | ||
| 213 | 213 | MLX5_PORT_DOWN = 2, |
| 214 | 214 | }; |
| 215 | 215 | |
| 216 | +enum mlx5_cmdif_state { | |
| 217 | + MLX5_CMDIF_STATE_UNINITIALIZED, | |
| 218 | + MLX5_CMDIF_STATE_UP, | |
| 219 | + MLX5_CMDIF_STATE_DOWN, | |
| 220 | +}; | |
| 221 | + | |
| 216 | 222 | struct mlx5_cmd_first { |
| 217 | 223 | __be32 data[4]; |
| 218 | 224 | }; |
| @@ -258,6 +264,7 @@ struct mlx5_cmd_stats { · 39 unmodified lines | ||
| 258 | 264 | struct mlx5_cmd { |
| 259 | 265 | struct mlx5_nb nb; |
| 260 | 266 | |
| 267 | + enum mlx5_cmdif_state state; | |
| 261 | 268 | void *cmd_alloc_buf; |
| 262 | 269 | dma_addr_t alloc_dma; |
| 263 | 270 | int alloc_size; |
| @@ -284,6 +291,7 @@ struct mlx5_cmd { · 20 unmodified lines | ||
| 284 | 291 | struct semaphore sem; |
| 285 | 292 | struct semaphore pages_sem; |
| 286 | 293 | int mode; |
| 294 | + u16 allowed_opcode; | |
| 287 | 295 | struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS]; |
| 288 | 296 | struct dma_pool *pool; |
| 289 | 297 | struct mlx5_cmd_debug dbg; |
| @@ -743,6 +751,7 @@ struct mlx5_cmd_work_ent { · 453 unmodified lines | ||
| 743 | 751 | struct delayed_work cb_timeout_work; |
| 744 | 752 | void *context; |
| 745 | 753 | int idx; |
| 754 | + struct completion handling; | |
| 746 | 755 | struct completion done; |
| 747 | 756 | struct mlx5_cmd *cmd; |
| 748 | 757 | struct work_struct work; |
| @@ -874,10 +883,17 @@ mlx5_frag_buf_get_idx_last_contig_stride(struct mlx5_frag_buf_ctrl *fbc, u32 ix) · 125 unmodified lines | ||
| 874 | 883 | return min_t(u32, last_frag_stride_idx - fbc->strides_offset, fbc->sz_m1); |
| 875 | 884 | } |
| 876 | 885 | |
| 886 | +enum { | |
| 887 | + CMD_ALLOWED_OPCODE_ALL, | |
| 888 | +}; | |
| 889 | + | |
| 877 | 890 | int mlx5_cmd_init(struct mlx5_core_dev *dev); |
| 878 | 891 | void mlx5_cmd_cleanup(struct mlx5_core_dev *dev); |
| 892 | +void mlx5_cmd_set_state(struct mlx5_core_dev *dev, | |
| 893 | + enum mlx5_cmdif_state cmdif_state); | |
| 879 | 894 | void mlx5_cmd_use_events(struct mlx5_core_dev *dev); |
| 880 | 895 | void mlx5_cmd_use_polling(struct mlx5_core_dev *dev); |
| 896 | +void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode); | |
| 881 | 897 | |
| 882 | 898 | struct mlx5_async_ctx { |
| 883 | 899 | struct mlx5_core_dev *dev; |
| @@ -105,10 +105,10 @@ struct ptp_system_timestamp { · 104 unmodified lines | ||
| 105 | 105 | * parameter func: the desired function to use. |
| 106 | 106 | * parameter chan: the function channel index to use. |
| 107 | 107 | * |
| 108 | − * @do_work: Request driver to perform auxiliary (periodic) operations | |
| 109 | − * Driver should return delay of the next auxiliary work scheduling | |
| 110 | − * time (>=0) or negative value in case further scheduling | |
| 111 | − * is not required. | |
| 108 | + * @do_aux_work: Request driver to perform auxiliary (periodic) operations | |
| 109 | + * Driver should return delay of the next auxiliary work | |
| 110 | + * scheduling time (>=0) or negative value in case further | |
| 111 | + * scheduling is not required. | |
| 112 | 112 | * |
| 113 | 113 | * Drivers should embed their ptp_clock_info within a private |
| 114 | 114 | * structure, obtaining a reference to it using container_of(). |
| @@ -187,6 +187,7 @@ static inline void sk_msg_xfer(struct sk_msg *dst, struct sk_msg *src, · 186 unmodified lines | ||
| 187 | 187 | dst->sg.data[which] = src->sg.data[which]; |
| 188 | 188 | dst->sg.data[which].length = size; |
| 189 | 189 | dst->sg.size += size; |
| 190 | + src->sg.size -= size; | |
| 190 | 191 | src->sg.data[which].length -= size; |
| 191 | 192 | src->sg.data[which].offset += size; |
| 192 | 193 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | struct gss_ctx { |
| 22 | 22 | struct gss_api_mech *mech_type; |
| 23 | 23 | void *internal_ctx_id; |
| 24 | + unsigned int slack, align; | |
| 24 | 25 | }; |
| 25 | 26 | |
| 26 | 27 | #define GSS_C_NO_BUFFER ((struct xdr_netobj) 0) |
| @@ -66,6 +67,7 @@ u32 gss_wrap( · 39 unmodified lines | ||
| 66 | 67 | u32 gss_unwrap( |
| 67 | 68 | struct gss_ctx *ctx_id, |
| 68 | 69 | int offset, |
| 70 | + int len, | |
| 69 | 71 | struct xdr_buf *inbuf); |
| 70 | 72 | u32 gss_delete_sec_context( |
| 71 | 73 | struct gss_ctx **ctx_id); |
| @@ -126,6 +128,7 @@ struct gss_api_ops { · 54 unmodified lines | ||
| 126 | 128 | u32 (*gss_unwrap)( |
| 127 | 129 | struct gss_ctx *ctx_id, |
| 128 | 130 | int offset, |
| 131 | + int len, | |
| 129 | 132 | struct xdr_buf *buf); |
| 130 | 133 | void (*gss_delete_sec_context)( |
| 131 | 134 | void *internal_ctx_id); |
| @@ -83,7 +83,7 @@ struct gss_krb5_enctype { · 82 unmodified lines | ||
| 83 | 83 | u32 (*encrypt_v2) (struct krb5_ctx *kctx, u32 offset, |
| 84 | 84 | struct xdr_buf *buf, |
| 85 | 85 | struct page **pages); /* v2 encryption function */ |
| 86 | − u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, | |
| 86 | + u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, u32 len, | |
| 87 | 87 | struct xdr_buf *buf, u32 *headskip, |
| 88 | 88 | u32 *tailskip); /* v2 decryption function */ |
| 89 | 89 | }; |
| @@ -255,7 +255,7 @@ gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset, · 165 unmodified lines | ||
| 255 | 255 | struct xdr_buf *outbuf, struct page **pages); |
| 256 | 256 | |
| 257 | 257 | u32 |
| 258 | −gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, | |
| 258 | +gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, int len, | |
| 259 | 259 | struct xdr_buf *buf); |
| 260 | 260 | |
| 261 | 261 | |
| @@ -312,7 +312,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, · 50 unmodified lines | ||
| 312 | 312 | struct page **pages); |
| 313 | 313 | |
| 314 | 314 | u32 |
| 315 | −gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, | |
| 315 | +gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, | |
| 316 | 316 | struct xdr_buf *buf, u32 *plainoffset, |
| 317 | 317 | u32 *plainlen); |
| 318 | 318 | |
| @@ -184,6 +184,7 @@ xdr_adjust_iovec(struct kvec *iov, __be32 *p) · 183 unmodified lines | ||
| 184 | 184 | extern void xdr_shift_buf(struct xdr_buf *, size_t); |
| 185 | 185 | extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *); |
| 186 | 186 | extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int); |
| 187 | +extern void xdr_buf_trim(struct xdr_buf *, unsigned int); | |
| 187 | 188 | extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); |
| 188 | 189 | extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); |
| 189 | 190 | |
| @@ -75,7 +75,8 @@ static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm) · 74 unmodified lines | ||
| 75 | 75 | { |
| 76 | 76 | dtm->install = jiffies_to_clock_t(jiffies - stm->install); |
| 77 | 77 | dtm->lastuse = jiffies_to_clock_t(jiffies - stm->lastuse); |
| 78 | − dtm->firstuse = jiffies_to_clock_t(jiffies - stm->firstuse); | |
| 78 | + dtm->firstuse = stm->firstuse ? | |
| 79 | + jiffies_to_clock_t(jiffies - stm->firstuse) : 0; | |
| 79 | 80 | dtm->expires = jiffies_to_clock_t(stm->expires); |
| 80 | 81 | } |
| 81 | 82 | |
| @@ -59,7 +59,7 @@ bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *, · 58 unmodified lines | ||
| 59 | 59 | void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *); |
| 60 | 60 | void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *, |
| 61 | 61 | struct sockaddr_rxrpc *); |
| 62 | −u64 rxrpc_kernel_get_rtt(struct socket *, struct rxrpc_call *); | |
| 62 | +u32 rxrpc_kernel_get_srtt(struct socket *, struct rxrpc_call *); | |
| 63 | 63 | int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, |
| 64 | 64 | rxrpc_user_attach_call_t, unsigned long, gfp_t, |
| 65 | 65 | unsigned int); |
| @@ -257,7 +257,6 @@ struct fib_dump_filter { · 256 unmodified lines | ||
| 257 | 257 | u32 table_id; |
| 258 | 258 | /* filter_set is an optimization that an entry is set */ |
| 259 | 259 | bool filter_set; |
| 260 | − bool dump_all_families; | |
| 261 | 260 | bool dump_routes; |
| 262 | 261 | bool dump_exceptions; |
| 263 | 262 | unsigned char protocol; |
| @@ -87,7 +87,7 @@ struct nf_conn { · 86 unmodified lines | ||
| 87 | 87 | struct hlist_node nat_bysource; |
| 88 | 88 | #endif |
| 89 | 89 | /* all members below initialized via memset */ |
| 90 | − u8 __nfct_init_offset[0]; | |
| 90 | + struct { } __nfct_init_offset; | |
| 91 | 91 | |
| 92 | 92 | /* If we were expected by an expectation, this will be it */ |
| 93 | 93 | struct nf_conn *master; |
| @@ -127,6 +127,7 @@ enum nf_flow_flags { · 126 unmodified lines | ||
| 127 | 127 | NF_FLOW_HW_DYING, |
| 128 | 128 | NF_FLOW_HW_DEAD, |
| 129 | 129 | NF_FLOW_HW_REFRESH, |
| 130 | + NF_FLOW_HW_PENDING, | |
| 130 | 131 | }; |
| 131 | 132 | |
| 132 | 133 | enum flow_offload_type { |
| @@ -1376,7 +1376,6 @@ static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) · 1375 unmodified lines | ||
| 1376 | 1376 | rx_opt->num_sacks = 0; |
| 1377 | 1377 | } |
| 1378 | 1378 | |
| 1379 | −u32 tcp_default_init_rwnd(u32 mss); | |
| 1380 | 1379 | void tcp_cwnd_restart(struct sock *sk, s32 delta); |
| 1381 | 1380 | |
| 1382 | 1381 | static inline void tcp_slow_start_after_idle_check(struct sock *sk) |
| @@ -1421,6 +1420,19 @@ static inline int tcp_full_space(const struct sock *sk) · 38 unmodified lines | ||
| 1421 | 1420 | return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); |
| 1422 | 1421 | } |
| 1423 | 1422 | |
| 1423 | +/* We provision sk_rcvbuf around 200% of sk_rcvlowat. | |
| 1424 | + * If 87.5 % (7/8) of the space has been consumed, we want to override | |
| 1425 | + * SO_RCVLOWAT constraint, since we are receiving skbs with too small | |
| 1426 | + * len/truesize ratio. | |
| 1427 | + */ | |
| 1428 | +static inline bool tcp_rmem_pressure(const struct sock *sk) | |
| 1429 | +{ | |
| 1430 | + int rcvbuf = READ_ONCE(sk->sk_rcvbuf); | |
| 1431 | + int threshold = rcvbuf - (rcvbuf >> 3); | |
| 1432 | + | |
| 1433 | + return atomic_read(&sk->sk_rmem_alloc) > threshold; | |
| 1434 | +} | |
| 1435 | + | |
| 1424 | 1436 | extern void tcp_openreq_init_rwin(struct request_sock *req, |
| 1425 | 1437 | const struct sock *sk_listener, |
| 1426 | 1438 | const struct dst_entry *dst); |
| @@ -143,14 +143,12 @@ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb · 142 unmodified lines | ||
| 143 | 143 | __be16 df, __be16 src_port, __be16 dst_port, |
| 144 | 144 | bool xnet, bool nocheck); |
| 145 | 145 | |
| 146 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 147 | 146 | int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, |
| 148 | 147 | struct sk_buff *skb, |
| 149 | 148 | struct net_device *dev, struct in6_addr *saddr, |
| 150 | 149 | struct in6_addr *daddr, |
| 151 | 150 | __u8 prio, __u8 ttl, __be32 label, |
| 152 | 151 | __be16 src_port, __be16 dst_port, bool nocheck); |
| 153 | −#endif | |
| 154 | 152 | |
| 155 | 153 | void udp_tunnel_sock_release(struct socket *sock); |
| 156 | 154 | |
| @@ -61,6 +61,7 @@ struct snd_rawmidi_runtime { · 60 unmodified lines | ||
| 61 | 61 | size_t avail_min; /* min avail for wakeup */ |
| 62 | 62 | size_t avail; /* max used buffer for wakeup */ |
| 63 | 63 | size_t xruns; /* over/underruns counter */ |
| 64 | + int buffer_ref; /* buffer reference count */ | |
| 64 | 65 | /* misc */ |
| 65 | 66 | spinlock_t lock; |
| 66 | 67 | wait_queue_head_t sleep; |
| @@ -1112,18 +1112,17 @@ TRACE_EVENT(rxrpc_rtt_tx, · 1111 unmodified lines | ||
| 1112 | 1112 | TRACE_EVENT(rxrpc_rtt_rx, |
| 1113 | 1113 | TP_PROTO(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why, |
| 1114 | 1114 | rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial, |
| 1115 | − s64 rtt, u8 nr, s64 avg), | |
| 1115 | + u32 rtt, u32 rto), | |
| 1116 | 1116 | |
| 1117 | − TP_ARGS(call, why, send_serial, resp_serial, rtt, nr, avg), | |
| 1117 | + TP_ARGS(call, why, send_serial, resp_serial, rtt, rto), | |
| 1118 | 1118 | |
| 1119 | 1119 | TP_STRUCT__entry( |
| 1120 | 1120 | __field(unsigned int, call ) |
| 1121 | 1121 | __field(enum rxrpc_rtt_rx_trace, why ) |
| 1122 | − __field(u8, nr ) | |
| 1123 | 1122 | __field(rxrpc_serial_t, send_serial ) |
| 1124 | 1123 | __field(rxrpc_serial_t, resp_serial ) |
| 1125 | − __field(s64, rtt ) | |
| 1126 | − __field(u64, avg ) | |
| 1124 | + __field(u32, rtt ) | |
| 1125 | + __field(u32, rto ) | |
| 1127 | 1126 | ), |
| 1128 | 1127 | |
| 1129 | 1128 | TP_fast_assign( |
| @@ -1132,18 +1131,16 @@ TRACE_EVENT(rxrpc_rtt_rx, · 2 unmodified lines | ||
| 1132 | 1131 | __entry->send_serial = send_serial; |
| 1133 | 1132 | __entry->resp_serial = resp_serial; |
| 1134 | 1133 | __entry->rtt = rtt; |
| 1135 | − __entry->nr = nr; | |
| 1136 | − __entry->avg = avg; | |
| 1134 | + __entry->rto = rto; | |
| 1137 | 1135 | ), |
| 1138 | 1136 | |
| 1139 | − TP_printk("c=%08x %s sr=%08x rr=%08x rtt=%lld nr=%u avg=%lld", | |
| 1137 | + TP_printk("c=%08x %s sr=%08x rr=%08x rtt=%u rto=%u", | |
| 1140 | 1138 | __entry->call, |
| 1141 | 1139 | __print_symbolic(__entry->why, rxrpc_rtt_rx_traces), |
| 1142 | 1140 | __entry->send_serial, |
| 1143 | 1141 | __entry->resp_serial, |
| 1144 | 1142 | __entry->rtt, |
| 1145 | − __entry->nr, | |
| 1146 | − __entry->avg) | |
| 1143 | + __entry->rto) | |
| 1147 | 1144 | ); |
| 1148 | 1145 | |
| 1149 | 1146 | TRACE_EVENT(rxrpc_timer, |
| @@ -1544,6 +1541,41 @@ TRACE_EVENT(rxrpc_notify_socket, · 394 unmodified lines | ||
| 1544 | 1541 | __entry->serial) |
| 1545 | 1542 | ); |
| 1546 | 1543 | |
| 1544 | +TRACE_EVENT(rxrpc_rx_discard_ack, | |
| 1545 | + TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial, | |
| 1546 | + rxrpc_seq_t first_soft_ack, rxrpc_seq_t call_ackr_first, | |
| 1547 | + rxrpc_seq_t prev_pkt, rxrpc_seq_t call_ackr_prev), | |
| 1548 | + | |
| 1549 | + TP_ARGS(debug_id, serial, first_soft_ack, call_ackr_first, | |
| 1550 | + prev_pkt, call_ackr_prev), | |
| 1551 | + | |
| 1552 | + TP_STRUCT__entry( | |
| 1553 | + __field(unsigned int, debug_id ) | |
| 1554 | + __field(rxrpc_serial_t, serial ) | |
| 1555 | + __field(rxrpc_seq_t, first_soft_ack) | |
| 1556 | + __field(rxrpc_seq_t, call_ackr_first) | |
| 1557 | + __field(rxrpc_seq_t, prev_pkt) | |
| 1558 | + __field(rxrpc_seq_t, call_ackr_prev) | |
| 1559 | + ), | |
| 1560 | + | |
| 1561 | + TP_fast_assign( | |
| 1562 | + __entry->debug_id = debug_id; | |
| 1563 | + __entry->serial = serial; | |
| 1564 | + __entry->first_soft_ack = first_soft_ack; | |
| 1565 | + __entry->call_ackr_first = call_ackr_first; | |
| 1566 | + __entry->prev_pkt = prev_pkt; | |
| 1567 | + __entry->call_ackr_prev = call_ackr_prev; | |
| 1568 | + ), | |
| 1569 | + | |
| 1570 | + TP_printk("c=%08x r=%08x %08x<%08x %08x<%08x", | |
| 1571 | + __entry->debug_id, | |
| 1572 | + __entry->serial, | |
| 1573 | + __entry->first_soft_ack, | |
| 1574 | + __entry->call_ackr_first, | |
| 1575 | + __entry->prev_pkt, | |
| 1576 | + __entry->call_ackr_prev) | |
| 1577 | + ); | |
| 1578 | + | |
| 1547 | 1579 | #endif /* _TRACE_RXRPC_H */ |
| 1548 | 1580 | |
| 1549 | 1581 | /* This part must be outside protection */ |
| @@ -93,6 +93,64 @@ struct usb_raw_ep_io { · 92 unmodified lines | ||
| 93 | 93 | __u8 data[0]; |
| 94 | 94 | }; |
| 95 | 95 | |
| 96 | +/* Maximum number of non-control endpoints in struct usb_raw_eps_info. */ | |
| 97 | +#define USB_RAW_EPS_NUM_MAX 30 | |
| 98 | + | |
| 99 | +/* Maximum length of UDC endpoint name in struct usb_raw_ep_info. */ | |
| 100 | +#define USB_RAW_EP_NAME_MAX 16 | |
| 101 | + | |
| 102 | +/* Used as addr in struct usb_raw_ep_info if endpoint accepts any address. */ | |
| 103 | +#define USB_RAW_EP_ADDR_ANY 0xff | |
| 104 | + | |
| 105 | +/* | |
| 106 | + * struct usb_raw_ep_caps - exposes endpoint capabilities from struct usb_ep | |
| 107 | + * (technically from its member struct usb_ep_caps). | |
| 108 | + */ | |
| 109 | +struct usb_raw_ep_caps { | |
| 110 | + __u32 type_control : 1; | |
| 111 | + __u32 type_iso : 1; | |
| 112 | + __u32 type_bulk : 1; | |
| 113 | + __u32 type_int : 1; | |
| 114 | + __u32 dir_in : 1; | |
| 115 | + __u32 dir_out : 1; | |
| 116 | +}; | |
| 117 | + | |
| 118 | +/* | |
| 119 | + * struct usb_raw_ep_limits - exposes endpoint limits from struct usb_ep. | |
| 120 | + * @maxpacket_limit: Maximum packet size value supported by this endpoint. | |
| 121 | + * @max_streams: maximum number of streams supported by this endpoint | |
| 122 | + * (actual number is 2^n). | |
| 123 | + * @reserved: Empty, reserved for potential future extensions. | |
| 124 | + */ | |
| 125 | +struct usb_raw_ep_limits { | |
| 126 | + __u16 maxpacket_limit; | |
| 127 | + __u16 max_streams; | |
| 128 | + __u32 reserved; | |
| 129 | +}; | |
| 130 | + | |
| 131 | +/* | |
| 132 | + * struct usb_raw_ep_info - stores information about a gadget endpoint. | |
| 133 | + * @name: Name of the endpoint as it is defined in the UDC driver. | |
| 134 | + * @addr: Address of the endpoint that must be specified in the endpoint | |
| 135 | + * descriptor passed to USB_RAW_IOCTL_EP_ENABLE ioctl. | |
| 136 | + * @caps: Endpoint capabilities. | |
| 137 | + * @limits: Endpoint limits. | |
| 138 | + */ | |
| 139 | +struct usb_raw_ep_info { | |
| 140 | + __u8 name[USB_RAW_EP_NAME_MAX]; | |
| 141 | + __u32 addr; | |
| 142 | + struct usb_raw_ep_caps caps; | |
| 143 | + struct usb_raw_ep_limits limits; | |
| 144 | +}; | |
| 145 | + | |
| 146 | +/* | |
| 147 | + * struct usb_raw_eps_info - argument for USB_RAW_IOCTL_EPS_INFO ioctl. | |
| 148 | + * eps: Structures that store information about non-control endpoints. | |
| 149 | + */ | |
| 150 | +struct usb_raw_eps_info { | |
| 151 | + struct usb_raw_ep_info eps[USB_RAW_EPS_NUM_MAX]; | |
| 152 | +}; | |
| 153 | + | |
| 96 | 154 | /* |
| 97 | 155 | * Initializes a Raw Gadget instance. |
| 98 | 156 | * Accepts a pointer to the usb_raw_init struct as an argument. |
| @@ -115,37 +173,38 @@ struct usb_raw_ep_io { · 16 unmodified lines | ||
| 115 | 173 | #define USB_RAW_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_raw_event) |
| 116 | 174 | |
| 117 | 175 | /* |
| 118 | − * Queues an IN (OUT for READ) urb as a response to the last control request | |
| 119 | − * received on endpoint 0, provided that was an IN (OUT for READ) request and | |
| 120 | − * waits until the urb is completed. Copies received data to user for READ. | |
| 176 | + * Queues an IN (OUT for READ) request as a response to the last setup request | |
| 177 | + * received on endpoint 0 (provided that was an IN (OUT for READ) request), and | |
| 178 | + * waits until the request is completed. Copies received data to user for READ. | |
| 121 | 179 | * Accepts a pointer to the usb_raw_ep_io struct as an argument. |
| 122 | − * Returns length of trasferred data on success or negative error code on | |
| 180 | + * Returns length of transferred data on success or negative error code on | |
| 123 | 181 | * failure. |
| 124 | 182 | */ |
| 125 | 183 | #define USB_RAW_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_raw_ep_io) |
| 126 | 184 | #define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io) |
| 127 | 185 | |
| 128 | 186 | /* |
| 129 | − * Finds an endpoint that supports the transfer type specified in the | |
| 130 | − * descriptor and enables it. | |
| 131 | − * Accepts a pointer to the usb_endpoint_descriptor struct as an argument. | |
| 187 | + * Finds an endpoint that satisfies the parameters specified in the provided | |
| 188 | + * descriptors (address, transfer type, etc.) and enables it. | |
| 189 | + * Accepts a pointer to the usb_raw_ep_descs struct as an argument. | |
| 132 | 190 | * Returns enabled endpoint handle on success or negative error code on failure. |
| 133 | 191 | */ |
| 134 | 192 | #define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor) |
| 135 | 193 | |
| 136 | −/* Disables specified endpoint. | |
| 194 | +/* | |
| 195 | + * Disables specified endpoint. | |
| 137 | 196 | * Accepts endpoint handle as an argument. |
| 138 | 197 | * Returns 0 on success or negative error code on failure. |
| 139 | 198 | */ |
| 140 | 199 | #define USB_RAW_IOCTL_EP_DISABLE _IOW('U', 6, __u32) |
| 141 | 200 | |
| 142 | 201 | /* |
| 143 | − * Queues an IN (OUT for READ) urb as a response to the last control request | |
| 144 | − * received on endpoint usb_raw_ep_io.ep, provided that was an IN (OUT for READ) | |
| 145 | − * request and waits until the urb is completed. Copies received data to user | |
| 146 | − * for READ. | |
| 202 | + * Queues an IN (OUT for READ) request as a response to the last setup request | |
| 203 | + * received on endpoint usb_raw_ep_io.ep (provided that was an IN (OUT for READ) | |
| 204 | + * request), and waits until the request is completed. Copies received data to | |
| 205 | + * user for READ. | |
| 147 | 206 | * Accepts a pointer to the usb_raw_ep_io struct as an argument. |
| 148 | − * Returns length of trasferred data on success or negative error code on | |
| 207 | + * Returns length of transferred data on success or negative error code on | |
| 149 | 208 | * failure. |
| 150 | 209 | */ |
| 151 | 210 | #define USB_RAW_IOCTL_EP_WRITE _IOW('U', 7, struct usb_raw_ep_io) |
| @@ -164,4 +223,27 @@ struct usb_raw_ep_io { · 12 unmodified lines | ||
| 164 | 223 | */ |
| 165 | 224 | #define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32) |
| 166 | 225 | |
| 226 | +/* | |
| 227 | + * Fills in the usb_raw_eps_info structure with information about non-control | |
| 228 | + * endpoints available for the currently connected UDC. | |
| 229 | + * Returns the number of available endpoints on success or negative error code | |
| 230 | + * on failure. | |
| 231 | + */ | |
| 232 | +#define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info) | |
| 233 | + | |
| 234 | +/* | |
| 235 | + * Stalls a pending control request on endpoint 0. | |
| 236 | + * Returns 0 on success or negative error code on failure. | |
| 237 | + */ | |
| 238 | +#define USB_RAW_IOCTL_EP0_STALL _IO('U', 12) | |
| 239 | + | |
| 240 | +/* | |
| 241 | + * Sets or clears halt or wedge status of the endpoint. | |
| 242 | + * Accepts endpoint handle as an argument. | |
| 243 | + * Returns 0 on success or negative error code on failure. | |
| 244 | + */ | |
| 245 | +#define USB_RAW_IOCTL_EP_SET_HALT _IOW('U', 13, __u32) | |
| 246 | +#define USB_RAW_IOCTL_EP_CLEAR_HALT _IOW('U', 14, __u32) | |
| 247 | +#define USB_RAW_IOCTL_EP_SET_WEDGE _IOW('U', 15, __u32) | |
| 248 | + | |
| 167 | 249 | #endif /* _UAPI__LINUX_USB_RAW_GADGET_H */ |
| @@ -2261,6 +2261,9 @@ config ASN1 · 2260 unmodified lines | ||
| 2261 | 2261 | |
| 2262 | 2262 | source "kernel/Kconfig.locks" |
| 2263 | 2263 | |
| 2264 | +config ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 2265 | + bool | |
| 2266 | + | |
| 2264 | 2267 | config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE |
| 2265 | 2268 | bool |
| 2266 | 2269 | |
| @@ -400,9 +400,8 @@ static void __init setup_boot_config(const char *cmdline) · 399 unmodified lines | ||
| 400 | 400 | char *data, *copy; |
| 401 | 401 | int ret; |
| 402 | 402 | |
| 403 | + /* Cut out the bootconfig data even if we have no bootconfig option */ | |
| 403 | 404 | data = get_boot_config_from_initrd(&size, &csum); |
| 404 | − if (!data) | |
| 405 | − goto not_found; | |
| 406 | 405 | |
| 407 | 406 | strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
| 408 | 407 | parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, |
| @@ -411,6 +410,11 @@ static void __init setup_boot_config(const char *cmdline) · 2 unmodified lines | ||
| 411 | 410 | if (!bootconfig_found) |
| 412 | 411 | return; |
| 413 | 412 | |
| 413 | + if (!data) { | |
| 414 | + pr_err("'bootconfig' found on command line, but no bootconfig found\n"); | |
| 415 | + return; | |
| 416 | + } | |
| 417 | + | |
| 414 | 418 | if (size >= XBC_DATA_MAX) { |
| 415 | 419 | pr_err("bootconfig size %d greater than max size %d\n", |
| 416 | 420 | size, XBC_DATA_MAX); |
| @@ -446,8 +450,6 @@ static void __init setup_boot_config(const char *cmdline) · 29 unmodified lines | ||
| 446 | 450 | extra_init_args = xbc_make_cmdline("init"); |
| 447 | 451 | } |
| 448 | 452 | return; |
| 449 | −not_found: | |
| 450 | − pr_err("'bootconfig' found on command line, but no bootconfig found\n"); | |
| 451 | 453 | } |
| 452 | 454 | |
| 453 | 455 | #else |
| @@ -1036,6 +1038,8 @@ asmlinkage __visible void __init start_kernel(void) · 582 unmodified lines | ||
| 1036 | 1038 | |
| 1037 | 1039 | /* Do the rest non-__init'ed, we're now alive */ |
| 1038 | 1040 | arch_call_rest_init(); |
| 1041 | + | |
| 1042 | + prevent_tail_call_optimization(); | |
| 1039 | 1043 | } |
| 1040 | 1044 | |
| 1041 | 1045 | /* Call all constructor functions linked into the kernel. */ |
| @@ -764,21 +764,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, · 763 unmodified lines | ||
| 764 | 764 | total++; |
| 765 | 765 | } |
| 766 | 766 | |
| 767 | − *new_pos = pos + 1; | |
| 767 | + ipc = NULL; | |
| 768 | 768 | if (total >= ids->in_use) |
| 769 | − return NULL; | |
| 769 | + goto out; | |
| 770 | 770 | |
| 771 | 771 | for (; pos < ipc_mni; pos++) { |
| 772 | 772 | ipc = idr_find(&ids->ipcs_idr, pos); |
| 773 | 773 | if (ipc != NULL) { |
| 774 | 774 | rcu_read_lock(); |
| 775 | 775 | ipc_lock_object(ipc); |
| 776 | − return ipc; | |
| 776 | + break; | |
| 777 | 777 | } |
| 778 | 778 | } |
| 779 | − | |
| 780 | − /* Out of range - return NULL to terminate iteration */ | |
| 781 | − return NULL; | |
| 779 | +out: | |
| 780 | + *new_pos = pos + 1; | |
| 781 | + return ipc; | |
| 782 | 782 | } |
| 783 | 783 | |
| 784 | 784 | static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) |
| @@ -486,7 +486,12 @@ static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma) · 485 unmodified lines | ||
| 486 | 486 | if (!(map->map_flags & BPF_F_MMAPABLE)) |
| 487 | 487 | return -EINVAL; |
| 488 | 488 | |
| 489 | − return remap_vmalloc_range(vma, array_map_vmalloc_addr(array), pgoff); | |
| 489 | + if (vma->vm_pgoff * PAGE_SIZE + (vma->vm_end - vma->vm_start) > | |
| 490 | + PAGE_ALIGN((u64)array->map.max_entries * array->elem_size)) | |
| 491 | + return -EINVAL; | |
| 492 | + | |
| 493 | + return remap_vmalloc_range(vma, array_map_vmalloc_addr(array), | |
| 494 | + vma->vm_pgoff + pgoff); | |
| 490 | 495 | } |
| 491 | 496 | |
| 492 | 497 | const struct bpf_map_ops array_map_ops = { |
| @@ -623,9 +623,20 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) · 622 unmodified lines | ||
| 623 | 623 | |
| 624 | 624 | mutex_lock(&map->freeze_mutex); |
| 625 | 625 | |
| 626 | − if ((vma->vm_flags & VM_WRITE) && map->frozen) { | |
| 627 | − err = -EPERM; | |
| 628 | − goto out; | |
| 626 | + if (vma->vm_flags & VM_WRITE) { | |
| 627 | + if (map->frozen) { | |
| 628 | + err = -EPERM; | |
| 629 | + goto out; | |
| 630 | + } | |
| 631 | + /* map is meant to be read-only, so do not allow mapping as | |
| 632 | + * writable, because it's possible to leak a writable page | |
| 633 | + * reference and allows user-space to still modify it after | |
| 634 | + * freezing, while verifier will assume contents do not change | |
| 635 | + */ | |
| 636 | + if (map->map_flags & BPF_F_RDONLY_PROG) { | |
| 637 | + err = -EACCES; | |
| 638 | + goto out; | |
| 639 | + } | |
| 629 | 640 | } |
| 630 | 641 | |
| 631 | 642 | /* set default open/close callbacks */ |
| @@ -1485,8 +1496,10 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr) · 853 unmodified lines | ||
| 1485 | 1496 | if (err) |
| 1486 | 1497 | goto free_value; |
| 1487 | 1498 | |
| 1488 | − if (copy_to_user(uvalue, value, value_size) != 0) | |
| 1499 | + if (copy_to_user(uvalue, value, value_size) != 0) { | |
| 1500 | + err = -EFAULT; | |
| 1489 | 1501 | goto free_value; |
| 1502 | + } | |
| 1490 | 1503 | |
| 1491 | 1504 | err = 0; |
| 1492 | 1505 | |
| @@ -4340,7 +4340,9 @@ static void do_refine_retval_range(struct bpf_reg_state *regs, int ret_type, · 4339 unmodified lines | ||
| 4340 | 4340 | |
| 4341 | 4341 | if (ret_type != RET_INTEGER || |
| 4342 | 4342 | (func_id != BPF_FUNC_get_stack && |
| 4343 | − func_id != BPF_FUNC_probe_read_str)) | |
| 4343 | + func_id != BPF_FUNC_probe_read_str && | |
| 4344 | + func_id != BPF_FUNC_probe_read_kernel_str && | |
| 4345 | + func_id != BPF_FUNC_probe_read_user_str)) | |
| 4344 | 4346 | return; |
| 4345 | 4347 | |
| 4346 | 4348 | ret_reg->smax_value = meta->msize_max_value; |
| @@ -7059,6 +7061,23 @@ static int check_return_code(struct bpf_verifier_env *env) · 2712 unmodified lines | ||
| 7059 | 7061 | return 0; |
| 7060 | 7062 | range = tnum_const(0); |
| 7061 | 7063 | break; |
| 7064 | + case BPF_PROG_TYPE_TRACING: | |
| 7065 | + switch (env->prog->expected_attach_type) { | |
| 7066 | + case BPF_TRACE_FENTRY: | |
| 7067 | + case BPF_TRACE_FEXIT: | |
| 7068 | + range = tnum_const(0); | |
| 7069 | + break; | |
| 7070 | + case BPF_TRACE_RAW_TP: | |
| 7071 | + case BPF_MODIFY_RETURN: | |
| 7072 | + return 0; | |
| 7073 | + default: | |
| 7074 | + return -ENOTSUPP; | |
| 7075 | + } | |
| 7076 | + break; | |
| 7077 | + case BPF_PROG_TYPE_EXT: | |
| 7078 | + /* freplace program can return anything as its return value | |
| 7079 | + * depends on the to-be-replaced kernel func or bpf program. | |
| 7080 | + */ | |
| 7062 | 7081 | default: |
| 7063 | 7082 | return 0; |
| 7064 | 7083 | } |
| @@ -2486,11 +2486,11 @@ long do_fork(unsigned long clone_flags, · 2485 unmodified lines | ||
| 2486 | 2486 | int __user *child_tidptr) |
| 2487 | 2487 | { |
| 2488 | 2488 | struct kernel_clone_args args = { |
| 2489 | − .flags = (clone_flags & ~CSIGNAL), | |
| 2489 | + .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), | |
| 2490 | 2490 | .pidfd = parent_tidptr, |
| 2491 | 2491 | .child_tid = child_tidptr, |
| 2492 | 2492 | .parent_tid = parent_tidptr, |
| 2493 | − .exit_signal = (clone_flags & CSIGNAL), | |
| 2493 | + .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), | |
| 2494 | 2494 | .stack = stack_start, |
| 2495 | 2495 | .stack_size = stack_size, |
| 2496 | 2496 | }; |
| @@ -2508,8 +2508,9 @@ long do_fork(unsigned long clone_flags, · 11 unmodified lines | ||
| 2508 | 2508 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) |
| 2509 | 2509 | { |
| 2510 | 2510 | struct kernel_clone_args args = { |
| 2511 | − .flags = ((flags | CLONE_VM | CLONE_UNTRACED) & ~CSIGNAL), | |
| 2512 | − .exit_signal = (flags & CSIGNAL), | |
| 2511 | + .flags = ((lower_32_bits(flags) | CLONE_VM | | |
| 2512 | + CLONE_UNTRACED) & ~CSIGNAL), | |
| 2513 | + .exit_signal = (lower_32_bits(flags) & CSIGNAL), | |
| 2513 | 2514 | .stack = (unsigned long)fn, |
| 2514 | 2515 | .stack_size = (unsigned long)arg, |
| 2515 | 2516 | }; |
| @@ -2570,11 +2571,11 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, · 54 unmodified lines | ||
| 2570 | 2571 | #endif |
| 2571 | 2572 | { |
| 2572 | 2573 | struct kernel_clone_args args = { |
| 2573 | − .flags = (clone_flags & ~CSIGNAL), | |
| 2574 | + .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), | |
| 2574 | 2575 | .pidfd = parent_tidptr, |
| 2575 | 2576 | .child_tid = child_tidptr, |
| 2576 | 2577 | .parent_tid = parent_tidptr, |
| 2577 | − .exit_signal = (clone_flags & CSIGNAL), | |
| 2578 | + .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), | |
| 2578 | 2579 | .stack = newsp, |
| 2579 | 2580 | .tls = tls, |
| 2580 | 2581 | }; |
| @@ -948,8 +948,8 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns, · 947 unmodified lines | ||
| 948 | 948 | P(se.avg.util_est.enqueued); |
| 949 | 949 | #endif |
| 950 | 950 | #ifdef CONFIG_UCLAMP_TASK |
| 951 | − __PS("uclamp.min", p->uclamp[UCLAMP_MIN].value); | |
| 952 | − __PS("uclamp.max", p->uclamp[UCLAMP_MAX].value); | |
| 951 | + __PS("uclamp.min", p->uclamp_req[UCLAMP_MIN].value); | |
| 952 | + __PS("uclamp.max", p->uclamp_req[UCLAMP_MAX].value); | |
| 953 | 953 | __PS("effective uclamp.min", uclamp_eff_value(p, UCLAMP_MIN)); |
| 954 | 954 | __PS("effective uclamp.max", uclamp_eff_value(p, UCLAMP_MAX)); |
| 955 | 955 | #endif |
| @@ -4774,7 +4774,6 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) · 4773 unmodified lines | ||
| 4774 | 4774 | struct rq *rq = rq_of(cfs_rq); |
| 4775 | 4775 | struct cfs_bandwidth *cfs_b = tg_cfs_bandwidth(cfs_rq->tg); |
| 4776 | 4776 | struct sched_entity *se; |
| 4777 | − int enqueue = 1; | |
| 4778 | 4777 | long task_delta, idle_task_delta; |
| 4779 | 4778 | |
| 4780 | 4779 | se = cfs_rq->tg->se[cpu_of(rq)]; |
| @@ -4798,26 +4797,44 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) · 17 unmodified lines | ||
| 4798 | 4797 | idle_task_delta = cfs_rq->idle_h_nr_running; |
| 4799 | 4798 | for_each_sched_entity(se) { |
| 4800 | 4799 | if (se->on_rq) |
| 4801 | − enqueue = 0; | |
| 4800 | + break; | |
| 4801 | + cfs_rq = cfs_rq_of(se); | |
| 4802 | + enqueue_entity(cfs_rq, se, ENQUEUE_WAKEUP); | |
| 4803 | + | |
| 4804 | + cfs_rq->h_nr_running += task_delta; | |
| 4805 | + cfs_rq->idle_h_nr_running += idle_task_delta; | |
| 4806 | + | |
| 4807 | + /* end evaluation on encountering a throttled cfs_rq */ | |
| 4808 | + if (cfs_rq_throttled(cfs_rq)) | |
| 4809 | + goto unthrottle_throttle; | |
| 4810 | + } | |
| 4802 | 4811 | |
| 4812 | + for_each_sched_entity(se) { | |
| 4803 | 4813 | cfs_rq = cfs_rq_of(se); |
| 4804 | − if (enqueue) { | |
| 4805 | − enqueue_entity(cfs_rq, se, ENQUEUE_WAKEUP); | |
| 4806 | − } else { | |
| 4807 | − update_load_avg(cfs_rq, se, 0); | |
| 4808 | − se_update_runnable(se); | |
| 4809 | − } | |
| 4814 | + | |
| 4815 | + update_load_avg(cfs_rq, se, UPDATE_TG); | |
| 4816 | + se_update_runnable(se); | |
| 4810 | 4817 | |
| 4811 | 4818 | cfs_rq->h_nr_running += task_delta; |
| 4812 | 4819 | cfs_rq->idle_h_nr_running += idle_task_delta; |
| 4813 | 4820 | |
| 4821 | + | |
| 4822 | + /* end evaluation on encountering a throttled cfs_rq */ | |
| 4814 | 4823 | if (cfs_rq_throttled(cfs_rq)) |
| 4815 | − break; | |
| 4824 | + goto unthrottle_throttle; | |
| 4825 | + | |
| 4826 | + /* | |
| 4827 | + * One parent has been throttled and cfs_rq removed from the | |
| 4828 | + * list. Add it back to not break the leaf list. | |
| 4829 | + */ | |
| 4830 | + if (throttled_hierarchy(cfs_rq)) | |
| 4831 | + list_add_leaf_cfs_rq(cfs_rq); | |
| 4816 | 4832 | } |
| 4817 | 4833 | |
| 4818 | − if (!se) | |
| 4819 | − add_nr_running(rq, task_delta); | |
| 4834 | + /* At this point se is NULL and we are at root level*/ | |
| 4835 | + add_nr_running(rq, task_delta); | |
| 4820 | 4836 | |
| 4837 | +unthrottle_throttle: | |
| 4821 | 4838 | /* |
| 4822 | 4839 | * The cfs_rq_throttled() breaks in the above iteration can result in |
| 4823 | 4840 | * incomplete leaf list maintenance, resulting in triggering the |
| @@ -4826,7 +4843,8 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) · 2 unmodified lines | ||
| 4826 | 4843 | for_each_sched_entity(se) { |
| 4827 | 4844 | cfs_rq = cfs_rq_of(se); |
| 4828 | 4845 | |
| 4829 | − list_add_leaf_cfs_rq(cfs_rq); | |
| 4846 | + if (list_add_leaf_cfs_rq(cfs_rq)) | |
| 4847 | + break; | |
| 4830 | 4848 | } |
| 4831 | 4849 | |
| 4832 | 4850 | assert_list_leaf_cfs_rq(rq); |
| @@ -5479,6 +5497,13 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) · 646 unmodified lines | ||
| 5479 | 5497 | /* end evaluation on encountering a throttled cfs_rq */ |
| 5480 | 5498 | if (cfs_rq_throttled(cfs_rq)) |
| 5481 | 5499 | goto enqueue_throttle; |
| 5500 | + | |
| 5501 | + /* | |
| 5502 | + * One parent has been throttled and cfs_rq removed from the | |
| 5503 | + * list. Add it back to not break the leaf list. | |
| 5504 | + */ | |
| 5505 | + if (throttled_hierarchy(cfs_rq)) | |
| 5506 | + list_add_leaf_cfs_rq(cfs_rq); | |
| 5482 | 5507 | } |
| 5483 | 5508 | |
| 5484 | 5509 | enqueue_throttle: |
| @@ -323,17 +323,15 @@ static const struct bpf_func_proto *bpf_get_probe_write_proto(void) · 322 unmodified lines | ||
| 323 | 323 | |
| 324 | 324 | /* |
| 325 | 325 | * Only limited trace_printk() conversion specifiers allowed: |
| 326 | − * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %s | |
| 326 | + * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %pks %pus %s | |
| 327 | 327 | */ |
| 328 | 328 | BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, |
| 329 | 329 | u64, arg2, u64, arg3) |
| 330 | 330 | { |
| 331 | + int i, mod[3] = {}, fmt_cnt = 0; | |
| 332 | + char buf[64], fmt_ptype; | |
| 333 | + void *unsafe_ptr = NULL; | |
| 331 | 334 | bool str_seen = false; |
| 332 | − int mod[3] = {}; | |
| 333 | − int fmt_cnt = 0; | |
| 334 | − u64 unsafe_addr; | |
| 335 | − char buf[64]; | |
| 336 | − int i; | |
| 337 | 335 | |
| 338 | 336 | /* |
| 339 | 337 | * bpf_check()->check_func_arg()->check_stack_boundary() |
| @@ -359,40 +357,71 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, · 19 unmodified lines | ||
| 359 | 357 | if (fmt[i] == 'l') { |
| 360 | 358 | mod[fmt_cnt]++; |
| 361 | 359 | i++; |
| 362 | − } else if (fmt[i] == 'p' || fmt[i] == 's') { | |
| 360 | + } else if (fmt[i] == 'p') { | |
| 363 | 361 | mod[fmt_cnt]++; |
| 362 | + if ((fmt[i + 1] == 'k' || | |
| 363 | + fmt[i + 1] == 'u') && | |
| 364 | + fmt[i + 2] == 's') { | |
| 365 | + fmt_ptype = fmt[i + 1]; | |
| 366 | + i += 2; | |
| 367 | + goto fmt_str; | |
| 368 | + } | |
| 369 | + | |
| 364 | 370 | /* disallow any further format extensions */ |
| 365 | 371 | if (fmt[i + 1] != 0 && |
| 366 | 372 | !isspace(fmt[i + 1]) && |
| 367 | 373 | !ispunct(fmt[i + 1])) |
| 368 | 374 | return -EINVAL; |
| 369 | − fmt_cnt++; | |
| 370 | − if (fmt[i] == 's') { | |
| 371 | − if (str_seen) | |
| 372 | − /* allow only one '%s' per fmt string */ | |
| 373 | − return -EINVAL; | |
| 374 | − str_seen = true; | |
| 375 | − | |
| 376 | − switch (fmt_cnt) { | |
| 377 | − case 1: | |
| 378 | − unsafe_addr = arg1; | |
| 379 | − arg1 = (long) buf; | |
| 380 | − break; | |
| 381 | − case 2: | |
| 382 | − unsafe_addr = arg2; | |
| 383 | − arg2 = (long) buf; | |
| 384 | − break; | |
| 385 | − case 3: | |
| 386 | − unsafe_addr = arg3; | |
| 387 | − arg3 = (long) buf; | |
| 388 | − break; | |
| 389 | − } | |
| 390 | − buf[0] = 0; | |
| 391 | − strncpy_from_unsafe(buf, | |
| 392 | − (void *) (long) unsafe_addr, | |
| 375 | + | |
| 376 | + goto fmt_next; | |
| 377 | + } else if (fmt[i] == 's') { | |
| 378 | + mod[fmt_cnt]++; | |
| 379 | + fmt_ptype = fmt[i]; | |
| 380 | +fmt_str: | |
| 381 | + if (str_seen) | |
| 382 | + /* allow only one '%s' per fmt string */ | |
| 383 | + return -EINVAL; | |
| 384 | + str_seen = true; | |
| 385 | + | |
| 386 | + if (fmt[i + 1] != 0 && | |
| 387 | + !isspace(fmt[i + 1]) && | |
| 388 | + !ispunct(fmt[i + 1])) | |
| 389 | + return -EINVAL; | |
| 390 | + | |
| 391 | + switch (fmt_cnt) { | |
| 392 | + case 0: | |
| 393 | + unsafe_ptr = (void *)(long)arg1; | |
| 394 | + arg1 = (long)buf; | |
| 395 | + break; | |
| 396 | + case 1: | |
| 397 | + unsafe_ptr = (void *)(long)arg2; | |
| 398 | + arg2 = (long)buf; | |
| 399 | + break; | |
| 400 | + case 2: | |
| 401 | + unsafe_ptr = (void *)(long)arg3; | |
| 402 | + arg3 = (long)buf; | |
| 403 | + break; | |
| 404 | + } | |
| 405 | + | |
| 406 | + buf[0] = 0; | |
| 407 | + switch (fmt_ptype) { | |
| 408 | + case 's': | |
| 409 | +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 410 | + strncpy_from_unsafe(buf, unsafe_ptr, | |
| 393 | 411 | sizeof(buf)); |
| 412 | + break; | |
| 413 | +#endif | |
| 414 | + case 'k': | |
| 415 | + strncpy_from_unsafe_strict(buf, unsafe_ptr, | |
| 416 | + sizeof(buf)); | |
| 417 | + break; | |
| 418 | + case 'u': | |
| 419 | + strncpy_from_unsafe_user(buf, | |
| 420 | + (__force void __user *)unsafe_ptr, | |
| 421 | + sizeof(buf)); | |
| 422 | + break; | |
| 394 | 423 | } |
| 395 | − continue; | |
| 424 | + goto fmt_next; | |
| 396 | 425 | } |
| 397 | 426 | |
| 398 | 427 | if (fmt[i] == 'l') { |
| @@ -403,6 +432,7 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, · 4 unmodified lines | ||
| 403 | 432 | if (fmt[i] != 'i' && fmt[i] != 'd' && |
| 404 | 433 | fmt[i] != 'u' && fmt[i] != 'x') |
| 405 | 434 | return -EINVAL; |
| 435 | +fmt_next: | |
| 406 | 436 | fmt_cnt++; |
| 407 | 437 | } |
| 408 | 438 | |
| @@ -825,14 +855,16 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 416 unmodified lines | ||
| 825 | 855 | return &bpf_probe_read_user_proto; |
| 826 | 856 | case BPF_FUNC_probe_read_kernel: |
| 827 | 857 | return &bpf_probe_read_kernel_proto; |
| 828 | − case BPF_FUNC_probe_read: | |
| 829 | − return &bpf_probe_read_compat_proto; | |
| 830 | 858 | case BPF_FUNC_probe_read_user_str: |
| 831 | 859 | return &bpf_probe_read_user_str_proto; |
| 832 | 860 | case BPF_FUNC_probe_read_kernel_str: |
| 833 | 861 | return &bpf_probe_read_kernel_str_proto; |
| 862 | +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE | |
| 863 | + case BPF_FUNC_probe_read: | |
| 864 | + return &bpf_probe_read_compat_proto; | |
| 834 | 865 | case BPF_FUNC_probe_read_str: |
| 835 | 866 | return &bpf_probe_read_compat_str_proto; |
| 867 | +#endif | |
| 836 | 868 | #ifdef CONFIG_CGROUPS |
| 837 | 869 | case BPF_FUNC_get_current_cgroup_id: |
| 838 | 870 | return &bpf_get_current_cgroup_id_proto; |
| @@ -4,28 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #ifdef CONFIG_FUNCTION_TRACER |
| 6 | 6 | |
| 7 | −/* | |
| 8 | − * Traverse the ftrace_global_list, invoking all entries. The reason that we | |
| 9 | − * can use rcu_dereference_raw_check() is that elements removed from this list | |
| 10 | − * are simply leaked, so there is no need to interact with a grace-period | |
| 11 | − * mechanism. The rcu_dereference_raw_check() calls are needed to handle | |
| 12 | − * concurrent insertions into the ftrace_global_list. | |
| 13 | − * | |
| 14 | − * Silly Alpha and silly pointer-speculation compiler optimizations! | |
| 15 | − */ | |
| 16 | −#define do_for_each_ftrace_op(op, list) \ | |
| 17 | − op = rcu_dereference_raw_check(list); \ | |
| 18 | − do | |
| 19 | − | |
| 20 | −/* | |
| 21 | − * Optimized for just a single item in the list (as that is the normal case). | |
| 22 | − */ | |
| 23 | −#define while_for_each_ftrace_op(op) \ | |
| 24 | − while (likely(op = rcu_dereference_raw_check((op)->next)) && \ | |
| 25 | − unlikely((op) != &ftrace_list_end)) | |
| 26 | − | |
| 27 | −extern struct ftrace_ops __rcu *ftrace_ops_list; | |
| 28 | −extern struct ftrace_ops ftrace_list_end; | |
| 29 | 7 | extern struct mutex ftrace_lock; |
| 30 | 8 | extern struct ftrace_ops global_ops; |
| 31 | 9 | |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/printk.h> |
| 17 | 17 | #include <linux/string.h> |
| 18 | 18 | #include <linux/sysfs.h> |
| 19 | +#include <linux/completion.h> | |
| 19 | 20 | |
| 20 | 21 | static ulong delay = 100; |
| 21 | 22 | static char test_mode[12] = "irq"; |
| @@ -28,6 +29,8 @@ MODULE_PARM_DESC(delay, "Period in microseconds (100 us default)"); · 6 unmodified lines | ||
| 28 | 29 | MODULE_PARM_DESC(test_mode, "Mode of the test such as preempt, irq, or alternate (default irq)"); |
| 29 | 30 | MODULE_PARM_DESC(burst_size, "The size of a burst (default 1)"); |
| 30 | 31 | |
| 32 | +static struct completion done; | |
| 33 | + | |
| 31 | 34 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) |
| 32 | 35 | |
| 33 | 36 | static void busy_wait(ulong time) |
| @@ -114,6 +117,8 @@ static int preemptirq_delay_run(void *data) · 80 unmodified lines | ||
| 114 | 117 | for (i = 0; i < s; i++) |
| 115 | 118 | (testfuncs[i])(i); |
| 116 | 119 | |
| 120 | + complete(&done); | |
| 121 | + | |
| 117 | 122 | set_current_state(TASK_INTERRUPTIBLE); |
| 118 | 123 | while (!kthread_should_stop()) { |
| 119 | 124 | schedule(); |
| @@ -128,15 +133,18 @@ static int preemptirq_delay_run(void *data) · 8 unmodified lines | ||
| 128 | 133 | static int preemptirq_run_test(void) |
| 129 | 134 | { |
| 130 | 135 | struct task_struct *task; |
| 131 | − | |
| 132 | 136 | char task_name[50]; |
| 133 | 137 | |
| 138 | + init_completion(&done); | |
| 139 | + | |
| 134 | 140 | snprintf(task_name, sizeof(task_name), "%s_test", test_mode); |
| 135 | 141 | task = kthread_run(preemptirq_delay_run, NULL, task_name); |
| 136 | 142 | if (IS_ERR(task)) |
| 137 | 143 | return PTR_ERR(task); |
| 138 | − if (task) | |
| 144 | + if (task) { | |
| 145 | + wait_for_completion(&done); | |
| 139 | 146 | kthread_stop(task); |
| 147 | + } | |
| 140 | 148 | return 0; |
| 141 | 149 | } |
| 142 | 150 | |
| @@ -193,7 +193,7 @@ rb_event_length(struct ring_buffer_event *event) · 192 unmodified lines | ||
| 193 | 193 | case RINGBUF_TYPE_DATA: |
| 194 | 194 | return rb_event_data_length(event); |
| 195 | 195 | default: |
| 196 | − BUG(); | |
| 196 | + WARN_ON_ONCE(1); | |
| 197 | 197 | } |
| 198 | 198 | /* not hit */ |
| 199 | 199 | return 0; |
| @@ -249,7 +249,7 @@ rb_event_data(struct ring_buffer_event *event) · 49 unmodified lines | ||
| 249 | 249 | { |
| 250 | 250 | if (extended_time(event)) |
| 251 | 251 | event = skip_time_extend(event); |
| 252 | − BUG_ON(event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX); | |
| 252 | + WARN_ON_ONCE(event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX); | |
| 253 | 253 | /* If length is in len field, then array[0] has the data */ |
| 254 | 254 | if (event->type_len) |
| 255 | 255 | return (void *)&event->array[0]; |
| @@ -3727,7 +3727,7 @@ rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer, · 3471 unmodified lines | ||
| 3727 | 3727 | return; |
| 3728 | 3728 | |
| 3729 | 3729 | default: |
| 3730 | − BUG(); | |
| 3730 | + RB_WARN_ON(cpu_buffer, 1); | |
| 3731 | 3731 | } |
| 3732 | 3732 | return; |
| 3733 | 3733 | } |
| @@ -3757,7 +3757,7 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *iter, · 23 unmodified lines | ||
| 3757 | 3757 | return; |
| 3758 | 3758 | |
| 3759 | 3759 | default: |
| 3760 | − BUG(); | |
| 3760 | + RB_WARN_ON(iter->cpu_buffer, 1); | |
| 3761 | 3761 | } |
| 3762 | 3762 | return; |
| 3763 | 3763 | } |
| @@ -4020,7 +4020,7 @@ rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts, · 256 unmodified lines | ||
| 4020 | 4020 | return event; |
| 4021 | 4021 | |
| 4022 | 4022 | default: |
| 4023 | − BUG(); | |
| 4023 | + RB_WARN_ON(cpu_buffer, 1); | |
| 4024 | 4024 | } |
| 4025 | 4025 | |
| 4026 | 4026 | return NULL; |
| @@ -4034,7 +4034,6 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) · 7 unmodified lines | ||
| 4034 | 4034 | struct ring_buffer_per_cpu *cpu_buffer; |
| 4035 | 4035 | struct ring_buffer_event *event; |
| 4036 | 4036 | int nr_loops = 0; |
| 4037 | − bool failed = false; | |
| 4038 | 4037 | |
| 4039 | 4038 | if (ts) |
| 4040 | 4039 | *ts = 0; |
| @@ -4056,19 +4055,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) · 15 unmodified lines | ||
| 4056 | 4055 | return NULL; |
| 4057 | 4056 | |
| 4058 | 4057 | /* |
| 4059 | − * We repeat when a time extend is encountered or we hit | |
| 4060 | − * the end of the page. Since the time extend is always attached | |
| 4061 | − * to a data event, we should never loop more than three times. | |
| 4062 | − * Once for going to next page, once on time extend, and | |
| 4063 | − * finally once to get the event. | |
| 4064 | − * We should never hit the following condition more than thrice, | |
| 4065 | − * unless the buffer is very small, and there's a writer | |
| 4066 | − * that is causing the reader to fail getting an event. | |
| 4058 | + * As the writer can mess with what the iterator is trying | |
| 4059 | + * to read, just give up if we fail to get an event after | |
| 4060 | + * three tries. The iterator is not as reliable when reading | |
| 4061 | + * the ring buffer with an active write as the consumer is. | |
| 4062 | + * Do not warn if the three failures is reached. | |
| 4067 | 4063 | */ |
| 4068 | − if (++nr_loops > 3) { | |
| 4069 | − RB_WARN_ON(cpu_buffer, !failed); | |
| 4064 | + if (++nr_loops > 3) | |
| 4070 | 4065 | return NULL; |
| 4071 | − } | |
| 4072 | 4066 | |
| 4073 | 4067 | if (rb_per_cpu_empty(cpu_buffer)) |
| 4074 | 4068 | return NULL; |
| @@ -4079,10 +4073,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) · 4 unmodified lines | ||
| 4079 | 4073 | } |
| 4080 | 4074 | |
| 4081 | 4075 | event = rb_iter_head_event(iter); |
| 4082 | − if (!event) { | |
| 4083 | − failed = true; | |
| 4076 | + if (!event) | |
| 4084 | 4077 | goto again; |
| 4085 | − } | |
| 4086 | 4078 | |
| 4087 | 4079 | switch (event->type_len) { |
| 4088 | 4080 | case RINGBUF_TYPE_PADDING: |
| @@ -4117,7 +4109,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) · 28 unmodified lines | ||
| 4117 | 4109 | return event; |
| 4118 | 4110 | |
| 4119 | 4111 | default: |
| 4120 | − BUG(); | |
| 4112 | + RB_WARN_ON(cpu_buffer, 1); | |
| 4121 | 4113 | } |
| 4122 | 4114 | |
| 4123 | 4115 | return NULL; |
| @@ -475,6 +475,12 @@ static void umh_clean_and_save_pid(struct subprocess_info *info) · 474 unmodified lines | ||
| 475 | 475 | { |
| 476 | 476 | struct umh_info *umh_info = info->data; |
| 477 | 477 | |
| 478 | + /* cleanup if umh_pipe_setup() was successful but exec failed */ | |
| 479 | + if (info->pid && info->retval) { | |
| 480 | + fput(umh_info->pipe_to_umh); | |
| 481 | + fput(umh_info->pipe_from_umh); | |
| 482 | + } | |
| 483 | + | |
| 478 | 484 | argv_free(info->argv); |
| 479 | 485 | umh_info->pid = info->pid; |
| 480 | 486 | } |
| @@ -214,6 +214,7 @@ test_string(void) · 213 unmodified lines | ||
| 214 | 214 | #define PTR_STR "ffff0123456789ab" |
| 215 | 215 | #define PTR_VAL_NO_CRNG "(____ptrval____)" |
| 216 | 216 | #define ZEROS "00000000" /* hex 32 zero bits */ |
| 217 | +#define ONES "ffffffff" /* hex 32 one bits */ | |
| 217 | 218 | |
| 218 | 219 | static int __init |
| 219 | 220 | plain_format(void) |
| @@ -245,6 +246,7 @@ plain_format(void) · 25 unmodified lines | ||
| 245 | 246 | #define PTR_STR "456789ab" |
| 246 | 247 | #define PTR_VAL_NO_CRNG "(ptrval)" |
| 247 | 248 | #define ZEROS "" |
| 249 | +#define ONES "" | |
| 248 | 250 | |
| 249 | 251 | static int __init |
| 250 | 252 | plain_format(void) |
| @@ -330,14 +332,28 @@ test_hashed(const char *fmt, const void *p) · 79 unmodified lines | ||
| 330 | 332 | test(buf, fmt, p); |
| 331 | 333 | } |
| 332 | 334 | |
| 335 | +/* | |
| 336 | + * NULL pointers aren't hashed. | |
| 337 | + */ | |
| 333 | 338 | static void __init |
| 334 | 339 | null_pointer(void) |
| 335 | 340 | { |
| 336 | − test_hashed("%p", NULL); | |
| 341 | + test(ZEROS "00000000", "%p", NULL); | |
| 337 | 342 | test(ZEROS "00000000", "%px", NULL); |
| 338 | 343 | test("(null)", "%pE", NULL); |
| 339 | 344 | } |
| 340 | 345 | |
| 346 | +/* | |
| 347 | + * Error pointers aren't hashed. | |
| 348 | + */ | |
| 349 | +static void __init | |
| 350 | +error_pointer(void) | |
| 351 | +{ | |
| 352 | + test(ONES "fffffff5", "%p", ERR_PTR(-11)); | |
| 353 | + test(ONES "fffffff5", "%px", ERR_PTR(-11)); | |
| 354 | + test("(efault)", "%pE", ERR_PTR(-11)); | |
| 355 | +} | |
| 356 | + | |
| 341 | 357 | #define PTR_INVALID ((void *)0x000000ab) |
| 342 | 358 | |
| 343 | 359 | static void __init |
| @@ -649,6 +665,7 @@ test_pointer(void) · 305 unmodified lines | ||
| 649 | 665 | { |
| 650 | 666 | plain(); |
| 651 | 667 | null_pointer(); |
| 668 | + error_pointer(); | |
| 652 | 669 | invalid_pointer(); |
| 653 | 670 | symbol_ptr(); |
| 654 | 671 | kernel_ptr(); |
| @@ -794,6 +794,13 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr, · 793 unmodified lines | ||
| 794 | 794 | unsigned long hashval; |
| 795 | 795 | int ret; |
| 796 | 796 | |
| 797 | + /* | |
| 798 | + * Print the real pointer value for NULL and error pointers, | |
| 799 | + * as they are not actual addresses. | |
| 800 | + */ | |
| 801 | + if (IS_ERR_OR_NULL(ptr)) | |
| 802 | + return pointer_string(buf, end, ptr, spec); | |
| 803 | + | |
| 797 | 804 | /* When debugging early boot use non-cryptographically secure hash. */ |
| 798 | 805 | if (unlikely(debug_boot_weak_hash)) { |
| 799 | 806 | hashval = hash_long((unsigned long)ptr, 32); |
| @@ -2168,6 +2175,10 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode, · 1368 unmodified lines | ||
| 2168 | 2175 | * f full name |
| 2169 | 2176 | * P node name, including a possible unit address |
| 2170 | 2177 | * - 'x' For printing the address. Equivalent to "%lx". |
| 2178 | + * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of | |
| 2179 | + * bpf_trace_printk() where [ku] prefix specifies either kernel (k) | |
| 2180 | + * or user (u) memory to probe, and: | |
| 2181 | + * s a string, equivalent to "%s" on direct vsnprintf() use | |
| 2171 | 2182 | * |
| 2172 | 2183 | * ** When making changes please also update: |
| 2173 | 2184 | * Documentation/core-api/printk-formats.rst |
| @@ -2251,6 +2262,14 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, · 77 unmodified lines | ||
| 2251 | 2262 | if (!IS_ERR(ptr)) |
| 2252 | 2263 | break; |
| 2253 | 2264 | return err_ptr(buf, end, ptr, spec); |
| 2265 | + case 'u': | |
| 2266 | + case 'k': | |
| 2267 | + switch (fmt[1]) { | |
| 2268 | + case 's': | |
| 2269 | + return string(buf, end, ptr, spec); | |
| 2270 | + default: | |
| 2271 | + return error_string(buf, end, "(einval)", spec); | |
| 2272 | + } | |
| 2254 | 2273 | } |
| 2255 | 2274 | |
| 2256 | 2275 | /* default is to _not_ leak addresses, hash before printing */ |
| @@ -1218,6 +1218,10 @@ retry: · 1217 unmodified lines | ||
| 1218 | 1218 | if (!vma_permits_fault(vma, fault_flags)) |
| 1219 | 1219 | return -EFAULT; |
| 1220 | 1220 | |
| 1221 | + if ((fault_flags & FAULT_FLAG_KILLABLE) && | |
| 1222 | + fatal_signal_pending(current)) | |
| 1223 | + return -EINTR; | |
| 1224 | + | |
| 1221 | 1225 | ret = handle_mm_fault(vma, address, fault_flags); |
| 1222 | 1226 | major |= ret & VM_FAULT_MAJOR; |
| 1223 | 1227 | if (ret & VM_FAULT_ERROR) { |
| @@ -1230,11 +1234,9 @@ retry: · 6 unmodified lines | ||
| 1230 | 1234 | |
| 1231 | 1235 | if (ret & VM_FAULT_RETRY) { |
| 1232 | 1236 | down_read(&mm->mmap_sem); |
| 1233 | − if (!(fault_flags & FAULT_FLAG_TRIED)) { | |
| 1234 | − *unlocked = true; | |
| 1235 | − fault_flags |= FAULT_FLAG_TRIED; | |
| 1236 | − goto retry; | |
| 1237 | − } | |
| 1237 | + *unlocked = true; | |
| 1238 | + fault_flags |= FAULT_FLAG_TRIED; | |
| 1239 | + goto retry; | |
| 1238 | 1240 | } |
| 1239 | 1241 | |
| 1240 | 1242 | if (tsk) { |
| @@ -1,23 +1,28 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | KASAN_SANITIZE := n |
| 3 | −UBSAN_SANITIZE_common.o := n | |
| 4 | −UBSAN_SANITIZE_generic.o := n | |
| 5 | −UBSAN_SANITIZE_generic_report.o := n | |
| 6 | −UBSAN_SANITIZE_tags.o := n | |
| 3 | +UBSAN_SANITIZE := n | |
| 7 | 4 | KCOV_INSTRUMENT := n |
| 8 | 5 | |
| 6 | +# Disable ftrace to avoid recursion. | |
| 9 | 7 | CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE) |
| 10 | 8 | CFLAGS_REMOVE_generic.o = $(CC_FLAGS_FTRACE) |
| 11 | 9 | CFLAGS_REMOVE_generic_report.o = $(CC_FLAGS_FTRACE) |
| 10 | +CFLAGS_REMOVE_init.o = $(CC_FLAGS_FTRACE) | |
| 11 | +CFLAGS_REMOVE_quarantine.o = $(CC_FLAGS_FTRACE) | |
| 12 | +CFLAGS_REMOVE_report.o = $(CC_FLAGS_FTRACE) | |
| 12 | 13 | CFLAGS_REMOVE_tags.o = $(CC_FLAGS_FTRACE) |
| 14 | +CFLAGS_REMOVE_tags_report.o = $(CC_FLAGS_FTRACE) | |
| 13 | 15 | |
| 14 | 16 | # Function splitter causes unnecessary splits in __asan_load1/__asan_store1 |
| 15 | 17 | # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533 |
| 16 | − | |
| 17 | −CFLAGS_common.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) | |
| 18 | −CFLAGS_generic.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) | |
| 19 | −CFLAGS_generic_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) | |
| 20 | −CFLAGS_tags.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) | |
| 18 | +CFLAGS_common.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 19 | +CFLAGS_generic.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 20 | +CFLAGS_generic_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 21 | +CFLAGS_init.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 22 | +CFLAGS_quarantine.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 23 | +CFLAGS_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 24 | +CFLAGS_tags.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 25 | +CFLAGS_tags_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) -DDISABLE_BRANCH_PROFILING | |
| 21 | 26 | |
| 22 | 27 | obj-$(CONFIG_KASAN) := common.o init.o report.o |
| 23 | 28 | obj-$(CONFIG_KASAN_GENERIC) += generic.o generic_report.o quarantine.o |
| @@ -15,7 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 18 | −#define DISABLE_BRANCH_PROFILING | |
| 19 | 18 | |
| 20 | 19 | #include <linux/export.h> |
| 21 | 20 | #include <linux/interrupt.h> |
| @@ -212,8 +212,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) · 211 unmodified lines | ||
| 212 | 212 | asmlinkage void kasan_unpoison_task_stack_below(const void *watermark); |
| 213 | 213 | void __asan_register_globals(struct kasan_global *globals, size_t size); |
| 214 | 214 | void __asan_unregister_globals(struct kasan_global *globals, size_t size); |
| 215 | −void __asan_loadN(unsigned long addr, size_t size); | |
| 216 | −void __asan_storeN(unsigned long addr, size_t size); | |
| 217 | 215 | void __asan_handle_no_return(void); |
| 218 | 216 | void __asan_alloca_poison(unsigned long addr, size_t size); |
| 219 | 217 | void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom); |
| @@ -228,6 +226,8 @@ void __asan_load8(unsigned long addr); · 8 unmodified lines | ||
| 228 | 226 | void __asan_store8(unsigned long addr); |
| 229 | 227 | void __asan_load16(unsigned long addr); |
| 230 | 228 | void __asan_store16(unsigned long addr); |
| 229 | +void __asan_loadN(unsigned long addr, size_t size); | |
| 230 | +void __asan_storeN(unsigned long addr, size_t size); | |
| 231 | 231 | |
| 232 | 232 | void __asan_load1_noabort(unsigned long addr); |
| 233 | 233 | void __asan_store1_noabort(unsigned long addr); |
| @@ -239,6 +239,21 @@ void __asan_load8_noabort(unsigned long addr); · 5 unmodified lines | ||
| 239 | 239 | void __asan_store8_noabort(unsigned long addr); |
| 240 | 240 | void __asan_load16_noabort(unsigned long addr); |
| 241 | 241 | void __asan_store16_noabort(unsigned long addr); |
| 242 | +void __asan_loadN_noabort(unsigned long addr, size_t size); | |
| 243 | +void __asan_storeN_noabort(unsigned long addr, size_t size); | |
| 244 | + | |
| 245 | +void __asan_report_load1_noabort(unsigned long addr); | |
| 246 | +void __asan_report_store1_noabort(unsigned long addr); | |
| 247 | +void __asan_report_load2_noabort(unsigned long addr); | |
| 248 | +void __asan_report_store2_noabort(unsigned long addr); | |
| 249 | +void __asan_report_load4_noabort(unsigned long addr); | |
| 250 | +void __asan_report_store4_noabort(unsigned long addr); | |
| 251 | +void __asan_report_load8_noabort(unsigned long addr); | |
| 252 | +void __asan_report_store8_noabort(unsigned long addr); | |
| 253 | +void __asan_report_load16_noabort(unsigned long addr); | |
| 254 | +void __asan_report_store16_noabort(unsigned long addr); | |
| 255 | +void __asan_report_load_n_noabort(unsigned long addr, size_t size); | |
| 256 | +void __asan_report_store_n_noabort(unsigned long addr, size_t size); | |
| 242 | 257 | |
| 243 | 258 | void __asan_set_shadow_00(const void *addr, size_t size); |
| 244 | 259 | void __asan_set_shadow_f1(const void *addr, size_t size); |
| @@ -247,4 +262,19 @@ void __asan_set_shadow_f3(const void *addr, size_t size); · 2 unmodified lines | ||
| 247 | 262 | void __asan_set_shadow_f5(const void *addr, size_t size); |
| 248 | 263 | void __asan_set_shadow_f8(const void *addr, size_t size); |
| 249 | 264 | |
| 265 | +void __hwasan_load1_noabort(unsigned long addr); | |
| 266 | +void __hwasan_store1_noabort(unsigned long addr); | |
| 267 | +void __hwasan_load2_noabort(unsigned long addr); | |
| 268 | +void __hwasan_store2_noabort(unsigned long addr); | |
| 269 | +void __hwasan_load4_noabort(unsigned long addr); | |
| 270 | +void __hwasan_store4_noabort(unsigned long addr); | |
| 271 | +void __hwasan_load8_noabort(unsigned long addr); | |
| 272 | +void __hwasan_store8_noabort(unsigned long addr); | |
| 273 | +void __hwasan_load16_noabort(unsigned long addr); | |
| 274 | +void __hwasan_store16_noabort(unsigned long addr); | |
| 275 | +void __hwasan_loadN_noabort(unsigned long addr, size_t size); | |
| 276 | +void __hwasan_storeN_noabort(unsigned long addr, size_t size); | |
| 277 | + | |
| 278 | +void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size); | |
| 279 | + | |
| 250 | 280 | #endif |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 15 | −#define DISABLE_BRANCH_PROFILING | |
| 16 | 15 | |
| 17 | 16 | #include <linux/export.h> |
| 18 | 17 | #include <linux/interrupt.h> |
| @@ -794,7 +794,7 @@ out: · 793 unmodified lines | ||
| 794 | 794 | if (locked && new_len > old_len) |
| 795 | 795 | mm_populate(new_addr + old_len, new_len - old_len); |
| 796 | 796 | userfaultfd_unmap_complete(mm, &uf_unmap_early); |
| 797 | − mremap_userfaultfd_complete(&uf, addr, new_addr, old_len); | |
| 797 | + mremap_userfaultfd_complete(&uf, addr, ret, old_len); | |
| 798 | 798 | userfaultfd_unmap_complete(mm, &uf_unmap); |
| 799 | 799 | return ret; |
| 800 | 800 | } |
| @@ -318,16 +318,16 @@ static inline void free_handle(unsigned long handle) · 317 unmodified lines | ||
| 318 | 318 | slots = handle_to_slots(handle); |
| 319 | 319 | write_lock(&slots->lock); |
| 320 | 320 | *(unsigned long *)handle = 0; |
| 321 | − write_unlock(&slots->lock); | |
| 322 | − if (zhdr->slots == slots) | |
| 321 | + if (zhdr->slots == slots) { | |
| 322 | + write_unlock(&slots->lock); | |
| 323 | 323 | return; /* simple case, nothing else to do */ |
| 324 | + } | |
| 324 | 325 | |
| 325 | 326 | /* we are freeing a foreign handle if we are here */ |
| 326 | 327 | zhdr->foreign_handles--; |
| 327 | 328 | is_free = true; |
| 328 | − read_lock(&slots->lock); | |
| 329 | 329 | if (!test_bit(HANDLES_ORPHANED, &slots->pool)) { |
| 330 | − read_unlock(&slots->lock); | |
| 330 | + write_unlock(&slots->lock); | |
| 331 | 331 | return; |
| 332 | 332 | } |
| 333 | 333 | for (i = 0; i <= BUDDY_MASK; i++) { |
| @@ -336,7 +336,7 @@ static inline void free_handle(unsigned long handle) · 2 unmodified lines | ||
| 336 | 336 | break; |
| 337 | 337 | } |
| 338 | 338 | } |
| 339 | − read_unlock(&slots->lock); | |
| 339 | + write_unlock(&slots->lock); | |
| 340 | 340 | |
| 341 | 341 | if (is_free) { |
| 342 | 342 | struct z3fold_pool *pool = slots_to_pool(slots); |
| @@ -422,6 +422,7 @@ static struct z3fold_header *init_z3fold_page(struct page *page, bool headless, · 79 unmodified lines | ||
| 422 | 422 | zhdr->start_middle = 0; |
| 423 | 423 | zhdr->cpu = -1; |
| 424 | 424 | zhdr->foreign_handles = 0; |
| 425 | + zhdr->mapped_count = 0; | |
| 425 | 426 | zhdr->slots = slots; |
| 426 | 427 | zhdr->pool = pool; |
| 427 | 428 | INIT_LIST_HEAD(&zhdr->buddy); |
| @@ -635,8 +635,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, · 634 unmodified lines | ||
| 635 | 635 | break; |
| 636 | 636 | |
| 637 | 637 | case SO_BINDTODEVICE: |
| 638 | − if (optlen > IFNAMSIZ) | |
| 639 | − optlen = IFNAMSIZ; | |
| 638 | + if (optlen > IFNAMSIZ - 1) | |
| 639 | + optlen = IFNAMSIZ - 1; | |
| 640 | + | |
| 641 | + memset(devname, 0, sizeof(devname)); | |
| 640 | 642 | |
| 641 | 643 | if (copy_from_user(devname, optval, optlen)) { |
| 642 | 644 | res = -EFAULT; |
| @@ -4988,11 +4988,12 @@ static inline int nf_ingress(struct sk_buff *skb, struct packet_type **pt_prev, · 4987 unmodified lines | ||
| 4988 | 4988 | return 0; |
| 4989 | 4989 | } |
| 4990 | 4990 | |
| 4991 | −static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc, | |
| 4991 | +static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc, | |
| 4992 | 4992 | struct packet_type **ppt_prev) |
| 4993 | 4993 | { |
| 4994 | 4994 | struct packet_type *ptype, *pt_prev; |
| 4995 | 4995 | rx_handler_func_t *rx_handler; |
| 4996 | + struct sk_buff *skb = *pskb; | |
| 4996 | 4997 | struct net_device *orig_dev; |
| 4997 | 4998 | bool deliver_exact = false; |
| 4998 | 4999 | int ret = NET_RX_DROP; |
| @@ -5023,8 +5024,10 @@ another_round: · 24 unmodified lines | ||
| 5023 | 5024 | ret2 = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb); |
| 5024 | 5025 | preempt_enable(); |
| 5025 | 5026 | |
| 5026 | − if (ret2 != XDP_PASS) | |
| 5027 | − return NET_RX_DROP; | |
| 5027 | + if (ret2 != XDP_PASS) { | |
| 5028 | + ret = NET_RX_DROP; | |
| 5029 | + goto out; | |
| 5030 | + } | |
| 5028 | 5031 | skb_reset_mac_len(skb); |
| 5029 | 5032 | } |
| 5030 | 5033 | |
| @@ -5174,6 +5177,13 @@ drop: · 143 unmodified lines | ||
| 5174 | 5177 | } |
| 5175 | 5178 | |
| 5176 | 5179 | out: |
| 5180 | + /* The invariant here is that if *ppt_prev is not NULL | |
| 5181 | + * then skb should also be non-NULL. | |
| 5182 | + * | |
| 5183 | + * Apparently *ppt_prev assignment above holds this invariant due to | |
| 5184 | + * skb dereferencing near it. | |
| 5185 | + */ | |
| 5186 | + *pskb = skb; | |
| 5177 | 5187 | return ret; |
| 5178 | 5188 | } |
| 5179 | 5189 | |
| @@ -5183,7 +5193,7 @@ static int __netif_receive_skb_one_core(struct sk_buff *skb, bool pfmemalloc) · 3 unmodified lines | ||
| 5183 | 5193 | struct packet_type *pt_prev = NULL; |
| 5184 | 5194 | int ret; |
| 5185 | 5195 | |
| 5186 | − ret = __netif_receive_skb_core(skb, pfmemalloc, &pt_prev); | |
| 5196 | + ret = __netif_receive_skb_core(&skb, pfmemalloc, &pt_prev); | |
| 5187 | 5197 | if (pt_prev) |
| 5188 | 5198 | ret = INDIRECT_CALL_INET(pt_prev->func, ipv6_rcv, ip_rcv, skb, |
| 5189 | 5199 | skb->dev, pt_prev, orig_dev); |
| @@ -5261,7 +5271,7 @@ static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemallo · 71 unmodified lines | ||
| 5261 | 5271 | struct packet_type *pt_prev = NULL; |
| 5262 | 5272 | |
| 5263 | 5273 | skb_list_del_init(skb); |
| 5264 | − __netif_receive_skb_core(skb, pfmemalloc, &pt_prev); | |
| 5274 | + __netif_receive_skb_core(&skb, pfmemalloc, &pt_prev); | |
| 5265 | 5275 | if (!pt_prev) |
| 5266 | 5276 | continue; |
| 5267 | 5277 | if (pt_curr != pt_prev || od_curr != orig_dev) { |
| @@ -8907,11 +8917,13 @@ static void netdev_sync_lower_features(struct net_device *upper, · 3639 unmodified lines | ||
| 8907 | 8917 | netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n", |
| 8908 | 8918 | &feature, lower->name); |
| 8909 | 8919 | lower->wanted_features &= ~feature; |
| 8910 | − netdev_update_features(lower); | |
| 8920 | + __netdev_update_features(lower); | |
| 8911 | 8921 | |
| 8912 | 8922 | if (unlikely(lower->features & feature)) |
| 8913 | 8923 | netdev_WARN(upper, "failed to disable %pNF on %s!\n", |
| 8914 | 8924 | &feature, lower->name); |
| 8925 | + else | |
| 8926 | + netdev_features_change(lower); | |
| 8915 | 8927 | } |
| 8916 | 8928 | } |
| 8917 | 8929 | } |
| @@ -2590,8 +2590,8 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, · 2589 unmodified lines | ||
| 2590 | 2590 | } |
| 2591 | 2591 | pop = 0; |
| 2592 | 2592 | } else if (pop >= sge->length - a) { |
| 2593 | − sge->length = a; | |
| 2594 | 2593 | pop -= (sge->length - a); |
| 2594 | + sge->length = a; | |
| 2595 | 2595 | } |
| 2596 | 2596 | } |
| 2597 | 2597 | |
| @@ -160,12 +160,10 @@ out: · 159 unmodified lines | ||
| 160 | 160 | return ret; |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | −int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr) | |
| 163 | +static int flow_dissector_bpf_prog_detach(struct net *net) | |
| 164 | 164 | { |
| 165 | 165 | struct bpf_prog *attached; |
| 166 | − struct net *net; | |
| 167 | 166 | |
| 168 | − net = current->nsproxy->net_ns; | |
| 169 | 167 | mutex_lock(&flow_dissector_mutex); |
| 170 | 168 | attached = rcu_dereference_protected(net->flow_dissector_prog, |
| 171 | 169 | lockdep_is_held(&flow_dissector_mutex)); |
| @@ -179,6 +177,24 @@ int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr) · 7 unmodified lines | ||
| 179 | 177 | return 0; |
| 180 | 178 | } |
| 181 | 179 | |
| 180 | +int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr) | |
| 181 | +{ | |
| 182 | + return flow_dissector_bpf_prog_detach(current->nsproxy->net_ns); | |
| 183 | +} | |
| 184 | + | |
| 185 | +static void __net_exit flow_dissector_pernet_pre_exit(struct net *net) | |
| 186 | +{ | |
| 187 | + /* We're not racing with attach/detach because there are no | |
| 188 | + * references to netns left when pre_exit gets called. | |
| 189 | + */ | |
| 190 | + if (rcu_access_pointer(net->flow_dissector_prog)) | |
| 191 | + flow_dissector_bpf_prog_detach(net); | |
| 192 | +} | |
| 193 | + | |
| 194 | +static struct pernet_operations flow_dissector_pernet_ops __net_initdata = { | |
| 195 | + .pre_exit = flow_dissector_pernet_pre_exit, | |
| 196 | +}; | |
| 197 | + | |
| 182 | 198 | /** |
| 183 | 199 | * __skb_flow_get_ports - extract the upper layer ports and return them |
| 184 | 200 | * @skb: sk_buff to extract the ports from |
| @@ -1836,7 +1852,7 @@ static int __init init_default_flow_dissectors(void) · 1651 unmodified lines | ||
| 1836 | 1852 | skb_flow_dissector_init(&flow_keys_basic_dissector, |
| 1837 | 1853 | flow_keys_basic_dissector_keys, |
| 1838 | 1854 | ARRAY_SIZE(flow_keys_basic_dissector_keys)); |
| 1839 | − return 0; | |
| 1840 | −} | |
| 1841 | 1855 | |
| 1856 | + return register_pernet_subsys(&flow_dissector_pernet_ops); | |
| 1857 | +} | |
| 1842 | 1858 | core_initcall(init_default_flow_dissectors); |
| @@ -236,6 +236,8 @@ static void net_prio_attach(struct cgroup_taskset *tset) · 235 unmodified lines | ||
| 236 | 236 | struct task_struct *p; |
| 237 | 237 | struct cgroup_subsys_state *css; |
| 238 | 238 | |
| 239 | + cgroup_sk_alloc_disable(); | |
| 240 | + | |
| 239 | 241 | cgroup_taskset_for_each(p, css, tset) { |
| 240 | 242 | void *v = (void *)(unsigned long)css->id; |
| 241 | 243 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 |
| 16 | 16 | #define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) |
| 17 | 17 | #define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0) |
| 18 | +#define MTK_HDR_XMIT_SA_DIS BIT(6) | |
| 18 | 19 | |
| 19 | 20 | static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, |
| 20 | 21 | struct net_device *dev) |
| @@ -22,6 +23,9 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, · 1 unmodified line | ||
| 22 | 23 | struct dsa_port *dp = dsa_slave_to_port(dev); |
| 23 | 24 | u8 *mtk_tag; |
| 24 | 25 | bool is_vlan_skb = true; |
| 26 | + unsigned char *dest = eth_hdr(skb)->h_dest; | |
| 27 | + bool is_multicast_skb = is_multicast_ether_addr(dest) && | |
| 28 | + !is_broadcast_ether_addr(dest); | |
| 25 | 29 | |
| 26 | 30 | /* Build the special tag after the MAC Source Address. If VLAN header |
| 27 | 31 | * is present, it's required that VLAN header and special tag is |
| @@ -47,6 +51,10 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, · 19 unmodified lines | ||
| 47 | 51 | MTK_HDR_XMIT_UNTAGGED; |
| 48 | 52 | mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; |
| 49 | 53 | |
| 54 | + /* Disable SA learning for multicast frames */ | |
| 55 | + if (unlikely(is_multicast_skb)) | |
| 56 | + mtk_tag[1] |= MTK_HDR_XMIT_SA_DIS; | |
| 57 | + | |
| 50 | 58 | /* Tag control information is kept for 802.1Q */ |
| 51 | 59 | if (!is_vlan_skb) { |
| 52 | 60 | mtk_tag[2] = 0; |
| @@ -61,6 +69,9 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, · 8 unmodified lines | ||
| 61 | 69 | { |
| 62 | 70 | int port; |
| 63 | 71 | __be16 *phdr, hdr; |
| 72 | + unsigned char *dest = eth_hdr(skb)->h_dest; | |
| 73 | + bool is_multicast_skb = is_multicast_ether_addr(dest) && | |
| 74 | + !is_broadcast_ether_addr(dest); | |
| 64 | 75 | |
| 65 | 76 | if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN))) |
| 66 | 77 | return NULL; |
| @@ -86,6 +97,10 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, · 19 unmodified lines | ||
| 86 | 97 | if (!skb->dev) |
| 87 | 98 | return NULL; |
| 88 | 99 | |
| 100 | + /* Only unicast or broadcast frames are offloaded */ | |
| 101 | + if (likely(!is_multicast_skb)) | |
| 102 | + skb->offload_fwd_mark = 1; | |
| 103 | + | |
| 89 | 104 | return skb; |
| 90 | 105 | } |
| 91 | 106 | |
| @@ -342,7 +342,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info) · 341 unmodified lines | ||
| 342 | 342 | ret = ops->reply_size(req_info, reply_data); |
| 343 | 343 | if (ret < 0) |
| 344 | 344 | goto err_cleanup; |
| 345 | − reply_len = ret; | |
| 345 | + reply_len = ret + ethnl_reply_header_size(); | |
| 346 | 346 | ret = -ENOMEM; |
| 347 | 347 | rskb = ethnl_reply_init(reply_len, req_info->dev, ops->reply_cmd, |
| 348 | 348 | ops->hdr_attr, info, &reply_payload); |
| @@ -588,7 +588,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd, · 239 unmodified lines | ||
| 588 | 588 | ret = ops->reply_size(req_info, reply_data); |
| 589 | 589 | if (ret < 0) |
| 590 | 590 | goto err_cleanup; |
| 591 | − reply_len = ret; | |
| 591 | + reply_len = ret + ethnl_reply_header_size(); | |
| 592 | 592 | ret = -ENOMEM; |
| 593 | 593 | skb = genlmsg_new(reply_len, GFP_KERNEL); |
| 594 | 594 | if (!skb) |
| @@ -324,7 +324,6 @@ static int strset_reply_size(const struct ethnl_req_info *req_base, · 323 unmodified lines | ||
| 324 | 324 | int len = 0; |
| 325 | 325 | int ret; |
| 326 | 326 | |
| 327 | − len += ethnl_reply_header_size(); | |
| 328 | 327 | for (i = 0; i < ETH_SS_COUNT; i++) { |
| 329 | 328 | const struct strset_info *set_info = &data->sets[i]; |
| 330 | 329 | |
| @@ -1258,7 +1258,8 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, · 1257 unmodified lines | ||
| 1258 | 1258 | return ret_val; |
| 1259 | 1259 | } |
| 1260 | 1260 | |
| 1261 | − secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1261 | + if (secattr->attr.mls.cat) | |
| 1262 | + secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1262 | 1263 | } |
| 1263 | 1264 | |
| 1264 | 1265 | return 0; |
| @@ -1439,7 +1440,8 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def, · 174 unmodified lines | ||
| 1439 | 1440 | return ret_val; |
| 1440 | 1441 | } |
| 1441 | 1442 | |
| 1442 | − secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1443 | + if (secattr->attr.mls.cat) | |
| 1444 | + secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1443 | 1445 | } |
| 1444 | 1446 | |
| 1445 | 1447 | return 0; |
| @@ -918,7 +918,6 @@ int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh, · 917 unmodified lines | ||
| 918 | 918 | else |
| 919 | 919 | filter->dump_exceptions = false; |
| 920 | 920 | |
| 921 | − filter->dump_all_families = (rtm->rtm_family == AF_UNSPEC); | |
| 922 | 921 | filter->flags = rtm->rtm_flags; |
| 923 | 922 | filter->protocol = rtm->rtm_protocol; |
| 924 | 923 | filter->rt_type = rtm->rtm_type; |
| @@ -990,7 +989,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) · 65 unmodified lines | ||
| 990 | 989 | if (filter.table_id) { |
| 991 | 990 | tb = fib_get_table(net, filter.table_id); |
| 992 | 991 | if (!tb) { |
| 993 | − if (filter.dump_all_families) | |
| 992 | + if (rtnl_msg_family(cb->nlh) != PF_INET) | |
| 994 | 993 | return skb->len; |
| 995 | 994 | |
| 996 | 995 | NL_SET_ERR_MSG(cb->extack, "ipv4: FIB table does not exist"); |
| @@ -24,17 +24,19 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <net/addrconf.h> |
| 25 | 25 | |
| 26 | 26 | #if IS_ENABLED(CONFIG_IPV6) |
| 27 | −/* match_wildcard == true: IPV6_ADDR_ANY equals to any IPv6 addresses if IPv6 | |
| 28 | − * only, and any IPv4 addresses if not IPv6 only | |
| 29 | − * match_wildcard == false: addresses must be exactly the same, i.e. | |
| 30 | − * IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY, | |
| 31 | − * and 0.0.0.0 equals to 0.0.0.0 only | |
| 27 | +/* match_sk*_wildcard == true: IPV6_ADDR_ANY equals to any IPv6 addresses | |
| 28 | + * if IPv6 only, and any IPv4 addresses | |
| 29 | + * if not IPv6 only | |
| 30 | + * match_sk*_wildcard == false: addresses must be exactly the same, i.e. | |
| 31 | + * IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY, | |
| 32 | + * and 0.0.0.0 equals to 0.0.0.0 only | |
| 32 | 33 | */ |
| 33 | 34 | static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, |
| 34 | 35 | const struct in6_addr *sk2_rcv_saddr6, |
| 35 | 36 | __be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, |
| 36 | 37 | bool sk1_ipv6only, bool sk2_ipv6only, |
| 37 | − bool match_wildcard) | |
| 38 | + bool match_sk1_wildcard, | |
| 39 | + bool match_sk2_wildcard) | |
| 38 | 40 | { |
| 39 | 41 | int addr_type = ipv6_addr_type(sk1_rcv_saddr6); |
| 40 | 42 | int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED; |
| @@ -44,8 +46,8 @@ static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, · 3 unmodified lines | ||
| 44 | 46 | if (!sk2_ipv6only) { |
| 45 | 47 | if (sk1_rcv_saddr == sk2_rcv_saddr) |
| 46 | 48 | return true; |
| 47 | − if (!sk1_rcv_saddr || !sk2_rcv_saddr) | |
| 48 | − return match_wildcard; | |
| 49 | + return (match_sk1_wildcard && !sk1_rcv_saddr) || | |
| 50 | + (match_sk2_wildcard && !sk2_rcv_saddr); | |
| 49 | 51 | } |
| 50 | 52 | return false; |
| 51 | 53 | } |
| @@ -53,11 +55,11 @@ static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, · 1 unmodified line | ||
| 53 | 55 | if (addr_type == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY) |
| 54 | 56 | return true; |
| 55 | 57 | |
| 56 | − if (addr_type2 == IPV6_ADDR_ANY && match_wildcard && | |
| 58 | + if (addr_type2 == IPV6_ADDR_ANY && match_sk2_wildcard && | |
| 57 | 59 | !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED)) |
| 58 | 60 | return true; |
| 59 | 61 | |
| 60 | − if (addr_type == IPV6_ADDR_ANY && match_wildcard && | |
| 62 | + if (addr_type == IPV6_ADDR_ANY && match_sk1_wildcard && | |
| 61 | 63 | !(sk1_ipv6only && addr_type2 == IPV6_ADDR_MAPPED)) |
| 62 | 64 | return true; |
| 63 | 65 | |
| @@ -69,18 +71,19 @@ static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, · 5 unmodified lines | ||
| 69 | 71 | } |
| 70 | 72 | #endif |
| 71 | 73 | |
| 72 | −/* match_wildcard == true: 0.0.0.0 equals to any IPv4 addresses | |
| 73 | − * match_wildcard == false: addresses must be exactly the same, i.e. | |
| 74 | − * 0.0.0.0 only equals to 0.0.0.0 | |
| 74 | +/* match_sk*_wildcard == true: 0.0.0.0 equals to any IPv4 addresses | |
| 75 | + * match_sk*_wildcard == false: addresses must be exactly the same, i.e. | |
| 76 | + * 0.0.0.0 only equals to 0.0.0.0 | |
| 75 | 77 | */ |
| 76 | 78 | static bool ipv4_rcv_saddr_equal(__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, |
| 77 | − bool sk2_ipv6only, bool match_wildcard) | |
| 79 | + bool sk2_ipv6only, bool match_sk1_wildcard, | |
| 80 | + bool match_sk2_wildcard) | |
| 78 | 81 | { |
| 79 | 82 | if (!sk2_ipv6only) { |
| 80 | 83 | if (sk1_rcv_saddr == sk2_rcv_saddr) |
| 81 | 84 | return true; |
| 82 | − if (!sk1_rcv_saddr || !sk2_rcv_saddr) | |
| 83 | − return match_wildcard; | |
| 85 | + return (match_sk1_wildcard && !sk1_rcv_saddr) || | |
| 86 | + (match_sk2_wildcard && !sk2_rcv_saddr); | |
| 84 | 87 | } |
| 85 | 88 | return false; |
| 86 | 89 | } |
| @@ -96,10 +99,12 @@ bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2, · 9 unmodified lines | ||
| 96 | 99 | sk2->sk_rcv_saddr, |
| 97 | 100 | ipv6_only_sock(sk), |
| 98 | 101 | ipv6_only_sock(sk2), |
| 102 | + match_wildcard, | |
| 99 | 103 | match_wildcard); |
| 100 | 104 | #endif |
| 101 | 105 | return ipv4_rcv_saddr_equal(sk->sk_rcv_saddr, sk2->sk_rcv_saddr, |
| 102 | − ipv6_only_sock(sk2), match_wildcard); | |
| 106 | + ipv6_only_sock(sk2), match_wildcard, | |
| 107 | + match_wildcard); | |
| 103 | 108 | } |
| 104 | 109 | EXPORT_SYMBOL(inet_rcv_saddr_equal); |
| 105 | 110 | |
| @@ -285,10 +290,10 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb, · 179 unmodified lines | ||
| 285 | 290 | tb->fast_rcv_saddr, |
| 286 | 291 | sk->sk_rcv_saddr, |
| 287 | 292 | tb->fast_ipv6_only, |
| 288 | − ipv6_only_sock(sk), true); | |
| 293 | + ipv6_only_sock(sk), true, false); | |
| 289 | 294 | #endif |
| 290 | 295 | return ipv4_rcv_saddr_equal(tb->fast_rcv_saddr, sk->sk_rcv_saddr, |
| 291 | − ipv6_only_sock(sk), true); | |
| 296 | + ipv6_only_sock(sk), true, false); | |
| 292 | 297 | } |
| 293 | 298 | |
| 294 | 299 | /* Obtain a reference to a local port for the given sock, |
| @@ -698,7 +698,7 @@ out: · 697 unmodified lines | ||
| 698 | 698 | |
| 699 | 699 | rtnl_link_failed: |
| 700 | 700 | #if IS_ENABLED(CONFIG_MPLS) |
| 701 | − xfrm4_tunnel_deregister(&mplsip_handler, AF_INET); | |
| 701 | + xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS); | |
| 702 | 702 | xfrm_tunnel_mplsip_failed: |
| 703 | 703 | |
| 704 | 704 | #endif |
| @@ -109,8 +109,10 @@ static void mroute_clean_tables(struct mr_table *mrt, int flags); · 108 unmodified lines | ||
| 109 | 109 | static void ipmr_expire_process(struct timer_list *t); |
| 110 | 110 | |
| 111 | 111 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
| 112 | −#define ipmr_for_each_table(mrt, net) \ | |
| 113 | − list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list) | |
| 112 | +#define ipmr_for_each_table(mrt, net) \ | |
| 113 | + list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list, \ | |
| 114 | + lockdep_rtnl_is_held() || \ | |
| 115 | + list_empty(&net->ipv4.mr_tables)) | |
| 114 | 116 | |
| 115 | 117 | static struct mr_table *ipmr_mr_table_iter(struct net *net, |
| 116 | 118 | struct mr_table *mrt) |
| @@ -2611,7 +2613,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) · 2494 unmodified lines | ||
| 2611 | 2613 | |
| 2612 | 2614 | mrt = ipmr_get_table(sock_net(skb->sk), filter.table_id); |
| 2613 | 2615 | if (!mrt) { |
| 2614 | − if (filter.dump_all_families) | |
| 2616 | + if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR) | |
| 2615 | 2617 | return skb->len; |
| 2616 | 2618 | |
| 2617 | 2619 | NL_SET_ERR_MSG(cb->extack, "ipv4: MR table does not exist"); |
| @@ -276,6 +276,7 @@ out: · 275 unmodified lines | ||
| 276 | 276 | return 0; |
| 277 | 277 | |
| 278 | 278 | nla_put_failure: |
| 279 | + nlmsg_cancel(skb, nlh); | |
| 279 | 280 | return -EMSGSIZE; |
| 280 | 281 | } |
| 281 | 282 | |
| @@ -433,7 +434,7 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[], · 151 unmodified lines | ||
| 433 | 434 | if (!valid_group_nh(nh, len, extack)) |
| 434 | 435 | return -EINVAL; |
| 435 | 436 | } |
| 436 | − for (i = NHA_GROUP + 1; i < __NHA_MAX; ++i) { | |
| 437 | + for (i = NHA_GROUP_TYPE + 1; i < __NHA_MAX; ++i) { | |
| 437 | 438 | if (!tb[i]) |
| 438 | 439 | continue; |
| 439 | 440 | |
| @@ -491,18 +491,16 @@ u32 ip_idents_reserve(u32 hash, int segs) · 490 unmodified lines | ||
| 491 | 491 | atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; |
| 492 | 492 | u32 old = READ_ONCE(*p_tstamp); |
| 493 | 493 | u32 now = (u32)jiffies; |
| 494 | − u32 new, delta = 0; | |
| 494 | + u32 delta = 0; | |
| 495 | 495 | |
| 496 | 496 | if (old != now && cmpxchg(p_tstamp, old, now) == old) |
| 497 | 497 | delta = prandom_u32_max(now - old); |
| 498 | 498 | |
| 499 | − /* Do not use atomic_add_return() as it makes UBSAN unhappy */ | |
| 500 | − do { | |
| 501 | − old = (u32)atomic_read(p_id); | |
| 502 | − new = old + delta + segs; | |
| 503 | − } while (atomic_cmpxchg(p_id, old, new) != old); | |
| 504 | − | |
| 505 | − return new - segs; | |
| 499 | + /* If UBSAN reports an error there, please make sure your compiler | |
| 500 | + * supports -fno-strict-overflow before reporting it that was a bug | |
| 501 | + * in UBSAN, and it has been fixed in GCC-8. | |
| 502 | + */ | |
| 503 | + return atomic_add_return(segs + delta, p_id) - segs; | |
| 506 | 504 | } |
| 507 | 505 | EXPORT_SYMBOL(ip_idents_reserve); |
| 508 | 506 | |
| @@ -915,7 +913,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) · 406 unmodified lines | ||
| 915 | 913 | /* Check for load limit; set rate_last to the latest sent |
| 916 | 914 | * redirect. |
| 917 | 915 | */ |
| 918 | − if (peer->rate_tokens == 0 || | |
| 916 | + if (peer->n_redirects == 0 || | |
| 919 | 917 | time_after(jiffies, |
| 920 | 918 | (peer->rate_last + |
| 921 | 919 | (ip_rt_redirect_load << peer->n_redirects)))) { |
| @@ -476,9 +476,17 @@ static void tcp_tx_timestamp(struct sock *sk, u16 tsflags) · 475 unmodified lines | ||
| 476 | 476 | static inline bool tcp_stream_is_readable(const struct tcp_sock *tp, |
| 477 | 477 | int target, struct sock *sk) |
| 478 | 478 | { |
| 479 | − return (READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq) >= target) || | |
| 480 | − (sk->sk_prot->stream_memory_read ? | |
| 481 | − sk->sk_prot->stream_memory_read(sk) : false); | |
| 479 | + int avail = READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq); | |
| 480 | + | |
| 481 | + if (avail > 0) { | |
| 482 | + if (avail >= target) | |
| 483 | + return true; | |
| 484 | + if (tcp_rmem_pressure(sk)) | |
| 485 | + return true; | |
| 486 | + } | |
| 487 | + if (sk->sk_prot->stream_memory_read) | |
| 488 | + return sk->sk_prot->stream_memory_read(sk); | |
| 489 | + return false; | |
| 482 | 490 | } |
| 483 | 491 | |
| 484 | 492 | /* |
| @@ -1756,10 +1764,11 @@ static int tcp_zerocopy_receive(struct sock *sk, · 1271 unmodified lines | ||
| 1756 | 1764 | |
| 1757 | 1765 | down_read(¤t->mm->mmap_sem); |
| 1758 | 1766 | |
| 1759 | − ret = -EINVAL; | |
| 1760 | 1767 | vma = find_vma(current->mm, address); |
| 1761 | − if (!vma || vma->vm_start > address || vma->vm_ops != &tcp_vm_ops) | |
| 1762 | − goto out; | |
| 1768 | + if (!vma || vma->vm_start > address || vma->vm_ops != &tcp_vm_ops) { | |
| 1769 | + up_read(¤t->mm->mmap_sem); | |
| 1770 | + return -EINVAL; | |
| 1771 | + } | |
| 1763 | 1772 | zc->length = min_t(unsigned long, zc->length, vma->vm_end - address); |
| 1764 | 1773 | |
| 1765 | 1774 | tp = tcp_sk(sk); |
| @@ -2154,13 +2163,15 @@ skip_copy: · 388 unmodified lines | ||
| 2154 | 2163 | tp->urg_data = 0; |
| 2155 | 2164 | tcp_fast_path_check(sk); |
| 2156 | 2165 | } |
| 2157 | − if (used + offset < skb->len) | |
| 2158 | − continue; | |
| 2159 | 2166 | |
| 2160 | 2167 | if (TCP_SKB_CB(skb)->has_rxtstamp) { |
| 2161 | 2168 | tcp_update_recv_tstamps(skb, &tss); |
| 2162 | 2169 | cmsg_flags |= 2; |
| 2163 | 2170 | } |
| 2171 | + | |
| 2172 | + if (used + offset < skb->len) | |
| 2173 | + continue; | |
| 2174 | + | |
| 2164 | 2175 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) |
| 2165 | 2176 | goto found_fin_ok; |
| 2166 | 2177 | if (!(flags & MSG_PEEK)) |
| @@ -125,7 +125,6 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, · 124 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | if (!ret) { |
| 127 | 127 | msg->sg.start = i; |
| 128 | − msg->sg.size -= apply_bytes; | |
| 129 | 128 | sk_psock_queue_msg(psock, tmp); |
| 130 | 129 | sk_psock_data_ready(sk, psock); |
| 131 | 130 | } else { |
| @@ -262,14 +261,17 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, · 130 unmodified lines | ||
| 262 | 261 | struct sk_psock *psock; |
| 263 | 262 | int copied, ret; |
| 264 | 263 | |
| 264 | + if (unlikely(flags & MSG_ERRQUEUE)) | |
| 265 | + return inet_recv_error(sk, msg, len, addr_len); | |
| 266 | + | |
| 265 | 267 | psock = sk_psock_get(sk); |
| 266 | 268 | if (unlikely(!psock)) |
| 267 | 269 | return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); |
| 268 | − if (unlikely(flags & MSG_ERRQUEUE)) | |
| 269 | − return inet_recv_error(sk, msg, len, addr_len); | |
| 270 | 270 | if (!skb_queue_empty(&sk->sk_receive_queue) && |
| 271 | − sk_psock_queue_empty(psock)) | |
| 271 | + sk_psock_queue_empty(psock)) { | |
| 272 | + sk_psock_put(sk, psock); | |
| 272 | 273 | return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); |
| 274 | + } | |
| 273 | 275 | lock_sock(sk); |
| 274 | 276 | msg_bytes_ready: |
| 275 | 277 | copied = __tcp_bpf_recvmsg(sk, psock, msg, len, flags); |
| @@ -4757,7 +4757,8 @@ void tcp_data_ready(struct sock *sk) · 4756 unmodified lines | ||
| 4757 | 4757 | const struct tcp_sock *tp = tcp_sk(sk); |
| 4758 | 4758 | int avail = tp->rcv_nxt - tp->copied_seq; |
| 4759 | 4759 | |
| 4760 | − if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) | |
| 4760 | + if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && | |
| 4761 | + !sock_flag(sk, SOCK_DONE)) | |
| 4761 | 4762 | return; |
| 4762 | 4763 | |
| 4763 | 4764 | sk->sk_data_ready(sk); |
| @@ -1047,7 +1047,8 @@ static int calipso_opt_getattr(const unsigned char *calipso, · 1046 unmodified lines | ||
| 1047 | 1047 | goto getattr_return; |
| 1048 | 1048 | } |
| 1049 | 1049 | |
| 1050 | − secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1050 | + if (secattr->attr.mls.cat) | |
| 1051 | + secattr->flags |= NETLBL_SECATTR_MLS_CAT; | |
| 1051 | 1052 | } |
| 1052 | 1053 | |
| 1053 | 1054 | secattr->type = NETLBL_NLTYPE_CALIPSO; |
| @@ -664,7 +664,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) · 663 unmodified lines | ||
| 664 | 664 | if (arg.filter.table_id) { |
| 665 | 665 | tb = fib6_get_table(net, arg.filter.table_id); |
| 666 | 666 | if (!tb) { |
| 667 | − if (arg.filter.dump_all_families) | |
| 667 | + if (rtnl_msg_family(cb->nlh) != PF_INET6) | |
| 668 | 668 | goto out; |
| 669 | 669 | |
| 670 | 670 | NL_SET_ERR_MSG_MOD(cb->extack, "FIB table does not exist"); |
| @@ -98,7 +98,8 @@ static void ipmr_expire_process(struct timer_list *t); · 97 unmodified lines | ||
| 98 | 98 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES |
| 99 | 99 | #define ip6mr_for_each_table(mrt, net) \ |
| 100 | 100 | list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \ |
| 101 | − lockdep_rtnl_is_held()) | |
| 101 | + lockdep_rtnl_is_held() || \ | |
| 102 | + list_empty(&net->ipv6.mr6_tables)) | |
| 102 | 103 | |
| 103 | 104 | static struct mr_table *ip6mr_mr_table_iter(struct net *net, |
| 104 | 105 | struct mr_table *mrt) |
| @@ -2502,7 +2503,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) · 2397 unmodified lines | ||
| 2502 | 2503 | |
| 2503 | 2504 | mrt = ip6mr_get_table(sock_net(skb->sk), filter.table_id); |
| 2504 | 2505 | if (!mrt) { |
| 2505 | − if (filter.dump_all_families) | |
| 2506 | + if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IP6MR) | |
| 2506 | 2507 | return skb->len; |
| 2507 | 2508 | |
| 2508 | 2509 | NL_SET_ERR_MSG_MOD(cb->extack, "MR table does not exist"); |
| @@ -2722,8 +2722,10 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, · 2721 unmodified lines | ||
| 2722 | 2722 | const struct in6_addr *daddr, *saddr; |
| 2723 | 2723 | struct rt6_info *rt6 = (struct rt6_info *)dst; |
| 2724 | 2724 | |
| 2725 | − if (dst_metric_locked(dst, RTAX_MTU)) | |
| 2726 | − return; | |
| 2725 | + /* Note: do *NOT* check dst_metric_locked(dst, RTAX_MTU) | |
| 2726 | + * IPv6 pmtu discovery isn't optional, so 'mtu lock' cannot disable it. | |
| 2727 | + * [see also comment in rt6_mtu_change_route()] | |
| 2728 | + */ | |
| 2727 | 2729 | |
| 2728 | 2730 | if (iph) { |
| 2729 | 2731 | daddr = &iph->daddr; |
| @@ -47,8 +47,6 @@ void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn) · 46 unmodified lines | ||
| 47 | 47 | void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac) |
| 48 | 48 | { |
| 49 | 49 | u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; |
| 50 | − __be32 mptcp_hashed_key[SHA256_DIGEST_WORDS]; | |
| 51 | − __be32 *hash_out = (__force __be32 *)hmac; | |
| 52 | 50 | struct sha256_state state; |
| 53 | 51 | u8 key1be[8]; |
| 54 | 52 | u8 key2be[8]; |
| @@ -86,11 +84,7 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac) · 31 unmodified lines | ||
| 86 | 84 | |
| 87 | 85 | sha256_init(&state); |
| 88 | 86 | sha256_update(&state, input, SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE); |
| 89 | − sha256_final(&state, (u8 *)mptcp_hashed_key); | |
| 90 | − | |
| 91 | − /* takes only first 160 bits */ | |
| 92 | − for (i = 0; i < 5; i++) | |
| 93 | − hash_out[i] = mptcp_hashed_key[i]; | |
| 87 | + sha256_final(&state, (u8 *)hmac); | |
| 94 | 88 | } |
| 95 | 89 | |
| 96 | 90 | #ifdef CONFIG_MPTCP_HMAC_TEST |
| @@ -101,29 +95,29 @@ struct test_cast { · 4 unmodified lines | ||
| 101 | 95 | }; |
| 102 | 96 | |
| 103 | 97 | /* we can't reuse RFC 4231 test vectors, as we have constraint on the |
| 104 | − * input and key size, and we truncate the output. | |
| 98 | + * input and key size. | |
| 105 | 99 | */ |
| 106 | 100 | static struct test_cast tests[] = { |
| 107 | 101 | { |
| 108 | 102 | .key = "0b0b0b0b0b0b0b0b", |
| 109 | 103 | .msg = "48692054", |
| 110 | − .result = "8385e24fb4235ac37556b6b886db106284a1da67", | |
| 104 | + .result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa", | |
| 111 | 105 | }, |
| 112 | 106 | { |
| 113 | 107 | .key = "aaaaaaaaaaaaaaaa", |
| 114 | 108 | .msg = "dddddddd", |
| 115 | − .result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492", | |
| 109 | + .result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9", | |
| 116 | 110 | }, |
| 117 | 111 | { |
| 118 | 112 | .key = "0102030405060708", |
| 119 | 113 | .msg = "cdcdcdcd", |
| 120 | − .result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6", | |
| 114 | + .result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d", | |
| 121 | 115 | }, |
| 122 | 116 | }; |
| 123 | 117 | |
| 124 | 118 | static int __init test_mptcp_crypto(void) |
| 125 | 119 | { |
| 126 | − char hmac[20], hmac_hex[41]; | |
| 120 | + char hmac[32], hmac_hex[65]; | |
| 127 | 121 | u32 nonce1, nonce2; |
| 128 | 122 | u64 key1, key2; |
| 129 | 123 | u8 msg[8]; |
| @@ -140,11 +134,11 @@ static int __init test_mptcp_crypto(void) · 10 unmodified lines | ||
| 140 | 134 | put_unaligned_be32(nonce2, &msg[4]); |
| 141 | 135 | |
| 142 | 136 | mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac); |
| 143 | − for (j = 0; j < 20; ++j) | |
| 137 | + for (j = 0; j < 32; ++j) | |
| 144 | 138 | sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff); |
| 145 | − hmac_hex[40] = 0; | |
| 139 | + hmac_hex[64] = 0; | |
| 146 | 140 | |
| 147 | − if (memcmp(hmac_hex, tests[i].result, 40)) | |
| 141 | + if (memcmp(hmac_hex, tests[i].result, 64)) | |
| 148 | 142 | pr_err("test %d failed, got %s expected %s", i, |
| 149 | 143 | hmac_hex, tests[i].result); |
| 150 | 144 | else |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #define pr_fmt(fmt) "MPTCP: " fmt |
| 8 | 8 | |
| 9 | 9 | #include <linux/kernel.h> |
| 10 | +#include <crypto/sha.h> | |
| 10 | 11 | #include <net/tcp.h> |
| 11 | 12 | #include <net/mptcp.h> |
| 12 | 13 | #include "protocol.h" |
| @@ -535,7 +536,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, · 522 unmodified lines | ||
| 535 | 536 | static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id, |
| 536 | 537 | struct in_addr *addr) |
| 537 | 538 | { |
| 538 | − u8 hmac[MPTCP_ADDR_HMAC_LEN]; | |
| 539 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 539 | 540 | u8 msg[7]; |
| 540 | 541 | |
| 541 | 542 | msg[0] = addr_id; |
| @@ -545,14 +546,14 @@ static u64 add_addr_generate_hmac(u64 key1, u64 key2, u8 addr_id, · 3 unmodified lines | ||
| 545 | 546 | |
| 546 | 547 | mptcp_crypto_hmac_sha(key1, key2, msg, 7, hmac); |
| 547 | 548 | |
| 548 | − return get_unaligned_be64(hmac); | |
| 549 | + return get_unaligned_be64(&hmac[SHA256_DIGEST_SIZE - sizeof(u64)]); | |
| 549 | 550 | } |
| 550 | 551 | |
| 551 | 552 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| 552 | 553 | static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id, |
| 553 | 554 | struct in6_addr *addr) |
| 554 | 555 | { |
| 555 | − u8 hmac[MPTCP_ADDR_HMAC_LEN]; | |
| 556 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 556 | 557 | u8 msg[19]; |
| 557 | 558 | |
| 558 | 559 | msg[0] = addr_id; |
| @@ -562,7 +563,7 @@ static u64 add_addr6_generate_hmac(u64 key1, u64 key2, u8 addr_id, · 3 unmodified lines | ||
| 562 | 563 | |
| 563 | 564 | mptcp_crypto_hmac_sha(key1, key2, msg, 19, hmac); |
| 564 | 565 | |
| 565 | − return get_unaligned_be64(hmac); | |
| 566 | + return get_unaligned_be64(&hmac[SHA256_DIGEST_SIZE - sizeof(u64)]); | |
| 566 | 567 | } |
| 567 | 568 | #endif |
| 568 | 569 | |
| @@ -1629,6 +1629,8 @@ bool mptcp_finish_join(struct sock *sk) · 1628 unmodified lines | ||
| 1629 | 1629 | |
| 1630 | 1630 | ret = mptcp_pm_allow_new_subflow(msk); |
| 1631 | 1631 | if (ret) { |
| 1632 | + subflow->map_seq = msk->ack_seq; | |
| 1633 | + | |
| 1632 | 1634 | /* active connections are already on conn_list */ |
| 1633 | 1635 | spin_lock_bh(&msk->join_list_lock); |
| 1634 | 1636 | if (!WARN_ON_ONCE(!list_empty(&subflow->node))) |
| @@ -81,7 +81,6 @@ · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | /* MPTCP ADD_ADDR flags */ |
| 83 | 83 | #define MPTCP_ADDR_ECHO BIT(0) |
| 84 | −#define MPTCP_ADDR_HMAC_LEN 20 | |
| 85 | 84 | #define MPTCP_ADDR_IPVERSION_4 4 |
| 86 | 85 | #define MPTCP_ADDR_IPVERSION_6 6 |
| 87 | 86 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/netdevice.h> |
| 12 | 12 | #include <crypto/algapi.h> |
| 13 | +#include <crypto/sha.h> | |
| 13 | 14 | #include <net/sock.h> |
| 14 | 15 | #include <net/inet_common.h> |
| 15 | 16 | #include <net/inet_hashtables.h> |
| @@ -89,7 +90,7 @@ static bool subflow_token_join_request(struct request_sock *req, · 73 unmodified lines | ||
| 89 | 90 | const struct sk_buff *skb) |
| 90 | 91 | { |
| 91 | 92 | struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); |
| 92 | − u8 hmac[MPTCPOPT_HMAC_LEN]; | |
| 93 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 93 | 94 | struct mptcp_sock *msk; |
| 94 | 95 | int local_id; |
| 95 | 96 | |
| @@ -201,7 +202,7 @@ static void subflow_v6_init_req(struct request_sock *req, · 105 unmodified lines | ||
| 201 | 202 | /* validate received truncated hmac and create hmac for third ACK */ |
| 202 | 203 | static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow) |
| 203 | 204 | { |
| 204 | − u8 hmac[MPTCPOPT_HMAC_LEN]; | |
| 205 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 205 | 206 | u64 thmac; |
| 206 | 207 | |
| 207 | 208 | subflow_generate_hmac(subflow->remote_key, subflow->local_key, |
| @@ -267,6 +268,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 59 unmodified lines | ||
| 267 | 268 | subflow->ssn_offset = TCP_SKB_CB(skb)->seq; |
| 268 | 269 | } |
| 269 | 270 | } else if (subflow->mp_join) { |
| 271 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 272 | + | |
| 270 | 273 | pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", |
| 271 | 274 | subflow, subflow->thmac, |
| 272 | 275 | subflow->remote_nonce); |
| @@ -279,7 +282,9 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 6 unmodified lines | ||
| 279 | 282 | subflow_generate_hmac(subflow->local_key, subflow->remote_key, |
| 280 | 283 | subflow->local_nonce, |
| 281 | 284 | subflow->remote_nonce, |
| 282 | − subflow->hmac); | |
| 285 | + hmac); | |
| 286 | + | |
| 287 | + memcpy(subflow->hmac, hmac, MPTCPOPT_HMAC_LEN); | |
| 283 | 288 | |
| 284 | 289 | if (skb) |
| 285 | 290 | subflow->ssn_offset = TCP_SKB_CB(skb)->seq; |
| @@ -347,7 +352,7 @@ static bool subflow_hmac_valid(const struct request_sock *req, · 61 unmodified lines | ||
| 347 | 352 | const struct mptcp_options_received *mp_opt) |
| 348 | 353 | { |
| 349 | 354 | const struct mptcp_subflow_request_sock *subflow_req; |
| 350 | − u8 hmac[MPTCPOPT_HMAC_LEN]; | |
| 355 | + u8 hmac[SHA256_DIGEST_SIZE]; | |
| 351 | 356 | struct mptcp_sock *msk; |
| 352 | 357 | bool ret; |
| 353 | 358 | |
| @@ -361,7 +366,7 @@ static bool subflow_hmac_valid(const struct request_sock *req, · 7 unmodified lines | ||
| 361 | 366 | subflow_req->local_nonce, hmac); |
| 362 | 367 | |
| 363 | 368 | ret = true; |
| 364 | − if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac))) | |
| 369 | + if (crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN)) | |
| 365 | 370 | ret = false; |
| 366 | 371 | |
| 367 | 372 | sock_put((struct sock *)msk); |
| @@ -1012,6 +1017,16 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) · 644 unmodified lines | ||
| 1012 | 1017 | if (err) |
| 1013 | 1018 | return err; |
| 1014 | 1019 | |
| 1020 | + /* the newly created socket really belongs to the owning MPTCP master | |
| 1021 | + * socket, even if for additional subflows the allocation is performed | |
| 1022 | + * by a kernel workqueue. Adjust inode references, so that the | |
| 1023 | + * procfs/diag interaces really show this one belonging to the correct | |
| 1024 | + * user. | |
| 1025 | + */ | |
| 1026 | + SOCK_INODE(sf)->i_ino = SOCK_INODE(sk->sk_socket)->i_ino; | |
| 1027 | + SOCK_INODE(sf)->i_uid = SOCK_INODE(sk->sk_socket)->i_uid; | |
| 1028 | + SOCK_INODE(sf)->i_gid = SOCK_INODE(sk->sk_socket)->i_gid; | |
| 1029 | + | |
| 1015 | 1030 | subflow = mptcp_subflow_ctx(sf->sk); |
| 1016 | 1031 | pr_debug("subflow=%p", subflow); |
| 1017 | 1032 | |
| @@ -1519,9 +1519,9 @@ __nf_conntrack_alloc(struct net *net, · 1518 unmodified lines | ||
| 1519 | 1519 | ct->status = 0; |
| 1520 | 1520 | ct->timeout = 0; |
| 1521 | 1521 | write_pnet(&ct->ct_net, net); |
| 1522 | − memset(&ct->__nfct_init_offset[0], 0, | |
| 1522 | + memset(&ct->__nfct_init_offset, 0, | |
| 1523 | 1523 | offsetof(struct nf_conn, proto) - |
| 1524 | − offsetof(struct nf_conn, __nfct_init_offset[0])); | |
| 1524 | + offsetof(struct nf_conn, __nfct_init_offset)); | |
| 1525 | 1525 | |
| 1526 | 1526 | nf_ct_zone_add(ct, zone); |
| 1527 | 1527 | |
| @@ -2139,8 +2139,19 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data), · 611 unmodified lines | ||
| 2139 | 2139 | nf_conntrack_lock(lockp); |
| 2140 | 2140 | if (*bucket < nf_conntrack_htable_size) { |
| 2141 | 2141 | hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnnode) { |
| 2142 | − if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) | |
| 2142 | + if (NF_CT_DIRECTION(h) != IP_CT_DIR_REPLY) | |
| 2143 | 2143 | continue; |
| 2144 | + /* All nf_conn objects are added to hash table twice, one | |
| 2145 | + * for original direction tuple, once for the reply tuple. | |
| 2146 | + * | |
| 2147 | + * Exception: In the IPS_NAT_CLASH case, only the reply | |
| 2148 | + * tuple is added (the original tuple already existed for | |
| 2149 | + * a different object). | |
| 2150 | + * | |
| 2151 | + * We only need to call the iterator once for each | |
| 2152 | + * conntrack, so we just use the 'reply' direction | |
| 2153 | + * tuple while iterating. | |
| 2154 | + */ | |
| 2144 | 2155 | ct = nf_ct_tuplehash_to_ctrack(h); |
| 2145 | 2156 | if (iter(ct, data)) |
| 2146 | 2157 | goto found; |
| @@ -284,7 +284,7 @@ static void flow_offload_del(struct nf_flowtable *flow_table, · 283 unmodified lines | ||
| 284 | 284 | |
| 285 | 285 | if (nf_flow_has_expired(flow)) |
| 286 | 286 | flow_offload_fixup_ct(flow->ct); |
| 287 | − else if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) | |
| 287 | + else | |
| 288 | 288 | flow_offload_fixup_ct_timeout(flow->ct); |
| 289 | 289 | |
| 290 | 290 | flow_offload_free(flow); |
| @@ -361,8 +361,10 @@ static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data) · 70 unmodified lines | ||
| 361 | 361 | { |
| 362 | 362 | struct nf_flowtable *flow_table = data; |
| 363 | 363 | |
| 364 | − if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct) || | |
| 365 | − test_bit(NF_FLOW_TEARDOWN, &flow->flags)) { | |
| 364 | + if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct)) | |
| 365 | + set_bit(NF_FLOW_TEARDOWN, &flow->flags); | |
| 366 | + | |
| 367 | + if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) { | |
| 366 | 368 | if (test_bit(NF_FLOW_HW, &flow->flags)) { |
| 367 | 369 | if (!test_bit(NF_FLOW_HW_DYING, &flow->flags)) |
| 368 | 370 | nf_flow_offload_del(flow_table, flow); |
| @@ -817,6 +817,7 @@ static void flow_offload_work_handler(struct work_struct *work) · 816 unmodified lines | ||
| 817 | 817 | WARN_ON_ONCE(1); |
| 818 | 818 | } |
| 819 | 819 | |
| 820 | + clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags); | |
| 820 | 821 | kfree(offload); |
| 821 | 822 | } |
| 822 | 823 | |
| @@ -831,9 +832,14 @@ nf_flow_offload_work_alloc(struct nf_flowtable *flowtable, · 8 unmodified lines | ||
| 831 | 832 | { |
| 832 | 833 | struct flow_offload_work *offload; |
| 833 | 834 | |
| 835 | + if (test_and_set_bit(NF_FLOW_HW_PENDING, &flow->flags)) | |
| 836 | + return NULL; | |
| 837 | + | |
| 834 | 838 | offload = kmalloc(sizeof(struct flow_offload_work), GFP_ATOMIC); |
| 835 | − if (!offload) | |
| 839 | + if (!offload) { | |
| 840 | + clear_bit(NF_FLOW_HW_PENDING, &flow->flags); | |
| 836 | 841 | return NULL; |
| 842 | + } | |
| 837 | 843 | |
| 838 | 844 | offload->cmd = cmd; |
| 839 | 845 | offload->flow = flow; |
| @@ -1056,7 +1062,7 @@ static struct flow_indr_block_entry block_ing_entry = { · 216 unmodified lines | ||
| 1056 | 1062 | int nf_flow_table_offload_init(void) |
| 1057 | 1063 | { |
| 1058 | 1064 | nf_flow_offload_wq = alloc_workqueue("nf_flow_table_offload", |
| 1059 | − WQ_UNBOUND | WQ_MEM_RECLAIM, 0); | |
| 1065 | + WQ_UNBOUND, 0); | |
| 1060 | 1066 | if (!nf_flow_offload_wq) |
| 1061 | 1067 | return -ENOMEM; |
| 1062 | 1068 | |
| @@ -79,6 +79,10 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set · 78 unmodified lines | ||
| 79 | 79 | parent = rcu_dereference_raw(parent->rb_left); |
| 80 | 80 | continue; |
| 81 | 81 | } |
| 82 | + | |
| 83 | + if (nft_set_elem_expired(&rbe->ext)) | |
| 84 | + return false; | |
| 85 | + | |
| 82 | 86 | if (nft_rbtree_interval_end(rbe)) { |
| 83 | 87 | if (nft_set_is_anonymous(set)) |
| 84 | 88 | return false; |
| @@ -94,6 +98,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set · 9 unmodified lines | ||
| 94 | 98 | |
| 95 | 99 | if (set->flags & NFT_SET_INTERVAL && interval != NULL && |
| 96 | 100 | nft_set_elem_active(&interval->ext, genmask) && |
| 101 | + !nft_set_elem_expired(&interval->ext) && | |
| 97 | 102 | nft_rbtree_interval_start(interval)) { |
| 98 | 103 | *ext = &interval->ext; |
| 99 | 104 | return true; |
| @@ -154,6 +159,9 @@ static bool __nft_rbtree_get(const struct net *net, const struct nft_set *set, · 54 unmodified lines | ||
| 154 | 159 | continue; |
| 155 | 160 | } |
| 156 | 161 | |
| 162 | + if (nft_set_elem_expired(&rbe->ext)) | |
| 163 | + return false; | |
| 164 | + | |
| 157 | 165 | if (!nft_set_ext_exists(&rbe->ext, NFT_SET_EXT_FLAGS) || |
| 158 | 166 | (*nft_set_ext_flags(&rbe->ext) & NFT_SET_ELEM_INTERVAL_END) == |
| 159 | 167 | (flags & NFT_SET_ELEM_INTERVAL_END)) { |
| @@ -170,6 +178,7 @@ static bool __nft_rbtree_get(const struct net *net, const struct nft_set *set, · 10 unmodified lines | ||
| 170 | 178 | |
| 171 | 179 | if (set->flags & NFT_SET_INTERVAL && interval != NULL && |
| 172 | 180 | nft_set_elem_active(&interval->ext, genmask) && |
| 181 | + !nft_set_elem_expired(&interval->ext) && | |
| 173 | 182 | ((!nft_rbtree_interval_end(interval) && |
| 174 | 183 | !(flags & NFT_SET_ELEM_INTERVAL_END)) || |
| 175 | 184 | (nft_rbtree_interval_end(interval) && |
| @@ -418,6 +427,8 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, · 242 unmodified lines | ||
| 418 | 427 | |
| 419 | 428 | if (iter->count < iter->skip) |
| 420 | 429 | goto cont; |
| 430 | + if (nft_set_elem_expired(&rbe->ext)) | |
| 431 | + goto cont; | |
| 421 | 432 | if (!nft_set_elem_active(&rbe->ext, iter->genmask)) |
| 422 | 433 | goto cont; |
| 423 | 434 | |
| @@ -734,6 +734,12 @@ int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, · 733 unmodified lines | ||
| 734 | 734 | if ((off & (BITS_PER_LONG - 1)) != 0) |
| 735 | 735 | return -EINVAL; |
| 736 | 736 | |
| 737 | + /* a null catmap is equivalent to an empty one */ | |
| 738 | + if (!catmap) { | |
| 739 | + *offset = (u32)-1; | |
| 740 | + return 0; | |
| 741 | + } | |
| 742 | + | |
| 737 | 743 | if (off < catmap->startbit) { |
| 738 | 744 | off = catmap->startbit; |
| 739 | 745 | *offset = off; |
| @@ -854,7 +854,7 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb, · 853 unmodified lines | ||
| 854 | 854 | } |
| 855 | 855 | mutex_unlock(&qrtr_node_lock); |
| 856 | 856 | |
| 857 | − qrtr_local_enqueue(node, skb, type, from, to); | |
| 857 | + qrtr_local_enqueue(NULL, skb, type, from, to); | |
| 858 | 858 | |
| 859 | 859 | return 0; |
| 860 | 860 | } |
| @@ -25,6 +25,7 @@ rxrpc-y := \ · 24 unmodified lines | ||
| 25 | 25 | peer_event.o \ |
| 26 | 26 | peer_object.o \ |
| 27 | 27 | recvmsg.o \ |
| 28 | + rtt.o \ | |
| 28 | 29 | security.o \ |
| 29 | 30 | sendmsg.o \ |
| 30 | 31 | skbuff.o \ |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/atomic.h> |
| 9 | 9 | #include <linux/seqlock.h> |
| 10 | +#include <linux/win_minmax.h> | |
| 10 | 11 | #include <net/net_namespace.h> |
| 11 | 12 | #include <net/netns/generic.h> |
| 12 | 13 | #include <net/sock.h> |
| @@ -311,11 +312,14 @@ struct rxrpc_peer { · 298 unmodified lines | ||
| 311 | 312 | #define RXRPC_RTT_CACHE_SIZE 32 |
| 312 | 313 | spinlock_t rtt_input_lock; /* RTT lock for input routine */ |
| 313 | 314 | ktime_t rtt_last_req; /* Time of last RTT request */ |
| 314 | − u64 rtt; /* Current RTT estimate (in nS) */ | |
| 315 | − u64 rtt_sum; /* Sum of cache contents */ | |
| 316 | − u64 rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* Determined RTT cache */ | |
| 317 | − u8 rtt_cursor; /* next entry at which to insert */ | |
| 318 | − u8 rtt_usage; /* amount of cache actually used */ | |
| 315 | + unsigned int rtt_count; /* Number of samples we've got */ | |
| 316 | + | |
| 317 | + u32 srtt_us; /* smoothed round trip time << 3 in usecs */ | |
| 318 | + u32 mdev_us; /* medium deviation */ | |
| 319 | + u32 mdev_max_us; /* maximal mdev for the last rtt period */ | |
| 320 | + u32 rttvar_us; /* smoothed mdev_max */ | |
| 321 | + u32 rto_j; /* Retransmission timeout in jiffies */ | |
| 322 | + u8 backoff; /* Backoff timeout */ | |
| 319 | 323 | |
| 320 | 324 | u8 cong_cwnd; /* Congestion window size */ |
| 321 | 325 | }; |
| @@ -1041,7 +1045,6 @@ extern unsigned long rxrpc_idle_ack_delay; · 719 unmodified lines | ||
| 1041 | 1045 | extern unsigned int rxrpc_rx_window_size; |
| 1042 | 1046 | extern unsigned int rxrpc_rx_mtu; |
| 1043 | 1047 | extern unsigned int rxrpc_rx_jumbo_max; |
| 1044 | −extern unsigned long rxrpc_resend_timeout; | |
| 1045 | 1048 | |
| 1046 | 1049 | extern const s8 rxrpc_ack_priority[]; |
| 1047 | 1050 | |
| @@ -1069,8 +1072,6 @@ void rxrpc_send_keepalive(struct rxrpc_peer *); · 21 unmodified lines | ||
| 1069 | 1072 | * peer_event.c |
| 1070 | 1073 | */ |
| 1071 | 1074 | void rxrpc_error_report(struct sock *); |
| 1072 | −void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace, | |
| 1073 | − rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t); | |
| 1074 | 1075 | void rxrpc_peer_keepalive_worker(struct work_struct *); |
| 1075 | 1076 | |
| 1076 | 1077 | /* |
| @@ -1102,6 +1103,14 @@ extern const struct seq_operations rxrpc_peer_seq_ops; · 25 unmodified lines | ||
| 1102 | 1103 | void rxrpc_notify_socket(struct rxrpc_call *); |
| 1103 | 1104 | int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int); |
| 1104 | 1105 | |
| 1106 | +/* | |
| 1107 | + * rtt.c | |
| 1108 | + */ | |
| 1109 | +void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace, | |
| 1110 | + rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t); | |
| 1111 | +unsigned long rxrpc_get_rto_backoff(struct rxrpc_peer *, bool); | |
| 1112 | +void rxrpc_peer_init_rtt(struct rxrpc_peer *); | |
| 1113 | + | |
| 1105 | 1114 | /* |
| 1106 | 1115 | * rxkad.c |
| 1107 | 1116 | */ |
| @@ -248,7 +248,7 @@ static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb) · 247 unmodified lines | ||
| 248 | 248 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 249 | 249 | ktime_t now = skb->tstamp; |
| 250 | 250 | |
| 251 | − if (call->peer->rtt_usage < 3 || | |
| 251 | + if (call->peer->rtt_count < 3 || | |
| 252 | 252 | ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) |
| 253 | 253 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, sp->hdr.serial, |
| 254 | 254 | true, true, |
| @@ -111,8 +111,8 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, · 110 unmodified lines | ||
| 111 | 111 | } else { |
| 112 | 112 | unsigned long now = jiffies, ack_at; |
| 113 | 113 | |
| 114 | − if (call->peer->rtt_usage > 0) | |
| 115 | − ack_at = nsecs_to_jiffies(call->peer->rtt); | |
| 114 | + if (call->peer->srtt_us != 0) | |
| 115 | + ack_at = usecs_to_jiffies(call->peer->srtt_us >> 3); | |
| 116 | 116 | else |
| 117 | 117 | ack_at = expiry; |
| 118 | 118 | |
| @@ -157,24 +157,18 @@ static void rxrpc_congestion_timeout(struct rxrpc_call *call) · 38 unmodified lines | ||
| 157 | 157 | static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) |
| 158 | 158 | { |
| 159 | 159 | struct sk_buff *skb; |
| 160 | − unsigned long resend_at; | |
| 160 | + unsigned long resend_at, rto_j; | |
| 161 | 161 | rxrpc_seq_t cursor, seq, top; |
| 162 | − ktime_t now, max_age, oldest, ack_ts, timeout, min_timeo; | |
| 162 | + ktime_t now, max_age, oldest, ack_ts; | |
| 163 | 163 | int ix; |
| 164 | 164 | u8 annotation, anno_type, retrans = 0, unacked = 0; |
| 165 | 165 | |
| 166 | 166 | _enter("{%d,%d}", call->tx_hard_ack, call->tx_top); |
| 167 | 167 | |
| 168 | − if (call->peer->rtt_usage > 1) | |
| 169 | − timeout = ns_to_ktime(call->peer->rtt * 3 / 2); | |
| 170 | − else | |
| 171 | − timeout = ms_to_ktime(rxrpc_resend_timeout); | |
| 172 | − min_timeo = ns_to_ktime((1000000000 / HZ) * 4); | |
| 173 | − if (ktime_before(timeout, min_timeo)) | |
| 174 | − timeout = min_timeo; | |
| 168 | + rto_j = call->peer->rto_j; | |
| 175 | 169 | |
| 176 | 170 | now = ktime_get_real(); |
| 177 | − max_age = ktime_sub(now, timeout); | |
| 171 | + max_age = ktime_sub(now, jiffies_to_usecs(rto_j)); | |
| 178 | 172 | |
| 179 | 173 | spin_lock_bh(&call->lock); |
| 180 | 174 | |
| @@ -219,7 +213,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) · 38 unmodified lines | ||
| 219 | 213 | } |
| 220 | 214 | |
| 221 | 215 | resend_at = nsecs_to_jiffies(ktime_to_ns(ktime_sub(now, oldest))); |
| 222 | − resend_at += jiffies + rxrpc_resend_timeout; | |
| 216 | + resend_at += jiffies + rto_j; | |
| 223 | 217 | WRITE_ONCE(call->resend_at, resend_at); |
| 224 | 218 | |
| 225 | 219 | if (unacked) |
| @@ -234,7 +228,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) · 8 unmodified lines | ||
| 234 | 228 | rxrpc_timer_set_for_resend); |
| 235 | 229 | spin_unlock_bh(&call->lock); |
| 236 | 230 | ack_ts = ktime_sub(now, call->acks_latest_ts); |
| 237 | − if (ktime_to_ns(ack_ts) < call->peer->rtt) | |
| 231 | + if (ktime_to_us(ack_ts) < (call->peer->srtt_us >> 3)) | |
| 238 | 232 | goto out; |
| 239 | 233 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, |
| 240 | 234 | rxrpc_propose_ack_ping_for_lost_ack); |
| @@ -91,11 +91,11 @@ static void rxrpc_congestion_management(struct rxrpc_call *call, · 90 unmodified lines | ||
| 91 | 91 | /* We analyse the number of packets that get ACK'd per RTT |
| 92 | 92 | * period and increase the window if we managed to fill it. |
| 93 | 93 | */ |
| 94 | − if (call->peer->rtt_usage == 0) | |
| 94 | + if (call->peer->rtt_count == 0) | |
| 95 | 95 | goto out; |
| 96 | 96 | if (ktime_before(skb->tstamp, |
| 97 | − ktime_add_ns(call->cong_tstamp, | |
| 98 | − call->peer->rtt))) | |
| 97 | + ktime_add_us(call->cong_tstamp, | |
| 98 | + call->peer->srtt_us >> 3))) | |
| 99 | 99 | goto out_no_clear_ca; |
| 100 | 100 | change = rxrpc_cong_rtt_window_end; |
| 101 | 101 | call->cong_tstamp = skb->tstamp; |
| @@ -802,6 +802,30 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks, · 700 unmodified lines | ||
| 802 | 802 | } |
| 803 | 803 | } |
| 804 | 804 | |
| 805 | +/* | |
| 806 | + * Return true if the ACK is valid - ie. it doesn't appear to have regressed | |
| 807 | + * with respect to the ack state conveyed by preceding ACKs. | |
| 808 | + */ | |
| 809 | +static bool rxrpc_is_ack_valid(struct rxrpc_call *call, | |
| 810 | + rxrpc_seq_t first_pkt, rxrpc_seq_t prev_pkt) | |
| 811 | +{ | |
| 812 | + rxrpc_seq_t base = READ_ONCE(call->ackr_first_seq); | |
| 813 | + | |
| 814 | + if (after(first_pkt, base)) | |
| 815 | + return true; /* The window advanced */ | |
| 816 | + | |
| 817 | + if (before(first_pkt, base)) | |
| 818 | + return false; /* firstPacket regressed */ | |
| 819 | + | |
| 820 | + if (after_eq(prev_pkt, call->ackr_prev_seq)) | |
| 821 | + return true; /* previousPacket hasn't regressed. */ | |
| 822 | + | |
| 823 | + /* Some rx implementations put a serial number in previousPacket. */ | |
| 824 | + if (after_eq(prev_pkt, base + call->tx_winsize)) | |
| 825 | + return false; | |
| 826 | + return true; | |
| 827 | +} | |
| 828 | + | |
| 805 | 829 | /* |
| 806 | 830 | * Process an ACK packet. |
| 807 | 831 | * |
| @@ -865,9 +889,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) · 57 unmodified lines | ||
| 865 | 889 | } |
| 866 | 890 | |
| 867 | 891 | /* Discard any out-of-order or duplicate ACKs (outside lock). */ |
| 868 | − if (before(first_soft_ack, call->ackr_first_seq) || | |
| 869 | − before(prev_pkt, call->ackr_prev_seq)) | |
| 892 | + if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { | |
| 893 | + trace_rxrpc_rx_discard_ack(call->debug_id, sp->hdr.serial, | |
| 894 | + first_soft_ack, call->ackr_first_seq, | |
| 895 | + prev_pkt, call->ackr_prev_seq); | |
| 870 | 896 | return; |
| 897 | + } | |
| 871 | 898 | |
| 872 | 899 | buf.info.rxMTU = 0; |
| 873 | 900 | ioffset = offset + nr_acks + 3; |
| @@ -878,9 +905,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) · 4 unmodified lines | ||
| 878 | 905 | spin_lock(&call->input_lock); |
| 879 | 906 | |
| 880 | 907 | /* Discard any out-of-order or duplicate ACKs (inside lock). */ |
| 881 | − if (before(first_soft_ack, call->ackr_first_seq) || | |
| 882 | − before(prev_pkt, call->ackr_prev_seq)) | |
| 908 | + if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { | |
| 909 | + trace_rxrpc_rx_discard_ack(call->debug_id, sp->hdr.serial, | |
| 910 | + first_soft_ack, call->ackr_first_seq, | |
| 911 | + prev_pkt, call->ackr_prev_seq); | |
| 883 | 912 | goto out; |
| 913 | + } | |
| 884 | 914 | call->acks_latest_ts = skb->tstamp; |
| 885 | 915 | |
| 886 | 916 | call->ackr_first_seq = first_soft_ack; |
| @@ -63,11 +63,6 @@ unsigned int rxrpc_rx_mtu = 5692; · 62 unmodified lines | ||
| 63 | 63 | */ |
| 64 | 64 | unsigned int rxrpc_rx_jumbo_max = 4; |
| 65 | 65 | |
| 66 | −/* | |
| 67 | − * Time till packet resend (in milliseconds). | |
| 68 | − */ | |
| 69 | −unsigned long rxrpc_resend_timeout = 4 * HZ; | |
| 70 | − | |
| 71 | 66 | const s8 rxrpc_ack_priority[] = { |
| 72 | 67 | [0] = 0, |
| 73 | 68 | [RXRPC_ACK_DELAY] = 1, |
| @@ -369,7 +369,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb, · 368 unmodified lines | ||
| 369 | 369 | (test_and_clear_bit(RXRPC_CALL_EV_ACK_LOST, &call->events) || |
| 370 | 370 | retrans || |
| 371 | 371 | call->cong_mode == RXRPC_CALL_SLOW_START || |
| 372 | − (call->peer->rtt_usage < 3 && sp->hdr.seq & 1) || | |
| 372 | + (call->peer->rtt_count < 3 && sp->hdr.seq & 1) || | |
| 373 | 373 | ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), |
| 374 | 374 | ktime_get_real()))) |
| 375 | 375 | whdr.flags |= RXRPC_REQUEST_ACK; |
| @@ -423,13 +423,10 @@ done: · 47 unmodified lines | ||
| 423 | 423 | if (whdr.flags & RXRPC_REQUEST_ACK) { |
| 424 | 424 | call->peer->rtt_last_req = skb->tstamp; |
| 425 | 425 | trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_data, serial); |
| 426 | − if (call->peer->rtt_usage > 1) { | |
| 426 | + if (call->peer->rtt_count > 1) { | |
| 427 | 427 | unsigned long nowj = jiffies, ack_lost_at; |
| 428 | 428 | |
| 429 | − ack_lost_at = nsecs_to_jiffies(2 * call->peer->rtt); | |
| 430 | − if (ack_lost_at < 1) | |
| 431 | − ack_lost_at = 1; | |
| 432 | − | |
| 429 | + ack_lost_at = rxrpc_get_rto_backoff(call->peer, retrans); | |
| 433 | 430 | ack_lost_at += nowj; |
| 434 | 431 | WRITE_ONCE(call->ack_lost_at, ack_lost_at); |
| 435 | 432 | rxrpc_reduce_call_timer(call, ack_lost_at, nowj, |
| @@ -295,52 +295,6 @@ static void rxrpc_distribute_error(struct rxrpc_peer *peer, int error, · 294 unmodified lines | ||
| 295 | 295 | } |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | −/* | |
| 299 | − * Add RTT information to cache. This is called in softirq mode and has | |
| 300 | − * exclusive access to the peer RTT data. | |
| 301 | − */ | |
| 302 | −void rxrpc_peer_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why, | |
| 303 | − rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial, | |
| 304 | − ktime_t send_time, ktime_t resp_time) | |
| 305 | −{ | |
| 306 | − struct rxrpc_peer *peer = call->peer; | |
| 307 | − s64 rtt; | |
| 308 | − u64 sum = peer->rtt_sum, avg; | |
| 309 | − u8 cursor = peer->rtt_cursor, usage = peer->rtt_usage; | |
| 310 | − | |
| 311 | − rtt = ktime_to_ns(ktime_sub(resp_time, send_time)); | |
| 312 | − if (rtt < 0) | |
| 313 | − return; | |
| 314 | − | |
| 315 | − spin_lock(&peer->rtt_input_lock); | |
| 316 | − | |
| 317 | − /* Replace the oldest datum in the RTT buffer */ | |
| 318 | − sum -= peer->rtt_cache[cursor]; | |
| 319 | − sum += rtt; | |
| 320 | − peer->rtt_cache[cursor] = rtt; | |
| 321 | − peer->rtt_cursor = (cursor + 1) & (RXRPC_RTT_CACHE_SIZE - 1); | |
| 322 | − peer->rtt_sum = sum; | |
| 323 | − if (usage < RXRPC_RTT_CACHE_SIZE) { | |
| 324 | − usage++; | |
| 325 | − peer->rtt_usage = usage; | |
| 326 | − } | |
| 327 | − | |
| 328 | − spin_unlock(&peer->rtt_input_lock); | |
| 329 | − | |
| 330 | − /* Now recalculate the average */ | |
| 331 | − if (usage == RXRPC_RTT_CACHE_SIZE) { | |
| 332 | − avg = sum / RXRPC_RTT_CACHE_SIZE; | |
| 333 | − } else { | |
| 334 | − avg = sum; | |
| 335 | − do_div(avg, usage); | |
| 336 | − } | |
| 337 | − | |
| 338 | − /* Don't need to update this under lock */ | |
| 339 | − peer->rtt = avg; | |
| 340 | − trace_rxrpc_rtt_rx(call, why, send_serial, resp_serial, rtt, | |
| 341 | − usage, avg); | |
| 342 | −} | |
| 343 | − | |
| 344 | 298 | /* |
| 345 | 299 | * Perform keep-alive pings. |
| 346 | 300 | */ |
| @@ -225,6 +225,8 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp) · 224 unmodified lines | ||
| 225 | 225 | spin_lock_init(&peer->rtt_input_lock); |
| 226 | 226 | peer->debug_id = atomic_inc_return(&rxrpc_debug_id); |
| 227 | 227 | |
| 228 | + rxrpc_peer_init_rtt(peer); | |
| 229 | + | |
| 228 | 230 | if (RXRPC_TX_SMSS > 2190) |
| 229 | 231 | peer->cong_cwnd = 2; |
| 230 | 232 | else if (RXRPC_TX_SMSS > 1095) |
| @@ -497,14 +499,14 @@ void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call, · 266 unmodified lines | ||
| 497 | 499 | EXPORT_SYMBOL(rxrpc_kernel_get_peer); |
| 498 | 500 | |
| 499 | 501 | /** |
| 500 | − * rxrpc_kernel_get_rtt - Get a call's peer RTT | |
| 502 | + * rxrpc_kernel_get_srtt - Get a call's peer smoothed RTT | |
| 501 | 503 | * @sock: The socket on which the call is in progress. |
| 502 | 504 | * @call: The call to query |
| 503 | 505 | * |
| 504 | − * Get the call's peer RTT. | |
| 506 | + * Get the call's peer smoothed RTT. | |
| 505 | 507 | */ |
| 506 | −u64 rxrpc_kernel_get_rtt(struct socket *sock, struct rxrpc_call *call) | |
| 508 | +u32 rxrpc_kernel_get_srtt(struct socket *sock, struct rxrpc_call *call) | |
| 507 | 509 | { |
| 508 | − return call->peer->rtt; | |
| 510 | + return call->peer->srtt_us >> 3; | |
| 509 | 511 | } |
| 510 | −EXPORT_SYMBOL(rxrpc_kernel_get_rtt); | |
| 512 | +EXPORT_SYMBOL(rxrpc_kernel_get_srtt); | |
| @@ -222,7 +222,7 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) · 221 unmodified lines | ||
| 222 | 222 | seq_puts(seq, |
| 223 | 223 | "Proto Local " |
| 224 | 224 | " Remote " |
| 225 | − " Use CW MTU LastUse RTT Rc\n" | |
| 225 | + " Use CW MTU LastUse RTT RTO\n" | |
| 226 | 226 | ); |
| 227 | 227 | return 0; |
| 228 | 228 | } |
| @@ -236,15 +236,15 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) · 7 unmodified lines | ||
| 236 | 236 | now = ktime_get_seconds(); |
| 237 | 237 | seq_printf(seq, |
| 238 | 238 | "UDP %-47.47s %-47.47s %3u" |
| 239 | − " %3u %5u %6llus %12llu %2u\n", | |
| 239 | + " %3u %5u %6llus %8u %8u\n", | |
| 240 | 240 | lbuff, |
| 241 | 241 | rbuff, |
| 242 | 242 | atomic_read(&peer->usage), |
| 243 | 243 | peer->cong_cwnd, |
| 244 | 244 | peer->mtu, |
| 245 | 245 | now - peer->last_tx_at, |
| 246 | − peer->rtt, | |
| 247 | − peer->rtt_cursor); | |
| 246 | + peer->srtt_us >> 3, | |
| 247 | + jiffies_to_usecs(peer->rto_j)); | |
| 248 | 248 | |
| 249 | 249 | return 0; |
| 250 | 250 | } |
| @@ -0,0 +1,195 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* RTT/RTO calculation. | |
| 3 | + * | |
| 4 | + * Adapted from TCP for AF_RXRPC by David Howells (dhowells@redhat.com) | |
| 5 | + * | |
| 6 | + * https://tools.ietf.org/html/rfc6298 | |
| 7 | + * https://tools.ietf.org/html/rfc1122#section-4.2.3.1 | |
| 8 | + * http://ccr.sigcomm.org/archive/1995/jan95/ccr-9501-partridge87.pdf | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/net.h> | |
| 12 | +#include "ar-internal.h" | |
| 13 | + | |
| 14 | +#define RXRPC_RTO_MAX ((unsigned)(120 * HZ)) | |
| 15 | +#define RXRPC_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */ | |
| 16 | +#define rxrpc_jiffies32 ((u32)jiffies) /* As rxrpc_jiffies32 */ | |
| 17 | +#define rxrpc_min_rtt_wlen 300 /* As sysctl_tcp_min_rtt_wlen */ | |
| 18 | + | |
| 19 | +static u32 rxrpc_rto_min_us(struct rxrpc_peer *peer) | |
| 20 | +{ | |
| 21 | + return 200; | |
| 22 | +} | |
| 23 | + | |
| 24 | +static u32 __rxrpc_set_rto(const struct rxrpc_peer *peer) | |
| 25 | +{ | |
| 26 | + return _usecs_to_jiffies((peer->srtt_us >> 3) + peer->rttvar_us); | |
| 27 | +} | |
| 28 | + | |
| 29 | +static u32 rxrpc_bound_rto(u32 rto) | |
| 30 | +{ | |
| 31 | + return min(rto, RXRPC_RTO_MAX); | |
| 32 | +} | |
| 33 | + | |
| 34 | +/* | |
| 35 | + * Called to compute a smoothed rtt estimate. The data fed to this | |
| 36 | + * routine either comes from timestamps, or from segments that were | |
| 37 | + * known _not_ to have been retransmitted [see Karn/Partridge | |
| 38 | + * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88 | |
| 39 | + * piece by Van Jacobson. | |
| 40 | + * NOTE: the next three routines used to be one big routine. | |
| 41 | + * To save cycles in the RFC 1323 implementation it was better to break | |
| 42 | + * it up into three procedures. -- erics | |
| 43 | + */ | |
| 44 | +static void rxrpc_rtt_estimator(struct rxrpc_peer *peer, long sample_rtt_us) | |
| 45 | +{ | |
| 46 | + long m = sample_rtt_us; /* RTT */ | |
| 47 | + u32 srtt = peer->srtt_us; | |
| 48 | + | |
| 49 | + /* The following amusing code comes from Jacobson's | |
| 50 | + * article in SIGCOMM '88. Note that rtt and mdev | |
| 51 | + * are scaled versions of rtt and mean deviation. | |
| 52 | + * This is designed to be as fast as possible | |
| 53 | + * m stands for "measurement". | |
| 54 | + * | |
| 55 | + * On a 1990 paper the rto value is changed to: | |
| 56 | + * RTO = rtt + 4 * mdev | |
| 57 | + * | |
| 58 | + * Funny. This algorithm seems to be very broken. | |
| 59 | + * These formulae increase RTO, when it should be decreased, increase | |
| 60 | + * too slowly, when it should be increased quickly, decrease too quickly | |
| 61 | + * etc. I guess in BSD RTO takes ONE value, so that it is absolutely | |
| 62 | + * does not matter how to _calculate_ it. Seems, it was trap | |
| 63 | + * that VJ failed to avoid. 8) | |
| 64 | + */ | |
| 65 | + if (srtt != 0) { | |
| 66 | + m -= (srtt >> 3); /* m is now error in rtt est */ | |
| 67 | + srtt += m; /* rtt = 7/8 rtt + 1/8 new */ | |
| 68 | + if (m < 0) { | |
| 69 | + m = -m; /* m is now abs(error) */ | |
| 70 | + m -= (peer->mdev_us >> 2); /* similar update on mdev */ | |
| 71 | + /* This is similar to one of Eifel findings. | |
| 72 | + * Eifel blocks mdev updates when rtt decreases. | |
| 73 | + * This solution is a bit different: we use finer gain | |
| 74 | + * for mdev in this case (alpha*beta). | |
| 75 | + * Like Eifel it also prevents growth of rto, | |
| 76 | + * but also it limits too fast rto decreases, | |
| 77 | + * happening in pure Eifel. | |
| 78 | + */ | |
| 79 | + if (m > 0) | |
| 80 | + m >>= 3; | |
| 81 | + } else { | |
| 82 | + m -= (peer->mdev_us >> 2); /* similar update on mdev */ | |
| 83 | + } | |
| 84 | + | |
| 85 | + peer->mdev_us += m; /* mdev = 3/4 mdev + 1/4 new */ | |
| 86 | + if (peer->mdev_us > peer->mdev_max_us) { | |
| 87 | + peer->mdev_max_us = peer->mdev_us; | |
| 88 | + if (peer->mdev_max_us > peer->rttvar_us) | |
| 89 | + peer->rttvar_us = peer->mdev_max_us; | |
| 90 | + } | |
| 91 | + } else { | |
| 92 | + /* no previous measure. */ | |
| 93 | + srtt = m << 3; /* take the measured time to be rtt */ | |
| 94 | + peer->mdev_us = m << 1; /* make sure rto = 3*rtt */ | |
| 95 | + peer->rttvar_us = max(peer->mdev_us, rxrpc_rto_min_us(peer)); | |
| 96 | + peer->mdev_max_us = peer->rttvar_us; | |
| 97 | + } | |
| 98 | + | |
| 99 | + peer->srtt_us = max(1U, srtt); | |
| 100 | +} | |
| 101 | + | |
| 102 | +/* | |
| 103 | + * Calculate rto without backoff. This is the second half of Van Jacobson's | |
| 104 | + * routine referred to above. | |
| 105 | + */ | |
| 106 | +static void rxrpc_set_rto(struct rxrpc_peer *peer) | |
| 107 | +{ | |
| 108 | + u32 rto; | |
| 109 | + | |
| 110 | + /* 1. If rtt variance happened to be less 50msec, it is hallucination. | |
| 111 | + * It cannot be less due to utterly erratic ACK generation made | |
| 112 | + * at least by solaris and freebsd. "Erratic ACKs" has _nothing_ | |
| 113 | + * to do with delayed acks, because at cwnd>2 true delack timeout | |
| 114 | + * is invisible. Actually, Linux-2.4 also generates erratic | |
| 115 | + * ACKs in some circumstances. | |
| 116 | + */ | |
| 117 | + rto = __rxrpc_set_rto(peer); | |
| 118 | + | |
| 119 | + /* 2. Fixups made earlier cannot be right. | |
| 120 | + * If we do not estimate RTO correctly without them, | |
| 121 | + * all the algo is pure shit and should be replaced | |
| 122 | + * with correct one. It is exactly, which we pretend to do. | |
| 123 | + */ | |
| 124 | + | |
| 125 | + /* NOTE: clamping at RXRPC_RTO_MIN is not required, current algo | |
| 126 | + * guarantees that rto is higher. | |
| 127 | + */ | |
| 128 | + peer->rto_j = rxrpc_bound_rto(rto); | |
| 129 | +} | |
| 130 | + | |
| 131 | +static void rxrpc_ack_update_rtt(struct rxrpc_peer *peer, long rtt_us) | |
| 132 | +{ | |
| 133 | + if (rtt_us < 0) | |
| 134 | + return; | |
| 135 | + | |
| 136 | + //rxrpc_update_rtt_min(peer, rtt_us); | |
| 137 | + rxrpc_rtt_estimator(peer, rtt_us); | |
| 138 | + rxrpc_set_rto(peer); | |
| 139 | + | |
| 140 | + /* RFC6298: only reset backoff on valid RTT measurement. */ | |
| 141 | + peer->backoff = 0; | |
| 142 | +} | |
| 143 | + | |
| 144 | +/* | |
| 145 | + * Add RTT information to cache. This is called in softirq mode and has | |
| 146 | + * exclusive access to the peer RTT data. | |
| 147 | + */ | |
| 148 | +void rxrpc_peer_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why, | |
| 149 | + rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial, | |
| 150 | + ktime_t send_time, ktime_t resp_time) | |
| 151 | +{ | |
| 152 | + struct rxrpc_peer *peer = call->peer; | |
| 153 | + s64 rtt_us; | |
| 154 | + | |
| 155 | + rtt_us = ktime_to_us(ktime_sub(resp_time, send_time)); | |
| 156 | + if (rtt_us < 0) | |
| 157 | + return; | |
| 158 | + | |
| 159 | + spin_lock(&peer->rtt_input_lock); | |
| 160 | + rxrpc_ack_update_rtt(peer, rtt_us); | |
| 161 | + if (peer->rtt_count < 3) | |
| 162 | + peer->rtt_count++; | |
| 163 | + spin_unlock(&peer->rtt_input_lock); | |
| 164 | + | |
| 165 | + trace_rxrpc_rtt_rx(call, why, send_serial, resp_serial, | |
| 166 | + peer->srtt_us >> 3, peer->rto_j); | |
| 167 | +} | |
| 168 | + | |
| 169 | +/* | |
| 170 | + * Get the retransmission timeout to set in jiffies, backing it off each time | |
| 171 | + * we retransmit. | |
| 172 | + */ | |
| 173 | +unsigned long rxrpc_get_rto_backoff(struct rxrpc_peer *peer, bool retrans) | |
| 174 | +{ | |
| 175 | + u64 timo_j; | |
| 176 | + u8 backoff = READ_ONCE(peer->backoff); | |
| 177 | + | |
| 178 | + timo_j = peer->rto_j; | |
| 179 | + timo_j <<= backoff; | |
| 180 | + if (retrans && timo_j * 2 <= RXRPC_RTO_MAX) | |
| 181 | + WRITE_ONCE(peer->backoff, backoff + 1); | |
| 182 | + | |
| 183 | + if (timo_j < 1) | |
| 184 | + timo_j = 1; | |
| 185 | + | |
| 186 | + return timo_j; | |
| 187 | +} | |
| 188 | + | |
| 189 | +void rxrpc_peer_init_rtt(struct rxrpc_peer *peer) | |
| 190 | +{ | |
| 191 | + peer->rto_j = RXRPC_TIMEOUT_INIT; | |
| 192 | + peer->mdev_us = jiffies_to_usecs(RXRPC_TIMEOUT_INIT); | |
| 193 | + peer->backoff = 0; | |
| 194 | + //minmax_reset(&peer->rtt_min, rxrpc_jiffies32, ~0U); | |
| 195 | +} | |
| @@ -1148,7 +1148,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn, · 1147 unmodified lines | ||
| 1148 | 1148 | ret = rxkad_decrypt_ticket(conn, skb, ticket, ticket_len, &session_key, |
| 1149 | 1149 | &expiry, _abort_code); |
| 1150 | 1150 | if (ret < 0) |
| 1151 | − goto temporary_error_free_resp; | |
| 1151 | + goto temporary_error_free_ticket; | |
| 1152 | 1152 | |
| 1153 | 1153 | /* use the session key from inside the ticket to decrypt the |
| 1154 | 1154 | * response */ |
| @@ -1230,7 +1230,6 @@ protocol_error: · 75 unmodified lines | ||
| 1230 | 1230 | |
| 1231 | 1231 | temporary_error_free_ticket: |
| 1232 | 1232 | kfree(ticket); |
| 1233 | −temporary_error_free_resp: | |
| 1234 | 1233 | kfree(response); |
| 1235 | 1234 | temporary_error: |
| 1236 | 1235 | /* Ignore the response packet if we got a temporary error such as |
| @@ -66,15 +66,14 @@ static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, · 65 unmodified lines | ||
| 66 | 66 | struct rxrpc_call *call) |
| 67 | 67 | { |
| 68 | 68 | rxrpc_seq_t tx_start, tx_win; |
| 69 | − signed long rtt2, timeout; | |
| 70 | − u64 rtt; | |
| 69 | + signed long rtt, timeout; | |
| 71 | 70 | |
| 72 | − rtt = READ_ONCE(call->peer->rtt); | |
| 73 | − rtt2 = nsecs_to_jiffies64(rtt) * 2; | |
| 74 | − if (rtt2 < 2) | |
| 75 | − rtt2 = 2; | |
| 71 | + rtt = READ_ONCE(call->peer->srtt_us) >> 3; | |
| 72 | + rtt = usecs_to_jiffies(rtt) * 2; | |
| 73 | + if (rtt < 2) | |
| 74 | + rtt = 2; | |
| 76 | 75 | |
| 77 | − timeout = rtt2; | |
| 76 | + timeout = rtt; | |
| 78 | 77 | tx_start = READ_ONCE(call->tx_hard_ack); |
| 79 | 78 | |
| 80 | 79 | for (;;) { |
| @@ -92,7 +91,7 @@ static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, · 11 unmodified lines | ||
| 92 | 91 | return -EINTR; |
| 93 | 92 | |
| 94 | 93 | if (tx_win != tx_start) { |
| 95 | − timeout = rtt2; | |
| 94 | + timeout = rtt; | |
| 96 | 95 | tx_start = tx_win; |
| 97 | 96 | } |
| 98 | 97 | |
| @@ -271,16 +270,9 @@ static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, · 172 unmodified lines | ||
| 271 | 270 | _debug("need instant resend %d", ret); |
| 272 | 271 | rxrpc_instant_resend(call, ix); |
| 273 | 272 | } else { |
| 274 | − unsigned long now = jiffies, resend_at; | |
| 273 | + unsigned long now = jiffies; | |
| 274 | + unsigned long resend_at = now + call->peer->rto_j; | |
| 275 | 275 | |
| 276 | − if (call->peer->rtt_usage > 1) | |
| 277 | − resend_at = nsecs_to_jiffies(call->peer->rtt * 3 / 2); | |
| 278 | − else | |
| 279 | − resend_at = rxrpc_resend_timeout; | |
| 280 | − if (resend_at < 1) | |
| 281 | − resend_at = 1; | |
| 282 | − | |
| 283 | − resend_at += now; | |
| 284 | 276 | WRITE_ONCE(call->resend_at, resend_at); |
| 285 | 277 | rxrpc_reduce_call_timer(call, resend_at, now, |
| 286 | 278 | rxrpc_timer_set_for_send); |
| @@ -71,15 +71,6 @@ static struct ctl_table rxrpc_sysctl_table[] = { · 70 unmodified lines | ||
| 71 | 71 | .extra1 = (void *)&one_jiffy, |
| 72 | 72 | .extra2 = (void *)&max_jiffies, |
| 73 | 73 | }, |
| 74 | − { | |
| 75 | − .procname = "resend_timeout", | |
| 76 | − .data = &rxrpc_resend_timeout, | |
| 77 | − .maxlen = sizeof(unsigned long), | |
| 78 | − .mode = 0644, | |
| 79 | − .proc_handler = proc_doulongvec_ms_jiffies_minmax, | |
| 80 | − .extra1 = (void *)&one_jiffy, | |
| 81 | − .extra2 = (void *)&max_jiffies, | |
| 82 | − }, | |
| 83 | 74 | |
| 84 | 75 | /* Non-time values */ |
| 85 | 76 | { |
| @@ -1523,9 +1523,17 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 1522 unmodified lines | ||
| 1523 | 1523 | timeout = asoc->timeouts[cmd->obj.to]; |
| 1524 | 1524 | BUG_ON(!timeout); |
| 1525 | 1525 | |
| 1526 | − timer->expires = jiffies + timeout; | |
| 1527 | − sctp_association_hold(asoc); | |
| 1528 | − add_timer(timer); | |
| 1526 | + /* | |
| 1527 | + * SCTP has a hard time with timer starts. Because we process | |
| 1528 | + * timer starts as side effects, it can be hard to tell if we | |
| 1529 | + * have already started a timer or not, which leads to BUG | |
| 1530 | + * halts when we call add_timer. So here, instead of just starting | |
| 1531 | + * a timer, if the timer is already started, and just mod | |
| 1532 | + * the timer with the shorter of the two expiration times | |
| 1533 | + */ | |
| 1534 | + if (!timer_pending(timer)) | |
| 1535 | + sctp_association_hold(asoc); | |
| 1536 | + timer_reduce(timer, jiffies + timeout); | |
| 1529 | 1537 | break; |
| 1530 | 1538 | |
| 1531 | 1539 | case SCTP_CMD_TIMER_RESTART: |
| @@ -1856,12 +1856,13 @@ static enum sctp_disposition sctp_sf_do_dupcook_a( · 1855 unmodified lines | ||
| 1856 | 1856 | /* Update the content of current association. */ |
| 1857 | 1857 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); |
| 1858 | 1858 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); |
| 1859 | − if (sctp_state(asoc, SHUTDOWN_PENDING) && | |
| 1859 | + if ((sctp_state(asoc, SHUTDOWN_PENDING) || | |
| 1860 | + sctp_state(asoc, SHUTDOWN_SENT)) && | |
| 1860 | 1861 | (sctp_sstate(asoc->base.sk, CLOSING) || |
| 1861 | 1862 | sock_flag(asoc->base.sk, SOCK_DEAD))) { |
| 1862 | − /* if were currently in SHUTDOWN_PENDING, but the socket | |
| 1863 | − * has been closed by user, don't transition to ESTABLISHED. | |
| 1864 | − * Instead trigger SHUTDOWN bundled with COOKIE_ACK. | |
| 1863 | + /* If the socket has been closed by user, don't | |
| 1864 | + * transition to ESTABLISHED. Instead trigger SHUTDOWN | |
| 1865 | + * bundled with COOKIE_ACK. | |
| 1865 | 1866 | */ |
| 1866 | 1867 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
| 1867 | 1868 | return sctp_sf_do_9_2_start_shutdown(net, ep, asoc, |
| @@ -2032,7 +2032,6 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred, · 2031 unmodified lines | ||
| 2032 | 2032 | struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; |
| 2033 | 2033 | struct kvec *head = rqstp->rq_rcv_buf.head; |
| 2034 | 2034 | struct rpc_auth *auth = cred->cr_auth; |
| 2035 | − unsigned int savedlen = rcv_buf->len; | |
| 2036 | 2035 | u32 offset, opaque_len, maj_stat; |
| 2037 | 2036 | __be32 *p; |
| 2038 | 2037 | |
| @@ -2043,9 +2042,9 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred, · 4 unmodified lines | ||
| 2043 | 2042 | offset = (u8 *)(p) - (u8 *)head->iov_base; |
| 2044 | 2043 | if (offset + opaque_len > rcv_buf->len) |
| 2045 | 2044 | goto unwrap_failed; |
| 2046 | − rcv_buf->len = offset + opaque_len; | |
| 2047 | 2045 | |
| 2048 | − maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf); | |
| 2046 | + maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, | |
| 2047 | + offset + opaque_len, rcv_buf); | |
| 2049 | 2048 | if (maj_stat == GSS_S_CONTEXT_EXPIRED) |
| 2050 | 2049 | clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); |
| 2051 | 2050 | if (maj_stat != GSS_S_COMPLETE) |
| @@ -2059,10 +2058,9 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred, · 7 unmodified lines | ||
| 2059 | 2058 | */ |
| 2060 | 2059 | xdr_init_decode(xdr, rcv_buf, p, rqstp); |
| 2061 | 2060 | |
| 2062 | − auth->au_rslack = auth->au_verfsize + 2 + | |
| 2063 | − XDR_QUADLEN(savedlen - rcv_buf->len); | |
| 2064 | − auth->au_ralign = auth->au_verfsize + 2 + | |
| 2065 | − XDR_QUADLEN(savedlen - rcv_buf->len); | |
| 2061 | + auth->au_rslack = auth->au_verfsize + 2 + ctx->gc_gss_ctx->slack; | |
| 2062 | + auth->au_ralign = auth->au_verfsize + 2 + ctx->gc_gss_ctx->align; | |
| 2063 | + | |
| 2066 | 2064 | return 0; |
| 2067 | 2065 | unwrap_failed: |
| 2068 | 2066 | trace_rpcgss_unwrap_failed(task); |
| @@ -851,8 +851,8 @@ out_err: · 850 unmodified lines | ||
| 851 | 851 | } |
| 852 | 852 | |
| 853 | 853 | u32 |
| 854 | −gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, | |
| 855 | − u32 *headskip, u32 *tailskip) | |
| 854 | +gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, | |
| 855 | + struct xdr_buf *buf, u32 *headskip, u32 *tailskip) | |
| 856 | 856 | { |
| 857 | 857 | struct xdr_buf subbuf; |
| 858 | 858 | u32 ret = 0; |
| @@ -881,7 +881,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, · 22 unmodified lines | ||
| 881 | 881 | |
| 882 | 882 | /* create a segment skipping the header and leaving out the checksum */ |
| 883 | 883 | xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN, |
| 884 | − (buf->len - offset - GSS_KRB5_TOK_HDR_LEN - | |
| 884 | + (len - offset - GSS_KRB5_TOK_HDR_LEN - | |
| 885 | 885 | kctx->gk5e->cksumlength)); |
| 886 | 886 | |
| 887 | 887 | nblocks = (subbuf.len + blocksize - 1) / blocksize; |
| @@ -926,7 +926,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, · 38 unmodified lines | ||
| 926 | 926 | goto out_err; |
| 927 | 927 | |
| 928 | 928 | /* Get the packet's hmac value */ |
| 929 | − ret = read_bytes_from_xdr_buf(buf, buf->len - kctx->gk5e->cksumlength, | |
| 929 | + ret = read_bytes_from_xdr_buf(buf, len - kctx->gk5e->cksumlength, | |
| 930 | 930 | pkt_hmac, kctx->gk5e->cksumlength); |
| 931 | 931 | if (ret) |
| 932 | 932 | goto out_err; |
| @@ -261,7 +261,9 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, · 260 unmodified lines | ||
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | static u32 |
| 264 | −gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) | |
| 264 | +gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len, | |
| 265 | + struct xdr_buf *buf, unsigned int *slack, | |
| 266 | + unsigned int *align) | |
| 265 | 267 | { |
| 266 | 268 | int signalg; |
| 267 | 269 | int sealalg; |
| @@ -279,12 +281,13 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 11 unmodified lines | ||
| 279 | 281 | u32 conflen = kctx->gk5e->conflen; |
| 280 | 282 | int crypt_offset; |
| 281 | 283 | u8 *cksumkey; |
| 284 | + unsigned int saved_len = buf->len; | |
| 282 | 285 | |
| 283 | 286 | dprintk("RPC: gss_unwrap_kerberos\n"); |
| 284 | 287 | |
| 285 | 288 | ptr = (u8 *)buf->head[0].iov_base + offset; |
| 286 | 289 | if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr, |
| 287 | − buf->len - offset)) | |
| 290 | + len - offset)) | |
| 288 | 291 | return GSS_S_DEFECTIVE_TOKEN; |
| 289 | 292 | |
| 290 | 293 | if ((ptr[0] != ((KG_TOK_WRAP_MSG >> 8) & 0xff)) || |
| @@ -324,6 +327,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 33 unmodified lines | ||
| 324 | 327 | (!kctx->initiate && direction != 0)) |
| 325 | 328 | return GSS_S_BAD_SIG; |
| 326 | 329 | |
| 330 | + buf->len = len; | |
| 327 | 331 | if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC) { |
| 328 | 332 | struct crypto_sync_skcipher *cipher; |
| 329 | 333 | int err; |
| @@ -376,11 +380,15 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 46 unmodified lines | ||
| 376 | 380 | data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start; |
| 377 | 381 | memmove(orig_start, data_start, data_len); |
| 378 | 382 | buf->head[0].iov_len -= (data_start - orig_start); |
| 379 | − buf->len -= (data_start - orig_start); | |
| 383 | + buf->len = len - (data_start - orig_start); | |
| 380 | 384 | |
| 381 | 385 | if (gss_krb5_remove_padding(buf, blocksize)) |
| 382 | 386 | return GSS_S_DEFECTIVE_TOKEN; |
| 383 | 387 | |
| 388 | + /* slack must include room for krb5 padding */ | |
| 389 | + *slack = XDR_QUADLEN(saved_len - buf->len); | |
| 390 | + /* The GSS blob always precedes the RPC message payload */ | |
| 391 | + *align = *slack; | |
| 384 | 392 | return GSS_S_COMPLETE; |
| 385 | 393 | } |
| 386 | 394 | |
| @@ -486,7 +494,9 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, · 99 unmodified lines | ||
| 486 | 494 | } |
| 487 | 495 | |
| 488 | 496 | static u32 |
| 489 | −gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) | |
| 497 | +gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, | |
| 498 | + struct xdr_buf *buf, unsigned int *slack, | |
| 499 | + unsigned int *align) | |
| 490 | 500 | { |
| 491 | 501 | time64_t now; |
| 492 | 502 | u8 *ptr; |
| @@ -532,7 +542,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 39 unmodified lines | ||
| 532 | 542 | if (rrc != 0) |
| 533 | 543 | rotate_left(offset + 16, buf, rrc); |
| 534 | 544 | |
| 535 | − err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf, | |
| 545 | + err = (*kctx->gk5e->decrypt_v2)(kctx, offset, len, buf, | |
| 536 | 546 | &headskip, &tailskip); |
| 537 | 547 | if (err) |
| 538 | 548 | return GSS_S_FAILURE; |
| @@ -542,7 +552,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 3 unmodified lines | ||
| 542 | 552 | * it against the original |
| 543 | 553 | */ |
| 544 | 554 | err = read_bytes_from_xdr_buf(buf, |
| 545 | − buf->len - GSS_KRB5_TOK_HDR_LEN - tailskip, | |
| 555 | + len - GSS_KRB5_TOK_HDR_LEN - tailskip, | |
| 546 | 556 | decrypted_hdr, GSS_KRB5_TOK_HDR_LEN); |
| 547 | 557 | if (err) { |
| 548 | 558 | dprintk("%s: error %u getting decrypted_hdr\n", __func__, err); |
| @@ -568,18 +578,19 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) · 19 unmodified lines | ||
| 568 | 578 | * Note that buf->head[0].iov_len may indicate the available |
| 569 | 579 | * head buffer space rather than that actually occupied. |
| 570 | 580 | */ |
| 571 | − movelen = min_t(unsigned int, buf->head[0].iov_len, buf->len); | |
| 581 | + movelen = min_t(unsigned int, buf->head[0].iov_len, len); | |
| 572 | 582 | movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip; |
| 573 | − if (offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen > | |
| 574 | − buf->head[0].iov_len) | |
| 575 | − return GSS_S_FAILURE; | |
| 583 | + BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen > | |
| 584 | + buf->head[0].iov_len); | |
| 576 | 585 | memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen); |
| 577 | 586 | buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; |
| 578 | − buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip; | |
| 587 | + buf->len = len - GSS_KRB5_TOK_HDR_LEN + headskip; | |
| 579 | 588 | |
| 580 | 589 | /* Trim off the trailing "extra count" and checksum blob */ |
| 581 | − buf->len -= ec + GSS_KRB5_TOK_HDR_LEN + tailskip; | |
| 590 | + xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip); | |
| 582 | 591 | |
| 592 | + *align = XDR_QUADLEN(GSS_KRB5_TOK_HDR_LEN + headskip); | |
| 593 | + *slack = *align + XDR_QUADLEN(ec + GSS_KRB5_TOK_HDR_LEN + tailskip); | |
| 583 | 594 | return GSS_S_COMPLETE; |
| 584 | 595 | } |
| 585 | 596 | |
| @@ -603,7 +614,8 @@ gss_wrap_kerberos(struct gss_ctx *gctx, int offset, · 17 unmodified lines | ||
| 603 | 614 | } |
| 604 | 615 | |
| 605 | 616 | u32 |
| 606 | −gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf) | |
| 617 | +gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, | |
| 618 | + int len, struct xdr_buf *buf) | |
| 607 | 619 | { |
| 608 | 620 | struct krb5_ctx *kctx = gctx->internal_ctx_id; |
| 609 | 621 | |
| @@ -613,9 +625,11 @@ gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf) · 3 unmodified lines | ||
| 613 | 625 | case ENCTYPE_DES_CBC_RAW: |
| 614 | 626 | case ENCTYPE_DES3_CBC_RAW: |
| 615 | 627 | case ENCTYPE_ARCFOUR_HMAC: |
| 616 | − return gss_unwrap_kerberos_v1(kctx, offset, buf); | |
| 628 | + return gss_unwrap_kerberos_v1(kctx, offset, len, buf, | |
| 629 | + &gctx->slack, &gctx->align); | |
| 617 | 630 | case ENCTYPE_AES128_CTS_HMAC_SHA1_96: |
| 618 | 631 | case ENCTYPE_AES256_CTS_HMAC_SHA1_96: |
| 619 | − return gss_unwrap_kerberos_v2(kctx, offset, buf); | |
| 632 | + return gss_unwrap_kerberos_v2(kctx, offset, len, buf, | |
| 633 | + &gctx->slack, &gctx->align); | |
| 620 | 634 | } |
| 621 | 635 | } |
| @@ -411,10 +411,11 @@ gss_wrap(struct gss_ctx *ctx_id, · 410 unmodified lines | ||
| 411 | 411 | u32 |
| 412 | 412 | gss_unwrap(struct gss_ctx *ctx_id, |
| 413 | 413 | int offset, |
| 414 | + int len, | |
| 414 | 415 | struct xdr_buf *buf) |
| 415 | 416 | { |
| 416 | 417 | return ctx_id->mech_type->gm_ops |
| 417 | − ->gss_unwrap(ctx_id, offset, buf); | |
| 418 | + ->gss_unwrap(ctx_id, offset, len, buf); | |
| 418 | 419 | } |
| 419 | 420 | |
| 420 | 421 | |
| @@ -906,7 +906,7 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g · 905 unmodified lines | ||
| 906 | 906 | if (svc_getnl(&buf->head[0]) != seq) |
| 907 | 907 | goto out; |
| 908 | 908 | /* trim off the mic and padding at the end before returning */ |
| 909 | − buf->len -= 4 + round_up_to_quad(mic.len); | |
| 909 | + xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4); | |
| 910 | 910 | stat = 0; |
| 911 | 911 | out: |
| 912 | 912 | kfree(mic.data); |
| @@ -934,7 +934,7 @@ static int · 21 unmodified lines | ||
| 934 | 934 | unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx) |
| 935 | 935 | { |
| 936 | 936 | u32 priv_len, maj_stat; |
| 937 | − int pad, saved_len, remaining_len, offset; | |
| 937 | + int pad, remaining_len, offset; | |
| 938 | 938 | |
| 939 | 939 | clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); |
| 940 | 940 | |
| @@ -954,12 +954,8 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs · 13 unmodified lines | ||
| 954 | 954 | buf->len -= pad; |
| 955 | 955 | fix_priv_head(buf, pad); |
| 956 | 956 | |
| 957 | − /* Maybe it would be better to give gss_unwrap a length parameter: */ | |
| 958 | − saved_len = buf->len; | |
| 959 | − buf->len = priv_len; | |
| 960 | − maj_stat = gss_unwrap(ctx, 0, buf); | |
| 957 | + maj_stat = gss_unwrap(ctx, 0, priv_len, buf); | |
| 961 | 958 | pad = priv_len - buf->len; |
| 962 | − buf->len = saved_len; | |
| 963 | 959 | buf->len -= pad; |
| 964 | 960 | /* The upper layers assume the buffer is aligned on 4-byte boundaries. |
| 965 | 961 | * In the krb5p case, at least, the data ends up offset, so we need to |
| @@ -889,7 +889,9 @@ static void rpc_free_client_work(struct work_struct *work) · 888 unmodified lines | ||
| 889 | 889 | * here. |
| 890 | 890 | */ |
| 891 | 891 | rpc_clnt_debugfs_unregister(clnt); |
| 892 | + rpc_free_clid(clnt); | |
| 892 | 893 | rpc_clnt_remove_pipedir(clnt); |
| 894 | + xprt_put(rcu_dereference_raw(clnt->cl_xprt)); | |
| 893 | 895 | |
| 894 | 896 | kfree(clnt); |
| 895 | 897 | rpciod_down(); |
| @@ -907,10 +909,8 @@ rpc_free_client(struct rpc_clnt *clnt) · 11 unmodified lines | ||
| 907 | 909 | rpc_unregister_client(clnt); |
| 908 | 910 | rpc_free_iostats(clnt->cl_metrics); |
| 909 | 911 | clnt->cl_metrics = NULL; |
| 910 | − xprt_put(rcu_dereference_raw(clnt->cl_xprt)); | |
| 911 | 912 | xprt_iter_destroy(&clnt->cl_xpi); |
| 912 | 913 | put_cred(clnt->cl_cred); |
| 913 | − rpc_free_clid(clnt); | |
| 914 | 914 | |
| 915 | 915 | INIT_WORK(&clnt->cl_work, rpc_free_client_work); |
| 916 | 916 | schedule_work(&clnt->cl_work); |
| @@ -2433,6 +2433,11 @@ rpc_check_timeout(struct rpc_task *task) · 1516 unmodified lines | ||
| 2433 | 2433 | { |
| 2434 | 2434 | struct rpc_clnt *clnt = task->tk_client; |
| 2435 | 2435 | |
| 2436 | + if (RPC_SIGNALLED(task)) { | |
| 2437 | + rpc_call_rpcerror(task, -ERESTARTSYS); | |
| 2438 | + return; | |
| 2439 | + } | |
| 2440 | + | |
| 2436 | 2441 | if (xprt_adjust_timeout(task->tk_rqstp) == 0) |
| 2437 | 2442 | return; |
| 2438 | 2443 | |
| @@ -1150,6 +1150,47 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, · 1149 unmodified lines | ||
| 1150 | 1150 | } |
| 1151 | 1151 | EXPORT_SYMBOL_GPL(xdr_buf_subsegment); |
| 1152 | 1152 | |
| 1153 | +/** | |
| 1154 | + * xdr_buf_trim - lop at most "len" bytes off the end of "buf" | |
| 1155 | + * @buf: buf to be trimmed | |
| 1156 | + * @len: number of bytes to reduce "buf" by | |
| 1157 | + * | |
| 1158 | + * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note | |
| 1159 | + * that it's possible that we'll trim less than that amount if the xdr_buf is | |
| 1160 | + * too small, or if (for instance) it's all in the head and the parser has | |
| 1161 | + * already read too far into it. | |
| 1162 | + */ | |
| 1163 | +void xdr_buf_trim(struct xdr_buf *buf, unsigned int len) | |
| 1164 | +{ | |
| 1165 | + size_t cur; | |
| 1166 | + unsigned int trim = len; | |
| 1167 | + | |
| 1168 | + if (buf->tail[0].iov_len) { | |
| 1169 | + cur = min_t(size_t, buf->tail[0].iov_len, trim); | |
| 1170 | + buf->tail[0].iov_len -= cur; | |
| 1171 | + trim -= cur; | |
| 1172 | + if (!trim) | |
| 1173 | + goto fix_len; | |
| 1174 | + } | |
| 1175 | + | |
| 1176 | + if (buf->page_len) { | |
| 1177 | + cur = min_t(unsigned int, buf->page_len, trim); | |
| 1178 | + buf->page_len -= cur; | |
| 1179 | + trim -= cur; | |
| 1180 | + if (!trim) | |
| 1181 | + goto fix_len; | |
| 1182 | + } | |
| 1183 | + | |
| 1184 | + if (buf->head[0].iov_len) { | |
| 1185 | + cur = min_t(size_t, buf->head[0].iov_len, trim); | |
| 1186 | + buf->head[0].iov_len -= cur; | |
| 1187 | + trim -= cur; | |
| 1188 | + } | |
| 1189 | +fix_len: | |
| 1190 | + buf->len -= (len - trim); | |
| 1191 | +} | |
| 1192 | +EXPORT_SYMBOL_GPL(xdr_buf_trim); | |
| 1193 | + | |
| 1153 | 1194 | static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) |
| 1154 | 1195 | { |
| 1155 | 1196 | unsigned int this_len; |
| @@ -1739,22 +1739,21 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct sk_buff *skb, · 1738 unmodified lines | ||
| 1739 | 1739 | return 0; |
| 1740 | 1740 | } |
| 1741 | 1741 | |
| 1742 | −static void tipc_sk_send_ack(struct tipc_sock *tsk) | |
| 1742 | +static struct sk_buff *tipc_sk_build_ack(struct tipc_sock *tsk) | |
| 1743 | 1743 | { |
| 1744 | 1744 | struct sock *sk = &tsk->sk; |
| 1745 | − struct net *net = sock_net(sk); | |
| 1746 | 1745 | struct sk_buff *skb = NULL; |
| 1747 | 1746 | struct tipc_msg *msg; |
| 1748 | 1747 | u32 peer_port = tsk_peer_port(tsk); |
| 1749 | 1748 | u32 dnode = tsk_peer_node(tsk); |
| 1750 | 1749 | |
| 1751 | 1750 | if (!tipc_sk_connected(sk)) |
| 1752 | − return; | |
| 1751 | + return NULL; | |
| 1753 | 1752 | skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, |
| 1754 | 1753 | dnode, tsk_own_node(tsk), peer_port, |
| 1755 | 1754 | tsk->portid, TIPC_OK); |
| 1756 | 1755 | if (!skb) |
| 1757 | − return; | |
| 1756 | + return NULL; | |
| 1758 | 1757 | msg = buf_msg(skb); |
| 1759 | 1758 | msg_set_conn_ack(msg, tsk->rcv_unacked); |
| 1760 | 1759 | tsk->rcv_unacked = 0; |
| @@ -1764,7 +1763,19 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk) · 3 unmodified lines | ||
| 1764 | 1763 | tsk->rcv_win = tsk_adv_blocks(tsk->sk.sk_rcvbuf); |
| 1765 | 1764 | msg_set_adv_win(msg, tsk->rcv_win); |
| 1766 | 1765 | } |
| 1767 | − tipc_node_xmit_skb(net, skb, dnode, msg_link_selector(msg)); | |
| 1766 | + return skb; | |
| 1767 | +} | |
| 1768 | + | |
| 1769 | +static void tipc_sk_send_ack(struct tipc_sock *tsk) | |
| 1770 | +{ | |
| 1771 | + struct sk_buff *skb; | |
| 1772 | + | |
| 1773 | + skb = tipc_sk_build_ack(tsk); | |
| 1774 | + if (!skb) | |
| 1775 | + return; | |
| 1776 | + | |
| 1777 | + tipc_node_xmit_skb(sock_net(&tsk->sk), skb, tsk_peer_node(tsk), | |
| 1778 | + msg_link_selector(buf_msg(skb))); | |
| 1768 | 1779 | } |
| 1769 | 1780 | |
| 1770 | 1781 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) |
| @@ -1938,7 +1949,6 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m, · 167 unmodified lines | ||
| 1938 | 1949 | bool peek = flags & MSG_PEEK; |
| 1939 | 1950 | int offset, required, copy, copied = 0; |
| 1940 | 1951 | int hlen, dlen, err, rc; |
| 1941 | − bool ack = false; | |
| 1942 | 1952 | long timeout; |
| 1943 | 1953 | |
| 1944 | 1954 | /* Catch invalid receive attempts */ |
| @@ -1983,7 +1993,6 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m, · 38 unmodified lines | ||
| 1983 | 1993 | |
| 1984 | 1994 | /* Copy data if msg ok, otherwise return error/partial data */ |
| 1985 | 1995 | if (likely(!err)) { |
| 1986 | − ack = msg_ack_required(hdr); | |
| 1987 | 1996 | offset = skb_cb->bytes_read; |
| 1988 | 1997 | copy = min_t(int, dlen - offset, buflen - copied); |
| 1989 | 1998 | rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy); |
| @@ -2011,7 +2020,7 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m, · 21 unmodified lines | ||
| 2011 | 2020 | |
| 2012 | 2021 | /* Send connection flow control advertisement when applicable */ |
| 2013 | 2022 | tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen); |
| 2014 | − if (ack || tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE) | |
| 2023 | + if (tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE) | |
| 2015 | 2024 | tipc_sk_send_ack(tsk); |
| 2016 | 2025 | |
| 2017 | 2026 | /* Exit if all requested data or FIN/error received */ |
| @@ -2105,9 +2114,11 @@ static void tipc_sk_proto_rcv(struct sock *sk, · 87 unmodified lines | ||
| 2105 | 2114 | * tipc_sk_filter_connect - check incoming message for a connection-based socket |
| 2106 | 2115 | * @tsk: TIPC socket |
| 2107 | 2116 | * @skb: pointer to message buffer. |
| 2117 | + * @xmitq: for Nagle ACK if any | |
| 2108 | 2118 | * Returns true if message should be added to receive queue, false otherwise |
| 2109 | 2119 | */ |
| 2110 | −static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |
| 2120 | +static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb, | |
| 2121 | + struct sk_buff_head *xmitq) | |
| 2111 | 2122 | { |
| 2112 | 2123 | struct sock *sk = &tsk->sk; |
| 2113 | 2124 | struct net *net = sock_net(sk); |
| @@ -2171,8 +2182,17 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) · 57 unmodified lines | ||
| 2171 | 2182 | if (!skb_queue_empty(&sk->sk_write_queue)) |
| 2172 | 2183 | tipc_sk_push_backlog(tsk); |
| 2173 | 2184 | /* Accept only connection-based messages sent by peer */ |
| 2174 | − if (likely(con_msg && !err && pport == oport && pnode == onode)) | |
| 2185 | + if (likely(con_msg && !err && pport == oport && | |
| 2186 | + pnode == onode)) { | |
| 2187 | + if (msg_ack_required(hdr)) { | |
| 2188 | + struct sk_buff *skb; | |
| 2189 | + | |
| 2190 | + skb = tipc_sk_build_ack(tsk); | |
| 2191 | + if (skb) | |
| 2192 | + __skb_queue_tail(xmitq, skb); | |
| 2193 | + } | |
| 2175 | 2194 | return true; |
| 2195 | + } | |
| 2176 | 2196 | if (!tsk_peer_msg(tsk, hdr)) |
| 2177 | 2197 | return false; |
| 2178 | 2198 | if (!err) |
| @@ -2267,7 +2287,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb, · 88 unmodified lines | ||
| 2267 | 2287 | while ((skb = __skb_dequeue(&inputq))) { |
| 2268 | 2288 | hdr = buf_msg(skb); |
| 2269 | 2289 | limit = rcvbuf_limit(sk, skb); |
| 2270 | − if ((sk_conn && !tipc_sk_filter_connect(tsk, skb)) || | |
| 2290 | + if ((sk_conn && !tipc_sk_filter_connect(tsk, skb, xmitq)) || | |
| 2271 | 2291 | (!sk_conn && msg_connected(hdr)) || |
| 2272 | 2292 | (!grp && msg_in_group(hdr))) |
| 2273 | 2293 | err = TIPC_ERR_NO_PORT; |
| @@ -96,6 +96,16 @@ void tipc_sub_get(struct tipc_subscription *subscription); · 95 unmodified lines | ||
| 96 | 96 | (swap_ ? swab32(val__) : val__); \ |
| 97 | 97 | }) |
| 98 | 98 | |
| 99 | +/* tipc_sub_write - write val_ to field_ of struct sub_ in user endian format | |
| 100 | + */ | |
| 101 | +#define tipc_sub_write(sub_, field_, val_) \ | |
| 102 | + ({ \ | |
| 103 | + struct tipc_subscr *sub__ = sub_; \ | |
| 104 | + u32 val__ = val_; \ | |
| 105 | + int swap_ = !((sub__)->filter & TIPC_FILTER_MASK); \ | |
| 106 | + (sub__)->field_ = swap_ ? swab32(val__) : val__; \ | |
| 107 | + }) | |
| 108 | + | |
| 99 | 109 | /* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format |
| 100 | 110 | */ |
| 101 | 111 | #define tipc_evt_write(evt_, field_, val_) \ |
| @@ -237,8 +237,8 @@ static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s) · 236 unmodified lines | ||
| 237 | 237 | if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) { |
| 238 | 238 | tipc_sub_unsubscribe(sub); |
| 239 | 239 | atomic_dec(&tn->subscription_count); |
| 240 | − } else if (s) { | |
| 241 | − break; | |
| 240 | + if (s) | |
| 241 | + break; | |
| 242 | 242 | } |
| 243 | 243 | } |
| 244 | 244 | spin_unlock_bh(&con->sub_lock); |
| @@ -362,9 +362,10 @@ static int tipc_conn_rcv_sub(struct tipc_topsrv *srv, · 117 unmodified lines | ||
| 362 | 362 | { |
| 363 | 363 | struct tipc_net *tn = tipc_net(srv->net); |
| 364 | 364 | struct tipc_subscription *sub; |
| 365 | + u32 s_filter = tipc_sub_read(s, filter); | |
| 365 | 366 | |
| 366 | − if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) { | |
| 367 | − s->filter &= __constant_ntohl(~TIPC_SUB_CANCEL); | |
| 367 | + if (s_filter & TIPC_SUB_CANCEL) { | |
| 368 | + tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL); | |
| 368 | 369 | tipc_conn_delete_sub(con, s); |
| 369 | 370 | return 0; |
| 370 | 371 | } |
| @@ -400,7 +401,9 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con) · 29 unmodified lines | ||
| 400 | 401 | return -EWOULDBLOCK; |
| 401 | 402 | if (ret == sizeof(s)) { |
| 402 | 403 | read_lock_bh(&sk->sk_callback_lock); |
| 403 | − ret = tipc_conn_rcv_sub(srv, con, &s); | |
| 404 | + /* RACE: the connection can be closed in the meantime */ | |
| 405 | + if (likely(connected(con))) | |
| 406 | + ret = tipc_conn_rcv_sub(srv, con, &s); | |
| 404 | 407 | read_unlock_bh(&sk->sk_callback_lock); |
| 405 | 408 | if (!ret) |
| 406 | 409 | return 0; |
| @@ -161,9 +161,11 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, · 160 unmodified lines | ||
| 161 | 161 | struct udp_bearer *ub, struct udp_media_addr *src, |
| 162 | 162 | struct udp_media_addr *dst, struct dst_cache *cache) |
| 163 | 163 | { |
| 164 | − struct dst_entry *ndst = dst_cache_get(cache); | |
| 164 | + struct dst_entry *ndst; | |
| 165 | 165 | int ttl, err = 0; |
| 166 | 166 | |
| 167 | + local_bh_disable(); | |
| 168 | + ndst = dst_cache_get(cache); | |
| 167 | 169 | if (dst->proto == htons(ETH_P_IP)) { |
| 168 | 170 | struct rtable *rt = (struct rtable *)ndst; |
| 169 | 171 | |
| @@ -210,9 +212,11 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, · 40 unmodified lines | ||
| 210 | 212 | src->port, dst->port, false); |
| 211 | 213 | #endif |
| 212 | 214 | } |
| 215 | + local_bh_enable(); | |
| 213 | 216 | return err; |
| 214 | 217 | |
| 215 | 218 | tx_error: |
| 219 | + local_bh_enable(); | |
| 216 | 220 | kfree_skb(skb); |
| 217 | 221 | return err; |
| 218 | 222 | } |
| @@ -780,7 +780,7 @@ static int tls_push_record(struct sock *sk, int flags, · 779 unmodified lines | ||
| 780 | 780 | |
| 781 | 781 | static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, |
| 782 | 782 | bool full_record, u8 record_type, |
| 783 | − size_t *copied, int flags) | |
| 783 | + ssize_t *copied, int flags) | |
| 784 | 784 | { |
| 785 | 785 | struct tls_context *tls_ctx = tls_get_ctx(sk); |
| 786 | 786 | struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); |
| @@ -796,9 +796,10 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, · 9 unmodified lines | ||
| 796 | 796 | psock = sk_psock_get(sk); |
| 797 | 797 | if (!psock || !policy) { |
| 798 | 798 | err = tls_push_record(sk, flags, record_type); |
| 799 | − if (err && err != -EINPROGRESS) { | |
| 799 | + if (err && sk->sk_err == EBADMSG) { | |
| 800 | 800 | *copied -= sk_msg_free(sk, msg); |
| 801 | 801 | tls_free_open_rec(sk); |
| 802 | + err = -sk->sk_err; | |
| 802 | 803 | } |
| 803 | 804 | if (psock) |
| 804 | 805 | sk_psock_put(sk, psock); |
| @@ -824,9 +825,10 @@ more_data: · 19 unmodified lines | ||
| 824 | 825 | switch (psock->eval) { |
| 825 | 826 | case __SK_PASS: |
| 826 | 827 | err = tls_push_record(sk, flags, record_type); |
| 827 | − if (err && err != -EINPROGRESS) { | |
| 828 | + if (err && sk->sk_err == EBADMSG) { | |
| 828 | 829 | *copied -= sk_msg_free(sk, msg); |
| 829 | 830 | tls_free_open_rec(sk); |
| 831 | + err = -sk->sk_err; | |
| 830 | 832 | goto out_err; |
| 831 | 833 | } |
| 832 | 834 | break; |
| @@ -916,7 +918,8 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) · 83 unmodified lines | ||
| 916 | 918 | unsigned char record_type = TLS_RECORD_TYPE_DATA; |
| 917 | 919 | bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); |
| 918 | 920 | bool eor = !(msg->msg_flags & MSG_MORE); |
| 919 | − size_t try_to_copy, copied = 0; | |
| 921 | + size_t try_to_copy; | |
| 922 | + ssize_t copied = 0; | |
| 920 | 923 | struct sk_msg *msg_pl, *msg_en; |
| 921 | 924 | struct tls_rec *rec; |
| 922 | 925 | int required_size; |
| @@ -1118,7 +1121,7 @@ send_end: · 195 unmodified lines | ||
| 1118 | 1121 | |
| 1119 | 1122 | release_sock(sk); |
| 1120 | 1123 | mutex_unlock(&tls_ctx->tx_lock); |
| 1121 | − return copied ? copied : ret; | |
| 1124 | + return copied > 0 ? copied : ret; | |
| 1122 | 1125 | } |
| 1123 | 1126 | |
| 1124 | 1127 | static int tls_sw_do_sendpage(struct sock *sk, struct page *page, |
| @@ -1132,7 +1135,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct page *page, · 7 unmodified lines | ||
| 1132 | 1135 | struct sk_msg *msg_pl; |
| 1133 | 1136 | struct tls_rec *rec; |
| 1134 | 1137 | int num_async = 0; |
| 1135 | − size_t copied = 0; | |
| 1138 | + ssize_t copied = 0; | |
| 1136 | 1139 | bool full_record; |
| 1137 | 1140 | int record_room; |
| 1138 | 1141 | int ret = 0; |
| @@ -1234,7 +1237,7 @@ wait_for_memory: · 95 unmodified lines | ||
| 1234 | 1237 | } |
| 1235 | 1238 | sendpage_end: |
| 1236 | 1239 | ret = sk_stream_error(sk, flags, ret); |
| 1237 | − return copied ? copied : ret; | |
| 1240 | + return copied > 0 ? copied : ret; | |
| 1238 | 1241 | } |
| 1239 | 1242 | |
| 1240 | 1243 | int tls_sw_sendpage_locked(struct sock *sk, struct page *page, |
| @@ -15,8 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | #define MAX_INDEX 64 |
| 16 | 16 | #define MAX_STARS 38 |
| 17 | 17 | |
| 18 | −char bpf_log_buf[BPF_LOG_BUF_SIZE]; | |
| 19 | − | |
| 20 | 18 | static void stars(char *str, long val, long max, int width) |
| 21 | 19 | { |
| 22 | 20 | int i; |
| @@ -454,7 +454,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, · 453 unmodified lines | ||
| 454 | 454 | */ |
| 455 | 455 | error = aa_may_manage_policy(label, ns, mask); |
| 456 | 456 | if (error) |
| 457 | − return error; | |
| 457 | + goto end_section; | |
| 458 | 458 | |
| 459 | 459 | data = aa_simple_write_to_buffer(buf, size, size, pos); |
| 460 | 460 | error = PTR_ERR(data); |
| @@ -462,6 +462,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, · 1 unmodified line | ||
| 462 | 462 | error = aa_replace_profiles(ns, label, mask, data); |
| 463 | 463 | aa_put_loaddata(data); |
| 464 | 464 | } |
| 465 | +end_section: | |
| 465 | 466 | end_current_label_crit_section(label); |
| 466 | 467 | |
| 467 | 468 | return error; |
| @@ -197,8 +197,9 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 196 unmodified lines | ||
| 197 | 197 | rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr, |
| 198 | 198 | GFP_KERNEL, true, false); |
| 199 | 199 | if (IS_ERR(rule->label)) { |
| 200 | + int err = PTR_ERR(rule->label); | |
| 200 | 201 | aa_audit_rule_free(rule); |
| 201 | − return PTR_ERR(rule->label); | |
| 202 | + return err; | |
| 202 | 203 | } |
| 203 | 204 | |
| 204 | 205 | *vrule = rule; |
| @@ -1328,6 +1328,7 @@ int aa_change_profile(const char *fqname, int flags) · 1327 unmodified lines | ||
| 1328 | 1328 | ctx->nnp = aa_get_label(label); |
| 1329 | 1329 | |
| 1330 | 1330 | if (!fqname || !*fqname) { |
| 1331 | + aa_put_label(label); | |
| 1331 | 1332 | AA_DEBUG("no profile name"); |
| 1332 | 1333 | return -EINVAL; |
| 1333 | 1334 | } |
| @@ -1346,8 +1347,6 @@ int aa_change_profile(const char *fqname, int flags) · 12 unmodified lines | ||
| 1346 | 1347 | op = OP_CHANGE_PROFILE; |
| 1347 | 1348 | } |
| 1348 | 1349 | |
| 1349 | − label = aa_get_current_label(); | |
| 1350 | − | |
| 1351 | 1350 | if (*fqname == '&') { |
| 1352 | 1351 | stack = true; |
| 1353 | 1352 | /* don't have label_parse() do stacking */ |
| @@ -73,7 +73,7 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo) · 72 unmodified lines | ||
| 73 | 73 | { |
| 74 | 74 | long rc; |
| 75 | 75 | const char *algo; |
| 76 | − struct crypto_shash **tfm; | |
| 76 | + struct crypto_shash **tfm, *tmp_tfm; | |
| 77 | 77 | struct shash_desc *desc; |
| 78 | 78 | |
| 79 | 79 | if (type == EVM_XATTR_HMAC) { |
| @@ -91,31 +91,31 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo) · 11 unmodified lines | ||
| 91 | 91 | algo = hash_algo_name[hash_algo]; |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | − if (*tfm == NULL) { | |
| 95 | − mutex_lock(&mutex); | |
| 96 | − if (*tfm) | |
| 97 | − goto out; | |
| 98 | − *tfm = crypto_alloc_shash(algo, 0, CRYPTO_NOLOAD); | |
| 99 | − if (IS_ERR(*tfm)) { | |
| 100 | − rc = PTR_ERR(*tfm); | |
| 101 | − pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); | |
| 102 | − *tfm = NULL; | |
| 94 | + if (*tfm) | |
| 95 | + goto alloc; | |
| 96 | + mutex_lock(&mutex); | |
| 97 | + if (*tfm) | |
| 98 | + goto unlock; | |
| 99 | + | |
| 100 | + tmp_tfm = crypto_alloc_shash(algo, 0, CRYPTO_NOLOAD); | |
| 101 | + if (IS_ERR(tmp_tfm)) { | |
| 102 | + pr_err("Can not allocate %s (reason: %ld)\n", algo, | |
| 103 | + PTR_ERR(tmp_tfm)); | |
| 104 | + mutex_unlock(&mutex); | |
| 105 | + return ERR_CAST(tmp_tfm); | |
| 106 | + } | |
| 107 | + if (type == EVM_XATTR_HMAC) { | |
| 108 | + rc = crypto_shash_setkey(tmp_tfm, evmkey, evmkey_len); | |
| 109 | + if (rc) { | |
| 110 | + crypto_free_shash(tmp_tfm); | |
| 103 | 111 | mutex_unlock(&mutex); |
| 104 | 112 | return ERR_PTR(rc); |
| 105 | 113 | } |
| 106 | − if (type == EVM_XATTR_HMAC) { | |
| 107 | − rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len); | |
| 108 | − if (rc) { | |
| 109 | − crypto_free_shash(*tfm); | |
| 110 | − *tfm = NULL; | |
| 111 | − mutex_unlock(&mutex); | |
| 112 | − return ERR_PTR(rc); | |
| 113 | − } | |
| 114 | − } | |
| 115 | −out: | |
| 116 | − mutex_unlock(&mutex); | |
| 117 | 114 | } |
| 118 | − | |
| 115 | + *tfm = tmp_tfm; | |
| 116 | +unlock: | |
| 117 | + mutex_unlock(&mutex); | |
| 118 | +alloc: | |
| 119 | 119 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), |
| 120 | 120 | GFP_KERNEL); |
| 121 | 121 | if (!desc) |
| @@ -207,7 +207,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, · 85 unmodified lines | ||
| 207 | 207 | data->hdr.length = crypto_shash_digestsize(desc->tfm); |
| 208 | 208 | |
| 209 | 209 | error = -ENODATA; |
| 210 | − list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { | |
| 210 | + list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) { | |
| 211 | 211 | bool is_ima = false; |
| 212 | 212 | |
| 213 | 213 | if (strcmp(xattr->name, XATTR_NAME_IMA) == 0) |
| @@ -97,7 +97,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry) · 96 unmodified lines | ||
| 97 | 97 | if (!(inode->i_opflags & IOP_XATTR)) |
| 98 | 98 | return -EOPNOTSUPP; |
| 99 | 99 | |
| 100 | − list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { | |
| 100 | + list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) { | |
| 101 | 101 | error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0); |
| 102 | 102 | if (error < 0) { |
| 103 | 103 | if (error == -ENODATA) |
| @@ -228,7 +228,7 @@ static int evm_protected_xattr(const char *req_xattr_name) · 124 unmodified lines | ||
| 228 | 228 | struct xattr_list *xattr; |
| 229 | 229 | |
| 230 | 230 | namelen = strlen(req_xattr_name); |
| 231 | − list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { | |
| 231 | + list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) { | |
| 232 | 232 | if ((strlen(xattr->name) == namelen) |
| 233 | 233 | && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) { |
| 234 | 234 | found = 1; |
| @@ -232,7 +232,14 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, · 231 unmodified lines | ||
| 232 | 232 | goto out; |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | − /* Guard against races in evm_read_xattrs */ | |
| 235 | + /* | |
| 236 | + * xattr_list_mutex guards against races in evm_read_xattrs(). | |
| 237 | + * Entries are only added to the evm_config_xattrnames list | |
| 238 | + * and never deleted. Therefore, the list is traversed | |
| 239 | + * using list_for_each_entry_lockless() without holding | |
| 240 | + * the mutex in evm_calc_hmac_or_hash(), evm_find_protected_xattrs() | |
| 241 | + * and evm_protected_xattr(). | |
| 242 | + */ | |
| 236 | 243 | mutex_lock(&xattr_list_mutex); |
| 237 | 244 | list_for_each_entry(tmp, &evm_config_xattrnames, list) { |
| 238 | 245 | if (strcmp(xattr->name, tmp->name) == 0) { |
| @@ -411,7 +411,7 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) · 410 unmodified lines | ||
| 411 | 411 | loff_t i_size; |
| 412 | 412 | int rc; |
| 413 | 413 | struct file *f = file; |
| 414 | − bool new_file_instance = false, modified_flags = false; | |
| 414 | + bool new_file_instance = false, modified_mode = false; | |
| 415 | 415 | |
| 416 | 416 | /* |
| 417 | 417 | * For consistency, fail file's opened with the O_DIRECT flag on |
| @@ -431,13 +431,13 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) · 13 unmodified lines | ||
| 431 | 431 | f = dentry_open(&file->f_path, flags, file->f_cred); |
| 432 | 432 | if (IS_ERR(f)) { |
| 433 | 433 | /* |
| 434 | − * Cannot open the file again, lets modify f_flags | |
| 434 | + * Cannot open the file again, lets modify f_mode | |
| 435 | 435 | * of original and continue |
| 436 | 436 | */ |
| 437 | 437 | pr_info_ratelimited("Unable to reopen file for reading.\n"); |
| 438 | 438 | f = file; |
| 439 | − f->f_flags |= FMODE_READ; | |
| 440 | − modified_flags = true; | |
| 439 | + f->f_mode |= FMODE_READ; | |
| 440 | + modified_mode = true; | |
| 441 | 441 | } else { |
| 442 | 442 | new_file_instance = true; |
| 443 | 443 | } |
| @@ -455,8 +455,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) · 11 unmodified lines | ||
| 455 | 455 | out: |
| 456 | 456 | if (new_file_instance) |
| 457 | 457 | fput(f); |
| 458 | − else if (modified_flags) | |
| 459 | − f->f_flags &= ~FMODE_READ; | |
| 458 | + else if (modified_mode) | |
| 459 | + f->f_mode &= ~FMODE_READ; | |
| 460 | 460 | return rc; |
| 461 | 461 | } |
| 462 | 462 | |
| @@ -338,8 +338,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, · 337 unmodified lines | ||
| 338 | 338 | integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, |
| 339 | 339 | "policy_update", "signed policy required", |
| 340 | 340 | 1, 0); |
| 341 | − if (ima_appraise & IMA_APPRAISE_ENFORCE) | |
| 342 | − result = -EACCES; | |
| 341 | + result = -EACCES; | |
| 343 | 342 | } else { |
| 344 | 343 | result = ima_parse_add_rule(data); |
| 345 | 344 | } |
| @@ -1965,8 +1965,20 @@ EXPORT_SYMBOL(security_ismaclabel); · 1964 unmodified lines | ||
| 1965 | 1965 | |
| 1966 | 1966 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
| 1967 | 1967 | { |
| 1968 | − return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, | |
| 1969 | − seclen); | |
| 1968 | + struct security_hook_list *hp; | |
| 1969 | + int rc; | |
| 1970 | + | |
| 1971 | + /* | |
| 1972 | + * Currently, only one LSM can implement secid_to_secctx (i.e this | |
| 1973 | + * LSM hook is not "stackable"). | |
| 1974 | + */ | |
| 1975 | + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { | |
| 1976 | + rc = hp->hook.secid_to_secctx(secid, secdata, seclen); | |
| 1977 | + if (rc != LSM_RET_DEFAULT(secid_to_secctx)) | |
| 1978 | + return rc; | |
| 1979 | + } | |
| 1980 | + | |
| 1981 | + return LSM_RET_DEFAULT(secid_to_secctx); | |
| 1970 | 1982 | } |
| 1971 | 1983 | EXPORT_SYMBOL(security_secid_to_secctx); |
| 1972 | 1984 | |
| @@ -433,6 +433,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 432 unmodified lines | ||
| 433 | 433 | |
| 434 | 434 | no_delta_check: |
| 435 | 435 | if (runtime->status->hw_ptr == new_hw_ptr) { |
| 436 | + runtime->hw_ptr_jiffies = curr_jiffies; | |
| 436 | 437 | update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp); |
| 437 | 438 | return 0; |
| 438 | 439 | } |
| @@ -120,6 +120,17 @@ static void snd_rawmidi_input_event_work(struct work_struct *work) · 119 unmodified lines | ||
| 120 | 120 | runtime->event(runtime->substream); |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | +/* buffer refcount management: call with runtime->lock held */ | |
| 124 | +static inline void snd_rawmidi_buffer_ref(struct snd_rawmidi_runtime *runtime) | |
| 125 | +{ | |
| 126 | + runtime->buffer_ref++; | |
| 127 | +} | |
| 128 | + | |
| 129 | +static inline void snd_rawmidi_buffer_unref(struct snd_rawmidi_runtime *runtime) | |
| 130 | +{ | |
| 131 | + runtime->buffer_ref--; | |
| 132 | +} | |
| 133 | + | |
| 123 | 134 | static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) |
| 124 | 135 | { |
| 125 | 136 | struct snd_rawmidi_runtime *runtime; |
| @@ -669,6 +680,11 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, · 543 unmodified lines | ||
| 669 | 680 | if (!newbuf) |
| 670 | 681 | return -ENOMEM; |
| 671 | 682 | spin_lock_irq(&runtime->lock); |
| 683 | + if (runtime->buffer_ref) { | |
| 684 | + spin_unlock_irq(&runtime->lock); | |
| 685 | + kvfree(newbuf); | |
| 686 | + return -EBUSY; | |
| 687 | + } | |
| 672 | 688 | oldbuf = runtime->buffer; |
| 673 | 689 | runtime->buffer = newbuf; |
| 674 | 690 | runtime->buffer_size = params->buffer_size; |
| @@ -1019,8 +1035,10 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, · 344 unmodified lines | ||
| 1019 | 1035 | long result = 0, count1; |
| 1020 | 1036 | struct snd_rawmidi_runtime *runtime = substream->runtime; |
| 1021 | 1037 | unsigned long appl_ptr; |
| 1038 | + int err = 0; | |
| 1022 | 1039 | |
| 1023 | 1040 | spin_lock_irqsave(&runtime->lock, flags); |
| 1041 | + snd_rawmidi_buffer_ref(runtime); | |
| 1024 | 1042 | while (count > 0 && runtime->avail) { |
| 1025 | 1043 | count1 = runtime->buffer_size - runtime->appl_ptr; |
| 1026 | 1044 | if (count1 > count) |
| @@ -1039,16 +1057,19 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, · 12 unmodified lines | ||
| 1039 | 1057 | if (userbuf) { |
| 1040 | 1058 | spin_unlock_irqrestore(&runtime->lock, flags); |
| 1041 | 1059 | if (copy_to_user(userbuf + result, |
| 1042 | − runtime->buffer + appl_ptr, count1)) { | |
| 1043 | − return result > 0 ? result : -EFAULT; | |
| 1044 | − } | |
| 1060 | + runtime->buffer + appl_ptr, count1)) | |
| 1061 | + err = -EFAULT; | |
| 1045 | 1062 | spin_lock_irqsave(&runtime->lock, flags); |
| 1063 | + if (err) | |
| 1064 | + goto out; | |
| 1046 | 1065 | } |
| 1047 | 1066 | result += count1; |
| 1048 | 1067 | count -= count1; |
| 1049 | 1068 | } |
| 1069 | + out: | |
| 1070 | + snd_rawmidi_buffer_unref(runtime); | |
| 1050 | 1071 | spin_unlock_irqrestore(&runtime->lock, flags); |
| 1051 | − return result; | |
| 1072 | + return result > 0 ? result : err; | |
| 1052 | 1073 | } |
| 1053 | 1074 | |
| 1054 | 1075 | long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, |
| @@ -1342,6 +1363,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, · 287 unmodified lines | ||
| 1342 | 1363 | return -EAGAIN; |
| 1343 | 1364 | } |
| 1344 | 1365 | } |
| 1366 | + snd_rawmidi_buffer_ref(runtime); | |
| 1345 | 1367 | while (count > 0 && runtime->avail > 0) { |
| 1346 | 1368 | count1 = runtime->buffer_size - runtime->appl_ptr; |
| 1347 | 1369 | if (count1 > count) |
| @@ -1373,6 +1395,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, · 25 unmodified lines | ||
| 1373 | 1395 | } |
| 1374 | 1396 | __end: |
| 1375 | 1397 | count1 = runtime->avail < runtime->buffer_size; |
| 1398 | + snd_rawmidi_buffer_unref(runtime); | |
| 1376 | 1399 | spin_unlock_irqrestore(&runtime->lock, flags); |
| 1377 | 1400 | if (count1) |
| 1378 | 1401 | snd_rawmidi_output_trigger(substream, 1); |
| @@ -66,8 +66,7 @@ TRACE_EVENT(amdtp_packet, · 65 unmodified lines | ||
| 66 | 66 | __entry->irq, |
| 67 | 67 | __entry->index, |
| 68 | 68 | __print_array(__get_dynamic_array(cip_header), |
| 69 | − __get_dynamic_array_len(cip_header), | |
| 70 | − sizeof(u8))) | |
| 69 | + __get_dynamic_array_len(cip_header), 1)) | |
| 71 | 70 | ); |
| 72 | 71 | |
| 73 | 72 | #endif |
| @@ -2457,6 +2457,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 2456 unmodified lines | ||
| 2457 | 2457 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
| 2458 | 2458 | SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), |
| 2459 | 2459 | SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), |
| 2460 | + SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950), | |
| 2460 | 2461 | SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950), |
| 2461 | 2462 | SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950), |
| 2462 | 2463 | SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950), |
| @@ -2472,6 +2473,9 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 9 unmodified lines | ||
| 2472 | 2473 | SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950), |
| 2473 | 2474 | SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2474 | 2475 | SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2476 | + SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | |
| 2477 | + SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | |
| 2478 | + SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | |
| 2475 | 2479 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
| 2476 | 2480 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
| 2477 | 2481 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
| @@ -5856,6 +5860,15 @@ static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec, · 3378 unmodified lines | ||
| 5856 | 5860 | } |
| 5857 | 5861 | } |
| 5858 | 5862 | |
| 5863 | +static void alc225_fixup_s3_pop_noise(struct hda_codec *codec, | |
| 5864 | + const struct hda_fixup *fix, int action) | |
| 5865 | +{ | |
| 5866 | + if (action != HDA_FIXUP_ACT_PRE_PROBE) | |
| 5867 | + return; | |
| 5868 | + | |
| 5869 | + codec->power_save_node = 1; | |
| 5870 | +} | |
| 5871 | + | |
| 5859 | 5872 | /* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */ |
| 5860 | 5873 | static void alc274_fixup_bind_dacs(struct hda_codec *codec, |
| 5861 | 5874 | const struct hda_fixup *fix, int action) |
| @@ -5960,6 +5973,7 @@ enum { · 98 unmodified lines | ||
| 5960 | 5973 | ALC269_FIXUP_HP_LINE1_MIC1_LED, |
| 5961 | 5974 | ALC269_FIXUP_INV_DMIC, |
| 5962 | 5975 | ALC269_FIXUP_LENOVO_DOCK, |
| 5976 | + ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, | |
| 5963 | 5977 | ALC269_FIXUP_NO_SHUTUP, |
| 5964 | 5978 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, |
| 5965 | 5979 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
| @@ -6045,6 +6059,7 @@ enum { · 79 unmodified lines | ||
| 6045 | 6059 | ALC233_FIXUP_ACER_HEADSET_MIC, |
| 6046 | 6060 | ALC294_FIXUP_LENOVO_MIC_LOCATION, |
| 6047 | 6061 | ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, |
| 6062 | + ALC225_FIXUP_S3_POP_NOISE, | |
| 6048 | 6063 | ALC700_FIXUP_INTEL_REFERENCE, |
| 6049 | 6064 | ALC274_FIXUP_DELL_BIND_DACS, |
| 6050 | 6065 | ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, |
| @@ -6080,9 +6095,12 @@ enum { · 29 unmodified lines | ||
| 6080 | 6095 | ALC294_FIXUP_ASUS_DUAL_SPK, |
| 6081 | 6096 | ALC285_FIXUP_THINKPAD_HEADSET_JACK, |
| 6082 | 6097 | ALC294_FIXUP_ASUS_HPE, |
| 6098 | + ALC294_FIXUP_ASUS_COEF_1B, | |
| 6083 | 6099 | ALC285_FIXUP_HP_GPIO_LED, |
| 6084 | 6100 | ALC285_FIXUP_HP_MUTE_LED, |
| 6085 | 6101 | ALC236_FIXUP_HP_MUTE_LED, |
| 6102 | + ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, | |
| 6103 | + ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, | |
| 6086 | 6104 | }; |
| 6087 | 6105 | |
| 6088 | 6106 | static const struct hda_fixup alc269_fixups[] = { |
| @@ -6280,6 +6298,12 @@ static const struct hda_fixup alc269_fixups[] = { · 191 unmodified lines | ||
| 6280 | 6298 | .chained = true, |
| 6281 | 6299 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT |
| 6282 | 6300 | }, |
| 6301 | + [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = { | |
| 6302 | + .type = HDA_FIXUP_FUNC, | |
| 6303 | + .v.func = alc269_fixup_limit_int_mic_boost, | |
| 6304 | + .chained = true, | |
| 6305 | + .chain_id = ALC269_FIXUP_LENOVO_DOCK, | |
| 6306 | + }, | |
| 6283 | 6307 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { |
| 6284 | 6308 | .type = HDA_FIXUP_FUNC, |
| 6285 | 6309 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
| @@ -6932,6 +6956,12 @@ static const struct hda_fixup alc269_fixups[] = { · 646 unmodified lines | ||
| 6932 | 6956 | { } |
| 6933 | 6957 | }, |
| 6934 | 6958 | .chained = true, |
| 6959 | + .chain_id = ALC225_FIXUP_S3_POP_NOISE | |
| 6960 | + }, | |
| 6961 | + [ALC225_FIXUP_S3_POP_NOISE] = { | |
| 6962 | + .type = HDA_FIXUP_FUNC, | |
| 6963 | + .v.func = alc225_fixup_s3_pop_noise, | |
| 6964 | + .chained = true, | |
| 6935 | 6965 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
| 6936 | 6966 | }, |
| 6937 | 6967 | [ALC700_FIXUP_INTEL_REFERENCE] = { |
| @@ -7204,6 +7234,17 @@ static const struct hda_fixup alc269_fixups[] = { · 266 unmodified lines | ||
| 7204 | 7234 | .chained = true, |
| 7205 | 7235 | .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC |
| 7206 | 7236 | }, |
| 7237 | + [ALC294_FIXUP_ASUS_COEF_1B] = { | |
| 7238 | + .type = HDA_FIXUP_VERBS, | |
| 7239 | + .v.verbs = (const struct hda_verb[]) { | |
| 7240 | + /* Set bit 10 to correct noisy output after reboot from | |
| 7241 | + * Windows 10 (due to pop noise reduction?) | |
| 7242 | + */ | |
| 7243 | + { 0x20, AC_VERB_SET_COEF_INDEX, 0x1b }, | |
| 7244 | + { 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b }, | |
| 7245 | + { } | |
| 7246 | + }, | |
| 7247 | + }, | |
| 7207 | 7248 | [ALC285_FIXUP_HP_GPIO_LED] = { |
| 7208 | 7249 | .type = HDA_FIXUP_FUNC, |
| 7209 | 7250 | .v.func = alc285_fixup_hp_gpio_led, |
| @@ -7216,6 +7257,22 @@ static const struct hda_fixup alc269_fixups[] = { · 6 unmodified lines | ||
| 7216 | 7257 | .type = HDA_FIXUP_FUNC, |
| 7217 | 7258 | .v.func = alc236_fixup_hp_mute_led, |
| 7218 | 7259 | }, |
| 7260 | + [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { | |
| 7261 | + .type = HDA_FIXUP_VERBS, | |
| 7262 | + .v.verbs = (const struct hda_verb[]) { | |
| 7263 | + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc5 }, | |
| 7264 | + { } | |
| 7265 | + }, | |
| 7266 | + }, | |
| 7267 | + [ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = { | |
| 7268 | + .type = HDA_FIXUP_PINS, | |
| 7269 | + .v.pins = (const struct hda_pintbl[]) { | |
| 7270 | + { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | |
| 7271 | + { } | |
| 7272 | + }, | |
| 7273 | + .chained = true, | |
| 7274 | + .chain_id = ALC269_FIXUP_HEADSET_MODE | |
| 7275 | + }, | |
| 7219 | 7276 | }; |
| 7220 | 7277 | |
| 7221 | 7278 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -7383,8 +7440,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 161 unmodified lines | ||
| 7383 | 7440 | SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), |
| 7384 | 7441 | SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), |
| 7385 | 7442 | SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), |
| 7443 | + SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE), | |
| 7386 | 7444 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
| 7387 | 7445 | SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), |
| 7446 | + SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B), | |
| 7388 | 7447 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
| 7389 | 7448 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), |
| 7390 | 7449 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| @@ -7410,6 +7469,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 19 unmodified lines | ||
| 7410 | 7469 | SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), |
| 7411 | 7470 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), |
| 7412 | 7471 | SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), |
| 7472 | + SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), | |
| 7473 | + SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), | |
| 7413 | 7474 | SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), |
| 7414 | 7475 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), |
| 7415 | 7476 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), |
| @@ -7426,7 +7487,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 10 unmodified lines | ||
| 7426 | 7487 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
| 7427 | 7488 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
| 7428 | 7489 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
| 7429 | − SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), | |
| 7490 | + SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST), | |
| 7430 | 7491 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), |
| 7431 | 7492 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), |
| 7432 | 7493 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), |
| @@ -7565,6 +7626,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { · 132 unmodified lines | ||
| 7565 | 7626 | {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"}, |
| 7566 | 7627 | {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"}, |
| 7567 | 7628 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
| 7629 | + {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"}, | |
| 7568 | 7630 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, |
| 7569 | 7631 | {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"}, |
| 7570 | 7632 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
| @@ -7993,6 +8055,18 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { · 422 unmodified lines | ||
| 7993 | 8055 | {0x12, 0x90a60130}, |
| 7994 | 8056 | {0x17, 0x90170110}, |
| 7995 | 8057 | {0x21, 0x03211020}), |
| 8058 | + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, | |
| 8059 | + {0x12, 0x90a60120}, | |
| 8060 | + {0x17, 0x90170110}, | |
| 8061 | + {0x21, 0x04211030}), | |
| 8062 | + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, | |
| 8063 | + {0x12, 0x90a60130}, | |
| 8064 | + {0x17, 0x90170110}, | |
| 8065 | + {0x21, 0x03211020}), | |
| 8066 | + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, | |
| 8067 | + {0x12, 0x90a60130}, | |
| 8068 | + {0x17, 0x90170110}, | |
| 8069 | + {0x21, 0x03211020}), | |
| 7996 | 8070 | SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, |
| 7997 | 8071 | {0x14, 0x90170110}, |
| 7998 | 8072 | {0x21, 0x04211020}), |
| @@ -8209,8 +8283,6 @@ static int patch_alc269(struct hda_codec *codec) · 210 unmodified lines | ||
| 8209 | 8283 | spec->gen.mixer_nid = 0; |
| 8210 | 8284 | break; |
| 8211 | 8285 | case 0x10ec0225: |
| 8212 | − codec->power_save_node = 1; | |
| 8213 | − /* fall through */ | |
| 8214 | 8286 | case 0x10ec0295: |
| 8215 | 8287 | case 0x10ec0299: |
| 8216 | 8288 | spec->codec_variant = ALC269_TYPE_ALC225; |
| @@ -2332,7 +2332,8 @@ static int snd_ice1712_chip_init(struct snd_ice1712 *ice) · 2331 unmodified lines | ||
| 2332 | 2332 | pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); |
| 2333 | 2333 | pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); |
| 2334 | 2334 | pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); |
| 2335 | − if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) { | |
| 2335 | + if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24 && | |
| 2336 | + ice->eeprom.subvendor != ICE1712_SUBDEVICE_STAUDIO_ADCIII) { | |
| 2336 | 2337 | ice->gpio.write_mask = ice->eeprom.gpiomask; |
| 2337 | 2338 | ice->gpio.direction = ice->eeprom.gpiodir; |
| 2338 | 2339 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, |
| @@ -549,6 +549,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { · 548 unmodified lines | ||
| 549 | 549 | .map = trx40_mobo_map, |
| 550 | 550 | .connector_map = trx40_mobo_connector_map, |
| 551 | 551 | }, |
| 552 | + { /* Asrock TRX40 Creator */ | |
| 553 | + .id = USB_ID(0x26ce, 0x0a01), | |
| 554 | + .map = trx40_mobo_map, | |
| 555 | + .connector_map = trx40_mobo_connector_map, | |
| 556 | + }, | |
| 552 | 557 | { 0 } /* terminator */ |
| 553 | 558 | }; |
| 554 | 559 | |
| @@ -3563,6 +3563,7 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), · 3562 unmodified lines | ||
| 3563 | 3563 | ALC1220_VB_DESKTOP(0x0414, 0xa002), /* Gigabyte TRX40 Aorus Pro WiFi */ |
| 3564 | 3564 | ALC1220_VB_DESKTOP(0x0db0, 0x0d64), /* MSI TRX40 Creator */ |
| 3565 | 3565 | ALC1220_VB_DESKTOP(0x0db0, 0x543d), /* MSI TRX40 */ |
| 3566 | +ALC1220_VB_DESKTOP(0x26ce, 0x0a01), /* Asrock TRX40 Creator */ | |
| 3566 | 3567 | #undef ALC1220_VB_DESKTOP |
| 3567 | 3568 | |
| 3568 | 3569 | #undef USB_DEVICE_VENDOR_SPEC |
| @@ -1636,13 +1636,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, · 1635 unmodified lines | ||
| 1636 | 1636 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
| 1637 | 1637 | msleep(20); |
| 1638 | 1638 | |
| 1639 | − /* Zoom R16/24, Logitech H650e, Jabra 550a needs a tiny delay here, | |
| 1640 | − * otherwise requests like get/set frequency return as failed despite | |
| 1641 | − * actually succeeding. | |
| 1639 | + /* Zoom R16/24, Logitech H650e, Jabra 550a, Kingston HyperX needs a tiny | |
| 1640 | + * delay here, otherwise requests like get/set frequency return as | |
| 1641 | + * failed despite actually succeeding. | |
| 1642 | 1642 | */ |
| 1643 | 1643 | if ((chip->usb_id == USB_ID(0x1686, 0x00dd) || |
| 1644 | 1644 | chip->usb_id == USB_ID(0x046d, 0x0a46) || |
| 1645 | − chip->usb_id == USB_ID(0x0b0e, 0x0349)) && | |
| 1645 | + chip->usb_id == USB_ID(0x0b0e, 0x0349) || | |
| 1646 | + chip->usb_id == USB_ID(0x0951, 0x16ad)) && | |
| 1646 | 1647 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
| 1647 | 1648 | usleep_range(1000, 2000); |
| 1648 | 1649 | } |
| @@ -337,6 +337,7 @@ int apply_xbc(const char *path, const char *xbc_path) · 336 unmodified lines | ||
| 337 | 337 | pr_err("Failed to apply a boot config magic: %d\n", ret); |
| 338 | 338 | goto out; |
| 339 | 339 | } |
| 340 | + ret = 0; | |
| 340 | 341 | out: |
| 341 | 342 | close(fd); |
| 342 | 343 | free(data); |
| @@ -148,11 +148,11 @@ struct pt_regs; · 147 unmodified lines | ||
| 148 | 148 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[4]) |
| 149 | 149 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[5]) |
| 150 | 150 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[6]) |
| 151 | −#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), grps[14]) | |
| 151 | +#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[14]) | |
| 152 | 152 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[11]) |
| 153 | 153 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2]) |
| 154 | 154 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[15]) |
| 155 | −#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), pdw.addr) | |
| 155 | +#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), psw.addr) | |
| 156 | 156 | |
| 157 | 157 | #elif defined(bpf_target_arm) |
| 158 | 158 | |
| @@ -19,7 +19,7 @@ void test_mmap(void) · 18 unmodified lines | ||
| 19 | 19 | const size_t map_sz = roundup_page(sizeof(struct map_data)); |
| 20 | 20 | const int zero = 0, one = 1, two = 2, far = 1500; |
| 21 | 21 | const long page_size = sysconf(_SC_PAGE_SIZE); |
| 22 | − int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd; | |
| 22 | + int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd, rdmap_fd; | |
| 23 | 23 | struct bpf_map *data_map, *bss_map; |
| 24 | 24 | void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp1, *tmp2; |
| 25 | 25 | struct test_mmap__bss *bss_data; |
| @@ -37,6 +37,17 @@ void test_mmap(void) · 11 unmodified lines | ||
| 37 | 37 | data_map = skel->maps.data_map; |
| 38 | 38 | data_map_fd = bpf_map__fd(data_map); |
| 39 | 39 | |
| 40 | + rdmap_fd = bpf_map__fd(skel->maps.rdonly_map); | |
| 41 | + tmp1 = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, rdmap_fd, 0); | |
| 42 | + if (CHECK(tmp1 != MAP_FAILED, "rdonly_write_mmap", "unexpected success\n")) { | |
| 43 | + munmap(tmp1, 4096); | |
| 44 | + goto cleanup; | |
| 45 | + } | |
| 46 | + /* now double-check if it's mmap()'able at all */ | |
| 47 | + tmp1 = mmap(NULL, 4096, PROT_READ, MAP_SHARED, rdmap_fd, 0); | |
| 48 | + if (CHECK(tmp1 == MAP_FAILED, "rdonly_read_mmap", "failed: %d\n", errno)) | |
| 49 | + goto cleanup; | |
| 50 | + | |
| 40 | 51 | /* get map's ID */ |
| 41 | 52 | memset(&map_info, 0, map_info_sz); |
| 42 | 53 | err = bpf_obj_get_info_by_fd(data_map_fd, &map_info, &map_info_sz); |
| @@ -217,6 +228,14 @@ void test_mmap(void) · 174 unmodified lines | ||
| 217 | 228 | |
| 218 | 229 | munmap(tmp2, 4 * page_size); |
| 219 | 230 | |
| 231 | + /* map all 4 pages, but with pg_off=1 page, should fail */ | |
| 232 | + tmp1 = mmap(NULL, 4 * page_size, PROT_READ, MAP_SHARED | MAP_FIXED, | |
| 233 | + data_map_fd, page_size /* initial page shift */); | |
| 234 | + if (CHECK(tmp1 != MAP_FAILED, "adv_mmap7", "unexpected success")) { | |
| 235 | + munmap(tmp1, 4 * page_size); | |
| 236 | + goto cleanup; | |
| 237 | + } | |
| 238 | + | |
| 220 | 239 | tmp1 = mmap(NULL, map_sz, PROT_READ, MAP_SHARED, data_map_fd, 0); |
| 221 | 240 | if (CHECK(tmp1 == MAP_FAILED, "last_mmap", "failed %d\n", errno)) |
| 222 | 241 | goto cleanup; |
| @@ -7,6 +7,14 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | char _license[] SEC("license") = "GPL"; |
| 9 | 9 | |
| 10 | +struct { | |
| 11 | + __uint(type, BPF_MAP_TYPE_ARRAY); | |
| 12 | + __uint(max_entries, 4096); | |
| 13 | + __uint(map_flags, BPF_F_MMAPABLE | BPF_F_RDONLY_PROG); | |
| 14 | + __type(key, __u32); | |
| 15 | + __type(value, char); | |
| 16 | +} rdonly_map SEC(".maps"); | |
| 17 | + | |
| 10 | 18 | struct { |
| 11 | 19 | __uint(type, BPF_MAP_TYPE_ARRAY); |
| 12 | 20 | __uint(max_entries, 512 * 4); /* at least 4 pages of data */ |
| @@ -30,13 +30,13 @@ int prog3(struct bpf_raw_tracepoint_args *ctx) · 29 unmodified lines | ||
| 30 | 30 | SEC("fentry/__set_task_comm") |
| 31 | 31 | int BPF_PROG(prog4, struct task_struct *tsk, const char *buf, bool exec) |
| 32 | 32 | { |
| 33 | − return !tsk; | |
| 33 | + return 0; | |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | SEC("fexit/__set_task_comm") |
| 37 | 37 | int BPF_PROG(prog5, struct task_struct *tsk, const char *buf, bool exec) |
| 38 | 38 | { |
| 39 | − return !tsk; | |
| 39 | + return 0; | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | char _license[] SEC("license") = "GPL"; |
| @@ -351,6 +351,7 @@ static int test_alloc_errors(char *heap_name) · 350 unmodified lines | ||
| 351 | 351 | } |
| 352 | 352 | |
| 353 | 353 | printf("Expected error checking passed\n"); |
| 354 | + ret = 0; | |
| 354 | 355 | out: |
| 355 | 356 | if (dmabuf_fd >= 0) |
| 356 | 357 | close(dmabuf_fd); |
| @@ -300,7 +300,7 @@ test_uc_aware() · 299 unmodified lines | ||
| 300 | 300 | local i |
| 301 | 301 | |
| 302 | 302 | for ((i = 0; i < attempts; ++i)); do |
| 303 | − if $ARPING -c 1 -I $h1 -b 192.0.2.66 -q -w 0.1; then | |
| 303 | + if $ARPING -c 1 -I $h1 -b 192.0.2.66 -q -w 1; then | |
| 304 | 304 | ((passes++)) |
| 305 | 305 | fi |
| 306 | 306 | |
| @@ -264,6 +264,8 @@ trap_policer_test() · 263 unmodified lines | ||
| 264 | 264 | local packets_t0 |
| 265 | 265 | local packets_t1 |
| 266 | 266 | |
| 267 | + RET=0 | |
| 268 | + | |
| 267 | 269 | if [ $(devlink_trap_policers_num_get) -eq 0 ]; then |
| 268 | 270 | check_err 1 "Failed to dump policers" |
| 269 | 271 | fi |
| @@ -328,6 +330,8 @@ trap_group_check_policer() · 58 unmodified lines | ||
| 328 | 330 | |
| 329 | 331 | trap_policer_bind_test() |
| 330 | 332 | { |
| 333 | + RET=0 | |
| 334 | + | |
| 331 | 335 | devlink trap group set $DEVLINK_DEV group l2_drops policer 1 |
| 332 | 336 | check_err $? "Failed to bind a valid policer" |
| 333 | 337 | if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then |
| @@ -17,7 +17,14 @@ unsup() { #msg · 16 unmodified lines | ||
| 17 | 17 | exit_unsupported |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | −modprobe $MOD || unsup "$MOD module not available" | |
| 20 | +unres() { #msg | |
| 21 | + reset_tracer | |
| 22 | + rmmod $MOD || true | |
| 23 | + echo $1 | |
| 24 | + exit_unresolved | |
| 25 | +} | |
| 26 | + | |
| 27 | +modprobe $MOD || unres "$MOD module not available" | |
| 21 | 28 | rmmod $MOD |
| 22 | 29 | |
| 23 | 30 | grep -q "preemptoff" available_tracers || unsup "preemptoff tracer not enabled" |
| @@ -54,6 +54,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test · 53 unmodified lines | ||
| 54 | 54 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test |
| 55 | 55 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test |
| 56 | 56 | TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test |
| 57 | +TEST_GEN_PROGS_x86_64 += x86_64/debug_regs | |
| 57 | 58 | TEST_GEN_PROGS_x86_64 += clear_dirty_log_test |
| 58 | 59 | TEST_GEN_PROGS_x86_64 += demand_paging_test |
| 59 | 60 | TEST_GEN_PROGS_x86_64 += dirty_log_test |
| @@ -143,6 +143,8 @@ struct kvm_run *vcpu_state(struct kvm_vm *vm, uint32_t vcpuid); · 142 unmodified lines | ||
| 143 | 143 | void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid); |
| 144 | 144 | int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid); |
| 145 | 145 | void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid); |
| 146 | +void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid, | |
| 147 | + struct kvm_guest_debug *debug); | |
| 146 | 148 | void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid, |
| 147 | 149 | struct kvm_mp_state *mp_state); |
| 148 | 150 | void vcpu_regs_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_regs *regs); |
| @@ -1201,6 +1201,15 @@ void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid) · 1200 unmodified lines | ||
| 1201 | 1201 | ret, errno); |
| 1202 | 1202 | } |
| 1203 | 1203 | |
| 1204 | +void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid, | |
| 1205 | + struct kvm_guest_debug *debug) | |
| 1206 | +{ | |
| 1207 | + struct vcpu *vcpu = vcpu_find(vm, vcpuid); | |
| 1208 | + int ret = ioctl(vcpu->fd, KVM_SET_GUEST_DEBUG, debug); | |
| 1209 | + | |
| 1210 | + TEST_ASSERT(ret == 0, "KVM_SET_GUEST_DEBUG failed: %d", ret); | |
| 1211 | +} | |
| 1212 | + | |
| 1204 | 1213 | /* |
| 1205 | 1214 | * VM VCPU Set MP State |
| 1206 | 1215 | * |
| @@ -0,0 +1,202 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * KVM guest debug register tests | |
| 4 | + * | |
| 5 | + * Copyright (C) 2020, Red Hat, Inc. | |
| 6 | + */ | |
| 7 | +#include <stdio.h> | |
| 8 | +#include <string.h> | |
| 9 | +#include "kvm_util.h" | |
| 10 | +#include "processor.h" | |
| 11 | + | |
| 12 | +#define VCPU_ID 0 | |
| 13 | + | |
| 14 | +#define DR6_BD (1 << 13) | |
| 15 | +#define DR7_GD (1 << 13) | |
| 16 | + | |
| 17 | +/* For testing data access debug BP */ | |
| 18 | +uint32_t guest_value; | |
| 19 | + | |
| 20 | +extern unsigned char sw_bp, hw_bp, write_data, ss_start, bd_start; | |
| 21 | + | |
| 22 | +static void guest_code(void) | |
| 23 | +{ | |
| 24 | + /* | |
| 25 | + * Software BP tests. | |
| 26 | + * | |
| 27 | + * NOTE: sw_bp need to be before the cmd here, because int3 is an | |
| 28 | + * exception rather than a normal trap for KVM_SET_GUEST_DEBUG (we | |
| 29 | + * capture it using the vcpu exception bitmap). | |
| 30 | + */ | |
| 31 | + asm volatile("sw_bp: int3"); | |
| 32 | + | |
| 33 | + /* Hardware instruction BP test */ | |
| 34 | + asm volatile("hw_bp: nop"); | |
| 35 | + | |
| 36 | + /* Hardware data BP test */ | |
| 37 | + asm volatile("mov $1234,%%rax;\n\t" | |
| 38 | + "mov %%rax,%0;\n\t write_data:" | |
| 39 | + : "=m" (guest_value) : : "rax"); | |
| 40 | + | |
| 41 | + /* Single step test, covers 2 basic instructions and 2 emulated */ | |
| 42 | + asm volatile("ss_start: " | |
| 43 | + "xor %%rax,%%rax\n\t" | |
| 44 | + "cpuid\n\t" | |
| 45 | + "movl $0x1a0,%%ecx\n\t" | |
| 46 | + "rdmsr\n\t" | |
| 47 | + : : : "rax", "ecx"); | |
| 48 | + | |
| 49 | + /* DR6.BD test */ | |
| 50 | + asm volatile("bd_start: mov %%dr0, %%rax" : : : "rax"); | |
| 51 | + GUEST_DONE(); | |
| 52 | +} | |
| 53 | + | |
| 54 | +#define CLEAR_DEBUG() memset(&debug, 0, sizeof(debug)) | |
| 55 | +#define APPLY_DEBUG() vcpu_set_guest_debug(vm, VCPU_ID, &debug) | |
| 56 | +#define CAST_TO_RIP(v) ((unsigned long long)&(v)) | |
| 57 | +#define SET_RIP(v) do { \ | |
| 58 | + vcpu_regs_get(vm, VCPU_ID, ®s); \ | |
| 59 | + regs.rip = (v); \ | |
| 60 | + vcpu_regs_set(vm, VCPU_ID, ®s); \ | |
| 61 | + } while (0) | |
| 62 | +#define MOVE_RIP(v) SET_RIP(regs.rip + (v)); | |
| 63 | + | |
| 64 | +int main(void) | |
| 65 | +{ | |
| 66 | + struct kvm_guest_debug debug; | |
| 67 | + unsigned long long target_dr6, target_rip; | |
| 68 | + struct kvm_regs regs; | |
| 69 | + struct kvm_run *run; | |
| 70 | + struct kvm_vm *vm; | |
| 71 | + struct ucall uc; | |
| 72 | + uint64_t cmd; | |
| 73 | + int i; | |
| 74 | + /* Instruction lengths starting at ss_start */ | |
| 75 | + int ss_size[4] = { | |
| 76 | + 3, /* xor */ | |
| 77 | + 2, /* cpuid */ | |
| 78 | + 5, /* mov */ | |
| 79 | + 2, /* rdmsr */ | |
| 80 | + }; | |
| 81 | + | |
| 82 | + if (!kvm_check_cap(KVM_CAP_SET_GUEST_DEBUG)) { | |
| 83 | + print_skip("KVM_CAP_SET_GUEST_DEBUG not supported"); | |
| 84 | + return 0; | |
| 85 | + } | |
| 86 | + | |
| 87 | + vm = vm_create_default(VCPU_ID, 0, guest_code); | |
| 88 | + vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); | |
| 89 | + run = vcpu_state(vm, VCPU_ID); | |
| 90 | + | |
| 91 | + /* Test software BPs - int3 */ | |
| 92 | + CLEAR_DEBUG(); | |
| 93 | + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; | |
| 94 | + APPLY_DEBUG(); | |
| 95 | + vcpu_run(vm, VCPU_ID); | |
| 96 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && | |
| 97 | + run->debug.arch.exception == BP_VECTOR && | |
| 98 | + run->debug.arch.pc == CAST_TO_RIP(sw_bp), | |
| 99 | + "INT3: exit %d exception %d rip 0x%llx (should be 0x%llx)", | |
| 100 | + run->exit_reason, run->debug.arch.exception, | |
| 101 | + run->debug.arch.pc, CAST_TO_RIP(sw_bp)); | |
| 102 | + MOVE_RIP(1); | |
| 103 | + | |
| 104 | + /* Test instruction HW BP over DR[0-3] */ | |
| 105 | + for (i = 0; i < 4; i++) { | |
| 106 | + CLEAR_DEBUG(); | |
| 107 | + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; | |
| 108 | + debug.arch.debugreg[i] = CAST_TO_RIP(hw_bp); | |
| 109 | + debug.arch.debugreg[7] = 0x400 | (1UL << (2*i+1)); | |
| 110 | + APPLY_DEBUG(); | |
| 111 | + vcpu_run(vm, VCPU_ID); | |
| 112 | + target_dr6 = 0xffff0ff0 | (1UL << i); | |
| 113 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && | |
| 114 | + run->debug.arch.exception == DB_VECTOR && | |
| 115 | + run->debug.arch.pc == CAST_TO_RIP(hw_bp) && | |
| 116 | + run->debug.arch.dr6 == target_dr6, | |
| 117 | + "INS_HW_BP (DR%d): exit %d exception %d rip 0x%llx " | |
| 118 | + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", | |
| 119 | + i, run->exit_reason, run->debug.arch.exception, | |
| 120 | + run->debug.arch.pc, CAST_TO_RIP(hw_bp), | |
| 121 | + run->debug.arch.dr6, target_dr6); | |
| 122 | + } | |
| 123 | + /* Skip "nop" */ | |
| 124 | + MOVE_RIP(1); | |
| 125 | + | |
| 126 | + /* Test data access HW BP over DR[0-3] */ | |
| 127 | + for (i = 0; i < 4; i++) { | |
| 128 | + CLEAR_DEBUG(); | |
| 129 | + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; | |
| 130 | + debug.arch.debugreg[i] = CAST_TO_RIP(guest_value); | |
| 131 | + debug.arch.debugreg[7] = 0x00000400 | (1UL << (2*i+1)) | | |
| 132 | + (0x000d0000UL << (4*i)); | |
| 133 | + APPLY_DEBUG(); | |
| 134 | + vcpu_run(vm, VCPU_ID); | |
| 135 | + target_dr6 = 0xffff0ff0 | (1UL << i); | |
| 136 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && | |
| 137 | + run->debug.arch.exception == DB_VECTOR && | |
| 138 | + run->debug.arch.pc == CAST_TO_RIP(write_data) && | |
| 139 | + run->debug.arch.dr6 == target_dr6, | |
| 140 | + "DATA_HW_BP (DR%d): exit %d exception %d rip 0x%llx " | |
| 141 | + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", | |
| 142 | + i, run->exit_reason, run->debug.arch.exception, | |
| 143 | + run->debug.arch.pc, CAST_TO_RIP(write_data), | |
| 144 | + run->debug.arch.dr6, target_dr6); | |
| 145 | + /* Rollback the 4-bytes "mov" */ | |
| 146 | + MOVE_RIP(-7); | |
| 147 | + } | |
| 148 | + /* Skip the 4-bytes "mov" */ | |
| 149 | + MOVE_RIP(7); | |
| 150 | + | |
| 151 | + /* Test single step */ | |
| 152 | + target_rip = CAST_TO_RIP(ss_start); | |
| 153 | + target_dr6 = 0xffff4ff0ULL; | |
| 154 | + vcpu_regs_get(vm, VCPU_ID, ®s); | |
| 155 | + for (i = 0; i < (sizeof(ss_size) / sizeof(ss_size[0])); i++) { | |
| 156 | + target_rip += ss_size[i]; | |
| 157 | + CLEAR_DEBUG(); | |
| 158 | + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; | |
| 159 | + debug.arch.debugreg[7] = 0x00000400; | |
| 160 | + APPLY_DEBUG(); | |
| 161 | + vcpu_run(vm, VCPU_ID); | |
| 162 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && | |
| 163 | + run->debug.arch.exception == DB_VECTOR && | |
| 164 | + run->debug.arch.pc == target_rip && | |
| 165 | + run->debug.arch.dr6 == target_dr6, | |
| 166 | + "SINGLE_STEP[%d]: exit %d exception %d rip 0x%llx " | |
| 167 | + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", | |
| 168 | + i, run->exit_reason, run->debug.arch.exception, | |
| 169 | + run->debug.arch.pc, target_rip, run->debug.arch.dr6, | |
| 170 | + target_dr6); | |
| 171 | + } | |
| 172 | + | |
| 173 | + /* Finally test global disable */ | |
| 174 | + CLEAR_DEBUG(); | |
| 175 | + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; | |
| 176 | + debug.arch.debugreg[7] = 0x400 | DR7_GD; | |
| 177 | + APPLY_DEBUG(); | |
| 178 | + vcpu_run(vm, VCPU_ID); | |
| 179 | + target_dr6 = 0xffff0ff0 | DR6_BD; | |
| 180 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_DEBUG && | |
| 181 | + run->debug.arch.exception == DB_VECTOR && | |
| 182 | + run->debug.arch.pc == CAST_TO_RIP(bd_start) && | |
| 183 | + run->debug.arch.dr6 == target_dr6, | |
| 184 | + "DR7.GD: exit %d exception %d rip 0x%llx " | |
| 185 | + "(should be 0x%llx) dr6 0x%llx (should be 0x%llx)", | |
| 186 | + run->exit_reason, run->debug.arch.exception, | |
| 187 | + run->debug.arch.pc, target_rip, run->debug.arch.dr6, | |
| 188 | + target_dr6); | |
| 189 | + | |
| 190 | + /* Disable all debug controls, run to the end */ | |
| 191 | + CLEAR_DEBUG(); | |
| 192 | + APPLY_DEBUG(); | |
| 193 | + | |
| 194 | + vcpu_run(vm, VCPU_ID); | |
| 195 | + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, "KVM_EXIT_IO"); | |
| 196 | + cmd = get_ucall(vm, VCPU_ID, &uc); | |
| 197 | + TEST_ASSERT(cmd == UCALL_DONE, "UCALL_DONE"); | |
| 198 | + | |
| 199 | + kvm_vm_free(vm); | |
| 200 | + | |
| 201 | + return 0; | |
| 202 | +} | |
| @@ -25,13 +25,13 @@ fi · 24 unmodified lines | ||
| 25 | 25 | # Figure out which test to run from our script name. |
| 26 | 26 | test=$(basename $0 .sh) |
| 27 | 27 | # Look up details about the test from master list of LKDTM tests. |
| 28 | −line=$(egrep '^#?'"$test"'\b' tests.txt) | |
| 28 | +line=$(grep -E '^#?'"$test"'\b' tests.txt) | |
| 29 | 29 | if [ -z "$line" ]; then |
| 30 | 30 | echo "Skipped: missing test '$test' in tests.txt" |
| 31 | 31 | exit $KSELFTEST_SKIP_TEST |
| 32 | 32 | fi |
| 33 | 33 | # Check that the test is known to LKDTM. |
| 34 | −if ! egrep -q '^'"$test"'$' "$TRIGGER" ; then | |
| 34 | +if ! grep -E -q '^'"$test"'$' "$TRIGGER" ; then | |
| 35 | 35 | echo "Skipped: test '$test' missing in $TRIGGER!" |
| 36 | 36 | exit $KSELFTEST_SKIP_TEST |
| 37 | 37 | fi |
| @@ -59,30 +59,32 @@ if [ -z "$expect" ]; then · 21 unmodified lines | ||
| 59 | 59 | expect="call trace:" |
| 60 | 60 | fi |
| 61 | 61 | |
| 62 | −# Clear out dmesg for output reporting | |
| 63 | −dmesg -c >/dev/null | |
| 64 | − | |
| 65 | 62 | # Prepare log for report checking |
| 66 | −LOG=$(mktemp --tmpdir -t lkdtm-XXXXXX) | |
| 63 | +LOG=$(mktemp --tmpdir -t lkdtm-log-XXXXXX) | |
| 64 | +DMESG=$(mktemp --tmpdir -t lkdtm-dmesg-XXXXXX) | |
| 67 | 65 | cleanup() { |
| 68 | − rm -f "$LOG" | |
| 66 | + rm -f "$LOG" "$DMESG" | |
| 69 | 67 | } |
| 70 | 68 | trap cleanup EXIT |
| 71 | 69 | |
| 70 | +# Save existing dmesg so we can detect new content below | |
| 71 | +dmesg > "$DMESG" | |
| 72 | + | |
| 72 | 73 | # Most shells yell about signals and we're expecting the "cat" process |
| 73 | 74 | # to usually be killed by the kernel. So we have to run it in a sub-shell |
| 74 | 75 | # and silence errors. |
| 75 | 76 | ($SHELL -c 'cat <(echo '"$test"') >'"$TRIGGER" 2>/dev/null) || true |
| 76 | 77 | |
| 77 | 78 | # Record and dump the results |
| 78 | −dmesg -c >"$LOG" | |
| 79 | +dmesg | diff --changed-group-format='%>' --unchanged-group-format='' "$DMESG" - > "$LOG" || true | |
| 80 | + | |
| 79 | 81 | cat "$LOG" |
| 80 | 82 | # Check for expected output |
| 81 | −if egrep -qi "$expect" "$LOG" ; then | |
| 83 | +if grep -E -qi "$expect" "$LOG" ; then | |
| 82 | 84 | echo "$test: saw '$expect': ok" |
| 83 | 85 | exit 0 |
| 84 | 86 | else |
| 85 | − if egrep -qi XFAIL: "$LOG" ; then | |
| 87 | + if grep -E -qi XFAIL: "$LOG" ; then | |
| 86 | 88 | echo "$test: saw 'XFAIL': [SKIP]" |
| 87 | 89 | exit $KSELFTEST_SKIP_TEST |
| 88 | 90 | else |
| @@ -30,7 +30,7 @@ ret=0 · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | cleanup() |
| 32 | 32 | { |
| 33 | − rm -f $out | |
| 33 | + rm -f $err | |
| 34 | 34 | ip netns del $ns1 |
| 35 | 35 | } |
| 36 | 36 | |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #define __stack_aligned__ __attribute__((aligned(16))) |
| 28 | 28 | struct cr_clone_arg { |
| 29 | 29 | char stack[128] __stack_aligned__; |
| 30 | − char stack_ptr[0]; | |
| 30 | + char stack_ptr[]; | |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | 33 | static int child(void *args) |
| @@ -6,6 +6,7 @@ map_populate · 5 unmodified lines | ||
| 6 | 6 | thuge-gen |
| 7 | 7 | compaction_test |
| 8 | 8 | mlock2-tests |
| 9 | +mremap_dontunmap | |
| 9 | 10 | on-fault-limit |
| 10 | 11 | transhuge-stress |
| 11 | 12 | userfaultfd |
| @@ -74,8 +74,6 @@ int main(int argc, char **argv) · 73 unmodified lines | ||
| 74 | 74 | int write = 0; |
| 75 | 75 | int reserve = 1; |
| 76 | 76 | |
| 77 | − unsigned long i; | |
| 78 | − | |
| 79 | 77 | if (signal(SIGINT, sig_handler) == SIG_ERR) |
| 80 | 78 | err(1, "\ncan't catch SIGINT\n"); |
| 81 | 79 | |
| @@ -44,7 +44,7 @@ endef · 43 unmodified lines | ||
| 44 | 44 | $(eval $(call tar_download,MUSL,musl,1.2.0,.tar.gz,https://musl.libc.org/releases/,c6de7b191139142d3f9a7b5b702c9cae1b5ee6e7f57e582da9328629408fd4e8)) |
| 45 | 45 | $(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c)) |
| 46 | 46 | $(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d)) |
| 47 | −$(eval $(call tar_download,IPROUTE2,iproute2,5.4.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,fe97aa60a0d4c5ac830be18937e18dc3400ca713a33a89ad896ff1e3d46086ae)) | |
| 47 | +$(eval $(call tar_download,IPROUTE2,iproute2,5.6.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,1b5b0e25ce6e23da7526ea1da044e814ad85ba761b10dd29c2b027c056b04692)) | |
| 48 | 48 | $(eval $(call tar_download,IPTABLES,iptables,1.8.4,.tar.bz2,https://www.netfilter.org/projects/iptables/files/,993a3a5490a544c2cbf2ef15cf7e7ed21af1845baf228318d5c36ef8827e157c)) |
| 49 | 49 | $(eval $(call tar_download,NMAP,nmap,7.80,.tar.bz2,https://nmap.org/dist/,fcfa5a0e42099e12e4bf7a68ebe6fde05553383a682e816a7ec9256ab4773faa)) |
| 50 | 50 | $(eval $(call tar_download,IPUTILS,iputils,s20190709,.tar.gz,https://github.com/iputils/iputils/archive/s20190709.tar.gz/#,a15720dd741d7538dd2645f9f516d193636ae4300ff7dbc8bfca757bf166490a)) |
| @@ -259,6 +259,7 @@ static inline bool kvm_kick_many_cpus(const struct cpumask *cpus, bool wait) · 258 unmodified lines | ||
| 259 | 259 | } |
| 260 | 260 | |
| 261 | 261 | bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, |
| 262 | + struct kvm_vcpu *except, | |
| 262 | 263 | unsigned long *vcpu_bitmap, cpumask_var_t tmp) |
| 263 | 264 | { |
| 264 | 265 | int i, cpu, me; |
| @@ -268,7 +269,8 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, · 3 unmodified lines | ||
| 268 | 269 | me = get_cpu(); |
| 269 | 270 | |
| 270 | 271 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 271 | − if (vcpu_bitmap && !test_bit(i, vcpu_bitmap)) | |
| 272 | + if ((vcpu_bitmap && !test_bit(i, vcpu_bitmap)) || | |
| 273 | + vcpu == except) | |
| 272 | 274 | continue; |
| 273 | 275 | |
| 274 | 276 | kvm_make_request(req, vcpu); |
| @@ -288,19 +290,25 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, · 13 unmodified lines | ||
| 288 | 290 | return called; |
| 289 | 291 | } |
| 290 | 292 | |
| 291 | −bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) | |
| 293 | +bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, | |
| 294 | + struct kvm_vcpu *except) | |
| 292 | 295 | { |
| 293 | 296 | cpumask_var_t cpus; |
| 294 | 297 | bool called; |
| 295 | 298 | |
| 296 | 299 | zalloc_cpumask_var(&cpus, GFP_ATOMIC); |
| 297 | 300 | |
| 298 | − called = kvm_make_vcpus_request_mask(kvm, req, NULL, cpus); | |
| 301 | + called = kvm_make_vcpus_request_mask(kvm, req, except, NULL, cpus); | |
| 299 | 302 | |
| 300 | 303 | free_cpumask_var(cpus); |
| 301 | 304 | return called; |
| 302 | 305 | } |
| 303 | 306 | |
| 307 | +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) | |
| 308 | +{ | |
| 309 | + return kvm_make_all_cpus_request_except(kvm, req, NULL); | |
| 310 | +} | |
| 311 | + | |
| 304 | 312 | #ifndef CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL |
| 305 | 313 | void kvm_flush_remote_tlbs(struct kvm *kvm) |
| 306 | 314 | { |