Merge tag 'v5.15.64' into rpi-5.15.y

This is the 5.15.64 stable release
This commit is contained in:
Dom Cobley
2022-09-05 12:46:18 +01:00
154 changed files with 2609 additions and 1654 deletions

View File

@@ -521,6 +521,7 @@ What: /sys/devices/system/cpu/vulnerabilities
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort /sys/devices/system/cpu/vulnerabilities/tsx_async_abort
/sys/devices/system/cpu/vulnerabilities/itlb_multihit /sys/devices/system/cpu/vulnerabilities/itlb_multihit
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
/sys/devices/system/cpu/vulnerabilities/retbleed
Date: January 2018 Date: January 2018
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Information about CPU vulnerabilities Description: Information about CPU vulnerabilities

View File

@@ -230,6 +230,20 @@ The possible values in this file are:
* - 'Mitigation: Clear CPU buffers' * - 'Mitigation: Clear CPU buffers'
- The processor is vulnerable and the CPU buffer clearing mitigation is - The processor is vulnerable and the CPU buffer clearing mitigation is
enabled. enabled.
* - 'Unknown: No mitigations'
- The processor vulnerability status is unknown because it is
out of Servicing period. Mitigation is not attempted.
Definitions:
------------
Servicing period: The process of providing functional and security updates to
Intel processors or platforms, utilizing the Intel Platform Update (IPU)
process or other similar mechanisms.
End of Servicing Updates (ESU): ESU is the date at which Intel will no
longer provide Servicing, such as through IPU or other similar update
processes. ESU dates will typically be aligned to end of quarter.
If the processor is vulnerable then the following information is appended to If the processor is vulnerable then the following information is appended to
the above information: the above information:

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 15 PATCHLEVEL = 15
SUBLEVEL = 63 SUBLEVEL = 64
EXTRAVERSION = EXTRAVERSION =
NAME = Trick or Treat NAME = Trick or Treat

View File

@@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_1286807 #ifdef CONFIG_ARM64_ERRATUM_1286807
{ {
ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0),
},
{
/* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */ /* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */
ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe), ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
}, },

View File

@@ -142,10 +142,10 @@ menu "Processor type and features"
choice choice
prompt "Processor type" prompt "Processor type"
default PA7000 default PA7000 if "$(ARCH)" = "parisc"
config PA7000 config PA7000
bool "PA7000/PA7100" bool "PA7000/PA7100" if "$(ARCH)" = "parisc"
help help
This is the processor type of your CPU. This information is This is the processor type of your CPU. This information is
used for optimizing purposes. In order to compile a kernel used for optimizing purposes. In order to compile a kernel
@@ -156,21 +156,21 @@ config PA7000
which is required on some machines. which is required on some machines.
config PA7100LC config PA7100LC
bool "PA7100LC" bool "PA7100LC" if "$(ARCH)" = "parisc"
help help
Select this option for the PCX-L processor, as used in the Select this option for the PCX-L processor, as used in the
712, 715/64, 715/80, 715/100, 715/100XC, 725/100, 743, 748, 712, 715/64, 715/80, 715/100, 715/100XC, 725/100, 743, 748,
D200, D210, D300, D310 and E-class D200, D210, D300, D310 and E-class
config PA7200 config PA7200
bool "PA7200" bool "PA7200" if "$(ARCH)" = "parisc"
help help
Select this option for the PCX-T' processor, as used in the Select this option for the PCX-T' processor, as used in the
C100, C110, J100, J110, J210XC, D250, D260, D350, D360, C100, C110, J100, J110, J210XC, D250, D260, D350, D360,
K100, K200, K210, K220, K400, K410 and K420 K100, K200, K210, K220, K400, K410 and K420
config PA7300LC config PA7300LC
bool "PA7300LC" bool "PA7300LC" if "$(ARCH)" = "parisc"
help help
Select this option for the PCX-L2 processor, as used in the Select this option for the PCX-L2 processor, as used in the
744, A180, B132L, B160L, B180L, C132L, C160L, C180L, 744, A180, B132L, B160L, B180L, C132L, C160L, C180L,
@@ -220,17 +220,8 @@ config MLONGCALLS
Enabling this option will probably slow down your kernel. Enabling this option will probably slow down your kernel.
config 64BIT config 64BIT
bool "64-bit kernel" def_bool "$(ARCH)" = "parisc64"
depends on PA8X00 depends on PA8X00
help
Enable this if you want to support 64bit kernel on PA-RISC platform.
At the moment, only people willing to use more than 2GB of RAM,
or having a 64bit-only capable PA-RISC machine should say Y here.
Since there is no 64bit userland on PA-RISC, there is no point to
enable this option otherwise. The 64bit kernel is significantly bigger
and slower than the 32bit one.
choice choice
prompt "Kernel page size" prompt "Kernel page size"

View File

@@ -107,7 +107,7 @@
#define R1(i) (((i)>>21)&0x1f) #define R1(i) (((i)>>21)&0x1f)
#define R2(i) (((i)>>16)&0x1f) #define R2(i) (((i)>>16)&0x1f)
#define R3(i) ((i)&0x1f) #define R3(i) ((i)&0x1f)
#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1)) #define FR3(i) ((((i)&0x1f)<<1)|(((i)>>6)&1))
#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0)) #define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0))
#define IM5_2(i) IM((i)>>16,5) #define IM5_2(i) IM((i)>>16,5)
#define IM5_3(i) IM((i),5) #define IM5_3(i) IM((i),5)

View File

@@ -42,6 +42,8 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE / sizeof(long)];
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/csr.h> #include <asm/csr.h>

View File

@@ -20,9 +20,10 @@
#include <asm/asm-prototypes.h> #include <asm/asm-prototypes.h>
#include <asm/bug.h> #include <asm/bug.h>
#include <asm/csr.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/csr.h> #include <asm/thread_info.h>
int show_unhandled_signals = 1; int show_unhandled_signals = 1;

View File

@@ -173,6 +173,13 @@ ENTRY(__asm_copy_from_user)
csrc CSR_STATUS, t6 csrc CSR_STATUS, t6
li a0, 0 li a0, 0
ret ret
/* Exception fixup code */
10:
/* Disable access to user memory */
csrc CSR_STATUS, t6
mv a0, t5
ret
ENDPROC(__asm_copy_to_user) ENDPROC(__asm_copy_to_user)
ENDPROC(__asm_copy_from_user) ENDPROC(__asm_copy_from_user)
EXPORT_SYMBOL(__asm_copy_to_user) EXPORT_SYMBOL(__asm_copy_to_user)
@@ -218,19 +225,12 @@ ENTRY(__clear_user)
addi a0, a0, 1 addi a0, a0, 1
bltu a0, a3, 5b bltu a0, a3, 5b
j 3b j 3b
ENDPROC(__clear_user)
EXPORT_SYMBOL(__clear_user)
.section .fixup,"ax" /* Exception fixup code */
.balign 4
/* Fixup code for __copy_user(10) and __clear_user(11) */
10:
/* Disable access to user memory */
csrs CSR_STATUS, t6
mv a0, t5
ret
11: 11:
csrs CSR_STATUS, t6 /* Disable access to user memory */
csrc CSR_STATUS, t6
mv a0, a1 mv a0, a1
ret ret
.previous ENDPROC(__clear_user)
EXPORT_SYMBOL(__clear_user)

View File

@@ -91,6 +91,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
memcpy(dst, src, arch_task_struct_size); memcpy(dst, src, arch_task_struct_size);
dst->thread.fpu.regs = dst->thread.fpu.fprs; dst->thread.fpu.regs = dst->thread.fpu.fprs;
/*
* Don't transfer over the runtime instrumentation or the guarded
* storage control block pointers. These fields are cleared here instead
* of in copy_thread() to avoid premature freeing of associated memory
* on fork() failure. Wait to clear the RI flag because ->stack still
* refers to the source thread.
*/
dst->thread.ri_cb = NULL;
dst->thread.gs_cb = NULL;
dst->thread.gs_bc_cb = NULL;
return 0; return 0;
} }
@@ -149,13 +161,11 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
frame->childregs.flags = 0; frame->childregs.flags = 0;
if (new_stackp) if (new_stackp)
frame->childregs.gprs[15] = new_stackp; frame->childregs.gprs[15] = new_stackp;
/*
/* Don't copy runtime instrumentation info */ * Clear the runtime instrumentation flag after the above childregs
p->thread.ri_cb = NULL; * copy. The CB pointer was already cleared in arch_dup_task_struct().
*/
frame->childregs.psw.mask &= ~PSW_MASK_RI; frame->childregs.psw.mask &= ~PSW_MASK_RI;
/* Don't copy guarded storage control block */
p->thread.gs_cb = NULL;
p->thread.gs_bc_cb = NULL;
/* Set a new TLS ? */ /* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS) { if (clone_flags & CLONE_SETTLS) {

View File

@@ -397,7 +397,9 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access)
flags = FAULT_FLAG_DEFAULT; flags = FAULT_FLAG_DEFAULT;
if (user_mode(regs)) if (user_mode(regs))
flags |= FAULT_FLAG_USER; flags |= FAULT_FLAG_USER;
if (access == VM_WRITE || is_write) if (is_write)
access = VM_WRITE;
if (access == VM_WRITE)
flags |= FAULT_FLAG_WRITE; flags |= FAULT_FLAG_WRITE;
mmap_read_lock(mm); mmap_read_lock(mm);

View File

@@ -373,6 +373,7 @@ SYM_CODE_END(xen_error_entry)
SYM_CODE_START(\asmsym) SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS offset=\has_error_code*8 UNWIND_HINT_IRET_REGS offset=\has_error_code*8
ASM_CLAC ASM_CLAC
cld
.if \has_error_code == 0 .if \has_error_code == 0
pushq $-1 /* ORIG_RAX: no syscall to restart */ pushq $-1 /* ORIG_RAX: no syscall to restart */
@@ -440,6 +441,7 @@ SYM_CODE_END(\asmsym)
SYM_CODE_START(\asmsym) SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS UNWIND_HINT_IRET_REGS
ASM_CLAC ASM_CLAC
cld
pushq $-1 /* ORIG_RAX: no syscall to restart */ pushq $-1 /* ORIG_RAX: no syscall to restart */
@@ -495,6 +497,7 @@ SYM_CODE_END(\asmsym)
SYM_CODE_START(\asmsym) SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS UNWIND_HINT_IRET_REGS
ASM_CLAC ASM_CLAC
cld
/* /*
* If the entry is from userspace, switch stacks and treat it as * If the entry is from userspace, switch stacks and treat it as
@@ -557,6 +560,7 @@ SYM_CODE_END(\asmsym)
SYM_CODE_START(\asmsym) SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS offset=8 UNWIND_HINT_IRET_REGS offset=8
ASM_CLAC ASM_CLAC
cld
/* paranoid_entry returns GS information for paranoid_exit in EBX. */ /* paranoid_entry returns GS information for paranoid_exit in EBX. */
call paranoid_entry call paranoid_entry
@@ -876,7 +880,6 @@ SYM_CODE_END(xen_failsafe_callback)
*/ */
SYM_CODE_START_LOCAL(paranoid_entry) SYM_CODE_START_LOCAL(paranoid_entry)
UNWIND_HINT_FUNC UNWIND_HINT_FUNC
cld
PUSH_AND_CLEAR_REGS save_ret=1 PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8 ENCODE_FRAME_POINTER 8
@@ -1012,7 +1015,6 @@ SYM_CODE_END(paranoid_exit)
*/ */
SYM_CODE_START_LOCAL(error_entry) SYM_CODE_START_LOCAL(error_entry)
UNWIND_HINT_FUNC UNWIND_HINT_FUNC
cld
PUSH_AND_CLEAR_REGS save_ret=1 PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8 ENCODE_FRAME_POINTER 8
@@ -1155,6 +1157,7 @@ SYM_CODE_START(asm_exc_nmi)
*/ */
ASM_CLAC ASM_CLAC
cld
/* Use %rdx as our temp variable throughout */ /* Use %rdx as our temp variable throughout */
pushq %rdx pushq %rdx
@@ -1174,7 +1177,6 @@ SYM_CODE_START(asm_exc_nmi)
*/ */
swapgs swapgs
cld
FENCE_SWAPGS_USER_ENTRY FENCE_SWAPGS_USER_ENTRY
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
movq %rsp, %rdx movq %rsp, %rdx

View File

@@ -236,6 +236,7 @@ static u64 load_latency_data(u64 status)
static u64 store_latency_data(u64 status) static u64 store_latency_data(u64 status)
{ {
union intel_x86_pebs_dse dse; union intel_x86_pebs_dse dse;
union perf_mem_data_src src;
u64 val; u64 val;
dse.val = status; dse.val = status;
@@ -263,7 +264,14 @@ static u64 store_latency_data(u64 status)
val |= P(BLK, NA); val |= P(BLK, NA);
return val; /*
* the pebs_data_source table is only for loads
* so override the mem_op to say STORE instead
*/
src.val = val;
src.mem_op = P(OP,STORE);
return src.val;
} }
struct pebs_record_core { struct pebs_record_core {

View File

@@ -1114,6 +1114,14 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
if (static_cpu_has(X86_FEATURE_ARCH_LBR)) { if (static_cpu_has(X86_FEATURE_ARCH_LBR)) {
reg->config = mask; reg->config = mask;
/*
* The Arch LBR HW can retrieve the common branch types
* from the LBR_INFO. It doesn't require the high overhead
* SW disassemble.
* Enable the branch type by default for the Arch LBR.
*/
reg->reg |= X86_BR_TYPE_SAVE;
return 0; return 0;
} }

View File

@@ -788,6 +788,22 @@ int snb_pci2phy_map_init(int devid)
return 0; return 0;
} }
static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
/*
* SNB IMC counters are 32-bit and are laid out back to back
* in MMIO space. Therefore we must use a 32-bit accessor function
* using readq() from uncore_mmio_read_counter() causes problems
* because it is reading 64-bit at a time. This is okay for the
* uncore_perf_event_update() function because it drops the upper
* 32-bits but not okay for plain uncore_read_counter() as invoked
* in uncore_pmu_event_start().
*/
return (u64)readl(box->io_addr + hwc->event_base);
}
static struct pmu snb_uncore_imc_pmu = { static struct pmu snb_uncore_imc_pmu = {
.task_ctx_nr = perf_invalid_context, .task_ctx_nr = perf_invalid_context,
.event_init = snb_uncore_imc_event_init, .event_init = snb_uncore_imc_event_init,
@@ -807,7 +823,7 @@ static struct intel_uncore_ops snb_uncore_imc_ops = {
.disable_event = snb_uncore_imc_disable_event, .disable_event = snb_uncore_imc_disable_event,
.enable_event = snb_uncore_imc_enable_event, .enable_event = snb_uncore_imc_enable_event,
.hw_config = snb_uncore_imc_hw_config, .hw_config = snb_uncore_imc_hw_config,
.read_counter = uncore_mmio_read_counter, .read_counter = snb_uncore_imc_read_counter,
}; };
static struct intel_uncore_type snb_uncore_imc = { static struct intel_uncore_type snb_uncore_imc = {

View File

@@ -446,7 +446,8 @@
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ #define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
#define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */ #define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */
#define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ #define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
#endif /* _ASM_X86_CPUFEATURES_H */ #endif /* _ASM_X86_CPUFEATURES_H */

View File

@@ -35,34 +35,57 @@
#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ #define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */
/* /*
* Common helper for __FILL_RETURN_BUFFER and __FILL_ONE_RETURN.
*/
#define __FILL_RETURN_SLOT \
ANNOTATE_INTRA_FUNCTION_CALL; \
call 772f; \
int3; \
772:
/*
* Stuff the entire RSB.
*
* Google experimented with loop-unrolling and this turned out to be * Google experimented with loop-unrolling and this turned out to be
* the optimal version - two calls, each with their own speculation * the optimal version - two calls, each with their own speculation
* trap should their return address end up getting used, in a loop. * trap should their return address end up getting used, in a loop.
*/ */
#define __FILL_RETURN_BUFFER(reg, nr, sp) \ #ifdef CONFIG_X86_64
#define __FILL_RETURN_BUFFER(reg, nr) \
mov $(nr/2), reg; \ mov $(nr/2), reg; \
771: \ 771: \
ANNOTATE_INTRA_FUNCTION_CALL; \ __FILL_RETURN_SLOT \
call 772f; \ __FILL_RETURN_SLOT \
773: /* speculation trap */ \ add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \
UNWIND_HINT_EMPTY; \
pause; \
lfence; \
jmp 773b; \
772: \
ANNOTATE_INTRA_FUNCTION_CALL; \
call 774f; \
775: /* speculation trap */ \
UNWIND_HINT_EMPTY; \
pause; \
lfence; \
jmp 775b; \
774: \
add $(BITS_PER_LONG/8) * 2, sp; \
dec reg; \ dec reg; \
jnz 771b; \ jnz 771b; \
/* barrier for jnz misprediction */ \ /* barrier for jnz misprediction */ \
lfence; lfence;
#else
/*
* i386 doesn't unconditionally have LFENCE, as such it can't
* do a loop.
*/
#define __FILL_RETURN_BUFFER(reg, nr) \
.rept nr; \
__FILL_RETURN_SLOT; \
.endr; \
add $(BITS_PER_LONG/8) * nr, %_ASM_SP;
#endif
/*
* Stuff a single RSB slot.
*
* To mitigate Post-Barrier RSB speculation, one CALL instruction must be
* forced to retire before letting a RET instruction execute.
*
* On PBRSB-vulnerable CPUs, it is not safe for a RET to be executed
* before this point.
*/
#define __FILL_ONE_RETURN \
__FILL_RETURN_SLOT \
add $(BITS_PER_LONG/8), %_ASM_SP; \
lfence;
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
@@ -120,28 +143,15 @@
#endif #endif
.endm .endm
.macro ISSUE_UNBALANCED_RET_GUARD
ANNOTATE_INTRA_FUNCTION_CALL
call .Lunbalanced_ret_guard_\@
int3
.Lunbalanced_ret_guard_\@:
add $(BITS_PER_LONG/8), %_ASM_SP
lfence
.endm
/* /*
* A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
* monstrosity above, manually. * monstrosity above, manually.
*/ */
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2 .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
.ifb \ftr2 ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
.else __stringify(__FILL_ONE_RETURN), \ftr2
ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2
.endif
__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
.Lunbalanced_\@:
ISSUE_UNBALANCED_RET_GUARD
.Lskip_rsb_\@: .Lskip_rsb_\@:
.endm .endm

View File

@@ -433,6 +433,7 @@ static void __init mmio_select_mitigation(void)
u64 ia32_cap; u64 ia32_cap;
if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
cpu_mitigations_off()) { cpu_mitigations_off()) {
mmio_mitigation = MMIO_MITIGATION_OFF; mmio_mitigation = MMIO_MITIGATION_OFF;
return; return;
@@ -538,6 +539,8 @@ out:
pr_info("TAA: %s\n", taa_strings[taa_mitigation]); pr_info("TAA: %s\n", taa_strings[taa_mitigation]);
if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]); pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
pr_info("MMIO Stale Data: Unknown: No mitigations\n");
} }
static void __init md_clear_select_mitigation(void) static void __init md_clear_select_mitigation(void)
@@ -2268,6 +2271,9 @@ static ssize_t tsx_async_abort_show_state(char *buf)
static ssize_t mmio_stale_data_show_state(char *buf) static ssize_t mmio_stale_data_show_state(char *buf)
{ {
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
return sysfs_emit(buf, "Unknown: No mitigations\n");
if (mmio_mitigation == MMIO_MITIGATION_OFF) if (mmio_mitigation == MMIO_MITIGATION_OFF)
return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]); return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]);
@@ -2414,6 +2420,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
return srbds_show_state(buf); return srbds_show_state(buf);
case X86_BUG_MMIO_STALE_DATA: case X86_BUG_MMIO_STALE_DATA:
case X86_BUG_MMIO_UNKNOWN:
return mmio_stale_data_show_state(buf); return mmio_stale_data_show_state(buf);
case X86_BUG_RETBLEED: case X86_BUG_RETBLEED:
@@ -2473,6 +2480,9 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *
ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf) ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf)
{ {
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_UNKNOWN);
else
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA); return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
} }

