Merge remote-tracking branch 'stable/linux-6.12.y' into rpi-6.12.y

This commit is contained in:
Dom Cobley
2025-12-01 15:52:53 +00:00
112 changed files with 850 additions and 522 deletions

View File

@@ -50,18 +50,20 @@ patternProperties:
groups:
description:
Name of the pin group to use for the functions.
$ref: /schemas/types.yaml#/definitions/string
enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp,
i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp,
spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp,
spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp,
uart0_grp, uart1_grp, uart2_grp, uart3_grp,
pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp,
pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp,
pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp,
pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp,
pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp,
pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp]
items:
enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp,
i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp,
spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp,
spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp,
uart0_grp, uart1_grp, uart2_grp, uart3_grp,
pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp,
pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp,
pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp,
pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp,
pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp,
pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp]
minItems: 1
maxItems: 8
drive-strength:
enum: [2, 4, 6, 8, 16, 24, 32]

View File

@@ -50,6 +50,7 @@ to matching WMI devices using a struct wmi_device_id table:
::
static const struct wmi_device_id foo_id_table[] = {
/* Only use uppercase letters! */
{ "936DA01F-9ABD-4D9D-80C7-02AF85C822A8", NULL },
{ }
};

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 12
SUBLEVEL = 59
SUBLEVEL = 60
EXTRAVERSION =
NAME = Baby Opossum Posse

View File

@@ -3,7 +3,7 @@
* Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd
*/
#include "rk3399.dtsi"
#include "rk3399-base.dtsi"
/ {
cluster0_opp: opp-table-0 {

View File

@@ -789,7 +789,7 @@
vccio1-supply = <&vccio_acodec>;
vccio2-supply = <&vcc_1v8>;
vccio3-supply = <&vccio_sd>;
vccio4-supply = <&vcc_1v8>;
vccio4-supply = <&vcca1v8_pmu>;
vccio5-supply = <&vcc_1v8>;
vccio6-supply = <&vcc1v8_dvp>;
vccio7-supply = <&vcc_3v3>;

View File

@@ -359,14 +359,12 @@
cap-mmc-highspeed;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
mmc-pwrseq = <&emmc_pwrseq>;
no-sdio;
no-sd;
non-removable;
pinctrl-names = "default";
pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk>;
vmmc-supply = <&vcc_3v3_s3>;
vqmmc-supply = <&vcc_1v8_s3>;
status = "okay";

View File

@@ -85,8 +85,8 @@
gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
regulator-name = "vcc3v3_pcie20";
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
startup-delay-us = <50000>;
vin-supply = <&vcc5v0_sys>;
};

View File

@@ -437,7 +437,7 @@ static void __do_ffa_mem_xfer(const u64 func_id,
struct ffa_mem_region_attributes *ep_mem_access;
struct ffa_composite_mem_region *reg;
struct ffa_mem_region *buf;
u32 offset, nr_ranges;
u32 offset, nr_ranges, checked_offset;
int ret = 0;
if (addr_mbz || npages_mbz || fraglen > len ||
@@ -474,7 +474,12 @@ static void __do_ffa_mem_xfer(const u64 func_id,
goto out_unlock;
}
if (fraglen < offset + sizeof(struct ffa_composite_mem_region)) {
if (check_add_overflow(offset, sizeof(struct ffa_composite_mem_region), &checked_offset)) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out_unlock;
}
if (fraglen < checked_offset) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out_unlock;
}

View File

@@ -2176,15 +2176,6 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
.val = 0, \
}
/* sys_reg_desc initialiser for known cpufeature ID registers */
#define AA32_ID_SANITISED(name) { \
ID_DESC(name), \
.set_user = set_id_reg, \
.visibility = aa32_id_visibility, \
.reset = kvm_read_sanitised_id_reg, \
.val = 0, \
}
/* sys_reg_desc initialiser for writable ID registers */
#define ID_WRITABLE(name, mask) { \
ID_DESC(name), \
@@ -2194,6 +2185,19 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
.val = mask, \
}
/*
* 32bit ID regs are fully writable when the guest is 32bit
* capable. Nothing in the KVM code should rely on 32bit features
* anyway, only 64bit, so let the VMM do its worse.
*/
#define AA32_ID_WRITABLE(name) { \
ID_DESC(name), \
.set_user = set_id_reg, \
.visibility = aa32_id_visibility, \
.reset = kvm_read_sanitised_id_reg, \
.val = GENMASK(31, 0), \
}
/*
* sys_reg_desc initialiser for architecturally unallocated cpufeature ID
* register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2
@@ -2380,40 +2384,39 @@ static const struct sys_reg_desc sys_reg_descs[] = {
/* AArch64 mappings of the AArch32 ID registers */
/* CRm=1 */
AA32_ID_SANITISED(ID_PFR0_EL1),
AA32_ID_SANITISED(ID_PFR1_EL1),
AA32_ID_WRITABLE(ID_PFR0_EL1),
AA32_ID_WRITABLE(ID_PFR1_EL1),
{ SYS_DESC(SYS_ID_DFR0_EL1),
.access = access_id_reg,
.get_user = get_id_reg,
.set_user = set_id_dfr0_el1,
.visibility = aa32_id_visibility,
.reset = read_sanitised_id_dfr0_el1,
.val = ID_DFR0_EL1_PerfMon_MASK |
ID_DFR0_EL1_CopDbg_MASK, },
.val = GENMASK(31, 0), },
ID_HIDDEN(ID_AFR0_EL1),
AA32_ID_SANITISED(ID_MMFR0_EL1),
AA32_ID_SANITISED(ID_MMFR1_EL1),
AA32_ID_SANITISED(ID_MMFR2_EL1),
AA32_ID_SANITISED(ID_MMFR3_EL1),
AA32_ID_WRITABLE(ID_MMFR0_EL1),
AA32_ID_WRITABLE(ID_MMFR1_EL1),
AA32_ID_WRITABLE(ID_MMFR2_EL1),
AA32_ID_WRITABLE(ID_MMFR3_EL1),
/* CRm=2 */
AA32_ID_SANITISED(ID_ISAR0_EL1),
AA32_ID_SANITISED(ID_ISAR1_EL1),
AA32_ID_SANITISED(ID_ISAR2_EL1),
AA32_ID_SANITISED(ID_ISAR3_EL1),
AA32_ID_SANITISED(ID_ISAR4_EL1),
AA32_ID_SANITISED(ID_ISAR5_EL1),
AA32_ID_SANITISED(ID_MMFR4_EL1),
AA32_ID_SANITISED(ID_ISAR6_EL1),
AA32_ID_WRITABLE(ID_ISAR0_EL1),
AA32_ID_WRITABLE(ID_ISAR1_EL1),
AA32_ID_WRITABLE(ID_ISAR2_EL1),
AA32_ID_WRITABLE(ID_ISAR3_EL1),
AA32_ID_WRITABLE(ID_ISAR4_EL1),
AA32_ID_WRITABLE(ID_ISAR5_EL1),
AA32_ID_WRITABLE(ID_MMFR4_EL1),
AA32_ID_WRITABLE(ID_ISAR6_EL1),
/* CRm=3 */
AA32_ID_SANITISED(MVFR0_EL1),
AA32_ID_SANITISED(MVFR1_EL1),
AA32_ID_SANITISED(MVFR2_EL1),
AA32_ID_WRITABLE(MVFR0_EL1),
AA32_ID_WRITABLE(MVFR1_EL1),
AA32_ID_WRITABLE(MVFR2_EL1),
ID_UNALLOCATED(3,3),
AA32_ID_SANITISED(ID_PFR2_EL1),
AA32_ID_WRITABLE(ID_PFR2_EL1),
ID_HIDDEN(ID_DFR1_EL1),
AA32_ID_SANITISED(ID_MMFR5_EL1),
AA32_ID_WRITABLE(ID_MMFR5_EL1),
ID_UNALLOCATED(3,7),
/* AArch64 ID registers */

View File

@@ -10,10 +10,6 @@
#include <linux/types.h>
#ifndef __KERNEL__
#include <stdint.h>
#endif
/*
* For PTRACE_{POKE,PEEK}USR. 0 - 31 are GPRs,
* 32 is syscall's original ARG0, 33 is PC, 34 is BADVADDR.
@@ -41,44 +37,44 @@ struct user_pt_regs {
} __attribute__((aligned(8)));
struct user_fp_state {
uint64_t fpr[32];
uint64_t fcc;
uint32_t fcsr;
__u64 fpr[32];
__u64 fcc;
__u32 fcsr;
};
struct user_lsx_state {
/* 32 registers, 128 bits width per register. */
uint64_t vregs[32*2];
__u64 vregs[32*2];
};
struct user_lasx_state {
/* 32 registers, 256 bits width per register. */
uint64_t vregs[32*4];
__u64 vregs[32*4];
};
struct user_lbt_state {
uint64_t scr[4];
uint32_t eflags;
uint32_t ftop;
__u64 scr[4];
__u32 eflags;
__u32 ftop;
};
struct user_watch_state {
uint64_t dbg_info;
__u64 dbg_info;
struct {
uint64_t addr;
uint64_t mask;
uint32_t ctrl;
uint32_t pad;
__u64 addr;
__u64 mask;
__u32 ctrl;
__u32 pad;
} dbg_regs[8];
};
struct user_watch_state_v2 {
uint64_t dbg_info;
__u64 dbg_info;
struct {
uint64_t addr;
uint64_t mask;
uint32_t ctrl;
uint32_t pad;
__u64 addr;
__u64 mask;
__u32 ctrl;
__u32 pad;
} dbg_regs[14];
};

View File

@@ -51,11 +51,11 @@ static int __init pcibios_init(void)
*/
lsize = cpu_last_level_cache_line_size();
BUG_ON(!lsize);
if (lsize) {
pci_dfl_cache_line_size = lsize >> 2;
pci_dfl_cache_line_size = lsize >> 2;
pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
}
return 0;
}

View File

@@ -241,16 +241,22 @@ mips_pci_controller:
#endif
/*
* Setup the Malta max (2GB) memory for PCI DMA in host bridge
* in transparent addressing mode.
* Set up memory mapping in host bridge for PCI DMA masters,
* in transparent addressing mode. For EVA use the Malta
* maximum of 2 GiB memory in the alias space at 0x80000000
* as per PHYS_OFFSET. Otherwise use 256 MiB of memory in
* the regular space, avoiding mapping the PCI MMIO window
* for DMA as it seems to confuse the system controller's
* logic, causing PCI MMIO to stop working.
*/
mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH;
MSC_WRITE(MSC01_PCI_BAR0, mask);
MSC_WRITE(MSC01_PCI_HEAD4, mask);
mask = PHYS_OFFSET ? PHYS_OFFSET : 0xf0000000;
MSC_WRITE(MSC01_PCI_BAR0,
mask | PCI_BASE_ADDRESS_MEM_PREFETCH);
MSC_WRITE(MSC01_PCI_HEAD4,
PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH);
mask &= MSC01_PCI_BAR0_SIZE_MSK;
MSC_WRITE(MSC01_PCI_P2SCMSKL, mask);
MSC_WRITE(MSC01_PCI_P2SCMAPL, mask);
MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET);
/* Don't handle target retries indefinitely. */
if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==

View File

@@ -1109,17 +1109,15 @@ static inline pte_t pte_mkhuge(pte_t pte)
#define IPTE_NODAT 0x400
#define IPTE_GUEST_ASCE 0x800
static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep,
unsigned long opt, unsigned long asce,
int local)
static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, int local)
{
unsigned long pto;
pto = __pa(ptep) & ~(PTRS_PER_PTE * sizeof(pte_t) - 1);
asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%[asce],%[m4]"
asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%%r0,%[m4]"
: "+m" (*ptep)
: [r1] "a" (pto), [r2] "a" ((addr & PAGE_MASK) | opt),
[asce] "a" (asce), [m4] "i" (local));
: [r1] "a" (pto), [r2] "a" (addr & PAGE_MASK),
[m4] "i" (local));
}
static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep,
@@ -1303,7 +1301,7 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
* A local RDP can be used to do the flush.
*/
if (MACHINE_HAS_RDP && !(pte_val(*ptep) & _PAGE_PROTECT))
__ptep_rdp(address, ptep, 0, 0, 1);
__ptep_rdp(address, ptep, 1);
}
#define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault

View File

