Files
linux-rockchip/arch/arm/kernel/process.c
Tao Huang daf2796321 Merge commit '52f971ee6e023d89d24f9e3cd145d86d707e459c'
* commit '52f971ee6e023d89d24f9e3cd145d86d707e459c': (84565 commits)
  arm64: dts: rockchip: rk3562: Enable viLKsvPwrActive for soc bus
  mtd: spi-nor: esmt: Support New devices
  mtd: spi-nor: fmsh: Support New devices
  mtd: spi-nor: gigadevice: Support New devices
  mtd: spinand: gsto: Add code
  mtd: spinand: hyf: Support new devices
  mmc: convert thunder boot dependency
  ARM: dts: rockchip: rv1106: add node for system sleep
  ARM: rockchip: support rv1106 suspend
  ARM: rockchip: add some pm-related functions
  video: rockchip: mpp: fix rk3528 avsd not probe issue
  arm64: dts: rockchip: rk3588-vehicle-maxim-serdes: Add BOE AV156FHT L83 support
  arm64: rockchip_defconfig: Enable CONFIG_DRM_PANEL_MAXIM_MAX96752F
  drm/panel: Add panel driver for Maxim MAX96752F based LCDs
  media: i2c: techpoint: add support 4 channel 2 lane mode
  drm/rockchip: dsi2: fix NULL in component_ops .unbind helper
  media: rockchip: vicap: fixes cma can not alloc when capture raw
  media: rockchip: vicap: fixed vc err for multi channel
  media: rockchip: hdmirx: fix timing info for interlaced resolution
  media: rockchip: hdmirx: fix code error for cec register failed
  ...

Change-Id: Ia7ac365455d87a295e62bbf481d80694a9712f30

