From Boris Ostrovsky: The KVM hypervisor may provide a guest with ability to defer remote TLB flush when the remote VCPU is not running. When this feature is used, the TLB flush will happen only when the remote VPCU is scheduled to run again. This will avoid unnecessary (and expensive) IPIs. Under certain circumstances, when a guest initiates such deferred action, the hypervisor may miss the request. It is also possible that the guest may mistakenly assume that it has already marked remote VCPU as needing a flush when in fact that request had already been processed by the hypervisor. In both cases this will result in an invalid translation being present in a vCPU, potentially allowing accesses to memory locations in that guest's address space that should not be accessible. Note that only intra-guest memory is vulnerable. The five patches address both of these problems: 1. The first patch makes sure the hypervisor doesn't accidentally clear a guest's remote flush request 2. The rest of the patches prevent the race between hypervisor acknowledging a remote flush request and guest issuing a new one.
Unified · Split
| @@ -111,7 +111,7 @@ patternProperties: · 110 unmodified lines | ||
| 111 | 111 | spi-rx-bus-width: |
| 112 | 112 | allOf: |
| 113 | 113 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 114 | − - enum: [ 1, 2, 4 ] | |
| 114 | + - enum: [ 1, 2, 4, 8 ] | |
| 115 | 115 | - default: 1 |
| 116 | 116 | description: |
| 117 | 117 | Bus width to the SPI bus used for MISO. |
| @@ -123,7 +123,7 @@ patternProperties: · 5 unmodified lines | ||
| 123 | 123 | spi-tx-bus-width: |
| 124 | 124 | allOf: |
| 125 | 125 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 126 | − - enum: [ 1, 2, 4 ] | |
| 126 | + - enum: [ 1, 2, 4, 8 ] | |
| 127 | 127 | - default: 1 |
| 128 | 128 | description: |
| 129 | 129 | Bus width to the SPI bus used for MOSI. |
| @@ -162,7 +162,7 @@ · 161 unmodified lines | ||
| 162 | 162 | #endif |
| 163 | 163 | |
| 164 | 164 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 165 | − ST2 r58, r59, PT_sp + 12 | |
| 165 | + ST2 r58, r59, PT_r58 | |
| 166 | 166 | #endif |
| 167 | 167 | |
| 168 | 168 | .endm |
| @@ -172,8 +172,8 @@ · 3 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) |
| 174 | 174 | |
| 175 | − ld r12, [sp, PT_sp + 4] | |
| 176 | − ld r30, [sp, PT_sp + 8] | |
| 175 | + ld r12, [sp, PT_r12] | |
| 176 | + ld r30, [sp, PT_r30] | |
| 177 | 177 | |
| 178 | 178 | ; Restore SP (into AUX_USER_SP) only if returning to U mode |
| 179 | 179 | ; - for K mode, it will be implicitly restored as stack is unwound |
| @@ -190,7 +190,7 @@ · 10 unmodified lines | ||
| 190 | 190 | #endif |
| 191 | 191 | |
| 192 | 192 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 193 | − LD2 r58, r59, PT_sp + 12 | |
| 193 | + LD2 r58, r59, PT_r58 | |
| 194 | 194 | #endif |
| 195 | 195 | .endm |
| 196 | 196 | |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #define _ASM_ARC_HUGEPAGE_H |
| 9 | 9 | |
| 10 | 10 | #include <linux/types.h> |
| 11 | −#define __ARCH_USE_5LEVEL_HACK | |
| 12 | 11 | #include <asm-generic/pgtable-nopmd.h> |
| 13 | 12 | |
| 14 | 13 | static inline pte_t pmd_pte(pmd_t pmd) |
| @@ -66,7 +66,15 @@ int main(void) · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); |
| 68 | 68 | DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); |
| 69 | − DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); | |
| 69 | + | |
| 70 | +#ifdef CONFIG_ISA_ARCV2 | |
| 71 | + OFFSET(PT_r12, pt_regs, r12); | |
| 72 | + OFFSET(PT_r30, pt_regs, r30); | |
| 73 | +#endif | |
| 74 | +#ifdef CONFIG_ARC_HAS_ACCL_REGS | |
| 75 | + OFFSET(PT_r58, pt_regs, r58); | |
| 76 | + OFFSET(PT_r59, pt_regs, r59); | |
| 77 | +#endif | |
| 70 | 78 | |
| 71 | 79 | return 0; |
| 72 | 80 | } |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | menuconfig ARC_PLAT_EZNPS |
| 8 | 8 | bool "\"EZchip\" ARC dev platform" |
| 9 | 9 | select CPU_BIG_ENDIAN |
| 10 | − select CLKSRC_NPS | |
| 10 | + select CLKSRC_NPS if !PHYS_ADDR_T_64BIT | |
| 11 | 11 | select EZNPS_GIC |
| 12 | 12 | select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET |
| 13 | 13 | help |
| @@ -85,13 +85,12 @@ · 84 unmodified lines | ||
| 85 | 85 | #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) |
| 86 | 86 | #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) |
| 87 | 87 | #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) |
| 88 | −#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) | |
| 89 | 88 | |
| 90 | 89 | #define __P000 PAGE_NONE |
| 91 | 90 | #define __P001 PAGE_READONLY |
| 92 | 91 | #define __P010 PAGE_READONLY |
| 93 | 92 | #define __P011 PAGE_READONLY |
| 94 | −#define __P100 PAGE_EXECONLY | |
| 93 | +#define __P100 PAGE_READONLY_EXEC | |
| 95 | 94 | #define __P101 PAGE_READONLY_EXEC |
| 96 | 95 | #define __P110 PAGE_READONLY_EXEC |
| 97 | 96 | #define __P111 PAGE_READONLY_EXEC |
| @@ -100,7 +99,7 @@ · 2 unmodified lines | ||
| 100 | 99 | #define __S001 PAGE_READONLY |
| 101 | 100 | #define __S010 PAGE_SHARED |
| 102 | 101 | #define __S011 PAGE_SHARED |
| 103 | −#define __S100 PAGE_EXECONLY | |
| 102 | +#define __S100 PAGE_READONLY_EXEC | |
| 104 | 103 | #define __S101 PAGE_READONLY_EXEC |
| 105 | 104 | #define __S110 PAGE_SHARED_EXEC |
| 106 | 105 | #define __S111 PAGE_SHARED_EXEC |
| @@ -96,12 +96,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 95 unmodified lines | ||
| 96 | 96 | #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) |
| 97 | 97 | |
| 98 | 98 | #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) |
| 99 | −/* | |
| 100 | − * Execute-only user mappings do not have the PTE_USER bit set. All valid | |
| 101 | − * kernel mappings have the PTE_UXN bit set. | |
| 102 | − */ | |
| 103 | 99 | #define pte_valid_not_user(pte) \ |
| 104 | − ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN)) | |
| 100 | + ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) | |
| 105 | 101 | #define pte_valid_young(pte) \ |
| 106 | 102 | ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) |
| 107 | 103 | #define pte_valid_user(pte) \ |
| @@ -117,8 +113,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 9 unmodified lines | ||
| 117 | 113 | |
| 118 | 114 | /* |
| 119 | 115 | * p??_access_permitted() is true for valid user mappings (subject to the |
| 120 | − * write permission check) other than user execute-only which do not have the | |
| 121 | − * PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set. | |
| 116 | + * write permission check). PROT_NONE mappings do not have the PTE_VALID bit | |
| 117 | + * set. | |
| 122 | 118 | */ |
| 123 | 119 | #define pte_access_permitted(pte, write) \ |
| 124 | 120 | (pte_valid_user(pte) && (!(write) || pte_write(pte))) |
| @@ -445,7 +445,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, · 444 unmodified lines | ||
| 445 | 445 | const struct fault_info *inf; |
| 446 | 446 | struct mm_struct *mm = current->mm; |
| 447 | 447 | vm_fault_t fault, major = 0; |
| 448 | − unsigned long vm_flags = VM_READ | VM_WRITE; | |
| 448 | + unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; | |
| 449 | 449 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
| 450 | 450 | |
| 451 | 451 | if (kprobe_page_fault(regs, esr)) |
| @@ -690,10 +690,10 @@ struct kvm_vcpu_arch { · 689 unmodified lines | ||
| 690 | 690 | bool pvclock_set_guest_stopped_request; |
| 691 | 691 | |
| 692 | 692 | struct { |
| 693 | + u8 preempted; | |
| 693 | 694 | u64 msr_val; |
| 694 | 695 | u64 last_steal; |
| 695 | − struct gfn_to_hva_cache stime; | |
| 696 | − struct kvm_steal_time steal; | |
| 696 | + struct gfn_to_pfn_cache cache; | |
| 697 | 697 | } st; |
| 698 | 698 | |
| 699 | 699 | u64 tsc_offset; |
| @@ -2648,45 +2648,47 @@ static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa) · 2647 unmodified lines | ||
| 2648 | 2648 | |
| 2649 | 2649 | static void record_steal_time(struct kvm_vcpu *vcpu) |
| 2650 | 2650 | { |
| 2651 | + struct kvm_host_map map; | |
| 2652 | + struct kvm_steal_time *st; | |
| 2653 | + | |
| 2651 | 2654 | if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) |
| 2652 | 2655 | return; |
| 2653 | 2656 | |
| 2654 | − if (unlikely(kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.st.stime, | |
| 2655 | − &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)))) | |
| 2657 | + /* -EAGAIN is returned in atomic context so we can just return. */ | |
| 2658 | + if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, | |
| 2659 | + &map, &vcpu->arch.st.cache, false)) | |
| 2656 | 2660 | return; |
| 2657 | 2661 | |
| 2662 | + st = map.hva + | |
| 2663 | + offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); | |
| 2664 | + | |
| 2658 | 2665 | /* |
| 2659 | 2666 | * Doing a TLB flush here, on the guest's behalf, can avoid |
| 2660 | 2667 | * expensive IPIs. |
| 2661 | 2668 | */ |
| 2662 | 2669 | trace_kvm_pv_tlb_flush(vcpu->vcpu_id, |
| 2663 | − vcpu->arch.st.steal.preempted & KVM_VCPU_FLUSH_TLB); | |
| 2664 | − if (xchg(&vcpu->arch.st.steal.preempted, 0) & KVM_VCPU_FLUSH_TLB) | |
| 2670 | + st->preempted & KVM_VCPU_FLUSH_TLB); | |
| 2671 | + if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB) | |
| 2665 | 2672 | kvm_vcpu_flush_tlb(vcpu, false); |
| 2666 | 2673 | |
| 2667 | − if (vcpu->arch.st.steal.version & 1) | |
| 2668 | − vcpu->arch.st.steal.version += 1; /* first time write, random junk */ | |
| 2674 | + vcpu->arch.st.preempted = 0; | |
| 2669 | 2675 | |
| 2670 | − vcpu->arch.st.steal.version += 1; | |
| 2676 | + if (st->version & 1) | |
| 2677 | + st->version += 1; /* first time write, random junk */ | |
| 2671 | 2678 | |
| 2672 | − kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime, | |
| 2673 | − &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)); | |
| 2679 | + st->version += 1; | |
| 2674 | 2680 | |
| 2675 | 2681 | smp_wmb(); |
| 2676 | 2682 | |
| 2677 | − vcpu->arch.st.steal.steal += current->sched_info.run_delay - | |
| 2683 | + st->steal += current->sched_info.run_delay - | |
| 2678 | 2684 | vcpu->arch.st.last_steal; |
| 2679 | 2685 | vcpu->arch.st.last_steal = current->sched_info.run_delay; |
| 2680 | 2686 | |
| 2681 | − kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime, | |
| 2682 | − &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)); | |
| 2683 | − | |
| 2684 | 2687 | smp_wmb(); |
| 2685 | 2688 | |
| 2686 | − vcpu->arch.st.steal.version += 1; | |
| 2689 | + st->version += 1; | |
| 2687 | 2690 | |
| 2688 | − kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime, | |
| 2689 | − &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)); | |
| 2691 | + kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, false); | |
| 2690 | 2692 | } |
| 2691 | 2693 | |
| 2692 | 2694 | int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| @@ -2853,11 +2855,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 160 unmodified lines | ||
| 2853 | 2855 | if (data & KVM_STEAL_RESERVED_MASK) |
| 2854 | 2856 | return 1; |
| 2855 | 2857 | |
| 2856 | − if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, | |
| 2857 | − data & KVM_STEAL_VALID_BITS, | |
| 2858 | − sizeof(struct kvm_steal_time))) | |
| 2859 | − return 1; | |
| 2860 | − | |
| 2861 | 2858 | vcpu->arch.st.msr_val = data; |
| 2862 | 2859 | |
| 2863 | 2860 | if (!(data & KVM_MSR_ENABLED)) |
| @@ -3567,15 +3564,25 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) · 703 unmodified lines | ||
| 3567 | 3564 | |
| 3568 | 3565 | static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) |
| 3569 | 3566 | { |
| 3567 | + struct kvm_host_map map; | |
| 3568 | + struct kvm_steal_time *st; | |
| 3569 | + | |
| 3570 | 3570 | if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) |
| 3571 | 3571 | return; |
| 3572 | 3572 | |
| 3573 | − vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED; | |
| 3573 | + if (vcpu->arch.st.preempted) | |
| 3574 | + return; | |
| 3575 | + | |
| 3576 | + if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map, | |
| 3577 | + &vcpu->arch.st.cache, true)) | |
| 3578 | + return; | |
| 3579 | + | |
| 3580 | + st = map.hva + | |
| 3581 | + offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); | |
| 3582 | + | |
| 3583 | + st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; | |
| 3574 | 3584 | |
| 3575 | − kvm_write_guest_offset_cached(vcpu->kvm, &vcpu->arch.st.stime, | |
| 3576 | − &vcpu->arch.st.steal.preempted, | |
| 3577 | − offsetof(struct kvm_steal_time, preempted), | |
| 3578 | − sizeof(vcpu->arch.st.steal.preempted)); | |
| 3585 | + kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true); | |
| 3579 | 3586 | } |
| 3580 | 3587 | |
| 3581 | 3588 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
| @@ -9325,8 +9332,11 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) · 5743 unmodified lines | ||
| 9325 | 9332 | |
| 9326 | 9333 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) |
| 9327 | 9334 | { |
| 9335 | + struct gfn_to_pfn_cache *cache = &vcpu->arch.st.cache; | |
| 9328 | 9336 | int idx; |
| 9329 | 9337 | |
| 9338 | + kvm_release_pfn(cache->pfn, cache->dirty, cache); | |
| 9339 | + | |
| 9330 | 9340 | kvmclock_reset(vcpu); |
| 9331 | 9341 | |
| 9332 | 9342 | kvm_x86_ops->vcpu_free(vcpu); |
| @@ -9855,11 +9865,18 @@ out_free: · 522 unmodified lines | ||
| 9855 | 9865 | |
| 9856 | 9866 | void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) |
| 9857 | 9867 | { |
| 9868 | + struct kvm_vcpu *vcpu; | |
| 9869 | + int i; | |
| 9870 | + | |
| 9858 | 9871 | /* |
| 9859 | 9872 | * memslots->generation has been incremented. |
| 9860 | 9873 | * mmio generation may have reached its maximum value. |
| 9861 | 9874 | */ |
| 9862 | 9875 | kvm_mmu_invalidate_mmio_sptes(kvm, gen); |
| 9876 | + | |
| 9877 | + /* Force re-initialization of steal_time cache */ | |
| 9878 | + kvm_for_each_vcpu(i, vcpu, kvm) | |
| 9879 | + kvm_vcpu_kick(vcpu); | |
| 9863 | 9880 | } |
| 9864 | 9881 | |
| 9865 | 9882 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
| @@ -978,13 +978,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 977 unmodified lines | ||
| 978 | 978 | |
| 979 | 979 | if (wait_startup(chip, 0) != 0) { |
| 980 | 980 | rc = -ENODEV; |
| 981 | − goto err_start; | |
| 981 | + goto out_err; | |
| 982 | 982 | } |
| 983 | 983 | |
| 984 | 984 | /* Take control of the TPM's interrupt hardware and shut it off */ |
| 985 | 985 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); |
| 986 | 986 | if (rc < 0) |
| 987 | − goto err_start; | |
| 987 | + goto out_err; | |
| 988 | 988 | |
| 989 | 989 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | |
| 990 | 990 | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; |
| @@ -993,21 +993,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 2 unmodified lines | ||
| 993 | 993 | |
| 994 | 994 | rc = tpm_chip_start(chip); |
| 995 | 995 | if (rc) |
| 996 | − goto err_start; | |
| 997 | − | |
| 996 | + goto out_err; | |
| 998 | 997 | rc = tpm2_probe(chip); |
| 998 | + tpm_chip_stop(chip); | |
| 999 | 999 | if (rc) |
| 1000 | − goto err_probe; | |
| 1000 | + goto out_err; | |
| 1001 | 1001 | |
| 1002 | 1002 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
| 1003 | 1003 | if (rc < 0) |
| 1004 | − goto err_probe; | |
| 1004 | + goto out_err; | |
| 1005 | 1005 | |
| 1006 | 1006 | priv->manufacturer_id = vendor; |
| 1007 | 1007 | |
| 1008 | 1008 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); |
| 1009 | 1009 | if (rc < 0) |
| 1010 | − goto err_probe; | |
| 1010 | + goto out_err; | |
| 1011 | 1011 | |
| 1012 | 1012 | dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", |
| 1013 | 1013 | (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", |
| @@ -1016,13 +1016,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 2 unmodified lines | ||
| 1016 | 1016 | probe = probe_itpm(chip); |
| 1017 | 1017 | if (probe < 0) { |
| 1018 | 1018 | rc = -ENODEV; |
| 1019 | − goto err_probe; | |
| 1019 | + goto out_err; | |
| 1020 | 1020 | } |
| 1021 | 1021 | |
| 1022 | 1022 | /* Figure out the capabilities */ |
| 1023 | 1023 | rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); |
| 1024 | 1024 | if (rc < 0) |
| 1025 | − goto err_probe; | |
| 1025 | + goto out_err; | |
| 1026 | 1026 | |
| 1027 | 1027 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", |
| 1028 | 1028 | intfcaps); |
| @@ -1056,10 +1056,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 27 unmodified lines | ||
| 1056 | 1056 | if (tpm_get_timeouts(chip)) { |
| 1057 | 1057 | dev_err(dev, "Could not get TPM timeouts and durations\n"); |
| 1058 | 1058 | rc = -ENODEV; |
| 1059 | − goto err_probe; | |
| 1059 | + goto out_err; | |
| 1060 | 1060 | } |
| 1061 | 1061 | |
| 1062 | − chip->flags |= TPM_CHIP_FLAG_IRQ; | |
| 1063 | 1062 | if (irq) { |
| 1064 | 1063 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, |
| 1065 | 1064 | irq); |
| @@ -1071,18 +1070,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 5 unmodified lines | ||
| 1071 | 1070 | } |
| 1072 | 1071 | } |
| 1073 | 1072 | |
| 1074 | − tpm_chip_stop(chip); | |
| 1075 | − | |
| 1076 | 1073 | rc = tpm_chip_register(chip); |
| 1077 | 1074 | if (rc) |
| 1078 | − goto err_start; | |
| 1079 | − | |
| 1080 | − return 0; | |
| 1075 | + goto out_err; | |
| 1081 | 1076 | |
| 1082 | −err_probe: | |
| 1083 | − tpm_chip_stop(chip); | |
| 1077 | + if (chip->ops->clk_enable != NULL) | |
| 1078 | + chip->ops->clk_enable(chip, false); | |
| 1084 | 1079 | |
| 1085 | −err_start: | |
| 1080 | + return 0; | |
| 1081 | +out_err: | |
| 1086 | 1082 | if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) |
| 1087 | 1083 | chip->ops->clk_enable(chip, false); |
| 1088 | 1084 | |
| @@ -413,10 +413,13 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) · 412 unmodified lines | ||
| 413 | 413 | int i; |
| 414 | 414 | |
| 415 | 415 | for (i = 0; i < rate_count; i++) { |
| 416 | − if (ramp <= slew_rates[i]) | |
| 417 | − cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); | |
| 418 | − else | |
| 416 | + if (ramp > slew_rates[i]) | |
| 419 | 417 | break; |
| 418 | + | |
| 419 | + if (id == AXP20X_DCDC2) | |
| 420 | + cfg = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(i); | |
| 421 | + else | |
| 422 | + cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); | |
| 420 | 423 | } |
| 421 | 424 | |
| 422 | 425 | if (cfg == 0xff) { |
| @@ -605,7 +608,7 @@ static const struct regulator_desc axp22x_regulators[] = { · 182 unmodified lines | ||
| 605 | 608 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), |
| 606 | 609 | AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100, |
| 607 | 610 | AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, |
| 608 | − AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), | |
| 611 | + AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK), | |
| 609 | 612 | AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100, |
| 610 | 613 | AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, |
| 611 | 614 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), |
| @@ -101,7 +101,6 @@ static const struct regulator_ops bd70528_ldo_ops = { · 100 unmodified lines | ||
| 101 | 101 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 102 | 102 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 103 | 103 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 104 | − .set_ramp_delay = bd70528_set_ramp_delay, | |
| 105 | 104 | }; |
| 106 | 105 | |
| 107 | 106 | static const struct regulator_ops bd70528_led_ops = { |
| @@ -172,20 +172,7 @@ int mc146818_set_time(struct rtc_time *time) · 171 unmodified lines | ||
| 172 | 172 | save_control = CMOS_READ(RTC_CONTROL); |
| 173 | 173 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); |
| 174 | 174 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); |
| 175 | − | |
| 176 | −#ifdef CONFIG_X86 | |
| 177 | − if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | |
| 178 | − boot_cpu_data.x86 == 0x17) || | |
| 179 | − boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { | |
| 180 | − CMOS_WRITE((save_freq_select & (~RTC_DIV_RESET2)), | |
| 181 | − RTC_FREQ_SELECT); | |
| 182 | − save_freq_select &= ~RTC_DIV_RESET2; | |
| 183 | − } else | |
| 184 | − CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), | |
| 185 | − RTC_FREQ_SELECT); | |
| 186 | −#else | |
| 187 | − CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT); | |
| 188 | −#endif | |
| 175 | + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | |
| 189 | 176 | |
| 190 | 177 | #ifdef CONFIG_MACH_DECSTATION |
| 191 | 178 | CMOS_WRITE(real_yrs, RTC_DEC_YEAR); |
| @@ -47,7 +47,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) · 46 unmodified lines | ||
| 47 | 47 | irqen = irqsta & ~RTC_IRQ_EN_AL; |
| 48 | 48 | mutex_lock(&rtc->lock); |
| 49 | 49 | if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, |
| 50 | − irqen) < 0) | |
| 50 | + irqen) == 0) | |
| 51 | 51 | mtk_rtc_write_trigger(rtc); |
| 52 | 52 | mutex_unlock(&rtc->lock); |
| 53 | 53 | |
| @@ -169,12 +169,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) · 115 unmodified lines | ||
| 169 | 169 | alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); |
| 170 | 170 | mutex_unlock(&rtc->lock); |
| 171 | 171 | |
| 172 | − tm->tm_sec = data[RTC_OFFSET_SEC]; | |
| 173 | − tm->tm_min = data[RTC_OFFSET_MIN]; | |
| 174 | − tm->tm_hour = data[RTC_OFFSET_HOUR]; | |
| 175 | − tm->tm_mday = data[RTC_OFFSET_DOM]; | |
| 176 | − tm->tm_mon = data[RTC_OFFSET_MTH]; | |
| 177 | − tm->tm_year = data[RTC_OFFSET_YEAR]; | |
| 172 | + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; | |
| 173 | + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; | |
| 174 | + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; | |
| 175 | + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; | |
| 176 | + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; | |
| 177 | + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; | |
| 178 | 178 | |
| 179 | 179 | tm->tm_year += RTC_MIN_YEAR_OFFSET; |
| 180 | 180 | tm->tm_mon--; |
| @@ -195,14 +195,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) · 14 unmodified lines | ||
| 195 | 195 | tm->tm_year -= RTC_MIN_YEAR_OFFSET; |
| 196 | 196 | tm->tm_mon++; |
| 197 | 197 | |
| 198 | − data[RTC_OFFSET_SEC] = tm->tm_sec; | |
| 199 | − data[RTC_OFFSET_MIN] = tm->tm_min; | |
| 200 | − data[RTC_OFFSET_HOUR] = tm->tm_hour; | |
| 201 | − data[RTC_OFFSET_DOM] = tm->tm_mday; | |
| 202 | − data[RTC_OFFSET_MTH] = tm->tm_mon; | |
| 203 | − data[RTC_OFFSET_YEAR] = tm->tm_year; | |
| 204 | − | |
| 205 | 198 | mutex_lock(&rtc->lock); |
| 199 | + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, | |
| 200 | + data, RTC_OFFSET_COUNT); | |
| 201 | + if (ret < 0) | |
| 202 | + goto exit; | |
| 203 | + | |
| 204 | + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) | | |
| 205 | + (tm->tm_sec & RTC_AL_SEC_MASK)); | |
| 206 | + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) | | |
| 207 | + (tm->tm_min & RTC_AL_MIN_MASK)); | |
| 208 | + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) | | |
| 209 | + (tm->tm_hour & RTC_AL_HOU_MASK)); | |
| 210 | + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) | | |
| 211 | + (tm->tm_mday & RTC_AL_DOM_MASK)); | |
| 212 | + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) | | |
| 213 | + (tm->tm_mon & RTC_AL_MTH_MASK)); | |
| 214 | + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) | | |
| 215 | + (tm->tm_year & RTC_AL_YEA_MASK)); | |
| 216 | + | |
| 206 | 217 | if (alm->enabled) { |
| 207 | 218 | ret = regmap_bulk_write(rtc->regmap, |
| 208 | 219 | rtc->addr_base + RTC_AL_SEC, |
| @@ -379,6 +379,22 @@ static void __init sun50i_h6_rtc_clk_init(struct device_node *node) · 378 unmodified lines | ||
| 379 | 379 | CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", |
| 380 | 380 | sun50i_h6_rtc_clk_init); |
| 381 | 381 | |
| 382 | +/* | |
| 383 | + * The R40 user manual is self-conflicting on whether the prescaler is | |
| 384 | + * fixed or configurable. The clock diagram shows it as fixed, but there | |
| 385 | + * is also a configurable divider in the RTC block. | |
| 386 | + */ | |
| 387 | +static const struct sun6i_rtc_clk_data sun8i_r40_rtc_data = { | |
| 388 | + .rc_osc_rate = 16000000, | |
| 389 | + .fixed_prescaler = 512, | |
| 390 | +}; | |
| 391 | +static void __init sun8i_r40_rtc_clk_init(struct device_node *node) | |
| 392 | +{ | |
| 393 | + sun6i_rtc_clk_init(node, &sun8i_r40_rtc_data); | |
| 394 | +} | |
| 395 | +CLK_OF_DECLARE_DRIVER(sun8i_r40_rtc_clk, "allwinner,sun8i-r40-rtc", | |
| 396 | + sun8i_r40_rtc_clk_init); | |
| 397 | + | |
| 382 | 398 | static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { |
| 383 | 399 | .rc_osc_rate = 32000, |
| 384 | 400 | .has_out_clk = 1, |
| @@ -172,9 +172,11 @@ static inline u32 rx_max(struct dw_spi *dws) · 171 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | static void dw_writer(struct dw_spi *dws) |
| 174 | 174 | { |
| 175 | − u32 max = tx_max(dws); | |
| 175 | + u32 max; | |
| 176 | 176 | u16 txw = 0; |
| 177 | 177 | |
| 178 | + spin_lock(&dws->buf_lock); | |
| 179 | + max = tx_max(dws); | |
| 178 | 180 | while (max--) { |
| 179 | 181 | /* Set the tx word if the transfer's original "tx" is not null */ |
| 180 | 182 | if (dws->tx_end - dws->len) { |
| @@ -186,13 +188,16 @@ static void dw_writer(struct dw_spi *dws) · 5 unmodified lines | ||
| 186 | 188 | dw_write_io_reg(dws, DW_SPI_DR, txw); |
| 187 | 189 | dws->tx += dws->n_bytes; |
| 188 | 190 | } |
| 191 | + spin_unlock(&dws->buf_lock); | |
| 189 | 192 | } |
| 190 | 193 | |
| 191 | 194 | static void dw_reader(struct dw_spi *dws) |
| 192 | 195 | { |
| 193 | − u32 max = rx_max(dws); | |
| 196 | + u32 max; | |
| 194 | 197 | u16 rxw; |
| 195 | 198 | |
| 199 | + spin_lock(&dws->buf_lock); | |
| 200 | + max = rx_max(dws); | |
| 196 | 201 | while (max--) { |
| 197 | 202 | rxw = dw_read_io_reg(dws, DW_SPI_DR); |
| 198 | 203 | /* Care rx only if the transfer's original "rx" is not null */ |
| @@ -204,6 +209,7 @@ static void dw_reader(struct dw_spi *dws) · 5 unmodified lines | ||
| 204 | 209 | } |
| 205 | 210 | dws->rx += dws->n_bytes; |
| 206 | 211 | } |
| 212 | + spin_unlock(&dws->buf_lock); | |
| 207 | 213 | } |
| 208 | 214 | |
| 209 | 215 | static void int_error_stop(struct dw_spi *dws, const char *msg) |
| @@ -276,18 +282,20 @@ static int dw_spi_transfer_one(struct spi_controller *master, · 66 unmodified lines | ||
| 276 | 282 | { |
| 277 | 283 | struct dw_spi *dws = spi_controller_get_devdata(master); |
| 278 | 284 | struct chip_data *chip = spi_get_ctldata(spi); |
| 285 | + unsigned long flags; | |
| 279 | 286 | u8 imask = 0; |
| 280 | 287 | u16 txlevel = 0; |
| 281 | 288 | u32 cr0; |
| 282 | 289 | int ret; |
| 283 | 290 | |
| 284 | 291 | dws->dma_mapped = 0; |
| 285 | − | |
| 292 | + spin_lock_irqsave(&dws->buf_lock, flags); | |
| 286 | 293 | dws->tx = (void *)transfer->tx_buf; |
| 287 | 294 | dws->tx_end = dws->tx + transfer->len; |
| 288 | 295 | dws->rx = transfer->rx_buf; |
| 289 | 296 | dws->rx_end = dws->rx + transfer->len; |
| 290 | 297 | dws->len = transfer->len; |
| 298 | + spin_unlock_irqrestore(&dws->buf_lock, flags); | |
| 291 | 299 | |
| 292 | 300 | spi_enable_chip(dws, 0); |
| 293 | 301 | |
| @@ -471,6 +479,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) · 177 unmodified lines | ||
| 471 | 479 | dws->type = SSI_MOTO_SPI; |
| 472 | 480 | dws->dma_inited = 0; |
| 473 | 481 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); |
| 482 | + spin_lock_init(&dws->buf_lock); | |
| 474 | 483 | |
| 475 | 484 | spi_controller_set_devdata(master, dws); |
| 476 | 485 | |
| @@ -119,6 +119,7 @@ struct dw_spi { · 118 unmodified lines | ||
| 119 | 119 | size_t len; |
| 120 | 120 | void *tx; |
| 121 | 121 | void *tx_end; |
| 122 | + spinlock_t buf_lock; | |
| 122 | 123 | void *rx; |
| 123 | 124 | void *rx_end; |
| 124 | 125 | int dma_mapped; |
| @@ -185,6 +185,7 @@ struct fsl_dspi { · 184 unmodified lines | ||
| 185 | 185 | struct spi_transfer *cur_transfer; |
| 186 | 186 | struct spi_message *cur_msg; |
| 187 | 187 | struct chip_data *cur_chip; |
| 188 | + size_t progress; | |
| 188 | 189 | size_t len; |
| 189 | 190 | const void *tx; |
| 190 | 191 | void *rx; |
| @@ -586,21 +587,14 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi) · 395 unmodified lines | ||
| 586 | 587 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; |
| 587 | 588 | |
| 588 | 589 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { |
| 589 | − /* Write two TX FIFO entries first, and then the corresponding | |
| 590 | − * CMD FIFO entry. | |
| 590 | + /* Write the CMD FIFO entry first, and then the two | |
| 591 | + * corresponding TX FIFO entries. | |
| 591 | 592 | */ |
| 592 | 593 | u32 data = dspi_pop_tx(dspi); |
| 593 | 594 | |
| 594 | − if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE) { | |
| 595 | − /* LSB */ | |
| 596 | − tx_fifo_write(dspi, data & 0xFFFF); | |
| 597 | − tx_fifo_write(dspi, data >> 16); | |
| 598 | − } else { | |
| 599 | − /* MSB */ | |
| 600 | − tx_fifo_write(dspi, data >> 16); | |
| 601 | − tx_fifo_write(dspi, data & 0xFFFF); | |
| 602 | − } | |
| 603 | 595 | cmd_fifo_write(dspi); |
| 596 | + tx_fifo_write(dspi, data & 0xFFFF); | |
| 597 | + tx_fifo_write(dspi, data >> 16); | |
| 604 | 598 | } else { |
| 605 | 599 | /* Write one entry to both TX FIFO and CMD FIFO |
| 606 | 600 | * simultaneously. |
| @@ -658,7 +652,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 51 unmodified lines | ||
| 658 | 652 | u32 spi_tcr; |
| 659 | 653 | |
| 660 | 654 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, |
| 661 | − dspi->tx - dspi->bytes_per_word, !dspi->irq); | |
| 655 | + dspi->progress, !dspi->irq); | |
| 662 | 656 | |
| 663 | 657 | /* Get transfer counter (in number of SPI transfers). It was |
| 664 | 658 | * reset to 0 when transfer(s) were started. |
| @@ -667,6 +661,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 2 unmodified lines | ||
| 667 | 661 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); |
| 668 | 662 | /* Update total number of bytes that were transferred */ |
| 669 | 663 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; |
| 664 | + dspi->progress += spi_tcnt; | |
| 670 | 665 | |
| 671 | 666 | trans_mode = dspi->devtype_data->trans_mode; |
| 672 | 667 | if (trans_mode == DSPI_EOQ_MODE) |
| @@ -679,7 +674,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 6 unmodified lines | ||
| 679 | 674 | return 0; |
| 680 | 675 | |
| 681 | 676 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 682 | − dspi->tx, !dspi->irq); | |
| 677 | + dspi->progress, !dspi->irq); | |
| 683 | 678 | |
| 684 | 679 | if (trans_mode == DSPI_EOQ_MODE) |
| 685 | 680 | dspi_eoq_write(dspi); |
| @@ -768,6 +763,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 82 unmodified lines | ||
| 768 | 763 | dspi->rx = transfer->rx_buf; |
| 769 | 764 | dspi->rx_end = dspi->rx + transfer->len; |
| 770 | 765 | dspi->len = transfer->len; |
| 766 | + dspi->progress = 0; | |
| 771 | 767 | /* Validated transfer specific frame size (defaults applied) */ |
| 772 | 768 | dspi->bits_per_word = transfer->bits_per_word; |
| 773 | 769 | if (transfer->bits_per_word <= 8) |
| @@ -789,7 +785,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 15 unmodified lines | ||
| 789 | 785 | SPI_CTARE_DTCP(1)); |
| 790 | 786 | |
| 791 | 787 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 792 | − dspi->tx, !dspi->irq); | |
| 788 | + dspi->progress, !dspi->irq); | |
| 793 | 789 | |
| 794 | 790 | trans_mode = dspi->devtype_data->trans_mode; |
| 795 | 791 | switch (trans_mode) { |
| @@ -290,25 +290,32 @@ static void uniphier_spi_recv(struct uniphier_spi_priv *priv) · 289 unmodified lines | ||
| 290 | 290 | } |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | −static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) | |
| 293 | +static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv, | |
| 294 | + unsigned int threshold) | |
| 294 | 295 | { |
| 295 | − unsigned int fifo_threshold, fill_bytes; | |
| 296 | 296 | u32 val; |
| 297 | 297 | |
| 298 | − fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, | |
| 299 | − bytes_per_word(priv->bits_per_word)); | |
| 300 | − fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); | |
| 301 | − | |
| 302 | − fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes); | |
| 303 | − | |
| 304 | − /* set fifo threshold */ | |
| 305 | 298 | val = readl(priv->base + SSI_FC); |
| 306 | 299 | val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); |
| 307 | − val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold); | |
| 308 | − val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold); | |
| 300 | + val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold); | |
| 301 | + val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold); | |
| 309 | 302 | writel(val, priv->base + SSI_FC); |
| 303 | +} | |
| 304 | + | |
| 305 | +static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) | |
| 306 | +{ | |
| 307 | + unsigned int fifo_threshold, fill_words; | |
| 308 | + unsigned int bpw = bytes_per_word(priv->bits_per_word); | |
| 309 | + | |
| 310 | + fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw); | |
| 311 | + fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); | |
| 312 | + | |
| 313 | + uniphier_spi_set_fifo_threshold(priv, fifo_threshold); | |
| 314 | + | |
| 315 | + fill_words = fifo_threshold - | |
| 316 | + DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw); | |
| 310 | 317 | |
| 311 | − while (fill_bytes--) | |
| 318 | + while (fill_words--) | |
| 312 | 319 | uniphier_spi_send(priv); |
| 313 | 320 | } |
| 314 | 321 | |
| @@ -1499,8 +1499,7 @@ static void spi_pump_messages(struct kthread_work *work) · 1498 unmodified lines | ||
| 1499 | 1499 | * advances its @tx buffer pointer monotonically. |
| 1500 | 1500 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1501 | 1501 | * @xfer: Pointer to the transfer being timestamped |
| 1502 | − * @tx: Pointer to the current word within the xfer->tx_buf that the driver is | |
| 1503 | − * preparing to transmit right now. | |
| 1502 | + * @progress: How many words (not bytes) have been transferred so far | |
| 1504 | 1503 | * @irqs_off: If true, will disable IRQs and preemption for the duration of the |
| 1505 | 1504 | * transfer, for less jitter in time measurement. Only compatible |
| 1506 | 1505 | * with PIO drivers. If true, must follow up with |
| @@ -1510,21 +1509,19 @@ static void spi_pump_messages(struct kthread_work *work) · 3 unmodified lines | ||
| 1510 | 1509 | */ |
| 1511 | 1510 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 1512 | 1511 | struct spi_transfer *xfer, |
| 1513 | − const void *tx, bool irqs_off) | |
| 1512 | + size_t progress, bool irqs_off) | |
| 1514 | 1513 | { |
| 1515 | − u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8); | |
| 1516 | − | |
| 1517 | 1514 | if (!xfer->ptp_sts) |
| 1518 | 1515 | return; |
| 1519 | 1516 | |
| 1520 | 1517 | if (xfer->timestamped_pre) |
| 1521 | 1518 | return; |
| 1522 | 1519 | |
| 1523 | − if (tx < (xfer->tx_buf + xfer->ptp_sts_word_pre * bytes_per_word)) | |
| 1520 | + if (progress < xfer->ptp_sts_word_pre) | |
| 1524 | 1521 | return; |
| 1525 | 1522 | |
| 1526 | 1523 | /* Capture the resolution of the timestamp */ |
| 1527 | − xfer->ptp_sts_word_pre = (tx - xfer->tx_buf) / bytes_per_word; | |
| 1524 | + xfer->ptp_sts_word_pre = progress; | |
| 1528 | 1525 | |
| 1529 | 1526 | xfer->timestamped_pre = true; |
| 1530 | 1527 | |
| @@ -1546,23 +1543,20 @@ EXPORT_SYMBOL_GPL(spi_take_timestamp_pre); · 15 unmodified lines | ||
| 1546 | 1543 | * timestamped. |
| 1547 | 1544 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1548 | 1545 | * @xfer: Pointer to the transfer being timestamped |
| 1549 | − * @tx: Pointer to the current word within the xfer->tx_buf that the driver has | |
| 1550 | − * just transmitted. | |
| 1546 | + * @progress: How many words (not bytes) have been transferred so far | |
| 1551 | 1547 | * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. |
| 1552 | 1548 | */ |
| 1553 | 1549 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 1554 | 1550 | struct spi_transfer *xfer, |
| 1555 | − const void *tx, bool irqs_off) | |
| 1551 | + size_t progress, bool irqs_off) | |
| 1556 | 1552 | { |
| 1557 | − u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8); | |
| 1558 | − | |
| 1559 | 1553 | if (!xfer->ptp_sts) |
| 1560 | 1554 | return; |
| 1561 | 1555 | |
| 1562 | 1556 | if (xfer->timestamped_post) |
| 1563 | 1557 | return; |
| 1564 | 1558 | |
| 1565 | − if (tx < (xfer->tx_buf + xfer->ptp_sts_word_post * bytes_per_word)) | |
| 1559 | + if (progress < xfer->ptp_sts_word_post) | |
| 1566 | 1560 | return; |
| 1567 | 1561 | |
| 1568 | 1562 | ptp_read_system_postts(xfer->ptp_sts); |
| @@ -1573,7 +1567,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, · 4 unmodified lines | ||
| 1573 | 1567 | } |
| 1574 | 1568 | |
| 1575 | 1569 | /* Capture the resolution of the timestamp */ |
| 1576 | − xfer->ptp_sts_word_post = (tx - xfer->tx_buf) / bytes_per_word; | |
| 1570 | + xfer->ptp_sts_word_post = progress; | |
| 1577 | 1571 | |
| 1578 | 1572 | xfer->timestamped_post = true; |
| 1579 | 1573 | } |
| @@ -687,6 +687,7 @@ config MAX63XX_WATCHDOG · 686 unmodified lines | ||
| 687 | 687 | config MAX77620_WATCHDOG |
| 688 | 688 | tristate "Maxim Max77620 Watchdog Timer" |
| 689 | 689 | depends on MFD_MAX77620 || COMPILE_TEST |
| 690 | + select WATCHDOG_CORE | |
| 690 | 691 | help |
| 691 | 692 | This is the driver for the Max77620 watchdog timer. |
| 692 | 693 | Say 'Y' here to enable the watchdog timer support for |
| @@ -1444,6 +1445,7 @@ config SMSC37B787_WDT · 751 unmodified lines | ||
| 1444 | 1445 | config TQMX86_WDT |
| 1445 | 1446 | tristate "TQ-Systems TQMX86 Watchdog Timer" |
| 1446 | 1447 | depends on X86 |
| 1448 | + select WATCHDOG_CORE | |
| 1447 | 1449 | help |
| 1448 | 1450 | This is the driver for the hardware watchdog timer in the TQMX86 IO |
| 1449 | 1451 | controller found on some of their ComExpress Modules. |
| @@ -112,7 +112,7 @@ static int imx7ulp_wdt_restart(struct watchdog_device *wdog, · 111 unmodified lines | ||
| 112 | 112 | { |
| 113 | 113 | struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog); |
| 114 | 114 | |
| 115 | − imx7ulp_wdt_enable(wdt->base, true); | |
| 115 | + imx7ulp_wdt_enable(wdog, true); | |
| 116 | 116 | imx7ulp_wdt_set_timeout(&wdt->wdd, 1); |
| 117 | 117 | |
| 118 | 118 | /* wait for wdog to fire */ |
| @@ -602,7 +602,7 @@ static int orion_wdt_probe(struct platform_device *pdev) · 601 unmodified lines | ||
| 602 | 602 | set_bit(WDOG_HW_RUNNING, &dev->wdt.status); |
| 603 | 603 | |
| 604 | 604 | /* Request the IRQ only after the watchdog is disabled */ |
| 605 | − irq = platform_get_irq(pdev, 0); | |
| 605 | + irq = platform_get_irq_optional(pdev, 0); | |
| 606 | 606 | if (irq > 0) { |
| 607 | 607 | /* |
| 608 | 608 | * Not all supported platforms specify an interrupt for the |
| @@ -617,7 +617,7 @@ static int orion_wdt_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 617 | 617 | } |
| 618 | 618 | |
| 619 | 619 | /* Optional 2nd interrupt for pretimeout */ |
| 620 | − irq = platform_get_irq(pdev, 1); | |
| 620 | + irq = platform_get_irq_optional(pdev, 1); | |
| 621 | 621 | if (irq > 0) { |
| 622 | 622 | orion_wdt_info.options |= WDIOF_PRETIMEOUT; |
| 623 | 623 | ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq, |
| @@ -188,6 +188,7 @@ static struct platform_driver rn5t618_wdt_driver = { · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | module_platform_driver(rn5t618_wdt_driver); |
| 190 | 190 | |
| 191 | +MODULE_ALIAS("platform:rn5t618-wdt"); | |
| 191 | 192 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); |
| 192 | 193 | MODULE_DESCRIPTION("RN5T618 watchdog driver"); |
| 193 | 194 | MODULE_LICENSE("GPL v2"); |
| @@ -420,7 +420,7 @@ static int wdt_find(int addr) · 419 unmodified lines | ||
| 420 | 420 | cr_wdt_csr = NCT6102D_WDT_CSR; |
| 421 | 421 | break; |
| 422 | 422 | case NCT6116_ID: |
| 423 | − ret = nct6102; | |
| 423 | + ret = nct6116; | |
| 424 | 424 | cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; |
| 425 | 425 | cr_wdt_control = NCT6102D_WDT_CONTROL; |
| 426 | 426 | cr_wdt_csr = NCT6102D_WDT_CSR; |
| @@ -720,6 +720,7 @@ void kvm_set_pfn_dirty(kvm_pfn_t pfn); · 719 unmodified lines | ||
| 720 | 720 | void kvm_set_pfn_accessed(kvm_pfn_t pfn); |
| 721 | 721 | void kvm_get_pfn(kvm_pfn_t pfn); |
| 722 | 722 | |
| 723 | +void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache); | |
| 723 | 724 | int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, |
| 724 | 725 | int len); |
| 725 | 726 | int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len); |
| @@ -770,8 +771,12 @@ struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn · 44 unmodified lines | ||
| 770 | 771 | kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn); |
| 771 | 772 | kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn); |
| 772 | 773 | int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *map); |
| 774 | +int kvm_map_gfn(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map, | |
| 775 | + struct gfn_to_pfn_cache *cache, bool atomic); | |
| 773 | 776 | struct page *kvm_vcpu_gfn_to_page(struct kvm_vcpu *vcpu, gfn_t gfn); |
| 774 | 777 | void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty); |
| 778 | +int kvm_unmap_gfn(struct kvm_vcpu *vcpu, struct kvm_host_map *map, | |
| 779 | + struct gfn_to_pfn_cache *cache, bool dirty, bool atomic); | |
| 775 | 780 | unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn); |
| 776 | 781 | unsigned long kvm_vcpu_gfn_to_hva_prot(struct kvm_vcpu *vcpu, gfn_t gfn, bool *writable); |
| 777 | 782 | int kvm_vcpu_read_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn, void *data, int offset, |
| @@ -18,7 +18,7 @@ struct kvm_memslots; · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | enum kvm_mr_change; |
| 20 | 20 | |
| 21 | −#include <asm/types.h> | |
| 21 | +#include <linux/types.h> | |
| 22 | 22 | |
| 23 | 23 | /* |
| 24 | 24 | * Address types: |
| @@ -51,4 +51,11 @@ struct gfn_to_hva_cache { · 26 unmodified lines | ||
| 51 | 51 | struct kvm_memory_slot *memslot; |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | +struct gfn_to_pfn_cache { | |
| 55 | + u64 generation; | |
| 56 | + gfn_t gfn; | |
| 57 | + kvm_pfn_t pfn; | |
| 58 | + bool dirty; | |
| 59 | +}; | |
| 60 | + | |
| 54 | 61 | #endif /* __KVM_TYPES_H__ */ |
| @@ -46,6 +46,14 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | #define RTC_AL_SEC 0x0018 |
| 48 | 48 | |
| 49 | +#define RTC_AL_SEC_MASK 0x003f | |
| 50 | +#define RTC_AL_MIN_MASK 0x003f | |
| 51 | +#define RTC_AL_HOU_MASK 0x001f | |
| 52 | +#define RTC_AL_DOM_MASK 0x001f | |
| 53 | +#define RTC_AL_DOW_MASK 0x0007 | |
| 54 | +#define RTC_AL_MTH_MASK 0x000f | |
| 55 | +#define RTC_AL_YEA_MASK 0x007f | |
| 56 | + | |
| 49 | 57 | #define RTC_PDN2 0x002e |
| 50 | 58 | #define RTC_PDN2_PWRON_ALARM BIT(4) |
| 51 | 59 | |
| @@ -689,10 +689,10 @@ extern void spi_finalize_current_transfer(struct spi_controller *ctlr); · 688 unmodified lines | ||
| 689 | 689 | /* Helper calls for driver to timestamp transfer */ |
| 690 | 690 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 691 | 691 | struct spi_transfer *xfer, |
| 692 | − const void *tx, bool irqs_off); | |
| 692 | + size_t progress, bool irqs_off); | |
| 693 | 693 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 694 | 694 | struct spi_transfer *xfer, |
| 695 | − const void *tx, bool irqs_off); | |
| 695 | + size_t progress, bool irqs_off); | |
| 696 | 696 | |
| 697 | 697 | /* the spi driver core manages memory for the spi_controller classdev */ |
| 698 | 698 | extern struct spi_controller *__spi_alloc_controller(struct device *host, |
| @@ -18,13 +18,13 @@ DECLARE_EVENT_CLASS(preemptirq_template, · 17 unmodified lines | ||
| 18 | 18 | TP_ARGS(ip, parent_ip), |
| 19 | 19 | |
| 20 | 20 | TP_STRUCT__entry( |
| 21 | − __field(u32, caller_offs) | |
| 22 | − __field(u32, parent_offs) | |
| 21 | + __field(s32, caller_offs) | |
| 22 | + __field(s32, parent_offs) | |
| 23 | 23 | ), |
| 24 | 24 | |
| 25 | 25 | TP_fast_assign( |
| 26 | − __entry->caller_offs = (u32)(ip - (unsigned long)_stext); | |
| 27 | − __entry->parent_offs = (u32)(parent_ip - (unsigned long)_stext); | |
| 26 | + __entry->caller_offs = (s32)(ip - (unsigned long)_stext); | |
| 27 | + __entry->parent_offs = (s32)(parent_ip - (unsigned long)_stext); | |
| 28 | 28 | ), |
| 29 | 29 | |
| 30 | 30 | TP_printk("caller=%pS parent=%pS", |
| @@ -96,6 +96,20 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, · 95 unmodified lines | ||
| 96 | 96 | return 0; |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | +/* | |
| 100 | + * Not all archs define MCOUNT_INSN_SIZE which is used to look for direct | |
| 101 | + * functions. But those archs currently don't support direct functions | |
| 102 | + * anyway, and ftrace_find_rec_direct() is just a stub for them. | |
| 103 | + * Define MCOUNT_INSN_SIZE to keep those archs compiling. | |
| 104 | + */ | |
| 105 | +#ifndef MCOUNT_INSN_SIZE | |
| 106 | +/* Make sure this only works without direct calls */ | |
| 107 | +# ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS | |
| 108 | +# error MCOUNT_INSN_SIZE not defined with direct calls enabled | |
| 109 | +# endif | |
| 110 | +# define MCOUNT_INSN_SIZE 0 | |
| 111 | +#endif | |
| 112 | + | |
| 99 | 113 | int function_graph_enter(unsigned long ret, unsigned long func, |
| 100 | 114 | unsigned long frame_pointer, unsigned long *retp) |
| 101 | 115 | { |
| @@ -526,8 +526,7 @@ static int function_stat_show(struct seq_file *m, void *v) · 525 unmodified lines | ||
| 526 | 526 | } |
| 527 | 527 | |
| 528 | 528 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 529 | − avg = rec->time; | |
| 530 | − do_div(avg, rec->counter); | |
| 529 | + avg = div64_ul(rec->time, rec->counter); | |
| 531 | 530 | if (tracing_thresh && (avg < tracing_thresh)) |
| 532 | 531 | goto out; |
| 533 | 532 | #endif |
| @@ -553,7 +552,8 @@ static int function_stat_show(struct seq_file *m, void *v) · 19 unmodified lines | ||
| 553 | 552 | * Divide only 1000 for ns^2 -> us^2 conversion. |
| 554 | 553 | * trace_print_graph_duration will divide 1000 again. |
| 555 | 554 | */ |
| 556 | − do_div(stddev, rec->counter * (rec->counter - 1) * 1000); | |
| 555 | + stddev = div64_ul(stddev, | |
| 556 | + rec->counter * (rec->counter - 1) * 1000); | |
| 557 | 557 | } |
| 558 | 558 | |
| 559 | 559 | trace_seq_init(&s); |
| @@ -195,7 +195,7 @@ static int parse_entry(char *str, struct trace_event_call *call, void **pentry) · 194 unmodified lines | ||
| 195 | 195 | unsigned long irq_flags; |
| 196 | 196 | void *entry = NULL; |
| 197 | 197 | int entry_size; |
| 198 | − u64 val; | |
| 198 | + u64 val = 0; | |
| 199 | 199 | int len; |
| 200 | 200 | |
| 201 | 201 | entry = trace_alloc_entry(call, &entry_size); |
| @@ -630,7 +630,7 @@ static void start_wakeup_tracer(struct trace_array *tr) · 629 unmodified lines | ||
| 630 | 630 | if (ret) { |
| 631 | 631 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 632 | 632 | " probe to kernel_sched_migrate_task\n"); |
| 633 | − return; | |
| 633 | + goto fail_deprobe_sched_switch; | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | wakeup_reset(tr); |
| @@ -648,6 +648,8 @@ static void start_wakeup_tracer(struct trace_array *tr) · 11 unmodified lines | ||
| 648 | 648 | printk(KERN_ERR "failed to start wakeup tracer\n"); |
| 649 | 649 | |
| 650 | 650 | return; |
| 651 | +fail_deprobe_sched_switch: | |
| 652 | + unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); | |
| 651 | 653 | fail_deprobe_wake_new: |
| 652 | 654 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 653 | 655 | fail_deprobe: |
| @@ -381,7 +381,7 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, · 380 unmodified lines | ||
| 381 | 381 | int prefix_type, int rowsize, int groupsize, |
| 382 | 382 | const void *buf, size_t len, bool ascii) |
| 383 | 383 | { |
| 384 | − unsigned int save_len = s->seq.len; | |
| 384 | + unsigned int save_len = s->seq.len; | |
| 385 | 385 | |
| 386 | 386 | if (s->full) |
| 387 | 387 | return 0; |
| @@ -283,6 +283,11 @@ static void check_stack(unsigned long ip, unsigned long *stack) · 282 unmodified lines | ||
| 283 | 283 | local_irq_restore(flags); |
| 284 | 284 | } |
| 285 | 285 | |
| 286 | +/* Some archs may not define MCOUNT_INSN_SIZE */ | |
| 287 | +#ifndef MCOUNT_INSN_SIZE | |
| 288 | +# define MCOUNT_INSN_SIZE 0 | |
| 289 | +#endif | |
| 290 | + | |
| 286 | 291 | static void |
| 287 | 292 | stack_trace_call(unsigned long ip, unsigned long parent_ip, |
| 288 | 293 | struct ftrace_ops *op, struct pt_regs *pt_regs) |
| @@ -90,12 +90,6 @@ static void unmap_region(struct mm_struct *mm, · 89 unmodified lines | ||
| 90 | 90 | * MAP_PRIVATE r: (no) no r: (yes) yes r: (no) yes r: (no) yes |
| 91 | 91 | * w: (no) no w: (no) no w: (copy) copy w: (no) no |
| 92 | 92 | * x: (no) no x: (no) yes x: (no) yes x: (yes) yes |
| 93 | − * | |
| 94 | − * On arm64, PROT_EXEC has the following behaviour for both MAP_SHARED and | |
| 95 | − * MAP_PRIVATE: | |
| 96 | − * r: (no) no | |
| 97 | − * w: (no) no | |
| 98 | − * x: (yes) yes | |
| 99 | 93 | */ |
| 100 | 94 | pgprot_t protection_map[16] __ro_after_init = { |
| 101 | 95 | __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, |
| @@ -1817,26 +1817,72 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) · 1816 unmodified lines | ||
| 1817 | 1817 | } |
| 1818 | 1818 | EXPORT_SYMBOL_GPL(gfn_to_page); |
| 1819 | 1819 | |
| 1820 | −static int __kvm_map_gfn(struct kvm_memory_slot *slot, gfn_t gfn, | |
| 1821 | − struct kvm_host_map *map) | |
| 1820 | +void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache) | |
| 1821 | +{ | |
| 1822 | + if (pfn == 0) | |
| 1823 | + return; | |
| 1824 | + | |
| 1825 | + if (cache) | |
| 1826 | + cache->pfn = cache->gfn = 0; | |
| 1827 | + | |
| 1828 | + if (dirty) | |
| 1829 | + kvm_release_pfn_dirty(pfn); | |
| 1830 | + else | |
| 1831 | + kvm_release_pfn_clean(pfn); | |
| 1832 | +} | |
| 1833 | + | |
| 1834 | +static void kvm_cache_gfn_to_pfn(struct kvm_memory_slot *slot, gfn_t gfn, | |
| 1835 | + struct gfn_to_pfn_cache *cache, u64 gen) | |
| 1836 | +{ | |
| 1837 | + kvm_release_pfn(cache->pfn, cache->dirty, cache); | |
| 1838 | + | |
| 1839 | + cache->pfn = gfn_to_pfn_memslot(slot, gfn); | |
| 1840 | + cache->gfn = gfn; | |
| 1841 | + cache->dirty = false; | |
| 1842 | + cache->generation = gen; | |
| 1843 | +} | |
| 1844 | + | |
| 1845 | +static int __kvm_map_gfn(struct kvm_memslots *slots, gfn_t gfn, | |
| 1846 | + struct kvm_host_map *map, | |
| 1847 | + struct gfn_to_pfn_cache *cache, | |
| 1848 | + bool atomic) | |
| 1822 | 1849 | { |
| 1823 | 1850 | kvm_pfn_t pfn; |
| 1824 | 1851 | void *hva = NULL; |
| 1825 | 1852 | struct page *page = KVM_UNMAPPED_PAGE; |
| 1853 | + struct kvm_memory_slot *slot = __gfn_to_memslot(slots, gfn); | |
| 1854 | + u64 gen = slots->generation; | |
| 1826 | 1855 | |
| 1827 | 1856 | if (!map) |
| 1828 | 1857 | return -EINVAL; |
| 1829 | 1858 | |
| 1830 | − pfn = gfn_to_pfn_memslot(slot, gfn); | |
| 1859 | + if (cache) { | |
| 1860 | + if (!cache->pfn || cache->gfn != gfn || | |
| 1861 | + cache->generation != gen) { | |
| 1862 | + if (atomic) | |
| 1863 | + return -EAGAIN; | |
| 1864 | + kvm_cache_gfn_to_pfn(slot, gfn, cache, gen); | |
| 1865 | + } | |
| 1866 | + pfn = cache->pfn; | |
| 1867 | + } else { | |
| 1868 | + if (atomic) | |
| 1869 | + return -EAGAIN; | |
| 1870 | + pfn = gfn_to_pfn_memslot(slot, gfn); | |
| 1871 | + } | |
| 1831 | 1872 | if (is_error_noslot_pfn(pfn)) |
| 1832 | 1873 | return -EINVAL; |
| 1833 | 1874 | |
| 1834 | 1875 | if (pfn_valid(pfn)) { |
| 1835 | 1876 | page = pfn_to_page(pfn); |
| 1836 | − hva = kmap(page); | |
| 1877 | + if (atomic) | |
| 1878 | + hva = kmap_atomic(page); | |
| 1879 | + else | |
| 1880 | + hva = kmap(page); | |
| 1837 | 1881 | #ifdef CONFIG_HAS_IOMEM |
| 1838 | − } else { | |
| 1882 | + } else if (!atomic) { | |
| 1839 | 1883 | hva = memremap(pfn_to_hpa(pfn), PAGE_SIZE, MEMREMAP_WB); |
| 1884 | + } else { | |
| 1885 | + return -EINVAL; | |
| 1840 | 1886 | #endif |
| 1841 | 1887 | } |
| 1842 | 1888 | |
| @@ -1851,14 +1897,25 @@ static int __kvm_map_gfn(struct kvm_memory_slot *slot, gfn_t gfn, · 8 unmodified lines | ||
| 1851 | 1897 | return 0; |
| 1852 | 1898 | } |
| 1853 | 1899 | |
| 1900 | +int kvm_map_gfn(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map, | |
| 1901 | + struct gfn_to_pfn_cache *cache, bool atomic) | |
| 1902 | +{ | |
| 1903 | + return __kvm_map_gfn(kvm_memslots(vcpu->kvm), gfn, map, | |
| 1904 | + cache, atomic); | |
| 1905 | +} | |
| 1906 | +EXPORT_SYMBOL_GPL(kvm_map_gfn); | |
| 1907 | + | |
| 1854 | 1908 | int kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map) |
| 1855 | 1909 | { |
| 1856 | − return __kvm_map_gfn(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn, map); | |
| 1910 | + return __kvm_map_gfn(kvm_vcpu_memslots(vcpu), gfn, map, | |
| 1911 | + NULL, false); | |
| 1857 | 1912 | } |
| 1858 | 1913 | EXPORT_SYMBOL_GPL(kvm_vcpu_map); |
| 1859 | 1914 | |
| 1860 | −void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, | |
| 1861 | − bool dirty) | |
| 1915 | +static void __kvm_unmap_gfn(struct kvm_memory_slot *memslot, | |
| 1916 | + struct kvm_host_map *map, | |
| 1917 | + struct gfn_to_pfn_cache *cache, | |
| 1918 | + bool dirty, bool atomic) | |
| 1862 | 1919 | { |
| 1863 | 1920 | if (!map) |
| 1864 | 1921 | return; |
| @@ -1866,23 +1923,45 @@ void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, · 1 unmodified line | ||
| 1866 | 1923 | if (!map->hva) |
| 1867 | 1924 | return; |
| 1868 | 1925 | |
| 1869 | − if (map->page != KVM_UNMAPPED_PAGE) | |
| 1870 | − kunmap(map->page); | |
| 1926 | + if (map->page != KVM_UNMAPPED_PAGE) { | |
| 1927 | + if (atomic) | |
| 1928 | + kunmap_atomic(map->hva); | |
| 1929 | + else | |
| 1930 | + kunmap(map->page); | |
| 1931 | + } | |
| 1871 | 1932 | #ifdef CONFIG_HAS_IOMEM |
| 1872 | − else | |
| 1933 | + else if (!atomic) | |
| 1873 | 1934 | memunmap(map->hva); |
| 1935 | + else | |
| 1936 | + WARN_ONCE(1, "Unexpected unmapping in atomic context"); | |
| 1874 | 1937 | #endif |
| 1875 | 1938 | |
| 1876 | − if (dirty) { | |
| 1877 | − kvm_vcpu_mark_page_dirty(vcpu, map->gfn); | |
| 1878 | − kvm_release_pfn_dirty(map->pfn); | |
| 1879 | − } else { | |
| 1880 | − kvm_release_pfn_clean(map->pfn); | |
| 1881 | − } | |
| 1939 | + if (dirty) | |
| 1940 | + mark_page_dirty_in_slot(memslot, map->gfn); | |
| 1941 | + | |
| 1942 | + if (cache) | |
| 1943 | + cache->dirty |= dirty; | |
| 1944 | + else | |
| 1945 | + kvm_release_pfn(map->pfn, dirty, NULL); | |
| 1882 | 1946 | |
| 1883 | 1947 | map->hva = NULL; |
| 1884 | 1948 | map->page = NULL; |
| 1885 | 1949 | } |
| 1950 | + | |
| 1951 | +int kvm_unmap_gfn(struct kvm_vcpu *vcpu, struct kvm_host_map *map, | |
| 1952 | + struct gfn_to_pfn_cache *cache, bool dirty, bool atomic) | |
| 1953 | +{ | |
| 1954 | + __kvm_unmap_gfn(gfn_to_memslot(vcpu->kvm, map->gfn), map, | |
| 1955 | + cache, dirty, atomic); | |
| 1956 | + return 0; | |
| 1957 | +} | |
| 1958 | +EXPORT_SYMBOL_GPL(kvm_unmap_gfn); | |
| 1959 | + | |
| 1960 | +void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty) | |
| 1961 | +{ | |
| 1962 | + __kvm_unmap_gfn(kvm_vcpu_gfn_to_memslot(vcpu, map->gfn), map, NULL, | |
| 1963 | + dirty, false); | |
| 1964 | +} | |
| 1886 | 1965 | EXPORT_SYMBOL_GPL(kvm_vcpu_unmap); |
| 1887 | 1966 | |
| 1888 | 1967 | struct page *kvm_vcpu_gfn_to_page(struct kvm_vcpu *vcpu, gfn_t gfn) |