* refs/heads/tmp-c9d74f2 Linux 4.4.135 Revert "vti4: Don't override MTU passed on link creation via IFLA_MTU" Revert "vti4: Don't override MTU passed on link creation via IFLA_MTU" Linux 4.4.134 s390/ftrace: use expoline for indirect branches kdb: make "mdr" command repeat Bluetooth: btusb: Add device ID for RTL8822BE ASoC: samsung: i2s: Ensure the RCLK rate is properly determined regulator: of: Add a missing 'of_node_put()' in an error handling path of 'of_regulator_match()' scsi: lpfc: Fix frequency of Release WQE CQEs scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing scsi: lpfc: Fix issue_lip if link is disabled netlabel: If PF_INET6, check sk_buff ip header version selftests/net: fixes psock_fanout eBPF test case perf report: Fix memory corruption in --branch-history mode --branch-history perf tests: Use arch__compare_symbol_names to compare symbols x86/apic: Set up through-local-APIC mode on the boot CPU if 'noapic' specified drm/rockchip: Respect page offset for PRIME mmap calls MIPS: Octeon: Fix logging messages with spurious periods after newlines audit: return on memory error to avoid null pointer dereference crypto: sunxi-ss - Add MODULE_ALIAS to sun4i-ss clk: samsung: exynos3250: Fix PLL rates clk: samsung: exynos5250: Fix PLL rates clk: samsung: exynos5433: Fix PLL rates clk: samsung: exynos5260: Fix PLL rates clk: samsung: s3c2410: Fix PLL rates media: cx25821: prevent out-of-bounds read on array card udf: Provide saner default for invalid uid / gid PCI: Add function 1 DMA alias quirk for Marvell 88SE9220 serial: arc_uart: Fix out-of-bounds access through DT alias serial: fsl_lpuart: Fix out-of-bounds access through DT alias serial: imx: Fix out-of-bounds access through serial port index serial: mxs-auart: Fix out-of-bounds access through serial port index serial: samsung: Fix out-of-bounds access through serial port index serial: xuartps: Fix out-of-bounds access through DT alias rtc: tx4939: avoid unintended sign extension on a 24 bit shift staging: rtl8192u: return -ENOMEM on failed allocation of priv->oldaddr hwrng: stm32 - add reset during probe enic: enable rq before updating rq descriptors clk: rockchip: Prevent calculating mmc phase if clock rate is zero media: em28xx: USB bulk packet size fix dmaengine: pl330: fix a race condition in case of threaded irqs media: s3c-camif: fix out-of-bounds array access media: cx23885: Set subdev host data to clk_freq pointer media: cx23885: Override 888 ImpactVCBe crystal frequency ALSA: vmaster: Propagate slave error x86/devicetree: Fix device IRQ settings in DT x86/devicetree: Initialize device tree before using it usb: gadget: composite: fix incorrect handling of OS desc requests usb: gadget: udc: change comparison to bitshift when dealing with a mask gfs2: Fix fallocate chunk size cdrom: do not call check_disk_change() inside cdrom_open() hwmon: (pmbus/adm1275) Accept negative page register values hwmon: (pmbus/max8688) Accept negative page register values perf/core: Fix perf_output_read_group() ASoC: topology: create TLV data for dapm widgets powerpc: Add missing prototype for arch_irq_work_raise() usb: gadget: ffs: Execute copy_to_user() with USER_DS set usb: gadget: ffs: Let setup() return USB_GADGET_DELAYED_STATUS usb: dwc2: Fix interval type issue ipmi_ssif: Fix kernel panic at msg_done_handler PCI: Restore config space on runtime resume despite being unbound MIPS: ath79: Fix AR724X_PLL_REG_PCIE_CONFIG offset xhci: zero usb device slot_id member when disabling and freeing a xhci slot KVM: lapic: stop advertising DIRECTED_EOI when in-kernel IOAPIC is in use i2c: mv64xxx: Apply errata delay only in standard mode ACPICA: acpi: acpica: fix acpi operand cache leak in nseval.c ACPICA: Events: add a return on failure from acpi_hw_register_read bcache: quit dc->writeback_thread when BCACHE_DEV_DETACHING is set zorro: Set up z->dev.dma_mask for the DMA API clk: Don't show the incorrect clock phase cpufreq: cppc_cpufreq: Fix cppc_cpufreq_init() failure path usb: dwc3: Update DWC_usb31 GTXFIFOSIZ reg fields arm: dts: socfpga: fix GIC PPI warning virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS ima: Fallback to the builtin hash algorithm ima: Fix Kconfig to select TPM 2.0 CRB interface ath10k: Fix kernel panic while using worker (ath10k_sta_rc_update_wk) net/mlx5: Protect from command bit overflow selftests: Print the test we're running to /dev/kmsg tools/thermal: tmon: fix for segfault powerpc/perf: Fix kernel address leak via sampling registers powerpc/perf: Prevent kernel address leak to userspace via BHRB buffer rtc: hctosys: Ensure system time doesn't overflow time_t hwmon: (nct6775) Fix writing pwmX_mode parisc/pci: Switch LBA PCI bus from Hard Fail to Soft Fail mode m68k: set dma and coherent masks for platform FEC ethernets powerpc/mpic: Check if cpu_possible() in mpic_physmask() ACPI: acpi_pad: Fix memory leak in power saving threads xen/acpi: off by one in read_acpi_id() btrfs: fix lockdep splat in btrfs_alloc_subvolume_writers Btrfs: fix copy_items() return value when logging an inode btrfs: tests/qgroup: Fix wrong tree backref level Bluetooth: btusb: Add USB ID 7392:a611 for Edimax EW-7611ULB net: bgmac: Fix endian access in bgmac_dma_tx_ring_free() rtc: snvs: Fix usage of snvs_rtc_enable sparc64: Make atomic_xchg() an inline function rather than a macro. fscache: Fix hanging wait on page discarded by writeback KVM: VMX: raise internal error for exception during invalid protected mode state sched/rt: Fix rq->clock_update_flags < RQCF_ACT_SKIP warning ocfs2/dlm: don't handle migrate lockres if already in shutdown btrfs: Fix possible softlock on single core machines Btrfs: fix NULL pointer dereference in log_dir_items Btrfs: bail out on error during replay_dir_deletes mm: fix races between address_space dereference and free in page_evicatable mm/ksm: fix interaction with THP dp83640: Ensure against premature access to PHY registers after reset scsi: aacraid: Insure command thread is not recursively stopped cpufreq: CPPC: Initialize shared perf capabilities of CPUs Force log to disk before reading the AGF during a fstrim sr: get/drop reference to device in revalidate and check_events swap: divide-by-zero when zero length swap file on ssd fs/proc/proc_sysctl.c: fix potential page fault while unregistering sysctl table x86/pgtable: Don't set huge PUD/PMD on non-leaf entries sh: fix debug trap failure to process signals before return to user net: mvneta: fix enable of all initialized RXQs net: Fix untag for vlan packets without ethernet header mm/kmemleak.c: wait for scan completion before disabling free llc: properly handle dev_queue_xmit() return value net-usb: add qmi_wwan if on lte modem wistron neweb d18q1 net/usb/qmi_wwan.c: Add USB id for lt4120 modem net: qmi_wwan: add BroadMobi BM806U 2020:2033 ARM: 8748/1: mm: Define vdso_start, vdso_end as array batman-adv: fix packet loss for broadcasted DHCP packets to a server batman-adv: fix multicast-via-unicast transmission with AP isolation selftests: ftrace: Add a testcase for probepoint selftests: ftrace: Add a testcase for string type with kprobe_event selftests: ftrace: Add probe event argument syntax testcase mm/mempolicy.c: avoid use uninitialized preferred_node RDMA/ucma: Correct option size check using optlen perf/cgroup: Fix child event counting bug vti4: Don't override MTU passed on link creation via IFLA_MTU vti4: Don't count header length twice on tunnel setup batman-adv: fix header size check in batadv_dbg_arp() net: Fix vlan untag for bridge and vlan_dev with reorder_hdr off sunvnet: does not support GSO for sctp ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu workqueue: use put_device() instead of kfree() bnxt_en: Check valid VNIC ID in bnxt_hwrm_vnic_set_tpa(). netfilter: ebtables: fix erroneous reject of last rule USB: OHCI: Fix NULL dereference in HCDs using HCD_LOCAL_MEM xen: xenbus: use put_device() instead of kfree() fbdev: Fixing arbitrary kernel leak in case FBIOGETCMAP_SPARC in sbusfb_ioctl_helper(). scsi: sd: Keep disk read-only when re-reading partition scsi: mpt3sas: Do not mark fw_event workqueue as WQ_MEM_RECLAIM usb: musb: call pm_runtime_{get,put}_sync before reading vbus registers e1000e: allocate ring descriptors with dma_zalloc_coherent e1000e: Fix check_for_link return value with autoneg off watchdog: f71808e_wdt: Fix magic close handling KVM: PPC: Book3S HV: Fix VRMA initialization with 2MB or 1GB memory backing selftests/powerpc: Skip the subpage_prot tests if the syscall is unavailable Btrfs: send, fix issuing write op when processing hole in no data mode xen/pirq: fix error path cleanup when binding MSIs net/tcp/illinois: replace broken algorithm reference link gianfar: Fix Rx byte accounting for ndev stats sit: fix IFLA_MTU ignored on NEWLINK bcache: fix kcrashes with fio in RAID5 backend dev dmaengine: rcar-dmac: fix max_chunk_size for R-Car Gen3 virtio-gpu: fix ioctl and expose the fixed status to userspace. r8152: fix tx packets accounting clocksource/drivers/fsl_ftm_timer: Fix error return checking nvme-pci: Fix nvme queue cleanup if IRQ setup fails netfilter: ebtables: convert BUG_ONs to WARN_ONs batman-adv: invalidate checksum on fragment reassembly batman-adv: fix packet checksum in receive path md/raid1: fix NULL pointer dereference media: dmxdev: fix error code for invalid ioctls x86/topology: Update the 'cpu cores' field in /proc/cpuinfo correctly across CPU hotplug operations locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs regulatory: add NUL to request alpha2 smsc75xx: fix smsc75xx_set_features() ARM: OMAP: Fix dmtimer init for omap1 s390/cio: clear timer when terminating driver I/O s390/cio: fix return code after missing interrupt powerpc/bpf/jit: Fix 32-bit JIT for seccomp_data access kernel/relay.c: limit kmalloc size to KMALLOC_MAX_SIZE md: raid5: avoid string overflow warning locking/xchg/alpha: Add unconditional memory barrier to cmpxchg() usb: musb: fix enumeration after resume drm/exynos: fix comparison to bitshift when dealing with a mask md raid10: fix NULL deference in handle_write_completed() mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4 NFC: llcp: Limit size of SDP URI ARM: OMAP1: clock: Fix debugfs_create_*() usage ARM: OMAP3: Fix prm wake interrupt for resume ARM: OMAP2+: timer: fix a kmemleak caused in omap_get_timer_dt scsi: qla4xxx: skip error recovery in case of register disconnect. scsi: aacraid: fix shutdown crash when init fails scsi: storvsc: Increase cmd_per_lun for higher speed devices selftests: memfd: add config fragment for fuse usb: dwc2: Fix dwc2_hsotg_core_init_disconnected() usb: gadget: fsl_udc_core: fix ep valid checks usb: gadget: f_uac2: fix bFirstInterface in composite gadget ARC: Fix malformed ARC_EMUL_UNALIGNED default scsi: qla2xxx: Avoid triggering undefined behavior in qla2x00_mbx_completion() scsi: mptfusion: Add bounds check in mptctl_hp_targetinfo() scsi: sym53c8xx_2: iterator underflow in sym_getsync() scsi: bnx2fc: Fix check in SCSI completion handler for timed out request scsi: ufs: Enable quirk to ignore sending WRITE_SAME command irqchip/gic-v3: Change pr_debug message to pr_devel locking/qspinlock: Ensure node->count is updated before initialising node tools/libbpf: handle issues with bpf ELF objects containing .eh_frames bcache: return attach error when no cache set exist bcache: fix for data collapse after re-attaching an attached device bcache: fix for allocator and register thread race bcache: properly set task state in bch_writeback_thread() cifs: silence compiler warnings showing up with gcc-8.0.0 proc: fix /proc/*/map_files lookup arm64: spinlock: Fix theoretical trylock() A-B-A with LSE atomics RDS: IB: Fix null pointer issue xen/grant-table: Use put_page instead of free_page xen-netfront: Fix race between device setup and open MIPS: TXx9: use IS_BUILTIN() for CONFIG_LEDS_CLASS bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y ACPI: processor_perflib: Do not send _PPC change notification if not ready firmware: dmi_scan: Fix handling of empty DMI strings x86/power: Fix swsusp_arch_resume prototype IB/ipoib: Fix for potential no-carrier state mm: pin address_space before dereferencing it while isolating an LRU page asm-generic: provide generic_pmdp_establish() mm/mempolicy: add nodes_empty check in SYSC_migrate_pages mm/mempolicy: fix the check of nodemask from user ocfs2: return error when we attempt to access a dirty bh in jbd2 ocfs2/acl: use 'ip_xattr_sem' to protect getting extended attribute ocfs2: return -EROFS to mount.ocfs2 if inode block is invalid ntb_transport: Fix bug with max_mw_size parameter RDMA/mlx5: Avoid memory leak in case of XRCD dealloc failure powerpc/numa: Ensure nodes initialized for hotplug powerpc/numa: Use ibm,max-associativity-domains to discover possible nodes jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path HID: roccat: prevent an out of bounds read in kovaplus_profile_activated() scsi: fas216: fix sense buffer initialization Btrfs: fix scrub to repair raid6 corruption btrfs: Fix out of bounds access in btrfs_search_slot Btrfs: set plug for fsync ipmi/powernv: Fix error return code in ipmi_powernv_probe() mac80211_hwsim: fix possible memory leak in hwsim_new_radio_nl() kconfig: Fix expr_free() E_NOT leak kconfig: Fix automatic menu creation mem leak kconfig: Don't leak main menus during parsing watchdog: sp5100_tco: Fix watchdog disable bit nfs: Do not convert nfs_idmap_cache_timeout to jiffies dm thin: fix documentation relative to low water mark threshold tools lib traceevent: Fix get_field_str() for dynamic strings perf callchain: Fix attr.sample_max_stack setting tools lib traceevent: Simplify pointer print logic and fix %pF PCI: Add function 1 DMA alias quirk for Marvell 9128 tracing/hrtimer: Fix tracing bugs by taking all clock bases and modes into account kvm: x86: fix KVM_XEN_HVM_CONFIG ioctl ASoC: au1x: Fix timeout tests in au1xac97c_ac97_read() ALSA: hda - Use IS_REACHABLE() for dependency on input NFSv4: always set NFS_LOCK_LOST when a lock is lost. firewire-ohci: work around oversized DMA reads on JMicron controllers do d_instantiate/unlock_new_inode combinations safely xfs: remove racy hasattr check from attr ops kernel/signal.c: avoid undefined behaviour in kill_something_info kernel/sys.c: fix potential Spectre v1 issue kasan: fix memory hotplug during boot ipc/shm: fix shmat() nil address after round-down when remapping Revert "ipc/shm: Fix shmat mmap nil-page protection" xen-swiotlb: fix the check condition for xen_swiotlb_free_coherent libata: blacklist Micron 500IT SSD with MU01 firmware libata: Blacklist some Sandisk SSDs for NCQ mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register ALSA: timer: Fix pause event notification aio: fix io_destroy(2) vs. lookup_ioctx() race affs_lookup(): close a race with affs_remove_link() KVM: Fix spelling mistake: "cop_unsuable" -> "cop_unusable" MIPS: Fix ptrace(2) PTRACE_PEEKUSR and PTRACE_POKEUSR accesses to o32 FGRs MIPS: ptrace: Expose FIR register through FP regset UPSTREAM: sched/fair: Consider RT/IRQ pressure in capacity_spare_wake Conflicts: drivers/media/dvb-core/dmxdev.c drivers/scsi/sd.c drivers/scsi/ufs/ufshcd.c drivers/usb/gadget/function/f_fs.c fs/ecryptfs/inode.c Change-Id: I15751ed8c82ec65ba7eedcb0d385b9f803c333f7 Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
339 lines
8.5 KiB
C
339 lines
8.5 KiB
C
/*
|
|
* Adapted from arm64 version.
|
|
*
|
|
* Copyright (C) 2012 ARM Limited
|
|
* Copyright (C) 2015 Mentor Graphics Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <linux/cache.h>
|
|
#include <linux/elf.h>
|
|
#include <linux/err.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/of.h>
|
|
#include <linux/printk.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/timekeeper_internal.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <asm/arch_timer.h>
|
|
#include <asm/barrier.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/page.h>
|
|
#include <asm/vdso.h>
|
|
#include <asm/vdso_datapage.h>
|
|
#include <clocksource/arm_arch_timer.h>
|
|
|
|
#define MAX_SYMNAME 64
|
|
|
|
static struct page **vdso_text_pagelist;
|
|
|
|
extern char vdso_start[], vdso_end[];
|
|
|
|
/* Total number of pages needed for the data and text portions of the VDSO. */
|
|
unsigned int vdso_total_pages __ro_after_init;
|
|
|
|
/*
|
|
* The VDSO data page.
|
|
*/
|
|
static union vdso_data_store vdso_data_store __page_aligned_data;
|
|
static struct vdso_data *vdso_data = &vdso_data_store.data;
|
|
|
|
static struct page *vdso_data_page __ro_after_init;
|
|
static const struct vm_special_mapping vdso_data_mapping = {
|
|
.name = "[vvar]",
|
|
.pages = &vdso_data_page,
|
|
};
|
|
|
|
static struct vm_special_mapping vdso_text_mapping __ro_after_init = {
|
|
.name = "[vdso]",
|
|
};
|
|
|
|
struct elfinfo {
|
|
Elf32_Ehdr *hdr; /* ptr to ELF */
|
|
Elf32_Sym *dynsym; /* ptr to .dynsym section */
|
|
unsigned long dynsymsize; /* size of .dynsym section */
|
|
char *dynstr; /* ptr to .dynstr section */
|
|
};
|
|
|
|
/* Cached result of boot-time check for whether the arch timer exists,
|
|
* and if so, whether the virtual counter is useable.
|
|
*/
|
|
static bool cntvct_ok __ro_after_init;
|
|
|
|
static bool __init cntvct_functional(void)
|
|
{
|
|
struct device_node *np;
|
|
bool ret = false;
|
|
|
|
if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
|
|
goto out;
|
|
|
|
/* The arm_arch_timer core should export
|
|
* arch_timer_use_virtual or similar so we don't have to do
|
|
* this.
|
|
*/
|
|
np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
|
|
if (!np)
|
|
goto out_put;
|
|
|
|
if (of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
|
|
goto out_put;
|
|
|
|
ret = true;
|
|
|
|
out_put:
|
|
of_node_put(np);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void * __init find_section(Elf32_Ehdr *ehdr, const char *name,
|
|
unsigned long *size)
|
|
{
|
|
Elf32_Shdr *sechdrs;
|
|
unsigned int i;
|
|
char *secnames;
|
|
|
|
/* Grab section headers and strings so we can tell who is who */
|
|
sechdrs = (void *)ehdr + ehdr->e_shoff;
|
|
secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
|
|
|
|
/* Find the section they want */
|
|
for (i = 1; i < ehdr->e_shnum; i++) {
|
|
if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
|
|
if (size)
|
|
*size = sechdrs[i].sh_size;
|
|
return (void *)ehdr + sechdrs[i].sh_offset;
|
|
}
|
|
}
|
|
|
|
if (size)
|
|
*size = 0;
|
|
return NULL;
|
|
}
|
|
|
|
static Elf32_Sym * __init find_symbol(struct elfinfo *lib, const char *symname)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
|
|
char name[MAX_SYMNAME], *c;
|
|
|
|
if (lib->dynsym[i].st_name == 0)
|
|
continue;
|
|
strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
|
|
MAX_SYMNAME);
|
|
c = strchr(name, '@');
|
|
if (c)
|
|
*c = 0;
|
|
if (strcmp(symname, name) == 0)
|
|
return &lib->dynsym[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void __init vdso_nullpatch_one(struct elfinfo *lib, const char *symname)
|
|
{
|
|
Elf32_Sym *sym;
|
|
|
|
sym = find_symbol(lib, symname);
|
|
if (!sym)
|
|
return;
|
|
|
|
sym->st_name = 0;
|
|
}
|
|
|
|
static void __init patch_vdso(void *ehdr)
|
|
{
|
|
struct elfinfo einfo;
|
|
|
|
einfo = (struct elfinfo) {
|
|
.hdr = ehdr,
|
|
};
|
|
|
|
einfo.dynsym = find_section(einfo.hdr, ".dynsym", &einfo.dynsymsize);
|
|
einfo.dynstr = find_section(einfo.hdr, ".dynstr", NULL);
|
|
|
|
/* If the virtual counter is absent or non-functional we don't
|
|
* want programs to incur the slight additional overhead of
|
|
* dispatching through the VDSO only to fall back to syscalls.
|
|
*/
|
|
if (!cntvct_ok) {
|
|
vdso_nullpatch_one(&einfo, "__vdso_gettimeofday");
|
|
vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
|
|
}
|
|
}
|
|
|
|
static int __init vdso_init(void)
|
|
{
|
|
unsigned int text_pages;
|
|
int i;
|
|
|
|
if (memcmp(vdso_start, "\177ELF", 4)) {
|
|
pr_err("VDSO is not a valid ELF object!\n");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
|
|
pr_debug("vdso: %i text pages at base %pK\n", text_pages, vdso_start);
|
|
|
|
/* Allocate the VDSO text pagelist */
|
|
vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
|
|
GFP_KERNEL);
|
|
if (vdso_text_pagelist == NULL)
|
|
return -ENOMEM;
|
|
|
|
/* Grab the VDSO data page. */
|
|
vdso_data_page = virt_to_page(vdso_data);
|
|
|
|
/* Grab the VDSO text pages. */
|
|
for (i = 0; i < text_pages; i++) {
|
|
struct page *page;
|
|
|
|
page = virt_to_page(vdso_start + i * PAGE_SIZE);
|
|
vdso_text_pagelist[i] = page;
|
|
}
|
|
|
|
vdso_text_mapping.pages = vdso_text_pagelist;
|
|
|
|
vdso_total_pages = 1; /* for the data/vvar page */
|
|
vdso_total_pages += text_pages;
|
|
|
|
cntvct_ok = cntvct_functional();
|
|
|
|
patch_vdso(vdso_start);
|
|
|
|
return 0;
|
|
}
|
|
arch_initcall(vdso_init);
|
|
|
|
static int install_vvar(struct mm_struct *mm, unsigned long addr)
|
|
{
|
|
struct vm_area_struct *vma;
|
|
|
|
vma = _install_special_mapping(mm, addr, PAGE_SIZE,
|
|
VM_READ | VM_MAYREAD,
|
|
&vdso_data_mapping);
|
|
|
|
return PTR_ERR_OR_ZERO(vma);
|
|
}
|
|
|
|
/* assumes mmap_sem is write-locked */
|
|
void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
|
|
{
|
|
struct vm_area_struct *vma;
|
|
unsigned long len;
|
|
|
|
mm->context.vdso = 0;
|
|
|
|
if (vdso_text_pagelist == NULL)
|
|
return;
|
|
|
|
if (install_vvar(mm, addr))
|
|
return;
|
|
|
|
/* Account for vvar page. */
|
|
addr += PAGE_SIZE;
|
|
len = (vdso_total_pages - 1) << PAGE_SHIFT;
|
|
|
|
vma = _install_special_mapping(mm, addr, len,
|
|
VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
|
|
&vdso_text_mapping);
|
|
|
|
if (!IS_ERR(vma))
|
|
mm->context.vdso = addr;
|
|
}
|
|
|
|
static void vdso_write_begin(struct vdso_data *vdata)
|
|
{
|
|
++vdso_data->seq_count;
|
|
smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */
|
|
}
|
|
|
|
static void vdso_write_end(struct vdso_data *vdata)
|
|
{
|
|
smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */
|
|
++vdso_data->seq_count;
|
|
}
|
|
|
|
static bool tk_is_cntvct(const struct timekeeper *tk)
|
|
{
|
|
if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
|
|
return false;
|
|
|
|
if (strcmp(tk->tkr_mono.clock->name, "arch_sys_counter") != 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* update_vsyscall - update the vdso data page
|
|
*
|
|
* Increment the sequence counter, making it odd, indicating to
|
|
* userspace that an update is in progress. Update the fields used
|
|
* for coarse clocks and, if the architected system timer is in use,
|
|
* the fields used for high precision clocks. Increment the sequence
|
|
* counter again, making it even, indicating to userspace that the
|
|
* update is finished.
|
|
*
|
|
* Userspace is expected to sample seq_count before reading any other
|
|
* fields from the data page. If seq_count is odd, userspace is
|
|
* expected to wait until it becomes even. After copying data from
|
|
* the page, userspace must sample seq_count again; if it has changed
|
|
* from its previous value, userspace must retry the whole sequence.
|
|
*
|
|
* Calls to update_vsyscall are serialized by the timekeeping core.
|
|
*/
|
|
void update_vsyscall(struct timekeeper *tk)
|
|
{
|
|
struct timespec64 *wtm = &tk->wall_to_monotonic;
|
|
|
|
if (!cntvct_ok) {
|
|
/* The entry points have been zeroed, so there is no
|
|
* point in updating the data page.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
vdso_write_begin(vdso_data);
|
|
|
|
vdso_data->tk_is_cntvct = tk_is_cntvct(tk);
|
|
vdso_data->xtime_coarse_sec = tk->xtime_sec;
|
|
vdso_data->xtime_coarse_nsec = (u32)(tk->tkr_mono.xtime_nsec >>
|
|
tk->tkr_mono.shift);
|
|
vdso_data->wtm_clock_sec = wtm->tv_sec;
|
|
vdso_data->wtm_clock_nsec = wtm->tv_nsec;
|
|
|
|
if (vdso_data->tk_is_cntvct) {
|
|
vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
|
|
vdso_data->xtime_clock_sec = tk->xtime_sec;
|
|
vdso_data->xtime_clock_snsec = tk->tkr_mono.xtime_nsec;
|
|
vdso_data->cs_mult = tk->tkr_mono.mult;
|
|
vdso_data->cs_shift = tk->tkr_mono.shift;
|
|
vdso_data->cs_mask = tk->tkr_mono.mask;
|
|
}
|
|
|
|
vdso_write_end(vdso_data);
|
|
|
|
flush_dcache_page(virt_to_page(vdso_data));
|
|
}
|
|
|
|
void update_vsyscall_tz(void)
|
|
{
|
|
vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
|
|
vdso_data->tz_dsttime = sys_tz.tz_dsttime;
|
|
flush_dcache_page(virt_to_page(vdso_data));
|
|
}
|