Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Conflicts:

drivers/net/ethernet/microsoft/mana/mana_en.c:
  17bfe0a8c0 ("net: mana: Add NULL guards in teardown path to prevent panic on attach failure")
  d07efe5a6e ("net: mana: Use per-queue allocation for tx_qp to reduce allocation size")

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni
2026-06-01 13:35:51 +02:00
90 changed files with 799 additions and 418 deletions

View File

@@ -1158,8 +1158,9 @@ F: Documentation/arch/x86/amd-hfi.rst
F: drivers/platform/x86/amd/hfi/
AMD IOMMU (AMD-VI)
M: Joerg Roedel <joro@8bytes.org>
M: Joerg Roedel (AMD) <joro@8bytes.org>
R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
R: Vasant Hegde <vasant.hegde@amd.com>
L: iommu@lists.linux.dev
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
@@ -13491,7 +13492,7 @@ F: include/linux/iommu-dma.h
F: include/linux/iova.h
IOMMU SUBSYSTEM
M: Joerg Roedel <joro@8bytes.org>
M: Joerg Roedel (AMD) <joro@8bytes.org>
M: Will Deacon <will@kernel.org>
R: Robin Murphy <robin.murphy@arm.com>
L: iommu@lists.linux.dev

View File

@@ -511,7 +511,6 @@ enum vcpu_sysreg {
ACTLR_EL2, /* Auxiliary Control Register (EL2) */
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
HACR_EL2, /* Hypervisor Auxiliary Control Register */
ZCR_EL2, /* SVE Control Register (EL2) */
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
TCR_EL2, /* Translation Control Register (EL2) */
@@ -543,6 +542,7 @@ enum vcpu_sysreg {
SCTLR2_EL2, /* System Control Register 2 (EL2) */
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
ZCR_EL2, /* SVE Control Register (EL2) */
/* Any VNCR-capable reg goes after this point */
MARKER(__VNCR_START__),

View File

@@ -462,11 +462,13 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
{
u64 zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
/*
* The vCPU's saved SVE state layout always matches the max VL of the
* vCPU. Start off with the max VL so we can load the SVE state.
*/
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
__sve_restore_state(vcpu_sve_pffr(vcpu),
&vcpu->arch.ctxt.fp_regs.fpsr,
true);
@@ -476,8 +478,10 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
* nested guest, as the guest hypervisor could select a smaller VL. Slap
* that into hardware before wrapping up.
*/
if (is_nested_ctxt(vcpu))
sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
if (is_nested_ctxt(vcpu)) {
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
}
write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
}
@@ -501,11 +505,11 @@ static inline void fpsimd_lazy_switch_to_guest(struct kvm_vcpu *vcpu)
return;
if (vcpu_has_sve(vcpu)) {
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
/* A guest hypervisor may restrict the effective max VL. */
if (is_nested_ctxt(vcpu))
zcr_el2 = __vcpu_sys_reg(vcpu, ZCR_EL2);
else
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
write_sysreg_el2(zcr_el2, SYS_ZCR);

View File

@@ -120,7 +120,7 @@ SYM_FUNC_START(__hyp_do_panic)
mov x29, x0
#ifdef PKVM_DISABLE_STAGE2_ON_PANIC
#ifdef CONFIG_PKVM_DISABLE_STAGE2_ON_PANIC
/* Ensure host stage-2 is disabled */
mrs x0, hcr_el2
bic x0, x0, #HCR_VM

View File

@@ -189,7 +189,7 @@ static void hyp_trace_buffer_unshare_hyp(struct hyp_trace_buffer *trace_buffer,
if (cpu > last_cpu)
break;
__share_page(rb_desc->meta_va);
__unshare_page(rb_desc->meta_va);
for (p = 0; p < rb_desc->nr_page_va; p++)
__unshare_page(rb_desc->page_va[p]);
}
@@ -212,14 +212,15 @@ static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffer)
}
if (ret) {
for (p--; p >= 0; p--)
while (--p >= 0)
__unshare_page(rb_desc->page_va[p]);
__unshare_page(rb_desc->meta_va);
break;
}
}
if (ret)
hyp_trace_buffer_unshare_hyp(trace_buffer, cpu--);
hyp_trace_buffer_unshare_hyp(trace_buffer, --cpu);
return ret;
}
@@ -248,6 +249,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
goto err_free_desc;
trace_buffer->desc = desc;
trace_buffer->desc_size = desc_size;
ret = hyp_trace_buffer_alloc_bpages_backing(trace_buffer, size);
if (ret)
@@ -297,6 +299,7 @@ static void hyp_trace_unload(struct trace_buffer_desc *desc, void *priv)
hyp_trace_buffer_free_bpages_backing(trace_buffer);
free_pages_exact(trace_buffer->desc, trace_buffer->desc_size);
trace_buffer->desc = NULL;
trace_buffer->desc_size = 0;
}
static int hyp_trace_enable_tracing(bool enable, void *priv)

View File

@@ -1834,6 +1834,11 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
resx.res1 = VNCR_EL2_RES1;
set_sysreg_masks(kvm, VNCR_EL2, resx);
/* ZCR_EL2 - bits 8:4 are RAZ/WI so treat them as RES0 */
resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4);
resx.res1 = ZCR_ELx_RES1;
set_sysreg_masks(kvm, ZCR_EL2, resx);
out:
for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++)
__vcpu_rmw_sys_reg(vcpu, sr, |=, 0);

View File

@@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct kvm_pmc *pmc, u64 val, bool force)
* action is to use PMCR.P, which will reset them to
* 0 (the only use of the 'force' parameter).
*/
val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32);
val |= lower_32_bits(val);
val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) |
lower_32_bits(val);
}
__vcpu_assign_sys_reg(vcpu, reg, val);

View File

@@ -2862,21 +2862,16 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
unsigned int vq;
if (guest_hyp_sve_traps_enabled(vcpu)) {
kvm_inject_nested_sve_trap(vcpu);
return false;
}
if (!p->is_write) {
if (!p->is_write)
p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2);
return true;
}
else
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, p->regval);
vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
vq = min(vq, vcpu_sve_max_vq(vcpu));
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1);
return true;
}

View File

