Merge branch 'android-4.19' into android-4.19-stable

Final merge of android-4.19

Change-Id: Ifa789a66260ed6207e829555ad2050d30e3de555
This commit is contained in:
Todd Kjos
2020-05-18 08:24:14 -07:00
1024 changed files with 74671 additions and 57934 deletions

View File

@@ -6,6 +6,8 @@ Description:
This file allows user to read/write the raw NVMEM contents. This file allows user to read/write the raw NVMEM contents.
Permissions for write to this file depends on the nvmem Permissions for write to this file depends on the nvmem
provider configuration. provider configuration.
Note: This file is only present if CONFIG_NVMEM_SYSFS
is enabled
ex: ex:
hexdump /sys/bus/nvmem/devices/qfprom0/nvmem hexdump /sys/bus/nvmem/devices/qfprom0/nvmem

View File

@@ -144,7 +144,8 @@ Description:
Access: Read Access: Read
Valid values: "Unknown", "Good", "Overheat", "Dead", Valid values: "Unknown", "Good", "Overheat", "Dead",
"Over voltage", "Unspecified failure", "Cold", "Over voltage", "Unspecified failure", "Cold",
"Watchdog timer expire", "Safety timer expire" "Watchdog timer expire", "Safety timer expire",
"Over current", "Warm", "Cool", "Hot"
What: /sys/class/power_supply/<supply_name>/precharge_current What: /sys/class/power_supply/<supply_name>/precharge_current
Date: June 2017 Date: June 2017

View File

@@ -323,3 +323,18 @@ What: /sys/fs/f2fs/<disk>/mounted_time_sec
Date: February 2020 Date: February 2020
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description: Show the mounted time in secs of this partition. Description: Show the mounted time in secs of this partition.
What: /sys/fs/f2fs/<disk>/data_io_flag
Date: April 2020
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description: Give a way to attach REQ_META|FUA to data writes
given temperature-based bits. Now the bits indicate:
* REQ_META | REQ_FUA |
* 5 | 4 | 3 | 2 | 1 | 0 |
* Cold | Warm | Hot | Cold | Warm | Hot |
What: /sys/fs/f2fs/<disk>/iostat_period_ms
Date: April 2020
Contact: "Daeho Jeong" <daehojeong@google.com>
Description: Give a way to change iostat_period time. 3secs by default.
The new iostat trace gives stats gap given the period.

View File