@@ -293,9 +293,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
preempt_disable();
atomic_inc(&mm->context.flush_count);
if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
__ptep_rdp(addr, ptep, 0, 0, 1);
__ptep_rdp(addr, ptep, 1);
else
__ptep_rdp(addr, ptep, 0, 0, 0);
__ptep_rdp(addr, ptep, 0);
/*
* PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That
* means it is still valid and active, and must not be changed according

View File

@@ -224,6 +224,24 @@ static bool need_sha_check(u32 cur_rev)
return true;
}
static bool cpu_has_entrysign(void)
{
unsigned int fam = x86_family(bsp_cpuid_1_eax);
unsigned int model = x86_model(bsp_cpuid_1_eax);
if (fam == 0x17 || fam == 0x19)
return true;
if (fam == 0x1a) {
if (model <= 0x2f ||
(0x40 <= model && model <= 0x4f) ||
(0x60 <= model && model <= 0x6f))
return true;
}
return false;
}
static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsigned int len)
{
struct patch_digest *pd = NULL;
@@ -231,7 +249,7 @@ static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsi
struct sha256_state s;
int i;
if (x86_family(bsp_cpuid_1_eax) < 0x17)
if (!cpu_has_entrysign())
return true;
if (!need_sha_check(cur_rev))

View File

@@ -282,7 +282,7 @@ bool __blk_crypto_bio_prep(struct bio **bio_ptr)
}
if (!bio_crypt_check_alignment(bio)) {
bio->bi_status = BLK_STS_IOERR;
bio->bi_status = BLK_STS_INVAL;
goto fail;
}

View File

@@ -991,6 +991,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
return;
}
if (ata_id_is_locked(dev->id)) {
/* Security locked */
/* LOGICAL UNIT ACCESS NOT AUTHORIZED */
ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71);
return;
}
if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
ata_dev_dbg(dev,
"Missing result TF: reporting aborted command\n");
@@ -4800,8 +4807,10 @@ void ata_scsi_dev_rescan(struct work_struct *work)
spin_unlock_irqrestore(ap->lock, flags);
if (do_resume) {
ret = scsi_resume_device(sdev);
if (ret == -EWOULDBLOCK)
if (ret == -EWOULDBLOCK) {
scsi_device_put(sdev);
goto unlock_scan;
}
dev->flags &= ~ATA_DFLAG_RESUMING;
}
ret = scsi_rescan_device(sdev);

View File

@@ -294,6 +294,8 @@ static int bcma_register_devices(struct bcma_bus *bus)
int err;
list_for_each_entry(core, &bus->cores, list) {
struct device_node *np;
/* We support that core ourselves */
switch (core->id.id) {
case BCMA_CORE_4706_CHIPCOMMON:
@@ -311,6 +313,10 @@ static int bcma_register_devices(struct bcma_bus *bus)
if (bcma_is_core_needed_early(core->id.id))
continue;
np = core->dev.of_node;
if (np && !of_device_is_available(np))
continue;
/* Only first GMAC core on BCM4706 is connected and working */
if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
core->core_unit > 0)

View File

@@ -41,7 +41,7 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode)
!strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME))
return ERR_PTR(-ENOENT);
gdev = gpio_device_find_by_fwnode(fwnode);
gdev = gpio_device_find_by_label(gdev_node->name);
return gdev ?: ERR_PTR(-EPROBE_DEFER);
}

View File

@@ -3090,10 +3090,11 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA))
continue;
/* skip CG for VCE/UVD, it's handled specially */
/* skip CG for VCE/UVD/VPE, it's handled specially */
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VPE &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_JPEG &&
adev->ip_blocks[i].version->funcs->set_powergating_state) {
/* enable powergating to save power */

View File

@@ -555,7 +555,8 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
return -EINVAL;
}
if (adev->kfd.init_complete && !amdgpu_in_reset(adev))
if (adev->kfd.init_complete && !amdgpu_in_reset(adev) &&
!adev->in_suspend)
flags |= AMDGPU_XCP_OPS_KFD;
if (flags & AMDGPU_XCP_OPS_KFD) {

View File

@@ -5642,9 +5642,9 @@ static void gfx_v11_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
if (flags & AMDGPU_IB_PREEMPTED)
control |= INDIRECT_BUFFER_PRE_RESUME(1);
if (vmid)
if (vmid && !ring->adev->gfx.rs64_enable)
gfx_v11_0_ring_emit_de_meta(ring,
(!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false);
!amdgpu_sriov_vf(ring->adev) && (flags & AMDGPU_IB_PREEMPTED));
}
if (ring->is_mes_queue)

View File

@@ -2297,7 +2297,9 @@ static int gfx_v9_4_3_cp_resume(struct amdgpu_device *adev)
r = amdgpu_xcp_init(adev->xcp_mgr, num_xcp, mode);
} else {
if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr,
if (adev->in_suspend)
amdgpu_xcp_restore_partition_mode(adev->xcp_mgr);
else if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr,
AMDGPU_XCP_FL_NONE) ==
AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE)
r = amdgpu_xcp_switch_partition_mode(

View File

@@ -846,26 +846,28 @@ struct dsc_mst_fairness_params {
};
#if defined(CONFIG_DRM_AMD_DC_FP)
static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link)
static uint64_t kbps_to_pbn(int kbps, bool is_peak_pbn)
{
u8 link_coding_cap;
uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B;
uint64_t effective_kbps = (uint64_t)kbps;
link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link);
if (link_coding_cap == DP_128b_132b_ENCODING)
fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B;
if (is_peak_pbn) { // add 0.6% (1006/1000) overhead into effective kbps
effective_kbps *= 1006;
effective_kbps = div_u64(effective_kbps, 1000);
}
return fec_overhead_multiplier_x1000;
return (uint64_t) DIV64_U64_ROUND_UP(effective_kbps * 64, (54 * 8 * 1000));
}
static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000)
static uint32_t pbn_to_kbps(unsigned int pbn, bool with_margin)
{
u64 peak_kbps = kbps;
uint64_t pbn_effective = (uint64_t)pbn;
peak_kbps *= 1006;
peak_kbps *= fec_overhead_multiplier_x1000;
peak_kbps = div_u64(peak_kbps, 1000 * 1000);
return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
if (with_margin) // deduct 0.6% (994/1000) overhead from effective pbn
pbn_effective *= (1000000 / PEAK_FACTOR_X1000);
else
pbn_effective *= 1000;
return DIV_U64_ROUND_UP(pbn_effective * 8 * 54, 64);
}
static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params,
@@ -936,7 +938,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options);
dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
kbps = pbn_to_kbps(pbn, false);
dc_dsc_compute_config(
param.sink->ctx->dc->res_pool->dscs[0],
&param.sink->dsc_caps.dsc_dec_caps,
@@ -965,12 +967,11 @@ static int increase_dsc_bpp(struct drm_atomic_state *state,
int link_timeslots_used;
int fair_pbn_alloc;
int ret = 0;
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
for (i = 0; i < count; i++) {
if (vars[i + k].dsc_enabled) {
initial_slack[i] =
kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn;
kbps_to_pbn(params[i].bw_range.max_kbps, false) - vars[i + k].pbn;
bpp_increased[i] = false;
remaining_to_increase += 1;
} else {
@@ -1066,7 +1067,6 @@ static int try_disable_dsc(struct drm_atomic_state *state,
int next_index;
int remaining_to_try = 0;
int ret;
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
int var_pbn;
for (i = 0; i < count; i++) {
@@ -1099,7 +1099,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index);
var_pbn = vars[next_index].pbn;
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
vars[next_index].pbn = kbps_to_pbn(params[next_index].bw_range.stream_kbps, true);
ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr,
params[next_index].port,
@@ -1159,7 +1159,6 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
int count = 0;
int i, k, ret;
bool debugfs_overwrite = false;
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
struct drm_connector_state *new_conn_state;
memset(params, 0, sizeof(params));
@@ -1240,7 +1239,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
DRM_DEBUG_DRIVER("MST_DSC Try no compression\n");
for (i = 0; i < count; i++) {
vars[i + k].aconnector = params[i].aconnector;
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false);
vars[i + k].dsc_enabled = false;
vars[i + k].bpp_x16 = 0;
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
@@ -1262,7 +1261,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
DRM_DEBUG_DRIVER("MST_DSC Try max compression\n");
for (i = 0; i < count; i++) {
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.min_kbps, false);
vars[i + k].dsc_enabled = true;
vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
@@ -1270,7 +1269,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
if (ret < 0)
return ret;
} else {
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false);
vars[i + k].dsc_enabled = false;
vars[i + k].bpp_x16 = 0;
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
@@ -1722,18 +1721,6 @@ clean_exit:
return ret;
}
static uint32_t kbps_from_pbn(unsigned int pbn)
{
uint64_t kbps = (uint64_t)pbn;
kbps *= (1000000 / PEAK_FACTOR_X1000);
kbps *= 8;
kbps *= 54;
kbps /= 64;
return (uint32_t)kbps;
}
static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
struct dc_dsc_bw_range *bw_range)
{
@@ -1825,7 +1812,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
dc_link_get_highest_encoding_format(stream->link));
cur_link_settings = stream->link->verified_link_cap;
root_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, &cur_link_settings);
virtual_channel_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn);
virtual_channel_bw_in_kbps = pbn_to_kbps(aconnector->mst_output_port->full_pbn, true);
/* pick the end to end bw bottleneck */
end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
@@ -1876,7 +1863,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
immediate_upstream_port = aconnector->mst_output_port->parent->port_parent;
if (immediate_upstream_port) {
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
virtual_channel_bw_in_kbps = pbn_to_kbps(immediate_upstream_port->full_pbn, true);
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
} else {
/* For topology LCT 1 case - only one mstb*/

View File

@@ -377,6 +377,8 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
display_count = dcn35_get_active_display_cnt_wa(dc, context, &all_active_disps);
if (new_clocks->dtbclk_en && !new_clocks->ref_dtbclk_khz)
new_clocks->ref_dtbclk_khz = 600000;
else if (!new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz > 590000)
new_clocks->ref_dtbclk_khz = 0;
/*
* if it is safe to lower, but we are already in the lower state, we don't have to do anything
@@ -393,6 +395,7 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
if (clk_mgr->base.ctx->dc->config.allow_0_dtb_clk)
dcn35_smu_set_dtbclk(clk_mgr, false);
clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
}
/* check that we're not already in lower */
@@ -410,11 +413,17 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
}
if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
dcn35_smu_set_dtbclk(clk_mgr, true);
clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
int actual_dtbclk = 0;
dcn35_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
dcn35_smu_set_dtbclk(clk_mgr, true);
actual_dtbclk = REG_READ(CLK1_CLK4_CURRENT_CNT);
if (actual_dtbclk > 590000) {
clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
}
}
/* check that we're not already in D0 */
@@ -581,12 +590,10 @@ static bool dcn35_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
static void init_clk_states(struct clk_mgr *clk_mgr)
{
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
if (clk_mgr_int->smu_ver >= SMU_VER_THRESHOLD)
clk_mgr->clks.dtbclk_en = true; // request DTBCLK disable on first commit
clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk
clk_mgr->clks.p_state_change_support = true;
clk_mgr->clks.prev_p_state_change_support = true;
@@ -597,6 +604,7 @@ static void init_clk_states(struct clk_mgr *clk_mgr)
void dcn35_init_clocks(struct clk_mgr *clk_mgr)
{
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
init_clk_states(clk_mgr);
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk

View File

@@ -39,6 +39,7 @@
#define CTX \
dccg_dcn->base.ctx
#include "logger_types.h"
#define DC_LOGGER \
dccg->ctx->logger
@@ -391,6 +392,7 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
return;
@@ -411,6 +413,8 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
BREAK_TO_DEBUGGER();
break;
}
//DC_LOG_DEBUG("%s: inst(%d) DPPCLK rcg_disable: %d\n", __func__, inst, enable ? 0 : 1);
}
static void dccg35_set_dpstreamclk_rcg(
@@ -1112,30 +1116,24 @@ static void dcn35_set_dppclk_enable(struct dccg *dccg,
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
switch (dpp_inst) {
case 0:
REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);
break;
case 1:
REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable);
break;
case 2:
REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable);
break;
case 3:
REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable);
break;
default:
break;
}
DC_LOG_DEBUG("%s: dpp_inst(%d) DPPCLK_EN = %d\n", __func__, dpp_inst, enable);
}
@@ -1163,14 +1161,18 @@ static void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst,
ASSERT(false);
phase = 0xff;
}
dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, phase,
DPPCLK0_DTO_MODULO, modulo);
dcn35_set_dppclk_enable(dccg, dpp_inst, true);
} else
} else {
dcn35_set_dppclk_enable(dccg, dpp_inst, false);
/*we have this in hwss: disable_plane*/
//dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
}
dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
}
@@ -1182,6 +1184,7 @@ static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
return;
switch (dpp_inst) {
case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);
@@ -1198,6 +1201,8 @@ static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,
default:
break;
}
//DC_LOG_DEBUG("%s: dpp_inst(%d) rcg: %d\n", __func__, dpp_inst, enable);
}
static void dccg35_get_pixel_rate_div(
@@ -1396,7 +1401,11 @@ static void dccg35_set_dtbclk_dto(
* PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the
* programming is handled in program_pix_clk() regardless, so it can be removed from here.
*/
} else {
DC_LOG_DEBUG("%s: OTG%d DTBCLK DTO enabled: pixclk_khz=%d, ref_dtbclk_khz=%d, req_dtbclk_khz=%d, phase=%d, modulo=%d\n",
__func__, params->otg_inst, params->pixclk_khz,
params->ref_dtbclk_khz, req_dtbclk_khz, phase, modulo);
} else if (!params->ref_dtbclk_khz && !req_dtbclk_khz) {
switch (params->otg_inst) {
case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 0);
@@ -1421,6 +1430,8 @@ static void dccg35_set_dtbclk_dto(
REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
DC_LOG_DEBUG("%s: OTG%d DTBCLK DTO disabled\n", __func__, params->otg_inst);
}
}
@@ -1465,6 +1476,8 @@ static void dccg35_set_dpstreamclk(
BREAK_TO_DEBUGGER();
return;
}
DC_LOG_DEBUG("%s: dp_hpo_inst(%d) DPSTREAMCLK_EN = %d, DPSTREAMCLK_SRC_SEL = %d\n",
__func__, dp_hpo_inst, (src == REFCLK) ? 0 : 1, otg_inst);
}
@@ -1504,6 +1517,8 @@ static void dccg35_set_dpstreamclk_root_clock_gating(
BREAK_TO_DEBUGGER();
return;
}
DC_LOG_DEBUG("%s: dp_hpo_inst(%d) DPSTREAMCLK_ROOT_GATE_DISABLE = %d\n",
__func__, dp_hpo_inst, enable ? 1 : 0);
}
@@ -1521,28 +1536,30 @@ static void dccg35_set_physymclk_root_clock_gating(
switch (phy_inst) {
case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break;
case 1:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break;
case 2:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break;
case 3:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break;
case 4:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break;
default:
BREAK_TO_DEBUGGER();
return;
}
DC_LOG_DEBUG("%s: dpp_inst(%d) PHYESYMCLK_ROOT_GATE_DISABLE: %d\n", __func__, phy_inst, enable ? 0 : 1);
}
static void dccg35_set_physymclk(
@@ -1614,6 +1631,8 @@ static void dccg35_set_physymclk(
BREAK_TO_DEBUGGER();
return;
}
DC_LOG_DEBUG("%s: phy_inst(%d) PHYxSYMCLK_EN = %d, PHYxSYMCLK_SRC_SEL = %d\n",
__func__, phy_inst, force_enable ? 1 : 0, clk_src);
}
static void dccg35_set_valid_pixel_rate(
@@ -1643,6 +1662,8 @@ static void dccg35_dpp_root_clock_control(
return;
if (clock_on) {
dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
/* turn off the DTO and leave phase/modulo at max */
dcn35_set_dppclk_enable(dccg, dpp_inst, 1);
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
@@ -1654,9 +1675,12 @@ static void dccg35_dpp_root_clock_control(
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, 0,
DPPCLK0_DTO_MODULO, 1);
/*we have this in hwss: disable_plane*/
//dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
}
dccg->dpp_clock_gated[dpp_inst] = !clock_on;
DC_LOG_DEBUG("%s: dpp_inst(%d) clock_on = %d\n", __func__, dpp_inst, clock_on);
}
static void dccg35_disable_symclk32_se(
@@ -1715,6 +1739,7 @@ static void dccg35_disable_symclk32_se(
BREAK_TO_DEBUGGER();
return;
}
}
static void dccg35_init_cb(struct dccg *dccg)
@@ -1722,7 +1747,6 @@ static void dccg35_init_cb(struct dccg *dccg)
(void)dccg;
/* Any RCG should be done when driver enter low power mode*/
}
void dccg35_init(struct dccg *dccg)
{
int otg_inst;
@@ -1737,6 +1761,8 @@ void dccg35_init(struct dccg *dccg)
for (otg_inst = 0; otg_inst < 2; otg_inst++) {
dccg31_disable_symclk32_le(dccg, otg_inst);
dccg31_set_symclk32_le_root_clock_gating(dccg, otg_inst, false);
DC_LOG_DEBUG("%s: OTG%d SYMCLK32_LE disabled and root clock gating disabled\n",
__func__, otg_inst);
}
// if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
@@ -1749,6 +1775,8 @@ void dccg35_init(struct dccg *dccg)
dccg35_set_dpstreamclk(dccg, REFCLK, otg_inst,
otg_inst);
dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);
DC_LOG_DEBUG("%s: OTG%d DPSTREAMCLK disabled and root clock gating disabled\n",
__func__, otg_inst);
}
/*

View File

@@ -604,6 +604,14 @@ void dcn20_dpp_pg_control(
* DOMAIN11_PGFSM_PWR_STATUS, pwr_status,
* 1, 1000);
*/
/* Force disable cursor on plane powerdown on DPP 5 using dpp_force_disable_cursor */
if (!power_on) {
struct dpp *dpp5 = hws->ctx->dc->res_pool->dpps[dpp_inst];
if (dpp5 && dpp5->funcs->dpp_force_disable_cursor)
dpp5->funcs->dpp_force_disable_cursor(dpp5);
}
break;
default:
BREAK_TO_DEBUGGER();