@@ -32,6 +32,10 @@ asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
__diag_push(); \
__diag_ignore(GCC, 8, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments"); \
__diag_ignore(clang, 23, "-Wunknown-warning-option", \
"Avoid breaking versions without -Wattribute-alias"); \
__diag_ignore(clang, 23, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments"); \
static long __se_##prefix##name(ulong, ulong, ulong, ulong, ulong, ulong, \
ulong) \
__attribute__((alias(__stringify(___se_##prefix##name)))); \

View File

@@ -1504,6 +1504,7 @@ struct kvm_arch {
bool use_master_clock;
u64 master_kernel_ns;
u64 master_cycle_now;
struct ratelimit_state kvmclock_update_rs;
#ifdef CONFIG_KVM_HYPERV
struct kvm_hv hyperv;

View File

@@ -206,6 +206,35 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
svm_clr_intercept(svm, INTERCEPT_CR8_WRITE);
/*
* Flush the TLB when enabling (x2)AVIC and when transitioning between
* xAVIC and x2AVIC, as the CPU may have inserted a TLB entry for the
* "wrong" mapping.
*
* KVM uses a per-VM "scratch" page to back the APIC memslot, because
* KVM also uses per-VM page tables *and* maintains the page table (NPT
* or shadow page) mappings for said memslot even if one or more vCPUs
* have their local APIC hardware-disabled or are in x2APIC mode, i.e.
* even if one or more vCPUs' APIC MMIO BAR is effectively disabled.
*
* If xAVIC is fully enabled, hardware ignores the physical address in
* KVM's page tables, i.e. in the leaf SPTE for the APIC memslot, and
* instead redirects the access to the AVIC backing page, i.e. to the
* vCPU's virtual APIC page. If xAVIC is not enabled (APIC is either
* hardware-disabled or in x2APIC mode), then guest accesses will use
* the page table mapping verbatim, i.e. will access the per-VM scratch
* page, as normal memory.
*
* In both cases, the CPU is allowed to cache TLB entries for the APIC
* base GPA. So, KVM needs to flush the TLB when enabling xAVIC, as
* accesses need to be redirected to the virtual APIC page, but the TLB
* may contain entries pointing at the scratch page. KVM also needs to
* flush the TLB when enabling x2AVIC, as accesses need to go to the
* scratch page, but the TLB may contain entries tagged as xAVIC, i.e.
* entries pointing to the vCPU's virtual APIC page.
*/
kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu);
/*
* Note: KVM supports hybrid-AVIC mode, where KVM emulates x2APIC MSR
* accesses, while interrupt injection to a running vCPU can be
@@ -219,12 +248,6 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
/* Disabling MSR intercept for x2APIC registers */
avic_set_x2apic_msr_interception(svm, false);
} else {
/*
* Flush the TLB, the guest may have inserted a non-APIC
* mapping into the TLB while AVIC was disabled.
*/
kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu);
/* Enabling MSR intercept for x2APIC registers */
avic_set_x2apic_msr_interception(svm, true);
}

View File

@@ -3662,23 +3662,26 @@ int pre_sev_run(struct vcpu_svm *svm, int cpu)
}
#define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE)
static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 min_len)
{
struct vmcb_control_area *control = &svm->vmcb->control;
u64 ghcb_scratch_beg, ghcb_scratch_end;
u64 scratch_gpa_beg, scratch_gpa_end;
void *scratch_va;
if (WARN_ON_ONCE(!min_len))
goto e_scratch;
scratch_gpa_beg = svm->sev_es.sw_scratch;
if (!scratch_gpa_beg) {
pr_err("vmgexit: scratch gpa not provided\n");
goto e_scratch;
}
scratch_gpa_end = scratch_gpa_beg + len;
scratch_gpa_end = scratch_gpa_beg + min_len;
if (scratch_gpa_end < scratch_gpa_beg) {
pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
len, scratch_gpa_beg);
min_len, scratch_gpa_beg);
goto e_scratch;
}
@@ -3702,21 +3705,27 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
scratch_va = (void *)svm->sev_es.ghcb;
scratch_va += (scratch_gpa_beg - control->ghcb_gpa);
svm->sev_es.ghcb_sa_len = ghcb_scratch_end - scratch_gpa_beg;
} else {
/* GHCB v2 requires the scratch area to be within the GHCB. */
if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
goto e_scratch;
/*
* The guest memory must be read into a kernel buffer, so
* limit the size
*/
if (len > GHCB_SCRATCH_AREA_LIMIT) {
if (min_len > GHCB_SCRATCH_AREA_LIMIT) {
pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
len, GHCB_SCRATCH_AREA_LIMIT);
min_len, GHCB_SCRATCH_AREA_LIMIT);
goto e_scratch;
}
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);
scratch_va = kvzalloc(min_len, GFP_KERNEL_ACCOUNT);
if (!scratch_va)
return -ENOMEM;
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, min_len)) {
/* Unable to copy scratch area from guest */
pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
@@ -3732,11 +3741,10 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
*/
svm->sev_es.ghcb_sa_sync = sync;
svm->sev_es.ghcb_sa_free = true;
svm->sev_es.ghcb_sa_len = min_len;
}
svm->sev_es.ghcb_sa = scratch_va;
svm->sev_es.ghcb_sa_len = len;
return 0;
e_scratch:
@@ -3833,7 +3841,7 @@ struct psc_buffer {
struct psc_entry entries[];
} __packed;
static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc);
static int snp_begin_psc(struct vcpu_svm *svm);
static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
{
@@ -3864,9 +3872,9 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
*/
for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
svm->sev_es.psc_inflight--, idx++) {
struct psc_entry *entry = &entries[idx];
struct psc_entry entry = READ_ONCE(entries[idx]);
entry->cur_page = entry->pagesize ? 512 : 1;
entries[idx].cur_page = entry.pagesize ? 512 : 1;
}
hdr->cur_entry = idx;
@@ -3875,7 +3883,6 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct psc_buffer *psc = svm->sev_es.ghcb_sa;
if (vcpu->run->hypercall.ret) {
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
@@ -3885,16 +3892,18 @@ static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
__snp_complete_one_psc(svm);
/* Handle the next range (if any). */
return snp_begin_psc(svm, psc);
return snp_begin_psc(svm);
}
static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
static int snp_begin_psc(struct vcpu_svm *svm)
{
struct vcpu_sev_es_state *sev_es = &svm->sev_es;
struct psc_buffer *psc = sev_es->ghcb_sa;
struct psc_entry *entries = psc->entries;
struct kvm_vcpu *vcpu = &svm->vcpu;
struct psc_hdr *hdr = &psc->hdr;
struct psc_entry entry_start;
u16 idx, idx_start, idx_end;
u16 idx, idx_start, idx_end, max_nr_entries;
int npages;
bool huge;
u64 gfn;
@@ -3904,6 +3913,19 @@ static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
return 1;
}
/*
* GHCB v2 requires the scratch area to reside within the GHCB itself,
* and PSC requests are only supported for GHCB v2+. Thus it should be
* impossible to exceed the max PSC entry count (which is derived from
* the size of the shared GHCB buffer).
*/
max_nr_entries = (sev_es->ghcb_sa_len - sizeof(struct psc_hdr)) /
sizeof(struct psc_entry);
if (WARN_ON_ONCE(max_nr_entries > VMGEXIT_PSC_MAX_COUNT)) {
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
return 1;
}
next_range:
/* There should be no other PSCs in-flight at this point. */
if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) {
@@ -3916,17 +3938,17 @@ static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
* validation, so take care to only use validated copies of values used
* for things like array indexing.
*/
idx_start = hdr->cur_entry;
idx_end = hdr->end_entry;
idx_start = READ_ONCE(hdr->cur_entry);
idx_end = READ_ONCE(hdr->end_entry);
if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {
if (idx_end >= max_nr_entries) {
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
return 1;
}
/* Find the start of the next range which needs processing. */
for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
entry_start = entries[idx];
entry_start = READ_ONCE(entries[idx]);
gfn = entry_start.gfn;
huge = entry_start.pagesize;
@@ -3970,7 +3992,7 @@ static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
* KVM_HC_MAP_GPA_RANGE exit.
*/
while (++idx <= idx_end) {
struct psc_entry entry = entries[idx];
struct psc_entry entry = READ_ONCE(entries[idx]);
if (entry.operation != entry_start.operation ||
entry.gfn != entry_start.gfn + npages ||
@@ -4493,13 +4515,22 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
case SVM_VMGEXIT_MMIO_READ:
case SVM_VMGEXIT_MMIO_WRITE: {
bool is_write = control->exit_code == SVM_VMGEXIT_MMIO_WRITE;
u64 len = control->exit_info_2;
ret = setup_vmgexit_scratch(svm, !is_write, control->exit_info_2);
if (!len)
return 1;
if (to_kvm_sev_info(vcpu->kvm)->ghcb_version >= 2 && len > 8) {
svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_INPUT);
return 1;
}
ret = setup_vmgexit_scratch(svm, !is_write, len);
if (ret)
break;
ret = kvm_sev_es_mmio(vcpu, is_write, control->exit_info_1,
control->exit_info_2, svm->sev_es.ghcb_sa);
ret = kvm_sev_es_mmio(vcpu, is_write, control->exit_info_1, len,
svm->sev_es.ghcb_sa);
break;
}
case SVM_VMGEXIT_NMI_COMPLETE:
@@ -4546,11 +4577,11 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
vcpu->run->system_event.data[0] = control->ghcb_gpa;
break;
case SVM_VMGEXIT_PSC:
ret = setup_vmgexit_scratch(svm, true, control->exit_info_2);
ret = setup_vmgexit_scratch(svm, true, sizeof(struct psc_hdr));
if (ret)
break;
ret = snp_begin_psc(svm, svm->sev_es.ghcb_sa);
ret = snp_begin_psc(svm);
break;
case SVM_VMGEXIT_AP_CREATION:
ret = sev_snp_ap_creation(svm);
@@ -4572,6 +4603,11 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
control->exit_info_1, control->exit_info_2);
ret = -EINVAL;
break;
case SVM_EXIT_IOIO:
if (!((control->exit_info_1 & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT))
return 1;
fallthrough;
default:
ret = svm_invoke_exit_handler(vcpu, control->exit_code);
}
@@ -4592,6 +4628,9 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
if (unlikely(check_mul_overflow(count, size, &bytes)))
return -EINVAL;
if (!bytes)
return 1;
r = setup_vmgexit_scratch(svm, in, bytes);
if (r)
return r;

View File

@@ -5227,8 +5227,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
* On a host with synchronized TSC, there is no need to update
* kvmclock on vcpu->cpu migration
*/
if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1)
kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1) {
if (__ratelimit(&vcpu->kvm->arch.kvmclock_update_rs))
kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
else
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
}
if (vcpu->cpu != cpu)
kvm_make_request(KVM_REQ_MIGRATE_TIMER, vcpu);
vcpu->cpu = cpu;
@@ -13366,6 +13371,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
raw_spin_lock_init(&kvm->arch.tsc_write_lock);
mutex_init(&kvm->arch.apic_map_lock);
seqcount_raw_spinlock_init(&kvm->arch.pvclock_sc, &kvm->arch.tsc_write_lock);
ratelimit_state_init(&kvm->arch.kvmclock_update_rs, HZ, 10);
ratelimit_set_flags(&kvm->arch.kvmclock_update_rs, RATELIMIT_MSG_ON_RELEASE);
kvm->arch.kvmclock_offset = -get_kvmclock_base_ns();
raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
@@ -14323,7 +14330,7 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva)
* the RAP (Return Address Predicator).
*/
if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS))
kvm_register_is_dirty(vcpu, VCPU_EXREG_ERAPS);
kvm_register_mark_dirty(vcpu, VCPU_EXREG_ERAPS);
kvm_invalidate_pcid(vcpu, operand.pcid);
return kvm_skip_emulated_instruction(vcpu);

View File

@@ -49,7 +49,20 @@ static void x86_virt_invoke_kvm_emergency_callback(void)
{
cpu_emergency_virt_cb *kvm_callback;
kvm_callback = rcu_dereference(kvm_emergency_callback);
/*
* RCU may not be watching the crashing CPU here, so rcu_dereference()
* triggers a suspicious-RCU-usage splat. In principle, a concurrent
* KVM module unload could race with this read; see commit 2baa33a8ddd6
* ("KVM: x86: Leave user-return notifier registered on reboot/shutdown")
* which notes that nothing prevents module unload during panic/reboot.
*
* However, taking a lock here would be riskier than the current race:
* the system is going down via NMI shootdown, and any lock could be
* held by an already-stopped CPU. Use rcu_dereference_raw() to silence
* the lockdep splat and accept the comically small remaining race;
* panic context inherently cannot guarantee complete correctness.
*/
kvm_callback = rcu_dereference_raw(kvm_emergency_callback);
if (kvm_callback)
kvm_callback();
}

View File

@@ -3246,7 +3246,7 @@ void blk_mq_submit_bio(struct bio *bio)
if (!rq)
blk_queue_exit(q);
else
blk_mq_free_request(rq);
rq_list_add_head(&plug->cached_rqs, rq);
}
#ifdef CONFIG_BLK_MQ_STACKING

View File

@@ -78,18 +78,22 @@ ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
/*******************************************************************************
*
* FUNCTION: acpi_enable_gpe
* FUNCTION: acpi_enable_gpe_cond
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
* dispatch_type - GPE dispatch type to match
*
* RETURN: Status
*
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled.
* DESCRIPTION: Add a reference to a GPE so long as its dispatch type matches
* the supplied one, or it is different from ACPI_GPE_DISPATCH_NONE
* if the supplied one is ACPI_GPE_DISPATCH_MASK. On the first
* reference, the GPE is hardware-enabled.
*
******************************************************************************/
acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
acpi_status acpi_enable_gpe_cond(acpi_handle gpe_device, u32 gpe_number,
u8 dispatch_type)
{
acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info;
@@ -100,14 +104,18 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/*
* Ensure that we have a valid GPE number and that there is some way
* of handling the GPE (handler or a GPE method). In other words, we
* won't allow a valid GPE to be enabled if there is no way to handle it.
* Ensure that we have a valid GPE number and that the dispatch type of
* the GPE matches the supplied one (or it is not ACPI_GPE_DISPATCH_NONE
* if the supplied one is ACPI_GPE_DISPATCH_MASK).
*/
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) {
if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_NONE) {
if (dispatch_type == ACPI_GPE_DISPATCH_MASK)
dispatch_type = ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags);
else if (dispatch_type != ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags))
dispatch_type = ACPI_GPE_DISPATCH_NONE;
if (dispatch_type != ACPI_GPE_DISPATCH_NONE) {
status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE);
if (ACPI_SUCCESS(status) &&
ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
@@ -128,6 +136,30 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_enable_gpe_cond)
/*******************************************************************************
*
* FUNCTION: acpi_enable_gpe
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
*
* RETURN: Status
*
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled.
*
******************************************************************************/
acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
{
/*
* Ensure that there is some way of handling the GPE (handler or a GPE
* method). In other words, we won't allow a valid GPE to be enabled if
* there is no way to handle it.
*/
return acpi_enable_gpe_cond(gpe_device, gpe_number, ACPI_GPE_DISPATCH_MASK);
}
ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
/*******************************************************************************

View File

@@ -179,6 +179,7 @@ struct acpi_button {
ktime_t last_time;
bool suspended;
bool lid_state_initialized;
bool gpe_enabled;
};
static struct acpi_device *lid_device;
@@ -646,6 +647,21 @@ static int acpi_button_probe(struct platform_device *pdev)
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY, handler,
button);
if (ACPI_SUCCESS(status) && device->wakeup.flags.valid) {
acpi_status st;
/*
* If the wakeup GPE has a handler method, enable it in
* case it is also used for signaling runtime events.
*/
st = acpi_enable_gpe_cond(device->wakeup.gpe_device,
device->wakeup.gpe_number,
ACPI_GPE_DISPATCH_METHOD);
button->gpe_enabled = ACPI_SUCCESS(st);
if (button->gpe_enabled)
dev_dbg(button->dev, "Enabled ACPI GPE%02llx\n",
device->wakeup.gpe_number);
}
break;
}
if (ACPI_FAILURE(status)) {
@@ -671,6 +687,7 @@ static int acpi_button_probe(struct platform_device *pdev)
acpi_button_remove_fs(button);
err_free_button:
kfree(button);
memset(acpi_device_class(device), 0, sizeof(acpi_device_class));
return error;
}
@@ -689,7 +706,13 @@ static void acpi_button_remove(struct platform_device *pdev)
acpi_button_event);
break;
default:
acpi_remove_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
if (button->gpe_enabled) {
dev_dbg(button->dev, "Disabling ACPI GPE%02llx\n",
adev->wakeup.gpe_number);
acpi_disable_gpe(adev->wakeup.gpe_device,
adev->wakeup.gpe_number);
}
acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY,
button->type == ACPI_BUTTON_TYPE_LID ?
acpi_lid_notify :
acpi_button_notify);

