This is the 4.4.228 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl7tx38ACgkQONu9yGCS aT657w/9EfyImC5i+I+ChzfgtIeT3/ckbnJpYu0WWQmbXINP7C8Yso9AawMMKylT 7Iz4OFBws/8qBUR9f1b/66+iJnQGPrmZRGpcrBJmQUDV3dJ9cei+lqsADjdi1d0J sY1BK6/3jbfWfs0nU94+W6pYtdkB/zo7nHYGRQEjf1Y2aDL+IMOr6I+Y67fmjzN6 tt/noD6+LYbT0sk7l5mfbEKCgTD0/AzHJd5BXD8yThNZ6GmEflvOEkW7chBycXSk RVmd3dfOwdsr48e2oQyUEmczx5kuKCLUZmuWsazGugDL5BTDhWjqLBgD7FaqhFje qH/yuhkjJC/gz9idqos6uc9SPW7R/Iu0Vn1Eqx1eBg19BTMJPcSR2K6zx1t75BuL NpGH9njjtoFcvqnHdE+RHmTjicOBF0ZhU8S5PKDNVXLCJ4OsLWhX29lxOsq5m8XH 8v66ZpTjDrz+9LFZhXLITqmZcUiTdzefM0lepereVvuZlB977PPKg6l2gSxQuihP g1wU54V6MaVAKhrUNQ1oVP5FMKxpB8RurxMWEaV3CJKapduAKgdR5yPulFHtCnfS OoblUEW6QufF73l8xZnPScNptwx64LDd47acDv3MIfesxkQRBmhIKhH99XTvoJSP FbSw1R3o4TN/SD/aktJfG2sPvKlpsuQX+eGC1lrvUzWgeOcbN48= =a0eo -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEJDfLduVEy2qz2d/TmXOSYMtstxYFAl7w8/QACgkQmXOSYMts txYNNg//dQ77S/tN5w0ocw4TchwRt8OnZFLSY3S14f/VcPSPOZC9cUlAOFWSQNmA T+Z4daKBwMZULlelAjxUjqcLN87y80eARhGn09oNOBRxsSh8ZplUnYto0gJ7qRCB VPIxoLpXeDHxRZGIIwnOhNzvgrQVMPAx2Kh5l1zpHPQqRHsLXwmel2kpNvJM8k2+ mdGeL4O2S6xqT6mxHwyP6Ewp6fENmwyTUOGf8ja15UFYU6hwPT2EcaaPwuUF1oQs A7+eTBTB3/PwqFF3/B6CRfXATx+YIIj8TDYm0CmwEtWQLAzswaD1ryWSWsY9jGYh /gPLFZdtoghPeoc+aX3suZldJ53IRxe0Wa5DV5FmjNUltF4+W2SAC+CjJlPqhwJg pk4yUqPO6jw0ghoapzKiYVWp41wKmupvSCUYSQ9SSgqeFBRnZnArOIpeQuG5fZ8c OqS5LoVqZuUkgjMaAOznY4jg3g9xpOjPiSi0s5+jCRJxqARquzhWRtVZtndZGX8E Sxp6lXLUQobqdinh5h1j4ywtGLzD1Hou+TbtIHlxpNZ06s5zQmO6O8SAIqx9CP4p EiI2ky6U6yEee/2EcDBHXEKT+eLuQF0RhNgssIe4s8h0EtQrZblKC3cj+Jzs12pa siPaS5ll8duzVhi1IemPwms9Sf5h4zK9x+CSlxB3WePMG46uP4s= =x63r -----END PGP SIGNATURE----- Merge 4.4.228 into kernel.lnx.4.4.r39-rel Changes in 4.4.228: (102 commits) ipv6: fix IPV6_ADDRFORM operation logic vxlan: Avoid infinite loop when suppressing NS messages with invalid options scsi: return correct blkprep status code in case scsi_init_io() fails. net: phy: marvell: Limit 88m1101 autoneg errata to 88E1145 as well. pwm: fsl-ftm: Use flat regmap cache igb: improve handling of disconnected adapters ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook sched/fair: Don't NUMA balance for kthreads ath9k_htc: Silence undersized packet warnings x86_64: Fix jiffies ODR violation x86/speculation: Prevent rogue cross-process SSBD shutdown x86/reboot/quirks: Add MacBook6,1 reboot quirk efi/efivars: Add missing kobject_put() in sysfs entry creation error path ALSA: es1688: Add the missed snd_card_free() ALSA: usb-audio: Fix inconsistent card PM state after resume ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() ACPI: PM: Avoid using power resources if there are none for D0 cgroup, blkcg: Prepare some symbols for module and !CONFIG_CGROUP usages nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() spi: bcm2835aux: Fix controller unregister order ALSA: pcm: disallow linking stream to itself x86/speculation: Change misspelled STIPB to STIBP x86/speculation: Add support for STIBP always-on preferred mode x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS. x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches. spi: dw: fix possible race condition spi: dw: Fix controller unregister order spi: No need to assign dummy value in spi_unregister_controller() spi: Fix controller unregister order spi: pxa2xx: Fix controller unregister order spi: bcm2835: Fix controller unregister order ovl: initialize error in ovl_copy_xattr proc: Use new_inode not new_inode_pseudo video: fbdev: w100fb: Fix a potential double free. KVM: nSVM: leave ASID aside in copy_vmcb_control_area KVM: nVMX: Consult only the "basic" exit reason when routing nested exit KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx ath9k: Fix use-after-free Write in ath9k_htc_rx_msg ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb Smack: slab-out-of-bounds in vsscanf mm/slub: fix a memory leak in sysfs_slab_add() fat: don't allow to mount if the FAT length == 0 can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices spi: dw: Zero DMA Tx and Rx configurations on stack Bluetooth: Add SCO fallback for invalid LMP parameters error kgdb: Prevent infinite recursive entries to the debugger spi: dw: Enable interrupts in accordance with DMA xfer mode clocksource: dw_apb_timer_of: Fix missing clockevent timers btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss() staging: android: ion: use vmap instead of vm_map_ram e1000: Distribute switch variables for initialization media: dvb: return -EREMOTEIO on i2c transfer failure. MIPS: Make sparse_init() using top-down allocation netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported lib/mpi: Fix 64-bit MIPS build with Clang net: lpc-enet: fix error return code in lpc_mii_init() net: allwinner: Fix use correct return type for ndo_start_xmit() powerpc/spufs: fix copy_to_user while atomic mips: cm: Fix an invalid error code of INTVN_*_ERR kgdb: Fix spurious true from in_dbg_master() md: don't flush workqueue unconditionally in md_open mwifiex: Fix memory corruption in dump_station mips: Add udelay lpj numbers adjustment x86/mm: Stop printing BRK addresses m68k: mac: Don't call via_flush_cache() on Mac IIfx macvlan: Skip loopback packets in RX handler PCI: Don't disable decoding when mmio_always_on is set MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe() ixgbe: fix signed-integer-overflow warning spi: dw: Return any value retrieved from the dma_transfer callback cpuidle: Fix three reference count leaks ima: Fix ima digest hash table key calculation ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max Btrfs: fix unreplayable log after snapshot delete + parent dir fsync btrfs: send: emit file capabilities after chown btrfs: fix error handling when submitting direct I/O bio ima: Directly assign the ima_default_policy pointer to ima_rules PCI: Program MPS for RCiEP devices e1000e: Relax condition to trigger reset for ME workaround carl9170: remove P2P_GO support media: go7007: fix a miss of snd_card_free b43legacy: Fix case where channel status is corrupted b43: Fix connection problem with WPA3 b43_legacy: Fix connection problem with WPA3 igb: Report speed and duplex as unknown when device is runtime suspended power: vexpress: add suppress_bind_attrs to true pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs sparc32: fix register window handling in genregs32_[gs]et() kernel/cpu_pm: Fix uninitted local in cpu_pm ARM: tegra: Correct PL310 Auxiliary Control Register initialization drivers/macintosh: Fix memleak in windfarm_pm112 driver kbuild: force to build vmlinux if CONFIG_MODVERSION=y sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate registrations. sunrpc: clean up properly in gss_mech_unregister() w1: omap-hdq: cleanup to add missing newline for some dev_dbg perf probe: Do not show the skipped events perf symbols: Fix debuginfo search for Ubuntu Linux 4.4.228 Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> Conflicts: arch/x86/kernel/vmlinux.lds.S
This commit is contained in:
commit
fd85389663
115 changed files with 841 additions and 470 deletions
15
Makefile
15
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 4
|
PATCHLEVEL = 4
|
||||||
SUBLEVEL = 227
|
SUBLEVEL = 228
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Blurry Fish Butt
|
NAME = Blurry Fish Butt
|
||||||
|
|
||||||
|
@ -313,12 +313,8 @@ KBUILD_MODULES :=
|
||||||
KBUILD_BUILTIN := 1
|
KBUILD_BUILTIN := 1
|
||||||
|
|
||||||
# If we have only "make modules", don't compile built-in objects.
|
# If we have only "make modules", don't compile built-in objects.
|
||||||
# When we're building modules with modversions, we need to consider
|
|
||||||
# the built-in objects during the descend as well, in order to
|
|
||||||
# make sure the checksums are up to date before we record them.
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),modules)
|
ifeq ($(MAKECMDGOALS),modules)
|
||||||
KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
|
KBUILD_BUILTIN :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# If we have "make <whatever> modules", compile modules
|
# If we have "make <whatever> modules", compile modules
|
||||||
|
@ -1178,6 +1174,13 @@ ifdef CONFIG_MODULES
|
||||||
|
|
||||||
all: modules
|
all: modules
|
||||||
|
|
||||||
|
# When we're building modules with modversions, we need to consider
|
||||||
|
# the built-in objects during the descend as well, in order to
|
||||||
|
# make sure the checksums are up to date before we record them.
|
||||||
|
ifdef CONFIG_MODVERSIONS
|
||||||
|
KBUILD_BUILTIN := 1
|
||||||
|
endif
|
||||||
|
|
||||||
# Build modules
|
# Build modules
|
||||||
#
|
#
|
||||||
# A module can be listed more than once in obj-m resulting in
|
# A module can be listed more than once in obj-m resulting in
|
||||||
|
|
|
@ -227,8 +227,8 @@ static struct undef_hook arm_break_hook = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct undef_hook thumb_break_hook = {
|
static struct undef_hook thumb_break_hook = {
|
||||||
.instr_mask = 0xffff,
|
.instr_mask = 0xffffffff,
|
||||||
.instr_val = 0xde01,
|
.instr_val = 0x0000de01,
|
||||||
.cpsr_mask = PSR_T_BIT,
|
.cpsr_mask = PSR_T_BIT,
|
||||||
.cpsr_val = PSR_T_BIT,
|
.cpsr_val = PSR_T_BIT,
|
||||||
.fn = break_trap,
|
.fn = break_trap,
|
||||||
|
|
|
@ -155,8 +155,8 @@ static const char * const tegra_dt_board_compat[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
|
DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
|
||||||
.l2c_aux_val = 0x3c400001,
|
.l2c_aux_val = 0x3c400000,
|
||||||
.l2c_aux_mask = 0xc20fc3fe,
|
.l2c_aux_mask = 0xc20fc3ff,
|
||||||
.smp = smp_ops(tegra_smp_ops),
|
.smp = smp_ops(tegra_smp_ops),
|
||||||
.map_io = tegra_map_common_io,
|
.map_io = tegra_map_common_io,
|
||||||
.init_early = tegra_init_early,
|
.init_early = tegra_init_early,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* VMA_VM_FLAGS
|
* VMA_VM_FLAGS
|
||||||
* VM_EXEC
|
* VM_EXEC
|
||||||
*/
|
*/
|
||||||
|
#include <linux/const.h>
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
* act_mm - get current->active_mm
|
* act_mm - get current->active_mm
|
||||||
*/
|
*/
|
||||||
.macro act_mm, rd
|
.macro act_mm, rd
|
||||||
bic \rd, sp, #8128
|
bic \rd, sp, #(THREAD_SIZE - 1) & ~63
|
||||||
bic \rd, \rd, #63
|
bic \rd, \rd, #63
|
||||||
ldr \rd, [\rd, #TI_TASK]
|
ldr \rd, [\rd, #TI_TASK]
|
||||||
ldr \rd, [\rd, #TSK_ACTIVE_MM]
|
ldr \rd, [\rd, #TSK_ACTIVE_MM]
|
||||||
|
|
|
@ -258,8 +258,10 @@ struct kvm_vcpu_arch {
|
||||||
* CP14 and CP15 live in the same array, as they are backed by the
|
* CP14 and CP15 live in the same array, as they are backed by the
|
||||||
* same system registers.
|
* same system registers.
|
||||||
*/
|
*/
|
||||||
#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r)])
|
#define CPx_BIAS IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)
|
||||||
#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r)])
|
|
||||||
|
#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS])
|
||||||
|
#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS])
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||||
#define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r))
|
#define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r))
|
||||||
|
|
|
@ -256,6 +256,7 @@ extern int rbv_present,via_alt_mapping;
|
||||||
|
|
||||||
struct irq_desc;
|
struct irq_desc;
|
||||||
|
|
||||||
|
extern void via_l2_flush(int writeback);
|
||||||
extern void via_register_interrupts(void);
|
extern void via_register_interrupts(void);
|
||||||
extern void via_irq_enable(int);
|
extern void via_irq_enable(int);
|
||||||
extern void via_irq_disable(int);
|
extern void via_irq_disable(int);
|
||||||
|
|
|
@ -60,7 +60,6 @@ extern void iop_preinit(void);
|
||||||
extern void iop_init(void);
|
extern void iop_init(void);
|
||||||
extern void via_init(void);
|
extern void via_init(void);
|
||||||
extern void via_init_clock(irq_handler_t func);
|
extern void via_init_clock(irq_handler_t func);
|
||||||
extern void via_flush_cache(void);
|
|
||||||
extern void oss_init(void);
|
extern void oss_init(void);
|
||||||
extern void psc_init(void);
|
extern void psc_init(void);
|
||||||
extern void baboon_init(void);
|
extern void baboon_init(void);
|
||||||
|
@ -131,21 +130,6 @@ int __init mac_parse_bootinfo(const struct bi_record *record)
|
||||||
return unknown;
|
return unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Flip into 24bit mode for an instant - flushes the L2 cache card. We
|
|
||||||
* have to disable interrupts for this. Our IRQ handlers will crap
|
|
||||||
* themselves if they take an IRQ in 24bit mode!
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void mac_cache_card_flush(int writeback)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
via_flush_cache();
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init config_mac(void)
|
void __init config_mac(void)
|
||||||
{
|
{
|
||||||
if (!MACH_IS_MAC)
|
if (!MACH_IS_MAC)
|
||||||
|
@ -178,9 +162,8 @@ void __init config_mac(void)
|
||||||
* not.
|
* not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (macintosh_config->ident == MAC_MODEL_IICI
|
if (macintosh_config->ident == MAC_MODEL_IICI)
|
||||||
|| macintosh_config->ident == MAC_MODEL_IIFX)
|
mach_l2_flush = via_l2_flush;
|
||||||
mach_l2_flush = mac_cache_card_flush;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -299,10 +299,14 @@ void via_debug_dump(void)
|
||||||
* the system into 24-bit mode for an instant.
|
* the system into 24-bit mode for an instant.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void via_flush_cache(void)
|
void via_l2_flush(int writeback)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
via2[gBufB] &= ~VIA2B_vMode32;
|
via2[gBufB] &= ~VIA2B_vMode32;
|
||||||
via2[gBufB] |= VIA2B_vMode32;
|
via2[gBufB] |= VIA2B_vMode32;
|
||||||
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -430,20 +430,20 @@ NESTED(nmi_handler, PT_SIZE, sp)
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro __build_clear_fpe
|
.macro __build_clear_fpe
|
||||||
|
CLI
|
||||||
|
TRACE_IRQS_OFF
|
||||||
.set push
|
.set push
|
||||||
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
|
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
|
||||||
.set mips1
|
.set mips1
|
||||||
SET_HARDFLOAT
|
SET_HARDFLOAT
|
||||||
cfc1 a1, fcr31
|
cfc1 a1, fcr31
|
||||||
.set pop
|
.set pop
|
||||||
CLI
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro __build_clear_msa_fpe
|
.macro __build_clear_msa_fpe
|
||||||
_cfcmsa a1, MSA_CSR
|
|
||||||
CLI
|
CLI
|
||||||
TRACE_IRQS_OFF
|
TRACE_IRQS_OFF
|
||||||
|
_cfcmsa a1, MSA_CSR
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro __build_clear_ade
|
.macro __build_clear_ade
|
||||||
|
|
|
@ -123,9 +123,9 @@ static char *cm2_causes[32] = {
|
||||||
"COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
|
"COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
|
||||||
"0x08", "0x09", "0x0a", "0x0b",
|
"0x08", "0x09", "0x0a", "0x0b",
|
||||||
"0x0c", "0x0d", "0x0e", "0x0f",
|
"0x0c", "0x0d", "0x0e", "0x0f",
|
||||||
"0x10", "0x11", "0x12", "0x13",
|
"0x10", "INTVN_WR_ERR", "INTVN_RD_ERR", "0x13",
|
||||||
"0x14", "0x15", "0x16", "INTVN_WR_ERR",
|
"0x14", "0x15", "0x16", "0x17",
|
||||||
"INTVN_RD_ERR", "0x19", "0x1a", "0x1b",
|
"0x18", "0x19", "0x1a", "0x1b",
|
||||||
"0x1c", "0x1d", "0x1e", "0x1f"
|
"0x1c", "0x1d", "0x1e", "0x1f"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -809,7 +809,17 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||||
BOOTMEM_DEFAULT);
|
BOOTMEM_DEFAULT);
|
||||||
#endif
|
#endif
|
||||||
device_tree_init();
|
device_tree_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to reduce the possibility of kernel panic when failed to
|
||||||
|
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
|
||||||
|
* low memory as small as possible before plat_swiotlb_setup(), so
|
||||||
|
* make sparse_init() using top-down allocation.
|
||||||
|
*/
|
||||||
|
memblock_set_bottom_up(false);
|
||||||
sparse_init();
|
sparse_init();
|
||||||
|
memblock_set_bottom_up(true);
|
||||||
|
|
||||||
plat_swiotlb_setup();
|
plat_swiotlb_setup();
|
||||||
paging_init();
|
paging_init();
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,82 @@
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/cpufreq.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
#include <asm/cpu-type.h>
|
#include <asm/cpu-type.h>
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_FREQ
|
||||||
|
|
||||||
|
static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref);
|
||||||
|
static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref_freq);
|
||||||
|
static unsigned long glb_lpj_ref;
|
||||||
|
static unsigned long glb_lpj_ref_freq;
|
||||||
|
|
||||||
|
static int cpufreq_callback(struct notifier_block *nb,
|
||||||
|
unsigned long val, void *data)
|
||||||
|
{
|
||||||
|
struct cpufreq_freqs *freq = data;
|
||||||
|
struct cpumask *cpus = freq->policy->cpus;
|
||||||
|
unsigned long lpj;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip lpj numbers adjustment if the CPU-freq transition is safe for
|
||||||
|
* the loops delay. (Is this possible?)
|
||||||
|
*/
|
||||||
|
if (freq->flags & CPUFREQ_CONST_LOOPS)
|
||||||
|
return NOTIFY_OK;
|
||||||
|
|
||||||
|
/* Save the initial values of the lpjes for future scaling. */
|
||||||
|
if (!glb_lpj_ref) {
|
||||||
|
glb_lpj_ref = boot_cpu_data.udelay_val;
|
||||||
|
glb_lpj_ref_freq = freq->old;
|
||||||
|
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
per_cpu(pcp_lpj_ref, cpu) =
|
||||||
|
cpu_data[cpu].udelay_val;
|
||||||
|
per_cpu(pcp_lpj_ref_freq, cpu) = freq->old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust global lpj variable and per-CPU udelay_val number in
|
||||||
|
* accordance with the new CPU frequency.
|
||||||
|
*/
|
||||||
|
if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
|
||||||
|
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
|
||||||
|
loops_per_jiffy = cpufreq_scale(glb_lpj_ref,
|
||||||
|
glb_lpj_ref_freq,
|
||||||
|
freq->new);
|
||||||
|
|
||||||
|
for_each_cpu(cpu, cpus) {
|
||||||
|
lpj = cpufreq_scale(per_cpu(pcp_lpj_ref, cpu),
|
||||||
|
per_cpu(pcp_lpj_ref_freq, cpu),
|
||||||
|
freq->new);
|
||||||
|
cpu_data[cpu].udelay_val = (unsigned int)lpj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block cpufreq_notifier = {
|
||||||
|
.notifier_call = cpufreq_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init register_cpufreq_notifier(void)
|
||||||
|
{
|
||||||
|
return cpufreq_register_notifier(&cpufreq_notifier,
|
||||||
|
CPUFREQ_TRANSITION_NOTIFIER);
|
||||||
|
}
|
||||||
|
core_initcall(register_cpufreq_notifier);
|
||||||
|
|
||||||
|
#endif /* CONFIG_CPU_FREQ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* forward reference
|
* forward reference
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2044,8 +2044,9 @@ static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
|
||||||
static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
|
static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
|
||||||
size_t len, loff_t *pos)
|
size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct spu_context *ctx = file->private_data;
|
struct spu_context *ctx = file->private_data;
|
||||||
|
u32 stat, data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2054,11 +2055,16 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
spin_lock(&ctx->csa.register_lock);
|
spin_lock(&ctx->csa.register_lock);
|
||||||
ret = __spufs_mbox_info_read(ctx, buf, len, pos);
|
stat = ctx->csa.prob.mb_stat_R;
|
||||||
|
data = ctx->csa.prob.pu_mb_R;
|
||||||
spin_unlock(&ctx->csa.register_lock);
|
spin_unlock(&ctx->csa.register_lock);
|
||||||
spu_release_saved(ctx);
|
spu_release_saved(ctx);
|
||||||
|
|
||||||
return ret;
|
/* EOF if there's no entry in the mbox */
|
||||||
|
if (!(stat & 0x0000ff))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return simple_read_from_buffer(buf, len, pos, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations spufs_mbox_info_fops = {
|
static const struct file_operations spufs_mbox_info_fops = {
|
||||||
|
@ -2085,6 +2091,7 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
|
||||||
size_t len, loff_t *pos)
|
size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct spu_context *ctx = file->private_data;
|
struct spu_context *ctx = file->private_data;
|
||||||
|
u32 stat, data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||||
|
@ -2094,11 +2101,16 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
spin_lock(&ctx->csa.register_lock);
|
spin_lock(&ctx->csa.register_lock);
|
||||||
ret = __spufs_ibox_info_read(ctx, buf, len, pos);
|
stat = ctx->csa.prob.mb_stat_R;
|
||||||
|
data = ctx->csa.priv2.puint_mb_R;
|
||||||
spin_unlock(&ctx->csa.register_lock);
|
spin_unlock(&ctx->csa.register_lock);
|
||||||
spu_release_saved(ctx);
|
spu_release_saved(ctx);
|
||||||
|
|
||||||
return ret;
|
/* EOF if there's no entry in the ibox */
|
||||||
|
if (!(stat & 0xff0000))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return simple_read_from_buffer(buf, len, pos, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations spufs_ibox_info_fops = {
|
static const struct file_operations spufs_ibox_info_fops = {
|
||||||
|
@ -2107,6 +2119,11 @@ static const struct file_operations spufs_ibox_info_fops = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static size_t spufs_wbox_info_cnt(struct spu_context *ctx)
|
||||||
|
{
|
||||||
|
return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32);
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t __spufs_wbox_info_read(struct spu_context *ctx,
|
static ssize_t __spufs_wbox_info_read(struct spu_context *ctx,
|
||||||
char __user *buf, size_t len, loff_t *pos)
|
char __user *buf, size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
|
@ -2115,7 +2132,7 @@ static ssize_t __spufs_wbox_info_read(struct spu_context *ctx,
|
||||||
u32 wbox_stat;
|
u32 wbox_stat;
|
||||||
|
|
||||||
wbox_stat = ctx->csa.prob.mb_stat_R;
|
wbox_stat = ctx->csa.prob.mb_stat_R;
|
||||||
cnt = 4 - ((wbox_stat & 0x00ff00) >> 8);
|
cnt = spufs_wbox_info_cnt(ctx);
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
data[i] = ctx->csa.spu_mailbox_data[i];
|
data[i] = ctx->csa.spu_mailbox_data[i];
|
||||||
}
|
}
|
||||||
|
@ -2128,7 +2145,8 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
|
||||||
size_t len, loff_t *pos)
|
size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct spu_context *ctx = file->private_data;
|
struct spu_context *ctx = file->private_data;
|
||||||
int ret;
|
u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)];
|
||||||
|
int ret, count;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2137,11 +2155,13 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
spin_lock(&ctx->csa.register_lock);
|
spin_lock(&ctx->csa.register_lock);
|
||||||
ret = __spufs_wbox_info_read(ctx, buf, len, pos);
|
count = spufs_wbox_info_cnt(ctx);
|
||||||
|
memcpy(&data, &ctx->csa.spu_mailbox_data, sizeof(data));
|
||||||
spin_unlock(&ctx->csa.register_lock);
|
spin_unlock(&ctx->csa.register_lock);
|
||||||
spu_release_saved(ctx);
|
spu_release_saved(ctx);
|
||||||
|
|
||||||
return ret;
|
return simple_read_from_buffer(buf, len, pos, &data,
|
||||||
|
count * sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations spufs_wbox_info_fops = {
|
static const struct file_operations spufs_wbox_info_fops = {
|
||||||
|
@ -2150,27 +2170,33 @@ static const struct file_operations spufs_wbox_info_fops = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t __spufs_dma_info_read(struct spu_context *ctx,
|
static void spufs_get_dma_info(struct spu_context *ctx,
|
||||||
char __user *buf, size_t len, loff_t *pos)
|
struct spu_dma_info *info)
|
||||||
{
|
{
|
||||||
struct spu_dma_info info;
|
|
||||||
struct mfc_cq_sr *qp, *spuqp;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW;
|
info->dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW;
|
||||||
info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0];
|
info->dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0];
|
||||||
info.dma_info_status = ctx->csa.spu_chnldata_RW[24];
|
info->dma_info_status = ctx->csa.spu_chnldata_RW[24];
|
||||||
info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25];
|
info->dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25];
|
||||||
info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27];
|
info->dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27];
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
qp = &info.dma_info_command_data[i];
|
struct mfc_cq_sr *qp = &info->dma_info_command_data[i];
|
||||||
spuqp = &ctx->csa.priv2.spuq[i];
|
struct mfc_cq_sr *spuqp = &ctx->csa.priv2.spuq[i];
|
||||||
|
|
||||||
qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW;
|
qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW;
|
||||||
qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW;
|
qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW;
|
||||||
qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW;
|
qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW;
|
||||||
qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW;
|
qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t __spufs_dma_info_read(struct spu_context *ctx,
|
||||||
|
char __user *buf, size_t len, loff_t *pos)
|
||||||
|
{
|
||||||
|
struct spu_dma_info info;
|
||||||
|
|
||||||
|
spufs_get_dma_info(ctx, &info);
|
||||||
|
|
||||||
return simple_read_from_buffer(buf, len, pos, &info,
|
return simple_read_from_buffer(buf, len, pos, &info,
|
||||||
sizeof info);
|
sizeof info);
|
||||||
|
@ -2180,6 +2206,7 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
|
||||||
size_t len, loff_t *pos)
|
size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct spu_context *ctx = file->private_data;
|
struct spu_context *ctx = file->private_data;
|
||||||
|
struct spu_dma_info info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||||
|
@ -2189,11 +2216,12 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
spin_lock(&ctx->csa.register_lock);
|
spin_lock(&ctx->csa.register_lock);
|
||||||
ret = __spufs_dma_info_read(ctx, buf, len, pos);
|
spufs_get_dma_info(ctx, &info);
|
||||||
spin_unlock(&ctx->csa.register_lock);
|
spin_unlock(&ctx->csa.register_lock);
|
||||||
spu_release_saved(ctx);
|
spu_release_saved(ctx);
|
||||||
|
|
||||||
return ret;
|
return simple_read_from_buffer(buf, len, pos, &info,
|
||||||
|
sizeof(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations spufs_dma_info_fops = {
|
static const struct file_operations spufs_dma_info_fops = {
|
||||||
|
@ -2202,13 +2230,31 @@ static const struct file_operations spufs_dma_info_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void spufs_get_proxydma_info(struct spu_context *ctx,
|
||||||
|
struct spu_proxydma_info *info)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
info->proxydma_info_type = ctx->csa.prob.dma_querytype_RW;
|
||||||
|
info->proxydma_info_mask = ctx->csa.prob.dma_querymask_RW;
|
||||||
|
info->proxydma_info_status = ctx->csa.prob.dma_tagstatus_R;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
struct mfc_cq_sr *qp = &info->proxydma_info_command_data[i];
|
||||||
|
struct mfc_cq_sr *puqp = &ctx->csa.priv2.puq[i];
|
||||||
|
|
||||||
|
qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW;
|
||||||
|
qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW;
|
||||||
|
qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW;
|
||||||
|
qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx,
|
static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx,
|
||||||
char __user *buf, size_t len, loff_t *pos)
|
char __user *buf, size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct spu_proxydma_info info;
|
struct spu_proxydma_info info;
|
||||||
struct mfc_cq_sr *qp, *puqp;
|
|
||||||
int ret = sizeof info;
|
int ret = sizeof info;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (len < ret)
|
if (len < ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -2216,18 +2262,7 @@ static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx,
|
||||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW;
|
spufs_get_proxydma_info(ctx, &info);
|
||||||
info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW;
|
|
||||||
info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
qp = &info.proxydma_info_command_data[i];
|
|
||||||
puqp = &ctx->csa.priv2.puq[i];
|
|
||||||
|
|
||||||
qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW;
|
|
||||||
qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW;
|
|
||||||
qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW;
|
|
||||||
qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW;
|
|
||||||
}
|
|
||||||
|
|
||||||
return simple_read_from_buffer(buf, len, pos, &info,
|
return simple_read_from_buffer(buf, len, pos, &info,
|
||||||
sizeof info);
|
sizeof info);
|
||||||
|
@ -2237,17 +2272,19 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
|
||||||
size_t len, loff_t *pos)
|
size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct spu_context *ctx = file->private_data;
|
struct spu_context *ctx = file->private_data;
|
||||||
|
struct spu_proxydma_info info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = spu_acquire_saved(ctx);
|
ret = spu_acquire_saved(ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
spin_lock(&ctx->csa.register_lock);
|
spin_lock(&ctx->csa.register_lock);
|
||||||
ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
|
spufs_get_proxydma_info(ctx, &info);
|
||||||
spin_unlock(&ctx->csa.register_lock);
|
spin_unlock(&ctx->csa.register_lock);
|
||||||
spu_release_saved(ctx);
|
spu_release_saved(ctx);
|
||||||
|
|
||||||
return ret;
|
return simple_read_from_buffer(buf, len, pos, &info,
|
||||||
|
sizeof(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations spufs_proxydma_info_fops = {
|
static const struct file_operations spufs_proxydma_info_fops = {
|
||||||
|
|
|
@ -45,82 +45,79 @@ enum sparc_regset {
|
||||||
REGSET_FP,
|
REGSET_FP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int regwindow32_get(struct task_struct *target,
|
||||||
|
const struct pt_regs *regs,
|
||||||
|
u32 *uregs)
|
||||||
|
{
|
||||||
|
unsigned long reg_window = regs->u_regs[UREG_I6];
|
||||||
|
int size = 16 * sizeof(u32);
|
||||||
|
|
||||||
|
if (target == current) {
|
||||||
|
if (copy_from_user(uregs, (void __user *)reg_window, size))
|
||||||
|
return -EFAULT;
|
||||||
|
} else {
|
||||||
|
if (access_process_vm(target, reg_window, uregs, size,
|
||||||
|
FOLL_FORCE) != size)
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regwindow32_set(struct task_struct *target,
|
||||||
|
const struct pt_regs *regs,
|
||||||
|
u32 *uregs)
|
||||||
|
{
|
||||||
|
unsigned long reg_window = regs->u_regs[UREG_I6];
|
||||||
|
int size = 16 * sizeof(u32);
|
||||||
|
|
||||||
|
if (target == current) {
|
||||||
|
if (copy_to_user((void __user *)reg_window, uregs, size))
|
||||||
|
return -EFAULT;
|
||||||
|
} else {
|
||||||
|
if (access_process_vm(target, reg_window, uregs, size,
|
||||||
|
FOLL_FORCE | FOLL_WRITE) != size)
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int genregs32_get(struct task_struct *target,
|
static int genregs32_get(struct task_struct *target,
|
||||||
const struct user_regset *regset,
|
const struct user_regset *regset,
|
||||||
unsigned int pos, unsigned int count,
|
unsigned int pos, unsigned int count,
|
||||||
void *kbuf, void __user *ubuf)
|
void *kbuf, void __user *ubuf)
|
||||||
{
|
{
|
||||||
const struct pt_regs *regs = target->thread.kregs;
|
const struct pt_regs *regs = target->thread.kregs;
|
||||||
unsigned long __user *reg_window;
|
u32 uregs[16];
|
||||||
unsigned long *k = kbuf;
|
int ret;
|
||||||
unsigned long __user *u = ubuf;
|
|
||||||
unsigned long reg;
|
|
||||||
|
|
||||||
if (target == current)
|
if (target == current)
|
||||||
flush_user_windows();
|
flush_user_windows();
|
||||||
|
|
||||||
pos /= sizeof(reg);
|
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||||
count /= sizeof(reg);
|
regs->u_regs,
|
||||||
|
0, 16 * sizeof(u32));
|
||||||
|
if (ret || !count)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (kbuf) {
|
if (pos < 32 * sizeof(u32)) {
|
||||||
for (; count > 0 && pos < 16; count--)
|
if (regwindow32_get(target, regs, uregs))
|
||||||
*k++ = regs->u_regs[pos++];
|
|
||||||
|
|
||||||
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
|
|
||||||
reg_window -= 16;
|
|
||||||
for (; count > 0 && pos < 32; count--) {
|
|
||||||
if (get_user(*k++, ®_window[pos++]))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (; count > 0 && pos < 16; count--) {
|
|
||||||
if (put_user(regs->u_regs[pos++], u++))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
|
|
||||||
reg_window -= 16;
|
|
||||||
for (; count > 0 && pos < 32; count--) {
|
|
||||||
if (get_user(reg, ®_window[pos++]) ||
|
|
||||||
put_user(reg, u++))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (count > 0) {
|
|
||||||
switch (pos) {
|
|
||||||
case 32: /* PSR */
|
|
||||||
reg = regs->psr;
|
|
||||||
break;
|
|
||||||
case 33: /* PC */
|
|
||||||
reg = regs->pc;
|
|
||||||
break;
|
|
||||||
case 34: /* NPC */
|
|
||||||
reg = regs->npc;
|
|
||||||
break;
|
|
||||||
case 35: /* Y */
|
|
||||||
reg = regs->y;
|
|
||||||
break;
|
|
||||||
case 36: /* WIM */
|
|
||||||
case 37: /* TBR */
|
|
||||||
reg = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kbuf)
|
|
||||||
*k++ = reg;
|
|
||||||
else if (put_user(reg, u++))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
pos++;
|
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||||
count--;
|
uregs,
|
||||||
|
16 * sizeof(u32), 32 * sizeof(u32));
|
||||||
|
if (ret || !count)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
finish:
|
|
||||||
pos *= sizeof(reg);
|
|
||||||
count *= sizeof(reg);
|
|
||||||
|
|
||||||
return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
|
uregs[0] = regs->psr;
|
||||||
38 * sizeof(reg), -1);
|
uregs[1] = regs->pc;
|
||||||
|
uregs[2] = regs->npc;
|
||||||
|
uregs[3] = regs->y;
|
||||||
|
uregs[4] = 0; /* WIM */
|
||||||
|
uregs[5] = 0; /* TBR */
|
||||||
|
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||||
|
uregs,
|
||||||
|
32 * sizeof(u32), 38 * sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int genregs32_set(struct task_struct *target,
|
static int genregs32_set(struct task_struct *target,
|
||||||
|
@ -129,82 +126,53 @@ static int genregs32_set(struct task_struct *target,
|
||||||
const void *kbuf, const void __user *ubuf)
|
const void *kbuf, const void __user *ubuf)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = target->thread.kregs;
|
struct pt_regs *regs = target->thread.kregs;
|
||||||
unsigned long __user *reg_window;
|
u32 uregs[16];
|
||||||
const unsigned long *k = kbuf;
|
u32 psr;
|
||||||
const unsigned long __user *u = ubuf;
|
int ret;
|
||||||
unsigned long reg;
|
|
||||||
|
|
||||||
if (target == current)
|
if (target == current)
|
||||||
flush_user_windows();
|
flush_user_windows();
|
||||||
|
|
||||||
pos /= sizeof(reg);
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
count /= sizeof(reg);
|
regs->u_regs,
|
||||||
|
0, 16 * sizeof(u32));
|
||||||
|
if (ret || !count)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (kbuf) {
|
if (pos < 32 * sizeof(u32)) {
|
||||||
for (; count > 0 && pos < 16; count--)
|
if (regwindow32_get(target, regs, uregs))
|
||||||
regs->u_regs[pos++] = *k++;
|
|
||||||
|
|
||||||
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
|
|
||||||
reg_window -= 16;
|
|
||||||
for (; count > 0 && pos < 32; count--) {
|
|
||||||
if (put_user(*k++, ®_window[pos++]))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (; count > 0 && pos < 16; count--) {
|
|
||||||
if (get_user(reg, u++))
|
|
||||||
return -EFAULT;
|
|
||||||
regs->u_regs[pos++] = reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
|
|
||||||
reg_window -= 16;
|
|
||||||
for (; count > 0 && pos < 32; count--) {
|
|
||||||
if (get_user(reg, u++) ||
|
|
||||||
put_user(reg, ®_window[pos++]))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (count > 0) {
|
|
||||||
unsigned long psr;
|
|
||||||
|
|
||||||
if (kbuf)
|
|
||||||
reg = *k++;
|
|
||||||
else if (get_user(reg, u++))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
switch (pos) {
|
uregs,
|
||||||
case 32: /* PSR */
|
16 * sizeof(u32), 32 * sizeof(u32));
|
||||||
psr = regs->psr;
|
if (ret)
|
||||||
psr &= ~(PSR_ICC | PSR_SYSCALL);
|
return ret;
|
||||||
psr |= (reg & (PSR_ICC | PSR_SYSCALL));
|
if (regwindow32_set(target, regs, uregs))
|
||||||
regs->psr = psr;
|
return -EFAULT;
|
||||||
break;
|
if (!count)
|
||||||
case 33: /* PC */
|
return 0;
|
||||||
regs->pc = reg;
|
|
||||||
break;
|
|
||||||
case 34: /* NPC */
|
|
||||||
regs->npc = reg;
|
|
||||||
break;
|
|
||||||
case 35: /* Y */
|
|
||||||
regs->y = reg;
|
|
||||||
break;
|
|
||||||
case 36: /* WIM */
|
|
||||||
case 37: /* TBR */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos++;
|
|
||||||
count--;
|
|
||||||
}
|
}
|
||||||
finish:
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
pos *= sizeof(reg);
|
&psr,
|
||||||
count *= sizeof(reg);
|
32 * sizeof(u32), 33 * sizeof(u32));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) |
|
||||||
|
(psr & (PSR_ICC | PSR_SYSCALL));
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
|
®s->pc,
|
||||||
|
33 * sizeof(u32), 34 * sizeof(u32));
|
||||||
|
if (ret || !count)
|
||||||
|
return ret;
|
||||||
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
|
®s->y,
|
||||||
|
34 * sizeof(u32), 35 * sizeof(u32));
|
||||||
|
if (ret || !count)
|
||||||
|
return ret;
|
||||||
return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
||||||
38 * sizeof(reg), -1);
|
35 * sizeof(u32), 38 * sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fpregs32_get(struct task_struct *target,
|
static int fpregs32_get(struct task_struct *target,
|
||||||
|
|
|
@ -270,6 +270,7 @@
|
||||||
#define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */
|
#define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */
|
||||||
#define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */
|
#define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */
|
||||||
#define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */
|
#define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */
|
||||||
|
#define X86_FEATURE_AMD_STIBP_ALWAYS_ON (13*32+17) /* "" Single Thread Indirect Branch Predictors always-on preferred */
|
||||||
#define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */
|
#define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */
|
||||||
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
|
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
|
||||||
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
|
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
|
||||||
|
@ -308,7 +309,6 @@
|
||||||
#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
|
#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
|
||||||
#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
|
#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
|
||||||
|
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
|
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
|
||||||
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
|
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
|
||||||
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
|
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
|
||||||
|
|
|
@ -178,6 +178,7 @@ enum spectre_v2_mitigation {
|
||||||
enum spectre_v2_user_mitigation {
|
enum spectre_v2_user_mitigation {
|
||||||
SPECTRE_V2_USER_NONE,
|
SPECTRE_V2_USER_NONE,
|
||||||
SPECTRE_V2_USER_STRICT,
|
SPECTRE_V2_USER_STRICT,
|
||||||
|
SPECTRE_V2_USER_STRICT_PREFERRED,
|
||||||
SPECTRE_V2_USER_PRCTL,
|
SPECTRE_V2_USER_PRCTL,
|
||||||
SPECTRE_V2_USER_SECCOMP,
|
SPECTRE_V2_USER_SECCOMP,
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,7 @@ static u64 x86_spec_ctrl_mask = SPEC_CTRL_IBRS;
|
||||||
u64 x86_amd_ls_cfg_base;
|
u64 x86_amd_ls_cfg_base;
|
||||||
u64 x86_amd_ls_cfg_ssbd_mask;
|
u64 x86_amd_ls_cfg_ssbd_mask;
|
||||||
|
|
||||||
/* Control conditional STIPB in switch_to() */
|
/* Control conditional STIBP in switch_to() */
|
||||||
DEFINE_STATIC_KEY_FALSE(switch_to_cond_stibp);
|
DEFINE_STATIC_KEY_FALSE(switch_to_cond_stibp);
|
||||||
/* Control conditional IBPB in switch_mm() */
|
/* Control conditional IBPB in switch_mm() */
|
||||||
DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb);
|
DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb);
|
||||||
|
@ -558,7 +558,8 @@ early_param("nospectre_v1", nospectre_v1_cmdline);
|
||||||
|
|
||||||
static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
|
static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
|
||||||
|
|
||||||
static enum spectre_v2_user_mitigation spectre_v2_user = SPECTRE_V2_USER_NONE;
|
static enum spectre_v2_user_mitigation spectre_v2_user_stibp = SPECTRE_V2_USER_NONE;
|
||||||
|
static enum spectre_v2_user_mitigation spectre_v2_user_ibpb = SPECTRE_V2_USER_NONE;
|
||||||
|
|
||||||
#ifdef RETPOLINE
|
#ifdef RETPOLINE
|
||||||
static bool spectre_v2_bad_module;
|
static bool spectre_v2_bad_module;
|
||||||
|
@ -609,10 +610,11 @@ enum spectre_v2_user_cmd {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const spectre_v2_user_strings[] = {
|
static const char * const spectre_v2_user_strings[] = {
|
||||||
[SPECTRE_V2_USER_NONE] = "User space: Vulnerable",
|
[SPECTRE_V2_USER_NONE] = "User space: Vulnerable",
|
||||||
[SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection",
|
[SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection",
|
||||||
[SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl",
|
[SPECTRE_V2_USER_STRICT_PREFERRED] = "User space: Mitigation: STIBP always-on protection",
|
||||||
[SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl",
|
[SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl",
|
||||||
|
[SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
|
@ -723,23 +725,36 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
|
||||||
pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n",
|
pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n",
|
||||||
static_key_enabled(&switch_mm_always_ibpb) ?
|
static_key_enabled(&switch_mm_always_ibpb) ?
|
||||||
"always-on" : "conditional");
|
"always-on" : "conditional");
|
||||||
|
|
||||||
|
spectre_v2_user_ibpb = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If enhanced IBRS is enabled no STIPB required */
|
/*
|
||||||
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
|
* If enhanced IBRS is enabled or SMT impossible, STIBP is not
|
||||||
|
* required.
|
||||||
|
*/
|
||||||
|
if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If SMT is not possible or STIBP is not available clear the STIPB
|
* At this point, an STIBP mode other than "off" has been set.
|
||||||
* mode.
|
* If STIBP support is not being forced, check if STIBP always-on
|
||||||
|
* is preferred.
|
||||||
*/
|
*/
|
||||||
if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP))
|
if (mode != SPECTRE_V2_USER_STRICT &&
|
||||||
|
boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
|
||||||
|
mode = SPECTRE_V2_USER_STRICT_PREFERRED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If STIBP is not available, clear the STIBP mode.
|
||||||
|
*/
|
||||||
|
if (!boot_cpu_has(X86_FEATURE_STIBP))
|
||||||
mode = SPECTRE_V2_USER_NONE;
|
mode = SPECTRE_V2_USER_NONE;
|
||||||
|
|
||||||
|
spectre_v2_user_stibp = mode;
|
||||||
|
|
||||||
set_mode:
|
set_mode:
|
||||||
spectre_v2_user = mode;
|
pr_info("%s\n", spectre_v2_user_strings[mode]);
|
||||||
/* Only print the STIBP mode when SMT possible */
|
|
||||||
if (smt_possible)
|
|
||||||
pr_info("%s\n", spectre_v2_user_strings[mode]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const spectre_v2_strings[] = {
|
static const char * const spectre_v2_strings[] = {
|
||||||
|
@ -979,10 +994,11 @@ void arch_smt_update(void)
|
||||||
{
|
{
|
||||||
mutex_lock(&spec_ctrl_mutex);
|
mutex_lock(&spec_ctrl_mutex);
|
||||||
|
|
||||||
switch (spectre_v2_user) {
|
switch (spectre_v2_user_stibp) {
|
||||||
case SPECTRE_V2_USER_NONE:
|
case SPECTRE_V2_USER_NONE:
|
||||||
break;
|
break;
|
||||||
case SPECTRE_V2_USER_STRICT:
|
case SPECTRE_V2_USER_STRICT:
|
||||||
|
case SPECTRE_V2_USER_STRICT_PREFERRED:
|
||||||
update_stibp_strict();
|
update_stibp_strict();
|
||||||
break;
|
break;
|
||||||
case SPECTRE_V2_USER_PRCTL:
|
case SPECTRE_V2_USER_PRCTL:
|
||||||
|
@ -1211,13 +1227,19 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||||
{
|
{
|
||||||
switch (ctrl) {
|
switch (ctrl) {
|
||||||
case PR_SPEC_ENABLE:
|
case PR_SPEC_ENABLE:
|
||||||
if (spectre_v2_user == SPECTRE_V2_USER_NONE)
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* Indirect branch speculation is always disabled in strict
|
* Indirect branch speculation is always disabled in strict
|
||||||
* mode.
|
* mode. It can neither be enabled if it was force-disabled
|
||||||
|
* by a previous prctl call.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED ||
|
||||||
|
task_spec_ib_force_disable(task))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
task_clear_spec_ib_disable(task);
|
task_clear_spec_ib_disable(task);
|
||||||
task_update_spec_tif(task);
|
task_update_spec_tif(task);
|
||||||
|
@ -1228,9 +1250,12 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||||
* Indirect branch speculation is always allowed when
|
* Indirect branch speculation is always allowed when
|
||||||
* mitigation is force disabled.
|
* mitigation is force disabled.
|
||||||
*/
|
*/
|
||||||
if (spectre_v2_user == SPECTRE_V2_USER_NONE)
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
|
||||||
return 0;
|
return 0;
|
||||||
task_set_spec_ib_disable(task);
|
task_set_spec_ib_disable(task);
|
||||||
if (ctrl == PR_SPEC_FORCE_DISABLE)
|
if (ctrl == PR_SPEC_FORCE_DISABLE)
|
||||||
|
@ -1261,7 +1286,8 @@ void arch_seccomp_spec_mitigate(struct task_struct *task)
|
||||||
{
|
{
|
||||||
if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP)
|
if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP)
|
||||||
ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE);
|
ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE);
|
||||||
if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP)
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP)
|
||||||
ib_prctl_set(task, PR_SPEC_FORCE_DISABLE);
|
ib_prctl_set(task, PR_SPEC_FORCE_DISABLE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1290,21 +1316,24 @@ static int ib_prctl_get(struct task_struct *task)
|
||||||
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
|
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
|
||||||
return PR_SPEC_NOT_AFFECTED;
|
return PR_SPEC_NOT_AFFECTED;
|
||||||
|
|
||||||
switch (spectre_v2_user) {
|
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
|
||||||
case SPECTRE_V2_USER_NONE:
|
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
|
||||||
return PR_SPEC_ENABLE;
|
return PR_SPEC_ENABLE;
|
||||||
case SPECTRE_V2_USER_PRCTL:
|
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
|
||||||
case SPECTRE_V2_USER_SECCOMP:
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
|
||||||
|
return PR_SPEC_DISABLE;
|
||||||
|
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
|
||||||
|
spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
|
||||||
|
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) {
|
||||||
if (task_spec_ib_force_disable(task))
|
if (task_spec_ib_force_disable(task))
|
||||||
return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
|
return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
|
||||||
if (task_spec_ib_disable(task))
|
if (task_spec_ib_disable(task))
|
||||||
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
|
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
|
||||||
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
|
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
|
||||||
case SPECTRE_V2_USER_STRICT:
|
} else
|
||||||
return PR_SPEC_DISABLE;
|
|
||||||
default:
|
|
||||||
return PR_SPEC_NOT_AFFECTED;
|
return PR_SPEC_NOT_AFFECTED;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
|
int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
|
||||||
|
@ -1445,11 +1474,13 @@ static char *stibp_state(void)
|
||||||
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
|
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
switch (spectre_v2_user) {
|
switch (spectre_v2_user_stibp) {
|
||||||
case SPECTRE_V2_USER_NONE:
|
case SPECTRE_V2_USER_NONE:
|
||||||
return ", STIBP: disabled";
|
return ", STIBP: disabled";
|
||||||
case SPECTRE_V2_USER_STRICT:
|
case SPECTRE_V2_USER_STRICT:
|
||||||
return ", STIBP: forced";
|
return ", STIBP: forced";
|
||||||
|
case SPECTRE_V2_USER_STRICT_PREFERRED:
|
||||||
|
return ", STIBP: always-on";
|
||||||
case SPECTRE_V2_USER_PRCTL:
|
case SPECTRE_V2_USER_PRCTL:
|
||||||
case SPECTRE_V2_USER_SECCOMP:
|
case SPECTRE_V2_USER_SECCOMP:
|
||||||
if (static_key_enabled(&switch_to_cond_stibp))
|
if (static_key_enabled(&switch_to_cond_stibp))
|
||||||
|
|
|
@ -319,28 +319,20 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
|
||||||
u64 msr = x86_spec_ctrl_base;
|
u64 msr = x86_spec_ctrl_base;
|
||||||
bool updmsr = false;
|
bool updmsr = false;
|
||||||
|
|
||||||
/*
|
/* Handle change of TIF_SSBD depending on the mitigation method. */
|
||||||
* If TIF_SSBD is different, select the proper mitigation
|
if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) {
|
||||||
* method. Note that if SSBD mitigation is disabled or permanentely
|
if (tif_diff & _TIF_SSBD)
|
||||||
* enabled this branch can't be taken because nothing can set
|
|
||||||
* TIF_SSBD.
|
|
||||||
*/
|
|
||||||
if (tif_diff & _TIF_SSBD) {
|
|
||||||
if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) {
|
|
||||||
amd_set_ssb_virt_state(tifn);
|
amd_set_ssb_virt_state(tifn);
|
||||||
} else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) {
|
} else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) {
|
||||||
|
if (tif_diff & _TIF_SSBD)
|
||||||
amd_set_core_ssb_state(tifn);
|
amd_set_core_ssb_state(tifn);
|
||||||
} else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
|
} else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
|
||||||
static_cpu_has(X86_FEATURE_AMD_SSBD)) {
|
static_cpu_has(X86_FEATURE_AMD_SSBD)) {
|
||||||
msr |= ssbd_tif_to_spec_ctrl(tifn);
|
updmsr |= !!(tif_diff & _TIF_SSBD);
|
||||||
updmsr = true;
|
msr |= ssbd_tif_to_spec_ctrl(tifn);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */
|
||||||
* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled,
|
|
||||||
* otherwise avoid the MSR write.
|
|
||||||
*/
|
|
||||||
if (IS_ENABLED(CONFIG_SMP) &&
|
if (IS_ENABLED(CONFIG_SMP) &&
|
||||||
static_branch_unlikely(&switch_to_cond_stibp)) {
|
static_branch_unlikely(&switch_to_cond_stibp)) {
|
||||||
updmsr |= !!(tif_diff & _TIF_SPEC_IB);
|
updmsr |= !!(tif_diff & _TIF_SPEC_IB);
|
||||||
|
|
|
@ -19,7 +19,7 @@ static inline void switch_to_extra(struct task_struct *prev,
|
||||||
if (IS_ENABLED(CONFIG_SMP)) {
|
if (IS_ENABLED(CONFIG_SMP)) {
|
||||||
/*
|
/*
|
||||||
* Avoid __switch_to_xtra() invocation when conditional
|
* Avoid __switch_to_xtra() invocation when conditional
|
||||||
* STIPB is disabled and the only different bit is
|
* STIBP is disabled and the only different bit is
|
||||||
* TIF_SPEC_IB. For CONFIG_SMP=n TIF_SPEC_IB is not
|
* TIF_SPEC_IB. For CONFIG_SMP=n TIF_SPEC_IB is not
|
||||||
* in the TIF_WORK_CTXSW masks.
|
* in the TIF_WORK_CTXSW masks.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -162,6 +162,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ /* Handle problems with rebooting on Apple MacBook6,1 */
|
||||||
|
.callback = set_pci_reboot,
|
||||||
|
.ident = "Apple MacBook6,1",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ /* Handle problems with rebooting on Apple MacBookPro5 */
|
{ /* Handle problems with rebooting on Apple MacBookPro5 */
|
||||||
.callback = set_pci_reboot,
|
.callback = set_pci_reboot,
|
||||||
.ident = "Apple MacBookPro5",
|
.ident = "Apple MacBookPro5",
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
#include <asm/hpet.h>
|
#include <asm/hpet.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
__visible volatile unsigned long jiffies __cacheline_aligned_in_smp = INITIAL_JIFFIES;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned long profile_pc(struct pt_regs *regs)
|
unsigned long profile_pc(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long pc = instruction_pointer(regs);
|
unsigned long pc = instruction_pointer(regs);
|
||||||
|
|
|
@ -34,13 +34,13 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT)
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
OUTPUT_ARCH(i386)
|
OUTPUT_ARCH(i386)
|
||||||
ENTRY(phys_startup_32)
|
ENTRY(phys_startup_32)
|
||||||
jiffies = jiffies_64;
|
|
||||||
#else
|
#else
|
||||||
OUTPUT_ARCH(i386:x86-64)
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
ENTRY(phys_startup_64)
|
ENTRY(phys_startup_64)
|
||||||
jiffies_64 = jiffies;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
jiffies = jiffies_64;
|
||||||
|
|
||||||
#if defined(CONFIG_X86_64)
|
#if defined(CONFIG_X86_64)
|
||||||
/*
|
/*
|
||||||
* On 64-bit, align RODATA to 2MB so we retain large page mappings for
|
* On 64-bit, align RODATA to 2MB so we retain large page mappings for
|
||||||
|
|
|
@ -2250,7 +2250,7 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr
|
||||||
dst->iopm_base_pa = from->iopm_base_pa;
|
dst->iopm_base_pa = from->iopm_base_pa;
|
||||||
dst->msrpm_base_pa = from->msrpm_base_pa;
|
dst->msrpm_base_pa = from->msrpm_base_pa;
|
||||||
dst->tsc_offset = from->tsc_offset;
|
dst->tsc_offset = from->tsc_offset;
|
||||||
dst->asid = from->asid;
|
/* asid not copied, it is handled manually for svm->vmcb. */
|
||||||
dst->tlb_ctl = from->tlb_ctl;
|
dst->tlb_ctl = from->tlb_ctl;
|
||||||
dst->int_ctl = from->int_ctl;
|
dst->int_ctl = from->int_ctl;
|
||||||
dst->int_vector = from->int_vector;
|
dst->int_vector = from->int_vector;
|
||||||
|
|
|
@ -7844,7 +7844,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (exit_reason) {
|
switch ((u16)exit_reason) {
|
||||||
case EXIT_REASON_EXCEPTION_NMI:
|
case EXIT_REASON_EXCEPTION_NMI:
|
||||||
if (is_nmi(intr_info))
|
if (is_nmi(intr_info))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -109,8 +109,6 @@ __ref void *alloc_low_pages(unsigned int num)
|
||||||
} else {
|
} else {
|
||||||
pfn = pgt_buf_end;
|
pfn = pgt_buf_end;
|
||||||
pgt_buf_end += num;
|
pgt_buf_end += num;
|
||||||
printk(KERN_DEBUG "BRK [%#010lx, %#010lx] PGTABLE\n",
|
|
||||||
pfn << PAGE_SHIFT, (pgt_buf_end << PAGE_SHIFT) - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
|
|
|
@ -170,7 +170,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
|
||||||
* possibly drop references to the power resources in use.
|
* possibly drop references to the power resources in use.
|
||||||
*/
|
*/
|
||||||
state = ACPI_STATE_D3_HOT;
|
state = ACPI_STATE_D3_HOT;
|
||||||
/* If _PR3 is not available, use D3hot as the target state. */
|
/* If D3cold is not supported, use D3hot as the target state. */
|
||||||
if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
|
if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
|
||||||
target_state = state;
|
target_state = state;
|
||||||
} else if (!device->power.states[state].flags.valid) {
|
} else if (!device->power.states[state].flags.valid) {
|
||||||
|
|
|
@ -907,12 +907,9 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
|
||||||
|
|
||||||
if (buffer.length && package
|
if (buffer.length && package
|
||||||
&& package->type == ACPI_TYPE_PACKAGE
|
&& package->type == ACPI_TYPE_PACKAGE
|
||||||
&& package->package.count) {
|
&& package->package.count)
|
||||||
int err = acpi_extract_power_resources(package, 0,
|
acpi_extract_power_resources(package, 0, &ps->resources);
|
||||||
&ps->resources);
|
|
||||||
if (!err)
|
|
||||||
device->power.flags.power_resources = 1;
|
|
||||||
}
|
|
||||||
ACPI_FREE(buffer.pointer);
|
ACPI_FREE(buffer.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,14 +956,27 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
|
||||||
acpi_bus_init_power_state(device, i);
|
acpi_bus_init_power_state(device, i);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources);
|
INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources);
|
||||||
if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
|
|
||||||
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
|
|
||||||
|
|
||||||
/* Set defaults for D0 and D3hot states (always valid) */
|
/* Set the defaults for D0 and D3hot (always supported). */
|
||||||
device->power.states[ACPI_STATE_D0].flags.valid = 1;
|
device->power.states[ACPI_STATE_D0].flags.valid = 1;
|
||||||
device->power.states[ACPI_STATE_D0].power = 100;
|
device->power.states[ACPI_STATE_D0].power = 100;
|
||||||
device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1;
|
device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use power resources only if the D0 list of them is populated, because
|
||||||
|
* some platforms may provide _PR3 only to indicate D3cold support and
|
||||||
|
* in those cases the power resources list returned by it may be bogus.
|
||||||
|
*/
|
||||||
|
if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) {
|
||||||
|
device->power.flags.power_resources = 1;
|
||||||
|
/*
|
||||||
|
* D3cold is supported if the D3hot list of power resources is
|
||||||
|
* not empty.
|
||||||
|
*/
|
||||||
|
if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
|
||||||
|
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (acpi_bus_init_power(device))
|
if (acpi_bus_init_power(device))
|
||||||
device->flags.power_manageable = 0;
|
device->flags.power_manageable = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -831,8 +831,10 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
|
||||||
|
|
||||||
error = kobject_init_and_add(&hotplug->kobj,
|
error = kobject_init_and_add(&hotplug->kobj,
|
||||||
&acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name);
|
&acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name);
|
||||||
if (error)
|
if (error) {
|
||||||
|
kobject_put(&hotplug->kobj);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
kobject_uevent(&hotplug->kobj, KOBJ_ADD);
|
kobject_uevent(&hotplug->kobj, KOBJ_ADD);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -134,16 +134,14 @@ static int num_called;
|
||||||
static void __init dw_apb_timer_init(struct device_node *timer)
|
static void __init dw_apb_timer_init(struct device_node *timer)
|
||||||
{
|
{
|
||||||
switch (num_called) {
|
switch (num_called) {
|
||||||
case 0:
|
|
||||||
pr_debug("%s: found clockevent timer\n", __func__);
|
|
||||||
add_clockevent(timer);
|
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
pr_debug("%s: found clocksource timer\n", __func__);
|
pr_debug("%s: found clocksource timer\n", __func__);
|
||||||
add_clocksource(timer);
|
add_clocksource(timer);
|
||||||
init_sched_clock();
|
init_sched_clock();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
pr_debug("%s: found clockevent timer\n", __func__);
|
||||||
|
add_clockevent(timer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -412,7 +412,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
|
||||||
ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
|
ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
|
||||||
&kdev->kobj, "state%d", i);
|
&kdev->kobj, "state%d", i);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(kobj);
|
kobject_put(&kobj->kobj);
|
||||||
goto error_state;
|
goto error_state;
|
||||||
}
|
}
|
||||||
kobject_uevent(&kobj->kobj, KOBJ_ADD);
|
kobject_uevent(&kobj->kobj, KOBJ_ADD);
|
||||||
|
@ -542,7 +542,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
|
||||||
ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
|
ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
|
||||||
&kdev->kobj, "driver");
|
&kdev->kobj, "driver");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(kdrv);
|
kobject_put(&kdrv->kobj);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
|
||||||
error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
|
error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
|
||||||
"cpuidle");
|
"cpuidle");
|
||||||
if (error) {
|
if (error) {
|
||||||
kfree(kdev);
|
kobject_put(&kdev->kobj);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -585,8 +585,10 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
|
||||||
ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
|
ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
|
||||||
NULL, "%s", short_name);
|
NULL, "%s", short_name);
|
||||||
kfree(short_name);
|
kfree(short_name);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
kobject_put(&new_var->kobj);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
kobject_uevent(&new_var->kobj, KOBJ_ADD);
|
kobject_uevent(&new_var->kobj, KOBJ_ADD);
|
||||||
efivar_entry_add(new_var, &efivar_sysfs_list);
|
efivar_entry_add(new_var, &efivar_sysfs_list);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/smu.h>
|
#include <asm/smu.h>
|
||||||
|
|
||||||
|
@ -133,14 +134,6 @@ static int create_cpu_loop(int cpu)
|
||||||
s32 tmax;
|
s32 tmax;
|
||||||
int fmin;
|
int fmin;
|
||||||
|
|
||||||
/* Get PID params from the appropriate SAT */
|
|
||||||
hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
|
|
||||||
if (hdr == NULL) {
|
|
||||||
printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
|
|
||||||
|
|
||||||
/* Get FVT params to get Tmax; if not found, assume default */
|
/* Get FVT params to get Tmax; if not found, assume default */
|
||||||
hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
|
hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
|
||||||
if (hdr) {
|
if (hdr) {
|
||||||
|
@ -153,6 +146,16 @@ static int create_cpu_loop(int cpu)
|
||||||
if (tmax < cpu_all_tmax)
|
if (tmax < cpu_all_tmax)
|
||||||
cpu_all_tmax = tmax;
|
cpu_all_tmax = tmax;
|
||||||
|
|
||||||
|
kfree(hdr);
|
||||||
|
|
||||||
|
/* Get PID params from the appropriate SAT */
|
||||||
|
hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Darwin has a minimum fan speed of 1000 rpm for the 4-way and
|
* Darwin has a minimum fan speed of 1000 rpm for the 4-way and
|
||||||
* 515 for the 2-way. That appears to be overkill, so for now,
|
* 515 for the 2-way. That appears to be overkill, so for now,
|
||||||
|
@ -175,6 +178,9 @@ static int create_cpu_loop(int cpu)
|
||||||
pid.min = fmin;
|
pid.min = fmin;
|
||||||
|
|
||||||
wf_cpu_pid_init(&cpu_pid[cpu], &pid);
|
wf_cpu_pid_init(&cpu_pid[cpu], &pid);
|
||||||
|
|
||||||
|
kfree(hdr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7038,7 +7038,8 @@ static int md_open(struct block_device *bdev, fmode_t mode)
|
||||||
*/
|
*/
|
||||||
mddev_put(mddev);
|
mddev_put(mddev);
|
||||||
/* Wait until bdev->bd_disk is definitely gone */
|
/* Wait until bdev->bd_disk is definitely gone */
|
||||||
flush_workqueue(md_misc_wq);
|
if (work_pending(&mddev->del_work))
|
||||||
|
flush_workqueue(md_misc_wq);
|
||||||
/* Then retry the open from the top */
|
/* Then retry the open from the top */
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
|
||||||
|
|
||||||
if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
|
if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
|
||||||
err("tuner i2c write failed.");
|
err("tuner i2c write failed.");
|
||||||
ret = -EREMOTEIO;
|
return -EREMOTEIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
|
if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
|
||||||
|
|
|
@ -243,22 +243,18 @@ int go7007_snd_init(struct go7007 *go)
|
||||||
gosnd->capturing = 0;
|
gosnd->capturing = 0;
|
||||||
ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
|
ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
|
||||||
&gosnd->card);
|
&gosnd->card);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
kfree(gosnd);
|
goto free_snd;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
|
ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
|
||||||
&go7007_snd_device_ops);
|
&go7007_snd_device_ops);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
kfree(gosnd);
|
goto free_card;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
|
ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
snd_card_free(gosnd->card);
|
goto free_card;
|
||||||
kfree(gosnd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
|
strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
|
||||||
strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
|
strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
|
||||||
strlcpy(gosnd->card->longname, gosnd->card->shortname,
|
strlcpy(gosnd->card->longname, gosnd->card->shortname,
|
||||||
|
@ -269,11 +265,8 @@ int go7007_snd_init(struct go7007 *go)
|
||||||
&go7007_snd_capture_ops);
|
&go7007_snd_capture_ops);
|
||||||
|
|
||||||
ret = snd_card_register(gosnd->card);
|
ret = snd_card_register(gosnd->card);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
snd_card_free(gosnd->card);
|
goto free_card;
|
||||||
kfree(gosnd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
gosnd->substream = NULL;
|
gosnd->substream = NULL;
|
||||||
go->snd_context = gosnd;
|
go->snd_context = gosnd;
|
||||||
|
@ -281,6 +274,12 @@ int go7007_snd_init(struct go7007 *go)
|
||||||
++dev;
|
++dev;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
free_card:
|
||||||
|
snd_card_free(gosnd->card);
|
||||||
|
free_snd:
|
||||||
|
kfree(gosnd);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(go7007_snd_init);
|
EXPORT_SYMBOL(go7007_snd_init);
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
|
buf = kzalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1457,7 +1457,7 @@ static int kvaser_usb_set_opt_mode(const struct kvaser_usb_net_priv *priv)
|
||||||
struct kvaser_msg *msg;
|
struct kvaser_msg *msg;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
|
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1590,7 +1590,7 @@ static int kvaser_usb_flush_queue(struct kvaser_usb_net_priv *priv)
|
||||||
struct kvaser_msg *msg;
|
struct kvaser_msg *msg;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
|
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ static void emac_timeout(struct net_device *dev)
|
||||||
/* Hardware start transmission.
|
/* Hardware start transmission.
|
||||||
* Send a packet to media from the upper layer.
|
* Send a packet to media from the upper layer.
|
||||||
*/
|
*/
|
||||||
static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct emac_board_info *db = netdev_priv(dev);
|
struct emac_board_info *db = netdev_priv(dev);
|
||||||
unsigned long channel;
|
unsigned long channel;
|
||||||
|
@ -446,7 +446,7 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
channel = db->tx_fifo_stat & 3;
|
channel = db->tx_fifo_stat & 3;
|
||||||
if (channel == 3)
|
if (channel == 3)
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
|
|
||||||
channel = (channel == 1 ? 1 : 0);
|
channel = (channel == 1 ? 1 : 0);
|
||||||
|
|
||||||
|
|
|
@ -3162,8 +3162,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
||||||
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
||||||
if (skb->data_len && hdr_len == len) {
|
if (skb->data_len && hdr_len == len) {
|
||||||
switch (hw->mac_type) {
|
switch (hw->mac_type) {
|
||||||
|
case e1000_82544: {
|
||||||
unsigned int pull_size;
|
unsigned int pull_size;
|
||||||
case e1000_82544:
|
|
||||||
/* Make sure we have room to chop off 4 bytes,
|
/* Make sure we have room to chop off 4 bytes,
|
||||||
* and that the end alignment will work out to
|
* and that the end alignment will work out to
|
||||||
* this hardware's requirements
|
* this hardware's requirements
|
||||||
|
@ -3184,6 +3185,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
len = skb_headlen(skb);
|
len = skb_headlen(skb);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -585,7 +585,6 @@ static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
|
||||||
|
|
||||||
#define er32(reg) __er32(hw, E1000_##reg)
|
#define er32(reg) __er32(hw, E1000_##reg)
|
||||||
|
|
||||||
s32 __ew32_prepare(struct e1000_hw *hw);
|
|
||||||
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val);
|
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val);
|
||||||
|
|
||||||
#define ew32(reg, val) __ew32(hw, E1000_##reg, (val))
|
#define ew32(reg, val) __ew32(hw, E1000_##reg, (val))
|
||||||
|
|
|
@ -136,14 +136,12 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = {
|
||||||
* has bit 24 set while ME is accessing MAC CSR registers, wait if it is set
|
* has bit 24 set while ME is accessing MAC CSR registers, wait if it is set
|
||||||
* and try again a number of times.
|
* and try again a number of times.
|
||||||
**/
|
**/
|
||||||
s32 __ew32_prepare(struct e1000_hw *hw)
|
static void __ew32_prepare(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT;
|
s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT;
|
||||||
|
|
||||||
while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i)
|
while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i)
|
||||||
udelay(50);
|
udelay(50);
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
|
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
|
||||||
|
@ -624,11 +622,11 @@ static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = rx_ring->adapter;
|
struct e1000_adapter *adapter = rx_ring->adapter;
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
s32 ret_val = __ew32_prepare(hw);
|
|
||||||
|
|
||||||
|
__ew32_prepare(hw);
|
||||||
writel(i, rx_ring->tail);
|
writel(i, rx_ring->tail);
|
||||||
|
|
||||||
if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
|
if (unlikely(i != readl(rx_ring->tail))) {
|
||||||
u32 rctl = er32(RCTL);
|
u32 rctl = er32(RCTL);
|
||||||
|
|
||||||
ew32(RCTL, rctl & ~E1000_RCTL_EN);
|
ew32(RCTL, rctl & ~E1000_RCTL_EN);
|
||||||
|
@ -641,11 +639,11 @@ static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = tx_ring->adapter;
|
struct e1000_adapter *adapter = tx_ring->adapter;
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
s32 ret_val = __ew32_prepare(hw);
|
|
||||||
|
|
||||||
|
__ew32_prepare(hw);
|
||||||
writel(i, tx_ring->tail);
|
writel(i, tx_ring->tail);
|
||||||
|
|
||||||
if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
|
if (unlikely(i != readl(tx_ring->tail))) {
|
||||||
u32 tctl = er32(TCTL);
|
u32 tctl = er32(TCTL);
|
||||||
|
|
||||||
ew32(TCTL, tctl & ~E1000_TCTL_EN);
|
ew32(TCTL, tctl & ~E1000_TCTL_EN);
|
||||||
|
|
|
@ -386,8 +386,7 @@ do { \
|
||||||
#define array_wr32(reg, offset, value) \
|
#define array_wr32(reg, offset, value) \
|
||||||
wr32((reg) + ((offset) << 2), (value))
|
wr32((reg) + ((offset) << 2), (value))
|
||||||
|
|
||||||
#define array_rd32(reg, offset) \
|
#define array_rd32(reg, offset) (igb_rd32(hw, reg + ((offset) << 2)))
|
||||||
(readl(hw->hw_addr + reg + ((offset) << 2)))
|
|
||||||
|
|
||||||
/* DMA Coalescing registers */
|
/* DMA Coalescing registers */
|
||||||
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
|
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
|
||||||
|
|
|
@ -143,7 +143,8 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||||
u32 status;
|
u32 status;
|
||||||
u32 speed;
|
u32 speed;
|
||||||
|
|
||||||
status = rd32(E1000_STATUS);
|
status = pm_runtime_suspended(&adapter->pdev->dev) ?
|
||||||
|
0 : rd32(E1000_STATUS);
|
||||||
if (hw->phy.media_type == e1000_media_type_copper) {
|
if (hw->phy.media_type == e1000_media_type_copper) {
|
||||||
|
|
||||||
ecmd->supported = (SUPPORTED_10baseT_Half |
|
ecmd->supported = (SUPPORTED_10baseT_Half |
|
||||||
|
|
|
@ -946,7 +946,6 @@ static void igb_configure_msix(struct igb_adapter *adapter)
|
||||||
static int igb_request_msix(struct igb_adapter *adapter)
|
static int igb_request_msix(struct igb_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
|
||||||
int i, err = 0, vector = 0, free_vector = 0;
|
int i, err = 0, vector = 0, free_vector = 0;
|
||||||
|
|
||||||
err = request_irq(adapter->msix_entries[vector].vector,
|
err = request_irq(adapter->msix_entries[vector].vector,
|
||||||
|
@ -959,7 +958,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
|
||||||
|
|
||||||
vector++;
|
vector++;
|
||||||
|
|
||||||
q_vector->itr_register = hw->hw_addr + E1000_EITR(vector);
|
q_vector->itr_register = adapter->io_addr + E1000_EITR(vector);
|
||||||
|
|
||||||
if (q_vector->rx.ring && q_vector->tx.ring)
|
if (q_vector->rx.ring && q_vector->tx.ring)
|
||||||
sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
|
sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
|
||||||
|
@ -1230,7 +1229,7 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
|
||||||
q_vector->tx.work_limit = adapter->tx_work_limit;
|
q_vector->tx.work_limit = adapter->tx_work_limit;
|
||||||
|
|
||||||
/* initialize ITR configuration */
|
/* initialize ITR configuration */
|
||||||
q_vector->itr_register = adapter->hw.hw_addr + E1000_EITR(0);
|
q_vector->itr_register = adapter->io_addr + E1000_EITR(0);
|
||||||
q_vector->itr_val = IGB_START_ITR;
|
q_vector->itr_val = IGB_START_ITR;
|
||||||
|
|
||||||
/* initialize pointer to rings */
|
/* initialize pointer to rings */
|
||||||
|
|
|
@ -2185,7 +2185,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure pause time (2 TCs per register) */
|
/* Configure pause time (2 TCs per register) */
|
||||||
reg = hw->fc.pause_time * 0x00010001;
|
reg = hw->fc.pause_time * 0x00010001U;
|
||||||
for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
|
for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
|
IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
|
||||||
|
|
||||||
|
|
|
@ -865,7 +865,8 @@ static int lpc_mii_init(struct netdata_local *pldat)
|
||||||
if (mdiobus_register(pldat->mii_bus))
|
if (mdiobus_register(pldat->mii_bus))
|
||||||
goto err_out_free_mdio_irq;
|
goto err_out_free_mdio_irq;
|
||||||
|
|
||||||
if (lpc_mii_probe(pldat->ndev) != 0)
|
err = lpc_mii_probe(pldat->ndev);
|
||||||
|
if (err)
|
||||||
goto err_out_unregister_bus;
|
goto err_out_unregister_bus;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -420,6 +420,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
|
||||||
int ret;
|
int ret;
|
||||||
rx_handler_result_t handle_res;
|
rx_handler_result_t handle_res;
|
||||||
|
|
||||||
|
/* Packets from dev_loopback_xmit() do not have L2 header, bail out */
|
||||||
|
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
|
||||||
|
return RX_HANDLER_PASS;
|
||||||
|
|
||||||
port = macvlan_port_get_rcu(skb->dev);
|
port = macvlan_port_get_rcu(skb->dev);
|
||||||
if (is_multicast_ether_addr(eth->h_dest)) {
|
if (is_multicast_ether_addr(eth->h_dest)) {
|
||||||
skb = ip_check_defrag(dev_net(skb->dev), skb, IP_DEFRAG_MACVLAN);
|
skb = ip_check_defrag(dev_net(skb->dev), skb, IP_DEFRAG_MACVLAN);
|
||||||
|
|
|
@ -1091,7 +1091,7 @@ static struct phy_driver marvell_drivers[] = {
|
||||||
.features = PHY_GBIT_FEATURES,
|
.features = PHY_GBIT_FEATURES,
|
||||||
.flags = PHY_HAS_INTERRUPT,
|
.flags = PHY_HAS_INTERRUPT,
|
||||||
.config_init = &m88e1145_config_init,
|
.config_init = &m88e1145_config_init,
|
||||||
.config_aneg = &marvell_config_aneg,
|
.config_aneg = &m88e1101_config_aneg,
|
||||||
.read_status = &genphy_read_status,
|
.read_status = &genphy_read_status,
|
||||||
.ack_interrupt = &marvell_ack_interrupt,
|
.ack_interrupt = &marvell_ack_interrupt,
|
||||||
.config_intr = &marvell_config_intr,
|
.config_intr = &marvell_config_intr,
|
||||||
|
|
|
@ -664,6 +664,8 @@ vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key, u8 *hfunc)
|
||||||
*hfunc = ETH_RSS_HASH_TOP;
|
*hfunc = ETH_RSS_HASH_TOP;
|
||||||
if (!p)
|
if (!p)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (n > UPT1_RSS_MAX_IND_TABLE_SIZE)
|
||||||
|
return 0;
|
||||||
while (n--)
|
while (n--)
|
||||||
p[n] = rssConf->indTable[n];
|
p[n] = rssConf->indTable[n];
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1476,6 +1476,10 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
|
||||||
daddr = eth_hdr(request)->h_source;
|
daddr = eth_hdr(request)->h_source;
|
||||||
ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns);
|
ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns);
|
||||||
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
|
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
|
||||||
|
if (!ns->opt[i + 1]) {
|
||||||
|
kfree_skb(reply);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
|
if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
|
||||||
daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
|
daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -608,6 +608,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
||||||
hif_dev->remain_skb = nskb;
|
hif_dev->remain_skb = nskb;
|
||||||
spin_unlock(&hif_dev->rx_lock);
|
spin_unlock(&hif_dev->rx_lock);
|
||||||
} else {
|
} else {
|
||||||
|
if (pool_index == MAX_PKT_NUM_IN_TRANSFER) {
|
||||||
|
dev_err(&hif_dev->udev->dev,
|
||||||
|
"ath9k_htc: over RX MAX_PKT_NUM\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
||||||
if (!nskb) {
|
if (!nskb) {
|
||||||
dev_err(&hif_dev->udev->dev,
|
dev_err(&hif_dev->udev->dev,
|
||||||
|
@ -634,9 +639,9 @@ err:
|
||||||
|
|
||||||
static void ath9k_hif_usb_rx_cb(struct urb *urb)
|
static void ath9k_hif_usb_rx_cb(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
|
||||||
struct hif_device_usb *hif_dev =
|
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
|
||||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
struct sk_buff *skb = rx_buf->skb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
|
@ -676,14 +681,15 @@ resubmit:
|
||||||
return;
|
return;
|
||||||
free:
|
free:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
kfree(rx_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
|
static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
|
||||||
|
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
|
||||||
|
struct sk_buff *skb = rx_buf->skb;
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
struct hif_device_usb *hif_dev =
|
|
||||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
|
@ -741,6 +747,7 @@ resubmit:
|
||||||
return;
|
return;
|
||||||
free:
|
free:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
kfree(rx_buf);
|
||||||
urb->context = NULL;
|
urb->context = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,7 +793,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
|
||||||
init_usb_anchor(&hif_dev->mgmt_submitted);
|
init_usb_anchor(&hif_dev->mgmt_submitted);
|
||||||
|
|
||||||
for (i = 0; i < MAX_TX_URB_NUM; i++) {
|
for (i = 0; i < MAX_TX_URB_NUM; i++) {
|
||||||
tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
|
tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL);
|
||||||
if (!tx_buf)
|
if (!tx_buf)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -823,8 +830,9 @@ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||||
|
|
||||||
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||||
{
|
{
|
||||||
struct urb *urb = NULL;
|
struct rx_buf *rx_buf = NULL;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
|
struct urb *urb = NULL;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
init_usb_anchor(&hif_dev->rx_submitted);
|
init_usb_anchor(&hif_dev->rx_submitted);
|
||||||
|
@ -832,6 +840,12 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||||
|
|
||||||
for (i = 0; i < MAX_RX_URB_NUM; i++) {
|
for (i = 0; i < MAX_RX_URB_NUM; i++) {
|
||||||
|
|
||||||
|
rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
|
||||||
|
if (!rx_buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_rxb;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate URB */
|
/* Allocate URB */
|
||||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
if (urb == NULL) {
|
if (urb == NULL) {
|
||||||
|
@ -846,11 +860,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
|
||||||
goto err_skb;
|
goto err_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rx_buf->hif_dev = hif_dev;
|
||||||
|
rx_buf->skb = skb;
|
||||||
|
|
||||||
usb_fill_bulk_urb(urb, hif_dev->udev,
|
usb_fill_bulk_urb(urb, hif_dev->udev,
|
||||||
usb_rcvbulkpipe(hif_dev->udev,
|
usb_rcvbulkpipe(hif_dev->udev,
|
||||||
USB_WLAN_RX_PIPE),
|
USB_WLAN_RX_PIPE),
|
||||||
skb->data, MAX_RX_BUF_SIZE,
|
skb->data, MAX_RX_BUF_SIZE,
|
||||||
ath9k_hif_usb_rx_cb, skb);
|
ath9k_hif_usb_rx_cb, rx_buf);
|
||||||
|
|
||||||
/* Anchor URB */
|
/* Anchor URB */
|
||||||
usb_anchor_urb(urb, &hif_dev->rx_submitted);
|
usb_anchor_urb(urb, &hif_dev->rx_submitted);
|
||||||
|
@ -876,6 +893,8 @@ err_submit:
|
||||||
err_skb:
|
err_skb:
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
err_urb:
|
err_urb:
|
||||||
|
kfree(rx_buf);
|
||||||
|
err_rxb:
|
||||||
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
|
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -887,14 +906,21 @@ static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||||
|
|
||||||
static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||||
{
|
{
|
||||||
struct urb *urb = NULL;
|
struct rx_buf *rx_buf = NULL;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
|
struct urb *urb = NULL;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
init_usb_anchor(&hif_dev->reg_in_submitted);
|
init_usb_anchor(&hif_dev->reg_in_submitted);
|
||||||
|
|
||||||
for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
|
for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
|
||||||
|
|
||||||
|
rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
|
||||||
|
if (!rx_buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_rxb;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate URB */
|
/* Allocate URB */
|
||||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
if (urb == NULL) {
|
if (urb == NULL) {
|
||||||
|
@ -909,11 +935,14 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
|
||||||
goto err_skb;
|
goto err_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rx_buf->hif_dev = hif_dev;
|
||||||
|
rx_buf->skb = skb;
|
||||||
|
|
||||||
usb_fill_int_urb(urb, hif_dev->udev,
|
usb_fill_int_urb(urb, hif_dev->udev,
|
||||||
usb_rcvintpipe(hif_dev->udev,
|
usb_rcvintpipe(hif_dev->udev,
|
||||||
USB_REG_IN_PIPE),
|
USB_REG_IN_PIPE),
|
||||||
skb->data, MAX_REG_IN_BUF_SIZE,
|
skb->data, MAX_REG_IN_BUF_SIZE,
|
||||||
ath9k_hif_usb_reg_in_cb, skb, 1);
|
ath9k_hif_usb_reg_in_cb, rx_buf, 1);
|
||||||
|
|
||||||
/* Anchor URB */
|
/* Anchor URB */
|
||||||
usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
|
usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
|
||||||
|
@ -939,6 +968,8 @@ err_submit:
|
||||||
err_skb:
|
err_skb:
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
err_urb:
|
err_urb:
|
||||||
|
kfree(rx_buf);
|
||||||
|
err_rxb:
|
||||||
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -969,7 +1000,7 @@ err:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
|
void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
|
||||||
{
|
{
|
||||||
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
|
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
|
||||||
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
|
||||||
|
@ -1336,8 +1367,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
|
||||||
|
|
||||||
if (hif_dev->flags & HIF_USB_READY) {
|
if (hif_dev->flags & HIF_USB_READY) {
|
||||||
ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
|
ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
|
||||||
ath9k_htc_hw_free(hif_dev->htc_handle);
|
|
||||||
ath9k_hif_usb_dev_deinit(hif_dev);
|
ath9k_hif_usb_dev_deinit(hif_dev);
|
||||||
|
ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv);
|
||||||
|
ath9k_htc_hw_free(hif_dev->htc_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_set_intfdata(interface, NULL);
|
usb_set_intfdata(interface, NULL);
|
||||||
|
|
|
@ -84,6 +84,11 @@ struct tx_buf {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rx_buf {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct hif_device_usb *hif_dev;
|
||||||
|
};
|
||||||
|
|
||||||
#define HIF_USB_TX_STOP BIT(0)
|
#define HIF_USB_TX_STOP BIT(0)
|
||||||
#define HIF_USB_TX_FLUSH BIT(1)
|
#define HIF_USB_TX_FLUSH BIT(1)
|
||||||
|
|
||||||
|
@ -131,5 +136,6 @@ struct hif_device_usb {
|
||||||
|
|
||||||
int ath9k_hif_usb_init(void);
|
int ath9k_hif_usb_init(void);
|
||||||
void ath9k_hif_usb_exit(void);
|
void ath9k_hif_usb_exit(void);
|
||||||
|
void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev);
|
||||||
|
|
||||||
#endif /* HTC_USB_H */
|
#endif /* HTC_USB_H */
|
||||||
|
|
|
@ -931,8 +931,9 @@ err_init:
|
||||||
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
||||||
u16 devid, char *product, u32 drv_info)
|
u16 devid, char *product, u32 drv_info)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw;
|
struct hif_device_usb *hif_dev;
|
||||||
struct ath9k_htc_priv *priv;
|
struct ath9k_htc_priv *priv;
|
||||||
|
struct ieee80211_hw *hw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
|
hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
|
||||||
|
@ -967,7 +968,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_init:
|
err_init:
|
||||||
ath9k_deinit_wmi(priv);
|
ath9k_stop_wmi(priv);
|
||||||
|
hif_dev = (struct hif_device_usb *)htc_handle->hif_dev;
|
||||||
|
ath9k_hif_usb_dealloc_urbs(hif_dev);
|
||||||
|
ath9k_destoy_wmi(priv);
|
||||||
err_free:
|
err_free:
|
||||||
ieee80211_free_hw(hw);
|
ieee80211_free_hw(hw);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -982,7 +986,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
|
||||||
htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
|
htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
|
||||||
|
|
||||||
ath9k_deinit_device(htc_handle->drv_priv);
|
ath9k_deinit_device(htc_handle->drv_priv);
|
||||||
ath9k_deinit_wmi(htc_handle->drv_priv);
|
ath9k_stop_wmi(htc_handle->drv_priv);
|
||||||
ieee80211_free_hw(htc_handle->drv_priv->hw);
|
ieee80211_free_hw(htc_handle->drv_priv->hw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -998,9 +998,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
|
||||||
* which are not PHY_ERROR (short radar pulses have a length of 3)
|
* which are not PHY_ERROR (short radar pulses have a length of 3)
|
||||||
*/
|
*/
|
||||||
if (unlikely(!rs_datalen || (rs_datalen < 10 && !is_phyerr))) {
|
if (unlikely(!rs_datalen || (rs_datalen < 10 && !is_phyerr))) {
|
||||||
ath_warn(common,
|
ath_dbg(common, ANY,
|
||||||
"Short RX data len, dropping (dlen: %d)\n",
|
"Short RX data len, dropping (dlen: %d)\n",
|
||||||
rs_datalen);
|
rs_datalen);
|
||||||
goto rx_next;
|
goto rx_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,9 @@ static void htc_process_conn_rsp(struct htc_target *target,
|
||||||
|
|
||||||
if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
|
if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
|
||||||
epid = svc_rspmsg->endpoint_id;
|
epid = svc_rspmsg->endpoint_id;
|
||||||
|
if (epid < 0 || epid >= ENDPOINT_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
service_id = be16_to_cpu(svc_rspmsg->service_id);
|
service_id = be16_to_cpu(svc_rspmsg->service_id);
|
||||||
max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
|
max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
|
||||||
endpoint = &target->endpoint[epid];
|
endpoint = &target->endpoint[epid];
|
||||||
|
|
|
@ -112,14 +112,17 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
|
||||||
return wmi;
|
return wmi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
|
void ath9k_stop_wmi(struct ath9k_htc_priv *priv)
|
||||||
{
|
{
|
||||||
struct wmi *wmi = priv->wmi;
|
struct wmi *wmi = priv->wmi;
|
||||||
|
|
||||||
mutex_lock(&wmi->op_mutex);
|
mutex_lock(&wmi->op_mutex);
|
||||||
wmi->stopped = true;
|
wmi->stopped = true;
|
||||||
mutex_unlock(&wmi->op_mutex);
|
mutex_unlock(&wmi->op_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ath9k_destoy_wmi(struct ath9k_htc_priv *priv)
|
||||||
|
{
|
||||||
kfree(priv->wmi);
|
kfree(priv->wmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,6 @@ struct wmi {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
|
struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
|
||||||
void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
|
|
||||||
int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
|
int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
|
||||||
enum htc_endpoint_id *wmi_ctrl_epid);
|
enum htc_endpoint_id *wmi_ctrl_epid);
|
||||||
int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||||
|
@ -189,6 +188,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||||
void ath9k_wmi_event_tasklet(unsigned long data);
|
void ath9k_wmi_event_tasklet(unsigned long data);
|
||||||
void ath9k_fatal_work(struct work_struct *work);
|
void ath9k_fatal_work(struct work_struct *work);
|
||||||
void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
|
void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
|
||||||
|
void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
|
||||||
|
void ath9k_destoy_wmi(struct ath9k_htc_priv *priv);
|
||||||
|
|
||||||
#define WMI_CMD(_wmi_cmd) \
|
#define WMI_CMD(_wmi_cmd) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -351,9 +351,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
|
||||||
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
||||||
|
|
||||||
if (SUPP(CARL9170FW_WLANTX_CAB)) {
|
if (SUPP(CARL9170FW_WLANTX_CAB)) {
|
||||||
if_comb_types |=
|
if_comb_types |= BIT(NL80211_IFTYPE_AP);
|
||||||
BIT(NL80211_IFTYPE_AP) |
|
|
||||||
BIT(NL80211_IFTYPE_P2P_GO);
|
|
||||||
|
|
||||||
#ifdef CONFIG_MAC80211_MESH
|
#ifdef CONFIG_MAC80211_MESH
|
||||||
if_comb_types |=
|
if_comb_types |=
|
||||||
|
|
|
@ -582,11 +582,10 @@ static int carl9170_init_interface(struct ar9170 *ar,
|
||||||
ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) &&
|
ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) &&
|
||||||
(vif->type != NL80211_IFTYPE_AP));
|
(vif->type != NL80211_IFTYPE_AP));
|
||||||
|
|
||||||
/* While the driver supports HW offload in a single
|
/* The driver used to have P2P GO+CLIENT support,
|
||||||
* P2P client configuration, it doesn't support HW
|
* but since this was dropped and we don't know if
|
||||||
* offload in the favourit, concurrent P2P GO+CLIENT
|
* there are any gremlins lurking in the shadows,
|
||||||
* configuration. Hence, HW offload will always be
|
* so best we keep HW offload disabled for P2P.
|
||||||
* disabled for P2P.
|
|
||||||
*/
|
*/
|
||||||
ar->disable_offload |= vif->p2p;
|
ar->disable_offload |= vif->p2p;
|
||||||
|
|
||||||
|
@ -639,18 +638,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw,
|
||||||
if (vif->type == NL80211_IFTYPE_STATION)
|
if (vif->type == NL80211_IFTYPE_STATION)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* P2P GO [master] use-case
|
|
||||||
* Because the P2P GO station is selected dynamically
|
|
||||||
* by all participating peers of a WIFI Direct network,
|
|
||||||
* the driver has be able to change the main interface
|
|
||||||
* operating mode on the fly.
|
|
||||||
*/
|
|
||||||
if (main_vif->p2p && vif->p2p &&
|
|
||||||
vif->type == NL80211_IFTYPE_AP) {
|
|
||||||
old_main = main_vif;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
|
|
@ -5611,7 +5611,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
|
||||||
/* fill hw info */
|
/* fill hw info */
|
||||||
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
|
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
|
||||||
ieee80211_hw_set(hw, SIGNAL_DBM);
|
ieee80211_hw_set(hw, SIGNAL_DBM);
|
||||||
|
ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||||
hw->wiphy->interface_modes =
|
hw->wiphy->interface_modes =
|
||||||
BIT(NL80211_IFTYPE_AP) |
|
BIT(NL80211_IFTYPE_AP) |
|
||||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||||
|
|
|
@ -3835,6 +3835,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
|
||||||
/* fill hw info */
|
/* fill hw info */
|
||||||
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
|
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
|
||||||
ieee80211_hw_set(hw, SIGNAL_DBM);
|
ieee80211_hw_set(hw, SIGNAL_DBM);
|
||||||
|
ieee80211_hw_set(hw, MFP_CAPABLE); /* Allow WPA3 in software */
|
||||||
|
|
||||||
hw->wiphy->interface_modes =
|
hw->wiphy->interface_modes =
|
||||||
BIT(NL80211_IFTYPE_AP) |
|
BIT(NL80211_IFTYPE_AP) |
|
||||||
|
|
|
@ -571,6 +571,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
|
||||||
default:
|
default:
|
||||||
b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
|
b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
|
||||||
chanstat);
|
chanstat);
|
||||||
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
|
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
|
||||||
|
|
|
@ -1387,7 +1387,8 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
|
||||||
int idx, u8 *mac, struct station_info *sinfo)
|
int idx, u8 *mac, struct station_info *sinfo)
|
||||||
{
|
{
|
||||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||||
static struct mwifiex_sta_node *node;
|
struct mwifiex_sta_node *node;
|
||||||
|
int i;
|
||||||
|
|
||||||
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
|
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
|
||||||
priv->media_connected && idx == 0) {
|
priv->media_connected && idx == 0) {
|
||||||
|
@ -1397,13 +1398,10 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
|
||||||
mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST,
|
mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST,
|
||||||
HostCmd_ACT_GEN_GET, 0, NULL, true);
|
HostCmd_ACT_GEN_GET, 0, NULL, true);
|
||||||
|
|
||||||
if (node && (&node->list == &priv->sta_list)) {
|
i = 0;
|
||||||
node = NULL;
|
list_for_each_entry(node, &priv->sta_list, list) {
|
||||||
return -ENOENT;
|
if (i++ != idx)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
node = list_prepare_entry(node, &priv->sta_list, list);
|
|
||||||
list_for_each_entry_continue(node, &priv->sta_list, list) {
|
|
||||||
ether_addr_copy(mac, node->mac_addr);
|
ether_addr_copy(mac, node->mac_addr);
|
||||||
return mwifiex_dump_station_info(priv, node, sinfo);
|
return mwifiex_dump_station_info(priv, node, sinfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1226,7 +1226,7 @@ int pci_setup_device(struct pci_dev *dev)
|
||||||
/* device class may be changed after fixup */
|
/* device class may be changed after fixup */
|
||||||
class = dev->class >> 8;
|
class = dev->class >> 8;
|
||||||
|
|
||||||
if (dev->non_compliant_bars) {
|
if (dev->non_compliant_bars && !dev->mmio_always_on) {
|
||||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||||
if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
|
if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
|
||||||
dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
|
dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
|
||||||
|
@ -1335,13 +1335,33 @@ static void pci_configure_mps(struct pci_dev *dev)
|
||||||
struct pci_dev *bridge = pci_upstream_bridge(dev);
|
struct pci_dev *bridge = pci_upstream_bridge(dev);
|
||||||
int mps, p_mps, rc;
|
int mps, p_mps, rc;
|
||||||
|
|
||||||
if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
|
if (!pci_is_pcie(dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */
|
/* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */
|
||||||
if (dev->is_virtfn)
|
if (dev->is_virtfn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For Root Complex Integrated Endpoints, program the maximum
|
||||||
|
* supported value unless limited by the PCIE_BUS_PEER2PEER case.
|
||||||
|
*/
|
||||||
|
if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) {
|
||||||
|
if (pcie_bus_config == PCIE_BUS_PEER2PEER)
|
||||||
|
mps = 128;
|
||||||
|
else
|
||||||
|
mps = 128 << dev->pcie_mpss;
|
||||||
|
rc = pcie_set_mps(dev, mps);
|
||||||
|
if (rc) {
|
||||||
|
dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
|
||||||
|
mps);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bridge || !pci_is_pcie(bridge))
|
||||||
|
return;
|
||||||
|
|
||||||
mps = pcie_get_mps(dev);
|
mps = pcie_get_mps(dev);
|
||||||
p_mps = pcie_get_mps(bridge);
|
p_mps = pcie_get_mps(bridge);
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,7 @@ struct exynos_eint_gpio_save {
|
||||||
u32 eint_con;
|
u32 eint_con;
|
||||||
u32 eint_fltcon0;
|
u32 eint_fltcon0;
|
||||||
u32 eint_fltcon1;
|
u32 eint_fltcon1;
|
||||||
|
u32 eint_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -588,10 +589,13 @@ static void exynos_pinctrl_suspend_bank(
|
||||||
+ 2 * bank->eint_offset);
|
+ 2 * bank->eint_offset);
|
||||||
save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
||||||
+ 2 * bank->eint_offset + 4);
|
+ 2 * bank->eint_offset + 4);
|
||||||
|
save->eint_mask = readl(regs + bank->irq_chip->eint_mask
|
||||||
|
+ bank->eint_offset);
|
||||||
|
|
||||||
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
|
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
|
||||||
pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
|
pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
|
||||||
pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
|
pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
|
||||||
|
pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
|
static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
|
||||||
|
@ -620,6 +624,9 @@ static void exynos_pinctrl_resume_bank(
|
||||||
pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
|
pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
|
||||||
readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
||||||
+ 2 * bank->eint_offset + 4), save->eint_fltcon1);
|
+ 2 * bank->eint_offset + 4), save->eint_fltcon1);
|
||||||
|
pr_debug("%s: mask %#010x => %#010x\n", bank->name,
|
||||||
|
readl(regs + bank->irq_chip->eint_mask
|
||||||
|
+ bank->eint_offset), save->eint_mask);
|
||||||
|
|
||||||
writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
|
writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
|
||||||
+ bank->eint_offset);
|
+ bank->eint_offset);
|
||||||
|
@ -627,6 +634,8 @@ static void exynos_pinctrl_resume_bank(
|
||||||
+ 2 * bank->eint_offset);
|
+ 2 * bank->eint_offset);
|
||||||
writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
|
||||||
+ 2 * bank->eint_offset + 4);
|
+ 2 * bank->eint_offset + 4);
|
||||||
|
writel(save->eint_mask, regs + bank->irq_chip->eint_mask
|
||||||
|
+ bank->eint_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
|
static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
|
||||||
|
|
|
@ -150,6 +150,7 @@ static struct platform_driver vexpress_reset_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "vexpress-reset",
|
.name = "vexpress-reset",
|
||||||
.of_match_table = vexpress_reset_of_match,
|
.of_match_table = vexpress_reset_of_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ static const struct regmap_config fsl_pwm_regmap_config = {
|
||||||
|
|
||||||
.max_register = FTM_PWMLOAD,
|
.max_register = FTM_PWMLOAD,
|
||||||
.volatile_reg = fsl_pwm_volatile_reg,
|
.volatile_reg = fsl_pwm_volatile_reg,
|
||||||
.cache_type = REGCACHE_RBTREE,
|
.cache_type = REGCACHE_FLAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fsl_pwm_probe(struct platform_device *pdev)
|
static int fsl_pwm_probe(struct platform_device *pdev)
|
||||||
|
|
|
@ -1118,10 +1118,10 @@ int scsi_init_io(struct scsi_cmnd *cmd)
|
||||||
struct scsi_device *sdev = cmd->device;
|
struct scsi_device *sdev = cmd->device;
|
||||||
struct request *rq = cmd->request;
|
struct request *rq = cmd->request;
|
||||||
bool is_mq = (rq->mq_ctx != NULL);
|
bool is_mq = (rq->mq_ctx != NULL);
|
||||||
int error;
|
int error = BLKPREP_KILL;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(!rq->nr_phys_segments))
|
if (WARN_ON_ONCE(!rq->nr_phys_segments))
|
||||||
return -EINVAL;
|
goto err_exit;
|
||||||
|
|
||||||
error = scsi_init_sgtable(rq, &cmd->sdb);
|
error = scsi_init_sgtable(rq, &cmd->sdb);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
@ -798,7 +798,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
|
||||||
goto out_clk_disable;
|
goto out_clk_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = devm_spi_register_master(&pdev->dev, master);
|
err = spi_register_master(master);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
|
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
|
||||||
goto out_clk_disable;
|
goto out_clk_disable;
|
||||||
|
@ -818,6 +818,8 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
|
||||||
struct spi_master *master = platform_get_drvdata(pdev);
|
struct spi_master *master = platform_get_drvdata(pdev);
|
||||||
struct bcm2835_spi *bs = spi_master_get_devdata(master);
|
struct bcm2835_spi *bs = spi_master_get_devdata(master);
|
||||||
|
|
||||||
|
spi_unregister_master(master);
|
||||||
|
|
||||||
/* Clear FIFOs, and disable the HW block */
|
/* Clear FIFOs, and disable the HW block */
|
||||||
bcm2835_wr(bs, BCM2835_SPI_CS,
|
bcm2835_wr(bs, BCM2835_SPI_CS,
|
||||||
BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
|
BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
|
||||||
|
|
|
@ -457,7 +457,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
|
||||||
goto out_clk_disable;
|
goto out_clk_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = devm_spi_register_master(&pdev->dev, master);
|
err = spi_register_master(master);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
|
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
|
||||||
goto out_clk_disable;
|
goto out_clk_disable;
|
||||||
|
@ -477,6 +477,8 @@ static int bcm2835aux_spi_remove(struct platform_device *pdev)
|
||||||
struct spi_master *master = platform_get_drvdata(pdev);
|
struct spi_master *master = platform_get_drvdata(pdev);
|
||||||
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
|
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
|
||||||
|
|
||||||
|
spi_unregister_master(master);
|
||||||
|
|
||||||
bcm2835aux_spi_reset_hw(bs);
|
bcm2835aux_spi_reset_hw(bs);
|
||||||
|
|
||||||
/* disable the HW block by releasing the clock */
|
/* disable the HW block by releasing the clock */
|
||||||
|
|
|
@ -155,6 +155,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws,
|
||||||
if (!xfer->tx_buf)
|
if (!xfer->tx_buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
memset(&txconf, 0, sizeof(txconf));
|
||||||
txconf.direction = DMA_MEM_TO_DEV;
|
txconf.direction = DMA_MEM_TO_DEV;
|
||||||
txconf.dst_addr = dws->dma_addr;
|
txconf.dst_addr = dws->dma_addr;
|
||||||
txconf.dst_maxburst = 16;
|
txconf.dst_maxburst = 16;
|
||||||
|
@ -201,6 +202,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
|
||||||
if (!xfer->rx_buf)
|
if (!xfer->rx_buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
memset(&rxconf, 0, sizeof(rxconf));
|
||||||
rxconf.direction = DMA_DEV_TO_MEM;
|
rxconf.direction = DMA_DEV_TO_MEM;
|
||||||
rxconf.src_addr = dws->dma_addr;
|
rxconf.src_addr = dws->dma_addr;
|
||||||
rxconf.src_maxburst = 16;
|
rxconf.src_maxburst = 16;
|
||||||
|
@ -226,19 +228,23 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
|
||||||
|
|
||||||
static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
|
static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
|
||||||
{
|
{
|
||||||
u16 dma_ctrl = 0;
|
u16 imr = 0, dma_ctrl = 0;
|
||||||
|
|
||||||
dw_writel(dws, DW_SPI_DMARDLR, 0xf);
|
dw_writel(dws, DW_SPI_DMARDLR, 0xf);
|
||||||
dw_writel(dws, DW_SPI_DMATDLR, 0x10);
|
dw_writel(dws, DW_SPI_DMATDLR, 0x10);
|
||||||
|
|
||||||
if (xfer->tx_buf)
|
if (xfer->tx_buf) {
|
||||||
dma_ctrl |= SPI_DMA_TDMAE;
|
dma_ctrl |= SPI_DMA_TDMAE;
|
||||||
if (xfer->rx_buf)
|
imr |= SPI_INT_TXOI;
|
||||||
|
}
|
||||||
|
if (xfer->rx_buf) {
|
||||||
dma_ctrl |= SPI_DMA_RDMAE;
|
dma_ctrl |= SPI_DMA_RDMAE;
|
||||||
|
imr |= SPI_INT_RXUI | SPI_INT_RXOI;
|
||||||
|
}
|
||||||
dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
|
dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
|
||||||
|
|
||||||
/* Set the interrupt mask */
|
/* Set the interrupt mask */
|
||||||
spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI);
|
spi_umask_intr(dws, imr);
|
||||||
|
|
||||||
dws->transfer_handler = dma_transfer;
|
dws->transfer_handler = dma_transfer;
|
||||||
|
|
||||||
|
@ -268,7 +274,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer)
|
||||||
dma_async_issue_pending(dws->txchan);
|
dma_async_issue_pending(dws->txchan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mid_spi_dma_stop(struct dw_spi *dws)
|
static void mid_spi_dma_stop(struct dw_spi *dws)
|
||||||
|
|
|
@ -385,11 +385,8 @@ static int dw_spi_transfer_one(struct spi_master *master,
|
||||||
|
|
||||||
spi_enable_chip(dws, 1);
|
spi_enable_chip(dws, 1);
|
||||||
|
|
||||||
if (dws->dma_mapped) {
|
if (dws->dma_mapped)
|
||||||
ret = dws->dma_ops->dma_transfer(dws, transfer);
|
return dws->dma_ops->dma_transfer(dws, transfer);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chip->poll_mode)
|
if (chip->poll_mode)
|
||||||
return poll_transfer(dws);
|
return poll_transfer(dws);
|
||||||
|
@ -501,6 +498,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
||||||
snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
|
snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
|
||||||
spin_lock_init(&dws->buf_lock);
|
spin_lock_init(&dws->buf_lock);
|
||||||
|
|
||||||
|
spi_master_set_devdata(master, dws);
|
||||||
|
|
||||||
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master);
|
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "can not get IRQ\n");
|
dev_err(dev, "can not get IRQ\n");
|
||||||
|
@ -532,8 +531,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_master_set_devdata(master, dws);
|
ret = spi_register_master(master);
|
||||||
ret = devm_spi_register_master(dev, master);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&master->dev, "problem registering spi master\n");
|
dev_err(&master->dev, "problem registering spi master\n");
|
||||||
goto err_dma_exit;
|
goto err_dma_exit;
|
||||||
|
@ -557,6 +555,8 @@ void dw_spi_remove_host(struct dw_spi *dws)
|
||||||
{
|
{
|
||||||
dw_spi_debugfs_remove(dws);
|
dw_spi_debugfs_remove(dws);
|
||||||
|
|
||||||
|
spi_unregister_master(dws->master);
|
||||||
|
|
||||||
if (dws->dma_ops && dws->dma_ops->dma_exit)
|
if (dws->dma_ops && dws->dma_ops->dma_exit)
|
||||||
dws->dma_ops->dma_exit(dws);
|
dws->dma_ops->dma_exit(dws);
|
||||||
|
|
||||||
|
|
|
@ -1605,7 +1605,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
/* Register with the SPI framework */
|
/* Register with the SPI framework */
|
||||||
platform_set_drvdata(pdev, drv_data);
|
platform_set_drvdata(pdev, drv_data);
|
||||||
status = devm_spi_register_master(&pdev->dev, master);
|
status = spi_register_master(master);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
dev_err(&pdev->dev, "problem registering spi master\n");
|
dev_err(&pdev->dev, "problem registering spi master\n");
|
||||||
goto out_error_clock_enabled;
|
goto out_error_clock_enabled;
|
||||||
|
@ -1635,6 +1635,8 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
pm_runtime_get_sync(&pdev->dev);
|
pm_runtime_get_sync(&pdev->dev);
|
||||||
|
|
||||||
|
spi_unregister_master(drv_data->master);
|
||||||
|
|
||||||
/* Disable the SSP at the peripheral and SOC level */
|
/* Disable the SSP at the peripheral and SOC level */
|
||||||
pxa2xx_spi_write(drv_data, SSCR0, 0);
|
pxa2xx_spi_write(drv_data, SSCR0, 0);
|
||||||
clk_disable_unprepare(ssp->clk);
|
clk_disable_unprepare(ssp->clk);
|
||||||
|
|
|
@ -2046,18 +2046,17 @@ static int __unregister(struct device *dev, void *null)
|
||||||
*/
|
*/
|
||||||
void spi_unregister_master(struct spi_master *master)
|
void spi_unregister_master(struct spi_master *master)
|
||||||
{
|
{
|
||||||
int dummy;
|
|
||||||
|
|
||||||
if (master->queued) {
|
if (master->queued) {
|
||||||
if (spi_destroy_queue(master))
|
if (spi_destroy_queue(master))
|
||||||
dev_err(&master->dev, "queue remove failed\n");
|
dev_err(&master->dev, "queue remove failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_for_each_child(&master->dev, NULL, __unregister);
|
||||||
|
|
||||||
mutex_lock(&board_lock);
|
mutex_lock(&board_lock);
|
||||||
list_del(&master->list);
|
list_del(&master->list);
|
||||||
mutex_unlock(&board_lock);
|
mutex_unlock(&board_lock);
|
||||||
|
|
||||||
dummy = device_for_each_child(&master->dev, NULL, __unregister);
|
|
||||||
device_unregister(&master->dev);
|
device_unregister(&master->dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spi_unregister_master);
|
EXPORT_SYMBOL_GPL(spi_unregister_master);
|
||||||
|
|
|
@ -109,12 +109,12 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
|
||||||
|
|
||||||
static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot)
|
static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot)
|
||||||
{
|
{
|
||||||
void *addr = vm_map_ram(pages, num, -1, pgprot);
|
void *addr = vmap(pages, num, VM_MAP, pgprot);
|
||||||
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
memset(addr, 0, PAGE_SIZE * num);
|
memset(addr, 0, PAGE_SIZE * num);
|
||||||
vm_unmap_ram(addr, num);
|
vunmap(addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -583,6 +583,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par)
|
||||||
memsize=par->mach->mem->size;
|
memsize=par->mach->mem->size;
|
||||||
memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize);
|
memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize);
|
||||||
vfree(par->saved_extmem);
|
vfree(par->saved_extmem);
|
||||||
|
par->saved_extmem = NULL;
|
||||||
}
|
}
|
||||||
if (par->saved_intmem) {
|
if (par->saved_intmem) {
|
||||||
memsize=MEM_INT_SIZE;
|
memsize=MEM_INT_SIZE;
|
||||||
|
@ -591,6 +592,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par)
|
||||||
else
|
else
|
||||||
memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize);
|
memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize);
|
||||||
vfree(par->saved_intmem);
|
vfree(par->saved_intmem);
|
||||||
|
par->saved_intmem = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status)
|
||||||
/* check irqstatus */
|
/* check irqstatus */
|
||||||
if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) {
|
if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) {
|
||||||
dev_dbg(hdq_data->dev, "timeout waiting for"
|
dev_dbg(hdq_data->dev, "timeout waiting for"
|
||||||
" TXCOMPLETE/RXCOMPLETE, %x", *status);
|
" TXCOMPLETE/RXCOMPLETE, %x\n", *status);
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status)
|
||||||
OMAP_HDQ_FLAG_CLEAR, &tmp_status);
|
OMAP_HDQ_FLAG_CLEAR, &tmp_status);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(hdq_data->dev, "timeout waiting GO bit"
|
dev_dbg(hdq_data->dev, "timeout waiting GO bit"
|
||||||
" return to zero, %x", tmp_status);
|
" return to zero, %x\n", tmp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -231,7 +231,7 @@ static irqreturn_t hdq_isr(int irq, void *_hdq)
|
||||||
spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
|
spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
|
||||||
hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
|
hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
|
||||||
spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
|
spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
|
||||||
dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus);
|
dev_dbg(hdq_data->dev, "hdq_isr: %x\n", hdq_data->hdq_irqstatus);
|
||||||
|
|
||||||
if (hdq_data->hdq_irqstatus &
|
if (hdq_data->hdq_irqstatus &
|
||||||
(OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE
|
(OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE
|
||||||
|
@ -339,7 +339,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data)
|
||||||
tmp_status = hdq_data->hdq_irqstatus;
|
tmp_status = hdq_data->hdq_irqstatus;
|
||||||
/* check irqstatus */
|
/* check irqstatus */
|
||||||
if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) {
|
if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) {
|
||||||
dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x",
|
dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x\n",
|
||||||
tmp_status);
|
tmp_status);
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -366,7 +366,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data)
|
||||||
&tmp_status);
|
&tmp_status);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits"
|
dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits"
|
||||||
" return to zero, %x", tmp_status);
|
" return to zero, %x\n", tmp_status);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&hdq_data->hdq_mutex);
|
mutex_unlock(&hdq_data->hdq_mutex);
|
||||||
|
|
|
@ -742,10 +742,12 @@ again:
|
||||||
nritems = btrfs_header_nritems(path->nodes[0]);
|
nritems = btrfs_header_nritems(path->nodes[0]);
|
||||||
if (!nritems || (path->slots[0] >= nritems - 1)) {
|
if (!nritems || (path->slots[0] >= nritems - 1)) {
|
||||||
ret = btrfs_next_leaf(root, path);
|
ret = btrfs_next_leaf(root, path);
|
||||||
if (ret == 1)
|
if (ret < 0) {
|
||||||
|
goto out;
|
||||||
|
} else if (ret > 0) {
|
||||||
found_next = 1;
|
found_next = 1;
|
||||||
if (ret != 0)
|
|
||||||
goto insert;
|
goto insert;
|
||||||
|
}
|
||||||
slot = path->slots[0];
|
slot = path->slots[0];
|
||||||
}
|
}
|
||||||
btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
|
btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
|
||||||
|
|
|
@ -8294,7 +8294,6 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
|
||||||
bio->bi_private = dip;
|
bio->bi_private = dip;
|
||||||
bio->bi_end_io = btrfs_end_dio_bio;
|
bio->bi_end_io = btrfs_end_dio_bio;
|
||||||
btrfs_io_bio(bio)->logical = file_offset;
|
btrfs_io_bio(bio)->logical = file_offset;
|
||||||
atomic_inc(&dip->pending_bios);
|
|
||||||
|
|
||||||
while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) {
|
while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) {
|
||||||
if (map_length < submit_len + bvec->bv_len ||
|
if (map_length < submit_len + bvec->bv_len ||
|
||||||
|
@ -8351,7 +8350,8 @@ submit:
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bio_put(bio);
|
if (bio != orig_bio)
|
||||||
|
bio_put(bio);
|
||||||
out_err:
|
out_err:
|
||||||
dip->errors = 1;
|
dip->errors = 1;
|
||||||
/*
|
/*
|
||||||
|
@ -8398,7 +8398,7 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
|
||||||
io_bio->bi_private = dip;
|
io_bio->bi_private = dip;
|
||||||
dip->orig_bio = io_bio;
|
dip->orig_bio = io_bio;
|
||||||
dip->dio_bio = dio_bio;
|
dip->dio_bio = dio_bio;
|
||||||
atomic_set(&dip->pending_bios, 0);
|
atomic_set(&dip->pending_bios, 1);
|
||||||
btrfs_bio = btrfs_io_bio(io_bio);
|
btrfs_bio = btrfs_io_bio(io_bio);
|
||||||
btrfs_bio->logical = file_offset;
|
btrfs_bio->logical = file_offset;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "props.h"
|
#include "props.h"
|
||||||
#include "sysfs.h"
|
#include "sysfs.h"
|
||||||
#include "qgroup.h"
|
#include "qgroup.h"
|
||||||
|
#include "tree-log.h"
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
/* If we have a 32-bit userspace and 64-bit kernel, then the UAPI
|
/* If we have a 32-bit userspace and 64-bit kernel, then the UAPI
|
||||||
|
@ -2540,6 +2541,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
||||||
out_end_trans:
|
out_end_trans:
|
||||||
trans->block_rsv = NULL;
|
trans->block_rsv = NULL;
|
||||||
trans->bytes_reserved = 0;
|
trans->bytes_reserved = 0;
|
||||||
|
if (!err)
|
||||||
|
btrfs_record_snapshot_destroy(trans, dir);
|
||||||
ret = btrfs_end_transaction(trans, root);
|
ret = btrfs_end_transaction(trans, root);
|
||||||
if (ret && !err)
|
if (ret && !err)
|
||||||
err = ret;
|
err = ret;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
#include "btrfs_inode.h"
|
#include "btrfs_inode.h"
|
||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
|
#include "xattr.h"
|
||||||
|
|
||||||
static int g_verbose = 0;
|
static int g_verbose = 0;
|
||||||
|
|
||||||
|
@ -4194,6 +4195,10 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
|
||||||
struct fs_path *p;
|
struct fs_path *p;
|
||||||
posix_acl_xattr_header dummy_acl;
|
posix_acl_xattr_header dummy_acl;
|
||||||
|
|
||||||
|
/* Capabilities are emitted by finish_inode_if_needed */
|
||||||
|
if (!strncmp(name, XATTR_NAME_CAPS, name_len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
p = fs_path_alloc();
|
p = fs_path_alloc();
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -4733,6 +4738,64 @@ static int send_extent_data(struct send_ctx *sctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search for a capability xattr related to sctx->cur_ino. If the capability is
|
||||||
|
* found, call send_set_xattr function to emit it.
|
||||||
|
*
|
||||||
|
* Return 0 if there isn't a capability, or when the capability was emitted
|
||||||
|
* successfully, or < 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
static int send_capabilities(struct send_ctx *sctx)
|
||||||
|
{
|
||||||
|
struct fs_path *fspath = NULL;
|
||||||
|
struct btrfs_path *path;
|
||||||
|
struct btrfs_dir_item *di;
|
||||||
|
struct extent_buffer *leaf;
|
||||||
|
unsigned long data_ptr;
|
||||||
|
char *buf = NULL;
|
||||||
|
int buf_len;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
path = alloc_path_for_send();
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
di = btrfs_lookup_xattr(NULL, sctx->send_root, path, sctx->cur_ino,
|
||||||
|
XATTR_NAME_CAPS, strlen(XATTR_NAME_CAPS), 0);
|
||||||
|
if (!di) {
|
||||||
|
/* There is no xattr for this inode */
|
||||||
|
goto out;
|
||||||
|
} else if (IS_ERR(di)) {
|
||||||
|
ret = PTR_ERR(di);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf = path->nodes[0];
|
||||||
|
buf_len = btrfs_dir_data_len(leaf, di);
|
||||||
|
|
||||||
|
fspath = fs_path_alloc();
|
||||||
|
buf = kmalloc(buf_len, GFP_KERNEL);
|
||||||
|
if (!fspath || !buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
|
||||||
|
read_extent_buffer(leaf, buf, data_ptr, buf_len);
|
||||||
|
|
||||||
|
ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
|
||||||
|
strlen(XATTR_NAME_CAPS), buf, buf_len);
|
||||||
|
out:
|
||||||
|
kfree(buf);
|
||||||
|
fs_path_free(fspath);
|
||||||
|
btrfs_free_path(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int clone_range(struct send_ctx *sctx,
|
static int clone_range(struct send_ctx *sctx,
|
||||||
struct clone_root *clone_root,
|
struct clone_root *clone_root,
|
||||||
const u64 disk_byte,
|
const u64 disk_byte,
|
||||||
|
@ -5444,6 +5507,10 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = send_capabilities(sctx);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If other directory inodes depended on our current directory
|
* If other directory inodes depended on our current directory
|
||||||
* inode's move/rename, now do their move/rename operations.
|
* inode's move/rename, now do their move/rename operations.
|
||||||
|
|
|
@ -5694,6 +5694,21 @@ record:
|
||||||
BTRFS_I(dir)->last_unlink_trans = trans->transid;
|
BTRFS_I(dir)->last_unlink_trans = trans->transid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that if someone attempts to fsync the parent directory of a deleted
|
||||||
|
* snapshot, it ends up triggering a transaction commit. This is to guarantee
|
||||||
|
* that after replaying the log tree of the parent directory's root we will not
|
||||||
|
* see the snapshot anymore and at log replay time we will not see any log tree
|
||||||
|
* corresponding to the deleted snapshot's root, which could lead to replaying
|
||||||
|
* it after replaying the log tree of the parent directory (which would replay
|
||||||
|
* the snapshot delete operation).
|
||||||
|
*/
|
||||||
|
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||||
|
struct inode *dir)
|
||||||
|
{
|
||||||
|
BTRFS_I(dir)->last_unlink_trans = trans->transid;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call this after adding a new name for a file and it will properly
|
* Call this after adding a new name for a file and it will properly
|
||||||
* update the log to reflect the new name.
|
* update the log to reflect the new name.
|
||||||
|
|
|
@ -79,6 +79,8 @@ int btrfs_pin_log_trans(struct btrfs_root *root);
|
||||||
void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
|
||||||
struct inode *dir, struct inode *inode,
|
struct inode *dir, struct inode *inode,
|
||||||
int for_rename);
|
int for_rename);
|
||||||
|
void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
|
||||||
|
struct inode *dir);
|
||||||
int btrfs_log_new_name(struct btrfs_trans_handle *trans,
|
int btrfs_log_new_name(struct btrfs_trans_handle *trans,
|
||||||
struct inode *inode, struct inode *old_dir,
|
struct inode *inode, struct inode *old_dir,
|
||||||
struct dentry *parent);
|
struct dentry *parent);
|
||||||
|
|
|
@ -169,10 +169,13 @@ struct ext4_ext_path {
|
||||||
(EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
|
(EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
|
||||||
#define EXT_LAST_INDEX(__hdr__) \
|
#define EXT_LAST_INDEX(__hdr__) \
|
||||||
(EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
|
(EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
|
||||||
#define EXT_MAX_EXTENT(__hdr__) \
|
#define EXT_MAX_EXTENT(__hdr__) \
|
||||||
(EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
|
((le16_to_cpu((__hdr__)->eh_max)) ? \
|
||||||
|
((EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) \
|
||||||
|
: 0)
|
||||||
#define EXT_MAX_INDEX(__hdr__) \
|
#define EXT_MAX_INDEX(__hdr__) \
|
||||||
(EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
|
((le16_to_cpu((__hdr__)->eh_max)) ? \
|
||||||
|
((EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) : 0)
|
||||||
|
|
||||||
static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
|
static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1423,6 +1423,12 @@ static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bpb->fat_fat_length == 0 && bpb->fat32_length == 0) {
|
||||||
|
if (!silent)
|
||||||
|
fat_msg(sb, KERN_ERR, "bogus number of FAT sectors");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -269,6 +269,7 @@ void __inode_attach_wb(struct inode *inode, struct page *page)
|
||||||
if (unlikely(cmpxchg(&inode->i_wb, NULL, wb)))
|
if (unlikely(cmpxchg(&inode->i_wb, NULL, wb)))
|
||||||
wb_put(wb);
|
wb_put(wb);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__inode_attach_wb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* locked_inode_to_wb_and_lock_list - determine a locked inode's wb and lock it
|
* locked_inode_to_wb_and_lock_list - determine a locked inode's wb and lock it
|
||||||
|
|
|
@ -2777,6 +2777,8 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
|
||||||
if (!nilfs->ns_writer)
|
if (!nilfs->ns_writer)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL);
|
||||||
|
|
||||||
err = nilfs_segctor_start_thread(nilfs->ns_writer);
|
err = nilfs_segctor_start_thread(nilfs->ns_writer);
|
||||||
if (err) {
|
if (err) {
|
||||||
kfree(nilfs->ns_writer);
|
kfree(nilfs->ns_writer);
|
||||||
|
|
|
@ -24,7 +24,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
|
||||||
{
|
{
|
||||||
ssize_t list_size, size, value_size = 0;
|
ssize_t list_size, size, value_size = 0;
|
||||||
char *buf, *name, *value = NULL;
|
char *buf, *name, *value = NULL;
|
||||||
int uninitialized_var(error);
|
int error = 0;
|
||||||
size_t slen;
|
size_t slen;
|
||||||
|
|
||||||
if (!old->d_inode->i_op->getxattr ||
|
if (!old->d_inode->i_op->getxattr ||
|
||||||
|
|
|
@ -415,7 +415,7 @@ const struct inode_operations proc_link_inode_operations = {
|
||||||
|
|
||||||
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
||||||
{
|
{
|
||||||
struct inode *inode = new_inode_pseudo(sb);
|
struct inode *inode = new_inode(sb);
|
||||||
|
|
||||||
if (inode) {
|
if (inode) {
|
||||||
inode->i_ino = de->low_ino;
|
inode->i_ino = de->low_ino;
|
||||||
|
|
|
@ -51,7 +51,7 @@ int proc_setup_self(struct super_block *s)
|
||||||
mutex_lock(&root_inode->i_mutex);
|
mutex_lock(&root_inode->i_mutex);
|
||||||
self = d_alloc_name(s->s_root, "self");
|
self = d_alloc_name(s->s_root, "self");
|
||||||
if (self) {
|
if (self) {
|
||||||
struct inode *inode = new_inode_pseudo(s);
|
struct inode *inode = new_inode(s);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
inode->i_ino = self_inum;
|
inode->i_ino = self_inum;
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||||
|
|
|
@ -52,7 +52,7 @@ int proc_setup_thread_self(struct super_block *s)
|
||||||
mutex_lock(&root_inode->i_mutex);
|
mutex_lock(&root_inode->i_mutex);
|
||||||
thread_self = d_alloc_name(s->s_root, "thread-self");
|
thread_self = d_alloc_name(s->s_root, "thread-self");
|
||||||
if (thread_self) {
|
if (thread_self) {
|
||||||
struct inode *inode = new_inode_pseudo(s);
|
struct inode *inode = new_inode(s);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
inode->i_ino = thread_self_inum;
|
inode->i_ino = thread_self_inum;
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||||
|
|
|
@ -317,7 +317,7 @@ extern void gdbstub_exit(int status);
|
||||||
extern int kgdb_single_step;
|
extern int kgdb_single_step;
|
||||||
extern atomic_t kgdb_active;
|
extern atomic_t kgdb_active;
|
||||||
#define in_dbg_master() \
|
#define in_dbg_master() \
|
||||||
(raw_smp_processor_id() == atomic_read(&kgdb_active))
|
(irqs_disabled() && (smp_processor_id() == atomic_read(&kgdb_active)))
|
||||||
extern bool dbg_is_early;
|
extern bool dbg_is_early;
|
||||||
extern void __init dbg_late_init(void);
|
extern void __init dbg_late_init(void);
|
||||||
#else /* ! CONFIG_KGDB */
|
#else /* ! CONFIG_KGDB */
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct pf_desc {
|
||||||
u32 service;
|
u32 service;
|
||||||
char *name;
|
char *name;
|
||||||
char *auth_domain_name;
|
char *auth_domain_name;
|
||||||
|
struct auth_domain *domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
|
/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
|
||||||
|
|
|
@ -20,7 +20,8 @@ int gss_svc_init(void);
|
||||||
void gss_svc_shutdown(void);
|
void gss_svc_shutdown(void);
|
||||||
int gss_svc_init_net(struct net *net);
|
int gss_svc_init_net(struct net *net);
|
||||||
void gss_svc_shutdown_net(struct net *net);
|
void gss_svc_shutdown_net(struct net *net);
|
||||||
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
|
struct auth_domain *svcauth_gss_register_pseudoflavor(u32 pseudoflavor,
|
||||||
|
char *name);
|
||||||
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
|
@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier);
|
||||||
*/
|
*/
|
||||||
int cpu_pm_enter(void)
|
int cpu_pm_enter(void)
|
||||||
{
|
{
|
||||||
int nr_calls;
|
int nr_calls = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
read_lock(&cpu_pm_notifier_lock);
|
read_lock(&cpu_pm_notifier_lock);
|
||||||
|
@ -159,7 +159,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_exit);
|
||||||
*/
|
*/
|
||||||
int cpu_cluster_pm_enter(unsigned long aff_level)
|
int cpu_cluster_pm_enter(unsigned long aff_level)
|
||||||
{
|
{
|
||||||
int nr_calls;
|
int nr_calls = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
read_lock(&cpu_pm_notifier_lock);
|
read_lock(&cpu_pm_notifier_lock);
|
||||||
|
|
|
@ -443,6 +443,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
|
||||||
|
|
||||||
if (exception_level > 1) {
|
if (exception_level > 1) {
|
||||||
dump_stack();
|
dump_stack();
|
||||||
|
kgdb_io_module_registered = false;
|
||||||
panic("Recursive entry to debugger");
|
panic("Recursive entry to debugger");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2504,7 +2504,7 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr)
|
||||||
/*
|
/*
|
||||||
* We don't care about NUMA placement if we don't have memory.
|
* We don't care about NUMA placement if we don't have memory.
|
||||||
*/
|
*/
|
||||||
if (!curr->mm || (curr->flags & PF_EXITING) || work->next != work)
|
if ((curr->flags & (PF_EXITING | PF_KTHREAD)) || work->next != work)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -671,7 +671,7 @@ do { \
|
||||||
************** MIPS/64 **************
|
************** MIPS/64 **************
|
||||||
***************************************/
|
***************************************/
|
||||||
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
|
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
|
||||||
#if defined(__mips_isa_rev) && __mips_isa_rev >= 6
|
#if defined(__mips_isa_rev) && __mips_isa_rev >= 6 && defined(CONFIG_CC_IS_GCC)
|
||||||
/*
|
/*
|
||||||
* GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C
|
* GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C
|
||||||
* code below, so we special case MIPS64r6 until the compiler can do better.
|
* code below, so we special case MIPS64r6 until the compiler can do better.
|
||||||
|
|
|
@ -5557,8 +5557,10 @@ static int sysfs_slab_add(struct kmem_cache *s)
|
||||||
|
|
||||||
s->kobj.kset = cache_kset(s);
|
s->kobj.kset = cache_kset(s);
|
||||||
err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
|
err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
|
||||||
if (err)
|
if (err) {
|
||||||
|
kobject_put(&s->kobj);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
err = sysfs_create_group(&s->kobj, &slab_attr_group);
|
err = sysfs_create_group(&s->kobj, &slab_attr_group);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -3761,6 +3761,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
|
||||||
case 0x11: /* Unsupported Feature or Parameter Value */
|
case 0x11: /* Unsupported Feature or Parameter Value */
|
||||||
case 0x1c: /* SCO interval rejected */
|
case 0x1c: /* SCO interval rejected */
|
||||||
case 0x1a: /* Unsupported Remote Feature */
|
case 0x1a: /* Unsupported Remote Feature */
|
||||||
|
case 0x1e: /* Invalid LMP Parameters */
|
||||||
case 0x1f: /* Unspecified error */
|
case 0x1f: /* Unspecified error */
|
||||||
case 0x20: /* Unsupported LMP Parameter value */
|
case 0x20: /* Unsupported LMP Parameter value */
|
||||||
if (conn->out) {
|
if (conn->out) {
|
||||||
|
|
|
@ -185,14 +185,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
retv = -EBUSY;
|
retv = -EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (sk->sk_protocol == IPPROTO_TCP) {
|
||||||
if (sk->sk_protocol == IPPROTO_TCP &&
|
if (sk->sk_prot != &tcpv6_prot) {
|
||||||
sk->sk_prot != &tcpv6_prot) {
|
retv = -EBUSY;
|
||||||
retv = -EBUSY;
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sk->sk_protocol != IPPROTO_TCP)
|
|
||||||
break;
|
|
||||||
if (sk->sk_state != TCP_ESTABLISHED) {
|
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||||
retv = -ENOTCONN;
|
retv = -ENOTCONN;
|
||||||
break;
|
break;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue