mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
This is the 4.14.316 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmR14EYACgkQONu9yGCS aT5FaBAAmUwAPNKytdgTNtrVo+mZdK8IQFL3ye+gI60A8DtleJjExE/vnVVrho4k PsWp8QdRuEgCWRWwe3u+59z0o/3Z+PK3L3G6rge/e/oso/FanrSZOHClbaZSfegm iRfj6IqlvAxLaFFPUyci0z5MlKeNj16XtCo64WmDGk+VIBgvYowj5ji0kgBk/JN8 lKpgstPhY88jA6cmLLbN5C5h8pKMOXo2DuQiJXLh3QO1LKO5gU7r1XAGD7yVM6bm LKT7Gi6mXnfsrfntI77h8F6bY8BOr4rgDaSizBVsx0o1DDcaLgk07xP+uM/pzuCx hxiS2g0vi4maR+agO2PkvjDGt3QWDXh1XyqzBH93QJ5OZcoak+UWpbHqqqVjAdmm eJ7GJAaqKDwWn4nLefoJw6kLz3a1MpfNZiFPsTdb5VYml9ilZat/80X1EVBWldgq bXIsBW/ktju/LRbr/HP3FqEhPLV8n5wdEb49qTN7nVx5+jIzZhO0hfiYq7OT5FHb /Ff6qOuFJ37ax50LYQQniXwpT43DBkb5oMElaLX7rQHqd6EPqX6hFpruwyK56m47 TvnezUveh5841XYNBB7d3vneMfB5TB9WWpZ39/1ocmN1A5iUFSNghXG4C4aXNYrY 2KYyk7IN4+rmZwuMjTKmpQ/mACrURT0StFJ/xdwKaMavg6DOa8A= =qekP -----END PGP SIGNATURE----- Merge 4.14.316 into android-4.14-stable Changes in 4.14.316 net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs(). netlink: annotate accesses to nlk->cb_running net: annotate sk->sk_err write from do_recvmmsg() ipvlan:Fix out-of-bounds caused by unclear skb->cb af_unix: Fix a data race of sk->sk_receive_queue->qlen. fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode() regmap: cache: Return error in cache sync operations for REGCACHE_NONE memstick: r592: Fix UAF bug in r592_remove due to race condition ACPI: EC: Fix oops when removing custom query handlers drm/tegra: Avoid potential 32-bit integer overflow ACPICA: Avoid undefined behavior: applying zero offset to null pointer ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in acpi_db_display_objects wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex ext2: Check block size validity during mount net: pasemi: Fix return type of pasemi_mac_start_tx() net: Catch invalid index in XPS mapping lib: cpu_rmap: Avoid use after free on rmap->obj array entries scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race condition gfs2: Fix inode height consistency check ext4: set goal start correctly in ext4_mb_normalize_request ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa() wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp staging: rtl8192e: Replace macro RTL_PCI_DEVICE with PCI_DEVICE HID: logitech-hidpp: Don't use the USB serial for USB devices HID: logitech-hidpp: Reconcile USB and Unifying serials spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3 HID: wacom: generic: Set battery quirk only when we see battery data serial: 8250: Reinit port->pm on port specific driver unbind mcb-pci: Reallocate memory region to avoid memory overlapping sched: Fix KCSAN noinstr violation recordmcount: Fix memory leaks in the uwrite function clk: tegra20: fix gcc-7 constant overflow warning Input: xpad - add constants for GIP interface numbers phy: st: miphy28lp: use _poll_timeout functions for waits mfd: dln2: Fix memory leak in dln2_probe() cpupower: Make TSC read per CPU for Mperf monitor af_key: Reject optional tunnel/BEET mode templates in outbound policies net: fec: Better handle pm_runtime_get() failing in .remove() vsock: avoid to close connected socket after the timeout media: netup_unidvb: fix use-after-free at del_timer() net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment() cassini: Fix a memory leak in the error handling path of cas_init_one() igb: fix bit_shift to be in [1..8] range vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit() usb-storage: fix deadlock when a scsi command timeouts more than once ALSA: hda: Fix Oops by 9.1 surround channel names ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table statfs: enforce statfs[64] structure initialization serial: Add support for Advantech PCI-1611U card ceph: force updating the msg pointer in non-split case nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode() netfilter: nf_tables: bogus EBUSY in helper removal from transaction spi: spi-fsl-spi: automatically adapt bits-per-word in cpu mode spi: fsl-spi: Re-organise transfer bits_per_word adaptation spi: fsl-cpm: Use 16 bit mode for large transfers with even size m68k: Move signal frame following exception on 68020/030 parisc: Allow to reboot machine after system halt netfilter: nftables: add nft_parse_register_load() and use it netfilter: nftables: add nft_parse_register_store() and use it netfilter: nftables: statify nft_parse_register() netfilter: nf_tables: validate registers coming from userspace. netfilter: nf_tables: add nft_setelem_parse_key() netfilter: nf_tables: allow up to 64 bytes in the set element data area netfilter: nf_tables: stricter validation of element data netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL netfilter: nf_tables: do not allow RULE_ID to refer to another chain netfilter: nf_tables: do not allow SET_ID to refer to another table netfilter: nf_tables: fix register ordering x86/mm: Avoid incomplete Global INVLPG flushes selftests/memfd: Fix unknown type name build failure USB: core: Add routines for endpoint checks in old drivers USB: sisusbvga: Add endpoint checks media: radio-shark: Add endpoint checks net: fix skb leak in __skb_tstamp_tx() ipv6: Fix out-of-bounds access in ipv6_find_tlv() power: supply: leds: Fix blink to LED on transition power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition power: supply: bq27xxx: Fix I2C IRQ race on remove power: supply: bq27xxx: Fix poll_interval handling and races on remove power: supply: sbs-charger: Fix INHIBITED bit for Status reg xen/pvcalls-back: fix double frees with pvcalls_new_active_socket() x86/show_trace_log_lvl: Ensure stack pointer is aligned, again forcedeth: Fix an error handling path in nv_probe() 3c589_cs: Fix an error handling path in tc589_probe() Linux 4.14.316 Change-Id: I3057e11d999112040cd36a7715309365928e3c02 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
a1789769b3
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 315
|
||||
SUBLEVEL = 316
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
@ -819,11 +819,17 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
|
||||
}
|
||||
|
||||
static inline void __user *
|
||||
get_sigframe(struct ksignal *ksig, size_t frame_size)
|
||||
get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size)
|
||||
{
|
||||
unsigned long usp = sigsp(rdusp(), ksig);
|
||||
unsigned long gap = 0;
|
||||
|
||||
return (void __user *)((usp - frame_size) & -8UL);
|
||||
if (CPU_IS_020_OR_030 && tregs->format == 0xb) {
|
||||
/* USP is unreliable so use worst-case value */
|
||||
gap = 256;
|
||||
}
|
||||
|
||||
return (void __user *)((usp - gap - frame_size) & -8UL);
|
||||
}
|
||||
|
||||
static int setup_frame(struct ksignal *ksig, sigset_t *set,
|
||||
@ -841,7 +847,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
frame = get_sigframe(ksig, sizeof(*frame) + fsize);
|
||||
frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize);
|
||||
|
||||
if (fsize)
|
||||
err |= copy_to_user (frame + 1, regs + 1, fsize);
|
||||
@ -912,7 +918,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
frame = get_sigframe(ksig, sizeof(*frame));
|
||||
frame = get_sigframe(ksig, tregs, sizeof(*frame));
|
||||
|
||||
if (fsize)
|
||||
err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
|
||||
|
@ -142,13 +142,18 @@ void machine_power_off(void)
|
||||
/* It seems we have no way to power the system off via
|
||||
* software. The user has to press the button himself. */
|
||||
|
||||
printk(KERN_EMERG "System shut down completed.\n"
|
||||
"Please power this system off now.");
|
||||
printk("Power off or press RETURN to reboot.\n");
|
||||
|
||||
/* prevent soft lockup/stalled CPU messages for endless loop. */
|
||||
rcu_sysrq_start();
|
||||
lockup_detector_soft_poweroff();
|
||||
for (;;);
|
||||
while (1) {
|
||||
/* reboot if user presses RETURN key */
|
||||
if (pdc_iodc_getc() == 13) {
|
||||
printk("Rebooting...\n");
|
||||
machine_restart(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void (*pm_power_off)(void) = machine_power_off;
|
||||
|
@ -73,6 +73,11 @@
|
||||
#define INTEL_FAM6_LAKEFIELD 0x8A
|
||||
#define INTEL_FAM6_ALDERLAKE 0x97
|
||||
#define INTEL_FAM6_ALDERLAKE_L 0x9A
|
||||
#define INTEL_FAM6_ALDERLAKE_N 0xBE
|
||||
|
||||
#define INTEL_FAM6_RAPTORLAKE 0xB7
|
||||
#define INTEL_FAM6_RAPTORLAKE_P 0xBA
|
||||
#define INTEL_FAM6_RAPTORLAKE_S 0xBF
|
||||
|
||||
#define INTEL_FAM6_TIGERLAKE_L 0x8C
|
||||
#define INTEL_FAM6_TIGERLAKE 0x8D
|
||||
|
@ -115,7 +115,6 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
||||
printk("%sCall Trace:\n", log_lvl);
|
||||
|
||||
unwind_start(&state, task, regs, stack);
|
||||
stack = stack ? : get_stack_pointer(task, regs);
|
||||
regs = unwind_get_entry_regs(&state, &partial);
|
||||
|
||||
/*
|
||||
@ -134,9 +133,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
||||
* - hardirq stack
|
||||
* - entry stack
|
||||
*/
|
||||
for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) {
|
||||
for (stack = stack ?: get_stack_pointer(task, regs);
|
||||
stack;
|
||||
stack = stack_info.next_sp) {
|
||||
const char *stack_name;
|
||||
|
||||
stack = PTR_ALIGN(stack, sizeof(long));
|
||||
|
||||
if (get_stack_info(stack, task, &stack_info, &visit_mask)) {
|
||||
/*
|
||||
* We weren't on a valid stack. It's possible that
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/swapops.h>
|
||||
|
||||
#include <asm/set_memory.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/init.h>
|
||||
#include <asm/page.h>
|
||||
@ -199,6 +200,24 @@ static void __init probe_page_size_mask(void)
|
||||
}
|
||||
}
|
||||
|
||||
#define INTEL_MATCH(_model) { .vendor = X86_VENDOR_INTEL, \
|
||||
.family = 6, \
|
||||
.model = _model, \
|
||||
}
|
||||
/*
|
||||
* INVLPG may not properly flush Global entries
|
||||
* on these CPUs when PCIDs are enabled.
|
||||
*/
|
||||
static const struct x86_cpu_id invlpg_miss_ids[] = {
|
||||
INTEL_MATCH(INTEL_FAM6_ALDERLAKE ),
|
||||
INTEL_MATCH(INTEL_FAM6_ALDERLAKE_L ),
|
||||
INTEL_MATCH(INTEL_FAM6_ALDERLAKE_N ),
|
||||
INTEL_MATCH(INTEL_FAM6_RAPTORLAKE ),
|
||||
INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_P),
|
||||
INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_S),
|
||||
{}
|
||||
};
|
||||
|
||||
static void setup_pcid(void)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_X86_64))
|
||||
@ -207,6 +226,12 @@ static void setup_pcid(void)
|
||||
if (!boot_cpu_has(X86_FEATURE_PCID))
|
||||
return;
|
||||
|
||||
if (x86_match_cpu(invlpg_miss_ids)) {
|
||||
pr_info("Incomplete global flushes, disabling PCID");
|
||||
setup_clear_cpu_cap(X86_FEATURE_PCID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_PGE)) {
|
||||
/*
|
||||
* This can't be cr4_set_bits_and_update_boot() -- the
|
||||
|
@ -600,6 +600,9 @@ acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
|
||||
object_info =
|
||||
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
|
||||
|
||||
if (!object_info)
|
||||
return (AE_NO_MEMORY);
|
||||
|
||||
/* Walk the namespace from the root */
|
||||
|
||||
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
||||
|
@ -610,9 +610,14 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
|
||||
ACPI_FUNCTION_TRACE(ds_init_aml_walk);
|
||||
|
||||
walk_state->parser_state.aml =
|
||||
walk_state->parser_state.aml_start = aml_start;
|
||||
walk_state->parser_state.aml_end =
|
||||
walk_state->parser_state.pkg_end = aml_start + aml_length;
|
||||
walk_state->parser_state.aml_start =
|
||||
walk_state->parser_state.aml_end =
|
||||
walk_state->parser_state.pkg_end = aml_start;
|
||||
/* Avoid undefined behavior: applying zero offset to null pointer */
|
||||
if (aml_length != 0) {
|
||||
walk_state->parser_state.aml_end += aml_length;
|
||||
walk_state->parser_state.pkg_end += aml_length;
|
||||
}
|
||||
|
||||
/* The next_op of the next_walk will be the beginning of the method */
|
||||
|
||||
|
@ -1135,6 +1135,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
|
||||
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
|
||||
{
|
||||
acpi_ec_remove_query_handlers(ec, false, query_bit);
|
||||
flush_workqueue(ec_query_wq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
|
||||
|
||||
|
@ -347,6 +347,9 @@ int regcache_sync(struct regmap *map)
|
||||
const char *name;
|
||||
bool bypass;
|
||||
|
||||
if (WARN_ON(map->cache_type == REGCACHE_NONE))
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(!map->cache_ops);
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
@ -416,6 +419,9 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
|
||||
const char *name;
|
||||
bool bypass;
|
||||
|
||||
if (WARN_ON(map->cache_type == REGCACHE_NONE))
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(!map->cache_ops);
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
|
@ -27,24 +27,24 @@
|
||||
#include "clk-id.h"
|
||||
|
||||
#define OSC_CTRL 0x50
|
||||
#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
|
||||
#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
|
||||
#define OSC_CTRL_OSC_FREQ_MASK (3u<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30)
|
||||
#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK)
|
||||
|
||||
#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_1 (0<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_2 (1<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_4 (2<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28)
|
||||
#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28)
|
||||
|
||||
#define OSC_FREQ_DET 0x58
|
||||
#define OSC_FREQ_DET_TRIG (1<<31)
|
||||
#define OSC_FREQ_DET_TRIG (1u<<31)
|
||||
|
||||
#define OSC_FREQ_DET_STATUS 0x5c
|
||||
#define OSC_FREQ_DET_BUSY (1<<31)
|
||||
#define OSC_FREQ_DET_CNT_MASK 0xFFFF
|
||||
#define OSC_FREQ_DET_BUSYu (1<<31)
|
||||
#define OSC_FREQ_DET_CNT_MASK 0xFFFFu
|
||||
|
||||
#define TEGRA20_CLK_PERIPH_BANKS 3
|
||||
|
||||
|
@ -709,7 +709,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
|
||||
struct drm_dp_link *link)
|
||||
{
|
||||
const u64 f = 100000, link_rate = link->rate * 1000;
|
||||
const u64 pclk = mode->clock * 1000;
|
||||
const u64 pclk = (u64)mode->clock * 1000;
|
||||
u64 input, output, watermark, num;
|
||||
struct tegra_sor_params params;
|
||||
u32 num_syms_per_line;
|
||||
|
@ -675,8 +675,7 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
|
||||
hdev->product, &serial);
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
|
||||
dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
|
||||
|
||||
name = hidpp_unifying_get_name(hidpp);
|
||||
@ -777,6 +776,54 @@ static bool hidpp_is_connected(struct hidpp_device *hidpp)
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0003: Device Information */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003
|
||||
|
||||
#define CMD_GET_DEVICE_INFO 0x00
|
||||
|
||||
static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial)
|
||||
{
|
||||
struct hidpp_report response;
|
||||
u8 feature_type;
|
||||
u8 feature_index;
|
||||
int ret;
|
||||
|
||||
ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION,
|
||||
&feature_index,
|
||||
&feature_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hidpp_send_fap_command_sync(hidpp, feature_index,
|
||||
CMD_GET_DEVICE_INFO,
|
||||
NULL, 0, &response);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* See hidpp_unifying_get_serial() */
|
||||
*serial = *((u32 *)&response.rap.params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hidpp_serial_init(struct hidpp_device *hidpp)
|
||||
{
|
||||
struct hid_device *hdev = hidpp->hid_dev;
|
||||
u32 serial;
|
||||
int ret;
|
||||
|
||||
ret = hidpp_get_serial(hidpp, &serial);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
|
||||
dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0005: GetDeviceNameType */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -3039,6 +3086,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
|
||||
if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
|
||||
hidpp_unifying_init(hidpp);
|
||||
else if (hid_is_usb(hidpp->hid_dev))
|
||||
hidpp_serial_init(hidpp);
|
||||
|
||||
connected = hidpp_is_connected(hidpp);
|
||||
atomic_set(&hidpp->connected, connected);
|
||||
|
@ -1782,18 +1782,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
|
||||
static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,
|
||||
struct hid_field *field, struct hid_usage *usage)
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
||||
struct wacom_features *features = &wacom_wac->features;
|
||||
unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
|
||||
|
||||
switch (equivalent_usage) {
|
||||
case HID_DG_BATTERYSTRENGTH:
|
||||
case WACOM_HID_WD_BATTERY_LEVEL:
|
||||
case WACOM_HID_WD_BATTERY_CHARGING:
|
||||
features->quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
|
||||
@ -1814,18 +1803,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
}
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
case WACOM_HID_WD_BATTERY_LEVEL:
|
||||
value = value * 100 / (field->logical_maximum - field->logical_minimum);
|
||||
wacom_wac->hid_data.battery_capacity = value;
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
case WACOM_HID_WD_BATTERY_CHARGING:
|
||||
wacom_wac->hid_data.bat_charging = value;
|
||||
wacom_wac->hid_data.ps_connected = value;
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1841,18 +1833,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev,
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
||||
struct wacom_features *features = &wacom_wac->features;
|
||||
|
||||
if (features->quirks & WACOM_QUIRK_BATTERY) {
|
||||
int status = wacom_wac->hid_data.bat_status;
|
||||
int capacity = wacom_wac->hid_data.battery_capacity;
|
||||
bool charging = wacom_wac->hid_data.bat_charging;
|
||||
bool connected = wacom_wac->hid_data.bat_connected;
|
||||
bool powered = wacom_wac->hid_data.ps_connected;
|
||||
int status = wacom_wac->hid_data.bat_status;
|
||||
int capacity = wacom_wac->hid_data.battery_capacity;
|
||||
bool charging = wacom_wac->hid_data.bat_charging;
|
||||
bool connected = wacom_wac->hid_data.bat_connected;
|
||||
bool powered = wacom_wac->hid_data.ps_connected;
|
||||
|
||||
wacom_notify_battery(wacom_wac, status, capacity, charging,
|
||||
connected, powered);
|
||||
}
|
||||
wacom_notify_battery(wacom_wac, status, capacity, charging,
|
||||
connected, powered);
|
||||
}
|
||||
|
||||
static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
|
||||
|
@ -506,6 +506,9 @@ struct xboxone_init_packet {
|
||||
}
|
||||
|
||||
|
||||
#define GIP_WIRED_INTF_DATA 0
|
||||
#define GIP_WIRED_INTF_AUDIO 1
|
||||
|
||||
/*
|
||||
* This packet is required for all Xbox One pads with 2015
|
||||
* or later firmware installed (or present from the factory).
|
||||
@ -1830,7 +1833,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
}
|
||||
|
||||
if (xpad->xtype == XTYPE_XBOXONE &&
|
||||
intf->cur_altsetting->desc.bInterfaceNumber != 0) {
|
||||
intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) {
|
||||
/*
|
||||
* The Xbox One controller lists three interfaces all with the
|
||||
* same interface class, subclass and protocol. Differentiate by
|
||||
|
@ -34,7 +34,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct resource *res;
|
||||
struct priv *priv;
|
||||
int ret;
|
||||
int ret, table_size;
|
||||
unsigned long flags;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
|
||||
@ -93,7 +93,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (ret < 0)
|
||||
goto out_mcb_bus;
|
||||
|
||||
dev_dbg(&pdev->dev, "Found %d cells\n", ret);
|
||||
table_size = ret;
|
||||
|
||||
if (table_size < CHAM_HEADER_SIZE) {
|
||||
/* Release the previous resources */
|
||||
devm_iounmap(&pdev->dev, priv->base);
|
||||
devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
|
||||
|
||||
/* Then, allocate it again with the actual chameleon table size */
|
||||
res = devm_request_mem_region(&pdev->dev, priv->mapbase,
|
||||
table_size,
|
||||
KBUILD_MODNAME);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Failed to request PCI memory\n");
|
||||
ret = -EBUSY;
|
||||
goto out_mcb_bus;
|
||||
}
|
||||
|
||||
priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size);
|
||||
if (!priv->base) {
|
||||
dev_err(&pdev->dev, "Cannot ioremap\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_mcb_bus;
|
||||
}
|
||||
}
|
||||
|
||||
mcb_bus_add_devices(priv->bus);
|
||||
|
||||
|
@ -707,7 +707,7 @@ static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num)
|
||||
netup_unidvb_dma_enable(dma, 0);
|
||||
msleep(50);
|
||||
cancel_work_sync(&dma->work);
|
||||
del_timer(&dma->timeout);
|
||||
del_timer_sync(&dma->timeout);
|
||||
}
|
||||
|
||||
static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev)
|
||||
|
@ -316,6 +316,16 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||
{
|
||||
struct shark_device *shark;
|
||||
int retval = -ENOMEM;
|
||||
static const u8 ep_addresses[] = {
|
||||
SHARK_IN_EP | USB_DIR_IN,
|
||||
SHARK_OUT_EP | USB_DIR_OUT,
|
||||
0};
|
||||
|
||||
/* Are the expected endpoints present? */
|
||||
if (!usb_check_int_endpoints(intf, ep_addresses)) {
|
||||
dev_err(&intf->dev, "Invalid radioSHARK device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
||||
if (!shark)
|
||||
|
@ -282,6 +282,16 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||
{
|
||||
struct shark_device *shark;
|
||||
int retval = -ENOMEM;
|
||||
static const u8 ep_addresses[] = {
|
||||
SHARK_IN_EP | USB_DIR_IN,
|
||||
SHARK_OUT_EP | USB_DIR_OUT,
|
||||
0};
|
||||
|
||||
/* Are the expected endpoints present? */
|
||||
if (!usb_check_int_endpoints(intf, ep_addresses)) {
|
||||
dev_err(&intf->dev, "Invalid radioSHARK2 device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
||||
if (!shark)
|
||||
|
@ -832,7 +832,7 @@ static void r592_remove(struct pci_dev *pdev)
|
||||
/* Stop the processing thread.
|
||||
That ensures that we won't take any more requests */
|
||||
kthread_stop(dev->io_thread);
|
||||
|
||||
del_timer_sync(&dev->detect_timer);
|
||||
r592_enable_device(dev, false);
|
||||
|
||||
while (!error && dev->req) {
|
||||
|
@ -1429,7 +1429,9 @@ mptlan_remove(struct pci_dev *pdev)
|
||||
{
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
struct net_device *dev = ioc->netdev;
|
||||
struct mpt_lan_priv *priv = netdev_priv(dev);
|
||||
|
||||
cancel_delayed_work_sync(&priv->post_buckets_task);
|
||||
if(dev != NULL) {
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
|
@ -804,6 +804,7 @@ out_stop_rx:
|
||||
dln2_stop_rx_urbs(dln2);
|
||||
|
||||
out_free:
|
||||
usb_put_dev(dln2->usb_dev);
|
||||
dln2_free(dln2);
|
||||
|
||||
return ret;
|
||||
|
@ -196,6 +196,7 @@ static int tc589_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct el3_private *lp;
|
||||
struct net_device *dev;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&link->dev, "3c589_attach()\n");
|
||||
|
||||
@ -219,7 +220,15 @@ static int tc589_probe(struct pcmcia_device *link)
|
||||
|
||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||
|
||||
return tc589_config(link);
|
||||
ret = tc589_config(link);
|
||||
if (ret)
|
||||
goto err_free_netdev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_netdev:
|
||||
free_netdev(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tc589_detach(struct pcmcia_device *link)
|
||||
|
@ -3569,7 +3569,9 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to resume device in remove callback (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
cancel_work_sync(&fep->tx_timeout_work);
|
||||
fec_ptp_stop(pdev);
|
||||
@ -3582,8 +3584,13 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(fep->phy_node);
|
||||
|
||||
clk_disable_unprepare(fep->clk_ahb);
|
||||
clk_disable_unprepare(fep->clk_ipg);
|
||||
/* After pm_runtime_get_sync() failed, the clks are still off, so skip
|
||||
* disabling them again.
|
||||
*/
|
||||
if (ret >= 0) {
|
||||
clk_disable_unprepare(fep->clk_ahb);
|
||||
clk_disable_unprepare(fep->clk_ipg);
|
||||
}
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
|
@ -445,7 +445,7 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
|
||||
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 hash_value, hash_mask;
|
||||
u8 bit_shift = 0;
|
||||
u8 bit_shift = 1;
|
||||
|
||||
/* Register count multiplied by bits per register */
|
||||
hash_mask = (hw->mac.mta_reg_count * 32) - 1;
|
||||
@ -453,7 +453,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
|
||||
* where 0xFF would still fall within the hash mask.
|
||||
*/
|
||||
while (hash_mask >> bit_shift != 0xFF)
|
||||
while (hash_mask >> bit_shift != 0xFF && bit_shift < 4)
|
||||
bit_shift++;
|
||||
|
||||
/* The portion of the address that is used for the hash table
|
||||
|
@ -6020,6 +6020,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
|
||||
return 0;
|
||||
|
||||
out_error:
|
||||
nv_mgmt_release_sema(dev);
|
||||
if (phystate_orig)
|
||||
writel(phystate|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
|
||||
out_freering:
|
||||
|
@ -1436,7 +1436,7 @@ static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
|
||||
write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
|
||||
}
|
||||
|
||||
static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_tx_t pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct pasemi_mac * const mac = netdev_priv(dev);
|
||||
struct pasemi_mac_txring * const txring = tx_ring(mac);
|
||||
|
@ -5152,6 +5152,8 @@ err_out_iounmap:
|
||||
cas_shutdown(cp);
|
||||
mutex_unlock(&cp->pm_mutex);
|
||||
|
||||
vfree(cp->fw_data);
|
||||
|
||||
pci_iounmap(pdev, cp->regs);
|
||||
|
||||
|
||||
|
@ -394,6 +394,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
|
||||
goto err;
|
||||
}
|
||||
skb_dst_set(skb, &rt->dst);
|
||||
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
|
||||
err = ip_local_out(net, skb->sk, skb);
|
||||
if (unlikely(net_xmit_eval(err)))
|
||||
dev->stats.tx_errors++;
|
||||
@ -431,6 +434,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
|
||||
goto err;
|
||||
}
|
||||
skb_dst_set(skb, dst);
|
||||
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
|
||||
err = ip6_local_out(net, skb->sk, skb);
|
||||
if (unlikely(net_xmit_eval(err)))
|
||||
dev->stats.tx_errors++;
|
||||
|
@ -1349,13 +1349,14 @@ static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
|
||||
static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
|
||||
{
|
||||
struct brcmf_wsec_pmk_le pmk;
|
||||
int i, err;
|
||||
int err;
|
||||
|
||||
/* convert to firmware key format */
|
||||
pmk.key_len = cpu_to_le16(pmk_len << 1);
|
||||
pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
|
||||
for (i = 0; i < pmk_len; i++)
|
||||
snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
|
||||
memset(&pmk, 0, sizeof(pmk));
|
||||
|
||||
/* pass pmk directly */
|
||||
pmk.key_len = cpu_to_le16(pmk_len);
|
||||
pmk.flags = cpu_to_le16(0);
|
||||
memcpy(pmk.key, pmk_data, pmk_len);
|
||||
|
||||
/* store psk in firmware */
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
|
||||
|
@ -1101,6 +1101,7 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
|
||||
{
|
||||
__le16 key_flags;
|
||||
struct iwl_addsta_cmd sta_cmd;
|
||||
size_t to_copy;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&priv->sta_lock);
|
||||
@ -1120,7 +1121,9 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
|
||||
sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
|
||||
for (i = 0; i < 5; i++)
|
||||
sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
|
||||
memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen);
|
||||
/* keyconf may contain MIC rx/tx keys which iwl does not use */
|
||||
to_copy = min_t(size_t, sizeof(sta_cmd.key.key), keyconf->keylen);
|
||||
memcpy(sta_cmd.key.key, keyconf->key, to_copy);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@ -488,19 +489,11 @@ static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy)
|
||||
|
||||
static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy)
|
||||
{
|
||||
unsigned long finish = jiffies + 5 * HZ;
|
||||
u8 val;
|
||||
|
||||
/* Waiting for Compensation to complete */
|
||||
do {
|
||||
val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6);
|
||||
|
||||
if (time_after_eq(jiffies, finish))
|
||||
return -EBUSY;
|
||||
cpu_relax();
|
||||
} while (!(val & COMP_DONE));
|
||||
|
||||
return 0;
|
||||
return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6,
|
||||
val, val & COMP_DONE, 1, 5 * USEC_PER_SEC);
|
||||
}
|
||||
|
||||
|
||||
@ -809,7 +802,6 @@ static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy)
|
||||
|
||||
static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
|
||||
{
|
||||
unsigned long finish = jiffies + 5 * HZ;
|
||||
u8 mask = HFC_PLL | HFC_RDY;
|
||||
u8 val;
|
||||
|
||||
@ -820,21 +812,14 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
|
||||
if (miphy_phy->type == PHY_TYPE_SATA)
|
||||
mask |= PHY_RDY;
|
||||
|
||||
do {
|
||||
val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1);
|
||||
if ((val & mask) != mask)
|
||||
cpu_relax();
|
||||
else
|
||||
return 0;
|
||||
} while (!time_after_eq(jiffies, finish));
|
||||
|
||||
return -EBUSY;
|
||||
return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1,
|
||||
val, (val & mask) == mask, 1,
|
||||
5 * USEC_PER_SEC);
|
||||
}
|
||||
|
||||
static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
|
||||
{
|
||||
struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
|
||||
unsigned long finish = jiffies + 5 * HZ;
|
||||
u32 val;
|
||||
|
||||
if (!miphy_phy->osc_rdy)
|
||||
@ -843,17 +828,10 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
|
||||
if (!miphy_phy->syscfg_reg[SYSCFG_STATUS])
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
regmap_read(miphy_dev->regmap,
|
||||
miphy_phy->syscfg_reg[SYSCFG_STATUS], &val);
|
||||
|
||||
if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY)
|
||||
cpu_relax();
|
||||
else
|
||||
return 0;
|
||||
} while (!time_after_eq(jiffies, finish));
|
||||
|
||||
return -EBUSY;
|
||||
return regmap_read_poll_timeout(miphy_dev->regmap,
|
||||
miphy_phy->syscfg_reg[SYSCFG_STATUS],
|
||||
val, val & MIPHY_OSC_RDY, 1,
|
||||
5 * USEC_PER_SEC);
|
||||
}
|
||||
|
||||
static int miphy28lp_get_resource_byname(struct device_node *child,
|
||||
|
@ -1506,7 +1506,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
|
||||
return POWER_SUPPLY_HEALTH_GOOD;
|
||||
}
|
||||
|
||||
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
|
||||
static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
|
||||
{
|
||||
struct bq27xxx_reg_cache cache = {0, };
|
||||
bool has_ci_flag = di->opts & BQ27XXX_O_ZERO;
|
||||
@ -1554,6 +1554,16 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
|
||||
di->cache = cache;
|
||||
|
||||
di->last_update = jiffies;
|
||||
|
||||
if (!di->removed && poll_interval > 0)
|
||||
mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
|
||||
}
|
||||
|
||||
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
|
||||
{
|
||||
mutex_lock(&di->lock);
|
||||
bq27xxx_battery_update_unlocked(di);
|
||||
mutex_unlock(&di->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
|
||||
|
||||
@ -1564,9 +1574,6 @@ static void bq27xxx_battery_poll(struct work_struct *work)
|
||||
work.work);
|
||||
|
||||
bq27xxx_battery_update(di);
|
||||
|
||||
if (poll_interval > 0)
|
||||
schedule_delayed_work(&di->work, poll_interval * HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1725,10 +1732,8 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
|
||||
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
|
||||
|
||||
mutex_lock(&di->lock);
|
||||
if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
|
||||
cancel_delayed_work_sync(&di->work);
|
||||
bq27xxx_battery_poll(&di->work.work);
|
||||
}
|
||||
if (time_is_before_jiffies(di->last_update + 5 * HZ))
|
||||
bq27xxx_battery_update_unlocked(di);
|
||||
mutex_unlock(&di->lock);
|
||||
|
||||
if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
|
||||
@ -1865,22 +1870,18 @@ EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);
|
||||
|
||||
void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
|
||||
{
|
||||
/*
|
||||
* power_supply_unregister call bq27xxx_battery_get_property which
|
||||
* call bq27xxx_battery_poll.
|
||||
* Make sure that bq27xxx_battery_poll will not call
|
||||
* schedule_delayed_work again after unregister (which cause OOPS).
|
||||
*/
|
||||
poll_interval = 0;
|
||||
|
||||
cancel_delayed_work_sync(&di->work);
|
||||
|
||||
power_supply_unregister(di->bat);
|
||||
|
||||
mutex_lock(&bq27xxx_list_lock);
|
||||
list_del(&di->list);
|
||||
mutex_unlock(&bq27xxx_list_lock);
|
||||
|
||||
/* Set removed to avoid bq27xxx_battery_update() re-queuing the work */
|
||||
mutex_lock(&di->lock);
|
||||
di->removed = true;
|
||||
mutex_unlock(&di->lock);
|
||||
|
||||
cancel_delayed_work_sync(&di->work);
|
||||
|
||||
power_supply_unregister(di->bat);
|
||||
mutex_destroy(&di->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
|
||||
|
@ -187,7 +187,7 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
||||
i2c_set_clientdata(client, di);
|
||||
|
||||
if (client->irq) {
|
||||
ret = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
ret = request_threaded_irq(client->irq,
|
||||
NULL, bq27xxx_battery_irq_handler_thread,
|
||||
IRQF_ONESHOT,
|
||||
di->name, di);
|
||||
@ -217,6 +217,7 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct bq27xxx_device_info *di = i2c_get_clientdata(client);
|
||||
|
||||
free_irq(client->irq, di);
|
||||
bq27xxx_battery_teardown(di);
|
||||
|
||||
mutex_lock(&battery_mutex);
|
||||
|
@ -35,8 +35,9 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
|
||||
led_trigger_event(psy->charging_full_trig, LED_FULL);
|
||||
led_trigger_event(psy->charging_trig, LED_OFF);
|
||||
led_trigger_event(psy->full_trig, LED_FULL);
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig,
|
||||
LED_FULL);
|
||||
/* Going from blink to LED on requires a LED_OFF event to stop blink */
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF);
|
||||
led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL);
|
||||
break;
|
||||
case POWER_SUPPLY_STATUS_CHARGING:
|
||||
led_trigger_event(psy->charging_full_trig, LED_FULL);
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define SBS_CHARGER_REG_STATUS 0x13
|
||||
#define SBS_CHARGER_REG_ALARM_WARNING 0x16
|
||||
|
||||
#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1)
|
||||
#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0)
|
||||
#define SBS_CHARGER_STATUS_RES_COLD BIT(9)
|
||||
#define SBS_CHARGER_STATUS_RES_HOT BIT(10)
|
||||
#define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
|
||||
#include "spi-fsl-cpm.h"
|
||||
#include "spi-fsl-lib.h"
|
||||
@ -124,6 +125,21 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi,
|
||||
mspi->rx_dma = mspi->dma_dummy_rx;
|
||||
mspi->map_rx_dma = 0;
|
||||
}
|
||||
if (t->bits_per_word == 16 && t->tx_buf) {
|
||||
const u16 *src = t->tx_buf;
|
||||
u16 *dst;
|
||||
int i;
|
||||
|
||||
dst = kmalloc(t->len, GFP_KERNEL);
|
||||
if (!dst)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < t->len >> 1; i++)
|
||||
dst[i] = cpu_to_le16p(src + i);
|
||||
|
||||
mspi->tx = dst;
|
||||
mspi->map_tx_dma = 1;
|
||||
}
|
||||
|
||||
if (mspi->map_tx_dma) {
|
||||
void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */
|
||||
@ -177,6 +193,13 @@ void fsl_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi)
|
||||
if (mspi->map_rx_dma)
|
||||
dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE);
|
||||
mspi->xfer_in_progress = NULL;
|
||||
|
||||
if (t->bits_per_word == 16 && t->rx_buf) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < t->len; i += 2)
|
||||
le16_to_cpus(t->rx_buf + i);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
|
||||
|
||||
|
@ -201,26 +201,6 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
return bits_per_word;
|
||||
}
|
||||
|
||||
static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
struct spi_device *spi,
|
||||
int bits_per_word)
|
||||
{
|
||||
/* CPM/QE uses Little Endian for words > 8
|
||||
* so transform 16 and 32 bits words into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now */
|
||||
/* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL */
|
||||
if (spi->mode & SPI_LSB_FIRST &&
|
||||
bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (bits_per_word <= 8)
|
||||
return bits_per_word;
|
||||
if (bits_per_word == 16 || bits_per_word == 32)
|
||||
return 8; /* pretend its 8 bits */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
struct spi_transfer *t)
|
||||
{
|
||||
@ -248,9 +228,6 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
|
||||
mpc8xxx_spi,
|
||||
bits_per_word);
|
||||
else
|
||||
bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
|
||||
bits_per_word);
|
||||
|
||||
if (bits_per_word < 0)
|
||||
return bits_per_word;
|
||||
@ -357,12 +334,44 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
|
||||
static int fsl_spi_do_one_msg(struct spi_master *master,
|
||||
struct spi_message *m)
|
||||
{
|
||||
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
|
||||
struct spi_device *spi = m->spi;
|
||||
struct spi_transfer *t, *first;
|
||||
unsigned int cs_change;
|
||||
const int nsecs = 50;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* In CPU mode, optimize large byte transfers to use larger
|
||||
* bits_per_word values to reduce number of interrupts taken.
|
||||
*/
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
|
||||
if (t->len < 256 || t->bits_per_word != 8)
|
||||
continue;
|
||||
if ((t->len & 3) == 0)
|
||||
t->bits_per_word = 32;
|
||||
else if ((t->len & 1) == 0)
|
||||
t->bits_per_word = 16;
|
||||
} else {
|
||||
/*
|
||||
* CPM/QE uses Little Endian for words > 8
|
||||
* so transform 16 and 32 bits words into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now
|
||||
* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL
|
||||
*/
|
||||
if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (t->bits_per_word == 16 || t->bits_per_word == 32)
|
||||
t->bits_per_word = 8; /* pretend its 8 bits */
|
||||
if (t->bits_per_word == 8 && t->len >= 256 &&
|
||||
(mpc8xxx_spi->flags & SPI_CPM1))
|
||||
t->bits_per_word = 16;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't allow changes if CS is active */
|
||||
first = list_first_entry(&m->transfers, struct spi_transfer,
|
||||
transfer_list);
|
||||
@ -642,8 +651,14 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
|
||||
if (mpc8xxx_spi->type == TYPE_GRLIB)
|
||||
fsl_spi_grlib_probe(dev);
|
||||
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
|
||||
if (mpc8xxx_spi->flags & SPI_CPM_MODE)
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
|
||||
else
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
|
||||
|
||||
master->bits_per_word_mask &=
|
||||
SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
|
||||
|
||||
if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
|
||||
|
@ -241,6 +241,18 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the number of natively supported chip selects for MX51 is 4. Some
|
||||
* devices may have less actual SS pins but the register map supports 4. When
|
||||
* using gpio chip selects the cs values passed into the macros below can go
|
||||
* outside the range 0 - 3. We therefore need to limit the cs value to avoid
|
||||
* corrupting bits outside the allocated locations.
|
||||
*
|
||||
* The simplest way to do this is to just mask the cs bits to 2 bits. This
|
||||
* still allows all 4 native chip selects to work as well as gpio chip selects
|
||||
* (which can use any of the 4 chip select configurations).
|
||||
*/
|
||||
|
||||
#define MX51_ECSPI_CTRL 0x08
|
||||
#define MX51_ECSPI_CTRL_ENABLE (1 << 0)
|
||||
#define MX51_ECSPI_CTRL_XCH (1 << 2)
|
||||
@ -249,16 +261,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
|
||||
#define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16)
|
||||
#define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8
|
||||
#define MX51_ECSPI_CTRL_PREDIV_OFFSET 12
|
||||
#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18)
|
||||
#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18)
|
||||
#define MX51_ECSPI_CTRL_BL_OFFSET 20
|
||||
#define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20)
|
||||
|
||||
#define MX51_ECSPI_CONFIG 0x0c
|
||||
#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4))
|
||||
#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8))
|
||||
#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12))
|
||||
#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4))
|
||||
#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8))
|
||||
#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12))
|
||||
#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20))
|
||||
|
||||
#define MX51_ECSPI_INT 0x10
|
||||
#define MX51_ECSPI_INT_TEEN (1 << 0)
|
||||
|
@ -61,9 +61,9 @@ static const struct rtl819x_ops rtl819xp_ops = {
|
||||
};
|
||||
|
||||
static struct pci_device_id rtl8192_pci_id_tbl[] = {
|
||||
{RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)},
|
||||
{RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)},
|
||||
{RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)},
|
||||
{PCI_DEVICE(0x10ec, 0x8192)},
|
||||
{PCI_DEVICE(0x07aa, 0x0044)},
|
||||
{PCI_DEVICE(0x07aa, 0x0047)},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -67,11 +67,6 @@
|
||||
#define IS_HARDWARE_TYPE_8192SE(_priv) \
|
||||
(((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE)
|
||||
|
||||
#define RTL_PCI_DEVICE(vend, dev, cfg) \
|
||||
.vendor = (vend), .device = (dev), \
|
||||
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \
|
||||
.driver_data = (kernel_ulong_t)&(cfg)
|
||||
|
||||
#define TOTAL_CAM_ENTRY 32
|
||||
#define CAM_CONTENT_COUNT 8
|
||||
|
||||
|
@ -1128,6 +1128,7 @@ void serial8250_unregister_port(int line)
|
||||
uart->port.type = PORT_UNKNOWN;
|
||||
uart->port.dev = &serial8250_isa_devs->dev;
|
||||
uart->capabilities = 0;
|
||||
serial8250_init_port(uart);
|
||||
serial8250_apply_quirks(uart);
|
||||
uart_add_one_port(&serial8250_reg, &uart->port);
|
||||
} else {
|
||||
|
@ -1651,6 +1651,8 @@ pci_wch_ch38x_setup(struct serial_private *priv,
|
||||
#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530
|
||||
#define PCI_VENDOR_ID_ADVANTECH 0x13fe
|
||||
#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618
|
||||
@ -3851,6 +3853,9 @@ static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one,
|
||||
pciserial_resume_one);
|
||||
|
||||
static const struct pci_device_id serial_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI1600,
|
||||
PCI_DEVICE_ID_ADVANTECH_PCI1600_1611, PCI_ANY_ID, 0, 0,
|
||||
pbn_b0_4_921600 },
|
||||
/* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
|
||||
{ PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
|
||||
PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
|
||||
|
@ -209,6 +209,82 @@ int usb_find_common_endpoints_reverse(struct usb_host_interface *alt,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_find_common_endpoints_reverse);
|
||||
|
||||
/**
|
||||
* usb_find_endpoint() - Given an endpoint address, search for the endpoint's
|
||||
* usb_host_endpoint structure in an interface's current altsetting.
|
||||
* @intf: the interface whose current altsetting should be searched
|
||||
* @ep_addr: the endpoint address (number and direction) to find
|
||||
*
|
||||
* Search the altsetting's list of endpoints for one with the specified address.
|
||||
*
|
||||
* Return: Pointer to the usb_host_endpoint if found, %NULL otherwise.
|
||||
*/
|
||||
static const struct usb_host_endpoint *usb_find_endpoint(
|
||||
const struct usb_interface *intf, unsigned int ep_addr)
|
||||
{
|
||||
int n;
|
||||
const struct usb_host_endpoint *ep;
|
||||
|
||||
n = intf->cur_altsetting->desc.bNumEndpoints;
|
||||
ep = intf->cur_altsetting->endpoint;
|
||||
for (; n > 0; (--n, ++ep)) {
|
||||
if (ep->desc.bEndpointAddress == ep_addr)
|
||||
return ep;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_check_bulk_endpoints - Check whether an interface's current altsetting
|
||||
* contains a set of bulk endpoints with the given addresses.
|
||||
* @intf: the interface whose current altsetting should be searched
|
||||
* @ep_addrs: 0-terminated array of the endpoint addresses (number and
|
||||
* direction) to look for
|
||||
*
|
||||
* Search for endpoints with the specified addresses and check their types.
|
||||
*
|
||||
* Return: %true if all the endpoints are found and are bulk, %false otherwise.
|
||||
*/
|
||||
bool usb_check_bulk_endpoints(
|
||||
const struct usb_interface *intf, const u8 *ep_addrs)
|
||||
{
|
||||
const struct usb_host_endpoint *ep;
|
||||
|
||||
for (; *ep_addrs; ++ep_addrs) {
|
||||
ep = usb_find_endpoint(intf, *ep_addrs);
|
||||
if (!ep || !usb_endpoint_xfer_bulk(&ep->desc))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_check_bulk_endpoints);
|
||||
|
||||
/**
|
||||
* usb_check_int_endpoints - Check whether an interface's current altsetting
|
||||
* contains a set of interrupt endpoints with the given addresses.
|
||||
* @intf: the interface whose current altsetting should be searched
|
||||
* @ep_addrs: 0-terminated array of the endpoint addresses (number and
|
||||
* direction) to look for
|
||||
*
|
||||
* Search for endpoints with the specified addresses and check their types.
|
||||
*
|
||||
* Return: %true if all the endpoints are found and are interrupt,
|
||||
* %false otherwise.
|
||||
*/
|
||||
bool usb_check_int_endpoints(
|
||||
const struct usb_interface *intf, const u8 *ep_addrs)
|
||||
{
|
||||
const struct usb_host_endpoint *ep;
|
||||
|
||||
for (; *ep_addrs; ++ep_addrs) {
|
||||
ep = usb_find_endpoint(intf, *ep_addrs);
|
||||
if (!ep || !usb_endpoint_xfer_int(&ep->desc))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_check_int_endpoints);
|
||||
|
||||
/**
|
||||
* usb_find_alt_setting() - Given a configuration, find the alternate setting
|
||||
* for the given interface.
|
||||
|
@ -3015,6 +3015,20 @@ static int sisusb_probe(struct usb_interface *intf,
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
struct sisusb_usb_data *sisusb;
|
||||
int retval = 0, i;
|
||||
static const u8 ep_addresses[] = {
|
||||
SISUSB_EP_GFX_IN | USB_DIR_IN,
|
||||
SISUSB_EP_GFX_OUT | USB_DIR_OUT,
|
||||
SISUSB_EP_GFX_BULK_OUT | USB_DIR_OUT,
|
||||
SISUSB_EP_GFX_LBULK_OUT | USB_DIR_OUT,
|
||||
SISUSB_EP_BRIDGE_IN | USB_DIR_IN,
|
||||
SISUSB_EP_BRIDGE_OUT | USB_DIR_OUT,
|
||||
0};
|
||||
|
||||
/* Are the expected endpoints present? */
|
||||
if (!usb_check_bulk_endpoints(intf, ep_addresses)) {
|
||||
dev_err(&intf->dev, "Invalid USB2VGA device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_info(&dev->dev, "USB2VGA dongle found at address %d\n",
|
||||
dev->devnum);
|
||||
|
@ -408,22 +408,25 @@ static DEF_SCSI_QCMD(queuecommand)
|
||||
***********************************************************************/
|
||||
|
||||
/* Command timeout and abort */
|
||||
static int command_abort(struct scsi_cmnd *srb)
|
||||
static int command_abort_matching(struct us_data *us, struct scsi_cmnd *srb_match)
|
||||
{
|
||||
struct us_data *us = host_to_us(srb->device->host);
|
||||
|
||||
usb_stor_dbg(us, "%s called\n", __func__);
|
||||
|
||||
/*
|
||||
* us->srb together with the TIMED_OUT, RESETTING, and ABORTING
|
||||
* bits are protected by the host lock.
|
||||
*/
|
||||
scsi_lock(us_to_host(us));
|
||||
|
||||
/* Is this command still active? */
|
||||
if (us->srb != srb) {
|
||||
/* is there any active pending command to abort ? */
|
||||
if (!us->srb) {
|
||||
scsi_unlock(us_to_host(us));
|
||||
usb_stor_dbg(us, "-- nothing to abort\n");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Does the command match the passed srb if any ? */
|
||||
if (srb_match && us->srb != srb_match) {
|
||||
scsi_unlock(us_to_host(us));
|
||||
usb_stor_dbg(us, "-- pending command mismatch\n");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@ -446,6 +449,14 @@ static int command_abort(struct scsi_cmnd *srb)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int command_abort(struct scsi_cmnd *srb)
|
||||
{
|
||||
struct us_data *us = host_to_us(srb->device->host);
|
||||
|
||||
usb_stor_dbg(us, "%s called\n", __func__);
|
||||
return command_abort_matching(us, srb);
|
||||
}
|
||||
|
||||
/*
|
||||
* This invokes the transport reset mechanism to reset the state of the
|
||||
* device
|
||||
@ -457,6 +468,9 @@ static int device_reset(struct scsi_cmnd *srb)
|
||||
|
||||
usb_stor_dbg(us, "%s called\n", __func__);
|
||||
|
||||
/* abort any pending command before reset */
|
||||
command_abort_matching(us, NULL);
|
||||
|
||||
/* lock the device pointers and do the reset */
|
||||
mutex_lock(&(us->dev_mutex));
|
||||
result = us->transport_reset(us);
|
||||
|
@ -338,8 +338,10 @@ static struct sock_mapping *pvcalls_new_active_socket(
|
||||
void *page;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (map == NULL)
|
||||
if (map == NULL) {
|
||||
sock_release(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map->fedata = fedata;
|
||||
map->sock = sock;
|
||||
@ -431,10 +433,8 @@ static int pvcalls_back_connect(struct xenbus_device *dev,
|
||||
req->u.connect.ref,
|
||||
req->u.connect.evtchn,
|
||||
sock);
|
||||
if (!map) {
|
||||
if (!map)
|
||||
ret = -EFAULT;
|
||||
sock_release(sock);
|
||||
}
|
||||
|
||||
out:
|
||||
rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++);
|
||||
@ -575,7 +575,6 @@ static void __pvcalls_back_accept(struct work_struct *work)
|
||||
sock);
|
||||
if (!map) {
|
||||
ret = -EFAULT;
|
||||
sock_release(sock);
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
|
@ -959,6 +959,19 @@ skip_inode:
|
||||
continue;
|
||||
adjust_snap_realm_parent(mdsc, child, realm->ino);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* In the non-split case both 'num_split_inos' and
|
||||
* 'num_split_realms' should be 0, making this a no-op.
|
||||
* However the MDS happens to populate 'split_realms' list
|
||||
* in one of the UPDATE op cases by mistake.
|
||||
*
|
||||
* Skip both lists just in case to ensure that 'p' is
|
||||
* positioned at the start of realm info, as expected by
|
||||
* ceph_update_snap_trace().
|
||||
*/
|
||||
p += sizeof(u64) * num_split_inos;
|
||||
p += sizeof(u64) * num_split_realms;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -177,6 +177,7 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
|
||||
#define EXT2_MIN_BLOCK_SIZE 1024
|
||||
#define EXT2_MAX_BLOCK_SIZE 4096
|
||||
#define EXT2_MIN_BLOCK_LOG_SIZE 10
|
||||
#define EXT2_MAX_BLOCK_LOG_SIZE 16
|
||||
#define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
|
||||
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
|
||||
#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
|
||||
|
@ -965,6 +965,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
|
||||
goto failed_mount;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(es->s_log_block_size) >
|
||||
(EXT2_MAX_BLOCK_LOG_SIZE - BLOCK_SIZE_BITS)) {
|
||||
ext2_msg(sb, KERN_ERR,
|
||||
"Invalid log block size: %u",
|
||||
le32_to_cpu(es->s_log_block_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
|
||||
|
||||
if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
|
||||
|
@ -3116,6 +3116,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
|
||||
struct ext4_allocation_request *ar)
|
||||
{
|
||||
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
|
||||
struct ext4_super_block *es = sbi->s_es;
|
||||
int bsbits, max;
|
||||
ext4_lblk_t end;
|
||||
loff_t size, start_off;
|
||||
@ -3296,18 +3297,21 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
|
||||
ac->ac_g_ex.fe_len = EXT4_NUM_B2C(sbi, size);
|
||||
|
||||
/* define goal start in order to merge */
|
||||
if (ar->pright && (ar->lright == (start + size))) {
|
||||
if (ar->pright && (ar->lright == (start + size)) &&
|
||||
ar->pright >= size &&
|
||||
ar->pright - size >= le32_to_cpu(es->s_first_data_block)) {
|
||||
/* merge to the right */
|
||||
ext4_get_group_no_and_offset(ac->ac_sb, ar->pright - size,
|
||||
&ac->ac_f_ex.fe_group,
|
||||
&ac->ac_f_ex.fe_start);
|
||||
&ac->ac_g_ex.fe_group,
|
||||
&ac->ac_g_ex.fe_start);
|
||||
ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
|
||||
}
|
||||
if (ar->pleft && (ar->lleft + 1 == start)) {
|
||||
if (ar->pleft && (ar->lleft + 1 == start) &&
|
||||
ar->pleft + 1 < ext4_blocks_count(es)) {
|
||||
/* merge to the left */
|
||||
ext4_get_group_no_and_offset(ac->ac_sb, ar->pleft + 1,
|
||||
&ac->ac_f_ex.fe_group,
|
||||
&ac->ac_f_ex.fe_start);
|
||||
&ac->ac_g_ex.fe_group,
|
||||
&ac->ac_g_ex.fe_start);
|
||||
ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
|
||||
}
|
||||
|
||||
@ -3399,6 +3403,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
|
||||
BUG_ON(start < pa->pa_pstart);
|
||||
BUG_ON(end > pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len));
|
||||
BUG_ON(pa->pa_free < len);
|
||||
BUG_ON(ac->ac_b_ex.fe_len <= 0);
|
||||
pa->pa_free -= len;
|
||||
|
||||
mb_debug(1, "use %llu/%u from inode pa %p\n", start, len, pa);
|
||||
@ -3703,10 +3708,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) {
|
||||
int winl;
|
||||
int wins;
|
||||
int win;
|
||||
int offs;
|
||||
int new_bex_start;
|
||||
int new_bex_end;
|
||||
|
||||
/* we can't allocate as much as normalizer wants.
|
||||
* so, found space must get proper lstart
|
||||
@ -3714,26 +3717,40 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
|
||||
BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
|
||||
BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
|
||||
|
||||
/* we're limited by original request in that
|
||||
* logical block must be covered any way
|
||||
* winl is window we can move our chunk within */
|
||||
winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical;
|
||||
/*
|
||||
* Use the below logic for adjusting best extent as it keeps
|
||||
* fragmentation in check while ensuring logical range of best
|
||||
* extent doesn't overflow out of goal extent:
|
||||
*
|
||||
* 1. Check if best ex can be kept at end of goal and still
|
||||
* cover original start
|
||||
* 2. Else, check if best ex can be kept at start of goal and
|
||||
* still cover original start
|
||||
* 3. Else, keep the best ex at start of original request.
|
||||
*/
|
||||
new_bex_end = ac->ac_g_ex.fe_logical +
|
||||
EXT4_C2B(sbi, ac->ac_g_ex.fe_len);
|
||||
new_bex_start = new_bex_end - EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
|
||||
if (ac->ac_o_ex.fe_logical >= new_bex_start)
|
||||
goto adjust_bex;
|
||||
|
||||
/* also, we should cover whole original request */
|
||||
wins = EXT4_C2B(sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len);
|
||||
new_bex_start = ac->ac_g_ex.fe_logical;
|
||||
new_bex_end =
|
||||
new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
|
||||
if (ac->ac_o_ex.fe_logical < new_bex_end)
|
||||
goto adjust_bex;
|
||||
|
||||
/* the smallest one defines real window */
|
||||
win = min(winl, wins);
|
||||
new_bex_start = ac->ac_o_ex.fe_logical;
|
||||
new_bex_end =
|
||||
new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
|
||||
|
||||
offs = ac->ac_o_ex.fe_logical %
|
||||
EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
|
||||
if (offs && offs < win)
|
||||
win = offs;
|
||||
adjust_bex:
|
||||
ac->ac_b_ex.fe_logical = new_bex_start;
|
||||
|
||||
ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
|
||||
EXT4_NUM_B2C(sbi, win);
|
||||
BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
|
||||
BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
|
||||
BUG_ON(new_bex_end > (ac->ac_g_ex.fe_logical +
|
||||
EXT4_C2B(sbi, ac->ac_g_ex.fe_len)));
|
||||
}
|
||||
|
||||
/* preallocation can change ac_b_ex, thus we store actually
|
||||
|
@ -333,6 +333,7 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl)
|
||||
|
||||
static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
|
||||
{
|
||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||
const struct gfs2_dinode *str = buf;
|
||||
struct timespec atime;
|
||||
u16 height, depth;
|
||||
@ -372,7 +373,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
|
||||
/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
|
||||
gfs2_set_inode_flags(&ip->i_inode);
|
||||
height = be16_to_cpu(str->di_height);
|
||||
if (unlikely(height > GFS2_MAX_META_HEIGHT))
|
||||
if (unlikely(height > sdp->sd_max_height))
|
||||
goto corrupt;
|
||||
ip->i_height = (u8)height;
|
||||
|
||||
|
@ -488,7 +488,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
|
||||
if (type == HFSPLUS_FOLDER) {
|
||||
struct hfsplus_cat_folder *folder = &entry.folder;
|
||||
|
||||
WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
|
||||
if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
|
||||
pr_err("bad catalog folder entry\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
|
||||
sizeof(struct hfsplus_cat_folder));
|
||||
hfsplus_get_perms(inode, &folder->permissions, 1);
|
||||
@ -508,7 +512,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
|
||||
} else if (type == HFSPLUS_FILE) {
|
||||
struct hfsplus_cat_file *file = &entry.file;
|
||||
|
||||
WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
|
||||
if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
|
||||
pr_err("bad catalog file entry\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
|
||||
sizeof(struct hfsplus_cat_file));
|
||||
|
||||
@ -539,6 +547,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
|
||||
pr_err("bad catalog entry used to create inode\n");
|
||||
res = -EIO;
|
||||
}
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -547,6 +556,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
|
||||
struct inode *main_inode = inode;
|
||||
struct hfs_find_data fd;
|
||||
hfsplus_cat_entry entry;
|
||||
int res = 0;
|
||||
|
||||
if (HFSPLUS_IS_RSRC(inode))
|
||||
main_inode = HFSPLUS_I(inode)->rsrc_inode;
|
||||
@ -565,7 +575,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
|
||||
if (S_ISDIR(main_inode->i_mode)) {
|
||||
struct hfsplus_cat_folder *folder = &entry.folder;
|
||||
|
||||
WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
|
||||
if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
|
||||
pr_err("bad catalog folder entry\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
|
||||
sizeof(struct hfsplus_cat_folder));
|
||||
/* simple node checks? */
|
||||
@ -590,7 +604,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
|
||||
} else {
|
||||
struct hfsplus_cat_file *file = &entry.file;
|
||||
|
||||
WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
|
||||
if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
|
||||
pr_err("bad catalog file entry\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
|
||||
sizeof(struct hfsplus_cat_file));
|
||||
hfsplus_inode_write_fork(inode, &file->data_fork);
|
||||
@ -611,5 +629,5 @@ int hfsplus_cat_write_inode(struct inode *inode)
|
||||
set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
|
||||
out:
|
||||
hfs_find_exit(&fd);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
@ -939,6 +939,7 @@ void nilfs_evict_inode(struct inode *inode)
|
||||
struct nilfs_transaction_info ti;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct the_nilfs *nilfs;
|
||||
int ret;
|
||||
|
||||
if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) {
|
||||
@ -951,6 +952,23 @@ void nilfs_evict_inode(struct inode *inode)
|
||||
|
||||
truncate_inode_pages_final(&inode->i_data);
|
||||
|
||||
nilfs = sb->s_fs_info;
|
||||
if (unlikely(sb_rdonly(sb) || !nilfs->ns_writer)) {
|
||||
/*
|
||||
* If this inode is about to be disposed after the file system
|
||||
* has been degraded to read-only due to file system corruption
|
||||
* or after the writer has been detached, do not make any
|
||||
* changes that cause writes, just clear it.
|
||||
* Do this check after read-locking ns_segctor_sem by
|
||||
* nilfs_transaction_begin() in order to avoid a race with
|
||||
* the writer detach operation.
|
||||
*/
|
||||
clear_inode(inode);
|
||||
nilfs_clear_inode(inode);
|
||||
nilfs_transaction_abort(sb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: some of the following operations may fail. */
|
||||
nilfs_truncate_bmap(ii, 0);
|
||||
nilfs_mark_inode_dirty(inode);
|
||||
|
@ -114,6 +114,7 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
|
||||
if (sizeof(buf) == sizeof(*st))
|
||||
memcpy(&buf, st, sizeof(*st));
|
||||
else {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (sizeof buf.f_blocks == 4) {
|
||||
if ((st->f_blocks | st->f_bfree | st->f_bavail |
|
||||
st->f_bsize | st->f_frsize) &
|
||||
@ -142,7 +143,6 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
|
||||
buf.f_namelen = st->f_namelen;
|
||||
buf.f_frsize = st->f_frsize;
|
||||
buf.f_flags = st->f_flags;
|
||||
memset(buf.f_spare, 0, sizeof(buf.f_spare));
|
||||
}
|
||||
if (copy_to_user(p, &buf, sizeof(buf)))
|
||||
return -EFAULT;
|
||||
@ -155,6 +155,7 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
|
||||
if (sizeof(buf) == sizeof(*st))
|
||||
memcpy(&buf, st, sizeof(*st));
|
||||
else {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.f_type = st->f_type;
|
||||
buf.f_bsize = st->f_bsize;
|
||||
buf.f_blocks = st->f_blocks;
|
||||
@ -166,7 +167,6 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
|
||||
buf.f_namelen = st->f_namelen;
|
||||
buf.f_frsize = st->f_frsize;
|
||||
buf.f_flags = st->f_flags;
|
||||
memset(buf.f_spare, 0, sizeof(buf.f_spare));
|
||||
}
|
||||
if (copy_to_user(p, &buf, sizeof(buf)))
|
||||
return -EFAULT;
|
||||
|
@ -61,6 +61,7 @@ struct bq27xxx_device_info {
|
||||
struct bq27xxx_access_methods bus;
|
||||
struct bq27xxx_reg_cache cache;
|
||||
int charge_design_full;
|
||||
bool removed;
|
||||
unsigned long last_update;
|
||||
struct delayed_work work;
|
||||
struct power_supply *bat;
|
||||
|
@ -23,7 +23,7 @@ static inline void *task_stack_page(const struct task_struct *task)
|
||||
|
||||
#define setup_thread_stack(new,old) do { } while(0)
|
||||
|
||||
static inline unsigned long *end_of_stack(const struct task_struct *task)
|
||||
static __always_inline unsigned long *end_of_stack(const struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_STACK_GROWSUP
|
||||
return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1;
|
||||
|
@ -279,6 +279,11 @@ void usb_put_intf(struct usb_interface *intf);
|
||||
#define USB_MAXINTERFACES 32
|
||||
#define USB_MAXIADS (USB_MAXINTERFACES/2)
|
||||
|
||||
bool usb_check_bulk_endpoints(
|
||||
const struct usb_interface *intf, const u8 *ep_addrs);
|
||||
bool usb_check_int_endpoints(
|
||||
const struct usb_interface *intf, const u8 *ep_addrs);
|
||||
|
||||
/*
|
||||
* USB Resume Timer: Every Host controller driver should drive the resume
|
||||
* signalling on the bus for the amount of time defined by this macro.
|
||||
|
@ -195,14 +195,13 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
|
||||
}
|
||||
|
||||
int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
|
||||
unsigned int nft_parse_register(const struct nlattr *attr);
|
||||
int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
|
||||
|
||||
int nft_validate_register_load(enum nft_registers reg, unsigned int len);
|
||||
int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
enum nft_registers reg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type, unsigned int len);
|
||||
int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
|
||||
int nft_parse_register_store(const struct nft_ctx *ctx,
|
||||
const struct nlattr *attr, u8 *dreg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type, unsigned int len);
|
||||
|
||||
/**
|
||||
* struct nft_userdata - user defined data associated with an object
|
||||
@ -230,6 +229,10 @@ struct nft_set_elem {
|
||||
u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
|
||||
struct nft_data val;
|
||||
} key;
|
||||
union {
|
||||
u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
|
||||
struct nft_data val;
|
||||
} data;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
@ -378,6 +381,7 @@ void nft_unregister_set(struct nft_set_type *type);
|
||||
*
|
||||
* @list: table set list node
|
||||
* @bindings: list of set bindings
|
||||
* @table: table this set belongs to
|
||||
* @name: name of the set
|
||||
* @ktype: key type (numeric type defined by userspace, not used in the kernel)
|
||||
* @dtype: data type (verdict or numeric type defined by userspace)
|
||||
@ -401,6 +405,7 @@ void nft_unregister_set(struct nft_set_type *type);
|
||||
struct nft_set {
|
||||
struct list_head list;
|
||||
struct list_head bindings;
|
||||
struct nft_table *table;
|
||||
char *name;
|
||||
u32 ktype;
|
||||
u32 dtype;
|
||||
|
@ -14,9 +14,17 @@ extern struct nft_expr_type nft_range_type;
|
||||
int nf_tables_core_module_init(void);
|
||||
void nf_tables_core_module_exit(void);
|
||||
|
||||
struct nft_bitwise_fast_expr {
|
||||
u32 mask;
|
||||
u32 xor;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
struct nft_cmp_fast_expr {
|
||||
u32 data;
|
||||
enum nft_registers sreg:8;
|
||||
u32 mask;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
};
|
||||
|
||||
@ -36,14 +44,14 @@ struct nft_payload {
|
||||
enum nft_payload_bases base:8;
|
||||
u8 offset;
|
||||
u8 len;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
struct nft_payload_set {
|
||||
enum nft_payload_bases base:8;
|
||||
u8 offset;
|
||||
u8 len;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 csum_type;
|
||||
u8 csum_offset;
|
||||
u8 csum_flags;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define _NFT_FIB_H_
|
||||
|
||||
struct nft_fib {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 result;
|
||||
u32 flags;
|
||||
};
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
struct nft_masq {
|
||||
u32 flags;
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
};
|
||||
|
||||
extern const struct nla_policy nft_masq_policy[];
|
||||
|
@ -5,8 +5,8 @@
|
||||
struct nft_meta {
|
||||
enum nft_meta_keys key:8;
|
||||
union {
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
#define _NFT_REDIR_H_
|
||||
|
||||
struct nft_redir {
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
u16 flags;
|
||||
};
|
||||
|
||||
|
@ -2317,7 +2317,7 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
|
||||
__sock_recv_ts_and_drops(msg, sk, skb);
|
||||
else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
|
||||
sock_write_timestamp(sk, skb->tstamp);
|
||||
else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
|
||||
else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP))
|
||||
sock_write_timestamp(sk, 0);
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ enum nft_rule_compat_attributes {
|
||||
* @NFT_SET_INTERVAL: set contains intervals
|
||||
* @NFT_SET_MAP: set is used as a dictionary
|
||||
* @NFT_SET_TIMEOUT: set uses timeouts
|
||||
* @NFT_SET_EVAL: set contains expressions for evaluation
|
||||
* @NFT_SET_EVAL: set can be updated from the evaluation path
|
||||
* @NFT_SET_OBJECT: set contains stateful objects
|
||||
*/
|
||||
enum nft_set_flags {
|
||||
|
@ -235,7 +235,8 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap)
|
||||
|
||||
for (index = 0; index < rmap->used; index++) {
|
||||
glue = rmap->obj[index];
|
||||
irq_set_affinity_notifier(glue->notify.irq, NULL);
|
||||
if (glue)
|
||||
irq_set_affinity_notifier(glue->notify.irq, NULL);
|
||||
}
|
||||
|
||||
cpu_rmap_put(rmap);
|
||||
@ -271,6 +272,7 @@ static void irq_cpu_rmap_release(struct kref *ref)
|
||||
container_of(ref, struct irq_glue, notify.kref);
|
||||
|
||||
cpu_rmap_put(glue->rmap);
|
||||
glue->rmap->obj[glue->index] = NULL;
|
||||
kfree(glue);
|
||||
}
|
||||
|
||||
@ -300,6 +302,7 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)
|
||||
rc = irq_set_affinity_notifier(irq, &glue->notify);
|
||||
if (rc) {
|
||||
cpu_rmap_put(glue->rmap);
|
||||
rmap->obj[glue->index] = NULL;
|
||||
kfree(glue);
|
||||
}
|
||||
return rc;
|
||||
|
@ -115,8 +115,8 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
|
||||
* NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
|
||||
* OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
|
||||
*/
|
||||
if (veth->h_vlan_proto != vlan->vlan_proto ||
|
||||
vlan->flags & VLAN_FLAG_REORDER_HDR) {
|
||||
if (vlan->flags & VLAN_FLAG_REORDER_HDR ||
|
||||
veth->h_vlan_proto != vlan->vlan_proto) {
|
||||
u16 vlan_tci;
|
||||
vlan_tci = vlan->vlan_id;
|
||||
vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority);
|
||||
|
@ -4392,7 +4392,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
||||
|
||||
chan = l2cap_get_chan_by_scid(conn, scid);
|
||||
if (!chan) {
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
|
||||
return nft_meta_get_init(ctx, expr, tb);
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_meta_bridge_type;
|
||||
|
@ -2165,6 +2165,8 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
|
||||
struct xps_map *map, *new_map;
|
||||
bool active = false;
|
||||
|
||||
WARN_ON_ONCE(index >= dev->num_tx_queues);
|
||||
|
||||
if (dev->num_tc) {
|
||||
num_tc = dev->num_tc;
|
||||
tc = netdev_txq_to_tc(dev, index);
|
||||
|
@ -4421,8 +4421,10 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
||||
} else {
|
||||
skb = skb_clone(orig_skb, GFP_ATOMIC);
|
||||
|
||||
if (skb_orphan_frags_rx(skb, GFP_ATOMIC))
|
||||
if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!skb)
|
||||
return;
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <net/netfilter/ipv4/nf_dup_ipv4.h>
|
||||
|
||||
struct nft_dup_ipv4 {
|
||||
enum nft_registers sreg_addr:8;
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_addr;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
static void nft_dup_ipv4_eval(const struct nft_expr *expr,
|
||||
@ -43,16 +43,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]);
|
||||
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in_addr));
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
|
||||
sizeof(struct in_addr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_DUP_SREG_DEV] != NULL) {
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
}
|
||||
return 0;
|
||||
if (tb[NFTA_DUP_SREG_DEV])
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
|
||||
&priv->sreg_dev, sizeof(int));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
@ -142,6 +142,8 @@ int ipv6_find_tlv(const struct sk_buff *skb, int offset, int type)
|
||||
optlen = 1;
|
||||
break;
|
||||
default:
|
||||
if (len < 2)
|
||||
goto bad;
|
||||
optlen = nh[offset + 1] + 2;
|
||||
if (optlen > len)
|
||||
goto bad;
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <net/netfilter/ipv6/nf_dup_ipv6.h>
|
||||
|
||||
struct nft_dup_ipv6 {
|
||||
enum nft_registers sreg_addr:8;
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_addr;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
static void nft_dup_ipv6_eval(const struct nft_expr *expr,
|
||||
@ -41,16 +41,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]);
|
||||
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in6_addr));
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
|
||||
sizeof(struct in6_addr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_DUP_SREG_DEV] != NULL) {
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
}
|
||||
return 0;
|
||||
if (tb[NFTA_DUP_SREG_DEV])
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
|
||||
&priv->sreg_dev, sizeof(int));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
@ -1950,7 +1950,8 @@ static u32 gen_reqid(struct net *net)
|
||||
}
|
||||
|
||||
static int
|
||||
parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
|
||||
parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_policy *pol,
|
||||
struct sadb_x_ipsecrequest *rq)
|
||||
{
|
||||
struct net *net = xp_net(xp);
|
||||
struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
|
||||
@ -1968,9 +1969,12 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
|
||||
if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
|
||||
return -EINVAL;
|
||||
t->mode = mode;
|
||||
if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
|
||||
if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) {
|
||||
if ((mode == XFRM_MODE_TUNNEL || mode == XFRM_MODE_BEET) &&
|
||||
pol->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
|
||||
return -EINVAL;
|
||||
t->optional = 1;
|
||||
else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
|
||||
} else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
|
||||
t->reqid = rq->sadb_x_ipsecrequest_reqid;
|
||||
if (t->reqid > IPSEC_MANUAL_REQID_MAX)
|
||||
t->reqid = 0;
|
||||
@ -2012,7 +2016,7 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol)
|
||||
rq->sadb_x_ipsecrequest_len < sizeof(*rq))
|
||||
return -EINVAL;
|
||||
|
||||
if ((err = parse_ipsecrequest(xp, rq)) < 0)
|
||||
if ((err = parse_ipsecrequest(xp, pol, rq)) < 0)
|
||||
return err;
|
||||
len -= rq->sadb_x_ipsecrequest_len;
|
||||
rq = (void*)((u8*)rq + rq->sadb_x_ipsecrequest_len);
|
||||
|
@ -2475,6 +2475,7 @@ err1:
|
||||
}
|
||||
|
||||
static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
|
||||
const struct nft_chain *chain,
|
||||
const struct nlattr *nla)
|
||||
{
|
||||
u32 id = ntohl(nla_get_be32(nla));
|
||||
@ -2484,6 +2485,7 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
|
||||
struct nft_rule *rule = nft_trans_rule(trans);
|
||||
|
||||
if (trans->msg_type == NFT_MSG_NEWRULE &&
|
||||
trans->ctx.chain == chain &&
|
||||
id == nft_trans_rule_id(trans))
|
||||
return rule;
|
||||
}
|
||||
@ -2530,7 +2532,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
|
||||
|
||||
err = nft_delrule(&ctx, rule);
|
||||
} else if (nla[NFTA_RULE_ID]) {
|
||||
rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
|
||||
rule = nft_rule_lookup_byid(net, chain, nla[NFTA_RULE_ID]);
|
||||
if (IS_ERR(rule))
|
||||
return PTR_ERR(rule);
|
||||
|
||||
@ -2744,6 +2746,7 @@ static struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
|
||||
}
|
||||
|
||||
static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
|
||||
const struct nft_table *table,
|
||||
const struct nlattr *nla,
|
||||
u8 genmask)
|
||||
{
|
||||
@ -2755,6 +2758,7 @@ static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
|
||||
struct nft_set *set = nft_trans_set(trans);
|
||||
|
||||
if (id == nft_trans_set_id(trans) &&
|
||||
set->table == table &&
|
||||
nft_active_genmask(set, genmask))
|
||||
return set;
|
||||
}
|
||||
@ -2775,7 +2779,7 @@ struct nft_set *nft_set_lookup(const struct net *net,
|
||||
if (!nla_set_id)
|
||||
return set;
|
||||
|
||||
set = nf_tables_set_lookup_byid(net, nla_set_id, genmask);
|
||||
set = nf_tables_set_lookup_byid(net, table, nla_set_id, genmask);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
@ -3270,6 +3274,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&set->bindings);
|
||||
set->table = table;
|
||||
set->ops = ops;
|
||||
set->ktype = ktype;
|
||||
set->klen = desc.klen;
|
||||
@ -3349,6 +3354,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
|
||||
return nft_delset(&ctx, set);
|
||||
}
|
||||
|
||||
static int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
enum nft_registers reg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type,
|
||||
unsigned int len);
|
||||
|
||||
static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
@ -3730,6 +3741,24 @@ static int nf_tables_dump_set_done(struct netlink_callback *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_data *key, struct nlattr *attr)
|
||||
{
|
||||
struct nft_data_desc desc;
|
||||
int err;
|
||||
|
||||
err = nft_data_init(ctx, key, NFT_DATA_VALUE_MAXLEN, &desc, attr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) {
|
||||
nft_data_release(key, desc.type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
|
||||
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
||||
const struct nlattr * const nla[],
|
||||
@ -3930,19 +3959,44 @@ static int nft_setelem_parse_flags(const struct nft_set *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_data_desc *desc,
|
||||
struct nft_data *data,
|
||||
struct nlattr *attr)
|
||||
{
|
||||
u32 dtype;
|
||||
int err;
|
||||
|
||||
err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (set->dtype == NFT_DATA_VERDICT)
|
||||
dtype = NFT_DATA_VERDICT;
|
||||
else
|
||||
dtype = NFT_DATA_VALUE;
|
||||
|
||||
if (dtype != desc->type ||
|
||||
set->dlen != desc->len) {
|
||||
nft_data_release(data, desc->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
const struct nlattr *attr, u32 nlmsg_flags)
|
||||
{
|
||||
struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
|
||||
u8 genmask = nft_genmask_next(ctx->net);
|
||||
struct nft_data_desc d1, d2;
|
||||
struct nft_set_ext_tmpl tmpl;
|
||||
struct nft_set_ext *ext, *ext2;
|
||||
struct nft_set_elem elem;
|
||||
struct nft_set_binding *binding;
|
||||
struct nft_object *obj = NULL;
|
||||
struct nft_userdata *udata;
|
||||
struct nft_data data;
|
||||
struct nft_data_desc desc;
|
||||
enum nft_registers dreg;
|
||||
struct nft_trans *trans;
|
||||
u32 flags = 0;
|
||||
@ -3994,15 +4048,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
timeout = set->timeout;
|
||||
}
|
||||
|
||||
err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
|
||||
nla[NFTA_SET_ELEM_KEY]);
|
||||
err = nft_setelem_parse_key(ctx, set, &elem.key.val,
|
||||
nla[NFTA_SET_ELEM_KEY]);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
err = -EINVAL;
|
||||
if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
|
||||
goto err2;
|
||||
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
|
||||
if (timeout > 0) {
|
||||
nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
|
||||
if (timeout != set->timeout)
|
||||
@ -4024,15 +4075,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
}
|
||||
|
||||
if (nla[NFTA_SET_ELEM_DATA] != NULL) {
|
||||
err = nft_data_init(ctx, &data, sizeof(data), &d2,
|
||||
nla[NFTA_SET_ELEM_DATA]);
|
||||
err = nft_setelem_parse_data(ctx, set, &desc, &elem.data.val,
|
||||
nla[NFTA_SET_ELEM_DATA]);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
err = -EINVAL;
|
||||
if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
|
||||
goto err3;
|
||||
|
||||
dreg = nft_type_to_reg(set->dtype);
|
||||
list_for_each_entry(binding, &set->bindings, list) {
|
||||
struct nft_ctx bind_ctx = {
|
||||
@ -4046,13 +4093,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
continue;
|
||||
|
||||
err = nft_validate_register_store(&bind_ctx, dreg,
|
||||
&data,
|
||||
d2.type, d2.len);
|
||||
&elem.data.val,
|
||||
desc.type, desc.len);
|
||||
if (err < 0)
|
||||
goto err3;
|
||||
}
|
||||
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, desc.len);
|
||||
}
|
||||
|
||||
/* The full maximum length of userdata can exceed the maximum
|
||||
@ -4068,7 +4115,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
}
|
||||
|
||||
err = -ENOMEM;
|
||||
elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
|
||||
elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data,
|
||||
elem.data.val.data,
|
||||
timeout, GFP_KERNEL);
|
||||
if (elem.priv == NULL)
|
||||
goto err3;
|
||||
@ -4135,9 +4183,9 @@ err4:
|
||||
kfree(elem.priv);
|
||||
err3:
|
||||
if (nla[NFTA_SET_ELEM_DATA] != NULL)
|
||||
nft_data_release(&data, d2.type);
|
||||
nft_data_release(&elem.data.val, desc.type);
|
||||
err2:
|
||||
nft_data_release(&elem.key.val, d1.type);
|
||||
nft_data_release(&elem.key.val, NFT_DATA_VALUE);
|
||||
err1:
|
||||
return err;
|
||||
}
|
||||
@ -4164,7 +4212,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
|
||||
genmask);
|
||||
if (IS_ERR(set)) {
|
||||
if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
|
||||
set = nf_tables_set_lookup_byid(net,
|
||||
set = nf_tables_set_lookup_byid(net, ctx.table,
|
||||
nla[NFTA_SET_ELEM_LIST_SET_ID],
|
||||
genmask);
|
||||
}
|
||||
@ -4235,7 +4283,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
{
|
||||
struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
|
||||
struct nft_set_ext_tmpl tmpl;
|
||||
struct nft_data_desc desc;
|
||||
struct nft_set_elem elem;
|
||||
struct nft_set_ext *ext;
|
||||
struct nft_trans *trans;
|
||||
@ -4246,11 +4293,10 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
|
||||
nft_set_elem_policy, NULL);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
return err;
|
||||
|
||||
err = -EINVAL;
|
||||
if (nla[NFTA_SET_ELEM_KEY] == NULL)
|
||||
goto err1;
|
||||
return -EINVAL;
|
||||
|
||||
nft_set_ext_prepare(&tmpl);
|
||||
|
||||
@ -4260,37 +4306,31 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
if (flags != 0)
|
||||
nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
|
||||
|
||||
err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
|
||||
nla[NFTA_SET_ELEM_KEY]);
|
||||
err = nft_setelem_parse_key(ctx, set, &elem.key.val,
|
||||
nla[NFTA_SET_ELEM_KEY]);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
return err;
|
||||
|
||||
err = -EINVAL;
|
||||
if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
|
||||
goto err2;
|
||||
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
|
||||
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
|
||||
|
||||
err = -ENOMEM;
|
||||
elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
|
||||
GFP_KERNEL);
|
||||
if (elem.priv == NULL)
|
||||
goto err2;
|
||||
goto fail_elem;
|
||||
|
||||
ext = nft_set_elem_ext(set, elem.priv);
|
||||
if (flags)
|
||||
*nft_set_ext_flags(ext) = flags;
|
||||
|
||||
trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
|
||||
if (trans == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto err3;
|
||||
}
|
||||
if (trans == NULL)
|
||||
goto fail_trans;
|
||||
|
||||
priv = set->ops->deactivate(ctx->net, set, &elem);
|
||||
if (priv == NULL) {
|
||||
err = -ENOENT;
|
||||
goto err4;
|
||||
goto fail_ops;
|
||||
}
|
||||
kfree(elem.priv);
|
||||
elem.priv = priv;
|
||||
@ -4301,13 +4341,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
fail_ops:
|
||||
kfree(trans);
|
||||
err3:
|
||||
fail_trans:
|
||||
kfree(elem.priv);
|
||||
err2:
|
||||
nft_data_release(&elem.key.val, desc.type);
|
||||
err1:
|
||||
fail_elem:
|
||||
nft_data_release(&elem.key.val, NFT_DATA_VALUE);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -5609,28 +5648,24 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_parse_u32_check);
|
||||
|
||||
/**
|
||||
* nft_parse_register - parse a register value from a netlink attribute
|
||||
*
|
||||
* @attr: netlink attribute
|
||||
*
|
||||
* Parse and translate a register value from a netlink attribute.
|
||||
* Registers used to be 128 bit wide, these register numbers will be
|
||||
* mapped to the corresponding 32 bit register numbers.
|
||||
*/
|
||||
unsigned int nft_parse_register(const struct nlattr *attr)
|
||||
static int nft_parse_register(const struct nlattr *attr, u32 *preg)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ntohl(nla_get_be32(attr));
|
||||
switch (reg) {
|
||||
case NFT_REG_VERDICT...NFT_REG_4:
|
||||
return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
|
||||
*preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE;
|
||||
break;
|
||||
case NFT_REG32_00...NFT_REG32_15:
|
||||
*preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
|
||||
break;
|
||||
default:
|
||||
return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_parse_register);
|
||||
|
||||
/**
|
||||
* nft_dump_register - dump a register value to a netlink attribute
|
||||
@ -5663,7 +5698,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register);
|
||||
* Validate that the input register is one of the general purpose
|
||||
* registers and that the length of the load is within the bounds.
|
||||
*/
|
||||
int nft_validate_register_load(enum nft_registers reg, unsigned int len)
|
||||
static int nft_validate_register_load(enum nft_registers reg, unsigned int len)
|
||||
{
|
||||
if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
|
||||
return -EINVAL;
|
||||
@ -5674,7 +5709,24 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_validate_register_load);
|
||||
|
||||
int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)
|
||||
{
|
||||
u32 reg;
|
||||
int err;
|
||||
|
||||
err = nft_parse_register(attr, ®);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = nft_validate_register_load(reg, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
*sreg = reg;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_parse_register_load);
|
||||
|
||||
/**
|
||||
* nft_validate_register_store - validate an expressions' register store
|
||||
@ -5690,10 +5742,11 @@ EXPORT_SYMBOL_GPL(nft_validate_register_load);
|
||||
* A value of NULL for the data means that its runtime gathered
|
||||
* data.
|
||||
*/
|
||||
int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
enum nft_registers reg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type, unsigned int len)
|
||||
static int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
enum nft_registers reg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type,
|
||||
unsigned int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -5732,7 +5785,27 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_validate_register_store);
|
||||
|
||||
int nft_parse_register_store(const struct nft_ctx *ctx,
|
||||
const struct nlattr *attr, u8 *dreg,
|
||||
const struct nft_data *data,
|
||||
enum nft_data_types type, unsigned int len)
|
||||
{
|
||||
int err;
|
||||
u32 reg;
|
||||
|
||||
err = nft_parse_register(attr, ®);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = nft_validate_register_store(ctx, reg, data, type, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
*dreg = reg;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_parse_register_store);
|
||||
|
||||
static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
|
||||
[NFTA_VERDICT_CODE] = { .type = NLA_U32 },
|
||||
@ -6032,18 +6105,25 @@ static int __init nf_tables_module_init(void)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
err = nf_tables_core_module_init();
|
||||
err = register_pernet_subsys(&nf_tables_net_ops);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
err = nfnetlink_subsys_register(&nf_tables_subsys);
|
||||
err = nf_tables_core_module_init();
|
||||
if (err < 0)
|
||||
goto err3;
|
||||
|
||||
/* must be last */
|
||||
err = nfnetlink_subsys_register(&nf_tables_subsys);
|
||||
if (err < 0)
|
||||
goto err4;
|
||||
|
||||
pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
|
||||
return register_pernet_subsys(&nf_tables_net_ops);
|
||||
err3:
|
||||
return err;
|
||||
err4:
|
||||
nf_tables_core_module_exit();
|
||||
err3:
|
||||
unregister_pernet_subsys(&nf_tables_net_ops);
|
||||
err2:
|
||||
kfree(info);
|
||||
err1:
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_bitwise {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
u8 len;
|
||||
struct nft_data mask;
|
||||
struct nft_data xor;
|
||||
@ -68,14 +68,14 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
|
||||
|
||||
priv->len = len;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, priv->len);
|
||||
err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_byteorder {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
enum nft_byteorder_ops op:8;
|
||||
u8 len;
|
||||
u8 size;
|
||||
@ -133,20 +133,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
|
||||
err = nft_parse_u32_check(tb[NFTA_BYTEORDER_LEN], U8_MAX, &len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->len = len;
|
||||
|
||||
err = nft_validate_register_load(priv->sreg, priv->len);
|
||||
err = nft_parse_register_load(tb[NFTA_BYTEORDER_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
struct nft_cmp_expr {
|
||||
struct nft_data data;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
enum nft_cmp_ops op:8;
|
||||
};
|
||||
@ -79,8 +79,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||
tb[NFTA_CMP_DATA]);
|
||||
BUG_ON(err < 0);
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc.len);
|
||||
err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -129,8 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
|
||||
tb[NFTA_CMP_DATA]);
|
||||
BUG_ON(err < 0);
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc.len);
|
||||
err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -27,8 +27,8 @@ struct nft_ct {
|
||||
enum nft_ct_keys key:8;
|
||||
enum ip_conntrack_dir dir:8;
|
||||
union {
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
};
|
||||
};
|
||||
|
||||
@ -483,9 +483,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -578,8 +577,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, len);
|
||||
err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <net/netfilter/nf_dup_netdev.h>
|
||||
|
||||
struct nft_dup_netdev {
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
static void nft_dup_netdev_eval(const struct nft_expr *expr,
|
||||
@ -42,8 +42,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_DUP_SREG_DEV] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev,
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
static const struct nft_expr_ops nft_dup_netdev_ingress_ops;
|
||||
|
@ -20,8 +20,8 @@ struct nft_dynset {
|
||||
struct nft_set *set;
|
||||
struct nft_set_ext_tmpl tmpl;
|
||||
enum nft_dynset_ops op:8;
|
||||
enum nft_registers sreg_key:8;
|
||||
enum nft_registers sreg_data:8;
|
||||
u8 sreg_key;
|
||||
u8 sreg_data;
|
||||
bool invert;
|
||||
u64 timeout;
|
||||
struct nft_expr *expr;
|
||||
@ -163,8 +163,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
||||
tb[NFTA_DYNSET_TIMEOUT])));
|
||||
}
|
||||
|
||||
priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
|
||||
err = nft_validate_register_load(priv->sreg_key, set->klen);;
|
||||
err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -174,8 +174,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
||||
if (set->dtype == NFT_DATA_VERDICT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
|
||||
err = nft_validate_register_load(priv->sreg_data, set->dlen);
|
||||
err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA],
|
||||
&priv->sreg_data, set->dlen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (set->flags & NFT_SET_MAP)
|
||||
@ -190,9 +190,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
||||
priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
|
||||
if (IS_ERR(priv->expr))
|
||||
return PTR_ERR(priv->expr);
|
||||
|
||||
} else if (set->flags & NFT_SET_EVAL)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nft_set_ext_prepare(&priv->tmpl);
|
||||
nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
|
||||
|
@ -23,8 +23,8 @@ struct nft_exthdr {
|
||||
u8 offset;
|
||||
u8 len;
|
||||
u8 op;
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
@ -257,12 +257,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
|
||||
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
|
||||
priv->offset = offset;
|
||||
priv->len = len;
|
||||
priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
|
||||
priv->flags = flags;
|
||||
priv->op = op;
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_EXTHDR_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
|
||||
@ -307,11 +307,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
|
||||
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
|
||||
priv->offset = offset;
|
||||
priv->len = len;
|
||||
priv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]);
|
||||
priv->flags = flags;
|
||||
priv->op = op;
|
||||
|
||||
return nft_validate_register_load(priv->sreg, priv->len);
|
||||
return nft_parse_register_load(tb[NFTA_EXTHDR_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv)
|
||||
|
@ -88,7 +88,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||
return -EINVAL;
|
||||
|
||||
priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
|
||||
priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]);
|
||||
|
||||
switch (priv->result) {
|
||||
case NFT_FIB_RESULT_OIF:
|
||||
@ -108,8 +107,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <net/netfilter/nf_dup_netdev.h>
|
||||
|
||||
struct nft_fwd_netdev {
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
static void nft_fwd_netdev_eval(const struct nft_expr *expr,
|
||||
@ -43,8 +43,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_FWD_SREG_DEV] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
static const struct nft_expr_ops nft_fwd_netdev_ingress_ops;
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <linux/jhash.h>
|
||||
|
||||
struct nft_jhash {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
u8 len;
|
||||
bool autogen_seed:1;
|
||||
u32 modulus;
|
||||
@ -40,7 +40,7 @@ static void nft_jhash_eval(const struct nft_expr *expr,
|
||||
}
|
||||
|
||||
struct nft_symhash {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
u32 offset;
|
||||
};
|
||||
@ -85,9 +85,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_HASH_OFFSET])
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
|
||||
priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
|
||||
|
||||
err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@ -96,6 +93,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
||||
|
||||
priv->len = len;
|
||||
|
||||
err = nft_parse_register_load(tb[NFTA_HASH_SREG], &priv->sreg, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
|
||||
if (priv->modulus <= 1)
|
||||
return -ERANGE;
|
||||
@ -110,9 +111,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
||||
get_random_bytes(&priv->seed, sizeof(priv->seed));
|
||||
}
|
||||
|
||||
return nft_validate_register_load(priv->sreg, len) &&
|
||||
nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
static int nft_symhash_init(const struct nft_ctx *ctx,
|
||||
@ -128,8 +128,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
|
||||
if (tb[NFTA_HASH_OFFSET])
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
|
||||
|
||||
priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
|
||||
if (priv->modulus < 1)
|
||||
return -ERANGE;
|
||||
@ -137,8 +135,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
|
||||
if (priv->offset + priv->modulus - 1 < priv->offset)
|
||||
return -EOVERFLOW;
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
static int nft_jhash_dump(struct sk_buff *skb,
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
struct nft_immediate_expr {
|
||||
struct nft_data data;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 dlen;
|
||||
};
|
||||
|
||||
@ -56,9 +56,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
|
||||
|
||||
priv->dlen = desc.len;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
|
||||
desc.type, desc.len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_IMMEDIATE_DREG],
|
||||
&priv->dreg, &priv->data, desc.type,
|
||||
desc.len);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
struct nft_lookup {
|
||||
struct nft_set *set;
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
bool invert;
|
||||
struct nft_set_binding binding;
|
||||
};
|
||||
@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
||||
if (IS_ERR(set))
|
||||
return PTR_ERR(set);
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, set->klen);
|
||||
err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
||||
if (!(set->flags & NFT_SET_MAP))
|
||||
return -EINVAL;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
set->dtype, set->dlen);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG],
|
||||
&priv->dreg, NULL, set->dtype,
|
||||
set->dlen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (set->flags & NFT_SET_MAP)
|
||||
|
@ -53,19 +53,15 @@ int nft_masq_init(const struct nft_ctx *ctx,
|
||||
}
|
||||
|
||||
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_MASQ_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
@ -314,9 +314,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_meta_get_init);
|
||||
|
||||
@ -374,8 +373,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, len);
|
||||
err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -27,10 +27,10 @@
|
||||
#include <net/ip.h>
|
||||
|
||||
struct nft_nat {
|
||||
enum nft_registers sreg_addr_min:8;
|
||||
enum nft_registers sreg_addr_max:8;
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_addr_min;
|
||||
u8 sreg_addr_max;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
enum nf_nat_manip_type type:8;
|
||||
u8 family;
|
||||
u16 flags;
|
||||
@ -160,18 +160,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||
priv->family = family;
|
||||
|
||||
if (tb[NFTA_NAT_REG_ADDR_MIN]) {
|
||||
priv->sreg_addr_min =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
|
||||
err = nft_validate_register_load(priv->sreg_addr_min, alen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN],
|
||||
&priv->sreg_addr_min, alen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_NAT_REG_ADDR_MAX]) {
|
||||
priv->sreg_addr_max =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_addr_max,
|
||||
alen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX],
|
||||
&priv->sreg_addr_max,
|
||||
alen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
@ -181,19 +178,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||
|
||||
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
|
||||
if (tb[NFTA_NAT_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_NAT_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
@ -20,7 +20,7 @@
|
||||
static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
|
||||
|
||||
struct nft_ng_inc {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
atomic_t counter;
|
||||
u32 offset;
|
||||
@ -64,11 +64,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
|
||||
if (priv->offset + priv->modulus - 1 < priv->offset)
|
||||
return -EOVERFLOW;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
|
||||
atomic_set(&priv->counter, priv->modulus - 1);
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
|
||||
@ -98,7 +97,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
}
|
||||
|
||||
struct nft_ng_random {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
u32 offset;
|
||||
};
|
||||
@ -133,10 +132,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
|
||||
|
||||
prandom_init_once(&nft_numgen_prandom_state);
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
@ -64,27 +64,40 @@ nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void nft_objref_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr)
|
||||
static void nft_objref_deactivate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
enum nft_trans_phase phase)
|
||||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
if (phase == NFT_TRANS_COMMIT)
|
||||
return;
|
||||
|
||||
obj->use--;
|
||||
}
|
||||
|
||||
static void nft_objref_activate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr)
|
||||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
obj->use++;
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_objref_type;
|
||||
static const struct nft_expr_ops nft_objref_ops = {
|
||||
.type = &nft_objref_type,
|
||||
.size = NFT_EXPR_SIZE(sizeof(struct nft_object *)),
|
||||
.eval = nft_objref_eval,
|
||||
.init = nft_objref_init,
|
||||
.destroy = nft_objref_destroy,
|
||||
.activate = nft_objref_activate,
|
||||
.deactivate = nft_objref_deactivate,
|
||||
.dump = nft_objref_dump,
|
||||
};
|
||||
|
||||
struct nft_objref_map {
|
||||
struct nft_set *set;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
struct nft_set_binding binding;
|
||||
};
|
||||
|
||||
@ -125,8 +138,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,
|
||||
if (!(set->flags & NFT_SET_OBJECT))
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_OBJREF_SET_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, set->klen);
|
||||
err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -135,10 +135,10 @@ static int nft_payload_init(const struct nft_ctx *ctx,
|
||||
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
|
||||
priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
@ -338,7 +338,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
||||
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
|
||||
priv->sreg = nft_parse_register(tb[NFTA_PAYLOAD_SREG]);
|
||||
|
||||
if (tb[NFTA_PAYLOAD_CSUM_TYPE])
|
||||
csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
|
||||
@ -369,7 +368,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
||||
}
|
||||
priv->csum_type = csum_type;
|
||||
|
||||
return nft_validate_register_load(priv->sreg, priv->len);
|
||||
return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
@ -22,10 +22,10 @@
|
||||
static u32 jhash_initval __read_mostly;
|
||||
|
||||
struct nft_queue {
|
||||
enum nft_registers sreg_qnum:8;
|
||||
u16 queuenum;
|
||||
u16 queues_total;
|
||||
u16 flags;
|
||||
u8 sreg_qnum;
|
||||
u16 queuenum;
|
||||
u16 queues_total;
|
||||
u16 flags;
|
||||
};
|
||||
|
||||
static void nft_queue_eval(const struct nft_expr *expr,
|
||||
@ -114,8 +114,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,
|
||||
struct nft_queue *priv = nft_expr_priv(expr);
|
||||
int err;
|
||||
|
||||
priv->sreg_qnum = nft_parse_register(tb[NFTA_QUEUE_SREG_QNUM]);
|
||||
err = nft_validate_register_load(priv->sreg_qnum, sizeof(u32));
|
||||
err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM],
|
||||
&priv->sreg_qnum, sizeof(u32));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
struct nft_range_expr {
|
||||
struct nft_data data_from;
|
||||
struct nft_data data_to;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
enum nft_range_ops op:8;
|
||||
};
|
||||
@ -80,8 +80,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
|
||||
goto err2;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_RANGE_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc_from.len);
|
||||
err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg,
|
||||
desc_from.len);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
|
@ -49,19 +49,15 @@ int nft_redir_init(const struct nft_ctx *ctx,
|
||||
|
||||
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
|
||||
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
struct nft_rt {
|
||||
enum nft_rt_keys key:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skbdst)
|
||||
@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_RT_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
static int nft_rt_get_dump(struct sk_buff *skb,
|
||||
|
@ -1977,7 +1977,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
||||
|
||||
skb_free_datagram(sk, skb);
|
||||
|
||||
if (nlk->cb_running &&
|
||||
if (READ_ONCE(nlk->cb_running) &&
|
||||
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
|
||||
ret = netlink_dump(sk);
|
||||
if (ret) {
|
||||
@ -2259,7 +2259,7 @@ static int netlink_dump(struct sock *sk)
|
||||
if (cb->done)
|
||||
cb->done(cb);
|
||||
|
||||
nlk->cb_running = false;
|
||||
WRITE_ONCE(nlk->cb_running, false);
|
||||
module = cb->module;
|
||||
skb = cb->skb;
|
||||
mutex_unlock(nlk->cb_mutex);
|
||||
@ -2320,7 +2320,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
|
||||
goto error_put;
|
||||
}
|
||||
|
||||
nlk->cb_running = true;
|
||||
WRITE_ONCE(nlk->cb_running, true);
|
||||
nlk->dump_done_errno = INT_MAX;
|
||||
|
||||
mutex_unlock(nlk->cb_mutex);
|
||||
@ -2633,7 +2633,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
|
||||
nlk->groups ? (u32)nlk->groups[0] : 0,
|
||||
sk_rmem_alloc_get(s),
|
||||
sk_wmem_alloc_get(s),
|
||||
nlk->cb_running,
|
||||
READ_ONCE(nlk->cb_running),
|
||||
refcount_read(&s->sk_refcnt),
|
||||
atomic_read(&s->sk_drops),
|
||||
sock_i_ino(s)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user