View File

@@ -3540,7 +3540,13 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev,
"firmware rome 0x%x build 0x%x",
rver_rom, rver_patch, ver_rom, ver_patch);
if (rver_rom != ver_rom || rver_patch <= ver_patch) {
/* Allow rampatch when the patch version equals the firmware version.
* A firmware download may be aborted by a transient USB error (e.g.
* disconnect) after the controller updates version info but before
* completion.
* Allowing equal versions enables re-flashing during recovery.
*/
if (rver_rom != ver_rom || rver_patch < ver_patch) {
bt_dev_err(hdev, "rampatch file version did not match with firmware");
err = -EINVAL;
goto done;

View File

@@ -1680,8 +1680,8 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
mod_timer(&qca->tx_idle_timer, jiffies +
msecs_to_jiffies(qca->tx_idle_delay));
/* Controller reset completion time is 50ms */
msleep(50);
/* Wait for the controller to load the rampatch and NVM. */
msleep(100);
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
clear_bit(QCA_IBS_DISABLED, &qca->flags);

View File

@@ -302,12 +302,6 @@ static int amd_pstate_ut_epp(u32 index)
cpufreq_cpu_put(policy);
policy = NULL;
/* disable dynamic EPP before running test */
if (cpudata->dynamic_epp) {
pr_debug("Dynamic EPP is enabled, disabling it\n");
amd_pstate_clear_dynamic_epp(policy);
}
buf = (char *)__get_free_page(GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -327,6 +321,16 @@ static int amd_pstate_ut_epp(u32 index)
orig_policy = cpudata->policy;
cpudata->policy = CPUFREQ_POLICY_POWERSAVE;
/*
* Disable dynamic EPP before running test. If "orig_dynamic_epp" is
* true, the driver will do a redundant switch at the end and there
* is no need for enabling it again at the end of the test.
*/
if (cpudata->dynamic_epp) {
pr_debug("Dynamic EPP is enabled, disabling it\n");
amd_pstate_clear_dynamic_epp(policy);
}
for (epp = 0; epp <= U8_MAX; epp++) {
u8 val;

View File

@@ -1284,6 +1284,7 @@
#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
#define USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE 0x0034
#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD2 0x0059
#define USB_VENDOR_ID_SIGMATEL 0x066F

View File

@@ -382,11 +382,9 @@ static int get_endpoint_address(struct hid_device *hdev)
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
struct usb_host_endpoint *ep;
if (intf) {
ep = intf->cur_altsetting->endpoint;
if (ep)
return ep->desc.bEndpointAddress;
}
ep = intf->cur_altsetting->endpoint;
if (ep)
return ep->desc.bEndpointAddress;
return -ENODEV;
}
@@ -1461,6 +1459,9 @@ static int hid_gos_probe(struct hid_device *hdev,
{
int ret, ep;
if (!hid_is_usb(hdev))
return -EINVAL;
ret = hid_parse(hdev);
if (ret) {
hid_err(hdev, "Parse failed\n");

View File

@@ -641,9 +641,6 @@ static int get_endpoint_address(struct hid_device *hdev)
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
struct usb_host_endpoint *ep;
if (!intf)
return -ENODEV;
ep = intf->cur_altsetting->endpoint;
if (!ep)
return -ENODEV;
@@ -2419,6 +2416,9 @@ static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret, ep;
if (!hid_is_usb(hdev))
return -EINVAL;
hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT;
ret = hid_parse(hdev);

View File

@@ -30,6 +30,7 @@
#include <linux/hid.h>
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/unaligned.h>
#include <linux/workqueue.h>
#include "hid-ids.h"
@@ -793,8 +794,8 @@ static int lenovo_raw_event(struct hid_device *hdev,
*/
if (unlikely((hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB
|| hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB2)
&& size >= 3 && report->id == 0x03))
return lenovo_raw_event_TP_X12_tab(hdev, le32_to_cpu(*(__le32 *)data));
&& size >= 4 && report->id == 0x03))
return lenovo_raw_event_TP_X12_tab(hdev, get_unaligned_le32(data));
return 0;
}

View File

@@ -187,6 +187,7 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH), HID_QUIRK_NOGET },

View File

@@ -341,29 +341,33 @@ static int u2fzero_probe(struct hid_device *hdev,
if (ret)
return ret;
u2fzero_fill_in_urb(dev);
ret = u2fzero_fill_in_urb(dev);
if (ret)
goto err_hid_hw_stop;
dev->present = true;
minor = ((struct hidraw *) hdev->hidraw)->minor;
ret = u2fzero_init_led(dev, minor);
if (ret) {
hid_hw_stop(hdev);
return ret;
}
if (ret)
goto err_free_urb;
hid_info(hdev, "%s LED initialised\n", hw_configs[dev->hw_revision].name);
ret = u2fzero_init_hwrng(dev, minor);
if (ret) {
hid_hw_stop(hdev);
return ret;
}
if (ret)
goto err_free_urb;
hid_info(hdev, "%s RNG initialised\n", hw_configs[dev->hw_revision].name);
return 0;
err_free_urb:
usb_free_urb(dev->urb);
err_hid_hw_stop:
hid_hw_stop(hdev);
return ret;
}
static void u2fzero_remove(struct hid_device *hdev)

View File

@@ -356,6 +356,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
hid_data->inputmode = field->report->id;
hid_data->inputmode_index = usage->usage_index;
hid_data->inputmode_field_index = field->index;
break;
case HID_UP_DIGITIZER:
@@ -571,9 +572,14 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev)
re = &(hdev->report_enum[HID_FEATURE_REPORT]);
r = re->report_id_hash[hid_data->inputmode];
if (r) {
r->field[0]->value[hid_data->inputmode_index] = 2;
hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
if (r && hid_data->inputmode_field_index >= 0 &&
hid_data->inputmode_field_index < r->maxfield) {
struct hid_field *field = r->field[hid_data->inputmode_field_index];
if (field && hid_data->inputmode_index < field->report_count) {
field->value[hid_data->inputmode_index] = 2;
hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
}
}
return 0;
}
@@ -2846,6 +2852,7 @@ static int wacom_probe(struct hid_device *hdev,
return -ENODEV;
wacom_wac->hid_data.inputmode = -1;
wacom_wac->hid_data.inputmode_field_index = -1;
wacom_wac->mode_report = -1;
if (hid_is_usb(hdev)) {

View File

@@ -295,6 +295,7 @@ struct wacom_shared {
struct hid_data {
__s16 inputmode; /* InputMode HID feature, -1 if non-existent */
__s16 inputmode_index; /* InputMode HID feature index in the report */
__s16 inputmode_field_index; /* InputMode HID feature field index in the report */
bool sense_state;
bool inrange_state;
bool eraser;

View File

@@ -254,37 +254,29 @@ void cache_tag_unassign_domain(struct dmar_domain *domain,
}
static unsigned long calculate_psi_aligned_address(unsigned long start,
unsigned long end,
unsigned long *_mask)
unsigned long last,
unsigned long *size_order)
{
unsigned long pages = aligned_nrpages(start, end - start + 1);
unsigned long aligned_pages = __roundup_pow_of_two(pages);
unsigned long bitmask = aligned_pages - 1;
unsigned long mask = ilog2(aligned_pages);
unsigned long pfn = IOVA_PFN(start);
/*
* PSI masks the low order bits of the base address. If the
* address isn't aligned to the mask, then compute a mask value
* needed to ensure the target range is flushed.
*/
if (unlikely(bitmask & pfn)) {
unsigned long end_pfn = pfn + pages - 1, shared_bits;
unsigned int sz_lg2;
/* Compute a sz_lg2 that spans start and last */
start &= GENMASK(BITS_PER_LONG - 1, VTD_PAGE_SHIFT);
sz_lg2 = fls_long(start ^ last);
if (sz_lg2 <= 12) {
*size_order = 0;
return start;
}
if (unlikely(sz_lg2 >= BITS_PER_LONG)) {
/*
* Since end_pfn <= pfn + bitmask, the only way bits
* higher than bitmask can differ in pfn and end_pfn is
* by carrying. This means after masking out bitmask,
* high bits starting with the first set bit in
* shared_bits are all equal in both pfn and end_pfn.
* MAX_AGAW_PFN_WIDTH triggers full invalidation in all
* downstream users.
*/
shared_bits = ~(pfn ^ end_pfn) & ~bitmask;
mask = shared_bits ? __ffs(shared_bits) : MAX_AGAW_PFN_WIDTH;
*size_order = MAX_AGAW_PFN_WIDTH;
return 0;
}
*_mask = mask;
return ALIGN_DOWN(start, VTD_PAGE_SIZE << mask);
*size_order = sz_lg2 - VTD_PAGE_SHIFT;
return start & GENMASK(BITS_PER_LONG - 1, sz_lg2);
}
static void qi_batch_flush_descs(struct intel_iommu *iommu, struct qi_batch *batch)
@@ -441,12 +433,7 @@ void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
struct cache_tag *tag;
unsigned long flags;
if (start == 0 && end == ULONG_MAX) {
addr = 0;
mask = MAX_AGAW_PFN_WIDTH;
} else {
addr = calculate_psi_aligned_address(start, end, &mask);
}
addr = calculate_psi_aligned_address(start, end, &mask);
spin_lock_irqsave(&domain->cache_lock, flags);
list_for_each_entry(tag, &domain->cache_tags, node) {

View File

@@ -777,21 +777,27 @@ struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
static struct io_pgtable_cfg *cfg_cookie __initdata;
static void __init dummy_tlb_flush_all(void *cookie)
/*
* __noipa prevents gcc from turning indirect iommu_flush_ops calls
* into direct calls from a specialized __arm_v7s_unmap() that triggers
* a build time section mismatch assertion.
*/
static __noipa void __init dummy_tlb_flush_all(void *cookie)
{
WARN_ON(cookie != cfg_cookie);
}
static void __init dummy_tlb_flush(unsigned long iova, size_t size,
size_t granule, void *cookie)
static __noipa void __init dummy_tlb_flush(unsigned long iova, size_t size,
size_t granule, void *cookie)
{
WARN_ON(cookie != cfg_cookie);
WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
}
static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
unsigned long iova, size_t granule,
void *cookie)
static __noipa void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
unsigned long iova,
size_t granule,
void *cookie)
{
dummy_tlb_flush(iova, granule, granule, cookie);
}

View File

@@ -1741,6 +1741,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
struct mana_rxq *rxq;
int err;
if (!apc->rxqs)
return;
for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
rxq = apc->rxqs[rxq_idx];
err = mana_fence_rq(apc, rxq);
@@ -2883,13 +2886,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
struct mana_rxq *rxq;
u32 rxq_idx;
for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
rxq = apc->rxqs[rxq_idx];
if (!rxq)
continue;
if (apc->rxqs) {
mana_destroy_rxq(apc, rxq, true);
apc->rxqs[rxq_idx] = NULL;
for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
rxq = apc->rxqs[rxq_idx];
if (!rxq)
continue;
mana_destroy_rxq(apc, rxq, true);
apc->rxqs[rxq_idx] = NULL;
}
}
mana_destroy_txq(apc);
@@ -3311,7 +3317,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
if (apc->port_is_up)
return -EINVAL;
mana_chn_setxdp(apc, NULL);
if (apc->rxqs)
mana_chn_setxdp(apc, NULL);
if (gd->gdma_context->is_pf && !apc->ac->bm_hostmode)
mana_pf_deregister_filter(apc);
@@ -3329,33 +3336,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
* number of queues.
*/
for (i = 0; i < apc->num_queues; i++) {
txq = &apc->tx_qp[i]->txq;
tsleep = 1000;
while (atomic_read(&txq->pending_sends) > 0 &&
time_before(jiffies, timeout)) {
usleep_range(tsleep, tsleep + 1000);
tsleep <<= 1;
}
if (atomic_read(&txq->pending_sends)) {
err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
if (err) {
netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
err, atomic_read(&txq->pending_sends),
txq->gdma_txq_id);
if (apc->tx_qp) {
for (i = 0; i < apc->num_queues; i++) {
txq = &apc->tx_qp[i]->txq;
tsleep = 1000;
while (atomic_read(&txq->pending_sends) > 0 &&
time_before(jiffies, timeout)) {
usleep_range(tsleep, tsleep + 1000);
tsleep <<= 1;
}
break;
if (atomic_read(&txq->pending_sends)) {
err =
pcie_flr(to_pci_dev(gd->gdma_context->dev));
if (err) {
netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
err,
atomic_read(&txq->pending_sends),
txq->gdma_txq_id);
}
break;
}
}
for (i = 0; i < apc->num_queues; i++) {
txq = &apc->tx_qp[i]->txq;
while ((skb = skb_dequeue(&txq->pending_skbs))) {
mana_unmap_skb(skb, apc);
dev_kfree_skb_any(skb);
}
atomic_set(&txq->pending_sends, 0);
}
}
for (i = 0; i < apc->num_queues; i++) {
txq = &apc->tx_qp[i]->txq;
while ((skb = skb_dequeue(&txq->pending_skbs))) {
mana_unmap_skb(skb, apc);
dev_kfree_skb_any(skb);
}
atomic_set(&txq->pending_sends, 0);
}
/* We're 100% sure the queues can no longer be woken up, because
* we're sure now mana_poll_tx_cq() can't be running.
*/
@@ -3380,6 +3392,12 @@ int mana_detach(struct net_device *ndev, bool from_close)
ASSERT_RTNL();
/* If already detached (indicates detach succeeded but attach failed
* previously). Now skip mana detach and just retry mana_attach.
*/
if (!from_close && !netif_device_present(ndev))
return 0;
apc->port_st_save = apc->port_is_up;
apc->port_is_up = false;

View File

@@ -129,6 +129,9 @@ static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
unsigned int val = 0;
int ret;
if (!fwnode)
return 0;
if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
default_pol = PHY_POL_INVERT;

View File

@@ -177,16 +177,6 @@ static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
trailer_len = padding_len + noise_encrypted_len(0);
plaintext_len = skb->len + padding_len;
/* Expand data section to have room for padding and auth tag. */
num_frags = skb_cow_data(skb, trailer_len, &trailer);
if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg)))
return false;
/* Set the padding to zeros, and make sure it and the auth tag are part
* of the skb.
*/
memset(skb_tail_pointer(trailer), 0, padding_len);
/* Expand head section to have room for our header and the network
* stack's headers.
*/
@@ -198,6 +188,16 @@ static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
skb_checksum_help(skb)))
return false;
/* Expand data section to have room for padding and auth tag. */
num_frags = skb_cow_data(skb, trailer_len, &trailer);
if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg)))
return false;
/* Set the padding to zeros, and make sure it and the auth tag are part
* of the skb.
*/
memset(skb_tail_pointer(trailer), 0, padding_len);
/* Only after checksumming can we safely add on the padding at the end
* and the header.
*/

