Merge 574686c807 ("ice: use DSN instead of PCI BDF for ice_adapter index") into android16-6.12-lts
Steps on the way to 6.12.29 Change-Id: Id846660f91db6f211ce79fc31186c6d8e78b0468 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -165,6 +165,19 @@
|
|||||||
startup-delay-us = <20000>;
|
startup-delay-us = <20000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc {
|
||||||
|
compatible = "regulator-gpio";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pinctrl_usdhc2_vsel>;
|
||||||
|
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
regulator-min-microvolt = <1800000>;
|
||||||
|
states = <1800000 0x1>,
|
||||||
|
<3300000 0x0>;
|
||||||
|
regulator-name = "PMIC_USDHC_VSELECT";
|
||||||
|
vin-supply = <®_nvcc_sd>;
|
||||||
|
};
|
||||||
|
|
||||||
reserved-memory {
|
reserved-memory {
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
@@ -290,7 +303,7 @@
|
|||||||
"SODIMM_19",
|
"SODIMM_19",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"PMIC_USDHC_VSELECT",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
@@ -801,6 +814,7 @@
|
|||||||
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
|
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
|
||||||
pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>;
|
pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>;
|
||||||
vmmc-supply = <®_usdhc2_vmmc>;
|
vmmc-supply = <®_usdhc2_vmmc>;
|
||||||
|
vqmmc-supply = <®_usdhc2_vqmmc>;
|
||||||
};
|
};
|
||||||
|
|
||||||
&wdog1 {
|
&wdog1 {
|
||||||
@@ -1222,13 +1236,17 @@
|
|||||||
<MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6>; /* SODIMM 76 */
|
<MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6>; /* SODIMM 76 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pinctrl_usdhc2_vsel: usdhc2vselgrp {
|
||||||
|
fsl,pins =
|
||||||
|
<MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x10>; /* PMIC_USDHC_VSELECT */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the
|
* Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the
|
||||||
* on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here.
|
* on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here.
|
||||||
*/
|
*/
|
||||||
pinctrl_usdhc2: usdhc2grp {
|
pinctrl_usdhc2: usdhc2grp {
|
||||||
fsl,pins =
|
fsl,pins =
|
||||||
<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>,
|
|
||||||
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */
|
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */
|
||||||
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */
|
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */
|
||||||
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */
|
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */
|
||||||
@@ -1239,7 +1257,6 @@
|
|||||||
|
|
||||||
pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
|
pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
|
||||||
fsl,pins =
|
fsl,pins =
|
||||||
<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>,
|
|
||||||
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>,
|
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>,
|
||||||
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>,
|
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>,
|
||||||
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>,
|
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>,
|
||||||
@@ -1250,7 +1267,6 @@
|
|||||||
|
|
||||||
pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
|
pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
|
||||||
fsl,pins =
|
fsl,pins =
|
||||||
<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>,
|
|
||||||
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>,
|
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>,
|
||||||
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>,
|
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>,
|
||||||
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>,
|
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>,
|
||||||
@@ -1262,7 +1278,6 @@
|
|||||||
/* Avoid backfeeding with removed card power */
|
/* Avoid backfeeding with removed card power */
|
||||||
pinctrl_usdhc2_sleep: usdhc2slpgrp {
|
pinctrl_usdhc2_sleep: usdhc2slpgrp {
|
||||||
fsl,pins =
|
fsl,pins =
|
||||||
<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x0>,
|
|
||||||
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>,
|
<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>,
|
||||||
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>,
|
<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>,
|
||||||
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>,
|
<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>,
|
||||||
|
|||||||
@@ -636,7 +636,8 @@ SYM_CODE_START(stack_overflow)
|
|||||||
stmg %r0,%r7,__PT_R0(%r11)
|
stmg %r0,%r7,__PT_R0(%r11)
|
||||||
stmg %r8,%r9,__PT_PSW(%r11)
|
stmg %r8,%r9,__PT_PSW(%r11)
|
||||||
mvc __PT_R8(64,%r11),0(%r14)
|
mvc __PT_R8(64,%r11),0(%r14)
|
||||||
stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
|
GET_LC %r2
|
||||||
|
mvc __PT_ORIG_GPR2(8,%r11),__LC_PGM_LAST_BREAK(%r2)
|
||||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||||
lgr %r2,%r11 # pass pointer to pt_regs
|
lgr %r2,%r11 # pass pointer to pt_regs
|
||||||
jg kernel_stack_overflow
|
jg kernel_stack_overflow
|
||||||
|
|||||||
@@ -422,6 +422,8 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state);
|
zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state);
|
||||||
|
if (IS_ERR(zdev))
|
||||||
|
return;
|
||||||
list_add_tail(&zdev->entry, scan_list);
|
list_add_tail(&zdev->entry, scan_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1219,7 +1219,8 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
|
static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
|
||||||
struct scmi_xfer *xfer, ktime_t stop)
|
struct scmi_xfer *xfer, ktime_t stop,
|
||||||
|
bool *ooo)
|
||||||
{
|
{
|
||||||
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
|
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
|
||||||
|
|
||||||
@@ -1228,7 +1229,7 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
|
|||||||
* in case of out-of-order receptions of delayed responses
|
* in case of out-of-order receptions of delayed responses
|
||||||
*/
|
*/
|
||||||
return info->desc->ops->poll_done(cinfo, xfer) ||
|
return info->desc->ops->poll_done(cinfo, xfer) ||
|
||||||
try_wait_for_completion(&xfer->done) ||
|
(*ooo = try_wait_for_completion(&xfer->done)) ||
|
||||||
ktime_after(ktime_get(), stop);
|
ktime_after(ktime_get(), stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1245,15 +1246,17 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
|
|||||||
* itself to support synchronous commands replies.
|
* itself to support synchronous commands replies.
|
||||||
*/
|
*/
|
||||||
if (!desc->sync_cmds_completed_on_ret) {
|
if (!desc->sync_cmds_completed_on_ret) {
|
||||||
|
bool ooo = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Poll on xfer using transport provided .poll_done();
|
* Poll on xfer using transport provided .poll_done();
|
||||||
* assumes no completion interrupt was available.
|
* assumes no completion interrupt was available.
|
||||||
*/
|
*/
|
||||||
ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
|
ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
|
||||||
|
|
||||||
spin_until_cond(scmi_xfer_done_no_timeout(cinfo,
|
spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer,
|
||||||
xfer, stop));
|
stop, &ooo));
|
||||||
if (ktime_after(ktime_get(), stop)) {
|
if (!ooo && !info->desc->ops->poll_done(cinfo, xfer)) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"timed out in resp(caller: %pS) - polling\n",
|
"timed out in resp(caller: %pS) - polling\n",
|
||||||
(void *)_RET_IP_);
|
(void *)_RET_IP_);
|
||||||
|
|||||||
@@ -1183,7 +1183,7 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
|
|||||||
|
|
||||||
t = dm_get_live_table(md, &srcu_idx);
|
t = dm_get_live_table(md, &srcu_idx);
|
||||||
if (!t)
|
if (!t)
|
||||||
return 0;
|
goto put_live_table;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < t->num_targets; i++) {
|
for (unsigned int i = 0; i < t->num_targets; i++) {
|
||||||
struct dm_target *ti = dm_table_get_target(t, i);
|
struct dm_target *ti = dm_table_get_target(t, i);
|
||||||
@@ -1194,6 +1194,7 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
|
|||||||
(void *)key);
|
(void *)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
put_live_table:
|
||||||
dm_put_live_table(md, srcu_idx);
|
dm_put_live_table(md, srcu_idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2372,6 +2372,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
|
|||||||
SET_NETDEV_DEV(net_dev, dev);
|
SET_NETDEV_DEV(net_dev, dev);
|
||||||
|
|
||||||
m_can_of_parse_mram(class_dev, mram_config_vals);
|
m_can_of_parse_mram(class_dev, mram_config_vals);
|
||||||
|
spin_lock_init(&class_dev->tx_handling_spinlock);
|
||||||
out:
|
out:
|
||||||
return class_dev;
|
return class_dev;
|
||||||
}
|
}
|
||||||
@@ -2456,9 +2457,9 @@ EXPORT_SYMBOL_GPL(m_can_class_register);
|
|||||||
|
|
||||||
void m_can_class_unregister(struct m_can_classdev *cdev)
|
void m_can_class_unregister(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
|
unregister_candev(cdev->net);
|
||||||
if (cdev->is_peripheral)
|
if (cdev->is_peripheral)
|
||||||
can_rx_offload_del(&cdev->offload);
|
can_rx_offload_del(&cdev->offload);
|
||||||
unregister_candev(cdev->net);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
||||||
|
|
||||||
|
|||||||
@@ -942,8 +942,8 @@ static void rkcanfd_remove(struct platform_device *pdev)
|
|||||||
struct rkcanfd_priv *priv = platform_get_drvdata(pdev);
|
struct rkcanfd_priv *priv = platform_get_drvdata(pdev);
|
||||||
struct net_device *ndev = priv->ndev;
|
struct net_device *ndev = priv->ndev;
|
||||||
|
|
||||||
can_rx_offload_del(&priv->offload);
|
|
||||||
rkcanfd_unregister(priv);
|
rkcanfd_unregister(priv);
|
||||||
|
can_rx_offload_del(&priv->offload);
|
||||||
free_candev(ndev);
|
free_candev(ndev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,24 @@ static const struct can_bittiming_const mcp251xfd_data_bittiming_const = {
|
|||||||
.brp_inc = 1,
|
.brp_inc = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* The datasheet of the mcp2518fd (DS20006027B) specifies a range of
|
||||||
|
* [-64,63] for TDCO, indicating a relative TDCO.
|
||||||
|
*
|
||||||
|
* Manual tests have shown, that using a relative TDCO configuration
|
||||||
|
* results in bus off, while an absolute configuration works.
|
||||||
|
*
|
||||||
|
* For TDCO use the max value (63) from the data sheet, but 0 as the
|
||||||
|
* minimum.
|
||||||
|
*/
|
||||||
|
static const struct can_tdc_const mcp251xfd_tdc_const = {
|
||||||
|
.tdcv_min = 0,
|
||||||
|
.tdcv_max = 63,
|
||||||
|
.tdco_min = 0,
|
||||||
|
.tdco_max = 63,
|
||||||
|
.tdcf_min = 0,
|
||||||
|
.tdcf_max = 0,
|
||||||
|
};
|
||||||
|
|
||||||
static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model)
|
static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model)
|
||||||
{
|
{
|
||||||
switch (model) {
|
switch (model) {
|
||||||
@@ -510,8 +528,7 @@ static int mcp251xfd_set_bittiming(const struct mcp251xfd_priv *priv)
|
|||||||
{
|
{
|
||||||
const struct can_bittiming *bt = &priv->can.bittiming;
|
const struct can_bittiming *bt = &priv->can.bittiming;
|
||||||
const struct can_bittiming *dbt = &priv->can.data_bittiming;
|
const struct can_bittiming *dbt = &priv->can.data_bittiming;
|
||||||
u32 val = 0;
|
u32 tdcmod, val = 0;
|
||||||
s8 tdco;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* CAN Control Register
|
/* CAN Control Register
|
||||||
@@ -575,11 +592,16 @@ static int mcp251xfd_set_bittiming(const struct mcp251xfd_priv *priv)
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* Transmitter Delay Compensation */
|
/* Transmitter Delay Compensation */
|
||||||
tdco = clamp_t(int, dbt->brp * (dbt->prop_seg + dbt->phase_seg1),
|
if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_AUTO)
|
||||||
-64, 63);
|
tdcmod = MCP251XFD_REG_TDC_TDCMOD_AUTO;
|
||||||
val = FIELD_PREP(MCP251XFD_REG_TDC_TDCMOD_MASK,
|
else if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_MANUAL)
|
||||||
MCP251XFD_REG_TDC_TDCMOD_AUTO) |
|
tdcmod = MCP251XFD_REG_TDC_TDCMOD_MANUAL;
|
||||||
FIELD_PREP(MCP251XFD_REG_TDC_TDCO_MASK, tdco);
|
else
|
||||||
|
tdcmod = MCP251XFD_REG_TDC_TDCMOD_DISABLED;
|
||||||
|
|
||||||
|
val = FIELD_PREP(MCP251XFD_REG_TDC_TDCMOD_MASK, tdcmod) |
|
||||||
|
FIELD_PREP(MCP251XFD_REG_TDC_TDCV_MASK, priv->can.tdc.tdcv) |
|
||||||
|
FIELD_PREP(MCP251XFD_REG_TDC_TDCO_MASK, priv->can.tdc.tdco);
|
||||||
|
|
||||||
return regmap_write(priv->map_reg, MCP251XFD_REG_TDC, val);
|
return regmap_write(priv->map_reg, MCP251XFD_REG_TDC, val);
|
||||||
}
|
}
|
||||||
@@ -2083,10 +2105,12 @@ static int mcp251xfd_probe(struct spi_device *spi)
|
|||||||
priv->can.do_get_berr_counter = mcp251xfd_get_berr_counter;
|
priv->can.do_get_berr_counter = mcp251xfd_get_berr_counter;
|
||||||
priv->can.bittiming_const = &mcp251xfd_bittiming_const;
|
priv->can.bittiming_const = &mcp251xfd_bittiming_const;
|
||||||
priv->can.data_bittiming_const = &mcp251xfd_data_bittiming_const;
|
priv->can.data_bittiming_const = &mcp251xfd_data_bittiming_const;
|
||||||
|
priv->can.tdc_const = &mcp251xfd_tdc_const;
|
||||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
||||||
CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING |
|
CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING |
|
||||||
CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO |
|
CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO |
|
||||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_TDC_AUTO |
|
||||||
|
CAN_CTRLMODE_TDC_MANUAL;
|
||||||
set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
|
set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
|
||||||
priv->ndev = ndev;
|
priv->ndev = ndev;
|
||||||
priv->spi = spi;
|
priv->spi = spi;
|
||||||
@@ -2174,8 +2198,8 @@ static void mcp251xfd_remove(struct spi_device *spi)
|
|||||||
struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
|
struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
|
||||||
struct net_device *ndev = priv->ndev;
|
struct net_device *ndev = priv->ndev;
|
||||||
|
|
||||||
can_rx_offload_del(&priv->offload);
|
|
||||||
mcp251xfd_unregister(priv);
|
mcp251xfd_unregister(priv);
|
||||||
|
can_rx_offload_del(&priv->offload);
|
||||||
spi->max_speed_hz = priv->spi_max_speed_hz_orig;
|
spi->max_speed_hz = priv->spi_max_speed_hz_orig;
|
||||||
free_candev(ndev);
|
free_candev(ndev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright Red Hat
|
// SPDX-FileCopyrightText: Copyright Red Hat
|
||||||
|
|
||||||
#include <linux/bitfield.h>
|
|
||||||
#include <linux/cleanup.h>
|
#include <linux/cleanup.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
@@ -9,27 +8,21 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/xarray.h>
|
#include <linux/xarray.h>
|
||||||
#include "ice_adapter.h"
|
#include "ice_adapter.h"
|
||||||
|
#include "ice.h"
|
||||||
|
|
||||||
static DEFINE_XARRAY(ice_adapters);
|
static DEFINE_XARRAY(ice_adapters);
|
||||||
static DEFINE_MUTEX(ice_adapters_mutex);
|
static DEFINE_MUTEX(ice_adapters_mutex);
|
||||||
|
|
||||||
/* PCI bus number is 8 bits. Slot is 5 bits. Domain can have the rest. */
|
static unsigned long ice_adapter_index(u64 dsn)
|
||||||
#define INDEX_FIELD_DOMAIN GENMASK(BITS_PER_LONG - 1, 13)
|
|
||||||
#define INDEX_FIELD_BUS GENMASK(12, 5)
|
|
||||||
#define INDEX_FIELD_SLOT GENMASK(4, 0)
|
|
||||||
|
|
||||||
static unsigned long ice_adapter_index(const struct pci_dev *pdev)
|
|
||||||
{
|
{
|
||||||
unsigned int domain = pci_domain_nr(pdev->bus);
|
#if BITS_PER_LONG == 64
|
||||||
|
return dsn;
|
||||||
WARN_ON(domain > FIELD_MAX(INDEX_FIELD_DOMAIN));
|
#else
|
||||||
|
return (u32)dsn ^ (u32)(dsn >> 32);
|
||||||
return FIELD_PREP(INDEX_FIELD_DOMAIN, domain) |
|
#endif
|
||||||
FIELD_PREP(INDEX_FIELD_BUS, pdev->bus->number) |
|
|
||||||
FIELD_PREP(INDEX_FIELD_SLOT, PCI_SLOT(pdev->devfn));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ice_adapter *ice_adapter_new(void)
|
static struct ice_adapter *ice_adapter_new(u64 dsn)
|
||||||
{
|
{
|
||||||
struct ice_adapter *adapter;
|
struct ice_adapter *adapter;
|
||||||
|
|
||||||
@@ -37,6 +30,7 @@ static struct ice_adapter *ice_adapter_new(void)
|
|||||||
if (!adapter)
|
if (!adapter)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
adapter->device_serial_number = dsn;
|
||||||
spin_lock_init(&adapter->ptp_gltsyn_time_lock);
|
spin_lock_init(&adapter->ptp_gltsyn_time_lock);
|
||||||
refcount_set(&adapter->refcount, 1);
|
refcount_set(&adapter->refcount, 1);
|
||||||
|
|
||||||
@@ -67,23 +61,26 @@ static void ice_adapter_free(struct ice_adapter *adapter)
|
|||||||
* Return: Pointer to ice_adapter on success.
|
* Return: Pointer to ice_adapter on success.
|
||||||
* ERR_PTR() on error. -ENOMEM is the only possible error.
|
* ERR_PTR() on error. -ENOMEM is the only possible error.
|
||||||
*/
|
*/
|
||||||
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)
|
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
unsigned long index = ice_adapter_index(pdev);
|
u64 dsn = pci_get_dsn(pdev);
|
||||||
struct ice_adapter *adapter;
|
struct ice_adapter *adapter;
|
||||||
|
unsigned long index;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
index = ice_adapter_index(dsn);
|
||||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||||
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
|
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
|
||||||
if (err == -EBUSY) {
|
if (err == -EBUSY) {
|
||||||
adapter = xa_load(&ice_adapters, index);
|
adapter = xa_load(&ice_adapters, index);
|
||||||
refcount_inc(&adapter->refcount);
|
refcount_inc(&adapter->refcount);
|
||||||
|
WARN_ON_ONCE(adapter->device_serial_number != dsn);
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
adapter = ice_adapter_new();
|
adapter = ice_adapter_new(dsn);
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
||||||
@@ -100,11 +97,13 @@ struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)
|
|||||||
*
|
*
|
||||||
* Context: Process, may sleep.
|
* Context: Process, may sleep.
|
||||||
*/
|
*/
|
||||||
void ice_adapter_put(const struct pci_dev *pdev)
|
void ice_adapter_put(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
unsigned long index = ice_adapter_index(pdev);
|
u64 dsn = pci_get_dsn(pdev);
|
||||||
struct ice_adapter *adapter;
|
struct ice_adapter *adapter;
|
||||||
|
unsigned long index;
|
||||||
|
|
||||||
|
index = ice_adapter_index(dsn);
|
||||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||||
adapter = xa_load(&ice_adapters, index);
|
adapter = xa_load(&ice_adapters, index);
|
||||||
if (WARN_ON(!adapter))
|
if (WARN_ON(!adapter))
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ struct ice_port_list {
|
|||||||
* @refcount: Reference count. struct ice_pf objects hold the references.
|
* @refcount: Reference count. struct ice_pf objects hold the references.
|
||||||
* @ctrl_pf: Control PF of the adapter
|
* @ctrl_pf: Control PF of the adapter
|
||||||
* @ports: Ports list
|
* @ports: Ports list
|
||||||
|
* @device_serial_number: DSN cached for collision detection on 32bit systems
|
||||||
*/
|
*/
|
||||||
struct ice_adapter {
|
struct ice_adapter {
|
||||||
refcount_t refcount;
|
refcount_t refcount;
|
||||||
@@ -40,9 +41,10 @@ struct ice_adapter {
|
|||||||
|
|
||||||
struct ice_pf *ctrl_pf;
|
struct ice_pf *ctrl_pf;
|
||||||
struct ice_port_list ports;
|
struct ice_port_list ports;
|
||||||
|
u64 device_serial_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev);
|
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
|
||||||
void ice_adapter_put(const struct pci_dev *pdev);
|
void ice_adapter_put(struct pci_dev *pdev);
|
||||||
|
|
||||||
#endif /* _ICE_ADAPTER_H */
|
#endif /* _ICE_ADAPTER_H */
|
||||||
|
|||||||
@@ -3140,11 +3140,19 @@ static int mtk_dma_init(struct mtk_eth *eth)
|
|||||||
static void mtk_dma_free(struct mtk_eth *eth)
|
static void mtk_dma_free(struct mtk_eth *eth)
|
||||||
{
|
{
|
||||||
const struct mtk_soc_data *soc = eth->soc;
|
const struct mtk_soc_data *soc = eth->soc;
|
||||||
int i;
|
int i, j, txqs = 1;
|
||||||
|
|
||||||
|
if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
|
||||||
|
txqs = MTK_QDMA_NUM_QUEUES;
|
||||||
|
|
||||||
|
for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||||
|
if (!eth->netdev[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < txqs; j++)
|
||||||
|
netdev_tx_reset_subqueue(eth->netdev[i], j);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < MTK_MAX_DEVS; i++)
|
|
||||||
if (eth->netdev[i])
|
|
||||||
netdev_reset_queue(eth->netdev[i]);
|
|
||||||
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
|
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
|
||||||
dma_free_coherent(eth->dma_dev,
|
dma_free_coherent(eth->dma_dev,
|
||||||
MTK_QDMA_RING_SIZE * soc->tx.desc_size,
|
MTK_QDMA_RING_SIZE * soc->tx.desc_size,
|
||||||
@@ -3419,9 +3427,6 @@ static int mtk_open(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
mtk_gdm_config(eth, target_mac->id, gdm_config);
|
mtk_gdm_config(eth, target_mac->id, gdm_config);
|
||||||
}
|
}
|
||||||
/* Reset and enable PSE */
|
|
||||||
mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
|
|
||||||
mtk_w32(eth, 0, MTK_RST_GL);
|
|
||||||
|
|
||||||
napi_enable(ð->tx_napi);
|
napi_enable(ð->tx_napi);
|
||||||
napi_enable(ð->rx_napi);
|
napi_enable(ð->rx_napi);
|
||||||
|
|||||||
@@ -298,6 +298,10 @@ struct send_queue {
|
|||||||
|
|
||||||
/* Record whether sq is in reset state. */
|
/* Record whether sq is in reset state. */
|
||||||
bool reset;
|
bool reset;
|
||||||
|
|
||||||
|
struct xsk_buff_pool *xsk_pool;
|
||||||
|
|
||||||
|
dma_addr_t xsk_hdr_dma_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Internal representation of a receive virtqueue */
|
/* Internal representation of a receive virtqueue */
|
||||||
@@ -501,6 +505,8 @@ struct virtio_net_common_hdr {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct virtio_net_common_hdr xsk_hdr;
|
||||||
|
|
||||||
static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf);
|
static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf);
|
||||||
static void virtnet_sq_free_unused_buf_done(struct virtqueue *vq);
|
static void virtnet_sq_free_unused_buf_done(struct virtqueue *vq);
|
||||||
static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
|
static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
|
||||||
@@ -5556,6 +5562,29 @@ unreg:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int virtnet_sq_bind_xsk_pool(struct virtnet_info *vi,
|
||||||
|
struct send_queue *sq,
|
||||||
|
struct xsk_buff_pool *pool)
|
||||||
|
{
|
||||||
|
int err, qindex;
|
||||||
|
|
||||||
|
qindex = sq - vi->sq;
|
||||||
|
|
||||||
|
virtnet_tx_pause(vi, sq);
|
||||||
|
|
||||||
|
err = virtqueue_reset(sq->vq, virtnet_sq_free_unused_buf);
|
||||||
|
if (err) {
|
||||||
|
netdev_err(vi->dev, "reset tx fail: tx queue index: %d err: %d\n", qindex, err);
|
||||||
|
pool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq->xsk_pool = pool;
|
||||||
|
|
||||||
|
virtnet_tx_resume(vi, sq);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int virtnet_xsk_pool_enable(struct net_device *dev,
|
static int virtnet_xsk_pool_enable(struct net_device *dev,
|
||||||
struct xsk_buff_pool *pool,
|
struct xsk_buff_pool *pool,
|
||||||
u16 qid)
|
u16 qid)
|
||||||
@@ -5564,6 +5593,7 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,
|
|||||||
struct receive_queue *rq;
|
struct receive_queue *rq;
|
||||||
struct device *dma_dev;
|
struct device *dma_dev;
|
||||||
struct send_queue *sq;
|
struct send_queue *sq;
|
||||||
|
dma_addr_t hdr_dma;
|
||||||
int err, size;
|
int err, size;
|
||||||
|
|
||||||
if (vi->hdr_len > xsk_pool_get_headroom(pool))
|
if (vi->hdr_len > xsk_pool_get_headroom(pool))
|
||||||
@@ -5601,6 +5631,13 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,
|
|||||||
if (!rq->xsk_buffs)
|
if (!rq->xsk_buffs)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hdr_dma = virtqueue_dma_map_single_attrs(sq->vq, &xsk_hdr, vi->hdr_len,
|
||||||
|
DMA_TO_DEVICE, 0);
|
||||||
|
if (virtqueue_dma_mapping_error(sq->vq, hdr_dma)) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_free_buffs;
|
||||||
|
}
|
||||||
|
|
||||||
err = xsk_pool_dma_map(pool, dma_dev, 0);
|
err = xsk_pool_dma_map(pool, dma_dev, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_xsk_map;
|
goto err_xsk_map;
|
||||||
@@ -5609,11 +5646,26 @@ static int virtnet_xsk_pool_enable(struct net_device *dev,
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_rq;
|
goto err_rq;
|
||||||
|
|
||||||
|
err = virtnet_sq_bind_xsk_pool(vi, sq, pool);
|
||||||
|
if (err)
|
||||||
|
goto err_sq;
|
||||||
|
|
||||||
|
/* Now, we do not support tx offload(such as tx csum), so all the tx
|
||||||
|
* virtnet hdr is zero. So all the tx packets can share a single hdr.
|
||||||
|
*/
|
||||||
|
sq->xsk_hdr_dma_addr = hdr_dma;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_sq:
|
||||||
|
virtnet_rq_bind_xsk_pool(vi, rq, NULL);
|
||||||
err_rq:
|
err_rq:
|
||||||
xsk_pool_dma_unmap(pool, 0);
|
xsk_pool_dma_unmap(pool, 0);
|
||||||
err_xsk_map:
|
err_xsk_map:
|
||||||
|
virtqueue_dma_unmap_single_attrs(rq->vq, hdr_dma, vi->hdr_len,
|
||||||
|
DMA_TO_DEVICE, 0);
|
||||||
|
err_free_buffs:
|
||||||
|
kvfree(rq->xsk_buffs);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5622,19 +5674,24 @@ static int virtnet_xsk_pool_disable(struct net_device *dev, u16 qid)
|
|||||||
struct virtnet_info *vi = netdev_priv(dev);
|
struct virtnet_info *vi = netdev_priv(dev);
|
||||||
struct xsk_buff_pool *pool;
|
struct xsk_buff_pool *pool;
|
||||||
struct receive_queue *rq;
|
struct receive_queue *rq;
|
||||||
|
struct send_queue *sq;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (qid >= vi->curr_queue_pairs)
|
if (qid >= vi->curr_queue_pairs)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
sq = &vi->sq[qid];
|
||||||
rq = &vi->rq[qid];
|
rq = &vi->rq[qid];
|
||||||
|
|
||||||
pool = rq->xsk_pool;
|
pool = rq->xsk_pool;
|
||||||
|
|
||||||
err = virtnet_rq_bind_xsk_pool(vi, rq, NULL);
|
err = virtnet_rq_bind_xsk_pool(vi, rq, NULL);
|
||||||
|
err |= virtnet_sq_bind_xsk_pool(vi, sq, NULL);
|
||||||
|
|
||||||
xsk_pool_dma_unmap(pool, 0);
|
xsk_pool_dma_unmap(pool, 0);
|
||||||
|
|
||||||
|
virtqueue_dma_unmap_single_attrs(sq->vq, sq->xsk_hdr_dma_addr,
|
||||||
|
vi->hdr_len, DMA_TO_DEVICE, 0);
|
||||||
kvfree(rq->xsk_buffs);
|
kvfree(rq->xsk_buffs);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
|
|||||||
|
|
||||||
pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
|
pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
|
||||||
if (pdev && pci_num_vf(pdev)) {
|
if (pdev && pci_num_vf(pdev)) {
|
||||||
pci_dev_put(pdev);
|
|
||||||
rc = -EBUSY;
|
rc = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1658,14 +1658,14 @@ static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
|
|||||||
{
|
{
|
||||||
struct vm_area_struct *vma = vmf->vma;
|
struct vm_area_struct *vma = vmf->vma;
|
||||||
struct vfio_pci_core_device *vdev = vma->vm_private_data;
|
struct vfio_pci_core_device *vdev = vma->vm_private_data;
|
||||||
unsigned long pfn, pgoff = vmf->pgoff - vma->vm_pgoff;
|
unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
|
||||||
|
unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
|
||||||
|
unsigned long pfn = vma_to_pfn(vma) + pgoff;
|
||||||
vm_fault_t ret = VM_FAULT_SIGBUS;
|
vm_fault_t ret = VM_FAULT_SIGBUS;
|
||||||
|
|
||||||
pfn = vma_to_pfn(vma) + pgoff;
|
if (order && (addr < vma->vm_start ||
|
||||||
|
addr + (PAGE_SIZE << order) > vma->vm_end ||
|
||||||
if (order && (pfn & ((1 << order) - 1) ||
|
pfn & ((1 << order) - 1))) {
|
||||||
vmf->address & ((PAGE_SIZE << order) - 1) ||
|
|
||||||
vmf->address + (PAGE_SIZE << order) > vma->vm_end)) {
|
|
||||||
ret = VM_FAULT_FALLBACK;
|
ret = VM_FAULT_FALLBACK;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-90
@@ -732,82 +732,6 @@ const u8 *btrfs_sb_fsid_ptr(const struct btrfs_super_block *sb)
|
|||||||
return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
|
return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We can have very weird soft links passed in.
|
|
||||||
* One example is "/proc/self/fd/<fd>", which can be a soft link to
|
|
||||||
* a block device.
|
|
||||||
*
|
|
||||||
* But it's never a good idea to use those weird names.
|
|
||||||
* Here we check if the path (not following symlinks) is a good one inside
|
|
||||||
* "/dev/".
|
|
||||||
*/
|
|
||||||
static bool is_good_dev_path(const char *dev_path)
|
|
||||||
{
|
|
||||||
struct path path = { .mnt = NULL, .dentry = NULL };
|
|
||||||
char *path_buf = NULL;
|
|
||||||
char *resolved_path;
|
|
||||||
bool is_good = false;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!dev_path)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
|
|
||||||
if (!path_buf)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not follow soft link, just check if the original path is inside
|
|
||||||
* "/dev/".
|
|
||||||
*/
|
|
||||||
ret = kern_path(dev_path, 0, &path);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
resolved_path = d_path(&path, path_buf, PATH_MAX);
|
|
||||||
if (IS_ERR(resolved_path))
|
|
||||||
goto out;
|
|
||||||
if (strncmp(resolved_path, "/dev/", strlen("/dev/")))
|
|
||||||
goto out;
|
|
||||||
is_good = true;
|
|
||||||
out:
|
|
||||||
kfree(path_buf);
|
|
||||||
path_put(&path);
|
|
||||||
return is_good;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_canonical_dev_path(const char *dev_path, char *canonical)
|
|
||||||
{
|
|
||||||
struct path path = { .mnt = NULL, .dentry = NULL };
|
|
||||||
char *path_buf = NULL;
|
|
||||||
char *resolved_path;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!dev_path) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
|
|
||||||
if (!path_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kern_path(dev_path, LOOKUP_FOLLOW, &path);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
resolved_path = d_path(&path, path_buf, PATH_MAX);
|
|
||||||
if (IS_ERR(resolved_path)) {
|
|
||||||
ret = PTR_ERR(resolved_path);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = strscpy(canonical, resolved_path, PATH_MAX);
|
|
||||||
out:
|
|
||||||
kfree(path_buf);
|
|
||||||
path_put(&path);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_same_device(struct btrfs_device *device, const char *new_path)
|
static bool is_same_device(struct btrfs_device *device, const char *new_path)
|
||||||
{
|
{
|
||||||
struct path old = { .mnt = NULL, .dentry = NULL };
|
struct path old = { .mnt = NULL, .dentry = NULL };
|
||||||
@@ -1495,23 +1419,12 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
|
|||||||
bool new_device_added = false;
|
bool new_device_added = false;
|
||||||
struct btrfs_device *device = NULL;
|
struct btrfs_device *device = NULL;
|
||||||
struct file *bdev_file;
|
struct file *bdev_file;
|
||||||
char *canonical_path = NULL;
|
|
||||||
u64 bytenr;
|
u64 bytenr;
|
||||||
dev_t devt;
|
dev_t devt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
lockdep_assert_held(&uuid_mutex);
|
lockdep_assert_held(&uuid_mutex);
|
||||||
|
|
||||||
if (!is_good_dev_path(path)) {
|
|
||||||
canonical_path = kmalloc(PATH_MAX, GFP_KERNEL);
|
|
||||||
if (canonical_path) {
|
|
||||||
ret = get_canonical_dev_path(path, canonical_path);
|
|
||||||
if (ret < 0) {
|
|
||||||
kfree(canonical_path);
|
|
||||||
canonical_path = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Avoid an exclusive open here, as the systemd-udev may initiate the
|
* Avoid an exclusive open here, as the systemd-udev may initiate the
|
||||||
* device scan which may race with the user's mount or mkfs command,
|
* device scan which may race with the user's mount or mkfs command,
|
||||||
@@ -1556,8 +1469,7 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
|
|||||||
goto free_disk_super;
|
goto free_disk_super;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = device_list_add(canonical_path ? : path, disk_super,
|
device = device_list_add(path, disk_super, &new_device_added);
|
||||||
&new_device_added);
|
|
||||||
if (!IS_ERR(device) && new_device_added)
|
if (!IS_ERR(device) && new_device_added)
|
||||||
btrfs_free_stale_devices(device->devt, device);
|
btrfs_free_stale_devices(device->devt, device);
|
||||||
|
|
||||||
@@ -1566,7 +1478,6 @@ free_disk_super:
|
|||||||
|
|
||||||
error_bdev_put:
|
error_bdev_put:
|
||||||
fput(bdev_file);
|
fput(bdev_file);
|
||||||
kfree(canonical_path);
|
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -150,10 +150,10 @@ io_retry:
|
|||||||
io->rq->bio.bi_iter.bi_sector = io->dev.m_pa >> 9;
|
io->rq->bio.bi_iter.bi_sector = io->dev.m_pa >> 9;
|
||||||
attached = 0;
|
attached = 0;
|
||||||
}
|
}
|
||||||
if (!attached++)
|
|
||||||
erofs_onlinefolio_split(folio);
|
|
||||||
if (!bio_add_folio(&io->rq->bio, folio, len, cur))
|
if (!bio_add_folio(&io->rq->bio, folio, len, cur))
|
||||||
goto io_retry;
|
goto io_retry;
|
||||||
|
if (!attached++)
|
||||||
|
erofs_onlinefolio_split(folio);
|
||||||
io->dev.m_pa += len;
|
io->dev.m_pa += len;
|
||||||
}
|
}
|
||||||
cur += len;
|
cur += len;
|
||||||
|
|||||||
@@ -1496,7 +1496,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
|
|||||||
|
|
||||||
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
|
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
|
||||||
sizeof(struct create_lease_v2) - 4)
|
sizeof(struct create_lease_v2) - 4)
|
||||||
return NULL;
|
goto err_out;
|
||||||
|
|
||||||
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
|
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
|
||||||
lreq->req_state = lc->lcontext.LeaseState;
|
lreq->req_state = lc->lcontext.LeaseState;
|
||||||
@@ -1512,7 +1512,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
|
|||||||
|
|
||||||
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
|
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
|
||||||
sizeof(struct create_lease))
|
sizeof(struct create_lease))
|
||||||
return NULL;
|
goto err_out;
|
||||||
|
|
||||||
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
|
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
|
||||||
lreq->req_state = lc->lcontext.LeaseState;
|
lreq->req_state = lc->lcontext.LeaseState;
|
||||||
@@ -1521,6 +1521,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
|
|||||||
lreq->version = 1;
|
lreq->version = 1;
|
||||||
}
|
}
|
||||||
return lreq;
|
return lreq;
|
||||||
|
err_out:
|
||||||
|
kfree(lreq);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -633,6 +633,11 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*name == '\0') {
|
||||||
|
kfree(name);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (*name == '\\') {
|
if (*name == '\\') {
|
||||||
pr_err("not allow directory name included leading slash\n");
|
pr_err("not allow directory name included leading slash\n");
|
||||||
kfree(name);
|
kfree(name);
|
||||||
|
|||||||
@@ -443,6 +443,13 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v_len <= *pos) {
|
||||||
|
pr_err("stream write position %lld is out of bounds (stream length: %zd)\n",
|
||||||
|
*pos, v_len);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (v_len < size) {
|
if (v_len < size) {
|
||||||
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
|
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
|
||||||
if (!wbuf) {
|
if (!wbuf) {
|
||||||
|
|||||||
@@ -661,21 +661,40 @@ __close_file_table_ids(struct ksmbd_file_table *ft,
|
|||||||
bool (*skip)(struct ksmbd_tree_connect *tcon,
|
bool (*skip)(struct ksmbd_tree_connect *tcon,
|
||||||
struct ksmbd_file *fp))
|
struct ksmbd_file *fp))
|
||||||
{
|
{
|
||||||
unsigned int id;
|
struct ksmbd_file *fp;
|
||||||
struct ksmbd_file *fp;
|
unsigned int id = 0;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
idr_for_each_entry(ft->idr, fp, id) {
|
while (1) {
|
||||||
if (skip(tcon, fp))
|
write_lock(&ft->lock);
|
||||||
|
fp = idr_get_next(ft->idr, &id);
|
||||||
|
if (!fp) {
|
||||||
|
write_unlock(&ft->lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip(tcon, fp) ||
|
||||||
|
!atomic_dec_and_test(&fp->refcount)) {
|
||||||
|
id++;
|
||||||
|
write_unlock(&ft->lock);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
set_close_state_blocked_works(fp);
|
set_close_state_blocked_works(fp);
|
||||||
|
idr_remove(ft->idr, fp->volatile_id);
|
||||||
|
fp->volatile_id = KSMBD_NO_FID;
|
||||||
|
write_unlock(&ft->lock);
|
||||||
|
|
||||||
|
down_write(&fp->f_ci->m_lock);
|
||||||
|
list_del_init(&fp->node);
|
||||||
|
up_write(&fp->f_ci->m_lock);
|
||||||
|
|
||||||
if (!atomic_dec_and_test(&fp->refcount))
|
|
||||||
continue;
|
|
||||||
__ksmbd_close_fd(ft, fp);
|
__ksmbd_close_fd(ft, fp);
|
||||||
|
|
||||||
num++;
|
num++;
|
||||||
|
id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1524,7 +1524,7 @@ struct ieee80211_mgmt {
|
|||||||
struct {
|
struct {
|
||||||
u8 action_code;
|
u8 action_code;
|
||||||
u8 dialog_token;
|
u8 dialog_token;
|
||||||
u8 status_code;
|
__le16 status_code;
|
||||||
u8 variable[];
|
u8 variable[];
|
||||||
} __packed ttlm_res;
|
} __packed ttlm_res;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
+91
-60
@@ -130,7 +130,7 @@ struct cgw_job {
|
|||||||
u32 handled_frames;
|
u32 handled_frames;
|
||||||
u32 dropped_frames;
|
u32 dropped_frames;
|
||||||
u32 deleted_frames;
|
u32 deleted_frames;
|
||||||
struct cf_mod mod;
|
struct cf_mod __rcu *cf_mod;
|
||||||
union {
|
union {
|
||||||
/* CAN frame data source */
|
/* CAN frame data source */
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
@@ -459,6 +459,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
|
|||||||
struct cgw_job *gwj = (struct cgw_job *)data;
|
struct cgw_job *gwj = (struct cgw_job *)data;
|
||||||
struct canfd_frame *cf;
|
struct canfd_frame *cf;
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
|
struct cf_mod *mod;
|
||||||
int modidx = 0;
|
int modidx = 0;
|
||||||
|
|
||||||
/* process strictly Classic CAN or CAN FD frames */
|
/* process strictly Classic CAN or CAN FD frames */
|
||||||
@@ -506,7 +507,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
|
|||||||
* When there is at least one modification function activated,
|
* When there is at least one modification function activated,
|
||||||
* we need to copy the skb as we want to modify skb->data.
|
* we need to copy the skb as we want to modify skb->data.
|
||||||
*/
|
*/
|
||||||
if (gwj->mod.modfunc[0])
|
mod = rcu_dereference(gwj->cf_mod);
|
||||||
|
if (mod->modfunc[0])
|
||||||
nskb = skb_copy(skb, GFP_ATOMIC);
|
nskb = skb_copy(skb, GFP_ATOMIC);
|
||||||
else
|
else
|
||||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||||
@@ -529,8 +531,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
|
|||||||
cf = (struct canfd_frame *)nskb->data;
|
cf = (struct canfd_frame *)nskb->data;
|
||||||
|
|
||||||
/* perform preprocessed modification functions if there are any */
|
/* perform preprocessed modification functions if there are any */
|
||||||
while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
|
while (modidx < MAX_MODFUNCTIONS && mod->modfunc[modidx])
|
||||||
(*gwj->mod.modfunc[modidx++])(cf, &gwj->mod);
|
(*mod->modfunc[modidx++])(cf, mod);
|
||||||
|
|
||||||
/* Has the CAN frame been modified? */
|
/* Has the CAN frame been modified? */
|
||||||
if (modidx) {
|
if (modidx) {
|
||||||
@@ -546,11 +548,11 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check for checksum updates */
|
/* check for checksum updates */
|
||||||
if (gwj->mod.csumfunc.crc8)
|
if (mod->csumfunc.crc8)
|
||||||
(*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
|
(*mod->csumfunc.crc8)(cf, &mod->csum.crc8);
|
||||||
|
|
||||||
if (gwj->mod.csumfunc.xor)
|
if (mod->csumfunc.xor)
|
||||||
(*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
|
(*mod->csumfunc.xor)(cf, &mod->csum.xor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the skb timestamp if not configured the other way */
|
/* clear the skb timestamp if not configured the other way */
|
||||||
@@ -581,9 +583,20 @@ static void cgw_job_free_rcu(struct rcu_head *rcu_head)
|
|||||||
{
|
{
|
||||||
struct cgw_job *gwj = container_of(rcu_head, struct cgw_job, rcu);
|
struct cgw_job *gwj = container_of(rcu_head, struct cgw_job, rcu);
|
||||||
|
|
||||||
|
/* cgw_job::cf_mod is always accessed from the same cgw_job object within
|
||||||
|
* the same RCU read section. Once cgw_job is scheduled for removal,
|
||||||
|
* cf_mod can also be removed without mandating an additional grace period.
|
||||||
|
*/
|
||||||
|
kfree(rcu_access_pointer(gwj->cf_mod));
|
||||||
kmem_cache_free(cgw_cache, gwj);
|
kmem_cache_free(cgw_cache, gwj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return cgw_job::cf_mod with RTNL protected section */
|
||||||
|
static struct cf_mod *cgw_job_cf_mod(struct cgw_job *gwj)
|
||||||
|
{
|
||||||
|
return rcu_dereference_protected(gwj->cf_mod, rtnl_is_locked());
|
||||||
|
}
|
||||||
|
|
||||||
static int cgw_notifier(struct notifier_block *nb,
|
static int cgw_notifier(struct notifier_block *nb,
|
||||||
unsigned long msg, void *ptr)
|
unsigned long msg, void *ptr)
|
||||||
{
|
{
|
||||||
@@ -616,6 +629,7 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
|
|||||||
{
|
{
|
||||||
struct rtcanmsg *rtcan;
|
struct rtcanmsg *rtcan;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
|
struct cf_mod *mod;
|
||||||
|
|
||||||
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtcan), flags);
|
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtcan), flags);
|
||||||
if (!nlh)
|
if (!nlh)
|
||||||
@@ -650,82 +664,83 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
|
|||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod = cgw_job_cf_mod(gwj);
|
||||||
if (gwj->flags & CGW_FLAGS_CAN_FD) {
|
if (gwj->flags & CGW_FLAGS_CAN_FD) {
|
||||||
struct cgw_fdframe_mod mb;
|
struct cgw_fdframe_mod mb;
|
||||||
|
|
||||||
if (gwj->mod.modtype.and) {
|
if (mod->modtype.and) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.and, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.and;
|
mb.modtype = mod->modtype.and;
|
||||||
if (nla_put(skb, CGW_FDMOD_AND, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_FDMOD_AND, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.or) {
|
if (mod->modtype.or) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.or, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.or;
|
mb.modtype = mod->modtype.or;
|
||||||
if (nla_put(skb, CGW_FDMOD_OR, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_FDMOD_OR, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.xor) {
|
if (mod->modtype.xor) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.xor, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.xor;
|
mb.modtype = mod->modtype.xor;
|
||||||
if (nla_put(skb, CGW_FDMOD_XOR, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_FDMOD_XOR, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.set) {
|
if (mod->modtype.set) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.set, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.set;
|
mb.modtype = mod->modtype.set;
|
||||||
if (nla_put(skb, CGW_FDMOD_SET, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_FDMOD_SET, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct cgw_frame_mod mb;
|
struct cgw_frame_mod mb;
|
||||||
|
|
||||||
if (gwj->mod.modtype.and) {
|
if (mod->modtype.and) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.and, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.and;
|
mb.modtype = mod->modtype.and;
|
||||||
if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.or) {
|
if (mod->modtype.or) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.or, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.or;
|
mb.modtype = mod->modtype.or;
|
||||||
if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.xor) {
|
if (mod->modtype.xor) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.xor, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.xor;
|
mb.modtype = mod->modtype.xor;
|
||||||
if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.modtype.set) {
|
if (mod->modtype.set) {
|
||||||
memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
|
memcpy(&mb.cf, &mod->modframe.set, sizeof(mb.cf));
|
||||||
mb.modtype = gwj->mod.modtype.set;
|
mb.modtype = mod->modtype.set;
|
||||||
if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
|
if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.uid) {
|
if (mod->uid) {
|
||||||
if (nla_put_u32(skb, CGW_MOD_UID, gwj->mod.uid) < 0)
|
if (nla_put_u32(skb, CGW_MOD_UID, mod->uid) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.csumfunc.crc8) {
|
if (mod->csumfunc.crc8) {
|
||||||
if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN,
|
if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN,
|
||||||
&gwj->mod.csum.crc8) < 0)
|
&mod->csum.crc8) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gwj->mod.csumfunc.xor) {
|
if (mod->csumfunc.xor) {
|
||||||
if (nla_put(skb, CGW_CS_XOR, CGW_CS_XOR_LEN,
|
if (nla_put(skb, CGW_CS_XOR, CGW_CS_XOR_LEN,
|
||||||
&gwj->mod.csum.xor) < 0)
|
&mod->csum.xor) < 0)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,7 +1074,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
struct rtcanmsg *r;
|
struct rtcanmsg *r;
|
||||||
struct cgw_job *gwj;
|
struct cgw_job *gwj;
|
||||||
struct cf_mod mod;
|
struct cf_mod *mod;
|
||||||
struct can_can_gw ccgw;
|
struct can_can_gw ccgw;
|
||||||
u8 limhops = 0;
|
u8 limhops = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@@ -1078,37 +1093,48 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
if (r->gwtype != CGW_TYPE_CAN_CAN)
|
if (r->gwtype != CGW_TYPE_CAN_CAN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = cgw_parse_attr(nlh, &mod, CGW_TYPE_CAN_CAN, &ccgw, &limhops);
|
mod = kmalloc(sizeof(*mod), GFP_KERNEL);
|
||||||
if (err < 0)
|
if (!mod)
|
||||||
return err;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (mod.uid) {
|
err = cgw_parse_attr(nlh, mod, CGW_TYPE_CAN_CAN, &ccgw, &limhops);
|
||||||
|
if (err < 0)
|
||||||
|
goto out_free_cf;
|
||||||
|
|
||||||
|
if (mod->uid) {
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
/* check for updating an existing job with identical uid */
|
/* check for updating an existing job with identical uid */
|
||||||
hlist_for_each_entry(gwj, &net->can.cgw_list, list) {
|
hlist_for_each_entry(gwj, &net->can.cgw_list, list) {
|
||||||
if (gwj->mod.uid != mod.uid)
|
struct cf_mod *old_cf;
|
||||||
|
|
||||||
|
old_cf = cgw_job_cf_mod(gwj);
|
||||||
|
if (old_cf->uid != mod->uid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* interfaces & filters must be identical */
|
/* interfaces & filters must be identical */
|
||||||
if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
|
if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw))) {
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto out_free_cf;
|
||||||
|
}
|
||||||
|
|
||||||
/* update modifications with disabled softirq & quit */
|
rcu_assign_pointer(gwj->cf_mod, mod);
|
||||||
local_bh_disable();
|
kfree_rcu_mightsleep(old_cf);
|
||||||
memcpy(&gwj->mod, &mod, sizeof(mod));
|
|
||||||
local_bh_enable();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ifindex == 0 is not allowed for job creation */
|
/* ifindex == 0 is not allowed for job creation */
|
||||||
if (!ccgw.src_idx || !ccgw.dst_idx)
|
if (!ccgw.src_idx || !ccgw.dst_idx) {
|
||||||
return -ENODEV;
|
err = -ENODEV;
|
||||||
|
goto out_free_cf;
|
||||||
|
}
|
||||||
|
|
||||||
gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL);
|
gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL);
|
||||||
if (!gwj)
|
if (!gwj) {
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
goto out_free_cf;
|
||||||
|
}
|
||||||
|
|
||||||
gwj->handled_frames = 0;
|
gwj->handled_frames = 0;
|
||||||
gwj->dropped_frames = 0;
|
gwj->dropped_frames = 0;
|
||||||
@@ -1118,7 +1144,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
gwj->limit_hops = limhops;
|
gwj->limit_hops = limhops;
|
||||||
|
|
||||||
/* insert already parsed information */
|
/* insert already parsed information */
|
||||||
memcpy(&gwj->mod, &mod, sizeof(mod));
|
RCU_INIT_POINTER(gwj->cf_mod, mod);
|
||||||
memcpy(&gwj->ccgw, &ccgw, sizeof(ccgw));
|
memcpy(&gwj->ccgw, &ccgw, sizeof(ccgw));
|
||||||
|
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
@@ -1152,9 +1178,11 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
if (!err)
|
if (!err)
|
||||||
hlist_add_head_rcu(&gwj->list, &net->can.cgw_list);
|
hlist_add_head_rcu(&gwj->list, &net->can.cgw_list);
|
||||||
out:
|
out:
|
||||||
if (err)
|
if (err) {
|
||||||
kmem_cache_free(cgw_cache, gwj);
|
kmem_cache_free(cgw_cache, gwj);
|
||||||
|
out_free_cf:
|
||||||
|
kfree(mod);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1214,19 +1242,22 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
|
|
||||||
/* remove only the first matching entry */
|
/* remove only the first matching entry */
|
||||||
hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
|
hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
|
||||||
|
struct cf_mod *cf_mod;
|
||||||
|
|
||||||
if (gwj->flags != r->flags)
|
if (gwj->flags != r->flags)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (gwj->limit_hops != limhops)
|
if (gwj->limit_hops != limhops)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
cf_mod = cgw_job_cf_mod(gwj);
|
||||||
/* we have a match when uid is enabled and identical */
|
/* we have a match when uid is enabled and identical */
|
||||||
if (gwj->mod.uid || mod.uid) {
|
if (cf_mod->uid || mod.uid) {
|
||||||
if (gwj->mod.uid != mod.uid)
|
if (cf_mod->uid != mod.uid)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* no uid => check for identical modifications */
|
/* no uid => check for identical modifications */
|
||||||
if (memcmp(&gwj->mod, &mod, sizeof(mod)))
|
if (memcmp(cf_mod, &mod, sizeof(mod)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -3259,16 +3259,13 @@ static void add_v4_addrs(struct inet6_dev *idev)
|
|||||||
struct in6_addr addr;
|
struct in6_addr addr;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct net *net = dev_net(idev->dev);
|
struct net *net = dev_net(idev->dev);
|
||||||
int scope, plen, offset = 0;
|
int scope, plen;
|
||||||
u32 pflags = 0;
|
u32 pflags = 0;
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(struct in6_addr));
|
memset(&addr, 0, sizeof(struct in6_addr));
|
||||||
/* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */
|
memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
|
||||||
if (idev->dev->addr_len == sizeof(struct in6_addr))
|
|
||||||
offset = sizeof(struct in6_addr) - 4;
|
|
||||||
memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
|
|
||||||
|
|
||||||
if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
|
if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
|
||||||
scope = IPV6_ADDR_COMPATv4;
|
scope = IPV6_ADDR_COMPATv4;
|
||||||
@@ -3579,7 +3576,13 @@ static void addrconf_gre_config(struct net_device *dev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->type == ARPHRD_ETHER) {
|
/* Generate the IPv6 link-local address using addrconf_addr_gen(),
|
||||||
|
* unless we have an IPv4 GRE device not bound to an IP address and
|
||||||
|
* which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this
|
||||||
|
* case). Such devices fall back to add_v4_addrs() instead.
|
||||||
|
*/
|
||||||
|
if (!(dev->type == ARPHRD_IPGRE && *(__be32 *)dev->dev_addr == 0 &&
|
||||||
|
idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)) {
|
||||||
addrconf_addr_gen(idev, true);
|
addrconf_addr_gen(idev, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -7177,6 +7177,7 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
|
|||||||
int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res);
|
int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res);
|
||||||
int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 +
|
int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 +
|
||||||
2 * 2 * IEEE80211_TTLM_NUM_TIDS;
|
2 * 2 * IEEE80211_TTLM_NUM_TIDS;
|
||||||
|
u16 status_code;
|
||||||
|
|
||||||
skb = dev_alloc_skb(local->tx_headroom + hdr_len + ttlm_max_len);
|
skb = dev_alloc_skb(local->tx_headroom + hdr_len + ttlm_max_len);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
@@ -7199,19 +7200,18 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
|
|||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case NEG_TTLM_RES_REJECT:
|
case NEG_TTLM_RES_REJECT:
|
||||||
mgmt->u.action.u.ttlm_res.status_code =
|
status_code = WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING;
|
||||||
WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING;
|
|
||||||
break;
|
break;
|
||||||
case NEG_TTLM_RES_ACCEPT:
|
case NEG_TTLM_RES_ACCEPT:
|
||||||
mgmt->u.action.u.ttlm_res.status_code = WLAN_STATUS_SUCCESS;
|
status_code = WLAN_STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
case NEG_TTLM_RES_SUGGEST_PREFERRED:
|
case NEG_TTLM_RES_SUGGEST_PREFERRED:
|
||||||
mgmt->u.action.u.ttlm_res.status_code =
|
status_code = WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED;
|
||||||
WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED;
|
|
||||||
ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm);
|
ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgmt->u.action.u.ttlm_res.status_code = cpu_to_le16(status_code);
|
||||||
ieee80211_tx_skb(sdata, skb);
|
ieee80211_tx_skb(sdata, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7377,7 +7377,7 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
|
|||||||
* This can be better implemented in the future, to handle request
|
* This can be better implemented in the future, to handle request
|
||||||
* rejections.
|
* rejections.
|
||||||
*/
|
*/
|
||||||
if (mgmt->u.action.u.ttlm_res.status_code != WLAN_STATUS_SUCCESS)
|
if (le16_to_cpu(mgmt->u.action.u.ttlm_res.status_code) != WLAN_STATUS_SUCCESS)
|
||||||
__ieee80211_disconnect(sdata);
|
__ieee80211_disconnect(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -975,8 +975,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
|||||||
upcall.cmd = OVS_PACKET_CMD_ACTION;
|
upcall.cmd = OVS_PACKET_CMD_ACTION;
|
||||||
upcall.mru = OVS_CB(skb)->mru;
|
upcall.mru = OVS_CB(skb)->mru;
|
||||||
|
|
||||||
for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
|
nla_for_each_nested(a, attr, rem) {
|
||||||
a = nla_next(a, &rem)) {
|
|
||||||
switch (nla_type(a)) {
|
switch (nla_type(a)) {
|
||||||
case OVS_USERSPACE_ATTR_USERDATA:
|
case OVS_USERSPACE_ATTR_USERDATA:
|
||||||
upcall.userdata = a;
|
upcall.userdata = a;
|
||||||
|
|||||||
+6
-9
@@ -348,7 +348,8 @@ static void htb_add_to_wait_tree(struct htb_sched *q,
|
|||||||
*/
|
*/
|
||||||
static inline void htb_next_rb_node(struct rb_node **n)
|
static inline void htb_next_rb_node(struct rb_node **n)
|
||||||
{
|
{
|
||||||
*n = rb_next(*n);
|
if (*n)
|
||||||
|
*n = rb_next(*n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -609,8 +610,8 @@ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl)
|
|||||||
*/
|
*/
|
||||||
static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl)
|
static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl)
|
||||||
{
|
{
|
||||||
WARN_ON(!cl->prio_activity);
|
if (!cl->prio_activity)
|
||||||
|
return;
|
||||||
htb_deactivate_prios(q, cl);
|
htb_deactivate_prios(q, cl);
|
||||||
cl->prio_activity = 0;
|
cl->prio_activity = 0;
|
||||||
}
|
}
|
||||||
@@ -1485,8 +1486,6 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg)
|
|||||||
{
|
{
|
||||||
struct htb_class *cl = (struct htb_class *)arg;
|
struct htb_class *cl = (struct htb_class *)arg;
|
||||||
|
|
||||||
if (!cl->prio_activity)
|
|
||||||
return;
|
|
||||||
htb_deactivate(qdisc_priv(sch), cl);
|
htb_deactivate(qdisc_priv(sch), cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1740,8 +1739,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg,
|
|||||||
if (cl->parent)
|
if (cl->parent)
|
||||||
cl->parent->children--;
|
cl->parent->children--;
|
||||||
|
|
||||||
if (cl->prio_activity)
|
htb_deactivate(q, cl);
|
||||||
htb_deactivate(q, cl);
|
|
||||||
|
|
||||||
if (cl->cmode != HTB_CAN_SEND)
|
if (cl->cmode != HTB_CAN_SEND)
|
||||||
htb_safe_rb_erase(&cl->pq_node,
|
htb_safe_rb_erase(&cl->pq_node,
|
||||||
@@ -1949,8 +1947,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
|||||||
/* turn parent into inner node */
|
/* turn parent into inner node */
|
||||||
qdisc_purge_queue(parent->leaf.q);
|
qdisc_purge_queue(parent->leaf.q);
|
||||||
parent_qdisc = parent->leaf.q;
|
parent_qdisc = parent->leaf.q;
|
||||||
if (parent->prio_activity)
|
htb_deactivate(q, parent);
|
||||||
htb_deactivate(q, parent);
|
|
||||||
|
|
||||||
/* remove from evt list because of level change */
|
/* remove from evt list because of level change */
|
||||||
if (parent->cmode != HTB_CAN_SEND) {
|
if (parent->cmode != HTB_CAN_SEND) {
|
||||||
|
|||||||
Reference in New Issue
Block a user