View File

@@ -1027,7 +1027,8 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
#define NO_SWAPGS BIT(6) #define NO_SWAPGS BIT(6)
#define NO_ITLB_MULTIHIT BIT(7) #define NO_ITLB_MULTIHIT BIT(7)
#define NO_SPECTRE_V2 BIT(8) #define NO_SPECTRE_V2 BIT(8)
#define NO_EIBRS_PBRSB BIT(9) #define NO_MMIO BIT(9)
#define NO_EIBRS_PBRSB BIT(10)
#define VULNWL(vendor, family, model, whitelist) \ #define VULNWL(vendor, family, model, whitelist) \
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist) X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
@@ -1048,6 +1049,11 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION),
/* Intel Family 6 */ /* Intel Family 6 */
VULNWL_INTEL(TIGERLAKE, NO_MMIO),
VULNWL_INTEL(TIGERLAKE_L, NO_MMIO),
VULNWL_INTEL(ALDERLAKE, NO_MMIO),
VULNWL_INTEL(ALDERLAKE_L, NO_MMIO),
VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
@@ -1066,9 +1072,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
/* /*
* Technically, swapgs isn't serializing on AMD (despite it previously * Technically, swapgs isn't serializing on AMD (despite it previously
@@ -1083,18 +1089,18 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/* AMD Family 0xf - 0x12 */ /* AMD Family 0xf - 0x12 */
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
/* Zhaoxin Family 7 */ /* Zhaoxin Family 7 */
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS), VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS), VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
{} {}
}; };
@@ -1248,10 +1254,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
* Affected CPU list is generally enough to enumerate the vulnerability, * Affected CPU list is generally enough to enumerate the vulnerability,
* but for virtualization case check for ARCH_CAP MSR bits also, VMM may * but for virtualization case check for ARCH_CAP MSR bits also, VMM may
* not want the guest to enumerate the bug. * not want the guest to enumerate the bug.
*
* Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist,
* nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits.
*/ */
if (cpu_matches(cpu_vuln_blacklist, MMIO) && if (!arch_cap_mmio_immune(ia32_cap)) {
!arch_cap_mmio_immune(ia32_cap)) if (cpu_matches(cpu_vuln_blacklist, MMIO))
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO))
setup_force_cpu_bug(X86_BUG_MMIO_UNKNOWN);
}
if (!cpu_has(c, X86_FEATURE_BTC_NO)) { if (!cpu_has(c, X86_FEATURE_BTC_NO)) {
if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA)) if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA))

View File

@@ -93,22 +93,27 @@ static struct orc_entry *orc_find(unsigned long ip);
static struct orc_entry *orc_ftrace_find(unsigned long ip) static struct orc_entry *orc_ftrace_find(unsigned long ip)
{ {
struct ftrace_ops *ops; struct ftrace_ops *ops;
unsigned long caller; unsigned long tramp_addr, offset;
ops = ftrace_ops_trampoline(ip); ops = ftrace_ops_trampoline(ip);
if (!ops) if (!ops)
return NULL; return NULL;
/* Set tramp_addr to the start of the code copied by the trampoline */
if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
caller = (unsigned long)ftrace_regs_call; tramp_addr = (unsigned long)ftrace_regs_caller;
else else
caller = (unsigned long)ftrace_call; tramp_addr = (unsigned long)ftrace_caller;
/* Now place tramp_addr to the location within the trampoline ip is at */
offset = ip - ops->trampoline;
tramp_addr += offset;
/* Prevent unlikely recursion */ /* Prevent unlikely recursion */
if (ip == caller) if (ip == tramp_addr)
return NULL; return NULL;
return orc_find(caller); return orc_find(tramp_addr);
} }
#else #else
static struct orc_entry *orc_ftrace_find(unsigned long ip) static struct orc_entry *orc_ftrace_find(unsigned long ip)

View File

@@ -1400,7 +1400,8 @@ out:
/* If we didn't flush the entire list, we could have told the driver /* If we didn't flush the entire list, we could have told the driver
* there was more coming, but that turned out to be a lie. * there was more coming, but that turned out to be a lie.
*/ */
if ((!list_empty(list) || errors) && q->mq_ops->commit_rqs && queued) if ((!list_empty(list) || errors || needs_resource ||
ret == BLK_STS_DEV_RESOURCE) && q->mq_ops->commit_rqs && queued)
q->mq_ops->commit_rqs(hctx); q->mq_ops->commit_rqs(hctx);
/* /*
* Any items that need requeuing? Stuff them into hctx->dispatch, * Any items that need requeuing? Stuff them into hctx->dispatch,
@@ -2111,6 +2112,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx,
list_del_init(&rq->queuelist); list_del_init(&rq->queuelist);
ret = blk_mq_request_issue_directly(rq, list_empty(list)); ret = blk_mq_request_issue_directly(rq, list_empty(list));
if (ret != BLK_STS_OK) { if (ret != BLK_STS_OK) {
errors++;
if (ret == BLK_STS_RESOURCE || if (ret == BLK_STS_RESOURCE ||
ret == BLK_STS_DEV_RESOURCE) { ret == BLK_STS_DEV_RESOURCE) {
blk_mq_request_bypass_insert(rq, false, blk_mq_request_bypass_insert(rq, false,
@@ -2118,7 +2120,6 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx,
break; break;
} }
blk_mq_end_request(rq, ret); blk_mq_end_request(rq, ret);
errors++;
} else } else
queued++; queued++;
} }

View File

@@ -144,7 +144,7 @@ void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
unsigned int cpu; unsigned int cpu;
for_each_cpu(cpu, policy->related_cpus) { for_each_cpu(cpu, policy->related_cpus) {
struct acpi_processor *pr = per_cpu(processors, policy->cpu); struct acpi_processor *pr = per_cpu(processors, cpu);
if (pr) if (pr)
freq_qos_remove_request(&pr->thermal_req); freq_qos_remove_request(&pr->thermal_req);

View File

@@ -395,12 +395,15 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
size_t size, data_offsets_size; size_t size, data_offsets_size;
int ret; int ret;
mmap_read_lock(alloc->vma_vm_mm);
if (!binder_alloc_get_vma(alloc)) { if (!binder_alloc_get_vma(alloc)) {
mmap_read_unlock(alloc->vma_vm_mm);
binder_alloc_debug(BINDER_DEBUG_USER_ERROR, binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
"%d: binder_alloc_buf, no vma\n", "%d: binder_alloc_buf, no vma\n",
alloc->pid); alloc->pid);
return ERR_PTR(-ESRCH); return ERR_PTR(-ESRCH);
} }
mmap_read_unlock(alloc->vma_vm_mm);
data_offsets_size = ALIGN(data_size, sizeof(void *)) + data_offsets_size = ALIGN(data_size, sizeof(void *)) +
ALIGN(offsets_size, sizeof(void *)); ALIGN(offsets_size, sizeof(void *));
@@ -922,7 +925,14 @@ void binder_alloc_print_pages(struct seq_file *m,
* Make sure the binder_alloc is fully initialized, otherwise we might * Make sure the binder_alloc is fully initialized, otherwise we might
* read inconsistent state. * read inconsistent state.
*/ */
if (binder_alloc_get_vma(alloc) != NULL) {
mmap_read_lock(alloc->vma_vm_mm);
if (binder_alloc_get_vma(alloc) == NULL) {
mmap_read_unlock(alloc->vma_vm_mm);
goto uninitialized;
}
mmap_read_unlock(alloc->vma_vm_mm);
for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) {
page = &alloc->pages[i]; page = &alloc->pages[i];
if (!page->page_ptr) if (!page->page_ptr)
@@ -932,7 +942,8 @@ void binder_alloc_print_pages(struct seq_file *m,
else else
lru++; lru++;
} }
}
uninitialized:
mutex_unlock(&alloc->mutex); mutex_unlock(&alloc->mutex);
seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); seq_printf(m, " pages: %d:%d:%d\n", active, lru, free);
seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high); seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high);

View File

@@ -45,7 +45,7 @@ static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj,
return n; return n;
} }
static BIN_ATTR_RO(cpumap, 0); static BIN_ATTR_RO(cpumap, CPUMAP_FILE_MAX_BYTES);
static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj, static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
@@ -66,7 +66,7 @@ static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj,
return n; return n;
} }
static BIN_ATTR_RO(cpulist, 0); static BIN_ATTR_RO(cpulist, CPULIST_FILE_MAX_BYTES);
/** /**
* struct node_access_nodes - Access class device to hold user visible * struct node_access_nodes - Access class device to hold user visible

View File

@@ -52,39 +52,39 @@ define_id_show_func(core_id);
static DEVICE_ATTR_RO(core_id); static DEVICE_ATTR_RO(core_id);
define_siblings_read_func(thread_siblings, sibling_cpumask); define_siblings_read_func(thread_siblings, sibling_cpumask);
static BIN_ATTR_RO(thread_siblings, 0); static BIN_ATTR_RO(thread_siblings, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(thread_siblings_list, 0); static BIN_ATTR_RO(thread_siblings_list, CPULIST_FILE_MAX_BYTES);
define_siblings_read_func(core_cpus, sibling_cpumask); define_siblings_read_func(core_cpus, sibling_cpumask);
static BIN_ATTR_RO(core_cpus, 0); static BIN_ATTR_RO(core_cpus, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(core_cpus_list, 0); static BIN_ATTR_RO(core_cpus_list, CPULIST_FILE_MAX_BYTES);
define_siblings_read_func(core_siblings, core_cpumask); define_siblings_read_func(core_siblings, core_cpumask);
static BIN_ATTR_RO(core_siblings, 0); static BIN_ATTR_RO(core_siblings, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(core_siblings_list, 0); static BIN_ATTR_RO(core_siblings_list, CPULIST_FILE_MAX_BYTES);
define_siblings_read_func(die_cpus, die_cpumask); define_siblings_read_func(die_cpus, die_cpumask);
static BIN_ATTR_RO(die_cpus, 0); static BIN_ATTR_RO(die_cpus, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(die_cpus_list, 0); static BIN_ATTR_RO(die_cpus_list, CPULIST_FILE_MAX_BYTES);
define_siblings_read_func(package_cpus, core_cpumask); define_siblings_read_func(package_cpus, core_cpumask);
static BIN_ATTR_RO(package_cpus, 0); static BIN_ATTR_RO(package_cpus, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(package_cpus_list, 0); static BIN_ATTR_RO(package_cpus_list, CPULIST_FILE_MAX_BYTES);
#ifdef CONFIG_SCHED_BOOK #ifdef CONFIG_SCHED_BOOK
define_id_show_func(book_id); define_id_show_func(book_id);
static DEVICE_ATTR_RO(book_id); static DEVICE_ATTR_RO(book_id);
define_siblings_read_func(book_siblings, book_cpumask); define_siblings_read_func(book_siblings, book_cpumask);
static BIN_ATTR_RO(book_siblings, 0); static BIN_ATTR_RO(book_siblings, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(book_siblings_list, 0); static BIN_ATTR_RO(book_siblings_list, CPULIST_FILE_MAX_BYTES);
#endif #endif
#ifdef CONFIG_SCHED_DRAWER #ifdef CONFIG_SCHED_DRAWER
define_id_show_func(drawer_id); define_id_show_func(drawer_id);
static DEVICE_ATTR_RO(drawer_id); static DEVICE_ATTR_RO(drawer_id);
define_siblings_read_func(drawer_siblings, drawer_cpumask); define_siblings_read_func(drawer_siblings, drawer_cpumask);
static BIN_ATTR_RO(drawer_siblings, 0); static BIN_ATTR_RO(drawer_siblings, CPUMAP_FILE_MAX_BYTES);
static BIN_ATTR_RO(drawer_siblings_list, 0); static BIN_ATTR_RO(drawer_siblings_list, CPULIST_FILE_MAX_BYTES);
#endif #endif
static struct bin_attribute *bin_attrs[] = { static struct bin_attribute *bin_attrs[] = {

View File

@@ -1154,6 +1154,11 @@ loop_set_status_from_info(struct loop_device *lo,
lo->lo_offset = info->lo_offset; lo->lo_offset = info->lo_offset;
lo->lo_sizelimit = info->lo_sizelimit; lo->lo_sizelimit = info->lo_sizelimit;
/* loff_t vars have been assigned __u64 */
if (lo->lo_offset < 0 || lo->lo_sizelimit < 0)
return -EOVERFLOW;
memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
lo->lo_file_name[LO_NAME_SIZE-1] = 0; lo->lo_file_name[LO_NAME_SIZE-1] = 0;

View File