View File

@@ -725,6 +725,11 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
*/
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_update_all_gpes(void))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
acpi_enable_gpe_cond(acpi_handle gpe_device,
u32 gpe_number,
u8 dispatch_type))
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
acpi_enable_gpe(acpi_handle gpe_device,
u32 gpe_number))

View File

@@ -72,6 +72,10 @@
__diag_push(); \
__diag_ignore(GCC, 8, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments");\
__diag_ignore(clang, 23, "-Wunknown-warning-option", \
"Avoid breaking versions without -Wattribute-alias"); \
__diag_ignore(clang, 23, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments"); \
asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(__se_compat_sys##name)))); \
ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \

View File

@@ -131,6 +131,12 @@
#define __diag_str(s) __diag_str1(s)
#define __diag(s) _Pragma(__diag_str(clang diagnostic s))
#if CONFIG_CLANG_VERSION >= 230000
#define __diag_clang_23(s) __diag(s)
#else
#define __diag_clang_23(s)
#endif
#define __diag_clang_13(s) __diag(s)
#define __diag_ignore_all(option, comment) \

View File

@@ -396,6 +396,17 @@
# define __disable_sanitizer_instrumentation
#endif
/*
* Optional: not supported by clang
*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-noipa
*/
#if __has_attribute(noipa)
# define __noipa __attribute__((noipa))
#else
# define __noipa
#endif
/*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute

View File

@@ -711,6 +711,10 @@ struct ftrace_likely_data {
#define __diag_GCC(version, severity, string)
#endif
#ifndef __diag_clang
#define __diag_clang(version, severity, string)
#endif
#define __diag_push() __diag(push)
#define __diag_pop() __diag(pop)

View File

@@ -1316,8 +1316,6 @@ void hid_quirks_exit(__u16 bus);
dev_notice(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_warn(hid, fmt, ...) \
dev_warn(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_warn_ratelimited(hid, fmt, ...) \
dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_info(hid, fmt, ...) \
dev_info(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_dbg(hid, fmt, ...) \

View File

@@ -247,6 +247,10 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
__diag_push(); \
__diag_ignore(GCC, 8, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments");\
__diag_ignore(clang, 23, "-Wunknown-warning-option", \
"Avoid breaking versions without -Wattribute-alias");\
__diag_ignore(clang, 23, "-Wattribute-alias", \
"Type aliasing is used to sanitize syscall arguments");\
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(__se_sys##name)))); \
ALLOW_ERROR_INJECTION(sys##name, ERRNO); \

View File

@@ -715,6 +715,7 @@ struct xfrm_mgr {
const struct xfrm_migrate *m,
int num_bundles,
const struct xfrm_kmaddress *k,
struct net *net,
const struct xfrm_encap_tmpl *encap);
bool (*is_alive)(const struct km_event *c);
};
@@ -1891,7 +1892,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
#ifdef CONFIG_XFRM_MIGRATE
int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_bundles,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap);
struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
u32 if_id);

View File

@@ -139,12 +139,14 @@ static int io_tctx_install_node(struct io_ring_ctx *ctx,
int __io_uring_add_tctx_node(struct io_ring_ctx *ctx)
{
struct io_uring_task *tctx = current->io_uring;
bool new_tctx = false;
int ret;
if (unlikely(!tctx)) {
tctx = io_uring_alloc_task_context(current, ctx);
if (IS_ERR(tctx))
return PTR_ERR(tctx);
new_tctx = true;
if (data_race(ctx->int_flags) & IO_RING_F_IOWQ_LIMITS_SET) {
unsigned int limits[2];
@@ -168,13 +170,15 @@ int __io_uring_add_tctx_node(struct io_ring_ctx *ctx)
if (tctx->io_wq)
io_wq_set_exit_on_idle(tctx->io_wq, false);
ret = io_tctx_install_node(ctx, tctx);
if (!ret) {
if (new_tctx)
current->io_uring = tctx;
ret = io_tctx_install_node(ctx, tctx);
if (!ret)
return 0;
}
if (!current->io_uring) {
err_free:
if (new_tctx) {
current->io_uring = NULL;
if (tctx->io_wq) {
io_wq_exit_start(tctx->io_wq);
io_wq_put_and_exit(tctx->io_wq);

View File

@@ -1222,7 +1222,7 @@ struct self_test {
static __initconst const struct debug_obj_descr descr_type_test;
static bool __init is_static_object(void *addr)
static __noipa bool __init is_static_object(void *addr)
{
struct self_test *obj = addr;

View File

@@ -486,6 +486,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
int ret;
local_skb = skb_clone(skb, GFP_ATOMIC);
if (!local_skb)
continue;
BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
netdev->name,

View File

@@ -870,8 +870,10 @@ static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn)
d->big_sync_term = true;
}
if (!d->pa_sync_term && !d->big_sync_term)
if (!d->pa_sync_term && !d->big_sync_term) {
kfree(d);
return 0;
}
ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
terminate_big_destroy);

View File

@@ -539,46 +539,9 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
hci_req_sync_lock(hdev);
/* Drop queues */
skb_queue_purge(&hdev->rx_q);
skb_queue_purge(&hdev->cmd_q);
/* Cancel these to avoid queueing non-chained pending work */
hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
/* Wait for
*
* if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
* queue_delayed_work(&hdev->{cmd,ncmd}_timer)
*
* inside RCU section to see the flag or complete scheduling.
*/
synchronize_rcu();
/* Explicitly cancel works in case scheduled after setting the flag. */
cancel_delayed_work(&hdev->cmd_timer);
cancel_delayed_work(&hdev->ncmd_timer);
/* Avoid potential lockdep warnings from the *_flush() calls by
* ensuring the workqueue is empty up front.
*/
drain_workqueue(hdev->workqueue);
hci_dev_lock(hdev);
hci_inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
hci_dev_unlock(hdev);
if (hdev->flush)
hdev->flush(hdev);
hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0;
hdev->sco_cnt = 0;
hdev->le_cnt = 0;
hdev->iso_cnt = 0;
ret = hci_reset_sync(hdev);
ret = hci_dev_close_sync(hdev);
if (!ret)
ret = hci_dev_open_sync(hdev);
hci_req_sync_unlock(hdev);
return ret;

View File

@@ -5301,6 +5301,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
bt_dev_dbg(hdev, "");
/* Set HCI_DRAIN_WORKQUEUE flag to prevent queuing work during
* reset/close. See hci_cmd_work() and handle_cmd_cnt_and_timer().
*/
hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
synchronize_rcu();
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
disable_delayed_work(&hdev->power_off);
disable_delayed_work(&hdev->ncmd_timer);
@@ -5324,6 +5330,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
cancel_delayed_work_sync(&hdev->cmd_timer);
hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
return err;
}
@@ -5386,6 +5393,10 @@ int hci_dev_close_sync(struct hci_dev *hdev)
/* Reset device */
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0;
hdev->sco_cnt = 0;
hdev->le_cnt = 0;
hdev->iso_cnt = 0;
if (hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE) &&
!auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
set_bit(HCI_INIT, &hdev->flags);
@@ -5423,6 +5434,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
/* Clear flags */
hdev->flags &= BIT(HCI_RAW);
hci_dev_clear_volatile_flags(hdev);
hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
@@ -6699,6 +6711,7 @@ int hci_le_create_cis_sync(struct hci_dev *hdev)
DEFINE_FLEX(struct hci_cp_le_create_cis, cmd, cis, num_cis, 0x1f);
size_t aux_num_cis = 0;
struct hci_conn *conn;
u16 timeout = 0;
u8 cig = BT_ISO_QOS_CIG_UNSET;
/* The spec allows only one pending LE Create CIS command at a time. If
@@ -6769,6 +6782,7 @@ int hci_le_create_cis_sync(struct hci_dev *hdev)
set_bit(HCI_CONN_CREATE_CIS, &conn->flags);
cis->acl_handle = cpu_to_le16(conn->parent->handle);
cis->cis_handle = cpu_to_le16(conn->handle);
timeout = conn->conn_timeout;
aux_num_cis++;
if (aux_num_cis >= cmd->num_cis)
@@ -6788,7 +6802,7 @@ int hci_le_create_cis_sync(struct hci_dev *hdev)
return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CIS,
struct_size(cmd, cis, cmd->num_cis),
cmd, HCI_EVT_LE_CIS_ESTABLISHED,
conn->conn_timeout, NULL);
timeout, NULL);
}
int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle)

View File

@@ -179,12 +179,21 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
{
struct input_dev *dev = session->input;
unsigned char *keys = session->keys;
unsigned char *udata = skb->data + 1;
signed char *sdata = skb->data + 1;
int i, size = skb->len - 1;
unsigned char *udata;
signed char *sdata;
u8 *hdr;
int i;
switch (skb->data[0]) {
hdr = skb_pull_data(skb, 1);
if (!hdr)
return;
switch (*hdr) {
case 0x01: /* Keyboard report */
udata = skb_pull_data(skb, 8);
if (!udata)
break;
for (i = 0; i < 8; i++)
input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
@@ -213,6 +222,10 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
break;
case 0x02: /* Mouse report */
sdata = skb_pull_data(skb, 3);
if (!sdata)
break;
input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
@@ -222,7 +235,7 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
input_report_rel(dev, REL_X, sdata[1]);
input_report_rel(dev, REL_Y, sdata[2]);
if (size > 3)
if (skb->len > 0)
input_report_rel(dev, REL_WHEEL, sdata[3]);
break;
}

