From 5c646b7e1d8bcb12317426287c516dfa4c5171c2 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Wed, 2 Dec 2020 04:10:32 +0800 Subject: [PATCH 01/25] KVM: arm64: Fix memory leak on stage2 update of a valid PTE When installing a new leaf PTE onto an invalid ptep, we need to get_page(ptep) to account for the new mapping. However, simply updating a valid PTE shouldn't result in any additional refcounting, as there is new mapping. This otherwise results in a page being forever wasted. Address this by fixing-up the refcount in stage2_map_walker_try_leaf() if the PTE was already valid, balancing out the later get_page() in stage2_map_walk_leaf(). Signed-off-by: Yanan Wang [maz: update commit message, add comment in the code] Signed-off-by: Marc Zyngier Acked-by: Will Deacon Link: https://lore.kernel.org/r/20201201201034.116760-2-wangyanan55@huawei.com --- arch/arm64/kvm/hyp/pgtable.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 0271b4a3b9fe..2beba1dc40ec 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -470,6 +470,15 @@ static bool stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, if (!kvm_block_mapping_supported(addr, end, phys, level)) return false; + /* + * If the PTE was already valid, drop the refcount on the table + * early, as it will be bumped-up again in stage2_map_walk_leaf(). + * This ensures that the refcount stays constant across a valid to + * valid PTE update. + */ + if (kvm_pte_valid(*ptep)) + put_page(virt_to_page(ptep)); + if (kvm_set_valid_leaf_pte(ptep, phys, data->attr, level)) goto out; From 3a0b870e3448302ca2ba703bea1b79b61c3f33c6 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Wed, 2 Dec 2020 04:10:33 +0800 Subject: [PATCH 02/25] KVM: arm64: Fix handling of merging tables into a block entry When dirty logging is enabled, we collapse block entries into tables as necessary. If dirty logging gets canceled, we can end-up merging tables back into block entries. When this happens, we must not only free the non-huge page-table pages but also invalidate all the TLB entries that can potentially cover the block. Otherwise, we end-up with multiple possible translations for the same physical page, which can legitimately result in a TLB conflict. To address this, replease the bogus invalidation by IPA with a full VM invalidation. Although this is pretty heavy handed, it happens very infrequently and saves a bunch of invalidations by IPA. Signed-off-by: Yanan Wang [maz: fixup commit message] Signed-off-by: Marc Zyngier Acked-by: Will Deacon Link: https://lore.kernel.org/r/20201201201034.116760-3-wangyanan55@huawei.com --- arch/arm64/kvm/hyp/pgtable.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 2beba1dc40ec..bdf8e55ed308 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -502,7 +502,13 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level, return 0; kvm_set_invalid_pte(ptep); - kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, data->mmu, addr, 0); + + /* + * Invalidate the whole stage-2, as we may have numerous leaf + * entries below us which would otherwise need invalidating + * individually. + */ + kvm_call_hyp(__kvm_tlb_flush_vmid, data->mmu); data->anchor = ptep; return 0; } From 7d894834a305568a0168c55d4729216f5f8cb4e6 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Wed, 2 Dec 2020 04:10:34 +0800 Subject: [PATCH 03/25] KVM: arm64: Add usage of stage 2 fault lookup level in user_mem_abort() If we get a FSC_PERM fault, just using (logging_active && writable) to determine calling kvm_pgtable_stage2_map(). There will be two more cases we should consider. (1) After logging_active is configged back to false from true. When we get a FSC_PERM fault with write_fault and adjustment of hugepage is needed, we should merge tables back to a block entry. This case is ignored by still calling kvm_pgtable_stage2_relax_perms(), which will lead to an endless loop and guest panic due to soft lockup. (2) We use (FSC_PERM && logging_active && writable) to determine collapsing a block entry into a table by calling kvm_pgtable_stage2_map(). But sometimes we may only need to relax permissions when trying to write to a page other than a block. In this condition,using kvm_pgtable_stage2_relax_perms() will be fine. The ISS filed bit[1:0] in ESR_EL2 regesiter indicates the stage2 lookup level at which a D-abort or I-abort occurred. By comparing granule of the fault lookup level with vma_pagesize, we can strictly distinguish conditions of calling kvm_pgtable_stage2_relax_perms() or kvm_pgtable_stage2_map(), and the above two cases will be well considered. Suggested-by: Keqian Zhu Signed-off-by: Yanan Wang Signed-off-by: Marc Zyngier Acked-by: Will Deacon Link: https://lore.kernel.org/r/20201201201034.116760-4-wangyanan55@huawei.com --- arch/arm64/include/asm/esr.h | 1 + arch/arm64/include/asm/kvm_emulate.h | 5 +++++ arch/arm64/kvm/mmu.c | 11 +++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 22c81f1edda2..85a3e49f92f4 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -104,6 +104,7 @@ /* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */ #define ESR_ELx_FSC (0x3F) #define ESR_ELx_FSC_TYPE (0x3C) +#define ESR_ELx_FSC_LEVEL (0x03) #define ESR_ELx_FSC_EXTABT (0x10) #define ESR_ELx_FSC_SERROR (0x11) #define ESR_ELx_FSC_ACCESS (0x08) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 5ef2669ccd6c..00bc6f1234ba 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -350,6 +350,11 @@ static __always_inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vc return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC_TYPE; } +static __always_inline u8 kvm_vcpu_trap_get_fault_level(const struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC_LEVEL; +} + static __always_inline bool kvm_vcpu_abt_issea(const struct kvm_vcpu *vcpu) { switch (kvm_vcpu_trap_get_fault(vcpu)) { diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 1a01da9fdc99..75814a02d189 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -754,10 +754,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, gfn_t gfn; kvm_pfn_t pfn; bool logging_active = memslot_is_logging(memslot); - unsigned long vma_pagesize; + unsigned long fault_level = kvm_vcpu_trap_get_fault_level(vcpu); + unsigned long vma_pagesize, fault_granule; enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R; struct kvm_pgtable *pgt; + fault_granule = 1UL << ARM64_HW_PGTABLE_LEVEL_SHIFT(fault_level); write_fault = kvm_is_write_fault(vcpu); exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu); VM_BUG_ON(write_fault && exec_fault); @@ -896,7 +898,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, else if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC)) prot |= KVM_PGTABLE_PROT_X; - if (fault_status == FSC_PERM && !(logging_active && writable)) { + /* + * Under the premise of getting a FSC_PERM fault, we just need to relax + * permissions only if vma_pagesize equals fault_granule. Otherwise, + * kvm_pgtable_stage2_map() should be called to change block size. + */ + if (fault_status == FSC_PERM && vma_pagesize == fault_granule) { ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot); } else { ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize, From 2d586494c4a001312650f0b919d534e429dd1e09 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Nov 2020 23:09:16 -0800 Subject: [PATCH 04/25] scsi: bnx2i: Requires MMU The SCSI_BNX2_ISCSI kconfig symbol selects CNIC and CNIC selects UIO, which depends on MMU. Since 'select' does not follow dependency chains, add the same MMU dependency to SCSI_BNX2_ISCSI. Quietens this kconfig warning: WARNING: unmet direct dependencies detected for CNIC Depends on [n]: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_BROADCOM [=y] && PCI [=y] && (IPV6 [=m] || IPV6 [=m]=n) && MMU [=n] Selected by [m]: - SCSI_BNX2_ISCSI [=m] && SCSI_LOWLEVEL [=y] && SCSI [=y] && NET [=y] && PCI [=y] && (IPV6 [=m] || IPV6 [=m]=n) Link: https://lore.kernel.org/r/20201129070916.3919-1-rdunlap@infradead.org Fixes: cf4e6363859d ("[SCSI] bnx2i: Add bnx2i iSCSI driver.") Cc: linux-scsi@vger.kernel.org Cc: Nilesh Javali Cc: Manish Rangankar Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Signed-off-by: Randy Dunlap Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2i/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/bnx2i/Kconfig b/drivers/scsi/bnx2i/Kconfig index 75ace2302fed..0cc06c2ce0b8 100644 --- a/drivers/scsi/bnx2i/Kconfig +++ b/drivers/scsi/bnx2i/Kconfig @@ -4,6 +4,7 @@ config SCSI_BNX2_ISCSI depends on NET depends on PCI depends on (IPV6 || IPV6=n) + depends on MMU select SCSI_ISCSI_ATTRS select NETDEVICES select ETHERNET From 0c55f867f0c96dff93d4e0b5973975d65afb26d8 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Wed, 2 Dec 2020 21:35:36 +0100 Subject: [PATCH 05/25] selftests: kvm/set_memory_region_test: Fix race in move region test The current memory region move test correctly handles the situation that the second (realigning) memslot move operation would temporarily trigger MMIO until it completes, however it does not handle the case in which the first (misaligning) move operation does this, too. This results in false test assertions in case it does so. Fix this by handling temporary MMIO from the first memslot move operation in the test guest code, too. Fixes: 8a0639fe9201 ("KVM: sefltests: Add explicit synchronization to move mem region test") Signed-off-by: Maciej S. Szmigiero Message-Id: <0fdddb94bb0e31b7da129a809a308d91c10c0b5e.1606941224.git.maciej.szmigiero@oracle.com> Signed-off-by: Paolo Bonzini --- .../selftests/kvm/set_memory_region_test.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c index b3ece55a2da6..6f441dd9f33c 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -156,14 +156,23 @@ static void guest_code_move_memory_region(void) GUEST_SYNC(0); /* - * Spin until the memory region is moved to a misaligned address. This - * may or may not trigger MMIO, as the window where the memslot is - * invalid is quite small. + * Spin until the memory region starts getting moved to a + * misaligned address. + * Every region move may or may not trigger MMIO, as the + * window where the memslot is invalid is usually quite small. */ val = guest_spin_on_val(0); GUEST_ASSERT_1(val == 1 || val == MMIO_VAL, val); - /* Spin until the memory region is realigned. */ + /* Spin until the misaligning memory region move completes. */ + val = guest_spin_on_val(MMIO_VAL); + GUEST_ASSERT_1(val == 1 || val == 0, val); + + /* Spin until the memory region starts to get re-aligned. */ + val = guest_spin_on_val(0); + GUEST_ASSERT_1(val == 1 || val == MMIO_VAL, val); + + /* Spin until the re-aligning memory region move completes. */ val = guest_spin_on_val(MMIO_VAL); GUEST_ASSERT_1(val == 1, val); From eeaf06af6f87e1dba371fbe42674e6f963220b9c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Dec 2020 15:18:26 +0300 Subject: [PATCH 06/25] scsi: be2iscsi: Revert "Fix a theoretical leak in beiscsi_create_eqs()" My patch caused kernel Oopses and delays in boot. Revert it. The problem was that I moved the "mem->dma = paddr;" before the call to be_fill_queue(). But the first thing that the be_fill_queue() function does is memset the whole struct to zero which overwrites the assignment. Link: https://lore.kernel.org/r/X8jXkt6eThjyVP1v@mwanda Fixes: 38b2db564d9a ("scsi: be2iscsi: Fix a theoretical leak in beiscsi_create_eqs()") Cc: stable Reported-by: Thomas Lamprecht Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 202ba925c494..5c3513a4b450 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -3020,7 +3020,6 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba, goto create_eq_error; } - mem->dma = paddr; mem->va = eq_vaddress; ret = be_fill_queue(eq, phba->params.num_eq_entries, sizeof(struct be_eq_entry), eq_vaddress); @@ -3030,6 +3029,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba, goto create_eq_error; } + mem->dma = paddr; ret = beiscsi_cmd_eq_create(&phba->ctrl, eq, BEISCSI_EQ_DELAY_DEF); if (ret) { @@ -3086,7 +3086,6 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba, goto create_cq_error; } - mem->dma = paddr; ret = be_fill_queue(cq, phba->params.num_cq_entries, sizeof(struct sol_cqe), cq_vaddress); if (ret) { @@ -3096,6 +3095,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba, goto create_cq_error; } + mem->dma = paddr; ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0); if (ret) { From a2b2d4bf5076832339762556b816eec58ca38f77 Mon Sep 17 00:00:00 2001 From: Jacob Xu Date: Thu, 3 Dec 2020 12:59:39 -0800 Subject: [PATCH 07/25] kvm: svm: de-allocate svm_cpu_data for all cpus in svm_cpu_uninit() The cpu arg for svm_cpu_uninit() was previously ignored resulting in the per cpu structure svm_cpu_data not being de-allocated for all cpus. Signed-off-by: Jacob Xu Message-Id: <20201203205939.1783969-1-jacobhxu@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 79b3a564f1c9..da7eb4aaf44f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -530,12 +530,12 @@ static int svm_hardware_enable(void) static void svm_cpu_uninit(int cpu) { - struct svm_cpu_data *sd = per_cpu(svm_data, raw_smp_processor_id()); + struct svm_cpu_data *sd = per_cpu(svm_data, cpu); if (!sd) return; - per_cpu(svm_data, raw_smp_processor_id()) = NULL; + per_cpu(svm_data, cpu) = NULL; kfree(sd->sev_vmcbs); __free_page(sd->save_area); kfree(sd); From 339f5a7fb2d6350fdb11f067da5240fd97e4f284 Mon Sep 17 00:00:00 2001 From: Rick Edgecombe Date: Thu, 3 Dec 2020 15:11:20 -0800 Subject: [PATCH 08/25] kvm: x86/mmu: Use cpuid to determine max gfn In the TDP MMU, use shadow_phys_bits to dermine the maximum possible GFN mapped in the guest for zapping operations. boot_cpu_data.x86_phys_bits may be reduced in the case of HW features that steal HPA bits for other purposes. However, this doesn't necessarily reduce GPA space that can be accessed via TDP. So zap based on a maximum gfn calculated with MAXPHYADDR retrieved from CPUID. This is already stored in shadow_phys_bits, so use it instead of x86_phys_bits. Fixes: faaf05b00aec ("kvm: x86/mmu: Support zapping SPTEs in the TDP MMU") Signed-off-by: Rick Edgecombe Message-Id: <20201203231120.27307-1-rick.p.edgecombe@intel.com> Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/tdp_mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index ff28a5c6abd6..84c8f06bec26 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -66,7 +66,7 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root) { - gfn_t max_gfn = 1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT); + gfn_t max_gfn = 1ULL << (shadow_phys_bits - PAGE_SHIFT); lockdep_assert_held(&kvm->mmu_lock); @@ -456,7 +456,7 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end) void kvm_tdp_mmu_zap_all(struct kvm *kvm) { - gfn_t max_gfn = 1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT); + gfn_t max_gfn = 1ULL << (shadow_phys_bits - PAGE_SHIFT); bool flush; flush = kvm_tdp_mmu_zap_gfn_range(kvm, 0, max_gfn); From 4e302c3b568eaf2aeebba804c07aba5d921a8c9e Mon Sep 17 00:00:00 2001 From: Diego Santa Cruz Date: Thu, 3 Dec 2020 22:47:03 +0100 Subject: [PATCH 09/25] misc: eeprom: at24: fix NVMEM name with custom AT24 device name When the "label" property is set on the AT24 EEPROM the NVMEM devid is set to NVMEM_DEVID_NONE, but it is not effective since there is a leftover line setting it back to NVMEM_DEVID_AUTO a few lines after. Fixes: 61f764c307f6 ("eeprom: at24: Support custom device names for AT24 EEPROMs") Signed-off-by: Diego Santa Cruz Signed-off-by: Bartosz Golaszewski --- drivers/misc/eeprom/at24.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 1c0a41803bb6..926408b41270 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -736,7 +736,6 @@ static int at24_probe(struct i2c_client *client) nvmem_config.type = NVMEM_TYPE_EEPROM; nvmem_config.dev = dev; - nvmem_config.id = NVMEM_DEVID_AUTO; nvmem_config.read_only = !writable; nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO); nvmem_config.owner = THIS_MODULE; From 3b384bd6c3f2d6d3526c77bfb264dfbaf737bc2a Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Sun, 6 Dec 2020 22:05:13 -0800 Subject: [PATCH 10/25] Input: raydium_ts_i2c - do not split tx transactions Raydium device does not like splitting of tx transactions into multiple messages - one for the register address and one for the actual data. This results in incorrect behavior on the device side. This change updates raydium_i2c_read and raydium_i2c_write to create i2c_msg arrays separately and passes those arrays into raydium_i2c_xfer which decides based on the address whether the bank switch command should be sent. The bank switch header is still added by raydium_i2c_read and raydium_i2c_write to ensure that all these operations are performed as part of a single I2C transfer. It guarantees that no other transactions are initiated to any other device on the same bus after the bank switch command is sent. Signed-off-by: Furquan Shaikh Link: https://lore.kernel.org/r/20201205005941.1427643-1-furquan@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/raydium_i2c_ts.c | 126 ++++++++++++++------- 1 file changed, 88 insertions(+), 38 deletions(-) diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index e694a9b2b1e5..603a948460d6 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -137,45 +137,25 @@ struct raydium_data { bool wake_irq_enabled; }; -static int raydium_i2c_xfer(struct i2c_client *client, - u32 addr, void *data, size_t len, bool is_read) +/* + * Header to be sent for RM_CMD_BANK_SWITCH command. This is used by + * raydium_i2c_{read|send} below. + */ +struct __packed raydium_bank_switch_header { + u8 cmd; + __be32 be_addr; +}; + +static int raydium_i2c_xfer(struct i2c_client *client, u32 addr, + struct i2c_msg *xfer, size_t xfer_count) { - struct raydium_bank_switch_header { - u8 cmd; - __be32 be_addr; - } __packed header = { - .cmd = RM_CMD_BANK_SWITCH, - .be_addr = cpu_to_be32(addr), - }; - - u8 reg_addr = addr & 0xff; - - struct i2c_msg xfer[] = { - { - .addr = client->addr, - .len = sizeof(header), - .buf = (u8 *)&header, - }, - { - .addr = client->addr, - .len = 1, - .buf = ®_addr, - }, - { - .addr = client->addr, - .len = len, - .buf = data, - .flags = is_read ? I2C_M_RD : 0, - } - }; - + int ret; /* * If address is greater than 255, then RM_CMD_BANK_SWITCH needs to be * sent first. Else, skip the header i.e. xfer[0]. */ int xfer_start_idx = (addr > 0xff) ? 0 : 1; - size_t xfer_count = ARRAY_SIZE(xfer) - xfer_start_idx; - int ret; + xfer_count -= xfer_start_idx; ret = i2c_transfer(client->adapter, &xfer[xfer_start_idx], xfer_count); if (likely(ret == xfer_count)) @@ -189,10 +169,46 @@ static int raydium_i2c_send(struct i2c_client *client, { int tries = 0; int error; + u8 *tx_buf; + u8 reg_addr = addr & 0xff; + + tx_buf = kmalloc(len + 1, GFP_KERNEL); + if (!tx_buf) + return -ENOMEM; + + tx_buf[0] = reg_addr; + memcpy(tx_buf + 1, data, len); do { - error = raydium_i2c_xfer(client, addr, (void *)data, len, - false); + struct raydium_bank_switch_header header = { + .cmd = RM_CMD_BANK_SWITCH, + .be_addr = cpu_to_be32(addr), + }; + + /* + * Perform as a single i2c_transfer transaction to ensure that + * no other I2C transactions are initiated on the bus to any + * other device in between. Initiating transacations to other + * devices after RM_CMD_BANK_SWITCH is sent is known to cause + * issues. This is also why regmap infrastructure cannot be used + * for this driver. Regmap handles page(bank) switch and reads + * as separate i2c_transfer() operations. This can result in + * problems if the Raydium device is on a shared I2C bus. + */ + struct i2c_msg xfer[] = { + { + .addr = client->addr, + .len = sizeof(header), + .buf = (u8 *)&header, + }, + { + .addr = client->addr, + .len = len + 1, + .buf = tx_buf, + }, + }; + + error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); if (likely(!error)) return 0; @@ -206,12 +222,46 @@ static int raydium_i2c_send(struct i2c_client *client, static int raydium_i2c_read(struct i2c_client *client, u32 addr, void *data, size_t len) { - size_t xfer_len; int error; while (len) { - xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); - error = raydium_i2c_xfer(client, addr, data, xfer_len, true); + u8 reg_addr = addr & 0xff; + struct raydium_bank_switch_header header = { + .cmd = RM_CMD_BANK_SWITCH, + .be_addr = cpu_to_be32(addr), + }; + size_t xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); + + /* + * Perform as a single i2c_transfer transaction to ensure that + * no other I2C transactions are initiated on the bus to any + * other device in between. Initiating transacations to other + * devices after RM_CMD_BANK_SWITCH is sent is known to cause + * issues. This is also why regmap infrastructure cannot be used + * for this driver. Regmap handles page(bank) switch and writes + * as separate i2c_transfer() operations. This can result in + * problems if the Raydium device is on a shared I2C bus. + */ + struct i2c_msg xfer[] = { + { + .addr = client->addr, + .len = sizeof(header), + .buf = (u8 *)&header, + }, + { + .addr = client->addr, + .len = 1, + .buf = ®_addr, + }, + { + .addr = client->addr, + .len = xfer_len, + .buf = data, + .flags = I2C_M_RD, + } + }; + + error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); if (unlikely(error)) return error; From 223f61b8c5ad80f01900bc25f8073dfa4f23a2be Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 6 Dec 2020 21:59:42 -0800 Subject: [PATCH 11/25] Input: soc_button_array - add Lenovo Yoga Tablet2 1051L to the dmi_use_low_level_irq list Add the Lenovo Yoga Tablet2 1051L to the list of devices where the ACPI AML code is poking the GPIO config register directly changing the IRQ type to a low_level_irq, which we need to work around. This fixes the home button on the Lenovo Yoga Tablet2 1051L not working. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201206161245.24798-1-hdegoede@redhat.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/soc_button_array.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index d14a65683c5e..cb6ec59a045d 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -83,6 +83,17 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = { DMI_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, }, + { + /* + * Lenovo Yoga Tab2 1051L, something messes with the home-button + * IRQ settings, leading to a non working home-button. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "60073"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1051L"), + }, + }, {} /* Terminating entry */ }; From e8c954df234145c5765870382c2bc630a48beec9 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 6 Dec 2020 22:22:46 +0000 Subject: [PATCH 12/25] io_uring: fix mis-seting personality's creds After io_identity_cow() copies an work.identity it wants to copy creds to the new just allocated id, not the old one. Otherwise it's akin to req->work.identity->creds = req->work.identity->creds. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index a2a7c65a77aa..908817cea4f5 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1284,7 +1284,7 @@ static bool io_identity_cow(struct io_kiocb *req) */ io_init_identity(id); if (creds) - req->work.identity->creds = creds; + id->creds = creds; /* add one for this request */ refcount_inc(&id->count); From 673235f915318ced5d7ec4b2bfd8cb909e6a4a55 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 2 Dec 2020 18:04:19 +0800 Subject: [PATCH 13/25] scsi: core: Fix race between handling STS_RESOURCE and completion When queuing I/O request to LLD, STS_RESOURCE may be returned because: - Host is in recovery or blocked - Target queue throttling or target is blocked - LLD rejection In these scenarios BLK_STS_DEV_RESOURCE is returned to the block layer to avoid an unnecessary re-run of the queue. However, all of the requests queued to this SCSI device may complete immediately after reading 'sdev->device_busy' and BLK_STS_DEV_RESOURCE is returned to block layer. In that case the current I/O won't get a chance to get queued since it is invisible at that time for both scsi_run_queue_async() and blk-mq's RESTART. Fix the issue by not returning BLK_STS_DEV_RESOURCE in this situation. Link: https://lore.kernel.org/r/20201202100419.525144-1-ming.lei@redhat.com Fixes: 86ff7c2a80cd ("blk-mq: introduce BLK_STS_DEV_RESOURCE") Cc: Hannes Reinecke Cc: Sumit Saxena Cc: Kashyap Desai Cc: Bart Van Assche Cc: Ewan Milne Cc: Long Li Reported-by: John Garry Tested-by: "chenxiang (M)" Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 60c7a7d74852..03c6d0620bfd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1703,8 +1703,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, break; case BLK_STS_RESOURCE: case BLK_STS_ZONE_RESOURCE: - if (atomic_read(&sdev->device_busy) || - scsi_device_blocked(sdev)) + if (scsi_device_blocked(sdev)) ret = BLK_STS_DEV_RESOURCE; break; default: From 359db63378eded1ee9c8c9ad72245f9b0158ae95 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Mon, 7 Dec 2020 21:30:55 +0800 Subject: [PATCH 14/25] scsi: hisi_sas: Select a suitable queue for internal I/Os For when managed interrupts are used (and shost->nr_hw_queues is set), a fixed queue - set per-device - is still used for internal I/Os. If all the CPUs mapped to that queue are offlined, then the completions for that queue are not serviced and any internal I/Os will time out. Fix by selecting a queue for internal I/Os from the queue mapped from the current CPU in this scenario. This is still not ideal as it does not deal with CPU hotplug for inflight internal I/Os, and needs proper support from [0]. [0] https://lore.kernel.org/linux-scsi/20200703130122.111448-1-hare@suse.de/T/#m7d77d049b18f33a24ef206af69ebb66d07440556 Link: https://lore.kernel.org/r/1607347855-59091-1-git-send-email-john.garry@huawei.com Fixes: 8d98416a55eb ("scsi: hisi_sas: Switch v3 hw to MQ") Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index c8dd8588f800..274ccf18ce2d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -452,6 +452,12 @@ static int hisi_sas_task_prep(struct sas_task *task, blk_tag = blk_mq_unique_tag(scmd->request); dq_index = blk_mq_unique_tag_to_hwq(blk_tag); *dq_pointer = dq = &hisi_hba->dq[dq_index]; + } else if (hisi_hba->shost->nr_hw_queues) { + struct Scsi_Host *shost = hisi_hba->shost; + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + int queue = qmap->mq_map[raw_smp_processor_id()]; + + *dq_pointer = dq = &hisi_hba->dq[queue]; } else { *dq_pointer = dq = sas_dev->dq; } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 7133ca859b5e..960de375ce69 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2452,6 +2452,11 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) rc = -ENOENT; goto free_irq_vectors; } + cq->irq_mask = pci_irq_get_affinity(pdev, i + BASE_VECTORS_V3_HW); + if (!cq->irq_mask) { + dev_err(dev, "could not get cq%d irq affinity!\n", i); + return -ENOENT; + } } return 0; From f26c08b444df833b19c00838a530d93963ce9cd0 Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Tue, 8 Dec 2020 08:54:26 -0700 Subject: [PATCH 15/25] io_uring: fix file leak on error path of io ctx creation Put file as part of error handling when setting up io ctx to fix memory leaks like the following one. BUG: memory leak unreferenced object 0xffff888101ea2200 (size 256): comm "syz-executor355", pid 8470, jiffies 4294953658 (age 32.400s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 20 59 03 01 81 88 ff ff 80 87 a8 10 81 88 ff ff Y.............. backtrace: [<000000002e0a7c5f>] kmem_cache_zalloc include/linux/slab.h:654 [inline] [<000000002e0a7c5f>] __alloc_file+0x1f/0x130 fs/file_table.c:101 [<000000001a55b73a>] alloc_empty_file+0x69/0x120 fs/file_table.c:151 [<00000000fb22349e>] alloc_file+0x33/0x1b0 fs/file_table.c:193 [<000000006e1465bb>] alloc_file_pseudo+0xb2/0x140 fs/file_table.c:233 [<000000007118092a>] anon_inode_getfile fs/anon_inodes.c:91 [inline] [<000000007118092a>] anon_inode_getfile+0xaa/0x120 fs/anon_inodes.c:74 [<000000002ae99012>] io_uring_get_fd fs/io_uring.c:9198 [inline] [<000000002ae99012>] io_uring_create fs/io_uring.c:9377 [inline] [<000000002ae99012>] io_uring_setup+0x1125/0x1630 fs/io_uring.c:9411 [<000000008280baad>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 [<00000000685d8cf0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported-by: syzbot+71c4697e27c99fddcf17@syzkaller.appspotmail.com Fixes: 0f2122045b94 ("io_uring: don't rely on weak ->files references") Cc: Pavel Begunkov Signed-off-by: Hillf Danton Signed-off-by: Jens Axboe --- fs/io_uring.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 908817cea4f5..86dac2b2e276 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9183,6 +9183,7 @@ static int io_uring_get_fd(struct io_ring_ctx *ctx) { struct file *file; int ret; + int fd; #if defined(CONFIG_UNIX) ret = sock_create_kern(&init_net, PF_UNIX, SOCK_RAW, IPPROTO_IP, @@ -9194,12 +9195,12 @@ static int io_uring_get_fd(struct io_ring_ctx *ctx) ret = get_unused_fd_flags(O_RDWR | O_CLOEXEC); if (ret < 0) goto err; + fd = ret; file = anon_inode_getfile("[io_uring]", &io_uring_fops, ctx, O_RDWR | O_CLOEXEC); if (IS_ERR(file)) { -err_fd: - put_unused_fd(ret); + put_unused_fd(fd); ret = PTR_ERR(file); goto err; } @@ -9207,12 +9208,14 @@ static int io_uring_get_fd(struct io_ring_ctx *ctx) #if defined(CONFIG_UNIX) ctx->ring_sock->file = file; #endif - if (unlikely(io_uring_add_task_file(ctx, file))) { - file = ERR_PTR(-ENOMEM); - goto err_fd; + ret = io_uring_add_task_file(ctx, file); + if (ret) { + fput(file); + put_unused_fd(fd); + goto err; } - fd_install(ret, file); - return ret; + fd_install(fd, file); + return fd; err: #if defined(CONFIG_UNIX) sock_release(ctx->ring_sock); From ca33479cc7be2c9b5f8be078c8bf3ac26b7d6186 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 7 Dec 2020 08:31:22 +0100 Subject: [PATCH 16/25] xen: add helpers for caching grant mapping pages Instead of having similar helpers in multiple backend drivers use common helpers for caching pages allocated via gnttab_alloc_pages(). Make use of those helpers in blkback and scsiback. Cc: # 5.9 Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/block/xen-blkback/blkback.c | 89 ++++++----------------------- drivers/block/xen-blkback/common.h | 4 +- drivers/block/xen-blkback/xenbus.c | 6 +- drivers/xen/grant-table.c | 72 +++++++++++++++++++++++ drivers/xen/xen-scsiback.c | 60 ++++--------------- include/xen/grant_table.h | 13 +++++ 6 files changed, 116 insertions(+), 128 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 501e9dacfff9..9ebf53903d7b 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -132,73 +132,12 @@ module_param(log_stats, int, 0644); #define BLKBACK_INVALID_HANDLE (~0) -/* Number of free pages to remove on each call to gnttab_free_pages */ -#define NUM_BATCH_FREE_PAGES 10 - static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt) { return pgrant_timeout && (jiffies - persistent_gnt->last_used >= HZ * pgrant_timeout); } -static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page) -{ - unsigned long flags; - - spin_lock_irqsave(&ring->free_pages_lock, flags); - if (list_empty(&ring->free_pages)) { - BUG_ON(ring->free_pages_num != 0); - spin_unlock_irqrestore(&ring->free_pages_lock, flags); - return gnttab_alloc_pages(1, page); - } - BUG_ON(ring->free_pages_num == 0); - page[0] = list_first_entry(&ring->free_pages, struct page, lru); - list_del(&page[0]->lru); - ring->free_pages_num--; - spin_unlock_irqrestore(&ring->free_pages_lock, flags); - - return 0; -} - -static inline void put_free_pages(struct xen_blkif_ring *ring, struct page **page, - int num) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&ring->free_pages_lock, flags); - for (i = 0; i < num; i++) - list_add(&page[i]->lru, &ring->free_pages); - ring->free_pages_num += num; - spin_unlock_irqrestore(&ring->free_pages_lock, flags); -} - -static inline void shrink_free_pagepool(struct xen_blkif_ring *ring, int num) -{ - /* Remove requested pages in batches of NUM_BATCH_FREE_PAGES */ - struct page *page[NUM_BATCH_FREE_PAGES]; - unsigned int num_pages = 0; - unsigned long flags; - - spin_lock_irqsave(&ring->free_pages_lock, flags); - while (ring->free_pages_num > num) { - BUG_ON(list_empty(&ring->free_pages)); - page[num_pages] = list_first_entry(&ring->free_pages, - struct page, lru); - list_del(&page[num_pages]->lru); - ring->free_pages_num--; - if (++num_pages == NUM_BATCH_FREE_PAGES) { - spin_unlock_irqrestore(&ring->free_pages_lock, flags); - gnttab_free_pages(num_pages, page); - spin_lock_irqsave(&ring->free_pages_lock, flags); - num_pages = 0; - } - } - spin_unlock_irqrestore(&ring->free_pages_lock, flags); - if (num_pages != 0) - gnttab_free_pages(num_pages, page); -} - #define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page))) static int do_block_io_op(struct xen_blkif_ring *ring, unsigned int *eoi_flags); @@ -331,7 +270,8 @@ static void free_persistent_gnts(struct xen_blkif_ring *ring, struct rb_root *ro unmap_data.count = segs_to_unmap; BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); - put_free_pages(ring, pages, segs_to_unmap); + gnttab_page_cache_put(&ring->free_pages, pages, + segs_to_unmap); segs_to_unmap = 0; } @@ -371,7 +311,8 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { unmap_data.count = segs_to_unmap; BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); - put_free_pages(ring, pages, segs_to_unmap); + gnttab_page_cache_put(&ring->free_pages, pages, + segs_to_unmap); segs_to_unmap = 0; } kfree(persistent_gnt); @@ -379,7 +320,7 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) if (segs_to_unmap > 0) { unmap_data.count = segs_to_unmap; BUG_ON(gnttab_unmap_refs_sync(&unmap_data)); - put_free_pages(ring, pages, segs_to_unmap); + gnttab_page_cache_put(&ring->free_pages, pages, segs_to_unmap); } } @@ -664,9 +605,10 @@ int xen_blkif_schedule(void *arg) /* Shrink the free pages pool if it is too large. */ if (time_before(jiffies, blkif->buffer_squeeze_end)) - shrink_free_pagepool(ring, 0); + gnttab_page_cache_shrink(&ring->free_pages, 0); else - shrink_free_pagepool(ring, max_buffer_pages); + gnttab_page_cache_shrink(&ring->free_pages, + max_buffer_pages); if (log_stats && time_after(jiffies, ring->st_print)) print_stats(ring); @@ -697,7 +639,7 @@ void xen_blkbk_free_caches(struct xen_blkif_ring *ring) ring->persistent_gnt_c = 0; /* Since we are shutting down remove all pages from the buffer */ - shrink_free_pagepool(ring, 0 /* All */); + gnttab_page_cache_shrink(&ring->free_pages, 0 /* All */); } static unsigned int xen_blkbk_unmap_prepare( @@ -736,7 +678,7 @@ static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_ but is this the best way to deal with this? */ BUG_ON(result); - put_free_pages(ring, data->pages, data->count); + gnttab_page_cache_put(&ring->free_pages, data->pages, data->count); make_response(ring, pending_req->id, pending_req->operation, pending_req->status); free_req(ring, pending_req); @@ -803,7 +745,8 @@ static void xen_blkbk_unmap(struct xen_blkif_ring *ring, if (invcount) { ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); BUG_ON(ret); - put_free_pages(ring, unmap_pages, invcount); + gnttab_page_cache_put(&ring->free_pages, unmap_pages, + invcount); } pages += batch; num -= batch; @@ -850,7 +793,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, pages[i]->page = persistent_gnt->page; pages[i]->persistent_gnt = persistent_gnt; } else { - if (get_free_page(ring, &pages[i]->page)) + if (gnttab_page_cache_get(&ring->free_pages, + &pages[i]->page)) goto out_of_memory; addr = vaddr(pages[i]->page); pages_to_gnt[segs_to_map] = pages[i]->page; @@ -883,7 +827,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, BUG_ON(new_map_idx >= segs_to_map); if (unlikely(map[new_map_idx].status != 0)) { pr_debug("invalid buffer -- could not remap it\n"); - put_free_pages(ring, &pages[seg_idx]->page, 1); + gnttab_page_cache_put(&ring->free_pages, + &pages[seg_idx]->page, 1); pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE; ret |= 1; goto next; @@ -944,7 +889,7 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, out_of_memory: pr_alert("%s: out of memory\n", __func__); - put_free_pages(ring, pages_to_gnt, segs_to_map); + gnttab_page_cache_put(&ring->free_pages, pages_to_gnt, segs_to_map); for (i = last_map; i < num; i++) pages[i]->handle = BLKBACK_INVALID_HANDLE; return -ENOMEM; diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index c6ea5d38c509..a1b9df2c4ef1 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -288,9 +288,7 @@ struct xen_blkif_ring { struct work_struct persistent_purge_work; /* Buffer of free pages to map grant refs. */ - spinlock_t free_pages_lock; - int free_pages_num; - struct list_head free_pages; + struct gnttab_page_cache free_pages; struct work_struct free_work; /* Thread shutdown wait queue. */ diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index f5705569e2a7..76912c584a76 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -144,8 +144,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) INIT_LIST_HEAD(&ring->pending_free); INIT_LIST_HEAD(&ring->persistent_purge_list); INIT_WORK(&ring->persistent_purge_work, xen_blkbk_unmap_purged_grants); - spin_lock_init(&ring->free_pages_lock); - INIT_LIST_HEAD(&ring->free_pages); + gnttab_page_cache_init(&ring->free_pages); spin_lock_init(&ring->pending_free_lock); init_waitqueue_head(&ring->pending_free_wq); @@ -317,8 +316,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) BUG_ON(atomic_read(&ring->persistent_gnt_in_use) != 0); BUG_ON(!list_empty(&ring->persistent_purge_list)); BUG_ON(!RB_EMPTY_ROOT(&ring->persistent_gnts)); - BUG_ON(!list_empty(&ring->free_pages)); - BUG_ON(ring->free_pages_num != 0); + BUG_ON(ring->free_pages.num_pages != 0); BUG_ON(ring->persistent_gnt_c != 0); WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); ring->active = false; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 523dcdf39cc9..e2e42912f241 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -813,6 +813,78 @@ int gnttab_alloc_pages(int nr_pages, struct page **pages) } EXPORT_SYMBOL_GPL(gnttab_alloc_pages); +void gnttab_page_cache_init(struct gnttab_page_cache *cache) +{ + spin_lock_init(&cache->lock); + INIT_LIST_HEAD(&cache->pages); + cache->num_pages = 0; +} +EXPORT_SYMBOL_GPL(gnttab_page_cache_init); + +int gnttab_page_cache_get(struct gnttab_page_cache *cache, struct page **page) +{ + unsigned long flags; + + spin_lock_irqsave(&cache->lock, flags); + + if (list_empty(&cache->pages)) { + spin_unlock_irqrestore(&cache->lock, flags); + return gnttab_alloc_pages(1, page); + } + + page[0] = list_first_entry(&cache->pages, struct page, lru); + list_del(&page[0]->lru); + cache->num_pages--; + + spin_unlock_irqrestore(&cache->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(gnttab_page_cache_get); + +void gnttab_page_cache_put(struct gnttab_page_cache *cache, struct page **page, + unsigned int num) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&cache->lock, flags); + + for (i = 0; i < num; i++) + list_add(&page[i]->lru, &cache->pages); + cache->num_pages += num; + + spin_unlock_irqrestore(&cache->lock, flags); +} +EXPORT_SYMBOL_GPL(gnttab_page_cache_put); + +void gnttab_page_cache_shrink(struct gnttab_page_cache *cache, unsigned int num) +{ + struct page *page[10]; + unsigned int i = 0; + unsigned long flags; + + spin_lock_irqsave(&cache->lock, flags); + + while (cache->num_pages > num) { + page[i] = list_first_entry(&cache->pages, struct page, lru); + list_del(&page[i]->lru); + cache->num_pages--; + if (++i == ARRAY_SIZE(page)) { + spin_unlock_irqrestore(&cache->lock, flags); + gnttab_free_pages(i, page); + i = 0; + spin_lock_irqsave(&cache->lock, flags); + } + } + + spin_unlock_irqrestore(&cache->lock, flags); + + if (i != 0) + gnttab_free_pages(i, page); +} +EXPORT_SYMBOL_GPL(gnttab_page_cache_shrink); + void gnttab_pages_clear_private(int nr_pages, struct page **pages) { int i; diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 4acc4e899600..862162dca33c 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -99,6 +99,8 @@ struct vscsibk_info { struct list_head v2p_entry_lists; wait_queue_head_t waiting_to_free; + + struct gnttab_page_cache free_pages; }; /* theoretical maximum of grants for one request */ @@ -188,10 +190,6 @@ module_param_named(max_buffer_pages, scsiback_max_buffer_pages, int, 0644); MODULE_PARM_DESC(max_buffer_pages, "Maximum number of free pages to keep in backend buffer"); -static DEFINE_SPINLOCK(free_pages_lock); -static int free_pages_num; -static LIST_HEAD(scsiback_free_pages); - /* Global spinlock to protect scsiback TPG list */ static DEFINE_MUTEX(scsiback_mutex); static LIST_HEAD(scsiback_list); @@ -207,41 +205,6 @@ static void scsiback_put(struct vscsibk_info *info) wake_up(&info->waiting_to_free); } -static void put_free_pages(struct page **page, int num) -{ - unsigned long flags; - int i = free_pages_num + num, n = num; - - if (num == 0) - return; - if (i > scsiback_max_buffer_pages) { - n = min(num, i - scsiback_max_buffer_pages); - gnttab_free_pages(n, page + num - n); - n = num - n; - } - spin_lock_irqsave(&free_pages_lock, flags); - for (i = 0; i < n; i++) - list_add(&page[i]->lru, &scsiback_free_pages); - free_pages_num += n; - spin_unlock_irqrestore(&free_pages_lock, flags); -} - -static int get_free_page(struct page **page) -{ - unsigned long flags; - - spin_lock_irqsave(&free_pages_lock, flags); - if (list_empty(&scsiback_free_pages)) { - spin_unlock_irqrestore(&free_pages_lock, flags); - return gnttab_alloc_pages(1, page); - } - page[0] = list_first_entry(&scsiback_free_pages, struct page, lru); - list_del(&page[0]->lru); - free_pages_num--; - spin_unlock_irqrestore(&free_pages_lock, flags); - return 0; -} - static unsigned long vaddr_page(struct page *page) { unsigned long pfn = page_to_pfn(page); @@ -302,7 +265,8 @@ static void scsiback_fast_flush_area(struct vscsibk_pend *req) BUG_ON(err); } - put_free_pages(req->pages, req->n_grants); + gnttab_page_cache_put(&req->info->free_pages, req->pages, + req->n_grants); req->n_grants = 0; } @@ -445,8 +409,8 @@ static int scsiback_gnttab_data_map_list(struct vscsibk_pend *pending_req, struct vscsibk_info *info = pending_req->info; for (i = 0; i < cnt; i++) { - if (get_free_page(pg + mapcount)) { - put_free_pages(pg, mapcount); + if (gnttab_page_cache_get(&info->free_pages, pg + mapcount)) { + gnttab_page_cache_put(&info->free_pages, pg, mapcount); pr_err("no grant page\n"); return -ENOMEM; } @@ -796,6 +760,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info, cond_resched(); } + gnttab_page_cache_shrink(&info->free_pages, scsiback_max_buffer_pages); + RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do); return more_to_do; } @@ -1233,6 +1199,8 @@ static int scsiback_remove(struct xenbus_device *dev) scsiback_release_translation_entry(info); + gnttab_page_cache_shrink(&info->free_pages, 0); + dev_set_drvdata(&dev->dev, NULL); return 0; @@ -1263,6 +1231,7 @@ static int scsiback_probe(struct xenbus_device *dev, info->irq = 0; INIT_LIST_HEAD(&info->v2p_entry_lists); spin_lock_init(&info->v2p_lock); + gnttab_page_cache_init(&info->free_pages); err = xenbus_printf(XBT_NIL, dev->nodename, "feature-sg-grant", "%u", SG_ALL); @@ -1879,13 +1848,6 @@ static int __init scsiback_init(void) static void __exit scsiback_exit(void) { - struct page *page; - - while (free_pages_num) { - if (get_free_page(&page)) - BUG(); - gnttab_free_pages(1, &page); - } target_unregister_template(&scsiback_ops); xenbus_unregister_driver(&scsiback_driver); } diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 9bc5bc07d4d3..c6ef8ffc1a09 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -198,6 +198,19 @@ void gnttab_free_auto_xlat_frames(void); int gnttab_alloc_pages(int nr_pages, struct page **pages); void gnttab_free_pages(int nr_pages, struct page **pages); +struct gnttab_page_cache { + spinlock_t lock; + struct list_head pages; + unsigned int num_pages; +}; + +void gnttab_page_cache_init(struct gnttab_page_cache *cache); +int gnttab_page_cache_get(struct gnttab_page_cache *cache, struct page **page); +void gnttab_page_cache_put(struct gnttab_page_cache *cache, struct page **page, + unsigned int num); +void gnttab_page_cache_shrink(struct gnttab_page_cache *cache, + unsigned int num); + #ifdef CONFIG_XEN_GRANT_DMA_ALLOC struct gnttab_dma_alloc_args { /* Device for which DMA memory will be/was allocated. */ From ee32f32335e8c7f6154bf397f4ac9b6175b488a8 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 7 Dec 2020 09:36:14 +0100 Subject: [PATCH 17/25] xen: don't use page->lru for ZONE_DEVICE memory Commit 9e2369c06c8a18 ("xen: add helpers to allocate unpopulated memory") introduced usage of ZONE_DEVICE memory for foreign memory mappings. Unfortunately this collides with using page->lru for Xen backend private page caches. Fix that by using page->zone_device_data instead. Cc: # 5.9 Fixes: 9e2369c06c8a18 ("xen: add helpers to allocate unpopulated memory") Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Reviewed-by: Jason Andryuk Signed-off-by: Juergen Gross --- drivers/xen/grant-table.c | 65 +++++++++++++++++++++++++++++---- drivers/xen/unpopulated-alloc.c | 20 +++++----- include/xen/grant_table.h | 4 ++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index e2e42912f241..3729bea0c989 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -813,10 +813,63 @@ int gnttab_alloc_pages(int nr_pages, struct page **pages) } EXPORT_SYMBOL_GPL(gnttab_alloc_pages); +#ifdef CONFIG_XEN_UNPOPULATED_ALLOC +static inline void cache_init(struct gnttab_page_cache *cache) +{ + cache->pages = NULL; +} + +static inline bool cache_empty(struct gnttab_page_cache *cache) +{ + return !cache->pages; +} + +static inline struct page *cache_deq(struct gnttab_page_cache *cache) +{ + struct page *page; + + page = cache->pages; + cache->pages = page->zone_device_data; + + return page; +} + +static inline void cache_enq(struct gnttab_page_cache *cache, struct page *page) +{ + page->zone_device_data = cache->pages; + cache->pages = page; +} +#else +static inline void cache_init(struct gnttab_page_cache *cache) +{ + INIT_LIST_HEAD(&cache->pages); +} + +static inline bool cache_empty(struct gnttab_page_cache *cache) +{ + return list_empty(&cache->pages); +} + +static inline struct page *cache_deq(struct gnttab_page_cache *cache) +{ + struct page *page; + + page = list_first_entry(&cache->pages, struct page, lru); + list_del(&page->lru); + + return page; +} + +static inline void cache_enq(struct gnttab_page_cache *cache, struct page *page) +{ + list_add(&page->lru, &cache->pages); +} +#endif + void gnttab_page_cache_init(struct gnttab_page_cache *cache) { spin_lock_init(&cache->lock); - INIT_LIST_HEAD(&cache->pages); + cache_init(cache); cache->num_pages = 0; } EXPORT_SYMBOL_GPL(gnttab_page_cache_init); @@ -827,13 +880,12 @@ int gnttab_page_cache_get(struct gnttab_page_cache *cache, struct page **page) spin_lock_irqsave(&cache->lock, flags); - if (list_empty(&cache->pages)) { + if (cache_empty(cache)) { spin_unlock_irqrestore(&cache->lock, flags); return gnttab_alloc_pages(1, page); } - page[0] = list_first_entry(&cache->pages, struct page, lru); - list_del(&page[0]->lru); + page[0] = cache_deq(cache); cache->num_pages--; spin_unlock_irqrestore(&cache->lock, flags); @@ -851,7 +903,7 @@ void gnttab_page_cache_put(struct gnttab_page_cache *cache, struct page **page, spin_lock_irqsave(&cache->lock, flags); for (i = 0; i < num; i++) - list_add(&page[i]->lru, &cache->pages); + cache_enq(cache, page[i]); cache->num_pages += num; spin_unlock_irqrestore(&cache->lock, flags); @@ -867,8 +919,7 @@ void gnttab_page_cache_shrink(struct gnttab_page_cache *cache, unsigned int num) spin_lock_irqsave(&cache->lock, flags); while (cache->num_pages > num) { - page[i] = list_first_entry(&cache->pages, struct page, lru); - list_del(&page[i]->lru); + page[i] = cache_deq(cache); cache->num_pages--; if (++i == ARRAY_SIZE(page)) { spin_unlock_irqrestore(&cache->lock, flags); diff --git a/drivers/xen/unpopulated-alloc.c b/drivers/xen/unpopulated-alloc.c index 8c512ea550bb..7762c1bb23cb 100644 --- a/drivers/xen/unpopulated-alloc.c +++ b/drivers/xen/unpopulated-alloc.c @@ -12,7 +12,7 @@ #include static DEFINE_MUTEX(list_lock); -static LIST_HEAD(page_list); +static struct page *page_list; static unsigned int list_count; static int fill_list(unsigned int nr_pages) @@ -84,7 +84,8 @@ static int fill_list(unsigned int nr_pages) struct page *pg = virt_to_page(vaddr + PAGE_SIZE * i); BUG_ON(!virt_addr_valid(vaddr + PAGE_SIZE * i)); - list_add(&pg->lru, &page_list); + pg->zone_device_data = page_list; + page_list = pg; list_count++; } @@ -118,12 +119,10 @@ int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages) } for (i = 0; i < nr_pages; i++) { - struct page *pg = list_first_entry_or_null(&page_list, - struct page, - lru); + struct page *pg = page_list; BUG_ON(!pg); - list_del(&pg->lru); + page_list = pg->zone_device_data; list_count--; pages[i] = pg; @@ -134,7 +133,8 @@ int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages) unsigned int j; for (j = 0; j <= i; j++) { - list_add(&pages[j]->lru, &page_list); + pages[j]->zone_device_data = page_list; + page_list = pages[j]; list_count++; } goto out; @@ -160,7 +160,8 @@ void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages) mutex_lock(&list_lock); for (i = 0; i < nr_pages; i++) { - list_add(&pages[i]->lru, &page_list); + pages[i]->zone_device_data = page_list; + page_list = pages[i]; list_count++; } mutex_unlock(&list_lock); @@ -189,7 +190,8 @@ static int __init init(void) struct page *pg = pfn_to_page(xen_extra_mem[i].start_pfn + j); - list_add(&pg->lru, &page_list); + pg->zone_device_data = page_list; + page_list = pg; list_count++; } } diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index c6ef8ffc1a09..b9c937b3a149 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -200,7 +200,11 @@ void gnttab_free_pages(int nr_pages, struct page **pages); struct gnttab_page_cache { spinlock_t lock; +#ifdef CONFIG_XEN_UNPOPULATED_ALLOC + struct page *pages; +#else struct list_head pages; +#endif unsigned int num_pages; }; From 80db2a087f425b63f0163bc95217abd01c637cb5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 9 Dec 2020 17:59:53 -0800 Subject: [PATCH 18/25] Input: cros_ec_keyb - send 'scancodes' in addition to key events To let userspace know what 'scancodes' should be used in EVIOCGKEYCODE and EVIOCSKEYCODE ioctls, we should send EV_MSC/MSC_SCAN events in addition to EV_KEY/KEY_* events. The driver already declared MSC_SCAN capability, so it is only matter of actually sending the events. Link: https://lore.kernel.org/r/X87aOaSptPTvZ3nZ@google.com Acked-by: Rajat Jain Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/cros_ec_keyb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index fc1793ca2f17..0a748aed0265 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -183,6 +183,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, "changed: [r%d c%d]: byte %02x\n", row, col, new_state); + input_event(idev, EV_MSC, MSC_SCAN, pos); input_report_key(idev, keycodes[pos], new_state); } From ce6520b0eafad5962ffc21dc47cd7bd3250e9045 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Wed, 9 Dec 2020 20:24:47 -0800 Subject: [PATCH 19/25] Input: i8042 - add Acer laptops to the i8042 reset list The touchpad operates in Basic Mode by default in the Acer BIOS setup, but some Aspire/TravelMate models require the i8042 to be reset in order to be correctly detected. Signed-off-by: Chris Chiu Link: https://lore.kernel.org/r/20201207071250.15021-1-chiu@endlessos.org Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 7ecb65176c1a..3a2dcf0805f1 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -611,6 +611,48 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"), + }, + }, { /* Advent 4211 */ .matches = { From ccbbfd1cbf365b38d014351d1482fedd26282041 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Wed, 25 Nov 2020 11:57:03 -0800 Subject: [PATCH 20/25] RISC-V: Define get_cycles64() regardless of M-mode The timer driver uses get_cycles64() unconditionally to obtain the current time. A recent refactoring lost the common definition for some configs, which is now the only one we need. Fixes: d5be89a8d118 ("RISC-V: Resurrect the MMIO timer implementation for M-mode systems") Reported-by: kernel test robot Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/timex.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h index ab104905d4db..81de51e6aa32 100644 --- a/arch/riscv/include/asm/timex.h +++ b/arch/riscv/include/asm/timex.h @@ -60,6 +60,8 @@ static inline u32 get_cycles_hi(void) } #define get_cycles_hi get_cycles_hi +#endif /* !CONFIG_RISCV_M_MODE */ + #ifdef CONFIG_64BIT static inline u64 get_cycles64(void) { @@ -79,8 +81,6 @@ static inline u64 get_cycles64(void) } #endif /* CONFIG_64BIT */ -#endif /* !CONFIG_RISCV_M_MODE */ - #define ARCH_HAS_READ_CURRENT_TIMER static inline int read_current_timer(unsigned long *timer_val) { From 4da3a54f5a025846f9930354cfb80f075b9952e0 Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Fri, 11 Dec 2020 14:14:04 +0100 Subject: [PATCH 21/25] Revert "scsi: storvsc: Validate length of incoming packet in storvsc_on_channel_callback()" This reverts commit 3b8c72d076c42bf27284cda7b2b2b522810686f8. Dexuan reported a regression where StorVSC fails to probe a device (and where, consequently, the VM may fail to boot). The root-cause analysis led to a long-standing race condition that is exposed by the validation /commit in question. Let's put the new validation aside until a proper solution for that race condition is in place. Link: https://lore.kernel.org/r/20201211131404.21359-1-parri.andrea@gmail.com Fixes: 3b8c72d076c4 ("scsi: storvsc: Validate length of incoming packet in storvsc_on_channel_callback()") Cc: Dexuan Cui Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Andrea Parri (Microsoft) Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 99c8ff81de74..ded00a89bfc4 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1246,11 +1246,6 @@ static void storvsc_on_channel_callback(void *context) request = (struct storvsc_cmd_request *) ((unsigned long)desc->trans_id); - if (hv_pkt_datalen(desc) < sizeof(struct vstor_packet) - vmscsi_size_delta) { - dev_err(&device->device, "Invalid packet len\n"); - continue; - } - if (request == &stor_device->init_request || request == &stor_device->reset_request) { memcpy(&request->vstor_packet, packet, From 82e06090473289ce63e23fdeb8737aad59b10645 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 9 Dec 2020 20:13:24 -0800 Subject: [PATCH 22/25] Input: cm109 - do not stomp on control URB We need to make sure we are not stomping on the control URB that was issued when opening the device when attempting to toggle buzzer. To do that we need to mark it as pending in cm109_open(). Reported-and-tested-by: syzbot+150f793ac5bc18eee150@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/cm109.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index e413801f0491..f515fae465c3 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c @@ -568,12 +568,15 @@ static int cm109_input_open(struct input_dev *idev) dev->ctl_data->byte[HID_OR2] = dev->keybit; dev->ctl_data->byte[HID_OR3] = 0x00; + dev->ctl_urb_pending = 1; error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); - if (error) + if (error) { + dev->ctl_urb_pending = 0; dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n", __func__, error); - else + } else { dev->open = 1; + } mutex_unlock(&dev->pm_mutex); From 34c0f6f2695a2db81e09a3ab7bdb2853f45d4d3d Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 5 Dec 2020 01:48:08 +0100 Subject: [PATCH 23/25] KVM: mmu: Fix SPTE encoding of MMIO generation upper half Commit cae7ed3c2cb0 ("KVM: x86: Refactor the MMIO SPTE generation handling") cleaned up the computation of MMIO generation SPTE masks, however it introduced a bug how the upper part was encoded: SPTE bits 52-61 were supposed to contain bits 10-19 of the current generation number, however a missing shift encoded bits 1-10 there instead (mostly duplicating the lower part of the encoded generation number that then consisted of bits 1-9). In the meantime, the upper part was shrunk by one bit and moved by subsequent commits to become an upper half of the encoded generation number (bits 9-17 of bits 0-17 encoded in a SPTE). In addition to the above, commit 56871d444bc4 ("KVM: x86: fix overlap between SPTE_MMIO_MASK and generation") has changed the SPTE bit range assigned to encode the generation number and the total number of bits encoded but did not update them in the comment attached to their defines, nor in the KVM MMU doc. Let's do it here, too, since it is too trivial thing to warrant a separate commit. Fixes: cae7ed3c2cb0 ("KVM: x86: Refactor the MMIO SPTE generation handling") Signed-off-by: Maciej S. Szmigiero Message-Id: <156700708db2a5296c5ed7a8b9ac71f1e9765c85.1607129096.git.maciej.szmigiero@oracle.com> Cc: stable@vger.kernel.org [Reorganize macros so that everything is computed from the bit ranges. - Paolo] Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/mmu.rst | 2 +- arch/x86/kvm/mmu/spte.c | 4 ++-- arch/x86/kvm/mmu/spte.h | 25 ++++++++++++++++++------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Documentation/virt/kvm/mmu.rst b/Documentation/virt/kvm/mmu.rst index 1c030dbac7c4..5bfe28b0728e 100644 --- a/Documentation/virt/kvm/mmu.rst +++ b/Documentation/virt/kvm/mmu.rst @@ -455,7 +455,7 @@ If the generation number of the spte does not equal the global generation number, it will ignore the cached MMIO information and handle the page fault through the slow path. -Since only 19 bits are used to store generation-number on mmio spte, all +Since only 18 bits are used to store generation-number on mmio spte, all pages are zapped when there is an overflow. Unfortunately, a single memory access might access kvm_memslots(kvm) multiple diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index fcac2cac78fe..c51ad544f25b 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -40,8 +40,8 @@ static u64 generation_mmio_spte_mask(u64 gen) WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); - mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK; - mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK; + mask = (gen << MMIO_SPTE_GEN_LOW_SHIFT) & MMIO_SPTE_GEN_LOW_MASK; + mask |= (gen << MMIO_SPTE_GEN_HIGH_SHIFT) & MMIO_SPTE_GEN_HIGH_MASK; return mask; } diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 5c75a451c000..2b3a30bd38b0 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -56,11 +56,11 @@ #define SPTE_MMU_WRITEABLE (1ULL << (PT_FIRST_AVAIL_BITS_SHIFT + 1)) /* - * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of + * Due to limited space in PTEs, the MMIO generation is a 18 bit subset of * the memslots generation and is derived as follows: * * Bits 0-8 of the MMIO generation are propagated to spte bits 3-11 - * Bits 9-18 of the MMIO generation are propagated to spte bits 52-61 + * Bits 9-17 of the MMIO generation are propagated to spte bits 54-62 * * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not included in * the MMIO generation number, as doing so would require stealing a bit from @@ -69,18 +69,29 @@ * requires a full MMU zap). The flag is instead explicitly queried when * checking for MMIO spte cache hits. */ -#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0) #define MMIO_SPTE_GEN_LOW_START 3 #define MMIO_SPTE_GEN_LOW_END 11 -#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ - MMIO_SPTE_GEN_LOW_START) #define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT #define MMIO_SPTE_GEN_HIGH_END 62 + +#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ + MMIO_SPTE_GEN_LOW_START) #define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \ MMIO_SPTE_GEN_HIGH_START) +#define MMIO_SPTE_GEN_LOW_BITS (MMIO_SPTE_GEN_LOW_END - MMIO_SPTE_GEN_LOW_START + 1) +#define MMIO_SPTE_GEN_HIGH_BITS (MMIO_SPTE_GEN_HIGH_END - MMIO_SPTE_GEN_HIGH_START + 1) + +/* remember to adjust the comment above as well if you change these */ +static_assert(MMIO_SPTE_GEN_LOW_BITS == 9 && MMIO_SPTE_GEN_HIGH_BITS == 9); + +#define MMIO_SPTE_GEN_LOW_SHIFT (MMIO_SPTE_GEN_LOW_START - 0) +#define MMIO_SPTE_GEN_HIGH_SHIFT (MMIO_SPTE_GEN_HIGH_START - MMIO_SPTE_GEN_LOW_BITS) + +#define MMIO_SPTE_GEN_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_BITS + MMIO_SPTE_GEN_HIGH_BITS - 1, 0) + extern u64 __read_mostly shadow_nx_mask; extern u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ extern u64 __read_mostly shadow_user_mask; @@ -228,8 +239,8 @@ static inline u64 get_mmio_spte_generation(u64 spte) { u64 gen; - gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START; - gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START; + gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_SHIFT; + gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_SHIFT; return gen; } From 111d0bda8eeb4b54e0c63897b071effbf9fd9251 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Tue, 8 Dec 2020 22:08:29 +0100 Subject: [PATCH 24/25] tools/kvm_stat: Exempt time-based counters The new counters halt_poll_success_ns and halt_poll_fail_ns do not count events. Instead they provide a time, and mess up our statistics. Therefore, we should exclude them. Removal is currently implemented with an exempt list. If more counters like these appear, we can think about a more general rule like excluding all fields name "*_ns", in case that's a standing convention. Signed-off-by: Stefan Raspl Tested-and-reported-by: Christian Borntraeger Message-Id: <20201208210829.101324-1-raspl@linux.ibm.com> Signed-off-by: Paolo Bonzini --- tools/kvm/kvm_stat/kvm_stat | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat index d199a3694be8..b0bf56c5f120 100755 --- a/tools/kvm/kvm_stat/kvm_stat +++ b/tools/kvm/kvm_stat/kvm_stat @@ -742,7 +742,11 @@ class DebugfsProvider(Provider): The fields are all available KVM debugfs files """ - return self.walkdir(PATH_DEBUGFS_KVM)[2] + exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns'] + fields = [field for field in self.walkdir(PATH_DEBUGFS_KVM)[2] + if field not in exempt_list] + + return fields def update_fields(self, fields_filter): """Refresh fields, applying fields_filter""" From cffdd6d90482316e18d686060a4397902ea04bd2 Mon Sep 17 00:00:00 2001 From: Simon Beginn Date: Fri, 11 Dec 2020 16:17:32 -0800 Subject: [PATCH 25/25] Input: goodix - add upside-down quirk for Teclast X98 Pro tablet The touchscreen on the Teclast x98 Pro is also mounted upside-down in relation to the display orientation. Signed-off-by: Simon Beginn Signed-off-by: Bastien Nocera Link: https://lore.kernel.org/r/20201117004253.27A5A27EFD@localhost Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 02c75ea385e0..6612f9e2d7e8 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -192,6 +192,18 @@ static const struct dmi_system_id rotated_screen[] = { DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), }, }, + { + .ident = "Teclast X98 Pro", + .matches = { + /* + * Only match BIOS date, because the manufacturers + * BIOS does not report the board name at all + * (sometimes)... + */ + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), + DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), + }, + }, { .ident = "WinBook TW100", .matches = {