View File

@@ -241,11 +241,6 @@ void dcn35_init_hw(struct dc *dc)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
}
if (res_pool->dccg->funcs->dccg_root_gate_disable_control) {
for (i = 0; i < res_pool->pipe_count; i++)
res_pool->dccg->funcs->dccg_root_gate_disable_control(res_pool->dccg, i, 0);
}
for (i = 0; i < res_pool->audio_count; i++) {
struct audio *audio = res_pool->audios[i];
@@ -885,12 +880,18 @@ void dcn35_init_pipes(struct dc *dc, struct dc_state *context)
void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
struct dc_state *context)
{
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dccg *dccg = dc->res_pool->dccg;
/* enable DCFCLK current DCHUB */
pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
/* initialize HUBP on power up */
pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
/*make sure DPPCLK is on*/
dccg->funcs->dccg_root_gate_disable_control(dccg, dpp->inst, true);
dpp->funcs->dpp_dppclk_control(dpp, false, true);
/* make sure OPP_PIPE_CLOCK_EN = 1 */
pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
pipe_ctx->stream_res.opp,
@@ -907,6 +908,7 @@ void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
// Program system aperture settings
pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
}
//DC_LOG_DEBUG("%s: dpp_inst(%d) =\n", __func__, dpp->inst);
if (!pipe_ctx->top_pipe
&& pipe_ctx->plane_state
@@ -922,6 +924,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dccg *dccg = dc->res_pool->dccg;
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
@@ -939,7 +943,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
hubp->funcs->hubp_clk_cntl(hubp, false);
dpp->funcs->dpp_dppclk_control(dpp, false, false);
/*to do, need to support both case*/
dccg->funcs->dccg_root_gate_disable_control(dccg, dpp->inst, false);
hubp->power_gated = true;
hubp->funcs->hubp_reset(hubp);
@@ -951,6 +956,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
pipe_ctx->top_pipe = NULL;
pipe_ctx->bottom_pipe = NULL;
pipe_ctx->plane_state = NULL;
//DC_LOG_DEBUG("%s: dpp_inst(%d)=\n", __func__, dpp->inst);
}
void dcn35_disable_plane(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx)

View File

@@ -1587,7 +1587,7 @@ static bool retrieve_link_cap(struct dc_link *link)
union edp_configuration_cap edp_config_cap;
union dp_downstream_port_present ds_port = { 0 };
enum dc_status status = DC_ERROR_UNEXPECTED;
uint32_t read_dpcd_retry_cnt = 3;
uint32_t read_dpcd_retry_cnt = 20;
int i;
struct dp_sink_hw_fw_revision dp_hw_fw_revision;
const uint32_t post_oui_delay = 30; // 30ms
@@ -1633,12 +1633,13 @@ static bool retrieve_link_cap(struct dc_link *link)
status = dpcd_get_tunneling_device_data(link);
dpcd_set_source_specific_data(link);
/* Sink may need to configure internals based on vendor, so allow some
* time before proceeding with possibly vendor specific transactions
*/
msleep(post_oui_delay);
for (i = 0; i < read_dpcd_retry_cnt; i++) {
/*
* Sink may need to configure internals based on vendor, so allow some
* time before proceeding with possibly vendor specific transactions
*/
msleep(post_oui_delay);
status = core_link_read_dpcd(
link,
DP_DPCD_REV,

View File

@@ -591,6 +591,10 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
/* TODO: Enable Panel Replay on MST once it's properly implemented. */
if (intel_dp->mst_detect == DRM_DP_MST)
return;
if (intel_dp_is_edp(intel_dp)) {
if (!intel_alpm_aux_less_wake_supported(intel_dp)) {
drm_dbg_kms(display->drm,

View File

@@ -159,6 +159,8 @@ nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *fw)
nvkm_memory_unref(&fw->inst);
nvkm_falcon_fw_dtor_sigs(fw);
nvkm_firmware_dtor(&fw->fw);
kfree(fw->boot);
fw->boot = NULL;
}
static const struct nvkm_firmware_func

View File

@@ -360,13 +360,6 @@ static bool radeon_fence_is_signaled(struct dma_fence *f)
if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq)
return true;
if (down_read_trylock(&rdev->exclusive_lock)) {
radeon_fence_process(rdev, ring);
up_read(&rdev->exclusive_lock);
if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq)
return true;
}
return false;
}

View File

@@ -3147,6 +3147,7 @@ static int tegra_dc_couple(struct tegra_dc *dc)
dc->client.parent = &parent->client;
dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion));
put_device(companion);
}
return 0;

View File

@@ -913,15 +913,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
u32 value;
int err;
/* If the bootloader enabled DSI it needs to be disabled
* in order for the panel initialization commands to be
* properly sent.
*/
value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
if (value & DSI_POWER_CONTROL_ENABLE)
tegra_dsi_disable(dsi);
err = tegra_dsi_prepare(dsi);
if (err < 0) {
dev_err(dsi->dev, "failed to prepare: %d\n", err);

View File

@@ -114,9 +114,12 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_
if (err)
goto put_channel;
if (supported)
if (supported) {
struct pid *pid = get_task_pid(current, PIDTYPE_TGID);
context->memory_context = host1x_memory_context_alloc(
host, client->base.dev, get_task_pid(current, PIDTYPE_TGID));
host, client->base.dev, pid);
put_pid(pid);
}
if (IS_ERR(context->memory_context)) {
if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) {

View File

@@ -2903,8 +2903,8 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe,
op == DRM_XE_VM_BIND_OP_PREFETCH) ||
XE_IOCTL_DBG(xe, prefetch_region &&
op != DRM_XE_VM_BIND_OP_PREFETCH) ||
XE_IOCTL_DBG(xe, !(BIT(prefetch_region) &
xe->info.mem_region_mask)) ||
XE_IOCTL_DBG(xe, prefetch_region >= (sizeof(xe->info.mem_region_mask) * 8) ||
!(BIT(prefetch_region) & xe->info.mem_region_mask)) ||
XE_IOCTL_DBG(xe, obj &&
op == DRM_XE_VM_BIND_OP_UNMAP)) {
err = -EINVAL;

View File

@@ -172,6 +172,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
if (rc)
goto cleanup;
mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
amd_sfh_wait_for_response(privdata, cl_data->sensor_idx[i], DISABLE_SENSOR);
writel(0, privdata->mmio + amd_get_p2c_val(privdata, 0));
mp2_ops->start(privdata, info);
status = amd_sfh_wait_for_response

View File

@@ -1534,7 +1534,7 @@
#define USB_VENDOR_ID_SIGNOTEC 0x2133
#define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018
#define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a
#define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155
#define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a
#define USB_DEVICE_ID_JIELI_SDK_4155 0x4155
#endif

View File

@@ -902,7 +902,6 @@ static const struct hid_device_id hid_ignore_list[] = {
#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) },
{ }
};
@@ -1059,6 +1058,18 @@ bool hid_ignore(struct hid_device *hdev)
strlen(elan_acpi_id[i].id)))
return true;
break;
case USB_VENDOR_ID_JIELI_SDK_DEFAULT:
/*
* Multiple USB devices with identical IDs (mic & touchscreen).
* The touch screen requires hid core processing, but the
* microphone does not. They can be distinguished by manufacturer
* and serial number.
*/
if (hdev->product == USB_DEVICE_ID_JIELI_SDK_4155 &&
strncmp(hdev->name, "SmartlinkTechnology", 19) == 0 &&
strncmp(hdev->uniq, "20201111000001", 14) == 0)
return true;
break;
}
if (hdev->type == HID_TYPE_USBMOUSE &&

View File

@@ -4,10 +4,9 @@ config INFINIBAND_IRDMA
depends on INET
depends on IPV6 || !IPV6
depends on PCI
depends on IDPF && ICE && I40E
depends on ICE && I40E
select GENERIC_ALLOCATOR
select AUXILIARY_BUS
help
This is an Intel(R) Ethernet Protocol Driver for RDMA that
supports IPU E2000 (RoCEv2), E810 (iWARP/RoCEv2) and X722 (iWARP)
network devices.
This is an Intel(R) Ethernet Protocol Driver for RDMA driver
that support E810 (iWARP/RoCE) and X722 (iWARP) network devices.

View File

@@ -261,6 +261,12 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
case EC_MKBP_EVENT_KEY_MATRIX:
pm_wakeup_event(ckdev->dev, 0);
if (!ckdev->idev) {
dev_warn_once(ckdev->dev,
"Unexpected key matrix event\n");
return NOTIFY_OK;
}
if (ckdev->ec->event_size != ckdev->cols) {
dev_err(ckdev->dev,
"Discarded incomplete key matrix event.\n");

View File

@@ -158,7 +158,7 @@ static int imx_sc_key_probe(struct platform_device *pdev)
return error;
}
error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, &priv);
error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, priv);
if (error)
return error;

View File

@@ -63,6 +63,9 @@
#define BUTTON_PRESSED 0xb5
#define COMMAND_VERSION 0xa9
/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */
#define NOTETAKER_PACKET_SIZE 6
/* in xy data packet */
#define BATTERY_NO_REPORT 0x40
#define BATTERY_LOW 0x41
@@ -303,6 +306,12 @@ static int pegasus_probe(struct usb_interface *intf,
}
pegasus->data_len = usb_maxpacket(dev, pipe);
if (pegasus->data_len < NOTETAKER_PACKET_SIZE) {
dev_err(&intf->dev, "packet size is too small (%d)\n",
pegasus->data_len);
error = -EINVAL;
goto err_free_mem;
}
pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL,
&pegasus->data_dma);

View File

@@ -1580,6 +1580,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id);
static const struct acpi_device_id goodix_acpi_match[] = {
{ "GDIX1001", 0 },
{ "GDIX1002", 0 },
{ "GDIX1003", 0 },
{ "GDX9110", 0 },
{ }
};

View File

@@ -599,6 +599,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp)
uint8_t *datbuf = NULL, *oobbuf = NULL;
size_t datbuf_len, oobbuf_len;
int ret = 0;
u64 end;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
@@ -618,7 +619,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp)
req.len &= 0xffffffff;
req.ooblen &= 0xffffffff;
if (req.start + req.len > mtd->size)
if (check_add_overflow(req.start, req.len, &end) || end > mtd->size)
return -EINVAL;
datbuf_len = min_t(size_t, req.len, mtd->erasesize);
@@ -698,6 +699,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp)
size_t datbuf_len, oobbuf_len;
size_t orig_len, orig_ooblen;
int ret = 0;
u64 end;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
@@ -724,7 +726,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp)
req.len &= 0xffffffff;
req.ooblen &= 0xffffffff;
if (req.start + req.len > mtd->size) {
if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) {
ret = -EINVAL;
goto out;
}

View File

@@ -2871,7 +2871,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl)
static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
{
dma_cap_mask_t mask;
struct dma_device *dma_dev = cdns_ctrl->dmac->device;
struct dma_device *dma_dev;
int ret;
cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2915,6 +2915,7 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
}
}
dma_dev = cdns_ctrl->dmac->device;
cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma,
cdns_ctrl->io.size,
DMA_BIDIRECTIONAL, 0);

View File

@@ -376,8 +376,18 @@ static int hellcreek_led_setup(struct hellcreek *hellcreek)
hellcreek_set_brightness(hellcreek, STATUS_OUT_IS_GM, 1);
/* Register both leds */
led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good);
led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm);
ret = led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good);
if (ret) {
dev_err(hellcreek->dev, "Failed to register sync_good LED\n");
goto out;
}
ret = led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm);
if (ret) {
dev_err(hellcreek->dev, "Failed to register is_gm LED\n");
led_classdev_unregister(&hellcreek->led_sync_good);
goto out;
}
ret = 0;

View File

@@ -339,6 +339,7 @@ static void lan937x_set_tune_adj(struct ksz_device *dev, int port,
ksz_pread16(dev, port, reg, &data16);
/* Update tune Adjust */
data16 &= ~PORT_TUNE_ADJ;
data16 |= FIELD_PREP(PORT_TUNE_ADJ, val);
ksz_pwrite16(dev, port, reg, data16);

View File

@@ -1296,7 +1296,8 @@ static void be_xmit_flush(struct be_adapter *adapter, struct be_tx_obj *txo)
(adapter->bmc_filt_mask & BMC_FILT_MULTICAST)
static bool be_send_pkt_to_bmc(struct be_adapter *adapter,
struct sk_buff **skb)
struct sk_buff **skb,
struct be_wrb_params *wrb_params)
{
struct ethhdr *eh = (struct ethhdr *)(*skb)->data;
bool os2bmc = false;
@@ -1360,7 +1361,7 @@ done:
* to BMC, asic expects the vlan to be inline in the packet.
*/
if (os2bmc)
*skb = be_insert_vlan_in_pkt(adapter, *skb, NULL);
*skb = be_insert_vlan_in_pkt(adapter, *skb, wrb_params);
return os2bmc;
}
@@ -1387,7 +1388,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
/* if os2bmc is enabled and if the pkt is destined to bmc,
* enqueue the pkt a 2nd time with mgmt bit set.
*/
if (be_send_pkt_to_bmc(adapter, &skb)) {
if (be_send_pkt_to_bmc(adapter, &skb, &wrb_params)) {
BE_WRB_F_SET(wrb_params.features, OS2BMC, 1);
wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
if (unlikely(!wrb_cnt))

View File

@@ -3409,7 +3409,7 @@ void ice_ptp_init(struct ice_pf *pf)
err = ice_ptp_init_port(pf, &ptp->port);
if (err)
goto err_exit;
goto err_clean_pf;
/* Start the PHY timestamping block */
ice_ptp_reset_phy_timestamping(pf);
@@ -3426,13 +3426,19 @@ void ice_ptp_init(struct ice_pf *pf)
dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
return;
err_clean_pf:
mutex_destroy(&ptp->port.ps_lock);
ice_ptp_cleanup_pf(pf);
err_exit:
/* If we registered a PTP clock, release it */
if (pf->ptp.clock) {
ptp_clock_unregister(ptp->clock);
pf->ptp.clock = NULL;
}
ptp->state = ICE_PTP_ERROR;
/* Keep ICE_PTP_UNINIT state to avoid ambiguity at driver unload
* and to avoid duplicated resources release.
*/
ptp->state = ICE_PTP_UNINIT;
dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err);
}
@@ -3445,9 +3451,19 @@ err_exit:
*/
void ice_ptp_release(struct ice_pf *pf)
{
if (pf->ptp.state != ICE_PTP_READY)
if (pf->ptp.state == ICE_PTP_UNINIT)
return;
if (pf->ptp.state != ICE_PTP_READY) {
mutex_destroy(&pf->ptp.port.ps_lock);
ice_ptp_cleanup_pf(pf);
if (pf->ptp.clock) {
ptp_clock_unregister(pf->ptp.clock);
pf->ptp.clock = NULL;
}
return;
}
pf->ptp.state = ICE_PTP_UNINIT;
/* Disable timestamping for both Tx and Rx */

View File

@@ -62,6 +62,8 @@ destroy_wqs:
destroy_workqueue(adapter->vc_event_wq);
for (i = 0; i < adapter->max_vports; i++) {
if (!adapter->vport_config[i])
continue;
kfree(adapter->vport_config[i]->user_config.q_coalesce);
kfree(adapter->vport_config[i]);
adapter->vport_config[i] = NULL;

View File

@@ -425,12 +425,14 @@ void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,
{
struct mlx5e_ktls_rx_resync_buf *buf = wi->tls_get_params.buf;
struct mlx5e_ktls_offload_context_rx *priv_rx;
struct tls_offload_context_rx *rx_ctx;
u8 tracker_state, auth_state, *ctx;
struct device *dev;
u32 hw_seq;
priv_rx = buf->priv_rx;
dev = mlx5_core_dma_dev(sq->channel->mdev);
rx_ctx = tls_offload_ctx_rx(tls_get_ctx(priv_rx->sk));
if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
goto out;
@@ -447,7 +449,8 @@ void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,
}
hw_seq = MLX5_GET(tls_progress_params, ctx, hw_resync_tcp_sn);
tls_offload_rx_resync_async_request_end(priv_rx->sk, cpu_to_be32(hw_seq));
tls_offload_rx_resync_async_request_end(rx_ctx->resync_async,
cpu_to_be32(hw_seq));
priv_rx->rq_stats->tls_resync_req_end++;
out:
mlx5e_ktls_priv_rx_put(priv_rx);
@@ -482,6 +485,7 @@ static bool resync_queue_get_psv(struct sock *sk)
static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)
{
struct ethhdr *eth = (struct ethhdr *)(skb->data);
struct tls_offload_resync_async *resync_async;
struct net_device *netdev = rq->netdev;
struct net *net = dev_net(netdev);
struct sock *sk = NULL;
@@ -528,7 +532,8 @@ static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)
seq = th->seq;
datalen = skb->len - depth;
tls_offload_rx_resync_async_request_start(sk, seq, datalen);
resync_async = tls_offload_ctx_rx(tls_get_ctx(sk))->resync_async;
tls_offload_rx_resync_async_request_start(resync_async, seq, datalen);
rq->stats->tls_resync_req_start++;
unref:

View File

@@ -324,10 +324,8 @@ err_xa:
free_irq(irq->map.virq, &irq->nh);
err_req_irq:
#ifdef CONFIG_RFS_ACCEL
if (i && rmap && *rmap) {
free_irq_cpu_rmap(*rmap);
*rmap = NULL;
}
if (i && rmap && *rmap)
irq_cpu_rmap_remove(*rmap, irq->map.virq);
err_irq_rmap:
#endif
if (i && pci_msix_can_alloc_dyn(dev->pdev))

View File

@@ -601,6 +601,8 @@ int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard,
err = devlink_info_version_fixed_put(req,
DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
info->psid);
if (err)
goto unlock;
sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor,
info->fw_sub_minor);

View File

@@ -820,8 +820,10 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
return -EINVAL;
rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie);
if (!rule)
return -EINVAL;
if (!rule) {
err = -EINVAL;
goto err_rule_get_stats;
}
err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes,
&drops, &lastuse, &used_hw_stats);

View File

@@ -4,6 +4,7 @@
* Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/array_size.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -960,7 +961,7 @@ static inline void qede_tpa_cont(struct qede_dev *edev,
{
int i;
for (i = 0; cqe->len_list[i]; i++)
for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++)
qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
le16_to_cpu(cqe->len_list[i]));
@@ -985,7 +986,7 @@ static int qede_tpa_end(struct qede_dev *edev,
dma_unmap_page(rxq->dev, tpa_info->buffer.mapping,
PAGE_SIZE, rxq->data_direction);
for (i = 0; cqe->len_list[i]; i++)
for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++)
qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
le16_to_cpu(cqe->len_list[i]));
if (unlikely(i > 1))

View File