View File

@@ -564,7 +564,7 @@ static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
struct sock *sk;
iso_conn_lock(conn);
sk = conn->sk;
sk = iso_sock_hold(conn);
iso_conn_unlock(conn);
if (!sk)
@@ -573,11 +573,15 @@ static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
BT_DBG("sk %p len %d", sk, skb->len);
if (sk->sk_state != BT_CONNECTED)
goto drop;
goto drop_put;
if (!sock_queue_rcv_skb(sk, skb))
if (!sock_queue_rcv_skb(sk, skb)) {
sock_put(sk);
return;
}
drop_put:
sock_put(sk);
drop:
kfree_skb(skb);
}
@@ -860,8 +864,8 @@ static void __iso_sock_close(struct sock *sk)
/* Must be called on unlocked socket. */
static void iso_sock_close(struct sock *sk)
{
iso_sock_clear_timer(sk);
lock_sock(sk);
iso_sock_clear_timer(sk);
__iso_sock_close(sk);
release_sock(sk);
iso_sock_kill(sk);

View File

@@ -411,8 +411,10 @@ static void l2cap_chan_timeout(struct work_struct *work)
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
if (!conn)
if (!conn) {
l2cap_chan_put(chan);
return;
}
mutex_lock(&conn->lock);
/* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
@@ -5260,6 +5262,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
cmd_len -= sizeof(*rsp);
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
struct l2cap_chan *orig;
u16 dcid;
if (chan->ident != cmd->ident ||
@@ -5281,8 +5284,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
orig = __l2cap_get_chan_by_dcid(conn, dcid);
/* Check if dcid is already in use */
if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
if (dcid && orig) {
/* If a device receives a
* L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
* already-assigned Destination CID, then both the
@@ -5291,10 +5296,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
*/
l2cap_chan_del(chan, ECONNREFUSED);
l2cap_chan_unlock(chan);
chan = __l2cap_get_chan_by_dcid(conn, dcid);
l2cap_chan_lock(chan);
l2cap_chan_del(chan, ECONNRESET);
l2cap_chan_unlock(chan);
/* Check that the dcid channel mode is
* L2CAP_MODE_EXT_FLOWCTL since this procedure is only
* valid for that mode and shouldn't disconnect a dcid
* in other modes.
*/
if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
l2cap_chan_lock(orig);
/* Disconnect the original channel as it may be
* considered connected since dcid has already
* been assigned; don't call l2cap_chan_close
* directly since that could lead to
* l2cap_chan_del and then removing the channel
* from the list while we're iterating over it.
*/
__set_chan_timer(orig, 0);
l2cap_chan_unlock(orig);
}
continue;
}
@@ -5458,14 +5477,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
BT_DBG("result 0x%4.4x", result);
if (!result)
if (!result) {
list_for_each_entry(chan, &conn->chan_l, list) {
if (chan->ident == cmd->ident)
chan->ident = 0;
}
return 0;
}
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
if (chan->ident != cmd->ident)
continue;
l2cap_chan_hold(chan);
if (!l2cap_chan_hold_unless_zero(chan))
continue;
l2cap_chan_lock(chan);
l2cap_chan_del(chan, ECONNRESET);

View File

@@ -1499,6 +1499,10 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
* pin it (hold_unless_zero() additionally skips a chan already past
* its last reference). We then drop the sk lock before taking
* chan->lock, so sk and chan locks are never held together.
*
* Since we cannot call l2cap_chan_close() without conn->lock,
* schedule l2cap_chan_timeout to close the channel; it already
* acquires conn->lock -> chan->lock in the correct order.
*/
while ((sk = bt_accept_dequeue(parent, NULL))) {
struct l2cap_chan *chan;
@@ -1516,14 +1520,12 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
state_to_string(chan->state));
l2cap_chan_lock(chan);
__clear_chan_timer(chan);
l2cap_chan_close(chan, ECONNRESET);
/* l2cap_conn_del() may already have killed this socket
* (it sets SOCK_DEAD); skip the duplicate to avoid a
* double sock_put()/l2cap_chan_put().
/* Since we cannot call l2cap_chan_close() without
* conn->lock, schedule its timer to trigger the close
* and cleanup of this channel.
*/
if (!sock_flag(sk, SOCK_DEAD))
l2cap_sock_kill(sk);
if (chan->conn)
__set_chan_timer(chan, 0);
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);

View File

@@ -2869,7 +2869,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
psge->length = start - offset;
rsge.length -= psge->length;
rsge.offset += start;
rsge.offset += start - offset;
sk_msg_iter_var_next(i);
sg_unmark_end(psge);

View File

@@ -6824,6 +6824,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
skb->len -= off;
/* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
* while refcounting frags below.
*/
skb_zcopy_downgrade_managed(skb);
memcpy((struct skb_shared_info *)(data + size),
skb_shinfo(skb),
offsetof(struct skb_shared_info,
@@ -6937,6 +6942,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
return -ENOMEM;
size = SKB_WITH_OVERHEAD(size);
/* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
* while refcounting frags below.
*/
skb_zcopy_downgrade_managed(skb);
memcpy((struct skb_shared_info *)(data + size),
skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
if (skb_orphan_frags(skb, gfp_mask)) {

View File

@@ -143,7 +143,7 @@ static void ah_output_done(void *data, int err)
}
kfree(AH_SKB_CB(skb)->tmp);
xfrm_output_resume(skb->sk, skb, err);
xfrm_output_resume(skb_to_full_sk(skb), skb, err);
}
static int ah_output(struct xfrm_state *x, struct sk_buff *skb)

View File

@@ -419,8 +419,8 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
return err;
}
if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
PAGE_SIZE)
goto cow;
if (!skb_cloned(skb)) {

View File

@@ -1013,7 +1013,7 @@ ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
list_for_each(p, &idev->addr_list) {
struct inet6_ifaddr *ifa
= list_entry(p, struct inet6_ifaddr, if_list);
if (ifp_scope > ipv6_addr_src_scope(&ifa->addr))
if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
break;
}

View File

@@ -337,7 +337,7 @@ static void ah6_output_done(void *data, int err)
ah6_restore_hdrs(top_iph, iph_ext, extlen);
kfree(AH_SKB_CB(skb)->tmp);
xfrm_output_resume(skb->sk, skb, err);
xfrm_output_resume(skb_to_full_sk(skb), skb, err);
}
static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)

View File

@@ -448,8 +448,8 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
return err;
}
if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
PAGE_SIZE)
goto cow;
if (!skb_cloned(skb)) {

View File

@@ -481,6 +481,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
const struct fib6_nh *nh = sibling->fib6_nh;
int nh_upper_bound;
if (!READ_ONCE(first->fib6_nsiblings))
break;
nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
if (hash > nh_upper_bound)
continue;
@@ -5902,6 +5905,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
goto nla_put_failure;
}
if (!READ_ONCE(rt->fib6_nsiblings))
break;
}
rcu_read_unlock();

View File

