Linux 5.7-rc4
Unified · Split
| @@ -182,12 +182,15 @@ fix_padding · 181 unmodified lines | ||
| 182 | 182 | space-efficient. If this option is not present, large padding is |
| 183 | 183 | used - that is for compatibility with older kernels. |
| 184 | 184 | |
| 185 | − | |
| 186 | −The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can | |
| 187 | −be changed when reloading the target (load an inactive table and swap the | |
| 188 | −tables with suspend and resume). The other arguments should not be changed | |
| 189 | −when reloading the target because the layout of disk data depend on them | |
| 190 | −and the reloaded target would be non-functional. | |
| 185 | +allow_discards | |
| 186 | + Allow block discard requests (a.k.a. TRIM) for the integrity device. | |
| 187 | + Discards are only allowed to devices using internal hash. | |
| 188 | + | |
| 189 | +The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and | |
| 190 | +allow_discards can be changed when reloading the target (load an inactive | |
| 191 | +table and swap the tables with suspend and resume). The other arguments | |
| 192 | +should not be changed when reloading the target because the layout of disk | |
| 193 | +data depend on them and the reloaded target would be non-functional. | |
| 191 | 194 | |
| 192 | 195 | |
| 193 | 196 | The layout of the formatted block device: |
| @@ -22,9 +22,7 @@ properties: · 21 unmodified lines | ||
| 22 | 22 | const: socionext,uniphier-xdmac |
| 23 | 23 | |
| 24 | 24 | reg: |
| 25 | − items: | |
| 26 | − - description: XDMAC base register region (offset and length) | |
| 27 | − - description: XDMAC extension register region (offset and length) | |
| 25 | + maxItems: 1 | |
| 28 | 26 | |
| 29 | 27 | interrupts: |
| 30 | 28 | maxItems: 1 |
| @@ -49,12 +47,13 @@ required: · 18 unmodified lines | ||
| 49 | 47 | - reg |
| 50 | 48 | - interrupts |
| 51 | 49 | - "#dma-cells" |
| 50 | + - dma-channels | |
| 52 | 51 | |
| 53 | 52 | examples: |
| 54 | 53 | - | |
| 55 | 54 | xdmac: dma-controller@5fc10000 { |
| 56 | 55 | compatible = "socionext,uniphier-xdmac"; |
| 57 | − reg = <0x5fc10000 0x1000>, <0x5fc20000 0x800>; | |
| 56 | + reg = <0x5fc10000 0x5300>; | |
| 58 | 57 | interrupts = <0 188 4>; |
| 59 | 58 | #dma-cells = <2>; |
| 60 | 59 | dma-channels = <16>; |
| @@ -3657,7 +3657,7 @@ L: linux-btrfs@vger.kernel.org · 3656 unmodified lines | ||
| 3657 | 3657 | S: Maintained |
| 3658 | 3658 | W: http://btrfs.wiki.kernel.org/ |
| 3659 | 3659 | Q: http://patchwork.kernel.org/project/linux-btrfs/list/ |
| 3660 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git | |
| 3660 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git | |
| 3661 | 3661 | F: Documentation/filesystems/btrfs.rst |
| 3662 | 3662 | F: fs/btrfs/ |
| 3663 | 3663 | F: include/linux/btrfs* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 7 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -32,7 +32,7 @@ UBSAN_SANITIZE := n · 31 unmodified lines | ||
| 32 | 32 | OBJECT_FILES_NON_STANDARD := y |
| 33 | 33 | KCOV_INSTRUMENT := n |
| 34 | 34 | |
| 35 | −CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny | |
| 35 | +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -fasynchronous-unwind-tables | |
| 36 | 36 | |
| 37 | 37 | ifneq ($(c-gettimeofday-y),) |
| 38 | 38 | CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) |
| @@ -60,7 +60,7 @@ config RISCV · 59 unmodified lines | ||
| 60 | 60 | select ARCH_HAS_GIGANTIC_PAGE |
| 61 | 61 | select ARCH_HAS_SET_DIRECT_MAP |
| 62 | 62 | select ARCH_HAS_SET_MEMORY |
| 63 | − select ARCH_HAS_STRICT_KERNEL_RWX | |
| 63 | + select ARCH_HAS_STRICT_KERNEL_RWX if MMU | |
| 64 | 64 | select ARCH_WANT_HUGE_PMD_SHARE if 64BIT |
| 65 | 65 | select SPARSEMEM_STATIC if 32BIT |
| 66 | 66 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU |
| @@ -102,7 +102,7 @@ void sbi_shutdown(void) · 101 unmodified lines | ||
| 102 | 102 | { |
| 103 | 103 | sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); |
| 104 | 104 | } |
| 105 | −EXPORT_SYMBOL(sbi_set_timer); | |
| 105 | +EXPORT_SYMBOL(sbi_shutdown); | |
| 106 | 106 | |
| 107 | 107 | /** |
| 108 | 108 | * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. |
| @@ -113,7 +113,7 @@ void sbi_clear_ipi(void) · 4 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0); |
| 115 | 115 | } |
| 116 | −EXPORT_SYMBOL(sbi_shutdown); | |
| 116 | +EXPORT_SYMBOL(sbi_clear_ipi); | |
| 117 | 117 | |
| 118 | 118 | /** |
| 119 | 119 | * sbi_set_timer_v01() - Program the timer for next timer event. |
| @@ -167,6 +167,11 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 47 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | return result; |
| 169 | 169 | } |
| 170 | + | |
| 171 | +static void sbi_set_power_off(void) | |
| 172 | +{ | |
| 173 | + pm_power_off = sbi_shutdown; | |
| 174 | +} | |
| 170 | 175 | #else |
| 171 | 176 | static void __sbi_set_timer_v01(uint64_t stime_value) |
| 172 | 177 | { |
| @@ -191,6 +196,8 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 18 unmodified lines | ||
| 191 | 196 | |
| 192 | 197 | return 0; |
| 193 | 198 | } |
| 199 | + | |
| 200 | +static void sbi_set_power_off(void) {} | |
| 194 | 201 | #endif /* CONFIG_RISCV_SBI_V01 */ |
| 195 | 202 | |
| 196 | 203 | static void __sbi_set_timer_v02(uint64_t stime_value) |
| @@ -540,16 +547,12 @@ static inline long sbi_get_firmware_version(void) · 343 unmodified lines | ||
| 540 | 547 | return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); |
| 541 | 548 | } |
| 542 | 549 | |
| 543 | −static void sbi_power_off(void) | |
| 544 | −{ | |
| 545 | − sbi_shutdown(); | |
| 546 | −} | |
| 547 | 550 | |
| 548 | 551 | int __init sbi_init(void) |
| 549 | 552 | { |
| 550 | 553 | int ret; |
| 551 | 554 | |
| 552 | − pm_power_off = sbi_power_off; | |
| 555 | + sbi_set_power_off(); | |
| 553 | 556 | ret = sbi_get_spec_version(); |
| 554 | 557 | if (ret > 0) |
| 555 | 558 | sbi_spec_version = ret; |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/stacktrace.h> |
| 13 | 13 | #include <linux/ftrace.h> |
| 14 | 14 | |
| 15 | +register unsigned long sp_in_global __asm__("sp"); | |
| 16 | + | |
| 15 | 17 | #ifdef CONFIG_FRAME_POINTER |
| 16 | 18 | |
| 17 | 19 | struct stackframe { |
| @@ -19,8 +21,6 @@ struct stackframe { · 1 unmodified line | ||
| 19 | 21 | unsigned long ra; |
| 20 | 22 | }; |
| 21 | 23 | |
| 22 | −register unsigned long sp_in_global __asm__("sp"); | |
| 23 | − | |
| 24 | 24 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, |
| 25 | 25 | bool (*fn)(unsigned long, void *), void *arg) |
| 26 | 26 | { |
| @@ -33,15 +33,15 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE · 32 unmodified lines | ||
| 33 | 33 | $(call if_changed,vdsold) |
| 34 | 34 | |
| 35 | 35 | # We also create a special relocatable object that should mirror the symbol |
| 36 | −# table and layout of the linked DSO. With ld -R we can then refer to | |
| 37 | −# these symbols in the kernel code rather than hand-coded addresses. | |
| 36 | +# table and layout of the linked DSO. With ld --just-symbols we can then | |
| 37 | +# refer to these symbols in the kernel code rather than hand-coded addresses. | |
| 38 | 38 | |
| 39 | 39 | SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ |
| 40 | 40 | -Wl,--build-id -Wl,--hash-style=both |
| 41 | 41 | $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE |
| 42 | 42 | $(call if_changed,vdsold) |
| 43 | 43 | |
| 44 | −LDFLAGS_vdso-syms.o := -r -R | |
| 44 | +LDFLAGS_vdso-syms.o := -r --just-symbols | |
| 45 | 45 | $(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE |
| 46 | 46 | $(call if_changed,ld) |
| 47 | 47 | |
| @@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void) · 63 unmodified lines | ||
| 64 | 64 | { |
| 65 | 65 | mm_segment_t old_fs; |
| 66 | 66 | unsigned long asce, cr; |
| 67 | + unsigned long flags; | |
| 67 | 68 | |
| 68 | 69 | old_fs = current->thread.mm_segment; |
| 69 | 70 | if (old_fs & 1) |
| 70 | 71 | return old_fs; |
| 72 | + /* protect against a concurrent page table upgrade */ | |
| 73 | + local_irq_save(flags); | |
| 71 | 74 | current->thread.mm_segment |= 1; |
| 72 | 75 | asce = S390_lowcore.kernel_asce; |
| 73 | 76 | if (likely(old_fs == USER_DS)) { |
| @@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void) · 9 unmodified lines | ||
| 83 | 86 | __ctl_load(asce, 7, 7); |
| 84 | 87 | set_cpu_flag(CIF_ASCE_SECONDARY); |
| 85 | 88 | } |
| 89 | + local_irq_restore(flags); | |
| 86 | 90 | return old_fs; |
| 87 | 91 | } |
| 88 | 92 | EXPORT_SYMBOL(enable_sacf_uaccess); |
| @@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg) · 69 unmodified lines | ||
| 70 | 70 | { |
| 71 | 71 | struct mm_struct *mm = arg; |
| 72 | 72 | |
| 73 | − if (current->active_mm == mm) | |
| 74 | − set_user_asce(mm); | |
| 73 | + /* we must change all active ASCEs to avoid the creation of new TLBs */ | |
| 74 | + if (current->active_mm == mm) { | |
| 75 | + S390_lowcore.user_asce = mm->context.asce; | |
| 76 | + if (current->thread.mm_segment == USER_DS) { | |
| 77 | + __ctl_load(S390_lowcore.user_asce, 1, 1); | |
| 78 | + /* Mark user-ASCE present in CR1 */ | |
| 79 | + clear_cpu_flag(CIF_ASCE_PRIMARY); | |
| 80 | + } | |
| 81 | + if (current->thread.mm_segment == USER_DS_SACF) { | |
| 82 | + __ctl_load(S390_lowcore.user_asce, 7, 7); | |
| 83 | + /* enable_sacf_uaccess does all or nothing */ | |
| 84 | + WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY)); | |
| 85 | + } | |
| 86 | + } | |
| 75 | 87 | __tlb_flush_local(); |
| 76 | 88 | } |
| 77 | 89 | |
| @@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu) · 72 unmodified lines | ||
| 73 | 73 | struct page *pg; |
| 74 | 74 | |
| 75 | 75 | input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | − pg = alloc_page(GFP_KERNEL); | |
| 76 | + /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ | |
| 77 | + pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); | |
| 77 | 78 | if (unlikely(!pg)) |
| 78 | 79 | return -ENOMEM; |
| 79 | 80 | *input_arg = page_address(pg); |
| @@ -254,6 +255,7 @@ static int __init hv_pci_init(void) · 174 unmodified lines | ||
| 254 | 255 | static int hv_suspend(void) |
| 255 | 256 | { |
| 256 | 257 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 258 | + int ret; | |
| 257 | 259 | |
| 258 | 260 | /* |
| 259 | 261 | * Reset the hypercall page as it is going to be invalidated |
| @@ -270,12 +272,17 @@ static int hv_suspend(void) · 10 unmodified lines | ||
| 270 | 272 | hypercall_msr.enable = 0; |
| 271 | 273 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 272 | 274 | |
| 273 | − return 0; | |
| 275 | + ret = hv_cpu_die(0); | |
| 276 | + return ret; | |
| 274 | 277 | } |
| 275 | 278 | |
| 276 | 279 | static void hv_resume(void) |
| 277 | 280 | { |
| 278 | 281 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 282 | + int ret; | |
| 283 | + | |
| 284 | + ret = hv_cpu_init(0); | |
| 285 | + WARN_ON(ret); | |
| 279 | 286 | |
| 280 | 287 | /* Re-enable the hypercall page */ |
| 281 | 288 | rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| @@ -288,6 +295,7 @@ static void hv_resume(void) · 6 unmodified lines | ||
| 288 | 295 | hv_hypercall_pg_saved = NULL; |
| 289 | 296 | } |
| 290 | 297 | |
| 298 | +/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ | |
| 291 | 299 | static struct syscore_ops hv_syscore_ops = { |
| 292 | 300 | .suspend = hv_suspend, |
| 293 | 301 | .resume = hv_resume, |
| @@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)( · 34 unmodified lines | ||
| 35 | 35 | rdmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 36 | 36 | #define hv_set_synint_state(int_num, val) \ |
| 37 | 37 | wrmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 38 | +#define hv_recommend_using_aeoi() \ | |
| 39 | + (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)) | |
| 38 | 40 | |
| 39 | 41 | #define hv_get_crash_ctl(val) \ |
| 40 | 42 | rdmsrl(HV_X64_MSR_CRASH_CTL, val) |
| @@ -496,7 +496,7 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) · 495 unmodified lines | ||
| 496 | 496 | |
| 497 | 497 | if (!disk_part_scan_enabled(disk)) |
| 498 | 498 | return 0; |
| 499 | − if (bdev->bd_part_count || bdev->bd_openers > 1) | |
| 499 | + if (bdev->bd_part_count) | |
| 500 | 500 | return -EBUSY; |
| 501 | 501 | res = invalidate_partition(disk, 0); |
| 502 | 502 | if (res) |
| @@ -273,13 +273,13 @@ int acpi_device_set_power(struct acpi_device *device, int state) · 272 unmodified lines | ||
| 273 | 273 | end: |
| 274 | 274 | if (result) { |
| 275 | 275 | dev_warn(&device->dev, "Failed to change power state to %s\n", |
| 276 | − acpi_power_state_string(state)); | |
| 276 | + acpi_power_state_string(target_state)); | |
| 277 | 277 | } else { |
| 278 | 278 | device->power.state = target_state; |
| 279 | 279 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 280 | 280 | "Device [%s] transitioned to %s\n", |
| 281 | 281 | device->pnp.bus_id, |
| 282 | − acpi_power_state_string(state))); | |
| 282 | + acpi_power_state_string(target_state))); | |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | return result; |
| @@ -1059,7 +1059,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, · 1058 unmodified lines | ||
| 1059 | 1059 | |
| 1060 | 1060 | update_turbo_state(); |
| 1061 | 1061 | if (global.turbo_disabled) { |
| 1062 | − pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); | |
| 1062 | + pr_notice_once("Turbo disabled by BIOS or unavailable on processor\n"); | |
| 1063 | 1063 | mutex_unlock(&intel_pstate_limits_lock); |
| 1064 | 1064 | mutex_unlock(&intel_pstate_driver_lock); |
| 1065 | 1065 | return -EPERM; |
| @@ -963,10 +963,12 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 962 unmodified lines | ||
| 963 | 963 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 964 | 964 | struct aead_edesc *edesc; |
| 965 | 965 | int ecode = 0; |
| 966 | + bool has_bklog; | |
| 966 | 967 | |
| 967 | 968 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 968 | 969 | |
| 969 | 970 | edesc = rctx->edesc; |
| 971 | + has_bklog = edesc->bklog; | |
| 970 | 972 | |
| 971 | 973 | if (err) |
| 972 | 974 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -979,7 +981,7 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 6 unmodified lines | ||
| 979 | 981 | * If no backlog flag, the completion of the request is done |
| 980 | 982 | * by CAAM, not crypto engine. |
| 981 | 983 | */ |
| 982 | − if (!edesc->bklog) | |
| 984 | + if (!has_bklog) | |
| 983 | 985 | aead_request_complete(req, ecode); |
| 984 | 986 | else |
| 985 | 987 | crypto_finalize_aead_request(jrp->engine, req, ecode); |
| @@ -995,10 +997,12 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 9 unmodified lines | ||
| 995 | 997 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 996 | 998 | int ivsize = crypto_skcipher_ivsize(skcipher); |
| 997 | 999 | int ecode = 0; |
| 1000 | + bool has_bklog; | |
| 998 | 1001 | |
| 999 | 1002 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 1000 | 1003 | |
| 1001 | 1004 | edesc = rctx->edesc; |
| 1005 | + has_bklog = edesc->bklog; | |
| 1002 | 1006 | if (err) |
| 1003 | 1007 | ecode = caam_jr_strstatus(jrdev, err); |
| 1004 | 1008 | |
| @@ -1028,7 +1032,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 23 unmodified lines | ||
| 1028 | 1032 | * If no backlog flag, the completion of the request is done |
| 1029 | 1033 | * by CAAM, not crypto engine. |
| 1030 | 1034 | */ |
| 1031 | − if (!edesc->bklog) | |
| 1035 | + if (!has_bklog) | |
| 1032 | 1036 | skcipher_request_complete(req, ecode); |
| 1033 | 1037 | else |
| 1034 | 1038 | crypto_finalize_skcipher_request(jrp->engine, req, ecode); |
| @@ -1711,7 +1715,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, · 676 unmodified lines | ||
| 1711 | 1715 | |
| 1712 | 1716 | if (ivsize || mapped_dst_nents > 1) |
| 1713 | 1717 | sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx + |
| 1714 | − mapped_dst_nents); | |
| 1718 | + mapped_dst_nents - 1 + !!ivsize); | |
| 1715 | 1719 | |
| 1716 | 1720 | if (sec4_sg_bytes) { |
| 1717 | 1721 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, |
| @@ -583,10 +583,12 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 582 unmodified lines | ||
| 583 | 583 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 584 | 584 | struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); |
| 585 | 585 | int ecode = 0; |
| 586 | + bool has_bklog; | |
| 586 | 587 | |
| 587 | 588 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 588 | 589 | |
| 589 | 590 | edesc = state->edesc; |
| 591 | + has_bklog = edesc->bklog; | |
| 590 | 592 | |
| 591 | 593 | if (err) |
| 592 | 594 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -603,7 +605,7 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 10 unmodified lines | ||
| 603 | 605 | * If no backlog flag, the completion of the request is done |
| 604 | 606 | * by CAAM, not crypto engine. |
| 605 | 607 | */ |
| 606 | − if (!edesc->bklog) | |
| 608 | + if (!has_bklog) | |
| 607 | 609 | req->base.complete(&req->base, ecode); |
| 608 | 610 | else |
| 609 | 611 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -632,10 +634,12 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 22 unmodified lines | ||
| 632 | 634 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 633 | 635 | int digestsize = crypto_ahash_digestsize(ahash); |
| 634 | 636 | int ecode = 0; |
| 637 | + bool has_bklog; | |
| 635 | 638 | |
| 636 | 639 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 637 | 640 | |
| 638 | 641 | edesc = state->edesc; |
| 642 | + has_bklog = edesc->bklog; | |
| 639 | 643 | if (err) |
| 640 | 644 | ecode = caam_jr_strstatus(jrdev, err); |
| 641 | 645 | |
| @@ -663,7 +667,7 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 21 unmodified lines | ||
| 663 | 667 | * If no backlog flag, the completion of the request is done |
| 664 | 668 | * by CAAM, not crypto engine. |
| 665 | 669 | */ |
| 666 | − if (!edesc->bklog) | |
| 670 | + if (!has_bklog) | |
| 667 | 671 | req->base.complete(&req->base, ecode); |
| 668 | 672 | else |
| 669 | 673 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -121,11 +121,13 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 120 unmodified lines | ||
| 121 | 121 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); |
| 122 | 122 | struct rsa_edesc *edesc; |
| 123 | 123 | int ecode = 0; |
| 124 | + bool has_bklog; | |
| 124 | 125 | |
| 125 | 126 | if (err) |
| 126 | 127 | ecode = caam_jr_strstatus(dev, err); |
| 127 | 128 | |
| 128 | 129 | edesc = req_ctx->edesc; |
| 130 | + has_bklog = edesc->bklog; | |
| 129 | 131 | |
| 130 | 132 | rsa_pub_unmap(dev, edesc, req); |
| 131 | 133 | rsa_io_unmap(dev, edesc, req); |
| @@ -135,7 +137,7 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 3 unmodified lines | ||
| 135 | 137 | * If no backlog flag, the completion of the request is done |
| 136 | 138 | * by CAAM, not crypto engine. |
| 137 | 139 | */ |
| 138 | − if (!edesc->bklog) | |
| 140 | + if (!has_bklog) | |
| 139 | 141 | akcipher_request_complete(req, ecode); |
| 140 | 142 | else |
| 141 | 143 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -152,11 +154,13 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 10 unmodified lines | ||
| 152 | 154 | struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); |
| 153 | 155 | struct rsa_edesc *edesc; |
| 154 | 156 | int ecode = 0; |
| 157 | + bool has_bklog; | |
| 155 | 158 | |
| 156 | 159 | if (err) |
| 157 | 160 | ecode = caam_jr_strstatus(dev, err); |
| 158 | 161 | |
| 159 | 162 | edesc = req_ctx->edesc; |
| 163 | + has_bklog = edesc->bklog; | |
| 160 | 164 | |
| 161 | 165 | switch (key->priv_form) { |
| 162 | 166 | case FORM1: |
| @@ -176,7 +180,7 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 13 unmodified lines | ||
| 176 | 180 | * If no backlog flag, the completion of the request is done |
| 177 | 181 | * by CAAM, not crypto engine. |
| 178 | 182 | */ |
| 179 | − if (!edesc->bklog) | |
| 183 | + if (!has_bklog) | |
| 180 | 184 | akcipher_request_complete(req, ecode); |
| 181 | 185 | else |
| 182 | 186 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *file, · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | return ret; |
| 390 | 390 | |
| 391 | − case DMA_BUF_SET_NAME: | |
| 391 | + case DMA_BUF_SET_NAME_A: | |
| 392 | + case DMA_BUF_SET_NAME_B: | |
| 392 | 393 | return dma_buf_set_name(dmabuf, (const char __user *)arg); |
| 393 | 394 | |
| 394 | 395 | default: |
| @@ -655,8 +656,8 @@ EXPORT_SYMBOL_GPL(dma_buf_put); · 260 unmodified lines | ||
| 655 | 656 | * calls attach() of dma_buf_ops to allow device-specific attach functionality |
| 656 | 657 | * @dmabuf: [in] buffer to attach device to. |
| 657 | 658 | * @dev: [in] device to be attached. |
| 658 | − * @importer_ops [in] importer operations for the attachment | |
| 659 | − * @importer_priv [in] importer private pointer for the attachment | |
| 659 | + * @importer_ops: [in] importer operations for the attachment | |
| 660 | + * @importer_priv: [in] importer private pointer for the attachment | |
| 660 | 661 | * |
| 661 | 662 | * Returns struct dma_buf_attachment pointer for this attachment. Attachments |
| 662 | 663 | * must be cleaned up by calling dma_buf_detach(). |
| @@ -241,7 +241,8 @@ config FSL_RAID · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | config HISI_DMA |
| 243 | 243 | tristate "HiSilicon DMA Engine support" |
| 244 | − depends on ARM64 || (COMPILE_TEST && PCI_MSI) | |
| 244 | + depends on ARM64 || COMPILE_TEST | |
| 245 | + depends on PCI_MSI | |
| 245 | 246 | select DMA_ENGINE |
| 246 | 247 | select DMA_VIRTUAL_CHANNELS |
| 247 | 248 | help |
| @@ -232,10 +232,6 @@ static void chan_dev_release(struct device *dev) · 231 unmodified lines | ||
| 232 | 232 | struct dma_chan_dev *chan_dev; |
| 233 | 233 | |
| 234 | 234 | chan_dev = container_of(dev, typeof(*chan_dev), device); |
| 235 | − if (atomic_dec_and_test(chan_dev->idr_ref)) { | |
| 236 | − ida_free(&dma_ida, chan_dev->dev_id); | |
| 237 | − kfree(chan_dev->idr_ref); | |
| 238 | − } | |
| 239 | 235 | kfree(chan_dev); |
| 240 | 236 | } |
| 241 | 237 | |
| @@ -1043,27 +1039,9 @@ static int get_dma_id(struct dma_device *device) · 801 unmodified lines | ||
| 1043 | 1039 | } |
| 1044 | 1040 | |
| 1045 | 1041 | static int __dma_async_device_channel_register(struct dma_device *device, |
| 1046 | − struct dma_chan *chan, | |
| 1047 | − int chan_id) | |
| 1042 | + struct dma_chan *chan) | |
| 1048 | 1043 | { |
| 1049 | 1044 | int rc = 0; |
| 1050 | − int chancnt = device->chancnt; | |
| 1051 | − atomic_t *idr_ref; | |
| 1052 | − struct dma_chan *tchan; | |
| 1053 | − | |
| 1054 | − tchan = list_first_entry_or_null(&device->channels, | |
| 1055 | − struct dma_chan, device_node); | |
| 1056 | − if (!tchan) | |
| 1057 | − return -ENODEV; | |
| 1058 | − | |
| 1059 | − if (tchan->dev) { | |
| 1060 | − idr_ref = tchan->dev->idr_ref; | |
| 1061 | − } else { | |
| 1062 | − idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL); | |
| 1063 | − if (!idr_ref) | |
| 1064 | − return -ENOMEM; | |
| 1065 | − atomic_set(idr_ref, 0); | |
| 1066 | − } | |
| 1067 | 1045 | |
| 1068 | 1046 | chan->local = alloc_percpu(typeof(*chan->local)); |
| 1069 | 1047 | if (!chan->local) |
| @@ -1079,29 +1057,36 @@ static int __dma_async_device_channel_register(struct dma_device *device, · 9 unmodified lines | ||
| 1079 | 1057 | * When the chan_id is a negative value, we are dynamically adding |
| 1080 | 1058 | * the channel. Otherwise we are static enumerating. |
| 1081 | 1059 | */ |
| 1082 | − chan->chan_id = chan_id < 0 ? chancnt : chan_id; | |
| 1060 | + mutex_lock(&device->chan_mutex); | |
| 1061 | + chan->chan_id = ida_alloc(&device->chan_ida, GFP_KERNEL); | |
| 1062 | + mutex_unlock(&device->chan_mutex); | |
| 1063 | + if (chan->chan_id < 0) { | |
| 1064 | + pr_err("%s: unable to alloc ida for chan: %d\n", | |
| 1065 | + __func__, chan->chan_id); | |
| 1066 | + goto err_out; | |
| 1067 | + } | |
| 1068 | + | |
| 1083 | 1069 | chan->dev->device.class = &dma_devclass; |
| 1084 | 1070 | chan->dev->device.parent = device->dev; |
| 1085 | 1071 | chan->dev->chan = chan; |
| 1086 | − chan->dev->idr_ref = idr_ref; | |
| 1087 | 1072 | chan->dev->dev_id = device->dev_id; |
| 1088 | − atomic_inc(idr_ref); | |
| 1089 | 1073 | dev_set_name(&chan->dev->device, "dma%dchan%d", |
| 1090 | 1074 | device->dev_id, chan->chan_id); |
| 1091 | − | |
| 1092 | 1075 | rc = device_register(&chan->dev->device); |
| 1093 | 1076 | if (rc) |
| 1094 | − goto err_out; | |
| 1077 | + goto err_out_ida; | |
| 1095 | 1078 | chan->client_count = 0; |
| 1096 | − device->chancnt = chan->chan_id + 1; | |
| 1079 | + device->chancnt++; | |
| 1097 | 1080 | |
| 1098 | 1081 | return 0; |
| 1099 | 1082 | |
| 1083 | + err_out_ida: | |
| 1084 | + mutex_lock(&device->chan_mutex); | |
| 1085 | + ida_free(&device->chan_ida, chan->chan_id); | |
| 1086 | + mutex_unlock(&device->chan_mutex); | |
| 1100 | 1087 | err_out: |
| 1101 | 1088 | free_percpu(chan->local); |
| 1102 | 1089 | kfree(chan->dev); |
| 1103 | − if (atomic_dec_return(idr_ref) == 0) | |
| 1104 | − kfree(idr_ref); | |
| 1105 | 1090 | return rc; |
| 1106 | 1091 | } |
| 1107 | 1092 | |
| @@ -1110,7 +1095,7 @@ int dma_async_device_channel_register(struct dma_device *device, · 2 unmodified lines | ||
| 1110 | 1095 | { |
| 1111 | 1096 | int rc; |
| 1112 | 1097 | |
| 1113 | − rc = __dma_async_device_channel_register(device, chan, -1); | |
| 1098 | + rc = __dma_async_device_channel_register(device, chan); | |
| 1114 | 1099 | if (rc < 0) |
| 1115 | 1100 | return rc; |
| 1116 | 1101 | |
| @@ -1130,6 +1115,9 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, · 13 unmodified lines | ||
| 1130 | 1115 | device->chancnt--; |
| 1131 | 1116 | chan->dev->chan = NULL; |
| 1132 | 1117 | mutex_unlock(&dma_list_mutex); |
| 1118 | + mutex_lock(&device->chan_mutex); | |
| 1119 | + ida_free(&device->chan_ida, chan->chan_id); | |
| 1120 | + mutex_unlock(&device->chan_mutex); | |
| 1133 | 1121 | device_unregister(&chan->dev->device); |
| 1134 | 1122 | free_percpu(chan->local); |
| 1135 | 1123 | } |
| @@ -1152,7 +1140,7 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_unregister); · 16 unmodified lines | ||
| 1152 | 1140 | */ |
| 1153 | 1141 | int dma_async_device_register(struct dma_device *device) |
| 1154 | 1142 | { |
| 1155 | − int rc, i = 0; | |
| 1143 | + int rc; | |
| 1156 | 1144 | struct dma_chan* chan; |
| 1157 | 1145 | |
| 1158 | 1146 | if (!device) |
| @@ -1257,9 +1245,12 @@ int dma_async_device_register(struct dma_device *device) · 98 unmodified lines | ||
| 1257 | 1245 | if (rc != 0) |
| 1258 | 1246 | return rc; |
| 1259 | 1247 | |
| 1248 | + mutex_init(&device->chan_mutex); | |
| 1249 | + ida_init(&device->chan_ida); | |
| 1250 | + | |
| 1260 | 1251 | /* represent channels in sysfs. Probably want devs too */ |
| 1261 | 1252 | list_for_each_entry(chan, &device->channels, device_node) { |
| 1262 | − rc = __dma_async_device_channel_register(device, chan, i++); | |
| 1253 | + rc = __dma_async_device_channel_register(device, chan); | |
| 1263 | 1254 | if (rc < 0) |
| 1264 | 1255 | goto err_out; |
| 1265 | 1256 | } |
| @@ -1334,6 +1325,7 @@ void dma_async_device_unregister(struct dma_device *device) · 68 unmodified lines | ||
| 1334 | 1325 | */ |
| 1335 | 1326 | dma_cap_set(DMA_PRIVATE, device->cap_mask); |
| 1336 | 1327 | dma_channel_rebalance(); |
| 1328 | + ida_free(&dma_ida, device->dev_id); | |
| 1337 | 1329 | dma_device_put(device); |
| 1338 | 1330 | mutex_unlock(&dma_list_mutex); |
| 1339 | 1331 | } |
| @@ -240,7 +240,7 @@ static bool is_threaded_test_run(struct dmatest_info *info) · 239 unmodified lines | ||
| 240 | 240 | struct dmatest_thread *thread; |
| 241 | 241 | |
| 242 | 242 | list_for_each_entry(thread, &dtc->threads, node) { |
| 243 | − if (!thread->done) | |
| 243 | + if (!thread->done && !thread->pending) | |
| 244 | 244 | return true; |
| 245 | 245 | } |
| 246 | 246 | } |
| @@ -662,8 +662,8 @@ static int dmatest_func(void *data) · 415 unmodified lines | ||
| 662 | 662 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
| 663 | 663 | |
| 664 | 664 | ktime = ktime_get(); |
| 665 | − while (!kthread_should_stop() | |
| 666 | − && !(params->iterations && total_tests >= params->iterations)) { | |
| 665 | + while (!(kthread_should_stop() || | |
| 666 | + (params->iterations && total_tests >= params->iterations))) { | |
| 667 | 667 | struct dma_async_tx_descriptor *tx = NULL; |
| 668 | 668 | struct dmaengine_unmap_data *um; |
| 669 | 669 | dma_addr_t *dsts; |
| @@ -363,6 +363,8 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) · 362 unmodified lines | ||
| 363 | 363 | gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, |
| 364 | 364 | size); |
| 365 | 365 | tdmac->desc_arr = NULL; |
| 366 | + if (tdmac->status == DMA_ERROR) | |
| 367 | + tdmac->status = DMA_COMPLETE; | |
| 366 | 368 | |
| 367 | 369 | return; |
| 368 | 370 | } |
| @@ -443,7 +445,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( · 74 unmodified lines | ||
| 443 | 445 | if (!desc) |
| 444 | 446 | goto err_out; |
| 445 | 447 | |
| 446 | − mmp_tdma_config_write(chan, direction, &tdmac->slave_config); | |
| 448 | + if (mmp_tdma_config_write(chan, direction, &tdmac->slave_config)) | |
| 449 | + goto err_out; | |
| 447 | 450 | |
| 448 | 451 | while (buf < buf_len) { |
| 449 | 452 | desc = &tdmac->desc_arr[i]; |
| @@ -865,6 +865,7 @@ static int pch_dma_probe(struct pci_dev *pdev, · 864 unmodified lines | ||
| 865 | 865 | } |
| 866 | 866 | |
| 867 | 867 | pci_set_master(pdev); |
| 868 | + pd->dma.dev = &pdev->dev; | |
| 868 | 869 | |
| 869 | 870 | err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); |
| 870 | 871 | if (err) { |
| @@ -880,7 +881,6 @@ static int pch_dma_probe(struct pci_dev *pdev, · 9 unmodified lines | ||
| 880 | 881 | goto err_free_irq; |
| 881 | 882 | } |
| 882 | 883 | |
| 883 | − pd->dma.dev = &pdev->dev; | |
| 884 | 884 | |
| 885 | 885 | INIT_LIST_HEAD(&pd->dma.channels); |
| 886 | 886 | |
| @@ -816,6 +816,13 @@ static bool tegra_dma_eoc_interrupt_deasserted(struct tegra_dma_channel *tdc) · 815 unmodified lines | ||
| 816 | 816 | static void tegra_dma_synchronize(struct dma_chan *dc) |
| 817 | 817 | { |
| 818 | 818 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
| 819 | + int err; | |
| 820 | + | |
| 821 | + err = pm_runtime_get_sync(tdc->tdma->dev); | |
| 822 | + if (err < 0) { | |
| 823 | + dev_err(tdc2dev(tdc), "Failed to synchronize DMA: %d\n", err); | |
| 824 | + return; | |
| 825 | + } | |
| 819 | 826 | |
| 820 | 827 | /* |
| 821 | 828 | * CPU, which handles interrupt, could be busy in |
| @@ -825,6 +832,8 @@ static void tegra_dma_synchronize(struct dma_chan *dc) · 3 unmodified lines | ||
| 825 | 832 | wait_event(tdc->wq, tegra_dma_eoc_interrupt_deasserted(tdc)); |
| 826 | 833 | |
| 827 | 834 | tasklet_kill(&tdc->tasklet); |
| 835 | + | |
| 836 | + pm_runtime_put(tdc->tdma->dev); | |
| 828 | 837 | } |
| 829 | 838 | |
| 830 | 839 | static unsigned int tegra_dma_sg_bytes_xferred(struct tegra_dma_channel *tdc, |
| @@ -27,6 +27,7 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id) · 26 unmodified lines | ||
| 27 | 27 | soc_ep_map = &j721e_ep_map; |
| 28 | 28 | } else { |
| 29 | 29 | pr_err("PSIL: No compatible machine found for map\n"); |
| 30 | + mutex_unlock(&ep_map_mutex); | |
| 30 | 31 | return ERR_PTR(-ENOTSUPP); |
| 31 | 32 | } |
| 32 | 33 | pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name); |
| @@ -1230,16 +1230,16 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, · 1229 unmodified lines | ||
| 1230 | 1230 | return ret; |
| 1231 | 1231 | |
| 1232 | 1232 | spin_lock_irqsave(&chan->lock, flags); |
| 1233 | − | |
| 1234 | − desc = list_last_entry(&chan->active_list, | |
| 1235 | − struct xilinx_dma_tx_descriptor, node); | |
| 1236 | − /* | |
| 1237 | − * VDMA and simple mode do not support residue reporting, so the | |
| 1238 | − * residue field will always be 0. | |
| 1239 | − */ | |
| 1240 | − if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) | |
| 1241 | − residue = xilinx_dma_get_residue(chan, desc); | |
| 1242 | − | |
| 1233 | + if (!list_empty(&chan->active_list)) { | |
| 1234 | + desc = list_last_entry(&chan->active_list, | |
| 1235 | + struct xilinx_dma_tx_descriptor, node); | |
| 1236 | + /* | |
| 1237 | + * VDMA and simple mode do not support residue reporting, so the | |
| 1238 | + * residue field will always be 0. | |
| 1239 | + */ | |
| 1240 | + if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) | |
| 1241 | + residue = xilinx_dma_get_residue(chan, desc); | |
| 1242 | + } | |
| 1243 | 1243 | spin_unlock_irqrestore(&chan->lock, flags); |
| 1244 | 1244 | |
| 1245 | 1245 | dma_set_residue(txstate, residue); |
| @@ -85,9 +85,10 @@ · 84 unmodified lines | ||
| 85 | 85 | * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches |
| 86 | 86 | * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask |
| 87 | 87 | * - 3.36.0 - Allow reading more status registers on si/cik |
| 88 | + * - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness | |
| 88 | 89 | */ |
| 89 | 90 | #define KMS_DRIVER_MAJOR 3 |
| 90 | −#define KMS_DRIVER_MINOR 36 | |
| 91 | +#define KMS_DRIVER_MINOR 37 | |
| 91 | 92 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 92 | 93 | |
| 93 | 94 | int amdgpu_vram_limit = 0; |
| @@ -73,6 +73,22 @@ · 72 unmodified lines | ||
| 73 | 73 | #define SDMA_OP_AQL_COPY 0 |
| 74 | 74 | #define SDMA_OP_AQL_BARRIER_OR 0 |
| 75 | 75 | |
| 76 | +#define SDMA_GCR_RANGE_IS_PA (1 << 18) | |
| 77 | +#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16) | |
| 78 | +#define SDMA_GCR_GL2_WB (1 << 15) | |
| 79 | +#define SDMA_GCR_GL2_INV (1 << 14) | |
| 80 | +#define SDMA_GCR_GL2_DISCARD (1 << 13) | |
| 81 | +#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11) | |
| 82 | +#define SDMA_GCR_GL2_US (1 << 10) | |
| 83 | +#define SDMA_GCR_GL1_INV (1 << 9) | |
| 84 | +#define SDMA_GCR_GLV_INV (1 << 8) | |
| 85 | +#define SDMA_GCR_GLK_INV (1 << 7) | |
| 86 | +#define SDMA_GCR_GLK_WB (1 << 6) | |
| 87 | +#define SDMA_GCR_GLM_INV (1 << 5) | |
| 88 | +#define SDMA_GCR_GLM_WB (1 << 4) | |
| 89 | +#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2) | |
| 90 | +#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0) | |
| 91 | + | |
| 76 | 92 | /*define for op field*/ |
| 77 | 93 | #define SDMA_PKT_HEADER_op_offset 0 |
| 78 | 94 | #define SDMA_PKT_HEADER_op_mask 0x000000FF |
| @@ -382,6 +382,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring, · 381 unmodified lines | ||
| 382 | 382 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); |
| 383 | 383 | uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); |
| 384 | 384 | |
| 385 | + /* Invalidate L2, because if we don't do it, we might get stale cache | |
| 386 | + * lines from previous IBs. | |
| 387 | + */ | |
| 388 | + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ)); | |
| 389 | + amdgpu_ring_write(ring, 0); | |
| 390 | + amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV | | |
| 391 | + SDMA_GCR_GL2_WB | | |
| 392 | + SDMA_GCR_GLM_INV | | |
| 393 | + SDMA_GCR_GLM_WB) << 16); | |
| 394 | + amdgpu_ring_write(ring, 0xffffff80); | |
| 395 | + amdgpu_ring_write(ring, 0xffff); | |
| 396 | + | |
| 385 | 397 | /* An IB packet must end on a 8 DW boundary--the next dword |
| 386 | 398 | * must be on a 8-dword boundary. Our IB packet below is 6 |
| 387 | 399 | * dwords long, thus add x number of NOPs, such that, in |
| @@ -1595,7 +1607,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = { · 1207 unmodified lines | ||
| 1595 | 1607 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + |
| 1596 | 1608 | SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + |
| 1597 | 1609 | 10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ |
| 1598 | − .emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */ | |
| 1610 | + .emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */ | |
| 1599 | 1611 | .emit_ib = sdma_v5_0_ring_emit_ib, |
| 1600 | 1612 | .emit_fence = sdma_v5_0_ring_emit_fence, |
| 1601 | 1613 | .emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, |
| @@ -3340,7 +3340,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 3339 unmodified lines | ||
| 3340 | 3340 | const union dc_tiling_info *tiling_info, |
| 3341 | 3341 | const uint64_t info, |
| 3342 | 3342 | struct dc_plane_dcc_param *dcc, |
| 3343 | − struct dc_plane_address *address) | |
| 3343 | + struct dc_plane_address *address, | |
| 3344 | + bool force_disable_dcc) | |
| 3344 | 3345 | { |
| 3345 | 3346 | struct dc *dc = adev->dm.dc; |
| 3346 | 3347 | struct dc_dcc_surface_param input; |
| @@ -3352,6 +3353,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 5 unmodified lines | ||
| 3352 | 3353 | memset(&input, 0, sizeof(input)); |
| 3353 | 3354 | memset(&output, 0, sizeof(output)); |
| 3354 | 3355 | |
| 3356 | + if (force_disable_dcc) | |
| 3357 | + return 0; | |
| 3358 | + | |
| 3355 | 3359 | if (!offset) |
| 3356 | 3360 | return 0; |
| 3357 | 3361 | |
| @@ -3401,7 +3405,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 43 unmodified lines | ||
| 3401 | 3405 | union dc_tiling_info *tiling_info, |
| 3402 | 3406 | struct plane_size *plane_size, |
| 3403 | 3407 | struct dc_plane_dcc_param *dcc, |
| 3404 | − struct dc_plane_address *address) | |
| 3408 | + struct dc_plane_address *address, | |
| 3409 | + bool force_disable_dcc) | |
| 3405 | 3410 | { |
| 3406 | 3411 | const struct drm_framebuffer *fb = &afb->base; |
| 3407 | 3412 | int ret; |
| @@ -3507,7 +3512,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 99 unmodified lines | ||
| 3507 | 3512 | |
| 3508 | 3513 | ret = fill_plane_dcc_attributes(adev, afb, format, rotation, |
| 3509 | 3514 | plane_size, tiling_info, |
| 3510 | − tiling_flags, dcc, address); | |
| 3515 | + tiling_flags, dcc, address, | |
| 3516 | + force_disable_dcc); | |
| 3511 | 3517 | if (ret) |
| 3512 | 3518 | return ret; |
| 3513 | 3519 | } |
| @@ -3599,7 +3605,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 85 unmodified lines | ||
| 3599 | 3605 | const struct drm_plane_state *plane_state, |
| 3600 | 3606 | const uint64_t tiling_flags, |
| 3601 | 3607 | struct dc_plane_info *plane_info, |
| 3602 | − struct dc_plane_address *address) | |
| 3608 | + struct dc_plane_address *address, | |
| 3609 | + bool force_disable_dcc) | |
| 3603 | 3610 | { |
| 3604 | 3611 | const struct drm_framebuffer *fb = plane_state->fb; |
| 3605 | 3612 | const struct amdgpu_framebuffer *afb = |
| @@ -3681,7 +3688,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 75 unmodified lines | ||
| 3681 | 3688 | plane_info->rotation, tiling_flags, |
| 3682 | 3689 | &plane_info->tiling_info, |
| 3683 | 3690 | &plane_info->plane_size, |
| 3684 | − &plane_info->dcc, address); | |
| 3691 | + &plane_info->dcc, address, | |
| 3692 | + force_disable_dcc); | |
| 3685 | 3693 | if (ret) |
| 3686 | 3694 | return ret; |
| 3687 | 3695 | |
| @@ -3704,6 +3712,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 16 unmodified lines | ||
| 3704 | 3712 | struct dc_plane_info plane_info; |
| 3705 | 3713 | uint64_t tiling_flags; |
| 3706 | 3714 | int ret; |
| 3715 | + bool force_disable_dcc = false; | |
| 3707 | 3716 | |
| 3708 | 3717 | ret = fill_dc_scaling_info(plane_state, &scaling_info); |
| 3709 | 3718 | if (ret) |
| @@ -3718,9 +3727,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 8 unmodified lines | ||
| 3718 | 3727 | if (ret) |
| 3719 | 3728 | return ret; |
| 3720 | 3729 | |
| 3730 | + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | |
| 3721 | 3731 | ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, |
| 3722 | 3732 | &plane_info, |
| 3723 | − &dc_plane_state->address); | |
| 3733 | + &dc_plane_state->address, | |
| 3734 | + force_disable_dcc); | |
| 3724 | 3735 | if (ret) |
| 3725 | 3736 | return ret; |
| 3726 | 3737 | |
| @@ -5342,6 +5353,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 1615 unmodified lines | ||
| 5342 | 5353 | uint64_t tiling_flags; |
| 5343 | 5354 | uint32_t domain; |
| 5344 | 5355 | int r; |
| 5356 | + bool force_disable_dcc = false; | |
| 5345 | 5357 | |
| 5346 | 5358 | dm_plane_state_old = to_dm_plane_state(plane->state); |
| 5347 | 5359 | dm_plane_state_new = to_dm_plane_state(new_state); |
| @@ -5400,11 +5412,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 52 unmodified lines | ||
| 5400 | 5412 | dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { |
| 5401 | 5413 | struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; |
| 5402 | 5414 | |
| 5415 | + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | |
| 5403 | 5416 | fill_plane_buffer_attributes( |
| 5404 | 5417 | adev, afb, plane_state->format, plane_state->rotation, |
| 5405 | 5418 | tiling_flags, &plane_state->tiling_info, |
| 5406 | 5419 | &plane_state->plane_size, &plane_state->dcc, |
| 5407 | − &plane_state->address); | |
| 5420 | + &plane_state->address, | |
| 5421 | + force_disable_dcc); | |
| 5408 | 5422 | } |
| 5409 | 5423 | |
| 5410 | 5424 | return 0; |
| @@ -6676,7 +6690,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1265 unmodified lines | ||
| 6676 | 6690 | fill_dc_plane_info_and_addr( |
| 6677 | 6691 | dm->adev, new_plane_state, tiling_flags, |
| 6678 | 6692 | &bundle->plane_infos[planes_count], |
| 6679 | − &bundle->flip_addrs[planes_count].address); | |
| 6693 | + &bundle->flip_addrs[planes_count].address, | |
| 6694 | + false); | |
| 6695 | + | |
| 6696 | + DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", | |
| 6697 | + new_plane_state->plane->index, | |
| 6698 | + bundle->plane_infos[planes_count].dcc.enable); | |
| 6680 | 6699 | |
| 6681 | 6700 | bundle->surface_updates[planes_count].plane_info = |
| 6682 | 6701 | &bundle->plane_infos[planes_count]; |
| @@ -8096,7 +8115,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, · 1413 unmodified lines | ||
| 8096 | 8115 | ret = fill_dc_plane_info_and_addr( |
| 8097 | 8116 | dm->adev, new_plane_state, tiling_flags, |
| 8098 | 8117 | plane_info, |
| 8099 | − &flip_addr->address); | |
| 8118 | + &flip_addr->address, | |
| 8119 | + false); | |
| 8100 | 8120 | if (ret) |
| 8101 | 8121 | goto cleanup; |
| 8102 | 8122 | |
| @@ -2908,6 +2908,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 2907 unmodified lines | ||
| 2908 | 2908 | sizeof(hpd_irq_dpcd_data), |
| 2909 | 2909 | "Status: "); |
| 2910 | 2910 | |
| 2911 | + for (i = 0; i < MAX_PIPES; i++) { | |
| 2912 | + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2913 | + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | |
| 2914 | + link->dc->hwss.blank_stream(pipe_ctx); | |
| 2915 | + } | |
| 2916 | + | |
| 2911 | 2917 | for (i = 0; i < MAX_PIPES; i++) { |
| 2912 | 2918 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2913 | 2919 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) |
| @@ -2927,6 +2933,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 13 unmodified lines | ||
| 2927 | 2933 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) |
| 2928 | 2934 | dc_link_reallocate_mst_payload(link); |
| 2929 | 2935 | |
| 2936 | + for (i = 0; i < MAX_PIPES; i++) { | |
| 2937 | + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2938 | + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | |
| 2939 | + link->dc->hwss.unblank_stream(pipe_ctx, &previous_link_settings); | |
| 2940 | + } | |
| 2941 | + | |
| 2930 | 2942 | status = false; |
| 2931 | 2943 | if (out_link_loss) |
| 2932 | 2944 | *out_link_loss = true; |
| @@ -4227,6 +4239,21 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) · 1294 unmodified lines | ||
| 4227 | 4239 | void dpcd_set_source_specific_data(struct dc_link *link) |
| 4228 | 4240 | { |
| 4229 | 4241 | const uint32_t post_oui_delay = 30; // 30ms |
| 4242 | + uint8_t dspc = 0; | |
| 4243 | + enum dc_status ret = DC_ERROR_UNEXPECTED; | |
| 4244 | + | |
| 4245 | + ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc, | |
| 4246 | + sizeof(dspc)); | |
| 4247 | + | |
| 4248 | + if (ret != DC_OK) { | |
| 4249 | + DC_LOG_ERROR("Error in DP aux read transaction," | |
| 4250 | + " not writing source specific data\n"); | |
| 4251 | + return; | |
| 4252 | + } | |
| 4253 | + | |
| 4254 | + /* Return if OUI unsupported */ | |
| 4255 | + if (!(dspc & DP_OUI_SUPPORT)) | |
| 4256 | + return; | |
| 4230 | 4257 | |
| 4231 | 4258 | if (!link->dc->vendor_signature.is_valid) { |
| 4232 | 4259 | struct dpcd_amd_signature amd_signature; |
| @@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status( · 230 unmodified lines | ||
| 231 | 231 | return dc_stream_get_status_from_state(dc->current_state, stream); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | −static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) | |
| 235 | −{ | |
| 236 | −#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 237 | − unsigned int vupdate_line; | |
| 238 | − unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos; | |
| 239 | − struct dc_stream_state *stream = pipe_ctx->stream; | |
| 240 | − unsigned int us_per_line; | |
| 241 | − | |
| 242 | − if (stream->ctx->asic_id.chip_family == FAMILY_RV && | |
| 243 | − ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) { | |
| 244 | − | |
| 245 | − vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); | |
| 246 | − if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) | |
| 247 | − return; | |
| 248 | − | |
| 249 | − if (vpos >= vupdate_line) | |
| 250 | − return; | |
| 251 | − | |
| 252 | − us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz; | |
| 253 | − lines_to_vupdate = vupdate_line - vpos; | |
| 254 | − us_to_vupdate = lines_to_vupdate * us_per_line; | |
| 255 | − | |
| 256 | − /* 70 us is a conservative estimate of cursor update time*/ | |
| 257 | − if (us_to_vupdate < 70) | |
| 258 | − udelay(us_to_vupdate); | |
| 259 | − } | |
| 260 | −#endif | |
| 261 | −} | |
| 262 | 234 | |
| 263 | 235 | /** |
| 264 | 236 | * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address |
| @@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes( · 33 unmodified lines | ||
| 298 | 270 | |
| 299 | 271 | if (!pipe_to_program) { |
| 300 | 272 | pipe_to_program = pipe_ctx; |
| 301 | − | |
| 302 | − delay_cursor_until_vupdate(pipe_ctx, dc); | |
| 303 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | |
| 273 | + dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 304 | 274 | } |
| 305 | 275 | |
| 306 | 276 | dc->hwss.set_cursor_attribute(pipe_ctx); |
| @@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes( · 2 unmodified lines | ||
| 309 | 279 | } |
| 310 | 280 | |
| 311 | 281 | if (pipe_to_program) |
| 312 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | |
| 282 | + dc->hwss.cursor_lock(dc, pipe_to_program, false); | |
| 313 | 283 | |
| 314 | 284 | return true; |
| 315 | 285 | } |
| @@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position( · 33 unmodified lines | ||
| 349 | 319 | |
| 350 | 320 | if (!pipe_to_program) { |
| 351 | 321 | pipe_to_program = pipe_ctx; |
| 352 | − | |
| 353 | − delay_cursor_until_vupdate(pipe_ctx, dc); | |
| 354 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | |
| 322 | + dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 355 | 323 | } |
| 356 | 324 | |
| 357 | 325 | dc->hwss.set_cursor_position(pipe_ctx); |
| 358 | 326 | } |
| 359 | 327 | |
| 360 | 328 | if (pipe_to_program) |
| 361 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | |
| 329 | + dc->hwss.cursor_lock(dc, pipe_to_program, false); | |
| 362 | 330 | |
| 363 | 331 | return true; |
| 364 | 332 | } |
| @@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { · 2756 unmodified lines | ||
| 2757 | 2757 | .disable_plane = dce110_power_down_fe, |
| 2758 | 2758 | .pipe_control_lock = dce_pipe_control_lock, |
| 2759 | 2759 | .interdependent_update_lock = NULL, |
| 2760 | + .cursor_lock = dce_pipe_control_lock, | |
| 2760 | 2761 | .prepare_bandwidth = dce110_prepare_bandwidth, |
| 2761 | 2762 | .optimize_bandwidth = dce110_optimize_bandwidth, |
| 2762 | 2763 | .set_drr = set_drr, |
| @@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock( · 1624 unmodified lines | ||
| 1625 | 1625 | hws->funcs.verify_allow_pstate_change_high(dc); |
| 1626 | 1626 | } |
| 1627 | 1627 | |
| 1628 | +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) | |
| 1629 | +{ | |
| 1630 | + /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ | |
| 1631 | + if (!pipe || pipe->top_pipe) | |
| 1632 | + return; | |
| 1633 | + | |
| 1634 | + dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, | |
| 1635 | + pipe->stream_res.opp->inst, lock); | |
| 1636 | +} | |
| 1637 | + | |
| 1628 | 1638 | static bool wait_for_reset_trigger_to_occur( |
| 1629 | 1639 | struct dc_context *dc_ctx, |
| 1630 | 1640 | struct timing_generator *tg) |
| @@ -49,6 +49,7 @@ void dcn10_pipe_control_lock( · 48 unmodified lines | ||
| 49 | 49 | struct dc *dc, |
| 50 | 50 | struct pipe_ctx *pipe, |
| 51 | 51 | bool lock); |
| 52 | +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock); | |
| 52 | 53 | void dcn10_blank_pixel_data( |
| 53 | 54 | struct dc *dc, |
| 54 | 55 | struct pipe_ctx *pipe_ctx, |
| @@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 49 unmodified lines | ||
| 50 | 50 | .disable_audio_stream = dce110_disable_audio_stream, |
| 51 | 51 | .disable_plane = dcn10_disable_plane, |
| 52 | 52 | .pipe_control_lock = dcn10_pipe_control_lock, |
| 53 | + .cursor_lock = dcn10_cursor_lock, | |
| 53 | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 54 | 55 | .prepare_bandwidth = dcn10_prepare_bandwidth, |
| 55 | 56 | .optimize_bandwidth = dcn10_optimize_bandwidth, |
| @@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane( · 222 unmodified lines | ||
| 223 | 223 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); |
| 224 | 224 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id); |
| 225 | 225 | |
| 226 | + /* Configure VUPDATE lock set for this MPCC to map to the OPP */ | |
| 227 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id); | |
| 228 | + | |
| 226 | 229 | /* update mpc tree mux setting */ |
| 227 | 230 | if (tree->opp_list == insert_above_mpcc) { |
| 228 | 231 | /* insert the toppest mpcc */ |
| @@ -318,6 +321,7 @@ void mpc1_remove_mpcc( · 89 unmodified lines | ||
| 318 | 321 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 319 | 322 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 320 | 323 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 324 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 321 | 325 | |
| 322 | 326 | /* mark this mpcc as not in use */ |
| 323 | 327 | mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); |
| @@ -328,6 +332,7 @@ void mpc1_remove_mpcc( · 4 unmodified lines | ||
| 328 | 332 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 329 | 333 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 330 | 334 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 335 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 331 | 336 | } |
| 332 | 337 | } |
| 333 | 338 | |
| @@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc) · 27 unmodified lines | ||
| 361 | 366 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 362 | 367 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 363 | 368 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 369 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 364 | 370 | |
| 365 | 371 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 366 | 372 | } |
| @@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id) · 14 unmodified lines | ||
| 381 | 387 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 382 | 388 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 383 | 389 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 390 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 384 | 391 | |
| 385 | 392 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 386 | 393 | |
| @@ -453,6 +460,13 @@ void mpc1_read_mpcc_state( · 66 unmodified lines | ||
| 453 | 460 | MPCC_BUSY, &s->busy); |
| 454 | 461 | } |
| 455 | 462 | |
| 463 | +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) | |
| 464 | +{ | |
| 465 | + struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); | |
| 466 | + | |
| 467 | + REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0); | |
| 468 | +} | |
| 469 | + | |
| 456 | 470 | static const struct mpc_funcs dcn10_mpc_funcs = { |
| 457 | 471 | .read_mpcc_state = mpc1_read_mpcc_state, |
| 458 | 472 | .insert_plane = mpc1_insert_plane, |
| @@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = { · 5 unmodified lines | ||
| 464 | 478 | .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, |
| 465 | 479 | .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, |
| 466 | 480 | .update_blending = mpc1_update_blending, |
| 481 | + .cursor_lock = mpc1_cursor_lock, | |
| 467 | 482 | .set_denorm = NULL, |
| 468 | 483 | .set_denorm_clamp = NULL, |
| 469 | 484 | .set_output_csc = NULL, |
| @@ -39,11 +39,12 @@ · 38 unmodified lines | ||
| 39 | 39 | SRII(MPCC_BG_G_Y, MPCC, inst),\ |
| 40 | 40 | SRII(MPCC_BG_R_CR, MPCC, inst),\ |
| 41 | 41 | SRII(MPCC_BG_B_CB, MPCC, inst),\ |
| 42 | − SRII(MPCC_BG_B_CB, MPCC, inst),\ | |
| 43 | − SRII(MPCC_SM_CONTROL, MPCC, inst) | |
| 42 | + SRII(MPCC_SM_CONTROL, MPCC, inst),\ | |
| 43 | + SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) | |
| 44 | 44 | |
| 45 | 45 | #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ |
| 46 | − SRII(MUX, MPC_OUT, inst) | |
| 46 | + SRII(MUX, MPC_OUT, inst),\ | |
| 47 | + VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) | |
| 47 | 48 | |
| 48 | 49 | #define MPC_COMMON_REG_VARIABLE_LIST \ |
| 49 | 50 | uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ |
| @@ -55,7 +56,9 @@ · 5 unmodified lines | ||
| 55 | 56 | uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ |
| 56 | 57 | uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ |
| 57 | 58 | uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ |
| 58 | − uint32_t MUX[MAX_OPP]; | |
| 59 | + uint32_t MUX[MAX_OPP]; \ | |
| 60 | + uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \ | |
| 61 | + uint32_t CUR[MAX_OPP]; | |
| 59 | 62 | |
| 60 | 63 | #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ |
| 61 | 64 | SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ |
| @@ -78,7 +81,8 @@ · 16 unmodified lines | ||
| 78 | 81 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ |
| 79 | 82 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ |
| 80 | 83 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ |
| 81 | − SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) | |
| 84 | + SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ | |
| 85 | + SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh) | |
| 82 | 86 | |
| 83 | 87 | #define MPC_REG_FIELD_LIST(type) \ |
| 84 | 88 | type MPCC_TOP_SEL;\ |
| @@ -101,7 +105,9 @@ · 16 unmodified lines | ||
| 101 | 105 | type MPCC_SM_FIELD_ALT;\ |
| 102 | 106 | type MPCC_SM_FORCE_NEXT_FRAME_POL;\ |
| 103 | 107 | type MPCC_SM_FORCE_NEXT_TOP_POL;\ |
| 104 | − type MPC_OUT_MUX; | |
| 108 | + type MPC_OUT_MUX;\ | |
| 109 | + type MPCC_UPDATE_LOCK_SEL;\ | |
| 110 | + type CUR_VUPDATE_LOCK_SET; | |
| 105 | 111 | |
| 106 | 112 | struct dcn_mpc_registers { |
| 107 | 113 | MPC_COMMON_REG_VARIABLE_LIST |
| @@ -192,4 +198,6 @@ void mpc1_read_mpcc_state( · 84 unmodified lines | ||
| 192 | 198 | int mpcc_inst, |
| 193 | 199 | struct mpcc_state *s); |
| 194 | 200 | |
| 201 | +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock); | |
| 202 | + | |
| 195 | 203 | #endif |
| @@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id { · 180 unmodified lines | ||
| 181 | 181 | .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 182 | 182 | mm ## block ## id ## _ ## reg_name |
| 183 | 183 | |
| 184 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 185 | + .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \ | |
| 186 | + mm ## reg_name ## 0 ## _ ## block ## id | |
| 187 | + | |
| 188 | +/* set field/register/bitfield name */ | |
| 189 | +#define SFRB(field_name, reg_name, bitfield, post_fix)\ | |
| 190 | + .field_name = reg_name ## __ ## bitfield ## post_fix | |
| 191 | + | |
| 184 | 192 | /* NBIO */ |
| 185 | 193 | #define NBIO_BASE_INNER(seg) \ |
| 186 | 194 | NBIF_BASE__INST0_SEG ## seg |
| @@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = { · 232 unmodified lines | ||
| 419 | 427 | }; |
| 420 | 428 | |
| 421 | 429 | static const struct dcn_mpc_shift mpc_shift = { |
| 422 | − MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) | |
| 430 | + MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\ | |
| 431 | + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT) | |
| 423 | 432 | }; |
| 424 | 433 | |
| 425 | 434 | static const struct dcn_mpc_mask mpc_mask = { |
| 426 | − MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), | |
| 435 | + MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\ | |
| 436 | + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK) | |
| 427 | 437 | }; |
| 428 | 438 | |
| 429 | 439 | #define tg_regs(id)\ |
| @@ -2294,7 +2294,8 @@ void dcn20_fpga_init_hw(struct dc *dc) · 2293 unmodified lines | ||
| 2294 | 2294 | |
| 2295 | 2295 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); |
| 2296 | 2296 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); |
| 2297 | − REG_WRITE(REFCLK_CNTL, 0); | |
| 2297 | + if (REG(REFCLK_CNTL)) | |
| 2298 | + REG_WRITE(REFCLK_CNTL, 0); | |
| 2298 | 2299 | // |
| 2299 | 2300 | |
| 2300 | 2301 | |
| @@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 51 unmodified lines | ||
| 52 | 52 | .disable_plane = dcn20_disable_plane, |
| 53 | 53 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 54 | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 55 | + .cursor_lock = dcn10_cursor_lock, | |
| 55 | 56 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 56 | 57 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 57 | 58 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = { · 544 unmodified lines | ||
| 545 | 545 | .mpc_init = mpc1_mpc_init, |
| 546 | 546 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
| 547 | 547 | .update_blending = mpc2_update_blending, |
| 548 | + .cursor_lock = mpc1_cursor_lock, | |
| 548 | 549 | .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, |
| 549 | 550 | .wait_for_idle = mpc2_assert_idle_mpcc, |
| 550 | 551 | .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, |
| @@ -179,7 +179,8 @@ · 178 unmodified lines | ||
| 179 | 179 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ |
| 180 | 180 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ |
| 181 | 181 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ |
| 182 | − SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) | |
| 182 | + SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\ | |
| 183 | + SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) | |
| 183 | 184 | |
| 184 | 185 | /* |
| 185 | 186 | * DCN2 MPC_OCSC debug status register: |
| @@ -508,6 +508,10 @@ enum dcn20_clk_src_array_id { · 507 unmodified lines | ||
| 508 | 508 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 509 | 509 | mm ## block ## id ## _ ## reg_name |
| 510 | 510 | |
| 511 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 512 | + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | |
| 513 | + mm ## reg_name ## _ ## block ## id | |
| 514 | + | |
| 511 | 515 | /* NBIO */ |
| 512 | 516 | #define NBIO_BASE_INNER(seg) \ |
| 513 | 517 | NBIO_BASE__INST0_SEG ## seg |
| @@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 52 unmodified lines | ||
| 53 | 53 | .disable_plane = dcn20_disable_plane, |
| 54 | 54 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 55 | 55 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 56 | + .cursor_lock = dcn10_cursor_lock, | |
| 56 | 57 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 57 | 58 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 58 | 59 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -284,7 +284,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 283 unmodified lines | ||
| 284 | 284 | .dram_channel_width_bytes = 4, |
| 285 | 285 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
| 286 | 286 | .dcn_downspread_percent = 0.5, |
| 287 | − .downspread_percent = 0.5, | |
| 287 | + .downspread_percent = 0.38, | |
| 288 | 288 | .dram_page_open_time_ns = 50.0, |
| 289 | 289 | .dram_rw_turnaround_time_ns = 17.5, |
| 290 | 290 | .dram_return_buffer_per_channel_bytes = 8192, |
| @@ -340,6 +340,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 49 unmodified lines | ||
| 340 | 340 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 341 | 341 | mm ## block ## id ## _ ## reg_name |
| 342 | 342 | |
| 343 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 344 | + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | |
| 345 | + mm ## reg_name ## _ ## block ## id | |
| 346 | + | |
| 343 | 347 | /* NBIO */ |
| 344 | 348 | #define NBIO_BASE_INNER(seg) \ |
| 345 | 349 | NBIF0_BASE__INST0_SEG ## seg |
| @@ -1374,64 +1378,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 1028 unmodified lines | ||
| 1374 | 1378 | { |
| 1375 | 1379 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); |
| 1376 | 1380 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
| 1377 | − unsigned int i, j, k; | |
| 1378 | − int closest_clk_lvl; | |
| 1381 | + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; | |
| 1382 | + unsigned int i, j, closest_clk_lvl; | |
| 1379 | 1383 | |
| 1380 | 1384 | // Default clock levels are used for diags, which may lead to overclocking. |
| 1381 | − if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 1385 | + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 1382 | 1386 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1383 | 1387 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1384 | 1388 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1385 | 1389 | |
| 1386 | − /* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */ | |
| 1387 | − dcn2_1_soc.clock_limits[0].state = 0; | |
| 1388 | − dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; | |
| 1389 | − dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz; | |
| 1390 | − dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz; | |
| 1391 | − dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2; | |
| 1392 | − | |
| 1393 | − /* | |
| 1394 | − * Other levels: find closest DCN clocks that fit the given clock limit using dcfclk | |
| 1395 | − * as indicator | |
| 1396 | − */ | |
| 1397 | − | |
| 1398 | − closest_clk_lvl = -1; | |
| 1399 | − /* index currently being filled */ | |
| 1400 | − k = 1; | |
| 1401 | − for (i = 1; i < clk_table->num_entries; i++) { | |
| 1402 | − /* loop backwards, skip duplicate state*/ | |
| 1403 | − for (j = dcn2_1_soc.num_states - 1; j >= k; j--) { | |
| 1390 | + ASSERT(clk_table->num_entries); | |
| 1391 | + for (i = 0; i < clk_table->num_entries; i++) { | |
| 1392 | + /* loop backwards*/ | |
| 1393 | + for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | |
| 1404 | 1394 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { |
| 1405 | 1395 | closest_clk_lvl = j; |
| 1406 | 1396 | break; |
| 1407 | 1397 | } |
| 1408 | 1398 | } |
| 1409 | 1399 | |
| 1410 | − /* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/ | |
| 1411 | − if (closest_clk_lvl != -1) { | |
| 1412 | − dcn2_1_soc.clock_limits[k].state = i; | |
| 1413 | − dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1414 | − dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1415 | − dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1416 | − dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1417 | − | |
| 1418 | − dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1419 | − dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1420 | − dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1421 | − dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1422 | − dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1423 | − dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1424 | − dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1425 | − k++; | |
| 1426 | − } | |
| 1400 | + clock_limits[i].state = i; | |
| 1401 | + clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1402 | + clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1403 | + clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1404 | + clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1405 | + | |
| 1406 | + clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1407 | + clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1408 | + clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1409 | + clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1410 | + clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1411 | + clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1412 | + clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1413 | + } | |
| 1414 | + for (i = 0; i < clk_table->num_entries; i++) | |
| 1415 | + dcn2_1_soc.clock_limits[i] = clock_limits[i]; | |
| 1416 | + if (clk_table->num_entries) { | |
| 1417 | + dcn2_1_soc.num_states = clk_table->num_entries; | |
| 1418 | + /* duplicate last level */ | |
| 1419 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1420 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1427 | 1421 | } |
| 1428 | − dcn2_1_soc.num_states = k; | |
| 1429 | 1422 | } |
| 1430 | 1423 | |
| 1431 | − /* duplicate last level */ | |
| 1432 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1433 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1434 | − | |
| 1435 | 1424 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); |
| 1436 | 1425 | } |
| 1437 | 1426 | |
| @@ -210,6 +210,22 @@ struct mpc_funcs { · 209 unmodified lines | ||
| 210 | 210 | struct mpcc_blnd_cfg *blnd_cfg, |
| 211 | 211 | int mpcc_id); |
| 212 | 212 | |
| 213 | + /* | |
| 214 | + * Lock cursor updates for the specified OPP. | |
| 215 | + * OPP defines the set of MPCC that are locked together for cursor. | |
| 216 | + * | |
| 217 | + * Parameters: | |
| 218 | + * [in] mpc - MPC context. | |
| 219 | + * [in] opp_id - The OPP to lock cursor updates on | |
| 220 | + * [in] lock - lock/unlock the OPP | |
| 221 | + * | |
| 222 | + * Return: void | |
| 223 | + */ | |
| 224 | + void (*cursor_lock)( | |
| 225 | + struct mpc *mpc, | |
| 226 | + int opp_id, | |
| 227 | + bool lock); | |
| 228 | + | |
| 213 | 229 | struct mpcc* (*get_mpcc_for_dpp)( |
| 214 | 230 | struct mpc_tree *tree, |
| 215 | 231 | int dpp_id); |
| @@ -86,6 +86,7 @@ struct hw_sequencer_funcs { · 85 unmodified lines | ||
| 86 | 86 | struct dc_state *context, bool lock); |
| 87 | 87 | void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, |
| 88 | 88 | bool flip_immediate); |
| 89 | + void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock); | |
| 89 | 90 | |
| 90 | 91 | /* Timing Related */ |
| 91 | 92 | void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, |
| @@ -1435,7 +1435,8 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1434 unmodified lines | ||
| 1435 | 1435 | if (!hwmgr) |
| 1436 | 1436 | return -EINVAL; |
| 1437 | 1437 | |
| 1438 | − if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability) | |
| 1438 | + if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1439 | + !hwmgr->hwmgr_func->get_asic_baco_capability) | |
| 1439 | 1440 | return 0; |
| 1440 | 1441 | |
| 1441 | 1442 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1452,8 +1453,7 @@ static int pp_get_asic_baco_state(void *handle, int *state) · 10 unmodified lines | ||
| 1452 | 1453 | if (!hwmgr) |
| 1453 | 1454 | return -EINVAL; |
| 1454 | 1455 | |
| 1455 | − if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1456 | − !hwmgr->hwmgr_func->get_asic_baco_state) | |
| 1456 | + if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state) | |
| 1457 | 1457 | return 0; |
| 1458 | 1458 | |
| 1459 | 1459 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1470,7 +1470,8 @@ static int pp_set_asic_baco_state(void *handle, int state) · 10 unmodified lines | ||
| 1470 | 1470 | if (!hwmgr) |
| 1471 | 1471 | return -EINVAL; |
| 1472 | 1472 | |
| 1473 | − if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state) | |
| 1473 | + if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1474 | + !hwmgr->hwmgr_func->set_asic_baco_state) | |
| 1474 | 1475 | return 0; |
| 1475 | 1476 | |
| 1476 | 1477 | mutex_lock(&hwmgr->smu_lock); |
| @@ -3442,8 +3442,12 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, · 3441 unmodified lines | ||
| 3442 | 3442 | drm_dp_queue_down_tx(mgr, txmsg); |
| 3443 | 3443 | |
| 3444 | 3444 | ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); |
| 3445 | − if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) | |
| 3446 | − ret = -EIO; | |
| 3445 | + if (ret > 0) { | |
| 3446 | + if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) | |
| 3447 | + ret = -EIO; | |
| 3448 | + else | |
| 3449 | + ret = size; | |
| 3450 | + } | |
| 3447 | 3451 | |
| 3448 | 3452 | kfree(txmsg); |
| 3449 | 3453 | fail_put: |
| @@ -5111,7 +5111,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d · 5110 unmodified lines | ||
| 5111 | 5111 | struct drm_display_mode *mode; |
| 5112 | 5112 | unsigned pixel_clock = (timings->pixel_clock[0] | |
| 5113 | 5113 | (timings->pixel_clock[1] << 8) | |
| 5114 | − (timings->pixel_clock[2] << 16)); | |
| 5114 | + (timings->pixel_clock[2] << 16)) + 1; | |
| 5115 | 5115 | unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; |
| 5116 | 5116 | unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; |
| 5117 | 5117 | unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; |
| @@ -182,21 +182,35 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, · 181 unmodified lines | ||
| 182 | 182 | int tiling_mode, unsigned int stride) |
| 183 | 183 | { |
| 184 | 184 | struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt; |
| 185 | − struct i915_vma *vma; | |
| 185 | + struct i915_vma *vma, *vn; | |
| 186 | + LIST_HEAD(unbind); | |
| 186 | 187 | int ret = 0; |
| 187 | 188 | |
| 188 | 189 | if (tiling_mode == I915_TILING_NONE) |
| 189 | 190 | return 0; |
| 190 | 191 | |
| 191 | 192 | mutex_lock(&ggtt->vm.mutex); |
| 193 | + | |
| 194 | + spin_lock(&obj->vma.lock); | |
| 192 | 195 | for_each_ggtt_vma(vma, obj) { |
| 196 | + GEM_BUG_ON(vma->vm != &ggtt->vm); | |
| 197 | + | |
| 193 | 198 | if (i915_vma_fence_prepare(vma, tiling_mode, stride)) |
| 194 | 199 | continue; |
| 195 | 200 | |
| 201 | + list_move(&vma->vm_link, &unbind); | |
| 202 | + } | |
| 203 | + spin_unlock(&obj->vma.lock); | |
| 204 | + | |
| 205 | + list_for_each_entry_safe(vma, vn, &unbind, vm_link) { | |
| 196 | 206 | ret = __i915_vma_unbind(vma); |
| 197 | − if (ret) | |
| 207 | + if (ret) { | |
| 208 | + /* Restore the remaining vma on an error */ | |
| 209 | + list_splice(&unbind, &ggtt->vm.bound_list); | |
| 198 | 210 | break; |
| 211 | + } | |
| 199 | 212 | } |
| 213 | + | |
| 200 | 214 | mutex_unlock(&ggtt->vm.mutex); |
| 201 | 215 | |
| 202 | 216 | return ret; |
| @@ -268,6 +282,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 65 unmodified lines | ||
| 268 | 282 | } |
| 269 | 283 | mutex_unlock(&obj->mm.lock); |
| 270 | 284 | |
| 285 | + spin_lock(&obj->vma.lock); | |
| 271 | 286 | for_each_ggtt_vma(vma, obj) { |
| 272 | 287 | vma->fence_size = |
| 273 | 288 | i915_gem_fence_size(i915, vma->size, tiling, stride); |
| @@ -278,6 +293,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 4 unmodified lines | ||
| 278 | 293 | if (vma->fence) |
| 279 | 294 | vma->fence->dirty = true; |
| 280 | 295 | } |
| 296 | + spin_unlock(&obj->vma.lock); | |
| 281 | 297 | |
| 282 | 298 | obj->tiling_and_stride = tiling | stride; |
| 283 | 299 | i915_gem_object_unlock(obj); |
| @@ -1477,8 +1477,10 @@ static int igt_ppgtt_pin_update(void *arg) · 1476 unmodified lines | ||
| 1477 | 1477 | unsigned int page_size = BIT(first); |
| 1478 | 1478 | |
| 1479 | 1479 | obj = i915_gem_object_create_internal(dev_priv, page_size); |
| 1480 | − if (IS_ERR(obj)) | |
| 1481 | − return PTR_ERR(obj); | |
| 1480 | + if (IS_ERR(obj)) { | |
| 1481 | + err = PTR_ERR(obj); | |
| 1482 | + goto out_vm; | |
| 1483 | + } | |
| 1482 | 1484 | |
| 1483 | 1485 | vma = i915_vma_instance(obj, vm, NULL); |
| 1484 | 1486 | if (IS_ERR(vma)) { |
| @@ -1531,8 +1533,10 @@ static int igt_ppgtt_pin_update(void *arg) · 46 unmodified lines | ||
| 1531 | 1533 | } |
| 1532 | 1534 | |
| 1533 | 1535 | obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE); |
| 1534 | − if (IS_ERR(obj)) | |
| 1535 | − return PTR_ERR(obj); | |
| 1536 | + if (IS_ERR(obj)) { | |
| 1537 | + err = PTR_ERR(obj); | |
| 1538 | + goto out_vm; | |
| 1539 | + } | |
| 1536 | 1540 | |
| 1537 | 1541 | vma = i915_vma_instance(obj, vm, NULL); |
| 1538 | 1542 | if (IS_ERR(vma)) { |
| @@ -521,6 +521,8 @@ int intel_timeline_read_hwsp(struct i915_request *from, · 520 unmodified lines | ||
| 521 | 521 | |
| 522 | 522 | rcu_read_lock(); |
| 523 | 523 | cl = rcu_dereference(from->hwsp_cacheline); |
| 524 | + if (i915_request_completed(from)) /* confirm cacheline is valid */ | |
| 525 | + goto unlock; | |
| 524 | 526 | if (unlikely(!i915_active_acquire_if_busy(&cl->active))) |
| 525 | 527 | goto unlock; /* seqno wrapped and completed! */ |
| 526 | 528 | if (unlikely(i915_request_completed(from))) |
| @@ -3358,7 +3358,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 3357 unmodified lines | ||
| 3358 | 3358 | { |
| 3359 | 3359 | struct intel_uncore *uncore = &dev_priv->uncore; |
| 3360 | 3360 | |
| 3361 | − u32 de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; | |
| 3361 | + u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | | |
| 3362 | + GEN8_PIPE_CDCLK_CRC_DONE; | |
| 3362 | 3363 | u32 de_pipe_enables; |
| 3363 | 3364 | u32 de_port_masked = GEN8_AUX_CHANNEL_A; |
| 3364 | 3365 | u32 de_port_enables; |
| @@ -3369,13 +3370,10 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 4 unmodified lines | ||
| 3369 | 3370 | de_misc_masked |= GEN8_DE_MISC_GSE; |
| 3370 | 3371 | |
| 3371 | 3372 | if (INTEL_GEN(dev_priv) >= 9) { |
| 3372 | − de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; | |
| 3373 | 3373 | de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | |
| 3374 | 3374 | GEN9_AUX_CHANNEL_D; |
| 3375 | 3375 | if (IS_GEN9_LP(dev_priv)) |
| 3376 | 3376 | de_port_masked |= BXT_DE_PORT_GMBUS; |
| 3377 | − } else { | |
| 3378 | − de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | |
| 3379 | 3377 | } |
| 3380 | 3378 | |
| 3381 | 3379 | if (INTEL_GEN(dev_priv) >= 11) |
| @@ -158,16 +158,18 @@ vma_create(struct drm_i915_gem_object *obj, · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | GEM_BUG_ON(!IS_ALIGNED(vma->size, I915_GTT_PAGE_SIZE)); |
| 160 | 160 | |
| 161 | + spin_lock(&obj->vma.lock); | |
| 162 | + | |
| 161 | 163 | if (i915_is_ggtt(vm)) { |
| 162 | 164 | if (unlikely(overflows_type(vma->size, u32))) |
| 163 | − goto err_vma; | |
| 165 | + goto err_unlock; | |
| 164 | 166 | |
| 165 | 167 | vma->fence_size = i915_gem_fence_size(vm->i915, vma->size, |
| 166 | 168 | i915_gem_object_get_tiling(obj), |
| 167 | 169 | i915_gem_object_get_stride(obj)); |
| 168 | 170 | if (unlikely(vma->fence_size < vma->size || /* overflow */ |
| 169 | 171 | vma->fence_size > vm->total)) |
| 170 | − goto err_vma; | |
| 172 | + goto err_unlock; | |
| 171 | 173 | |
| 172 | 174 | GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT)); |
| 173 | 175 | |
| @@ -179,8 +181,6 @@ vma_create(struct drm_i915_gem_object *obj, · 5 unmodified lines | ||
| 179 | 181 | __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma)); |
| 180 | 182 | } |
| 181 | 183 | |
| 182 | − spin_lock(&obj->vma.lock); | |
| 183 | − | |
| 184 | 184 | rb = NULL; |
| 185 | 185 | p = &obj->vma.tree.rb_node; |
| 186 | 186 | while (*p) { |
| @@ -225,6 +225,8 @@ vma_create(struct drm_i915_gem_object *obj, · 38 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | return vma; |
| 227 | 227 | |
| 228 | +err_unlock: | |
| 229 | + spin_unlock(&obj->vma.lock); | |
| 228 | 230 | err_vma: |
| 229 | 231 | i915_vma_free(vma); |
| 230 | 232 | return ERR_PTR(-E2BIG); |
| @@ -480,9 +480,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 479 unmodified lines | ||
| 480 | 480 | return ret; |
| 481 | 481 | |
| 482 | 482 | ret = qxl_release_reserve_list(release, true); |
| 483 | − if (ret) | |
| 483 | + if (ret) { | |
| 484 | + qxl_release_free(qdev, release); | |
| 484 | 485 | return ret; |
| 485 | − | |
| 486 | + } | |
| 486 | 487 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); |
| 487 | 488 | cmd->type = QXL_SURFACE_CMD_CREATE; |
| 488 | 489 | cmd->flags = QXL_SURF_FLAG_KEEP_DATA; |
| @@ -499,8 +500,8 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 10 unmodified lines | ||
| 499 | 500 | /* no need to add a release to the fence for this surface bo, |
| 500 | 501 | since it is only released when we ask to destroy the surface |
| 501 | 502 | and it would never signal otherwise */ |
| 502 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 503 | 503 | qxl_release_fence_buffer_objects(release); |
| 504 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 504 | 505 | |
| 505 | 506 | surf->hw_surf_alloc = true; |
| 506 | 507 | spin_lock(&qdev->surf_id_idr_lock); |
| @@ -542,9 +543,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, · 35 unmodified lines | ||
| 542 | 543 | cmd->surface_id = id; |
| 543 | 544 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 544 | 545 | |
| 545 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 546 | − | |
| 547 | 546 | qxl_release_fence_buffer_objects(release); |
| 547 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 548 | 548 | |
| 549 | 549 | return 0; |
| 550 | 550 | } |
| @@ -510,8 +510,8 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane) · 509 unmodified lines | ||
| 510 | 510 | cmd->u.set.visible = 1; |
| 511 | 511 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 512 | 512 | |
| 513 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 514 | 513 | qxl_release_fence_buffer_objects(release); |
| 514 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 515 | 515 | |
| 516 | 516 | return ret; |
| 517 | 517 | |
| @@ -652,8 +652,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, · 134 unmodified lines | ||
| 652 | 652 | cmd->u.position.y = plane->state->crtc_y + fb->hot_y; |
| 653 | 653 | |
| 654 | 654 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 655 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 656 | 655 | qxl_release_fence_buffer_objects(release); |
| 656 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 657 | 657 | |
| 658 | 658 | if (old_cursor_bo != NULL) |
| 659 | 659 | qxl_bo_unpin(old_cursor_bo); |
| @@ -700,8 +700,8 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, · 40 unmodified lines | ||
| 700 | 700 | cmd->type = QXL_CURSOR_HIDE; |
| 701 | 701 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 702 | 702 | |
| 703 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 704 | 703 | qxl_release_fence_buffer_objects(release); |
| 704 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 705 | 705 | } |
| 706 | 706 | |
| 707 | 707 | static void qxl_update_dumb_head(struct qxl_device *qdev, |
| @@ -209,9 +209,10 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 208 unmodified lines | ||
| 209 | 209 | goto out_release_backoff; |
| 210 | 210 | |
| 211 | 211 | rects = drawable_set_clipping(qdev, num_clips, clips_bo); |
| 212 | − if (!rects) | |
| 212 | + if (!rects) { | |
| 213 | + ret = -EINVAL; | |
| 213 | 214 | goto out_release_backoff; |
| 214 | − | |
| 215 | + } | |
| 215 | 216 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
| 216 | 217 | |
| 217 | 218 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; |
| @@ -242,8 +243,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 24 unmodified lines | ||
| 242 | 243 | } |
| 243 | 244 | qxl_bo_kunmap(clips_bo); |
| 244 | 245 | |
| 245 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | |
| 246 | 246 | qxl_release_fence_buffer_objects(release); |
| 247 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | |
| 247 | 248 | |
| 248 | 249 | out_release_backoff: |
| 249 | 250 | if (ret) |
| @@ -212,7 +212,8 @@ qxl_image_init_helper(struct qxl_device *qdev, · 211 unmodified lines | ||
| 212 | 212 | break; |
| 213 | 213 | default: |
| 214 | 214 | DRM_ERROR("unsupported image bit depth\n"); |
| 215 | − return -EINVAL; /* TODO: cleanup */ | |
| 215 | + qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); | |
| 216 | + return -EINVAL; | |
| 216 | 217 | } |
| 217 | 218 | image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; |
| 218 | 219 | image->u.bitmap.x = width; |
| @@ -261,11 +261,8 @@ static int qxl_process_single_command(struct qxl_device *qdev, · 260 unmodified lines | ||
| 261 | 261 | apply_surf_reloc(qdev, &reloc_info[i]); |
| 262 | 262 | } |
| 263 | 263 | |
| 264 | + qxl_release_fence_buffer_objects(release); | |
| 264 | 265 | ret = qxl_push_command_ring_release(qdev, release, cmd->type, true); |
| 265 | − if (ret) | |
| 266 | − qxl_release_backoff_reserve_list(release); | |
| 267 | − else | |
| 268 | − qxl_release_fence_buffer_objects(release); | |
| 269 | 266 | |
| 270 | 267 | out_free_bos: |
| 271 | 268 | out_free_release: |
| @@ -53,14 +53,6 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) · 52 unmodified lines | ||
| 53 | 53 | events_clear, &events_clear); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | −static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, | |
| 57 | − uint32_t ctx_id) | |
| 58 | −{ | |
| 59 | − virtio_gpu_cmd_context_destroy(vgdev, ctx_id); | |
| 60 | − virtio_gpu_notify(vgdev); | |
| 61 | − ida_free(&vgdev->ctx_id_ida, ctx_id - 1); | |
| 62 | −} | |
| 63 | − | |
| 64 | 56 | static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, |
| 65 | 57 | void (*work_func)(struct work_struct *work)) |
| 66 | 58 | { |
| @@ -275,14 +267,17 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) · 208 unmodified lines | ||
| 275 | 267 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) |
| 276 | 268 | { |
| 277 | 269 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| 278 | − struct virtio_gpu_fpriv *vfpriv; | |
| 270 | + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; | |
| 279 | 271 | |
| 280 | 272 | if (!vgdev->has_virgl_3d) |
| 281 | 273 | return; |
| 282 | 274 | |
| 283 | − vfpriv = file->driver_priv; | |
| 275 | + if (vfpriv->context_created) { | |
| 276 | + virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id); | |
| 277 | + virtio_gpu_notify(vgdev); | |
| 278 | + } | |
| 284 | 279 | |
| 285 | − virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id); | |
| 280 | + ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1); | |
| 286 | 281 | mutex_destroy(&vfpriv->context_lock); |
| 287 | 282 | kfree(vfpriv); |
| 288 | 283 | file->driver_priv = NULL; |
| @@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu) · 183 unmodified lines | ||
| 184 | 184 | |
| 185 | 185 | shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; |
| 186 | 186 | shared_sint.masked = false; |
| 187 | − if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) | |
| 188 | − shared_sint.auto_eoi = false; | |
| 189 | − else | |
| 190 | − shared_sint.auto_eoi = true; | |
| 191 | − | |
| 187 | + shared_sint.auto_eoi = hv_recommend_using_aeoi(); | |
| 192 | 188 | hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); |
| 193 | 189 | |
| 194 | 190 | /* Enable the global synic bit */ |
| @@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request, · 285 unmodified lines | ||
| 286 | 286 | __field(int, ret) |
| 287 | 287 | ), |
| 288 | 288 | TP_fast_assign( |
| 289 | − memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16); | |
| 290 | − memcpy(__entry->host_id, &msg->host_service_id.b, 16); | |
| 289 | + export_guid(__entry->guest_id, &msg->guest_endpoint_id); | |
| 290 | + export_guid(__entry->host_id, &msg->host_service_id); | |
| 291 | 291 | __entry->ret = ret; |
| 292 | 292 | ), |
| 293 | 293 | TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, " |
| @@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device) · 977 unmodified lines | ||
| 978 | 978 | |
| 979 | 979 | return drv->resume(dev); |
| 980 | 980 | } |
| 981 | +#else | |
| 982 | +#define vmbus_suspend NULL | |
| 983 | +#define vmbus_resume NULL | |
| 981 | 984 | #endif /* CONFIG_PM_SLEEP */ |
| 982 | 985 | |
| 983 | 986 | /* |
| @@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device) · 13 unmodified lines | ||
| 997 | 1000 | } |
| 998 | 1001 | |
| 999 | 1002 | /* |
| 1000 | − * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | |
| 1001 | − * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm. | |
| 1003 | + * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm. | |
| 1004 | + * | |
| 1005 | + * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we | |
| 1006 | + * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there | |
| 1007 | + * is no way to wake up a Generation-2 VM. | |
| 1008 | + * | |
| 1009 | + * The other 4 ops are for hibernation. | |
| 1002 | 1010 | */ |
| 1011 | + | |
| 1003 | 1012 | static const struct dev_pm_ops vmbus_pm = { |
| 1004 | − SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume) | |
| 1013 | + .suspend_noirq = NULL, | |
| 1014 | + .resume_noirq = NULL, | |
| 1015 | + .freeze_noirq = vmbus_suspend, | |
| 1016 | + .thaw_noirq = vmbus_resume, | |
| 1017 | + .poweroff_noirq = vmbus_suspend, | |
| 1018 | + .restore_noirq = vmbus_resume, | |
| 1005 | 1019 | }; |
| 1006 | 1020 | |
| 1007 | 1021 | /* The one and only one */ |
| @@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev) · 1273 unmodified lines | ||
| 2281 | 2295 | |
| 2282 | 2296 | return 0; |
| 2283 | 2297 | } |
| 2298 | +#else | |
| 2299 | +#define vmbus_bus_suspend NULL | |
| 2300 | +#define vmbus_bus_resume NULL | |
| 2284 | 2301 | #endif /* CONFIG_PM_SLEEP */ |
| 2285 | 2302 | |
| 2286 | 2303 | static const struct acpi_device_id vmbus_acpi_device_ids[] = { |
| @@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = { · 4 unmodified lines | ||
| 2291 | 2308 | MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); |
| 2292 | 2309 | |
| 2293 | 2310 | /* |
| 2294 | − * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | |
| 2295 | − * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the | |
| 2296 | − * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the | |
| 2297 | − * pci "noirq" restore callback runs before "non-noirq" callbacks (see | |
| 2311 | + * Note: we must use the "no_irq" ops, otherwise hibernation can not work with | |
| 2312 | + * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in | |
| 2313 | + * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see | |
| 2298 | 2314 | * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> |
| 2299 | 2315 | * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's |
| 2300 | − * resume callback must also run via the "noirq" callbacks. | |
| 2316 | + * resume callback must also run via the "noirq" ops. | |
| 2317 | + * | |
| 2318 | + * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment | |
| 2319 | + * earlier in this file before vmbus_pm. | |
| 2301 | 2320 | */ |
| 2321 | + | |
| 2302 | 2322 | static const struct dev_pm_ops vmbus_bus_pm = { |
| 2303 | − SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) | |
| 2323 | + .suspend_noirq = NULL, | |
| 2324 | + .resume_noirq = NULL, | |
| 2325 | + .freeze_noirq = vmbus_bus_suspend, | |
| 2326 | + .thaw_noirq = vmbus_bus_resume, | |
| 2327 | + .poweroff_noirq = vmbus_bus_suspend, | |
| 2328 | + .restore_noirq = vmbus_bus_resume | |
| 2304 | 2329 | }; |
| 2305 | 2330 | |
| 2306 | 2331 | static struct acpi_driver vmbus_acpi_driver = { |
| @@ -349,12 +349,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pci_dev, · 348 unmodified lines | ||
| 349 | 349 | if (!privdata) |
| 350 | 350 | return -ENOMEM; |
| 351 | 351 | |
| 352 | + privdata->pci_dev = pci_dev; | |
| 352 | 353 | rc = amd_mp2_pci_init(privdata, pci_dev); |
| 353 | 354 | if (rc) |
| 354 | 355 | return rc; |
| 355 | 356 | |
| 356 | 357 | mutex_init(&privdata->c2p_lock); |
| 357 | − privdata->pci_dev = pci_dev; | |
| 358 | 358 | |
| 359 | 359 | pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000); |
| 360 | 360 | pm_runtime_use_autosuspend(&pci_dev->dev); |
| @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 602 unmodified lines | ||
| 603 | 603 | /* Ack all interrupts except for Rx done */ |
| 604 | 604 | writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, |
| 605 | 605 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 606 | + readl(bus->base + ASPEED_I2C_INTR_STS_REG); | |
| 606 | 607 | irq_remaining = irq_received; |
| 607 | 608 | |
| 608 | 609 | #if IS_ENABLED(CONFIG_I2C_SLAVE) |
| @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 36 unmodified lines | ||
| 645 | 646 | irq_received, irq_handled); |
| 646 | 647 | |
| 647 | 648 | /* Ack Rx done */ |
| 648 | − if (irq_received & ASPEED_I2CD_INTR_RX_DONE) | |
| 649 | + if (irq_received & ASPEED_I2CD_INTR_RX_DONE) { | |
| 649 | 650 | writel(ASPEED_I2CD_INTR_RX_DONE, |
| 650 | 651 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 652 | + readl(bus->base + ASPEED_I2C_INTR_STS_REG); | |
| 653 | + } | |
| 651 | 654 | spin_unlock(&bus->lock); |
| 652 | 655 | return irq_remaining ? IRQ_NONE : IRQ_HANDLED; |
| 653 | 656 | } |
| @@ -360,6 +360,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, · 359 unmodified lines | ||
| 360 | 360 | value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); |
| 361 | 361 | i2c_slave_event(iproc_i2c->slave, |
| 362 | 362 | I2C_SLAVE_WRITE_RECEIVED, &value); |
| 363 | + if (rx_status == I2C_SLAVE_RX_END) | |
| 364 | + i2c_slave_event(iproc_i2c->slave, | |
| 365 | + I2C_SLAVE_STOP, &value); | |
| 363 | 366 | } |
| 364 | 367 | } else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { |
| 365 | 368 | /* Master read other than start */ |
| @@ -996,13 +996,14 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 995 unmodified lines | ||
| 996 | 996 | do { |
| 997 | 997 | u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS); |
| 998 | 998 | |
| 999 | − if (status) | |
| 999 | + if (status) { | |
| 1000 | 1000 | tegra_i2c_isr(i2c_dev->irq, i2c_dev); |
| 1001 | 1001 | |
| 1002 | − if (completion_done(complete)) { | |
| 1003 | − s64 delta = ktime_ms_delta(ktimeout, ktime); | |
| 1002 | + if (completion_done(complete)) { | |
| 1003 | + s64 delta = ktime_ms_delta(ktimeout, ktime); | |
| 1004 | 1004 | |
| 1005 | − return msecs_to_jiffies(delta) ?: 1; | |
| 1005 | + return msecs_to_jiffies(delta) ?: 1; | |
| 1006 | + } | |
| 1006 | 1007 | } |
| 1007 | 1008 | |
| 1008 | 1009 | ktime = ktime_get(); |
| @@ -1029,18 +1030,14 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 20 unmodified lines | ||
| 1029 | 1030 | disable_irq(i2c_dev->irq); |
| 1030 | 1031 | |
| 1031 | 1032 | /* |
| 1032 | − * Under some rare circumstances (like running KASAN + | |
| 1033 | − * NFS root) CPU, which handles interrupt, may stuck in | |
| 1034 | − * uninterruptible state for a significant time. In this | |
| 1035 | − * case we will get timeout if I2C transfer is running on | |
| 1036 | − * a sibling CPU, despite of IRQ being raised. | |
| 1037 | − * | |
| 1038 | − * In order to handle this rare condition, the IRQ status | |
| 1039 | − * needs to be checked after timeout. | |
| 1033 | + * There is a chance that completion may happen after IRQ | |
| 1034 | + * synchronization, which is done by disable_irq(). | |
| 1040 | 1035 | */ |
| 1041 | − if (ret == 0) | |
| 1042 | − ret = tegra_i2c_poll_completion_timeout(i2c_dev, | |
| 1043 | − complete, 0); | |
| 1036 | + if (ret == 0 && completion_done(complete)) { | |
| 1037 | + dev_warn(i2c_dev->dev, | |
| 1038 | + "completion done after timeout\n"); | |
| 1039 | + ret = 1; | |
| 1040 | + } | |
| 1044 | 1041 | } |
| 1045 | 1042 | |
| 1046 | 1043 | return ret; |
| @@ -1219,15 +1216,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 172 unmodified lines | ||
| 1219 | 1216 | time_left = tegra_i2c_wait_completion_timeout( |
| 1220 | 1217 | i2c_dev, &i2c_dev->dma_complete, xfer_time); |
| 1221 | 1218 | |
| 1222 | − /* | |
| 1223 | − * Synchronize DMA first, since dmaengine_terminate_sync() | |
| 1224 | − * performs synchronization after the transfer's termination | |
| 1225 | − * and we want to get a completion if transfer succeeded. | |
| 1226 | − */ | |
| 1227 | − dmaengine_synchronize(i2c_dev->msg_read ? | |
| 1228 | − i2c_dev->rx_dma_chan : | |
| 1229 | − i2c_dev->tx_dma_chan); | |
| 1230 | − | |
| 1231 | 1219 | dmaengine_terminate_sync(i2c_dev->msg_read ? |
| 1232 | 1220 | i2c_dev->rx_dma_chan : |
| 1233 | 1221 | i2c_dev->tx_dma_chan); |
| @@ -862,7 +862,7 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, · 861 unmodified lines | ||
| 862 | 862 | |
| 863 | 863 | ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b, |
| 864 | 864 | &cm.local_id_next, GFP_KERNEL); |
| 865 | − if (ret) | |
| 865 | + if (ret < 0) | |
| 866 | 866 | goto error; |
| 867 | 867 | cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; |
| 868 | 868 | |
| @@ -1828,11 +1828,9 @@ static void cm_format_mra(struct cm_mra_msg *mra_msg, · 959 unmodified lines | ||
| 1828 | 1828 | |
| 1829 | 1829 | static void cm_format_rej(struct cm_rej_msg *rej_msg, |
| 1830 | 1830 | struct cm_id_private *cm_id_priv, |
| 1831 | − enum ib_cm_rej_reason reason, | |
| 1832 | − void *ari, | |
| 1833 | − u8 ari_length, | |
| 1834 | − const void *private_data, | |
| 1835 | − u8 private_data_len) | |
| 1831 | + enum ib_cm_rej_reason reason, void *ari, | |
| 1832 | + u8 ari_length, const void *private_data, | |
| 1833 | + u8 private_data_len, enum ib_cm_state state) | |
| 1836 | 1834 | { |
| 1837 | 1835 | lockdep_assert_held(&cm_id_priv->lock); |
| 1838 | 1836 | |
| @@ -1840,7 +1838,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg, · 1 unmodified line | ||
| 1840 | 1838 | IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, |
| 1841 | 1839 | be32_to_cpu(cm_id_priv->id.remote_id)); |
| 1842 | 1840 | |
| 1843 | − switch(cm_id_priv->id.state) { | |
| 1841 | + switch (state) { | |
| 1844 | 1842 | case IB_CM_REQ_RCVD: |
| 1845 | 1843 | IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0)); |
| 1846 | 1844 | IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); |
| @@ -1905,8 +1903,9 @@ static void cm_dup_req_handler(struct cm_work *work, · 58 unmodified lines | ||
| 1905 | 1903 | cm_id_priv->private_data_len); |
| 1906 | 1904 | break; |
| 1907 | 1905 | case IB_CM_TIMEWAIT: |
| 1908 | − cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv, | |
| 1909 | − IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0); | |
| 1906 | + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, | |
| 1907 | + IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0, | |
| 1908 | + IB_CM_TIMEWAIT); | |
| 1910 | 1909 | break; |
| 1911 | 1910 | default: |
| 1912 | 1911 | goto unlock; |
| @@ -2904,6 +2903,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 991 unmodified lines | ||
| 2904 | 2903 | u8 ari_length, const void *private_data, |
| 2905 | 2904 | u8 private_data_len) |
| 2906 | 2905 | { |
| 2906 | + enum ib_cm_state state = cm_id_priv->id.state; | |
| 2907 | 2907 | struct ib_mad_send_buf *msg; |
| 2908 | 2908 | int ret; |
| 2909 | 2909 | |
| @@ -2913,7 +2913,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 3 unmodified lines | ||
| 2913 | 2913 | (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) |
| 2914 | 2914 | return -EINVAL; |
| 2915 | 2915 | |
| 2916 | − switch (cm_id_priv->id.state) { | |
| 2916 | + switch (state) { | |
| 2917 | 2917 | case IB_CM_REQ_SENT: |
| 2918 | 2918 | case IB_CM_MRA_REQ_RCVD: |
| 2919 | 2919 | case IB_CM_REQ_RCVD: |
| @@ -2925,7 +2925,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 5 unmodified lines | ||
| 2925 | 2925 | if (ret) |
| 2926 | 2926 | return ret; |
| 2927 | 2927 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2928 | − ari, ari_length, private_data, private_data_len); | |
| 2928 | + ari, ari_length, private_data, private_data_len, | |
| 2929 | + state); | |
| 2929 | 2930 | break; |
| 2930 | 2931 | case IB_CM_REP_SENT: |
| 2931 | 2932 | case IB_CM_MRA_REP_RCVD: |
| @@ -2934,7 +2935,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 2 unmodified lines | ||
| 2934 | 2935 | if (ret) |
| 2935 | 2936 | return ret; |
| 2936 | 2937 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2937 | − ari, ari_length, private_data, private_data_len); | |
| 2938 | + ari, ari_length, private_data, private_data_len, | |
| 2939 | + state); | |
| 2938 | 2940 | break; |
| 2939 | 2941 | default: |
| 2940 | 2942 | pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
| @@ -360,7 +360,7 @@ lookup_get_fd_uobject(const struct uverbs_api_object *obj, · 359 unmodified lines | ||
| 360 | 360 | * uverbs_uobject_fd_release(), and the caller is expected to ensure |
| 361 | 361 | * that release is never done while a call to lookup is possible. |
| 362 | 362 | */ |
| 363 | − if (f->f_op != fd_type->fops) { | |
| 363 | + if (f->f_op != fd_type->fops || uobject->ufile != ufile) { | |
| 364 | 364 | fput(f); |
| 365 | 365 | return ERR_PTR(-EBADF); |
| 366 | 366 | } |
| @@ -474,16 +474,15 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj, · 107 unmodified lines | ||
| 474 | 474 | filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, |
| 475 | 475 | fd_type->flags); |
| 476 | 476 | if (IS_ERR(filp)) { |
| 477 | + uverbs_uobject_put(uobj); | |
| 477 | 478 | uobj = ERR_CAST(filp); |
| 478 | − goto err_uobj; | |
| 479 | + goto err_fd; | |
| 479 | 480 | } |
| 480 | 481 | uobj->object = filp; |
| 481 | 482 | |
| 482 | 483 | uobj->id = new_fd; |
| 483 | 484 | return uobj; |
| 484 | 485 | |
| 485 | −err_uobj: | |
| 486 | − uverbs_uobject_put(uobj); | |
| 487 | 486 | err_fd: |
| 488 | 487 | put_unused_fd(new_fd); |
| 489 | 488 | return uobj; |
| @@ -679,7 +678,6 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 189 unmodified lines | ||
| 679 | 678 | enum rdma_lookup_mode mode) |
| 680 | 679 | { |
| 681 | 680 | assert_uverbs_usecnt(uobj, mode); |
| 682 | − uobj->uapi_object->type_class->lookup_put(uobj, mode); | |
| 683 | 681 | /* |
| 684 | 682 | * In order to unlock an object, either decrease its usecnt for |
| 685 | 683 | * read access or zero it in case of exclusive access. See |
| @@ -696,6 +694,7 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 10 unmodified lines | ||
| 696 | 694 | break; |
| 697 | 695 | } |
| 698 | 696 | |
| 697 | + uobj->uapi_object->type_class->lookup_put(uobj, mode); | |
| 699 | 698 | /* Pairs with the kref obtained by type->lookup_get */ |
| 700 | 699 | uverbs_uobject_put(uobj); |
| 701 | 700 | } |
| @@ -820,6 +820,10 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile) · 819 unmodified lines | ||
| 820 | 820 | ret = mmget_not_zero(mm); |
| 821 | 821 | if (!ret) { |
| 822 | 822 | list_del_init(&priv->list); |
| 823 | + if (priv->entry) { | |
| 824 | + rdma_user_mmap_entry_put(priv->entry); | |
| 825 | + priv->entry = NULL; | |
| 826 | + } | |
| 823 | 827 | mm = NULL; |
| 824 | 828 | continue; |
| 825 | 829 | } |
| @@ -1046,7 +1046,7 @@ i40iw_sc_query_rdma_features(struct i40iw_sc_cqp *cqp, · 1045 unmodified lines | ||
| 1046 | 1046 | u64 header; |
| 1047 | 1047 | |
| 1048 | 1048 | wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch); |
| 1049 | − if (wqe) | |
| 1049 | + if (!wqe) | |
| 1050 | 1050 | return I40IW_ERR_RING_FULL; |
| 1051 | 1051 | |
| 1052 | 1052 | set_64bit_val(wqe, 32, feat_mem->pa); |
| @@ -1499,8 +1499,9 @@ static int __mlx4_ib_create_default_rules( · 1498 unmodified lines | ||
| 1499 | 1499 | int i; |
| 1500 | 1500 | |
| 1501 | 1501 | for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { |
| 1502 | + union ib_flow_spec ib_spec = {}; | |
| 1502 | 1503 | int ret; |
| 1503 | − union ib_flow_spec ib_spec; | |
| 1504 | + | |
| 1504 | 1505 | switch (pdefault_rules->rules_create_list[i]) { |
| 1505 | 1506 | case 0: |
| 1506 | 1507 | /* no rule */ |
| @@ -5558,7 +5558,9 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev, · 5557 unmodified lines | ||
| 5558 | 5558 | rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); |
| 5559 | 5559 | rdma_ah_set_static_rate(ah_attr, |
| 5560 | 5560 | path->static_rate ? path->static_rate - 5 : 0); |
| 5561 | − if (path->grh_mlid & (1 << 7)) { | |
| 5561 | + | |
| 5562 | + if (path->grh_mlid & (1 << 7) || | |
| 5563 | + ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { | |
| 5562 | 5564 | u32 tc_fl = be32_to_cpu(path->tclass_flowlabel); |
| 5563 | 5565 | |
| 5564 | 5566 | rdma_ah_set_grh(ah_attr, NULL, |
| @@ -248,8 +248,8 @@ int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, · 247 unmodified lines | ||
| 248 | 248 | */ |
| 249 | 249 | if (udata && udata->outlen >= sizeof(__u64)) { |
| 250 | 250 | cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc); |
| 251 | − if (!cq->ip) { | |
| 252 | − err = -ENOMEM; | |
| 251 | + if (IS_ERR(cq->ip)) { | |
| 252 | + err = PTR_ERR(cq->ip); | |
| 253 | 253 | goto bail_wc; |
| 254 | 254 | } |
| 255 | 255 | |
| @@ -154,7 +154,7 @@ done: · 153 unmodified lines | ||
| 154 | 154 | * @udata: user data (must be valid!) |
| 155 | 155 | * @obj: opaque pointer to a cq, wq etc |
| 156 | 156 | * |
| 157 | − * Return: rvt_mmap struct on success | |
| 157 | + * Return: rvt_mmap struct on success, ERR_PTR on failure | |
| 158 | 158 | */ |
| 159 | 159 | struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, |
| 160 | 160 | struct ib_udata *udata, void *obj) |
| @@ -166,7 +166,7 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, · 5 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node); |
| 168 | 168 | if (!ip) |
| 169 | − return ip; | |
| 169 | + return ERR_PTR(-ENOMEM); | |
| 170 | 170 | |
| 171 | 171 | size = PAGE_ALIGN(size); |
| 172 | 172 | |
| @@ -1244,8 +1244,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, · 1243 unmodified lines | ||
| 1244 | 1244 | |
| 1245 | 1245 | qp->ip = rvt_create_mmap_info(rdi, s, udata, |
| 1246 | 1246 | qp->r_rq.wq); |
| 1247 | − if (!qp->ip) { | |
| 1248 | − ret = ERR_PTR(-ENOMEM); | |
| 1247 | + if (IS_ERR(qp->ip)) { | |
| 1248 | + ret = ERR_CAST(qp->ip); | |
| 1249 | 1249 | goto bail_qpn; |
| 1250 | 1250 | } |
| 1251 | 1251 | |
| @@ -111,8 +111,8 @@ int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr, · 110 unmodified lines | ||
| 111 | 111 | u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz; |
| 112 | 112 | |
| 113 | 113 | srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); |
| 114 | − if (!srq->ip) { | |
| 115 | − ret = -ENOMEM; | |
| 114 | + if (IS_ERR(srq->ip)) { | |
| 115 | + ret = PTR_ERR(srq->ip); | |
| 116 | 116 | goto bail_wq; |
| 117 | 117 | } |
| 118 | 118 | |
| @@ -920,20 +920,27 @@ static int siw_fastreg_mr(struct ib_pd *pd, struct siw_sqe *sqe) · 919 unmodified lines | ||
| 920 | 920 | { |
| 921 | 921 | struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr; |
| 922 | 922 | struct siw_device *sdev = to_siw_dev(pd->device); |
| 923 | − struct siw_mem *mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | |
| 923 | + struct siw_mem *mem; | |
| 924 | 924 | int rv = 0; |
| 925 | 925 | |
| 926 | 926 | siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey); |
| 927 | 927 | |
| 928 | − if (unlikely(!mem || !base_mr)) { | |
| 928 | + if (unlikely(!base_mr)) { | |
| 929 | 929 | pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); |
| 930 | 930 | return -EINVAL; |
| 931 | 931 | } |
| 932 | + | |
| 932 | 933 | if (unlikely(base_mr->rkey >> 8 != sqe->rkey >> 8)) { |
| 933 | 934 | pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey); |
| 934 | − rv = -EINVAL; | |
| 935 | − goto out; | |
| 935 | + return -EINVAL; | |
| 936 | 936 | } |
| 937 | + | |
| 938 | + mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | |
| 939 | + if (unlikely(!mem)) { | |
| 940 | + pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); | |
| 941 | + return -EINVAL; | |
| 942 | + } | |
| 943 | + | |
| 937 | 944 | if (unlikely(mem->pd != pd)) { |
| 938 | 945 | pr_warn("siw: fastreg: PD mismatch\n"); |
| 939 | 946 | rv = -EINVAL; |
| @@ -362,7 +362,7 @@ config IPMMU_VMSA · 361 unmodified lines | ||
| 362 | 362 | |
| 363 | 363 | config SPAPR_TCE_IOMMU |
| 364 | 364 | bool "sPAPR TCE IOMMU Support" |
| 365 | − depends on PPC_POWERNV || PPC_PSERIES || (PPC && COMPILE_TEST) | |
| 365 | + depends on PPC_POWERNV || PPC_PSERIES | |
| 366 | 366 | select IOMMU_API |
| 367 | 367 | help |
| 368 | 368 | Enables bits of IOMMU API required by VFIO. The iommu_ops |
| @@ -457,7 +457,7 @@ config S390_AP_IOMMU · 88 unmodified lines | ||
| 457 | 457 | |
| 458 | 458 | config MTK_IOMMU |
| 459 | 459 | bool "MTK IOMMU Support" |
| 460 | − depends on ARM || ARM64 || COMPILE_TEST | |
| 460 | + depends on HAS_DMA | |
| 461 | 461 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 462 | 462 | select ARM_DMA_USE_IOMMU |
| 463 | 463 | select IOMMU_API |
| @@ -2936,7 +2936,7 @@ static int __init parse_amd_iommu_intr(char *str) · 2935 unmodified lines | ||
| 2936 | 2936 | { |
| 2937 | 2937 | for (; *str; ++str) { |
| 2938 | 2938 | if (strncmp(str, "legacy", 6) == 0) { |
| 2939 | − amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; | |
| 2939 | + amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA; | |
| 2940 | 2940 | break; |
| 2941 | 2941 | } |
| 2942 | 2942 | if (strncmp(str, "vapic", 5) == 0) { |
| @@ -371,11 +371,11 @@ int dmar_disabled = 0; · 370 unmodified lines | ||
| 371 | 371 | int dmar_disabled = 1; |
| 372 | 372 | #endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */ |
| 373 | 373 | |
| 374 | −#ifdef INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON | |
| 374 | +#ifdef CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON | |
| 375 | 375 | int intel_iommu_sm = 1; |
| 376 | 376 | #else |
| 377 | 377 | int intel_iommu_sm; |
| 378 | −#endif /* INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ | |
| 378 | +#endif /* CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ | |
| 379 | 379 | |
| 380 | 380 | int intel_iommu_enabled = 0; |
| 381 | 381 | EXPORT_SYMBOL_GPL(intel_iommu_enabled); |
| @@ -184,6 +184,7 @@ static struct dev_iommu *dev_iommu_get(struct device *dev) · 183 unmodified lines | ||
| 184 | 184 | |
| 185 | 185 | static void dev_iommu_free(struct device *dev) |
| 186 | 186 | { |
| 187 | + iommu_fwspec_free(dev); | |
| 187 | 188 | kfree(dev->iommu); |
| 188 | 189 | dev->iommu = NULL; |
| 189 | 190 | } |
| @@ -814,8 +814,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev) · 813 unmodified lines | ||
| 814 | 814 | qcom_iommu->dev = dev; |
| 815 | 815 | |
| 816 | 816 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 817 | − if (res) | |
| 817 | + if (res) { | |
| 818 | 818 | qcom_iommu->local_base = devm_ioremap_resource(dev, res); |
| 819 | + if (IS_ERR(qcom_iommu->local_base)) | |
| 820 | + return PTR_ERR(qcom_iommu->local_base); | |
| 821 | + } | |
| 819 | 822 | |
| 820 | 823 | qcom_iommu->iface_clk = devm_clk_get(dev, "iface"); |
| 821 | 824 | if (IS_ERR(qcom_iommu->iface_clk)) { |
| @@ -585,10 +585,12 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) · 584 unmodified lines | ||
| 585 | 585 | |
| 586 | 586 | /* Do we need to select a new pgpath? */ |
| 587 | 587 | pgpath = READ_ONCE(m->current_pgpath); |
| 588 | − queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 589 | − if (!pgpath || !queue_io) | |
| 588 | + if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 590 | 589 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
| 591 | 590 | |
| 591 | + /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ | |
| 592 | + queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 593 | + | |
| 592 | 594 | if ((pgpath && queue_io) || |
| 593 | 595 | (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { |
| 594 | 596 | /* Queue for the daemon to resubmit */ |
| @@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, · 434 unmodified lines | ||
| 435 | 435 | fio->level++; |
| 436 | 436 | |
| 437 | 437 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) |
| 438 | − block += v->data_blocks; | |
| 438 | + block = block - v->hash_start + v->data_blocks; | |
| 439 | 439 | |
| 440 | 440 | /* |
| 441 | 441 | * For RS(M, N), the continuous FEC data is divided into blocks of N |
| @@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 930 unmodified lines | ||
| 931 | 931 | return 0; |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | +static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors) | |
| 935 | +{ | |
| 936 | + struct dm_io_region region; | |
| 937 | + struct dm_io_request req; | |
| 938 | + | |
| 939 | + region.bdev = wc->ssd_dev->bdev; | |
| 940 | + region.sector = wc->start_sector; | |
| 941 | + region.count = n_sectors; | |
| 942 | + req.bi_op = REQ_OP_READ; | |
| 943 | + req.bi_op_flags = REQ_SYNC; | |
| 944 | + req.mem.type = DM_IO_VMA; | |
| 945 | + req.mem.ptr.vma = (char *)wc->memory_map; | |
| 946 | + req.client = wc->dm_io; | |
| 947 | + req.notify.fn = NULL; | |
| 948 | + | |
| 949 | + return dm_io(&req, 1, ®ion, NULL); | |
| 950 | +} | |
| 951 | + | |
| 934 | 952 | static void writecache_resume(struct dm_target *ti) |
| 935 | 953 | { |
| 936 | 954 | struct dm_writecache *wc = ti->private; |
| @@ -941,8 +959,18 @@ static void writecache_resume(struct dm_target *ti) · 4 unmodified lines | ||
| 941 | 959 | |
| 942 | 960 | wc_lock(wc); |
| 943 | 961 | |
| 944 | − if (WC_MODE_PMEM(wc)) | |
| 962 | + if (WC_MODE_PMEM(wc)) { | |
| 945 | 963 | persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size); |
| 964 | + } else { | |
| 965 | + r = writecache_read_metadata(wc, wc->metadata_sectors); | |
| 966 | + if (r) { | |
| 967 | + size_t sb_entries_offset; | |
| 968 | + writecache_error(wc, r, "unable to read metadata: %d", r); | |
| 969 | + sb_entries_offset = offsetof(struct wc_memory_superblock, entries); | |
| 970 | + memset((char *)wc->memory_map + sb_entries_offset, -1, | |
| 971 | + (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset); | |
| 972 | + } | |
| 973 | + } | |
| 946 | 974 | |
| 947 | 975 | wc->tree = RB_ROOT; |
| 948 | 976 | INIT_LIST_HEAD(&wc->lru); |
| @@ -2102,6 +2130,12 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) · 1153 unmodified lines | ||
| 2102 | 2130 | ti->error = "Invalid block size"; |
| 2103 | 2131 | goto bad; |
| 2104 | 2132 | } |
| 2133 | + if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) || | |
| 2134 | + wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) { | |
| 2135 | + r = -EINVAL; | |
| 2136 | + ti->error = "Block size is smaller than device logical block size"; | |
| 2137 | + goto bad; | |
| 2138 | + } | |
| 2105 | 2139 | wc->block_size_bits = __ffs(wc->block_size); |
| 2106 | 2140 | |
| 2107 | 2141 | wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; |
| @@ -2200,8 +2234,6 @@ invalid_optional: · 92 unmodified lines | ||
| 2200 | 2234 | goto bad; |
| 2201 | 2235 | } |
| 2202 | 2236 | } else { |
| 2203 | − struct dm_io_region region; | |
| 2204 | − struct dm_io_request req; | |
| 2205 | 2237 | size_t n_blocks, n_metadata_blocks; |
| 2206 | 2238 | uint64_t n_bitmap_bits; |
| 2207 | 2239 | |
| @@ -2258,19 +2290,9 @@ invalid_optional: · 50 unmodified lines | ||
| 2258 | 2290 | goto bad; |
| 2259 | 2291 | } |
| 2260 | 2292 | |
| 2261 | − region.bdev = wc->ssd_dev->bdev; | |
| 2262 | − region.sector = wc->start_sector; | |
| 2263 | − region.count = wc->metadata_sectors; | |
| 2264 | − req.bi_op = REQ_OP_READ; | |
| 2265 | − req.bi_op_flags = REQ_SYNC; | |
| 2266 | − req.mem.type = DM_IO_VMA; | |
| 2267 | − req.mem.ptr.vma = (char *)wc->memory_map; | |
| 2268 | − req.client = wc->dm_io; | |
| 2269 | − req.notify.fn = NULL; | |
| 2270 | − | |
| 2271 | − r = dm_io(&req, 1, ®ion, NULL); | |
| 2293 | + r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT); | |
| 2272 | 2294 | if (r) { |
| 2273 | − ti->error = "Unable to read metadata"; | |
| 2295 | + ti->error = "Unable to read first block of metadata"; | |
| 2274 | 2296 | goto bad; |
| 2275 | 2297 | } |
| 2276 | 2298 | } |
| @@ -878,7 +878,7 @@ static int mmc_send_hpi_cmd(struct mmc_card *card) · 877 unmodified lines | ||
| 878 | 878 | * Issued High Priority Interrupt, and check for card status |
| 879 | 879 | * until out-of prg-state. |
| 880 | 880 | */ |
| 881 | −int mmc_interrupt_hpi(struct mmc_card *card) | |
| 881 | +static int mmc_interrupt_hpi(struct mmc_card *card) | |
| 882 | 882 | { |
| 883 | 883 | int err; |
| 884 | 884 | u32 status; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/delay.h> |
| 6 | 6 | #include <linux/highmem.h> |
| 7 | 7 | #include <linux/io.h> |
| 8 | +#include <linux/iopoll.h> | |
| 8 | 9 | #include <linux/module.h> |
| 9 | 10 | #include <linux/dma-mapping.h> |
| 10 | 11 | #include <linux/slab.h> |
| @@ -349,12 +350,16 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) · 338 unmodified lines | ||
| 349 | 350 | /* CQHCI is idle and should halt immediately, so set a small timeout */ |
| 350 | 351 | #define CQHCI_OFF_TIMEOUT 100 |
| 351 | 352 | |
| 353 | +static u32 cqhci_read_ctl(struct cqhci_host *cq_host) | |
| 354 | +{ | |
| 355 | + return cqhci_readl(cq_host, CQHCI_CTL); | |
| 356 | +} | |
| 357 | + | |
| 352 | 358 | static void cqhci_off(struct mmc_host *mmc) |
| 353 | 359 | { |
| 354 | 360 | struct cqhci_host *cq_host = mmc->cqe_private; |
| 355 | − ktime_t timeout; | |
| 356 | − bool timed_out; | |
| 357 | 361 | u32 reg; |
| 362 | + int err; | |
| 358 | 363 | |
| 359 | 364 | if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) |
| 360 | 365 | return; |
| @@ -364,15 +369,9 @@ static void cqhci_off(struct mmc_host *mmc) · 3 unmodified lines | ||
| 364 | 369 | |
| 365 | 370 | cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); |
| 366 | 371 | |
| 367 | − timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT); | |
| 368 | − while (1) { | |
| 369 | − timed_out = ktime_compare(ktime_get(), timeout) > 0; | |
| 370 | − reg = cqhci_readl(cq_host, CQHCI_CTL); | |
| 371 | − if ((reg & CQHCI_HALT) || timed_out) | |
| 372 | − break; | |
| 373 | − } | |
| 374 | − | |
| 375 | − if (timed_out) | |
| 372 | + err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg, | |
| 373 | + reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT); | |
| 374 | + if (err < 0) | |
| 376 | 375 | pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); |
| 377 | 376 | else |
| 378 | 377 | pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); |
| @@ -357,14 +357,6 @@ static void meson_mx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) · 356 unmodified lines | ||
| 357 | 357 | meson_mx_mmc_start_cmd(mmc, mrq->cmd); |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | −static int meson_mx_mmc_card_busy(struct mmc_host *mmc) | |
| 361 | −{ | |
| 362 | − struct meson_mx_mmc_host *host = mmc_priv(mmc); | |
| 363 | − u32 irqc = readl(host->base + MESON_MX_SDIO_IRQC); | |
| 364 | − | |
| 365 | − return !!(irqc & MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK); | |
| 366 | −} | |
| 367 | − | |
| 368 | 360 | static void meson_mx_mmc_read_response(struct mmc_host *mmc, |
| 369 | 361 | struct mmc_command *cmd) |
| 370 | 362 | { |
| @@ -506,7 +498,6 @@ static void meson_mx_mmc_timeout(struct timer_list *t) · 135 unmodified lines | ||
| 506 | 498 | static struct mmc_host_ops meson_mx_mmc_ops = { |
| 507 | 499 | .request = meson_mx_mmc_request, |
| 508 | 500 | .set_ios = meson_mx_mmc_set_ios, |
| 509 | − .card_busy = meson_mx_mmc_card_busy, | |
| 510 | 501 | .get_cd = mmc_gpio_get_cd, |
| 511 | 502 | .get_ro = mmc_gpio_get_ro, |
| 512 | 503 | }; |
| @@ -570,7 +561,7 @@ static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host) · 57 unmodified lines | ||
| 570 | 561 | mmc->f_max = clk_round_rate(host->cfg_div_clk, |
| 571 | 562 | clk_get_rate(host->parent_clk)); |
| 572 | 563 | |
| 573 | − mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | |
| 564 | + mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY; | |
| 574 | 565 | mmc->ops = &meson_mx_mmc_ops; |
| 575 | 566 | |
| 576 | 567 | ret = mmc_of_parse(mmc); |
| @@ -2087,6 +2087,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) · 2086 unmodified lines | ||
| 2087 | 2087 | goto clk_disable; |
| 2088 | 2088 | } |
| 2089 | 2089 | |
| 2090 | + msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; | |
| 2091 | + | |
| 2090 | 2092 | pm_runtime_get_noresume(&pdev->dev); |
| 2091 | 2093 | pm_runtime_set_active(&pdev->dev); |
| 2092 | 2094 | pm_runtime_enable(&pdev->dev); |
| @@ -601,6 +601,9 @@ static int intel_select_drive_strength(struct mmc_card *card, · 600 unmodified lines | ||
| 601 | 601 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 602 | 602 | struct intel_host *intel_host = sdhci_pci_priv(slot); |
| 603 | 603 | |
| 604 | + if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv)) | |
| 605 | + return 0; | |
| 606 | + | |
| 604 | 607 | return intel_host->drv_strength; |
| 605 | 608 | } |
| 606 | 609 | |
| @@ -235,6 +235,16 @@ static void xenon_voltage_switch(struct sdhci_host *host) · 234 unmodified lines | ||
| 235 | 235 | { |
| 236 | 236 | /* Wait for 5ms after set 1.8V signal enable bit */ |
| 237 | 237 | usleep_range(5000, 5500); |
| 238 | + | |
| 239 | + /* | |
| 240 | + * For some reason the controller's Host Control2 register reports | |
| 241 | + * the bit representing 1.8V signaling as 0 when read after it was | |
| 242 | + * written as 1. Subsequent read reports 1. | |
| 243 | + * | |
| 244 | + * Since this may cause some issues, do an empty read of the Host | |
| 245 | + * Control2 register here to circumvent this. | |
| 246 | + */ | |
| 247 | + sdhci_readw(host, SDHCI_HOST_CONTROL2); | |
| 238 | 248 | } |
| 239 | 249 | |
| 240 | 250 | static const struct sdhci_ops sdhci_xenon_ops = { |
| @@ -3642,6 +3642,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 3641 unmodified lines | ||
| 3642 | 3642 | |
| 3643 | 3643 | return; |
| 3644 | 3644 | out_put_disk: |
| 3645 | + /* prevent double queue cleanup */ | |
| 3646 | + ns->disk->queue = NULL; | |
| 3645 | 3647 | put_disk(ns->disk); |
| 3646 | 3648 | out_unlink_ns: |
| 3647 | 3649 | mutex_lock(&ctrl->subsys->lock); |
| @@ -3732,6 +3732,13 @@ qla2x00_remove_one(struct pci_dev *pdev) · 3731 unmodified lines | ||
| 3732 | 3732 | } |
| 3733 | 3733 | qla2x00_wait_for_hba_ready(base_vha); |
| 3734 | 3734 | |
| 3735 | + /* | |
| 3736 | + * if UNLOADING flag is already set, then continue unload, | |
| 3737 | + * where it was set first. | |
| 3738 | + */ | |
| 3739 | + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 3740 | + return; | |
| 3741 | + | |
| 3735 | 3742 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
| 3736 | 3743 | IS_QLA28XX(ha)) { |
| 3737 | 3744 | if (ha->flags.fw_started) |
| @@ -3750,15 +3757,6 @@ qla2x00_remove_one(struct pci_dev *pdev) · 12 unmodified lines | ||
| 3750 | 3757 | |
| 3751 | 3758 | qla2x00_wait_for_sess_deletion(base_vha); |
| 3752 | 3759 | |
| 3753 | − /* | |
| 3754 | − * if UNLOAD flag is already set, then continue unload, | |
| 3755 | − * where it was set first. | |
| 3756 | − */ | |
| 3757 | − if (test_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 3758 | − return; | |
| 3759 | − | |
| 3760 | − set_bit(UNLOADING, &base_vha->dpc_flags); | |
| 3761 | − | |
| 3762 | 3760 | qla_nvme_delete(base_vha); |
| 3763 | 3761 | |
| 3764 | 3762 | dma_free_coherent(&ha->pdev->dev, |
| @@ -4864,6 +4862,9 @@ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) · 1099 unmodified lines | ||
| 4864 | 4862 | struct qla_work_evt *e; |
| 4865 | 4863 | uint8_t bail; |
| 4866 | 4864 | |
| 4865 | + if (test_bit(UNLOADING, &vha->dpc_flags)) | |
| 4866 | + return NULL; | |
| 4867 | + | |
| 4867 | 4868 | QLA_VHA_MARK_BUSY(vha, bail); |
| 4868 | 4869 | if (bail) |
| 4869 | 4870 | return NULL; |
| @@ -6628,13 +6629,6 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 1758 unmodified lines | ||
| 6628 | 6629 | struct pci_dev *pdev = ha->pdev; |
| 6629 | 6630 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
| 6630 | 6631 | |
| 6631 | − /* | |
| 6632 | − * if UNLOAD flag is already set, then continue unload, | |
| 6633 | − * where it was set first. | |
| 6634 | − */ | |
| 6635 | − if (test_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 6636 | − return; | |
| 6637 | − | |
| 6638 | 6632 | ql_log(ql_log_warn, base_vha, 0x015b, |
| 6639 | 6633 | "Disabling adapter.\n"); |
| 6640 | 6634 | |
| @@ -6645,9 +6639,14 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 4 unmodified lines | ||
| 6645 | 6639 | return; |
| 6646 | 6640 | } |
| 6647 | 6641 | |
| 6648 | − qla2x00_wait_for_sess_deletion(base_vha); | |
| 6642 | + /* | |
| 6643 | + * if UNLOADING flag is already set, then continue unload, | |
| 6644 | + * where it was set first. | |
| 6645 | + */ | |
| 6646 | + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 6647 | + return; | |
| 6649 | 6648 | |
| 6650 | − set_bit(UNLOADING, &base_vha->dpc_flags); | |
| 6649 | + qla2x00_wait_for_sess_deletion(base_vha); | |
| 6651 | 6650 | |
| 6652 | 6651 | qla2x00_delete_all_vps(ha, base_vha); |
| 6653 | 6652 | |
| @@ -2284,6 +2284,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) · 2283 unmodified lines | ||
| 2284 | 2284 | switch (oldstate) { |
| 2285 | 2285 | case SDEV_RUNNING: |
| 2286 | 2286 | case SDEV_CREATED_BLOCK: |
| 2287 | + case SDEV_QUIESCE: | |
| 2287 | 2288 | case SDEV_OFFLINE: |
| 2288 | 2289 | break; |
| 2289 | 2290 | default: |
| @@ -432,7 +432,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) · 431 unmodified lines | ||
| 432 | 432 | target_to_linux_sector(dev, cmd->t_task_lba), |
| 433 | 433 | target_to_linux_sector(dev, |
| 434 | 434 | sbc_get_write_same_sectors(cmd)), |
| 435 | − GFP_KERNEL, false); | |
| 435 | + GFP_KERNEL, BLKDEV_ZERO_NOUNMAP); | |
| 436 | 436 | if (ret) |
| 437 | 437 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 438 | 438 | |
| @@ -88,7 +88,7 @@ config HVC_DCC · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | config HVC_RISCV_SBI |
| 90 | 90 | bool "RISC-V SBI console support" |
| 91 | − depends on RISCV_SBI | |
| 91 | + depends on RISCV_SBI_V01 | |
| 92 | 92 | select HVC_DRIVER |
| 93 | 93 | help |
| 94 | 94 | This enables support for console output via RISC-V SBI calls, which |
| @@ -86,7 +86,7 @@ config SERIAL_EARLYCON_ARM_SEMIHOST · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | config SERIAL_EARLYCON_RISCV_SBI |
| 88 | 88 | bool "Early console using RISC-V SBI" |
| 89 | − depends on RISCV_SBI | |
| 89 | + depends on RISCV_SBI_V01 | |
| 90 | 90 | select SERIAL_CORE |
| 91 | 91 | select SERIAL_CORE_CONSOLE |
| 92 | 92 | select SERIAL_EARLYCON |
| @@ -342,8 +342,8 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 341 unmodified lines | ||
| 342 | 342 | vma = find_vma_intersection(mm, vaddr, vaddr + 1); |
| 343 | 343 | |
| 344 | 344 | if (vma && vma->vm_flags & VM_PFNMAP) { |
| 345 | − *pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | |
| 346 | − if (is_invalid_reserved_pfn(*pfn)) | |
| 345 | + if (!follow_pfn(vma, vaddr, pfn) && | |
| 346 | + is_invalid_reserved_pfn(*pfn)) | |
| 347 | 347 | ret = 0; |
| 348 | 348 | } |
| 349 | 349 | done: |
| @@ -555,7 +555,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data, · 205 unmodified lines | ||
| 555 | 555 | continue; |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | − remote_vaddr = dma->vaddr + iova - dma->iova; | |
| 558 | + remote_vaddr = dma->vaddr + (iova - dma->iova); | |
| 559 | 559 | ret = vfio_pin_page_external(dma, remote_vaddr, &phys_pfn[i], |
| 560 | 560 | do_accounting); |
| 561 | 561 | if (ret) |
| @@ -2345,10 +2345,10 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu, · 1783 unmodified lines | ||
| 2345 | 2345 | vaddr = dma->vaddr + offset; |
| 2346 | 2346 | |
| 2347 | 2347 | if (write) |
| 2348 | − *copied = __copy_to_user((void __user *)vaddr, data, | |
| 2348 | + *copied = copy_to_user((void __user *)vaddr, data, | |
| 2349 | 2349 | count) ? 0 : count; |
| 2350 | 2350 | else |
| 2351 | − *copied = __copy_from_user(data, (void __user *)vaddr, | |
| 2351 | + *copied = copy_from_user(data, (void __user *)vaddr, | |
| 2352 | 2352 | count) ? 0 : count; |
| 2353 | 2353 | if (kthread) |
| 2354 | 2354 | unuse_mm(mm); |
| @@ -391,7 +391,7 @@ static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr) · 390 unmodified lines | ||
| 391 | 391 | struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; |
| 392 | 392 | struct rb_node *parent = NULL; |
| 393 | 393 | struct prelim_ref *ref = NULL; |
| 394 | − struct prelim_ref target = {0}; | |
| 394 | + struct prelim_ref target = {}; | |
| 395 | 395 | int result; |
| 396 | 396 | |
| 397 | 397 | target.parent = bytenr; |
| @@ -916,7 +916,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 915 unmodified lines | ||
| 916 | 916 | path = btrfs_alloc_path(); |
| 917 | 917 | if (!path) { |
| 918 | 918 | ret = -ENOMEM; |
| 919 | − goto out; | |
| 919 | + goto out_put_group; | |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | 922 | /* |
| @@ -954,7 +954,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 31 unmodified lines | ||
| 954 | 954 | ret = btrfs_orphan_add(trans, BTRFS_I(inode)); |
| 955 | 955 | if (ret) { |
| 956 | 956 | btrfs_add_delayed_iput(inode); |
| 957 | − goto out; | |
| 957 | + goto out_put_group; | |
| 958 | 958 | } |
| 959 | 959 | clear_nlink(inode); |
| 960 | 960 | /* One for the block groups ref */ |
| @@ -977,13 +977,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | ||
| 977 | 977 | |
| 978 | 978 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
| 979 | 979 | if (ret < 0) |
| 980 | − goto out; | |
| 980 | + goto out_put_group; | |
| 981 | 981 | if (ret > 0) |
| 982 | 982 | btrfs_release_path(path); |
| 983 | 983 | if (ret == 0) { |
| 984 | 984 | ret = btrfs_del_item(trans, tree_root, path); |
| 985 | 985 | if (ret) |
| 986 | − goto out; | |
| 986 | + goto out_put_group; | |
| 987 | 987 | btrfs_release_path(path); |
| 988 | 988 | } |
| 989 | 989 | |
| @@ -1102,9 +1102,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 112 unmodified lines | ||
| 1102 | 1102 | |
| 1103 | 1103 | ret = remove_block_group_free_space(trans, block_group); |
| 1104 | 1104 | if (ret) |
| 1105 | − goto out; | |
| 1105 | + goto out_put_group; | |
| 1106 | 1106 | |
| 1107 | − btrfs_put_block_group(block_group); | |
| 1107 | + /* Once for the block groups rbtree */ | |
| 1108 | 1108 | btrfs_put_block_group(block_group); |
| 1109 | 1109 | |
| 1110 | 1110 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| @@ -1127,6 +1127,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | ||
| 1127 | 1127 | /* once for the tree */ |
| 1128 | 1128 | free_extent_map(em); |
| 1129 | 1129 | } |
| 1130 | + | |
| 1131 | +out_put_group: | |
| 1132 | + /* Once for the lookup reference */ | |
| 1133 | + btrfs_put_block_group(block_group); | |
| 1130 | 1134 | out: |
| 1131 | 1135 | if (remove_rsv) |
| 1132 | 1136 | btrfs_delayed_refs_rsv_release(fs_info, 1); |
| @@ -1288,11 +1292,15 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans, · 155 unmodified lines | ||
| 1288 | 1292 | if (ret) |
| 1289 | 1293 | goto err; |
| 1290 | 1294 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1295 | + if (prev_trans) | |
| 1296 | + btrfs_put_transaction(prev_trans); | |
| 1291 | 1297 | |
| 1292 | 1298 | return true; |
| 1293 | 1299 | |
| 1294 | 1300 | err: |
| 1295 | 1301 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1302 | + if (prev_trans) | |
| 1303 | + btrfs_put_transaction(prev_trans); | |
| 1296 | 1304 | btrfs_dec_block_group_ro(bg); |
| 1297 | 1305 | return false; |
| 1298 | 1306 | } |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | |
| 3 | 3 | #ifndef BTRFS_DISCARD_H |
| 4 | 4 | #define BTRFS_DISCARD_H |
| @@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info) · 2035 unmodified lines | ||
| 2036 | 2036 | for (i = 0; i < ret; i++) |
| 2037 | 2037 | btrfs_drop_and_free_fs_root(fs_info, gang[i]); |
| 2038 | 2038 | } |
| 2039 | − | |
| 2040 | − if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) | |
| 2041 | − btrfs_free_log_root_tree(NULL, fs_info); | |
| 2042 | 2039 | } |
| 2043 | 2040 | |
| 2044 | 2041 | static void btrfs_init_scrub(struct btrfs_fs_info *fs_info) |
| @@ -3888,7 +3885,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, · 1843 unmodified lines | ||
| 3888 | 3885 | spin_unlock(&fs_info->fs_roots_radix_lock); |
| 3889 | 3886 | |
| 3890 | 3887 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
| 3891 | − btrfs_free_log(NULL, root); | |
| 3888 | + ASSERT(root->log_root == NULL); | |
| 3892 | 3889 | if (root->reloc_root) { |
| 3893 | 3890 | btrfs_put_root(root->reloc_root); |
| 3894 | 3891 | root->reloc_root = NULL; |
| @@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) · 316 unmodified lines | ||
| 4211 | 4208 | up_write(&fs_info->cleanup_work_sem); |
| 4212 | 4209 | } |
| 4213 | 4210 | |
| 4211 | +static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info) | |
| 4212 | +{ | |
| 4213 | + struct btrfs_root *gang[8]; | |
| 4214 | + u64 root_objectid = 0; | |
| 4215 | + int ret; | |
| 4216 | + | |
| 4217 | + spin_lock(&fs_info->fs_roots_radix_lock); | |
| 4218 | + while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, | |
| 4219 | + (void **)gang, root_objectid, | |
| 4220 | + ARRAY_SIZE(gang))) != 0) { | |
| 4221 | + int i; | |
| 4222 | + | |
| 4223 | + for (i = 0; i < ret; i++) | |
| 4224 | + gang[i] = btrfs_grab_root(gang[i]); | |
| 4225 | + spin_unlock(&fs_info->fs_roots_radix_lock); | |
| 4226 | + | |
| 4227 | + for (i = 0; i < ret; i++) { | |
| 4228 | + if (!gang[i]) | |
| 4229 | + continue; | |
| 4230 | + root_objectid = gang[i]->root_key.objectid; | |
| 4231 | + btrfs_free_log(NULL, gang[i]); | |
| 4232 | + btrfs_put_root(gang[i]); | |
| 4233 | + } | |
| 4234 | + root_objectid++; | |
| 4235 | + spin_lock(&fs_info->fs_roots_radix_lock); | |
| 4236 | + } | |
| 4237 | + spin_unlock(&fs_info->fs_roots_radix_lock); | |
| 4238 | + btrfs_free_log_root_tree(NULL, fs_info); | |
| 4239 | +} | |
| 4240 | + | |
| 4214 | 4241 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) |
| 4215 | 4242 | { |
| 4216 | 4243 | struct btrfs_ordered_extent *ordered; |
| @@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) · 386 unmodified lines | ||
| 4603 | 4630 | btrfs_destroy_delayed_inodes(fs_info); |
| 4604 | 4631 | btrfs_assert_delayed_root_empty(fs_info); |
| 4605 | 4632 | btrfs_destroy_all_delalloc_inodes(fs_info); |
| 4633 | + btrfs_drop_all_logs(fs_info); | |
| 4606 | 4634 | mutex_unlock(&fs_info->transaction_kthread_mutex); |
| 4607 | 4635 | |
| 4608 | 4636 | return 0; |
| @@ -4559,6 +4559,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) · 4558 unmodified lines | ||
| 4559 | 4559 | if (IS_ERR(fs_root)) { |
| 4560 | 4560 | err = PTR_ERR(fs_root); |
| 4561 | 4561 | list_add_tail(&reloc_root->root_list, &reloc_roots); |
| 4562 | + btrfs_end_transaction(trans); | |
| 4562 | 4563 | goto out_unset; |
| 4563 | 4564 | } |
| 4564 | 4565 | |
| @@ -662,10 +662,19 @@ again: · 661 unmodified lines | ||
| 662 | 662 | } |
| 663 | 663 | |
| 664 | 664 | got_it: |
| 665 | − btrfs_record_root_in_trans(h, root); | |
| 666 | − | |
| 667 | 665 | if (!current->journal_info) |
| 668 | 666 | current->journal_info = h; |
| 667 | + | |
| 668 | + /* | |
| 669 | + * btrfs_record_root_in_trans() needs to alloc new extents, and may | |
| 670 | + * call btrfs_join_transaction() while we're also starting a | |
| 671 | + * transaction. | |
| 672 | + * | |
| 673 | + * Thus it need to be called after current->journal_info initialized, | |
| 674 | + * or we can deadlock. | |
| 675 | + */ | |
| 676 | + btrfs_record_root_in_trans(h, root); | |
| 677 | + | |
| 669 | 678 | return h; |
| 670 | 679 | |
| 671 | 680 | join_fail: |
| @@ -4226,6 +4226,9 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 4225 unmodified lines | ||
| 4226 | 4226 | const u64 ino = btrfs_ino(inode); |
| 4227 | 4227 | struct btrfs_path *dst_path = NULL; |
| 4228 | 4228 | bool dropped_extents = false; |
| 4229 | + u64 truncate_offset = i_size; | |
| 4230 | + struct extent_buffer *leaf; | |
| 4231 | + int slot; | |
| 4229 | 4232 | int ins_nr = 0; |
| 4230 | 4233 | int start_slot; |
| 4231 | 4234 | int ret; |
| @@ -4240,9 +4243,43 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 8 unmodified lines | ||
| 4240 | 4243 | if (ret < 0) |
| 4241 | 4244 | goto out; |
| 4242 | 4245 | |
| 4246 | + /* | |
| 4247 | + * We must check if there is a prealloc extent that starts before the | |
| 4248 | + * i_size and crosses the i_size boundary. This is to ensure later we | |
| 4249 | + * truncate down to the end of that extent and not to the i_size, as | |
| 4250 | + * otherwise we end up losing part of the prealloc extent after a log | |
| 4251 | + * replay and with an implicit hole if there is another prealloc extent | |
| 4252 | + * that starts at an offset beyond i_size. | |
| 4253 | + */ | |
| 4254 | + ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY); | |
| 4255 | + if (ret < 0) | |
| 4256 | + goto out; | |
| 4257 | + | |
| 4258 | + if (ret == 0) { | |
| 4259 | + struct btrfs_file_extent_item *ei; | |
| 4260 | + | |
| 4261 | + leaf = path->nodes[0]; | |
| 4262 | + slot = path->slots[0]; | |
| 4263 | + ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | |
| 4264 | + | |
| 4265 | + if (btrfs_file_extent_type(leaf, ei) == | |
| 4266 | + BTRFS_FILE_EXTENT_PREALLOC) { | |
| 4267 | + u64 extent_end; | |
| 4268 | + | |
| 4269 | + btrfs_item_key_to_cpu(leaf, &key, slot); | |
| 4270 | + extent_end = key.offset + | |
| 4271 | + btrfs_file_extent_num_bytes(leaf, ei); | |
| 4272 | + | |
| 4273 | + if (extent_end > i_size) | |
| 4274 | + truncate_offset = extent_end; | |
| 4275 | + } | |
| 4276 | + } else { | |
| 4277 | + ret = 0; | |
| 4278 | + } | |
| 4279 | + | |
| 4243 | 4280 | while (true) { |
| 4244 | − struct extent_buffer *leaf = path->nodes[0]; | |
| 4245 | − int slot = path->slots[0]; | |
| 4281 | + leaf = path->nodes[0]; | |
| 4282 | + slot = path->slots[0]; | |
| 4246 | 4283 | |
| 4247 | 4284 | if (slot >= btrfs_header_nritems(leaf)) { |
| 4248 | 4285 | if (ins_nr > 0) { |
| @@ -4280,7 +4317,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 31 unmodified lines | ||
| 4280 | 4317 | ret = btrfs_truncate_inode_items(trans, |
| 4281 | 4318 | root->log_root, |
| 4282 | 4319 | &inode->vfs_inode, |
| 4283 | − i_size, | |
| 4320 | + truncate_offset, | |
| 4284 | 4321 | BTRFS_EXTENT_DATA_KEY); |
| 4285 | 4322 | } while (ret == -EAGAIN); |
| 4286 | 4323 | if (ret) |
| @@ -524,6 +524,7 @@ enum { · 523 unmodified lines | ||
| 524 | 524 | REQ_F_OVERFLOW_BIT, |
| 525 | 525 | REQ_F_POLLED_BIT, |
| 526 | 526 | REQ_F_BUFFER_SELECTED_BIT, |
| 527 | + REQ_F_NO_FILE_TABLE_BIT, | |
| 527 | 528 | |
| 528 | 529 | /* not a real bit, just to check we're not overflowing the space */ |
| 529 | 530 | __REQ_F_LAST_BIT, |
| @@ -577,6 +578,8 @@ enum { · 47 unmodified lines | ||
| 577 | 578 | REQ_F_POLLED = BIT(REQ_F_POLLED_BIT), |
| 578 | 579 | /* buffer already selected */ |
| 579 | 580 | REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT), |
| 581 | + /* doesn't need file table for this request */ | |
| 582 | + REQ_F_NO_FILE_TABLE = BIT(REQ_F_NO_FILE_TABLE_BIT), | |
| 580 | 583 | }; |
| 581 | 584 | |
| 582 | 585 | struct async_poll { |
| @@ -799,6 +802,7 @@ static const struct io_op_def io_op_defs[] = { · 216 unmodified lines | ||
| 799 | 802 | .needs_file = 1, |
| 800 | 803 | .fd_non_neg = 1, |
| 801 | 804 | .needs_fs = 1, |
| 805 | + .file_table = 1, | |
| 802 | 806 | }, |
| 803 | 807 | [IORING_OP_READ] = { |
| 804 | 808 | .needs_mm = 1, |
| @@ -1291,7 +1295,7 @@ static struct io_kiocb *io_get_fallback_req(struct io_ring_ctx *ctx) · 486 unmodified lines | ||
| 1291 | 1295 | struct io_kiocb *req; |
| 1292 | 1296 | |
| 1293 | 1297 | req = ctx->fallback_req; |
| 1294 | − if (!test_and_set_bit_lock(0, (unsigned long *) ctx->fallback_req)) | |
| 1298 | + if (!test_and_set_bit_lock(0, (unsigned long *) &ctx->fallback_req)) | |
| 1295 | 1299 | return req; |
| 1296 | 1300 | |
| 1297 | 1301 | return NULL; |
| @@ -1378,7 +1382,7 @@ static void __io_free_req(struct io_kiocb *req) · 80 unmodified lines | ||
| 1378 | 1382 | if (likely(!io_is_fallback_req(req))) |
| 1379 | 1383 | kmem_cache_free(req_cachep, req); |
| 1380 | 1384 | else |
| 1381 | − clear_bit_unlock(0, (unsigned long *) req->ctx->fallback_req); | |
| 1385 | + clear_bit_unlock(0, (unsigned long *) &req->ctx->fallback_req); | |
| 1382 | 1386 | } |
| 1383 | 1387 | |
| 1384 | 1388 | struct req_batch { |
| @@ -2034,7 +2038,7 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd) · 649 unmodified lines | ||
| 2034 | 2038 | * any file. For now, just ensure that anything potentially problematic is done |
| 2035 | 2039 | * inline. |
| 2036 | 2040 | */ |
| 2037 | −static bool io_file_supports_async(struct file *file) | |
| 2041 | +static bool io_file_supports_async(struct file *file, int rw) | |
| 2038 | 2042 | { |
| 2039 | 2043 | umode_t mode = file_inode(file)->i_mode; |
| 2040 | 2044 | |
| @@ -2043,7 +2047,13 @@ static bool io_file_supports_async(struct file *file) · 2 unmodified lines | ||
| 2043 | 2047 | if (S_ISREG(mode) && file->f_op != &io_uring_fops) |
| 2044 | 2048 | return true; |
| 2045 | 2049 | |
| 2046 | − return false; | |
| 2050 | + if (!(file->f_mode & FMODE_NOWAIT)) | |
| 2051 | + return false; | |
| 2052 | + | |
| 2053 | + if (rw == READ) | |
| 2054 | + return file->f_op->read_iter != NULL; | |
| 2055 | + | |
| 2056 | + return file->f_op->write_iter != NULL; | |
| 2047 | 2057 | } |
| 2048 | 2058 | |
| 2049 | 2059 | static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| @@ -2571,7 +2581,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) · 521 unmodified lines | ||
| 2571 | 2581 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2572 | 2582 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2573 | 2583 | */ |
| 2574 | − if (force_nonblock && !io_file_supports_async(req->file)) | |
| 2584 | + if (force_nonblock && !io_file_supports_async(req->file, READ)) | |
| 2575 | 2585 | goto copy_iov; |
| 2576 | 2586 | |
| 2577 | 2587 | iov_count = iov_iter_count(&iter); |
| @@ -2594,7 +2604,8 @@ copy_iov: · 16 unmodified lines | ||
| 2594 | 2604 | if (ret) |
| 2595 | 2605 | goto out_free; |
| 2596 | 2606 | /* any defer here is final, must blocking retry */ |
| 2597 | − if (!(req->flags & REQ_F_NOWAIT)) | |
| 2607 | + if (!(req->flags & REQ_F_NOWAIT) && | |
| 2608 | + !file_can_poll(req->file)) | |
| 2598 | 2609 | req->flags |= REQ_F_MUST_PUNT; |
| 2599 | 2610 | return -EAGAIN; |
| 2600 | 2611 | } |
| @@ -2662,7 +2673,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock) · 61 unmodified lines | ||
| 2662 | 2673 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2663 | 2674 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2664 | 2675 | */ |
| 2665 | − if (force_nonblock && !io_file_supports_async(req->file)) | |
| 2676 | + if (force_nonblock && !io_file_supports_async(req->file, WRITE)) | |
| 2666 | 2677 | goto copy_iov; |
| 2667 | 2678 | |
| 2668 | 2679 | /* file path doesn't support NOWAIT for non-direct_IO */ |
| @@ -2716,7 +2727,8 @@ copy_iov: · 47 unmodified lines | ||
| 2716 | 2727 | if (ret) |
| 2717 | 2728 | goto out_free; |
| 2718 | 2729 | /* any defer here is final, must blocking retry */ |
| 2719 | − req->flags |= REQ_F_MUST_PUNT; | |
| 2730 | + if (!file_can_poll(req->file)) | |
| 2731 | + req->flags |= REQ_F_MUST_PUNT; | |
| 2720 | 2732 | return -EAGAIN; |
| 2721 | 2733 | } |
| 2722 | 2734 | } |
| @@ -2756,15 +2768,6 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 33 unmodified lines | ||
| 2756 | 2768 | return 0; |
| 2757 | 2769 | } |
| 2758 | 2770 | |
| 2759 | −static bool io_splice_punt(struct file *file) | |
| 2760 | −{ | |
| 2761 | − if (get_pipe_info(file)) | |
| 2762 | − return false; | |
| 2763 | − if (!io_file_supports_async(file)) | |
| 2764 | − return true; | |
| 2765 | − return !(file->f_flags & O_NONBLOCK); | |
| 2766 | −} | |
| 2767 | − | |
| 2768 | 2771 | static int io_splice(struct io_kiocb *req, bool force_nonblock) |
| 2769 | 2772 | { |
| 2770 | 2773 | struct io_splice *sp = &req->splice; |
| @@ -2774,11 +2777,8 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock) · 3 unmodified lines | ||
| 2774 | 2777 | loff_t *poff_in, *poff_out; |
| 2775 | 2778 | long ret; |
| 2776 | 2779 | |
| 2777 | − if (force_nonblock) { | |
| 2778 | − if (io_splice_punt(in) || io_splice_punt(out)) | |
| 2779 | − return -EAGAIN; | |
| 2780 | − flags |= SPLICE_F_NONBLOCK; | |
| 2781 | − } | |
| 2780 | + if (force_nonblock) | |
| 2781 | + return -EAGAIN; | |
| 2782 | 2782 | |
| 2783 | 2783 | poff_in = (sp->off_in == -1) ? NULL : &sp->off_in; |
| 2784 | 2784 | poff_out = (sp->off_out == -1) ? NULL : &sp->off_out; |
| @@ -3355,8 +3355,12 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock) · 570 unmodified lines | ||
| 3355 | 3355 | struct kstat stat; |
| 3356 | 3356 | int ret; |
| 3357 | 3357 | |
| 3358 | − if (force_nonblock) | |
| 3358 | + if (force_nonblock) { | |
| 3359 | + /* only need file table for an actual valid fd */ | |
| 3360 | + if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD) | |
| 3361 | + req->flags |= REQ_F_NO_FILE_TABLE; | |
| 3359 | 3362 | return -EAGAIN; |
| 3363 | + } | |
| 3360 | 3364 | |
| 3361 | 3365 | if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags)) |
| 3362 | 3366 | return -EINVAL; |
| @@ -3502,7 +3506,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr) · 139 unmodified lines | ||
| 3502 | 3506 | if (io_req_cancelled(req)) |
| 3503 | 3507 | return; |
| 3504 | 3508 | __io_sync_file_range(req); |
| 3505 | − io_put_req(req); /* put submission ref */ | |
| 3509 | + io_steal_work(req, workptr); | |
| 3506 | 3510 | } |
| 3507 | 3511 | |
| 3508 | 3512 | static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock) |
| @@ -5015,7 +5019,7 @@ static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 1506 unmodified lines | ||
| 5015 | 5019 | int ret; |
| 5016 | 5020 | |
| 5017 | 5021 | /* Still need defer if there is pending req in defer list. */ |
| 5018 | − if (!req_need_defer(req) && list_empty(&ctx->defer_list)) | |
| 5022 | + if (!req_need_defer(req) && list_empty_careful(&ctx->defer_list)) | |
| 5019 | 5023 | return 0; |
| 5020 | 5024 | |
| 5021 | 5025 | if (!req->io && io_alloc_async_ctx(req)) |
| @@ -5429,7 +5433,7 @@ static int io_grab_files(struct io_kiocb *req) · 407 unmodified lines | ||
| 5429 | 5433 | int ret = -EBADF; |
| 5430 | 5434 | struct io_ring_ctx *ctx = req->ctx; |
| 5431 | 5435 | |
| 5432 | − if (req->work.files) | |
| 5436 | + if (req->work.files || (req->flags & REQ_F_NO_FILE_TABLE)) | |
| 5433 | 5437 | return 0; |
| 5434 | 5438 | if (!ctx->ring_file) |
| 5435 | 5439 | return -EBADF; |
| @@ -7327,7 +7331,7 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) · 1891 unmodified lines | ||
| 7327 | 7331 | * it could cause shutdown to hang. |
| 7328 | 7332 | */ |
| 7329 | 7333 | while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait)) |
| 7330 | − cpu_relax(); | |
| 7334 | + cond_resched(); | |
| 7331 | 7335 | |
| 7332 | 7336 | io_kill_timeouts(ctx); |
| 7333 | 7337 | io_poll_remove_all(ctx); |
| @@ -55,6 +55,7 @@ EXPORT_SYMBOL(vfs_ioctl); · 54 unmodified lines | ||
| 55 | 55 | static int ioctl_fibmap(struct file *filp, int __user *p) |
| 56 | 56 | { |
| 57 | 57 | struct inode *inode = file_inode(filp); |
| 58 | + struct super_block *sb = inode->i_sb; | |
| 58 | 59 | int error, ur_block; |
| 59 | 60 | sector_t block; |
| 60 | 61 | |
| @@ -71,6 +72,13 @@ static int ioctl_fibmap(struct file *filp, int __user *p) · 10 unmodified lines | ||
| 71 | 72 | block = ur_block; |
| 72 | 73 | error = bmap(inode, &block); |
| 73 | 74 | |
| 75 | + if (block > INT_MAX) { | |
| 76 | + error = -ERANGE; | |
| 77 | + pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n", | |
| 78 | + current->comm, task_pid_nr(current), | |
| 79 | + sb->s_id, filp); | |
| 80 | + } | |
| 81 | + | |
| 74 | 82 | if (error) |
| 75 | 83 | ur_block = 0; |
| 76 | 84 | else |
| @@ -117,10 +117,7 @@ iomap_bmap_actor(struct inode *inode, loff_t pos, loff_t length, · 116 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | if (iomap->type == IOMAP_MAPPED) { |
| 119 | 119 | addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits; |
| 120 | − if (addr > INT_MAX) | |
| 121 | − WARN(1, "would truncate bmap result\n"); | |
| 122 | − else | |
| 123 | − *bno = addr; | |
| 120 | + *bno = addr; | |
| 124 | 121 | } |
| 125 | 122 | return 0; |
| 126 | 123 | } |
| @@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, · 252 unmodified lines | ||
| 253 | 253 | |
| 254 | 254 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
| 255 | 255 | { |
| 256 | − struct posix_acl *alloc = NULL, *dfacl = NULL; | |
| 256 | + struct posix_acl *orig = acl, *dfacl = NULL, *alloc; | |
| 257 | 257 | int status; |
| 258 | 258 | |
| 259 | 259 | if (S_ISDIR(inode->i_mode)) { |
| 260 | 260 | switch(type) { |
| 261 | 261 | case ACL_TYPE_ACCESS: |
| 262 | − alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT); | |
| 262 | + alloc = get_acl(inode, ACL_TYPE_DEFAULT); | |
| 263 | 263 | if (IS_ERR(alloc)) |
| 264 | 264 | goto fail; |
| 265 | + dfacl = alloc; | |
| 265 | 266 | break; |
| 266 | 267 | |
| 267 | 268 | case ACL_TYPE_DEFAULT: |
| 268 | − dfacl = acl; | |
| 269 | − alloc = acl = get_acl(inode, ACL_TYPE_ACCESS); | |
| 269 | + alloc = get_acl(inode, ACL_TYPE_ACCESS); | |
| 270 | 270 | if (IS_ERR(alloc)) |
| 271 | 271 | goto fail; |
| 272 | + dfacl = acl; | |
| 273 | + acl = alloc; | |
| 272 | 274 | break; |
| 273 | 275 | } |
| 274 | 276 | } |
| 275 | 277 | |
| 276 | 278 | if (acl == NULL) { |
| 277 | − alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | |
| 279 | + alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | |
| 278 | 280 | if (IS_ERR(alloc)) |
| 279 | 281 | goto fail; |
| 282 | + acl = alloc; | |
| 280 | 283 | } |
| 281 | 284 | status = __nfs3_proc_setacls(inode, acl, dfacl); |
| 282 | − posix_acl_release(alloc); | |
| 285 | +out: | |
| 286 | + if (acl != orig) | |
| 287 | + posix_acl_release(acl); | |
| 288 | + if (dfacl != orig) | |
| 289 | + posix_acl_release(dfacl); | |
| 283 | 290 | return status; |
| 284 | 291 | |
| 285 | 292 | fail: |
| 286 | − return PTR_ERR(alloc); | |
| 293 | + status = PTR_ERR(alloc); | |
| 294 | + goto out; | |
| 287 | 295 | } |
| 288 | 296 | |
| 289 | 297 | const struct xattr_handler *nfs3_xattr_handlers[] = { |
| @@ -7891,6 +7891,7 @@ static void · 7890 unmodified lines | ||
| 7891 | 7891 | nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) |
| 7892 | 7892 | { |
| 7893 | 7893 | struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp; |
| 7894 | + struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp; | |
| 7894 | 7895 | struct nfs_client *clp = args->client; |
| 7895 | 7896 | |
| 7896 | 7897 | switch (task->tk_status) { |
| @@ -7899,6 +7900,12 @@ nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) · 2 unmodified lines | ||
| 7899 | 7900 | nfs4_schedule_session_recovery(clp->cl_session, |
| 7900 | 7901 | task->tk_status); |
| 7901 | 7902 | } |
| 7903 | + if (args->dir == NFS4_CDFC4_FORE_OR_BOTH && | |
| 7904 | + res->dir != NFS4_CDFS4_BOTH) { | |
| 7905 | + rpc_task_close_connection(task); | |
| 7906 | + if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES) | |
| 7907 | + rpc_restart_call(task); | |
| 7908 | + } | |
| 7902 | 7909 | } |
| 7903 | 7910 | |
| 7904 | 7911 | static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { |
| @@ -7921,6 +7928,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt, · 16 unmodified lines | ||
| 7921 | 7928 | struct nfs41_bind_conn_to_session_args args = { |
| 7922 | 7929 | .client = clp, |
| 7923 | 7930 | .dir = NFS4_CDFC4_FORE_OR_BOTH, |
| 7931 | + .retries = 0, | |
| 7924 | 7932 | }; |
| 7925 | 7933 | struct nfs41_bind_conn_to_session_res res; |
| 7926 | 7934 | struct rpc_message msg = { |
| @@ -9191,8 +9199,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout) · 1264 unmodified lines | ||
| 9191 | 9199 | nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0); |
| 9192 | 9200 | |
| 9193 | 9201 | task = rpc_run_task(&task_setup_data); |
| 9194 | − if (IS_ERR(task)) | |
| 9195 | − return ERR_CAST(task); | |
| 9202 | + | |
| 9196 | 9203 | status = rpc_wait_for_completion_task(task); |
| 9197 | 9204 | if (status != 0) |
| 9198 | 9205 | goto out; |
| @@ -1332,13 +1332,15 @@ _pnfs_return_layout(struct inode *ino) · 1331 unmodified lines | ||
| 1332 | 1332 | !valid_layout) { |
| 1333 | 1333 | spin_unlock(&ino->i_lock); |
| 1334 | 1334 | dprintk("NFS: %s no layout segments to return\n", __func__); |
| 1335 | − goto out_put_layout_hdr; | |
| 1335 | + goto out_wait_layoutreturn; | |
| 1336 | 1336 | } |
| 1337 | 1337 | |
| 1338 | 1338 | send = pnfs_prepare_layoutreturn(lo, &stateid, &cred, NULL); |
| 1339 | 1339 | spin_unlock(&ino->i_lock); |
| 1340 | 1340 | if (send) |
| 1341 | 1341 | status = pnfs_send_layoutreturn(lo, &stateid, &cred, IOMODE_ANY, true); |
| 1342 | +out_wait_layoutreturn: | |
| 1343 | + wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN, TASK_UNINTERRUPTIBLE); | |
| 1342 | 1344 | out_put_layout_hdr: |
| 1343 | 1345 | pnfs_free_lseg_list(&tmp_list); |
| 1344 | 1346 | pnfs_put_layout_hdr(lo); |
| @@ -1456,18 +1458,15 @@ retry: · 111 unmodified lines | ||
| 1456 | 1458 | /* lo ref dropped in pnfs_roc_release() */ |
| 1457 | 1459 | layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &lc_cred, &iomode); |
| 1458 | 1460 | /* If the creds don't match, we can't compound the layoutreturn */ |
| 1459 | − if (!layoutreturn) | |
| 1461 | + if (!layoutreturn || cred_fscmp(cred, lc_cred) != 0) | |
| 1460 | 1462 | goto out_noroc; |
| 1461 | − if (cred_fscmp(cred, lc_cred) != 0) | |
| 1462 | − goto out_noroc_put_cred; | |
| 1463 | 1463 | |
| 1464 | 1464 | roc = layoutreturn; |
| 1465 | 1465 | pnfs_init_layoutreturn_args(args, lo, &stateid, iomode); |
| 1466 | 1466 | res->lrs_present = 0; |
| 1467 | 1467 | layoutreturn = false; |
| 1468 | − | |
| 1469 | −out_noroc_put_cred: | |
| 1470 | 1468 | put_cred(lc_cred); |
| 1469 | + | |
| 1471 | 1470 | out_noroc: |
| 1472 | 1471 | spin_unlock(&ino->i_lock); |
| 1473 | 1472 | rcu_read_unlock(); |
| @@ -185,7 +185,7 @@ static int __nfs_list_for_each_server(struct list_head *head, · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | rcu_read_lock(); |
| 187 | 187 | list_for_each_entry_rcu(server, head, client_link) { |
| 188 | − if (!nfs_sb_active(server->super)) | |
| 188 | + if (!(server->super && nfs_sb_active(server->super))) | |
| 189 | 189 | continue; |
| 190 | 190 | rcu_read_unlock(); |
| 191 | 191 | if (last) |
| @@ -275,7 +275,6 @@ static ssize_t dlmfs_file_write(struct file *filp, · 274 unmodified lines | ||
| 275 | 275 | loff_t *ppos) |
| 276 | 276 | { |
| 277 | 277 | int bytes_left; |
| 278 | − ssize_t writelen; | |
| 279 | 278 | char *lvb_buf; |
| 280 | 279 | struct inode *inode = file_inode(filp); |
| 281 | 280 | |
| @@ -285,32 +284,30 @@ static ssize_t dlmfs_file_write(struct file *filp, · 3 unmodified lines | ||
| 285 | 284 | if (*ppos >= i_size_read(inode)) |
| 286 | 285 | return -ENOSPC; |
| 287 | 286 | |
| 287 | + /* don't write past the lvb */ | |
| 288 | + if (count > i_size_read(inode) - *ppos) | |
| 289 | + count = i_size_read(inode) - *ppos; | |
| 290 | + | |
| 288 | 291 | if (!count) |
| 289 | 292 | return 0; |
| 290 | 293 | |
| 291 | 294 | if (!access_ok(buf, count)) |
| 292 | 295 | return -EFAULT; |
| 293 | 296 | |
| 294 | − /* don't write past the lvb */ | |
| 295 | − if ((count + *ppos) > i_size_read(inode)) | |
| 296 | − writelen = i_size_read(inode) - *ppos; | |
| 297 | − else | |
| 298 | − writelen = count - *ppos; | |
| 299 | − | |
| 300 | − lvb_buf = kmalloc(writelen, GFP_NOFS); | |
| 297 | + lvb_buf = kmalloc(count, GFP_NOFS); | |
| 301 | 298 | if (!lvb_buf) |
| 302 | 299 | return -ENOMEM; |
| 303 | 300 | |
| 304 | − bytes_left = copy_from_user(lvb_buf, buf, writelen); | |
| 305 | − writelen -= bytes_left; | |
| 306 | − if (writelen) | |
| 307 | − user_dlm_write_lvb(inode, lvb_buf, writelen); | |
| 301 | + bytes_left = copy_from_user(lvb_buf, buf, count); | |
| 302 | + count -= bytes_left; | |
| 303 | + if (count) | |
| 304 | + user_dlm_write_lvb(inode, lvb_buf, count); | |
| 308 | 305 | |
| 309 | 306 | kfree(lvb_buf); |
| 310 | 307 | |
| 311 | − *ppos = *ppos + writelen; | |
| 312 | − mlog(0, "wrote %zd bytes\n", writelen); | |
| 313 | − return writelen; | |
| 308 | + *ppos = *ppos + count; | |
| 309 | + mlog(0, "wrote %zu bytes\n", count); | |
| 310 | + return count; | |
| 314 | 311 | } |
| 315 | 312 | |
| 316 | 313 | static void dlmfs_init_once(void *foo) |
| @@ -261,14 +261,13 @@ static int propagate_one(struct mount *m) · 260 unmodified lines | ||
| 261 | 261 | child = copy_tree(last_source, last_source->mnt.mnt_root, type); |
| 262 | 262 | if (IS_ERR(child)) |
| 263 | 263 | return PTR_ERR(child); |
| 264 | + read_seqlock_excl(&mount_lock); | |
| 264 | 265 | mnt_set_mountpoint(m, mp, child); |
| 266 | + if (m->mnt_master != dest_master) | |
| 267 | + SET_MNT_MARK(m->mnt_master); | |
| 268 | + read_sequnlock_excl(&mount_lock); | |
| 265 | 269 | last_dest = m; |
| 266 | 270 | last_source = child; |
| 267 | − if (m->mnt_master != dest_master) { | |
| 268 | − read_seqlock_excl(&mount_lock); | |
| 269 | − SET_MNT_MARK(m->mnt_master); | |
| 270 | − read_sequnlock_excl(&mount_lock); | |
| 271 | − } | |
| 272 | 271 | hlist_add_head(&child->mnt_hash, list); |
| 273 | 272 | return count_mounts(m->mnt_ns, child); |
| 274 | 273 | } |
| @@ -1302,8 +1302,8 @@ int get_tree_bdev(struct fs_context *fc, · 1301 unmodified lines | ||
| 1302 | 1302 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 1303 | 1303 | if (bdev->bd_fsfreeze_count > 0) { |
| 1304 | 1304 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 1305 | − blkdev_put(bdev, mode); | |
| 1306 | 1305 | warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); |
| 1306 | + blkdev_put(bdev, mode); | |
| 1307 | 1307 | return -EBUSY; |
| 1308 | 1308 | } |
| 1309 | 1309 | |
| @@ -329,13 +329,12 @@ struct dma_buf { · 328 unmodified lines | ||
| 329 | 329 | |
| 330 | 330 | /** |
| 331 | 331 | * struct dma_buf_attach_ops - importer operations for an attachment |
| 332 | − * @move_notify: [optional] notification that the DMA-buf is moving | |
| 333 | 332 | * |
| 334 | 333 | * Attachment operations implemented by the importer. |
| 335 | 334 | */ |
| 336 | 335 | struct dma_buf_attach_ops { |
| 337 | 336 | /** |
| 338 | − * @move_notify | |
| 337 | + * @move_notify: [optional] notification that the DMA-buf is moving | |
| 339 | 338 | * |
| 340 | 339 | * If this callback is provided the framework can avoid pinning the |
| 341 | 340 | * backing store while mappings exists. |
| @@ -83,9 +83,9 @@ enum dma_transfer_direction { · 82 unmodified lines | ||
| 83 | 83 | /** |
| 84 | 84 | * Interleaved Transfer Request |
| 85 | 85 | * ---------------------------- |
| 86 | − * A chunk is collection of contiguous bytes to be transfered. | |
| 86 | + * A chunk is collection of contiguous bytes to be transferred. | |
| 87 | 87 | * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG). |
| 88 | − * ICGs may or maynot change between chunks. | |
| 88 | + * ICGs may or may not change between chunks. | |
| 89 | 89 | * A FRAME is the smallest series of contiguous {chunk,icg} pairs, |
| 90 | 90 | * that when repeated an integral number of times, specifies the transfer. |
| 91 | 91 | * A transfer template is specification of a Frame, the number of times |
| @@ -341,13 +341,11 @@ struct dma_chan { · 249 unmodified lines | ||
| 341 | 341 | * @chan: driver channel device |
| 342 | 342 | * @device: sysfs device |
| 343 | 343 | * @dev_id: parent dma_device dev_id |
| 344 | − * @idr_ref: reference count to gate release of dma_device dev_id | |
| 345 | 344 | */ |
| 346 | 345 | struct dma_chan_dev { |
| 347 | 346 | struct dma_chan *chan; |
| 348 | 347 | struct device device; |
| 349 | 348 | int dev_id; |
| 350 | − atomic_t *idr_ref; | |
| 351 | 349 | }; |
| 352 | 350 | |
| 353 | 351 | /** |
| @@ -835,6 +833,8 @@ struct dma_device { · 481 unmodified lines | ||
| 835 | 833 | int dev_id; |
| 836 | 834 | struct device *dev; |
| 837 | 835 | struct module *owner; |
| 836 | + struct ida chan_ida; | |
| 837 | + struct mutex chan_mutex; /* to protect chan_ida */ | |
| 838 | 838 | |
| 839 | 839 | u32 src_addr_widths; |
| 840 | 840 | u32 dst_addr_widths; |
| @@ -1069,7 +1069,7 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan) · 228 unmodified lines | ||
| 1069 | 1069 | * dmaengine_synchronize() needs to be called before it is safe to free |
| 1070 | 1070 | * any memory that is accessed by previously submitted descriptors or before |
| 1071 | 1071 | * freeing any resources accessed from within the completion callback of any |
| 1072 | − * perviously submitted descriptors. | |
| 1072 | + * previously submitted descriptors. | |
| 1073 | 1073 | * |
| 1074 | 1074 | * This function can be called from atomic context as well as from within a |
| 1075 | 1075 | * complete callback of a descriptor submitted on the same channel. |
| @@ -1091,7 +1091,7 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan) · 15 unmodified lines | ||
| 1091 | 1091 | * |
| 1092 | 1092 | * Synchronizes to the DMA channel termination to the current context. When this |
| 1093 | 1093 | * function returns it is guaranteed that all transfers for previously issued |
| 1094 | − * descriptors have stopped and and it is safe to free the memory assoicated | |
| 1094 | + * descriptors have stopped and it is safe to free the memory associated | |
| 1095 | 1095 | * with them. Furthermore it is guaranteed that all complete callback functions |
| 1096 | 1096 | * for a previously submitted descriptor have finished running and it is safe to |
| 1097 | 1097 | * free resources accessed from within the complete callbacks. |
| @@ -1317,11 +1317,13 @@ struct nfs41_impl_id { · 1316 unmodified lines | ||
| 1317 | 1317 | struct nfstime4 date; |
| 1318 | 1318 | }; |
| 1319 | 1319 | |
| 1320 | +#define MAX_BIND_CONN_TO_SESSION_RETRIES 3 | |
| 1320 | 1321 | struct nfs41_bind_conn_to_session_args { |
| 1321 | 1322 | struct nfs_client *client; |
| 1322 | 1323 | struct nfs4_sessionid sessionid; |
| 1323 | 1324 | u32 dir; |
| 1324 | 1325 | bool use_conn_in_rdma_mode; |
| 1326 | + int retries; | |
| 1325 | 1327 | }; |
| 1326 | 1328 | |
| 1327 | 1329 | struct nfs41_bind_conn_to_session_res { |
| @@ -71,7 +71,13 @@ struct rpc_clnt { · 70 unmodified lines | ||
| 71 | 71 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
| 72 | 72 | struct dentry *cl_debugfs; /* debugfs directory */ |
| 73 | 73 | #endif |
| 74 | − struct rpc_xprt_iter cl_xpi; | |
| 74 | + /* cl_work is only needed after cl_xpi is no longer used, | |
| 75 | + * and that are of similar size | |
| 76 | + */ | |
| 77 | + union { | |
| 78 | + struct rpc_xprt_iter cl_xpi; | |
| 79 | + struct work_struct cl_work; | |
| 80 | + }; | |
| 75 | 81 | const struct cred *cl_cred; |
| 76 | 82 | }; |
| 77 | 83 | |
| @@ -236,4 +242,9 @@ static inline int rpc_reply_expected(struct rpc_task *task) · 158 unmodified lines | ||
| 236 | 242 | (task->tk_msg.rpc_proc->p_decode != NULL); |
| 237 | 243 | } |
| 238 | 244 | |
| 245 | +static inline void rpc_task_close_connection(struct rpc_task *task) | |
| 246 | +{ | |
| 247 | + if (task->tk_xprt) | |
| 248 | + xprt_force_disconnect(task->tk_xprt); | |
| 249 | +} | |
| 239 | 250 | #endif /* _LINUX_SUNRPC_CLNT_H */ |
| @@ -692,11 +692,10 @@ TRACE_EVENT(xprtrdma_prepsend_failed, · 691 unmodified lines | ||
| 692 | 692 | |
| 693 | 693 | TRACE_EVENT(xprtrdma_post_send, |
| 694 | 694 | TP_PROTO( |
| 695 | − const struct rpcrdma_req *req, | |
| 696 | − int status | |
| 695 | + const struct rpcrdma_req *req | |
| 697 | 696 | ), |
| 698 | 697 | |
| 699 | − TP_ARGS(req, status), | |
| 698 | + TP_ARGS(req), | |
| 700 | 699 | |
| 701 | 700 | TP_STRUCT__entry( |
| 702 | 701 | __field(const void *, req) |
| @@ -705,7 +704,6 @@ TRACE_EVENT(xprtrdma_post_send, · 2 unmodified lines | ||
| 705 | 704 | __field(unsigned int, client_id) |
| 706 | 705 | __field(int, num_sge) |
| 707 | 706 | __field(int, signaled) |
| 708 | − __field(int, status) | |
| 709 | 707 | ), |
| 710 | 708 | |
| 711 | 709 | TP_fast_assign( |
| @@ -718,15 +716,13 @@ TRACE_EVENT(xprtrdma_post_send, · 6 unmodified lines | ||
| 718 | 716 | __entry->sc = req->rl_sendctx; |
| 719 | 717 | __entry->num_sge = req->rl_wr.num_sge; |
| 720 | 718 | __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; |
| 721 | − __entry->status = status; | |
| 722 | 719 | ), |
| 723 | 720 | |
| 724 | − TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d", | |
| 721 | + TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %s", | |
| 725 | 722 | __entry->task_id, __entry->client_id, |
| 726 | 723 | __entry->req, __entry->sc, __entry->num_sge, |
| 727 | 724 | (__entry->num_sge == 1 ? "" : "s"), |
| 728 | − (__entry->signaled ? "signaled " : ""), | |
| 729 | − __entry->status | |
| 725 | + (__entry->signaled ? "signaled" : "") | |
| 730 | 726 | ) |
| 731 | 727 | ); |
| 732 | 728 | |
| @@ -346,6 +346,10 @@ struct drm_amdgpu_gem_userptr { · 345 unmodified lines | ||
| 346 | 346 | #define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF |
| 347 | 347 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43 |
| 348 | 348 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1 |
| 349 | +#define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44 | |
| 350 | +#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1 | |
| 351 | +#define AMDGPU_TILING_SCANOUT_SHIFT 63 | |
| 352 | +#define AMDGPU_TILING_SCANOUT_MASK 0x1 | |
| 349 | 353 | |
| 350 | 354 | /* Set/Get helpers for tiling flags. */ |
| 351 | 355 | #define AMDGPU_TILING_SET(field, value) \ |
| @@ -39,6 +39,12 @@ struct dma_buf_sync { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define DMA_BUF_BASE 'b' |
| 41 | 41 | #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) |
| 42 | + | |
| 43 | +/* 32/64bitness of this uapi was botched in android, there's no difference | |
| 44 | + * between them in actual uapi, they're just different numbers. | |
| 45 | + */ | |
| 42 | 46 | #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) |
| 47 | +#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) | |
| 48 | +#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) | |
| 43 | 49 | |
| 44 | 50 | #endif |
| @@ -119,8 +119,8 @@ enum hv_fcopy_op { · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | struct hv_fcopy_hdr { |
| 121 | 121 | __u32 operation; |
| 122 | − uuid_le service_id0; /* currently unused */ | |
| 123 | − uuid_le service_id1; /* currently unused */ | |
| 122 | + __u8 service_id0[16]; /* currently unused */ | |
| 123 | + __u8 service_id1[16]; /* currently unused */ | |
| 124 | 124 | } __attribute__((packed)); |
| 125 | 125 | |
| 126 | 126 | #define OVER_WRITE 0x1 |
| @@ -898,6 +898,13 @@ static int software_resume(void) · 897 unmodified lines | ||
| 898 | 898 | error = freeze_processes(); |
| 899 | 899 | if (error) |
| 900 | 900 | goto Close_Finish; |
| 901 | + | |
| 902 | + error = freeze_kernel_threads(); | |
| 903 | + if (error) { | |
| 904 | + thaw_processes(); | |
| 905 | + goto Close_Finish; | |
| 906 | + } | |
| 907 | + | |
| 901 | 908 | error = load_image_and_restore(); |
| 902 | 909 | thaw_processes(); |
| 903 | 910 | Finish: |
| @@ -93,7 +93,7 @@ static void kunit_print_ok_not_ok(void *test_or_suite, · 92 unmodified lines | ||
| 93 | 93 | * representation. |
| 94 | 94 | */ |
| 95 | 95 | if (suite) |
| 96 | − pr_info("%s %zd - %s", | |
| 96 | + pr_info("%s %zd - %s\n", | |
| 97 | 97 | kunit_status_to_string(is_ok), |
| 98 | 98 | test_number, description); |
| 99 | 99 | else |
| @@ -880,6 +880,20 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); · 879 unmodified lines | ||
| 880 | 880 | /* |
| 881 | 881 | * Free an RPC client |
| 882 | 882 | */ |
| 883 | +static void rpc_free_client_work(struct work_struct *work) | |
| 884 | +{ | |
| 885 | + struct rpc_clnt *clnt = container_of(work, struct rpc_clnt, cl_work); | |
| 886 | + | |
| 887 | + /* These might block on processes that might allocate memory, | |
| 888 | + * so they cannot be called in rpciod, so they are handled separately | |
| 889 | + * here. | |
| 890 | + */ | |
| 891 | + rpc_clnt_debugfs_unregister(clnt); | |
| 892 | + rpc_clnt_remove_pipedir(clnt); | |
| 893 | + | |
| 894 | + kfree(clnt); | |
| 895 | + rpciod_down(); | |
| 896 | +} | |
| 883 | 897 | static struct rpc_clnt * |
| 884 | 898 | rpc_free_client(struct rpc_clnt *clnt) |
| 885 | 899 | { |
| @@ -890,17 +904,16 @@ rpc_free_client(struct rpc_clnt *clnt) · 4 unmodified lines | ||
| 890 | 904 | rcu_dereference(clnt->cl_xprt)->servername); |
| 891 | 905 | if (clnt->cl_parent != clnt) |
| 892 | 906 | parent = clnt->cl_parent; |
| 893 | − rpc_clnt_debugfs_unregister(clnt); | |
| 894 | − rpc_clnt_remove_pipedir(clnt); | |
| 895 | 907 | rpc_unregister_client(clnt); |
| 896 | 908 | rpc_free_iostats(clnt->cl_metrics); |
| 897 | 909 | clnt->cl_metrics = NULL; |
| 898 | 910 | xprt_put(rcu_dereference_raw(clnt->cl_xprt)); |
| 899 | 911 | xprt_iter_destroy(&clnt->cl_xpi); |
| 900 | − rpciod_down(); | |
| 901 | 912 | put_cred(clnt->cl_cred); |
| 902 | 913 | rpc_free_clid(clnt); |
| 903 | − kfree(clnt); | |
| 914 | + | |
| 915 | + INIT_WORK(&clnt->cl_work, rpc_free_client_work); | |
| 916 | + schedule_work(&clnt->cl_work); | |
| 904 | 917 | return parent; |
| 905 | 918 | } |
| 906 | 919 | |
| @@ -2808,8 +2821,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, · 1901 unmodified lines | ||
| 2808 | 2821 | task = rpc_call_null_helper(clnt, xprt, NULL, |
| 2809 | 2822 | RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS, |
| 2810 | 2823 | &rpc_cb_add_xprt_call_ops, data); |
| 2811 | − if (IS_ERR(task)) | |
| 2812 | − return PTR_ERR(task); | |
| 2824 | + | |
| 2813 | 2825 | rpc_put_task(task); |
| 2814 | 2826 | success: |
| 2815 | 2827 | return 1; |
| @@ -388,7 +388,9 @@ static int rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, · 387 unmodified lines | ||
| 388 | 388 | } while (nsegs); |
| 389 | 389 | |
| 390 | 390 | done: |
| 391 | − return xdr_stream_encode_item_absent(xdr); | |
| 391 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 392 | + return -EMSGSIZE; | |
| 393 | + return 0; | |
| 392 | 394 | } |
| 393 | 395 | |
| 394 | 396 | /* Register and XDR encode the Write list. Supports encoding a list |
| @@ -454,7 +456,9 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, · 59 unmodified lines | ||
| 454 | 456 | *segcount = cpu_to_be32(nchunks); |
| 455 | 457 | |
| 456 | 458 | done: |
| 457 | − return xdr_stream_encode_item_absent(xdr); | |
| 459 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 460 | + return -EMSGSIZE; | |
| 461 | + return 0; | |
| 458 | 462 | } |
| 459 | 463 | |
| 460 | 464 | /* Register and XDR encode the Reply chunk. Supports encoding an array |
| @@ -480,8 +484,11 @@ static int rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, · 19 unmodified lines | ||
| 480 | 484 | int nsegs, nchunks; |
| 481 | 485 | __be32 *segcount; |
| 482 | 486 | |
| 483 | − if (wtype != rpcrdma_replych) | |
| 484 | − return xdr_stream_encode_item_absent(xdr); | |
| 487 | + if (wtype != rpcrdma_replych) { | |
| 488 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 489 | + return -EMSGSIZE; | |
| 490 | + return 0; | |
| 491 | + } | |
| 485 | 492 | |
| 486 | 493 | seg = req->rl_segments; |
| 487 | 494 | nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg); |
| @@ -289,6 +289,7 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) · 288 unmodified lines | ||
| 289 | 289 | case RDMA_CM_EVENT_DISCONNECTED: |
| 290 | 290 | ep->re_connect_status = -ECONNABORTED; |
| 291 | 291 | disconnected: |
| 292 | + xprt_force_disconnect(xprt); | |
| 292 | 293 | return rpcrdma_ep_destroy(ep); |
| 293 | 294 | default: |
| 294 | 295 | break; |
| @@ -1355,8 +1356,8 @@ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 1060 unmodified lines | ||
| 1355 | 1356 | --ep->re_send_count; |
| 1356 | 1357 | } |
| 1357 | 1358 | |
| 1359 | + trace_xprtrdma_post_send(req); | |
| 1358 | 1360 | rc = frwr_send(r_xprt, req); |
| 1359 | − trace_xprtrdma_post_send(req, rc); | |
| 1360 | 1361 | if (rc) |
| 1361 | 1362 | return -ENOTCONN; |
| 1362 | 1363 | return 0; |
| @@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv, · 5841 unmodified lines | ||
| 5842 | 5842 | |
| 5843 | 5843 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 5844 | 5844 | { |
| 5845 | − int err = 0; | |
| 5846 | − u32 perm; | |
| 5845 | + int rc = 0; | |
| 5846 | + unsigned int msg_len; | |
| 5847 | + unsigned int data_len = skb->len; | |
| 5848 | + unsigned char *data = skb->data; | |
| 5847 | 5849 | struct nlmsghdr *nlh; |
| 5848 | 5850 | struct sk_security_struct *sksec = sk->sk_security; |
| 5851 | + u16 sclass = sksec->sclass; | |
| 5852 | + u32 perm; | |
| 5849 | 5853 | |
| 5850 | − if (skb->len < NLMSG_HDRLEN) { | |
| 5851 | − err = -EINVAL; | |
| 5852 | − goto out; | |
| 5853 | − } | |
| 5854 | − nlh = nlmsg_hdr(skb); | |
| 5854 | + while (data_len >= nlmsg_total_size(0)) { | |
| 5855 | + nlh = (struct nlmsghdr *)data; | |
| 5856 | + | |
| 5857 | + /* NOTE: the nlmsg_len field isn't reliably set by some netlink | |
| 5858 | + * users which means we can't reject skb's with bogus | |
| 5859 | + * length fields; our solution is to follow what | |
| 5860 | + * netlink_rcv_skb() does and simply skip processing at | |
| 5861 | + * messages with length fields that are clearly junk | |
| 5862 | + */ | |
| 5863 | + if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len) | |
| 5864 | + return 0; | |
| 5855 | 5865 | |
| 5856 | − err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); | |
| 5857 | − if (err) { | |
| 5858 | − if (err == -EINVAL) { | |
| 5866 | + rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); | |
| 5867 | + if (rc == 0) { | |
| 5868 | + rc = sock_has_perm(sk, perm); | |
| 5869 | + if (rc) | |
| 5870 | + return rc; | |
| 5871 | + } else if (rc == -EINVAL) { | |
| 5872 | + /* -EINVAL is a missing msg/perm mapping */ | |
| 5859 | 5873 | pr_warn_ratelimited("SELinux: unrecognized netlink" |
| 5860 | − " message: protocol=%hu nlmsg_type=%hu sclass=%s" | |
| 5861 | − " pid=%d comm=%s\n", | |
| 5862 | − sk->sk_protocol, nlh->nlmsg_type, | |
| 5863 | − secclass_map[sksec->sclass - 1].name, | |
| 5864 | − task_pid_nr(current), current->comm); | |
| 5865 | − if (!enforcing_enabled(&selinux_state) || | |
| 5866 | − security_get_allow_unknown(&selinux_state)) | |
| 5867 | − err = 0; | |
| 5874 | + " message: protocol=%hu nlmsg_type=%hu sclass=%s" | |
| 5875 | + " pid=%d comm=%s\n", | |
| 5876 | + sk->sk_protocol, nlh->nlmsg_type, | |
| 5877 | + secclass_map[sclass - 1].name, | |
| 5878 | + task_pid_nr(current), current->comm); | |
| 5879 | + if (enforcing_enabled(&selinux_state) && | |
| 5880 | + !security_get_allow_unknown(&selinux_state)) | |
| 5881 | + return rc; | |
| 5882 | + rc = 0; | |
| 5883 | + } else if (rc == -ENOENT) { | |
| 5884 | + /* -ENOENT is a missing socket/class mapping, ignore */ | |
| 5885 | + rc = 0; | |
| 5886 | + } else { | |
| 5887 | + return rc; | |
| 5868 | 5888 | } |
| 5869 | 5889 | |
| 5870 | − /* Ignore */ | |
| 5871 | − if (err == -ENOENT) | |
| 5872 | − err = 0; | |
| 5873 | − goto out; | |
| 5890 | + /* move to the next message after applying netlink padding */ | |
| 5891 | + msg_len = NLMSG_ALIGN(nlh->nlmsg_len); | |
| 5892 | + if (msg_len >= data_len) | |
| 5893 | + return 0; | |
| 5894 | + data_len -= msg_len; | |
| 5895 | + data += msg_len; | |
| 5874 | 5896 | } |
| 5875 | 5897 | |
| 5876 | − err = sock_has_perm(sk, perm); | |
| 5877 | −out: | |
| 5878 | − return err; | |
| 5898 | + return rc; | |
| 5879 | 5899 | } |
| 5880 | 5900 | |
| 5881 | 5901 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
| @@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp) · 428 unmodified lines | ||
| 429 | 429 | |
| 430 | 430 | p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); |
| 431 | 431 | if (!p->cond_list) |
| 432 | − return rc; | |
| 432 | + return -ENOMEM; | |
| 433 | 433 | |
| 434 | 434 | rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); |
| 435 | 435 | if (rc) |
| @@ -205,13 +205,14 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, · 204 unmodified lines | ||
| 205 | 205 | plugin = snd_pcm_plug_first(plug); |
| 206 | 206 | while (plugin && frames > 0) { |
| 207 | 207 | plugin_next = plugin->next; |
| 208 | + if (check_size && plugin->buf_frames && | |
| 209 | + frames > plugin->buf_frames) | |
| 210 | + frames = plugin->buf_frames; | |
| 208 | 211 | if (plugin->dst_frames) { |
| 209 | 212 | frames = plugin->dst_frames(plugin, frames); |
| 210 | 213 | if (frames < 0) |
| 211 | 214 | return frames; |
| 212 | 215 | } |
| 213 | − if (check_size && frames > plugin->buf_frames) | |
| 214 | − frames = plugin->buf_frames; | |
| 215 | 216 | plugin = plugin_next; |
| 216 | 217 | } |
| 217 | 218 | return frames; |
| @@ -225,14 +226,15 @@ static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug, · 7 unmodified lines | ||
| 225 | 226 | |
| 226 | 227 | plugin = snd_pcm_plug_last(plug); |
| 227 | 228 | while (plugin && frames > 0) { |
| 228 | − if (check_size && frames > plugin->buf_frames) | |
| 229 | − frames = plugin->buf_frames; | |
| 230 | 229 | plugin_prev = plugin->prev; |
| 231 | 230 | if (plugin->src_frames) { |
| 232 | 231 | frames = plugin->src_frames(plugin, frames); |
| 233 | 232 | if (frames < 0) |
| 234 | 233 | return frames; |
| 235 | 234 | } |
| 235 | + if (check_size && plugin->buf_frames && | |
| 236 | + frames > plugin->buf_frames) | |
| 237 | + frames = plugin->buf_frames; | |
| 236 | 238 | plugin = plugin_prev; |
| 237 | 239 | } |
| 238 | 240 | return frames; |
| @@ -867,10 +867,13 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg, · 866 unmodified lines | ||
| 867 | 867 | spin_unlock_irqrestore(&chip->lock, flags); |
| 868 | 868 | } |
| 869 | 869 | |
| 870 | +static inline void snd_miro_write_mask(struct snd_miro *chip, | |
| 871 | + unsigned char reg, unsigned char value, unsigned char mask) | |
| 872 | +{ | |
| 873 | + unsigned char oldval = snd_miro_read(chip, reg); | |
| 870 | 874 | |
| 871 | −#define snd_miro_write_mask(chip, reg, value, mask) \ | |
| 872 | − snd_miro_write(chip, reg, \ | |
| 873 | − (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask))) | |
| 875 | + snd_miro_write(chip, reg, (oldval & ~mask) | (value & mask)); | |
| 876 | +} | |
| 874 | 877 | |
| 875 | 878 | /* |
| 876 | 879 | * Proc Interface |
| @@ -317,10 +317,13 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, · 316 unmodified lines | ||
| 317 | 317 | } |
| 318 | 318 | |
| 319 | 319 | |
| 320 | −#define snd_opti9xx_write_mask(chip, reg, value, mask) \ | |
| 321 | − snd_opti9xx_write(chip, reg, \ | |
| 322 | − (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | |
| 320 | +static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip, | |
| 321 | + unsigned char reg, unsigned char value, unsigned char mask) | |
| 322 | +{ | |
| 323 | + unsigned char oldval = snd_opti9xx_read(chip, reg); | |
| 323 | 324 | |
| 325 | + snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask)); | |
| 326 | +} | |
| 324 | 327 | |
| 325 | 328 | static int snd_opti9xx_configure(struct snd_opti9xx *chip, |
| 326 | 329 | long port, |
| @@ -2078,9 +2078,10 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, · 2077 unmodified lines | ||
| 2078 | 2078 | * some HD-audio PCI entries are exposed without any codecs, and such devices |
| 2079 | 2079 | * should be ignored from the beginning. |
| 2080 | 2080 | */ |
| 2081 | −static const struct snd_pci_quirk driver_blacklist[] = { | |
| 2082 | − SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0), | |
| 2083 | − SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0), | |
| 2081 | +static const struct pci_device_id driver_blacklist[] = { | |
| 2082 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */ | |
| 2083 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */ | |
| 2084 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */ | |
| 2084 | 2085 | {} |
| 2085 | 2086 | }; |
| 2086 | 2087 | |
| @@ -2100,7 +2101,7 @@ static int azx_probe(struct pci_dev *pci, · 13 unmodified lines | ||
| 2100 | 2101 | bool schedule_probe; |
| 2101 | 2102 | int err; |
| 2102 | 2103 | |
| 2103 | − if (snd_pci_quirk_lookup(pci, driver_blacklist)) { | |
| 2104 | + if (pci_match_id(driver_blacklist, pci)) { | |
| 2104 | 2105 | dev_info(&pci->dev, "Skipping the blacklisted device\n"); |
| 2105 | 2106 | return -ENODEV; |
| 2106 | 2107 | } |
| @@ -1848,8 +1848,10 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) · 1847 unmodified lines | ||
| 1848 | 1848 | /* Add sanity check to pass klockwork check. |
| 1849 | 1849 | * This should never happen. |
| 1850 | 1850 | */ |
| 1851 | − if (WARN_ON(spdif == NULL)) | |
| 1851 | + if (WARN_ON(spdif == NULL)) { | |
| 1852 | + mutex_unlock(&codec->spdif_mutex); | |
| 1852 | 1853 | return true; |
| 1854 | + } | |
| 1853 | 1855 | non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO); |
| 1854 | 1856 | mutex_unlock(&codec->spdif_mutex); |
| 1855 | 1857 | return non_pcm; |
| @@ -2198,7 +2200,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) · 342 unmodified lines | ||
| 2198 | 2200 | |
| 2199 | 2201 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 2200 | 2202 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
| 2203 | + struct hdmi_eld *pin_eld = &per_pin->sink_eld; | |
| 2201 | 2204 | |
| 2205 | + pin_eld->eld_valid = false; | |
| 2202 | 2206 | hdmi_present_sense(per_pin, 0); |
| 2203 | 2207 | } |
| 2204 | 2208 | |
| @@ -7420,6 +7420,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7419 unmodified lines | ||
| 7420 | 7420 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7421 | 7421 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7422 | 7422 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), |
| 7423 | + SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), | |
| 7423 | 7424 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
| 7424 | 7425 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
| 7425 | 7426 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
| @@ -21,8 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | enum { |
| 22 | 22 | LINE6_PODHD300, |
| 23 | 23 | LINE6_PODHD400, |
| 24 | − LINE6_PODHD500_0, | |
| 25 | − LINE6_PODHD500_1, | |
| 24 | + LINE6_PODHD500, | |
| 26 | 25 | LINE6_PODX3, |
| 27 | 26 | LINE6_PODX3LIVE, |
| 28 | 27 | LINE6_PODHD500X, |
| @@ -318,8 +317,7 @@ static const struct usb_device_id podhd_id_table[] = { · 289 unmodified lines | ||
| 318 | 317 | /* TODO: no need to alloc data interfaces when only audio is used */ |
| 319 | 318 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, |
| 320 | 319 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, |
| 321 | − { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | |
| 322 | − { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | |
| 320 | + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 }, | |
| 323 | 321 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, |
| 324 | 322 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, |
| 325 | 323 | { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, |
| @@ -352,23 +350,13 @@ static const struct line6_properties podhd_properties_table[] = { · 26 unmodified lines | ||
| 352 | 350 | .ep_audio_r = 0x82, |
| 353 | 351 | .ep_audio_w = 0x01, |
| 354 | 352 | }, |
| 355 | − [LINE6_PODHD500_0] = { | |
| 353 | + [LINE6_PODHD500] = { | |
| 356 | 354 | .id = "PODHD500", |
| 357 | 355 | .name = "POD HD500", |
| 358 | − .capabilities = LINE6_CAP_PCM | |
| 356 | + .capabilities = LINE6_CAP_PCM | LINE6_CAP_CONTROL | |
| 359 | 357 | | LINE6_CAP_HWMON, |
| 360 | 358 | .altsetting = 1, |
| 361 | − .ep_ctrl_r = 0x81, | |
| 362 | − .ep_ctrl_w = 0x01, | |
| 363 | − .ep_audio_r = 0x86, | |
| 364 | − .ep_audio_w = 0x02, | |
| 365 | − }, | |
| 366 | − [LINE6_PODHD500_1] = { | |
| 367 | − .id = "PODHD500", | |
| 368 | − .name = "POD HD500", | |
| 369 | − .capabilities = LINE6_CAP_PCM | |
| 370 | − | LINE6_CAP_HWMON, | |
| 371 | − .altsetting = 0, | |
| 359 | + .ctrl_if = 1, | |
| 372 | 360 | .ep_ctrl_r = 0x81, |
| 373 | 361 | .ep_ctrl_w = 0x01, |
| 374 | 362 | .ep_audio_r = 0x86, |
| @@ -1687,7 +1687,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, · 1686 unmodified lines | ||
| 1687 | 1687 | |
| 1688 | 1688 | case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ |
| 1689 | 1689 | case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ |
| 1690 | − case USB_ID(0x16b0, 0x06b2): /* NuPrime DAC-10 */ | |
| 1690 | + case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */ | |
| 1691 | 1691 | case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ |
| 1692 | 1692 | case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ |
| 1693 | 1693 | case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ |
| @@ -10,10 +10,7 @@ if ! grep -q function_graph available_tracers; then · 9 unmodified lines | ||
| 10 | 10 | exit_unsupported |
| 11 | 11 | fi |
| 12 | 12 | |
| 13 | −if [ ! -f set_ftrace_filter ]; then | |
| 14 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 15 | − exit_unsupported | |
| 16 | −fi | |
| 13 | +check_filter_file set_ftrace_filter | |
| 17 | 14 | |
| 18 | 15 | do_reset() { |
| 19 | 16 | if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then |
| @@ -9,6 +9,8 @@ if ! grep -q function_graph available_tracers; then · 8 unmodified lines | ||
| 9 | 9 | exit_unsupported |
| 10 | 10 | fi |
| 11 | 11 | |
| 12 | +check_filter_file set_ftrace_filter | |
| 13 | + | |
| 12 | 14 | fail() { # msg |
| 13 | 15 | echo $1 |
| 14 | 16 | exit_fail |
| @@ -9,6 +9,8 @@ if ! grep -q function available_tracers; then · 8 unmodified lines | ||
| 9 | 9 | exit_unsupported |
| 10 | 10 | fi |
| 11 | 11 | |
| 12 | +check_filter_file set_ftrace_filter | |
| 13 | + | |
| 12 | 14 | disable_tracing |
| 13 | 15 | clear_trace |
| 14 | 16 | |
| @@ -15,10 +15,7 @@ if [ ! -f set_ftrace_notrace_pid ]; then · 14 unmodified lines | ||
| 15 | 15 | exit_unsupported |
| 16 | 16 | fi |
| 17 | 17 | |
| 18 | −if [ ! -f set_ftrace_filter ]; then | |
| 19 | − echo "set_ftrace_filter not found? Is function tracer not set?" | |
| 20 | − exit_unsupported | |
| 21 | −fi | |
| 18 | +check_filter_file set_ftrace_filter | |
| 22 | 19 | |
| 23 | 20 | do_function_fork=1 |
| 24 | 21 | |
| @@ -16,10 +16,7 @@ if [ ! -f set_ftrace_pid ]; then · 15 unmodified lines | ||
| 16 | 16 | exit_unsupported |
| 17 | 17 | fi |
| 18 | 18 | |
| 19 | −if [ ! -f set_ftrace_filter ]; then | |
| 20 | − echo "set_ftrace_filter not found? Is function tracer not set?" | |
| 21 | − exit_unsupported | |
| 22 | −fi | |
| 19 | +check_filter_file set_ftrace_filter | |
| 23 | 20 | |
| 24 | 21 | do_function_fork=1 |
| 25 | 22 | |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | # description: ftrace - stacktrace filter command |
| 4 | 4 | # flags: instance |
| 5 | 5 | |
| 6 | −[ ! -f set_ftrace_filter ] && exit_unsupported | |
| 6 | +check_filter_file set_ftrace_filter | |
| 7 | 7 | |
| 8 | 8 | echo _do_fork:stacktrace >> set_ftrace_filter |
| 9 | 9 | |
| @@ -11,10 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | # |
| 12 | 12 | |
| 13 | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | −if [ ! -f set_ftrace_filter ]; then | |
| 15 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 16 | − exit_unsupported | |
| 17 | −fi | |
| 14 | +check_filter_file set_ftrace_filter | |
| 18 | 15 | |
| 19 | 16 | do_reset() { |
| 20 | 17 | reset_ftrace_filter |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | # description: ftrace - function trace on module |
| 4 | 4 | |
| 5 | −[ ! -f set_ftrace_filter ] && exit_unsupported | |
| 5 | +check_filter_file set_ftrace_filter | |
| 6 | 6 | |
| 7 | 7 | : "mod: allows to filter a non exist function" |
| 8 | 8 | echo 'non_exist_func:mod:non_exist_module' > set_ftrace_filter |
| @@ -18,10 +18,7 @@ if ! grep -q function_graph available_tracers; then · 17 unmodified lines | ||
| 18 | 18 | exit_unsupported; |
| 19 | 19 | fi |
| 20 | 20 | |
| 21 | −if [ ! -f set_ftrace_filter ]; then | |
| 22 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 23 | − exit_unsupported | |
| 24 | −fi | |
| 21 | +check_filter_file set_ftrace_filter | |
| 25 | 22 | |
| 26 | 23 | if [ ! -f function_profile_enabled ]; then |
| 27 | 24 | echo "function_profile_enabled not found, function profiling enabled?" |
| @@ -10,10 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | # |
| 11 | 11 | |
| 12 | 12 | # The triggers are set within the set_ftrace_filter file |
| 13 | −if [ ! -f set_ftrace_filter ]; then | |
| 14 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 15 | − exit_unsupported | |
| 16 | −fi | |
| 13 | +check_filter_file set_ftrace_filter | |
| 17 | 14 | |
| 18 | 15 | fail() { # mesg |
| 19 | 16 | echo $1 |
| @@ -8,6 +8,8 @@ if [ ! -f stack_trace ]; then · 7 unmodified lines | ||
| 8 | 8 | exit_unsupported |
| 9 | 9 | fi |
| 10 | 10 | |
| 11 | +check_filter_file stack_trace_filter | |
| 12 | + | |
| 11 | 13 | echo > stack_trace_filter |
| 12 | 14 | echo 0 > stack_max_size |
| 13 | 15 | echo 1 > /proc/sys/kernel/stack_tracer_enabled |
| @@ -11,10 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | # |
| 12 | 12 | |
| 13 | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | −if [ ! -f set_ftrace_filter ]; then | |
| 15 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 16 | − exit_unsupported | |
| 17 | −fi | |
| 14 | +check_filter_file set_ftrace_filter | |
| 18 | 15 | |
| 19 | 16 | fail() { # mesg |
| 20 | 17 | echo $1 |
| @@ -1,3 +1,9 @@ | ||
| 1 | +check_filter_file() { # check filter file introduced by dynamic ftrace | |
| 2 | + if [ ! -f "$1" ]; then | |
| 3 | + echo "$1 not found? Is dynamic ftrace not set?" | |
| 4 | + exit_unsupported | |
| 5 | + fi | |
| 6 | +} | |
| 1 | 7 | |
| 2 | 8 | clear_trace() { # reset trace output |
| 3 | 9 | echo > trace |
| @@ -38,7 +38,7 @@ for width in 64 32 16 8; do · 37 unmodified lines | ||
| 38 | 38 | echo 0 > events/kprobes/testprobe/enable |
| 39 | 39 | |
| 40 | 40 | : "Confirm the arguments is recorded in given types correctly" |
| 41 | − ARGS=`grep "testprobe" trace | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` | |
| 41 | + ARGS=`grep "testprobe" trace | head -n 1 | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` | |
| 42 | 42 | check_types $ARGS $width |
| 43 | 43 | |
| 44 | 44 | : "Clear event for next loop" |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable |
| 6 | 6 | grep "function" available_tracers || exit_unsupported # this is configurable |
| 7 | 7 | |
| 8 | +check_filter_file set_ftrace_filter | |
| 9 | + | |
| 8 | 10 | # prepare |
| 9 | 11 | echo nop > current_tracer |
| 10 | 12 | echo _do_fork > set_ftrace_filter |
| @@ -1,13 +1,13 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −MOUNT_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) | |
| 4 | −MOUNT_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) | |
| 5 | −ifeq ($(MOUNT_LDLIBS),) | |
| 6 | −MOUNT_LDLIBS := -lmount -I/usr/include/libmount | |
| 3 | +VAR_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) | |
| 4 | +VAR_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) | |
| 5 | +ifeq ($(VAR_LDLIBS),) | |
| 6 | +VAR_LDLIBS := -lmount -I/usr/include/libmount | |
| 7 | 7 | endif |
| 8 | 8 | |
| 9 | −CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) | |
| 10 | −LDLIBS += $(MOUNT_LDLIBS) | |
| 9 | +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) | |
| 10 | +LDLIBS += $(VAR_LDLIBS) | |
| 11 | 11 | |
| 12 | 12 | TEST_PROGS := gpio-mockup.sh |
| 13 | 13 | TEST_FILES := gpio-mockup-sysfs.sh |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE |
| 3 | −LDLIBS := $(LDLIBS) -lm | |
| 3 | +LDLIBS += -lm | |
| 4 | 4 | |
| 5 | 5 | uname_M := $(shell uname -m 2>/dev/null || echo not) |
| 6 | 6 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) |
| @@ -0,0 +1,272 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# SPDX-License-Identifier: GPL-2.0 | |
| 3 | +# kselftest_deps.sh | |
| 4 | +# | |
| 5 | +# Checks for kselftest build dependencies on the build system. | |
| 6 | +# Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org> | |
| 7 | +# | |
| 8 | +# | |
| 9 | + | |
| 10 | +usage() | |
| 11 | +{ | |
| 12 | + | |
| 13 | +echo -e "Usage: $0 -[p] <compiler> [test_name]\n" | |
| 14 | +echo -e "\tkselftest_deps.sh [-p] gcc" | |
| 15 | +echo -e "\tkselftest_deps.sh [-p] gcc vm" | |
| 16 | +echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc" | |
| 17 | +echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc vm\n" | |
| 18 | +echo "- Should be run in selftests directory in the kernel repo." | |
| 19 | +echo "- Checks if Kselftests can be built/cross-built on a system." | |
| 20 | +echo "- Parses all test/sub-test Makefile to find library dependencies." | |
| 21 | +echo "- Runs compile test on a trivial C file with LDLIBS specified" | |
| 22 | +echo " in the test Makefiles to identify missing library dependencies." | |
| 23 | +echo "- Prints suggested target list for a system filtering out tests" | |
| 24 | +echo " failed the build dependency check from the TARGETS in Selftests" | |
| 25 | +echo " main Makefile when optional -p is specified." | |
| 26 | +echo "- Prints pass/fail dependency check for each tests/sub-test." | |
| 27 | +echo "- Prints pass/fail targets and libraries." | |
| 28 | +echo "- Default: runs dependency checks on all tests." | |
| 29 | +echo "- Optional test name can be specified to check dependencies for it." | |
| 30 | +exit 1 | |
| 31 | + | |
| 32 | +} | |
| 33 | + | |
| 34 | +# Start main() | |
| 35 | +main() | |
| 36 | +{ | |
| 37 | + | |
| 38 | +base_dir=`pwd` | |
| 39 | +# Make sure we're in the selftests top-level directory. | |
| 40 | +if [ $(basename "$base_dir") != "selftests" ]; then | |
| 41 | + echo -e "\tPlease run $0 in" | |
| 42 | + echo -e "\ttools/testing/selftests directory ..." | |
| 43 | + exit 1 | |
| 44 | +fi | |
| 45 | + | |
| 46 | +print_targets=0 | |
| 47 | + | |
| 48 | +while getopts "p" arg; do | |
| 49 | + case $arg in | |
| 50 | + p) | |
| 51 | + print_targets=1 | |
| 52 | + shift;; | |
| 53 | + esac | |
| 54 | +done | |
| 55 | + | |
| 56 | +if [ $# -eq 0 ] | |
| 57 | +then | |
| 58 | + usage | |
| 59 | +fi | |
| 60 | + | |
| 61 | +# Compiler | |
| 62 | +CC=$1 | |
| 63 | + | |
| 64 | +tmp_file=$(mktemp).c | |
| 65 | +trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT | |
| 66 | +#echo $tmp_file | |
| 67 | + | |
| 68 | +pass=$(mktemp).out | |
| 69 | +trap "rm -f $pass" EXIT | |
| 70 | +#echo $pass | |
| 71 | + | |
| 72 | +fail=$(mktemp).out | |
| 73 | +trap "rm -f $fail" EXIT | |
| 74 | +#echo $fail | |
| 75 | + | |
| 76 | +# Generate tmp source fire for compile test | |
| 77 | +cat << "EOF" > $tmp_file | |
| 78 | +int main() | |
| 79 | +{ | |
| 80 | +} | |
| 81 | +EOF | |
| 82 | + | |
| 83 | +# Save results | |
| 84 | +total_cnt=0 | |
| 85 | +fail_trgts=() | |
| 86 | +fail_libs=() | |
| 87 | +fail_cnt=0 | |
| 88 | +pass_trgts=() | |
| 89 | +pass_libs=() | |
| 90 | +pass_cnt=0 | |
| 91 | + | |
| 92 | +# Get all TARGETS from selftests Makefile | |
| 93 | +targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) | |
| 94 | + | |
| 95 | +# Single test case | |
| 96 | +if [ $# -eq 2 ] | |
| 97 | +then | |
| 98 | + test=$2/Makefile | |
| 99 | + | |
| 100 | + l1_test $test | |
| 101 | + l2_test $test | |
| 102 | + l3_test $test | |
| 103 | + | |
| 104 | + print_results $1 $2 | |
| 105 | + exit $? | |
| 106 | +fi | |
| 107 | + | |
| 108 | +# Level 1: LDLIBS set static. | |
| 109 | +# | |
| 110 | +# Find all LDLIBS set statically for all executables built by a Makefile | |
| 111 | +# and filter out VAR_LDLIBS to discard the following: | |
| 112 | +# gpio/Makefile:LDLIBS += $(VAR_LDLIBS) | |
| 113 | +# Append space at the end of the list to append more tests. | |
| 114 | + | |
| 115 | +l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ | |
| 116 | + grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | |
| 117 | + | |
| 118 | +# Level 2: LDLIBS set dynamically. | |
| 119 | +# | |
| 120 | +# Level 2 | |
| 121 | +# Some tests have multiple valid LDLIBS lines for individual sub-tests | |
| 122 | +# that need dependency checks. Find them and append them to the tests | |
| 123 | +# e.g: vm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread | |
| 124 | +# Filter out VAR_LDLIBS to discard the following: | |
| 125 | +# memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) | |
| 126 | +# Append space at the end of the list to append more tests. | |
| 127 | + | |
| 128 | +l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ | |
| 129 | + grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | |
| 130 | + | |
| 131 | +# Level 3 | |
| 132 | +# gpio, memfd and others use pkg-config to find mount and fuse libs | |
| 133 | +# respectively and save it in VAR_LDLIBS. If pkg-config doesn't find | |
| 134 | +# any, VAR_LDLIBS set to default. | |
| 135 | +# Use the default value and filter out pkg-config for dependency check. | |
| 136 | +# e.g: | |
| 137 | +# gpio/Makefile | |
| 138 | +# VAR_LDLIBS := $(shell pkg-config --libs mount) 2>/dev/null) | |
| 139 | +# memfd/Makefile | |
| 140 | +# VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | |
| 141 | + | |
| 142 | +l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ | |
| 143 | + grep -v "pkg-config" | awk -F: '{print $1}') | |
| 144 | + | |
| 145 | +#echo $l1_tests | |
| 146 | +#echo $l2_1_tests | |
| 147 | +#echo $l3_tests | |
| 148 | + | |
| 149 | +all_tests | |
| 150 | +print_results $1 $2 | |
| 151 | + | |
| 152 | +exit $? | |
| 153 | +} | |
| 154 | +# end main() | |
| 155 | + | |
| 156 | +all_tests() | |
| 157 | +{ | |
| 158 | + for test in $l1_tests; do | |
| 159 | + l1_test $test | |
| 160 | + done | |
| 161 | + | |
| 162 | + for test in $l2_tests; do | |
| 163 | + l2_test $test | |
| 164 | + done | |
| 165 | + | |
| 166 | + for test in $l3_tests; do | |
| 167 | + l3_test $test | |
| 168 | + done | |
| 169 | +} | |
| 170 | + | |
| 171 | +# Use same parsing used for l1_tests and pick libraries this time. | |
| 172 | +l1_test() | |
| 173 | +{ | |
| 174 | + test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ | |
| 175 | + grep -v "VAR_LDLIBS" | \ | |
| 176 | + sed -e 's/\:/ /' | \ | |
| 177 | + sed -e 's/+/ /' | cut -d "=" -f 2) | |
| 178 | + | |
| 179 | + check_libs $test $test_libs | |
| 180 | +} | |
| 181 | + | |
| 182 | +# Use same parsing used for l2__tests and pick libraries this time. | |
| 183 | +l2_test() | |
| 184 | +{ | |
| 185 | + test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ | |
| 186 | + grep -v "VAR_LDLIBS" | \ | |
| 187 | + sed -e 's/\:/ /' | sed -e 's/+/ /' | \ | |
| 188 | + cut -d "=" -f 2) | |
| 189 | + | |
| 190 | + check_libs $test $test_libs | |
| 191 | +} | |
| 192 | + | |
| 193 | +l3_test() | |
| 194 | +{ | |
| 195 | + test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \ | |
| 196 | + grep -v "pkg-config" | sed -e 's/\:/ /' | | |
| 197 | + sed -e 's/+/ /' | cut -d "=" -f 2) | |
| 198 | + | |
| 199 | + check_libs $test $test_libs | |
| 200 | +} | |
| 201 | + | |
| 202 | +check_libs() | |
| 203 | +{ | |
| 204 | + | |
| 205 | +if [[ ! -z "${test_libs// }" ]] | |
| 206 | +then | |
| 207 | + | |
| 208 | + #echo $test_libs | |
| 209 | + | |
| 210 | + for lib in $test_libs; do | |
| 211 | + | |
| 212 | + let total_cnt+=1 | |
| 213 | + $CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1 | |
| 214 | + if [ $? -ne 0 ]; then | |
| 215 | + echo "FAIL: $test dependency check: $lib" >> $fail | |
| 216 | + let fail_cnt+=1 | |
| 217 | + fail_libs+="$lib " | |
| 218 | + fail_target=$(echo "$test" | cut -d "/" -f1) | |
| 219 | + fail_trgts+="$fail_target " | |
| 220 | + targets=$(echo "$targets" | grep -v "$fail_target") | |
| 221 | + else | |
| 222 | + echo "PASS: $test dependency check passed $lib" >> $pass | |
| 223 | + let pass_cnt+=1 | |
| 224 | + pass_libs+="$lib " | |
| 225 | + pass_trgts+="$(echo "$test" | cut -d "/" -f1) " | |
| 226 | + fi | |
| 227 | + | |
| 228 | + done | |
| 229 | +fi | |
| 230 | +} | |
| 231 | + | |
| 232 | +print_results() | |
| 233 | +{ | |
| 234 | + echo -e "========================================================"; | |
| 235 | + echo -e "Kselftest Dependency Check for [$0 $1 $2] results..." | |
| 236 | + | |
| 237 | + if [ $print_targets -ne 0 ] | |
| 238 | + then | |
| 239 | + echo -e "Suggested Selftest Targets for your configuration:" | |
| 240 | + echo -e "$targets"; | |
| 241 | + fi | |
| 242 | + | |
| 243 | + echo -e "========================================================"; | |
| 244 | + echo -e "Checked tests defining LDLIBS dependencies" | |
| 245 | + echo -e "--------------------------------------------------------"; | |
| 246 | + echo -e "Total tests with Dependencies:" | |
| 247 | + echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt"; | |
| 248 | + | |
| 249 | + if [ $pass_cnt -ne 0 ]; then | |
| 250 | + echo -e "--------------------------------------------------------"; | |
| 251 | + cat $pass | |
| 252 | + echo -e "--------------------------------------------------------"; | |
| 253 | + echo -e "Targets passed build dependency check on system:" | |
| 254 | + echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)" | |
| 255 | + fi | |
| 256 | + | |
| 257 | + if [ $fail_cnt -ne 0 ]; then | |
| 258 | + echo -e "--------------------------------------------------------"; | |
| 259 | + cat $fail | |
| 260 | + echo -e "--------------------------------------------------------"; | |
| 261 | + echo -e "Targets failed build dependency check on system:" | |
| 262 | + echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)" | |
| 263 | + echo -e "--------------------------------------------------------"; | |
| 264 | + echo -e "Missing libraries system" | |
| 265 | + echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)" | |
| 266 | + fi | |
| 267 | + | |
| 268 | + echo -e "--------------------------------------------------------"; | |
| 269 | + echo -e "========================================================"; | |
| 270 | +} | |
| 271 | + | |
| 272 | +main "$@" | |
| @@ -8,11 +8,21 @@ TEST_GEN_PROGS := memfd_test · 7 unmodified lines | ||
| 8 | 8 | TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh |
| 9 | 9 | TEST_GEN_FILES := fuse_test fuse_mnt |
| 10 | 10 | |
| 11 | −fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | |
| 11 | +VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) | |
| 12 | +ifeq ($(VAR_CFLAGS),) | |
| 13 | +VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse | |
| 14 | +endif | |
| 15 | + | |
| 16 | +VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | |
| 17 | +ifeq ($(VAR_LDLIBS),) | |
| 18 | +VAR_LDLIBS := -lfuse -pthread | |
| 19 | +endif | |
| 20 | + | |
| 21 | +fuse_mnt.o: CFLAGS += $(VAR_CFLAGS) | |
| 12 | 22 | |
| 13 | 23 | include ../lib.mk |
| 14 | 24 | |
| 15 | −$(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) | |
| 25 | +$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) | |
| 16 | 26 | |
| 17 | 27 | $(OUTPUT)/memfd_test: memfd_test.c common.c |
| 18 | 28 | $(OUTPUT)/fuse_test: fuse_test.c common.c |