@@ -820,6 +820,15 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict,
if (ret == 0) { if (ret == 0) {
ret = nouveau_fence_new(chan, false, &fence); ret = nouveau_fence_new(chan, false, &fence);
if (ret == 0) { if (ret == 0) {
/* TODO: figure out a better solution here
*
* wait on the fence here explicitly as going through
* ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
*
* Without this the operation can timeout and we'll fallback to a
* software copy, which might take several minutes to finish.
*/
nouveau_fence_wait(fence, false, false);
ret = ttm_bo_move_accel_cleanup(bo, ret = ttm_bo_move_accel_cleanup(bo,
&fence->base, &fence->base,
evict, false, evict, false,

File diff suppressed because it is too large Load Diff

View File

@@ -6251,11 +6251,11 @@ static void mddev_detach(struct mddev *mddev)
static void __md_stop(struct mddev *mddev) static void __md_stop(struct mddev *mddev)
{ {
struct md_personality *pers = mddev->pers; struct md_personality *pers = mddev->pers;
md_bitmap_destroy(mddev);
mddev_detach(mddev); mddev_detach(mddev);
/* Ensure ->event_work is done */ /* Ensure ->event_work is done */
if (mddev->event_work.func) if (mddev->event_work.func)
flush_workqueue(md_misc_wq); flush_workqueue(md_misc_wq);
md_bitmap_destroy(mddev);
spin_lock(&mddev->lock); spin_lock(&mddev->lock);
mddev->pers = NULL; mddev->pers = NULL;
spin_unlock(&mddev->lock); spin_unlock(&mddev->lock);
@@ -6272,6 +6272,7 @@ void md_stop(struct mddev *mddev)
/* stop the array and free an attached data structures. /* stop the array and free an attached data structures.
* This is called from dm-raid * This is called from dm-raid
*/ */
__md_stop_writes(mddev);
__md_stop(mddev); __md_stop(mddev);
bioset_exit(&mddev->bio_set); bioset_exit(&mddev->bio_set);
bioset_exit(&mddev->sync_set); bioset_exit(&mddev->sync_set);

View File

@@ -2007,12 +2007,7 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
*/ */
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
{ {
/* check that the bond is not initialized yet */
if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
bond->dev->dev_addr)) {
BOND_AD_INFO(bond).aggregator_identifier = 0; BOND_AD_INFO(bond).aggregator_identifier = 0;
BOND_AD_INFO(bond).system.sys_priority = BOND_AD_INFO(bond).system.sys_priority =
bond->params.ad_actor_sys_prio; bond->params.ad_actor_sys_prio;
if (is_zero_ether_addr(bond->params.ad_actor_system)) if (is_zero_ether_addr(bond->params.ad_actor_system))
@@ -2030,7 +2025,6 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
bond_3ad_initiate_agg_selection(bond, bond_3ad_initiate_agg_selection(bond,
AD_AGGREGATOR_SELECTION_TIMER * AD_AGGREGATOR_SELECTION_TIMER *
ad_ticks_per_sec); ad_ticks_per_sec);
}
} }
/** /**

View File

@@ -623,7 +623,7 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs, bool reset)
hw_resc->max_stat_ctxs -= le16_to_cpu(req->min_stat_ctx) * n; hw_resc->max_stat_ctxs -= le16_to_cpu(req->min_stat_ctx) * n;
hw_resc->max_vnics -= le16_to_cpu(req->min_vnics) * n; hw_resc->max_vnics -= le16_to_cpu(req->min_vnics) * n;
if (bp->flags & BNXT_FLAG_CHIP_P5) if (bp->flags & BNXT_FLAG_CHIP_P5)
hw_resc->max_irqs -= vf_msix * n; hw_resc->max_nqs -= vf_msix;
rc = pf->active_vfs; rc = pf->active_vfs;
} }

View File

@@ -4385,7 +4385,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
(struct in6_addr *)&ipv6_full_mask)) (struct in6_addr *)&ipv6_full_mask))
new_mask |= I40E_L3_V6_DST_MASK; new_mask |= I40E_L3_V6_DST_MASK;
else if (ipv6_addr_any((struct in6_addr *) else if (ipv6_addr_any((struct in6_addr *)
&usr_ip6_spec->ip6src)) &usr_ip6_spec->ip6dst))
new_mask &= ~I40E_L3_V6_DST_MASK; new_mask &= ~I40E_L3_V6_DST_MASK;
else else
return -EOPNOTSUPP; return -EOPNOTSUPP;

View File

@@ -321,6 +321,19 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
bool if_running, pool_present = !!pool; bool if_running, pool_present = !!pool;
int ret = 0, pool_failure = 0; int ret = 0, pool_failure = 0;
if (qid >= vsi->num_rxq || qid >= vsi->num_txq) {
netdev_err(vsi->netdev, "Please use queue id in scope of combined queues count\n");
pool_failure = -EINVAL;
goto failure;
}
if (!is_power_of_2(vsi->rx_rings[qid]->count) ||
!is_power_of_2(vsi->tx_rings[qid]->count)) {
netdev_err(vsi->netdev, "Please align ring sizes to power of 2\n");
pool_failure = -EINVAL;
goto failure;
}
if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi); if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi);
if (if_running) { if (if_running) {
@@ -343,6 +356,7 @@ xsk_pool_if_up:
netdev_err(vsi->netdev, "ice_qp_ena error = %d\n", ret); netdev_err(vsi->netdev, "ice_qp_ena error = %d\n", ret);
} }
failure:
if (pool_failure) { if (pool_failure) {
netdev_err(vsi->netdev, "Could not %sable buffer pool, error = %d\n", netdev_err(vsi->netdev, "Could not %sable buffer pool, error = %d\n",
pool_present ? "en" : "dis", pool_failure); pool_present ? "en" : "dis", pool_failure);

View File

@@ -1212,7 +1212,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
struct cyclecounter cc; struct cyclecounter cc;
unsigned long flags; unsigned long flags;
u32 incval = 0; u32 incval = 0;
u32 tsauxc = 0;
u32 fuse0 = 0; u32 fuse0 = 0;
/* For some of the boards below this mask is technically incorrect. /* For some of the boards below this mask is technically incorrect.
@@ -1247,18 +1246,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
case ixgbe_mac_x550em_a: case ixgbe_mac_x550em_a:
case ixgbe_mac_X550: case ixgbe_mac_X550:
cc.read = ixgbe_ptp_read_X550; cc.read = ixgbe_ptp_read_X550;
/* enable SYSTIME counter */
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
IXGBE_WRITE_FLUSH(hw);
break; break;
case ixgbe_mac_X540: case ixgbe_mac_X540:
cc.read = ixgbe_ptp_read_82599; cc.read = ixgbe_ptp_read_82599;
@@ -1290,6 +1277,50 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
spin_unlock_irqrestore(&adapter->tmreg_lock, flags); spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
} }
/**
* ixgbe_ptp_init_systime - Initialize SYSTIME registers
* @adapter: the ixgbe private board structure
*
* Initialize and start the SYSTIME registers.
*/
static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 tsauxc;
switch (hw->mac.type) {
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
case ixgbe_mac_X550:
tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
/* Reset SYSTIME registers to 0 */
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
/* Reset interrupt settings */
IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
/* Activate the SYSTIME counter */
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
break;
case ixgbe_mac_X540:
case ixgbe_mac_82599EB:
/* Reset SYSTIME registers to 0 */
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
break;
default:
/* Other devices aren't supported */
return;
};
IXGBE_WRITE_FLUSH(hw);
}
/** /**
* ixgbe_ptp_reset * ixgbe_ptp_reset
* @adapter: the ixgbe private board structure * @adapter: the ixgbe private board structure
@@ -1316,6 +1347,8 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
ixgbe_ptp_start_cyclecounter(adapter); ixgbe_ptp_start_cyclecounter(adapter);
ixgbe_ptp_init_systime(adapter);
spin_lock_irqsave(&adapter->tmreg_lock, flags); spin_lock_irqsave(&adapter->tmreg_lock, flags);
timecounter_init(&adapter->hw_tc, &adapter->hw_cc, timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
ktime_to_ns(ktime_get_real())); ktime_to_ns(ktime_get_real()));

View File

@@ -3325,7 +3325,9 @@ static int set_feature_hw_tc(struct net_device *netdev, bool enable)
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
if (!enable && mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD))) { int tc_flag = mlx5e_is_uplink_rep(priv) ? MLX5_TC_FLAG(ESW_OFFLOAD) :
MLX5_TC_FLAG(NIC_OFFLOAD);
if (!enable && mlx5e_tc_num_filters(priv, tc_flag)) {
netdev_err(netdev, netdev_err(netdev,
"Active offloaded tc filters, can't turn hw_tc_offload off\n"); "Active offloaded tc filters, can't turn hw_tc_offload off\n");
return -EINVAL; return -EINVAL;
@@ -4350,14 +4352,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
/* RQ */ /* RQ */
mlx5e_build_rq_params(mdev, params); mlx5e_build_rq_params(mdev, params);
/* HW LRO */
if (MLX5_CAP_ETH(mdev, lro_cap) &&
params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
/* No XSK params: checking the availability of striding RQ in general. */
if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL))
params->packet_merge.type = slow_pci_heuristic(mdev) ?
MLX5E_PACKET_MERGE_NONE : MLX5E_PACKET_MERGE_LRO;
}
params->packet_merge.timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT); params->packet_merge.timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
/* CQ moderation params */ /* CQ moderation params */

View File

@@ -618,6 +618,8 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
params->mqprio.num_tc = 1; params->mqprio.num_tc = 1;
params->tunneled_offload_en = false; params->tunneled_offload_en = false;
if (rep->vport != MLX5_VPORT_UPLINK)
params->vlan_strip_disable = true;
/* Set an initial non-zero value, so that mlx5e_select_queue won't /* Set an initial non-zero value, so that mlx5e_select_queue won't
* divide by zero if called before first activating channels. * divide by zero if called before first activating channels.

View File

@@ -1427,7 +1427,9 @@ int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
memcpy(&dev->profile, &profile[profile_idx], sizeof(dev->profile)); memcpy(&dev->profile, &profile[profile_idx], sizeof(dev->profile));
INIT_LIST_HEAD(&priv->ctx_list); INIT_LIST_HEAD(&priv->ctx_list);
spin_lock_init(&priv->ctx_lock); spin_lock_init(&priv->ctx_lock);
lockdep_register_key(&dev->lock_key);
mutex_init(&dev->intf_state_mutex); mutex_init(&dev->intf_state_mutex);
lockdep_set_class(&dev->intf_state_mutex, &dev->lock_key);
mutex_init(&priv->bfregs.reg_head.lock); mutex_init(&priv->bfregs.reg_head.lock);
mutex_init(&priv->bfregs.wc_head.lock); mutex_init(&priv->bfregs.wc_head.lock);
@@ -1474,6 +1476,7 @@ err_health_init:
mutex_destroy(&priv->bfregs.wc_head.lock); mutex_destroy(&priv->bfregs.wc_head.lock);
mutex_destroy(&priv->bfregs.reg_head.lock); mutex_destroy(&priv->bfregs.reg_head.lock);
mutex_destroy(&dev->intf_state_mutex); mutex_destroy(&dev->intf_state_mutex);
lockdep_unregister_key(&dev->lock_key);
return err; return err;
} }
@@ -1491,6 +1494,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev)
mutex_destroy(&priv->bfregs.wc_head.lock); mutex_destroy(&priv->bfregs.wc_head.lock);
mutex_destroy(&priv->bfregs.reg_head.lock); mutex_destroy(&priv->bfregs.reg_head.lock);
mutex_destroy(&dev->intf_state_mutex); mutex_destroy(&dev->intf_state_mutex);
lockdep_unregister_key(&dev->lock_key);
} }
static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)

View File

@@ -74,11 +74,6 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
static void moxart_mac_free_memory(struct net_device *ndev) static void moxart_mac_free_memory(struct net_device *ndev)
{ {
struct moxart_mac_priv_t *priv = netdev_priv(ndev); struct moxart_mac_priv_t *priv = netdev_priv(ndev);
int i;
for (i = 0; i < RX_DESC_NUM; i++)
dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i],
priv->rx_buf_size, DMA_FROM_DEVICE);
if (priv->tx_desc_base) if (priv->tx_desc_base)
dma_free_coherent(&priv->pdev->dev, dma_free_coherent(&priv->pdev->dev,
@@ -193,6 +188,7 @@ static int moxart_mac_open(struct net_device *ndev)
static int moxart_mac_stop(struct net_device *ndev) static int moxart_mac_stop(struct net_device *ndev)
{ {
struct moxart_mac_priv_t *priv = netdev_priv(ndev); struct moxart_mac_priv_t *priv = netdev_priv(ndev);
int i;
napi_disable(&priv->napi); napi_disable(&priv->napi);
@@ -204,6 +200,11 @@ static int moxart_mac_stop(struct net_device *ndev)
/* disable all functions */ /* disable all functions */
writel(0, priv->base + REG_MAC_CTRL); writel(0, priv->base + REG_MAC_CTRL);
/* unmap areas mapped in moxart_mac_setup_desc_ring() */
for (i = 0; i < RX_DESC_NUM; i++)
dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i],
priv->rx_buf_size, DMA_FROM_DEVICE);
return 0; return 0;
} }

View File

@@ -1692,8 +1692,67 @@ static int ionic_set_features(struct net_device *netdev,
return err; return err;
} }
static int ionic_set_attr_mac(struct ionic_lif *lif, u8 *mac)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.lif_setattr = {
.opcode = IONIC_CMD_LIF_SETATTR,
.index = cpu_to_le16(lif->index),
.attr = IONIC_LIF_ATTR_MAC,
},
};
ether_addr_copy(ctx.cmd.lif_setattr.mac, mac);
return ionic_adminq_post_wait(lif, &ctx);
}
static int ionic_get_attr_mac(struct ionic_lif *lif, u8 *mac_addr)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.lif_getattr = {
.opcode = IONIC_CMD_LIF_GETATTR,
.index = cpu_to_le16(lif->index),
.attr = IONIC_LIF_ATTR_MAC,
},
};
int err;
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
ether_addr_copy(mac_addr, ctx.comp.lif_getattr.mac);
return 0;
}
static int ionic_program_mac(struct ionic_lif *lif, u8 *mac)
{
u8 get_mac[ETH_ALEN];
int err;
err = ionic_set_attr_mac(lif, mac);
if (err)
return err;
err = ionic_get_attr_mac(lif, get_mac);
if (err)
return err;
/* To deal with older firmware that silently ignores the set attr mac:
* doesn't actually change the mac and doesn't return an error, so we
* do the get attr to verify whether or not the set actually happened
*/
if (!ether_addr_equal(get_mac, mac))
return 1;
return 0;
}
static int ionic_set_mac_address(struct net_device *netdev, void *sa) static int ionic_set_mac_address(struct net_device *netdev, void *sa)
{ {
struct ionic_lif *lif = netdev_priv(netdev);
struct sockaddr *addr = sa; struct sockaddr *addr = sa;
u8 *mac; u8 *mac;
int err; int err;
@@ -1702,6 +1761,14 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
if (ether_addr_equal(netdev->dev_addr, mac)) if (ether_addr_equal(netdev->dev_addr, mac))
return 0; return 0;
err = ionic_program_mac(lif, mac);
if (err < 0)
return err;
if (err > 0)
netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
__func__);
err = eth_prepare_mac_addr_change(netdev, addr); err = eth_prepare_mac_addr_change(netdev, addr);
if (err) if (err)
return err; return err;
@@ -2974,11 +3041,10 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
netif_device_detach(lif->netdev); netif_device_detach(lif->netdev);
mutex_lock(&lif->queue_lock);
if (test_bit(IONIC_LIF_F_UP, lif->state)) { if (test_bit(IONIC_LIF_F_UP, lif->state)) {
dev_info(ionic->dev, "Surprise FW stop, stopping queues\n"); dev_info(ionic->dev, "Surprise FW stop, stopping queues\n");
mutex_lock(&lif->queue_lock);
ionic_stop_queues(lif); ionic_stop_queues(lif);
mutex_unlock(&lif->queue_lock);
} }
if (netif_running(lif->netdev)) { if (netif_running(lif->netdev)) {
@@ -2989,6 +3055,8 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
ionic_reset(ionic); ionic_reset(ionic);
ionic_qcqs_free(lif); ionic_qcqs_free(lif);
mutex_unlock(&lif->queue_lock);
dev_info(ionic->dev, "FW Down: LIFs stopped\n"); dev_info(ionic->dev, "FW Down: LIFs stopped\n");
} }
@@ -3012,9 +3080,15 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
err = ionic_port_init(ionic); err = ionic_port_init(ionic);
if (err) if (err)
goto err_out; goto err_out;
mutex_lock(&lif->queue_lock);
if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
dev_info(ionic->dev, "FW Up: clearing broken state\n");
err = ionic_qcqs_alloc(lif); err = ionic_qcqs_alloc(lif);
if (err) if (err)
goto err_out; goto err_unlock;
err = ionic_lif_init(lif); err = ionic_lif_init(lif);
if (err) if (err)
@@ -3035,6 +3109,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
goto err_txrx_free; goto err_txrx_free;
} }
mutex_unlock(&lif->queue_lock);
clear_bit(IONIC_LIF_F_FW_RESET, lif->state); clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
ionic_link_status_check_request(lif, CAN_SLEEP); ionic_link_status_check_request(lif, CAN_SLEEP);
netif_device_attach(lif->netdev); netif_device_attach(lif->netdev);
@@ -3051,6 +3127,8 @@ err_lifs_deinit:
ionic_lif_deinit(lif); ionic_lif_deinit(lif);
err_qcqs_free: err_qcqs_free:
ionic_qcqs_free(lif); ionic_qcqs_free(lif);
err_unlock:
mutex_unlock(&lif->queue_lock);
err_out: err_out:
dev_err(ionic->dev, "FW Up: LIFs restart failed - err %d\n", err); dev_err(ionic->dev, "FW Up: LIFs restart failed - err %d\n", err);
} }
@@ -3215,6 +3293,7 @@ static int ionic_station_set(struct ionic_lif *lif)
.attr = IONIC_LIF_ATTR_MAC, .attr = IONIC_LIF_ATTR_MAC,
}, },
}; };
u8 mac_address[ETH_ALEN];
struct sockaddr addr; struct sockaddr addr;
int err; int err;
@@ -3223,8 +3302,23 @@ static int ionic_station_set(struct ionic_lif *lif)
return err; return err;
netdev_dbg(lif->netdev, "found initial MAC addr %pM\n", netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
ctx.comp.lif_getattr.mac); ctx.comp.lif_getattr.mac);
if (is_zero_ether_addr(ctx.comp.lif_getattr.mac)) ether_addr_copy(mac_address, ctx.comp.lif_getattr.mac);
if (is_zero_ether_addr(mac_address)) {
eth_hw_addr_random(netdev);
netdev_dbg(netdev, "Random Mac generated: %pM\n", netdev->dev_addr);
ether_addr_copy(mac_address, netdev->dev_addr);
err = ionic_program_mac(lif, mac_address);
if (err < 0)
return err;
if (err > 0) {
netdev_dbg(netdev, "%s:SET/GET ATTR Mac are not same-due to old FW running\n",
__func__);
return 0; return 0;
}
}
if (!is_zero_ether_addr(netdev->dev_addr)) { if (!is_zero_ether_addr(netdev->dev_addr)) {
/* If the netdev mac is non-zero and doesn't match the default /* If the netdev mac is non-zero and doesn't match the default
@@ -3232,12 +3326,11 @@ static int ionic_station_set(struct ionic_lif *lif)
* likely here again after a fw-upgrade reset. We need to be * likely here again after a fw-upgrade reset. We need to be
* sure the netdev mac is in our filter list. * sure the netdev mac is in our filter list.
*/ */
if (!ether_addr_equal(ctx.comp.lif_getattr.mac, if (!ether_addr_equal(mac_address, netdev->dev_addr))
netdev->dev_addr))
ionic_lif_addr_add(lif, netdev->dev_addr); ionic_lif_addr_add(lif, netdev->dev_addr);
} else { } else {
/* Update the netdev mac with the device's mac */ /* Update the netdev mac with the device's mac */
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); ether_addr_copy(addr.sa_data, mac_address);
addr.sa_family = AF_INET; addr.sa_family = AF_INET;
err = eth_prepare_mac_addr_change(netdev, &addr); err = eth_prepare_mac_addr_change(netdev, &addr);
if (err) { if (err) {

View File

@@ -395,8 +395,8 @@ try_again:
ionic_opcode_to_str(opcode), opcode, ionic_opcode_to_str(opcode), opcode,
ionic_error_to_str(err), err); ionic_error_to_str(err), err);
msleep(1000);
iowrite32(0, &idev->dev_cmd_regs->done); iowrite32(0, &idev->dev_cmd_regs->done);
msleep(1000);
iowrite32(1, &idev->dev_cmd_regs->doorbell); iowrite32(1, &idev->dev_cmd_regs->doorbell);
goto try_again; goto try_again;
} }
@@ -409,6 +409,8 @@ try_again:
return ionic_error_to_errno(err); return ionic_error_to_errno(err);
} }
ionic_dev_cmd_clean(ionic);
return 0; return 0;
} }