@@ -4032,7 +4032,9 @@
[[,]s[mp]#### \ [[,]s[mp]#### \
[[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \ [[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \
[[,]f[orce] [[,]f[orce]
Where reboot_mode is one of warm (soft) or cold (hard) or gpio, Where reboot_mode is one of warm (soft) or cold (hard) or gpio
(prefix with 'panic_' to set mode for panic
reboot only),
reboot_type is one of bios, acpi, kbd, triple, efi, or pci, reboot_type is one of bios, acpi, kbd, triple, efi, or pci,
reboot_force is either force or not specified, reboot_force is either force or not specified,
reboot_cpu is s[mp]#### with #### being the processor reboot_cpu is s[mp]#### with #### being the processor

View File

@@ -0,0 +1,27 @@
==================
ARM64 Architecture
==================
.. toctree::
:maxdepth: 1
acpi_object_usage
arm-acpi
booting
cpu-feature-registers
elf_hwcaps
hugetlbpage
legacy_instructions
memory
pointer-authentication
silicon-errata
sve
tagged-address-abi
tagged-pointers
.. only:: subproject and html
Indices
=======
* :ref:`genindex`

View File

@@ -59,6 +59,7 @@ stable kernels.
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 | | ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
| ARM | MMU-500 | #841119,#826419 | N/A | | ARM | MMU-500 | #841119,#826419 | N/A |
| | | | | | | | | |
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |

View File

@@ -0,0 +1,75 @@
=========================================
Tagged virtual addresses in AArch64 Linux
=========================================
Author: Will Deacon <will.deacon@arm.com>
Date : 12 June 2013
This document briefly describes the provision of tagged virtual
addresses in the AArch64 translation system and their potential uses
in AArch64 Linux.
The kernel configures the translation tables so that translations made
via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of
the virtual address ignored by the translation hardware. This frees up
this byte for application use.
Passing tagged addresses to the kernel
--------------------------------------
All interpretation of userspace memory addresses by the kernel assumes
an address tag of 0x00, unless the application enables the AArch64
Tagged Address ABI explicitly
(Documentation/arm64/tagged-address-abi.rst).
This includes, but is not limited to, addresses found in:
- pointer arguments to system calls, including pointers in structures
passed to system calls,
- the stack pointer (sp), e.g. when interpreting it to deliver a
signal,
- the frame pointer (x29) and frame records, e.g. when interpreting
them to generate a backtrace or call graph.
Using non-zero address tags in any of these locations when the
userspace application did not enable the AArch64 Tagged Address ABI may
result in an error code being returned, a (fatal) signal being raised,
or other modes of failure.
For these reasons, when the AArch64 Tagged Address ABI is disabled,
passing non-zero address tags to the kernel via system calls is
forbidden, and using a non-zero address tag for sp is strongly
discouraged.
Programs maintaining a frame pointer and frame records that use non-zero
address tags may suffer impaired or inaccurate debug and profiling
visibility.
Preserving tags
---------------
Non-zero tags are not preserved when delivering signals. This means that
signal handlers in applications making use of tags cannot rely on the
tag information for user virtual addresses being maintained for fields
inside siginfo_t. One exception to this rule is for signals raised in
response to watchpoint debug exceptions, where the tag information will
be preserved.
The architecture prevents the use of a tagged PC, so the upper byte will
be set to a sign-extension of bit 55 on exception return.
This behaviour is maintained when the AArch64 Tagged Address ABI is
enabled.
Other considerations
--------------------
Special care should be taken when using tagged pointers, since it is
likely that C compilers will not hazard two virtual addresses differing
only in the upper byte.

View File

@@ -183,6 +183,11 @@ partial drain
EOF is reached and now DSP can start skipping padding delay. Also next write EOF is reached and now DSP can start skipping padding delay. Also next write
data would belong to next track data would belong to next track
- set_next_track_param
This routine is called to send to DSP codec specific data of subsequent track
in gapless before first write.
Sequence flow for gapless would be: Sequence flow for gapless would be:
- Open - Open
- Get caps / codec caps - Get caps / codec caps
@@ -194,6 +199,7 @@ Sequence flow for gapless would be:
- Indicate next track data by sending set_next_track - Indicate next track data by sending set_next_track
- Set metadata of the next track - Set metadata of the next track
- then call partial_drain to flush most of buffer in DSP - then call partial_drain to flush most of buffer in DSP
- set codec specific data of subsequent track
- Fill data of the next track - Fill data of the next track
- DSP switches to second track - DSP switches to second track

View File

@@ -8,3 +8,4 @@ HD-Audio
models models
controls controls
dp-mst dp-mst
realtek-pc-beep

View File

@@ -216,8 +216,6 @@ alc298-dell-aio
ALC298 fixups on Dell AIO machines ALC298 fixups on Dell AIO machines
alc275-dell-xps alc275-dell-xps
ALC275 fixups on Dell XPS models ALC275 fixups on Dell XPS models
alc256-dell-xps13
ALC256 fixups on Dell XPS13
lenovo-spk-noise lenovo-spk-noise
Workaround for speaker noise on Lenovo machines Workaround for speaker noise on Lenovo machines
lenovo-hotkey lenovo-hotkey

View File

@@ -0,0 +1,129 @@
===============================
Realtek PC Beep Hidden Register
===============================
This file documents the "PC Beep Hidden Register", which is present in certain
Realtek HDA codecs and controls a muxer and pair of passthrough mixers that can
route audio between pins but aren't themselves exposed as HDA widgets. As far
as I can tell, these hidden routes are designed to allow flexible PC Beep output
for codecs that don't have mixer widgets in their output paths. Why it's easier
to hide a mixer behind an undocumented vendor register than to just expose it
as a widget, I have no idea.
Register Description
====================
The register is accessed via processing coefficient 0x36 on NID 20h. Bits not
identified below have no discernible effect on my machine, a Dell XPS 13 9350::
MSB LSB
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |h|S|L| | B |R| | Known bits
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1Ah input select (B): 2 bits
When zero, expose the PC Beep line (from the internal beep generator, when
enabled with the Set Beep Generation verb on NID 01h, or else from the
external PCBEEP pin) on the 1Ah pin node. When nonzero, expose the headphone
jack (or possibly Line In on some machines) input instead. If PC Beep is
selected, the 1Ah boost control has no effect.
Amplify 1Ah loopback, left (L): 1 bit
Amplify the left channel of 1Ah before mixing it into outputs as specified
by h and S bits. Does not affect the level of 1Ah exposed to other widgets.
Amplify 1Ah loopback, right (R): 1 bit
Amplify the right channel of 1Ah before mixing it into outputs as specified
by h and S bits. Does not affect the level of 1Ah exposed to other widgets.
Loopback 1Ah to 21h [active low] (h): 1 bit
When zero, mix 1Ah (possibly with amplification, depending on L and R bits)
into 21h (headphone jack on my machine). Mixed signal respects the mute
setting on 21h.
Loopback 1Ah to 14h (S): 1 bit
When one, mix 1Ah (possibly with amplification, depending on L and R bits)
into 14h (internal speaker on my machine). Mixed signal **ignores** the mute
setting on 14h and is present whenever 14h is configured as an output.
Path diagrams
=============
1Ah input selection (DIV is the PC Beep divider set on NID 01h)::
<Beep generator> <PCBEEP pin> <Headphone jack>
| | |
+--DIV--+--!DIV--+ {1Ah boost control}
| |
+--(b == 0)--+--(b != 0)--+
|
>1Ah (Beep/Headphone Mic/Line In)<
Loopback of 1Ah to 21h/14h::
<1Ah (Beep/Headphone Mic/Line In)>
|
{amplify if L/R}
|
+-----!h-----+-----S-----+
| |
{21h mute control} |
| |
>21h (Headphone)< >14h (Internal Speaker)<
Background
==========
All Realtek HDA codecs have a vendor-defined widget with node ID 20h which
provides access to a bank of registers that control various codec functions.
Registers are read and written via the standard HDA processing coefficient
verbs (Set/Get Coefficient Index, Set/Get Processing Coefficient). The node is
named "Realtek Vendor Registers" in public datasheets' verb listings and,
apart from that, is entirely undocumented.
This particular register, exposed at coefficient 0x36 and named in commits from
Realtek, is of note: unlike most registers, which seem to control detailed
amplifier parameters not in scope of the HDA specification, it controls audio
routing which could just as easily have been defined using standard HDA mixer
and selector widgets.
Specifically, it selects between two sources for the input pin widget with Node
ID (NID) 1Ah: the widget's signal can come either from an audio jack (on my
laptop, a Dell XPS 13 9350, it's the headphone jack, but comments in Realtek
commits indicate that it might be a Line In on some machines) or from the PC
Beep line (which is itself multiplexed between the codec's internal beep
generator and external PCBEEP pin, depending on if the beep generator is
enabled via verbs on NID 01h). Additionally, it can mix (with optional
amplification) that signal onto the 21h and/or 14h output pins.
The register's reset value is 0x3717, corresponding to PC Beep on 1Ah that is
then amplified and mixed into both the headphones and the speakers. Not only
does this violate the HDA specification, which says that "[a vendor defined
beep input pin] connection may be maintained *only* while the Link reset
(**RST#**) is asserted", it means that we cannot ignore the register if we care
about the input that 1Ah would otherwise expose or if the PCBEEP trace is
poorly shielded and picks up chassis noise (both of which are the case on my
machine).
Unfortunately, there are lots of ways to get this register configuration wrong.
Linux, it seems, has gone through most of them. For one, the register resets
after S3 suspend: judging by existing code, this isn't the case for all vendor
registers, and it's led to some fixes that improve behavior on cold boot but
don't last after suspend. Other fixes have successfully switched the 1Ah input
away from PC Beep but have failed to disable both loopback paths. On my
machine, this means that the headphone input is amplified and looped back to
the headphone output, which uses the exact same pins! As you might expect, this
causes terrible headphone noise, the character of which is controlled by the
1Ah boost control. (If you've seen instructions online to fix XPS 13 headphone
noise by changing "Headphone Mic Boost" in ALSA, now you know why.)
The information here has been obtained through black-box reverse engineering of
the ALC256 codec's behavior and is not guaranteed to be correct. It likely
also applies for the ALC255, ALC257, ALC235, and ALC236, since those codecs
seem to be close relatives of the ALC256. (They all share one initialization
function.) Additionally, other codecs like the ALC225 and ALC285 also have this
register, judging by existing fixups in ``patch_realtek.c``, but specific
data (e.g. node IDs, bit positions, pin mappings) for those codecs may differ
from what I've described here.

View File

@@ -64,7 +64,6 @@ Currently, these files are in /proc/sys/vm:
- swappiness - swappiness
- user_reserve_kbytes - user_reserve_kbytes
- vfs_cache_pressure - vfs_cache_pressure
- watermark_boost_factor
- watermark_scale_factor - watermark_scale_factor
- zone_reclaim_mode - zone_reclaim_mode
@@ -873,26 +872,6 @@ ten times more freeable objects than there are.
============================================================= =============================================================
watermark_boost_factor:
This factor controls the level of reclaim when memory is being fragmented.
It defines the percentage of the high watermark of a zone that will be
reclaimed if pages of different mobility are being mixed within pageblocks.
The intent is that compaction has less work to do in the future and to
increase the success rate of future high-order allocations such as SLUB
allocations, THP and hugetlbfs pages.
To make it sensible with respect to the watermark_scale_factor parameter,
the unit is in fractions of 10,000. The default value of 15,000 means
that up to 150% of the high watermark will be reclaimed in the event of
a pageblock being mixed due to fragmentation. The level of reclaim is
determined by the number of fragmentation events that occurred in the
recent past. If this value is smaller than a pageblock then a pageblocks
worth of pages will be reclaimed (e.g. 2MB on 64-bit x86). A boost factor
of 0 will disable the feature.
=============================================================
watermark_scale_factor: watermark_scale_factor:
This factor controls the aggressiveness of kswapd. It defines the This factor controls the aggressiveness of kswapd. It defines the

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 4 VERSION = 4
PATCHLEVEL = 19 PATCHLEVEL = 19
SUBLEVEL = 114 SUBLEVEL = 123
EXTRAVERSION = EXTRAVERSION =
NAME = "People's Front" NAME = "People's Front"

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,6 @@
__cpu_online_mask __cpu_online_mask
cpus_read_lock cpus_read_lock
cpus_read_unlock cpus_read_unlock
debug_smp_processor_id
delayed_work_timer_fn delayed_work_timer_fn
destroy_workqueue destroy_workqueue
_dev_err _dev_err
@@ -124,8 +123,6 @@
platform_device_unregister platform_device_unregister
__platform_driver_register __platform_driver_register
platform_driver_unregister platform_driver_unregister
preempt_count_add
preempt_count_sub
preempt_schedule preempt_schedule
preempt_schedule_notrace preempt_schedule_notrace
prepare_to_wait_event prepare_to_wait_event
@@ -437,7 +434,6 @@
copy_page copy_page
dev_driver_string dev_driver_string
devres_add devres_add
__devres_alloc_node
devres_destroy devres_destroy
devres_free devres_free
dma_buf_get dma_buf_get
@@ -610,7 +606,6 @@
kmem_cache_free kmem_cache_free
memdup_user memdup_user
put_unused_fd put_unused_fd
remove_conflicting_framebuffers
sg_alloc_table_from_pages sg_alloc_table_from_pages
sync_file_create sync_file_create
sync_file_get_fence sync_file_get_fence

View File

@@ -16,7 +16,6 @@
__arch_copy_from_user __arch_copy_from_user
__arch_copy_to_user __arch_copy_to_user
arch_setup_dma_ops arch_setup_dma_ops
arch_timer_read_ool_enabled
arm64_const_caps_ready arm64_const_caps_ready
atomic_notifier_call_chain atomic_notifier_call_chain
atomic_notifier_chain_register atomic_notifier_chain_register
@@ -48,6 +47,7 @@
cdev_add cdev_add
cdev_del cdev_del
cdev_init cdev_init
__cfi_slowpath
__check_object_size __check_object_size
__class_create __class_create
class_destroy class_destroy
@@ -108,22 +108,6 @@
crypto_destroy_tfm crypto_destroy_tfm
crypto_shash_setkey crypto_shash_setkey
_ctype _ctype
debugfs_attr_read
debugfs_attr_write
debugfs_create_atomic_t
debugfs_create_bool
debugfs_create_dir
debugfs_create_file
debugfs_create_file_unsafe
debugfs_create_u16
debugfs_create_u32
debugfs_create_u64
debugfs_create_u8
debugfs_create_x32
debugfs_create_x8
debugfs_print_regs32
debugfs_remove
debugfs_remove_recursive
delayed_work_timer_fn delayed_work_timer_fn
del_timer del_timer
del_timer_sync del_timer_sync
@@ -246,6 +230,7 @@
dma_fence_signal_locked dma_fence_signal_locked
__dma_flush_area __dma_flush_area
__dma_inv_area __dma_inv_area
dmam_alloc_coherent
dma_release_from_dev_coherent dma_release_from_dev_coherent
dma_request_slave_channel dma_request_slave_channel
do_exit do_exit
@@ -258,8 +243,6 @@
drm_panel_notifier_unregister drm_panel_notifier_unregister
dst_release dst_release
dummy_dma_ops dummy_dma_ops
__dynamic_dev_dbg
__dynamic_pr_debug
enable_irq enable_irq
ether_setup ether_setup
eth_type_trans eth_type_trans
@@ -291,23 +274,9 @@
freezing_slow_path freezing_slow_path
fwnode_property_read_u32_array fwnode_property_read_u32_array
gcd gcd
generic_file_llseek
generic_handle_irq generic_handle_irq
geni_abort_m_cmd genl_register_family
geni_cancel_m_cmd genl_unregister_family
geni_se_dump_dbg_regs
geni_se_init
geni_se_iommu_map_buf
geni_se_iommu_unmap_buf
geni_se_resources_init
geni_se_rx_dma_prep
geni_se_rx_dma_unprep
geni_se_select_mode
geni_setup_m_cmd
geni_se_tx_dma_prep
geni_se_tx_dma_unprep
geni_write_reg
genlmsg_put
gen_pool_add_virt gen_pool_add_virt
gen_pool_alloc gen_pool_alloc
gen_pool_create gen_pool_create
@@ -318,9 +287,7 @@
__get_free_pages __get_free_pages
get_pid_task get_pid_task
get_random_bytes get_random_bytes
get_se_proto
__get_task_comm __get_task_comm
get_tx_fifo_depth
get_unused_fd_flags get_unused_fd_flags
gpiochip_add_data_with_key gpiochip_add_data_with_key
gpiochip_add_pin_range gpiochip_add_pin_range
@@ -345,7 +312,6 @@
handle_edge_irq handle_edge_irq
handle_level_irq handle_level_irq
handle_nested_irq handle_nested_irq
hex2bin
hex_dump_to_buffer hex_dump_to_buffer
hrtimer_active hrtimer_active
hrtimer_cancel hrtimer_cancel
@@ -470,12 +436,9 @@
kstrtoint kstrtoint
kstrtoll kstrtoll
kstrtos8 kstrtos8
kstrtos8_from_user
kstrtou16 kstrtou16
kstrtou8 kstrtou8
kstrtou8_from_user
kstrtouint kstrtouint
kstrtouint_from_user
kstrtoull kstrtoull
kthread_cancel_work_sync kthread_cancel_work_sync
kthread_create_on_node kthread_create_on_node
@@ -486,7 +449,6 @@
kthread_stop kthread_stop
kthread_worker_fn kthread_worker_fn
ktime_get ktime_get
ktime_get_coarse_real_ts64
ktime_get_real_ts64 ktime_get_real_ts64
ktime_get_with_offset ktime_get_with_offset
kvfree kvfree
@@ -542,7 +504,6 @@
module_put module_put
__msecs_to_jiffies __msecs_to_jiffies
msleep msleep
msleep_interruptible
__mutex_init __mutex_init
mutex_lock mutex_lock
mutex_lock_interruptible mutex_lock_interruptible
@@ -572,9 +533,9 @@
nla_put nla_put
__nlmsg_put __nlmsg_put
no_llseek no_llseek
nonseekable_open
nr_cpu_ids nr_cpu_ids
ns_capable ns_capable
ns_to_timespec64
ns_to_timespec ns_to_timespec
nvmem_cell_get nvmem_cell_get
nvmem_cell_put nvmem_cell_put
@@ -749,6 +710,7 @@
_raw_spin_lock_bh _raw_spin_lock_bh
_raw_spin_lock_irq _raw_spin_lock_irq
_raw_spin_lock_irqsave _raw_spin_lock_irqsave
_raw_spin_trylock
_raw_spin_trylock_bh _raw_spin_trylock_bh
_raw_spin_unlock _raw_spin_unlock
_raw_spin_unlock_bh _raw_spin_unlock_bh
@@ -790,6 +752,7 @@
__regmap_init __regmap_init
regmap_multi_reg_write regmap_multi_reg_write
regmap_raw_read regmap_raw_read
regmap_raw_write
regmap_read regmap_read
regmap_update_bits_base regmap_update_bits_base
regmap_write regmap_write
@@ -798,6 +761,7 @@
regulator_disable regulator_disable
regulator_enable regulator_enable
regulator_get regulator_get
regulator_get_voltage
regulator_is_enabled regulator_is_enabled
regulator_put regulator_put
regulator_set_load regulator_set_load
@@ -817,8 +781,6 @@
rtc_time64_to_tm rtc_time64_to_tm
rtc_tm_to_time64 rtc_tm_to_time64
rtc_valid_tm rtc_valid_tm
rt_mutex_lock
rt_mutex_unlock
rtnl_is_locked rtnl_is_locked
rtnl_unlock rtnl_unlock
saved_command_line saved_command_line
@@ -827,18 +789,12 @@
schedule schedule
schedule_timeout schedule_timeout
scnprintf scnprintf
se_config_packing
se_geni_clks_off
se_geni_resources_off
se_geni_resources_on
seq_lseek seq_lseek
seq_open seq_open
seq_printf seq_printf
seq_putc
seq_puts seq_puts
seq_read seq_read
seq_release seq_release
seq_write
set_normalized_timespec set_normalized_timespec
set_user_nice set_user_nice
sg_alloc_table sg_alloc_table
@@ -848,15 +804,7 @@
sg_next sg_next
__sg_page_iter_next __sg_page_iter_next
__sg_page_iter_start __sg_page_iter_start
simple_attr_open
simple_attr_read
simple_attr_release
simple_attr_write
simple_open
simple_read_from_buffer simple_read_from_buffer
simple_write_to_buffer
single_open
single_release
sk_alloc sk_alloc
skb_add_rx_frag skb_add_rx_frag
skb_clone skb_clone
@@ -969,6 +917,7 @@
sysfs_remove_group sysfs_remove_group
sysfs_remove_groups sysfs_remove_groups
sysfs_streq sysfs_streq
system_freezable_wq
system_freezing_cnt system_freezing_cnt
system_highpri_wq system_highpri_wq
system_long_wq system_long_wq
@@ -998,16 +947,22 @@
trace_event_reg trace_event_reg
trace_handle_return trace_handle_return
trace_print_flags_seq trace_print_flags_seq
trace_print_hex_seq
trace_print_symbols_seq
trace_raw_output_prep trace_raw_output_prep
trace_seq_printf trace_seq_printf
try_module_get try_module_get
tty_flip_buffer_push
typec_register_partner typec_register_partner
typec_register_port typec_register_port
typec_set_data_role typec_set_data_role
typec_set_pwr_role typec_set_pwr_role
typec_unregister_partner typec_unregister_partner
uart_add_one_port
uart_register_driver
uart_remove_one_port
uart_unregister_driver
__udelay __udelay
uncached_logk
__unregister_chrdev __unregister_chrdev
unregister_chrdev_region unregister_chrdev_region
unregister_inet6addr_notifier unregister_inet6addr_notifier
@@ -1035,7 +990,6 @@
usb_free_all_descriptors usb_free_all_descriptors
usb_function_register usb_function_register
usb_function_unregister usb_function_unregister
usb_func_wakeup
usb_gadget_wakeup usb_gadget_wakeup
usb_get_dr_mode usb_get_dr_mode
usb_interface_id usb_interface_id
@@ -1125,7 +1079,6 @@
iommu_group_remove_device iommu_group_remove_device
iommu_group_set_iommudata iommu_group_set_iommudata
iommu_put_dma_cookie iommu_put_dma_cookie
kstrtoull_from_user
of_dma_is_coherent of_dma_is_coherent
of_n_addr_cells of_n_addr_cells
of_n_size_cells of_n_size_cells
@@ -1180,9 +1133,6 @@
# required by cam_flash.ko # required by cam_flash.ko
thermal_zone_get_cdev_by_name thermal_zone_get_cdev_by_name
# required by cam_ife_csid.ko
ns_to_timespec64
# required by cam_ife_hw_mgr.ko # required by cam_ife_hw_mgr.ko
__ll_sc_atomic_fetch_add __ll_sc_atomic_fetch_add
@@ -1199,6 +1149,10 @@
led_trigger_register_simple led_trigger_register_simple
led_trigger_unregister_simple led_trigger_unregister_simple
# required by cam_smmu_api.ko
iommu_dma_enable_best_fit_algo
iommu_dma_reserve_iova
# required by cam_utils.ko # required by cam_utils.ko
gpio_free_array gpio_free_array
of_clk_get_from_provider of_clk_get_from_provider
@@ -1206,13 +1160,13 @@
__request_region __request_region
# required by citadel-spi.ko # required by citadel-spi.ko
nonseekable_open
spi_bus_lock spi_bus_lock
spi_bus_unlock spi_bus_unlock
spi_sync_locked spi_sync_locked
# required by clk-qcom.ko # required by clk-qcom.ko
clk_aggregate_rate clk_aggregate_rate
clk_debug_print_hw
__clk_determine_rate __clk_determine_rate
clk_fixed_rate_ops clk_fixed_rate_ops
clk_hw_get_flags clk_hw_get_flags
@@ -1276,18 +1230,6 @@
send_sig_info send_sig_info
time64_to_tm time64_to_tm
# required by dm-default-key.ko
bio_crypt_alloc_ctx
blk_crypto_evict_key
blk_crypto_init_key
dm_get_device
dm_put_device
dm_read_arg_group
dm_register_target
dm_shift_arg
dm_table_get_mode
dm_unregister_target
# required by dwc3-haps.ko # required by dwc3-haps.ko
pcim_enable_device pcim_enable_device
__pci_register_driver __pci_register_driver
@@ -1323,7 +1265,6 @@
pinctrl_pm_select_default_state pinctrl_pm_select_default_state
pinctrl_pm_select_sleep_state pinctrl_pm_select_sleep_state
strcat strcat
system_freezable_wq
usb_add_gadget_udc usb_add_gadget_udc
usb_del_gadget_udc usb_del_gadget_udc
usb_ep_set_maxpacket_limit usb_ep_set_maxpacket_limit
@@ -1368,12 +1309,7 @@
xt_unregister_target xt_unregister_target
# required by eud.ko # required by eud.ko
tty_flip_buffer_push
uart_add_one_port
uart_insert_char uart_insert_char
uart_register_driver
uart_remove_one_port
uart_unregister_driver
# required by event_timer.ko # required by event_timer.ko
cpumask_next_and cpumask_next_and
@@ -1385,7 +1321,9 @@
of_find_i2c_device_by_node of_find_i2c_device_by_node
# required by ftm5.ko # required by ftm5.ko
ktime_get_coarse_real_ts64
proc_create proc_create
seq_write
# required by google-battery.ko # required by google-battery.ko
simple_strtoull simple_strtoull
@@ -1396,12 +1334,6 @@
# required by governor_bw_hwmon.ko # required by governor_bw_hwmon.ko
argv_free argv_free
argv_split argv_split
__tracepoint_bw_hwmon_meas
__tracepoint_bw_hwmon_update
# required by governor_memlat.ko
__tracepoint_memlat_dev_meas
__tracepoint_memlat_dev_update
# required by gpi.ko # required by gpi.ko
dma_async_device_register dma_async_device_register
@@ -1437,11 +1369,13 @@
i2c_put_dma_safe_msg_buf i2c_put_dma_safe_msg_buf
# required by ion-alloc.ko # required by ion-alloc.ko
dentry_path
dma_buf_export dma_buf_export
dma_get_device_base dma_get_device_base
dma_get_size dma_get_size
__ll_sc_atomic64_sub_return
mm_event_count
__next_zones_zonelist __next_zones_zonelist
ptr_to_hashval
sched_setattr sched_setattr
split_page split_page
vm_map_ram vm_map_ram
@@ -1452,6 +1386,7 @@
add_wait_queue add_wait_queue
alloc_etherdev_mqs alloc_etherdev_mqs
eth_mac_addr eth_mac_addr
kstrtos8_from_user
pci_clear_master pci_clear_master
pci_disable_device pci_disable_device
pci_enable_device pci_enable_device
@@ -1471,7 +1406,7 @@
# required by lpm-stats.ko # required by lpm-stats.ko
kobject_get kobject_get
module_ktype module_ktype
on_each_cpu simple_write_to_buffer
# required by machine_dlkm.ko # required by machine_dlkm.ko
devm_snd_soc_register_card devm_snd_soc_register_card
@@ -1483,6 +1418,7 @@
snd_soc_dai_set_pll snd_soc_dai_set_pll
snd_soc_dai_set_sysclk snd_soc_dai_set_sysclk
snd_soc_dai_set_tdm_slot snd_soc_dai_set_tdm_slot
snd_soc_get_pcm_runtime
snd_soc_of_get_dai_link_codecs snd_soc_of_get_dai_link_codecs
snd_soc_of_parse_audio_routing snd_soc_of_parse_audio_routing
snd_soc_of_parse_card_name snd_soc_of_parse_card_name
@@ -1538,7 +1474,6 @@
bpf_trace_run10 bpf_trace_run10
_cleanup_srcu_struct _cleanup_srcu_struct
__clk_get_name __clk_get_name
debugfs_lookup
devfreq_cooling_unregister devfreq_cooling_unregister
device_show_int device_show_int
device_store_int device_store_int
@@ -1566,7 +1501,7 @@
__ll_sc_atomic_or __ll_sc_atomic_or
mmap_min_addr mmap_min_addr
mmput mmput
noop_llseek mm_trace_rss_stat
of_devfreq_cooling_register of_devfreq_cooling_register
plist_del plist_del
rb_last rb_last
@@ -1577,21 +1512,18 @@
sysfs_create_bin_file sysfs_create_bin_file
sysfs_remove_bin_file sysfs_remove_bin_file
sysfs_remove_files sysfs_remove_files
trace_print_symbols_seq
unmapped_area_topdown unmapped_area_topdown
unregister_shrinker unregister_shrinker
vm_insert_page vm_insert_page
vm_insert_pfn vm_insert_pfn
# required by msm_bus_rpmh.ko # required by msm_bus_rpmh.ko
__msm_bus_scale_client_update_request_cb
__msm_bus_scale_register_cb
__msm_bus_scale_register_client_cb
__msm_bus_scale_update_bw_cb
of_clk_get_by_name of_clk_get_by_name
raw_notifier_call_chain raw_notifier_call_chain
raw_notifier_chain_register raw_notifier_chain_register
raw_notifier_chain_unregister raw_notifier_chain_unregister
rt_mutex_lock
rt_mutex_unlock
# required by msm_drm.ko # required by msm_drm.ko
adjust_managed_page_count adjust_managed_page_count
@@ -1599,7 +1531,6 @@
bpf_trace_run12 bpf_trace_run12
__clk_get_hw __clk_get_hw
clk_get_parent clk_get_parent
debugfs_create_size_t
device_create_with_groups device_create_with_groups
devm_clk_bulk_get devm_clk_bulk_get
devm_of_pwm_get devm_of_pwm_get
@@ -1863,7 +1794,6 @@
shmem_truncate_range shmem_truncate_range
strreplace strreplace
timespec64_to_jiffies timespec64_to_jiffies
tracing_off
unmap_kernel_range unmap_kernel_range
unmap_mapping_range unmap_mapping_range
vm_get_page_prot vm_get_page_prot
@@ -1873,15 +1803,25 @@
# required by msm_ext_display.ko # required by msm_ext_display.ko
devm_extcon_dev_unregister devm_extcon_dev_unregister
# required by msm_gsi.ko # required by msm_geni_serial.ko
kstrtoint_from_user console_stop
console_suspend_enabled
# required by msm_icnss.ko do_SAK
dmam_alloc_coherent handle_sysrq
oops_in_progress
__tty_insert_flip_char
tty_insert_flip_string_fixed_flag
uart_console_device
uart_console_write
uart_get_baud_rate
uart_parse_options
uart_resume_port
uart_set_options
uart_suspend_port
uart_update_timeout
uart_write_wakeup
# required by msm_ipc_logging.ko # required by msm_ipc_logging.ko
debugfs_file_get
debugfs_file_put
_raw_read_lock_irq _raw_read_lock_irq
_raw_read_unlock_irq _raw_read_unlock_irq
_raw_write_lock_irqsave _raw_write_lock_irqsave
@@ -1893,14 +1833,13 @@
__tracepoint_clock_set_rate __tracepoint_clock_set_rate
# required by msm_minidump.ko # required by msm_minidump.ko
linux_banner linux_banner_ptr
# required by msm_npu.ko # required by msm_npu.ko
kmem_cache_create_usercopy kmem_cache_create_usercopy
# required by msm_pm.ko # required by msm_pm.ko
arm_cpuidle_suspend arm_cpuidle_suspend
clock_debug_print_enabled
cpu_do_idle cpu_do_idle
cpuidle_dev cpuidle_dev
cpuidle_register_device cpuidle_register_device
@@ -1913,10 +1852,8 @@
param_get_bool param_get_bool
param_get_uint param_get_uint
pending_ipi pending_ipi
pm_gpio_debug_mask
pm_qos_request_for_cpu pm_qos_request_for_cpu
pm_qos_request_for_cpumask pm_qos_request_for_cpumask
regulator_debug_print_enabled
s2idle_set_ops s2idle_set_ops
set_update_ipi_history_callback set_update_ipi_history_callback
suspend_set_ops suspend_set_ops
@@ -1934,10 +1871,6 @@
hwrng_register hwrng_register
hwrng_unregister hwrng_unregister
# required by msm_rtb.ko
arch_timer_read_counter
set_uncached_logk_func
# required by msm_scm.ko # required by msm_scm.ko
__arm_smccc_smc __arm_smccc_smc
@@ -1969,14 +1902,10 @@
irq_chip_set_wake_parent irq_chip_set_wake_parent
irq_create_fwspec_mapping irq_create_fwspec_mapping
irq_domain_free_irqs_top irq_domain_free_irqs_top
msm_gpio_dump_builtin_cb
of_irq_domain_map of_irq_domain_map
register_restart_handler register_restart_handler
unregister_restart_handler unregister_restart_handler
# required by pinctrl-spmi-gpio.ko
pmic_gpio_dump_builtin_cb
# required by platform_dlkm.ko # required by platform_dlkm.ko
__ll_sc___cmpxchg_case_mb_8 __ll_sc___cmpxchg_case_mb_8
of_property_read_variable_u16_array of_property_read_variable_u16_array
@@ -2115,7 +2044,6 @@
# required by qpnp-smb5-charger.ko # required by qpnp-smb5-charger.ko
iio_channel_release iio_channel_release
regulator_get_voltage
# required by qpnp_pdphy.ko # required by qpnp_pdphy.ko
device_get_named_child_node device_get_named_child_node
@@ -2179,9 +2107,7 @@
csum_tcpudp_nofold csum_tcpudp_nofold
__dev_get_by_index __dev_get_by_index
dev_queue_xmit dev_queue_xmit
__dynamic_netdev_dbg genlmsg_put
genl_register_family
genl_unregister_family
get_current_napi_context get_current_napi_context
gro_cells_destroy gro_cells_destroy
gro_cells_init gro_cells_init
@@ -2201,11 +2127,11 @@
skb_append_pagefrags skb_append_pagefrags
skb_checksum skb_checksum
synchronize_rcu synchronize_rcu
trace_print_hex_seq
unregister_netdevice_many unregister_netdevice_many
# required by rndis.ko # required by rndis.ko
dev_get_stats dev_get_stats
print_hex_dump_bytes
# required by roles.ko # required by roles.ko
class_find_device class_find_device
@@ -2424,7 +2350,6 @@
# required by snd-soc-wm-adsp.ko # required by snd-soc-wm-adsp.ko
regmap_async_complete regmap_async_complete
regmap_raw_write
regmap_raw_write_async regmap_raw_write_async
snd_compr_stop_error snd_compr_stop_error
snd_soc_component_disable_pin snd_soc_component_disable_pin
@@ -2432,13 +2357,6 @@
# required by spi-geni-qcom.ko # required by spi-geni-qcom.ko
dma_release_channel dma_release_channel
geni_read_reg
geni_se_clk_freq_match
geni_se_qupv3_hw_version
get_rx_fifo_depth
get_tx_fifo_width
se_geni_clks_on
se_get_packing_config
__spi_alloc_controller __spi_alloc_controller
spi_register_controller spi_register_controller
spi_unregister_controller spi_unregister_controller
@@ -2450,7 +2368,6 @@
spmi_controller_remove spmi_controller_remove
# required by st21nfc.ko # required by st21nfc.ko
desc_to_gpio
device_set_wakeup_capable device_set_wakeup_capable
# required by subsystem-restart.ko # required by subsystem-restart.ko
@@ -2480,7 +2397,6 @@
typec_set_vconn_role typec_set_vconn_role
typec_unregister_altmode typec_unregister_altmode
typec_unregister_port typec_unregister_port
usb_debug_root
# required by tps-regulator.ko # required by tps-regulator.ko
gpiod_export gpiod_export
@@ -2488,21 +2404,44 @@
regulator_list_voltage_table regulator_list_voltage_table
regulator_map_voltage_ascend regulator_map_voltage_ascend
# required by ufs_qcom.ko # required by ufshcd-core.ko
ufsdbg_pr_buf_to_std async_schedule
ufshcd_dme_get_attr bio_crypt_should_process
ufshcd_dme_set_attr blk_queue_max_segment_size
ufshcd_get_local_unipro_ver blk_queue_rq_timeout
ufshcd_hold blk_queue_update_dma_pad
ufshcd_pltfrm_init dev_pm_opp_remove
ufshcd_pltfrm_resume down_read_trylock
ufshcd_pltfrm_runtime_idle down_write_trylock
ufshcd_pltfrm_runtime_resume keyslot_manager_create
ufshcd_pltfrm_runtime_suspend keyslot_manager_destroy
ufshcd_pltfrm_shutdown keyslot_manager_private
ufshcd_pltfrm_suspend keyslot_manager_reprogram_all_keys
ufshcd_release keyslot_manager_set_max_dun_bytes
ufshcd_remove __ll_sc_atomic64_fetch_andnot_release
__ll_sc_atomic64_fetch_or_acquire
__scsi_add_device
scsi_add_host_with_dma
scsi_block_requests
scsi_change_queue_depth
scsi_device_get
scsi_device_put
scsi_dma_map
scsi_dma_unmap
__scsi_execute
scsi_host_alloc
scsi_host_put
scsi_print_command
scsi_print_sense_hdr
scsi_remove_device
scsi_remove_host
scsi_report_bus_reset
scsi_scan_host
scsi_set_cmd_timeout_override
scsi_unblock_requests
sdev_prefix_printk
trace_output_call
utf16s_to_utf8s
# required by wlan.ko # required by wlan.ko
bitmap_print_to_pagebuf bitmap_print_to_pagebuf
@@ -2538,7 +2477,6 @@
cfg80211_unlink_bss cfg80211_unlink_bss
cfg80211_update_owe_info_event cfg80211_update_owe_info_event
cfg80211_vendor_cmd_reply cfg80211_vendor_cmd_reply
cld80211_get_genl_family
complete_and_exit complete_and_exit
cpufreq_quick_get_max cpufreq_quick_get_max
__cpuhp_remove_state __cpuhp_remove_state
@@ -2550,10 +2488,9 @@
crypto_alloc_skcipher crypto_alloc_skcipher
crypto_shash_final crypto_shash_final
crypto_shash_update crypto_shash_update
default_llseek
deregister_cld_cmd_cb
dev_alloc_name dev_alloc_name
dump_stack dump_stack
hex2bin
hex_to_bin hex_to_bin
ieee80211_channel_to_frequency ieee80211_channel_to_frequency
ieee80211_frequency_to_channel ieee80211_frequency_to_channel
@@ -2561,6 +2498,7 @@
ieee80211_hdrlen ieee80211_hdrlen
irq_set_affinity_hint irq_set_affinity_hint
mac_pton mac_pton
msleep_interruptible
netif_tx_stop_all_queues netif_tx_stop_all_queues
netlink_broadcast netlink_broadcast
__netlink_kernel_create __netlink_kernel_create
@@ -2579,17 +2517,16 @@
pm_system_wakeup pm_system_wakeup
proc_create_data proc_create_data
proc_mkdir proc_mkdir
_raw_spin_trylock
register_cld_cmd_cb
register_netevent_notifier register_netevent_notifier
register_sysctl_table register_sysctl_table
regulatory_set_wiphy_regd regulatory_set_wiphy_regd
rtnl_lock rtnl_lock
save_stack_trace_tsk save_stack_trace_tsk
schedule_timeout_interruptible schedule_timeout_interruptible
seq_hex_dump
seq_vprintf seq_vprintf
set_cpus_allowed_ptr set_cpus_allowed_ptr
single_open
single_release
skip_spaces skip_spaces
strchrnul strchrnul
unregister_netevent_notifier unregister_netevent_notifier
@@ -2635,10 +2572,10 @@
# required by usb_f_gsi.ko # required by usb_f_gsi.ko
dev_get_by_name dev_get_by_name
kstrtou16_from_user
usb_composite_setup_continue usb_composite_setup_continue
usb_ep_autoconfig_by_name usb_ep_autoconfig_by_name
usb_func_ep_queue usb_func_ep_queue
usb_func_wakeup
usb_gsi_ep_op usb_gsi_ep_op
# required by usb_f_mtp.ko # required by usb_f_mtp.ko

View File

@@ -1,4 +1,221 @@
[abi_whitelist] [abi_whitelist]
# commonly used symbols # commonly used symbols
__cfi_slowpath
__const_udelay
_dev_err
devm_ioremap_resource
devm_kmalloc
devm_request_threaded_irq
_dev_warn
dummy_dma_ops
find_next_bit
find_next_zero_bit
kfree
__kmalloc
kmalloc_caches
kmem_cache_alloc_trace
ktime_get
__list_add_valid
__ll_sc_atomic64_andnot
__ll_sc_atomic_add_return
module_layout module_layout
__mutex_init
mutex_lock
mutex_unlock
of_find_property
of_property_read_variable_u32_array
platform_get_irq
platform_get_resource
printk
__put_task_struct __put_task_struct
___ratelimit
_raw_spin_lock_irqsave
_raw_spin_unlock_irqrestore
snprintf
__stack_chk_fail
__stack_chk_guard
strcmp
__udelay
# required by arm-smmu.ko
alloc_io_pgtable_ops
amba_bustype
bus_set_iommu
devm_free_irq
_dev_notice
driver_find_device
driver_for_each_device
free_io_pgtable_ops
generic_device_group
iommu_alloc_resv_region
iommu_device_link
iommu_device_register
iommu_device_sysfs_add
iommu_device_unlink
iommu_dma_get_resv_regions
iommu_fwspec_add_ids
iommu_fwspec_free
iommu_fwspec_init
iommu_get_dma_cookie
iommu_group_get_for_dev
iommu_group_put
iommu_group_ref_get
iommu_group_remove_device
iommu_present
iommu_put_dma_cookie
__ll_sc_atomic64_fetch_or
of_device_get_match_data
of_dma_is_coherent
of_phandle_iterator_args
of_phandle_iterator_init
of_phandle_iterator_next
param_ops_bool
param_ops_int
pci_bus_type
pci_device_group
pci_for_each_dma_alias
pci_request_acs
platform_bus_type
__platform_driver_register
platform_driver_unregister
put_device
# required by ufshcd-core.ko
__alloc_workqueue_key
async_schedule
bio_crypt_should_process
blk_queue_max_segment_size
blk_queue_update_dma_pad
bpf_trace_run2
bpf_trace_run4
bpf_trace_run5
bpf_trace_run8
cancel_delayed_work
cancel_delayed_work_sync
cancel_work_sync
clk_disable
clk_enable
clk_prepare
clk_set_rate
clk_unprepare
complete
cpu_number
__cpu_online_mask
delayed_work_timer_fn
destroy_workqueue
dev_driver_string
devfreq_add_device
devfreq_remove_device
devfreq_resume_device
devfreq_suspend_device
device_create_file
device_remove_file
devm_clk_get
devm_kfree
devm_regulator_get
dev_pm_opp_add
dev_pm_opp_remove
dmam_alloc_coherent
down_read
down_read_trylock
down_write
event_triggers_call
find_last_bit
finish_wait
flush_work
free_irq
__init_rwsem
init_timer_key
init_wait_entry
__init_waitqueue_head
jiffies
jiffies_to_usecs
keyslot_manager_create
keyslot_manager_destroy
keyslot_manager_private
keyslot_manager_reprogram_all_keys
keyslot_manager_set_max_dun_bytes
kstrtouint
kstrtoull
__ll_sc_atomic64_fetch_andnot_release
__ll_sc_atomic64_fetch_or_acquire
__ll_sc_atomic_sub_return
memcpy
memset
memzero_explicit
__msecs_to_jiffies
msleep
perf_trace_buf_alloc
perf_trace_run_bpf_submit
__pm_runtime_idle
__pm_runtime_resume
preempt_schedule_notrace
prepare_to_wait_event
print_hex_dump
queue_delayed_work_on
queue_work_on
_raw_spin_lock
_raw_spin_unlock
regulator_count_voltages
regulator_disable
regulator_enable
regulator_set_load
regulator_set_voltage
request_threaded_irq
schedule
schedule_timeout
__scsi_add_device
scsi_add_host_with_dma
scsi_block_requests
scsi_change_queue_depth
scsi_device_get
scsi_device_put
scsi_dma_map
scsi_dma_unmap
__scsi_execute
scsi_host_alloc
scsi_host_put
scsi_print_command
scsi_print_sense_hdr
scsi_remove_device
scsi_remove_host
scsi_report_bus_reset
scsi_scan_host
scsi_unblock_requests
sdev_prefix_printk
sg_next
sprintf
strcpy
strlcpy
strlen
strncmp
sysfs_create_groups
sysfs_remove_groups
system_wq
trace_define_field
trace_event_buffer_commit
trace_event_buffer_reserve
trace_event_ignore_this_pid
trace_event_raw_init
trace_event_reg
trace_handle_return
trace_print_hex_seq
trace_print_symbols_seq
trace_raw_output_prep
trace_seq_printf
up_read
up_write
usleep_range
utf16s_to_utf8s
wait_for_completion_timeout
__wake_up
__warn_printk
# required by ufshcd-pltfrm.ko
_dev_info
kstrdup
of_get_property
of_parse_phandle
of_property_read_string_helper
pm_runtime_enable
__pm_runtime_set_status

View File

@@ -476,6 +476,7 @@
"dsi0_ddr2", "dsi0_ddr2",
"dsi0_ddr"; "dsi0_ddr";
status = "disabled";
}; };
thermal: thermal@7e212000 { thermal: thermal@7e212000 {

View File

@@ -1013,9 +1013,8 @@
compatible = "fsl,imx6q-fec"; compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>; reg = <0x02188000 0x4000>;
interrupt-names = "int0", "pps"; interrupt-names = "int0", "pps";
interrupts-extended = interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
<&intc 0 118 IRQ_TYPE_LEVEL_HIGH>, <0 119 IRQ_TYPE_LEVEL_HIGH>;
<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_ENET>, clocks = <&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET_REF>; <&clks IMX6QDL_CLK_ENET_REF>;

View File

@@ -77,7 +77,6 @@
}; };
&fec { &fec {
/delete-property/interrupts-extended;
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
<0 119 IRQ_TYPE_LEVEL_HIGH>; <0 119 IRQ_TYPE_LEVEL_HIGH>;
}; };

View File

@@ -318,8 +318,8 @@
}; };
&reg_dldo3 { &reg_dldo3 {
regulator-min-microvolt = <2800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2800000>; regulator-max-microvolt = <1800000>;
regulator-name = "vdd-csi"; regulator-name = "vdd-csi";
}; };

View File

@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_CLOCKSOURCE_H #ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H
struct arch_clocksource_data { #include <asm/vdso/clocksource.h>
bool vdso_direct; /* Usable for direct VDSO access? */
};
#endif #endif /* _ASM_CLOCKSOURCE_H */

View File

@@ -50,25 +50,7 @@
#ifdef CONFIG_CPU_CP15 #ifdef CONFIG_CPU_CP15
#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \ #include <asm/vdso/cp15.h>
"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
#define __ACCESS_CP15_64(Op1, CRm) \
"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
#define __read_sysreg(r, w, c, t) ({ \
t __val; \
asm volatile(r " " c : "=r" (__val)); \
__val; \
})
#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
#define CNTVCT __ACCESS_CP15_64(1, c14)
extern unsigned long cr_alignment; /* defined in entry-armv.S */ extern unsigned long cr_alignment; /* defined in entry-armv.S */

View File

@@ -23,6 +23,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/unified.h> #include <asm/unified.h>
#include <asm/vdso/processor.h>
#ifdef __KERNEL__ #ifdef __KERNEL__
#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ #define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
@@ -94,16 +95,6 @@ extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p); unsigned long get_wchan(struct task_struct *p);
#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
#define cpu_relax() \
do { \
smp_mb(); \
__asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
} while (0)
#else
#define cpu_relax() barrier()
#endif
#define task_pt_regs(p) \ #define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)

View File

@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSOCLOCKSOURCE_H
#define __ASM_VDSOCLOCKSOURCE_H
struct arch_clocksource_data {
bool vdso_direct; /* Usable for direct VDSO access? */
};
#endif /* __ASM_VDSOCLOCKSOURCE_H */

View File

@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 ARM Ltd.
*/
#ifndef __ASM_VDSO_CP15_H
#define __ASM_VDSO_CP15_H
#ifndef __ASSEMBLY__
#ifdef CONFIG_CPU_CP15
#include <linux/stringify.h>
#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
#define __ACCESS_CP15_64(Op1, CRm) \
"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
#define __read_sysreg(r, w, c, t) ({ \
t __val; \
asm volatile(r " " c : "=r" (__val)); \
__val; \
})
#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
#define CNTVCT __ACCESS_CP15_64(1, c14)
#endif /* CONFIG_CPU_CP15 */
#endif /* __ASSEMBLY__ */
#endif /* __ASM_VDSO_CP15_H */

View File

@@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 ARM Limited
*/
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifndef __ASSEMBLY__
#include <asm/errno.h>
#include <asm/unistd.h>
#include <asm/vdso/cp15.h>
#include <uapi/linux/time.h>
#define VDSO_HAS_CLOCK_GETRES 1
extern struct vdso_data *__get_datapage(void);
static __always_inline int gettimeofday_fallback(
struct __kernel_old_timeval *_tv,
struct timezone *_tz)
{
register struct timezone *tz asm("r1") = _tz;
register struct __kernel_old_timeval *tv asm("r0") = _tv;
register long ret asm ("r0");
register long nr asm("r7") = __NR_gettimeofday;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (tv), "r" (tz), "r" (nr)
: "memory");
return ret;
}
static __always_inline long clock_gettime_fallback(
clockid_t _clkid,
struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_clock_gettime64;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline long clock_gettime32_fallback(
clockid_t _clkid,
struct old_timespec32 *_ts)
{
register struct old_timespec32 *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_clock_gettime;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline int clock_getres_fallback(
clockid_t _clkid,
struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_clock_getres_time64;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline int clock_getres32_fallback(
clockid_t _clkid,
struct old_timespec32 *_ts)
{
register struct old_timespec32 *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_clock_getres;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static inline bool arm_vdso_hres_capable(void)
{
return IS_ENABLED(CONFIG_ARM_ARCH_TIMER);
}
#define __arch_vdso_hres_capable arm_vdso_hres_capable
static __always_inline u64 __arch_get_hw_counter(int clock_mode)
{
#ifdef CONFIG_ARM_ARCH_TIMER
u64 cycle_now;
/*
* Core checks for mode already, so this raced against a concurrent
* update. Return something. Core will do another round and then
* see the mode change and fallback to the syscall.
*/
if (clock_mode == VDSO_CLOCKMODE_NONE)
return 0;
isb();
cycle_now = read_sysreg(CNTVCT);
return cycle_now;
#else
/* Make GCC happy. This is compiled out anyway */
return 0;
#endif
}
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
return __get_datapage();
}
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */

View File

@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 ARM Ltd.
*/
#ifndef __ASM_VDSO_PROCESSOR_H
#define __ASM_VDSO_PROCESSOR_H
#ifndef __ASSEMBLY__
#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
#define cpu_relax() \
do { \
smp_mb(); \
__asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
} while (0)
#else
#define cpu_relax() barrier()
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ASM_VDSO_PROCESSOR_H */

View File

@@ -116,6 +116,14 @@ EXPORT_SYMBOL(elf_hwcap2);
char* (*arch_read_hardware_id)(void); char* (*arch_read_hardware_id)(void);
EXPORT_SYMBOL(arch_read_hardware_id); EXPORT_SYMBOL(arch_read_hardware_id);
/* Vendor stub */
unsigned int boot_reason;
EXPORT_SYMBOL_GPL(boot_reason);
/* Vendor stub */
unsigned int cold_boot;
EXPORT_SYMBOL_GPL(cold_boot);
#ifdef MULTI_CPU #ifdef MULTI_CPU
struct processor processor __ro_after_init; struct processor processor __ro_after_init;
#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)

View File

@@ -89,8 +89,10 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
endif endif
ifeq ($(CONFIG_ARM_CPU_SUSPEND),y)
AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SOC_IMX6) += resume-imx6.o obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
endif
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o obj-$(CONFIG_SOC_IMX1) += mach-imx1.o

View File

@@ -378,7 +378,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
static void __dma_free_remap(void *cpu_addr, size_t size) static void __dma_free_remap(void *cpu_addr, size_t size)
{ {
dma_common_free_remap(cpu_addr, size, dma_common_free_remap(cpu_addr, size,
VM_ARM_DMA_CONSISTENT | VM_USERMAP); VM_ARM_DMA_CONSISTENT | VM_USERMAP, false);
} }
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
@@ -1648,7 +1648,7 @@ void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0) { if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0) {
dma_common_free_remap(cpu_addr, size, dma_common_free_remap(cpu_addr, size,
VM_ARM_DMA_CONSISTENT | VM_USERMAP); VM_ARM_DMA_CONSISTENT | VM_USERMAP, false);
} }
__iommu_remove_mapping(dev, handle, size); __iommu_remove_mapping(dev, handle, size);

View File

@@ -930,7 +930,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[],
rd = arm_bpf_get_reg64(dst, tmp, ctx); rd = arm_bpf_get_reg64(dst, tmp, ctx);
/* Do LSR operation */ /* Do LSR operation */
if (val < 32) { if (val == 0) {
/* An immediate value of 0 encodes a shift amount of 32
* for LSR. To shift by 0, don't do anything.
*/
} else if (val < 32) {
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
@@ -956,7 +960,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[],
rd = arm_bpf_get_reg64(dst, tmp, ctx); rd = arm_bpf_get_reg64(dst, tmp, ctx);
/* Do ARSH operation */ /* Do ARSH operation */
if (val < 32) { if (val == 0) {
/* An immediate value of 0 encodes a shift amount of 32
* for ASR. To shift by 0, don't do anything.
*/
} else if (val < 32) {
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
@@ -993,21 +1001,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
arm_bpf_put_reg32(dst_hi, rd[0], ctx); arm_bpf_put_reg32(dst_hi, rd[0], ctx);
} }
static bool is_ldst_imm(s16 off, const u8 size)
{
s16 off_max = 0;
switch (size) {
case BPF_B:
case BPF_W:
off_max = 0xfff;
break;
case BPF_H:
off_max = 0xff;
break;
case BPF_DW:
/* Need to make sure off+4 does not overflow. */
off_max = 0xfff - 4;
break;
}
return -off_max <= off && off <= off_max;
}
/* *(size *)(dst + off) = src */ /* *(size *)(dst + off) = src */
static inline void emit_str_r(const s8 dst, const s8 src[], static inline void emit_str_r(const s8 dst, const s8 src[],
s32 off, struct jit_ctx *ctx, const u8 sz){ s16 off, struct jit_ctx *ctx, const u8 sz){
const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *tmp = bpf2a32[TMP_REG_1];
s32 off_max;
s8 rd; s8 rd;
rd = arm_bpf_get_reg32(dst, tmp[1], ctx); rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
if (sz == BPF_H) if (!is_ldst_imm(off, sz)) {
off_max = 0xff;
else
off_max = 0xfff;
if (off < 0 || off > off_max) {
emit_a32_mov_i(tmp[0], off, ctx); emit_a32_mov_i(tmp[0], off, ctx);
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
rd = tmp[0]; rd = tmp[0];
@@ -1036,18 +1058,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[],
/* dst = *(size*)(src + off) */ /* dst = *(size*)(src + off) */
static inline void emit_ldx_r(const s8 dst[], const s8 src, static inline void emit_ldx_r(const s8 dst[], const s8 src,
s32 off, struct jit_ctx *ctx, const u8 sz){ s16 off, struct jit_ctx *ctx, const u8 sz){
const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *tmp = bpf2a32[TMP_REG_1];
const s8 *rd = is_stacked(dst_lo) ? tmp : dst; const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
s8 rm = src; s8 rm = src;
s32 off_max;
if (sz == BPF_H) if (!is_ldst_imm(off, sz)) {
off_max = 0xff;
else
off_max = 0xfff;
if (off < 0 || off > off_max) {
emit_a32_mov_i(tmp[0], off, ctx); emit_a32_mov_i(tmp[0], off, ctx);
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
rm = tmp[0]; rm = tmp[0];

View File

@@ -100,6 +100,7 @@ config ARM64
select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select HANDLE_DOMAIN_IRQ select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND select HARDIRQS_SW_RESEND
select HAVE_ACPI_APEI if (ACPI && EFI) select HAVE_ACPI_APEI if (ACPI && EFI)
@@ -138,6 +139,8 @@ config ARM64
select HAVE_GENERIC_DMA_COHERENT select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IRQ_TIME_ACCOUNTING select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZ4
select HAVE_MEMBLOCK select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP if NUMA select HAVE_MEMBLOCK_NODE_MAP if NUMA
select HAVE_NMI select HAVE_NMI
@@ -152,6 +155,7 @@ config ARM64
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_KRETPROBES select HAVE_KRETPROBES
select HAVE_GENERIC_VDSO
select IOMMU_DMA if IOMMU_SUPPORT select IOMMU_DMA if IOMMU_SUPPORT
select IRQ_DOMAIN select IRQ_DOMAIN
select IRQ_FORCED_THREADING select IRQ_FORCED_THREADING
@@ -503,6 +507,22 @@ config ARM64_ERRATUM_1463225
If unsure, say Y. If unsure, say Y.
config ARM64_ERRATUM_1542419
bool "Neoverse-N1: workaround mis-ordering of instruction fetches"
default y
help
This option adds a workaround for ARM Neoverse-N1 erratum
1542419.
Affected Neoverse-N1 cores could execute a stale instruction when
modified by another CPU. The workaround depends on a firmware
counterpart.
Workaround the issue by hiding the DIC feature from EL0. This
forces user-space to perform cache maintenance.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y
@@ -752,6 +772,18 @@ config HOTPLUG_CPU
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu. can be controlled through /sys/devices/system/cpu.
# The GPIO number here must be sorted by descending number. In case of
# a multiplatform kernel, we just want the highest value required by the
# selected platforms.
config ARCH_NR_GPIO
int "Number of GPIOs in the system"
default 1280 if ARCH_QCOM
default 256
help
Maximum number of GPIOs in the system.
If unsure, leave the default value.
# Common NUMA Features # Common NUMA Features
config NUMA config NUMA
bool "Numa Memory Allocation and Scheduler Support" bool "Numa Memory Allocation and Scheduler Support"
@@ -830,6 +862,37 @@ config ARCH_HAS_CACHE_LINE_SIZE
config CC_HAVE_SHADOW_CALL_STACK config CC_HAVE_SHADOW_CALL_STACK
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18) def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
config ARM64_DMA_USE_IOMMU
bool "ARM64 DMA iommu integration"
select ARM_HAS_SG_CHAIN
select NEED_SG_DMA_LENGTH
help
Enable using iommu through the standard dma apis.
dma_alloc_coherent() will allocate scatter-gather memory
which is made virtually contiguous via iommu.
Enable if system contains IOMMU hardware.
if ARM64_DMA_USE_IOMMU
config ARM64_DMA_IOMMU_ALIGNMENT
int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers"
range 4 9
default 9
help
DMA mapping framework by default aligns all buffers to the smallest
PAGE_SIZE order which is greater than or equal to the requested buffer
size. This works well for buffers up to a few hundreds kilobytes, but
for larger buffers it just a waste of address space. Drivers which has
relatively small addressing window (like 64Mib) might run out of
virtual space with just a few allocations.
With this parameter you can specify the maximum PAGE_SIZE order for
DMA IOMMU buffers. Larger buffers will be aligned only to this
specified order. The order is expressed as a power of two multiplied
by the PAGE_SIZE.
endif
config SECCOMP config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode" bool "Enable seccomp to safely compute untrusted bytecode"
---help--- ---help---
@@ -981,6 +1044,19 @@ config ARM64_TAGGED_ADDR_ABI
to system calls as pointer arguments. For details, see to system calls as pointer arguments. For details, see
Documentation/arm64/tagged-address-abi.rst. Documentation/arm64/tagged-address-abi.rst.
config COMPAT_VDSO
bool "Enable vDSO for 32-bit applications"
depends on !CPU_BIG_ENDIAN && "$(CROSS_COMPILE_COMPAT)" != ""
select GENERIC_COMPAT_VDSO
default y
help
Place in the process address space of 32-bit applications an
ELF shared object providing fast implementations of gettimeofday
and clock_gettime.
You must have a 32-bit build of glibc 2.22 or later for programs
to seamlessly take advantage of this.
menuconfig ARMV8_DEPRECATED menuconfig ARMV8_DEPRECATED
bool "Emulate deprecated/obsolete ARMv8 instructions" bool "Emulate deprecated/obsolete ARMv8 instructions"
depends on COMPAT depends on COMPAT
@@ -1358,6 +1434,34 @@ config COMPAT
If you want to execute 32-bit userspace applications, say Y. If you want to execute 32-bit userspace applications, say Y.
config KUSER_HELPERS
bool "Enable kuser helpers page for 32 bit applications."
depends on COMPAT
default y
help
Warning: disabling this option may break 32-bit user programs.
Provide kuser helpers to compat tasks. The kernel provides
helper code to userspace in read only form at a fixed location
to allow userspace to be independent of the CPU type fitted to
the system. This permits binaries to be run on ARMv4 through
to ARMv8 without modification.
See Documentation/arm/kernel_user_helpers.txt for details.
However, the fixed address nature of these helpers can be used
by ROP (return orientated programming) authors when creating
exploits.
If all of the binaries and libraries which run on your platform
are built specifically for your platform, and make no use of
these helpers, then you can turn this option off to hinder
such exploits. However, in that case, if a binary or library
relying on those helpers is run, it will not function correctly.
Say N here only if you are absolutely certain that you do not
need these helpers; otherwise, the safe option is to say Y.
config SYSVIPC_COMPAT config SYSVIPC_COMPAT
def_bool y def_bool y
depends on COMPAT && SYSVIPC depends on COMPAT && SYSVIPC

View File

@@ -49,10 +49,10 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
endif endif
endif endif
KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) $(compat_vdso)
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
KBUILD_CFLAGS += $(call cc-disable-warning, psabi) KBUILD_CFLAGS += $(call cc-disable-warning, psabi)
KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) $(compat_vdso)
KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
@@ -171,6 +171,9 @@ ifeq ($(KBUILD_EXTMOD),)
prepare: vdso_prepare prepare: vdso_prepare
vdso_prepare: prepare0 vdso_prepare: prepare0
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h
$(if $(CONFIG_COMPAT_VDSO),$(Q)$(MAKE) \
$(build)=arch/arm64/kernel/vdso32 \
include/generated/vdso32-offsets.h)
endif endif
define archhelp define archhelp

View File

@@ -70,8 +70,7 @@
}; };
pmu { pmu {
compatible = "arm,cortex-a53-pmu", compatible = "arm,cortex-a53-pmu";
"arm,armv8-pmuv3";
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,

View File

@@ -2,6 +2,7 @@ CONFIG_AUDIT=y
CONFIG_NO_HZ=y CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_TASKSTATS=y CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
@@ -14,12 +15,12 @@ CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_SCHED=y
# CONFIG_FAIR_GROUP_SCHED is not set
CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_BPF=y CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set # CONFIG_PID_NS is not set
CONFIG_SCHED_TUNE=y CONFIG_SCHED_TUNE=y
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
@@ -49,6 +50,7 @@ CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=32 CONFIG_NR_CPUS=32
CONFIG_SECCOMP=y CONFIG_SECCOMP=y
CONFIG_PARAVIRT=y CONFIG_PARAVIRT=y
# CONFIG_ARM64_TAGGED_ADDR_ABI is not set
CONFIG_ARMV8_DEPRECATED=y CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y
@@ -64,6 +66,7 @@ CONFIG_ENERGY_MODEL=y
CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_TIMES=y CONFIG_CPU_FREQ_TIMES=y
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@@ -94,6 +97,7 @@ CONFIG_CLEANCACHE=y
CONFIG_CMA=y CONFIG_CMA=y
CONFIG_CMA_AREAS=16 CONFIG_CMA_AREAS=16
CONFIG_ZSMALLOC=y CONFIG_ZSMALLOC=y
CONFIG_MM_EVENT_STAT=y
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
@@ -106,7 +110,9 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPGRE_DEMUX=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPVTI=y CONFIG_NET_IPVTI=y
CONFIG_INET_ESP=y CONFIG_INET_ESP=y
CONFIG_INET_UDP_DIAG=y CONFIG_INET_UDP_DIAG=y
@@ -118,6 +124,7 @@ CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y CONFIG_IPV6_MIP6=y
CONFIG_IPV6_VTI=y CONFIG_IPV6_VTI=y
CONFIG_IPV6_GRE=y
CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y CONFIG_NETFILTER=y
@@ -209,6 +216,8 @@ CONFIG_CFG80211=y
CONFIG_MAC80211=y CONFIG_MAC80211=y
CONFIG_RFKILL=y CONFIG_RFKILL=y
# CONFIG_UEVENT_HELPER is not set # CONFIG_UEVENT_HELPER is not set
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
# CONFIG_FW_CACHE is not set # CONFIG_FW_CACHE is not set
# CONFIG_ALLOW_DEV_COREDUMP is not set # CONFIG_ALLOW_DEV_COREDUMP is not set
CONFIG_DMA_CMA=y CONFIG_DMA_CMA=y
@@ -221,8 +230,9 @@ CONFIG_UID_SYS_STATS=y
CONFIG_SCSI=y CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set # CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_UFSHCD=y CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFSHCD=m
CONFIG_SCSI_UFSHCD_PLATFORM=m
CONFIG_SCSI_UFS_CRYPTO=y CONFIG_SCSI_UFS_CRYPTO=y
CONFIG_MD=y CONFIG_MD=y
CONFIG_BLK_DEV_DM=y CONFIG_BLK_DEV_DM=y
@@ -237,6 +247,7 @@ CONFIG_DM_BOW=y
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_DUMMY=y CONFIG_DUMMY=y
CONFIG_TUN=y CONFIG_TUN=y
CONFIG_VETH=y
# CONFIG_ETHERNET is not set # CONFIG_ETHERNET is not set
CONFIG_PHYLIB=y CONFIG_PHYLIB=y
CONFIG_PPP=y CONFIG_PPP=y
@@ -288,31 +299,39 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_MSM_GENI_EARLY_CONSOLE=y
CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_BUS=y
CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_CAVIUM is not set # CONFIG_HW_RANDOM_CAVIUM is not set
# CONFIG_DEVPORT is not set # CONFIG_DEVPORT is not set
# CONFIG_I2C_COMPAT is not set # CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_HELPER_AUTO is not set # CONFIG_I2C_HELPER_AUTO is not set
CONFIG_SPI=y CONFIG_SPI=y
CONFIG_SPMI=y CONFIG_SPMI=y
# CONFIG_SPMI_MSM_PMIC_ARB is not set
CONFIG_PINCTRL_AMD=y CONFIG_PINCTRL_AMD=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_AVS=y CONFIG_POWER_AVS=y
CONFIG_POWER_RESET_HISI=y CONFIG_POWER_RESET_HISI=y
# CONFIG_HWMON is not set
CONFIG_THERMAL=y CONFIG_THERMAL=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y CONFIG_DEVFREQ_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_CORE=y
CONFIG_MFD_ACT8945A=y CONFIG_MFD_ACT8945A=y
CONFIG_MFD_SYSCON=y CONFIG_MFD_SYSCON=y
CONFIG_REGULATOR=y CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_VGA_ARB is not set # CONFIG_VGA_ARB is not set
CONFIG_DRM=y CONFIG_DRM=y
# CONFIG_DRM_FBDEV_EMULATION is not set # CONFIG_DRM_FBDEV_EMULATION is not set
@@ -325,7 +344,6 @@ CONFIG_SND=y
CONFIG_SND_HRTIMER=y CONFIG_SND_HRTIMER=y
CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_DYNAMIC_MINORS=y
# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_SUPPORT_OLD_API is not set
# CONFIG_SND_VERBOSE_PROCFS is not set
# CONFIG_SND_DRIVERS is not set # CONFIG_SND_DRIVERS is not set
CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO=y
CONFIG_SND_SOC=y CONFIG_SND_SOC=y
@@ -354,14 +372,15 @@ CONFIG_TYPEC=y
CONFIG_MMC=y CONFIG_MMC=y
# CONFIG_PWRSEQ_EMMC is not set # CONFIG_PWRSEQ_EMMC is not set
# CONFIG_PWRSEQ_SIMPLE is not set # CONFIG_PWRSEQ_SIMPLE is not set
CONFIG_MMC_CRYPTO=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_NEW_LEDS=y CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_EDAC=y CONFIG_EDAC=y
CONFIG_RTC_CLASS=y CONFIG_RTC_CLASS=y
# CONFIG_RTC_SYSTOHC is not set
CONFIG_RTC_DRV_PL030=y CONFIG_RTC_DRV_PL030=y
CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_PL031=y
CONFIG_DMADEVICES=y CONFIG_DMADEVICES=y
@@ -373,7 +392,10 @@ CONFIG_COMMON_CLK_SCPI=y
# CONFIG_COMMON_CLK_XGENE is not set # CONFIG_COMMON_CLK_XGENE is not set
CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK=y
CONFIG_MAILBOX=y CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_ARM_SMMU=m
CONFIG_REMOTEPROC=y
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y
CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DEVFREQ_GOV_USERSPACE=y
@@ -464,6 +486,8 @@ CONFIG_SECURITY=y
CONFIG_SECURITYFS=y CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK=y
CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX=y
CONFIG_INIT_STACK_ALL=y CONFIG_INIT_STACK_ALL=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
@@ -487,5 +511,3 @@ CONFIG_PANIC_TIMEOUT=5
CONFIG_SCHEDSTATS=y CONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_LIST=y CONFIG_DEBUG_LIST=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_STM=y

View File

@@ -22,6 +22,7 @@
#define CTR_L1IP_MASK 3 #define CTR_L1IP_MASK 3
#define CTR_DMINLINE_SHIFT 16 #define CTR_DMINLINE_SHIFT 16
#define CTR_IMINLINE_SHIFT 0 #define CTR_IMINLINE_SHIFT 0
#define CTR_IMINLINE_MASK 0xf
#define CTR_ERG_SHIFT 20 #define CTR_ERG_SHIFT 20
#define CTR_CWG_SHIFT 24 #define CTR_CWG_SHIFT 24
#define CTR_CWG_MASK 15 #define CTR_CWG_MASK 15
@@ -29,7 +30,7 @@
#define CTR_DIC_SHIFT 29 #define CTR_DIC_SHIFT 29
#define CTR_CACHE_MINLINE_MASK \ #define CTR_CACHE_MINLINE_MASK \
(0xf << CTR_DMINLINE_SHIFT | 0xf << CTR_IMINLINE_SHIFT) (0xf << CTR_DMINLINE_SHIFT | CTR_IMINLINE_MASK << CTR_IMINLINE_SHIFT)
#define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) #define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK)

View File

@@ -131,6 +131,15 @@ static inline void flush_cache_range(struct vm_area_struct *vma,
extern void __dma_map_area(const void *, size_t, int); extern void __dma_map_area(const void *, size_t, int);
extern void __dma_unmap_area(const void *, size_t, int); extern void __dma_unmap_area(const void *, size_t, int);
extern void __dma_flush_area(const void *, size_t); extern void __dma_flush_area(const void *, size_t);
extern void __dma_inv_area(const void *start, size_t size);
extern void __dma_clean_area(const void *start, size_t size);
#define dmac_flush_range(start, end) \
__dma_flush_area(start, (void *)(end) - (void *)(start))
#define dmac_inv_range(start, end) \
__dma_inv_area(start, (void *)(end) - (void *)(start))
#define dmac_clean_range(start, end) \
__dma_clean_area(start, (void *)(end) - (void *)(start))
/* /*
* Copy user data from/to a page which is mapped into a different * Copy user data from/to a page which is mapped into a different

View File

@@ -2,8 +2,6 @@
#ifndef _ASM_CLOCKSOURCE_H #ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H
struct arch_clocksource_data { #include <asm/vdso/clocksource.h>
bool vdso_direct; /* Usable for direct VDSO access? */
};
#endif #endif

View File

@@ -53,8 +53,9 @@
#define ARM64_HAS_STAGE2_FWB 32 #define ARM64_HAS_STAGE2_FWB 32
#define ARM64_WORKAROUND_1463225 33 #define ARM64_WORKAROUND_1463225 33
#define ARM64_SSBS 34 #define ARM64_SSBS 34
#define ARM64_WORKAROUND_1542419 35
/* kabi: reserve 35 - 62 for future cpu capabilities */ /* kabi: reserve 36 - 62 for future cpu capabilities */
#define ARM64_NCAPS 62 #define ARM64_NCAPS 62
#endif /* __ASM_CPUCAPS_H */ #endif /* __ASM_CPUCAPS_H */

View File

@@ -80,6 +80,7 @@
#define ARM_CPU_PART_CORTEX_A35 0xD04 #define ARM_CPU_PART_CORTEX_A35 0xD04
#define ARM_CPU_PART_CORTEX_A55 0xD05 #define ARM_CPU_PART_CORTEX_A55 0xD05
#define ARM_CPU_PART_CORTEX_A76 0xD0B #define ARM_CPU_PART_CORTEX_A76 0xD0B
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
#define APM_CPU_PART_POTENZA 0x000 #define APM_CPU_PART_POTENZA 0x000
@@ -107,6 +108,7 @@
#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35) #define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)

View File

@@ -24,9 +24,18 @@ struct dev_archdata {
const struct dma_map_ops *dev_dma_ops; const struct dma_map_ops *dev_dma_ops;
#endif #endif
bool dma_coherent; bool dma_coherent;
#ifdef CONFIG_ARM64_DMA_USE_IOMMU
struct dma_iommu_mapping *mapping;
#endif
}; };
struct pdev_archdata { struct pdev_archdata {
}; };
#ifdef CONFIG_ARM64_DMA_USE_IOMMU
#define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
#else
#define to_dma_iommu_mapping(dev) NULL
#endif
#endif #endif

View File

@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013,2017-2018 The Linux Foundation. All rights reserved.
*/
#ifndef _ASM_DMA_CONTIGUOUS_H
#define _ASM_DMA_CONTIGUOUS_H
#ifdef __KERNEL__
#ifdef CONFIG_DMA_CMA
#include <linux/types.h>
void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
#endif
#endif
#endif

View File

@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef ASMARM_DMA_IOMMU_H
#define ASMARM_DMA_IOMMU_H
#ifdef __KERNEL__
#include <linux/err.h>
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
#include <linux/dma-debug.h>
#include <linux/kref.h>
#include <linux/dma-mapping-fast.h>
struct dma_iommu_mapping {
/* iommu specific data */
struct iommu_domain *domain;
bool init;
struct kref kref;
const struct dma_map_ops *ops;
/* Protects bitmap */
spinlock_t lock;
void *bitmap;
size_t bits;
dma_addr_t base;
struct dma_fast_smmu_mapping *fast;
};
#ifdef CONFIG_ARM64_DMA_USE_IOMMU
void arm_iommu_put_dma_cookie(struct iommu_domain *domain);
#else /* !CONFIG_ARM64_DMA_USE_IOMMU */
static inline void arm_iommu_put_dma_cookie(struct iommu_domain *domain) {}
#endif /* CONFIG_ARM64_DMA_USE_IOMMU */
#endif /* __KERNEL__ */
#endif

View File

@@ -209,11 +209,25 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
({ \ ({ \
set_thread_flag(TIF_32BIT); \ set_thread_flag(TIF_32BIT); \
}) })
#ifdef CONFIG_COMPAT_VDSO
#define COMPAT_ARCH_DLINFO \
do { \
/* \
* Note that we use Elf64_Off instead of elf_addr_t because \
* elf_addr_t in compat is defined as Elf32_Addr and casting \
* current->mm->context.vdso to it triggers a cast warning of \
* cast from pointer to integer of different size. \
*/ \
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
(Elf64_Off)current->mm->context.vdso); \
} while (0)
#else
#define COMPAT_ARCH_DLINFO #define COMPAT_ARCH_DLINFO
extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, #endif
int uses_interp); extern int aarch32_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
#define compat_arch_setup_additional_pages \ #define compat_arch_setup_additional_pages \
aarch32_setup_vectors_page aarch32_setup_additional_pages
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */

View File

@@ -21,7 +21,7 @@
#else /* __ASSEMBLER__ */ #else /* __ASSEMBLER__ */
#ifdef CONFIG_LTO_CLANG #ifdef CONFIG_LTO_CLANG
#define __LSE_PREAMBLE ".arch armv8-a+lse\n" #define __LSE_PREAMBLE ".arch_extension lse\n"
#else #else
__asm__(".arch_extension lse"); __asm__(".arch_extension lse");
#define __LSE_PREAMBLE #define __LSE_PREAMBLE

View File

@@ -40,6 +40,8 @@
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/string.h> #include <linux/string.h>
#include <vdso/processor.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/hw_breakpoint.h> #include <asm/hw_breakpoint.h>
@@ -53,7 +55,7 @@
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
*/ */
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#ifdef CONFIG_ARM64_64K_PAGES #if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS)
/* /*
* With CONFIG_ARM64_64K_PAGES enabled, the last page is occupied * With CONFIG_ARM64_64K_PAGES enabled, the last page is occupied
* by the compat vectors page. * by the compat vectors page.
@@ -227,11 +229,6 @@ extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p); unsigned long get_wchan(struct task_struct *p);
static inline void cpu_relax(void)
{
asm volatile("yield" ::: "memory");
}
/* Thread switching */ /* Thread switching */
extern struct task_struct *cpu_switch_to(struct task_struct *prev, extern struct task_struct *cpu_switch_to(struct task_struct *prev,
struct task_struct *next); struct task_struct *next);

View File

@@ -20,7 +20,51 @@
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <linux/compat.h> #include <linux/compat.h>
#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500 struct compat_sigcontext {
/* We always set these two fields to 0 */
compat_ulong_t trap_no;
compat_ulong_t error_code;
compat_ulong_t oldmask;
compat_ulong_t arm_r0;
compat_ulong_t arm_r1;
compat_ulong_t arm_r2;
compat_ulong_t arm_r3;
compat_ulong_t arm_r4;
compat_ulong_t arm_r5;
compat_ulong_t arm_r6;
compat_ulong_t arm_r7;
compat_ulong_t arm_r8;
compat_ulong_t arm_r9;
compat_ulong_t arm_r10;
compat_ulong_t arm_fp;
compat_ulong_t arm_ip;
compat_ulong_t arm_sp;
compat_ulong_t arm_lr;
compat_ulong_t arm_pc;
compat_ulong_t arm_cpsr;
compat_ulong_t fault_address;
};
struct compat_ucontext {
compat_ulong_t uc_flags;
compat_uptr_t uc_link;
compat_stack_t uc_stack;
struct compat_sigcontext uc_mcontext;
compat_sigset_t uc_sigmask;
int __unused[32 - (sizeof(compat_sigset_t) / sizeof(int))];
compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8)));
};
struct compat_sigframe {
struct compat_ucontext uc;
compat_ulong_t retcode[2];
};
struct compat_rt_sigframe {
struct compat_siginfo info;
struct compat_sigframe sig;
};
int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs); struct pt_regs *regs);

View File

@@ -60,7 +60,9 @@
#ifndef CONFIG_BROKEN_GAS_INST #ifndef CONFIG_BROKEN_GAS_INST
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#define __emit_inst(x) .inst (x) // The space separator is omitted so that __emit_inst(x) can be parsed as
// either an assembler directive or an assembler macro argument.
#define __emit_inst(x) .inst(x)
#else #else
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t" #define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
#endif #endif

View File

@@ -33,8 +33,13 @@
#define __NR_compat_exit 1 #define __NR_compat_exit 1
#define __NR_compat_read 3 #define __NR_compat_read 3
#define __NR_compat_write 4 #define __NR_compat_write 4
#define __NR_compat_gettimeofday 78
#define __NR_compat_sigreturn 119 #define __NR_compat_sigreturn 119
#define __NR_compat_rt_sigreturn 173 #define __NR_compat_rt_sigreturn 173
#define __NR_compat_clock_gettime 263
#define __NR_compat_clock_getres 264
#define __NR_compat_clock_gettime64 403
#define __NR_compat_clock_getres_time64 406
/* /*
* The following SVCs are ARM private. * The following SVCs are ARM private.

View File

@@ -28,6 +28,9 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <generated/vdso-offsets.h> #include <generated/vdso-offsets.h>
#ifdef CONFIG_COMPAT_VDSO
#include <generated/vdso32-offsets.h>
#endif
#define VDSO_SYMBOL(base, name) \ #define VDSO_SYMBOL(base, name) \
({ \ ({ \

View File

@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSOCLOCKSOURCE_H
#define __ASM_VDSOCLOCKSOURCE_H
struct arch_clocksource_data {
bool vdso_direct; /* Usable for direct VDSO access? */
};
#endif

View File

@@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 ARM Limited
*/
#ifndef __COMPAT_BARRIER_H
#define __COMPAT_BARRIER_H
#ifndef __ASSEMBLY__
/*
* Warning: This code is meant to be used with
* ENABLE_COMPAT_VDSO only.
*/
#ifndef ENABLE_COMPAT_VDSO
#error This header is meant to be used with ENABLE_COMPAT_VDSO only
#endif
#ifdef dmb
#undef dmb
#endif
#if __LINUX_ARM_ARCH__ >= 7
#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
#elif __LINUX_ARM_ARCH__ == 6
#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
: : "r" (0) : "memory")
#else
#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
#endif
#if __LINUX_ARM_ARCH__ >= 8 && defined(CONFIG_AS_DMB_ISHLD)
#define aarch32_smp_mb() dmb(ish)
#define aarch32_smp_rmb() dmb(ishld)
#define aarch32_smp_wmb() dmb(ishst)
#else
#define aarch32_smp_mb() dmb(ish)
#define aarch32_smp_rmb() aarch32_smp_mb()
#define aarch32_smp_wmb() dmb(ishst)
#endif
#undef smp_mb
#undef smp_rmb
#undef smp_wmb
#define smp_mb() aarch32_smp_mb()
#define smp_rmb() aarch32_smp_rmb()
#define smp_wmb() aarch32_smp_wmb()
#endif /* !__ASSEMBLY__ */
#endif /* __COMPAT_BARRIER_H */

View File

@@ -0,0 +1,124 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 ARM Limited
*/
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifndef __ASSEMBLY__
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/vdso/compat_barrier.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
#define VDSO_HAS_CLOCK_GETRES 1
#define BUILD_VDSO32 1
static __always_inline
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
struct timezone *_tz)
{
register struct timezone *tz asm("r1") = _tz;
register struct __kernel_old_timeval *tv asm("r0") = _tv;
register long ret asm ("r0");
register long nr asm("r7") = __NR_compat_gettimeofday;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (tv), "r" (tz), "r" (nr)
: "memory");
return ret;
}
static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_compat_clock_gettime;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("r1") = _ts;
register clockid_t clkid asm("r0") = _clkid;
register long ret asm ("r0");
register long nr asm("r7") = __NR_compat_clock_getres;
asm volatile(
" swi #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
u64 res;
/*
* clock_mode == 0 implies that vDSO are enabled otherwise
* fallback on syscall.
*/
if (clock_mode)
return __VDSO_USE_SYSCALL;
/*
* This isb() is required to prevent that the counter value
* is speculated.
*/
isb();
asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (res));
/*
* This isb() is required to prevent that the seq lock is
* speculated.
*/
isb();
return res;
}
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
const struct vdso_data *ret;
/*
* This simply puts &_vdso_data into ret. The reason why we don't use
* `ret = _vdso_data` is that the compiler tends to optimise this in a
* very suboptimal way: instead of keeping &_vdso_data in a register,
* it goes through a relocation almost every time _vdso_data must be
* accessed (even in subfunctions). This is both time and space
* consuming: each relocation uses a word in the code section, and it
* has to be loaded at runtime.
*
* This trick hides the assignment from the compiler. Since it cannot
* track where the pointer comes from, it will only use one relocation
* where __arch_get_vdso_data() is called, and then keep the result in
* a register.
*/
asm volatile("mov %0, %1" : "=r"(ret) : "r"(_vdso_data));
return ret;
}
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */

View File

@@ -0,0 +1,102 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 ARM Limited
*/
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H
#ifndef __ASSEMBLY__
#include <asm/unistd.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
#define VDSO_HAS_CLOCK_GETRES 1
static __always_inline
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
struct timezone *_tz)
{
register struct timezone *tz asm("x1") = _tz;
register struct __kernel_old_timeval *tv asm("x0") = _tv;
register long ret asm ("x0");
register long nr asm("x8") = __NR_gettimeofday;
asm volatile(
" svc #0\n"
: "=r" (ret)
: "r" (tv), "r" (tz), "r" (nr)
: "memory");
return ret;
}
static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("x1") = _ts;
register clockid_t clkid asm("x0") = _clkid;
register long ret asm ("x0");
register long nr asm("x8") = __NR_clock_gettime;
asm volatile(
" svc #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register struct __kernel_timespec *ts asm("x1") = _ts;
register clockid_t clkid asm("x0") = _clkid;
register long ret asm ("x0");
register long nr asm("x8") = __NR_clock_getres;
asm volatile(
" svc #0\n"
: "=r" (ret)
: "r" (clkid), "r" (ts), "r" (nr)
: "memory");
return ret;
}
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
u64 res;
/*
* clock_mode == 0 implies that vDSO are enabled otherwise
* fallback on syscall.
*/
if (clock_mode)
return __VDSO_USE_SYSCALL;
/*
* This isb() is required to prevent that the counter value
* is speculated.
*/
isb();
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
/*
* This isb() is required to prevent that the seq lock is
* speculated.#
*/
isb();
return res;
}
static __always_inline
const struct vdso_data *__arch_get_vdso_data(void)
{
return _vdso_data;
}
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */

View File

@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 ARM Ltd.
*/
#ifndef __ASM_VDSO_PROCESSOR_H
#define __ASM_VDSO_PROCESSOR_H
#ifndef __ASSEMBLY__
static inline void cpu_relax(void)
{
asm volatile("yield" ::: "memory");
}
#endif /* __ASSEMBLY__ */
#endif /* __ASM_VDSO_PROCESSOR_H */

View File

@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSO_VSYSCALL_H
#define __ASM_VDSO_VSYSCALL_H
#ifndef __ASSEMBLY__
#include <linux/timekeeper_internal.h>
#include <vdso/datapage.h>
#define VDSO_PRECISION_MASK ~(0xFF00ULL<<48)
extern struct vdso_data *vdso_data;
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline
struct vdso_data *__arm64_get_k_vdso_data(void)
{
return vdso_data;
}
#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
static __always_inline
int __arm64_get_clock_mode(struct timekeeper *tk)
{
u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
return use_syscall;
}
#define __arch_get_clock_mode __arm64_get_clock_mode
static __always_inline
int __arm64_use_vsyscall(struct vdso_data *vdata)
{
return !vdata[CS_HRES_COARSE].clock_mode;
}
#define __arch_use_vsyscall __arm64_use_vsyscall
static __always_inline
void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
{
vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
}
#define __arch_update_vsyscall __arm64_update_vsyscall
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_VSYSCALL_H */

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2012 ARM Limited
*
* 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/>.
*/
#ifndef __ASM_VDSO_DATAPAGE_H
#define __ASM_VDSO_DATAPAGE_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
struct vdso_data {
__u64 cs_cycle_last; /* Timebase at clocksource init */
__u64 raw_time_sec; /* Raw time */
__u64 raw_time_nsec;
__u64 xtime_clock_sec; /* Kernel time */
__u64 xtime_clock_nsec;
__u64 xtime_coarse_sec; /* Coarse time */
__u64 xtime_coarse_nsec;
__u64 wtm_clock_sec; /* Wall to monotonic time */
__u64 wtm_clock_nsec;
__u32 tb_seq_count; /* Timebase sequence counter */
/* cs_* members must be adjacent and in this order (ldp accesses) */
__u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */
__u32 cs_shift; /* Clocksource shift (mono = raw) */
__u32 cs_raw_mult; /* Raw clocksource multiplier */
__u32 tz_minuteswest; /* Whacky timezone stuff */
__u32 tz_dsttime;
__u32 use_syscall;
__u32 hrtimer_res;
};
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __ASM_VDSO_DATAPAGE_H */

View File

@@ -22,6 +22,6 @@
#include <linux/types.h> #include <linux/types.h>
#define COMMAND_LINE_SIZE 2048 #define COMMAND_LINE_SIZE 4096
#endif #endif

View File

@@ -27,8 +27,12 @@ OBJCOPYFLAGS := --prefix-symbols=__efistub_
$(obj)/%.stub.o: $(obj)/%.o FORCE $(obj)/%.stub.o: $(obj)/%.o FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ arm64-obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
sys_compat.o sys_compat.o
ifneq ($(CONFIG_COMPAT_VDSO), y)
arm64-obj-$(CONFIG_COMPAT) += sigreturn32.o
endif
arm64-obj-$(CONFIG_KUSER_HELPERS) += kuser32.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
@@ -61,6 +65,7 @@ arm64-obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
obj-y += $(arm64-obj-y) vdso/ probes/ obj-y += $(arm64-obj-y) vdso/ probes/
obj-m += $(arm64-obj-m) obj-m += $(arm64-obj-m)
obj-$(CONFIG_COMPAT_VDSO) += vdso32/
head-y := head.o head-y := head.o
extra-y += $(head-y) vmlinux.lds extra-y += $(head-y) vmlinux.lds

View File

@@ -29,6 +29,7 @@
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <asm/cacheflush.h>
#include <asm/checksum.h> #include <asm/checksum.h>
EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(copy_page);
@@ -86,3 +87,15 @@ extern long long __ashrti3(long long a, int b);
EXPORT_SYMBOL(__ashrti3); EXPORT_SYMBOL(__ashrti3);
extern long long __lshrti3(long long a, int b); extern long long __lshrti3(long long a, int b);
EXPORT_SYMBOL(__lshrti3); EXPORT_SYMBOL(__lshrti3);
/* caching functions */
EXPORT_SYMBOL_GPL(__dma_inv_area);
EXPORT_SYMBOL_GPL(__dma_clean_area);
EXPORT_SYMBOL_GPL(__dma_flush_area);
EXPORT_SYMBOL_GPL(__flush_dcache_area);
EXPORT_SYMBOL_GPL(__bss_stop);
EXPORT_SYMBOL_GPL(__per_cpu_start);
EXPORT_SYMBOL_GPL(__per_cpu_end);
EXPORT_SYMBOL_GPL(_sdata);
EXPORT_SYMBOL_GPL(cpu_do_idle);

View File

@@ -604,7 +604,7 @@ static struct undef_hook setend_hooks[] = {
}, },
{ {
/* Thumb mode */ /* Thumb mode */
.instr_mask = 0x0000fff7, .instr_mask = 0xfffffff7,
.instr_val = 0x0000b650, .instr_val = 0x0000b650,
.pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK), .pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK),
.pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR), .pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),

View File

@@ -25,13 +25,14 @@
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <linux/preempt.h> #include <linux/preempt.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <vdso/datapage.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/signal32.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/suspend.h> #include <asm/suspend.h>
#include <asm/vdso_datapage.h>
#include <linux/kbuild.h> #include <linux/kbuild.h>
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
@@ -84,6 +85,11 @@ int main(void)
DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe));
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK(); BLANK();
#ifdef CONFIG_COMPAT
DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0));
DEFINE(COMPAT_RT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_rt_sigframe, sig.uc.uc_mcontext.arm_r0));
BLANK();
#endif
DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter)); DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));
BLANK(); BLANK();
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
@@ -108,22 +114,28 @@ int main(void)
DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC); DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
BLANK(); BLANK();
DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last)); DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec)); DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
DEFINE(VDSO_RAW_TIME_NSEC, offsetof(struct vdso_data, raw_time_nsec)); DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec)); DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec)); DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec)); DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec)); DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count)); DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult)); DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
DEFINE(VDSO_CS_RAW_MULT, offsetof(struct vdso_data, cs_raw_mult)); DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift)); DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
BLANK(); BLANK();
DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec)); DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
DEFINE(TVAL_TV_USEC, offsetof(struct timeval, tv_usec)); DEFINE(TVAL_TV_USEC, offsetof(struct timeval, tv_usec));

View File

@@ -643,6 +643,18 @@ needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry,
return false; return false;
} }
static bool __maybe_unused
has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
int scope)
{
u32 midr = read_cpuid_id();
bool has_dic = read_cpuid_cachetype() & BIT(CTR_DIC_SHIFT);
const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
return is_midr_in_range(midr, &range) && has_dic;
}
#ifdef CONFIG_HARDEN_EL2_VECTORS #ifdef CONFIG_HARDEN_EL2_VECTORS
static const struct midr_range arm64_harden_el2_vectors[] = { static const struct midr_range arm64_harden_el2_vectors[] = {
@@ -834,6 +846,16 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), ERRATA_MIDR_RANGE_LIST(tx2_family_cpus),
.matches = needs_tx2_tvm_workaround, .matches = needs_tx2_tvm_workaround,
}, },
#endif
#ifdef CONFIG_ARM64_ERRATUM_1542419
{
/* we depend on the firmware portion for correctness */
.desc = "ARM erratum 1542419 (kernel portion)",
.capability = ARM64_WORKAROUND_1542419,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = has_neoverse_n1_erratum_1542419,
.cpu_enable = cpu_enable_trap_ctr_access,
},
#endif #endif
{ {
} }

View File

@@ -42,6 +42,7 @@ int arm_cpuidle_suspend(int index)
return cpu_ops[cpu]->cpu_suspend(index); return cpu_ops[cpu]->cpu_suspend(index);
} }
EXPORT_SYMBOL_GPL(arm_cpuidle_suspend);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI

View File

@@ -674,7 +674,7 @@ ENTRY(__boot_cpu_mode)
* with MMU turned off. * with MMU turned off.
*/ */
ENTRY(__early_cpu_boot_status) ENTRY(__early_cpu_boot_status)
.long 0 .quad 0
.popsection .popsection

View File

@@ -1,29 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* /*
* Low-level user helpers placed in the vectors page for AArch32. * AArch32 user helpers.
* Based on the kuser helpers in arch/arm/kernel/entry-armv.S. * Based on the kuser helpers in arch/arm/kernel/entry-armv.S.
* *
* Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net> * Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net>
* Copyright (C) 2012 ARM Ltd. * Copyright (C) 2012-2018 ARM Ltd.
* *
* This program is free software; you can redistribute it and/or modify * The kuser helpers below are mapped at a fixed address by
* it under the terms of the GNU General Public License version 2 as * aarch32_setup_additional_pages() and are provided for compatibility
* published by the Free Software Foundation. * reasons with 32 bit (aarch32) applications that need them.
*
* 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/>.
*
*
* AArch32 user helpers.
*
* Each segment is 32-byte aligned and will be moved to the top of the high
* vector page. New segments (if ever needed) must be added in front of
* existing ones. This mechanism should be used only for things that are
* really small and justified, and not be abused freely.
* *
* See Documentation/arm/kernel_user_helpers.txt for formal definitions. * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
*/ */
@@ -77,42 +62,3 @@ __kuser_helper_version: // 0xffff0ffc
.word ((__kuser_helper_end - __kuser_helper_start) >> 5) .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
.globl __kuser_helper_end .globl __kuser_helper_end
__kuser_helper_end: __kuser_helper_end:
/*
* AArch32 sigreturn code
*
* For ARM syscalls, the syscall number has to be loaded into r7.
* We do not support an OABI userspace.
*
* For Thumb syscalls, we also pass the syscall number via r7. We therefore
* need two 16-bit instructions.
*/
.globl __aarch32_sigret_code_start
__aarch32_sigret_code_start:
/*
* ARM Code
*/
.byte __NR_compat_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_sigreturn
.byte __NR_compat_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_sigreturn
/*
* Thumb code
*/
.byte __NR_compat_sigreturn, 0x27 // svc #__NR_compat_sigreturn
.byte __NR_compat_sigreturn, 0xdf // mov r7, #__NR_compat_sigreturn
/*
* ARM code
*/
.byte __NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_rt_sigreturn
.byte __NR_compat_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_rt_sigreturn
/*
* Thumb code
*/
.byte __NR_compat_rt_sigreturn, 0x27 // svc #__NR_compat_rt_sigreturn
.byte __NR_compat_rt_sigreturn, 0xdf // mov r7, #__NR_compat_rt_sigreturn
.globl __aarch32_sigret_code_end
__aarch32_sigret_code_end:

View File

@@ -75,6 +75,7 @@ void (*pm_power_off)(void);
EXPORT_SYMBOL_GPL(pm_power_off); EXPORT_SYMBOL_GPL(pm_power_off);
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
EXPORT_SYMBOL_GPL(arm_pm_restart);
/* /*
* This is our default idle handler. * This is our default idle handler.

View File

@@ -69,6 +69,14 @@ static struct resource *standard_resources;
phys_addr_t __fdt_pointer __initdata; phys_addr_t __fdt_pointer __initdata;
/* Vendor stub */
unsigned int boot_reason;
EXPORT_SYMBOL_GPL(boot_reason);
/* Vendor stub */
unsigned int cold_boot;
EXPORT_SYMBOL_GPL(cold_boot);
/* /*
* Standard memory resources * Standard memory resources
*/ */

View File

@@ -29,42 +29,7 @@
#include <asm/traps.h> #include <asm/traps.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/vdso.h>
struct compat_sigcontext {
/* We always set these two fields to 0 */
compat_ulong_t trap_no;
compat_ulong_t error_code;
compat_ulong_t oldmask;
compat_ulong_t arm_r0;
compat_ulong_t arm_r1;
compat_ulong_t arm_r2;
compat_ulong_t arm_r3;
compat_ulong_t arm_r4;
compat_ulong_t arm_r5;
compat_ulong_t arm_r6;
compat_ulong_t arm_r7;
compat_ulong_t arm_r8;
compat_ulong_t arm_r9;
compat_ulong_t arm_r10;
compat_ulong_t arm_fp;
compat_ulong_t arm_ip;
compat_ulong_t arm_sp;
compat_ulong_t arm_lr;
compat_ulong_t arm_pc;
compat_ulong_t arm_cpsr;
compat_ulong_t fault_address;
};
struct compat_ucontext {
compat_ulong_t uc_flags;
compat_uptr_t uc_link;
compat_stack_t uc_stack;
struct compat_sigcontext uc_mcontext;
compat_sigset_t uc_sigmask;
int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))];
compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8)));
};
struct compat_vfp_sigframe { struct compat_vfp_sigframe {
compat_ulong_t magic; compat_ulong_t magic;
@@ -92,16 +57,6 @@ struct compat_aux_sigframe {
unsigned long end_magic; unsigned long end_magic;
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
struct compat_sigframe {
struct compat_ucontext uc;
compat_ulong_t retcode[2];
};
struct compat_rt_sigframe {
struct compat_siginfo info;
struct compat_sigframe sig;
};
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
@@ -398,14 +353,38 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
retcode = ptr_to_compat(ka->sa.sa_restorer); retcode = ptr_to_compat(ka->sa.sa_restorer);
} else { } else {
/* Set up sigreturn pointer */ /* Set up sigreturn pointer */
#ifdef CONFIG_COMPAT_VDSO
void *vdso_base = current->mm->context.vdso;
void *vdso_trampoline;
if (ka->sa.sa_flags & SA_SIGINFO) {
if (thumb) {
vdso_trampoline = VDSO_SYMBOL(vdso_base,
compat_rt_sigreturn_thumb);
} else {
vdso_trampoline = VDSO_SYMBOL(vdso_base,
compat_rt_sigreturn_arm);
}
} else {
if (thumb) {
vdso_trampoline = VDSO_SYMBOL(vdso_base,
compat_sigreturn_thumb);
} else {
vdso_trampoline = VDSO_SYMBOL(vdso_base,
compat_sigreturn_arm);
}
}
retcode = ptr_to_compat(vdso_trampoline) + thumb;
#else
unsigned int idx = thumb << 1; unsigned int idx = thumb << 1;
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
idx += 3; idx += 3;
retcode = AARCH32_VECTORS_BASE + retcode = (unsigned long)current->mm->context.vdso +
AARCH32_KERN_SIGRET_CODE_OFFSET +
(idx << 2) + thumb; (idx << 2) + thumb;
#endif
} }
regs->regs[0] = usig; regs->regs[0] = usig;

View File

@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* AArch32 sigreturn code.
* Based on the kuser helpers in arch/arm/kernel/entry-armv.S.
*
* Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net>
* Copyright (C) 2012-2018 ARM Ltd.
*
* For ARM syscalls, the syscall number has to be loaded into r7.
* We do not support an OABI userspace.
*
* For Thumb syscalls, we also pass the syscall number via r7. We therefore
* need two 16-bit instructions.
*/
#include <asm/unistd.h>
.globl __aarch32_sigret_code_start
__aarch32_sigret_code_start:
/*
* ARM Code
*/
.byte __NR_compat_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_sigreturn
.byte __NR_compat_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_sigreturn
/*
* Thumb code
*/
.byte __NR_compat_sigreturn, 0x27 // svc #__NR_compat_sigreturn
.byte __NR_compat_sigreturn, 0xdf // mov r7, #__NR_compat_sigreturn
/*
* ARM code
*/
.byte __NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_rt_sigreturn
.byte __NR_compat_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_rt_sigreturn
/*
* Thumb code
*/
.byte __NR_compat_rt_sigreturn, 0x27 // svc #__NR_compat_rt_sigreturn
.byte __NR_compat_rt_sigreturn, 0xdf // mov r7, #__NR_compat_rt_sigreturn
.globl __aarch32_sigret_code_end
__aarch32_sigret_code_end:

View File

@@ -597,6 +597,9 @@ static void __init acpi_parse_and_init_cpus(void)
#else #else
#define acpi_parse_and_init_cpus(...) do { } while (0) #define acpi_parse_and_init_cpus(...) do { } while (0)
#endif #endif
/* Dummy vendor field */
DEFINE_PER_CPU(bool, pending_ipi);
EXPORT_SYMBOL_GPL(pending_ipi);
static void (*__smp_update_ipi_history_cb)(int cpu); static void (*__smp_update_ipi_history_cb)(int cpu);
/* /*

View File

@@ -19,6 +19,7 @@
*/ */
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cpufeature.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
@@ -28,6 +29,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
#include <asm/tlbflush.h>
#include <asm/unistd.h> #include <asm/unistd.h>
static long static long
@@ -41,6 +43,15 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
if (fatal_signal_pending(current)) if (fatal_signal_pending(current))
return 0; return 0;
if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) {
/*
* The workaround requires an inner-shareable tlbi.
* We pick the reserved-ASID to minimise the impact.
*/
__tlbi(aside1is, __TLBI_VADDR(0, 0));
dsb(ish);
}
ret = __flush_cache_user_range(start, start + chunk); ret = __flush_cache_user_range(start, start + chunk);
if (ret) if (ret)
return ret; return ret;

View File

@@ -482,6 +482,15 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0); unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0);
if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) {
/* Hide DIC so that we can trap the unnecessary maintenance...*/
val &= ~BIT(CTR_DIC_SHIFT);
/* ... and fake IminLine to reduce the number of traps. */
val &= ~CTR_IMINLINE_MASK;
val |= (PAGE_SHIFT - 2) & CTR_IMINLINE_MASK;
}
pt_regs_write_reg(regs, rt, val); pt_regs_write_reg(regs, rt, val);
arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);

View File