@@ -3564,7 +3564,7 @@ static int set_ipsecrequest(struct sk_buff *skb,
#ifdef CONFIG_NET_KEY_MIGRATE
static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_bundles,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap)
{
int i;
@@ -3669,7 +3669,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
}
/* broadcast migrate message to sockets */
pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, net);
return 0;
@@ -3680,7 +3680,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
#else
static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_bundles,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap)
{
return -ENOPROTOOPT;

View File

@@ -9403,6 +9403,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
release_sock(sk);
current_timeo = schedule_timeout(current_timeo);
lock_sock(sk);
if (sk != asoc->base.sk)
goto do_error;
*timeo_p = current_timeo;
}

View File

@@ -205,6 +205,7 @@ static u16 virtio_transport_get_type(struct sock *sk)
static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,
size_t payload_len,
bool zcopy,
struct ubuf_info *uarg,
u32 src_cid,
u32 src_port,
u32 dst_cid,
@@ -245,6 +246,12 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
if (info->msg && payload_len > 0) {
int err;
/* Bind the zerocopy lifetime before filling frags so error
* rollback frees managed fixed-buffer pages through
* the uarg-aware path.
*/
skb_zcopy_set(skb, uarg, NULL);
err = virtio_transport_fill_skb(skb, info, payload_len, zcopy);
if (err)
goto out;
@@ -364,6 +371,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
skb_len = min(max_skb_len, rest_len);
skb = virtio_transport_alloc_skb(info, skb_len, can_zcopy,
uarg,
src_cid, src_port,
dst_cid, dst_port);
if (!skb) {
@@ -371,8 +379,6 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
break;
}
skb_zcopy_set(skb, uarg, NULL);
virtio_transport_inc_tx_pkt(vvs, skb);
ret = t_ops->send_pkt(skb, info->net);
@@ -1183,7 +1189,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
if (!t)
return -ENOTCONN;
reply = virtio_transport_alloc_skb(&info, 0, false,
reply = virtio_transport_alloc_skb(&info, 0, false, NULL,
le64_to_cpu(hdr->dst_cid),
le32_to_cpu(hdr->dst_port),
le64_to_cpu(hdr->src_cid),

View File

@@ -797,9 +797,12 @@ static void xfrm_trans_reinject(struct work_struct *work)
spin_unlock_bh(&trans->queue_lock);
local_bh_disable();
while ((skb = __skb_dequeue(&queue)))
XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
NULL, skb);
while ((skb = __skb_dequeue(&queue))) {
struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
put_net(net);
}
local_bh_enable();
}
@@ -808,6 +811,7 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
struct sk_buff *))
{
struct xfrm_trans_tasklet *trans;
struct net *hold_net;
trans = this_cpu_ptr(&xfrm_trans_tasklet);
@@ -816,8 +820,12 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
hold_net = maybe_get_net(net);
if (!hold_net)
return -ENODEV;
XFRM_TRANS_SKB_CB(skb)->finish = finish;
XFRM_TRANS_SKB_CB(skb)->net = net;
XFRM_TRANS_SKB_CB(skb)->net = hold_net;
spin_lock_bh(&trans->queue_lock);
__skb_queue_tail(&trans->queue, skb);
spin_unlock_bh(&trans->queue_lock);

View File

@@ -51,11 +51,15 @@ static int ipcomp_post_acomp(struct sk_buff *skb, int err, int hlen)
struct scatterlist *dsg;
int len, dlen;
if (unlikely(err))
goto out_free_req;
if (unlikely(!req))
return err;
extra = acomp_request_extra(req);
dsg = extra->sg;
if (unlikely(err))
goto out_free_req;
dlen = req->dlen;
pskb_trim_unique(skb, 0);
@@ -84,10 +88,10 @@ static int ipcomp_post_acomp(struct sk_buff *skb, int err, int hlen)
skb_shinfo(skb)->nr_frags++;
} while ((dlen -= len));
for (; dsg; dsg = sg_next(dsg))
out_free_req:
for (; dsg && sg_page(dsg); dsg = sg_next(dsg))
__free_page(sg_page(dsg));
out_free_req:
acomp_request_free(req);
return err;
}

View File

@@ -2650,7 +2650,8 @@ static void __iptfs_init_state(struct xfrm_state *x,
x->props.enc_hdr_len = sizeof(struct ip_iptfs_hdr);
/* Always keep a module reference when x->mode_data is set */
__module_get(x->mode_cbs->owner);
if (x->mode_data != xtfs)
__module_get(x->mode_cbs->owner);
x->mode_data = xtfs;
xtfs->x = x;
@@ -2658,22 +2659,39 @@ static void __iptfs_init_state(struct xfrm_state *x,
static int iptfs_clone_state(struct xfrm_state *x, struct xfrm_state *orig)
{
struct skb_wseq *w_saved = NULL;
struct xfrm_iptfs_data *xtfs;
xtfs = kmemdup(orig->mode_data, sizeof(*xtfs), GFP_KERNEL);
if (!xtfs)
return -ENOMEM;
xtfs->ra_newskb = NULL;
if (xtfs->cfg.reorder_win_size) {
xtfs->w_saved = kzalloc_objs(*xtfs->w_saved,
xtfs->cfg.reorder_win_size);
if (!xtfs->w_saved) {
w_saved = kzalloc_objs(*w_saved, xtfs->cfg.reorder_win_size);
if (!w_saved) {
kfree_sensitive(xtfs);
return -ENOMEM;
}
}
xtfs->w_saved = w_saved;
__skb_queue_head_init(&xtfs->queue);
xtfs->queue_size = 0;
hrtimer_setup(&xtfs->iptfs_timer, iptfs_delay_timer, CLOCK_MONOTONIC,
IPTFS_HRTIMER_MODE);
spin_lock_init(&xtfs->drop_lock);
hrtimer_setup(&xtfs->drop_timer, iptfs_drop_timer, CLOCK_MONOTONIC,
IPTFS_HRTIMER_MODE);
xtfs->w_seq_set = false;
xtfs->w_wantseq = 0;
xtfs->w_savedlen = 0;
xtfs->ra_newskb = NULL;
xtfs->ra_wantseq = 0;
xtfs->ra_runtlen = 0;
__module_get(x->mode_cbs->owner);
x->mode_data = xtfs;
xtfs->x = x;

View File

@@ -4276,21 +4276,21 @@ static int __net_init xfrm_policy_init(struct net *net)
return -ENOMEM;
}
static void xfrm_policy_fini(struct net *net)
static void __net_exit xfrm_net_pre_exit(struct net *net)
{
struct xfrm_pol_inexact_bin *b, *t;
unsigned int sz;
int dir;
disable_work_sync(&net->xfrm.policy_hthresh.work);
flush_work(&net->xfrm.policy_hash_work);
#ifdef CONFIG_XFRM_SUB_POLICY
xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, false);
#endif
xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false);
}
synchronize_rcu();
static void xfrm_policy_fini(struct net *net)
{
struct xfrm_pol_inexact_bin *b, *t;
unsigned int sz;
int dir;
WARN_ON(!list_empty(&net->xfrm.policy_all));
@@ -4368,6 +4368,7 @@ static void __net_exit xfrm_net_exit(struct net *net)
static struct pernet_operations __net_initdata xfrm_net_ops = {
.init = xfrm_net_init,
.pre_exit = xfrm_net_pre_exit,
.exit = xfrm_net_exit,
};
@@ -4703,7 +4704,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
}
/* Stage 5 - announce */
km_migrate(sel, dir, type, m, num_migrate, k, encap);
km_migrate(sel, dir, type, m, num_migrate, k, net, encap);
xfrm_pol_put(pol);

View File

@@ -2837,7 +2837,7 @@ EXPORT_SYMBOL(km_policy_expired);
#ifdef CONFIG_XFRM_MIGRATE
int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_migrate,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap)
{
int err = -EINVAL;
@@ -2848,7 +2848,7 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
list_for_each_entry_rcu(km, &xfrm_km_list, list) {
if (km->migrate) {
ret = km->migrate(sel, dir, type, m, num_migrate, k,
encap);
net, encap);
if (!ret)
err = ret;
}
@@ -3114,10 +3114,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
const struct xfrm_type *type = READ_ONCE(x->type);
struct crypto_aead *aead;
u32 blksize, net_adj = 0;
u32 overhead, payload_mtu;
if (x->km.state != XFRM_STATE_VALID ||
!type || type->proto != IPPROTO_ESP)
!type || type->proto != IPPROTO_ESP) {
if (mtu <= x->props.header_len)
return 1;
return mtu - x->props.header_len;
}
aead = x->data;
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
@@ -3140,8 +3144,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
break;
}
return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
net_adj) & ~(blksize - 1)) + net_adj - 2;
overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
if (mtu <= overhead)
return 1;
payload_mtu = mtu - overhead;
payload_mtu &= ~(blksize - 1);
if (payload_mtu <= 2)
return 1;
return payload_mtu + net_adj - 2;
}
EXPORT_SYMBOL_GPL(xfrm_state_mtu);

View File

@@ -3271,10 +3271,9 @@ static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m,
static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_migrate,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap)
{
struct net *net = &init_net;
struct sk_buff *skb;
int err;
@@ -3292,7 +3291,7 @@ static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
#else
static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
const struct xfrm_migrate *m, int num_migrate,
const struct xfrm_kmaddress *k,
const struct xfrm_kmaddress *k, struct net *net,
const struct xfrm_encap_tmpl *encap)
{
return -ENOPROTOOPT;

View File

@@ -2974,8 +2974,10 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_pcm_str *pstr = entry->private_data;
struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
struct snd_pcm_oss_setup *setup;
guard(mutex)(&pstr->oss.setup_mutex);
setup = pstr->oss.setup_list;
while (setup) {
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
setup->task_name,
@@ -3060,6 +3062,13 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
buffer->error = -ENOMEM;
return;
}
template.task_name = kstrdup(task_name, GFP_KERNEL);
if (!template.task_name) {
kfree(setup);
buffer->error = -ENOMEM;
return;
}
*setup = template;
if (pstr->oss.setup_list == NULL)
pstr->oss.setup_list = setup;
else {
@@ -3067,12 +3076,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
setup1->next; setup1 = setup1->next);
setup1->next = setup;
}
template.task_name = kstrdup(task_name, GFP_KERNEL);
if (! template.task_name) {
kfree(setup);
buffer->error = -ENOMEM;
return;
}
continue;
}
*setup = template;
}

View File