@@ -1338,10 +1338,10 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe)
tx_pipe->dma_channel = knav_dma_open_channel(dev,
tx_pipe->dma_chan_name, &config);
if (IS_ERR(tx_pipe->dma_channel)) {
if (!tx_pipe->dma_channel) {
dev_err(dev, "failed opening tx chan(%s)\n",
tx_pipe->dma_chan_name);
ret = PTR_ERR(tx_pipe->dma_channel);
ret = -EINVAL;
goto err;
}
@@ -1359,7 +1359,7 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe)
return 0;
err:
if (!IS_ERR_OR_NULL(tx_pipe->dma_channel))
if (tx_pipe->dma_channel)
knav_dma_close_channel(tx_pipe->dma_channel);
tx_pipe->dma_channel = NULL;
return ret;
@@ -1678,10 +1678,10 @@ static int netcp_setup_navigator_resources(struct net_device *ndev)
netcp->rx_channel = knav_dma_open_channel(netcp->netcp_device->device,
netcp->dma_chan_name, &config);
if (IS_ERR(netcp->rx_channel)) {
if (!netcp->rx_channel) {
dev_err(netcp->ndev_dev, "failed opening rx chan(%s\n",
netcp->dma_chan_name);
ret = PTR_ERR(netcp->rx_channel);
ret = -EINVAL;
goto fail;
}

View File

@@ -2349,17 +2349,11 @@ nvme_fc_ctrl_free(struct kref *ref)
container_of(ref, struct nvme_fc_ctrl, ref);
unsigned long flags;
if (ctrl->ctrl.tagset)
nvme_remove_io_tag_set(&ctrl->ctrl);
/* remove from rport list */
spin_lock_irqsave(&ctrl->rport->lock, flags);
list_del(&ctrl->ctrl_list);
spin_unlock_irqrestore(&ctrl->rport->lock, flags);
nvme_unquiesce_admin_queue(&ctrl->ctrl);
nvme_remove_admin_tag_set(&ctrl->ctrl);
kfree(ctrl->queues);
put_device(ctrl->dev);
@@ -3253,13 +3247,20 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);
cancel_work_sync(&ctrl->ioerr_work);
cancel_delayed_work_sync(&ctrl->connect_work);
/*
* kill the association on the link side. this will block
* waiting for io to terminate
*/
nvme_fc_delete_association(ctrl);
cancel_work_sync(&ctrl->ioerr_work);
if (ctrl->ctrl.tagset)
nvme_remove_io_tag_set(&ctrl->ctrl);
nvme_unquiesce_admin_queue(&ctrl->ctrl);
nvme_remove_admin_tag_set(&ctrl->ctrl);
}
static void

View File

@@ -687,7 +687,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
return;
}
nvme_add_ns_head_cdev(head);
kblockd_schedule_work(&head->partition_scan_work);
queue_work(nvme_wq, &head->partition_scan_work);
}
mutex_lock(&head->lock);

View File

@@ -1016,7 +1016,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
/* compute hardware counter index */
hidx = info->csr - CSR_CYCLE;
/* check if the corresponding bit is set in sscountovf or overflow mask in shmem */
/* check if the corresponding bit is set in scountovf or overflow mask in shmem */
if (!(overflow & BIT(hidx)))
continue;

View File

@@ -527,6 +527,11 @@ static int cs42l43_gpio_add_pin_ranges(struct gpio_chip *chip)
return ret;
}
static void cs42l43_fwnode_put(void *data)
{
fwnode_handle_put(data);
}
static int cs42l43_pin_probe(struct platform_device *pdev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
@@ -558,10 +563,20 @@ static int cs42l43_pin_probe(struct platform_device *pdev)
priv->gpio_chip.ngpio = CS42L43_NUM_GPIOS;
if (is_of_node(fwnode)) {
fwnode = fwnode_get_named_child_node(fwnode, "pinctrl");
struct fwnode_handle *child;
if (fwnode && !fwnode->dev)
fwnode->dev = priv->dev;
child = fwnode_get_named_child_node(fwnode, "pinctrl");
if (child) {
ret = devm_add_action_or_reset(&pdev->dev,
cs42l43_fwnode_put, child);
if (ret) {
fwnode_handle_put(child);
return ret;
}
if (!child->dev)
child->dev = priv->dev;
fwnode = child;
}
}
priv->gpio_chip.fwnode = fwnode;

View File

@@ -392,6 +392,7 @@ static int s32_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
gpio_pin->pin_id = offset;
gpio_pin->config = config;
INIT_LIST_HEAD(&gpio_pin->list);
spin_lock_irqsave(&ipctl->gpio_configs_lock, flags);
list_add(&gpio_pin->list, &ipctl->gpio_configs);
@@ -951,7 +952,7 @@ int s32_pinctrl_probe(struct platform_device *pdev,
spin_lock_init(&ipctl->gpio_configs_lock);
s32_pinctrl_desc =
devm_kmalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL);
devm_kzalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL);
if (!s32_pinctrl_desc)
return -ENOMEM;

View File

@@ -6,6 +6,7 @@ config PINCTRL_RTD
default y
select PINMUX
select GENERIC_PINCONF
select REGMAP_MMIO
config PINCTRL_RTD1619B
tristate "Realtek DHC 1619B pin controller driver"

View File

@@ -726,6 +726,7 @@ config MSI_WMI
config MSI_WMI_PLATFORM
tristate "MSI WMI Platform features"
depends on ACPI_WMI
depends on DMI
depends on HWMON
help
Say Y here if you want to have support for WMI-based platform features

View File

@@ -108,11 +108,11 @@ static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ret = pci_read_config_dword(pdev, 0xD0, &mmio_base);
if (ret)
return ret;
return pcibios_err_to_errno(ret);
ret = pci_read_config_dword(pdev, 0xFC, &pcu_base);
if (ret)
return ret;
return pcibios_err_to_errno(ret);
pcu_base &= GENMASK(10, 0);
base_addr = (u64)mmio_base << 23 | (u64) pcu_base << 12;

View File

@@ -14,6 +14,7 @@
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/device/driver.h>
#include <linux/dmi.h>
#include <linux/errno.h>
#include <linux/hwmon.h>
#include <linux/kernel.h>
@@ -28,7 +29,7 @@
#define DRIVER_NAME "msi-wmi-platform"
#define MSI_PLATFORM_GUID "ABBC0F6E-8EA1-11d1-00A0-C90629100000"
#define MSI_PLATFORM_GUID "ABBC0F6E-8EA1-11D1-00A0-C90629100000"
#define MSI_WMI_PLATFORM_INTERFACE_VERSION 2
@@ -448,7 +449,45 @@ static struct wmi_driver msi_wmi_platform_driver = {
.probe = msi_wmi_platform_probe,
.no_singleton = true,
};
module_wmi_driver(msi_wmi_platform_driver);
/*
* MSI reused the WMI GUID from the WMI-ACPI sample code provided by Microsoft,
* so other manufacturers might use it as well for their WMI-ACPI implementations.
*/
static const struct dmi_system_id msi_wmi_platform_whitelist[] __initconst = {
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
},
},
{ }
};
static int __init msi_wmi_platform_module_init(void)
{
if (!dmi_check_system(msi_wmi_platform_whitelist)) {
if (!force)
return -ENODEV;
pr_warn("Ignoring DMI whitelist\n");
}
return wmi_driver_register(&msi_wmi_platform_driver);
}
static void __exit msi_wmi_platform_module_exit(void)
{
wmi_driver_unregister(&msi_wmi_platform_driver);
}
module_init(msi_wmi_platform_module_init);
module_exit(msi_wmi_platform_module_exit);
MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
MODULE_DESCRIPTION("MSI WMI platform features");

View File

@@ -700,7 +700,6 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
grp->sweep_req_pend_num--;
ctcmpc_send_sweep_resp(ch);
kfree(mpcginfo);
return;
}

View File

@@ -607,8 +607,9 @@ int scsi_host_busy(struct Scsi_Host *shost)
{
int cnt = 0;
blk_mq_tagset_busy_iter(&shost->tag_set,
scsi_host_check_in_flight, &cnt);
if (shost->tag_set.ops)
blk_mq_tagset_busy_iter(&shost->tag_set,
scsi_host_check_in_flight, &cnt);
return cnt;
}
EXPORT_SYMBOL(scsi_host_busy);

View File

@@ -2210,9 +2210,17 @@ sg_remove_sfp_usercontext(struct work_struct *work)
write_lock_irqsave(&sfp->rq_list_lock, iflags);
while (!list_empty(&sfp->rq_list)) {
srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
sg_finish_rem_req(srp);
list_del(&srp->entry);
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
sg_finish_rem_req(srp);
/*
* sg_rq_end_io() uses srp->parentfp. Hence, only clear
* srp->parentfp after blk_mq_free_request() has been called.
*/
srp->parentfp = NULL;
write_lock_irqsave(&sfp->rq_list_lock, iflags);
}
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);

View File

@@ -402,7 +402,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name,
* @name: slave channel name
* @config: dma configuration parameters
*
* Returns pointer to appropriate DMA channel on success or error.
* Return: Pointer to appropriate DMA channel on success or NULL on error.
*/
void *knav_dma_open_channel(struct device *dev, const char *name,
struct knav_dma_cfg *config)
@@ -414,13 +414,13 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
if (!kdev) {
pr_err("keystone-navigator-dma driver not registered\n");
return (void *)-EINVAL;
return NULL;
}
chan_num = of_channel_match_helper(dev->of_node, name, &instance);
if (chan_num < 0) {
dev_err(kdev->dev, "No DMA instance with name %s\n", name);
return (void *)-EINVAL;
return NULL;
}
dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n",
@@ -431,7 +431,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
if (config->direction != DMA_MEM_TO_DEV &&
config->direction != DMA_DEV_TO_MEM) {
dev_err(kdev->dev, "bad direction\n");
return (void *)-EINVAL;
return NULL;
}
/* Look for correct dma instance */
@@ -443,7 +443,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
}
if (!dma) {
dev_err(kdev->dev, "No DMA instance with name %s\n", instance);
return (void *)-EINVAL;
return NULL;
}
/* Look for correct dma channel from dma instance */
@@ -463,14 +463,14 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
if (!chan) {
dev_err(kdev->dev, "channel %d is not in DMA %s\n",
chan_num, instance);
return (void *)-EINVAL;
return NULL;
}
if (atomic_read(&chan->ref_count) >= 1) {
if (!check_config(chan, config)) {
dev_err(kdev->dev, "channel %d config miss-match\n",
chan_num);
return (void *)-EINVAL;
return NULL;
}
}

View File

@@ -893,6 +893,9 @@ static ssize_t tcm_loop_tpg_address_show(struct config_item *item,
struct tcm_loop_tpg, tl_se_tpg);
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
if (!tl_hba->sh)
return -ENODEV;
return snprintf(page, PAGE_SIZE, "%d:0:%d\n",
tl_hba->sh->host_no, tl_tpg->tl_tpgt);
}

View File

@@ -924,8 +924,10 @@ int vt_ioctl(struct tty_struct *tty,
if (vc) {
/* FIXME: review v tty lock */
ret = __vc_resize(vc_cons[i].d, cc, ll, true);
if (ret)
if (ret) {
console_unlock();
return ret;
}
}
}
console_unlock();

View File

@@ -452,7 +452,10 @@ static int exfat_read_boot_sector(struct super_block *sb)
struct exfat_sb_info *sbi = EXFAT_SB(sb);
/* set block size to read super block */
sb_min_blocksize(sb, 512);
if (!sb_min_blocksize(sb, 512)) {
exfat_err(sb, "unable to set blocksize");
return -EINVAL;
}
/* read boot sector */
sbi->boot_bh = sb_bread(sb, 0);

View File

@@ -610,6 +610,11 @@ static int isofs_fill_super(struct super_block *s, struct fs_context *fc)
goto out_freesbi;
}
opt->blocksize = sb_min_blocksize(s, opt->blocksize);
if (!opt->blocksize) {
printk(KERN_ERR
"ISOFS: unable to set blocksize\n");
goto out_freesbi;
}
sbi->s_high_sierra = 0; /* default is iso9660 */
sbi->s_session = opt->session;

View File