Conflicts:
	.gitignore
	Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
	Documentation/devicetree/bindings/connector/usb-connector.yaml
	Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
	Documentation/devicetree/bindings/hwmon/pwm-fan.txt
	Documentation/devicetree/bindings/iio/light/vl6180.txt
	Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
	Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml
	Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
	Documentation/devicetree/bindings/net/snps,dwmac.yaml
	Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
	Documentation/devicetree/bindings/power/rockchip-io-domain.txt
	Documentation/devicetree/bindings/regulator/fan53555.txt
	Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
	Documentation/devicetree/bindings/sound/rockchip,pdm.yaml
	Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
	Documentation/devicetree/bindings/spi/spi-rockchip.yaml
	Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
	Documentation/devicetree/bindings/usb/usb-xhci.txt
	Documentation/filesystems/erofs.rst
	arch/arm/Kconfig
	arch/arm/Makefile
	arch/arm/boot/compressed/head.S
	arch/arm/boot/dts/rk3036.dtsi
	arch/arm/boot/dts/rk3066a-rayeager.dts
	arch/arm/boot/dts/rk3066a.dtsi
	arch/arm/boot/dts/rk322x.dtsi
	arch/arm/boot/dts/rk3288.dtsi
	arch/arm/boot/dts/rk3xxx.dtsi
	arch/arm64/boot/dts/rockchip/Makefile
	arch/arm64/boot/dts/rockchip/px30.dtsi
	arch/arm64/boot/dts/rockchip/rk3308.dtsi
	arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
	arch/arm64/boot/dts/rockchip/rk3399.dtsi
	arch/arm64/boot/dts/rockchip/rk3566.dtsi
	arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
	arch/arm64/boot/dts/rockchip/rk3568.dtsi
	arch/arm64/boot/dts/rockchip/rockchip-pinconf.dtsi
	arch/arm64/kernel/process.c
	arch/arm64/mm/Makefile
	arch/arm64/mm/fault.c
	arch/arm64/mm/init.c
	drivers/Kconfig
	drivers/Makefile
	drivers/android/Kconfig
	drivers/ata/ahci_platform.c
	drivers/char/hw_random/Kconfig
	drivers/char/hw_random/Makefile
	drivers/clk/clk.c
	drivers/clk/rockchip/Kconfig
	drivers/clk/rockchip/Makefile
	drivers/clk/rockchip/clk-cpu.c
	drivers/clk/rockchip/clk-rk3036.c
	drivers/clk/rockchip/clk-rk3188.c
	drivers/clk/rockchip/clk-rk3308.c
	drivers/clk/rockchip/clk-rk3399.c
	drivers/clk/rockchip/clk-rk3568.c
	drivers/clk/rockchip/clk-rv1126.c
	drivers/clk/rockchip/clk.c
	drivers/clk/rockchip/clk.h
	drivers/cpufreq/cpufreq-dt.c
	drivers/crypto/Kconfig
	drivers/devfreq/Makefile
	drivers/devfreq/devfreq.c
	drivers/dma-buf/dma-buf.c
	drivers/dma-buf/heaps/Makefile
	drivers/dma/pl330.c
	drivers/firmware/Kconfig
	drivers/gpio/Kconfig
	drivers/gpio/Makefile
	drivers/gpio/gpio-rockchip.c
	drivers/gpu/Makefile
	drivers/gpu/drm/Kconfig
	drivers/gpu/drm/Makefile
	drivers/gpu/drm/bridge/Kconfig
	drivers/gpu/drm/bridge/Makefile
	drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
	drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
	drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
	drivers/gpu/drm/bridge/display-connector.c
	drivers/gpu/drm/bridge/sii902x.c
	drivers/gpu/drm/bridge/synopsys/Makefile
	drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
	drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
	drivers/gpu/drm/drm_atomic_helper.c
	drivers/gpu/drm/drm_crtc_internal.h
	drivers/gpu/drm/drm_edid.c
	drivers/gpu/drm/panel/panel-simple.c
	drivers/gpu/drm/rockchip/Kconfig
	drivers/gpu/drm/rockchip/Makefile
	drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
	drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
	drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
	drivers/gpu/drm/rockchip/inno_hdmi.c
	drivers/gpu/drm/rockchip/rockchip_drm_drv.c
	drivers/gpu/drm/rockchip/rockchip_drm_drv.h
	drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
	drivers/gpu/drm/rockchip/rockchip_drm_gem.c
	drivers/gpu/drm/rockchip/rockchip_drm_vop.c
	drivers/gpu/drm/rockchip/rockchip_drm_vop.h
	drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
	drivers/gpu/drm/rockchip/rockchip_lvds.c
	drivers/gpu/drm/rockchip/rockchip_rgb.c
	drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
	drivers/gpu/drm/rockchip/rockchip_vop_reg.c
	drivers/gpu/drm/rockchip/rockchip_vop_reg.h
	drivers/hwmon/pwm-fan.c
	drivers/hwspinlock/Kconfig
	drivers/hwspinlock/Makefile
	drivers/i2c/busses/i2c-rk3x.c
	drivers/i2c/i2c-core-base.c
	drivers/iio/adc/Kconfig
	drivers/iio/adc/rockchip_saradc.c
	drivers/iio/industrialio-event.c
	drivers/input/touchscreen/Makefile
	drivers/iommu/iommu.c
	drivers/iommu/rockchip-iommu.c
	drivers/irqchip/irq-gic-v3-its.c
	drivers/leds/Makefile
	drivers/mailbox/Kconfig
	drivers/media/common/videobuf2/Makefile
	drivers/media/i2c/Kconfig
	drivers/media/i2c/Makefile
	drivers/media/i2c/dw9714.c
	drivers/media/i2c/hi556.c
	drivers/media/i2c/imx214.c
	drivers/media/i2c/imx258.c
	drivers/media/i2c/imx334.c
	drivers/media/i2c/imx335.c
	drivers/media/i2c/ov5648.c
	drivers/media/i2c/ov5670.c
	drivers/media/i2c/ov5695.c
	drivers/media/i2c/ov7251.c
	drivers/media/platform/Kconfig
	drivers/media/platform/Makefile
	drivers/media/platform/rockchip/Kconfig
	drivers/media/spi/Kconfig
	drivers/media/spi/Makefile
	drivers/media/usb/uvc/uvc_driver.c
	drivers/media/usb/uvc/uvcvideo.h
	drivers/media/v4l2-core/v4l2-async.c
	drivers/media/v4l2-core/v4l2-ioctl.c
	drivers/mfd/rk808.c
	drivers/mmc/core/block.c
	drivers/mmc/core/host.c
	drivers/mmc/core/mmc.c
	drivers/mmc/core/mmc_ops.c
	drivers/mmc/host/Makefile
	drivers/mmc/host/dw_mmc-rockchip.c
	drivers/mmc/host/dw_mmc.c
	drivers/mmc/host/dw_mmc.h
	drivers/mmc/host/sdhci-of-dwcmshc.c
	drivers/mtd/nand/Makefile
	drivers/mtd/nand/raw/Kconfig
	drivers/mtd/nand/raw/Makefile
	drivers/mtd/nand/raw/rockchip-nand-controller.c
	drivers/mtd/nand/spi/Makefile
	drivers/mtd/nand/spi/core.c
	drivers/mtd/nand/spi/gigadevice.c
	drivers/mtd/nand/spi/macronix.c
	drivers/mtd/nand/spi/xtx.c
	drivers/mtd/spi-nor/Kconfig
	drivers/mtd/spi-nor/Makefile
	drivers/mtd/spi-nor/core.c
	drivers/mtd/spi-nor/core.h
	drivers/mtd/spi-nor/eon.c
	drivers/mtd/spi-nor/esmt.c
	drivers/mtd/spi-nor/gigadevice.c
	drivers/mtd/spi-nor/macronix.c
	drivers/mtd/spi-nor/winbond.c
	drivers/mtd/spi-nor/xmc.c
	drivers/net/ethernet/stmicro/stmmac/Makefile
	drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
	drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
	drivers/net/ethernet/stmicro/stmmac/stmmac.h
	drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
	drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
	drivers/net/phy/Kconfig
	drivers/net/phy/motorcomm.c
	drivers/net/phy/phy_device.c
	drivers/nvmem/Kconfig
	drivers/nvmem/Makefile
	drivers/pci/controller/dwc/Makefile
	drivers/pci/controller/dwc/pcie-designware-host.c
	drivers/pci/controller/dwc/pcie-dw-rockchip.c
	drivers/pci/controller/pcie-rockchip-host.c
	drivers/pci/controller/pcie-rockchip.h
	drivers/pci/pci-sysfs.c
	drivers/pci/pcie/Makefile
	drivers/phy/rockchip/Kconfig
	drivers/phy/rockchip/Makefile
	drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
	drivers/phy/rockchip/phy-rockchip-inno-usb2.c
	drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
	drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
	drivers/phy/rockchip/phy-rockchip-typec.c
	drivers/pinctrl/Kconfig
	drivers/pinctrl/Makefile
	drivers/pinctrl/pinctrl-rk805.c
	drivers/pinctrl/pinctrl-rockchip.c
	drivers/pinctrl/pinctrl-rockchip.h
	drivers/power/supply/Kconfig
	drivers/power/supply/Makefile
	drivers/power/supply/bq25890_charger.c
	drivers/power/supply/rk817_charger.c
	drivers/pwm/core.c
	drivers/pwm/pwm-rockchip.c
	drivers/regulator/fan53555.c
	drivers/regulator/rk808-regulator.c
	drivers/rtc/rtc-hym8563.c
	drivers/soc/rockchip/Kconfig
	drivers/soc/rockchip/Makefile
	drivers/soc/rockchip/grf.c
	drivers/soc/rockchip/io-domain.c
	drivers/soc/rockchip/pm_domains.c
	drivers/spi/Kconfig
	drivers/spi/spi-rockchip-sfc.c
	drivers/spi/spi-rockchip.c
	drivers/spi/spidev.c
	drivers/staging/android/ion/heaps/ion_system_heap.c
	drivers/thermal/rockchip_thermal.c
	drivers/tty/serial/8250/8250_dma.c
	drivers/tty/serial/8250/8250_dw.c
	drivers/tty/serial/8250/8250_dwlib.c
	drivers/tty/serial/8250/8250_port.c
	drivers/usb/dwc2/platform.c
	drivers/usb/dwc3/core.c
	drivers/usb/dwc3/core.h
	drivers/usb/dwc3/ep0.c
	drivers/usb/dwc3/gadget.c
	drivers/usb/gadget/configfs.c
	drivers/usb/gadget/function/f_fs.c
	drivers/usb/gadget/function/f_uvc.c
	drivers/usb/gadget/function/uvc.h
	drivers/usb/gadget/function/uvc_configfs.c
	drivers/usb/gadget/function/uvc_queue.c
	drivers/usb/gadget/function/uvc_v4l2.c
	drivers/usb/gadget/function/uvc_video.c
	drivers/usb/gadget/udc/core.c
	drivers/usb/host/ehci-hcd.c
	drivers/usb/host/ehci-platform.c
	drivers/usb/storage/unusual_uas.h
	drivers/usb/typec/altmodes/Kconfig
	drivers/usb/typec/altmodes/displayport.c
	drivers/usb/typec/class.c
	drivers/usb/typec/tcpm/tcpm.c
	fs/Kconfig
	fs/cifs/inode.c
	fs/dax.c
	fs/erofs/data.c
	fs/erofs/inode.c
	fs/erofs/internal.h
	fs/erofs/super.c
	fs/f2fs/super.c
	fs/fuse/dev.c
	include/drm/bridge/dw_hdmi.h
	include/drm/drm_connector.h
	include/drm/drm_edid.h
	include/dt-bindings/clock/rk3568-cru.h
	include/dt-bindings/power/rk3568-power.h
	include/dt-bindings/power/rk3588-power.h
	include/linux/clk-provider.h
	include/linux/cma.h
	include/linux/dma-buf.h
	include/linux/dma-heap.h
	include/linux/mfd/rk808.h
	include/linux/mtd/spi-nor.h
	include/linux/mtd/spinand.h
	include/linux/phy/pcie.h
	include/linux/pwm.h
	include/linux/sched/sysctl.h
	include/linux/slub_def.h
	include/linux/stmmac.h
	include/linux/usb/typec.h
	include/media/v4l2-async.h
	include/soc/rockchip/pm_domains.h
	include/uapi/drm/drm_fourcc.h
	include/uapi/linux/iio/types.h
	include/uapi/linux/media-bus-format.h
	init/Kconfig
	init/main.c
	kernel/printk/printk.c
	kernel/rcu/Kconfig.debug
	kernel/rcu/tree_stall.h
	kernel/sched/core.c
	kernel/sched/cpufreq_schedutil.c
	kernel/sched/fair.c
	kernel/sched/pelt.c
	kernel/sched/rt.c
	kernel/sched/sched.h
	kernel/softirq.c
	kernel/sysctl.c
	mm/Makefile
	mm/cma.c
	mm/page_alloc.c
	mm/slub.c
	scripts/.gitignore
	scripts/headers_install.sh
	sound/soc/codecs/Kconfig
	sound/soc/codecs/Makefile
	sound/soc/codecs/es8326.c
	sound/soc/codecs/es8326.h
	sound/soc/codecs/hdmi-codec.c
	sound/soc/codecs/rk817_codec.c
	sound/soc/rockchip/Kconfig
	sound/soc/rockchip/Makefile
	sound/soc/rockchip/rockchip_i2s.c
	sound/soc/rockchip/rockchip_i2s_tdm.c
	sound/soc/rockchip/rockchip_i2s_tdm.h
	sound/soc/rockchip/rockchip_pdm.c
	sound/soc/rockchip/rockchip_spdif.c
	sound/soc/soc-generic-dmaengine-pcm.c
	tools/iio/iio_event_monitor.c