View File

@@ -258,13 +258,17 @@ EXPORT_SYMBOL_GPL(stmmac_set_mac_addr);
/* Enable disable MAC RX/TX */ /* Enable disable MAC RX/TX */
void stmmac_set_mac(void __iomem *ioaddr, bool enable) void stmmac_set_mac(void __iomem *ioaddr, bool enable)
{ {
u32 value = readl(ioaddr + MAC_CTRL_REG); u32 old_val, value;
old_val = readl(ioaddr + MAC_CTRL_REG);
value = old_val;
if (enable) if (enable)
value |= MAC_ENABLE_RX | MAC_ENABLE_TX; value |= MAC_ENABLE_RX | MAC_ENABLE_TX;
else else
value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX); value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX);
if (value != old_val)
writel(value, ioaddr + MAC_CTRL_REG); writel(value, ioaddr + MAC_CTRL_REG);
} }

View File

@@ -1083,10 +1083,10 @@ static void stmmac_mac_link_up(struct phylink_config *config,
bool tx_pause, bool rx_pause) bool tx_pause, bool rx_pause)
{ {
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
u32 ctrl; u32 old_ctrl, ctrl;
ctrl = readl(priv->ioaddr + MAC_CTRL_REG); old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
ctrl &= ~priv->hw->link.speed_mask; ctrl = old_ctrl & ~priv->hw->link.speed_mask;
if (interface == PHY_INTERFACE_MODE_USXGMII) { if (interface == PHY_INTERFACE_MODE_USXGMII) {
switch (speed) { switch (speed) {
@@ -1161,6 +1161,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
if (tx_pause && rx_pause) if (tx_pause && rx_pause)
stmmac_mac_flow_ctrl(priv, duplex); stmmac_mac_flow_ctrl(priv, duplex);
if (ctrl != old_ctrl)
writel(ctrl, priv->ioaddr + MAC_CTRL_REG); writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
stmmac_mac_set(priv, priv->ioaddr, true); stmmac_mac_set(priv, priv->ioaddr, true);

View File

@@ -1325,7 +1325,7 @@ static void cas_init_rx_dma(struct cas *cp)
writel(val, cp->regs + REG_RX_PAGE_SIZE); writel(val, cp->regs + REG_RX_PAGE_SIZE);
/* enable the header parser if desired */ /* enable the header parser if desired */
if (CAS_HP_FIRMWARE == cas_prog_null) if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0])
return; return;
val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS); val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS);
@@ -3794,7 +3794,7 @@ static void cas_reset(struct cas *cp, int blkflag)
/* program header parser */ /* program header parser */
if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) ||
(CAS_HP_ALT_FIRMWARE == cas_prog_null)) { (&CAS_HP_ALT_FIRMWARE[0] == &cas_prog_null[0])) {
cas_load_firmware(cp, CAS_HP_FIRMWARE); cas_load_firmware(cp, CAS_HP_FIRMWARE);
} else { } else {
cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE);

View File

@@ -570,7 +570,7 @@ static int ipa_smem_init(struct ipa *ipa, u32 item, size_t size)
} }
/* Align the address down and the size up to a page boundary */ /* Align the address down and the size up to a page boundary */
addr = qcom_smem_virt_to_phys(virt) & PAGE_MASK; addr = qcom_smem_virt_to_phys(virt);
phys = addr & PAGE_MASK; phys = addr & PAGE_MASK;
size = PAGE_ALIGN(size + addr - phys); size = PAGE_ALIGN(size + addr - phys);
iova = phys; /* We just want a direct mapping */ iova = phys; /* We just want a direct mapping */

View File

@@ -787,7 +787,7 @@ static int ipvlan_device_event(struct notifier_block *unused,
case NETDEV_CHANGEADDR: case NETDEV_CHANGEADDR:
list_for_each_entry(ipvlan, &port->ipvlans, pnode) { list_for_each_entry(ipvlan, &port->ipvlans, pnode) {
ether_addr_copy(ipvlan->dev->dev_addr, dev->dev_addr); eth_hw_addr_set(ipvlan->dev, dev->dev_addr);
call_netdevice_notifiers(NETDEV_CHANGEADDR, ipvlan->dev); call_netdevice_notifiers(NETDEV_CHANGEADDR, ipvlan->dev);
} }
break; break;

View File

@@ -194,7 +194,7 @@ static struct notifier_block ipvtap_notifier_block __read_mostly = {
.notifier_call = ipvtap_device_event, .notifier_call = ipvtap_device_event,
}; };
static int ipvtap_init(void) static int __init ipvtap_init(void)
{ {
int err; int err;
@@ -228,7 +228,7 @@ out1:
} }
module_init(ipvtap_init); module_init(ipvtap_init);
static void ipvtap_exit(void) static void __exit ipvtap_exit(void)
{ {
rtnl_link_unregister(&ipvtap_link_ops); rtnl_link_unregister(&ipvtap_link_ops);
unregister_netdevice_notifier(&ipvtap_notifier_block); unregister_netdevice_notifier(&ipvtap_notifier_block);

View File

@@ -447,11 +447,6 @@ static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *skb)
return (struct macsec_eth_header *)skb_mac_header(skb); return (struct macsec_eth_header *)skb_mac_header(skb);
} }
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
{
return make_sci(dev->dev_addr, port);
}
static void __macsec_pn_wrapped(struct macsec_secy *secy, static void __macsec_pn_wrapped(struct macsec_secy *secy,
struct macsec_tx_sa *tx_sa) struct macsec_tx_sa *tx_sa)
{ {
@@ -3616,8 +3611,7 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
dev_uc_del(real_dev, dev->dev_addr); dev_uc_del(real_dev, dev->dev_addr);
out: out:
ether_addr_copy(dev->dev_addr, addr->sa_data); eth_hw_addr_set(dev, addr->sa_data);
macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES);
/* If h/w offloading is available, propagate to the device */ /* If h/w offloading is available, propagate to the device */
if (macsec_is_offloaded(macsec)) { if (macsec_is_offloaded(macsec)) {
@@ -3953,6 +3947,11 @@ static bool sci_exists(struct net_device *dev, sci_t sci)
return false; return false;
} }
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
{
return make_sci(dev->dev_addr, port);
}
static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
{ {
struct macsec_dev *macsec = macsec_priv(dev); struct macsec_dev *macsec = macsec_priv(dev);

View File

@@ -711,7 +711,7 @@ static int macvlan_sync_address(struct net_device *dev, unsigned char *addr)
if (!(dev->flags & IFF_UP)) { if (!(dev->flags & IFF_UP)) {
/* Just copy in the new address */ /* Just copy in the new address */
ether_addr_copy(dev->dev_addr, addr); eth_hw_addr_set(dev, addr);
} else { } else {
/* Rehash and update the device filters */ /* Rehash and update the device filters */
if (macvlan_addr_busy(vlan->port, addr)) if (macvlan_addr_busy(vlan->port, addr))

View File

@@ -315,11 +315,11 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
phydev->suspended_by_mdio_bus = 0; phydev->suspended_by_mdio_bus = 0;
/* If we managed to get here with the PHY state machine in a state other /* If we manged to get here with the PHY state machine in a state neither
* than PHY_HALTED this is an indication that something went wrong and * PHY_HALTED nor PHY_READY this is an indication that something went wrong
* we should most likely be using MAC managed PM and we are not. * and we should most likely be using MAC managed PM and we are not.
*/ */
WARN_ON(phydev->state != PHY_HALTED && !phydev->mac_managed_pm); WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY);
ret = phy_init_hw(phydev); ret = phy_init_hw(phydev);
if (ret < 0) if (ret < 0)

View File

@@ -5904,6 +5904,11 @@ static void r8153_enter_oob(struct r8152 *tp)
ocp_data &= ~NOW_IS_OOB; ocp_data &= ~NOW_IS_OOB;
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
/* RX FIFO settings for OOB */
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB);
rtl_disable(tp); rtl_disable(tp);
rtl_reset_bmu(tp); rtl_reset_bmu(tp);
@@ -6429,21 +6434,8 @@ static void r8156_fc_parameter(struct r8152 *tp)
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
switch (tp->version) {
case RTL_VER_10:
case RTL_VER_11:
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8);
break;
case RTL_VER_12:
case RTL_VER_13:
case RTL_VER_15:
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
break;
default:
break;
}
} }
static void rtl8156_change_mtu(struct r8152 *tp) static void rtl8156_change_mtu(struct r8152 *tp)
@@ -6555,6 +6547,11 @@ static void rtl8156_down(struct r8152 *tp)
ocp_data &= ~NOW_IS_OOB; ocp_data &= ~NOW_IS_OOB;
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
/* RX FIFO settings for OOB */
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16);
rtl_disable(tp); rtl_disable(tp);
rtl_reset_bmu(tp); rtl_reset_bmu(tp);

View File