@@ -386,6 +386,8 @@ unsigned int snd_motu_register_dsp_message_parser_count_event(struct snd_motu *m
{
struct msg_parser *parser = motu->message_parser;
guard(spinlock_irqsave)(&parser->lock);
if (parser->pull_pos > parser->push_pos)
return EVENT_QUEUE_SIZE - parser->pull_pos + parser->push_pos;
else
@@ -395,13 +397,14 @@ unsigned int snd_motu_register_dsp_message_parser_count_event(struct snd_motu *m
bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32 *event)
{
struct msg_parser *parser = motu->message_parser;
unsigned int pos = parser->pull_pos;
if (pos == parser->push_pos)
return false;
unsigned int pos;
guard(spinlock_irqsave)(&parser->lock);
if (parser->pull_pos == parser->push_pos)
return false;
pos = parser->pull_pos;
*event = parser->event_queue[pos];
++pos;

View File

@@ -582,6 +582,7 @@ static const struct hda_quirk cs4208_mac_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
SND_PCI_QUIRK(0x106b, 0x7800, "MacPro 6,1", CS4208_MACMINI),
SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
SND_PCI_QUIRK(0x106b, 0x7f00, "iMac 16,1", CS4208_MBP11),
{} /* terminator */
};

View File

@@ -5458,7 +5458,7 @@ static const struct hda_fixup alc269_fixups[] = {
[ALC299_FIXUP_PREDATOR_SPK] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
{ 0x21, 0x90170150 }, /* use as internal speaker */
{ }
}
},
@@ -7070,6 +7070,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a06, "HP Dragonfly Folio G3 2-in-1", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
@@ -7324,6 +7325,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
HDA_CODEC_QUIRK(0x1043, 0x1204, "ASUS Strix G16 G615JMR", ALC287_FIXUP_TXNW2781_I2C_ASUS),
SND_PCI_QUIRK(0x1043, 0x1204, "ASUS Strix G615JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
HDA_CODEC_QUIRK(0x1043, 0x1214, "ASUS ROG Strix G615LP", ALC287_FIXUP_TXNW2781_I2C_ASUS),
SND_PCI_QUIRK(0x1043, 0x1214, "ASUS Strix G615LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
@@ -7778,6 +7780,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3920, "Yoga S990-16 pro Quad VECO Quad", ALC287_FIXUP_TXNW2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3929, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x392b, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
HDA_CODEC_QUIRK(0x17aa, 0x394c, "Lenovo Yoga Slim 7 14AGP11", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
@@ -7845,6 +7848,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1e39, 0xca14, "MEDION NM14LNL", ALC233_FIXUP_MEDION_MTL_SPK),
SND_PCI_QUIRK(0x1e50, 0x7007, "Positivo DN50E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1e50, 0x7038, "Positivo DN140", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1ee7, 0x2078, "HONOR BRB-X M1010", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1ee7, 0x2081, "HONOR MRB-XXX M1020", ALC256_FIXUP_HONOR_MRB_XXX_M1020_AUDIO),
SND_PCI_QUIRK(0x1f4c, 0xe001, "Minisforum V3 (SE)", ALC245_FIXUP_BASS_HP_DAC),

View File

@@ -1025,7 +1025,7 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
u32 values[HDA_MAX_COMPONENTS];
char hid_string[8];
struct acpi_device *adev;
const char *property, *sub;
const char *property;
int i, ret;
/*
@@ -1047,7 +1047,8 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
/* Initialize things that could be overwritten by a fixup */
cs35l56->index = -1;
sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
const char *sub __free(kfree) = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
ret = cs35l56_hda_apply_platform_fixups(cs35l56, sub, &id);
if (ret)
return ret;
@@ -1095,15 +1096,16 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
ret = cirrus_scodec_get_speaker_id(cs35l56->base.dev, cs35l56->index,
cs35l56->num_amps, -1);
if (ret == -ENOENT) {
cs35l56->system_name = sub;
cs35l56->system_name = devm_kstrdup(cs35l56->base.dev, sub, GFP_KERNEL);
} else if (ret >= 0) {
cs35l56->system_name = kasprintf(GFP_KERNEL, "%s-spkid%d", sub, ret);
kfree(sub);
if (!cs35l56->system_name)
return -ENOMEM;
cs35l56->system_name = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL,
"%s-spkid%d", sub, ret);
} else {
return ret;
}
if (!cs35l56->system_name)
return -ENOMEM;
}
cs35l56->base.reset_gpio = devm_gpiod_get_index_optional(cs35l56->base.dev,
@@ -1254,7 +1256,6 @@ void cs35l56_hda_remove(struct device *dev)
cs_dsp_remove(&cs35l56->cs_dsp);
kfree(cs35l56->system_name);
pm_runtime_put_noidle(cs35l56->base.dev);
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);

View File

@@ -51,7 +51,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
struct simple_mux *priv = snd_soc_component_get_drvdata(c);
if (ucontrol->value.enumerated.item[0] > e->items)
if (ucontrol->value.enumerated.item[0] >= e->items)
return -EINVAL;
if (priv->mux == ucontrol->value.enumerated.item[0])

View File

@@ -40,6 +40,7 @@ struct byt_cht_es8316_private {
struct gpio_desc *speaker_en_gpio;
struct device *codec_dev;
bool speaker_en;
bool mclk_enabled;
};
enum {
@@ -170,6 +171,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
},
};
static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
{
if (!priv->mclk_enabled)
return;
clk_disable_unprepare(priv->mclk);
priv->mclk_enabled = false;
}
static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
{
struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
@@ -227,12 +237,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
ret = clk_prepare_enable(priv->mclk);
if (ret)
dev_err(card->dev, "unable to enable MCLK\n");
else
priv->mclk_enabled = true;
ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000,
SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(card->dev, "can't set codec clock %d\n", ret);
return ret;
goto err_disable_mclk;
}
ret = snd_soc_card_jack_new_pins(card, "Headset",
@@ -241,13 +253,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
ARRAY_SIZE(byt_cht_es8316_jack_pins));
if (ret) {
dev_err(card->dev, "jack creation failed %d\n", ret);
return ret;
goto err_disable_mclk;
}
snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
snd_soc_component_set_jack(codec, &priv->jack, NULL);
return 0;
err_disable_mclk:
byt_cht_es8316_disable_mclk(priv);
return ret;
}
static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
{
struct snd_soc_card *card = runtime->card;
struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
byt_cht_es8316_disable_mclk(priv);
}
static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
@@ -353,6 +377,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
| SND_SOC_DAIFMT_CBC_CFC,
.be_hw_params_fixup = byt_cht_es8316_codec_fixup,
.init = byt_cht_es8316_init,
.exit = byt_cht_es8316_exit,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};

View File