2023-05-20 18:57:29 +08:00

447 lines
10 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* linux/arch/arm/kernel/process.c
*
* Copyright (C) 1996-2000 Russell King - Converted to ARM.
* Original Copyright (C) 1995 Linus Torvalds
*/
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/elfcore.h>
#include <linux/pm.h>
#include <linux/tick.h>
#include <linux/utsname.h>
#include <linux/uaccess.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
#include <linux/leds.h>
#include <asm/processor.h>
#include <asm/thread_notify.h>
#include <asm/stacktrace.h>
#include <asm/system_misc.h>
#include <asm/mach/time.h>
#include <asm/tls.h>
#include <asm/vdso.h>
#include "signal.h"
#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
DEFINE_PER_CPU(struct task_struct *, __entry_task);
#endif
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
#ifndef CONFIG_CURRENT_POINTER_IN_TPIDRURO
asmlinkage struct task_struct *__current;
EXPORT_SYMBOL(__current);
#endif
static const char *processor_modes[] __maybe_unused = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
"USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "MON_32" , "ABT_32" ,
"UK8_32" , "UK9_32" , "HYP_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
};
static const char *isa_modes[] __maybe_unused = {
"ARM" , "Thumb" , "Jazelle", "ThumbEE"
};
/*
* This is our default idle handler.
*/
void (*arm_pm_idle)(void);
/*
* Called from the core idle loop.
*/
void arch_cpu_idle(void)
{
if (arm_pm_idle)
arm_pm_idle();
else
cpu_do_idle();
raw_local_irq_enable();
}
void arch_cpu_idle_prepare(void)
{
local_fiq_enable();
}
void arch_cpu_idle_enter(void)
{
idle_notifier_call_chain(IDLE_START);
ledtrig_cpu(CPU_LED_IDLE_START);
#ifdef CONFIG_PL310_ERRATA_769419
wmb();
#endif
}
void arch_cpu_idle_exit(void)
{
ledtrig_cpu(CPU_LED_IDLE_END);
idle_notifier_call_chain(IDLE_END);
}
void __show_regs_alloc_free(struct pt_regs *regs)
{
int i;
/* check for r0 - r12 only */
for (i = 0; i < 13; i++) {
pr_alert("Register r%d information:", i);
mem_dump_obj((void *)regs->uregs[i]);
}
}
void __show_regs(struct pt_regs *regs)
{
unsigned long flags;
char buf[64];
#ifndef CONFIG_CPU_V7M
unsigned int domain;
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Get the domain register for the parent context. In user
* mode, we don't save the DACR, so lets use what it should
* be. For other modes, we place it after the pt_regs struct.
*/
if (user_mode(regs)) {
domain = DACR_UACCESS_ENABLE;
} else {
domain = to_svc_pt_regs(regs)->dacr;
}
#else
domain = get_domain();
#endif
#endif
show_regs_print_info(KERN_DEFAULT);
printk("PC is at %pS\n", (void *)instruction_pointer(regs));
printk("LR is at %pS\n", (void *)regs->ARM_lr);
printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n",
regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr);
printk("sp : %08lx ip : %08lx fp : %08lx\n",
regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
regs->ARM_r10, regs->ARM_r9,
regs->ARM_r8);
printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
regs->ARM_r7, regs->ARM_r6,
regs->ARM_r5, regs->ARM_r4);
printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
regs->ARM_r3, regs->ARM_r2,
regs->ARM_r1, regs->ARM_r0);
flags = regs->ARM_cpsr;
buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
buf[4] = '\0';
#ifndef CONFIG_CPU_V7M
{
const char *segment;
if ((domain & domain_mask(DOMAIN_USER)) ==
domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
segment = "none";
else
segment = "user";
printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n",
buf, interrupts_enabled(regs) ? "n" : "ff",
fast_interrupts_enabled(regs) ? "n" : "ff",
processor_modes[processor_mode(regs)],
isa_modes[isa_mode(regs)], segment);
}
#else
printk("xPSR: %08lx\n", regs->ARM_cpsr);
#endif
#ifdef CONFIG_CPU_CP15
{
unsigned int ctrl;
buf[0] = '\0';
#ifdef CONFIG_CPU_CP15_MMU
{
unsigned int transbase;
asm("mrc p15, 0, %0, c2, c0\n\t"
: "=r" (transbase));
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
transbase, domain);
}
#endif
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
printk("Control: %08x%s\n", ctrl, buf);
}
#endif
}
void show_regs(struct pt_regs * regs)
{
__show_regs(regs);
dump_backtrace(regs, NULL, KERN_DEFAULT);
}
ATOMIC_NOTIFIER_HEAD(thread_notify_head);
EXPORT_SYMBOL_GPL(thread_notify_head);
/*
* Free current thread data structures etc..
*/
void exit_thread(struct task_struct *tsk)
{
thread_notify(THREAD_NOTIFY_EXIT, task_thread_info(tsk));
}
void flush_thread(void)
{
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
flush_ptrace_hw_breakpoint(tsk);
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
memset(&thread->fpstate, 0, sizeof(union fp_state));
flush_tls();
thread_notify(THREAD_NOTIFY_FLUSH, thread);
}
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
unsigned long clone_flags = args->flags;
unsigned long stack_start = args->stack;
unsigned long tls = args->tls;
struct thread_info *thread = task_thread_info(p);
struct pt_regs *childregs = task_pt_regs(p);
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
#ifdef CONFIG_CPU_USE_DOMAINS
/*
* Copy the initial value of the domain access control register
* from the current thread: thread->addr_limit will have been
* copied from the current thread via setup_thread_stack() in
* kernel/fork.c
*/
thread->cpu_domain = get_domain();
#endif
if (likely(!args->fn)) {
*childregs = *current_pt_regs();
childregs->ARM_r0 = 0;
if (stack_start)
childregs->ARM_sp = stack_start;
} else {
memset(childregs, 0, sizeof(struct pt_regs));
thread->cpu_context.r4 = (unsigned long)args->fn_arg;
thread->cpu_context.r5 = (unsigned long)args->fn;
childregs->ARM_cpsr = SVC_MODE;
}
thread->cpu_context.pc = (unsigned long)ret_from_fork;
thread->cpu_context.sp = (unsigned long)childregs;
clear_ptrace_hw_breakpoint(p);
if (clone_flags & CLONE_SETTLS)
thread->tp_value[0] = tls;
thread->tp_value[1] = get_tpuser();
thread_notify(THREAD_NOTIFY_COPY, thread);
return 0;
}
unsigned long __get_wchan(struct task_struct *p)
{
struct stackframe frame;
unsigned long stack_page;
int count = 0;
frame.fp = thread_saved_fp(p);
frame.sp = thread_saved_sp(p);
frame.lr = 0; /* recovered from the stack */
frame.pc = thread_saved_pc(p);
stack_page = (unsigned long)task_stack_page(p);
do {
if (frame.sp < stack_page ||
frame.sp >= stack_page + THREAD_SIZE ||
unwind_frame(&frame) < 0)
return 0;
if (!in_sched_functions(frame.pc))
return frame.pc;
} while (count ++ < 16);
return 0;
}
#ifdef CONFIG_MMU
#ifdef CONFIG_KUSER_HELPERS
/*
* The vectors page is always readable from user space for the
* atomic helpers. Insert it into the gate_vma so that it is visible
* through ptrace and /proc/<pid>/mem.
*/
static struct vm_area_struct gate_vma;
static int __init gate_vma_init(void)
{
vma_init(&gate_vma, NULL);
gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
gate_vma.vm_start = 0xffff0000;
gate_vma.vm_end = 0xffff0000 + PAGE_SIZE;
gate_vma.vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
return 0;
}
arch_initcall(gate_vma_init);
struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
{
return &gate_vma;
}
int in_gate_area(struct mm_struct *mm, unsigned long addr)
{
return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
}
int in_gate_area_no_mm(unsigned long addr)
{
return in_gate_area(NULL, addr);
}
#define is_gate_vma(vma) ((vma) == &gate_vma)
#else
#define is_gate_vma(vma) 0
#endif
const char *arch_vma_name(struct vm_area_struct *vma)
{
return is_gate_vma(vma) ? "[vectors]" : NULL;
}
/* If possible, provide a placement hint at a random offset from the
* stack for the sigpage and vdso pages.
*/
static unsigned long sigpage_addr(const struct mm_struct *mm,
unsigned int npages)
{
unsigned long offset;
unsigned long first;
unsigned long last;
unsigned long addr;
unsigned int slots;
first = PAGE_ALIGN(mm->start_stack);
last = TASK_SIZE - (npages << PAGE_SHIFT);
/* No room after stack? */
if (first > last)
return 0;
/* Just enough room? */
if (first == last)
return first;
slots = ((last - first) >> PAGE_SHIFT) + 1;
offset = prandom_u32_max(slots);
addr = first + (offset << PAGE_SHIFT);
return addr;
}
static struct page *signal_page;
extern struct page *get_signal_page(void);
static int sigpage_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{
current->mm->context.sigpage = new_vma->vm_start;
return 0;
}
static const struct vm_special_mapping sigpage_mapping = {
.name = "[sigpage]",
.pages = &signal_page,
.mremap = sigpage_mremap,
};
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long npages;
unsigned long addr;
unsigned long hint;
int ret = 0;
if (!signal_page)
signal_page = get_signal_page();
if (!signal_page)
return -ENOMEM;
npages = 1; /* for sigpage */
npages += vdso_total_pages;
if (mmap_write_lock_killable(mm))
return -EINTR;
hint = sigpage_addr(mm, npages);
addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;
}
vma = _install_special_mapping(mm, addr, PAGE_SIZE,
VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
&sigpage_mapping);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto up_fail;
}
mm->context.sigpage = addr;
/* Unlike the sigpage, failure to install the vdso is unlikely
* to be fatal to the process, so no error check needed
* here.
*/
arm_install_vdso(mm, addr + PAGE_SIZE);
up_fail:
mmap_write_unlock(mm);
return ret;
}
#endif