@@ -18,8 +18,6 @@
#include <linux/usb/usbnet.h> #include <linux/usb/usbnet.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/mdio.h> #include <linux/mdio.h>
#include <linux/phy.h> #include <linux/phy.h>
#include "smsc95xx.h" #include "smsc95xx.h"
@@ -54,9 +52,6 @@
SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3)
#define MAC_ADDR_LEN (6) #define MAC_ADDR_LEN (6)
#define SMSC95XX_NR_IRQS (1) /* raise to 12 for GPIOs */
#define PHY_HWIRQ (SMSC95XX_NR_IRQS - 1)
struct smsc95xx_priv { struct smsc95xx_priv {
u32 mac_cr; u32 mac_cr;
u32 hash_hi; u32 hash_hi;
@@ -65,12 +60,8 @@ struct smsc95xx_priv {
spinlock_t mac_cr_lock; spinlock_t mac_cr_lock;
u8 features; u8 features;
u8 suspend_flags; u8 suspend_flags;
struct irq_chip irqchip;
struct irq_domain *irqdomain;
struct fwnode_handle *irqfwnode;
struct mii_bus *mdiobus; struct mii_bus *mdiobus;
struct phy_device *phydev; struct phy_device *phydev;
struct task_struct *pm_task;
}; };
static bool turbo_mode = true; static bool turbo_mode = true;
@@ -92,14 +83,13 @@ MODULE_PARM_DESC(macaddr, "MAC address");
static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data, int in_pm) u32 *data, int in_pm)
{ {
struct smsc95xx_priv *pdata = dev->driver_priv;
u32 buf; u32 buf;
int ret; int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
BUG_ON(!dev); BUG_ON(!dev);
if (current != pdata->pm_task) if (!in_pm)
fn = usbnet_read_cmd; fn = usbnet_read_cmd;
else else
fn = usbnet_read_cmd_nopm; fn = usbnet_read_cmd_nopm;
@@ -123,14 +113,13 @@ static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index, static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index,
u32 data, int in_pm) u32 data, int in_pm)
{ {
struct smsc95xx_priv *pdata = dev->driver_priv;
u32 buf; u32 buf;
int ret; int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
BUG_ON(!dev); BUG_ON(!dev);
if (current != pdata->pm_task) if (!in_pm)
fn = usbnet_write_cmd; fn = usbnet_write_cmd;
else else
fn = usbnet_write_cmd_nopm; fn = usbnet_write_cmd_nopm;
@@ -619,8 +608,6 @@ static void smsc95xx_mac_update_fullduplex(struct usbnet *dev)
static void smsc95xx_status(struct usbnet *dev, struct urb *urb) static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
{ {
struct smsc95xx_priv *pdata = dev->driver_priv;
unsigned long flags;
u32 intdata; u32 intdata;
if (urb->actual_length != 4) { if (urb->actual_length != 4) {
@@ -632,15 +619,11 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
intdata = get_unaligned_le32(urb->transfer_buffer); intdata = get_unaligned_le32(urb->transfer_buffer);
netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
local_irq_save(flags);
if (intdata & INT_ENP_PHY_INT_) if (intdata & INT_ENP_PHY_INT_)
generic_handle_domain_irq(pdata->irqdomain, PHY_HWIRQ); ;
else else
netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n",
intdata); intdata);
local_irq_restore(flags);
} }
/* Enable or disable Tx & Rx checksum offload engines */ /* Enable or disable Tx & Rx checksum offload engines */
@@ -1153,9 +1136,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{ {
struct smsc95xx_priv *pdata; struct smsc95xx_priv *pdata;
bool is_internal_phy; bool is_internal_phy;
char usb_path[64];
int ret, phy_irq;
u32 val; u32 val;
int ret;
printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
@@ -1195,38 +1177,10 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
if (ret) if (ret)
goto free_pdata; goto free_pdata;
/* create irq domain for use by PHY driver and GPIO consumers */
usb_make_path(dev->udev, usb_path, sizeof(usb_path));
pdata->irqfwnode = irq_domain_alloc_named_fwnode(usb_path);
if (!pdata->irqfwnode) {
ret = -ENOMEM;
goto free_pdata;
}
pdata->irqdomain = irq_domain_create_linear(pdata->irqfwnode,
SMSC95XX_NR_IRQS,
&irq_domain_simple_ops,
pdata);
if (!pdata->irqdomain) {
ret = -ENOMEM;
goto free_irqfwnode;
}
phy_irq = irq_create_mapping(pdata->irqdomain, PHY_HWIRQ);
if (!phy_irq) {
ret = -ENOENT;
goto remove_irqdomain;
}
pdata->irqchip = dummy_irq_chip;
pdata->irqchip.name = SMSC_CHIPNAME;
irq_set_chip_and_handler_name(phy_irq, &pdata->irqchip,
handle_simple_irq, "phy");
pdata->mdiobus = mdiobus_alloc(); pdata->mdiobus = mdiobus_alloc();
if (!pdata->mdiobus) { if (!pdata->mdiobus) {
ret = -ENOMEM; ret = -ENOMEM;
goto dispose_irq; goto free_pdata;
} }
ret = smsc95xx_read_reg(dev, HW_CFG, &val); ret = smsc95xx_read_reg(dev, HW_CFG, &val);
@@ -1259,7 +1213,6 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
goto unregister_mdio; goto unregister_mdio;
} }
pdata->phydev->irq = phy_irq;
pdata->phydev->is_internal = is_internal_phy; pdata->phydev->is_internal = is_internal_phy;
/* detect device revision as different features may be available */ /* detect device revision as different features may be available */
@@ -1302,15 +1255,6 @@ unregister_mdio:
free_mdio: free_mdio:
mdiobus_free(pdata->mdiobus); mdiobus_free(pdata->mdiobus);
dispose_irq:
irq_dispose_mapping(phy_irq);
remove_irqdomain:
irq_domain_remove(pdata->irqdomain);
free_irqfwnode:
irq_domain_free_fwnode(pdata->irqfwnode);
free_pdata: free_pdata:
kfree(pdata); kfree(pdata);
return ret; return ret;
@@ -1323,9 +1267,6 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
phy_disconnect(dev->net->phydev); phy_disconnect(dev->net->phydev);
mdiobus_unregister(pdata->mdiobus); mdiobus_unregister(pdata->mdiobus);
mdiobus_free(pdata->mdiobus); mdiobus_free(pdata->mdiobus);
irq_dispose_mapping(irq_find_mapping(pdata->irqdomain, PHY_HWIRQ));
irq_domain_remove(pdata->irqdomain);
irq_domain_free_fwnode(pdata->irqfwnode);
netif_dbg(dev, ifdown, dev->net, "free pdata\n"); netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata); kfree(pdata);
} }
@@ -1350,6 +1291,29 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter)
return crc << ((filter % 2) * 16); return crc << ((filter % 2) * 16);
} }
static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask)
{
int ret;
netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n");
/* read to clear */
ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC);
if (ret < 0)
return ret;
/* enable interrupt source */
ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK);
if (ret < 0)
return ret;
ret |= mask;
smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret);
return 0;
}
static int smsc95xx_link_ok_nopm(struct usbnet *dev) static int smsc95xx_link_ok_nopm(struct usbnet *dev)
{ {
int ret; int ret;
@@ -1516,6 +1480,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev)
static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
{ {
struct smsc95xx_priv *pdata = dev->driver_priv; struct smsc95xx_priv *pdata = dev->driver_priv;
int ret;
if (!netif_running(dev->net)) { if (!netif_running(dev->net)) {
/* interface is ifconfig down so fully power down hw */ /* interface is ifconfig down so fully power down hw */
@@ -1534,10 +1499,27 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
} }
netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n");
/* enable PHY wakeup events for if cable is attached */
ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
PHY_INT_MASK_ANEG_COMP_);
if (ret < 0) {
netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
return ret;
}
netdev_info(dev->net, "entering SUSPEND1 mode\n"); netdev_info(dev->net, "entering SUSPEND1 mode\n");
return smsc95xx_enter_suspend1(dev); return smsc95xx_enter_suspend1(dev);
} }
/* enable PHY wakeup events so we remote wakeup if cable is pulled */
ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
PHY_INT_MASK_LINK_DOWN_);
if (ret < 0) {
netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
return ret;
}
netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n");
return smsc95xx_enter_suspend3(dev); return smsc95xx_enter_suspend3(dev);
} }
@@ -1549,12 +1531,9 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
u32 val, link_up; u32 val, link_up;
int ret; int ret;
pdata->pm_task = current;
ret = usbnet_suspend(intf, message); ret = usbnet_suspend(intf, message);
if (ret < 0) { if (ret < 0) {
netdev_warn(dev->net, "usbnet_suspend error\n"); netdev_warn(dev->net, "usbnet_suspend error\n");
pdata->pm_task = NULL;
return ret; return ret;
} }
@@ -1606,6 +1585,13 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
} }
if (pdata->wolopts & WAKE_PHY) { if (pdata->wolopts & WAKE_PHY) {
ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
(PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_));
if (ret < 0) {
netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
goto done;
}
/* if link is down then configure EDPD and enter SUSPEND1, /* if link is down then configure EDPD and enter SUSPEND1,
* otherwise enter SUSPEND0 below * otherwise enter SUSPEND0 below
*/ */
@@ -1794,7 +1780,6 @@ done:
if (ret && PMSG_IS_AUTO(message)) if (ret && PMSG_IS_AUTO(message))
usbnet_resume(intf); usbnet_resume(intf);
pdata->pm_task = NULL;
return ret; return ret;
} }
@@ -1815,53 +1800,45 @@ static int smsc95xx_resume(struct usb_interface *intf)
/* do this first to ensure it's cleared even in error case */ /* do this first to ensure it's cleared even in error case */
pdata->suspend_flags = 0; pdata->suspend_flags = 0;
pdata->pm_task = current;
if (suspend_flags & SUSPEND_ALLMODES) { if (suspend_flags & SUSPEND_ALLMODES) {
/* clear wake-up sources */ /* clear wake-up sources */
ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
if (ret < 0) if (ret < 0)
goto done; return ret;
val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_); val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
if (ret < 0) if (ret < 0)
goto done; return ret;
/* clear wake-up status */ /* clear wake-up status */
ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
if (ret < 0) if (ret < 0)
goto done; return ret;
val &= ~PM_CTL_WOL_EN_; val &= ~PM_CTL_WOL_EN_;
val |= PM_CTL_WUPS_; val |= PM_CTL_WUPS_;
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
if (ret < 0) if (ret < 0)
goto done; return ret;
} }
phy_init_hw(pdata->phydev);
ret = usbnet_resume(intf); ret = usbnet_resume(intf);
if (ret < 0) if (ret < 0)
netdev_warn(dev->net, "usbnet_resume error\n"); netdev_warn(dev->net, "usbnet_resume error\n");
done: phy_init_hw(pdata->phydev);
pdata->pm_task = NULL;
return ret; return ret;
} }
static int smsc95xx_reset_resume(struct usb_interface *intf) static int smsc95xx_reset_resume(struct usb_interface *intf)
{ {
struct usbnet *dev = usb_get_intfdata(intf); struct usbnet *dev = usb_get_intfdata(intf);
struct smsc95xx_priv *pdata = dev->driver_priv;
int ret; int ret;
pdata->pm_task = current;
ret = smsc95xx_reset(dev); ret = smsc95xx_reset(dev);
pdata->pm_task = NULL;
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@@ -2386,9 +2386,6 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
"Just Read IQK Matrix reg for channel:%d....\n", "Just Read IQK Matrix reg for channel:%d....\n",
channel); channel);
if ((rtlphy->iqk_matrix[indexforchannel].
value[0] != NULL)
/*&&(regea4 != 0) */)
_rtl92d_phy_patha_fill_iqk_matrix(hw, true, _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
rtlphy->iqk_matrix[ rtlphy->iqk_matrix[
indexforchannel].value, 0, indexforchannel].value, 0,

View File

@@ -310,6 +310,7 @@ static void pn532_uart_remove(struct serdev_device *serdev)
pn53x_unregister_nfc(pn532->priv); pn53x_unregister_nfc(pn532->priv);
serdev_device_close(serdev); serdev_device_close(serdev);
pn53x_common_clean(pn532->priv); pn53x_common_clean(pn532->priv);
del_timer_sync(&pn532->cmd_timeout);
kfree_skb(pn532->recv_skb); kfree_skb(pn532->recv_skb);
kfree(pn532); kfree(pn532);
} }

View File

@@ -34,8 +34,7 @@ static int validate_conv_zones_cb(struct blk_zone *z,
bool nvmet_bdev_zns_enable(struct nvmet_ns *ns) bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
{ {
struct request_queue *q = ns->bdev->bd_disk->queue; u8 zasl = nvmet_zasl(bdev_max_zone_append_sectors(ns->bdev));
u8 zasl = nvmet_zasl(queue_max_zone_append_sectors(q));
struct gendisk *bd_disk = ns->bdev->bd_disk; struct gendisk *bd_disk = ns->bdev->bd_disk;
int ret; int ret;

View File

@@ -192,6 +192,8 @@ extern int ql2xfulldump_on_mpifail;
extern int ql2xsecenable; extern int ql2xsecenable;
extern int ql2xenforce_iocb_limit; extern int ql2xenforce_iocb_limit;
extern int ql2xabts_wait_nvme; extern int ql2xabts_wait_nvme;
extern int ql2xrspq_follow_inptr;
extern int ql2xrspq_follow_inptr_legacy;
extern int qla2x00_loop_reset(scsi_qla_host_t *); extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);

View File

@@ -3707,12 +3707,11 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
* Return: 0 all iocbs has arrived, xx- all iocbs have not arrived. * Return: 0 all iocbs has arrived, xx- all iocbs have not arrived.
*/ */
static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha, static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
struct rsp_que *rsp, response_t *pkt) struct rsp_que *rsp, response_t *pkt, u32 rsp_q_in)
{ {
int start_pkt_ring_index, end_pkt_ring_index, n_ring_index; int start_pkt_ring_index;
response_t *end_pkt; u32 iocb_cnt = 0;
int rc = 0; int rc = 0;
u32 rsp_q_in;
if (pkt->entry_count == 1) if (pkt->entry_count == 1)
return rc; return rc;
@@ -3723,34 +3722,18 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
else else
start_pkt_ring_index = rsp->ring_index - 1; start_pkt_ring_index = rsp->ring_index - 1;
if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length) if (rsp_q_in < start_pkt_ring_index)
end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - /* q in ptr is wrapped */
rsp->length - 1; iocb_cnt = rsp->length - start_pkt_ring_index + rsp_q_in;
else else
end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1; iocb_cnt = rsp_q_in - start_pkt_ring_index;
end_pkt = rsp->ring + end_pkt_ring_index; if (iocb_cnt < pkt->entry_count)
/* next pkt = end_pkt + 1 */
n_ring_index = end_pkt_ring_index + 1;
if (n_ring_index >= rsp->length)
n_ring_index = 0;
rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr :
rd_reg_dword(rsp->rsp_q_in);
/* rsp_q_in is either wrapped or pointing beyond endpkt */
if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) ||
rsp_q_in >= n_ring_index)
/* all IOCBs arrived. */
rc = 0;
else
rc = -EIO; rc = -EIO;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091, ql_dbg(ql_dbg_init, vha, 0x5091,
"%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n", "%s - ring %p pkt %p entry count %d iocb_cnt %d rsp_q_in %d rc %d\n",
__func__, rsp->ring, pkt, end_pkt, pkt->entry_count, __func__, rsp->ring, pkt, pkt->entry_count, iocb_cnt, rsp_q_in, rc);
rsp_q_in, rc);
return rc; return rc;
} }
@@ -3767,6 +3750,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct purex_entry_24xx *purex_entry; struct purex_entry_24xx *purex_entry;
struct purex_item *pure_item; struct purex_item *pure_item;
u16 rsp_in = 0, cur_ring_index;
int follow_inptr, is_shadow_hba;
if (!ha->flags.fw_started) if (!ha->flags.fw_started)
return; return;
@@ -3776,8 +3761,27 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
qla_cpu_update(rsp->qpair, smp_processor_id()); qla_cpu_update(rsp->qpair, smp_processor_id());
} }
while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { #define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \
do { \
if (_update) { \
_rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \
rd_reg_dword_relaxed((_rsp)->rsp_q_in); \
} \
} while (0)
is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha);
follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr :
ql2xrspq_follow_inptr_legacy;
__update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in);
while ((likely(follow_inptr &&
rsp->ring_index != rsp_in &&
rsp->ring_ptr->signature != RESPONSE_PROCESSED)) ||
(!follow_inptr &&
rsp->ring_ptr->signature != RESPONSE_PROCESSED)) {
pkt = (struct sts_entry_24xx *)rsp->ring_ptr; pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
cur_ring_index = rsp->ring_index;
rsp->ring_index++; rsp->ring_index++;
if (rsp->ring_index == rsp->length) { if (rsp->ring_index == rsp->length) {
@@ -3889,6 +3893,8 @@ process_err:
} }
pure_item = qla27xx_copy_fpin_pkt(vha, pure_item = qla27xx_copy_fpin_pkt(vha,
(void **)&pkt, &rsp); (void **)&pkt, &rsp);
__update_rsp_in(follow_inptr, is_shadow_hba,
rsp, rsp_in);
if (!pure_item) if (!pure_item)
break; break;
qla24xx_queue_purex_item(vha, pure_item, qla24xx_queue_purex_item(vha, pure_item,
@@ -3896,7 +3902,17 @@ process_err:
break; break;
case ELS_AUTH_ELS: case ELS_AUTH_ELS:
if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) { if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt, rsp_in)) {
/*
* ring_ptr and ring_index were
* pre-incremented above. Reset them
* back to current. Wait for next
* interrupt with all IOCBs to arrive
* and re-process.
*/
rsp->ring_ptr = (response_t *)pkt;
rsp->ring_index = cur_ring_index;
ql_dbg(ql_dbg_init, vha, 0x5091, ql_dbg(ql_dbg_init, vha, 0x5091,
"Defer processing ELS opcode %#x...\n", "Defer processing ELS opcode %#x...\n",
purex_entry->els_frame_payload[3]); purex_entry->els_frame_payload[3]);

View File

@@ -338,6 +338,16 @@ module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling, MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling,
"Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n"); "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n");
int ql2xrspq_follow_inptr = 1;
module_param(ql2xrspq_follow_inptr, int, 0644);
MODULE_PARM_DESC(ql2xrspq_follow_inptr,
"Follow RSP IN pointer for RSP updates for HBAs 27xx and newer (default: 1).");
int ql2xrspq_follow_inptr_legacy = 1;
module_param(ql2xrspq_follow_inptr_legacy, int, 0644);
MODULE_PARM_DESC(ql2xrspq_follow_inptr_legacy,
"Follow RSP IN pointer for RSP updates for HBAs older than 27XX. (default: 1).");
static void qla2x00_clear_drv_active(struct qla_hw_data *); static void qla2x00_clear_drv_active(struct qla_hw_data *);
static void qla2x00_free_device(scsi_qla_host_t *); static void qla2x00_free_device(scsi_qla_host_t *);
static int qla2xxx_map_queues(struct Scsi_Host *shost); static int qla2xxx_map_queues(struct Scsi_Host *shost);

View File

