Merge tag 'v5.15.64' into rpi-5.15.y
This is the 5.15.64 stable release
This commit is contained in:
@@ -521,6 +521,7 @@ What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
|
||||
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
|
||||
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
|
||||
/sys/devices/system/cpu/vulnerabilities/retbleed
|
||||
Date: January 2018
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: Information about CPU vulnerabilities
|
||||
|
||||
@@ -230,6 +230,20 @@ The possible values in this file are:
|
||||
* - 'Mitigation: Clear CPU buffers'
|
||||
- The processor is vulnerable and the CPU buffer clearing mitigation is
|
||||
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
|
||||
the above information:
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 63
|
||||
SUBLEVEL = 64
|
||||
EXTRAVERSION =
|
||||
NAME = Trick or Treat
|
||||
|
||||
|
||||
@@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1286807
|
||||
{
|
||||
ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0),
|
||||
},
|
||||
{
|
||||
/* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */
|
||||
ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
|
||||
},
|
||||
|
||||
@@ -142,10 +142,10 @@ menu "Processor type and features"
|
||||
|
||||
choice
|
||||
prompt "Processor type"
|
||||
default PA7000
|
||||
default PA7000 if "$(ARCH)" = "parisc"
|
||||
|
||||
config PA7000
|
||||
bool "PA7000/PA7100"
|
||||
bool "PA7000/PA7100" if "$(ARCH)" = "parisc"
|
||||
help
|
||||
This is the processor type of your CPU. This information is
|
||||
used for optimizing purposes. In order to compile a kernel
|
||||
@@ -156,21 +156,21 @@ config PA7000
|
||||
which is required on some machines.
|
||||
|
||||
config PA7100LC
|
||||
bool "PA7100LC"
|
||||
bool "PA7100LC" if "$(ARCH)" = "parisc"
|
||||
help
|
||||
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,
|
||||
D200, D210, D300, D310 and E-class
|
||||
|
||||
config PA7200
|
||||
bool "PA7200"
|
||||
bool "PA7200" if "$(ARCH)" = "parisc"
|
||||
help
|
||||
Select this option for the PCX-T' processor, as used in the
|
||||
C100, C110, J100, J110, J210XC, D250, D260, D350, D360,
|
||||
K100, K200, K210, K220, K400, K410 and K420
|
||||
|
||||
config PA7300LC
|
||||
bool "PA7300LC"
|
||||
bool "PA7300LC" if "$(ARCH)" = "parisc"
|
||||
help
|
||||
Select this option for the PCX-L2 processor, as used in the
|
||||
744, A180, B132L, B160L, B180L, C132L, C160L, C180L,
|
||||
@@ -220,17 +220,8 @@ config MLONGCALLS
|
||||
Enabling this option will probably slow down your kernel.
|
||||
|
||||
config 64BIT
|
||||
bool "64-bit kernel"
|
||||
def_bool "$(ARCH)" = "parisc64"
|
||||
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
|
||||
prompt "Kernel page size"
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
#define R1(i) (((i)>>21)&0x1f)
|
||||
#define R2(i) (((i)>>16)&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 IM5_2(i) IM((i)>>16,5)
|
||||
#define IM5_3(i) IM((i),5)
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE / sizeof(long)];
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/csr.h>
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
|
||||
#include <asm/asm-prototypes.h>
|
||||
#include <asm/bug.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
int show_unhandled_signals = 1;
|
||||
|
||||
|
||||
@@ -173,6 +173,13 @@ ENTRY(__asm_copy_from_user)
|
||||
csrc CSR_STATUS, t6
|
||||
li a0, 0
|
||||
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_from_user)
|
||||
EXPORT_SYMBOL(__asm_copy_to_user)
|
||||
@@ -218,19 +225,12 @@ ENTRY(__clear_user)
|
||||
addi a0, a0, 1
|
||||
bltu a0, a3, 5b
|
||||
j 3b
|
||||
ENDPROC(__clear_user)
|
||||
EXPORT_SYMBOL(__clear_user)
|
||||
|
||||
.section .fixup,"ax"
|
||||
.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
|
||||
/* Exception fixup code */
|
||||
11:
|
||||
csrs CSR_STATUS, t6
|
||||
/* Disable access to user memory */
|
||||
csrc CSR_STATUS, t6
|
||||
mv a0, a1
|
||||
ret
|
||||
.previous
|
||||
ENDPROC(__clear_user)
|
||||
EXPORT_SYMBOL(__clear_user)
|
||||
|
||||
@@ -91,6 +91,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
||||
|
||||
memcpy(dst, src, arch_task_struct_size);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -149,13 +161,11 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
|
||||
frame->childregs.flags = 0;
|
||||
if (new_stackp)
|
||||
frame->childregs.gprs[15] = new_stackp;
|
||||
|
||||
/* Don't copy runtime instrumentation info */
|
||||
p->thread.ri_cb = NULL;
|
||||
/*
|
||||
* Clear the runtime instrumentation flag after the above childregs
|
||||
* copy. The CB pointer was already cleared in arch_dup_task_struct().
|
||||
*/
|
||||
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 ? */
|
||||
if (clone_flags & CLONE_SETTLS) {
|
||||
|
||||
@@ -397,7 +397,9 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access)
|
||||
flags = FAULT_FLAG_DEFAULT;
|
||||
if (user_mode(regs))
|
||||
flags |= FAULT_FLAG_USER;
|
||||
if (access == VM_WRITE || is_write)
|
||||
if (is_write)
|
||||
access = VM_WRITE;
|
||||
if (access == VM_WRITE)
|
||||
flags |= FAULT_FLAG_WRITE;
|
||||
mmap_read_lock(mm);
|
||||
|
||||
|
||||
@@ -373,6 +373,7 @@ SYM_CODE_END(xen_error_entry)
|
||||
SYM_CODE_START(\asmsym)
|
||||
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
.if \has_error_code == 0
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
@@ -440,6 +441,7 @@ SYM_CODE_END(\asmsym)
|
||||
SYM_CODE_START(\asmsym)
|
||||
UNWIND_HINT_IRET_REGS
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
|
||||
@@ -495,6 +497,7 @@ SYM_CODE_END(\asmsym)
|
||||
SYM_CODE_START(\asmsym)
|
||||
UNWIND_HINT_IRET_REGS
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/*
|
||||
* If the entry is from userspace, switch stacks and treat it as
|
||||
@@ -557,6 +560,7 @@ SYM_CODE_END(\asmsym)
|
||||
SYM_CODE_START(\asmsym)
|
||||
UNWIND_HINT_IRET_REGS offset=8
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/* paranoid_entry returns GS information for paranoid_exit in EBX. */
|
||||
call paranoid_entry
|
||||
@@ -876,7 +880,6 @@ SYM_CODE_END(xen_failsafe_callback)
|
||||
*/
|
||||
SYM_CODE_START_LOCAL(paranoid_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
cld
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
|
||||
@@ -1012,7 +1015,6 @@ SYM_CODE_END(paranoid_exit)
|
||||
*/
|
||||
SYM_CODE_START_LOCAL(error_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
cld
|
||||
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
@@ -1155,6 +1157,7 @@ SYM_CODE_START(asm_exc_nmi)
|
||||
*/
|
||||
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/* Use %rdx as our temp variable throughout */
|
||||
pushq %rdx
|
||||
@@ -1174,7 +1177,6 @@ SYM_CODE_START(asm_exc_nmi)
|
||||
*/
|
||||
|
||||
swapgs
|
||||
cld
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
|
||||
movq %rsp, %rdx
|
||||
|
||||
@@ -236,6 +236,7 @@ static u64 load_latency_data(u64 status)
|
||||
static u64 store_latency_data(u64 status)
|
||||
{
|
||||
union intel_x86_pebs_dse dse;
|
||||
union perf_mem_data_src src;
|
||||
u64 val;
|
||||
|
||||
dse.val = status;
|
||||
@@ -263,7 +264,14 @@ static u64 store_latency_data(u64 status)
|
||||
|
||||
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 {
|
||||
|
||||
@@ -1114,6 +1114,14 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_ARCH_LBR)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -788,6 +788,22 @@ int snb_pci2phy_map_init(int devid)
|
||||
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 = {
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.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,
|
||||
.enable_event = snb_uncore_imc_enable_event,
|
||||
.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 = {
|
||||
|
||||
@@ -446,7 +446,8 @@
|
||||
#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_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_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
|
||||
#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */
|
||||
#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 */
|
||||
|
||||
@@ -35,34 +35,57 @@
|
||||
#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
|
||||
* the optimal version - two calls, each with their own speculation
|
||||
* 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; \
|
||||
771: \
|
||||
ANNOTATE_INTRA_FUNCTION_CALL; \
|
||||
call 772f; \
|
||||
773: /* speculation trap */ \
|
||||
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; \
|
||||
__FILL_RETURN_SLOT \
|
||||
__FILL_RETURN_SLOT \
|
||||
add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \
|
||||
dec reg; \
|
||||
jnz 771b; \
|
||||
/* barrier for jnz misprediction */ \
|
||||
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__
|
||||
|
||||
@@ -120,28 +143,15 @@
|
||||
#endif
|
||||
.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
|
||||
* monstrosity above, manually.
|
||||
*/
|
||||
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2
|
||||
.ifb \ftr2
|
||||
ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr
|
||||
.else
|
||||
ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2
|
||||
.endif
|
||||
__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
|
||||
.Lunbalanced_\@:
|
||||
ISSUE_UNBALANCED_RET_GUARD
|
||||
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
|
||||
ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
|
||||
__stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
|
||||
__stringify(__FILL_ONE_RETURN), \ftr2
|
||||
|
||||
.Lskip_rsb_\@:
|
||||
.endm
|
||||
|
||||
|
||||
@@ -433,6 +433,7 @@ static void __init mmio_select_mitigation(void)
|
||||
u64 ia32_cap;
|
||||
|
||||
if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
|
||||
boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
|
||||
cpu_mitigations_off()) {
|
||||
mmio_mitigation = MMIO_MITIGATION_OFF;
|
||||
return;
|
||||
@@ -538,6 +539,8 @@ out:
|
||||
pr_info("TAA: %s\n", taa_strings[taa_mitigation]);
|
||||
if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
|
||||
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)
|
||||
@@ -2268,6 +2271,9 @@ static ssize_t tsx_async_abort_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)
|
||||
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);
|
||||
|
||||
case X86_BUG_MMIO_STALE_DATA:
|
||||
case X86_BUG_MMIO_UNKNOWN:
|
||||
return mmio_stale_data_show_state(buf);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1027,7 +1027,8 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
||||
#define NO_SWAPGS BIT(6)
|
||||
#define NO_ITLB_MULTIHIT BIT(7)
|
||||
#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) \
|
||||
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),
|
||||
|
||||
/* 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_TABLET, 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_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_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
|
||||
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 | NO_MMIO),
|
||||
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
|
||||
@@ -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),
|
||||
|
||||
/* AMD Family 0xf - 0x12 */
|
||||
VULNWL_AMD(0x0f, 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),
|
||||
VULNWL_AMD(0x11, 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),
|
||||
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 | NO_MMIO),
|
||||
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 | NO_MMIO),
|
||||
|
||||
/* 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_HYGON(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 | NO_MMIO),
|
||||
|
||||
/* Zhaoxin Family 7 */
|
||||
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS),
|
||||
VULNWL(ZHAOXIN, 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 | 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,
|
||||
* but for virtualization case check for ARCH_CAP MSR bits also, VMM may
|
||||
* 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) &&
|
||||
!arch_cap_mmio_immune(ia32_cap))
|
||||
if (!arch_cap_mmio_immune(ia32_cap)) {
|
||||
if (cpu_matches(cpu_vuln_blacklist, MMIO))
|
||||
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_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA))
|
||||
|
||||
@@ -93,22 +93,27 @@ static struct orc_entry *orc_find(unsigned long ip);
|
||||
static struct orc_entry *orc_ftrace_find(unsigned long ip)
|
||||
{
|
||||
struct ftrace_ops *ops;
|
||||
unsigned long caller;
|
||||
unsigned long tramp_addr, offset;
|
||||
|
||||
ops = ftrace_ops_trampoline(ip);
|
||||
if (!ops)
|
||||
return NULL;
|
||||
|
||||
/* Set tramp_addr to the start of the code copied by the trampoline */
|
||||
if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
|
||||
caller = (unsigned long)ftrace_regs_call;
|
||||
tramp_addr = (unsigned long)ftrace_regs_caller;
|
||||
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 */
|
||||
if (ip == caller)
|
||||
if (ip == tramp_addr)
|
||||
return NULL;
|
||||
|
||||
return orc_find(caller);
|
||||
return orc_find(tramp_addr);
|
||||
}
|
||||
#else
|
||||
static struct orc_entry *orc_ftrace_find(unsigned long ip)
|
||||
|
||||
@@ -1400,7 +1400,8 @@ out:
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
/*
|
||||
* 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);
|
||||
ret = blk_mq_request_issue_directly(rq, list_empty(list));
|
||||
if (ret != BLK_STS_OK) {
|
||||
errors++;
|
||||
if (ret == BLK_STS_RESOURCE ||
|
||||
ret == BLK_STS_DEV_RESOURCE) {
|
||||
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;
|
||||
}
|
||||
blk_mq_end_request(rq, ret);
|
||||
errors++;
|
||||
} else
|
||||
queued++;
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
unsigned int cpu;
|
||||
|
||||
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)
|
||||
freq_qos_remove_request(&pr->thermal_req);
|
||||
|
||||
@@ -395,12 +395,15 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
|
||||
size_t size, data_offsets_size;
|
||||
int ret;
|
||||
|
||||
mmap_read_lock(alloc->vma_vm_mm);
|
||||
if (!binder_alloc_get_vma(alloc)) {
|
||||
mmap_read_unlock(alloc->vma_vm_mm);
|
||||
binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
|
||||
"%d: binder_alloc_buf, no vma\n",
|
||||
alloc->pid);
|
||||
return ERR_PTR(-ESRCH);
|
||||
}
|
||||
mmap_read_unlock(alloc->vma_vm_mm);
|
||||
|
||||
data_offsets_size = ALIGN(data_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
|
||||
* 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++) {
|
||||
page = &alloc->pages[i];
|
||||
if (!page->page_ptr)
|
||||
@@ -932,7 +942,8 @@ void binder_alloc_print_pages(struct seq_file *m,
|
||||
else
|
||||
lru++;
|
||||
}
|
||||
}
|
||||
|
||||
uninitialized:
|
||||
mutex_unlock(&alloc->mutex);
|
||||
seq_printf(m, " pages: %d:%d:%d\n", active, lru, free);
|
||||
seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high);
|
||||
|
||||
@@ -45,7 +45,7 @@ static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj,
|
||||
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,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
@@ -66,7 +66,7 @@ static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj,
|
||||
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
|
||||
|
||||
@@ -52,39 +52,39 @@ define_id_show_func(core_id);
|
||||
static DEVICE_ATTR_RO(core_id);
|
||||
|
||||
define_siblings_read_func(thread_siblings, sibling_cpumask);
|
||||
static BIN_ATTR_RO(thread_siblings, 0);
|
||||
static BIN_ATTR_RO(thread_siblings_list, 0);
|
||||
static BIN_ATTR_RO(thread_siblings, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(thread_siblings_list, CPULIST_FILE_MAX_BYTES);
|
||||
|
||||
define_siblings_read_func(core_cpus, sibling_cpumask);
|
||||
static BIN_ATTR_RO(core_cpus, 0);
|
||||
static BIN_ATTR_RO(core_cpus_list, 0);
|
||||
static BIN_ATTR_RO(core_cpus, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(core_cpus_list, CPULIST_FILE_MAX_BYTES);
|
||||
|
||||
define_siblings_read_func(core_siblings, core_cpumask);
|
||||
static BIN_ATTR_RO(core_siblings, 0);
|
||||
static BIN_ATTR_RO(core_siblings_list, 0);
|
||||
static BIN_ATTR_RO(core_siblings, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(core_siblings_list, CPULIST_FILE_MAX_BYTES);
|
||||
|
||||
define_siblings_read_func(die_cpus, die_cpumask);
|
||||
static BIN_ATTR_RO(die_cpus, 0);
|
||||
static BIN_ATTR_RO(die_cpus_list, 0);
|
||||
static BIN_ATTR_RO(die_cpus, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(die_cpus_list, CPULIST_FILE_MAX_BYTES);
|
||||
|
||||
define_siblings_read_func(package_cpus, core_cpumask);
|
||||
static BIN_ATTR_RO(package_cpus, 0);
|
||||
static BIN_ATTR_RO(package_cpus_list, 0);
|
||||
static BIN_ATTR_RO(package_cpus, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(package_cpus_list, CPULIST_FILE_MAX_BYTES);
|
||||
|
||||
#ifdef CONFIG_SCHED_BOOK
|
||||
define_id_show_func(book_id);
|
||||
static DEVICE_ATTR_RO(book_id);
|
||||
define_siblings_read_func(book_siblings, book_cpumask);
|
||||
static BIN_ATTR_RO(book_siblings, 0);
|
||||
static BIN_ATTR_RO(book_siblings_list, 0);
|
||||
static BIN_ATTR_RO(book_siblings, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(book_siblings_list, CPULIST_FILE_MAX_BYTES);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_DRAWER
|
||||
define_id_show_func(drawer_id);
|
||||
static DEVICE_ATTR_RO(drawer_id);
|
||||
define_siblings_read_func(drawer_siblings, drawer_cpumask);
|
||||
static BIN_ATTR_RO(drawer_siblings, 0);
|
||||
static BIN_ATTR_RO(drawer_siblings_list, 0);
|
||||
static BIN_ATTR_RO(drawer_siblings, CPUMAP_FILE_MAX_BYTES);
|
||||
static BIN_ATTR_RO(drawer_siblings_list, CPULIST_FILE_MAX_BYTES);
|
||||
#endif
|
||||
|
||||
static struct bin_attribute *bin_attrs[] = {
|
||||
|
||||
@@ -1154,6 +1154,11 @@ loop_set_status_from_info(struct loop_device *lo,
|
||||
|
||||
lo->lo_offset = info->lo_offset;
|
||||
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_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
|
||||
lo->lo_file_name[LO_NAME_SIZE-1] = 0;
|
||||
|
||||
@@ -820,6 +820,15 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict,
|
||||
if (ret == 0) {
|
||||
ret = nouveau_fence_new(chan, false, &fence);
|
||||
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,
|
||||
&fence->base,
|
||||
evict, false,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6251,11 +6251,11 @@ static void mddev_detach(struct mddev *mddev)
|
||||
static void __md_stop(struct mddev *mddev)
|
||||
{
|
||||
struct md_personality *pers = mddev->pers;
|
||||
md_bitmap_destroy(mddev);
|
||||
mddev_detach(mddev);
|
||||
/* Ensure ->event_work is done */
|
||||
if (mddev->event_work.func)
|
||||
flush_workqueue(md_misc_wq);
|
||||
md_bitmap_destroy(mddev);
|
||||
spin_lock(&mddev->lock);
|
||||
mddev->pers = NULL;
|
||||
spin_unlock(&mddev->lock);
|
||||
@@ -6272,6 +6272,7 @@ void md_stop(struct mddev *mddev)
|
||||
/* stop the array and free an attached data structures.
|
||||
* This is called from dm-raid
|
||||
*/
|
||||
__md_stop_writes(mddev);
|
||||
__md_stop(mddev);
|
||||
bioset_exit(&mddev->bio_set);
|
||||
bioset_exit(&mddev->sync_set);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
/* 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).system.sys_priority =
|
||||
bond->params.ad_actor_sys_prio;
|
||||
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,
|
||||
AD_AGGREGATOR_SELECTION_TIMER *
|
||||
ad_ticks_per_sec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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_vnics -= le16_to_cpu(req->min_vnics) * n;
|
||||
if (bp->flags & BNXT_FLAG_CHIP_P5)
|
||||
hw_resc->max_irqs -= vf_msix * n;
|
||||
hw_resc->max_nqs -= vf_msix;
|
||||
|
||||
rc = pf->active_vfs;
|
||||
}
|
||||
|
||||
@@ -4385,7 +4385,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
|
||||
(struct in6_addr *)&ipv6_full_mask))
|
||||
new_mask |= I40E_L3_V6_DST_MASK;
|
||||
else if (ipv6_addr_any((struct in6_addr *)
|
||||
&usr_ip6_spec->ip6src))
|
||||
&usr_ip6_spec->ip6dst))
|
||||
new_mask &= ~I40E_L3_V6_DST_MASK;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -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;
|
||||
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 (if_running) {
|
||||
@@ -343,6 +356,7 @@ xsk_pool_if_up:
|
||||
netdev_err(vsi->netdev, "ice_qp_ena error = %d\n", ret);
|
||||
}
|
||||
|
||||
failure:
|
||||
if (pool_failure) {
|
||||
netdev_err(vsi->netdev, "Could not %sable buffer pool, error = %d\n",
|
||||
pool_present ? "en" : "dis", pool_failure);
|
||||
|
||||
@@ -1212,7 +1212,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
|
||||
struct cyclecounter cc;
|
||||
unsigned long flags;
|
||||
u32 incval = 0;
|
||||
u32 tsauxc = 0;
|
||||
u32 fuse0 = 0;
|
||||
|
||||
/* 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_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;
|
||||
case ixgbe_mac_X540:
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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_init_systime(adapter);
|
||||
|
||||
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||
timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
|
||||
ktime_to_ns(ktime_get_real()));
|
||||
|
||||
@@ -3325,7 +3325,9 @@ static int set_feature_hw_tc(struct net_device *netdev, bool enable)
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
|
||||
#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,
|
||||
"Active offloaded tc filters, can't turn hw_tc_offload off\n");
|
||||
return -EINVAL;
|
||||
@@ -4350,14 +4352,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
|
||||
/* RQ */
|
||||
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);
|
||||
|
||||
/* CQ moderation params */
|
||||
|
||||
@@ -618,6 +618,8 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
|
||||
|
||||
params->mqprio.num_tc = 1;
|
||||
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
|
||||
* divide by zero if called before first activating channels.
|
||||
|
||||
@@ -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));
|
||||
INIT_LIST_HEAD(&priv->ctx_list);
|
||||
spin_lock_init(&priv->ctx_lock);
|
||||
lockdep_register_key(&dev->lock_key);
|
||||
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.wc_head.lock);
|
||||
@@ -1474,6 +1476,7 @@ err_health_init:
|
||||
mutex_destroy(&priv->bfregs.wc_head.lock);
|
||||
mutex_destroy(&priv->bfregs.reg_head.lock);
|
||||
mutex_destroy(&dev->intf_state_mutex);
|
||||
lockdep_unregister_key(&dev->lock_key);
|
||||
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.reg_head.lock);
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
int i;
|
||||
|
||||
napi_disable(&priv->napi);
|
||||
|
||||
@@ -204,6 +200,11 @@ static int moxart_mac_stop(struct net_device *ndev)
|
||||
/* disable all functions */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1692,8 +1692,67 @@ static int ionic_set_features(struct net_device *netdev,
|
||||
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)
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
struct sockaddr *addr = sa;
|
||||
u8 *mac;
|
||||
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))
|
||||
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);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -2974,11 +3041,10 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
|
||||
|
||||
netif_device_detach(lif->netdev);
|
||||
|
||||
mutex_lock(&lif->queue_lock);
|
||||
if (test_bit(IONIC_LIF_F_UP, lif->state)) {
|
||||
dev_info(ionic->dev, "Surprise FW stop, stopping queues\n");
|
||||
mutex_lock(&lif->queue_lock);
|
||||
ionic_stop_queues(lif);
|
||||
mutex_unlock(&lif->queue_lock);
|
||||
}
|
||||
|
||||
if (netif_running(lif->netdev)) {
|
||||
@@ -2989,6 +3055,8 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
|
||||
ionic_reset(ionic);
|
||||
ionic_qcqs_free(lif);
|
||||
|
||||
mutex_unlock(&lif->queue_lock);
|
||||
|
||||
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);
|
||||
if (err)
|
||||
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);
|
||||
if (err)
|
||||
goto err_out;
|
||||
goto err_unlock;
|
||||
|
||||
err = ionic_lif_init(lif);
|
||||
if (err)
|
||||
@@ -3035,6 +3109,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
|
||||
goto err_txrx_free;
|
||||
}
|
||||
|
||||
mutex_unlock(&lif->queue_lock);
|
||||
|
||||
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
|
||||
ionic_link_status_check_request(lif, CAN_SLEEP);
|
||||
netif_device_attach(lif->netdev);
|
||||
@@ -3051,6 +3127,8 @@ err_lifs_deinit:
|
||||
ionic_lif_deinit(lif);
|
||||
err_qcqs_free:
|
||||
ionic_qcqs_free(lif);
|
||||
err_unlock:
|
||||
mutex_unlock(&lif->queue_lock);
|
||||
err_out:
|
||||
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,
|
||||
},
|
||||
};
|
||||
u8 mac_address[ETH_ALEN];
|
||||
struct sockaddr addr;
|
||||
int err;
|
||||
|
||||
@@ -3223,8 +3302,23 @@ static int ionic_station_set(struct ionic_lif *lif)
|
||||
return err;
|
||||
netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_zero_ether_addr(netdev->dev_addr)) {
|
||||
/* 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
|
||||
* sure the netdev mac is in our filter list.
|
||||
*/
|
||||
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
|
||||
netdev->dev_addr))
|
||||
if (!ether_addr_equal(mac_address, netdev->dev_addr))
|
||||
ionic_lif_addr_add(lif, netdev->dev_addr);
|
||||
} else {
|
||||
/* 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;
|
||||
err = eth_prepare_mac_addr_change(netdev, &addr);
|
||||
if (err) {
|
||||
|
||||
@@ -395,8 +395,8 @@ try_again:
|
||||
ionic_opcode_to_str(opcode), opcode,
|
||||
ionic_error_to_str(err), err);
|
||||
|
||||
msleep(1000);
|
||||
iowrite32(0, &idev->dev_cmd_regs->done);
|
||||
msleep(1000);
|
||||
iowrite32(1, &idev->dev_cmd_regs->doorbell);
|
||||
goto try_again;
|
||||
}
|
||||
@@ -409,6 +409,8 @@ try_again:
|
||||
return ionic_error_to_errno(err);
|
||||
}
|
||||
|
||||
ionic_dev_cmd_clean(ionic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,13 +258,17 @@ EXPORT_SYMBOL_GPL(stmmac_set_mac_addr);
|
||||
/* Enable disable MAC RX/TX */
|
||||
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)
|
||||
value |= MAC_ENABLE_RX | MAC_ENABLE_TX;
|
||||
else
|
||||
value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX);
|
||||
|
||||
if (value != old_val)
|
||||
writel(value, ioaddr + MAC_CTRL_REG);
|
||||
}
|
||||
|
||||
|
||||
@@ -1083,10 +1083,10 @@ static void stmmac_mac_link_up(struct phylink_config *config,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
|
||||
u32 ctrl;
|
||||
u32 old_ctrl, ctrl;
|
||||
|
||||
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
ctrl &= ~priv->hw->link.speed_mask;
|
||||
old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
ctrl = old_ctrl & ~priv->hw->link.speed_mask;
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
switch (speed) {
|
||||
@@ -1161,6 +1161,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
|
||||
if (tx_pause && rx_pause)
|
||||
stmmac_mac_flow_ctrl(priv, duplex);
|
||||
|
||||
if (ctrl != old_ctrl)
|
||||
writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
|
||||
|
||||
stmmac_mac_set(priv, priv->ioaddr, true);
|
||||
|
||||
@@ -1325,7 +1325,7 @@ static void cas_init_rx_dma(struct cas *cp)
|
||||
writel(val, cp->regs + REG_RX_PAGE_SIZE);
|
||||
|
||||
/* enable the header parser if desired */
|
||||
if (CAS_HP_FIRMWARE == cas_prog_null)
|
||||
if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0])
|
||||
return;
|
||||
|
||||
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 */
|
||||
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);
|
||||
} else {
|
||||
cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE);
|
||||
|
||||
@@ -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 */
|
||||
addr = qcom_smem_virt_to_phys(virt) & PAGE_MASK;
|
||||
addr = qcom_smem_virt_to_phys(virt);
|
||||
phys = addr & PAGE_MASK;
|
||||
size = PAGE_ALIGN(size + addr - phys);
|
||||
iova = phys; /* We just want a direct mapping */
|
||||
|
||||
@@ -787,7 +787,7 @@ static int ipvlan_device_event(struct notifier_block *unused,
|
||||
|
||||
case NETDEV_CHANGEADDR:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -194,7 +194,7 @@ static struct notifier_block ipvtap_notifier_block __read_mostly = {
|
||||
.notifier_call = ipvtap_device_event,
|
||||
};
|
||||
|
||||
static int ipvtap_init(void)
|
||||
static int __init ipvtap_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -228,7 +228,7 @@ out1:
|
||||
}
|
||||
module_init(ipvtap_init);
|
||||
|
||||
static void ipvtap_exit(void)
|
||||
static void __exit ipvtap_exit(void)
|
||||
{
|
||||
rtnl_link_unregister(&ipvtap_link_ops);
|
||||
unregister_netdevice_notifier(&ipvtap_notifier_block);
|
||||
|
||||
@@ -447,11 +447,6 @@ static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *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,
|
||||
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);
|
||||
|
||||
out:
|
||||
ether_addr_copy(dev->dev_addr, addr->sa_data);
|
||||
macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES);
|
||||
eth_hw_addr_set(dev, addr->sa_data);
|
||||
|
||||
/* If h/w offloading is available, propagate to the device */
|
||||
if (macsec_is_offloaded(macsec)) {
|
||||
@@ -3953,6 +3947,11 @@ static bool sci_exists(struct net_device *dev, sci_t sci)
|
||||
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)
|
||||
{
|
||||
struct macsec_dev *macsec = macsec_priv(dev);
|
||||
|
||||
@@ -711,7 +711,7 @@ static int macvlan_sync_address(struct net_device *dev, unsigned char *addr)
|
||||
|
||||
if (!(dev->flags & IFF_UP)) {
|
||||
/* Just copy in the new address */
|
||||
ether_addr_copy(dev->dev_addr, addr);
|
||||
eth_hw_addr_set(dev, addr);
|
||||
} else {
|
||||
/* Rehash and update the device filters */
|
||||
if (macvlan_addr_busy(vlan->port, addr))
|
||||
|
||||
@@ -315,11 +315,11 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
|
||||
|
||||
phydev->suspended_by_mdio_bus = 0;
|
||||
|
||||
/* If we managed to get here with the PHY state machine in a state other
|
||||
* than PHY_HALTED this is an indication that something went wrong and
|
||||
* we should most likely be using MAC managed PM and we are not.
|
||||
/* If we manged to get here with the PHY state machine in a state neither
|
||||
* PHY_HALTED nor PHY_READY this is an indication that something went wrong
|
||||
* 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);
|
||||
if (ret < 0)
|
||||
|
||||
@@ -5904,6 +5904,11 @@ static void r8153_enter_oob(struct r8152 *tp)
|
||||
ocp_data &= ~NOW_IS_OOB;
|
||||
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_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_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_EMPTY, pause_off / 16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_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_reset_bmu(tp);
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <linux/usb/usbnet.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/phy.h>
|
||||
#include "smsc95xx.h"
|
||||
@@ -54,9 +52,6 @@
|
||||
SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3)
|
||||
#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 {
|
||||
u32 mac_cr;
|
||||
u32 hash_hi;
|
||||
@@ -65,12 +60,8 @@ struct smsc95xx_priv {
|
||||
spinlock_t mac_cr_lock;
|
||||
u8 features;
|
||||
u8 suspend_flags;
|
||||
struct irq_chip irqchip;
|
||||
struct irq_domain *irqdomain;
|
||||
struct fwnode_handle *irqfwnode;
|
||||
struct mii_bus *mdiobus;
|
||||
struct phy_device *phydev;
|
||||
struct task_struct *pm_task;
|
||||
};
|
||||
|
||||
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,
|
||||
u32 *data, int in_pm)
|
||||
{
|
||||
struct smsc95xx_priv *pdata = dev->driver_priv;
|
||||
u32 buf;
|
||||
int ret;
|
||||
int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
|
||||
|
||||
BUG_ON(!dev);
|
||||
|
||||
if (current != pdata->pm_task)
|
||||
if (!in_pm)
|
||||
fn = usbnet_read_cmd;
|
||||
else
|
||||
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,
|
||||
u32 data, int in_pm)
|
||||
{
|
||||
struct smsc95xx_priv *pdata = dev->driver_priv;
|
||||
u32 buf;
|
||||
int ret;
|
||||
int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
|
||||
|
||||
BUG_ON(!dev);
|
||||
|
||||
if (current != pdata->pm_task)
|
||||
if (!in_pm)
|
||||
fn = usbnet_write_cmd;
|
||||
else
|
||||
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)
|
||||
{
|
||||
struct smsc95xx_priv *pdata = dev->driver_priv;
|
||||
unsigned long flags;
|
||||
u32 intdata;
|
||||
|
||||
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);
|
||||
netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (intdata & INT_ENP_PHY_INT_)
|
||||
generic_handle_domain_irq(pdata->irqdomain, PHY_HWIRQ);
|
||||
;
|
||||
else
|
||||
netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n",
|
||||
intdata);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
bool is_internal_phy;
|
||||
char usb_path[64];
|
||||
int ret, phy_irq;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
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)
|
||||
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();
|
||||
if (!pdata->mdiobus) {
|
||||
ret = -ENOMEM;
|
||||
goto dispose_irq;
|
||||
goto free_pdata;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pdata->phydev->irq = phy_irq;
|
||||
pdata->phydev->is_internal = is_internal_phy;
|
||||
|
||||
/* detect device revision as different features may be available */
|
||||
@@ -1302,15 +1255,6 @@ unregister_mdio:
|
||||
free_mdio:
|
||||
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:
|
||||
kfree(pdata);
|
||||
return ret;
|
||||
@@ -1323,9 +1267,6 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
|
||||
phy_disconnect(dev->net->phydev);
|
||||
mdiobus_unregister(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");
|
||||
kfree(pdata);
|
||||
}
|
||||
@@ -1350,6 +1291,29 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter)
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
@@ -1516,6 +1480,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev)
|
||||
static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
|
||||
{
|
||||
struct smsc95xx_priv *pdata = dev->driver_priv;
|
||||
int ret;
|
||||
|
||||
if (!netif_running(dev->net)) {
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
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");
|
||||
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;
|
||||
int ret;
|
||||
|
||||
pdata->pm_task = current;
|
||||
|
||||
ret = usbnet_suspend(intf, message);
|
||||
if (ret < 0) {
|
||||
netdev_warn(dev->net, "usbnet_suspend error\n");
|
||||
pdata->pm_task = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1606,6 +1585,13 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
}
|
||||
|
||||
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,
|
||||
* otherwise enter SUSPEND0 below
|
||||
*/
|
||||
@@ -1794,7 +1780,6 @@ done:
|
||||
if (ret && PMSG_IS_AUTO(message))
|
||||
usbnet_resume(intf);
|
||||
|
||||
pdata->pm_task = NULL;
|
||||
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 */
|
||||
pdata->suspend_flags = 0;
|
||||
|
||||
pdata->pm_task = current;
|
||||
|
||||
if (suspend_flags & SUSPEND_ALLMODES) {
|
||||
/* clear wake-up sources */
|
||||
ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
|
||||
val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
|
||||
|
||||
ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
|
||||
/* clear wake-up status */
|
||||
ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
|
||||
val &= ~PM_CTL_WOL_EN_;
|
||||
val |= PM_CTL_WUPS_;
|
||||
|
||||
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
}
|
||||
|
||||
phy_init_hw(pdata->phydev);
|
||||
|
||||
ret = usbnet_resume(intf);
|
||||
if (ret < 0)
|
||||
netdev_warn(dev->net, "usbnet_resume error\n");
|
||||
|
||||
done:
|
||||
pdata->pm_task = NULL;
|
||||
phy_init_hw(pdata->phydev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smsc95xx_reset_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct usbnet *dev = usb_get_intfdata(intf);
|
||||
struct smsc95xx_priv *pdata = dev->driver_priv;
|
||||
int ret;
|
||||
|
||||
pdata->pm_task = current;
|
||||
ret = smsc95xx_reset(dev);
|
||||
pdata->pm_task = NULL;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -2386,9 +2386,6 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
|
||||
rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
|
||||
"Just Read IQK Matrix reg for channel:%d....\n",
|
||||
channel);
|
||||
if ((rtlphy->iqk_matrix[indexforchannel].
|
||||
value[0] != NULL)
|
||||
/*&&(regea4 != 0) */)
|
||||
_rtl92d_phy_patha_fill_iqk_matrix(hw, true,
|
||||
rtlphy->iqk_matrix[
|
||||
indexforchannel].value, 0,
|
||||
|
||||
@@ -310,6 +310,7 @@ static void pn532_uart_remove(struct serdev_device *serdev)
|
||||
pn53x_unregister_nfc(pn532->priv);
|
||||
serdev_device_close(serdev);
|
||||
pn53x_common_clean(pn532->priv);
|
||||
del_timer_sync(&pn532->cmd_timeout);
|
||||
kfree_skb(pn532->recv_skb);
|
||||
kfree(pn532);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ static int validate_conv_zones_cb(struct blk_zone *z,
|
||||
|
||||
bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
|
||||
{
|
||||
struct request_queue *q = ns->bdev->bd_disk->queue;
|
||||
u8 zasl = nvmet_zasl(queue_max_zone_append_sectors(q));
|
||||
u8 zasl = nvmet_zasl(bdev_max_zone_append_sectors(ns->bdev));
|
||||
struct gendisk *bd_disk = ns->bdev->bd_disk;
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -192,6 +192,8 @@ extern int ql2xfulldump_on_mpifail;
|
||||
extern int ql2xsecenable;
|
||||
extern int ql2xenforce_iocb_limit;
|
||||
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 void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
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;
|
||||
response_t *end_pkt;
|
||||
int start_pkt_ring_index;
|
||||
u32 iocb_cnt = 0;
|
||||
int rc = 0;
|
||||
u32 rsp_q_in;
|
||||
|
||||
if (pkt->entry_count == 1)
|
||||
return rc;
|
||||
@@ -3723,34 +3722,18 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
|
||||
else
|
||||
start_pkt_ring_index = rsp->ring_index - 1;
|
||||
|
||||
if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length)
|
||||
end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count -
|
||||
rsp->length - 1;
|
||||
if (rsp_q_in < start_pkt_ring_index)
|
||||
/* q in ptr is wrapped */
|
||||
iocb_cnt = rsp->length - start_pkt_ring_index + rsp_q_in;
|
||||
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;
|
||||
|
||||
/* 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
|
||||
if (iocb_cnt < pkt->entry_count)
|
||||
rc = -EIO;
|
||||
|
||||
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091,
|
||||
"%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n",
|
||||
__func__, rsp->ring, pkt, end_pkt, pkt->entry_count,
|
||||
rsp_q_in, rc);
|
||||
ql_dbg(ql_dbg_init, vha, 0x5091,
|
||||
"%s - ring %p pkt %p entry count %d iocb_cnt %d rsp_q_in %d rc %d\n",
|
||||
__func__, rsp->ring, pkt, pkt->entry_count, iocb_cnt, rsp_q_in, 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 purex_entry_24xx *purex_entry;
|
||||
struct purex_item *pure_item;
|
||||
u16 rsp_in = 0, cur_ring_index;
|
||||
int follow_inptr, is_shadow_hba;
|
||||
|
||||
if (!ha->flags.fw_started)
|
||||
return;
|
||||
@@ -3776,8 +3761,27 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
|
||||
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;
|
||||
cur_ring_index = rsp->ring_index;
|
||||
|
||||
rsp->ring_index++;
|
||||
if (rsp->ring_index == rsp->length) {
|
||||
@@ -3889,6 +3893,8 @@ process_err:
|
||||
}
|
||||
pure_item = qla27xx_copy_fpin_pkt(vha,
|
||||
(void **)&pkt, &rsp);
|
||||
__update_rsp_in(follow_inptr, is_shadow_hba,
|
||||
rsp, rsp_in);
|
||||
if (!pure_item)
|
||||
break;
|
||||
qla24xx_queue_purex_item(vha, pure_item,
|
||||
@@ -3896,7 +3902,17 @@ process_err:
|
||||
break;
|
||||
|
||||
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,
|
||||
"Defer processing ELS opcode %#x...\n",
|
||||
purex_entry->els_frame_payload[3]);
|
||||
|
||||
@@ -338,6 +338,16 @@ module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
|
||||
MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling,
|
||||
"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_free_device(scsi_qla_host_t *);
|
||||
static int qla2xxx_map_queues(struct Scsi_Host *shost);
|
||||
|
||||
@@ -2093,7 +2093,7 @@ static int storvsc_probe(struct hv_device *device,
|
||||
*/
|
||||
host_dev->handle_error_wq =
|
||||
alloc_ordered_workqueue("storvsc_error_wq_%d",
|
||||
WQ_MEM_RECLAIM,
|
||||
0,
|
||||
host->host_no);
|
||||
if (!host_dev->handle_error_wq) {
|
||||
ret = -ENOMEM;
|
||||
|
||||
@@ -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_ERROR_MASK (UIC_ERROR |\
|
||||
DEVICE_FATAL_ERROR |\
|
||||
CONTROLLER_FATAL_ERROR |\
|
||||
SYSTEM_BUS_FATAL_ERROR |\
|
||||
CRYPTO_ENGINE_FATAL_ERROR)
|
||||
#define UFSHCD_ERROR_MASK (UIC_ERROR | INT_FATAL_ERRORS)
|
||||
|
||||
#define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\
|
||||
CONTROLLER_FATAL_ERROR |\
|
||||
|
||||
@@ -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 fbcon_ops *ops = info->fbcon_par;
|
||||
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;
|
||||
|
||||
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
|
||||
if (p->userfont)
|
||||
old_data = vc->vc_font.data;
|
||||
vc->vc_font.data = (void *)(p->fontdata = data);
|
||||
old_userfont = p->userfont;
|
||||
if ((p->userfont = userfont))
|
||||
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.height = h;
|
||||
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);
|
||||
cols /= w;
|
||||
rows /= h;
|
||||
vc_resize(vc, cols, rows);
|
||||
ret = vc_resize(vc, cols, rows);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
} else if (con_is_visible(vc)
|
||||
&& vc->vc_mode == KD_TEXT) {
|
||||
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))
|
||||
kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -581,27 +581,30 @@ static int lock_pages(
|
||||
struct privcmd_dm_op_buf kbufs[], unsigned int num,
|
||||
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;
|
||||
int page_count;
|
||||
|
||||
requested = DIV_ROUND_UP(
|
||||
offset_in_page(kbufs[i].uptr) + kbufs[i].size,
|
||||
PAGE_SIZE);
|
||||
PAGE_SIZE) - off;
|
||||
if (requested > nr_pages)
|
||||
return -ENOSPC;
|
||||
|
||||
page_count = pin_user_pages_fast(
|
||||
(unsigned long) kbufs[i].uptr,
|
||||
(unsigned long)kbufs[i].uptr + off * PAGE_SIZE,
|
||||
requested, FOLL_WRITE, pages);
|
||||
if (page_count < 0)
|
||||
return page_count;
|
||||
if (page_count <= 0)
|
||||
return page_count ? : -EFAULT;
|
||||
|
||||
*pinned += page_count;
|
||||
nr_pages -= page_count;
|
||||
pages += page_count;
|
||||
|
||||
off = (requested == page_count) ? 0 : off + page_count;
|
||||
i += !off;
|
||||
}
|
||||
|
||||
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);
|
||||
if (rc < 0) {
|
||||
nr_pages = pinned;
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < kdata.num; i++) {
|
||||
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();
|
||||
|
||||
out:
|
||||
unlock_pages(pages, nr_pages);
|
||||
unlock_pages(pages, pinned);
|
||||
kfree(xbufs);
|
||||
kfree(pages);
|
||||
kfree(kbufs);
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
#include "ordered-data.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
|
||||
* to have good data has been truncated to zero. When it is set
|
||||
@@ -164,8 +171,9 @@ struct btrfs_inode {
|
||||
u64 disk_i_size;
|
||||
|
||||
/*
|
||||
* if this is a directory then index_cnt is the counter for the index
|
||||
* number for new files that are created
|
||||
* If this is a directory then index_cnt is the counter for the index
|
||||
* number for new files that are created. For an empty directory, this
|
||||
* must be initialized to BTRFS_DIR_START_INDEX.
|
||||
*/
|
||||
u64 index_cnt;
|
||||
|
||||
|
||||
@@ -105,14 +105,6 @@ struct btrfs_ref;
|
||||
#define BTRFS_STAT_CURR 0
|
||||
#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)
|
||||
{
|
||||
BUG_ON(num_stripes == 0);
|
||||
@@ -999,6 +991,12 @@ struct btrfs_fs_info {
|
||||
u32 csums_per_leaf;
|
||||
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. */
|
||||
spinlock_t swapfile_pins_lock;
|
||||
struct rb_root swapfile_pins;
|
||||
@@ -1017,6 +1015,8 @@ struct btrfs_fs_info {
|
||||
u64 zoned;
|
||||
};
|
||||
|
||||
/* Max size to emit ZONE_APPEND write command */
|
||||
u64 max_zone_append_size;
|
||||
struct mutex zoned_meta_io_lock;
|
||||
spinlock_t treelog_bg_lock;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID;
|
||||
|
||||
@@ -273,7 +273,7 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
|
||||
u64 num_bytes, u64 *meta_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 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.
|
||||
*/
|
||||
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);
|
||||
inode->csum_bytes += num_bytes;
|
||||
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;
|
||||
|
||||
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_calculate_inode_block_rsv_size(fs_info, inode);
|
||||
spin_unlock(&inode->lock);
|
||||
|
||||
@@ -165,7 +165,7 @@ no_valid_dev_replace_entry_found:
|
||||
*/
|
||||
if (btrfs_find_device(fs_info->fs_devices, &args)) {
|
||||
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;
|
||||
} else {
|
||||
dev_replace->srcdev = NULL;
|
||||
@@ -1151,8 +1151,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
|
||||
up_write(&dev_replace->rwsem);
|
||||
|
||||
/* Scrub for replace must not be running in suspended state */
|
||||
ret = btrfs_scrub_cancel(fs_info);
|
||||
ASSERT(ret != -ENOTCONN);
|
||||
btrfs_scrub_cancel(fs_info);
|
||||
|
||||
trans = btrfs_start_transaction(root, 0);
|
||||
if (IS_ERR(trans)) {
|
||||
|
||||
@@ -3006,6 +3006,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
|
||||
fs_info->sectorsize_bits = ilog2(4096);
|
||||
fs_info->stripesize = 4096;
|
||||
|
||||
fs_info->max_extent_size = BTRFS_MAX_EXTENT_SIZE;
|
||||
|
||||
spin_lock_init(&fs_info->swapfile_pins_lock);
|
||||
fs_info->swapfile_pins = RB_ROOT;
|
||||
|
||||
|
||||
@@ -1985,8 +1985,10 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
|
||||
struct page *locked_page, u64 *start,
|
||||
u64 *end)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
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_end;
|
||||
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,
|
||||
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;
|
||||
u64 delalloc_start = page_offset(page);
|
||||
u64 delalloc_to_write = 0;
|
||||
u64 delalloc_end = 0;
|
||||
int ret;
|
||||
@@ -4066,8 +4069,8 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
|
||||
struct extent_page_data *epd)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
u64 start = page_offset(page);
|
||||
u64 page_end = start + PAGE_SIZE - 1;
|
||||
const u64 page_start = page_offset(page);
|
||||
const u64 page_end = page_start + PAGE_SIZE - 1;
|
||||
int ret;
|
||||
int nr = 0;
|
||||
size_t pg_offset;
|
||||
@@ -4102,8 +4105,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
|
||||
}
|
||||
|
||||
if (!epd->extent_locked) {
|
||||
ret = writepage_delalloc(BTRFS_I(inode), page, wbc, start,
|
||||
&nr_written);
|
||||
ret = writepage_delalloc(BTRFS_I(inode), page, wbc, &nr_written);
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
if (ret)
|
||||
@@ -4153,7 +4155,7 @@ done:
|
||||
* capable of that.
|
||||
*/
|
||||
if (PageError(page))
|
||||
end_extent_writepage(page, ret, start, page_end);
|
||||
end_extent_writepage(page, ret, page_start, page_end);
|
||||
unlock_page(page);
|
||||
ASSERT(ret <= 0);
|
||||
return ret;
|
||||
|
||||
@@ -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,
|
||||
struct extent_state *orig, u64 split)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
u64 size;
|
||||
|
||||
/* not delalloc, ignore it */
|
||||
@@ -2039,7 +2040,7 @@ void btrfs_split_delalloc_extent(struct inode *inode,
|
||||
return;
|
||||
|
||||
size = orig->end - orig->start + 1;
|
||||
if (size > BTRFS_MAX_EXTENT_SIZE) {
|
||||
if (size > fs_info->max_extent_size) {
|
||||
u32 num_extents;
|
||||
u64 new_size;
|
||||
|
||||
@@ -2048,10 +2049,10 @@ void btrfs_split_delalloc_extent(struct inode *inode,
|
||||
* applies here, just in reverse.
|
||||
*/
|
||||
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;
|
||||
num_extents += count_max_extents(new_size);
|
||||
if (count_max_extents(size) >= num_extents)
|
||||
num_extents += count_max_extents(fs_info, new_size);
|
||||
if (count_max_extents(fs_info, size) >= num_extents)
|
||||
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,
|
||||
struct extent_state *other)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
u64 new_size, old_size;
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
btrfs_mod_outstanding_extents(BTRFS_I(inode), -1);
|
||||
spin_unlock(&BTRFS_I(inode)->lock);
|
||||
@@ -2107,10 +2109,10 @@ void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,
|
||||
* this case.
|
||||
*/
|
||||
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;
|
||||
num_extents += count_max_extents(old_size);
|
||||
if (count_max_extents(new_size) >= num_extents)
|
||||
num_extents += count_max_extents(fs_info, old_size);
|
||||
if (count_max_extents(fs_info, new_size) >= num_extents)
|
||||
return;
|
||||
|
||||
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)) {
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
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));
|
||||
|
||||
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_fs_info *fs_info = btrfs_sb(vfs_inode->i_sb);
|
||||
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)) {
|
||||
spin_lock(&inode->lock);
|
||||
@@ -6394,14 +6396,8 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode)
|
||||
goto out;
|
||||
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) {
|
||||
inode->index_cnt = 2;
|
||||
inode->index_cnt = BTRFS_DIR_START_INDEX;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -6412,7 +6408,7 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode)
|
||||
|
||||
if (found_key.objectid != btrfs_ino(inode) ||
|
||||
found_key.type != BTRFS_DIR_INDEX_KEY) {
|
||||
inode->index_cnt = 2;
|
||||
inode->index_cnt = BTRFS_DIR_START_INDEX;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -6956,7 +6952,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
goto fail;
|
||||
}
|
||||
d_instantiate(dentry, inode);
|
||||
btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent);
|
||||
btrfs_log_new_name(trans, old_dentry, NULL, parent);
|
||||
}
|
||||
|
||||
fail:
|
||||
@@ -9625,13 +9621,13 @@ static int btrfs_rename_exchange(struct inode *old_dir,
|
||||
BTRFS_I(new_inode)->dir_index = new_idx;
|
||||
|
||||
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);
|
||||
btrfs_end_log_trans(root);
|
||||
root_log_pinned = false;
|
||||
}
|
||||
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);
|
||||
btrfs_end_log_trans(dest);
|
||||
dest_log_pinned = false;
|
||||
@@ -9912,7 +9908,7 @@ static int btrfs_rename(struct user_namespace *mnt_userns,
|
||||
BTRFS_I(old_inode)->dir_index = index;
|
||||
|
||||
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);
|
||||
btrfs_end_log_trans(root);
|
||||
log_pinned = false;
|
||||
|
||||
@@ -351,9 +351,10 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
|
||||
key.offset = ref_id;
|
||||
again:
|
||||
ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
err = ret;
|
||||
goto out;
|
||||
if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
leaf = path->nodes[0];
|
||||
ref = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_root_ref);
|
||||
|
||||
@@ -6628,14 +6628,25 @@ void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||
mutex_unlock(&dir->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this after adding a new name for a file and it will properly
|
||||
* update the log to reflect the new name.
|
||||
/**
|
||||
* Update the log after adding a new name for an inode.
|
||||
*
|
||||
* @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,
|
||||
struct btrfs_inode *inode, struct btrfs_inode *old_dir,
|
||||
struct dentry *old_dentry, struct btrfs_inode *old_dir,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct btrfs_inode *inode = BTRFS_I(d_inode(old_dentry));
|
||||
struct btrfs_log_ctx ctx;
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,7 +84,7 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_inode *dir);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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,
|
||||
&bdev, &disk_super);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
btrfs_put_dev_args_from_path(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
args->devid = btrfs_stack_device_id(&disk_super->dev_item);
|
||||
memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE);
|
||||
if (btrfs_fs_incompat(fs_info, METADATA_UUID))
|
||||
|
||||
@@ -391,6 +391,9 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
|
||||
const char *name, const void *buffer,
|
||||
size_t size, int flags)
|
||||
{
|
||||
if (btrfs_root_readonly(BTRFS_I(inode)->root))
|
||||
return -EROFS;
|
||||
|
||||
name = xattr_full_name(handler, name);
|
||||
return btrfs_setxattr_trans(inode, name, buffer, size, flags);
|
||||
}
|
||||
|
||||
@@ -386,6 +386,16 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
|
||||
nr_sectors = bdev_nr_sectors(bdev);
|
||||
zone_info->zone_size_shift = ilog2(zone_info->zone_size);
|
||||
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))
|
||||
zone_info->nr_zones++;
|
||||
|
||||
@@ -570,6 +580,7 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||
u64 zoned_devices = 0;
|
||||
u64 nr_devices = 0;
|
||||
u64 zone_size = 0;
|
||||
u64 max_zone_append_size = 0;
|
||||
const bool incompat_zoned = btrfs_fs_incompat(fs_info, ZONED);
|
||||
int ret = 0;
|
||||
|
||||
@@ -605,6 +616,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||
ret = -EINVAL;
|
||||
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++;
|
||||
}
|
||||
@@ -654,7 +670,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
@@ -23,6 +23,7 @@ struct btrfs_zoned_device_info {
|
||||
*/
|
||||
u64 zone_size;
|
||||
u8 zone_size_shift;
|
||||
u64 max_zone_append_size;
|
||||
u32 nr_zones;
|
||||
unsigned long *seq_zones;
|
||||
unsigned long *empty_zones;
|
||||
|
||||
@@ -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,
|
||||
loff_t offset, loff_t len)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct cifsFileInfo *cfile = file->private_data;
|
||||
struct file_zero_data_information fsctl_buf;
|
||||
long rc;
|
||||
@@ -3608,14 +3608,12 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
inode = d_inode(cfile->dentry);
|
||||
|
||||
inode_lock(inode);
|
||||
/* Need to make file sparse, if not already, before freeing range. */
|
||||
/* Consider adding equivalent for compressed since it could also work */
|
||||
if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
free_xid(xid);
|
||||
return rc;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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,
|
||||
sizeof(struct file_zero_data_information),
|
||||
CIFSMaxBufSize, NULL, NULL);
|
||||
free_xid(xid);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
out:
|
||||
inode_unlock(inode);
|
||||
free_xid(xid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,10 +134,10 @@ static bool inode_io_list_move_locked(struct inode *inode,
|
||||
|
||||
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))
|
||||
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,
|
||||
@@ -164,7 +164,7 @@ static void wb_queue_work(struct bdi_writeback *wb,
|
||||
if (work->done)
|
||||
atomic_inc(&work->done->cnt);
|
||||
|
||||
spin_lock_bh(&wb->work_lock);
|
||||
spin_lock_irq(&wb->work_lock);
|
||||
|
||||
if (test_bit(WB_registered, &wb->state)) {
|
||||
list_add_tail(&work->list, &wb->work_list);
|
||||
@@ -172,7 +172,7 @@ static void wb_queue_work(struct bdi_writeback *wb,
|
||||
} else
|
||||
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;
|
||||
|
||||
spin_lock_bh(&wb->work_lock);
|
||||
spin_lock_irq(&wb->work_lock);
|
||||
if (!list_empty(&wb->work_list)) {
|
||||
work = list_entry(wb->work_list.next,
|
||||
struct wb_writeback_work, list);
|
||||
list_del_init(&work->list);
|
||||
}
|
||||
spin_unlock_bh(&wb->work_lock);
|
||||
spin_unlock_irq(&wb->work_lock);
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
@@ -3720,7 +3720,12 @@ done:
|
||||
copy_iov:
|
||||
iov_iter_restore(iter, state);
|
||||
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:
|
||||
/* it's reportedly faster than delegating the null check to kfree() */
|
||||
|
||||
@@ -4168,6 +4168,13 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
|
||||
err = -EPERM;
|
||||
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);
|
||||
|
||||
out_fput:
|
||||
|
||||
@@ -319,7 +319,7 @@ static int read_name_gen = 1;
|
||||
static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
||||
struct nfs_fh *src_fh, nfs4_stateid *stateid)
|
||||
{
|
||||
struct nfs_fattr fattr;
|
||||
struct nfs_fattr *fattr = nfs_alloc_fattr();
|
||||
struct file *filep, *res;
|
||||
struct nfs_server *server;
|
||||
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);
|
||||
|
||||
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) {
|
||||
res = ERR_PTR(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!S_ISREG(fattr->mode)) {
|
||||
res = ERR_PTR(-EBADF);
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = ERR_PTR(-ENOMEM);
|
||||
len = strlen(SSC_READ_NAME_BODY) + 16;
|
||||
read_name = kzalloc(len, GFP_NOFS);
|
||||
@@ -345,7 +351,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
||||
goto out;
|
||||
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);
|
||||
if (IS_ERR(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);
|
||||
if (IS_ERR(filep)) {
|
||||
res = ERR_CAST(filep);
|
||||
iput(r_ino);
|
||||
goto out_free_name;
|
||||
}
|
||||
filep->f_mode |= FMODE_READ;
|
||||
@@ -390,6 +397,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
||||
out_free_name:
|
||||
kfree(read_name);
|
||||
out:
|
||||
nfs_free_fattr(fattr);
|
||||
return res;
|
||||
out_stateowner:
|
||||
nfs4_put_state_owner(sp);
|
||||
|
||||
@@ -476,8 +476,7 @@ out:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
|
||||
static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns,
|
||||
struct inode *inode, int type,
|
||||
static struct posix_acl *ntfs_get_acl_ex(struct inode *inode, int type,
|
||||
int locked)
|
||||
{
|
||||
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. */
|
||||
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) {
|
||||
acl = NULL;
|
||||
} else {
|
||||
@@ -535,8 +534,7 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
|
||||
if (rcu)
|
||||
return ERR_PTR(-ECHILD);
|
||||
|
||||
/* TODO: init_user_ns? */
|
||||
return ntfs_get_acl_ex(&init_user_ns, inode, type, 0);
|
||||
return ntfs_get_acl_ex(inode, type, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!value)
|
||||
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)
|
||||
goto out;
|
||||
flags = 0;
|
||||
@@ -639,7 +637,7 @@ static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
|
||||
if (!acl)
|
||||
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);
|
||||
|
||||
return err;
|
||||
@@ -663,12 +661,12 @@ static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
|
||||
if (!value) {
|
||||
acl = NULL;
|
||||
} else {
|
||||
acl = posix_acl_from_xattr(mnt_userns, value, size);
|
||||
acl = posix_acl_from_xattr(&init_user_ns, value, size);
|
||||
if (IS_ERR(acl))
|
||||
return PTR_ERR(acl);
|
||||
|
||||
if (acl) {
|
||||
err = posix_acl_valid(mnt_userns, acl);
|
||||
err = posix_acl_valid(&init_user_ns, acl);
|
||||
if (err)
|
||||
goto release_and_out;
|
||||
}
|
||||
|
||||
@@ -503,10 +503,12 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
|
||||
struct vm_area_struct *vma = walk->vma;
|
||||
bool locked = !!(vma->vm_flags & VM_LOCKED);
|
||||
struct page *page = NULL;
|
||||
bool migration = false;
|
||||
bool migration = false, young = false, dirty = false;
|
||||
|
||||
if (pte_present(*pte)) {
|
||||
page = vm_normal_page(vma, addr, *pte);
|
||||
young = pte_young(*pte);
|
||||
dirty = pte_dirty(*pte);
|
||||
} else if (is_swap_pte(*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)
|
||||
return;
|
||||
|
||||
smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte),
|
||||
locked, migration);
|
||||
smaps_account(mss, page, false, young, dirty, locked, migration);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
|
||||
@@ -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 zonefs_inode_info *zi = ZONEFS_I(inode);
|
||||
struct block_device *bdev = inode->i_sb->s_bdev;
|
||||
unsigned int max;
|
||||
unsigned int max = bdev_max_zone_append_sectors(bdev);
|
||||
struct bio *bio;
|
||||
ssize_t size;
|
||||
int nr_pages;
|
||||
ssize_t ret;
|
||||
|
||||
max = queue_max_zone_append_sectors(bdev_get_queue(bdev));
|
||||
max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
|
||||
iov_iter_truncate(from, max);
|
||||
|
||||
|
||||
@@ -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
|
||||
* 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
|
||||
* @virt: virtual address 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;
|
||||
|
||||
return (virt >= begin && virt < end) || (vend >= begin && vend < end);
|
||||
if (virt < end && vend > begin)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int retval = 512;
|
||||
|
||||
@@ -1045,4 +1045,22 @@ cpumap_print_list_to_buf(char *buf, const struct cpumask *mask,
|
||||
[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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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,
|
||||
enum node_stat_item idx)
|
||||
{
|
||||
struct mem_cgroup_per_node *pn;
|
||||
long x;
|
||||
|
||||
if (mem_cgroup_disabled())
|
||||
return node_page_state(lruvec_pgdat(lruvec), idx);
|
||||
|
||||
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,
|
||||
|
||||
@@ -759,6 +759,7 @@ struct mlx5_core_dev {
|
||||
enum mlx5_device_state state;
|
||||
/* sync interface state */
|
||||
struct mutex intf_state_mutex;
|
||||
struct lock_class_key lock_key;
|
||||
unsigned long intf_state;
|
||||
struct mlx5_priv priv;
|
||||
struct mlx5_profile profile;
|
||||
|
||||
@@ -626,9 +626,23 @@ extern int sysctl_devconf_inherit_init_net;
|
||||
*/
|
||||
static inline bool net_has_fallback_tunnels(const struct net *net)
|
||||
{
|
||||
return !IS_ENABLED(CONFIG_SYSCTL) ||
|
||||
!sysctl_fb_tunnels_only_for_init_net ||
|
||||
(net == &init_net && sysctl_fb_tunnels_only_for_init_net == 1);
|
||||
#if IS_ENABLED(CONFIG_SYSCTL)
|
||||
int fb_tunnels_only_for_init_net = READ_ONCE(sysctl_fb_tunnels_only_for_init_net);
|
||||
|
||||
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)
|
||||
|
||||
@@ -94,10 +94,6 @@ struct ebt_table {
|
||||
struct ebt_replace_kernel *table;
|
||||
unsigned int valid_hooks;
|
||||
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 */
|
||||
struct ebt_table_info *private;
|
||||
struct nf_hook_ops *ops;
|
||||
|
||||
@@ -33,7 +33,7 @@ extern unsigned int sysctl_net_busy_poll __read_mostly;
|
||||
|
||||
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)
|
||||
|
||||
@@ -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 *tuple);
|
||||
void nf_flow_table_gc_run(struct nf_flowtable *flow_table);
|
||||
void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
|
||||
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);
|
||||
|
||||
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,
|
||||
struct net_device *dev,
|
||||
enum flow_block_command cmd);
|
||||
|
||||
@@ -193,13 +193,18 @@ struct nft_ctx {
|
||||
bool report;
|
||||
};
|
||||
|
||||
struct nft_data_desc {
|
||||
enum nft_data_types type;
|
||||
unsigned int len;
|
||||
enum nft_data_desc_flags {
|
||||
NFT_DATA_DESC_SETELEM = (1 << 0),
|
||||
};
|
||||
|
||||
int nft_data_init(const struct nft_ctx *ctx,
|
||||
struct nft_data *data, unsigned int size,
|
||||
struct nft_data_desc {
|
||||
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);
|
||||
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);
|
||||
@@ -1595,6 +1600,7 @@ struct nftables_pernet {
|
||||
struct list_head module_list;
|
||||
struct list_head notify_list;
|
||||
struct mutex commit_mutex;
|
||||
u64 table_handle;
|
||||
unsigned int base_seq;
|
||||
u8 validate_state;
|
||||
};
|
||||
|
||||
@@ -40,6 +40,14 @@ struct nft_cmp_fast_expr {
|
||||
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_data data;
|
||||
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_cmp16_fast_ops;
|
||||
|
||||
struct nft_payload {
|
||||
enum nft_payload_bases base:8;
|
||||
|
||||
@@ -571,6 +571,8 @@ __u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss);
|
||||
#endif
|
||||
/* 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,
|
||||
int nonagle);
|
||||
int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs);
|
||||
|
||||
@@ -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);
|
||||
if (ret < 0) {
|
||||
audit_mark->path = NULL;
|
||||
fsnotify_put_mark(&audit_mark->mark);
|
||||
audit_mark = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
@@ -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_reg_state *regs = cur_regs(env), *reg;
|
||||
struct bpf_map *map = meta->map_ptr;
|
||||
struct tnum range;
|
||||
u64 val;
|
||||
u64 val, max;
|
||||
int err;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
range = tnum_range(0, map->max_entries - 1);
|
||||
reg = ®s[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);
|
||||
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);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val = reg->var_off.value;
|
||||
if (bpf_map_key_unseen(aux))
|
||||
bpf_map_key_store(aux, val);
|
||||
else if (!bpf_map_key_poisoned(aux) &&
|
||||
|
||||
@@ -1810,6 +1810,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
|
||||
|
||||
if (ss->css_rstat_flush) {
|
||||
list_del_rcu(&css->rstat_css_node);
|
||||
synchronize_rcu();
|
||||
list_add_rcu(&css->rstat_css_node,
|
||||
&dcgrp->rstat_css_list);
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@ COND_SYSCALL(landlock_restrict_self);
|
||||
|
||||
/* mm/fadvise.c */
|
||||
COND_SYSCALL(fadvise64_64);
|
||||
COND_SYSCALL_COMPAT(fadvise64_64);
|
||||
|
||||
/* mm/, CONFIG_MMU only */
|
||||
COND_SYSCALL(swapon);
|
||||
|
||||
@@ -26,10 +26,16 @@
|
||||
*/
|
||||
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;
|
||||
int ret;
|
||||
|
||||
if (!rs->interval)
|
||||
if (!interval)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
@@ -44,7 +50,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
||||
if (!rs->begin)
|
||||
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->flags & RATELIMIT_MSG_ON_RELEASE)) {
|
||||
printk_deferred(KERN_WARNING
|
||||
@@ -56,7 +62,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
||||
rs->begin = jiffies;
|
||||
rs->printed = 0;
|
||||
}
|
||||
if (rs->burst && rs->burst > rs->printed) {
|
||||
if (burst && burst > rs->printed) {
|
||||
rs->printed++;
|
||||
ret = 1;
|
||||
} else {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user