@@ -186,12 +186,10 @@ static void event_handler(uint32_t opcode, uint32_t token,
case ASM_CLIENT_EVENT_CMD_RUN_DONE:
break;
case ASM_CLIENT_EVENT_CMD_EOS_DONE:
prtd->state = Q6ASM_STREAM_STOPPED;
break;
case ASM_CLIENT_EVENT_DATA_WRITE_DONE: {
case ASM_CLIENT_EVENT_DATA_WRITE_DONE:
snd_pcm_period_elapsed(substream);
break;
}
case ASM_CLIENT_EVENT_DATA_READ_DONE:
snd_pcm_period_elapsed(substream);
if (prtd->state == Q6ASM_STREAM_RUNNING)
@@ -227,9 +225,19 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
/* rate and channels are sent to audio driver */
if (prtd->state == Q6ASM_STREAM_RUNNING) {
/* clear the previous setup if any */
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
q6asm_unmap_memory_regions(substream->stream,
prtd->audio_client);
ret = q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
if (ret < 0) {
dev_err(dev, "Failed to close q6asm stream %d\n", prtd->stream_id);
return ret;
}
ret = q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
if (ret < 0) {
dev_err(dev, "Failed to unmap memory regions for q6asm stream %d\n",
prtd->stream_id);
return ret;
}
q6routing_stream_close(soc_prtd->dai_link->id,
substream->stream);
prtd->state = Q6ASM_STREAM_STOPPED;
@@ -297,8 +305,6 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
open_err:
q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
return ret;
}
@@ -341,7 +347,6 @@ static int q6asm_dai_trigger(struct snd_soc_component *component,
0, 0, 0);
break;
case SNDRV_PCM_TRIGGER_STOP:
prtd->state = Q6ASM_STREAM_STOPPED;
ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
CMD_EOS);
break;
@@ -378,7 +383,7 @@ static int q6asm_dai_open(struct snd_soc_component *component,
return -EINVAL;
}
prtd = kzalloc_obj(struct q6asm_dai_rtd);
prtd = kzalloc_obj(*prtd);
if (prtd == NULL)
return -ENOMEM;
@@ -457,12 +462,12 @@ static int q6asm_dai_close(struct snd_soc_component *component,
struct q6asm_dai_rtd *prtd = runtime->private_data;
if (prtd->audio_client) {
if (prtd->state)
if (prtd->state == Q6ASM_STREAM_RUNNING) {
q6asm_cmd(prtd->audio_client, prtd->stream_id,
CMD_CLOSE);
q6asm_unmap_memory_regions(substream->stream,
q6asm_unmap_memory_regions(substream->stream,
prtd->audio_client);
}
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
}
@@ -555,8 +560,6 @@ static void compress_event_handler(uint32_t opcode, uint32_t token,
snd_compr_drain_notify(prtd->cstream);
prtd->notify_on_drain = false;
} else {
prtd->state = Q6ASM_STREAM_STOPPED;
}
break;
@@ -674,7 +677,7 @@ static int q6asm_dai_compr_free(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd = stream->private_data;
if (prtd->audio_client) {
if (prtd->state) {
if (prtd->state == Q6ASM_STREAM_RUNNING) {
q6asm_cmd(prtd->audio_client, prtd->stream_id,
CMD_CLOSE);
if (prtd->next_track_stream_id) {
@@ -682,11 +685,11 @@ static int q6asm_dai_compr_free(struct snd_soc_component *component,
prtd->next_track_stream_id,
CMD_CLOSE);
}
}
snd_dma_free_pages(&prtd->dma_buffer);
q6asm_unmap_memory_regions(stream->direction,
q6asm_unmap_memory_regions(stream->direction,
prtd->audio_client);
}
snd_dma_free_pages(&prtd->dma_buffer);
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
}
@@ -916,7 +919,7 @@ static int q6asm_dai_compr_set_params(struct snd_soc_component *component,
prtd->session_id, dir);
if (ret) {
dev_err(dev, "Stream reg failed ret:%d\n", ret);
goto q6_err;
goto routing_err;
}
ret = __q6asm_dai_compr_set_codec_params(component, stream,
@@ -942,11 +945,11 @@ static int q6asm_dai_compr_set_params(struct snd_soc_component *component,
return 0;
q6_err:
q6routing_stream_close(rtd->dai_link->id, dir);
routing_err:
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
open_err:
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
return ret;
}
@@ -1014,7 +1017,6 @@ static int q6asm_dai_compr_trigger(struct snd_soc_component *component,
0, 0, 0);
break;
case SNDRV_PCM_TRIGGER_STOP:
prtd->state = Q6ASM_STREAM_STOPPED;
ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
CMD_EOS);
break;

View File

@@ -2504,6 +2504,27 @@ static int scarlett2_has_config_item(
return !!private->config_set->items[config_item_num].offset;
}
/* Return the configuration item's offset, applying any per-firmware
* overrides.
*
* Firmware 2417 for the 2i2 Gen 4 moved DIRECT_MONITOR_GAIN by 4
* bytes. Apply that shift here so that the rest of the driver can
* keep using the single config set. This override can be removed
* once the multi-config-set framework lands.
*/
static int scarlett2_config_item_offset(
struct scarlett2_data *private, int config_item_num)
{
int offset = private->config_set->items[config_item_num].offset;
if (config_item_num == SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN &&
private->info == &s2i2_gen4_info &&
private->firmware_version >= 2417)
offset = 0x2a4;
return offset;
}
/* Send a USB message to get configuration parameters; result placed in *buf */
static int scarlett2_usb_get_config(
struct usb_mixer_interface *mixer,
@@ -2513,6 +2534,7 @@ static int scarlett2_usb_get_config(
const struct scarlett2_config *config_item =
&private->config_set->items[config_item_num];
int size, err, i;
int item_offset;
u8 *buf_8;
u8 value;
@@ -2522,13 +2544,15 @@ static int scarlett2_usb_get_config(
if (!config_item->offset)
return -EFAULT;
item_offset = scarlett2_config_item_offset(private, config_item_num);
/* Writes to the parameter buffer are always 1 byte */
size = config_item->size ? config_item->size : 8;
/* For byte-sized parameters, retrieve directly into buf */
if (size >= 8) {
size = size / 8 * count;
err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
err = scarlett2_usb_get(mixer, item_offset, buf, size);
if (err < 0)
return err;
if (config_item->size == 16) {
@@ -2546,7 +2570,7 @@ static int scarlett2_usb_get_config(
}
/* For bit-sized parameters, retrieve into value */
err = scarlett2_usb_get(mixer, config_item->offset, &value, 1);
err = scarlett2_usb_get(mixer, item_offset, &value, 1);
if (err < 0)
return err;
@@ -2696,7 +2720,8 @@ static int scarlett2_usb_set_config(
*/
if (config_item->size >= 8) {
size = config_item->size / 8;
offset = config_item->offset + index * size;
offset = scarlett2_config_item_offset(private, config_item_num) +
index * size;
/* If updating a bit, retrieve the old value, set/clear the
* bit as needed, and update value
@@ -2705,7 +2730,7 @@ static int scarlett2_usb_set_config(
u8 tmp;
size = 1;
offset = config_item->offset;
offset = scarlett2_config_item_offset(private, config_item_num);
err = scarlett2_usb_get(mixer, offset, &tmp, 1);
if (err < 0)

View File

@@ -2449,6 +2449,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_DSD_RAW),
DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */
QUIRK_FLAG_SET_IFACE_FIRST),
DEVICE_FLG(0x25aa, 0x600b, /* TAE1159 */
QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
DEVICE_FLG(0x262a, 0x9302, /* ddHiFi TC44C */
QUIRK_FLAG_DSD_RAW),
DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */

View File

@@ -1523,6 +1523,23 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
#define SZ_64G (SZ_32G * 2)
#endif
static int cxl_mock_platform_device_add(struct platform_device *pdev,
struct platform_device **ppdev)
{
int rc;
if (ppdev)
*ppdev = pdev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
if (ppdev)
*ppdev = NULL;
}
return rc;
}
static __init int cxl_rch_topo_init(void)
{
int rc, i;
@@ -1537,13 +1554,10 @@ static __init int cxl_rch_topo_init(void)
goto err_bridge;
mock_companion(adev, &pdev->dev);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_rch[i]);
if (rc)
goto err_bridge;
}
cxl_rch[i] = pdev;
mock_pci_bus[idx].bridge = &pdev->dev;
rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
"firmware_node");
@@ -1595,13 +1609,10 @@ static __init int cxl_single_topo_init(void)
goto err_bridge;
mock_companion(adev, &pdev->dev);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_hb_single[i]);
if (rc)
goto err_bridge;
}
cxl_hb_single[i] = pdev;
mock_pci_bus[i + NR_CXL_HOST_BRIDGES].bridge = &pdev->dev;
rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
"physical_node");
@@ -1620,12 +1631,9 @@ static __init int cxl_single_topo_init(void)
goto err_port;
pdev->dev.parent = &bridge->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_root_single[i]);
if (rc)
goto err_port;
}
cxl_root_single[i] = pdev;
}
for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++) {
@@ -1638,12 +1646,9 @@ static __init int cxl_single_topo_init(void)
goto err_uport;
pdev->dev.parent = &root_port->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_swu_single[i]);
if (rc)
goto err_uport;
}
cxl_swu_single[i] = pdev;
}
for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++) {
@@ -1657,12 +1662,9 @@ static __init int cxl_single_topo_init(void)
goto err_dport;
pdev->dev.parent = &uport->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_swd_single[i]);
if (rc)
goto err_dport;
}
cxl_swd_single[i] = pdev;
}
return 0;
@@ -1735,12 +1737,9 @@ static int cxl_mem_init(void)
pdev->dev.parent = &dport->dev;
set_dev_node(&pdev->dev, i % 2);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_mem[i]);
if (rc)
goto err_mem;
}
cxl_mem[i] = pdev;
}
for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
@@ -1753,12 +1752,9 @@ static int cxl_mem_init(void)
pdev->dev.parent = &dport->dev;
set_dev_node(&pdev->dev, i % 2);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_mem_single[i]);
if (rc)
goto err_single;
}
cxl_mem_single[i] = pdev;
}
for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
@@ -1772,12 +1768,9 @@ static int cxl_mem_init(void)
pdev->dev.parent = &rch->dev;
set_dev_node(&pdev->dev, i % 2);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_rcd[i]);
if (rc)
goto err_rcd;
}
cxl_rcd[i] = pdev;
}
return 0;
@@ -1869,13 +1862,10 @@ static __init int cxl_test_init(void)
goto err_bridge;
mock_companion(adev, &pdev->dev);
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_host_bridge[i]);
if (rc)
goto err_bridge;
}
cxl_host_bridge[i] = pdev;
mock_pci_bus[i].bridge = &pdev->dev;
rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
"physical_node");
@@ -1893,12 +1883,9 @@ static __init int cxl_test_init(void)
goto err_port;
pdev->dev.parent = &bridge->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_root_port[i]);
if (rc)
goto err_port;
}
cxl_root_port[i] = pdev;
}
BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
@@ -1911,12 +1898,9 @@ static __init int cxl_test_init(void)
goto err_uport;
pdev->dev.parent = &root_port->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_switch_uport[i]);
if (rc)
goto err_uport;
}
cxl_switch_uport[i] = pdev;
}
for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
@@ -1929,12 +1913,9 @@ static __init int cxl_test_init(void)
goto err_dport;
pdev->dev.parent = &uport->dev;
rc = platform_device_add(pdev);
if (rc) {
platform_device_put(pdev);
rc = cxl_mock_platform_device_add(pdev, &cxl_switch_dport[i]);
if (rc)
goto err_dport;
}
cxl_switch_dport[i] = pdev;
}
rc = cxl_single_topo_init();
@@ -1953,9 +1934,9 @@ static __init int cxl_test_init(void)
acpi0017_mock.dev.bus = &platform_bus_type;
cxl_acpi->dev.groups = cxl_acpi_groups;
rc = platform_device_add(cxl_acpi);
rc = cxl_mock_platform_device_add(cxl_acpi, NULL);
if (rc)
goto err_root;
goto err_rch;
rc = cxl_mem_init();
if (rc)

View File

@@ -41,10 +41,10 @@
#include <inttypes.h>
#include <limits.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "kvm_syscalls.h"
#include "kvm_util.h"
#include "test_util.h"
#include "memstress.h"

View File

@@ -14,10 +14,10 @@
#include <linux/bitmap.h>
#include <linux/falloc.h>
#include <linux/sizes.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "kvm_syscalls.h"
#include "kvm_util.h"
#include "numaif.h"
#include "test_util.h"

View File

@@ -2,8 +2,18 @@
#ifndef SELFTEST_KVM_SYSCALLS_H
#define SELFTEST_KVM_SYSCALLS_H
/*
* Include both the kernel and libc versions of mman.h. The kernel provides
* the most up-to-date flags and definitions, while libc provides the syscall
* wrappers tests expect.
*/
#include <linux/mman.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <test_util.h>
#define MAP_ARGS0(m,...)
#define MAP_ARGS1(m,t,a,...) m(t,a)
#define MAP_ARGS2(m,t,a,...) m(t,a), MAP_ARGS1(m,__VA_ARGS__)

View File

@@ -19,9 +19,9 @@
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "kselftest.h"
#include <linux/mman.h>
#include <linux/types.h>
#define msecs_to_usecs(msec) ((msec) * 1000ULL)

View File

@@ -6,11 +6,14 @@
*/
#include "test_util.h"
#include <execinfo.h>
#include <sys/syscall.h>
#include "kselftest.h"
#ifdef __GLIBC__
#include <execinfo.h>
/* Dumps the current stack trace to stderr. */
static void __attribute__((noinline)) test_dump_stack(void);
static void test_dump_stack(void)
@@ -57,6 +60,9 @@ static void test_dump_stack(void)
system(cmd);
#pragma GCC diagnostic pop
}
#else
static void test_dump_stack(void) {}
#endif
static pid_t _gettid(void)
{

View File

@@ -5,13 +5,13 @@
* Copyright (C) 2018, Google LLC.
*/
#include "test_util.h"
#include "kvm_syscalls.h"
#include "kvm_util.h"
#include "processor.h"
#include "ucall_common.h"
#include <assert.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@@ -15,7 +15,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
@@ -23,6 +22,7 @@
#include <linux/sizes.h>
#include <test_util.h>
#include <kvm_syscalls.h>
#include <kvm_util.h>
#include <processor.h>
#include <ucall_common.h>

View File

@@ -4,11 +4,10 @@
*
* Copyright (C) 2024, Red Hat, Inc.
*/
#include <sys/mman.h>
#include <linux/fs.h>
#include "test_util.h"
#include "kvm_syscalls.h"
#include "kvm_util.h"
#include "kselftest.h"
#include "ucall_common.h"

View File

@@ -4,8 +4,8 @@
*
* Copyright IBM Corp. 2021
*/
#include <sys/mman.h>
#include "test_util.h"
#include "kvm_syscalls.h"
#include "kvm_util.h"
#include "kselftest.h"
#include "ucall_common.h"

View File

@@ -8,11 +8,11 @@
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/compiler.h>
#include <test_util.h>
#include <kvm_syscalls.h>
#include <kvm_util.h>
#include <processor.h>

View File

@@ -273,8 +273,8 @@ setup()
ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1 &>/dev/null
ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0 &>/dev/null
ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
ip -netns $ioam_node_alpha addr add 2001:db8:1::50/64 dev veth0 &>/dev/null
ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
ip -netns $ioam_node_alpha link set veth0 up &>/dev/null
ip -netns $ioam_node_alpha link set lo up &>/dev/null
ip -netns $ioam_node_alpha route add 2001:db8:2::/64 \