mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
This is the 4.14.84 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlv9XnwACgkQONu9yGCS aT7SQw/8DNAVTNInqqvXPj0JnhSl+jtLS9jhzU08mabBWtNB9bRSJ2wf3BNHwzxp mBuUKyynhJILnuYRRngSWEpsxlYF8PxVfi6hhHJVb7ufiXCEnyQPwOUBovYQengc l+NolggkvaqkQuimom5RYBJZ8tzCszBqwMY7dHMivoKdnzKdW1N69YiGFecmVqzS 9p/I0rwSKuhZDEuBE0kJDRfpDdzpDG+XWV1StV1x8/A/+AOclTjsi6vVkPYqXBVT dXXCaSXHvsxpnAiHlfEGV8M1u8F1Ujjpk1l4YfeLr6+XGFQhu00QMcEXlEiDdC90 7djWg74J+ggguhWkMysUzo3+gZILw4mMS6/6t/Gg+GZWw0/Fx4UP+IxYqLeAHaZ6 O5n6Lm8M3sVEGzBbhbXN9uMGSRN55Cdbcs/eB/RsysiqQmCk9auuf4DFiCaqKqEp dJKE3PLKsHjrS4tU3OEQHkC2ekYYtsg0QKC2bvzdMyO2IbrnhAEvx3ChhQHNDPHQ foo5DWzO3lLa78K+g4EbMROc8DaKWJL3bP59J1yYObpfiqGKV7kMpqYlLS6F3AsS gm/lCXn1ZhMRoyx9VAqDmTTs+g6m8tQpwy69Buo+uDwny9i3OPIfuNjXz0N0dCx8 SyK7XpLh2nS5PtSVZUP+pEGsM06SUa67+lpo9QgFMziHYdnGaiA= =k58w -----END PGP SIGNATURE----- Merge 4.14.84 into android-4.14-p Changes in 4.14.84 cifs: don't dereference smb_file_target before null check cifs: fix return value for cifs_listxattr arm64: kprobe: make page to RO mode when allocate it ixgbe: fix MAC anti-spoofing filter after VFLR reiserfs: propagate errors from fill_with_dentries() properly hfs: prevent btree data loss on root split hfsplus: prevent btree data loss on root split um: Give start_idle_thread() a return code drm/edid: Add 6 bpc quirk for BOE panel. platform/x86: intel_telemetry: report debugfs failure clk: fixed-rate: fix of_node_get-put imbalance perf symbols: Set PLT entry/header sizes properly on Sparc fs/exofs: fix potential memory leak in mount option parsing clk: samsung: exynos5420: Enable PERIS clocks for suspend apparmor: Fix uninitialized value in aa_split_fqname x86/earlyprintk: Add a force option for pciserial device platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307 arm64: percpu: Initialize ret in the default case s390/vdso: add missing FORCE to build targets netfilter: ipset: list:set: Decrease refcount synchronously on deletion and replace netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net s390/mm: Fix ERROR: "__node_distance" undefined! netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment() netfilter: xt_IDLETIMER: add sysfs filename checking routine s390/qeth: fix HiperSockets sniffer hwmon: (ibmpowernv) Remove bogus __init annotations Revert "drm/exynos/decon5433: implement frame counter" clk: fixed-factor: fix of_node_get-put imbalance lib/raid6: Fix arm64 test build s390/perf: Change CPUM_CF return code in event init function sched/core: Take the hotplug lock in sched_init_smp() perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features qed: Fix memory/entry leak in qed_init_sp_request() qed: Fix blocking/unlimited SPQ entries leak qed: Fix potential memory corruption net: stmmac: Fix RX packet size > 8191 zram: close udev startup race condition as default groups SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer() ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM perf machine: Add machine__is() to identify machine arch perf tools: Fix kernel_start for PTI on x86 perf machine: Add nr_cpus_avail() perf machine: Workaround missing maps for x86 PTI entry trampolines perf test code-reading: Fix perf_env setup for PTI entry trampolines x86/mm: Move LDT remap out of KASLR region on 5-level paging x86/ldt: Unmap PTEs for the slot before freeing LDT pages media: v4l: event: Add subscription to list before calling "add" operation MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver uio: Fix an Oops on load usb: cdc-acm: add entry for Hiro (Conexant) modem USB: quirks: Add no-lpm quirk for Raydium touchscreens usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data USB: misc: appledisplay: add 20" Apple Cinema Display drivers/misc/sgi-gru: fix Spectre v1 vulnerability ACPI / platform: Add SMB0001 HID to forbidden_id_list HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges libceph: fall back to sendmsg for slab pages Linux 4.14.84 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
fa255125cd
@ -1014,7 +1014,7 @@
|
||||
earlyprintk=serial[,0x...[,baudrate]]
|
||||
earlyprintk=ttySn[,baudrate]
|
||||
earlyprintk=dbgp[debugController#]
|
||||
earlyprintk=pciserial,bus:device.function[,baudrate]
|
||||
earlyprintk=pciserial[,force],bus:device.function[,baudrate]
|
||||
earlyprintk=xdbc[xhciController#]
|
||||
|
||||
earlyprintk is useful when the kernel crashes before
|
||||
@ -1046,6 +1046,10 @@
|
||||
|
||||
The sclp output can only be used on s390.
|
||||
|
||||
The optional "force" to "pciserial" enables use of a
|
||||
PCI device even when its classcode is not of the
|
||||
UART class.
|
||||
|
||||
edac_report= [HW,EDAC] Control how to report EDAC event
|
||||
Format: {"on" | "off" | "force"}
|
||||
on: enable EDAC to report H/W event. May be overridden
|
||||
|
@ -4,8 +4,9 @@ Virtual memory map with 4 level page tables:
|
||||
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
|
||||
hole caused by [47:63] sign extension
|
||||
ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor
|
||||
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
|
||||
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
|
||||
ffff880000000000 - ffff887fffffffff (=39 bits) LDT remap for PTI
|
||||
ffff888000000000 - ffffc87fffffffff (=64 TB) direct mapping of all phys. memory
|
||||
ffffc88000000000 - ffffc8ffffffffff (=39 bits) hole
|
||||
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
|
||||
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
||||
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||
@ -30,8 +31,9 @@ Virtual memory map with 5 level page tables:
|
||||
0000000000000000 - 00ffffffffffffff (=56 bits) user space, different per mm
|
||||
hole caused by [56:63] sign extension
|
||||
ff00000000000000 - ff0fffffffffffff (=52 bits) guard hole, reserved for hypervisor
|
||||
ff10000000000000 - ff8fffffffffffff (=55 bits) direct mapping of all phys. memory
|
||||
ff90000000000000 - ff9fffffffffffff (=52 bits) LDT remap for PTI
|
||||
ff10000000000000 - ff10ffffffffffff (=48 bits) LDT remap for PTI
|
||||
ff11000000000000 - ff90ffffffffffff (=55 bits) direct mapping of all phys. memory
|
||||
ff91000000000000 - ff9fffffffffffff (=3840 TB) hole
|
||||
ffa0000000000000 - ffd1ffffffffffff (=54 bits) vmalloc/ioremap space (12800 TB)
|
||||
ffd2000000000000 - ffd3ffffffffffff (=49 bits) hole
|
||||
ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB)
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 83
|
||||
SUBLEVEL = 84
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
@ -93,6 +93,7 @@ static inline unsigned long __percpu_##op(void *ptr, \
|
||||
: [val] "Ir" (val)); \
|
||||
break; \
|
||||
default: \
|
||||
ret = 0; \
|
||||
BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
@ -122,6 +123,7 @@ static inline unsigned long __percpu_read(void *ptr, int size)
|
||||
ret = READ_ONCE(*(u64 *)ptr);
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
BUILD_BUG();
|
||||
}
|
||||
|
||||
@ -191,6 +193,7 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
|
||||
: [val] "r" (val));
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
BUILD_BUG();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/set_memory.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@ -42,10 +44,21 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
static void __kprobes
|
||||
post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
|
||||
|
||||
static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
|
||||
{
|
||||
void *addrs[1];
|
||||
u32 insns[1];
|
||||
|
||||
addrs[0] = addr;
|
||||
insns[0] = opcode;
|
||||
|
||||
return aarch64_insn_patch_text(addrs, insns, 1);
|
||||
}
|
||||
|
||||
static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
|
||||
{
|
||||
/* prepare insn slot */
|
||||
p->ainsn.api.insn[0] = cpu_to_le32(p->opcode);
|
||||
patch_text(p->ainsn.api.insn, p->opcode);
|
||||
|
||||
flush_icache_range((uintptr_t) (p->ainsn.api.insn),
|
||||
(uintptr_t) (p->ainsn.api.insn) +
|
||||
@ -118,15 +131,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
|
||||
void *alloc_insn_page(void)
|
||||
{
|
||||
void *addrs[1];
|
||||
u32 insns[1];
|
||||
void *page;
|
||||
|
||||
addrs[0] = (void *)addr;
|
||||
insns[0] = (u32)opcode;
|
||||
page = vmalloc_exec(PAGE_SIZE);
|
||||
if (page)
|
||||
set_memory_ro((unsigned long)page, 1);
|
||||
|
||||
return aarch64_insn_patch_text(addrs, insns, 1);
|
||||
return page;
|
||||
}
|
||||
|
||||
/* arm kprobe: install breakpoint in text */
|
||||
|
@ -140,6 +140,7 @@ CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_DS1307=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_OCTEON_ETHERNET=y
|
||||
CONFIG_OCTEON_USB=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_RAS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
|
@ -376,7 +376,7 @@ static int __hw_perf_event_init(struct perf_event *event)
|
||||
return -ENOENT;
|
||||
|
||||
if (ev > PERF_CPUM_CF_MAX_CTR)
|
||||
return -EINVAL;
|
||||
return -ENOENT;
|
||||
|
||||
/* Obtain the counter set to which the specified counter belongs */
|
||||
set = get_counter_set(ev);
|
||||
|
@ -33,7 +33,7 @@ UBSAN_SANITIZE := n
|
||||
$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
|
||||
|
||||
# link rule for the .so file, .lds has to be first
|
||||
$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32)
|
||||
$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) FORCE
|
||||
$(call if_changed,vdso32ld)
|
||||
|
||||
# strip rule for the .so file
|
||||
@ -42,12 +42,12 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
# assembly rules for the .S files
|
||||
$(obj-vdso32): %.o: %.S
|
||||
$(obj-vdso32): %.o: %.S FORCE
|
||||
$(call if_changed_dep,vdso32as)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso32ld = VDSO32L $@
|
||||
cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
|
||||
cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
|
||||
quiet_cmd_vdso32as = VDSO32A $@
|
||||
cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $<
|
||||
|
||||
|
@ -33,7 +33,7 @@ UBSAN_SANITIZE := n
|
||||
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
|
||||
|
||||
# link rule for the .so file, .lds has to be first
|
||||
$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64)
|
||||
$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE
|
||||
$(call if_changed,vdso64ld)
|
||||
|
||||
# strip rule for the .so file
|
||||
@ -42,12 +42,12 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
# assembly rules for the .S files
|
||||
$(obj-vdso64): %.o: %.S
|
||||
$(obj-vdso64): %.o: %.S FORCE
|
||||
$(call if_changed_dep,vdso64as)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso64ld = VDSO64L $@
|
||||
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
|
||||
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
|
||||
quiet_cmd_vdso64as = VDSO64A $@
|
||||
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
|
||||
|
||||
|
@ -54,6 +54,7 @@ int __node_distance(int a, int b)
|
||||
{
|
||||
return mode->distance ? mode->distance(a, b) : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__node_distance);
|
||||
|
||||
int numa_debug_enabled;
|
||||
|
||||
|
@ -610,6 +610,11 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
|
||||
fatal_sigsegv();
|
||||
}
|
||||
longjmp(*switch_buf, 1);
|
||||
|
||||
/* unreachable */
|
||||
printk(UM_KERN_ERR "impossible long jump!");
|
||||
fatal_sigsegv();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initial_thread_cb_skas(void (*proc)(void *), void *arg)
|
||||
|
@ -33,14 +33,16 @@
|
||||
|
||||
/*
|
||||
* Set __PAGE_OFFSET to the most negative possible address +
|
||||
* PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a
|
||||
* hypervisor to fit. Choosing 16 slots here is arbitrary, but it's
|
||||
* what Xen requires.
|
||||
* PGDIR_SIZE*17 (pgd slot 273).
|
||||
*
|
||||
* The gap is to allow a space for LDT remap for PTI (1 pgd slot) and space for
|
||||
* a hypervisor (16 slots). Choosing 16 slots for a hypervisor is arbitrary,
|
||||
* but it's what Xen requires.
|
||||
*/
|
||||
#ifdef CONFIG_X86_5LEVEL
|
||||
#define __PAGE_OFFSET_BASE _AC(0xff10000000000000, UL)
|
||||
#define __PAGE_OFFSET_BASE _AC(0xff11000000000000, UL)
|
||||
#else
|
||||
#define __PAGE_OFFSET_BASE _AC(0xffff880000000000, UL)
|
||||
#define __PAGE_OFFSET_BASE _AC(0xffff888000000000, UL)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_MEMORY
|
||||
|
@ -88,16 +88,15 @@ typedef struct { pteval_t pte; } pte_t;
|
||||
# define VMALLOC_SIZE_TB _AC(12800, UL)
|
||||
# define __VMALLOC_BASE _AC(0xffa0000000000000, UL)
|
||||
# define __VMEMMAP_BASE _AC(0xffd4000000000000, UL)
|
||||
# define LDT_PGD_ENTRY _AC(-112, UL)
|
||||
# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
|
||||
#else
|
||||
# define VMALLOC_SIZE_TB _AC(32, UL)
|
||||
# define __VMALLOC_BASE _AC(0xffffc90000000000, UL)
|
||||
# define __VMEMMAP_BASE _AC(0xffffea0000000000, UL)
|
||||
# define LDT_PGD_ENTRY _AC(-3, UL)
|
||||
# define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
|
||||
#endif
|
||||
|
||||
#define LDT_PGD_ENTRY -240UL
|
||||
#define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT)
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_MEMORY
|
||||
# define VMALLOC_START vmalloc_base
|
||||
# define VMEMMAP_START vmemmap_base
|
||||
|
@ -213,8 +213,9 @@ static unsigned int mem32_serial_in(unsigned long addr, int offset)
|
||||
* early_pci_serial_init()
|
||||
*
|
||||
* This function is invoked when the early_printk param starts with "pciserial"
|
||||
* The rest of the param should be ",B:D.F,baud" where B, D & F describe the
|
||||
* location of a PCI device that must be a UART device.
|
||||
* The rest of the param should be "[force],B:D.F,baud", where B, D & F describe
|
||||
* the location of a PCI device that must be a UART device. "force" is optional
|
||||
* and overrides the use of an UART device with a wrong PCI class code.
|
||||
*/
|
||||
static __init void early_pci_serial_init(char *s)
|
||||
{
|
||||
@ -224,17 +225,23 @@ static __init void early_pci_serial_init(char *s)
|
||||
u32 classcode, bar0;
|
||||
u16 cmdreg;
|
||||
char *e;
|
||||
int force = 0;
|
||||
|
||||
|
||||
/*
|
||||
* First, part the param to get the BDF values
|
||||
*/
|
||||
if (*s == ',')
|
||||
++s;
|
||||
|
||||
if (*s == 0)
|
||||
return;
|
||||
|
||||
/* Force the use of an UART device with wrong class code */
|
||||
if (!strncmp(s, "force,", 6)) {
|
||||
force = 1;
|
||||
s += 6;
|
||||
}
|
||||
|
||||
/*
|
||||
* Part the param to get the BDF values
|
||||
*/
|
||||
bus = (u8)simple_strtoul(s, &e, 16);
|
||||
s = e;
|
||||
if (*s != ':')
|
||||
@ -253,7 +260,7 @@ static __init void early_pci_serial_init(char *s)
|
||||
s++;
|
||||
|
||||
/*
|
||||
* Second, find the device from the BDF
|
||||
* Find the device from the BDF
|
||||
*/
|
||||
cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND);
|
||||
classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
|
||||
@ -264,8 +271,10 @@ static __init void early_pci_serial_init(char *s)
|
||||
*/
|
||||
if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) &&
|
||||
(classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) ||
|
||||
(((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */
|
||||
return;
|
||||
(((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ {
|
||||
if (!force)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if it is IO or memory mapped
|
||||
@ -289,7 +298,7 @@ static __init void early_pci_serial_init(char *s)
|
||||
}
|
||||
|
||||
/*
|
||||
* Lastly, initialize the hardware
|
||||
* Initialize the hardware
|
||||
*/
|
||||
if (*s) {
|
||||
if (strcmp(s, "nocfg") == 0)
|
||||
|
@ -103,14 +103,6 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
|
||||
/*
|
||||
* If PTI is enabled, this maps the LDT into the kernelmode and
|
||||
* usermode tables for the given mm.
|
||||
*
|
||||
* There is no corresponding unmap function. Even if the LDT is freed, we
|
||||
* leave the PTEs around until the slot is reused or the mm is destroyed.
|
||||
* This is harmless: the LDT is always in ordinary memory, and no one will
|
||||
* access the freed slot.
|
||||
*
|
||||
* If we wanted to unmap freed LDTs, we'd also need to do a flush to make
|
||||
* it useful, and the flush would slow down modify_ldt().
|
||||
*/
|
||||
static int
|
||||
map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
|
||||
@ -119,8 +111,8 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
|
||||
bool is_vmalloc, had_top_level_entry;
|
||||
unsigned long va;
|
||||
spinlock_t *ptl;
|
||||
int i, nr_pages;
|
||||
pgd_t *pgd;
|
||||
int i;
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
return 0;
|
||||
@ -141,7 +133,9 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
|
||||
|
||||
is_vmalloc = is_vmalloc_addr(ldt->entries);
|
||||
|
||||
for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) {
|
||||
nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
unsigned long offset = i << PAGE_SHIFT;
|
||||
const void *src = (char *)ldt->entries + offset;
|
||||
unsigned long pfn;
|
||||
@ -189,14 +183,42 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
|
||||
}
|
||||
}
|
||||
|
||||
va = (unsigned long)ldt_slot_va(slot);
|
||||
flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, 0);
|
||||
|
||||
ldt->slot = slot;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
|
||||
{
|
||||
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||
unsigned long va;
|
||||
int i, nr_pages;
|
||||
|
||||
if (!ldt)
|
||||
return;
|
||||
|
||||
/* LDT map/unmap is only required for PTI */
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
unsigned long offset = i << PAGE_SHIFT;
|
||||
spinlock_t *ptl;
|
||||
pte_t *ptep;
|
||||
|
||||
va = (unsigned long)ldt_slot_va(ldt->slot) + offset;
|
||||
ptep = get_locked_pte(mm, va, &ptl);
|
||||
pte_clear(mm, va, ptep);
|
||||
pte_unmap_unlock(ptep, ptl);
|
||||
}
|
||||
|
||||
va = (unsigned long)ldt_slot_va(ldt->slot);
|
||||
flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, 0);
|
||||
#endif /* CONFIG_PAGE_TABLE_ISOLATION */
|
||||
}
|
||||
|
||||
static void free_ldt_pgtables(struct mm_struct *mm)
|
||||
{
|
||||
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||
@ -433,6 +455,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
|
||||
}
|
||||
|
||||
install_ldt(mm, new_ldt);
|
||||
unmap_ldt_struct(mm, old_ldt);
|
||||
free_ldt_struct(old_ldt);
|
||||
error = 0;
|
||||
|
||||
|
@ -1869,7 +1869,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
|
||||
init_top_pgt[0] = __pgd(0);
|
||||
|
||||
/* Pre-constructed entries are in pfn, so convert to mfn */
|
||||
/* L4[272] -> level3_ident_pgt */
|
||||
/* L4[273] -> level3_ident_pgt */
|
||||
/* L4[511] -> level3_kernel_pgt */
|
||||
convert_pfn_mfn(init_top_pgt);
|
||||
|
||||
@ -1889,8 +1889,8 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
|
||||
addr[0] = (unsigned long)pgd;
|
||||
addr[1] = (unsigned long)l3;
|
||||
addr[2] = (unsigned long)l2;
|
||||
/* Graft it onto L4[272][0]. Note that we creating an aliasing problem:
|
||||
* Both L4[272][0] and L4[511][510] have entries that point to the same
|
||||
/* Graft it onto L4[273][0]. Note that we creating an aliasing problem:
|
||||
* Both L4[273][0] and L4[511][510] have entries that point to the same
|
||||
* L2 (PMD) tables. Meaning that if you modify it in __va space
|
||||
* it will be also modified in the __ka space! (But if you just
|
||||
* modify the PMD table to point to other PTE's or none, then you
|
||||
|
@ -30,6 +30,7 @@ static const struct acpi_device_id forbidden_id_list[] = {
|
||||
{"PNP0200", 0}, /* AT DMA Controller */
|
||||
{"ACPI0009", 0}, /* IOxAPIC */
|
||||
{"ACPI000A", 0}, /* IOAPIC */
|
||||
{"SMB0001", 0}, /* ACPI SMBUS virtual device */
|
||||
{"", 0},
|
||||
};
|
||||
|
||||
|
@ -12,35 +12,51 @@
|
||||
#define pr_fmt(fmt) "ACPI: watchdog: " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static const struct dmi_system_id acpi_watchdog_skip[] = {
|
||||
{
|
||||
/*
|
||||
* On Lenovo Z50-70 there are two issues with the WDAT
|
||||
* table. First some of the instructions use RTC SRAM
|
||||
* to store persistent information. This does not work well
|
||||
* with Linux RTC driver. Second, more important thing is
|
||||
* that the instructions do not actually reset the system.
|
||||
*
|
||||
* On this particular system iTCO_wdt seems to work just
|
||||
* fine so we prefer that over WDAT for now.
|
||||
*
|
||||
* See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
|
||||
*/
|
||||
.ident = "Lenovo Z50-70",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
#ifdef CONFIG_RTC_MC146818_LIB
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
/*
|
||||
* There are several systems where the WDAT table is accessing RTC SRAM to
|
||||
* store persistent information. This does not work well with the Linux RTC
|
||||
* driver so on those systems we skip WDAT driver and prefer iTCO_wdt
|
||||
* instead.
|
||||
*
|
||||
* See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
|
||||
*/
|
||||
static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
|
||||
{
|
||||
const struct acpi_wdat_entry *entries;
|
||||
int i;
|
||||
|
||||
entries = (struct acpi_wdat_entry *)(wdat + 1);
|
||||
for (i = 0; i < wdat->entries; i++) {
|
||||
const struct acpi_generic_address *gas;
|
||||
|
||||
gas = &entries[i].register_region;
|
||||
if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
|
||||
switch (gas->address) {
|
||||
case RTC_PORT(0):
|
||||
case RTC_PORT(1):
|
||||
case RTC_PORT(2):
|
||||
case RTC_PORT(3):
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
|
||||
{
|
||||
@ -50,9 +66,6 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
|
||||
if (acpi_disabled)
|
||||
return NULL;
|
||||
|
||||
if (dmi_check_system(acpi_watchdog_skip))
|
||||
return NULL;
|
||||
|
||||
status = acpi_get_table(ACPI_SIG_WDAT, 0,
|
||||
(struct acpi_table_header **)&wdat);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
@ -60,6 +73,11 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (acpi_watchdog_uses_rtc(wdat)) {
|
||||
pr_info("Skipping WDAT on this system because it uses RTC SRAM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wdat;
|
||||
}
|
||||
|
||||
|
@ -1491,6 +1491,11 @@ static const struct attribute_group zram_disk_attr_group = {
|
||||
.attrs = zram_disk_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *zram_disk_attr_groups[] = {
|
||||
&zram_disk_attr_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate and initialize new zram device. the function returns
|
||||
* '>= 0' device_id upon success, and negative value otherwise.
|
||||
@ -1568,23 +1573,14 @@ static int zram_add(void)
|
||||
if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE)
|
||||
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
|
||||
|
||||
disk_to_dev(zram->disk)->groups = zram_disk_attr_groups;
|
||||
add_disk(zram->disk);
|
||||
|
||||
ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj,
|
||||
&zram_disk_attr_group);
|
||||
if (ret < 0) {
|
||||
pr_err("Error creating sysfs group for device %d\n",
|
||||
device_id);
|
||||
goto out_free_disk;
|
||||
}
|
||||
strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor));
|
||||
|
||||
pr_info("Added device: %s\n", zram->disk->disk_name);
|
||||
return device_id;
|
||||
|
||||
out_free_disk:
|
||||
del_gendisk(zram->disk);
|
||||
put_disk(zram->disk);
|
||||
out_free_queue:
|
||||
blk_cleanup_queue(queue);
|
||||
out_free_idr:
|
||||
@ -1612,16 +1608,6 @@ static int zram_remove(struct zram *zram)
|
||||
zram->claim = true;
|
||||
mutex_unlock(&bdev->bd_mutex);
|
||||
|
||||
/*
|
||||
* Remove sysfs first, so no one will perform a disksize
|
||||
* store while we destroy the devices. This also helps during
|
||||
* hot_remove -- zram_reset_device() is the last holder of
|
||||
* ->init_lock, no later/concurrent disksize_store() or any
|
||||
* other sysfs handlers are possible.
|
||||
*/
|
||||
sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
|
||||
&zram_disk_attr_group);
|
||||
|
||||
/* Make sure all the pending I/O are finished */
|
||||
fsync_bdev(bdev);
|
||||
zram_reset_device(zram);
|
||||
|
@ -210,6 +210,7 @@ static int of_fixed_factor_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk = platform_get_drvdata(pdev);
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
clk_unregister_fixed_factor(clk);
|
||||
|
||||
return 0;
|
||||
|
@ -200,6 +200,7 @@ static int of_fixed_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk = platform_get_drvdata(pdev);
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
clk_unregister_fixed_rate(clk);
|
||||
|
||||
return 0;
|
||||
|
@ -280,6 +280,7 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
|
||||
{ .offset = GATE_BUS_TOP, .value = 0xffffffff, },
|
||||
{ .offset = GATE_BUS_DISP1, .value = 0xffffffff, },
|
||||
{ .offset = GATE_IP_PERIC, .value = 0xffffffff, },
|
||||
{ .offset = GATE_IP_PERIS, .value = 0xffffffff, },
|
||||
};
|
||||
|
||||
static int exynos5420_clk_suspend(void)
|
||||
|
@ -120,6 +120,9 @@ static const struct edid_quirk {
|
||||
/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
|
||||
{ "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
|
||||
|
||||
/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
|
||||
{ "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
|
||||
|
||||
/* Belinea 10 15 55 */
|
||||
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
|
@ -160,13 +160,6 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
|
||||
return frm;
|
||||
}
|
||||
|
||||
static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
|
||||
{
|
||||
struct decon_context *ctx = crtc->ctx;
|
||||
|
||||
return decon_get_frame_count(ctx, false);
|
||||
}
|
||||
|
||||
static void decon_setup_trigger(struct decon_context *ctx)
|
||||
{
|
||||
if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG))
|
||||
@ -532,7 +525,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
|
||||
.disable = decon_disable,
|
||||
.enable_vblank = decon_enable_vblank,
|
||||
.disable_vblank = decon_disable_vblank,
|
||||
.get_vblank_counter = decon_get_vblank_counter,
|
||||
.atomic_begin = decon_atomic_begin,
|
||||
.update_plane = decon_update_plane,
|
||||
.disable_plane = decon_disable_plane,
|
||||
@ -550,7 +542,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
|
||||
int ret;
|
||||
|
||||
ctx->drm_dev = drm_dev;
|
||||
drm_dev->max_vblank_count = 0xffffffff;
|
||||
|
||||
for (win = ctx->first_win; win < WINDOWS_NR; win++) {
|
||||
int tmp = (win == ctx->first_win) ? 0 : win;
|
||||
|
@ -147,16 +147,6 @@ static void exynos_drm_crtc_disable_vblank(struct drm_crtc *crtc)
|
||||
exynos_crtc->ops->disable_vblank(exynos_crtc);
|
||||
}
|
||||
|
||||
static u32 exynos_drm_crtc_get_vblank_counter(struct drm_crtc *crtc)
|
||||
{
|
||||
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
|
||||
|
||||
if (exynos_crtc->ops->get_vblank_counter)
|
||||
return exynos_crtc->ops->get_vblank_counter(exynos_crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs exynos_crtc_funcs = {
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
@ -166,7 +156,6 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = {
|
||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||
.enable_vblank = exynos_drm_crtc_enable_vblank,
|
||||
.disable_vblank = exynos_drm_crtc_disable_vblank,
|
||||
.get_vblank_counter = exynos_drm_crtc_get_vblank_counter,
|
||||
};
|
||||
|
||||
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
||||
|
@ -133,7 +133,6 @@ struct exynos_drm_crtc_ops {
|
||||
void (*disable)(struct exynos_drm_crtc *crtc);
|
||||
int (*enable_vblank)(struct exynos_drm_crtc *crtc);
|
||||
void (*disable_vblank)(struct exynos_drm_crtc *crtc);
|
||||
u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
|
||||
enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode);
|
||||
int (*atomic_check)(struct exynos_drm_crtc *crtc,
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/hid.h>
|
||||
@ -722,6 +723,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
|
||||
|
||||
switch (uhid->input_buf.type) {
|
||||
case UHID_CREATE:
|
||||
/*
|
||||
* 'struct uhid_create_req' contains a __user pointer which is
|
||||
* copied from, so it's unsafe to allow this with elevated
|
||||
* privileges (e.g. from a setuid binary) or via kernel_write().
|
||||
*/
|
||||
if (file->f_cred != current_cred() || uaccess_kernel()) {
|
||||
pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n",
|
||||
task_tgid_vnr(current), current->comm);
|
||||
ret = -EACCES;
|
||||
goto unlock;
|
||||
}
|
||||
ret = uhid_dev_create(uhid, &uhid->input_buf);
|
||||
break;
|
||||
case UHID_CREATE2:
|
||||
|
@ -126,7 +126,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
|
||||
return sprintf(buf, "%s\n", sdata->label);
|
||||
}
|
||||
|
||||
static int __init get_logical_cpu(int hwcpu)
|
||||
static int get_logical_cpu(int hwcpu)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
@ -137,9 +137,8 @@ static int __init get_logical_cpu(int hwcpu)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void __init make_sensor_label(struct device_node *np,
|
||||
struct sensor_data *sdata,
|
||||
const char *label)
|
||||
static void make_sensor_label(struct device_node *np,
|
||||
struct sensor_data *sdata, const char *label)
|
||||
{
|
||||
u32 id;
|
||||
size_t n;
|
||||
|
@ -193,6 +193,22 @@ int v4l2_event_pending(struct v4l2_fh *fh)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_event_pending);
|
||||
|
||||
static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev)
|
||||
{
|
||||
struct v4l2_fh *fh = sev->fh;
|
||||
unsigned int i;
|
||||
|
||||
lockdep_assert_held(&fh->subscribe_lock);
|
||||
assert_spin_locked(&fh->vdev->fh_lock);
|
||||
|
||||
/* Remove any pending events for this subscription */
|
||||
for (i = 0; i < sev->in_use; i++) {
|
||||
list_del(&sev->events[sev_pos(sev, i)].list);
|
||||
fh->navailable--;
|
||||
}
|
||||
list_del(&sev->list);
|
||||
}
|
||||
|
||||
int v4l2_event_subscribe(struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub, unsigned elems,
|
||||
const struct v4l2_subscribed_event_ops *ops)
|
||||
@ -225,27 +241,23 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
|
||||
|
||||
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
|
||||
found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
|
||||
if (!found_ev)
|
||||
list_add(&sev->list, &fh->subscribed);
|
||||
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
|
||||
|
||||
if (found_ev) {
|
||||
/* Already listening */
|
||||
kvfree(sev);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (sev->ops && sev->ops->add) {
|
||||
} else if (sev->ops && sev->ops->add) {
|
||||
ret = sev->ops->add(sev, elems);
|
||||
if (ret) {
|
||||
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
|
||||
__v4l2_event_unsubscribe(sev);
|
||||
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
|
||||
kvfree(sev);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
|
||||
list_add(&sev->list, &fh->subscribed);
|
||||
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&fh->subscribe_lock);
|
||||
|
||||
return ret;
|
||||
@ -280,7 +292,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
|
||||
{
|
||||
struct v4l2_subscribed_event *sev;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
if (sub->type == V4L2_EVENT_ALL) {
|
||||
v4l2_event_unsubscribe_all(fh);
|
||||
@ -292,14 +303,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
|
||||
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
|
||||
|
||||
sev = v4l2_event_subscribed(fh, sub->type, sub->id);
|
||||
if (sev != NULL) {
|
||||
/* Remove any pending events for this subscription */
|
||||
for (i = 0; i < sev->in_use; i++) {
|
||||
list_del(&sev->events[sev_pos(sev, i)].list);
|
||||
fh->navailable--;
|
||||
}
|
||||
list_del(&sev->list);
|
||||
}
|
||||
if (sev != NULL)
|
||||
__v4l2_event_unsubscribe(sev);
|
||||
|
||||
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
|
||||
|
||||
|
@ -132,7 +132,7 @@ static const struct of_device_id atmel_ssc_dt_ids[] = {
|
||||
MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids);
|
||||
#endif
|
||||
|
||||
static inline const struct atmel_ssc_platform_data * __init
|
||||
static inline const struct atmel_ssc_platform_data *
|
||||
atmel_ssc_get_driver_data(struct platform_device *pdev)
|
||||
{
|
||||
if (pdev->dev.of_node) {
|
||||
|
@ -27,6 +27,9 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/uv/uv_hub.h>
|
||||
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include "gru.h"
|
||||
#include "grutables.h"
|
||||
#include "gruhandles.h"
|
||||
@ -196,6 +199,7 @@ int gru_dump_chiplet_request(unsigned long arg)
|
||||
/* Currently, only dump by gid is implemented */
|
||||
if (req.gid >= gru_max_gids)
|
||||
return -EINVAL;
|
||||
req.gid = array_index_nospec(req.gid, gru_max_gids);
|
||||
|
||||
gru = GID_TO_GRU(req.gid);
|
||||
ubuf = req.buf;
|
||||
|
@ -9688,6 +9688,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
||||
NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM |
|
||||
NETIF_F_GSO_PARTIAL |
|
||||
NETIF_F_GSO_IPXIP4 |
|
||||
NETIF_F_GSO_IPXIP6 |
|
||||
NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
||||
NETIF_F_SCTP_CRC |
|
||||
|
@ -760,8 +760,10 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
|
||||
ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
|
||||
adapter->default_up, vf);
|
||||
|
||||
if (vfinfo->spoofchk_enabled)
|
||||
if (vfinfo->spoofchk_enabled) {
|
||||
hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
|
||||
hw->mac.ops.set_mac_anti_spoofing(hw, true, vf);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset multicast table array for vf */
|
||||
|
@ -167,6 +167,9 @@ struct qed_spq_entry {
|
||||
enum spq_mode comp_mode;
|
||||
struct qed_spq_comp_cb comp_cb;
|
||||
struct qed_spq_comp_done comp_done; /* SPQ_MODE_EBLOCK */
|
||||
|
||||
/* Posted entry for unlimited list entry in EBLOCK mode */
|
||||
struct qed_spq_entry *post_ent;
|
||||
};
|
||||
|
||||
struct qed_eq {
|
||||
|
@ -80,7 +80,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
|
||||
|
||||
case QED_SPQ_MODE_BLOCK:
|
||||
if (!p_data->p_comp_data)
|
||||
return -EINVAL;
|
||||
goto err;
|
||||
|
||||
p_ent->comp_cb.cookie = p_data->p_comp_data->cookie;
|
||||
break;
|
||||
@ -95,7 +95,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
|
||||
default:
|
||||
DP_NOTICE(p_hwfn, "Unknown SPQE completion mode %d\n",
|
||||
p_ent->comp_mode);
|
||||
return -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
|
||||
@ -109,6 +109,18 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
|
||||
memset(&p_ent->ramrod, 0, sizeof(p_ent->ramrod));
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* qed_spq_get_entry() can either get an entry from the free_pool,
|
||||
* or, if no entries are left, allocate a new entry and add it to
|
||||
* the unlimited_pending list.
|
||||
*/
|
||||
if (p_ent->queue == &p_hwfn->p_spq->unlimited_pending)
|
||||
kfree(p_ent);
|
||||
else
|
||||
qed_spq_return_entry(p_hwfn, p_ent);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static enum tunnel_clss qed_tunn_clss_to_fw_clss(u8 type)
|
||||
|
@ -144,6 +144,7 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
|
||||
|
||||
DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n");
|
||||
rc = qed_mcp_drain(p_hwfn, p_ptt);
|
||||
qed_ptt_release(p_hwfn, p_ptt);
|
||||
if (rc) {
|
||||
DP_NOTICE(p_hwfn, "MCP drain failed\n");
|
||||
goto err;
|
||||
@ -152,18 +153,15 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
|
||||
/* Retry after drain */
|
||||
rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
|
||||
if (!rc)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
|
||||
if (comp_done->done == 1)
|
||||
if (comp_done->done == 1) {
|
||||
if (p_fw_ret)
|
||||
*p_fw_ret = comp_done->fw_return_code;
|
||||
out:
|
||||
qed_ptt_release(p_hwfn, p_ptt);
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
err:
|
||||
qed_ptt_release(p_hwfn, p_ptt);
|
||||
DP_NOTICE(p_hwfn,
|
||||
"Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
|
||||
le32_to_cpu(p_ent->elem.hdr.cid),
|
||||
@ -687,6 +685,8 @@ static int qed_spq_add_entry(struct qed_hwfn *p_hwfn,
|
||||
/* EBLOCK responsible to free the allocated p_ent */
|
||||
if (p_ent->comp_mode != QED_SPQ_MODE_EBLOCK)
|
||||
kfree(p_ent);
|
||||
else
|
||||
p_ent->post_ent = p_en2;
|
||||
|
||||
p_ent = p_en2;
|
||||
}
|
||||
@ -770,6 +770,25 @@ static int qed_spq_pend_post(struct qed_hwfn *p_hwfn)
|
||||
SPQ_HIGH_PRI_RESERVE_DEFAULT);
|
||||
}
|
||||
|
||||
/* Avoid overriding of SPQ entries when getting out-of-order completions, by
|
||||
* marking the completions in a bitmap and increasing the chain consumer only
|
||||
* for the first successive completed entries.
|
||||
*/
|
||||
static void qed_spq_comp_bmap_update(struct qed_hwfn *p_hwfn, __le16 echo)
|
||||
{
|
||||
u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE;
|
||||
struct qed_spq *p_spq = p_hwfn->p_spq;
|
||||
|
||||
__set_bit(pos, p_spq->p_comp_bitmap);
|
||||
while (test_bit(p_spq->comp_bitmap_idx,
|
||||
p_spq->p_comp_bitmap)) {
|
||||
__clear_bit(p_spq->comp_bitmap_idx,
|
||||
p_spq->p_comp_bitmap);
|
||||
p_spq->comp_bitmap_idx++;
|
||||
qed_chain_return_produced(&p_spq->chain);
|
||||
}
|
||||
}
|
||||
|
||||
int qed_spq_post(struct qed_hwfn *p_hwfn,
|
||||
struct qed_spq_entry *p_ent, u8 *fw_return_code)
|
||||
{
|
||||
@ -821,11 +840,12 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
|
||||
p_ent->queue == &p_spq->unlimited_pending);
|
||||
|
||||
if (p_ent->queue == &p_spq->unlimited_pending) {
|
||||
/* This is an allocated p_ent which does not need to
|
||||
* return to pool.
|
||||
*/
|
||||
struct qed_spq_entry *p_post_ent = p_ent->post_ent;
|
||||
|
||||
kfree(p_ent);
|
||||
return rc;
|
||||
|
||||
/* Return the entry which was actually posted */
|
||||
p_ent = p_post_ent;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
@ -839,7 +859,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
|
||||
spq_post_fail2:
|
||||
spin_lock_bh(&p_spq->lock);
|
||||
list_del(&p_ent->list);
|
||||
qed_chain_return_produced(&p_spq->chain);
|
||||
qed_spq_comp_bmap_update(p_hwfn, p_ent->elem.hdr.echo);
|
||||
|
||||
spq_post_fail:
|
||||
/* return to the free pool */
|
||||
@ -871,25 +891,8 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
|
||||
spin_lock_bh(&p_spq->lock);
|
||||
list_for_each_entry_safe(p_ent, tmp, &p_spq->completion_pending, list) {
|
||||
if (p_ent->elem.hdr.echo == echo) {
|
||||
u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE;
|
||||
|
||||
list_del(&p_ent->list);
|
||||
|
||||
/* Avoid overriding of SPQ entries when getting
|
||||
* out-of-order completions, by marking the completions
|
||||
* in a bitmap and increasing the chain consumer only
|
||||
* for the first successive completed entries.
|
||||
*/
|
||||
__set_bit(pos, p_spq->p_comp_bitmap);
|
||||
|
||||
while (test_bit(p_spq->comp_bitmap_idx,
|
||||
p_spq->p_comp_bitmap)) {
|
||||
__clear_bit(p_spq->comp_bitmap_idx,
|
||||
p_spq->p_comp_bitmap);
|
||||
p_spq->comp_bitmap_idx++;
|
||||
qed_chain_return_produced(&p_spq->chain);
|
||||
}
|
||||
|
||||
qed_spq_comp_bmap_update(p_hwfn, echo);
|
||||
p_spq->comp_count++;
|
||||
found = p_ent;
|
||||
break;
|
||||
@ -928,11 +931,9 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
|
||||
QED_MSG_SPQ,
|
||||
"Got a completion without a callback function\n");
|
||||
|
||||
if ((found->comp_mode != QED_SPQ_MODE_EBLOCK) ||
|
||||
(found->queue == &p_spq->unlimited_pending))
|
||||
if (found->comp_mode != QED_SPQ_MODE_EBLOCK)
|
||||
/* EBLOCK is responsible for returning its own entry into the
|
||||
* free list, unless it originally added the entry into the
|
||||
* unlimited pending list.
|
||||
* free list.
|
||||
*/
|
||||
qed_spq_return_entry(p_hwfn, found);
|
||||
|
||||
|
@ -340,7 +340,8 @@ struct dma_features {
|
||||
|
||||
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
|
||||
#define BUF_SIZE_16KiB 16384
|
||||
#define BUF_SIZE_8KiB 8192
|
||||
/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */
|
||||
#define BUF_SIZE_8KiB 8188
|
||||
#define BUF_SIZE_4KiB 4096
|
||||
#define BUF_SIZE_2KiB 2048
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
/* Enhanced descriptors */
|
||||
static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end)
|
||||
{
|
||||
p->des1 |= cpu_to_le32(((BUF_SIZE_8KiB - 1)
|
||||
p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
|
||||
<< ERDES1_BUFFER2_SIZE_SHIFT)
|
||||
& ERDES1_BUFFER2_SIZE_MASK);
|
||||
|
||||
|
@ -262,7 +262,7 @@ static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
|
||||
int mode, int end)
|
||||
{
|
||||
p->des0 |= cpu_to_le32(RDES0_OWN);
|
||||
p->des1 |= cpu_to_le32((BUF_SIZE_8KiB - 1) & ERDES1_BUFFER1_SIZE_MASK);
|
||||
p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK);
|
||||
|
||||
if (mode == STMMAC_CHAIN_MODE)
|
||||
ehn_desc_rx_set_on_chain(p);
|
||||
|
@ -143,7 +143,7 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
|
||||
static int stmmac_set_16kib_bfsize(int mtu)
|
||||
{
|
||||
int ret = 0;
|
||||
if (unlikely(mtu >= BUF_SIZE_8KiB))
|
||||
if (unlikely(mtu > BUF_SIZE_8KiB))
|
||||
ret = BUF_SIZE_16KiB;
|
||||
return ret;
|
||||
}
|
||||
|
@ -233,6 +233,7 @@ static const struct bios_settings bios_tbl[] = {
|
||||
{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3307", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
/* Packard Bell */
|
||||
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0},
|
||||
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0},
|
||||
|
@ -968,12 +968,16 @@ static int __init telemetry_debugfs_init(void)
|
||||
debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
|
||||
|
||||
err = telemetry_pltconfig_valid();
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = telemetry_debugfs_check_evts();
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
pr_info("telemetry_debugfs_check_evts failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
register_pm_notifier(&pm_notifier);
|
||||
|
||||
|
@ -358,9 +358,6 @@ static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover)
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "clearip");
|
||||
|
||||
if (recover && card->options.sniffer)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
|
||||
hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
|
||||
@ -818,6 +815,8 @@ static int qeth_l3_register_addr_entry(struct qeth_card *card,
|
||||
int rc = 0;
|
||||
int cnt = 3;
|
||||
|
||||
if (card->options.sniffer)
|
||||
return 0;
|
||||
|
||||
if (addr->proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "setaddr4");
|
||||
@ -853,6 +852,9 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (card->options.sniffer)
|
||||
return 0;
|
||||
|
||||
if (addr->proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "deladdr4");
|
||||
QETH_CARD_HEX(card, 3, &addr->u.a4.addr, sizeof(int));
|
||||
|
@ -850,6 +850,8 @@ int __uio_register_device(struct module *owner,
|
||||
if (ret)
|
||||
goto err_uio_dev_add_attributes;
|
||||
|
||||
info->uio_dev = idev;
|
||||
|
||||
if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
|
||||
/*
|
||||
* Note that we deliberately don't use devm_request_irq
|
||||
@ -861,11 +863,12 @@ int __uio_register_device(struct module *owner,
|
||||
*/
|
||||
ret = request_irq(info->irq, uio_interrupt,
|
||||
info->irq_flags, info->name, idev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
info->uio_dev = NULL;
|
||||
goto err_request_irq;
|
||||
}
|
||||
}
|
||||
|
||||
info->uio_dev = idev;
|
||||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
|
@ -1724,6 +1724,9 @@ static const struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x0572, 0x1349), /* Hiro (Conexant) USB MODEM H50228 */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */
|
||||
.driver_info = QUIRK_CONTROL_LINE_STATE, },
|
||||
{ USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */
|
||||
|
@ -243,6 +243,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT |
|
||||
USB_QUIRK_DELAY_CTRL_MSG },
|
||||
|
||||
/* Corsair K70 LUX RGB */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b33), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Corsair K70 LUX */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
@ -263,6 +266,11 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* Raydium Touchscreen */
|
||||
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
{ USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* DJI CineSSD */
|
||||
{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
|
@ -63,6 +63,7 @@ static const struct usb_device_id appledisplay_table[] = {
|
||||
{ APPLEDISPLAY_DEVICE(0x9219) },
|
||||
{ APPLEDISPLAY_DEVICE(0x921c) },
|
||||
{ APPLEDISPLAY_DEVICE(0x921d) },
|
||||
{ APPLEDISPLAY_DEVICE(0x9222) },
|
||||
{ APPLEDISPLAY_DEVICE(0x9236) },
|
||||
|
||||
/* Terminating entry */
|
||||
|
@ -933,8 +933,8 @@ static int cifs_clone_file_range(struct file *src_file, loff_t off,
|
||||
struct inode *src_inode = file_inode(src_file);
|
||||
struct inode *target_inode = file_inode(dst_file);
|
||||
struct cifsFileInfo *smb_file_src = src_file->private_data;
|
||||
struct cifsFileInfo *smb_file_target = dst_file->private_data;
|
||||
struct cifs_tcon *target_tcon = tlink_tcon(smb_file_target->tlink);
|
||||
struct cifsFileInfo *smb_file_target;
|
||||
struct cifs_tcon *target_tcon;
|
||||
unsigned int xid;
|
||||
int rc;
|
||||
|
||||
@ -948,6 +948,9 @@ static int cifs_clone_file_range(struct file *src_file, loff_t off,
|
||||
goto out;
|
||||
}
|
||||
|
||||
smb_file_target = dst_file->private_data;
|
||||
target_tcon = tlink_tcon(smb_file_target->tlink);
|
||||
|
||||
/*
|
||||
* Note: cifs case is easier than btrfs since server responsible for
|
||||
* checks for proper open modes and file type and if it wants
|
||||
|
@ -441,6 +441,7 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
|
||||
int rc = 0;
|
||||
unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
|
||||
char *name, *value;
|
||||
size_t buf_size = dst_size;
|
||||
size_t name_len, value_len, user_name_len;
|
||||
|
||||
while (src_size > 0) {
|
||||
@ -476,9 +477,10 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
|
||||
/* 'user.' plus a terminating null */
|
||||
user_name_len = 5 + 1 + name_len;
|
||||
|
||||
rc += user_name_len;
|
||||
|
||||
if (dst_size >= user_name_len) {
|
||||
if (buf_size == 0) {
|
||||
/* skip copy - calc size only */
|
||||
rc += user_name_len;
|
||||
} else if (dst_size >= user_name_len) {
|
||||
dst_size -= user_name_len;
|
||||
memcpy(dst, "user.", 5);
|
||||
dst += 5;
|
||||
@ -486,8 +488,7 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
|
||||
dst += name_len;
|
||||
*dst = 0;
|
||||
++dst;
|
||||
} else if (dst_size == 0) {
|
||||
/* skip copy - calc size only */
|
||||
rc += user_name_len;
|
||||
} else {
|
||||
/* stop before overrun buffer */
|
||||
rc = -ERANGE;
|
||||
|
@ -100,6 +100,7 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
|
||||
token = match_token(p, tokens, args);
|
||||
switch (token) {
|
||||
case Opt_name:
|
||||
kfree(opts->dev_name);
|
||||
opts->dev_name = match_strdup(&args[0]);
|
||||
if (unlikely(!opts->dev_name)) {
|
||||
EXOFS_ERR("Error allocating dev_name");
|
||||
@ -863,8 +864,10 @@ static struct dentry *exofs_mount(struct file_system_type *type,
|
||||
int ret;
|
||||
|
||||
ret = parse_options(data, &opts);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(opts.dev_name);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
if (!opts.dev_name)
|
||||
opts.dev_name = dev_name;
|
||||
|
@ -425,6 +425,10 @@ skip:
|
||||
if (new_node) {
|
||||
__be32 cnid;
|
||||
|
||||
if (!new_node->parent) {
|
||||
hfs_btree_inc_height(tree);
|
||||
new_node->parent = tree->root;
|
||||
}
|
||||
fd->bnode = hfs_bnode_find(tree, new_node->parent);
|
||||
/* create index key and entry */
|
||||
hfs_bnode_read_key(new_node, fd->search_key, 14);
|
||||
|
@ -428,6 +428,10 @@ skip:
|
||||
if (new_node) {
|
||||
__be32 cnid;
|
||||
|
||||
if (!new_node->parent) {
|
||||
hfs_btree_inc_height(tree);
|
||||
new_node->parent = tree->root;
|
||||
}
|
||||
fd->bnode = hfs_bnode_find(tree, new_node->parent);
|
||||
/* create index key and entry */
|
||||
hfs_bnode_read_key(new_node, fd->search_key, 14);
|
||||
|
@ -185,6 +185,7 @@ struct reiserfs_dentry_buf {
|
||||
struct dir_context ctx;
|
||||
struct dentry *xadir;
|
||||
int count;
|
||||
int err;
|
||||
struct dentry *dentries[8];
|
||||
};
|
||||
|
||||
@ -207,6 +208,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
||||
|
||||
dentry = lookup_one_len(name, dbuf->xadir, namelen);
|
||||
if (IS_ERR(dentry)) {
|
||||
dbuf->err = PTR_ERR(dentry);
|
||||
return PTR_ERR(dentry);
|
||||
} else if (d_really_is_negative(dentry)) {
|
||||
/* A directory entry exists, but no file? */
|
||||
@ -215,6 +217,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
||||
"not found for file %pd.\n",
|
||||
dentry, dbuf->xadir);
|
||||
dput(dentry);
|
||||
dbuf->err = -EIO;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -262,6 +265,10 @@ static int reiserfs_for_each_xattr(struct inode *inode,
|
||||
err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx);
|
||||
if (err)
|
||||
break;
|
||||
if (buf.err) {
|
||||
err = buf.err;
|
||||
break;
|
||||
}
|
||||
if (!buf.count)
|
||||
break;
|
||||
for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) {
|
||||
|
@ -312,7 +312,7 @@ enum {
|
||||
extern ip_set_id_t ip_set_get_byname(struct net *net,
|
||||
const char *name, struct ip_set **set);
|
||||
extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
|
||||
extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
|
||||
extern void ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name);
|
||||
extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
|
||||
extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
|
||||
|
||||
|
@ -43,11 +43,11 @@ ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment,
|
||||
rcu_assign_pointer(comment->c, c);
|
||||
}
|
||||
|
||||
/* Used only when dumping a set, protected by rcu_read_lock_bh() */
|
||||
/* Used only when dumping a set, protected by rcu_read_lock() */
|
||||
static inline int
|
||||
ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment)
|
||||
{
|
||||
struct ip_set_comment_rcu *c = rcu_dereference_bh(comment->c);
|
||||
struct ip_set_comment_rcu *c = rcu_dereference(comment->c);
|
||||
|
||||
if (!c)
|
||||
return 0;
|
||||
|
@ -5799,14 +5799,17 @@ void __init sched_init_smp(void)
|
||||
/*
|
||||
* There's no userspace yet to cause hotplug operations; hence all the
|
||||
* CPU masks are stable and all blatant races in the below code cannot
|
||||
* happen.
|
||||
* happen. The hotplug lock is nevertheless taken to satisfy lockdep,
|
||||
* but there won't be any contention on it.
|
||||
*/
|
||||
cpus_read_lock();
|
||||
mutex_lock(&sched_domains_mutex);
|
||||
sched_init_domains(cpu_active_mask);
|
||||
cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
|
||||
if (cpumask_empty(non_isolated_cpus))
|
||||
cpumask_set_cpu(smp_processor_id(), non_isolated_cpus);
|
||||
mutex_unlock(&sched_domains_mutex);
|
||||
cpus_read_unlock();
|
||||
|
||||
/* Move init over to a non-isolated CPU */
|
||||
if (set_cpus_allowed_ptr(current, non_isolated_cpus) < 0)
|
||||
|
@ -27,7 +27,7 @@ ifeq ($(ARCH),arm)
|
||||
CFLAGS += -I../../../arch/arm/include -mfpu=neon
|
||||
HAS_NEON = yes
|
||||
endif
|
||||
ifeq ($(ARCH),arm64)
|
||||
ifeq ($(ARCH),aarch64)
|
||||
CFLAGS += -I../../../arch/arm64/include
|
||||
HAS_NEON = yes
|
||||
endif
|
||||
@ -41,7 +41,7 @@ ifeq ($(IS_X86),yes)
|
||||
gcc -c -x assembler - >&/dev/null && \
|
||||
rm ./-.o && echo -DCONFIG_AS_AVX512=1)
|
||||
else ifeq ($(HAS_NEON),yes)
|
||||
OBJS += neon.o neon1.o neon2.o neon4.o neon8.o
|
||||
OBJS += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o
|
||||
CFLAGS += -DCONFIG_KERNEL_MODE_NEON=1
|
||||
else
|
||||
HAS_ALTIVEC := $(shell printf '\#include <altivec.h>\nvector int a;\n' |\
|
||||
|
@ -594,9 +594,15 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
|
||||
struct bio_vec bvec;
|
||||
int ret;
|
||||
|
||||
/* sendpage cannot properly handle pages with page_count == 0,
|
||||
* we need to fallback to sendmsg if that's the case */
|
||||
if (page_count(page) >= 1)
|
||||
/*
|
||||
* sendpage cannot properly handle pages with page_count == 0,
|
||||
* we need to fall back to sendmsg if that's the case.
|
||||
*
|
||||
* Same goes for slab pages: skb_can_coalesce() allows
|
||||
* coalescing neighboring slab objects into a single frag which
|
||||
* triggers one of hardened usercopy checks.
|
||||
*/
|
||||
if (page_count(page) >= 1 && !PageSlab(page))
|
||||
return __ceph_tcp_sendpage(sock, page, offset, size, more);
|
||||
|
||||
bvec.bv_page = page;
|
||||
|
@ -668,21 +668,20 @@ ip_set_put_byindex(struct net *net, ip_set_id_t index)
|
||||
EXPORT_SYMBOL_GPL(ip_set_put_byindex);
|
||||
|
||||
/* Get the name of a set behind a set index.
|
||||
* We assume the set is referenced, so it does exist and
|
||||
* can't be destroyed. The set cannot be renamed due to
|
||||
* the referencing either.
|
||||
*
|
||||
* Set itself is protected by RCU, but its name isn't: to protect against
|
||||
* renaming, grab ip_set_ref_lock as reader (see ip_set_rename()) and copy the
|
||||
* name.
|
||||
*/
|
||||
const char *
|
||||
ip_set_name_byindex(struct net *net, ip_set_id_t index)
|
||||
void
|
||||
ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name)
|
||||
{
|
||||
const struct ip_set *set = ip_set_rcu_get(net, index);
|
||||
struct ip_set *set = ip_set_rcu_get(net, index);
|
||||
|
||||
BUG_ON(!set);
|
||||
BUG_ON(set->ref == 0);
|
||||
|
||||
/* Referenced, so it's safe */
|
||||
return set->name;
|
||||
read_lock_bh(&ip_set_ref_lock);
|
||||
strncpy(name, set->name, IPSET_MAXNAMELEN);
|
||||
read_unlock_bh(&ip_set_ref_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip_set_name_byindex);
|
||||
|
||||
@ -1128,7 +1127,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
|
||||
if (!set)
|
||||
return -ENOENT;
|
||||
|
||||
read_lock_bh(&ip_set_ref_lock);
|
||||
write_lock_bh(&ip_set_ref_lock);
|
||||
if (set->ref != 0) {
|
||||
ret = -IPSET_ERR_REFERENCED;
|
||||
goto out;
|
||||
@ -1145,7 +1144,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
|
||||
strncpy(set->name, name2, IPSET_MAXNAMELEN);
|
||||
|
||||
out:
|
||||
read_unlock_bh(&ip_set_ref_lock);
|
||||
write_unlock_bh(&ip_set_ref_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -213,13 +213,13 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
|
||||
if (tb[IPSET_ATTR_CIDR]) {
|
||||
e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
|
||||
if (!e.cidr[0] || e.cidr[0] > HOST_MASK)
|
||||
if (e.cidr[0] > HOST_MASK)
|
||||
return -IPSET_ERR_INVALID_CIDR;
|
||||
}
|
||||
|
||||
if (tb[IPSET_ATTR_CIDR2]) {
|
||||
e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
|
||||
if (!e.cidr[1] || e.cidr[1] > HOST_MASK)
|
||||
if (e.cidr[1] > HOST_MASK)
|
||||
return -IPSET_ERR_INVALID_CIDR;
|
||||
}
|
||||
|
||||
@ -492,13 +492,13 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
|
||||
if (tb[IPSET_ATTR_CIDR]) {
|
||||
e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
|
||||
if (!e.cidr[0] || e.cidr[0] > HOST_MASK)
|
||||
if (e.cidr[0] > HOST_MASK)
|
||||
return -IPSET_ERR_INVALID_CIDR;
|
||||
}
|
||||
|
||||
if (tb[IPSET_ATTR_CIDR2]) {
|
||||
e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
|
||||
if (!e.cidr[1] || e.cidr[1] > HOST_MASK)
|
||||
if (e.cidr[1] > HOST_MASK)
|
||||
return -IPSET_ERR_INVALID_CIDR;
|
||||
}
|
||||
|
||||
|
@ -156,9 +156,7 @@ __list_set_del_rcu(struct rcu_head * rcu)
|
||||
{
|
||||
struct set_elem *e = container_of(rcu, struct set_elem, rcu);
|
||||
struct ip_set *set = e->set;
|
||||
struct list_set *map = set->data;
|
||||
|
||||
ip_set_put_byindex(map->net, e->id);
|
||||
ip_set_ext_destroy(set, e);
|
||||
kfree(e);
|
||||
}
|
||||
@ -166,15 +164,21 @@ __list_set_del_rcu(struct rcu_head * rcu)
|
||||
static inline void
|
||||
list_set_del(struct ip_set *set, struct set_elem *e)
|
||||
{
|
||||
struct list_set *map = set->data;
|
||||
|
||||
set->elements--;
|
||||
list_del_rcu(&e->list);
|
||||
ip_set_put_byindex(map->net, e->id);
|
||||
call_rcu(&e->rcu, __list_set_del_rcu);
|
||||
}
|
||||
|
||||
static inline void
|
||||
list_set_replace(struct set_elem *e, struct set_elem *old)
|
||||
list_set_replace(struct ip_set *set, struct set_elem *e, struct set_elem *old)
|
||||
{
|
||||
struct list_set *map = set->data;
|
||||
|
||||
list_replace_rcu(&old->list, &e->list);
|
||||
ip_set_put_byindex(map->net, old->id);
|
||||
call_rcu(&old->rcu, __list_set_del_rcu);
|
||||
}
|
||||
|
||||
@ -306,7 +310,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
||||
INIT_LIST_HEAD(&e->list);
|
||||
list_set_init_extensions(set, ext, e);
|
||||
if (n)
|
||||
list_set_replace(e, n);
|
||||
list_set_replace(set, e, n);
|
||||
else if (next)
|
||||
list_add_tail_rcu(&e->list, &next->list);
|
||||
else if (prev)
|
||||
@ -497,6 +501,7 @@ list_set_list(const struct ip_set *set,
|
||||
const struct list_set *map = set->data;
|
||||
struct nlattr *atd, *nested;
|
||||
u32 i = 0, first = cb->args[IPSET_CB_ARG0];
|
||||
char name[IPSET_MAXNAMELEN];
|
||||
struct set_elem *e;
|
||||
int ret = 0;
|
||||
|
||||
@ -515,8 +520,8 @@ list_set_list(const struct ip_set *set,
|
||||
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
|
||||
if (!nested)
|
||||
goto nla_put_failure;
|
||||
if (nla_put_string(skb, IPSET_ATTR_NAME,
|
||||
ip_set_name_byindex(map->net, e->id)))
|
||||
ip_set_name_byindex(map->net, e->id, name);
|
||||
if (nla_put_string(skb, IPSET_ATTR_NAME, name))
|
||||
goto nla_put_failure;
|
||||
if (ip_set_put_extensions(skb, set, e, true))
|
||||
goto nla_put_failure;
|
||||
|
@ -277,6 +277,22 @@ static int idletimer_resume(struct notifier_block *notifier,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int idletimer_check_sysfs_name(const char *name, unsigned int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xt_check_proc_name(name, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!strcmp(name, "power") ||
|
||||
!strcmp(name, "subsystem") ||
|
||||
!strcmp(name, "uevent"))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int idletimer_tg_create(struct idletimer_tg_info *info)
|
||||
{
|
||||
int ret;
|
||||
@ -287,6 +303,10 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = idletimer_check_sysfs_name(info->label, sizeof(info->label));
|
||||
if (ret < 0)
|
||||
goto out_free_timer;
|
||||
|
||||
sysfs_attr_init(&info->timer->attr.attr);
|
||||
info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
|
||||
if (!info->timer->attr.attr.name) {
|
||||
|
@ -512,7 +512,7 @@ EXPORT_SYMBOL_GPL(xdr_commit_encode);
|
||||
static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
|
||||
size_t nbytes)
|
||||
{
|
||||
static __be32 *p;
|
||||
__be32 *p;
|
||||
int space_left;
|
||||
int frag1bytes, frag2bytes;
|
||||
|
||||
|
@ -90,10 +90,12 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
|
||||
const char *end = fqname + n;
|
||||
const char *name = skipn_spaces(fqname, n);
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
*ns_name = NULL;
|
||||
*ns_len = 0;
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
if (name[0] == ':') {
|
||||
char *split = strnchr(&name[1], end - &name[1], ':');
|
||||
*ns_name = skipn_spaces(&name[1], end - &name[1]);
|
||||
|
@ -125,7 +125,7 @@ perf_get_timestamp(void)
|
||||
}
|
||||
|
||||
static int
|
||||
debug_cache_init(void)
|
||||
create_jit_cache_dir(void)
|
||||
{
|
||||
char str[32];
|
||||
char *base, *p;
|
||||
@ -144,8 +144,13 @@ debug_cache_init(void)
|
||||
|
||||
strftime(str, sizeof(str), JIT_LANG"-jit-%Y%m%d", &tm);
|
||||
|
||||
snprintf(jit_path, PATH_MAX - 1, "%s/.debug/", base);
|
||||
|
||||
ret = snprintf(jit_path, PATH_MAX, "%s/.debug/", base);
|
||||
if (ret >= PATH_MAX) {
|
||||
warnx("jvmti: cannot generate jit cache dir because %s/.debug/"
|
||||
" is too long, please check the cwd, JITDUMPDIR, and"
|
||||
" HOME variables", base);
|
||||
return -1;
|
||||
}
|
||||
ret = mkdir(jit_path, 0755);
|
||||
if (ret == -1) {
|
||||
if (errno != EEXIST) {
|
||||
@ -154,20 +159,32 @@ debug_cache_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(jit_path, PATH_MAX - 1, "%s/.debug/jit", base);
|
||||
ret = snprintf(jit_path, PATH_MAX, "%s/.debug/jit", base);
|
||||
if (ret >= PATH_MAX) {
|
||||
warnx("jvmti: cannot generate jit cache dir because"
|
||||
" %s/.debug/jit is too long, please check the cwd,"
|
||||
" JITDUMPDIR, and HOME variables", base);
|
||||
return -1;
|
||||
}
|
||||
ret = mkdir(jit_path, 0755);
|
||||
if (ret == -1) {
|
||||
if (errno != EEXIST) {
|
||||
warn("cannot create jit cache dir %s", jit_path);
|
||||
warn("jvmti: cannot create jit cache dir %s", jit_path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(jit_path, PATH_MAX - 1, "%s/.debug/jit/%s.XXXXXXXX", base, str);
|
||||
|
||||
ret = snprintf(jit_path, PATH_MAX, "%s/.debug/jit/%s.XXXXXXXX", base, str);
|
||||
if (ret >= PATH_MAX) {
|
||||
warnx("jvmti: cannot generate jit cache dir because"
|
||||
" %s/.debug/jit/%s.XXXXXXXX is too long, please check"
|
||||
" the cwd, JITDUMPDIR, and HOME variables",
|
||||
base, str);
|
||||
return -1;
|
||||
}
|
||||
p = mkdtemp(jit_path);
|
||||
if (p != jit_path) {
|
||||
warn("cannot create jit cache dir %s", jit_path);
|
||||
warn("jvmti: cannot create jit cache dir %s", jit_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -228,7 +245,7 @@ void *jvmti_open(void)
|
||||
{
|
||||
char dump_path[PATH_MAX];
|
||||
struct jitheader header;
|
||||
int fd;
|
||||
int fd, ret;
|
||||
FILE *fp;
|
||||
|
||||
init_arch_timestamp();
|
||||
@ -245,12 +262,22 @@ void *jvmti_open(void)
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
|
||||
debug_cache_init();
|
||||
/*
|
||||
* jitdump file dir
|
||||
*/
|
||||
if (create_jit_cache_dir() < 0)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* jitdump file name
|
||||
*/
|
||||
scnprintf(dump_path, PATH_MAX, "%s/jit-%i.dump", jit_path, getpid());
|
||||
ret = snprintf(dump_path, PATH_MAX, "%s/jit-%i.dump", jit_path, getpid());
|
||||
if (ret >= PATH_MAX) {
|
||||
warnx("jvmti: cannot generate jitdump file full path because"
|
||||
" %s/jit-%i.dump is too long, please check the cwd,"
|
||||
" JITDUMPDIR, and HOME variables", jit_path, getpid());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = open(dump_path, O_CREAT|O_TRUNC|O_RDWR, 0666);
|
||||
if (fd == -1)
|
||||
|
@ -527,6 +527,7 @@ static int do_test_code_reading(bool try_kcore)
|
||||
pid = getpid();
|
||||
|
||||
machine = machine__new_host();
|
||||
machine->env = &perf_env;
|
||||
|
||||
ret = machine__create_kernel_maps(machine);
|
||||
if (ret < 0) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "env.h"
|
||||
#include "util.h"
|
||||
#include <errno.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
struct perf_env perf_env;
|
||||
|
||||
@ -87,6 +88,37 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_env__read_arch(struct perf_env *env)
|
||||
{
|
||||
struct utsname uts;
|
||||
|
||||
if (env->arch)
|
||||
return 0;
|
||||
|
||||
if (!uname(&uts))
|
||||
env->arch = strdup(uts.machine);
|
||||
|
||||
return env->arch ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int perf_env__read_nr_cpus_avail(struct perf_env *env)
|
||||
{
|
||||
if (env->nr_cpus_avail == 0)
|
||||
env->nr_cpus_avail = cpu__max_present_cpu();
|
||||
|
||||
return env->nr_cpus_avail ? 0 : -ENOENT;
|
||||
}
|
||||
|
||||
const char *perf_env__raw_arch(struct perf_env *env)
|
||||
{
|
||||
return env && !perf_env__read_arch(env) ? env->arch : "unknown";
|
||||
}
|
||||
|
||||
int perf_env__nr_cpus_avail(struct perf_env *env)
|
||||
{
|
||||
return env && !perf_env__read_nr_cpus_avail(env) ? env->nr_cpus_avail : 0;
|
||||
}
|
||||
|
||||
void cpu_cache_level__free(struct cpu_cache_level *cache)
|
||||
{
|
||||
free(cache->type);
|
||||
|
@ -65,4 +65,8 @@ int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);
|
||||
int perf_env__read_cpu_topology_map(struct perf_env *env);
|
||||
|
||||
void cpu_cache_level__free(struct cpu_cache_level *cache);
|
||||
|
||||
const char *perf_env__raw_arch(struct perf_env *env);
|
||||
int perf_env__nr_cpus_avail(struct perf_env *env);
|
||||
|
||||
#endif /* __PERF_ENV_H */
|
||||
|
@ -818,6 +818,102 @@ static int machine__get_running_kernel_start(struct machine *machine,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kernel-space maps for symbols that are outside the main kernel map and module maps */
|
||||
struct extra_kernel_map {
|
||||
u64 start;
|
||||
u64 end;
|
||||
u64 pgoff;
|
||||
};
|
||||
|
||||
static int machine__create_extra_kernel_map(struct machine *machine,
|
||||
struct dso *kernel,
|
||||
struct extra_kernel_map *xm)
|
||||
{
|
||||
struct kmap *kmap;
|
||||
struct map *map;
|
||||
|
||||
map = map__new2(xm->start, kernel, MAP__FUNCTION);
|
||||
if (!map)
|
||||
return -1;
|
||||
|
||||
map->end = xm->end;
|
||||
map->pgoff = xm->pgoff;
|
||||
|
||||
kmap = map__kmap(map);
|
||||
|
||||
kmap->kmaps = &machine->kmaps;
|
||||
|
||||
map_groups__insert(&machine->kmaps, map);
|
||||
|
||||
pr_debug2("Added extra kernel map %" PRIx64 "-%" PRIx64 "\n",
|
||||
map->start, map->end);
|
||||
|
||||
map__put(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 find_entry_trampoline(struct dso *dso)
|
||||
{
|
||||
/* Duplicates are removed so lookup all aliases */
|
||||
const char *syms[] = {
|
||||
"_entry_trampoline",
|
||||
"__entry_trampoline_start",
|
||||
"entry_SYSCALL_64_trampoline",
|
||||
};
|
||||
struct symbol *sym = dso__first_symbol(dso, MAP__FUNCTION);
|
||||
unsigned int i;
|
||||
|
||||
for (; sym; sym = dso__next_symbol(sym)) {
|
||||
if (sym->binding != STB_GLOBAL)
|
||||
continue;
|
||||
for (i = 0; i < ARRAY_SIZE(syms); i++) {
|
||||
if (!strcmp(sym->name, syms[i]))
|
||||
return sym->start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These values can be used for kernels that do not have symbols for the entry
|
||||
* trampolines in kallsyms.
|
||||
*/
|
||||
#define X86_64_CPU_ENTRY_AREA_PER_CPU 0xfffffe0000000000ULL
|
||||
#define X86_64_CPU_ENTRY_AREA_SIZE 0x2c000
|
||||
#define X86_64_ENTRY_TRAMPOLINE 0x6000
|
||||
|
||||
/* Map x86_64 PTI entry trampolines */
|
||||
int machine__map_x86_64_entry_trampolines(struct machine *machine,
|
||||
struct dso *kernel)
|
||||
{
|
||||
u64 pgoff = find_entry_trampoline(kernel);
|
||||
int nr_cpus_avail, cpu;
|
||||
|
||||
if (!pgoff)
|
||||
return 0;
|
||||
|
||||
nr_cpus_avail = machine__nr_cpus_avail(machine);
|
||||
|
||||
/* Add a 1 page map for each CPU's entry trampoline */
|
||||
for (cpu = 0; cpu < nr_cpus_avail; cpu++) {
|
||||
u64 va = X86_64_CPU_ENTRY_AREA_PER_CPU +
|
||||
cpu * X86_64_CPU_ENTRY_AREA_SIZE +
|
||||
X86_64_ENTRY_TRAMPOLINE;
|
||||
struct extra_kernel_map xm = {
|
||||
.start = va,
|
||||
.end = va + page_size,
|
||||
.pgoff = pgoff,
|
||||
};
|
||||
|
||||
if (machine__create_extra_kernel_map(machine, kernel, &xm) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
|
||||
{
|
||||
int type;
|
||||
@ -2238,6 +2334,20 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares the raw arch string. N.B. see instead perf_env__arch() if a
|
||||
* normalized arch is needed.
|
||||
*/
|
||||
bool machine__is(struct machine *machine, const char *arch)
|
||||
{
|
||||
return machine && !strcmp(perf_env__raw_arch(machine->env), arch);
|
||||
}
|
||||
|
||||
int machine__nr_cpus_avail(struct machine *machine)
|
||||
{
|
||||
return machine ? perf_env__nr_cpus_avail(machine->env) : 0;
|
||||
}
|
||||
|
||||
int machine__get_kernel_start(struct machine *machine)
|
||||
{
|
||||
struct map *map = machine__kernel_map(machine);
|
||||
@ -2254,7 +2364,12 @@ int machine__get_kernel_start(struct machine *machine)
|
||||
machine->kernel_start = 1ULL << 63;
|
||||
if (map) {
|
||||
err = map__load(map);
|
||||
if (!err)
|
||||
/*
|
||||
* On x86_64, PTI entry trampolines are less than the
|
||||
* start of kernel text, but still above 2^63. So leave
|
||||
* kernel_start = 1ULL << 63 for x86_64.
|
||||
*/
|
||||
if (!err && !machine__is(machine, "x86_64"))
|
||||
machine->kernel_start = map->start;
|
||||
}
|
||||
return err;
|
||||
|
@ -169,6 +169,9 @@ static inline bool machine__is_host(struct machine *machine)
|
||||
return machine ? machine->pid == HOST_KERNEL_ID : false;
|
||||
}
|
||||
|
||||
bool machine__is(struct machine *machine, const char *arch);
|
||||
int machine__nr_cpus_avail(struct machine *machine);
|
||||
|
||||
struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
|
||||
struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
|
||||
|
||||
@ -263,4 +266,7 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
|
||||
*/
|
||||
char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp);
|
||||
|
||||
int machine__map_x86_64_entry_trampolines(struct machine *machine,
|
||||
struct dso *kernel);
|
||||
|
||||
#endif /* __PERF_MACHINE_H */
|
||||
|
@ -338,7 +338,17 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
|
||||
plt_entry_size = 16;
|
||||
break;
|
||||
|
||||
default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa need to be checked */
|
||||
case EM_SPARC:
|
||||
plt_header_size = 48;
|
||||
plt_entry_size = 12;
|
||||
break;
|
||||
|
||||
case EM_SPARCV9:
|
||||
plt_header_size = 128;
|
||||
plt_entry_size = 32;
|
||||
break;
|
||||
|
||||
default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/xtensa need to be checked */
|
||||
plt_header_size = shdr_plt.sh_entsize;
|
||||
plt_entry_size = shdr_plt.sh_entsize;
|
||||
break;
|
||||
|
@ -1513,20 +1513,22 @@ int dso__load(struct dso *dso, struct map *map)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (map->groups && map->groups->machine)
|
||||
machine = map->groups->machine;
|
||||
else
|
||||
machine = NULL;
|
||||
|
||||
if (dso->kernel) {
|
||||
if (dso->kernel == DSO_TYPE_KERNEL)
|
||||
ret = dso__load_kernel_sym(dso, map);
|
||||
else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||
ret = dso__load_guest_kernel_sym(dso, map);
|
||||
|
||||
if (machine__is(machine, "x86_64"))
|
||||
machine__map_x86_64_entry_trampolines(machine, dso);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (map->groups && map->groups->machine)
|
||||
machine = map->groups->machine;
|
||||
else
|
||||
machine = NULL;
|
||||
|
||||
dso->adjust_symbols = 0;
|
||||
|
||||
if (perfmap) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user