android_kernel_oneplus_msm8998/arch/arm64/kernel/sleep.S
Blagovest Kolenichev 901bf6ddcc Merge android-4.4@4b8fc9f (v4.4.82) into msm-4.4
* refs/heads/tmp-4b8fc9f
  UPSTREAM: locking: avoid passing around 'thread_info' in mutex debugging code
  ANDROID: arm64: fix undeclared 'init_thread_info' error
  UPSTREAM: kdb: use task_cpu() instead of task_thread_info()->cpu
  Linux 4.4.82
  net: account for current skb length when deciding about UFO
  ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output
  mm/mempool: avoid KASAN marking mempool poison checks as use-after-free
  KVM: arm/arm64: Handle hva aging while destroying the vm
  sparc64: Prevent perf from running during super critical sections
  udp: consistently apply ufo or fragmentation
  revert "ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output"
  revert "net: account for current skb length when deciding about UFO"
  packet: fix tp_reserve race in packet_set_ring
  net: avoid skb_warn_bad_offload false positives on UFO
  tcp: fastopen: tcp_connect() must refresh the route
  net: sched: set xt_tgchk_param par.nft_compat as 0 in ipt_init_target
  bpf, s390: fix jit branch offset related to ldimm64
  net: fix keepalive code vs TCP_FASTOPEN_CONNECT
  tcp: avoid setting cwnd to invalid ssthresh after cwnd reduction states
  ANDROID: keychord: Fix for a memory leak in keychord.
  ANDROID: keychord: Fix races in keychord_write.
  Use %zu to print resid (size_t).
  ANDROID: keychord: Fix a slab out-of-bounds read.
  Linux 4.4.81
  workqueue: implicit ordered attribute should be overridable
  net: account for current skb length when deciding about UFO
  ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output
  mm: don't dereference struct page fields of invalid pages
  signal: protect SIGNAL_UNKILLABLE from unintentional clearing.
  lib/Kconfig.debug: fix frv build failure
  mm, slab: make sure that KMALLOC_MAX_SIZE will fit into MAX_ORDER
  ARM: 8632/1: ftrace: fix syscall name matching
  virtio_blk: fix panic in initialization error path
  drm/virtio: fix framebuffer sparse warning
  scsi: qla2xxx: Get mutex lock before checking optrom_state
  phy state machine: failsafe leave invalid RUNNING state
  x86/boot: Add missing declaration of string functions
  tg3: Fix race condition in tg3_get_stats64().
  net: phy: dp83867: fix irq generation
  sh_eth: R8A7740 supports packet shecksumming
  wext: handle NULL extra data in iwe_stream_add_point better
  sparc64: Measure receiver forward progress to avoid send mondo timeout
  xen-netback: correctly schedule rate-limited queues
  net: phy: Fix PHY unbind crash
  net: phy: Correctly process PHY_HALTED in phy_stop_machine()
  net/mlx5: Fix command bad flow on command entry allocation failure
  sctp: fix the check for _sctp_walk_params and _sctp_walk_errors
  sctp: don't dereference ptr before leaving _sctp_walk_{params, errors}()
  dccp: fix a memleak for dccp_feat_init err process
  dccp: fix a memleak that dccp_ipv4 doesn't put reqsk properly
  dccp: fix a memleak that dccp_ipv6 doesn't put reqsk properly
  net: ethernet: nb8800: Handle all 4 RGMII modes identically
  ipv6: Don't increase IPSTATS_MIB_FRAGFAILS twice in ip6_fragment()
  packet: fix use-after-free in prb_retire_rx_blk_timer_expired()
  openvswitch: fix potential out of bound access in parse_ct
  mcs7780: Fix initialization when CONFIG_VMAP_STACK is enabled
  rtnetlink: allocate more memory for dev_set_mac_address()
  ipv4: initialize fib_trie prior to register_netdev_notifier call.
  ipv6: avoid overflow of offset in ip6_find_1stfragopt
  net: Zero terminate ifr_name in dev_ifname().
  ipv4: ipv6: initialize treq->txhash in cookie_v[46]_check()
  saa7164: fix double fetch PCIe access condition
  drm: rcar-du: fix backport bug
  f2fs: sanity check checkpoint segno and blkoff
  media: lirc: LIRC_GET_REC_RESOLUTION should return microseconds
  mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries
  iser-target: Avoid isert_conn->cm_id dereference in isert_login_recv_done
  iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP
  iscsi-target: Fix initial login PDU asynchronous socket close OOPs
  iscsi-target: Fix early sk_data_ready LOGIN_FLAGS_READY race
  iscsi-target: Always wait for kthread_should_stop() before kthread exit
  target: Avoid mappedlun symlink creation during lun shutdown
  media: platform: davinci: return -EINVAL for VPFE_CMD_S_CCDC_RAW_PARAMS ioctl
  ARM: dts: armada-38x: Fix irq type for pca955
  ext4: fix overflow caused by missing cast in ext4_resize_fs()
  ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize
  mm/page_alloc: Remove kernel address exposure in free_reserved_area()
  KVM: async_pf: make rcu irq exit if not triggered from idle task
  ASoC: do not close shared backend dailink
  ALSA: hda - Fix speaker output from VAIO VPCL14M1R
  workqueue: restore WQ_UNBOUND/max_active==1 to be ordered
  libata: array underflow in ata_find_dev()
  ANDROID: binder: don't queue async transactions to thread.
  ANDROID: binder: don't enqueue death notifications to thread todo.
  ANDROID: binder: call poll_wait() unconditionally.
  android: configs: move quota-related configs to recommended
  BACKPORT: arm64: split thread_info from task stack
  UPSTREAM: arm64: assembler: introduce ldr_this_cpu
  UPSTREAM: arm64: make cpu number a percpu variable
  UPSTREAM: arm64: smp: prepare for smp_processor_id() rework
  BACKPORT: arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
  UPSTREAM: arm64: prep stack walkers for THREAD_INFO_IN_TASK
  UPSTREAM: arm64: unexport walk_stackframe
  UPSTREAM: arm64: traps: simplify die() and __die()
  UPSTREAM: arm64: factor out current_stack_pointer
  BACKPORT: arm64: asm-offsets: remove unused definitions
  UPSTREAM: arm64: thread_info remove stale items
  UPSTREAM: thread_info: include <current.h> for THREAD_INFO_IN_TASK
  UPSTREAM: thread_info: factor out restart_block
  UPSTREAM: kthread: Pin the stack via try_get_task_stack()/put_task_stack() in to_live_kthread() function
  UPSTREAM: sched/core: Add try_get_task_stack() and put_task_stack()
  UPSTREAM: sched/core: Allow putting thread_info into task_struct
  UPSTREAM: printk: when dumping regs, show the stack, not thread_info
  UPSTREAM: fix up initial thread stack pointer vs thread_info confusion
  UPSTREAM: Clarify naming of thread info/stack allocators
  ANDROID: sdcardfs: override credential for ioctl to lower fs

Conflicts:
	android/configs/android-base.cfg
	arch/arm64/Kconfig
	arch/arm64/include/asm/suspend.h
	arch/arm64/kernel/head.S
	arch/arm64/kernel/smp.c
	arch/arm64/kernel/suspend.c
	arch/arm64/kernel/traps.c
	arch/arm64/mm/proc.S
	kernel/fork.c
	sound/soc/soc-pcm.c

Change-Id: I273e216c94899a838bbd208391c6cbe20b2bf683
Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
2017-09-01 11:47:49 -07:00

145 lines
4.5 KiB
ArmAsm

#include <linux/errno.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/assembler.h>
.text
/*
* Implementation of MPIDR_EL1 hash algorithm through shifting
* and OR'ing.
*
* @dst: register containing hash result
* @rs0: register containing affinity level 0 bit shift
* @rs1: register containing affinity level 1 bit shift
* @rs2: register containing affinity level 2 bit shift
* @rs3: register containing affinity level 3 bit shift
* @mpidr: register containing MPIDR_EL1 value
* @mask: register containing MPIDR mask
*
* Pseudo C-code:
*
*u32 dst;
*
*compute_mpidr_hash(u32 rs0, u32 rs1, u32 rs2, u32 rs3, u64 mpidr, u64 mask) {
* u32 aff0, aff1, aff2, aff3;
* u64 mpidr_masked = mpidr & mask;
* aff0 = mpidr_masked & 0xff;
* aff1 = mpidr_masked & 0xff00;
* aff2 = mpidr_masked & 0xff0000;
* aff2 = mpidr_masked & 0xff00000000;
* dst = (aff0 >> rs0 | aff1 >> rs1 | aff2 >> rs2 | aff3 >> rs3);
*}
* Input registers: rs0, rs1, rs2, rs3, mpidr, mask
* Output register: dst
* Note: input and output registers must be disjoint register sets
(eg: a macro instance with mpidr = x1 and dst = x1 is invalid)
*/
.macro compute_mpidr_hash dst, rs0, rs1, rs2, rs3, mpidr, mask
and \mpidr, \mpidr, \mask // mask out MPIDR bits
and \dst, \mpidr, #0xff // mask=aff0
lsr \dst ,\dst, \rs0 // dst=aff0>>rs0
and \mask, \mpidr, #0xff00 // mask = aff1
lsr \mask ,\mask, \rs1
orr \dst, \dst, \mask // dst|=(aff1>>rs1)
and \mask, \mpidr, #0xff0000 // mask = aff2
lsr \mask ,\mask, \rs2
orr \dst, \dst, \mask // dst|=(aff2>>rs2)
and \mask, \mpidr, #0xff00000000 // mask = aff3
lsr \mask ,\mask, \rs3
orr \dst, \dst, \mask // dst|=(aff3>>rs3)
.endm
/*
* Save CPU state in the provided sleep_stack_data area, and publish its
* location for cpu_resume()'s use in sleep_save_stash.
*
* cpu_resume() will restore this saved state, and return. Because the
* link-register is saved and restored, it will appear to return from this
* function. So that the caller can tell the suspend/resume paths apart,
* __cpu_suspend_enter() will always return a non-zero value, whereas the
* path through cpu_resume() will return 0.
*
* x0 = struct sleep_stack_data area
*/
ENTRY(__cpu_suspend_enter)
stp x29, lr, [x0, #SLEEP_STACK_DATA_CALLEE_REGS]
stp x19, x20, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+16]
stp x21, x22, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+32]
stp x23, x24, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+48]
stp x25, x26, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+64]
stp x27, x28, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+80]
/* save the sp in cpu_suspend_ctx */
mov x2, sp
str x2, [x0, #SLEEP_STACK_DATA_SYSTEM_REGS + CPU_CTX_SP]
/* find the mpidr_hash */
ldr x1, =sleep_save_stash
ldr x1, [x1]
mrs x7, mpidr_el1
ldr x9, =mpidr_hash
ldr x10, [x9, #MPIDR_HASH_MASK]
/*
* Following code relies on the struct mpidr_hash
* members size.
*/
ldp w3, w4, [x9, #MPIDR_HASH_SHIFTS]
ldp w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
add x1, x1, x8, lsl #3
str x0, [x1]
add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
stp x29, lr, [sp, #-16]!
bl cpu_do_suspend
ldp x29, lr, [sp], #16
mov x0, #1
ret
ENDPROC(__cpu_suspend_enter)
.ltorg
ENTRY(cpu_resume)
bl el2_setup // if in EL2 drop to EL1 cleanly
/* enable the MMU early - so we can access sleep_save_stash by va */
adr_l lr, __enable_mmu /* __cpu_setup will return here */
ldr x27, =_cpu_resume /* __enable_mmu will branch here */
adrp x25, idmap_pg_dir
adrp x26, swapper_pg_dir
b __cpu_setup
ENDPROC(cpu_resume)
ENTRY(_cpu_resume)
mrs x1, mpidr_el1
adrp x8, mpidr_hash
add x8, x8, #:lo12:mpidr_hash // x8 = struct mpidr_hash phys address
/* retrieve mpidr_hash members to compute the hash */
ldr x2, [x8, #MPIDR_HASH_MASK]
ldp w3, w4, [x8, #MPIDR_HASH_SHIFTS]
ldp w5, w6, [x8, #(MPIDR_HASH_SHIFTS + 8)]
compute_mpidr_hash x7, x3, x4, x5, x6, x1, x2
/* x7 contains hash index, let's use it to grab context pointer */
ldr_l x0, sleep_save_stash
ldr x0, [x0, x7, lsl #3]
add x29, x0, #SLEEP_STACK_DATA_CALLEE_REGS
add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
/* load sp from context */
ldr x2, [x0, #CPU_CTX_SP]
mov sp, x2
/*
* cpu_do_resume expects x0 to contain context address pointer
*/
bl cpu_do_resume
#ifdef CONFIG_KASAN
mov x0, sp
bl kasan_unpoison_remaining_stack
#endif
ldp x19, x20, [x29, #16]
ldp x21, x22, [x29, #32]
ldp x23, x24, [x29, #48]
ldp x25, x26, [x29, #64]
ldp x27, x28, [x29, #80]
ldp x29, lr, [x29]
mov x0, #0
ret
ENDPROC(_cpu_resume)