@@ -1,5 +1,5 @@
/* /*
* VDSO implementation for AArch64 and vector page setup for AArch32. * VDSO implementations.
* *
* Copyright (C) 2012 ARM Limited * Copyright (C) 2012 ARM Limited
* *
@@ -31,90 +31,74 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/timekeeper_internal.h> #include <linux/timekeeper_internal.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
#include <vdso/vsyscall.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/signal32.h> #include <asm/signal32.h>
#include <asm/vdso.h> #include <asm/vdso.h>
#include <asm/vdso_datapage.h>
extern char vdso_start[], vdso_end[]; extern char vdso_start[], vdso_end[];
static unsigned long vdso_pages __ro_after_init; #ifdef CONFIG_COMPAT_VDSO
extern char vdso32_start[], vdso32_end[];
#endif /* CONFIG_COMPAT_VDSO */
/* vdso_lookup arch_index */
enum arch_vdso_type {
ARM64_VDSO = 0,
#ifdef CONFIG_COMPAT_VDSO
ARM64_VDSO32 = 1,
#endif /* CONFIG_COMPAT_VDSO */
};
#ifdef CONFIG_COMPAT_VDSO
#define VDSO_TYPES (ARM64_VDSO32 + 1)
#else
#define VDSO_TYPES (ARM64_VDSO + 1)
#endif /* CONFIG_COMPAT_VDSO */
struct __vdso_abi {
const char *name;
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_pages;
/* Data Mapping */
struct vm_special_mapping *dm;
/* Code Mapping */
struct vm_special_mapping *cm;
};
static struct __vdso_abi vdso_lookup[VDSO_TYPES] __ro_after_init = {
{
.name = "vdso",
.vdso_code_start = vdso_start,
.vdso_code_end = vdso_end,
},
#ifdef CONFIG_COMPAT_VDSO
{
.name = "vdso32",
.vdso_code_start = vdso32_start,
.vdso_code_end = vdso32_end,
},
#endif /* CONFIG_COMPAT_VDSO */
};
/* /*
* The vDSO data page. * The vDSO data page.
*/ */
static union { static union {
struct vdso_data data; struct vdso_data data[CS_BASES];
u8 page[PAGE_SIZE]; u8 page[PAGE_SIZE];
} vdso_data_store __page_aligned_data; } vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = &vdso_data_store.data; struct vdso_data *vdso_data = vdso_data_store.data;
#ifdef CONFIG_COMPAT static int __vdso_remap(enum arch_vdso_type arch_index,
/* const struct vm_special_mapping *sm,
* Create and map the vectors page for AArch32 tasks. struct vm_area_struct *new_vma)
*/
static struct page *vectors_page[1] __ro_after_init;
static int __init alloc_vectors_page(void)
{
extern char __kuser_helper_start[], __kuser_helper_end[];
extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
int kuser_sz = __kuser_helper_end - __kuser_helper_start;
int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
unsigned long vpage;
vpage = get_zeroed_page(GFP_ATOMIC);
if (!vpage)
return -ENOMEM;
/* kuser helpers */
memcpy((void *)vpage + 0x1000 - kuser_sz, __kuser_helper_start,
kuser_sz);
/* sigreturn code */
memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET,
__aarch32_sigret_code_start, sigret_sz);
flush_icache_range(vpage, vpage + PAGE_SIZE);
vectors_page[0] = virt_to_page(vpage);
return 0;
}
arch_initcall(alloc_vectors_page);
int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
unsigned long addr = AARCH32_VECTORS_BASE;
static const struct vm_special_mapping spec = {
.name = "[vectors]",
.pages = vectors_page,
};
void *ret;
if (down_write_killable(&mm->mmap_sem))
return -EINTR;
current->mm->context.vdso = (void *)addr;
/* Map vectors page at the high address. */
ret = _install_special_mapping(mm, addr, PAGE_SIZE,
VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC,
&spec);
up_write(&mm->mmap_sem);
return PTR_ERR_OR_ZERO(ret);
}
#endif /* CONFIG_COMPAT */
static int vdso_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{ {
unsigned long new_size = new_vma->vm_end - new_vma->vm_start; unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
unsigned long vdso_size = vdso_end - vdso_start; unsigned long vdso_size = vdso_lookup[arch_index].vdso_code_end -
vdso_lookup[arch_index].vdso_code_start;
if (vdso_size != new_size) if (vdso_size != new_size)
return -EINVAL; return -EINVAL;
@@ -124,7 +108,303 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
return 0; return 0;
} }
static struct vm_special_mapping vdso_spec[2] __ro_after_init = { static int __vdso_init(enum arch_vdso_type arch_index)
{
int i;
struct page **vdso_pagelist;
unsigned long pfn;
if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
vdso_lookup[arch_index].vdso_pages = (
vdso_lookup[arch_index].vdso_code_end -
vdso_lookup[arch_index].vdso_code_start) >>
PAGE_SHIFT;
/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_lookup[arch_index].vdso_pages + 1,
sizeof(struct page *),
GFP_KERNEL);
if (vdso_pagelist == NULL)
return -ENOMEM;
/* Grab the vDSO data page. */
vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
/* Grab the vDSO code pages. */
pfn = sym_to_pfn(vdso_lookup[arch_index].vdso_code_start);
for (i = 0; i < vdso_lookup[arch_index].vdso_pages; i++)
vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
vdso_lookup[arch_index].dm->pages = &vdso_pagelist[0];
vdso_lookup[arch_index].cm->pages = &vdso_pagelist[1];
return 0;
}
static int __setup_additional_pages(enum arch_vdso_type arch_index,
struct mm_struct *mm,
struct linux_binprm *bprm,
int uses_interp)
{
unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
void *ret;
vdso_text_len = vdso_lookup[arch_index].vdso_pages << PAGE_SHIFT;
/* Be sure to map the data page */
vdso_mapping_len = vdso_text_len + PAGE_SIZE;
vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
if (IS_ERR_VALUE(vdso_base)) {
ret = ERR_PTR(vdso_base);
goto up_fail;
}
ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
VM_READ|VM_MAYREAD,
vdso_lookup[arch_index].dm);
if (IS_ERR(ret))
goto up_fail;
vdso_base += PAGE_SIZE;
mm->context.vdso = (void *)vdso_base;
ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
vdso_lookup[arch_index].cm);
if (IS_ERR(ret))
goto up_fail;
return 0;
up_fail:
mm->context.vdso = NULL;
return PTR_ERR(ret);
}
#ifdef CONFIG_COMPAT
/*
* Create and map the vectors page for AArch32 tasks.
*/
#ifdef CONFIG_COMPAT_VDSO
static int aarch32_vdso_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{
return __vdso_remap(ARM64_VDSO32, sm, new_vma);
}
#endif /* CONFIG_COMPAT_VDSO */
/*
* aarch32_vdso_pages:
* 0 - kuser helpers
* 1 - sigreturn code
* or (CONFIG_COMPAT_VDSO):
* 0 - kuser helpers
* 1 - vdso data
* 2 - vdso code
*/
#define C_VECTORS 0
#ifdef CONFIG_COMPAT_VDSO
#define C_VVAR 1
#define C_VDSO 2
#define C_PAGES (C_VDSO + 1)
#else
#define C_SIGPAGE 1
#define C_PAGES (C_SIGPAGE + 1)
#endif /* CONFIG_COMPAT_VDSO */
static struct page *aarch32_vdso_pages[C_PAGES] __ro_after_init;
static struct vm_special_mapping aarch32_vdso_spec[C_PAGES] = {
{
.name = "[vectors]", /* ABI */
.pages = &aarch32_vdso_pages[C_VECTORS],
},
#ifdef CONFIG_COMPAT_VDSO
{
.name = "[vvar]",
},
{
.name = "[vdso]",
.mremap = aarch32_vdso_mremap,
},
#else
{
.name = "[sigpage]", /* ABI */
.pages = &aarch32_vdso_pages[C_SIGPAGE],
},
#endif /* CONFIG_COMPAT_VDSO */
};
static int aarch32_alloc_kuser_vdso_page(void)
{
extern char __kuser_helper_start[], __kuser_helper_end[];
int kuser_sz = __kuser_helper_end - __kuser_helper_start;
unsigned long vdso_page;
if (!IS_ENABLED(CONFIG_KUSER_HELPERS))
return 0;
vdso_page = get_zeroed_page(GFP_ATOMIC);
if (!vdso_page)
return -ENOMEM;
memcpy((void *)(vdso_page + 0x1000 - kuser_sz), __kuser_helper_start,
kuser_sz);
aarch32_vdso_pages[C_VECTORS] = virt_to_page(vdso_page);
flush_dcache_page(aarch32_vdso_pages[C_VECTORS]);
return 0;
}
#ifdef CONFIG_COMPAT_VDSO
static int __aarch32_alloc_vdso_pages(void)
{
int ret;
vdso_lookup[ARM64_VDSO32].dm = &aarch32_vdso_spec[C_VVAR];
vdso_lookup[ARM64_VDSO32].cm = &aarch32_vdso_spec[C_VDSO];
ret = __vdso_init(ARM64_VDSO32);
if (ret)
return ret;
ret = aarch32_alloc_kuser_vdso_page();
if (ret) {
unsigned long c_vvar =
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]);
unsigned long c_vdso =
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]);
free_page(c_vvar);
free_page(c_vdso);
}
return ret;
}
#else
static int __aarch32_alloc_vdso_pages(void)
{
extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
unsigned long sigpage;
int ret;
sigpage = get_zeroed_page(GFP_ATOMIC);
if (!sigpage)
return -ENOMEM;
memcpy((void *)sigpage, __aarch32_sigret_code_start, sigret_sz);
aarch32_vdso_pages[C_SIGPAGE] = virt_to_page(sigpage);
flush_dcache_page(aarch32_vdso_pages[C_SIGPAGE]);
ret = aarch32_alloc_kuser_vdso_page();
if (ret)
free_page(sigpage);
return ret;
}
#endif /* CONFIG_COMPAT_VDSO */
static int __init aarch32_alloc_vdso_pages(void)
{
return __aarch32_alloc_vdso_pages();
}
arch_initcall(aarch32_alloc_vdso_pages);
static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
{
void *ret;
if (!IS_ENABLED(CONFIG_KUSER_HELPERS))
return 0;
/*
* Avoid VM_MAYWRITE for compatibility with arch/arm/, where it's
* not safe to CoW the page containing the CPU exception vectors.
*/
ret = _install_special_mapping(mm, AARCH32_VECTORS_BASE, PAGE_SIZE,
VM_READ | VM_EXEC |
VM_MAYREAD | VM_MAYEXEC,
&aarch32_vdso_spec[C_VECTORS]);
return PTR_ERR_OR_ZERO(ret);
}
#ifndef CONFIG_COMPAT_VDSO
static int aarch32_sigreturn_setup(struct mm_struct *mm)
{
unsigned long addr;
void *ret;
addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
if (IS_ERR_VALUE(addr)) {
ret = ERR_PTR(addr);
goto out;
}
/*
* VM_MAYWRITE is required to allow gdb to Copy-on-Write and
* set breakpoints.
*/
ret = _install_special_mapping(mm, addr, PAGE_SIZE,
VM_READ | VM_EXEC | VM_MAYREAD |
VM_MAYWRITE | VM_MAYEXEC,
&aarch32_vdso_spec[C_SIGPAGE]);
if (IS_ERR(ret))
goto out;
mm->context.vdso = (void *)addr;
out:
return PTR_ERR_OR_ZERO(ret);
}
#endif /* !CONFIG_COMPAT_VDSO */
int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
int ret;
if (down_write_killable(&mm->mmap_sem))
return -EINTR;
ret = aarch32_kuser_helpers_setup(mm);
if (ret)
goto out;
#ifdef CONFIG_COMPAT_VDSO
ret = __setup_additional_pages(ARM64_VDSO32,
mm,
bprm,
uses_interp);
#else
ret = aarch32_sigreturn_setup(mm);
#endif /* CONFIG_COMPAT_VDSO */
out:
up_write(&mm->mmap_sem);
return ret;
}
#endif /* CONFIG_COMPAT */
static int vdso_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{
return __vdso_remap(ARM64_VDSO, sm, new_vma);
}
/*
* aarch64_vdso_pages:
* 0 - vvar
* 1 - vdso
*/
#define A_VVAR 0
#define A_VDSO 1
#define A_PAGES (A_VDSO + 1)
static struct vm_special_mapping vdso_spec[A_PAGES] __ro_after_init = {
{ {
.name = "[vvar]", .name = "[vvar]",
}, },
@@ -136,37 +416,10 @@ static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
static int __init vdso_init(void) static int __init vdso_init(void)
{ {
int i; vdso_lookup[ARM64_VDSO].dm = &vdso_spec[A_VVAR];
struct page **vdso_pagelist; vdso_lookup[ARM64_VDSO].cm = &vdso_spec[A_VDSO];
unsigned long pfn;
if (memcmp(vdso_start, "\177ELF", 4)) { return __vdso_init(ARM64_VDSO);
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
GFP_KERNEL);
if (vdso_pagelist == NULL)
return -ENOMEM;
/* Grab the vDSO data page. */
vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
/* Grab the vDSO code pages. */
pfn = sym_to_pfn(vdso_start);
for (i = 0; i < vdso_pages; i++)
vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
vdso_spec[0].pages = &vdso_pagelist[0];
vdso_spec[1].pages = &vdso_pagelist[1];
return 0;
} }
arch_initcall(vdso_init); arch_initcall(vdso_init);
@@ -174,84 +427,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp) int uses_interp)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long vdso_base, vdso_text_len, vdso_mapping_len; int ret;
void *ret;
vdso_text_len = vdso_pages << PAGE_SHIFT;
/* Be sure to map the data page */
vdso_mapping_len = vdso_text_len + PAGE_SIZE;
if (down_write_killable(&mm->mmap_sem)) if (down_write_killable(&mm->mmap_sem))
return -EINTR; return -EINTR;
vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
if (IS_ERR_VALUE(vdso_base)) {
ret = ERR_PTR(vdso_base);
goto up_fail;
}
ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
VM_READ|VM_MAYREAD,
&vdso_spec[0]);
if (IS_ERR(ret))
goto up_fail;
vdso_base += PAGE_SIZE;
mm->context.vdso = (void *)vdso_base;
ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
&vdso_spec[1]);
if (IS_ERR(ret))
goto up_fail;
ret = __setup_additional_pages(ARM64_VDSO,
mm,
bprm,
uses_interp);
up_write(&mm->mmap_sem); up_write(&mm->mmap_sem);
return 0;
up_fail: return ret;
mm->context.vdso = NULL;
up_write(&mm->mmap_sem);
return PTR_ERR(ret);
}
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
void update_vsyscall(struct timekeeper *tk)
{
u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
++vdso_data->tb_seq_count;
smp_wmb();
vdso_data->use_syscall = use_syscall;
vdso_data->xtime_coarse_sec = tk->xtime_sec;
vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
tk->tkr_mono.shift;
vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
/* Read without the seqlock held by clock_getres() */
WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution);
if (!use_syscall) {
/* tkr_mono.cycle_last == tkr_raw.cycle_last */
vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
vdso_data->raw_time_sec = tk->raw_sec;
vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
vdso_data->xtime_clock_sec = tk->xtime_sec;
vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
vdso_data->cs_mono_mult = tk->tkr_mono.mult;
vdso_data->cs_raw_mult = tk->tkr_raw.mult;
/* tkr_mono.shift == tkr_raw.shift */
vdso_data->cs_shift = tk->tkr_mono.shift;
}
smp_wmb();
++vdso_data->tb_seq_count;
}
void update_vsyscall_tz(void)
{
vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
vdso_data->tz_dsttime = sys_tz.tz_dsttime;
} }

View File

@@ -6,26 +6,51 @@
# Heavily based on the vDSO Makefiles for other archs. # Heavily based on the vDSO Makefiles for other archs.
# #
obj-vdso := gettimeofday.o note.o sigreturn.o # Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
# the inclusion of generic Makefile.
ARCH_REL_TYPE_ABS := R_AARCH64_JUMP_SLOT|R_AARCH64_GLOB_DAT|R_AARCH64_ABS64
include $(srctree)/lib/vdso/Makefile
obj-vdso := vgettimeofday.o note.o sigreturn.o
# Build rules # Build rules
targets := $(obj-vdso) vdso.so vdso.so.dbg targets := $(obj-vdso) vdso.so vdso.so.dbg
obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
ccflags-y := -shared -fno-common -fno-builtin ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \ --build-id -n -T
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
ccflags-y += $(DISABLE_LTO) ccflags-y += $(DISABLE_LTO)
CFLAGS_REMOVE_vgettimeofday.o += $(CC_FLAGS_SCS) CFLAGS_REMOVE_vgettimeofday.o += $(CC_FLAGS_SCS)
ccflags-y := -fno-common -fno-builtin -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
VDSO_LDFLAGS := -Bsymbolic
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
KBUILD_CFLAGS += $(DISABLE_LTO)
KASAN_SANITIZE := n
UBSAN_SANITIZE := n
OBJECT_FILES_NON_STANDARD := y
KCOV_INSTRUMENT := n
CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny
ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
endif
# Clang versions less than 8 do not support -mcmodel=tiny
ifeq ($(CONFIG_CC_IS_CLANG), y)
ifeq ($(shell test $(CONFIG_CLANG_VERSION) -lt 80000; echo $$?),0)
CFLAGS_REMOVE_vgettimeofday.o += -mcmodel=tiny
endif
endif
# Disable gcov profiling for VDSO code # Disable gcov profiling for VDSO code
GCOV_PROFILE := n GCOV_PROFILE := n
# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared
# down to collect2, resulting in silent corruption of the vDSO image.
ccflags-y += -Wl,-shared
obj-y += vdso.o obj-y += vdso.o
extra-y += vdso.lds extra-y += vdso.lds
CPPFLAGS_vdso.lds += -P -C -U$(ARCH) CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
@@ -35,7 +60,7 @@ $(obj)/vdso.o : $(obj)/vdso.so
# Link rule for the .so file, .lds has to be first # Link rule for the .so file, .lds has to be first
$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso)
$(call if_changed,vdsold) $(call if_changed,vdsold_and_vdso_check)
# Strip rule for the .so file # Strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S $(obj)/%.so: OBJCOPYFLAGS := -S
@@ -52,16 +77,13 @@ endef
include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
$(call if_changed,vdsosym) $(call if_changed,vdsosym)
# Assembly rules for the .S files
$(obj-vdso): %.o: %.S FORCE
$(call if_changed_dep,vdsoas)
# Actual build commands # Actual build commands
quiet_cmd_vdsold = VDSOL $@
cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
quiet_cmd_vdsoas = VDSOA $@ quiet_cmd_vdsoas = VDSOA $@
cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
quiet_cmd_vdsold_and_vdso_check = LD $@
cmd_vdsold_and_vdso_check = $(cmd_ld); $(cmd_vdso_check)
# Install commands for the unstripped file # Install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@ quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@

View File

@@ -1,334 +0,0 @@
/*
* Userspace implementations of gettimeofday() and friends.
*
* Copyright (C) 2012 ARM Limited
*
* 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/>.
*
* Author: Will Deacon <will.deacon@arm.com>
*/
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#define NSEC_PER_SEC_LO16 0xca00
#define NSEC_PER_SEC_HI16 0x3b9a
vdso_data .req x6
seqcnt .req w7
w_tmp .req w8
x_tmp .req x8
/*
* Conventions for macro arguments:
* - An argument is write-only if its name starts with "res".
* - All other arguments are read-only, unless otherwise specified.
*/
.macro seqcnt_acquire
9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
tbnz seqcnt, #0, 9999b
dmb ishld
.endm
.macro seqcnt_check fail
dmb ishld
ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT]
cmp w_tmp, seqcnt
b.ne \fail
.endm
.macro syscall_check fail
ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL]
cbnz w_tmp, \fail
.endm
.macro get_nsec_per_sec res
mov \res, #NSEC_PER_SEC_LO16
movk \res, #NSEC_PER_SEC_HI16, lsl #16
.endm
/*
* Returns the clock delta, in nanoseconds left-shifted by the clock
* shift.
*/
.macro get_clock_shifted_nsec res, cycle_last, mult
/* Read the virtual counter. */
isb
mrs x_tmp, cntvct_el0
/* Calculate cycle delta and convert to ns. */
sub \res, x_tmp, \cycle_last
/* We can only guarantee 56 bits of precision. */
movn x_tmp, #0xff00, lsl #48
and \res, x_tmp, \res
mul \res, \res, \mult
/*
* Fake address dependency from the value computed from the counter
* register to subsequent data page accesses so that the sequence
* locking also orders the read of the counter.
*/
and x_tmp, \res, xzr
add vdso_data, vdso_data, x_tmp
.endm
/*
* Returns in res_{sec,nsec} the REALTIME timespec, based on the
* "wall time" (xtime) and the clock_mono delta.
*/
.macro get_ts_realtime res_sec, res_nsec, \
clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec
add \res_nsec, \clock_nsec, \xtime_nsec
udiv x_tmp, \res_nsec, \nsec_to_sec
add \res_sec, \xtime_sec, x_tmp
msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec
.endm
/*
* Returns in res_{sec,nsec} the timespec based on the clock_raw delta,
* used for CLOCK_MONOTONIC_RAW.
*/
.macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec
udiv \res_sec, \clock_nsec, \nsec_to_sec
msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec
.endm
/* sec and nsec are modified in place. */
.macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec
/* Add timespec. */
add \sec, \sec, \ts_sec
add \nsec, \nsec, \ts_nsec
/* Normalise the new timespec. */
cmp \nsec, \nsec_to_sec
b.lt 9999f
sub \nsec, \nsec, \nsec_to_sec
add \sec, \sec, #1
9999:
cmp \nsec, #0
b.ge 9998f
add \nsec, \nsec, \nsec_to_sec
sub \sec, \sec, #1
9998:
.endm
.macro clock_gettime_return, shift=0
.if \shift == 1
lsr x11, x11, x12
.endif
stp x10, x11, [x1, #TSPEC_TV_SEC]
mov x0, xzr
ret
.endm
.macro jump_slot jumptable, index, label
.if (. - \jumptable) != 4 * (\index)
.error "Jump slot index mismatch"
.endif
b \label
.endm
.text
/* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
ENTRY(__kernel_gettimeofday)
.cfi_startproc
adr vdso_data, _vdso_data
/* If tv is NULL, skip to the timezone code. */
cbz x0, 2f
/* Compute the time of day. */
1: seqcnt_acquire
syscall_check fail=4f
ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
/* w11 = cs_mono_mult, w12 = cs_shift */
ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
get_nsec_per_sec res=x9
lsl x9, x9, x12
get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
seqcnt_check fail=1b
get_ts_realtime res_sec=x10, res_nsec=x11, \
clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
/* Convert ns to us. */
mov x13, #1000
lsl x13, x13, x12
udiv x11, x11, x13
stp x10, x11, [x0, #TVAL_TV_SEC]
2:
/* If tz is NULL, return 0. */
cbz x1, 3f
ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
stp w4, w5, [x1, #TZ_MINWEST]
3:
mov x0, xzr
ret
4:
/* Syscall fallback. */
mov x8, #__NR_gettimeofday
svc #0
ret
.cfi_endproc
ENDPROC(__kernel_gettimeofday)
#define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE
/* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
ENTRY(__kernel_clock_gettime)
.cfi_startproc
cmp w0, #JUMPSLOT_MAX
b.hi syscall
adr vdso_data, _vdso_data
adr x_tmp, jumptable
add x_tmp, x_tmp, w0, uxtw #2
br x_tmp
ALIGN
jumptable:
jump_slot jumptable, CLOCK_REALTIME, realtime
jump_slot jumptable, CLOCK_MONOTONIC, monotonic
b syscall
b syscall
jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw
jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse
jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse
.if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1)
.error "Wrong jumptable size"
.endif
ALIGN
realtime:
seqcnt_acquire
syscall_check fail=syscall
ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
/* w11 = cs_mono_mult, w12 = cs_shift */
ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
/* All computations are done with left-shifted nsecs. */
get_nsec_per_sec res=x9
lsl x9, x9, x12
get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
seqcnt_check fail=realtime
get_ts_realtime res_sec=x10, res_nsec=x11, \
clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
clock_gettime_return, shift=1
ALIGN
monotonic:
seqcnt_acquire
syscall_check fail=syscall
ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
/* w11 = cs_mono_mult, w12 = cs_shift */
ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC]
/* All computations are done with left-shifted nsecs. */
lsl x4, x4, x12
get_nsec_per_sec res=x9
lsl x9, x9, x12
get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
seqcnt_check fail=monotonic
get_ts_realtime res_sec=x10, res_nsec=x11, \
clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9
clock_gettime_return, shift=1
ALIGN
monotonic_raw:
seqcnt_acquire
syscall_check fail=syscall
ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
/* w11 = cs_raw_mult, w12 = cs_shift */
ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT]
ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC]
/* All computations are done with left-shifted nsecs. */
get_nsec_per_sec res=x9
lsl x9, x9, x12
get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
seqcnt_check fail=monotonic_raw
get_ts_clock_raw res_sec=x10, res_nsec=x11, \
clock_nsec=x15, nsec_to_sec=x9
add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
clock_gettime_return, shift=1
ALIGN
realtime_coarse:
seqcnt_acquire
ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
seqcnt_check fail=realtime_coarse
clock_gettime_return
ALIGN
monotonic_coarse:
seqcnt_acquire
ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC]
seqcnt_check fail=monotonic_coarse
/* Computations are done in (non-shifted) nsecs. */
get_nsec_per_sec res=x9
add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
clock_gettime_return
ALIGN
syscall: /* Syscall fallback. */
mov x8, #__NR_clock_gettime
svc #0
ret
.cfi_endproc
ENDPROC(__kernel_clock_gettime)
/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
ENTRY(__kernel_clock_getres)
.cfi_startproc
cmp w0, #CLOCK_REALTIME
ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
b.ne 1f
adr vdso_data, _vdso_data
ldr w2, [vdso_data, #CLOCK_REALTIME_RES]
b 2f
1:
cmp w0, #CLOCK_REALTIME_COARSE
ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
b.ne 4f
ldr x2, 5f
2:
cbz x1, 3f
stp xzr, x2, [x1]
3: /* res == NULL. */
mov w0, wzr
ret
4: /* Syscall fallback. */
mov x8, #__NR_clock_getres
svc #0
ret
5:
.quad CLOCK_COARSE_RES
.cfi_endproc
ENDPROC(__kernel_clock_getres)

View File

@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
/*
* ARM64 userspace implementations of gettimeofday() and similar.
*
* Copyright (C) 2018 ARM Limited
*
*/
int __kernel_clock_gettime(clockid_t clock,
struct __kernel_timespec *ts)
{
return __cvdso_clock_gettime(clock, ts);
}
int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
struct timezone *tz)
{
return __cvdso_gettimeofday(tv, tz);
}
int __kernel_clock_getres(clockid_t clock_id,
struct __kernel_timespec *res)
{
return __cvdso_clock_getres(clock_id, res);
}

2
arch/arm64/kernel/vdso32/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
vdso.lds
vdso.so.raw

View File

