diff options
Diffstat (limited to '4.7.8/1007_linux-4.7.8.patch')
-rw-r--r-- | 4.7.8/1007_linux-4.7.8.patch | 1626 |
1 files changed, 1626 insertions, 0 deletions
diff --git a/4.7.8/1007_linux-4.7.8.patch b/4.7.8/1007_linux-4.7.8.patch new file mode 100644 index 0000000..dd5c7d8 --- /dev/null +++ b/4.7.8/1007_linux-4.7.8.patch @@ -0,0 +1,1626 @@ +diff --git a/Documentation/virtual/kvm/devices/vcpu.txt b/Documentation/virtual/kvm/devices/vcpu.txt +index c041658..02f5068 100644 +--- a/Documentation/virtual/kvm/devices/vcpu.txt ++++ b/Documentation/virtual/kvm/devices/vcpu.txt +@@ -30,4 +30,6 @@ Returns: -ENODEV: PMUv3 not supported + attribute + -EBUSY: PMUv3 already initialized + +-Request the initialization of the PMUv3. ++Request the initialization of the PMUv3. This must be done after creating the ++in-kernel irqchip. Creating a PMU with a userspace irqchip is currently not ++supported. +diff --git a/Makefile b/Makefile +index 320a930..4e17baa 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 7 +-SUBLEVEL = 7 ++SUBLEVEL = 8 + EXTRAVERSION = + NAME = Psychotic Stoned Sheep + +diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi +index 094e39c..6cd18d8 100644 +--- a/arch/arm/boot/dts/armada-390.dtsi ++++ b/arch/arm/boot/dts/armada-390.dtsi +@@ -47,6 +47,8 @@ + #include "armada-39x.dtsi" + + / { ++ compatible = "marvell,armada390"; ++ + soc { + internal-regs { + pinctrl@18000 { +@@ -54,4 +56,5 @@ + reg = <0x18000 0x20>; + }; + }; ++ }; + }; +diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi +index df96ccd..779f844 100644 +--- a/arch/arm/boot/dts/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi +@@ -5,6 +5,7 @@ + #include <dt-bindings/reset/qcom,gcc-msm8960.h> + #include <dt-bindings/clock/qcom,mmcc-msm8960.h> + #include <dt-bindings/soc/qcom,gsbi.h> ++#include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + / { + model = "Qualcomm APQ8064"; +@@ -552,22 +553,50 @@ + compatible = "qcom,pm8921-gpio", + "qcom,ssbi-gpio"; + reg = <0x150>; +- interrupts = <192 1>, <193 1>, <194 1>, +- <195 1>, <196 1>, <197 1>, +- <198 1>, <199 1>, <200 1>, +- <201 1>, <202 1>, <203 1>, +- <204 1>, <205 1>, <206 1>, +- <207 1>, <208 1>, <209 1>, +- <210 1>, <211 1>, <212 1>, +- <213 1>, <214 1>, <215 1>, +- <216 1>, <217 1>, <218 1>, +- <219 1>, <220 1>, <221 1>, +- <222 1>, <223 1>, <224 1>, +- <225 1>, <226 1>, <227 1>, +- <228 1>, <229 1>, <230 1>, +- <231 1>, <232 1>, <233 1>, +- <234 1>, <235 1>; +- ++ interrupts = <192 IRQ_TYPE_NONE>, ++ <193 IRQ_TYPE_NONE>, ++ <194 IRQ_TYPE_NONE>, ++ <195 IRQ_TYPE_NONE>, ++ <196 IRQ_TYPE_NONE>, ++ <197 IRQ_TYPE_NONE>, ++ <198 IRQ_TYPE_NONE>, ++ <199 IRQ_TYPE_NONE>, ++ <200 IRQ_TYPE_NONE>, ++ <201 IRQ_TYPE_NONE>, ++ <202 IRQ_TYPE_NONE>, ++ <203 IRQ_TYPE_NONE>, ++ <204 IRQ_TYPE_NONE>, ++ <205 IRQ_TYPE_NONE>, ++ <206 IRQ_TYPE_NONE>, ++ <207 IRQ_TYPE_NONE>, ++ <208 IRQ_TYPE_NONE>, ++ <209 IRQ_TYPE_NONE>, ++ <210 IRQ_TYPE_NONE>, ++ <211 IRQ_TYPE_NONE>, ++ <212 IRQ_TYPE_NONE>, ++ <213 IRQ_TYPE_NONE>, ++ <214 IRQ_TYPE_NONE>, ++ <215 IRQ_TYPE_NONE>, ++ <216 IRQ_TYPE_NONE>, ++ <217 IRQ_TYPE_NONE>, ++ <218 IRQ_TYPE_NONE>, ++ <219 IRQ_TYPE_NONE>, ++ <220 IRQ_TYPE_NONE>, ++ <221 IRQ_TYPE_NONE>, ++ <222 IRQ_TYPE_NONE>, ++ <223 IRQ_TYPE_NONE>, ++ <224 IRQ_TYPE_NONE>, ++ <225 IRQ_TYPE_NONE>, ++ <226 IRQ_TYPE_NONE>, ++ <227 IRQ_TYPE_NONE>, ++ <228 IRQ_TYPE_NONE>, ++ <229 IRQ_TYPE_NONE>, ++ <230 IRQ_TYPE_NONE>, ++ <231 IRQ_TYPE_NONE>, ++ <232 IRQ_TYPE_NONE>, ++ <233 IRQ_TYPE_NONE>, ++ <234 IRQ_TYPE_NONE>, ++ <235 IRQ_TYPE_NONE>; + gpio-controller; + #gpio-cells = <2>; + +@@ -580,9 +609,18 @@ + gpio-controller; + #gpio-cells = <2>; + interrupts = +- <128 1>, <129 1>, <130 1>, <131 1>, +- <132 1>, <133 1>, <134 1>, <135 1>, +- <136 1>, <137 1>, <138 1>, <139 1>; ++ <128 IRQ_TYPE_NONE>, ++ <129 IRQ_TYPE_NONE>, ++ <130 IRQ_TYPE_NONE>, ++ <131 IRQ_TYPE_NONE>, ++ <132 IRQ_TYPE_NONE>, ++ <133 IRQ_TYPE_NONE>, ++ <134 IRQ_TYPE_NONE>, ++ <135 IRQ_TYPE_NONE>, ++ <136 IRQ_TYPE_NONE>, ++ <137 IRQ_TYPE_NONE>, ++ <138 IRQ_TYPE_NONE>, ++ <139 IRQ_TYPE_NONE>; + }; + + rtc@11d { +diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c +index d9751a4..d34fd72 100644 +--- a/arch/arm64/kernel/stacktrace.c ++++ b/arch/arm64/kernel/stacktrace.c +@@ -43,6 +43,9 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) + unsigned long fp = frame->fp; + unsigned long irq_stack_ptr; + ++ if (!tsk) ++ tsk = current; ++ + /* + * Switching between stacks is valid when tracing current and in + * non-preemptible context. +@@ -67,7 +70,7 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) + frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); + + #ifdef CONFIG_FUNCTION_GRAPH_TRACER +- if (tsk && tsk->ret_stack && ++ if (tsk->ret_stack && + (frame->pc == (unsigned long)return_to_handler)) { + /* + * This is a case where function graph tracer has +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index 2a43012..f014df9 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -149,6 +149,11 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) + unsigned long irq_stack_ptr; + int skip; + ++ pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); ++ ++ if (!tsk) ++ tsk = current; ++ + /* + * Switching between stacks is valid when tracing current and in + * non-preemptible context. +@@ -158,11 +163,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) + else + irq_stack_ptr = 0; + +- pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); +- +- if (!tsk) +- tsk = current; +- + if (tsk == current) { + frame.fp = (unsigned long)__builtin_frame_address(0); + frame.sp = current_stack_pointer; +diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c +index 2b42a74..efa592f 100644 +--- a/arch/mips/kvm/emulate.c ++++ b/arch/mips/kvm/emulate.c +@@ -807,6 +807,47 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu) + return EMULATE_FAIL; + } + ++/** ++ * kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map. ++ * @vcpu: VCPU with changed mappings. ++ * @tlb: TLB entry being removed. ++ * ++ * This is called to indicate a single change in guest MMU mappings, so that we ++ * can arrange TLB flushes on this and other CPUs. ++ */ ++static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu, ++ struct kvm_mips_tlb *tlb) ++{ ++ int cpu, i; ++ bool user; ++ ++ /* No need to flush for entries which are already invalid */ ++ if (!((tlb->tlb_lo[0] | tlb->tlb_lo[1]) & ENTRYLO_V)) ++ return; ++ /* User address space doesn't need flushing for KSeg2/3 changes */ ++ user = tlb->tlb_hi < KVM_GUEST_KSEG0; ++ ++ preempt_disable(); ++ ++ /* ++ * Probe the shadow host TLB for the entry being overwritten, if one ++ * matches, invalidate it ++ */ ++ kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi); ++ ++ /* Invalidate the whole ASID on other CPUs */ ++ cpu = smp_processor_id(); ++ for_each_possible_cpu(i) { ++ if (i == cpu) ++ continue; ++ if (user) ++ vcpu->arch.guest_user_asid[i] = 0; ++ vcpu->arch.guest_kernel_asid[i] = 0; ++ } ++ ++ preempt_enable(); ++} ++ + /* Write Guest TLB Entry @ Index */ + enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu) + { +@@ -826,11 +867,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu) + } + + tlb = &vcpu->arch.guest_tlb[index]; +- /* +- * Probe the shadow host TLB for the entry being overwritten, if one +- * matches, invalidate it +- */ +- kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi); ++ ++ kvm_mips_invalidate_guest_tlb(vcpu, tlb); + + tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0); + tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0); +@@ -859,11 +897,7 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu) + + tlb = &vcpu->arch.guest_tlb[index]; + +- /* +- * Probe the shadow host TLB for the entry being overwritten, if one +- * matches, invalidate it +- */ +- kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi); ++ kvm_mips_invalidate_guest_tlb(vcpu, tlb); + + tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0); + tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0); +@@ -982,6 +1016,7 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, + int32_t rt, rd, copz, sel, co_bit, op; + uint32_t pc = vcpu->arch.pc; + unsigned long curr_pc; ++ int cpu, i; + + /* + * Update PC and hold onto current PC in case there is +@@ -1089,8 +1124,16 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, + vcpu->arch.gprs[rt] + & KVM_ENTRYHI_ASID); + ++ preempt_disable(); + /* Blow away the shadow host TLBs */ + kvm_mips_flush_host_tlb(1); ++ cpu = smp_processor_id(); ++ for_each_possible_cpu(i) ++ if (i != cpu) { ++ vcpu->arch.guest_user_asid[i] = 0; ++ vcpu->arch.guest_kernel_asid[i] = 0; ++ } ++ preempt_enable(); + } + kvm_write_c0_guest_entryhi(cop0, + vcpu->arch.gprs[rt]); +diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h +index 467c0b0..9e9d38a 100644 +--- a/arch/powerpc/include/asm/pci-bridge.h ++++ b/arch/powerpc/include/asm/pci-bridge.h +@@ -299,6 +299,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, + /* Allocate & free a PCI host bridge structure */ + extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); + extern void pcibios_free_controller(struct pci_controller *phb); ++extern void pcibios_free_controller_deferred(struct pci_host_bridge *bridge); + + #ifdef CONFIG_PCI + extern int pcibios_vaddr_is_ioport(void __iomem *address); +diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h +index a0948f4..145e5b7 100644 +--- a/arch/powerpc/include/asm/reg.h ++++ b/arch/powerpc/include/asm/reg.h +@@ -718,6 +718,7 @@ + #define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ + #define SPRN_MMCR1 798 + #define SPRN_MMCR2 785 ++#define SPRN_UMMCR2 769 + #define SPRN_MMCRA 0x312 + #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ + #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL +diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c +index 0f7a60f..14af45c 100644 +--- a/arch/powerpc/kernel/pci-common.c ++++ b/arch/powerpc/kernel/pci-common.c +@@ -103,6 +103,42 @@ void pcibios_free_controller(struct pci_controller *phb) + EXPORT_SYMBOL_GPL(pcibios_free_controller); + + /* ++ * This function is used to call pcibios_free_controller() ++ * in a deferred manner: a callback from the PCI subsystem. ++ * ++ * _*DO NOT*_ call pcibios_free_controller() explicitly if ++ * this is used (or it may access an invalid *phb pointer). ++ * ++ * The callback occurs when all references to the root bus ++ * are dropped (e.g., child buses/devices and their users). ++ * ++ * It's called as .release_fn() of 'struct pci_host_bridge' ++ * which is associated with the 'struct pci_controller.bus' ++ * (root bus) - it expects .release_data to hold a pointer ++ * to 'struct pci_controller'. ++ * ++ * In order to use it, register .release_fn()/release_data ++ * like this: ++ * ++ * pci_set_host_bridge_release(bridge, ++ * pcibios_free_controller_deferred ++ * (void *) phb); ++ * ++ * e.g. in the pcibios_root_bridge_prepare() callback from ++ * pci_create_root_bus(). ++ */ ++void pcibios_free_controller_deferred(struct pci_host_bridge *bridge) ++{ ++ struct pci_controller *phb = (struct pci_controller *) ++ bridge->release_data; ++ ++ pr_debug("domain %d, dynamic %d\n", phb->global_number, phb->is_dynamic); ++ ++ pcibios_free_controller(phb); ++} ++EXPORT_SYMBOL_GPL(pcibios_free_controller_deferred); ++ ++/* + * The function is used to return the minimal alignment + * for memory or I/O windows of the associated P2P bridge. + * By default, 4KiB alignment for I/O windows and 1MiB for +diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c +index 2afdb9c..729f8fa 100644 +--- a/arch/powerpc/kvm/book3s_emulate.c ++++ b/arch/powerpc/kvm/book3s_emulate.c +@@ -498,6 +498,7 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) + case SPRN_MMCR0: + case SPRN_MMCR1: + case SPRN_MMCR2: ++ case SPRN_UMMCR2: + #endif + break; + unprivileged: +@@ -640,6 +641,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val + case SPRN_MMCR0: + case SPRN_MMCR1: + case SPRN_MMCR2: ++ case SPRN_UMMCR2: + case SPRN_TIR: + #endif + *spr_val = 0; +diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c +index 4afae69..eb283c5 100644 +--- a/arch/powerpc/kvm/booke.c ++++ b/arch/powerpc/kvm/booke.c +@@ -2038,7 +2038,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, + if (type == KVMPPC_DEBUG_NONE) + continue; + +- if (type & !(KVMPPC_DEBUG_WATCH_READ | ++ if (type & ~(KVMPPC_DEBUG_WATCH_READ | + KVMPPC_DEBUG_WATCH_WRITE | + KVMPPC_DEBUG_BREAKPOINT)) + return -EINVAL; +diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c +index fe16a50..09eba5a 100644 +--- a/arch/powerpc/platforms/pseries/pci.c ++++ b/arch/powerpc/platforms/pseries/pci.c +@@ -119,6 +119,10 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) + + bus = bridge->bus; + ++ /* Rely on the pcibios_free_controller_deferred() callback. */ ++ pci_set_host_bridge_release(bridge, pcibios_free_controller_deferred, ++ (void *) pci_bus_to_host(bus)); ++ + dn = pcibios_get_phb_of_node(bus); + if (!dn) + return 0; +diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c +index 906dbaa..547fd13 100644 +--- a/arch/powerpc/platforms/pseries/pci_dlpar.c ++++ b/arch/powerpc/platforms/pseries/pci_dlpar.c +@@ -106,8 +106,11 @@ int remove_phb_dynamic(struct pci_controller *phb) + release_resource(res); + } + +- /* Free pci_controller data structure */ +- pcibios_free_controller(phb); ++ /* ++ * The pci_controller data structure is freed by ++ * the pcibios_free_controller_deferred() callback; ++ * see pseries_root_bridge_prepare(). ++ */ + + return 0; + } +diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h +index 38951b0..993a072 100644 +--- a/arch/x86/include/asm/fpu/xstate.h ++++ b/arch/x86/include/asm/fpu/xstate.h +@@ -24,11 +24,12 @@ + XFEATURE_MASK_YMM | \ + XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_ZMM_Hi256 | \ +- XFEATURE_MASK_Hi16_ZMM | \ +- XFEATURE_MASK_PKRU) ++ XFEATURE_MASK_Hi16_ZMM) + + /* Supported features which require eager state saving */ +-#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR) ++#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | \ ++ XFEATURE_MASK_BNDCSR | \ ++ XFEATURE_MASK_PKRU) + + /* All currently supported features */ + #define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER) +diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h +index b07233b..c2f94dc 100644 +--- a/arch/x86/include/asm/mpspec.h ++++ b/arch/x86/include/asm/mpspec.h +@@ -6,7 +6,6 @@ + #include <asm/x86_init.h> + #include <asm/apicdef.h> + +-extern int apic_version[]; + extern int pic_mode; + + #ifdef CONFIG_X86_32 +@@ -40,6 +39,7 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES]; + extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); + + extern unsigned int boot_cpu_physical_apicid; ++extern u8 boot_cpu_apic_version; + extern unsigned long mp_lapic_addr; + + #ifdef CONFIG_X86_LOCAL_APIC +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 9414f84..8e6e8bc 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -180,7 +180,7 @@ static int acpi_register_lapic(int id, u8 enabled) + } + + if (boot_cpu_physical_apicid != -1U) +- ver = apic_version[boot_cpu_physical_apicid]; ++ ver = boot_cpu_apic_version; + + return generic_processor_info(id, ver); + } +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index b15e1c1..cc7bc8b 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -64,6 +64,8 @@ unsigned disabled_cpus; + unsigned int boot_cpu_physical_apicid = -1U; + EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid); + ++u8 boot_cpu_apic_version; ++ + /* + * The highest APIC ID seen during enumeration. + */ +@@ -1790,8 +1792,7 @@ void __init init_apic_mappings(void) + * since smp_sanity_check is prepared for such a case + * and disable smp mode + */ +- apic_version[new_apicid] = +- GET_APIC_VERSION(apic_read(APIC_LVR)); ++ boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR)); + } + } + +@@ -1806,13 +1807,10 @@ void __init register_lapic_address(unsigned long address) + } + if (boot_cpu_physical_apicid == -1U) { + boot_cpu_physical_apicid = read_apic_id(); +- apic_version[boot_cpu_physical_apicid] = +- GET_APIC_VERSION(apic_read(APIC_LVR)); ++ boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR)); + } + } + +-int apic_version[MAX_LOCAL_APIC]; +- + /* + * Local APIC interrupts + */ +@@ -2102,11 +2100,10 @@ int generic_processor_info(int apicid, int version) + cpu, apicid); + version = 0x10; + } +- apic_version[apicid] = version; + +- if (version != apic_version[boot_cpu_physical_apicid]) { ++ if (version != boot_cpu_apic_version) { + pr_warning("BIOS bug: APIC version mismatch, boot CPU: %x, CPU %d: version %x\n", +- apic_version[boot_cpu_physical_apicid], cpu, version); ++ boot_cpu_apic_version, cpu, version); + } + + physid_set(apicid, phys_cpu_present_map); +@@ -2249,7 +2246,7 @@ int __init APIC_init_uniprocessor(void) + * Complain if the BIOS pretends there is one. + */ + if (!boot_cpu_has(X86_FEATURE_APIC) && +- APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { ++ APIC_INTEGRATED(boot_cpu_apic_version)) { + pr_err("BIOS bug, local APIC 0x%x not detected!...\n", + boot_cpu_physical_apicid); + return -1; +diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c +index 446702e..fbfb244 100644 +--- a/arch/x86/kernel/apic/io_apic.c ++++ b/arch/x86/kernel/apic/io_apic.c +@@ -1592,7 +1592,7 @@ void __init setup_ioapic_ids_from_mpc(void) + * no meaning without the serial APIC bus. + */ + if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) +- || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) ++ || APIC_XAPIC(boot_cpu_apic_version)) + return; + setup_ioapic_ids_from_mpc_nocheck(); + } +@@ -2422,7 +2422,7 @@ static int io_apic_get_unique_id(int ioapic, int apic_id) + static u8 io_apic_unique_id(int idx, u8 id) + { + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && +- !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) ++ !APIC_XAPIC(boot_cpu_apic_version)) + return io_apic_get_unique_id(idx, id); + else + return id; +diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c +index f316e34..49da80cf 100644 +--- a/arch/x86/kernel/apic/probe_32.c ++++ b/arch/x86/kernel/apic/probe_32.c +@@ -153,7 +153,7 @@ early_param("apic", parse_apic); + + void __init default_setup_apic_routing(void) + { +- int version = apic_version[boot_cpu_physical_apicid]; ++ int version = boot_cpu_apic_version; + + if (num_possible_cpus() > 8) { + switch (boot_cpu_data.x86_vendor) { +diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c +index a5e400a..84eced5 100644 +--- a/arch/x86/kernel/apic/vector.c ++++ b/arch/x86/kernel/apic/vector.c +@@ -661,11 +661,28 @@ void irq_complete_move(struct irq_cfg *cfg) + */ + void irq_force_complete_move(struct irq_desc *desc) + { +- struct irq_data *irqdata = irq_desc_get_irq_data(desc); +- struct apic_chip_data *data = apic_chip_data(irqdata); +- struct irq_cfg *cfg = data ? &data->cfg : NULL; ++ struct irq_data *irqdata; ++ struct apic_chip_data *data; ++ struct irq_cfg *cfg; + unsigned int cpu; + ++ /* ++ * The function is called for all descriptors regardless of which ++ * irqdomain they belong to. For example if an IRQ is provided by ++ * an irq_chip as part of a GPIO driver, the chip data for that ++ * descriptor is specific to the irq_chip in question. ++ * ++ * Check first that the chip_data is what we expect ++ * (apic_chip_data) before touching it any further. ++ */ ++ irqdata = irq_domain_get_irq_data(x86_vector_domain, ++ irq_desc_get_irq(desc)); ++ if (!irqdata) ++ return; ++ ++ data = apic_chip_data(irqdata); ++ cfg = data ? &data->cfg : NULL; ++ + if (!cfg) + return; + +diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c +index 621b501..8a90f15 100644 +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -348,7 +348,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, + * continue building up new bios map based on this + * information + */ +- if (current_type != last_type || current_type == E820_PRAM) { ++ if (current_type != last_type) { + if (last_type != 0) { + new_bios[new_bios_entry].size = + change_point[chgidx]->addr - last_addr; +@@ -754,7 +754,7 @@ u64 __init early_reserve_e820(u64 size, u64 align) + /* + * Find the highest page frame number we have available + */ +-static unsigned long __init e820_end_pfn(unsigned long limit_pfn) ++static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) + { + int i; + unsigned long last_pfn = 0; +@@ -765,11 +765,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn) + unsigned long start_pfn; + unsigned long end_pfn; + +- /* +- * Persistent memory is accounted as ram for purposes of +- * establishing max_pfn and mem_map. +- */ +- if (ei->type != E820_RAM && ei->type != E820_PRAM) ++ if (ei->type != type) + continue; + + start_pfn = ei->addr >> PAGE_SHIFT; +@@ -794,12 +790,12 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn) + } + unsigned long __init e820_end_of_ram_pfn(void) + { +- return e820_end_pfn(MAX_ARCH_PFN); ++ return e820_end_pfn(MAX_ARCH_PFN, E820_RAM); + } + + unsigned long __init e820_end_of_low_ram_pfn(void) + { +- return e820_end_pfn(1UL << (32-PAGE_SHIFT)); ++ return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_RAM); + } + + static void early_panic(char *msg) +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index 6e789ca..5dc86d2 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -110,12 +110,13 @@ void __show_regs(struct pt_regs *regs, int all) + get_debugreg(d7, 7); + + /* Only print out debug registers if they are in their non-default state. */ +- if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && +- (d6 == DR6_RESERVED) && (d7 == 0x400)) +- return; +- +- printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); +- printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); ++ if (!((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && ++ (d6 == DR6_RESERVED) && (d7 == 0x400))) { ++ printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", ++ d0, d1, d2); ++ printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", ++ d3, d6, d7); ++ } + + if (boot_cpu_has(X86_FEATURE_OSPKE)) + printk(KERN_DEFAULT "PKRU: %08x\n", read_pkru()); +diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c +index 600edd2..67ed18e 100644 +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -173,8 +173,8 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) + return sp; + + prev_esp = (u32 *)(context); +- if (prev_esp) +- return (unsigned long)prev_esp; ++ if (*prev_esp) ++ return (unsigned long)*prev_esp; + + return (unsigned long)regs; + } +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index fafe8b9..694c529 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -676,7 +676,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip) + * Give the other CPU some time to accept the IPI. + */ + udelay(200); +- if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { ++ if (APIC_INTEGRATED(boot_cpu_apic_version)) { + maxlvt = lapic_get_maxlvt(); + if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ + apic_write(APIC_ESR, 0); +@@ -703,7 +703,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) + /* + * Be paranoid about clearing APIC errors. + */ +- if (APIC_INTEGRATED(apic_version[phys_apicid])) { ++ if (APIC_INTEGRATED(boot_cpu_apic_version)) { + if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ + apic_write(APIC_ESR, 0); + apic_read(APIC_ESR); +@@ -742,7 +742,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) + * Determine this based on the APIC version. + * If we don't have an integrated APIC, don't send the STARTUP IPIs. + */ +- if (APIC_INTEGRATED(apic_version[phys_apicid])) ++ if (APIC_INTEGRATED(boot_cpu_apic_version)) + num_starts = 2; + else + num_starts = 0; +@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) + /* + * Be paranoid about clearing APIC errors. + */ +- if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { ++ if (APIC_INTEGRATED(boot_cpu_apic_version)) { + apic_write(APIC_ESR, 0); + apic_read(APIC_ESR); + } +@@ -1235,7 +1235,7 @@ static int __init smp_sanity_check(unsigned max_cpus) + /* + * If we couldn't find a local APIC, then get out of here now! + */ +- if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && ++ if (APIC_INTEGRATED(boot_cpu_apic_version) && + !boot_cpu_has(X86_FEATURE_APIC)) { + if (!disable_apic) { + pr_err("BIOS bug, local APIC #%d not detected!...\n", +@@ -1393,9 +1393,21 @@ __init void prefill_possible_map(void) + { + int i, possible; + +- /* no processor from mptable or madt */ +- if (!num_processors) +- num_processors = 1; ++ /* No boot processor was found in mptable or ACPI MADT */ ++ if (!num_processors) { ++ int apicid = boot_cpu_physical_apicid; ++ int cpu = hard_smp_processor_id(); ++ ++ pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu); ++ ++ /* Make sure boot cpu is enumerated */ ++ if (apic->cpu_present_to_apicid(0) == BAD_APICID && ++ apic->apic_id_valid(apicid)) ++ generic_processor_info(apicid, boot_cpu_apic_version); ++ ++ if (!num_processors) ++ num_processors = 1; ++ } + + i = setup_max_cpus ?: 1; + if (setup_possible_cpus == -1) { +diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c +index 719cf29..40c3aab9 100644 +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -87,6 +87,12 @@ static void cpu_bringup(void) + cpu_data(cpu).x86_max_cores = 1; + set_cpu_sibling_map(cpu); + ++ /* ++ * identify_cpu() may have set logical_pkg_id to -1 due ++ * to incorrect phys_proc_id. Let's re-comupte it. ++ */ ++ topology_update_package_map(apic->cpu_present_to_apicid(cpu), cpu); ++ + xen_setup_cpu_clockevents(); + + notify_cpu_starting(cpu); +diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c +index de0337e..4f3137d 100644 +--- a/drivers/char/tpm/tpm-dev.c ++++ b/drivers/char/tpm/tpm-dev.c +@@ -139,7 +139,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, + + /* atomic tpm command send and result receive */ + out_size = tpm_transmit(priv->chip, priv->data_buffer, +- sizeof(priv->data_buffer)); ++ sizeof(priv->data_buffer), 0); + if (out_size < 0) { + mutex_unlock(&priv->buffer_mutex); + return out_size; +diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c +index e2fa89c..9ba86eb3 100644 +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -330,8 +330,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); + /* + * Internal kernel interface to transmit TPM commands + */ +-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, +- size_t bufsiz) ++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, ++ unsigned int flags) + { + ssize_t rc; + u32 count, ordinal; +@@ -350,7 +350,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, + return -E2BIG; + } + +- mutex_lock(&chip->tpm_mutex); ++ if (!(flags & TPM_TRANSMIT_UNLOCKED)) ++ mutex_lock(&chip->tpm_mutex); + + rc = chip->ops->send(chip, (u8 *) buf, count); + if (rc < 0) { +@@ -393,20 +394,21 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, + dev_err(chip->pdev, + "tpm_transmit: tpm_recv: error %zd\n", rc); + out: +- mutex_unlock(&chip->tpm_mutex); ++ if (!(flags & TPM_TRANSMIT_UNLOCKED)) ++ mutex_unlock(&chip->tpm_mutex); + return rc; + } + + #define TPM_DIGEST_SIZE 20 + #define TPM_RET_CODE_IDX 6 + +-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, +- int len, const char *desc) ++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, ++ int len, unsigned int flags, const char *desc) + { +- struct tpm_output_header *header; ++ const struct tpm_output_header *header; + int err; + +- len = tpm_transmit(chip, (u8 *) cmd, len); ++ len = tpm_transmit(chip, (const u8 *)cmd, len, flags); + if (len < 0) + return len; + else if (len < TPM_HEADER_SIZE) +@@ -454,7 +456,8 @@ ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap, + tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); + tpm_cmd.params.getcap_in.subcap = subcap_id; + } +- rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc); ++ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0, ++ desc); + if (!rc) + *cap = tpm_cmd.params.getcap_out.cap; + return rc; +@@ -470,7 +473,7 @@ void tpm_gen_interrupt(struct tpm_chip *chip) + tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); + tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; + +- rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0, + "attempting to determine the timeouts"); + } + EXPORT_SYMBOL_GPL(tpm_gen_interrupt); +@@ -491,7 +494,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) + start_cmd.header.in = tpm_startup_header; + + start_cmd.params.startup_in.startup_type = startup_type; +- return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, ++ return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0, + "attempting to start the TPM"); + } + +@@ -522,7 +525,8 @@ int tpm_get_timeouts(struct tpm_chip *chip) + tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; + tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); + tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; +- rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL); ++ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0, ++ NULL); + + if (rc == TPM_ERR_INVALID_POSTINIT) { + /* The TPM is not started, we are the first to talk to it. +@@ -536,7 +540,7 @@ int tpm_get_timeouts(struct tpm_chip *chip) + tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); + tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; + rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, +- NULL); ++ 0, NULL); + } + if (rc) { + dev_err(chip->pdev, +@@ -597,7 +601,7 @@ int tpm_get_timeouts(struct tpm_chip *chip) + tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); + tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION; + +- rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0, + "attempting to determine the durations"); + if (rc) + return rc; +@@ -653,7 +657,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip) + struct tpm_cmd_t cmd; + + cmd.header.in = continue_selftest_header; +- rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0, + "continue selftest"); + return rc; + } +@@ -673,7 +677,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) + + cmd.header.in = pcrread_header; + cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx); +- rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0, + "attempting to read a pcr value"); + + if (rc == 0) +@@ -771,7 +775,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) + cmd.header.in = pcrextend_header; + cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); + memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); +- rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0, + "attempting extend a PCR value"); + + tpm_chip_put(chip); +@@ -810,7 +814,7 @@ int tpm_do_selftest(struct tpm_chip *chip) + /* Attempt to read a PCR value */ + cmd.header.in = pcrread_header; + cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0); +- rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE); ++ rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE, 0); + /* Some buggy TPMs will not respond to tpm_tis_ready() for + * around 300ms while the self test is ongoing, keep trying + * until the self test duration expires. */ +@@ -851,7 +855,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen) + if (chip == NULL) + return -ENODEV; + +- rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd"); ++ rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd"); + + tpm_chip_put(chip); + return rc; +@@ -953,14 +957,15 @@ int tpm_pm_suspend(struct device *dev) + cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr); + memcpy(cmd.params.pcrextend_in.hash, dummy_hash, + TPM_DIGEST_SIZE); +- rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, ++ rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0, + "extending dummy pcr before suspend"); + } + + /* now do the actual savestate */ + for (try = 0; try < TPM_RETRY; try++) { + cmd.header.in = savestate_header; +- rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL); ++ rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0, ++ NULL); + + /* + * If the TPM indicates that it is too busy to respond to +@@ -1044,8 +1049,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) + tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); + + err = tpm_transmit_cmd(chip, &tpm_cmd, +- TPM_GETRANDOM_RESULT_SIZE + num_bytes, +- "attempting get random"); ++ TPM_GETRANDOM_RESULT_SIZE + num_bytes, ++ 0, "attempting get random"); + if (err) + break; + +diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c +index ee66fd4..f880856 100644 +--- a/drivers/char/tpm/tpm-sysfs.c ++++ b/drivers/char/tpm/tpm-sysfs.c +@@ -39,7 +39,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, + struct tpm_chip *chip = dev_get_drvdata(dev); + + tpm_cmd.header.in = tpm_readpubek_header; +- err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, ++ err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 0, + "attempting to read the PUBEK"); + if (err) + goto out; +diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h +index 28b477e..f475b74 100644 +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -494,11 +494,15 @@ extern struct class *tpm_class; + extern dev_t tpm_devt; + extern const struct file_operations tpm_fops; + ++enum tpm_transmit_flags { ++ TPM_TRANSMIT_UNLOCKED = BIT(0), ++}; ++ ++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, ++ unsigned int flags); ++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, int len, ++ unsigned int flags, const char *desc); + ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); +-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, +- size_t bufsiz); +-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len, +- const char *desc); + extern int tpm_get_timeouts(struct tpm_chip *); + extern void tpm_gen_interrupt(struct tpm_chip *); + extern int tpm_do_selftest(struct tpm_chip *); +diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c +index ca2d238..19f14dc 100644 +--- a/drivers/char/tpm/tpm2-cmd.c ++++ b/drivers/char/tpm/tpm2-cmd.c +@@ -282,7 +282,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) + sizeof(cmd.params.pcrread_in.pcr_select)); + cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); + +- rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), ++ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, + "attempting to read a pcr value"); + if (rc == 0) { + buf = cmd.params.pcrread_out.digest; +@@ -330,7 +330,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash) + cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1); + memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE); + +- rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), ++ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, + "attempting extend a PCR value"); + + return rc; +@@ -376,7 +376,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max) + cmd.header.in = tpm2_getrandom_header; + cmd.params.getrandom_in.size = cpu_to_be16(num_bytes); + +- err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), ++ err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, + "attempting get random"); + if (err) + break; +@@ -434,12 +434,12 @@ static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle, + } + + /** +- * tpm2_seal_trusted() - seal a trusted key +- * @chip_num: A specific chip number for the request or TPM_ANY_NUM +- * @options: authentication values and other options ++ * tpm2_seal_trusted() - seal the payload of a trusted key ++ * @chip_num: TPM chip to use + * @payload: the key data in clear and encrypted form ++ * @options: authentication values and other options + * +- * Returns < 0 on error and 0 on success. ++ * Return: < 0 on error and 0 on success. + */ + int tpm2_seal_trusted(struct tpm_chip *chip, + struct trusted_key_payload *payload, +@@ -512,7 +512,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, + goto out; + } + +- rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "sealing data"); ++ rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0, "sealing data"); + if (rc) + goto out; + +@@ -538,10 +538,18 @@ int tpm2_seal_trusted(struct tpm_chip *chip, + return rc; + } + +-static int tpm2_load(struct tpm_chip *chip, +- struct trusted_key_payload *payload, +- struct trusted_key_options *options, +- u32 *blob_handle) ++/** ++ * tpm2_load_cmd() - execute a TPM2_Load command ++ * @chip_num: TPM chip to use ++ * @payload: the key data in clear and encrypted form ++ * @options: authentication values and other options ++ * ++ * Return: same as with tpm_transmit_cmd ++ */ ++static int tpm2_load_cmd(struct tpm_chip *chip, ++ struct trusted_key_payload *payload, ++ struct trusted_key_options *options, ++ u32 *blob_handle, unsigned int flags) + { + struct tpm_buf buf; + unsigned int private_len; +@@ -576,7 +584,7 @@ static int tpm2_load(struct tpm_chip *chip, + goto out; + } + +- rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "loading blob"); ++ rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "loading blob"); + if (!rc) + *blob_handle = be32_to_cpup( + (__be32 *) &buf.data[TPM_HEADER_SIZE]); +@@ -590,7 +598,16 @@ static int tpm2_load(struct tpm_chip *chip, + return rc; + } + +-static void tpm2_flush_context(struct tpm_chip *chip, u32 handle) ++/** ++ * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command ++ * @chip_num: TPM chip to use ++ * @payload: the key data in clear and encrypted form ++ * @options: authentication values and other options ++ * ++ * Return: same as with tpm_transmit_cmd ++ */ ++static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, ++ unsigned int flags) + { + struct tpm_buf buf; + int rc; +@@ -604,7 +621,8 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle) + + tpm_buf_append_u32(&buf, handle); + +- rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context"); ++ rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, ++ "flushing context"); + if (rc) + dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle, + rc); +@@ -612,10 +630,18 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle) + tpm_buf_destroy(&buf); + } + +-static int tpm2_unseal(struct tpm_chip *chip, +- struct trusted_key_payload *payload, +- struct trusted_key_options *options, +- u32 blob_handle) ++/** ++ * tpm2_unseal_cmd() - execute a TPM2_Unload command ++ * @chip_num: TPM chip to use ++ * @payload: the key data in clear and encrypted form ++ * @options: authentication values and other options ++ * ++ * Return: same as with tpm_transmit_cmd ++ */ ++static int tpm2_unseal_cmd(struct tpm_chip *chip, ++ struct trusted_key_payload *payload, ++ struct trusted_key_options *options, ++ u32 blob_handle, unsigned int flags) + { + struct tpm_buf buf; + u16 data_len; +@@ -635,7 +661,7 @@ static int tpm2_unseal(struct tpm_chip *chip, + options->blobauth /* hmac */, + TPM_DIGEST_SIZE); + +- rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "unsealing"); ++ rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "unsealing"); + if (rc > 0) + rc = -EPERM; + +@@ -654,12 +680,12 @@ static int tpm2_unseal(struct tpm_chip *chip, + } + + /** +- * tpm_unseal_trusted() - unseal a trusted key +- * @chip_num: A specific chip number for the request or TPM_ANY_NUM +- * @options: authentication values and other options ++ * tpm_unseal_trusted() - unseal the payload of a trusted key ++ * @chip_num: TPM chip to use + * @payload: the key data in clear and encrypted form ++ * @options: authentication values and other options + * +- * Returns < 0 on error and 0 on success. ++ * Return: < 0 on error and 0 on success. + */ + int tpm2_unseal_trusted(struct tpm_chip *chip, + struct trusted_key_payload *payload, +@@ -668,14 +694,17 @@ int tpm2_unseal_trusted(struct tpm_chip *chip, + u32 blob_handle; + int rc; + +- rc = tpm2_load(chip, payload, options, &blob_handle); ++ mutex_lock(&chip->tpm_mutex); ++ rc = tpm2_load_cmd(chip, payload, options, &blob_handle, ++ TPM_TRANSMIT_UNLOCKED); + if (rc) +- return rc; +- +- rc = tpm2_unseal(chip, payload, options, blob_handle); +- +- tpm2_flush_context(chip, blob_handle); ++ goto out; + ++ rc = tpm2_unseal_cmd(chip, payload, options, blob_handle, ++ TPM_TRANSMIT_UNLOCKED); ++ tpm2_flush_context_cmd(chip, blob_handle, TPM_TRANSMIT_UNLOCKED); ++out: ++ mutex_unlock(&chip->tpm_mutex); + return rc; + } + +@@ -701,7 +730,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value, + cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id); + cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1); + +- rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc); ++ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, desc); + if (!rc) + *value = be32_to_cpu(cmd.params.get_tpm_pt_out.value); + +@@ -735,7 +764,7 @@ int tpm2_startup(struct tpm_chip *chip, u16 startup_type) + cmd.header.in = tpm2_startup_header; + + cmd.params.startup_in.startup_type = cpu_to_be16(startup_type); +- return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), ++ return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, + "attempting to start the TPM"); + } + EXPORT_SYMBOL_GPL(tpm2_startup); +@@ -764,7 +793,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type) + cmd.header.in = tpm2_shutdown_header; + cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type); + +- rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM"); ++ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, "stopping the TPM"); + + /* In places where shutdown command is sent there's no much we can do + * except print the error code on a system failure. +@@ -830,7 +859,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full) + cmd.header.in = tpm2_selftest_header; + cmd.params.selftest_in.full_test = full; + +- rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, ++ rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, 0, + "continue selftest"); + + /* At least some prototype chips seem to give RC_TESTING error +@@ -882,7 +911,7 @@ int tpm2_do_selftest(struct tpm_chip *chip) + cmd.params.pcrread_in.pcr_select[1] = 0x00; + cmd.params.pcrread_in.pcr_select[2] = 0x00; + +- rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL); ++ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, NULL); + if (rc < 0) + break; + +@@ -931,7 +960,7 @@ int tpm2_probe(struct tpm_chip *chip) + cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100); + cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1); + +- rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd)); ++ rc = tpm_transmit(chip, (const u8 *)&cmd, sizeof(cmd), 0); + if (rc < 0) + return rc; + else if (rc < TPM_HEADER_SIZE) +diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c +index 0f7ec0d..ee300bd 100644 +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -142,6 +142,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) + struct crb_priv *priv = chip->vendor.priv; + int rc = 0; + ++ /* Zero the cancel register so that the next command will not get ++ * canceled. ++ */ ++ iowrite32(0, &priv->cca->cancel); ++ + if (len > ioread32(&priv->cca->cmd_size)) { + dev_err(&chip->dev, + "invalid command count value %x %zx\n", +@@ -175,8 +180,6 @@ static void crb_cancel(struct tpm_chip *chip) + + if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip)) + dev_err(&chip->dev, "ACPI Start failed\n"); +- +- iowrite32(0, &priv->cca->cancel); + } + + static bool crb_req_canceled(struct tpm_chip *chip, u8 status) +diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c +index e342565e..1855b9e 100644 +--- a/drivers/cpuidle/cpuidle-arm.c ++++ b/drivers/cpuidle/cpuidle-arm.c +@@ -135,6 +135,7 @@ static int __init arm_idle_init(void) + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + pr_err("Failed to allocate cpuidle device\n"); ++ ret = -ENOMEM; + goto out_fail; + } + dev->cpu = cpu; +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 1bcf601..26c084d 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1535,6 +1535,7 @@ config MFD_WM8350 + config MFD_WM8350_I2C + bool "Wolfson Microelectronics WM8350 with I2C" + select MFD_WM8350 ++ select REGMAP_I2C + depends on I2C=y + help + The WM8350 is an integrated audio and power management +diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c +index eca7ea6..4b15b08 100644 +--- a/drivers/mfd/atmel-hlcdc.c ++++ b/drivers/mfd/atmel-hlcdc.c +@@ -50,8 +50,9 @@ static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg, + if (reg <= ATMEL_HLCDC_DIS) { + u32 status; + +- readl_poll_timeout(hregmap->regs + ATMEL_HLCDC_SR, status, +- !(status & ATMEL_HLCDC_SIP), 1, 100); ++ readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR, ++ status, !(status & ATMEL_HLCDC_SIP), ++ 1, 100); + } + + writel(val, hregmap->regs + reg); +diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c +index dbd907d..691dab7 100644 +--- a/drivers/mfd/rtsx_usb.c ++++ b/drivers/mfd/rtsx_usb.c +@@ -46,9 +46,6 @@ static void rtsx_usb_sg_timed_out(unsigned long data) + + dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__); + usb_sg_cancel(&ucr->current_sg); +- +- /* we know the cancellation is caused by time-out */ +- ucr->current_sg.status = -ETIMEDOUT; + } + + static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, +@@ -67,12 +64,15 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, + ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); + add_timer(&ucr->sg_timer); + usb_sg_wait(&ucr->current_sg); +- del_timer_sync(&ucr->sg_timer); ++ if (!del_timer_sync(&ucr->sg_timer)) ++ ret = -ETIMEDOUT; ++ else ++ ret = ucr->current_sg.status; + + if (act_len) + *act_len = ucr->current_sg.bytes; + +- return ucr->current_sg.status; ++ return ret; + } + + int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe, +diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c +index cdc7723..bec6c22 100644 +--- a/drivers/misc/cxl/vphb.c ++++ b/drivers/misc/cxl/vphb.c +@@ -243,6 +243,11 @@ int cxl_pci_vphb_add(struct cxl_afu *afu) + if (phb->bus == NULL) + return -ENXIO; + ++ /* Set release hook on root bus */ ++ pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge), ++ pcibios_free_controller_deferred, ++ (void *) phb); ++ + /* Claim resources. This might need some rework as well depending + * whether we are doing probe-only or not, like assigning unassigned + * resources etc... +@@ -269,7 +274,10 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu) + afu->phb = NULL; + + pci_remove_root_bus(phb->bus); +- pcibios_free_controller(phb); ++ /* ++ * We don't free phb here - that's handled by ++ * pcibios_free_controller_deferred() ++ */ + } + + bool cxl_pci_is_vphb_device(struct pci_dev *dev) +diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c +index 5f4a2e0..add6623 100644 +--- a/drivers/pci/host-bridge.c ++++ b/drivers/pci/host-bridge.c +@@ -44,6 +44,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, + bridge->release_fn = release_fn; + bridge->release_data = release_data; + } ++EXPORT_SYMBOL_GPL(pci_set_host_bridge_release); + + void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, + struct resource *res) +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 05a5300..b16813c 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -363,7 +363,8 @@ static int dwc3_send_clear_stall_ep_cmd(struct dwc3_ep *dep) + * IN transfers due to a mishandled error condition. Synopsys + * STAR 9000614252. + */ +- if (dep->direction && (dwc->revision >= DWC3_REVISION_260A)) ++ if (dep->direction && (dwc->revision >= DWC3_REVISION_260A) && ++ (dwc->gadget.speed >= USB_SPEED_SUPER)) + cmd |= DWC3_DEPCMD_CLEARPENDIN; + + memset(¶ms, 0, sizeof(params)); +diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h +index d409ceb..c118a7e 100644 +--- a/include/linux/mfd/88pm80x.h ++++ b/include/linux/mfd/88pm80x.h +@@ -350,7 +350,7 @@ static inline int pm80x_dev_suspend(struct device *dev) + int irq = platform_get_irq(pdev, 0); + + if (device_may_wakeup(dev)) +- set_bit((1 << irq), &chip->wu_flag); ++ set_bit(irq, &chip->wu_flag); + + return 0; + } +@@ -362,7 +362,7 @@ static inline int pm80x_dev_resume(struct device *dev) + int irq = platform_get_irq(pdev, 0); + + if (device_may_wakeup(dev)) +- clear_bit((1 << irq), &chip->wu_flag); ++ clear_bit(irq, &chip->wu_flag); + + return 0; + } +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index b6c3945..1b72b17 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -403,8 +403,11 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) + tkr = tkf->base + (seq & 0x01); + now = ktime_to_ns(tkr->base); + +- now += clocksource_delta(tkr->read(tkr->clock), +- tkr->cycle_last, tkr->mask); ++ now += timekeeping_delta_to_ns(tkr, ++ clocksource_delta( ++ tkr->read(tkr->clock), ++ tkr->cycle_last, ++ tkr->mask)); + } while (read_seqcount_retry(&tkf->seq, seq)); + + return now; +diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c +index 1bcbc12..b5b932c 100644 +--- a/security/integrity/ima/ima_appraise.c ++++ b/security/integrity/ima/ima_appraise.c +@@ -190,7 +190,7 @@ int ima_appraise_measurement(enum ima_hooks func, + { + static const char op[] = "appraise_data"; + char *cause = "unknown"; +- struct dentry *dentry = file->f_path.dentry; ++ struct dentry *dentry = file_dentry(file); + struct inode *inode = d_backing_inode(dentry); + enum integrity_status status = INTEGRITY_UNKNOWN; + int rc = xattr_len, hash_start = 0; +@@ -295,7 +295,7 @@ int ima_appraise_measurement(enum ima_hooks func, + */ + void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) + { +- struct dentry *dentry = file->f_path.dentry; ++ struct dentry *dentry = file_dentry(file); + int rc = 0; + + /* do not collect and update hash for digital signatures */ +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index 68b26c3..60ac3ae 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -222,7 +222,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size, + if ((action & IMA_APPRAISE_SUBMASK) || + strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) + /* read 'security.ima' */ +- xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value); ++ xattr_len = ima_read_xattr(file_dentry(file), &xattr_value); + + hash_algo = ima_get_hash_algo(xattr_value, xattr_len); + +diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c +index 36470af..92b819e 100644 +--- a/sound/pci/ali5451/ali5451.c ++++ b/sound/pci/ali5451/ali5451.c +@@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream) + spin_unlock(&codec->reg_lock); + dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); + ++ cso %= runtime->buffer_size; + return cso; + } + +@@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) + cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); + spin_unlock(&codec->reg_lock); + ++ cso %= runtime->buffer_size; + return cso; + } + +diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c +index 81b7da8..183311c 100644 +--- a/sound/usb/line6/driver.c ++++ b/sound/usb/line6/driver.c +@@ -29,7 +29,7 @@ + /* + This is Line 6's MIDI manufacturer ID. + */ +-const unsigned char line6_midi_id[] = { ++const unsigned char line6_midi_id[3] = { + 0x00, 0x01, 0x0c + }; + EXPORT_SYMBOL_GPL(line6_midi_id); +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index f6c3bf7..04991b0 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, + } + + static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, ++ struct usb_mixer_elem_info *cval, + struct snd_kcontrol *kctl) + { + /* Approximation using 10 ranges based on output measurement on hw v1.2. +@@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, + 41, 50, TLV_DB_MINMAX_ITEM(-441, 0), + ); + +- usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n"); +- kctl->tlv.p = scale; +- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; +- kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; ++ if (cval->min == 0 && cval->max == 50) { ++ usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n"); ++ kctl->tlv.p = scale; ++ kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; ++ kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; ++ ++ } else if (cval->min == 0 && cval->max <= 1000) { ++ /* Some other clearly broken DragonFly variant. ++ * At least a 0..53 variant (hw v1.0) exists. ++ */ ++ usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device"); ++ kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; ++ } + } + + void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, +@@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, + { + switch (mixer->chip->usb_id) { + case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ +- if (unitid == 7 && cval->min == 0 && cval->max == 50) +- snd_dragonfly_quirk_db_scale(mixer, kctl); ++ if (unitid == 7 && cval->control == UAC_FU_VOLUME) ++ snd_dragonfly_quirk_db_scale(mixer, cval, kctl); + break; + } + } +diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c +index a027569..6e9c40e 100644 +--- a/virt/kvm/arm/pmu.c ++++ b/virt/kvm/arm/pmu.c +@@ -423,6 +423,14 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) + if (!kvm_arm_support_pmu_v3()) + return -ENODEV; + ++ /* ++ * We currently require an in-kernel VGIC to use the PMU emulation, ++ * because we do not support forwarding PMU overflow interrupts to ++ * userspace yet. ++ */ ++ if (!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm)) ++ return -ENODEV; ++ + if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features) || + !kvm_arm_pmu_irq_initialized(vcpu)) + return -ENXIO; +diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c +index 69b61ab..7ea7911 100644 +--- a/virt/kvm/arm/vgic/vgic.c ++++ b/virt/kvm/arm/vgic/vgic.c +@@ -553,6 +553,9 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) + /* Sync back the hardware VGIC state into our emulation after a guest's run. */ + void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) + { ++ if (unlikely(!vgic_initialized(vcpu->kvm))) ++ return; ++ + vgic_process_maintenance_interrupt(vcpu); + vgic_fold_lr_state(vcpu); + vgic_prune_ap_list(vcpu); +@@ -561,6 +564,9 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) + /* Flush our emulation state into the GIC hardware before entering the guest. */ + void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) + { ++ if (unlikely(!vgic_initialized(vcpu->kvm))) ++ return; ++ + spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock); + vgic_flush_lr_state(vcpu); + spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock); |