@@ -2093,7 +2093,7 @@ static int storvsc_probe(struct hv_device *device,
*/ */
host_dev->handle_error_wq = host_dev->handle_error_wq =
alloc_ordered_workqueue("storvsc_error_wq_%d", alloc_ordered_workqueue("storvsc_error_wq_%d",
WQ_MEM_RECLAIM, 0,
host->host_no); host->host_no);
if (!host_dev->handle_error_wq) { if (!host_dev->handle_error_wq) {
ret = -ENOMEM; ret = -ENOMEM;

View File

@@ -133,11 +133,7 @@ static inline u32 ufshci_version(u32 major, u32 minor)
#define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK) #define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK)
#define UFSHCD_ERROR_MASK (UIC_ERROR |\ #define UFSHCD_ERROR_MASK (UIC_ERROR | INT_FATAL_ERRORS)
DEVICE_FATAL_ERROR |\
CONTROLLER_FATAL_ERROR |\
SYSTEM_BUS_FATAL_ERROR |\
CRYPTO_ENGINE_FATAL_ERROR)
#define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ #define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\
CONTROLLER_FATAL_ERROR |\ CONTROLLER_FATAL_ERROR |\

View File

@@ -2413,15 +2413,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par; struct fbcon_ops *ops = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num]; struct fbcon_display *p = &fb_display[vc->vc_num];
int resize; int resize, ret, old_userfont, old_width, old_height, old_charcount;
char *old_data = NULL; char *old_data = NULL;
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
if (p->userfont) if (p->userfont)
old_data = vc->vc_font.data; old_data = vc->vc_font.data;
vc->vc_font.data = (void *)(p->fontdata = data); vc->vc_font.data = (void *)(p->fontdata = data);
old_userfont = p->userfont;
if ((p->userfont = userfont)) if ((p->userfont = userfont))
REFCOUNT(data)++; REFCOUNT(data)++;
old_width = vc->vc_font.width;
old_height = vc->vc_font.height;
old_charcount = vc->vc_font.charcount;
vc->vc_font.width = w; vc->vc_font.width = w;
vc->vc_font.height = h; vc->vc_font.height = h;
vc->vc_font.charcount = charcount; vc->vc_font.charcount = charcount;
@@ -2437,7 +2443,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
cols /= w; cols /= w;
rows /= h; rows /= h;
vc_resize(vc, cols, rows); ret = vc_resize(vc, cols, rows);
if (ret)
goto err_out;
} else if (con_is_visible(vc) } else if (con_is_visible(vc)
&& vc->vc_mode == KD_TEXT) { && vc->vc_mode == KD_TEXT) {
fbcon_clear_margins(vc, 0); fbcon_clear_margins(vc, 0);
@@ -2447,6 +2455,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
if (old_data && (--REFCOUNT(old_data) == 0)) if (old_data && (--REFCOUNT(old_data) == 0))
kfree(old_data - FONT_EXTRA_WORDS * sizeof(int)); kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
return 0; return 0;
err_out:
p->fontdata = old_data;
vc->vc_font.data = (void *)old_data;
if (userfont) {
p->userfont = old_userfont;
REFCOUNT(data)--;
}
vc->vc_font.width = old_width;
vc->vc_font.height = old_height;
vc->vc_font.charcount = old_charcount;
return ret;
} }
/* /*

View File

@@ -581,27 +581,30 @@ static int lock_pages(
struct privcmd_dm_op_buf kbufs[], unsigned int num, struct privcmd_dm_op_buf kbufs[], unsigned int num,
struct page *pages[], unsigned int nr_pages, unsigned int *pinned) struct page *pages[], unsigned int nr_pages, unsigned int *pinned)
{ {
unsigned int i; unsigned int i, off = 0;
for (i = 0; i < num; i++) { for (i = 0; i < num; ) {
unsigned int requested; unsigned int requested;
int page_count; int page_count;
requested = DIV_ROUND_UP( requested = DIV_ROUND_UP(
offset_in_page(kbufs[i].uptr) + kbufs[i].size, offset_in_page(kbufs[i].uptr) + kbufs[i].size,
PAGE_SIZE); PAGE_SIZE) - off;
if (requested > nr_pages) if (requested > nr_pages)
return -ENOSPC; return -ENOSPC;
page_count = pin_user_pages_fast( page_count = pin_user_pages_fast(
(unsigned long) kbufs[i].uptr, (unsigned long)kbufs[i].uptr + off * PAGE_SIZE,
requested, FOLL_WRITE, pages); requested, FOLL_WRITE, pages);
if (page_count < 0) if (page_count <= 0)
return page_count; return page_count ? : -EFAULT;
*pinned += page_count; *pinned += page_count;
nr_pages -= page_count; nr_pages -= page_count;
pages += page_count; pages += page_count;
off = (requested == page_count) ? 0 : off + page_count;
i += !off;
} }
return 0; return 0;
@@ -677,10 +680,8 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
} }
rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned); rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned);
if (rc < 0) { if (rc < 0)
nr_pages = pinned;
goto out; goto out;
}
for (i = 0; i < kdata.num; i++) { for (i = 0; i < kdata.num; i++) {
set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr); set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr);
@@ -692,7 +693,7 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
xen_preemptible_hcall_end(); xen_preemptible_hcall_end();
out: out:
unlock_pages(pages, nr_pages); unlock_pages(pages, pinned);
kfree(xbufs); kfree(xbufs);
kfree(pages); kfree(pages);
kfree(kbufs); kfree(kbufs);

View File

@@ -13,6 +13,13 @@
#include "ordered-data.h" #include "ordered-data.h"
#include "delayed-inode.h" #include "delayed-inode.h"
/*
* Since we search a directory based on f_pos (struct dir_context::pos) we have
* to start at 2 since '.' and '..' have f_pos of 0 and 1 respectively, so
* everybody else has to start at 2 (see btrfs_real_readdir() and dir_emit_dots()).
*/
#define BTRFS_DIR_START_INDEX 2
/* /*
* ordered_data_close is set by truncate when a file that used * ordered_data_close is set by truncate when a file that used
* to have good data has been truncated to zero. When it is set * to have good data has been truncated to zero. When it is set
@@ -164,8 +171,9 @@ struct btrfs_inode {
u64 disk_i_size; u64 disk_i_size;
/* /*
* if this is a directory then index_cnt is the counter for the index * If this is a directory then index_cnt is the counter for the index
* number for new files that are created * number for new files that are created. For an empty directory, this
* must be initialized to BTRFS_DIR_START_INDEX.
*/ */
u64 index_cnt; u64 index_cnt;

View File

@@ -105,14 +105,6 @@ struct btrfs_ref;
#define BTRFS_STAT_CURR 0 #define BTRFS_STAT_CURR 0
#define BTRFS_STAT_PREV 1 #define BTRFS_STAT_PREV 1
/*
* Count how many BTRFS_MAX_EXTENT_SIZE cover the @size
*/
static inline u32 count_max_extents(u64 size)
{
return div_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, BTRFS_MAX_EXTENT_SIZE);
}
static inline unsigned long btrfs_chunk_item_size(int num_stripes) static inline unsigned long btrfs_chunk_item_size(int num_stripes)
{ {
BUG_ON(num_stripes == 0); BUG_ON(num_stripes == 0);
@@ -999,6 +991,12 @@ struct btrfs_fs_info {
u32 csums_per_leaf; u32 csums_per_leaf;
u32 stripesize; u32 stripesize;
/*
* Maximum size of an extent. BTRFS_MAX_EXTENT_SIZE on regular
* filesystem, on zoned it depends on the device constraints.
*/
u64 max_extent_size;
/* Block groups and devices containing active swapfiles. */ /* Block groups and devices containing active swapfiles. */
spinlock_t swapfile_pins_lock; spinlock_t swapfile_pins_lock;
struct rb_root swapfile_pins; struct rb_root swapfile_pins;
@@ -1017,6 +1015,8 @@ struct btrfs_fs_info {
u64 zoned; u64 zoned;
}; };
/* Max size to emit ZONE_APPEND write command */
u64 max_zone_append_size;
struct mutex zoned_meta_io_lock; struct mutex zoned_meta_io_lock;
spinlock_t treelog_bg_lock; spinlock_t treelog_bg_lock;
u64 treelog_bg; u64 treelog_bg;
@@ -3870,6 +3870,19 @@ static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)
return fs_info->zoned != 0; return fs_info->zoned != 0;
} }
/*
* Count how many fs_info->max_extent_size cover the @size
*/
static inline u32 count_max_extents(struct btrfs_fs_info *fs_info, u64 size)
{
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
if (!fs_info)
return div_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, BTRFS_MAX_EXTENT_SIZE);
#endif
return div_u64(size + fs_info->max_extent_size - 1, fs_info->max_extent_size);
}
static inline bool btrfs_is_data_reloc_root(const struct btrfs_root *root) static inline bool btrfs_is_data_reloc_root(const struct btrfs_root *root)
{ {
return root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID; return root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID;

View File

@@ -273,7 +273,7 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
u64 num_bytes, u64 *meta_reserve, u64 num_bytes, u64 *meta_reserve,
u64 *qgroup_reserve) u64 *qgroup_reserve)
{ {
u64 nr_extents = count_max_extents(num_bytes); u64 nr_extents = count_max_extents(fs_info, num_bytes);
u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, num_bytes); u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, num_bytes);
u64 inode_update = btrfs_calc_metadata_size(fs_info, 1); u64 inode_update = btrfs_calc_metadata_size(fs_info, 1);
@@ -347,7 +347,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
* needs to free the reservation we just made. * needs to free the reservation we just made.
*/ */
spin_lock(&inode->lock); spin_lock(&inode->lock);
nr_extents = count_max_extents(num_bytes); nr_extents = count_max_extents(fs_info, num_bytes);
btrfs_mod_outstanding_extents(inode, nr_extents); btrfs_mod_outstanding_extents(inode, nr_extents);
inode->csum_bytes += num_bytes; inode->csum_bytes += num_bytes;
btrfs_calculate_inode_block_rsv_size(fs_info, inode); btrfs_calculate_inode_block_rsv_size(fs_info, inode);
@@ -410,7 +410,7 @@ void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes)
unsigned num_extents; unsigned num_extents;
spin_lock(&inode->lock); spin_lock(&inode->lock);
num_extents = count_max_extents(num_bytes); num_extents = count_max_extents(fs_info, num_bytes);
btrfs_mod_outstanding_extents(inode, -num_extents); btrfs_mod_outstanding_extents(inode, -num_extents);
btrfs_calculate_inode_block_rsv_size(fs_info, inode); btrfs_calculate_inode_block_rsv_size(fs_info, inode);
spin_unlock(&inode->lock); spin_unlock(&inode->lock);

View File