@@ -0,0 +1,211 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for vdso32
#
# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
# the inclusion of generic Makefile.
ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32
include $(srctree)/lib/vdso/Makefile
# Same as cc-*option, but using CC_COMPAT instead of CC
ifeq ($(CONFIG_CC_IS_CLANG), y)
COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)
CC_COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
CC_COMPAT_CLANG_FLAGS += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
CC_COMPAT_CLANG_FLAGS += -no-integrated-as -Qunused-arguments
ifneq ($(COMPAT_GCC_TOOLCHAIN),)
CC_COMPAT_CLANG_FLAGS += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
endif
CC_COMPAT ?= $(CC)
CC_COMPAT += $(CC_COMPAT_CLANG_FLAGS)
else
CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
endif
cc32-option = $(call try-run,\
$(CC_COMPAT) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
cc32-disable-warning = $(call try-run,\
$(CC_COMPAT) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
cc32-ldoption = $(call try-run,\
$(CC_COMPAT) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
cc32-as-instr = $(call try-run,\
printf "%b\n" "$(1)" | $(CC_COMPAT) $(VDSO_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
# We cannot use the global flags to compile the vDSO files, the main reason
# being that the 32-bit compiler may be older than the main (64-bit) compiler
# and therefore may not understand flags set using $(cc-option ...). Besides,
# arch-specific options should be taken from the arm Makefile instead of the
# arm64 one.
# As a result we set our own flags here.
# KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile
VDSO_CPPFLAGS := -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include)
VDSO_CPPFLAGS += $(LINUXINCLUDE)
# Common C and assembly flags
# From top-level Makefile
VDSO_CAFLAGS := $(VDSO_CPPFLAGS)
ifneq ($(shell $(CC_COMPAT) --version 2>&1 | head -n 1 | grep clang),)
VDSO_CAFLAGS += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
endif
VDSO_CAFLAGS += $(call cc32-option,-fno-PIE)
ifdef CONFIG_DEBUG_INFO
VDSO_CAFLAGS += -g
endif
# From arm Makefile
VDSO_CAFLAGS += $(call cc32-option,-fno-dwarf2-cfi-asm)
VDSO_CAFLAGS += -mabi=aapcs-linux -mfloat-abi=soft
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
VDSO_CAFLAGS += -mbig-endian
else
VDSO_CAFLAGS += -mlittle-endian
endif
# From arm vDSO Makefile
VDSO_CAFLAGS += -fPIC -fno-builtin -fno-stack-protector
VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING
# Try to compile for ARMv8. If the compiler is too old and doesn't support it,
# fall back to v7. There is no easy way to check for what architecture the code
# is being compiled, so define a macro specifying that (see arch/arm/Makefile).
VDSO_CAFLAGS += $(call cc32-option,-march=armv8-a -D__LINUX_ARM_ARCH__=8,\
-march=armv7-a -D__LINUX_ARM_ARCH__=7)
VDSO_CFLAGS := $(VDSO_CAFLAGS)
VDSO_CFLAGS += -DENABLE_COMPAT_VDSO=1
# KBUILD_CFLAGS from top-level Makefile
VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration \
-Wno-format-security \
-std=gnu89
VDSO_CFLAGS += -O2
# Some useful compiler-dependent flags from top-level Makefile
VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,)
VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign)
VDSO_CFLAGS += $(call cc32-option,-fno-strict-overflow)
VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes)
VDSO_CFLAGS += $(call cc32-option,-Werror=date-time)
VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types)
# The 32-bit compiler does not provide 128-bit integers, which are used in
# some headers that are indirectly included from the vDSO code.
# This hack makes the compiler happy and should trigger a warning/error if
# variables of such type are referenced.
VDSO_CFLAGS += -D__uint128_t='void*'
# Silence some warnings coming from headers that operate on long's
# (on GCC 4.8 or older, there is unfortunately no way to silence this warning)
VDSO_CFLAGS += $(call cc32-disable-warning,shift-count-overflow)
VDSO_CFLAGS += -Wno-int-to-pointer-cast
VDSO_AFLAGS := $(VDSO_CAFLAGS)
VDSO_AFLAGS += -D__ASSEMBLY__
# Check for binutils support for dmb ishld
dmbinstr := $(call cc32-as-instr,dmb ishld,-DCONFIG_AS_DMB_ISHLD=1)
VDSO_CFLAGS += $(dmbinstr)
VDSO_AFLAGS += $(dmbinstr)
VDSO_LDFLAGS := $(VDSO_CPPFLAGS)
# From arm vDSO Makefile
VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1
VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
VDSO_LDFLAGS += -nostdlib -shared -mfloat-abi=soft
VDSO_LDFLAGS += $(call cc32-ldoption,-Wl$(comma)--hash-style=sysv)
VDSO_LDFLAGS += $(call cc32-ldoption,-Wl$(comma)--build-id)
VDSO_LDFLAGS += $(call cc32-ldoption,-fuse-ld=bfd)
# Borrow vdsomunge.c from the arm vDSO
# We have to use a relative path because scripts/Makefile.host prefixes
# $(hostprogs-y) with $(obj)
munge := ../../../arm/vdso/vdsomunge
hostprogs-y := $(munge)
c-obj-vdso := note.o
c-obj-vdso-gettimeofday := vgettimeofday.o
asm-obj-vdso := sigreturn.o
ifneq ($(c-gettimeofday-y),)
VDSO_CFLAGS_gettimeofday_o += -include $(c-gettimeofday-y)
endif
VDSO_CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
# Build rules
targets := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) vdso.so vdso.so.dbg vdso.so.raw
c-obj-vdso := $(addprefix $(obj)/, $(c-obj-vdso))
c-obj-vdso-gettimeofday := $(addprefix $(obj)/, $(c-obj-vdso-gettimeofday))
asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso))
obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso)
obj-y += vdso.o
extra-y += vdso.lds
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
# Force dependency (vdso.s includes vdso.so through incbin)
$(obj)/vdso.o: $(obj)/vdso.so
include/generated/vdso32-offsets.h: $(obj)/vdso.so.dbg FORCE
$(call if_changed,vdsosym)
# Strip rule for vdso.so
$(obj)/vdso.so: OBJCOPYFLAGS := -S
$(obj)/vdso.so: $(obj)/vdso.so.dbg FORCE
$(call if_changed,objcopy)
$(obj)/vdso.so.dbg: $(obj)/vdso.so.raw $(obj)/$(munge) FORCE
$(call if_changed,vdsomunge)
# Link rule for the .so file, .lds has to be first
$(obj)/vdso.so.raw: $(src)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold_and_vdso_check)
# Compilation rules for the vDSO sources
$(c-obj-vdso): %.o: %.c FORCE
$(call if_changed_dep,vdsocc)
$(c-obj-vdso-gettimeofday): %.o: %.c FORCE
$(call if_changed_dep,vdsocc_gettimeofday)
$(asm-obj-vdso): %.o: %.S FORCE
$(call if_changed_dep,vdsoas)
# Actual build commands
quiet_cmd_vdsold_and_vdso_check = LD32 $@
cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check)
quiet_cmd_vdsold = LD32 $@
cmd_vdsold = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \
-Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
quiet_cmd_vdsocc = CC32 $@
cmd_vdsocc = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $<
quiet_cmd_vdsocc_gettimeofday = CC32 $@
cmd_vdsocc_gettimeofday = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $<
quiet_cmd_vdsoas = AS32 $@
cmd_vdsoas = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $<
quiet_cmd_vdsomunge = MUNGE $@
cmd_vdsomunge = $(obj)/$(munge) $< $@
# Generate vDSO offsets using helper script (borrowed from the 64-bit vDSO)
gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
quiet_cmd_vdsosym = VDSOSYM $@
# The AArch64 nm should be able to read an AArch32 binary
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
# Install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/vdso32.so
vdso.so: $(obj)/vdso.so.dbg
@mkdir -p $(MODLIB)/vdso
$(call cmd,vdso_install)
vdso_install: vdso.so

View File

@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2012-2018 ARM Limited
*
* This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
* Here we can supply some information useful to userland.
*/
#include <linux/uts.h>
#include <linux/version.h>
#include <linux/elfnote.h>
#include <linux/build-salt.h>
ELFNOTE32("Linux", 0, LINUX_VERSION_CODE);
BUILD_SALT;

View File

@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This file provides both A32 and T32 versions, in accordance with the
* arm sigreturn code.
*
* Copyright (C) 2018 ARM Limited
*/
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#define ARM_ENTRY(name) \
ENTRY(name)
#define ARM_ENDPROC(name) \
.type name, %function; \
END(name)
.text
.arm
.fnstart
.save {r0-r15}
.pad #COMPAT_SIGFRAME_REGS_OFFSET
nop
ARM_ENTRY(__kernel_sigreturn_arm)
mov r7, #__NR_compat_sigreturn
svc #0
.fnend
ARM_ENDPROC(__kernel_sigreturn_arm)
.fnstart
.save {r0-r15}
.pad #COMPAT_RT_SIGFRAME_REGS_OFFSET
nop
ARM_ENTRY(__kernel_rt_sigreturn_arm)
mov r7, #__NR_compat_rt_sigreturn
svc #0
.fnend
ARM_ENDPROC(__kernel_rt_sigreturn_arm)
.thumb
.fnstart
.save {r0-r15}
.pad #COMPAT_SIGFRAME_REGS_OFFSET
nop
ARM_ENTRY(__kernel_sigreturn_thumb)
mov r7, #__NR_compat_sigreturn
svc #0
.fnend
ARM_ENDPROC(__kernel_sigreturn_thumb)
.fnstart
.save {r0-r15}
.pad #COMPAT_RT_SIGFRAME_REGS_OFFSET
nop
ARM_ENTRY(__kernel_rt_sigreturn_thumb)
mov r7, #__NR_compat_rt_sigreturn
svc #0
.fnend
ARM_ENDPROC(__kernel_rt_sigreturn_thumb)

View File

@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2012 ARM Limited
*/
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/const.h>
#include <asm/page.h>
.globl vdso32_start, vdso32_end
.section .rodata
.balign PAGE_SIZE
vdso32_start:
.incbin "arch/arm64/kernel/vdso32/vdso.so"
.balign PAGE_SIZE
vdso32_end:
.previous

View File

@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Adapted from arm64 version.
*
* GNU linker script for the VDSO library.
* Heavily based on the vDSO linker scripts for other archs.
*
* Copyright (C) 2012-2018 ARM Limited
*/
#include <linux/const.h>
#include <asm/page.h>
#include <asm/vdso.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SECTIONS
{
PROVIDE_HIDDEN(_vdso_data = . - PAGE_SIZE);
. = VDSO_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.note : { *(.note.*) } :text :note
.dynamic : { *(.dynamic) } :text :dynamic
.rodata : { *(.rodata*) } :text
.text : { *(.text*) } :text =0xe7f001f2
.got : { *(.got) }
.rel.plt : { *(.rel.plt) }
/DISCARD/ : {
*(.note.GNU-stack)
*(.data .data.* .gnu.linkonce.d.* .sdata*)
*(.bss .sbss .dynbss .dynsbss)
}
}
/*
* We must supply the ELF program headers explicitly to get just one
* PT_LOAD segment, and set the flags explicitly to make segments read-only.
*/
PHDRS
{
text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
note PT_NOTE FLAGS(4); /* PF_R */
}
VERSION
{
LINUX_2.6 {
global:
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_clock_getres;
__kernel_sigreturn_arm;
__kernel_sigreturn_thumb;
__kernel_rt_sigreturn_arm;
__kernel_rt_sigreturn_thumb;
__vdso_clock_gettime64;
local: *;
};
}
/*
* Make the sigreturn code visible to the kernel.
*/
VDSO_compat_sigreturn_arm = __kernel_sigreturn_arm;
VDSO_compat_sigreturn_thumb = __kernel_sigreturn_thumb;
VDSO_compat_rt_sigreturn_arm = __kernel_rt_sigreturn_arm;
VDSO_compat_rt_sigreturn_thumb = __kernel_rt_sigreturn_thumb;

View File

@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0
/*
* ARM64 compat userspace implementations of gettimeofday() and similar.
*
* Copyright (C) 2018 ARM Limited
*
*/
int __vdso_clock_gettime(clockid_t clock,
struct old_timespec32 *ts)
{
return __cvdso_clock_gettime32(clock, ts);
}
int __vdso_clock_gettime64(clockid_t clock,
struct __kernel_timespec *ts)
{
return __cvdso_clock_gettime(clock, ts);
}
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
struct timezone *tz)
{
return __cvdso_gettimeofday(tv, tz);
}
int __vdso_clock_getres(clockid_t clock_id,
struct old_timespec32 *res)
{
return __cvdso_clock_getres_time32(clock_id, res);
}
/* Avoid unresolved references emitted by GCC */
void __aeabi_unwind_cpp_pr0(void)
{
}
void __aeabi_unwind_cpp_pr1(void)
{
}
void __aeabi_unwind_cpp_pr2(void)
{
}

View File

@@ -179,6 +179,13 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
} }
memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id)); memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id));
if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) {
int i;
for (i = 0; i < 16; i++)
*vcpu_reg32(vcpu, i) = (u32)*vcpu_reg32(vcpu, i);
}
out: out:
return err; return err;
} }

View File

@@ -230,7 +230,7 @@ ENTRY(__inval_dcache_area)
* - start - virtual start address of region * - start - virtual start address of region
* - size - size in question * - size - size in question
*/ */
__dma_inv_area: ENTRY(__dma_inv_area)
add x1, x1, x0 add x1, x1, x0
dcache_line_size x2, x3 dcache_line_size x2, x3
sub x3, x2, #1 sub x3, x2, #1
@@ -269,7 +269,7 @@ ENTRY(__clean_dcache_area_poc)
* - start - virtual start address of region * - start - virtual start address of region
* - size - size in question * - size - size in question
*/ */
__dma_clean_area: ENTRY(__dma_clean_area)
dcache_by_line_op cvac, sy, x0, x1, x2, x3 dcache_by_line_op cvac, sy, x0, x1, x2, x3
ret ret
ENDPIPROC(__clean_dcache_area_poc) ENDPIPROC(__clean_dcache_area_poc)

View File