@@ -16,6 +16,7 @@ static struct cached_fid *init_cached_dir(const char *path);
static void free_cached_dir(struct cached_fid *cfid);
static void smb2_close_cached_fid(struct kref *ref);
static void cfids_laundromat_worker(struct work_struct *work);
static void close_cached_dir_locked(struct cached_fid *cfid);
struct cached_dir_dentry {
struct list_head entry;
@@ -362,7 +363,7 @@ out:
* lease. Release one here, and the second below.
*/
cfid->has_lease = false;
close_cached_dir(cfid);
close_cached_dir_locked(cfid);
}
spin_unlock(&cfids->cfid_list_lock);
@@ -448,18 +449,52 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
spin_lock(&cfid->cfids->cfid_list_lock);
if (cfid->has_lease) {
cfid->has_lease = false;
close_cached_dir(cfid);
close_cached_dir_locked(cfid);
}
spin_unlock(&cfid->cfids->cfid_list_lock);
close_cached_dir(cfid);
}
/**
* close_cached_dir - drop a reference of a cached dir
*
* The release function will be called with cfid_list_lock held to remove the
* cached dirs from the list before any other thread can take another @cfid
* ref. Must not be called with cfid_list_lock held; use
* close_cached_dir_locked() called instead.
*
* @cfid: cached dir
*/
void close_cached_dir(struct cached_fid *cfid)
{
lockdep_assert_not_held(&cfid->cfids->cfid_list_lock);
kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock);
}
/**
* close_cached_dir_locked - put a reference of a cached dir with
* cfid_list_lock held
*
* Calling close_cached_dir() with cfid_list_lock held has the potential effect
* of causing a deadlock if the invariant of refcount >= 2 is false.
*
* This function is used in paths that hold cfid_list_lock and expect at least
* two references. If that invariant is violated, WARNs and returns without
* dropping a reference; the final put must still go through
* close_cached_dir().
*
* @cfid: cached dir
*/
static void close_cached_dir_locked(struct cached_fid *cfid)
{
lockdep_assert_held(&cfid->cfids->cfid_list_lock);
if (WARN_ON(kref_read(&cfid->refcount) < 2))
return;
kref_put(&cfid->refcount, smb2_close_cached_fid);
}
/*
* Called from cifs_kill_sb when we unmount a share
*/
@@ -692,7 +727,7 @@ static void cfids_invalidation_worker(struct work_struct *work)
list_for_each_entry_safe(cfid, q, &entry, entry) {
list_del(&cfid->entry);
/* Drop the ref-count acquired in invalidate_all_cached_dirs */
kref_put(&cfid->refcount, smb2_close_cached_fid);
close_cached_dir(cfid);
}
}

View File

@@ -134,7 +134,7 @@ module_param(enable_oplocks, bool, 0644);
MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1");
module_param(enable_gcm_256, bool, 0644);
MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0");
MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/1");
module_param(require_gcm_256, bool, 0644);
MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0");

View File

@@ -1764,6 +1764,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
ctx->password = NULL;
kfree_sensitive(ctx->password2);
ctx->password2 = NULL;
kfree(ctx->source);
ctx->source = NULL;
kfree(fc->source);
fc->source = NULL;
return -EINVAL;
}

View File

@@ -184,8 +184,8 @@ xrep_symlink_salvage_inline(
sc->ip->i_disk_size == 1 && old_target[0] == '?')
return 0;
nr = min(XFS_SYMLINK_MAXLEN, xfs_inode_data_fork_size(ip));
strncpy(target_buf, ifp->if_data, nr);
nr = min(XFS_SYMLINK_MAXLEN, ifp->if_bytes);
memcpy(target_buf, ifp->if_data, nr);
return nr;
}

View File

@@ -566,6 +566,7 @@ struct ata_bmdma_prd {
#define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8))
#define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1)
#define ata_id_removable(id) ((id)[ATA_ID_CONFIG] & (1 << 7))
#define ata_id_is_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7)
#define ata_id_has_atapi_AN(id) \
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \

View File

@@ -448,25 +448,26 @@ static inline void tls_offload_rx_resync_request(struct sock *sk, __be32 seq)
/* Log all TLS record header TCP sequences in [seq, seq+len] */
static inline void
tls_offload_rx_resync_async_request_start(struct sock *sk, __be32 seq, u16 len)
tls_offload_rx_resync_async_request_start(struct tls_offload_resync_async *resync_async,
__be32 seq, u16 len)
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
atomic64_set(&rx_ctx->resync_async->req, ((u64)ntohl(seq) << 32) |
atomic64_set(&resync_async->req, ((u64)ntohl(seq) << 32) |
((u64)len << 16) | RESYNC_REQ | RESYNC_REQ_ASYNC);
rx_ctx->resync_async->loglen = 0;
rx_ctx->resync_async->rcd_delta = 0;
resync_async->loglen = 0;
resync_async->rcd_delta = 0;
}
static inline void
tls_offload_rx_resync_async_request_end(struct sock *sk, __be32 seq)
tls_offload_rx_resync_async_request_end(struct tls_offload_resync_async *resync_async,
__be32 seq)
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
atomic64_set(&resync_async->req, ((u64)ntohl(seq) << 32) | RESYNC_REQ);
}
atomic64_set(&rx_ctx->resync_async->req,
((u64)ntohl(seq) << 32) | RESYNC_REQ);
static inline void
tls_offload_rx_resync_async_request_cancel(struct tls_offload_resync_async *resync_async)
{
atomic64_set(&resync_async->req, 0);
}
static inline void

View File

@@ -472,7 +472,8 @@ static inline int xfrm_af2proto(unsigned int family)
static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
{
if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
if ((x->sel.family != AF_UNSPEC) ||
(ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
(ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
return &x->inner_mode;
else

View File

@@ -1505,10 +1505,11 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown)
base = lock_timer_base(timer, &flags);
if (base->running_timer != timer)
if (base->running_timer != timer) {
ret = detach_if_pending(timer, base, true);
if (shutdown)
timer->function = NULL;
if (shutdown)
timer->function = NULL;
}
raw_spin_unlock_irqrestore(&base->lock, flags);

View File

@@ -64,6 +64,8 @@
#define CREATE_TRACE_POINTS
#include <trace/events/maple_tree.h>
#define TP_FCT tracepoint_string(__func__)
#define MA_ROOT_PARENT 1
/*
@@ -2949,7 +2951,7 @@ static inline void mas_rebalance(struct ma_state *mas,
MA_STATE(l_mas, mas->tree, mas->index, mas->last);
MA_STATE(r_mas, mas->tree, mas->index, mas->last);
trace_ma_op(__func__, mas);
trace_ma_op(TP_FCT, mas);
/*
* Rebalancing occurs if a node is insufficient. Data is rebalanced
@@ -3314,7 +3316,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node)
MA_STATE(prev_l_mas, mas->tree, mas->index, mas->last);
MA_STATE(prev_r_mas, mas->tree, mas->index, mas->last);
trace_ma_op(__func__, mas);
trace_ma_op(TP_FCT, mas);
mas->depth = mas_mt_height(mas);
mast.l = &l_mas;
@@ -3487,7 +3489,7 @@ static bool mas_is_span_wr(struct ma_wr_state *wr_mas)
return false;
}
trace_ma_write(__func__, wr_mas->mas, wr_mas->r_max, entry);
trace_ma_write(TP_FCT, wr_mas->mas, wr_mas->r_max, entry);
return true;
}
@@ -3721,7 +3723,7 @@ static noinline void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
* of data may happen.
*/
mas = wr_mas->mas;
trace_ma_op(__func__, mas);
trace_ma_op(TP_FCT, mas);
if (unlikely(!mas->index && mas->last == ULONG_MAX))
return mas_new_root(mas, wr_mas->entry);
@@ -3858,7 +3860,7 @@ done:
} else {
memcpy(wr_mas->node, newnode, sizeof(struct maple_node));
}
trace_ma_write(__func__, mas, 0, wr_mas->entry);
trace_ma_write(TP_FCT, mas, 0, wr_mas->entry);
mas_update_gap(mas);
mas->end = new_end;
return;
@@ -3903,7 +3905,7 @@ static inline void mas_wr_slot_store(struct ma_wr_state *wr_mas)
return;
}
trace_ma_write(__func__, mas, 0, wr_mas->entry);
trace_ma_write(TP_FCT, mas, 0, wr_mas->entry);
/*
* Only update gap when the new entry is empty or there is an empty
* entry in the original two ranges.
@@ -4024,7 +4026,7 @@ static inline void mas_wr_append(struct ma_wr_state *wr_mas,
mas_update_gap(mas);
mas->end = new_end;
trace_ma_write(__func__, mas, new_end, wr_mas->entry);
trace_ma_write(TP_FCT, mas, new_end, wr_mas->entry);
return;
}
@@ -4038,7 +4040,7 @@ static void mas_wr_bnode(struct ma_wr_state *wr_mas)
{
struct maple_big_node b_node;
trace_ma_write(__func__, wr_mas->mas, 0, wr_mas->entry);
trace_ma_write(TP_FCT, wr_mas->mas, 0, wr_mas->entry);
memset(&b_node, 0, sizeof(struct maple_big_node));
mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end);
mas_commit_b_node(wr_mas, &b_node);
@@ -5418,7 +5420,7 @@ void *mas_store(struct ma_state *mas, void *entry)
int request;
MA_WR_STATE(wr_mas, mas, entry);
trace_ma_write(__func__, mas, 0, entry);
trace_ma_write(TP_FCT, mas, 0, entry);
#ifdef CONFIG_DEBUG_MAPLE_TREE
if (MAS_WARN_ON(mas, mas->index > mas->last))
pr_err("Error %lX > %lX %p\n", mas->index, mas->last, entry);
@@ -5518,7 +5520,7 @@ void mas_store_prealloc(struct ma_state *mas, void *entry)
}
store:
trace_ma_write(__func__, mas, 0, entry);
trace_ma_write(TP_FCT, mas, 0, entry);
mas_wr_store_entry(&wr_mas);
MAS_WR_BUG_ON(&wr_mas, mas_is_err(mas));
mas_destroy(mas);
@@ -6320,7 +6322,7 @@ void *mtree_load(struct maple_tree *mt, unsigned long index)
MA_STATE(mas, mt, index, index);
void *entry;
trace_ma_read(__func__, &mas);
trace_ma_read(TP_FCT, &mas);
rcu_read_lock();
retry:
entry = mas_start(&mas);
@@ -6363,7 +6365,7 @@ int mtree_store_range(struct maple_tree *mt, unsigned long index,
MA_STATE(mas, mt, index, last);
int ret = 0;
trace_ma_write(__func__, &mas, 0, entry);
trace_ma_write(TP_FCT, &mas, 0, entry);
if (WARN_ON_ONCE(xa_is_advanced(entry)))
return -EINVAL;
@@ -6586,7 +6588,7 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index)
void *entry = NULL;
MA_STATE(mas, mt, index, index);
trace_ma_op(__func__, &mas);
trace_ma_op(TP_FCT, &mas);
mtree_lock(mt);
entry = mas_erase(&mas);
@@ -6924,7 +6926,7 @@ void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max)
unsigned long copy = *index;
#endif
trace_ma_read(__func__, &mas);
trace_ma_read(TP_FCT, &mas);
if ((*index) > max)
return NULL;

View File

@@ -68,10 +68,20 @@ static void check_element(mempool_t *pool, void *element)
} else if (pool->free == mempool_free_pages) {
/* Mempools backed by page allocator */
int order = (int)(long)pool->pool_data;
void *addr = kmap_local_page((struct page *)element);
__check_element(pool, addr, 1UL << (PAGE_SHIFT + order));
kunmap_local(addr);
#ifdef CONFIG_HIGHMEM
for (int i = 0; i < (1 << order); i++) {
struct page *page = (struct page *)element;
void *addr = kmap_local_page(page + i);
__check_element(pool, addr, PAGE_SIZE);
kunmap_local(addr);
}
#else
void *addr = page_address((struct page *)element);
__check_element(pool, addr, PAGE_SIZE << order);
#endif
}
}
@@ -97,10 +107,20 @@ static void poison_element(mempool_t *pool, void *element)
} else if (pool->alloc == mempool_alloc_pages) {
/* Mempools backed by page allocator */
int order = (int)(long)pool->pool_data;
void *addr = kmap_local_page((struct page *)element);
__poison_element(addr, 1UL << (PAGE_SHIFT + order));
kunmap_local(addr);
#ifdef CONFIG_HIGHMEM
for (int i = 0; i < (1 << order); i++) {
struct page *page = (struct page *)element;
void *addr = kmap_local_page(page + i);
__poison_element(addr, PAGE_SIZE);
kunmap_local(addr);
}
#else
void *addr = page_address((struct page *)element);
__poison_element(addr, PAGE_SIZE << order);
#endif
}
}
#else /* CONFIG_SLUB_DEBUG_ON */

View File