@@ -165,7 +165,7 @@ no_valid_dev_replace_entry_found:
*/ */
if (btrfs_find_device(fs_info->fs_devices, &args)) { if (btrfs_find_device(fs_info->fs_devices, &args)) {
btrfs_err(fs_info, btrfs_err(fs_info,
"replace devid present without an active replace item"); "replace without active item, run 'device scan --forget' on the target device");
ret = -EUCLEAN; ret = -EUCLEAN;
} else { } else {
dev_replace->srcdev = NULL; dev_replace->srcdev = NULL;
@@ -1151,8 +1151,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
up_write(&dev_replace->rwsem); up_write(&dev_replace->rwsem);
/* Scrub for replace must not be running in suspended state */ /* Scrub for replace must not be running in suspended state */
ret = btrfs_scrub_cancel(fs_info); btrfs_scrub_cancel(fs_info);
ASSERT(ret != -ENOTCONN);
trans = btrfs_start_transaction(root, 0); trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans)) { if (IS_ERR(trans)) {

View File

@@ -3006,6 +3006,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
fs_info->sectorsize_bits = ilog2(4096); fs_info->sectorsize_bits = ilog2(4096);
fs_info->stripesize = 4096; fs_info->stripesize = 4096;
fs_info->max_extent_size = BTRFS_MAX_EXTENT_SIZE;
spin_lock_init(&fs_info->swapfile_pins_lock); spin_lock_init(&fs_info->swapfile_pins_lock);
fs_info->swapfile_pins = RB_ROOT; fs_info->swapfile_pins = RB_ROOT;

View File

@@ -1985,8 +1985,10 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
struct page *locked_page, u64 *start, struct page *locked_page, u64 *start,
u64 *end) u64 *end)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
u64 max_bytes = BTRFS_MAX_EXTENT_SIZE; /* The sanity tests may not set a valid fs_info. */
u64 max_bytes = fs_info ? fs_info->max_extent_size : BTRFS_MAX_EXTENT_SIZE;
u64 delalloc_start; u64 delalloc_start;
u64 delalloc_end; u64 delalloc_end;
bool found; bool found;
@@ -3778,10 +3780,11 @@ static void update_nr_written(struct writeback_control *wbc,
*/ */
static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode, static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
struct page *page, struct writeback_control *wbc, struct page *page, struct writeback_control *wbc,
u64 delalloc_start, unsigned long *nr_written) unsigned long *nr_written)
{ {
u64 page_end = delalloc_start + PAGE_SIZE - 1; u64 page_end = page_offset(page) + PAGE_SIZE - 1;
bool found; bool found;
u64 delalloc_start = page_offset(page);
u64 delalloc_to_write = 0; u64 delalloc_to_write = 0;
u64 delalloc_end = 0; u64 delalloc_end = 0;
int ret; int ret;
@@ -4066,8 +4069,8 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
struct extent_page_data *epd) struct extent_page_data *epd)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
u64 start = page_offset(page); const u64 page_start = page_offset(page);
u64 page_end = start + PAGE_SIZE - 1; const u64 page_end = page_start + PAGE_SIZE - 1;
int ret; int ret;
int nr = 0; int nr = 0;
size_t pg_offset; size_t pg_offset;
@@ -4102,8 +4105,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
} }
if (!epd->extent_locked) { if (!epd->extent_locked) {
ret = writepage_delalloc(BTRFS_I(inode), page, wbc, start, ret = writepage_delalloc(BTRFS_I(inode), page, wbc, &nr_written);
&nr_written);
if (ret == 1) if (ret == 1)
return 0; return 0;
if (ret) if (ret)
@@ -4153,7 +4155,7 @@ done:
* capable of that. * capable of that.
*/ */
if (PageError(page)) if (PageError(page))
end_extent_writepage(page, ret, start, page_end); end_extent_writepage(page, ret, page_start, page_end);
unlock_page(page); unlock_page(page);
ASSERT(ret <= 0); ASSERT(ret <= 0);
return ret; return ret;

View File

@@ -2032,6 +2032,7 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
void btrfs_split_delalloc_extent(struct inode *inode, void btrfs_split_delalloc_extent(struct inode *inode,
struct extent_state *orig, u64 split) struct extent_state *orig, u64 split)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
u64 size; u64 size;
/* not delalloc, ignore it */ /* not delalloc, ignore it */
@@ -2039,7 +2040,7 @@ void btrfs_split_delalloc_extent(struct inode *inode,
return; return;
size = orig->end - orig->start + 1; size = orig->end - orig->start + 1;
if (size > BTRFS_MAX_EXTENT_SIZE) { if (size > fs_info->max_extent_size) {
u32 num_extents; u32 num_extents;
u64 new_size; u64 new_size;
@@ -2048,10 +2049,10 @@ void btrfs_split_delalloc_extent(struct inode *inode,
* applies here, just in reverse. * applies here, just in reverse.
*/ */
new_size = orig->end - split + 1; new_size = orig->end - split + 1;
num_extents = count_max_extents(new_size); num_extents = count_max_extents(fs_info, new_size);
new_size = split - orig->start; new_size = split - orig->start;
num_extents += count_max_extents(new_size); num_extents += count_max_extents(fs_info, new_size);
if (count_max_extents(size) >= num_extents) if (count_max_extents(fs_info, size) >= num_extents)
return; return;
} }
@@ -2068,6 +2069,7 @@ void btrfs_split_delalloc_extent(struct inode *inode,
void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new, void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,
struct extent_state *other) struct extent_state *other)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
u64 new_size, old_size; u64 new_size, old_size;
u32 num_extents; u32 num_extents;
@@ -2081,7 +2083,7 @@ void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,
new_size = other->end - new->start + 1; new_size = other->end - new->start + 1;
/* we're not bigger than the max, unreserve the space and go */ /* we're not bigger than the max, unreserve the space and go */
if (new_size <= BTRFS_MAX_EXTENT_SIZE) { if (new_size <= fs_info->max_extent_size) {
spin_lock(&BTRFS_I(inode)->lock); spin_lock(&BTRFS_I(inode)->lock);
btrfs_mod_outstanding_extents(BTRFS_I(inode), -1); btrfs_mod_outstanding_extents(BTRFS_I(inode), -1);
spin_unlock(&BTRFS_I(inode)->lock); spin_unlock(&BTRFS_I(inode)->lock);
@@ -2107,10 +2109,10 @@ void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,
* this case. * this case.
*/ */
old_size = other->end - other->start + 1; old_size = other->end - other->start + 1;
num_extents = count_max_extents(old_size); num_extents = count_max_extents(fs_info, old_size);
old_size = new->end - new->start + 1; old_size = new->end - new->start + 1;
num_extents += count_max_extents(old_size); num_extents += count_max_extents(fs_info, old_size);
if (count_max_extents(new_size) >= num_extents) if (count_max_extents(fs_info, new_size) >= num_extents)
return; return;
spin_lock(&BTRFS_I(inode)->lock); spin_lock(&BTRFS_I(inode)->lock);
@@ -2189,7 +2191,7 @@ void btrfs_set_delalloc_extent(struct inode *inode, struct extent_state *state,
if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
u64 len = state->end + 1 - state->start; u64 len = state->end + 1 - state->start;
u32 num_extents = count_max_extents(len); u32 num_extents = count_max_extents(fs_info, len);
bool do_list = !btrfs_is_free_space_inode(BTRFS_I(inode)); bool do_list = !btrfs_is_free_space_inode(BTRFS_I(inode));
spin_lock(&BTRFS_I(inode)->lock); spin_lock(&BTRFS_I(inode)->lock);
@@ -2231,7 +2233,7 @@ void btrfs_clear_delalloc_extent(struct inode *vfs_inode,
struct btrfs_inode *inode = BTRFS_I(vfs_inode); struct btrfs_inode *inode = BTRFS_I(vfs_inode);
struct btrfs_fs_info *fs_info = btrfs_sb(vfs_inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(vfs_inode->i_sb);
u64 len = state->end + 1 - state->start; u64 len = state->end + 1 - state->start;
u32 num_extents = count_max_extents(len); u32 num_extents = count_max_extents(fs_info, len);
if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG)) { if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG)) {
spin_lock(&inode->lock); spin_lock(&inode->lock);
@@ -6394,14 +6396,8 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode)
goto out; goto out;
ret = 0; ret = 0;
/*
* MAGIC NUMBER EXPLANATION:
* since we search a directory based on f_pos we have to start at 2
* since '.' and '..' have f_pos of 0 and 1 respectively, so everybody
* else has to start at 2
*/
if (path->slots[0] == 0) { if (path->slots[0] == 0) {
inode->index_cnt = 2; inode->index_cnt = BTRFS_DIR_START_INDEX;
goto out; goto out;
} }
@@ -6412,7 +6408,7 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode)
if (found_key.objectid != btrfs_ino(inode) || if (found_key.objectid != btrfs_ino(inode) ||
found_key.type != BTRFS_DIR_INDEX_KEY) { found_key.type != BTRFS_DIR_INDEX_KEY) {
inode->index_cnt = 2; inode->index_cnt = BTRFS_DIR_START_INDEX;
goto out; goto out;
} }
@@ -6956,7 +6952,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
goto fail; goto fail;
} }
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent); btrfs_log_new_name(trans, old_dentry, NULL, parent);
} }
fail: fail:
@@ -9625,13 +9621,13 @@ static int btrfs_rename_exchange(struct inode *old_dir,
BTRFS_I(new_inode)->dir_index = new_idx; BTRFS_I(new_inode)->dir_index = new_idx;
if (root_log_pinned) { if (root_log_pinned) {
btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir), btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir),
new_dentry->d_parent); new_dentry->d_parent);
btrfs_end_log_trans(root); btrfs_end_log_trans(root);
root_log_pinned = false; root_log_pinned = false;
} }
if (dest_log_pinned) { if (dest_log_pinned) {
btrfs_log_new_name(trans, BTRFS_I(new_inode), BTRFS_I(new_dir), btrfs_log_new_name(trans, new_dentry, BTRFS_I(new_dir),
old_dentry->d_parent); old_dentry->d_parent);
btrfs_end_log_trans(dest); btrfs_end_log_trans(dest);
dest_log_pinned = false; dest_log_pinned = false;
@@ -9912,7 +9908,7 @@ static int btrfs_rename(struct user_namespace *mnt_userns,
BTRFS_I(old_inode)->dir_index = index; BTRFS_I(old_inode)->dir_index = index;
if (log_pinned) { if (log_pinned) {
btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir), btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir),
new_dentry->d_parent); new_dentry->d_parent);
btrfs_end_log_trans(root); btrfs_end_log_trans(root);
log_pinned = false; log_pinned = false;

View File

@@ -351,9 +351,10 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
key.offset = ref_id; key.offset = ref_id;
again: again:
ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
if (ret < 0) if (ret < 0) {
err = ret;
goto out; goto out;
if (ret == 0) { } else if (ret == 0) {
leaf = path->nodes[0]; leaf = path->nodes[0];
ref = btrfs_item_ptr(leaf, path->slots[0], ref = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_root_ref); struct btrfs_root_ref);

View File

@@ -6628,14 +6628,25 @@ void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
mutex_unlock(&dir->log_mutex); mutex_unlock(&dir->log_mutex);
} }
/* /**
* Call this after adding a new name for a file and it will properly * Update the log after adding a new name for an inode.
* update the log to reflect the new name. *
* @trans: Transaction handle.
* @old_dentry: The dentry associated with the old name and the old
* parent directory.
* @old_dir: The inode of the previous parent directory for the case
* of a rename. For a link operation, it must be NULL.
* @parent: The dentry associated with the directory under which the
* new name is located.
*
* Call this after adding a new name for an inode, as a result of a link or
* rename operation, and it will properly update the log to reflect the new name.
*/ */
void btrfs_log_new_name(struct btrfs_trans_handle *trans, void btrfs_log_new_name(struct btrfs_trans_handle *trans,
struct btrfs_inode *inode, struct btrfs_inode *old_dir, struct dentry *old_dentry, struct btrfs_inode *old_dir,
struct dentry *parent) struct dentry *parent)
{ {
struct btrfs_inode *inode = BTRFS_I(d_inode(old_dentry));
struct btrfs_log_ctx ctx; struct btrfs_log_ctx ctx;
/* /*

View File

@@ -84,7 +84,7 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans, void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
struct btrfs_inode *dir); struct btrfs_inode *dir);
void btrfs_log_new_name(struct btrfs_trans_handle *trans, void btrfs_log_new_name(struct btrfs_trans_handle *trans,
struct btrfs_inode *inode, struct btrfs_inode *old_dir, struct dentry *old_dentry, struct btrfs_inode *old_dir,
struct dentry *parent); struct dentry *parent);
#endif #endif

View File

@@ -2392,8 +2392,11 @@ int btrfs_get_dev_args_from_path(struct btrfs_fs_info *fs_info,
ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0, ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0,
&bdev, &disk_super); &bdev, &disk_super);
if (ret) if (ret) {
btrfs_put_dev_args_from_path(args);
return ret; return ret;
}
args->devid = btrfs_stack_device_id(&disk_super->dev_item); args->devid = btrfs_stack_device_id(&disk_super->dev_item);
memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE); memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE);
if (btrfs_fs_incompat(fs_info, METADATA_UUID)) if (btrfs_fs_incompat(fs_info, METADATA_UUID))

View File

@@ -391,6 +391,9 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
const char *name, const void *buffer, const char *name, const void *buffer,
size_t size, int flags) size_t size, int flags)
{ {
if (btrfs_root_readonly(BTRFS_I(inode)->root))
return -EROFS;
name = xattr_full_name(handler, name); name = xattr_full_name(handler, name);
return btrfs_setxattr_trans(inode, name, buffer, size, flags); return btrfs_setxattr_trans(inode, name, buffer, size, flags);
} }

View File

@@ -386,6 +386,16 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
nr_sectors = bdev_nr_sectors(bdev); nr_sectors = bdev_nr_sectors(bdev);
zone_info->zone_size_shift = ilog2(zone_info->zone_size); zone_info->zone_size_shift = ilog2(zone_info->zone_size);
zone_info->nr_zones = nr_sectors >> ilog2(zone_sectors); zone_info->nr_zones = nr_sectors >> ilog2(zone_sectors);
/*
* We limit max_zone_append_size also by max_segments *
* PAGE_SIZE. Technically, we can have multiple pages per segment. But,
* since btrfs adds the pages one by one to a bio, and btrfs cannot
* increase the metadata reservation even if it increases the number of
* extents, it is safe to stick with the limit.
*/
zone_info->max_zone_append_size =
min_t(u64, (u64)bdev_max_zone_append_sectors(bdev) << SECTOR_SHIFT,
(u64)bdev_max_segments(bdev) << PAGE_SHIFT);
if (!IS_ALIGNED(nr_sectors, zone_sectors)) if (!IS_ALIGNED(nr_sectors, zone_sectors))
zone_info->nr_zones++; zone_info->nr_zones++;
@@ -570,6 +580,7 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
u64 zoned_devices = 0; u64 zoned_devices = 0;
u64 nr_devices = 0; u64 nr_devices = 0;
u64 zone_size = 0; u64 zone_size = 0;
u64 max_zone_append_size = 0;
const bool incompat_zoned = btrfs_fs_incompat(fs_info, ZONED); const bool incompat_zoned = btrfs_fs_incompat(fs_info, ZONED);
int ret = 0; int ret = 0;
@@ -605,6 +616,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (!max_zone_append_size ||
(zone_info->max_zone_append_size &&
zone_info->max_zone_append_size < max_zone_append_size))
max_zone_append_size =
zone_info->max_zone_append_size;
} }
nr_devices++; nr_devices++;
} }
@@ -654,7 +670,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
} }
fs_info->zone_size = zone_size; fs_info->zone_size = zone_size;
fs_info->max_zone_append_size = ALIGN_DOWN(max_zone_append_size,
fs_info->sectorsize);
fs_info->fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_ZONED; fs_info->fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_ZONED;
if (fs_info->max_zone_append_size < fs_info->max_extent_size)
fs_info->max_extent_size = fs_info->max_zone_append_size;
/* /*
* Check mount options here, because we might change fs_info->zoned * Check mount options here, because we might change fs_info->zoned

View File

@@ -23,6 +23,7 @@ struct btrfs_zoned_device_info {
*/ */
u64 zone_size; u64 zone_size;
u8 zone_size_shift; u8 zone_size_shift;
u64 max_zone_append_size;
u32 nr_zones; u32 nr_zones;
unsigned long *seq_zones; unsigned long *seq_zones;
unsigned long *empty_zones; unsigned long *empty_zones;

View File

@@ -3599,7 +3599,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
loff_t offset, loff_t len) loff_t offset, loff_t len)
{ {
struct inode *inode; struct inode *inode = file_inode(file);
struct cifsFileInfo *cfile = file->private_data; struct cifsFileInfo *cfile = file->private_data;
struct file_zero_data_information fsctl_buf; struct file_zero_data_information fsctl_buf;
long rc; long rc;
@@ -3608,14 +3608,12 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
xid = get_xid(); xid = get_xid();
inode = d_inode(cfile->dentry); inode_lock(inode);
/* Need to make file sparse, if not already, before freeing range. */ /* Need to make file sparse, if not already, before freeing range. */
/* Consider adding equivalent for compressed since it could also work */ /* Consider adding equivalent for compressed since it could also work */
if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) { if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
free_xid(xid); goto out;
return rc;
} }
filemap_invalidate_lock(inode->i_mapping); filemap_invalidate_lock(inode->i_mapping);
@@ -3635,8 +3633,10 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
true /* is_fctl */, (char *)&fsctl_buf, true /* is_fctl */, (char *)&fsctl_buf,
sizeof(struct file_zero_data_information), sizeof(struct file_zero_data_information),
CIFSMaxBufSize, NULL, NULL); CIFSMaxBufSize, NULL, NULL);
free_xid(xid);
filemap_invalidate_unlock(inode->i_mapping); filemap_invalidate_unlock(inode->i_mapping);
out:
inode_unlock(inode);
free_xid(xid);
return rc; return rc;
} }

View File

@@ -134,10 +134,10 @@ static bool inode_io_list_move_locked(struct inode *inode,
static void wb_wakeup(struct bdi_writeback *wb) static void wb_wakeup(struct bdi_writeback *wb)
{ {
spin_lock_bh(&wb->work_lock); spin_lock_irq(&wb->work_lock);
if (test_bit(WB_registered, &wb->state)) if (test_bit(WB_registered, &wb->state))
mod_delayed_work(bdi_wq, &wb->dwork, 0); mod_delayed_work(bdi_wq, &wb->dwork, 0);
spin_unlock_bh(&wb->work_lock); spin_unlock_irq(&wb->work_lock);
} }
static void finish_writeback_work(struct bdi_writeback *wb, static void finish_writeback_work(struct bdi_writeback *wb,
@@ -164,7 +164,7 @@ static void wb_queue_work(struct bdi_writeback *wb,
if (work->done) if (work->done)
atomic_inc(&work->done->cnt); atomic_inc(&work->done->cnt);
spin_lock_bh(&wb->work_lock); spin_lock_irq(&wb->work_lock);
if (test_bit(WB_registered, &wb->state)) { if (test_bit(WB_registered, &wb->state)) {
list_add_tail(&work->list, &wb->work_list); list_add_tail(&work->list, &wb->work_list);
@@ -172,7 +172,7 @@ static void wb_queue_work(struct bdi_writeback *wb,
} else } else
finish_writeback_work(wb, work); finish_writeback_work(wb, work);
spin_unlock_bh(&wb->work_lock); spin_unlock_irq(&wb->work_lock);
} }
/** /**
@@ -2109,13 +2109,13 @@ static struct wb_writeback_work *get_next_work_item(struct bdi_writeback *wb)
{ {
struct wb_writeback_work *work = NULL; struct wb_writeback_work *work = NULL;
spin_lock_bh(&wb->work_lock); spin_lock_irq(&wb->work_lock);
if (!list_empty(&wb->work_list)) { if (!list_empty(&wb->work_list)) {
work = list_entry(wb->work_list.next, work = list_entry(wb->work_list.next,
struct wb_writeback_work, list); struct wb_writeback_work, list);
list_del_init(&work->list); list_del_init(&work->list);
} }
spin_unlock_bh(&wb->work_lock); spin_unlock_irq(&wb->work_lock);
return work; return work;
} }

View File

@@ -3720,7 +3720,12 @@ done:
copy_iov: copy_iov:
iov_iter_restore(iter, state); iov_iter_restore(iter, state);
ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
return ret ?: -EAGAIN; if (!ret) {
if (kiocb->ki_flags & IOCB_WRITE)
kiocb_end_write(req);
return -EAGAIN;
}
return ret;
} }
out_free: out_free:
/* it's reportedly faster than delegating the null check to kfree() */ /* it's reportedly faster than delegating the null check to kfree() */

View File

@@ -4168,6 +4168,13 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
err = -EPERM; err = -EPERM;
goto out_fput; goto out_fput;
} }
/* We're not controlling the target namespace. */
if (!ns_capable(mnt_userns, CAP_SYS_ADMIN)) {
err = -EPERM;
goto out_fput;
}
kattr->mnt_userns = get_user_ns(mnt_userns); kattr->mnt_userns = get_user_ns(mnt_userns);
out_fput: out_fput:

View File

@@ -319,7 +319,7 @@ static int read_name_gen = 1;
static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt, static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
struct nfs_fh *src_fh, nfs4_stateid *stateid) struct nfs_fh *src_fh, nfs4_stateid *stateid)
{ {
struct nfs_fattr fattr; struct nfs_fattr *fattr = nfs_alloc_fattr();
struct file *filep, *res; struct file *filep, *res;
struct nfs_server *server; struct nfs_server *server;
struct inode *r_ino = NULL; struct inode *r_ino = NULL;
@@ -330,14 +330,20 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
server = NFS_SERVER(ss_mnt->mnt_root->d_inode); server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
nfs_fattr_init(&fattr); if (!fattr)
return ERR_PTR(-ENOMEM);
status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL); status = nfs4_proc_getattr(server, src_fh, fattr, NULL, NULL);
if (status < 0) { if (status < 0) {
res = ERR_PTR(status); res = ERR_PTR(status);
goto out; goto out;
} }
if (!S_ISREG(fattr->mode)) {
res = ERR_PTR(-EBADF);
goto out;
}
res = ERR_PTR(-ENOMEM); res = ERR_PTR(-ENOMEM);
len = strlen(SSC_READ_NAME_BODY) + 16; len = strlen(SSC_READ_NAME_BODY) + 16;
read_name = kzalloc(len, GFP_NOFS); read_name = kzalloc(len, GFP_NOFS);
@@ -345,7 +351,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
goto out; goto out;
snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++); snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr, r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, fattr,
NULL); NULL);
if (IS_ERR(r_ino)) { if (IS_ERR(r_ino)) {
res = ERR_CAST(r_ino); res = ERR_CAST(r_ino);
@@ -356,6 +362,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
r_ino->i_fop); r_ino->i_fop);
if (IS_ERR(filep)) { if (IS_ERR(filep)) {
res = ERR_CAST(filep); res = ERR_CAST(filep);
iput(r_ino);
goto out_free_name; goto out_free_name;
} }
filep->f_mode |= FMODE_READ; filep->f_mode |= FMODE_READ;
@@ -390,6 +397,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
out_free_name: out_free_name:
kfree(read_name); kfree(read_name);
out: out:
nfs_free_fattr(fattr);
return res; return res;
out_stateowner: out_stateowner:
nfs4_put_state_owner(sp); nfs4_put_state_owner(sp);

View File