@@ -26,26 +26,47 @@
#include <linux/genalloc.h> #include <linux/genalloc.h>
#include <linux/dma-direct.h> #include <linux/dma-direct.h>
#include <linux/dma-contiguous.h> #include <linux/dma-contiguous.h>
#include <linux/mm.h>
#include <linux/iommu.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/swiotlb.h> #include <linux/swiotlb.h>
#include <linux/dma-removed.h> #include <linux/dma-removed.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/dma-iommu.h>
#include <linux/of_address.h>
#include <linux/dma-mapping-fast.h>
static int swiotlb __ro_after_init; static int swiotlb __ro_after_init;
static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
bool coherent) bool coherent)
{ {
if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE)) if (attrs & DMA_ATTR_STRONGLY_ORDERED)
return pgprot_noncached(prot);
else if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE))
return pgprot_writecombine(prot); return pgprot_writecombine(prot);
return prot; return prot;
} }
static bool is_dma_coherent(struct device *dev, unsigned long attrs)
{
if (attrs & DMA_ATTR_FORCE_COHERENT)
return true;
else if (attrs & DMA_ATTR_FORCE_NON_COHERENT)
return false;
else if (is_device_dma_coherent(dev))
return true;
else
return false;
}
static struct gen_pool *atomic_pool __ro_after_init; static struct gen_pool *atomic_pool __ro_after_init;
#define NO_KERNEL_MAPPING_DUMMY 0x2222
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE;
@@ -93,13 +114,50 @@ static int __free_from_pool(void *start, size_t size)
return 1; return 1;
} }
static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
void *data)
{
struct page *page = virt_to_page(addr);
pgprot_t prot = *(pgprot_t *)data;
set_pte(pte, mk_pte(page, prot));
return 0;
}
static int __dma_clear_pte(pte_t *pte, pgtable_t token, unsigned long addr,
void *data)
{
pte_clear(&init_mm, addr, pte);
return 0;
}
static void __dma_remap(struct page *page, size_t size, pgprot_t prot,
bool no_kernel_map)
{
unsigned long start = (unsigned long) page_address(page);
unsigned long end = start + size;
int (*func)(pte_t *pte, pgtable_t token, unsigned long addr,
void *data);
if (no_kernel_map)
func = __dma_clear_pte;
else
func = __dma_update_pte;
apply_to_page_range(&init_mm, start, size, func, &prot);
/* ensure prot is applied before returning */
mb();
flush_tlb_kernel_range(start, end);
}
static void *__dma_alloc(struct device *dev, size_t size, static void *__dma_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags, dma_addr_t *dma_handle, gfp_t flags,
unsigned long attrs) unsigned long attrs)
{ {
struct page *page; struct page *page;
void *ptr, *coherent_ptr; void *ptr, *coherent_ptr;
bool coherent = is_device_dma_coherent(dev); bool coherent = is_dma_coherent(dev, attrs);
pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false); pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false);
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
@@ -115,6 +173,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
} }
ptr = swiotlb_alloc(dev, size, dma_handle, flags, attrs); ptr = swiotlb_alloc(dev, size, dma_handle, flags, attrs);
if (!ptr) if (!ptr)
goto no_mem; goto no_mem;
@@ -122,19 +181,31 @@ static void *__dma_alloc(struct device *dev, size_t size,
if (coherent) if (coherent)
return ptr; return ptr;
/* remove any dirty cache lines on the kernel alias */
__dma_flush_area(ptr, size); __dma_flush_area(ptr, size);
/* create a coherent mapping */ if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
page = virt_to_page(ptr); coherent_ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP, __dma_remap(virt_to_page(ptr), size, __pgprot(0), true);
prot, __builtin_return_address(0)); } else {
if (!coherent_ptr) if ((attrs & DMA_ATTR_STRONGLY_ORDERED))
goto no_map; __dma_remap(virt_to_page(ptr), size, __pgprot(0), true);
/* create a coherent mapping */
page = virt_to_page(ptr);
coherent_ptr = dma_common_contiguous_remap(
page, size, VM_USERMAP, prot,
__builtin_return_address(0));
if (!coherent_ptr)
goto no_map;
}
return coherent_ptr; return coherent_ptr;
no_map: no_map:
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
(attrs & DMA_ATTR_STRONGLY_ORDERED))
__dma_remap(phys_to_page(dma_to_phys(dev, *dma_handle)),
size, PAGE_KERNEL, false);
swiotlb_free(dev, size, ptr, *dma_handle, attrs); swiotlb_free(dev, size, ptr, *dma_handle, attrs);
no_mem: no_mem:
return NULL; return NULL;
@@ -148,11 +219,17 @@ static void __dma_free(struct device *dev, size_t size,
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
if (!is_device_dma_coherent(dev)) { if (!is_dma_coherent(dev, attrs)) {
if (__free_from_pool(vaddr, size)) if (__free_from_pool(vaddr, size))
return; return;
vunmap(vaddr); if (!(attrs & DMA_ATTR_NO_KERNEL_MAPPING))
vunmap(vaddr);
} }
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
(attrs & DMA_ATTR_STRONGLY_ORDERED))
__dma_remap(phys_to_page(dma_to_phys(dev, dma_handle)),
size, PAGE_KERNEL, false);
swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs); swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs);
} }
@@ -164,7 +241,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
dma_addr_t dev_addr; dma_addr_t dev_addr;
dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs); dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs);
if (!is_device_dma_coherent(dev) && if (!is_dma_coherent(dev, attrs) &&
(attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
__dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
@@ -176,7 +253,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
size_t size, enum dma_data_direction dir, size_t size, enum dma_data_direction dir,
unsigned long attrs) unsigned long attrs)
{ {
if (!is_device_dma_coherent(dev) && if (!is_dma_coherent(dev, attrs) &&
(attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
__dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
swiotlb_unmap_page(dev, dev_addr, size, dir, attrs); swiotlb_unmap_page(dev, dev_addr, size, dir, attrs);
@@ -190,7 +267,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
int i, ret; int i, ret;
ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs); ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
if (!is_device_dma_coherent(dev) && if (!is_dma_coherent(dev, attrs) &&
(attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
for_each_sg(sgl, sg, ret, i) for_each_sg(sgl, sg, ret, i)
__dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
@@ -207,7 +284,7 @@ static void __swiotlb_unmap_sg_attrs(struct device *dev,
struct scatterlist *sg; struct scatterlist *sg;
int i; int i;
if (!is_device_dma_coherent(dev) && if (!is_dma_coherent(dev, attrs) &&
(attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
for_each_sg(sgl, sg, nelems, i) for_each_sg(sgl, sg, nelems, i)
__dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
@@ -284,11 +361,11 @@ static int __swiotlb_mmap(struct device *dev,
void *cpu_addr, dma_addr_t dma_addr, size_t size, void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs) unsigned long attrs)
{ {
int ret; int ret = -ENXIO;
unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT; unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT;
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
is_device_dma_coherent(dev)); is_dma_coherent(dev, attrs));
if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret; return ret;
@@ -447,7 +524,7 @@ static int __init atomic_pool_init(void)
goto out; goto out;
remove_mapping: remove_mapping:
dma_common_free_remap(addr, atomic_pool_size, VM_USERMAP); dma_common_free_remap(addr, atomic_pool_size, VM_USERMAP, false);
destroy_genpool: destroy_genpool:
gen_pool_destroy(atomic_pool); gen_pool_destroy(atomic_pool);
atomic_pool = NULL; atomic_pool = NULL;
@@ -468,6 +545,7 @@ static void *__dummy_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags, dma_addr_t *dma_handle, gfp_t flags,
unsigned long attrs) unsigned long attrs)
{ {
WARN(1, "dma alloc failure, device may be missing a call to arch_setup_dma_ops");
return NULL; return NULL;
} }
@@ -582,7 +660,7 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t gfp, dma_addr_t *handle, gfp_t gfp,
unsigned long attrs) unsigned long attrs)
{ {
bool coherent = is_device_dma_coherent(dev); bool coherent = is_dma_coherent(dev, attrs);
int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs); int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs);
size_t iosize = size; size_t iosize = size;
void *addr; void *addr;
@@ -596,7 +674,8 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
* Some drivers rely on this, and we probably don't want the * Some drivers rely on this, and we probably don't want the
* possibility of stale kernel data being read by devices anyway. * possibility of stale kernel data being read by devices anyway.
*/ */
gfp |= __GFP_ZERO; if (!(attrs & DMA_ATTR_SKIP_ZEROING))
gfp |= __GFP_ZERO;
if (!gfpflags_allow_blocking(gfp)) { if (!gfpflags_allow_blocking(gfp)) {
struct page *page; struct page *page;
@@ -688,17 +767,16 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
__free_from_pool(cpu_addr, size); __free_from_pool(cpu_addr, size);
} else if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { } else if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
struct page *page = vmalloc_to_page(cpu_addr); struct page *page = vmalloc_to_page(cpu_addr);
iommu_dma_unmap_page(dev, handle, iosize, 0, attrs); iommu_dma_unmap_page(dev, handle, iosize, 0, attrs);
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
dma_common_free_remap(cpu_addr, size, VM_USERMAP); dma_common_free_remap(cpu_addr, size, VM_USERMAP, false);
} else if (is_vmalloc_addr(cpu_addr)){ } else if (is_vmalloc_addr(cpu_addr)) {
struct vm_struct *area = find_vm_area(cpu_addr); struct vm_struct *area = find_vm_area(cpu_addr);
if (WARN_ON(!area || !area->pages)) if (WARN_ON(!area || !area->pages))
return; return;
iommu_dma_free(dev, area->pages, iosize, &handle); iommu_dma_free(dev, area->pages, iosize, &handle);
dma_common_free_remap(cpu_addr, size, VM_USERMAP); dma_common_free_remap(cpu_addr, size, VM_USERMAP, false);
} else { } else {
iommu_dma_unmap_page(dev, handle, iosize, 0, 0); iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
__free_pages(virt_to_page(cpu_addr), get_order(size)); __free_pages(virt_to_page(cpu_addr), get_order(size));
@@ -711,32 +789,31 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
{ {
struct vm_struct *area; struct vm_struct *area;
int ret; int ret;
unsigned long pfn = 0;
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
is_device_dma_coherent(dev)); is_dma_coherent(dev, attrs));
if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret; return ret;
if (!is_vmalloc_addr(cpu_addr)) {
unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
return __swiotlb_mmap_pfn(vma, pfn, size);
}
if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
/*
* DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped,
* hence in the vmalloc space.
*/
unsigned long pfn = vmalloc_to_pfn(cpu_addr);
return __swiotlb_mmap_pfn(vma, pfn, size);
}
area = find_vm_area(cpu_addr); area = find_vm_area(cpu_addr);
if (WARN_ON(!area || !area->pages))
return -ENXIO;
return iommu_dma_mmap(area->pages, size, vma); if (area && area->pages)
return iommu_dma_mmap(area->pages, size, vma);
else if (!is_vmalloc_addr(cpu_addr))
pfn = page_to_pfn(virt_to_page(cpu_addr));
else if (is_vmalloc_addr(cpu_addr))
/*
* DMA_ATTR_FORCE_CONTIGUOUS and atomic pool allocations are
* always remapped, hence in the vmalloc space.
*/
pfn = vmalloc_to_pfn(cpu_addr);
if (pfn)
return __swiotlb_mmap_pfn(vma, pfn, size);
return -ENXIO;
} }
static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
@@ -744,27 +821,24 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
size_t size, unsigned long attrs) size_t size, unsigned long attrs)
{ {
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
struct page *page = NULL;
struct vm_struct *area = find_vm_area(cpu_addr); struct vm_struct *area = find_vm_area(cpu_addr);
if (!is_vmalloc_addr(cpu_addr)) { if (area && area->pages)
struct page *page = virt_to_page(cpu_addr); return sg_alloc_table_from_pages(sgt, area->pages, count, 0,
return __swiotlb_get_sgtable_page(sgt, page, size); size, GFP_KERNEL);
} else if (!is_vmalloc_addr(cpu_addr))
page = virt_to_page(cpu_addr);
if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) { else if (is_vmalloc_addr(cpu_addr))
/* /*
* DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped, * DMA_ATTR_FORCE_CONTIGUOUS and atomic pool allocations
* hence in the vmalloc space. * are always remapped, hence in the vmalloc space.
*/ */
struct page *page = vmalloc_to_page(cpu_addr); page = vmalloc_to_page(cpu_addr);
if (page)
return __swiotlb_get_sgtable_page(sgt, page, size); return __swiotlb_get_sgtable_page(sgt, page, size);
} return -ENXIO;
if (WARN_ON(!area || !area->pages))
return -ENXIO;
return sg_alloc_table_from_pages(sgt, area->pages, count, 0, size,
GFP_KERNEL);
} }
static void __iommu_sync_single_for_cpu(struct device *dev, static void __iommu_sync_single_for_cpu(struct device *dev,
@@ -772,11 +846,12 @@ static void __iommu_sync_single_for_cpu(struct device *dev,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
phys_addr_t phys; phys_addr_t phys;
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
if (is_device_dma_coherent(dev)) if (!domain || iommu_is_iova_coherent(domain, dev_addr))
return; return;
phys = iommu_iova_to_phys(iommu_get_domain_for_dev(dev), dev_addr); phys = iommu_iova_to_phys(domain, dev_addr);
__dma_unmap_area(phys_to_virt(phys), size, dir); __dma_unmap_area(phys_to_virt(phys), size, dir);
} }
@@ -785,11 +860,12 @@ static void __iommu_sync_single_for_device(struct device *dev,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
phys_addr_t phys; phys_addr_t phys;
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
if (is_device_dma_coherent(dev)) if (!domain || iommu_is_iova_coherent(domain, dev_addr))
return; return;
phys = iommu_iova_to_phys(iommu_get_domain_for_dev(dev), dev_addr); phys = iommu_iova_to_phys(domain, dev_addr);
__dma_map_area(phys_to_virt(phys), size, dir); __dma_map_area(phys_to_virt(phys), size, dir);
} }
@@ -798,7 +874,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
enum dma_data_direction dir, enum dma_data_direction dir,
unsigned long attrs) unsigned long attrs)
{ {
bool coherent = is_device_dma_coherent(dev); bool coherent = is_dma_coherent(dev, attrs);
int prot = dma_info_to_prot(dir, coherent, attrs); int prot = dma_info_to_prot(dir, coherent, attrs);
dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot); dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot);
@@ -824,9 +900,11 @@ static void __iommu_sync_sg_for_cpu(struct device *dev,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
struct scatterlist *sg; struct scatterlist *sg;
dma_addr_t iova = sg_dma_address(sgl);
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
int i; int i;
if (is_device_dma_coherent(dev)) if (!domain || iommu_is_iova_coherent(domain, iova))
return; return;
for_each_sg(sgl, sg, nelems, i) for_each_sg(sgl, sg, nelems, i)
@@ -838,9 +916,11 @@ static void __iommu_sync_sg_for_device(struct device *dev,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
struct scatterlist *sg; struct scatterlist *sg;
dma_addr_t iova = sg_dma_address(sgl);
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
int i; int i;
if (is_device_dma_coherent(dev)) if (!domain || iommu_is_iova_coherent(domain, iova))
return; return;
for_each_sg(sgl, sg, nelems, i) for_each_sg(sgl, sg, nelems, i)
@@ -851,13 +931,18 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
int nelems, enum dma_data_direction dir, int nelems, enum dma_data_direction dir,
unsigned long attrs) unsigned long attrs)
{ {
bool coherent = is_device_dma_coherent(dev); bool coherent = is_dma_coherent(dev, attrs);
int ret;
ret = iommu_dma_map_sg(dev, sgl, nelems,
dma_info_to_prot(dir, coherent, attrs));
if (!ret)
return ret;
if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
__iommu_sync_sg_for_device(dev, sgl, nelems, dir); __iommu_sync_sg_for_device(dev, sgl, nelems, dir);
return iommu_dma_map_sg(dev, sgl, nelems, return ret;
dma_info_to_prot(dir, coherent, attrs));
} }
static void __iommu_unmap_sg_attrs(struct device *dev, static void __iommu_unmap_sg_attrs(struct device *dev,
@@ -895,50 +980,14 @@ static int __init __iommu_dma_init(void)
} }
arch_initcall(__iommu_dma_init); arch_initcall(__iommu_dma_init);
static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *ops)
{
struct iommu_domain *domain;
if (!ops)
return;
/*
* The IOMMU core code allocates the default DMA domain, which the
* underlying IOMMU driver needs to support via the dma-iommu layer.
*/
domain = iommu_get_domain_for_dev(dev);
if (!domain)
goto out_err;
if (domain->type == IOMMU_DOMAIN_DMA) {
if (iommu_dma_init_domain(domain, dma_base, size, dev))
goto out_err;
dev->dma_ops = &iommu_dma_ops;
}
return;
out_err:
pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev));
}
void arch_teardown_dma_ops(struct device *dev) void arch_teardown_dma_ops(struct device *dev)
{ {
dev->dma_ops = NULL; dev->dma_ops = NULL;
} }
#else
static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *iommu)
{ }
#endif /* CONFIG_IOMMU_DMA */ #endif /* CONFIG_IOMMU_DMA */
static void arm_iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size);
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *iommu, bool coherent) const struct iommu_ops *iommu, bool coherent)
{ {
@@ -950,7 +999,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
} }
dev->archdata.dma_coherent = coherent; dev->archdata.dma_coherent = coherent;
__iommu_setup_dma_ops(dev, dma_base, size, iommu); arm_iommu_setup_dma_ops(dev, dma_base, size);
#ifdef CONFIG_XEN #ifdef CONFIG_XEN
if (xen_initial_domain()) { if (xen_initial_domain()) {
@@ -960,3 +1009,149 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
#endif #endif
} }
EXPORT_SYMBOL_GPL(arch_setup_dma_ops); EXPORT_SYMBOL_GPL(arch_setup_dma_ops);
#ifdef CONFIG_ARM64_DMA_USE_IOMMU
/* guards initialization of default_domain->iova_cookie */
static DEFINE_MUTEX(iommu_dma_init_mutex);
static int
iommu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping)
{
struct iommu_domain *domain = mapping->domain;
dma_addr_t dma_base = mapping->base;
u64 size = mapping->bits << PAGE_SHIFT;
int ret;
bool own_cookie;
/*
* if own_cookie is false, then we are sharing the iova_cookie with
* another driver, and should not free it on error. Cleanup will be
* done when the iommu_domain is freed.
*/
own_cookie = !domain->iova_cookie;
if (own_cookie) {
ret = iommu_get_dma_cookie(domain);
if (ret) {
dev_err(dev, "iommu_get_dma_cookie failed: %d\n", ret);
return ret;
}
}
ret = iommu_dma_init_domain(domain, dma_base, size, dev);
if (ret) {
dev_err(dev, "iommu_dma_init_domain failed: %d\n", ret);
if (own_cookie)
iommu_put_dma_cookie(domain);
return ret;
}
mapping->ops = &iommu_dma_ops;
return 0;
}
static int arm_iommu_get_dma_cookie(struct device *dev,
struct dma_iommu_mapping *mapping)
{
int s1_bypass = 0, is_fast = 0;
int err = 0;
mutex_lock(&iommu_dma_init_mutex);
iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
&s1_bypass);
iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
if (s1_bypass)
mapping->ops = &arm64_swiotlb_dma_ops;
else if (is_fast)
err = fast_smmu_init_mapping(dev, mapping);
else
err = iommu_init_mapping(dev, mapping);
mutex_unlock(&iommu_dma_init_mutex);
return err;
}
/*
* Checks for "qcom,iommu-dma-addr-pool" property.
* If not present, leaves dma_addr and dma_size unmodified.
*/
static void arm_iommu_get_dma_window(struct device *dev, u64 *dma_addr,
u64 *dma_size)
{
struct device_node *np;
int naddr, nsize, len;
const __be32 *ranges;
if (!dev->of_node)
return;
np = of_parse_phandle(dev->of_node, "qcom,iommu-group", 0);
if (!np)
np = dev->of_node;
ranges = of_get_property(np, "qcom,iommu-dma-addr-pool", &len);
if (!ranges)
return;
len /= sizeof(u32);
naddr = of_n_addr_cells(np);
nsize = of_n_size_cells(np);
if (len < naddr + nsize) {
dev_err(dev, "Invalid length for qcom,iommu-dma-addr-pool, expected %d cells\n",
naddr + nsize);
return;
}
if (naddr == 0 || nsize == 0) {
dev_err(dev, "Invalid #address-cells %d or #size-cells %d\n",
naddr, nsize);
return;
}
*dma_addr = of_read_number(ranges, naddr);
*dma_size = of_read_number(ranges + naddr, nsize);
}
static void arm_iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size)
{
struct iommu_domain *domain;
struct iommu_group *group;
struct dma_iommu_mapping mapping = {0};
group = dev->iommu_group;
if (!group)
return;
arm_iommu_get_dma_window(dev, &dma_base, &size);
domain = iommu_get_domain_for_dev(dev);
if (!domain)
return;
/* Allow iommu-debug to call arch_setup_dma_ops to reconfigure itself */
if (domain->type != IOMMU_DOMAIN_DMA &&
!of_device_is_compatible(dev->of_node, "iommu-debug-test")) {
dev_err(dev, "Invalid iommu domain type!\n");
return;
}
mapping.base = dma_base;
mapping.bits = size >> PAGE_SHIFT;
mapping.domain = domain;
if (arm_iommu_get_dma_cookie(dev, &mapping)) {
dev_err(dev, "Failed to get dma cookie\n");
return;
}
set_dma_ops(dev, mapping.ops);
}
#else /*!CONFIG_ARM64_DMA_USE_IOMMU */
static void arm_iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size)
{
}
#endif

View File

@@ -218,6 +218,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
ptep = (pte_t *)pudp; ptep = (pte_t *)pudp;
} else if (sz == (PAGE_SIZE * CONT_PTES)) { } else if (sz == (PAGE_SIZE * CONT_PTES)) {
pmdp = pmd_alloc(mm, pudp, addr); pmdp = pmd_alloc(mm, pudp, addr);
if (!pmdp)
return NULL;
WARN_ON(addr & (sz - 1)); WARN_ON(addr & (sz - 1));
/* /*

View File

@@ -53,6 +53,8 @@
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/alternative.h> #include <asm/alternative.h>
EXPORT_SYMBOL_GPL(kimage_vaddr);
/* /*
* We need to be able to catch inadvertent references to memstart_addr * We need to be able to catch inadvertent references to memstart_addr
* that occur (potentially in generic code) before arm64_memblock_init() * that occur (potentially in generic code) before arm64_memblock_init()

View File

@@ -32,6 +32,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/dma-contiguous.h>
#include <linux/cma.h>
#include <asm/barrier.h> #include <asm/barrier.h>
#include <asm/cputype.h> #include <asm/cputype.h>
@@ -67,6 +69,40 @@ static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused; static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused; static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;
struct dma_contig_early_reserve {
phys_addr_t base;
unsigned long size;
};
static struct dma_contig_early_reserve dma_mmu_remap[MAX_CMA_AREAS];
static int dma_mmu_remap_num;
void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
{
if (dma_mmu_remap_num >= ARRAY_SIZE(dma_mmu_remap)) {
pr_err("ARM64: Not enough slots for DMA fixup reserved regions!\n");
return;
}
dma_mmu_remap[dma_mmu_remap_num].base = base;
dma_mmu_remap[dma_mmu_remap_num].size = size;
dma_mmu_remap_num++;
}
static bool dma_overlap(phys_addr_t start, phys_addr_t end)
{
int i;
for (i = 0; i < dma_mmu_remap_num; i++) {
phys_addr_t dma_base = dma_mmu_remap[i].base;
phys_addr_t dma_end = dma_mmu_remap[i].base +
dma_mmu_remap[i].size;
if ((dma_base < end) && (dma_end > start))
return true;
}
return false;
}
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot) unsigned long size, pgprot_t vma_prot)
{ {
@@ -200,7 +236,8 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
/* try section mapping first */ /* try section mapping first */
if (((addr | next | phys) & ~SECTION_MASK) == 0 && if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
(flags & NO_BLOCK_MAPPINGS) == 0) { (flags & NO_BLOCK_MAPPINGS) == 0 &&
!dma_overlap(phys, phys + next - addr)) {
pmd_set_huge(pmdp, phys, prot); pmd_set_huge(pmdp, phys, prot);
/* /*
@@ -299,7 +336,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
* For 4K granule only, attempt to put down a 1GB block * For 4K granule only, attempt to put down a 1GB block
*/ */
if (use_1G_block(addr, next, phys) && if (use_1G_block(addr, next, phys) &&
(flags & NO_BLOCK_MAPPINGS) == 0) { (flags & NO_BLOCK_MAPPINGS) == 0 &&
!dma_overlap(phys, phys + next - addr)) {
pud_set_huge(pudp, phys, prot); pud_set_huge(pudp, phys, prot);
/* /*
@@ -720,6 +758,7 @@ int kern_addr_valid(unsigned long addr)
return pfn_valid(pte_pfn(pte)); return pfn_valid(pte_pfn(pte));
} }
EXPORT_SYMBOL_GPL(kern_addr_valid);
#ifdef CONFIG_SPARSEMEM_VMEMMAP #ifdef CONFIG_SPARSEMEM_VMEMMAP
#if !ARM64_SWAPPER_USES_SECTION_MAPS #if !ARM64_SWAPPER_USES_SECTION_MAPS
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,

View File

@@ -186,16 +186,10 @@ static inline void writel(u32 data, volatile void __iomem *addr)
#define mmiowb() #define mmiowb()
/* void __iomem *ioremap(unsigned long phys_addr, unsigned long size);
* Need an mtype somewhere in here, for cache type deals? #define ioremap_nocache ioremap
* This is probably too long for an inline. #define ioremap_uc(X, Y) ioremap((X), (Y))
*/
void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
{
return ioremap_nocache(phys_addr, size);
}
static inline void iounmap(volatile void __iomem *addr) static inline void iounmap(volatile void __iomem *addr)
{ {

View File

@@ -33,7 +33,7 @@ EXPORT_SYMBOL(__vmgetie);
EXPORT_SYMBOL(__vmsetie); EXPORT_SYMBOL(__vmsetie);
EXPORT_SYMBOL(__vmyield); EXPORT_SYMBOL(__vmyield);
EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(ioremap_nocache); EXPORT_SYMBOL(ioremap);
EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);

View File

@@ -22,7 +22,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/mm.h> #include <linux/mm.h>
void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size) void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
{ {
unsigned long last_addr, addr; unsigned long last_addr, addr;
unsigned long offset = phys_addr & ~PAGE_MASK; unsigned long offset = phys_addr & ~PAGE_MASK;

View File

@@ -21,6 +21,7 @@ config MIPS
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_CMOS_UPDATE select GENERIC_CMOS_UPDATE
select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_AUTOPROBE
select GENERIC_GETTIMEOFDAY
select GENERIC_IRQ_PROBE select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select GENERIC_LIB_ASHLDI3 select GENERIC_LIB_ASHLDI3
@@ -71,6 +72,7 @@ config MIPS
select HAVE_STACKPROTECTOR select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
select HAVE_GENERIC_VDSO
select IRQ_FORCED_THREADING select IRQ_FORCED_THREADING
select MODULES_USE_ELF_RELA if MODULES && 64BIT select MODULES_USE_ELF_RELA if MODULES && 64BIT
select MODULES_USE_ELF_REL if MODULES select MODULES_USE_ELF_REL if MODULES

View File

@@ -2199,6 +2199,9 @@ static int octeon_irq_cib_map(struct irq_domain *d,
} }
cd = kzalloc(sizeof(*cd), GFP_KERNEL); cd = kzalloc(sizeof(*cd), GFP_KERNEL);
if (!cd)
return -ENOMEM;
cd->host_data = host_data; cd->host_data = host_data;
cd->bit = hw; cd->bit = hw;

View File

@@ -11,19 +11,6 @@
#ifndef __ASM_CLOCKSOURCE_H #ifndef __ASM_CLOCKSOURCE_H
#define __ASM_CLOCKSOURCE_H #define __ASM_CLOCKSOURCE_H
#include <linux/types.h> #include <asm/vdso/clocksource.h>
/* VDSO clocksources. */
#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */
#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */
#define VDSO_CLOCK_GIC 2 /* Use the GIC. */
/**
* struct arch_clocksource_data - Architecture-specific clocksource information.
* @vdso_clock_mode: Method the VDSO should use to access the clocksource.
*/
struct arch_clocksource_data {
u8 vdso_clock_mode;
};
#endif /* __ASM_CLOCKSOURCE_H */ #endif /* __ASM_CLOCKSOURCE_H */

View File

@@ -22,6 +22,7 @@
#include <asm/dsemul.h> #include <asm/dsemul.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/prefetch.h> #include <asm/prefetch.h>
#include <asm/vdso/processor.h>
/* /*
* Return current * instruction pointer ("program counter"). * Return current * instruction pointer ("program counter").
@@ -386,21 +387,6 @@ unsigned long get_wchan(struct task_struct *p);
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29]) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
#define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status) #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
#ifdef CONFIG_CPU_LOONGSON3
/*
* Loongson-3's SFB (Store-Fill-Buffer) may buffer writes indefinitely when a
* tight read loop is executed, because reads take priority over writes & the
* hardware (incorrectly) doesn't ensure that writes will eventually occur.
*
* Since spin loops of any kind should have a cpu_relax() in them, force an SFB
* flush from cpu_relax() such that any pending writes will become visible as
* expected.
*/
#define cpu_relax() smp_mb()
#else
#define cpu_relax() barrier()
#endif
/* /*
* Return_address is a replacement for __builtin_return_address(count) * Return_address is a replacement for __builtin_return_address(count)
* which on certain architectures cannot reasonably be implemented in GCC * which on certain architectures cannot reasonably be implemented in GCC

View File

@@ -12,6 +12,7 @@
#define __ASM_VDSO_H #define __ASM_VDSO_H
#include <linux/mm_types.h> #include <linux/mm_types.h>
#include <vdso/datapage.h>
#include <asm/barrier.h> #include <asm/barrier.h>
@@ -53,84 +54,9 @@ extern struct mips_vdso_image vdso_image_o32;
extern struct mips_vdso_image vdso_image_n32; extern struct mips_vdso_image vdso_image_n32;
#endif #endif
/**
* union mips_vdso_data - Data provided by the kernel for the VDSO.
* @xtime_sec: Current real time (seconds part).
* @xtime_nsec: Current real time (nanoseconds part, shifted).
* @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
* @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
* @seq_count: Counter to synchronise updates (odd = updating).
* @cs_shift: Clocksource shift value.
* @clock_mode: Clocksource to use for time functions.
* @cs_mult: Clocksource multiplier value.
* @cs_cycle_last: Clock cycle value at last update.
* @cs_mask: Clocksource mask value.
* @tz_minuteswest: Minutes west of Greenwich (from timezone).
* @tz_dsttime: Type of DST correction (from timezone).
*
* This structure contains data needed by functions within the VDSO. It is
* populated by the kernel and mapped read-only into user memory. The time
* fields are mirrors of internal data from the timekeeping infrastructure.
*
* Note: Care should be taken when modifying as the layout must remain the same
* for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
*/
union mips_vdso_data { union mips_vdso_data {
struct { struct vdso_data data[CS_BASES];
u64 xtime_sec;
u64 xtime_nsec;
u64 wall_to_mono_sec;
u64 wall_to_mono_nsec;
u32 seq_count;
u32 cs_shift;
u8 clock_mode;
u32 cs_mult;
u64 cs_cycle_last;
u64 cs_mask;
s32 tz_minuteswest;
s32 tz_dsttime;
};
u8 page[PAGE_SIZE]; u8 page[PAGE_SIZE];
}; };
static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
{
u32 seq;
while (true) {
seq = READ_ONCE(data->seq_count);
if (likely(!(seq & 1))) {
/* Paired with smp_wmb() in vdso_data_write_*(). */
smp_rmb();
return seq;
}
cpu_relax();
}
}
static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
u32 start_seq)
{
/* Paired with smp_wmb() in vdso_data_write_*(). */
smp_rmb();
return unlikely(data->seq_count != start_seq);
}
static inline void vdso_data_write_begin(union mips_vdso_data *data)
{
++data->seq_count;
/* Ensure sequence update is written before other data page values. */
smp_wmb();
}
static inline void vdso_data_write_end(union mips_vdso_data *data)
{
/* Ensure data values are written before updating sequence again. */
smp_wmb();
++data->seq_count;
}
#endif /* __ASM_VDSO_H */ #endif /* __ASM_VDSO_H */

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __ASM_VDSOCLOCKSOURCE_H
#define __ASM_VDSOCLOCKSOURCE_H
#include <linux/types.h>
/* VDSO clocksources. */
#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */
#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */
#define VDSO_CLOCK_GIC 2 /* Use the GIC. */
/**
* struct arch_clocksource_data - Architecture-specific clocksource information.
* @vdso_clock_mode: Method the VDSO should use to access the clocksource.
*/
struct arch_clocksource_data {
u8 vdso_clock_mode;
};
#endif /* __ASM_VDSOCLOCKSOURCE_H */

Some files were not shown because too many files have changed in this diff Show More