@@ -127,8 +127,7 @@ struct shmem_options {
#define SHMEM_SEEN_INODES 2
#define SHMEM_SEEN_HUGE 4
#define SHMEM_SEEN_INUMS 8
#define SHMEM_SEEN_NOSWAP 16
#define SHMEM_SEEN_QUOTA 32
#define SHMEM_SEEN_QUOTA 16
};
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -4330,7 +4329,6 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
"Turning off swap in unprivileged tmpfs mounts unsupported");
}
ctx->noswap = true;
ctx->seen |= SHMEM_SEEN_NOSWAP;
break;
case Opt_quota:
if (fc->user_ns != &init_user_ns)
@@ -4480,14 +4478,15 @@ static int shmem_reconfigure(struct fs_context *fc)
err = "Current inum too high to switch to 32-bit inums";
goto out;
}
if ((ctx->seen & SHMEM_SEEN_NOSWAP) && ctx->noswap && !sbinfo->noswap) {
/*
* "noswap" doesn't use fsparam_flag_no, i.e. there's no "swap"
* counterpart for (re-)enabling swap.
*/
if (ctx->noswap && !sbinfo->noswap) {
err = "Cannot disable swap on remount";
goto out;
}
if (!(ctx->seen & SHMEM_SEEN_NOSWAP) && !ctx->noswap && sbinfo->noswap) {
err = "Cannot enable swap on remount if it was disabled on first mount";
goto out;
}
if (ctx->seen & SHMEM_SEEN_QUOTA &&
!sb_any_quota_loaded(fc->root->d_sb)) {

View File

@@ -701,13 +701,15 @@ void devl_rate_nodes_destroy(struct devlink *devlink)
if (!devlink_rate->parent)
continue;
refcount_dec(&devlink_rate->parent->refcnt);
if (devlink_rate_is_leaf(devlink_rate))
ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
NULL, NULL);
else if (devlink_rate_is_node(devlink_rate))
ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
NULL, NULL);
refcount_dec(&devlink_rate->parent->refcnt);
devlink_rate->parent = NULL;
}
list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
if (devlink_rate_is_node(devlink_rate)) {

View File

@@ -122,8 +122,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb,
netdev_features_t features)
{
__be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6)
: htons(ETH_P_IP);
const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x,
XFRM_MODE_SKB_CB(skb)->protocol);
__be16 type = inner_mode->family == AF_INET6 ? htons(ETH_P_IPV6)
: htons(ETH_P_IP);
return skb_eth_gso_segment(skb, features, type);
}

View File

@@ -158,8 +158,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb,
netdev_features_t features)
{
__be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP)
: htons(ETH_P_IPV6);
const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x,
XFRM_MODE_SKB_CB(skb)->protocol);
__be16 type = inner_mode->family == AF_INET ? htons(ETH_P_IP)
: htons(ETH_P_IPV6);
return skb_eth_gso_segment(skb, features, type);
}

View File

@@ -839,8 +839,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
opts->suboptions = 0;
/* Force later mptcp_write_options(), but do not use any actual
* option space.
*/
if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb)))
return false;
return true;
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
@@ -1041,6 +1044,31 @@ static void __mptcp_snd_una_update(struct mptcp_sock *msk, u64 new_snd_una)
WRITE_ONCE(msk->snd_una, new_snd_una);
}
static void rwin_update(struct mptcp_sock *msk, struct sock *ssk,
struct sk_buff *skb)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
struct tcp_sock *tp = tcp_sk(ssk);
u64 mptcp_rcv_wnd;
/* Avoid touching extra cachelines if TCP is going to accept this
* skb without filling the TCP-level window even with a possibly
* outdated mptcp-level rwin.
*/
if (!skb->len || skb->len < tcp_receive_window(tp))
return;
mptcp_rcv_wnd = atomic64_read(&msk->rcv_wnd_sent);
if (!after64(mptcp_rcv_wnd, subflow->rcv_wnd_sent))
return;
/* Some other subflow grew the mptcp-level rwin since rcv_wup,
* resync.
*/
tp->rcv_wnd += mptcp_rcv_wnd - subflow->rcv_wnd_sent;
subflow->rcv_wnd_sent = mptcp_rcv_wnd;
}
static void ack_update_msk(struct mptcp_sock *msk,
struct sock *ssk,
struct mptcp_options_received *mp_opt)
@@ -1208,6 +1236,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
*/
if (mp_opt.use_ack)
ack_update_msk(msk, sk, &mp_opt);
rwin_update(msk, sk, skb);
/* Zero-data-length packets are dropped by the caller and not
* propagated to the MPTCP layer, so the skb extension does not
@@ -1294,6 +1323,10 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th)
if (rcv_wnd_new != rcv_wnd_old) {
raise_win:
/* The msk-level rcv wnd is after the tcp level one,
* sync the latter.
*/
rcv_wnd_new = rcv_wnd_old;
win = rcv_wnd_old - ack_seq;
tp->rcv_wnd = min_t(u64, win, U32_MAX);
new_win = tp->rcv_wnd;
@@ -1317,6 +1350,21 @@ raise_win:
update_wspace:
WRITE_ONCE(msk->old_wspace, tp->rcv_wnd);
subflow->rcv_wnd_sent = rcv_wnd_new;
}
static void mptcp_track_rwin(struct tcp_sock *tp)
{
const struct sock *ssk = (const struct sock *)tp;
struct mptcp_subflow_context *subflow;
struct mptcp_sock *msk;
if (!ssk)
return;
subflow = mptcp_subflow_ctx(ssk);
msk = mptcp_sk(subflow->conn);
WRITE_ONCE(msk->old_wspace, tp->rcv_wnd);
}
__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum)
@@ -1611,6 +1659,10 @@ mp_rst:
opts->reset_transient,
opts->reset_reason);
return;
} else if (unlikely(!opts->suboptions)) {
/* Fallback to TCP */
mptcp_track_rwin(tp);
return;
}
if (OPTION_MPTCP_PRIO & opts->suboptions) {

View File

@@ -24,6 +24,7 @@ struct mptcp_pm_add_entry {
u8 retrans_times;
struct timer_list add_timer;
struct mptcp_sock *sock;
struct rcu_head rcu;
};
struct pm_nl_pernet {
@@ -343,22 +344,27 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
{
struct mptcp_pm_add_entry *entry;
struct sock *sk = (struct sock *)msk;
struct timer_list *add_timer = NULL;
bool stop_timer = false;
rcu_read_lock();
spin_lock_bh(&msk->pm.lock);
entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
if (entry && (!check_id || entry->addr.id == addr->id)) {
entry->retrans_times = ADD_ADDR_RETRANS_MAX;
add_timer = &entry->add_timer;
stop_timer = true;
}
if (!check_id && entry)
list_del(&entry->list);
spin_unlock_bh(&msk->pm.lock);
/* no lock, because sk_stop_timer_sync() is calling del_timer_sync() */
if (add_timer)
sk_stop_timer_sync(sk, add_timer);
/* Note: entry might have been removed by another thread.
* We hold rcu_read_lock() to ensure it is not freed under us.
*/
if (stop_timer)
sk_stop_timer_sync(sk, &entry->add_timer);
rcu_read_unlock();
return entry;
}
@@ -414,7 +420,7 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
list_for_each_entry_safe(entry, tmp, &free_list, list) {
sk_stop_timer_sync(sk, &entry->add_timer);
kfree(entry);
kfree_rcu(entry, rcu);
}
}
@@ -1525,7 +1531,7 @@ static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
entry = mptcp_pm_del_add_timer(msk, addr, false);
if (entry) {
kfree(entry);
kfree_rcu(entry, rcu);
return true;
}

View File

@@ -57,11 +57,13 @@ static u64 mptcp_wnd_end(const struct mptcp_sock *msk)
static const struct proto_ops *mptcp_fallback_tcp_ops(const struct sock *sk)
{
unsigned short family = READ_ONCE(sk->sk_family);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
if (sk->sk_prot == &tcpv6_prot)
if (family == AF_INET6)
return &inet6_stream_ops;
#endif
WARN_ON_ONCE(sk->sk_prot != &tcp_prot);
WARN_ON_ONCE(family != AF_INET);
return &inet_stream_ops;
}
@@ -904,6 +906,13 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
if (sk->sk_state != TCP_ESTABLISHED)
return false;
/* The caller possibly is not holding the msk socket lock, but
* in the fallback case only the current subflow is touching
* the OoO queue.
*/
if (!RB_EMPTY_ROOT(&msk->out_of_order_queue))
return false;
spin_lock_bh(&msk->fallback_lock);
if (!msk->allow_subflows) {
spin_unlock_bh(&msk->fallback_lock);
@@ -961,14 +970,19 @@ static void mptcp_reset_rtx_timer(struct sock *sk)
bool mptcp_schedule_work(struct sock *sk)
{
if (inet_sk_state_load(sk) != TCP_CLOSE &&
schedule_work(&mptcp_sk(sk)->work)) {
/* each subflow already holds a reference to the sk, and the
* workqueue is invoked by a subflow, so sk can't go away here.
*/
sock_hold(sk);
if (inet_sk_state_load(sk) == TCP_CLOSE)
return false;
/* Get a reference on this socket, mptcp_worker() will release it.
* As mptcp_worker() might complete before us, we can not avoid
* a sock_hold()/sock_put() if schedule_work() returns false.
*/
sock_hold(sk);
if (schedule_work(&mptcp_sk(sk)->work))
return true;
}
sock_put(sk);
return false;
}
@@ -2454,7 +2468,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
/* flags for __mptcp_close_ssk() */
#define MPTCP_CF_PUSH BIT(1)
#define MPTCP_CF_FASTCLOSE BIT(2)
/* be sure to send a reset only if the caller asked for it, also
* clean completely the subflow status when the subflow reaches
@@ -2465,7 +2478,7 @@ static void __mptcp_subflow_disconnect(struct sock *ssk,
unsigned int flags)
{
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
(flags & MPTCP_CF_FASTCLOSE)) {
subflow->send_fastclose) {
/* The MPTCP code never wait on the subflow sockets, TCP-level
* disconnect should never fail
*/
@@ -2512,14 +2525,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) {
/* be sure to force the tcp_close path
* to generate the egress reset
*/
ssk->sk_lingertime = 0;
sock_set_flag(ssk, SOCK_LINGER);
subflow->send_fastclose = 1;
}
if (subflow->send_fastclose && ssk->sk_state != TCP_CLOSE)
tcp_set_state(ssk, TCP_CLOSE);
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
if (!dispose_it) {
@@ -2615,7 +2622,8 @@ static void __mptcp_close_subflow(struct sock *sk)
if (ssk_state != TCP_CLOSE &&
(ssk_state != TCP_CLOSE_WAIT ||
inet_sk_state_load(sk) != TCP_ESTABLISHED))
inet_sk_state_load(sk) != TCP_ESTABLISHED ||
__mptcp_check_fallback(msk)))
continue;
/* 'subflow_data_ready' will re-sched once rx queue is empty */
@@ -2822,9 +2830,26 @@ static void mptcp_do_fastclose(struct sock *sk)
struct mptcp_sock *msk = mptcp_sk(sk);
mptcp_set_state(sk, TCP_CLOSE);
mptcp_for_each_subflow_safe(msk, subflow, tmp)
__mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow),
subflow, MPTCP_CF_FASTCLOSE);
/* Explicitly send the fastclose reset as need */
if (__mptcp_check_fallback(msk))
return;
mptcp_for_each_subflow_safe(msk, subflow, tmp) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
lock_sock(ssk);
/* Some subflow socket states don't allow/need a reset.*/
if ((1 << ssk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
goto unlock;
subflow->send_fastclose = 1;
tcp_send_active_reset(ssk, ssk->sk_allocation,
SK_RST_REASON_TCP_ABORT_ON_CLOSE);
unlock:
release_sock(ssk);
}
}
static void mptcp_worker(struct work_struct *work)
@@ -2851,7 +2876,11 @@ static void mptcp_worker(struct work_struct *work)
__mptcp_close_subflow(sk);
if (mptcp_close_tout_expired(sk)) {
struct mptcp_subflow_context *subflow, *tmp;
mptcp_do_fastclose(sk);
mptcp_for_each_subflow_safe(msk, subflow, tmp)
__mptcp_close_ssk(sk, subflow->tcp_sock, subflow, 0);
mptcp_close_wake_up(sk);
}
@@ -3283,7 +3312,8 @@ static int mptcp_disconnect(struct sock *sk, int flags)
/* msk->subflow is still intact, the following will not free the first
* subflow
*/
mptcp_destroy_common(msk, MPTCP_CF_FASTCLOSE);
mptcp_do_fastclose(sk);
mptcp_destroy_common(msk);
/* The first subflow is already in TCP_CLOSE status, the following
* can't overlap with a fallback anymore
@@ -3465,7 +3495,7 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk)
msk->rcvq_space.space = TCP_INIT_CWND * TCP_MSS_DEFAULT;
}
void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags)
void mptcp_destroy_common(struct mptcp_sock *msk)
{
struct mptcp_subflow_context *subflow, *tmp;
struct sock *sk = (struct sock *)msk;
@@ -3474,7 +3504,7 @@ void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags)
/* join list will be eventually flushed (with rst) at sock lock release time */
mptcp_for_each_subflow_safe(msk, subflow, tmp)
__mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, flags);
__mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, 0);
/* move to sk_receive_queue, sk_stream_kill_queues will purge it */
mptcp_data_lock(sk);
@@ -3499,7 +3529,7 @@ static void mptcp_destroy(struct sock *sk)
/* allow the following to close even the initial subflow */
msk->free_first = 1;
mptcp_destroy_common(msk, 0);
mptcp_destroy_common(msk);
sk_sockets_allocated_dec(sk);
}