@@ -476,8 +476,7 @@ out:
} }
#ifdef CONFIG_NTFS3_FS_POSIX_ACL #ifdef CONFIG_NTFS3_FS_POSIX_ACL
static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns, static struct posix_acl *ntfs_get_acl_ex(struct inode *inode, int type,
struct inode *inode, int type,
int locked) int locked)
{ {
struct ntfs_inode *ni = ntfs_i(inode); struct ntfs_inode *ni = ntfs_i(inode);
@@ -512,7 +511,7 @@ static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns,
/* Translate extended attribute to acl. */ /* Translate extended attribute to acl. */
if (err >= 0) { if (err >= 0) {
acl = posix_acl_from_xattr(mnt_userns, buf, err); acl = posix_acl_from_xattr(&init_user_ns, buf, err);
} else if (err == -ENODATA) { } else if (err == -ENODATA) {
acl = NULL; acl = NULL;
} else { } else {
@@ -535,8 +534,7 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
if (rcu) if (rcu)
return ERR_PTR(-ECHILD); return ERR_PTR(-ECHILD);
/* TODO: init_user_ns? */ return ntfs_get_acl_ex(inode, type, 0);
return ntfs_get_acl_ex(&init_user_ns, inode, type, 0);
} }
static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns, static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
@@ -588,7 +586,7 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
value = kmalloc(size, GFP_NOFS); value = kmalloc(size, GFP_NOFS);
if (!value) if (!value)
return -ENOMEM; return -ENOMEM;
err = posix_acl_to_xattr(mnt_userns, acl, value, size); err = posix_acl_to_xattr(&init_user_ns, acl, value, size);
if (err < 0) if (err < 0)
goto out; goto out;
flags = 0; flags = 0;
@@ -639,7 +637,7 @@ static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
if (!acl) if (!acl)
return -ENODATA; return -ENODATA;
err = posix_acl_to_xattr(mnt_userns, acl, buffer, size); err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl); posix_acl_release(acl);
return err; return err;
@@ -663,12 +661,12 @@ static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
if (!value) { if (!value) {
acl = NULL; acl = NULL;
} else { } else {
acl = posix_acl_from_xattr(mnt_userns, value, size); acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl)) if (IS_ERR(acl))
return PTR_ERR(acl); return PTR_ERR(acl);
if (acl) { if (acl) {
err = posix_acl_valid(mnt_userns, acl); err = posix_acl_valid(&init_user_ns, acl);
if (err) if (err)
goto release_and_out; goto release_and_out;
} }

View File

@@ -503,10 +503,12 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
struct vm_area_struct *vma = walk->vma; struct vm_area_struct *vma = walk->vma;
bool locked = !!(vma->vm_flags & VM_LOCKED); bool locked = !!(vma->vm_flags & VM_LOCKED);
struct page *page = NULL; struct page *page = NULL;
bool migration = false; bool migration = false, young = false, dirty = false;
if (pte_present(*pte)) { if (pte_present(*pte)) {
page = vm_normal_page(vma, addr, *pte); page = vm_normal_page(vma, addr, *pte);
young = pte_young(*pte);
dirty = pte_dirty(*pte);
} else if (is_swap_pte(*pte)) { } else if (is_swap_pte(*pte)) {
swp_entry_t swpent = pte_to_swp_entry(*pte); swp_entry_t swpent = pte_to_swp_entry(*pte);
@@ -540,8 +542,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
if (!page) if (!page)
return; return;
smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte), smaps_account(mss, page, false, young, dirty, locked, migration);
locked, migration);
} }
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE

View File

@@ -723,13 +723,12 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
struct zonefs_inode_info *zi = ZONEFS_I(inode); struct zonefs_inode_info *zi = ZONEFS_I(inode);
struct block_device *bdev = inode->i_sb->s_bdev; struct block_device *bdev = inode->i_sb->s_bdev;
unsigned int max; unsigned int max = bdev_max_zone_append_sectors(bdev);
struct bio *bio; struct bio *bio;
ssize_t size; ssize_t size;
int nr_pages; int nr_pages;
ssize_t ret; ssize_t ret;
max = queue_max_zone_append_sectors(bdev_get_queue(bdev));
max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize); max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
iov_iter_truncate(from, max); iov_iter_truncate(from, max);

View File

@@ -114,7 +114,7 @@ static inline bool memory_contains(void *begin, void *end, void *virt,
/** /**
* memory_intersects - checks if the region occupied by an object intersects * memory_intersects - checks if the region occupied by an object intersects
* with another memory region * with another memory region
* @begin: virtual address of the beginning of the memory regien * @begin: virtual address of the beginning of the memory region
* @end: virtual address of the end of the memory region * @end: virtual address of the end of the memory region
* @virt: virtual address of the memory object * @virt: virtual address of the memory object
* @size: size of the memory object * @size: size of the memory object
@@ -127,7 +127,10 @@ static inline bool memory_intersects(void *begin, void *end, void *virt,
{ {
void *vend = virt + size; void *vend = virt + size;
return (virt >= begin && virt < end) || (vend >= begin && vend < end); if (virt < end && vend > begin)
return true;
return false;
} }
/** /**

View File

@@ -1387,6 +1387,17 @@ static inline unsigned int queue_max_zone_append_sectors(const struct request_qu
return min(l->max_zone_append_sectors, l->max_sectors); return min(l->max_zone_append_sectors, l->max_sectors);
} }
static inline unsigned int
bdev_max_zone_append_sectors(struct block_device *bdev)
{
return queue_max_zone_append_sectors(bdev_get_queue(bdev));
}
static inline unsigned int bdev_max_segments(struct block_device *bdev)
{
return queue_max_segments(bdev_get_queue(bdev));
}
static inline unsigned queue_logical_block_size(const struct request_queue *q) static inline unsigned queue_logical_block_size(const struct request_queue *q)
{ {
int retval = 512; int retval = 512;

View File

@@ -1045,4 +1045,22 @@ cpumap_print_list_to_buf(char *buf, const struct cpumask *mask,
[0] = 1UL \ [0] = 1UL \
} } } }
/*
* Provide a valid theoretical max size for cpumap and cpulist sysfs files
* to avoid breaking userspace which may allocate a buffer based on the size
* reported by e.g. fstat.
*
* for cpumap NR_CPUS * 9/32 - 1 should be an exact length.
*
* For cpulist 7 is (ceil(log10(NR_CPUS)) + 1) allowing for NR_CPUS to be up
* to 2 orders of magnitude larger than 8192. And then we divide by 2 to
* cover a worst-case of every other cpu being on one of two nodes for a
* very large NR_CPUS.
*
* Use PAGE_SIZE as a minimum for smaller configurations.
*/
#define CPUMAP_FILE_MAX_BYTES ((((NR_CPUS * 9)/32 - 1) > PAGE_SIZE) \
? (NR_CPUS * 9)/32 - 1 : PAGE_SIZE)
#define CPULIST_FILE_MAX_BYTES (((NR_CPUS * 7)/2 > PAGE_SIZE) ? (NR_CPUS * 7)/2 : PAGE_SIZE)
#endif /* __LINUX_CPUMASK_H */ #endif /* __LINUX_CPUMASK_H */

View File

@@ -966,19 +966,30 @@ static inline void mod_memcg_state(struct mem_cgroup *memcg,
static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx) static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx)
{ {
return READ_ONCE(memcg->vmstats.state[idx]); long x = READ_ONCE(memcg->vmstats.state[idx]);
#ifdef CONFIG_SMP
if (x < 0)
x = 0;
#endif
return x;
} }
static inline unsigned long lruvec_page_state(struct lruvec *lruvec, static inline unsigned long lruvec_page_state(struct lruvec *lruvec,
enum node_stat_item idx) enum node_stat_item idx)
{ {
struct mem_cgroup_per_node *pn; struct mem_cgroup_per_node *pn;
long x;
if (mem_cgroup_disabled()) if (mem_cgroup_disabled())
return node_page_state(lruvec_pgdat(lruvec), idx); return node_page_state(lruvec_pgdat(lruvec), idx);
pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
return READ_ONCE(pn->lruvec_stats.state[idx]); x = READ_ONCE(pn->lruvec_stats.state[idx]);
#ifdef CONFIG_SMP
if (x < 0)
x = 0;
#endif
return x;
} }
static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec, static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,

View File

@@ -759,6 +759,7 @@ struct mlx5_core_dev {
enum mlx5_device_state state; enum mlx5_device_state state;
/* sync interface state */ /* sync interface state */
struct mutex intf_state_mutex; struct mutex intf_state_mutex;
struct lock_class_key lock_key;
unsigned long intf_state; unsigned long intf_state;
struct mlx5_priv priv; struct mlx5_priv priv;
struct mlx5_profile profile; struct mlx5_profile profile;

View File

@@ -626,9 +626,23 @@ extern int sysctl_devconf_inherit_init_net;
*/ */
static inline bool net_has_fallback_tunnels(const struct net *net) static inline bool net_has_fallback_tunnels(const struct net *net)
{ {
return !IS_ENABLED(CONFIG_SYSCTL) || #if IS_ENABLED(CONFIG_SYSCTL)
!sysctl_fb_tunnels_only_for_init_net || int fb_tunnels_only_for_init_net = READ_ONCE(sysctl_fb_tunnels_only_for_init_net);
(net == &init_net && sysctl_fb_tunnels_only_for_init_net == 1);
return !fb_tunnels_only_for_init_net ||
(net_eq(net, &init_net) && fb_tunnels_only_for_init_net == 1);
#else
return true;
#endif
}
static inline int net_inherit_devconf(void)
{
#if IS_ENABLED(CONFIG_SYSCTL)
return READ_ONCE(sysctl_devconf_inherit_init_net);
#else
return 0;
#endif
} }
static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)

View File

@@ -94,10 +94,6 @@ struct ebt_table {
struct ebt_replace_kernel *table; struct ebt_replace_kernel *table;
unsigned int valid_hooks; unsigned int valid_hooks;
rwlock_t lock; rwlock_t lock;
/* e.g. could be the table explicitly only allows certain
* matches, targets, ... 0 == let it in */
int (*check)(const struct ebt_table_info *info,
unsigned int valid_hooks);
/* the data used by the kernel */ /* the data used by the kernel */
struct ebt_table_info *private; struct ebt_table_info *private;
struct nf_hook_ops *ops; struct nf_hook_ops *ops;

View File

@@ -33,7 +33,7 @@ extern unsigned int sysctl_net_busy_poll __read_mostly;
static inline bool net_busy_loop_on(void) static inline bool net_busy_loop_on(void)
{ {
return sysctl_net_busy_poll; return READ_ONCE(sysctl_net_busy_poll);
} }
static inline bool sk_can_busy_loop(const struct sock *sk) static inline bool sk_can_busy_loop(const struct sock *sk)

View File

@@ -266,6 +266,7 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
struct flow_offload_tuple *tuple); struct flow_offload_tuple *tuple);
void nf_flow_table_gc_run(struct nf_flowtable *flow_table);
void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable, void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
struct net_device *dev); struct net_device *dev);
void nf_flow_table_cleanup(struct net_device *dev); void nf_flow_table_cleanup(struct net_device *dev);
@@ -302,6 +303,8 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable,
struct flow_offload *flow); struct flow_offload *flow);
void nf_flow_table_offload_flush(struct nf_flowtable *flowtable); void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable);
int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
struct net_device *dev, struct net_device *dev,
enum flow_block_command cmd); enum flow_block_command cmd);

View File

@@ -193,13 +193,18 @@ struct nft_ctx {
bool report; bool report;
}; };
struct nft_data_desc { enum nft_data_desc_flags {
enum nft_data_types type; NFT_DATA_DESC_SETELEM = (1 << 0),
unsigned int len;
}; };
int nft_data_init(const struct nft_ctx *ctx, struct nft_data_desc {
struct nft_data *data, unsigned int size, enum nft_data_types type;
unsigned int size;
unsigned int len;
unsigned int flags;
};
int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
struct nft_data_desc *desc, const struct nlattr *nla); struct nft_data_desc *desc, const struct nlattr *nla);
void nft_data_hold(const struct nft_data *data, enum nft_data_types type); void nft_data_hold(const struct nft_data *data, enum nft_data_types type);
void nft_data_release(const struct nft_data *data, enum nft_data_types type); void nft_data_release(const struct nft_data *data, enum nft_data_types type);
@@ -1595,6 +1600,7 @@ struct nftables_pernet {
struct list_head module_list; struct list_head module_list;
struct list_head notify_list; struct list_head notify_list;
struct mutex commit_mutex; struct mutex commit_mutex;
u64 table_handle;
unsigned int base_seq; unsigned int base_seq;
u8 validate_state; u8 validate_state;
}; };

View File

@@ -40,6 +40,14 @@ struct nft_cmp_fast_expr {
bool inv; bool inv;
}; };
struct nft_cmp16_fast_expr {
struct nft_data data;
struct nft_data mask;
u8 sreg;
u8 len;
bool inv;
};
struct nft_immediate_expr { struct nft_immediate_expr {
struct nft_data data; struct nft_data data;
u8 dreg; u8 dreg;
@@ -57,6 +65,7 @@ static inline u32 nft_cmp_fast_mask(unsigned int len)
} }
extern const struct nft_expr_ops nft_cmp_fast_ops; extern const struct nft_expr_ops nft_cmp_fast_ops;
extern const struct nft_expr_ops nft_cmp16_fast_ops;
struct nft_payload { struct nft_payload {
enum nft_payload_bases base:8; enum nft_payload_bases base:8;

View File

@@ -571,6 +571,8 @@ __u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss);
#endif #endif
/* tcp_output.c */ /* tcp_output.c */
void tcp_skb_entail(struct sock *sk, struct sk_buff *skb);
void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb);
void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
int nonagle); int nonagle);
int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs);

View File

@@ -102,6 +102,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa
ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, true); ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, true);
if (ret < 0) { if (ret < 0) {
audit_mark->path = NULL;
fsnotify_put_mark(&audit_mark->mark); fsnotify_put_mark(&audit_mark->mark);
audit_mark = ERR_PTR(ret); audit_mark = ERR_PTR(ret);
} }

View File

@@ -6096,8 +6096,7 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx]; struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
struct bpf_reg_state *regs = cur_regs(env), *reg; struct bpf_reg_state *regs = cur_regs(env), *reg;
struct bpf_map *map = meta->map_ptr; struct bpf_map *map = meta->map_ptr;
struct tnum range; u64 val, max;
u64 val;
int err; int err;
if (func_id != BPF_FUNC_tail_call) if (func_id != BPF_FUNC_tail_call)
@@ -6107,10 +6106,11 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
return -EINVAL; return -EINVAL;
} }
range = tnum_range(0, map->max_entries - 1);
reg = &regs[BPF_REG_3]; reg = &regs[BPF_REG_3];
val = reg->var_off.value;
max = map->max_entries;
if (!register_is_const(reg) || !tnum_in(range, reg->var_off)) { if (!(register_is_const(reg) && val < max)) {
bpf_map_key_store(aux, BPF_MAP_KEY_POISON); bpf_map_key_store(aux, BPF_MAP_KEY_POISON);
return 0; return 0;
} }
@@ -6118,8 +6118,6 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
err = mark_chain_precision(env, BPF_REG_3); err = mark_chain_precision(env, BPF_REG_3);
if (err) if (err)
return err; return err;
val = reg->var_off.value;
if (bpf_map_key_unseen(aux)) if (bpf_map_key_unseen(aux))
bpf_map_key_store(aux, val); bpf_map_key_store(aux, val);
else if (!bpf_map_key_poisoned(aux) && else if (!bpf_map_key_poisoned(aux) &&

View File

@@ -1810,6 +1810,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
if (ss->css_rstat_flush) { if (ss->css_rstat_flush) {
list_del_rcu(&css->rstat_css_node); list_del_rcu(&css->rstat_css_node);
synchronize_rcu();
list_add_rcu(&css->rstat_css_node, list_add_rcu(&css->rstat_css_node,
&dcgrp->rstat_css_list); &dcgrp->rstat_css_list);
} }

View File

@@ -276,6 +276,7 @@ COND_SYSCALL(landlock_restrict_self);
/* mm/fadvise.c */ /* mm/fadvise.c */
COND_SYSCALL(fadvise64_64); COND_SYSCALL(fadvise64_64);
COND_SYSCALL_COMPAT(fadvise64_64);
/* mm/, CONFIG_MMU only */ /* mm/, CONFIG_MMU only */
COND_SYSCALL(swapon); COND_SYSCALL(swapon);

View File

@@ -26,10 +26,16 @@
*/ */
int ___ratelimit(struct ratelimit_state *rs, const char *func) int ___ratelimit(struct ratelimit_state *rs, const char *func)
{ {
/* Paired with WRITE_ONCE() in .proc_handler().
* Changing two values seperately could be inconsistent
* and some message could be lost. (See: net_ratelimit_state).
*/
int interval = READ_ONCE(rs->interval);
int burst = READ_ONCE(rs->burst);
unsigned long flags; unsigned long flags;
int ret; int ret;
if (!rs->interval) if (!interval)
return 1; return 1;
/* /*
@@ -44,7 +50,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
if (!rs->begin) if (!rs->begin)
rs->begin = jiffies; rs->begin = jiffies;
if (time_is_before_jiffies(rs->begin + rs->interval)) { if (time_is_before_jiffies(rs->begin + interval)) {
if (rs->missed) { if (rs->missed) {
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
printk_deferred(KERN_WARNING printk_deferred(KERN_WARNING
@@ -56,7 +62,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
rs->begin = jiffies; rs->begin = jiffies;
rs->printed = 0; rs->printed = 0;
} }
if (rs->burst && rs->burst > rs->printed) { if (burst && burst > rs->printed) {
rs->printed++; rs->printed++;
ret = 1; ret = 1;
} else { } else {

Some files were not shown because too many files have changed in this diff Show More