View File

@@ -508,6 +508,7 @@ struct mptcp_subflow_context {
u64 remote_key;
u64 idsn;
u64 map_seq;
u64 rcv_wnd_sent;
u32 snd_isn;
u32 token;
u32 rel_write_seq;
@@ -967,7 +968,7 @@ static inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk)
local_bh_enable();
}
void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags);
void mptcp_destroy_common(struct mptcp_sock *msk);
#define MPTCP_TOKEN_MAX_RETRIES 4

View File

@@ -2150,6 +2150,10 @@ void __init mptcp_subflow_init(void)
tcp_prot_override = tcp_prot;
tcp_prot_override.release_cb = tcp_release_cb_override;
tcp_prot_override.diag_destroy = tcp_abort_override;
#ifdef CONFIG_BPF_SYSCALL
/* Disable sockmap processing for subflows */
tcp_prot_override.psock_update_sk_prot = NULL;
#endif
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
@@ -2186,6 +2190,10 @@ void __init mptcp_subflow_init(void)
tcpv6_prot_override = tcpv6_prot;
tcpv6_prot_override.release_cb = tcp_release_cb_override;
tcpv6_prot_override.diag_destroy = tcp_abort_override;
#ifdef CONFIG_BPF_SYSCALL
/* Disable sockmap processing for subflows */
tcpv6_prot_override.psock_update_sk_prot = NULL;
#endif
#endif
mptcp_diag_subflow_init(&subflow_ulp_ops);

View File

@@ -613,69 +613,6 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
return 0;
}
static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
const struct nlattr *a)
{
struct nshhdr *nh;
size_t length;
int err;
u8 flags;
u8 ttl;
int i;
struct ovs_key_nsh key;
struct ovs_key_nsh mask;
err = nsh_key_from_nlattr(a, &key, &mask);
if (err)
return err;
/* Make sure the NSH base header is there */
if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN))
return -ENOMEM;
nh = nsh_hdr(skb);
length = nsh_hdr_len(nh);
/* Make sure the whole NSH header is there */
err = skb_ensure_writable(skb, skb_network_offset(skb) +
length);
if (unlikely(err))
return err;
nh = nsh_hdr(skb);
skb_postpull_rcsum(skb, nh, length);
flags = nsh_get_flags(nh);
flags = OVS_MASKED(flags, key.base.flags, mask.base.flags);
flow_key->nsh.base.flags = flags;
ttl = nsh_get_ttl(nh);
ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl);
flow_key->nsh.base.ttl = ttl;
nsh_set_flags_and_ttl(nh, flags, ttl);
nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr,
mask.base.path_hdr);
flow_key->nsh.base.path_hdr = nh->path_hdr;
switch (nh->mdtype) {
case NSH_M_TYPE1:
for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
nh->md1.context[i] =
OVS_MASKED(nh->md1.context[i], key.context[i],
mask.context[i]);
}
memcpy(flow_key->nsh.context, nh->md1.context,
sizeof(nh->md1.context));
break;
case NSH_M_TYPE2:
memset(flow_key->nsh.context, 0,
sizeof(flow_key->nsh.context));
break;
default:
return -EINVAL;
}
skb_postpush_rcsum(skb, nh, length);
return 0;
}
/* Must follow skb_ensure_writable() since that can move the skb data. */
static void set_tp_port(struct sk_buff *skb, __be16 *port,
__be16 new_port, __sum16 *check)
@@ -1169,10 +1106,6 @@ static int execute_masked_set_action(struct sk_buff *skb,
get_mask(a, struct ovs_key_ethernet *));
break;
case OVS_KEY_ATTR_NSH:
err = set_nsh(skb, flow_key, a);
break;
case OVS_KEY_ATTR_IPV4:
err = set_ipv4(skb, flow_key, nla_data(a),
get_mask(a, struct ovs_key_ipv4 *));
@@ -1209,6 +1142,7 @@ static int execute_masked_set_action(struct sk_buff *skb,
case OVS_KEY_ATTR_CT_LABELS:
case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4:
case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6:
case OVS_KEY_ATTR_NSH:
err = -EINVAL;
break;
}

View File

@@ -1305,6 +1305,11 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
return 0;
}
/*
* Constructs NSH header 'nh' from attributes of OVS_ACTION_ATTR_PUSH_NSH,
* where 'nh' points to a memory block of 'size' bytes. It's assumed that
* attributes were previously validated with validate_push_nsh().
*/
int nsh_hdr_from_nlattr(const struct nlattr *attr,
struct nshhdr *nh, size_t size)
{
@@ -1314,8 +1319,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr,
u8 ttl = 0;
int mdlen = 0;
/* validate_nsh has check this, so we needn't do duplicate check here
*/
if (size < NSH_BASE_HDR_LEN)
return -ENOBUFS;
@@ -1359,46 +1362,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr,
return 0;
}
int nsh_key_from_nlattr(const struct nlattr *attr,
struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
{
struct nlattr *a;
int rem;
/* validate_nsh has check this, so we needn't do duplicate check here
*/
nla_for_each_nested(a, attr, rem) {
int type = nla_type(a);
switch (type) {
case OVS_NSH_KEY_ATTR_BASE: {
const struct ovs_nsh_key_base *base = nla_data(a);
const struct ovs_nsh_key_base *base_mask = base + 1;
nsh->base = *base;
nsh_mask->base = *base_mask;
break;
}
case OVS_NSH_KEY_ATTR_MD1: {
const struct ovs_nsh_key_md1 *md1 = nla_data(a);
const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
memcpy(nsh->context, md1->context, sizeof(*md1));
memcpy(nsh_mask->context, md1_mask->context,
sizeof(*md1_mask));
break;
}
case OVS_NSH_KEY_ATTR_MD2:
/* Not supported yet */
return -ENOTSUPP;
default:
return -EINVAL;
}
}
return 0;
}
static int nsh_key_put_from_nlattr(const struct nlattr *attr,
struct sw_flow_match *match, bool is_mask,
bool is_push_nsh, bool log)
@@ -2839,17 +2802,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err;
}
static bool validate_nsh(const struct nlattr *attr, bool is_mask,
bool is_push_nsh, bool log)
static bool validate_push_nsh(const struct nlattr *attr, bool log)
{
struct sw_flow_match match;
struct sw_flow_key key;
int ret = 0;
ovs_match_init(&match, &key, true, NULL);
ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
is_push_nsh, log);
return !ret;
return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
}
/* Return false if there are any non-masked bits set.
@@ -2997,13 +2956,6 @@ static int validate_set(const struct nlattr *a,
break;
case OVS_KEY_ATTR_NSH:
if (eth_type != htons(ETH_P_NSH))
return -EINVAL;
if (!validate_nsh(nla_data(a), masked, false, log))
return -EINVAL;
break;
default:
return -EINVAL;
}
@@ -3436,7 +3388,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
return -EINVAL;
}
mac_proto = MAC_PROTO_NONE;
if (!validate_nsh(nla_data(a), false, true, true))
if (!validate_push_nsh(nla_data(a), log))
return -EINVAL;
break;

View File

@@ -65,8 +65,6 @@ int ovs_nla_put_actions(const struct nlattr *attr,
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
struct ovs_key_nsh *nsh_mask);
int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh,
size_t size);

View File

@@ -721,8 +721,10 @@ tls_device_rx_resync_async(struct tls_offload_resync_async *resync_async,
/* shouldn't get to wraparound:
* too long in async stage, something bad happened
*/
if (WARN_ON_ONCE(resync_async->rcd_delta == USHRT_MAX))
if (WARN_ON_ONCE(resync_async->rcd_delta == USHRT_MAX)) {
tls_offload_rx_resync_async_request_cancel(resync_async);
return false;
}
/* asynchronous stage: log all headers seq such that
* req_seq <= seq <= end_seq, and wait for real resync request

View File

@@ -2769,20 +2769,21 @@ static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
static int unix_stream_read_generic(struct unix_stream_read_state *state,
bool freezable)
{
struct scm_cookie scm;
int noblock = state->flags & MSG_DONTWAIT;
struct socket *sock = state->socket;
struct msghdr *msg = state->msg;
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
int copied = 0;
size_t size = state->size;
int flags = state->flags;
int noblock = flags & MSG_DONTWAIT;
bool check_creds = false;
int target;
struct scm_cookie scm;
unsigned int last_len;
struct unix_sock *u;
int copied = 0;
int err = 0;
long timeo;
int target;
int skip;
size_t size = state->size;
unsigned int last_len;
if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) {
err = -EINVAL;
@@ -2802,6 +2803,9 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
memset(&scm, 0, sizeof(scm));
u = unix_sk(sk);
redo:
/* Lock the socket to prevent queue disordering
* while sleeps in memcpy_tomsg
*/
@@ -2813,7 +2817,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
struct sk_buff *skb, *last;
int chunk;
redo:
unix_state_lock(sk);
if (sock_flag(sk, SOCK_DEAD)) {
err = -ECONNRESET;
@@ -2863,7 +2866,6 @@ again:
goto out;
}
mutex_lock(&u->iolock);
goto redo;
unlock:
unix_state_unlock(sk);
@@ -2894,14 +2896,12 @@ unlock:
}
/* Copy address just once */
if (state->msg && state->msg->msg_name) {
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
state->msg->msg_name);
unix_copy_addr(state->msg, skb->sk);
if (msg && msg->msg_name) {
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk,
state->msg->msg_name,
&state->msg->msg_namelen);
unix_copy_addr(msg, skb->sk);
BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, msg->msg_name,
&msg->msg_namelen);
sunaddr = NULL;
}
@@ -2959,8 +2959,8 @@ unlock:
} while (size);
mutex_unlock(&u->iolock);
if (state->msg)
scm_recv_unix(sock, state->msg, &scm, flags);
if (msg)
scm_recv_unix(sock, msg, &scm, flags);
else
scm_destroy(&scm);
out:

View File

@@ -1616,18 +1616,40 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr,
timeout = schedule_timeout(timeout);
lock_sock(sk);
if (signal_pending(current)) {
err = sock_intr_errno(timeout);
sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE;
sock->state = SS_UNCONNECTED;
vsock_transport_cancel_pkt(vsk);
vsock_remove_connected(vsk);
goto out_wait;
} else if ((sk->sk_state != TCP_ESTABLISHED) && (timeout == 0)) {
err = -ETIMEDOUT;
/* Connection established. Whatever happens to socket once we
* release it, that's not connect()'s concern. No need to go
* into signal and timeout handling. Call it a day.
*
* Note that allowing to "reset" an already established socket
* here is racy and insecure.
*/
if (sk->sk_state == TCP_ESTABLISHED)
break;
/* If connection was _not_ established and a signal/timeout came
* to be, we want the socket's state reset. User space may want
* to retry.
*
* sk_state != TCP_ESTABLISHED implies that socket is not on
* vsock_connected_table. We keep the binding and the transport
* assigned.
*/
if (signal_pending(current) || timeout == 0) {
err = timeout == 0 ? -ETIMEDOUT : sock_intr_errno(timeout);
/* Listener might have already responded with
* VIRTIO_VSOCK_OP_RESPONSE. Its handling expects our
* sk_state == TCP_SYN_SENT, which hereby we break.
* In such case VIRTIO_VSOCK_OP_RST will follow.
*/
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
/* Try to cancel VIRTIO_VSOCK_OP_REQUEST skb sent out by
* transport->connect().
*/
vsock_transport_cancel_pkt(vsk);
goto out_wait;
}

View File

@@ -766,8 +766,12 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
/* Exclusive direct xmit for tunnel mode, as
* some filtering or matching rules may apply
* in transport mode.
* Locally generated packets also require
* the normal XFRM path for L2 header setup,
* as the hardware needs the L2 header to match
* for encryption, so skip direct output as well.
*/
if (x->props.mode == XFRM_MODE_TUNNEL)
if (x->props.mode == XFRM_MODE_TUNNEL && !skb->sk)
return xfrm_dev_direct_output(sk, x, skb);
return xfrm_output_resume(sk, skb, 0);

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