Merge branch 'android14-6.1' into android14-6.1-lts

Sync up with recent changes in android14-6.1.  Changes included here
are:

* 1ffc24e7e8 UPSTREAM: Revert "PCI: Use preserve_config in place of pci_flags"
* 34aea58089 Merge tag 'android14-6.1.124_r00' into android14-6.1
* 11620ab958 FROMGIT: KVM: arm64: Flush hyp bss section after initialization of variables in bss
* 2f2e115eec Merge 6.1.121-lts branch changes into android14-6.1
* d2841af63f Merge 6.1.119-lts branch changes into android14-6.1
* ef4fb40b87 ANDROID: GKI: Add Paragon symbol list
* 72db89d3d9 ANDROID: common-android14-6.1 Update the ABI symbol list
* 092a580916 ANDROID: KVM: arm64: Present the 16Kb granule support to the guest VMs
* 0405a25a6e ANDROID: KVM: arm64: Fix corrupted PSTATE during guest debug
* d12538e9da BACKPORT: PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown
* dbdf659cc6 UPSTREAM: selinux: ignore unknown extended permissions
* e09bed3008 BACKPORT: f2fs: prevent writing without fallocate() for pinned files
* 8a225f954d ANDROID: Enable PM_USERSPACE_AUTOSLEEP in gki_defconfig
* a33878393a ANDROID: Update the ABI symbol list
* 6f0b82dd8a ANDROID: mm: add kswapd wake/done rvh
* 770852bf7d ANDROID: ABI: update protected symbol list
* bda0401cd8 ANDROID: GKI: load vendor modules without tainting the kernel
* 7e96f2bfaa UPSTREAM: cgroup: remove cgroup_rstat_flush_atomic()
* b5b6e46444 UPSTREAM: memcg: remove mem_cgroup_flush_stats_atomic()
* 4b27ab0c6b UPSTREAM: memcg: calculate root usage from global state
* 0ef8d00e37 UPSTREAM: memcg: flush stats non-atomically in mem_cgroup_wb_stats()
* c0d8df37a0 UPSTREAM: writeback: move wb_over_bg_thresh() call outside lock section
* 681efac6a1 UPSTREAM: memcg: do not modify rstat tree for zero updates
* 5795558d86 UPSTREAM: vmscan: memcg: sleep when flushing stats during reclaim
* e3e3beed82 UPSTREAM: workingset: memcg: sleep when flushing stats in workingset_refault()
* 0448f92c8d UPSTREAM: memcg: sleep during flushing stats in safe contexts
* c47c4c0966 UPSTREAM: memcg: replace stats_flush_lock with an atomic
* 86ff69608f UPSTREAM: memcg: do not flush stats in irq context
* a77a4ca4f4 UPSTREAM: memcg: rename mem_cgroup_flush_stats_"delayed" to "ratelimited"
* 978adc3d3a UPSTREAM: cgroup: rename cgroup_rstat_flush_"irqsafe" to "atomic"
* 616d7c64fd BACKPORT: epoll: Add synchronous wakeup support for ep_poll_callback
* 66ae563a65 UPSTREAM: bpf: sync_linked_regs() must preserve subreg_def
* eeccb29218 UPSTREAM: ALSA: usb-audio: Fix a DMA to stack memory bug
* e2b9748880 ANDROID: ABI: update symbol list for honor
* 3f924195e2 FROMGIT: usb: dwc3: gadget: Fix incorrect UDC state after manual deconfiguration
* c141a306c4 ANDROID: scsi: sd: Fix unexpect removal code on Merge commit
* 4c2d86d81f ANDROID: GKI: Update oplus symbol list
* 3e3f2b9e9f BACKPORT: f2fs: fix to account dirty data in __get_secs_required()
* e50cf165f4 BACKPORT: usb: gadget: uvc: configfs: Add frame-based frame format support
* 4bcafa4d00 ANDROID: dm-bow: Fix empty else blocks
* d5dfee96ac ANDROID: dm-bow: Pass through zero sized requests
* 1149e6d6fc ANDROID: dm-bow: Fix 5.15 compatibility issue
* 1f8f8e5cd9 ANDROID: dm-bow: Fix up revert remove dm-bow
* e8944a38b4 Revert "ANDROID: dm-bow: remove dm-bow"
* d0e1b23b5d UPSTREAM: ALSA: usb-audio: Fix out of bounds reads when finding clock sources
* e93c64d683 ANDROID: GKI: Update symbols need by rockchip drm
* a84242054b UPSTREAM: ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox devices
* 204945a2da UPSTREAM: vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans
* 367540fdf9 Merge tag 'android14-6.1.118_r00' into android14-6.1
* 22b7ded8b5 ANDROID: ABI: update symbol list for honor
* dbb9fda3cf ANDROID: fs: add vendor hook to collect IO statistics
* b9ba16d91d UPSTREAM: usb: xhci: Implement xhci_handshake_check_state() helper
* 191acd0d6a Revert "UPSTREAM: unicode: Don't special case ignorable code points"
* 0a310649d8 Reapply "UPSTREAM: unicode: Don't special case ignorable code points"
* e318dc4c06 ANDROID: abi_gki_aarch64_qcom: Update symbols list for Qcom
* 904ebc320c Revert "UPSTREAM: unicode: Don't special case ignorable code points"
* 0f332d7edc ANDROID: KVM: arm64: Fix missing mutex init for hyp trace readers
* affd0c0263 ANDROID: mm: EXPORT_SYMBOL_GPL(reclaim_pages) position adjustment
* d8ccecb7c2 ANDROID: GKI: Update symbol list for mtk
* 853ec04e2d UPSTREAM: HID: core: zero-initialize the report buffer
* c276c53965 ANDROID: GKI: Update symbol list for mtk
* fddf80a6ac UPSTREAM: of: property: fw_devlink: Add support for "post-init-providers" property
* b865d3ed06 UPSTREAM: driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
* 0a05df9c8a UPSTREAM: driver core: Adds flags param to fwnode_link_add()
* 182b090f35 UPSTREAM: f2fs: modify f2fs_is_checkpoint_ready logic to allow more data to be written with the CP disable
* 38149d5303 BACKPORT: f2fs: introduce get_available_block_count() for cleanup
* 997d1e6f69 FROMGIT: pinmux: Use sequential access to access desc->pinmux data
* fa34bcaf9e BACKPORT: firmware: arm_scmi: Support 'reg-io-width' property for shared memory
* c9e7fc262f UPSTREAM: dt-bindings: sram: Document reg-io-width property
* cdea241bf6 ANDROID: GKI: Update symbol list for mtk
* a887a44ace ANDROID: KVM: arm64: Always check state from host_ack_unshare()
* fb69bae8ea FROMLIST: KVM: arm64: Always check the state from hyp_ack_unshare()
* bfad6b019c Merge tag 'android14-6.1.115_r00' into android14-6.1
* 93460febf9 UPSTREAM: f2fs: fix fiemap failure issue when page size is 16KB
* 3a856b7c13 ANDROID: GKI: Update symbol list for mtk
* 929ff4817a UPSTREAM: net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
* 7cd56b010f UPSTREAM: net: sched: use RCU read-side critical section in taprio_dump()
* 226e9f92a0 UPSTREAM: f2fs: compress: don't redirty sparse cluster during {,de}compress
* 84a9f618b5 UPSTREAM: f2fs: compress: don't {,de}compress non-full cluster
* 3b2e004494 UPSTREAM: f2fs: allow f2fs_ioc_{,de}compress_file to be interrupted
* 24492cb6b9 UPSTREAM: f2fs: compress: do sanity check on cluster when CONFIG_F2FS_CHECK_FS is on
* 268f1fed50 UPSTREAM: f2fs: support SEEK_DATA and SEEK_HOLE for compression files
* 672918d432 ANDROID: add file for recording allowed ABI breaks
* 1ca5db7e29 ANDROID: GKI: update symbol list for honor
* 13f2b693c7 ANDROID: vendor_hooks: add hook to record reboot reason
* 51bee18173 BACKPORT: FROMGIT: binder: add delivered_freeze to debugfs output
* 2791dfac50 BACKPORT: FROMGIT: binder: fix memleak of proc->delivered_freeze
* c5233c5678 FROMGIT: binder: allow freeze notification for dead nodes
* 194a332e5f FROMGIT: binder: fix BINDER_WORK_CLEAR_FREEZE_NOTIFICATION debug logs
* 5b095ade12 ANDROID: GKI: Update symbol list for BCMSTB
* 516ca8799f ANDROID: psi: Add vendor hooks for PSI tracing
* 4a105e4e1c ANDROID: ABI: Update pixel symbol list
* 6cf2e7d968 ANDROID: GKI: update symbol list for honor
* eb0102684f ANDROID: vendor_hooks: add hook to record slab alloc and free
* defe0024cf UPSTREAM: Revert "arm64: dts: qcom: sm8250: switch UFS QMP PHY to new style of bindings"
* 55c3fa9885 ANDROID: GKI: Update Honor abi symbol list
* cbc36a1928 ANDROID: Allow vendor modules perform more operationson.
* 7160754546 ANDROID: GKI: Add drm symbol need by rockchip soc
* 5f814d6bb4 ANDROID: GKI: Update symbol list for mtk
* 351af49c1d ANDROID: GKI: Update rockchip symbols for some customers.
* 8ed9a61b54 ANDROID: usb: dwc3: core: Introduce vendor struct to deal with ABI breakage
* 9f49b974c8 BACKPORT: usb: dwc3: core: Refactor PHY logic to support Multiport Controller
* 28c74caaf3 BACKPORT: usb: dwc3: core: Access XHCI address space temporarily to read port info
* 38859a233e BACKPORT: f2fs: compress: fix to update i_compr_blocks correctly
* a7a882d905 ANDROID: abi_gki_aarch64_qcom: Update symbol list
* 96ad4e759f UPSTREAM: USB: media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in uvc_parse_format
* eef3d33656 ANDROID: GKI: Update symbol list for honor
* ce0653fd2c ANDROID: Allow vendor modules perform more operations on memleak detect
* d3daafbfd2 ANDROID: ABI: Update transsion symbol list and stg
* 11512e4a72 ANDROID: mmc: Add vendor hooks for sdcard failure diagnostics
* f3367f466a BACKPORT: usb: dwc3: Avoid waking up gadget during startxfer

Change-Id: I4a88143ff6c8c0dfc1621e084fd9280f3524c5ad
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-01-28 15:36:18 +00:00
92 changed files with 5226 additions and 415 deletions

View File

@@ -115,6 +115,7 @@ filegroup(
"android/abi_gki_aarch64_mtk",
"android/abi_gki_aarch64_nothing",
"android/abi_gki_aarch64_oplus",
"android/abi_gki_aarch64_paragon",
"android/abi_gki_aarch64_pasa",
"android/abi_gki_aarch64_pixel",
"android/abi_gki_aarch64_qcom",

View File

@@ -295,6 +295,70 @@ Description: Specific uncompressed frame descriptors
support
========================= =====================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased
Date: Sept 2024
KernelVersion: 5.15
Description: Framebased format descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name
Date: Sept 2024
KernelVersion: 5.15
Description: Specific framebased format descriptors
================== =======================================
bFormatIndex unique id for this format descriptor;
only defined after parent header is
linked into the streaming class;
read-only
bmaControls this format's data for bmaControls in
the streaming header
bmInterlaceFlags specifies interlace information,
read-only
bAspectRatioY the X dimension of the picture aspect
ratio, read-only
bAspectRatioX the Y dimension of the picture aspect
ratio, read-only
bDefaultFrameIndex optimum frame index for this stream
bBitsPerPixel number of bits per pixel used to
specify color in the decoded video
frame
guidFormat globally unique id used to identify
stream-encoding format
================== =======================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name/name
Date: Sept 2024
KernelVersion: 5.15
Description: Specific framebased frame descriptors
========================= =====================================
bFrameIndex unique id for this framedescriptor;
only defined after parent format is
linked into the streaming header;
read-only
dwFrameInterval indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
dwDefaultFrameInterval the frame interval the device would
like to use as default
dwBytesPerLine Specifies the number of bytes per line
of video for packed fixed frame size
formats, allowing the receiver to
perform stride alignment of the video.
If the bVariableSize value (above) is
TRUE (1), or if the format does not
permit such alignment, this value shall
be set to zero (0).
dwMaxBitRate the maximum bit rate at the shortest
frame interval in bps
dwMinBitRate the minimum bit rate at the longest
frame interval in bps
wHeight height of decoded bitmap frame in px
wWidth width of decoded bitmam frame in px
bmCapabilities still image support, fixed frame-rate
support
========================= =====================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
Date: Dec 2014
KernelVersion: 4.0

View File

@@ -0,0 +1,99 @@
dm_bow (backup on write)
========================
dm_bow is a device mapper driver that uses the free space on a device to back up
data that is overwritten. The changes can then be committed by a simple state
change, or rolled back by removing the dm_bow device and running a command line
utility over the underlying device.
dm_bow has three states, set by writing 1 or 2 to /sys/block/dm-?/bow/state.
It is only possible to go from state 0 (initial state) to state 1, and then from
state 1 to state 2.
State 0: dm_bow collects all trims to the device and assumes that these mark
free space on the overlying file system that can be safely used. Typically the
mount code would create the dm_bow device, mount the file system, call the
FITRIM ioctl on the file system then switch to state 1. These trims are not
propagated to the underlying device.
State 1: All writes to the device cause the underlying data to be backed up to
the free (trimmed) area as needed in such a way as they can be restored.
However, the writes, with one exception, then happen exactly as they would
without dm_bow, so the device is always in a good final state. The exception is
that sector 0 is used to keep a log of the latest changes, both to indicate that
we are in this state and to allow rollback. See below for all details. If there
isn't enough free space, writes are failed with -ENOSPC.
State 2: The transition to state 2 triggers replacing the special sector 0 with
the normal sector 0, and the freeing of all state information. dm_bow then
becomes a pass-through driver, allowing the device to continue to be used with
minimal performance impact.
Usage
=====
dm-bow takes one command line parameter, the name of the underlying device.
dm-bow will typically be used in the following way. dm-bow will be loaded with a
suitable underlying device and the resultant device will be mounted. A file
system trim will be issued via the FITRIM ioctl, then the device will be
switched to state 1. The file system will now be used as normal. At some point,
the changes can either be committed by switching to state 2, or rolled back by
unmounting the file system, removing the dm-bow device and running the command
line utility. Note that rebooting the device will be equivalent to unmounting
and removing, but the command line utility must still be run
Details of operation in state 1
===============================
dm_bow maintains a type for all sectors. A sector can be any of:
SECTOR0
SECTOR0_CURRENT
UNCHANGED
FREE
CHANGED
BACKUP
SECTOR0 is the first sector on the device, and is used to hold the log of
changes. This is the one exception.
SECTOR0_CURRENT is a sector picked from the FREE sectors, and is where reads and
writes from the true sector zero are redirected to. Note that like any backup
sector, if the sector is written to directly, it must be moved again.
UNCHANGED means that the sector has not been changed since we entered state 1.
Thus if it is written to or trimmed, the contents must first be backed up.
FREE means that the sector was trimmed in state 0 and has not yet been written
to or used for backup. On being written to, a FREE sector is changed to CHANGED.
CHANGED means that the sector has been modified, and can be further modified
without further backup.
BACKUP means that this is a free sector being used as a backup. On being written
to, the contents must first be backed up again.
All backup operations are logged to the first sector. The log sector has the
format:
--------------------------------------------------------
| Magic | Count | Sequence | Log entry | Log entry | …
--------------------------------------------------------
Magic is a magic number. Count is the number of log entries. Sequence is 0
initially. A log entry is
-----------------------------------
| Source | Dest | Size | Checksum |
-----------------------------------
When SECTOR0 is full, the log sector is backed up and another empty log sector
created with sequence number one higher. The first entry in any log entry with
sequence > 0 therefore must be the log of the backing up of the previous log
sector. Note that sequence is not strictly needed, but is a useful sanity check
and potentially limits the time spent trying to restore a corrupted snapshot.
On entering state 1, dm_bow has a list of free sectors. All other sectors are
unchanged. Sector0_current is selected from the free sectors and the contents of
sector 0 are copied there. The sector 0 is backed up, which triggers the first
log entry to be written.

View File

@@ -100,6 +100,12 @@ patternProperties:
IO mem address range, relative to the SRAM range.
maxItems: 1
reg-io-width:
description:
The size (in bytes) of the IO accesses that should be performed on the
SRAM.
enum: [1, 2, 4, 8]
pool:
description:
Indicates that the particular reserved SRAM area is addressable

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,139 @@
# How to use this file: http://go/approve-abi-break
# ABI freeze commit: 35fe0d393f80627879e12d457ca44d0112703a68
type 'struct kvm_cpu_context' changed
member changed from 'struct kvm_vcpu* __hyp_running_vcpu' to 'void* __hyp_running_vcpu'
type changed from 'struct kvm_vcpu*' to 'void*'
pointed-to type changed from 'struct kvm_vcpu' to 'void'
type 'struct xhci_hcd' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { struct xhci_vendor_ops* vendor_ops; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct size_class' changed
byte size changed from 136 to 128
member 'spinlock_t lock' was removed
6 members ('struct list_head fullness_list[4]' .. 'struct zs_size_stat stats') changed
offset changed by -64
type 'struct zs_pool' changed
member 'rwlock_t migrate_lock' was removed
member 'spinlock_t lock' was added
member 'atomic_t compaction_in_progress' was added
type 'struct zs_pool' changed
member 'atomic_t compaction_in_progress' was added
type 'struct task_struct' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { unsigned int saved_state; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct hid_device' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { struct { __s32 battery_charge_status; u32 padding; }; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct trace_buffer' changed
byte size changed from 224 to 216
member 'atomic_t resizing' was added
2 members ('bool time_stamp_abs' .. 'struct ring_buffer_ext_cb* ext_cb') changed
offset changed by -64
type 'struct fscrypt_policy_v2' changed
member '__u8 log2_data_unit_size' was added
member changed from '__u8 __reserved[4]' to '__u8 __reserved[3]'
offset changed from 32 to 40
type changed from '__u8[4]' to '__u8[3]'
number of elements changed from 4 to 3
type 'struct fscrypt_info' changed
member 'u8 ci_data_unit_bits' was added
member 'u8 ci_data_units_per_block_bits' was added
type 'struct pkvm_module_ops' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { int(* host_stage2_mod_prot_range)(u64, enum kvm_pgtable_prot, u64); struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct perf_event' changed
member 'unsigned int group_generation' was added
type 'struct tcpm_port' changed
byte size changed from 12536 to 12552
member 'struct usb_power_delivery* pd' was removed
member 'struct usb_power_delivery** pds' was added
member 'struct pd_data** pd_list' was added
5 members ('struct usb_power_delivery_capabilities* port_source_caps' .. 'struct usb_power_delivery_capabilities* partner_sink_caps') changed
offset changed by 64
member 'struct usb_power_delivery* selected_pd' was added
5 members ('u32 sink_request' .. 'unsigned int nr_sink_caps') changed
offset changed by 128
member 'unsigned int pd_count' was added
14 members ('u32 src_pdo[7]' .. 'u32 supply_voltage') changed
offset changed by 160
32 members ('struct power_supply* psy' .. 'u8* logbuffer[1024]') changed
offset changed by 128
type 'struct ipv6_devconf' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { struct { __s32 accept_ra_min_lft; u32 padding; }; struct { u64 android_kabi_reserved1; }; union { }; }' was added
1 variable symbol(s) removed
'struct tracepoint __tracepoint_android_vh_binder_detect_low_async_space_locked'
1 function symbol(s) removed
'int __traceiter_android_vh_binder_detect_low_async_space_locked(void*, int, size_t*, int, bool*)'
type 'struct queue_limits' changed
member 'bool sub_page_limits' was added
type 'struct prefix_info' changed
member '__u8 reserved:6' was removed
member '__u8 autoconf:1' was removed
member '__u8 onlink:1' was removed
member 'union { __u8 flags; struct { __u8 reserved:6; __u8 autoconf:1; __u8 onlink:1; }; }' was added
type 'struct userfaultfd_ctx' changed
byte size changed from 128 to 208
member 'struct rw_semaphore map_changing_lock' was added
member 'atomic_t mmap_changing' changed
offset changed by 544
member 'struct mm_struct* mm' changed
offset changed by 576
member 'u64 android_kabi_reserved1' was added
type 'struct rb_irq_work' changed
byte size changed from 96 to 88
member 'long wait_index' was removed
3 members ('bool waiters_pending' .. 'bool wakeup_full') changed
offset changed by -64
type 'struct ring_buffer_per_cpu' changed
byte size changed from 496 to 488
type 'struct trace_buffer' changed
byte size changed from 224 to 216
2 members ('bool time_stamp_abs' .. 'struct ring_buffer_ext_cb* ext_cb') changed
offset changed by -64
type 'struct sk_buff' changed
member 'union { struct sock* sk; int ip_defrag_offset; }' was removed
member 'struct sock* sk' was added
type 'struct ufs_clk_scaling' changed
member 'bool suspend_on_no_request' was added
type 'struct clk_core' changed
byte size changed from 248 to 264
member 'struct hlist_node rpm_node' was added
30 members ('struct device_node* of_node' .. 'struct kref ref') changed
offset changed by 128
type 'enum binder_work_type' changed
enumerator 'BINDER_WORK_FROZEN_BINDER' (9) was added
... 1 other enumerator(s) added
type 'struct geni_wrapper' changed
byte size changed from 48 to 56
member 'struct clk_bulk_data ahb_clks[2]' was removed
member 'struct clk_bulk_data clks[2]' was added
member 'unsigned int num_clks' was added

View File

@@ -1760,6 +1760,7 @@
# required by nexusmem.ko
restore_online_page_callback
__alloc_pages_bulk
# required by nexus.ko
recalc_sigpending

View File

@@ -288,6 +288,7 @@
skb_copy_ubufs
smpboot_register_percpu_thread
smpboot_unregister_percpu_thread
snd_card_ref
snd_soc_add_card_controls
snd_soc_find_dai
snd_soc_info_volsw_sx

View File

@@ -11,6 +11,7 @@
__tracepoint_android_vh_should_continue_reclaim
__tracepoint_android_vh_tune_fault_around_bytes
__tracepoint_android_vh_should_memcg_bypass
__tracepoint_android_vh_io_statistics
__traceiter_android_vh_get_page_wmark
__traceiter_android_vh_page_add_new_anon_rmap
__traceiter_android_vh_do_shrink_slab
@@ -27,12 +28,27 @@
__traceiter_android_vh_should_continue_reclaim
__traceiter_android_vh_tune_fault_around_bytes
__traceiter_android_vh_should_memcg_bypass
__traceiter_android_vh_io_statistics
__traceiter_rpm_idle
__tracepoint_rpm_idle
__traceiter_rpm_suspend
__tracepoint_rpm_suspend
__traceiter_rpm_resume
__tracepoint_rpm_resume
__traceiter_rpm_return_int
__tracepoint_rpm_return_int
binder_alloc_copy_from_buffer
kfree
__kmalloc
mod_node_page_state
page_cache_sync_ra
proc_create
arch_vma_name
__pmd_trans_huge_lock
anon_vma_name
vm_normal_page
walk_page_range
pmd_clear_bad
profile_event_register
profile_event_unregister
drop_super
@@ -48,7 +64,14 @@
udp4_lib_lookup
udp6_lib_lookup
next_arg
pm_wakeup_irq
__tracepoint_android_vh_dc_send_copy
__traceiter_android_vh_dc_send_copy
__tracepoint_android_vh_dc_receive
__traceiter_android_vh_dc_receive
__tracepoint_android_vh_slab_alloc_node
__traceiter_android_vh_slab_alloc_node
__tracepoint_android_vh_slab_free
__traceiter_android_vh_slab_free
__traceiter_android_rvh_hw_protection_shutdown
__tracepoint_android_rvh_hw_protection_shutdown

View File

@@ -20,6 +20,7 @@
alloc_contig_range
alloc_etherdev_mqs
alloc_io_pgtable_ops
alloc_iova_fast
alloc_netdev_mqs
__alloc_pages
alloc_pages_exact
@@ -83,6 +84,7 @@
bitmap_release_region
__bitmap_set
__bitmap_subset
bitmap_to_arr32
__bitmap_weight
__bitmap_xor
bitmap_zalloc
@@ -103,6 +105,10 @@
blocking_notifier_call_chain
blocking_notifier_chain_register
blocking_notifier_chain_unregister
bpf_dispatcher_xdp_func
bpf_master_redirect_enabled_key
bpf_prog_put
bpf_stats_enabled_key
bpf_trace_run1
bpf_trace_run10
bpf_trace_run11
@@ -115,6 +121,7 @@
bpf_trace_run7
bpf_trace_run8
bpf_trace_run9
bpf_warn_invalid_xdp_action
build_skb
bus_find_device
bus_for_each_dev
@@ -414,6 +421,7 @@
device_get_child_node_count
device_get_match_data
device_get_next_child_node
device_get_phy_mode
device_initialize
device_link_add
device_link_remove
@@ -483,6 +491,9 @@
devm_devfreq_remove_device
devm_devfreq_unregister_notifier
devm_devfreq_unregister_opp_notifier
devm_drm_bridge_add
devm_drm_of_get_bridge
devm_drm_panel_bridge_add
devm_extcon_dev_allocate
devm_extcon_dev_register
devm_extcon_register_notifier
@@ -516,6 +527,7 @@
devm_mbox_controller_register
devm_mdiobus_alloc_size
devm_memremap
devm_memremap_pages
devm_mfd_add_devices
devm_nvmem_cell_get
devm_nvmem_device_get
@@ -570,6 +582,7 @@
devm_watchdog_register_device
dev_nit_active
_dev_notice
dev_open
dev_pm_clear_wake_irq
dev_pm_domain_attach_by_id
dev_pm_domain_attach_by_name
@@ -631,6 +644,7 @@
dma_async_tx_descriptor_init
dma_buf_attach
dma_buf_begin_cpu_access
dma_buf_begin_cpu_access_partial
dma_buf_detach
dma_buf_end_cpu_access
dma_buf_end_cpu_access_partial
@@ -639,13 +653,16 @@
dma_buf_get
dma_buf_get_each
dma_buf_map_attachment
dma_buf_map_attachment_unlocked
dma_buf_mmap
dmabuf_page_pool_alloc
dmabuf_page_pool_create
dmabuf_page_pool_destroy
dmabuf_page_pool_free
dmabuf_page_pool_get_size
dma_buf_put
dma_buf_unmap_attachment
dma_buf_unmap_attachment_unlocked
dma_buf_vmap
dma_buf_vunmap
dma_contiguous_default_area
@@ -719,6 +736,8 @@
down_write_killable
d_path
dput
dql_completed
dql_reset
drain_workqueue
driver_attach
driver_create_file
@@ -729,11 +748,16 @@
drm_add_edid_modes
drm_add_modes_noedid
drm_atomic_add_affected_connectors
drm_atomic_bridge_chain_post_disable
drm_atomic_bridge_chain_pre_enable
drm_atomic_get_connector_state
drm_atomic_get_crtc_state
drm_atomic_get_new_private_obj_state
drm_atomic_get_old_private_obj_state
drm_atomic_get_private_obj_state
drm_atomic_helper_bridge_destroy_state
drm_atomic_helper_bridge_duplicate_state
drm_atomic_helper_bridge_reset
drm_atomic_helper_check
drm_atomic_helper_check_plane_state
drm_atomic_helper_cleanup_planes
@@ -769,7 +793,10 @@
drm_atomic_state_default_release
__drm_atomic_state_free
drm_atomic_state_init
drm_bridge_add
drm_bridge_attach
drm_bridge_connector_init
drm_bridge_remove
drm_calc_timestamping_constants
drm_compat_ioctl
drm_connector_attach_encoder
@@ -783,6 +810,7 @@
drm_crtc_cleanup
__drm_crtc_commit_free
drm_crtc_commit_wait
drm_crtc_from_index
drm_crtc_handle_vblank
drm_crtc_init_with_planes
drm_crtc_send_vblank_event
@@ -800,7 +828,9 @@
drm_dev_put
drm_dev_register
drm_dev_unregister
drm_display_info_set_bus_formats
drm_display_mode_from_cea_vic
drm_display_mode_from_videomode
drm_display_mode_to_videomode
drm_edid_duplicate
drm_edid_get_monitor_name
@@ -846,6 +876,7 @@
drm_mode_config_cleanup
drm_mode_config_reset
drm_mode_copy
drm_mode_create
drm_mode_crtc_set_gamma_size
drm_mode_duplicate
drm_mode_equal
@@ -860,6 +891,7 @@
drm_mode_vrefresh
drm_object_attach_property
drm_object_property_set_value
drm_of_find_panel_or_bridge
drm_open
drm_panel_add
drm_panel_disable
@@ -884,6 +916,7 @@
drm_property_lookup_blob
drm_read
drm_release
drm_simple_encoder_init
drm_universal_plane_init
drm_vblank_init
drm_writeback_connector_init
@@ -949,6 +982,11 @@
firmware_request_nowarn
fixed_phy_register
fixed_phy_unregister
flow_block_cb_setup_simple
flow_rule_match_basic
flow_rule_match_ipv4_addrs
flow_rule_match_ports
flow_rule_match_vlan
flush_dcache_page
flush_delayed_fput
flush_delayed_work
@@ -970,6 +1008,7 @@
frame_vector_to_pfns
free_contig_range
free_io_pgtable_ops
free_iova_fast
free_irq
free_netdev
__free_pages
@@ -992,7 +1031,9 @@
fsg_config_from_params
fwnode_device_is_available
fwnode_get_name
fwnode_get_named_child_node
fwnode_get_next_available_child_node
fwnode_get_phy_node
fwnode_graph_get_next_endpoint
fwnode_graph_get_port_parent
fwnode_graph_get_remote_endpoint
@@ -1047,6 +1088,7 @@
get_cpu_idle_time_us
get_cpu_iowait_time_us
get_device
get_device_system_crosststamp
__get_free_pages
get_governor_parent_kobj
get_kernel_pages
@@ -1109,6 +1151,7 @@
handle_simple_irq
handle_sysrq
have_governor_per_policy
hci_cmd_sync_status
hex2bin
hex_asc
hex_asc_upper
@@ -1221,8 +1264,10 @@
init_uts_ns
init_wait_entry
__init_waitqueue_head
input_alloc_absinfo
input_allocate_device
input_close_device
input_copy_abs
input_event
input_free_device
input_mt_destroy_slots
@@ -1491,12 +1536,15 @@
mdiobus_alloc_size
mdiobus_free
mdiobus_get_phy
mdiobus_modify_changed
__mdiobus_read
mdiobus_read
__mdiobus_register
mdiobus_unregister
__mdiobus_write
mdiobus_write
mdio_device_create
mdio_device_free
media_create_ancillary_link
media_create_intf_link
media_create_pad_link
@@ -1522,6 +1570,7 @@
memchr_inv
memcmp
memcpy
memcpy_and_pad
__memcpy_fromio
__memcpy_toio
memdup_user
@@ -1583,6 +1632,7 @@
mmc_send_tuning
mmc_set_data_timeout
mmc_switch
mmc_wait_for_cmd
mmc_wait_for_req
__mmdrop
mmput
@@ -1620,13 +1670,16 @@
nd_tbl
neigh_destroy
neigh_lookup
netdev_alert
__netdev_alloc_frag_align
__netdev_alloc_skb
netdev_err
netdev_info
netdev_name_in_use
netdev_notice
netdev_pick_tx
netdev_printk
netdev_rss_key_fill
netdev_set_default_ethtool_ops
netdev_update_features
netdev_upper_dev_link
@@ -1642,6 +1695,9 @@
netif_receive_skb
netif_receive_skb_list
netif_rx
netif_schedule_queue
netif_set_real_num_rx_queues
netif_set_real_num_tx_queues
netif_set_tso_max_size
netif_stacked_transfer_operstate
netif_tx_lock
@@ -1737,6 +1793,7 @@
__of_get_address
of_get_child_by_name
of_get_cpu_node
of_get_display_timing
of_get_mac_address
of_get_named_gpio_flags
of_get_next_available_child
@@ -1744,6 +1801,7 @@
of_get_next_parent
of_get_parent
of_get_pci_domain_nr
of_get_phy_mode
of_get_property
of_get_regulator_init_data
of_graph_get_next_endpoint
@@ -1767,7 +1825,9 @@
of_pci_get_max_link_speed
of_phandle_iterator_init
of_phandle_iterator_next
of_phy_find_device
of_phy_get_and_connect
of_phy_is_fixed_link
of_phy_simple_xlate
of_platform_depopulate
of_platform_device_create
@@ -1804,6 +1864,7 @@
page_pool_create
page_pool_destroy
page_pool_put_defragged_page
page_pool_release_page
panic
panic_notifier_list
param_array_ops
@@ -1899,6 +1960,7 @@
perf_trace_run_bpf_submit
pfn_is_map_memory
phy_attached_info
phy_configure
phy_connect
phy_connect_direct
phy_create_lookup
@@ -1918,6 +1980,7 @@
phy_ethtool_set_wol
phy_exit
phy_find_first
phy_gbit_features
phy_get
phy_get_c45_ids
phy_get_pause
@@ -1928,10 +1991,25 @@
phylink_create
phylink_destroy
phylink_disconnect_phy
phylink_ethtool_get_eee
phylink_ethtool_get_pauseparam
phylink_ethtool_get_wol
phylink_ethtool_ksettings_get
phylink_ethtool_ksettings_set
phylink_ethtool_nway_reset
phylink_ethtool_set_eee
phylink_ethtool_set_pauseparam
phylink_ethtool_set_wol
phylink_expects_phy
phylink_fwnode_phy_connect
phylink_generic_validate
phylink_get_eee_err
phylink_mii_c22_pcs_decode_state
phylink_mii_c22_pcs_encode_advertisement
phylink_mii_ioctl
phylink_resume
phylink_speed_down
phylink_speed_up
phylink_start
phylink_stop
phylink_suspend
@@ -1943,6 +2021,7 @@
phy_read_mmd
phy_register_fixup_for_uid
phy_remove_link_mode
phy_reset
phy_restore_page
phy_save_page
phy_set_mode_ext
@@ -2183,6 +2262,7 @@
regmap_bulk_write
regmap_field_read
regmap_field_update_bits_base
regmap_get_val_bytes
regmap_irq_get_domain
regmap_multi_reg_write
regmap_raw_read
@@ -2284,6 +2364,7 @@
rproc_alloc
rproc_boot
rproc_del
rproc_detach
rproc_free
rproc_get_by_phandle
rproc_put
@@ -2434,6 +2515,7 @@
simple_attr_write
simple_open
simple_read_from_buffer
simple_strtoul
simple_write_to_buffer
single_open
single_open_size
@@ -2488,6 +2570,7 @@
snd_ctl_boolean_mono_info
snd_jack_set_key
snd_pcm_format_physical_width
snd_pcm_format_set_silence
snd_pcm_format_width
snd_pcm_hw_constraint_integer
snd_pcm_hw_constraint_minmax
@@ -2513,6 +2596,7 @@
snd_soc_dapm_add_routes
snd_soc_dapm_disable_pin
snd_soc_dapm_enable_pin
snd_soc_dapm_force_enable_pin
snd_soc_dapm_get_enum_double
snd_soc_dapm_get_pin_switch
snd_soc_dapm_get_volsw
@@ -2552,6 +2636,7 @@
sock_common_getsockopt
sock_common_recvmsg
sock_common_setsockopt
sock_copy_user_timeval
__sock_create
sock_create_kern
sock_diag_register
@@ -2559,6 +2644,7 @@
sock_diag_unregister
sock_efree
sockfd_lookup
sock_get_timeout
sock_gettstamp
sock_i_ino
sock_init_data
@@ -2592,15 +2678,18 @@
spi_add_device
__spi_alloc_controller
spi_alloc_device
spi_async
spi_bus_type
spi_controller_resume
spi_controller_suspend
spi_delay_to_ns
spi_finalize_current_transfer
spi_get_device_id
spi_mem_default_supports_op
__spi_register_driver
spi_setup
spi_sync
spi_write_then_read
split_page
spmi_controller_add
spmi_controller_alloc
@@ -2619,6 +2708,7 @@
__stack_chk_fail
stack_trace_print
stack_trace_save
stack_trace_save_tsk
static_key_slow_dec
static_key_slow_inc
stop_one_cpu
@@ -2672,6 +2762,7 @@
sysfs_create_group
sysfs_create_link
sysfs_emit
__sysfs_match_string
sysfs_merge_group
sysfs_notify
sysfs_remove_bin_file
@@ -2686,6 +2777,7 @@
system_highpri_wq
system_long_wq
system_power_efficient_wq
system_state
system_unbound_wq
system_wq
sys_tz
@@ -2710,6 +2802,7 @@
thread_group_cputime_adjusted
tick_nohz_get_sleep_length
time64_to_tm
timecounter_cyc2time
timecounter_init
timecounter_read
timer_of_init
@@ -2718,6 +2811,8 @@
topology_clear_scale_freq_source
topology_update_thermal_pressure
_totalram_pages
touchscreen_parse_properties
touchscreen_report_pos
_trace_android_vh_record_pcpu_rwsem_starttime
_trace_android_vh_record_pcpu_rwsem_time_early
__trace_bprintk
@@ -2834,6 +2929,7 @@
__traceiter_pelt_se_tp
__traceiter_sched_update_nr_running_tp
__traceiter_task_newtask
__traceiter_xdp_exception
trace_output_call
__tracepoint_android_rvh_after_dequeue_task
__tracepoint_android_rvh_after_enqueue_task
@@ -2946,6 +3042,7 @@
__tracepoint_sched_update_nr_running_tp
tracepoint_srcu
__tracepoint_task_newtask
__tracepoint_xdp_exception
trace_print_array_seq
trace_print_flags_seq
trace_print_hex_seq
@@ -2960,6 +3057,7 @@
try_module_get
try_wait_for_completion
__tty_alloc_driver
tty_buffer_space_avail
tty_chars_in_buffer
tty_driver_flush_buffer
tty_driver_kref_put
@@ -3000,6 +3098,9 @@
tty_vhangup
tty_wakeup
tty_write_room
tun_get_socket
tun_get_tx_ring
tun_ptr_free
typec_get_drvdata
typec_mux_get_drvdata
typec_mux_put
@@ -3211,6 +3312,7 @@
usb_role_switch_unregister
usb_root_hub_lost_power
usb_scuttle_anchored_urbs
usb_set_configuration
usb_set_interface
usb_show_dynids
usb_speed_string
@@ -3351,6 +3453,7 @@
video_device_release
video_device_release_empty
video_ioctl2
videomode_from_timing
__video_register_device
video_unregister_device
virtqueue_add_inbuf
@@ -3368,6 +3471,7 @@
vlan_uses_dev
vlan_vid_add
vlan_vid_del
__vmalloc
vmalloc
vmalloc_to_page
vmalloc_to_pfn
@@ -3386,6 +3490,16 @@
vring_new_virtqueue
vscnprintf
vsnprintf
vsock_addr_bound
vsock_addr_cast
vsock_addr_equals_addr
vsock_addr_init
vsock_addr_unbind
vsock_addr_validate
vsock_core_register
vsock_core_unregister
vsock_deliver_tap
vsock_for_each_connected_socket
vsprintf
vunmap
vzalloc
@@ -3427,6 +3541,34 @@
ww_mutex_unlock
__xa_alloc
xa_erase
xdp_convert_zc_to_xdp_frame
xdp_do_flush
xdp_do_redirect
xdp_master_redirect
xdp_return_frame
xdp_return_frame_rx_napi
xdp_rxq_info_is_reg
__xdp_rxq_info_reg
xdp_rxq_info_reg_mem_model
xdp_rxq_info_unreg
xdp_rxq_info_unreg_mem_model
xdp_warn
xp_alloc
xp_dma_map
xp_dma_sync_for_cpu_slow
xp_dma_sync_for_device_slow
xp_dma_unmap
xp_free
xp_raw_get_dma
xp_set_rxq_info
xsk_clear_rx_need_wakeup
xsk_get_pool_from_qid
xsk_set_rx_need_wakeup
xsk_set_tx_need_wakeup
xsk_tx_completed
xsk_tx_peek_desc
xsk_tx_release
xsk_uses_need_wakeup
zlib_deflate
zlib_deflateEnd
zlib_deflateInit2

View File

@@ -126,6 +126,7 @@
tcf_exts_dump_stats
tcf_exts_validate
tcf_queue_work
tcp_cong_avoid_ai
__traceiter_android_rvh_post_init_entity_util_avg
__traceiter_android_rvh_rtmutex_force_update
__traceiter_android_vh_account_process_tick_gran

View File

@@ -0,0 +1,21 @@
[abi_symbol_list]
add_to_page_cache_lru
alloc_buffer_head
blkdev_issue_zeroout
__cond_resched_lock
d_rehash
filemap_fdatawrite_wbc
__find_get_block
free_buffer_head
__posix_acl_create
posix_acl_equiv_mode
posix_acl_from_xattr
posix_acl_to_xattr
posix_acl_valid
set_cached_acl
shrink_dcache_sb
sync_inodes_sb
try_to_free_buffers
wait_for_completion_io
write_dirty_buffer
yield

View File

@@ -1253,6 +1253,14 @@
kfree_skb_reason
kill_fasync
kimage_voffset
klist_add_head
klist_add_tail
klist_init
klist_iter_exit
klist_iter_init
klist_next
klist_node_attached
klist_remove
__kmalloc
kmalloc_caches
kmalloc_large
@@ -1595,6 +1603,7 @@
param_set_copystring
param_set_int
param_set_uint
param_set_uint_minmax
pci_alloc_irq_vectors_affinity
pci_assign_resource
pci_clear_master
@@ -1894,6 +1903,7 @@
regulator_set_load
regulator_set_voltage
regulator_set_voltage_sel_regmap
regulator_sync_voltage
regulator_unregister
release_firmware
__release_region
@@ -2387,8 +2397,11 @@
__traceiter_android_rvh_usb_dev_suspend
__traceiter_android_rvh_util_est_update
__traceiter_android_rvh_util_fits_cpu
__traceiter_android_rvh_vmscan_kswapd_done
__traceiter_android_rvh_vmscan_kswapd_wake
__traceiter_android_vh_arch_set_freq_scale
__traceiter_android_vh_audio_usb_offload_connect
__traceiter_android_vh_binder_proc_transaction_finish
__traceiter_android_vh_binder_restore_priority
__traceiter_android_vh_binder_set_priority
__traceiter_android_vh_cpu_idle_enter
@@ -2415,6 +2428,7 @@
__traceiter_android_vh_sound_usb_support_cpu_suspend
__traceiter_android_vh_sysrq_crash
__traceiter_android_vh_timerfd_create
__traceiter_android_vh_tune_swappiness
__traceiter_android_vh_typec_store_partner_src_caps
__traceiter_android_vh_typec_tcpci_override_toggling
__traceiter_android_vh_typec_tcpm_get_timer
@@ -2522,8 +2536,11 @@
__tracepoint_android_rvh_usb_dev_suspend
__tracepoint_android_rvh_util_est_update
__tracepoint_android_rvh_util_fits_cpu
__tracepoint_android_rvh_vmscan_kswapd_done
__tracepoint_android_rvh_vmscan_kswapd_wake
__tracepoint_android_vh_arch_set_freq_scale
__tracepoint_android_vh_audio_usb_offload_connect
__tracepoint_android_vh_binder_proc_transaction_finish
__tracepoint_android_vh_binder_restore_priority
__tracepoint_android_vh_binder_set_priority
__tracepoint_android_vh_cpu_idle_enter
@@ -2550,6 +2567,7 @@
__tracepoint_android_vh_sound_usb_support_cpu_suspend
__tracepoint_android_vh_sysrq_crash
__tracepoint_android_vh_timerfd_create
__tracepoint_android_vh_tune_swappiness
__tracepoint_android_vh_typec_store_partner_src_caps
__tracepoint_android_vh_typec_tcpci_override_toggling
__tracepoint_android_vh_typec_tcpm_get_timer

View File

@@ -72,6 +72,8 @@
bdev_end_io_acct
bdev_start_io_acct
bin2hex
bio_associate_blkg
bio_chain
bio_endio
bio_end_io_acct_remapped
bio_split
@@ -82,6 +84,7 @@
__bitmap_clear
__bitmap_complement
__bitmap_equal
bitmap_find_free_region
bitmap_find_next_zero_area_off
bitmap_free
__bitmap_intersects
@@ -495,6 +498,7 @@
dec_node_page_state
dec_zone_page_state
default_llseek
default_qdisc_ops
default_wake_function
deferred_free
delayed_work_timer_fn
@@ -503,6 +507,7 @@
del_timer_sync
desc_to_gpio
destroy_workqueue
dev_activate
dev_add_pack
dev_addr_mod
dev_alloc_name
@@ -513,6 +518,7 @@
dev_coredumpm
dev_coredumpv
_dev_crit
dev_deactivate
dev_driver_string
_dev_err
dev_err_probe
@@ -538,6 +544,7 @@
dev_get_regmap
dev_get_stats
dev_get_tstats64
dev_graft_qdisc
device_add
device_add_disk
device_add_groups
@@ -609,6 +616,7 @@
devm_gpiochip_add_data_with_key
devm_gpiod_get
devm_gpiod_get_optional
devm_gpiod_put
devm_gpio_request_one
devm_hwspin_lock_register
devm_i2c_new_dummy_device
@@ -629,6 +637,7 @@
devm_led_classdev_flash_register_ext
devm_led_classdev_register_ext
devm_mbox_controller_register
devm_memremap
devm_mipi_dsi_attach
devm_mipi_dsi_device_register_full
devm_nvmem_cell_get
@@ -1175,6 +1184,7 @@
freq_qos_add_request
freq_qos_remove_request
freq_qos_update_request
fs_bio_set
fsync_bdev
ftrace_dump
fwnode_find_reference
@@ -1219,13 +1229,16 @@
genphy_check_and_restart_aneg
__genphy_config_aneg
genphy_read_abilities
genphy_read_lpa
genphy_read_mmd_unsupported
genphy_read_status
genphy_read_status_fixed
genphy_restart_aneg
genphy_resume
genphy_setup_forced
genphy_soft_reset
genphy_suspend
genphy_update_link
genphy_write_mmd_unsupported
gen_pool_add_owner
gen_pool_alloc_algo_owner
@@ -1282,6 +1295,11 @@
gic_v3_cpu_init
gic_v3_dist_init
gic_v3_dist_wait_for_rwp
gnet_stats_add_basic
gnet_stats_add_queue
gnet_stats_basic_sync_init
gnet_stats_copy_basic
gnet_stats_copy_queue
gov_attr_set_init
gov_attr_set_put
governor_sysfs_ops
@@ -1572,6 +1590,7 @@
iommu_device_register
iommu_device_sysfs_add
iommu_device_sysfs_remove
iommu_device_unlink
iommu_device_unregister
iommu_dma_get_resv_regions
iommu_domain_alloc
@@ -1995,6 +2014,7 @@
module_layout
module_put
__module_put_and_kthread_exit
mq_change_real_num_tx
__msecs_to_jiffies
msi_first_desc
msi_get_virq
@@ -2042,6 +2062,7 @@
netdev_rx_handler_register
netdev_rx_handler_unregister
netdev_set_default_ethtool_ops
netdev_txq_to_tc
netdev_update_features
netdev_upper_dev_link
netdev_upper_dev_unlink
@@ -2117,6 +2138,7 @@
__nlmsg_put
nonseekable_open
noop_llseek
noop_qdisc
nr_cpu_ids
nr_ipi_get
nr_irqs
@@ -2139,6 +2161,7 @@
of_clk_add_hw_provider
of_clk_add_provider
of_clk_del_provider
of_clk_get
of_clk_get_from_provider
of_clk_get_parent_name
of_clk_hw_simple_get
@@ -2175,6 +2198,7 @@
of_genpd_del_provider
__of_get_address
of_get_child_by_name
of_get_compatible_child
of_get_cpu_node
of_get_mac_address
of_get_named_gpio_flags
@@ -2182,6 +2206,7 @@
of_get_next_child
of_get_next_parent
of_get_parent
of_get_phy_mode
of_get_property
of_get_regulator_init_data
of_get_required_opp_performance_state
@@ -2235,6 +2260,7 @@
of_reserved_mem_device_init_by_idx
of_reserved_mem_device_release
of_reserved_mem_lookup
__of_reset_control_get
of_root
of_thermal_get_ntrips
of_thermal_get_trip_points
@@ -2347,6 +2373,9 @@
perf_pmu_unregister
perf_trace_buf_alloc
perf_trace_run_bpf_submit
pfifo_fast_ops
pfifo_qdisc_ops
pfn_is_map_memory
phy_attached_info
phy_calibrate
phy_config_aneg
@@ -2356,6 +2385,7 @@
phy_drivers_register
phy_drivers_unregister
phy_error
phy_ethtool_get_eee
phy_ethtool_get_wol
phy_ethtool_set_wol
phy_exit
@@ -2395,19 +2425,32 @@
phylink_stop
phylink_suspend
phy_mac_interrupt
__phy_modify
phy_modify
phy_modify_changed
phy_modify_mmd
phy_modify_mmd_changed
phy_modify_paged
phy_modify_paged_changed
phy_power_off
phy_power_on
phy_read_mmd
phy_read_paged
phy_resolve_aneg_linkmode
phy_resolve_aneg_pause
phy_restart_aneg
phy_restore_page
phy_save_page
phy_select_page
phy_set_max_speed
phy_set_mode_ext
phy_sfp_attach
phy_sfp_detach
phy_sfp_probe
phy_suspend
phy_trigger_machine
phy_write_mmd
phy_write_paged
pick_highest_pushable_task
pick_migrate_task
pid_nr_ns
@@ -2573,6 +2616,15 @@
qcom_smem_state_register
qcom_smem_state_unregister
qcom_smem_state_update_bits
qdisc_create_dflt
qdisc_hash_add
qdisc_put
qdisc_reset
qdisc_tree_reduce_backlog
qdisc_watchdog_cancel
qdisc_watchdog_init
qdisc_watchdog_init_clockid
qdisc_watchdog_schedule_range_ns
queue_delayed_work_on
queue_work_on
radix_tree_delete
@@ -2765,6 +2817,7 @@
reset_control_acquire
reset_control_assert
reset_control_deassert
reset_control_put
reset_control_release
reset_control_reset
return_address
@@ -2832,6 +2885,7 @@
rt_mutex_trylock
rt_mutex_unlock
rtnl_is_locked
rtnl_kfree_skbs
rtnl_link_register
rtnl_link_unregister
rtnl_lock
@@ -3121,6 +3175,7 @@
snd_usb_endpoint_prepare
snd_usb_power_domain_set
snprintf
soc_device_match
soc_device_register
soc_device_unregister
sock_alloc_send_pskb
@@ -3129,6 +3184,7 @@
sock_common_recvmsg
sock_common_setsockopt
__sock_create
sock_create
sock_create_kern
sock_diag_register
sock_diag_save_cookie
@@ -3153,6 +3209,7 @@
sock_no_sendpage
sock_no_shutdown
sock_no_socketpair
sock_queue_err_skb
__sock_queue_rcv_skb
sock_queue_rcv_skb_reason
__sock_recv_cmsgs
@@ -3239,6 +3296,7 @@
strscpy_pad
strsep
strstr
submit_bio
__sw_hweight16
__sw_hweight32
__sw_hweight64

View File

@@ -2461,7 +2461,10 @@
devm_of_phy_get_by_index
driver_find_device
drm_aperture_remove_conflicting_framebuffers
drm_atomic_add_encoder_bridges
drm_atomic_bridge_chain_check
drm_atomic_commit
drm_atomic_get_bridge_state
drm_atomic_get_plane_state
drm_atomic_helper_check
drm_atomic_helper_check_plane_state
@@ -3034,3 +3037,16 @@
drm_edid_read_ddc
drm_edid_raw
drm_edid_connector_update
# required by 8250_dw.ko
serial8250_em485_supported
serial8250_em485_start_tx
serial8250_em485_stop_tx
serial8250_em485_config
serial8250_do_set_divisor
serial8250_do_set_ldisc
serial8250_update_uartclk
serial8250_clear_and_reinit_fifos
# required by pl2303.ko
tty_termios_hw_change

View File

@@ -70,3 +70,13 @@
register_tracepoint_module_notifier
scsi_register_driver
trace_seq_puts
# required for failure diagnostics
__traceiter_android_vh_mmc_blk_reset
__traceiter_android_vh_mmc_attach_sd
__traceiter_android_vh_sdhci_get_cd
__traceiter_android_vh_mmc_gpio_cd_irqt
__tracepoint_android_vh_mmc_blk_reset
__tracepoint_android_vh_mmc_attach_sd
__tracepoint_android_vh_sdhci_get_cd
__tracepoint_android_vh_mmc_gpio_cd_irqt

View File

@@ -25,6 +25,7 @@ bt_procfs_init
bt_sock_alloc
bt_sock_ioctl
bt_sock_link
bt_sock_linked
bt_sock_poll
bt_sock_reclassify_lock
bt_sock_recvmsg
@@ -97,6 +98,7 @@ hci_alloc_dev_priv
hci_cmd_sync
hci_cmd_sync_cancel
hci_cmd_sync_queue
hci_cmd_sync_status
hci_cmd_sync_submit
hci_conn_check_secure
hci_conn_security

View File

@@ -69,6 +69,7 @@ CONFIG_CMDLINE="console=ttynull stack_depot_disable=on cgroup_disable=pressure k
CONFIG_CMDLINE_EXTEND=y
# CONFIG_DMI is not set
CONFIG_HIBERNATION=y
CONFIG_PM_USERSPACE_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
@@ -341,6 +342,7 @@ CONFIG_DM_SNAPSHOT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_DM_BOW=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_WIREGUARD=y

View File

@@ -110,12 +110,14 @@ void pkvm_host_reclaim_page(struct kvm *host_kvm, phys_addr_t ipa);
* - Distinction between Secure and Non-secure Memory
* - Mixed-endian at EL0 only
* - Non-context synchronizing exception entry and exit
* - 16Kb stage-1 granule support
*/
#define PVM_ID_AA64MMFR0_ALLOW (\
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) \
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_TGRAN16) \
)
/*

View File

@@ -2084,6 +2084,12 @@ static void kvm_hyp_init_symbols(void)
kvm_nvhe_sym(kvm_arm_vmid_bits) = kvm_arm_vmid_bits;
kvm_nvhe_sym(smccc_trng_available) = smccc_trng_available;
kvm_nvhe_sym(kvm_host_sve_max_vl) = kvm_host_sve_max_vl;
/*
* Flush entire BSS since part of its data is read while the MMU is off.
*/
kvm_flush_dcache_to_poc(kvm_ksym_ref(__hyp_bss_start),
kvm_ksym_ref(__hyp_bss_end) - kvm_ksym_ref(__hyp_bss_start));
}
int kvm_hyp_init_events(void);

View File

@@ -567,6 +567,10 @@ static void sync_debug_state(struct pkvm_hyp_vcpu *hyp_vcpu)
return;
__vcpu_restore_guest_debug_regs(vcpu);
vcpu_write_sys_reg(host_vcpu, vcpu_read_sys_reg(vcpu, MDSCR_EL1),
MDSCR_EL1);
*vcpu_cpsr(host_vcpu) = *vcpu_cpsr(vcpu);
vcpu->arch.debug_ptr = &host_vcpu->arch.vcpu_debug_state;
}

View File

@@ -1122,7 +1122,9 @@ static int host_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
static int host_ack_unshare(u64 addr, const struct pkvm_mem_transition *tx)
{
return __host_ack_transition(addr, tx, PKVM_PAGE_SHARED_BORROWED);
u64 size = tx->nr_pages * PAGE_SIZE;
return __host_check_page_state_range(addr, size, PKVM_PAGE_SHARED_BORROWED);
}
static int host_complete_share(u64 addr, const struct pkvm_mem_transition *tx,
@@ -1237,9 +1239,6 @@ static int hyp_ack_unshare(u64 addr, const struct pkvm_mem_transition *tx)
if (tx->initiator.id == PKVM_ID_HOST && hyp_page_count((void *)addr))
return -EBUSY;
if (__hyp_ack_skip_pgtable_check(tx))
return 0;
return __hyp_check_page_state_range(addr, size,
PKVM_PAGE_SHARED_BORROWED);
}

View File

@@ -979,6 +979,9 @@ int init_hyp_tracefs(void)
if (!is_protected_kvm_enabled())
return 0;
for_each_possible_cpu(cpu)
mutex_init(&per_cpu(hyp_trace_reader_lock, cpu));
root_dir = tracefs_create_dir(TRACEFS_DIR, NULL);
if (!root_dir) {
pr_err("Failed to create tracefs "TRACEFS_DIR"/\n");

View File

@@ -64,6 +64,7 @@ CONFIG_EFI=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttynull stack_depot_disable=on cgroup_disable=pressure bootconfig"
CONFIG_HIBERNATION=y
CONFIG_PM_USERSPACE_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
@@ -319,6 +320,7 @@ CONFIG_DM_SNAPSHOT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_DM_BOW=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_WIREGUARD=y

View File

@@ -4080,7 +4080,6 @@ binder_request_freeze_notification(struct binder_proc *proc,
{
struct binder_ref_freeze *freeze;
struct binder_ref *ref;
bool is_frozen;
freeze = kzalloc(sizeof(*freeze), GFP_KERNEL);
if (!freeze)
@@ -4096,31 +4095,30 @@ binder_request_freeze_notification(struct binder_proc *proc,
}
binder_node_lock(ref->node);
if (ref->freeze || !ref->node->proc) {
binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n",
proc->pid, thread->pid,
ref->freeze ? "already set" : "dead node");
if (ref->freeze) {
binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n",
proc->pid, thread->pid);
binder_node_unlock(ref->node);
binder_proc_unlock(proc);
kfree(freeze);
return -EINVAL;
}
binder_inner_proc_lock(ref->node->proc);
is_frozen = ref->node->proc->is_frozen;
binder_inner_proc_unlock(ref->node->proc);
INIT_LIST_HEAD(&freeze->work.entry);
freeze->cookie = handle_cookie->cookie;
freeze->work.type = BINDER_WORK_FROZEN_BINDER;
freeze->is_frozen = is_frozen;
ref->freeze = freeze;
binder_inner_proc_lock(proc);
binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo);
binder_wakeup_proc_ilocked(proc);
binder_inner_proc_unlock(proc);
if (ref->node->proc) {
binder_inner_proc_lock(ref->node->proc);
freeze->is_frozen = ref->node->proc->is_frozen;
binder_inner_proc_unlock(ref->node->proc);
binder_inner_proc_lock(proc);
binder_enqueue_work_ilocked(&freeze->work, &proc->todo);
binder_wakeup_proc_ilocked(proc);
binder_inner_proc_unlock(proc);
}
binder_node_unlock(ref->node);
binder_proc_unlock(proc);
@@ -5400,6 +5398,15 @@ static void binder_release_work(struct binder_proc *proc,
} break;
case BINDER_WORK_NODE:
break;
case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: {
struct binder_ref_freeze *freeze;
freeze = container_of(w, struct binder_ref_freeze, work);
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
"undelivered freeze notification, %016llx\n",
(u64)freeze->cookie);
kfree(freeze);
} break;
default:
pr_err("unexpected work type, %d, not freed\n",
wtype);
@@ -6547,6 +6554,7 @@ static void binder_deferred_release(struct binder_proc *proc)
binder_release_work(proc, &proc->todo);
binder_release_work(proc, &proc->delivered_death);
binder_release_work(proc, &proc_wrapper(proc)->delivered_freeze);
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
"%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n",
@@ -6684,6 +6692,9 @@ static void print_binder_work_ilocked(struct seq_file *m,
case BINDER_WORK_FROZEN_BINDER:
seq_printf(m, "%shas frozen binder\n", prefix);
break;
case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION:
seq_printf(m, "%shas cleared freeze notification\n", prefix);
break;
default:
seq_printf(m, "%sunknown work: type %d\n", prefix, w->type);
break;
@@ -6833,6 +6844,10 @@ static void print_binder_proc(struct seq_file *m,
seq_puts(m, " has delivered dead binder\n");
break;
}
list_for_each_entry(w, &proc_wrapper(proc)->delivered_freeze, entry) {
seq_puts(m, " has delivered freeze binder\n");
break;
}
binder_inner_proc_unlock(proc);
if (!print_all && m->count == header_pos)
m->count = start_pos;

View File

@@ -45,6 +45,7 @@
#include <trace/hooks/selinux.h>
#include <trace/hooks/syscall_check.h>
#include <trace/hooks/remoteproc.h>
#include <trace/hooks/reboot.h>
#include <trace/hooks/rwsem.h>
#include <trace/hooks/futex.h>
#include <trace/hooks/fips140.h>
@@ -192,6 +193,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unreserve_highatomic_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rmqueue_bulk_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ra_tuning_max_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_mmap_readaround);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_slab_alloc_node);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_slab_free);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_hw_protection_shutdown);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_insert);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_node_delete);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_node_replace);
@@ -379,6 +383,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_compaction_try_to_compact_pages_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_alloc_pages_direct_reclaim_enter);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_alloc_pages_direct_reclaim_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_alloc_pages_may_oom_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_vmscan_kswapd_wake);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_vmscan_kswapd_done);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vmscan_kswapd_done);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_compaction_begin);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_compaction_end);
@@ -418,6 +424,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_delayacct_compact_start);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_delayacct_compact_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_delayacct_wpcopy_start);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_delayacct_wpcopy_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_io_statistics);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_usb_dev_suspend);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_usb_dev_resume);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sound_usb_support_cpu_suspend);
@@ -459,3 +466,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_oom_swapmem_gather_finish);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_read_fault);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_read);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_map_pages);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_blk_reset);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_attach_sd);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sdhci_get_cd);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt);

View File

@@ -104,12 +104,13 @@ static int __fwnode_link_add(struct fwnode_handle *con,
return 0;
}
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
u8 flags)
{
int ret;
mutex_lock(&fwnode_link_lock);
ret = __fwnode_link_add(con, sup, 0);
ret = __fwnode_link_add(con, sup, flags);
mutex_unlock(&fwnode_link_lock);
return ret;
}

View File

@@ -1008,6 +1008,7 @@ unsigned int pm_wakeup_irq(void)
{
return wakeup_irq[0];
}
EXPORT_SYMBOL_GPL(pm_wakeup_irq);
/**
* pm_get_wakeup_count - Read the number of registered wakeup events.

View File

@@ -231,20 +231,44 @@ extern const struct scmi_desc scmi_optee_desc;
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
/* Used for compactness and signature validation of the function pointers being
* passed.
*/
typedef void (*shmem_copy_toio_t)(void __iomem *to, const void *from,
size_t count);
typedef void (*shmem_copy_fromio_t)(void *to, const void __iomem *from,
size_t count);
/**
* struct scmi_shmem_io_ops - I/O operations to read from/write to
* Shared Memory
*
* @toio: Copy data to the shared memory area
* @fromio: Copy data from the shared memory area
*/
struct scmi_shmem_io_ops {
shmem_copy_fromio_t fromio;
shmem_copy_toio_t toio;
};
/* shmem related declarations */
struct scmi_shared_mem;
void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo);
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo,
shmem_copy_toio_t toio);
u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer);
struct scmi_xfer *xfer,
shmem_copy_fromio_t fromio);
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer);
size_t max_len, struct scmi_xfer *xfer,
shmem_copy_fromio_t fromio);
void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer);
bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem);
struct scmi_shmem_io_ops *shmem_get_io_ops(struct device_node *shmem);
/* declarations for message passing transports */
struct scmi_msg_payld;

View File

@@ -23,6 +23,7 @@
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
* @chan_lock: Lock that prevents multiple xfers from being queued
* @io_ops: Transport specific I/O operations
*/
struct scmi_mailbox {
struct mbox_client cl;
@@ -30,6 +31,7 @@ struct scmi_mailbox {
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
struct mutex chan_lock;
struct scmi_shmem_io_ops *io_ops;
};
#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@@ -38,7 +40,8 @@ static void tx_prepare(struct mbox_client *cl, void *m)
{
struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
shmem_tx_prepare(smbox->shmem, m, smbox->cinfo);
shmem_tx_prepare(smbox->shmem, m, smbox->cinfo,
smbox->io_ops->toio);
}
static void rx_callback(struct mbox_client *cl, void *m)
@@ -147,6 +150,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
cl->rx_callback = rx_callback;
cl->tx_block = false;
cl->knows_txdone = tx;
smbox->io_ops = shmem_get_io_ops(shmem);
smbox->chan = mbox_request_channel(cl, tx ? 0 : 1);
if (IS_ERR(smbox->chan)) {
@@ -222,7 +226,7 @@ static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
{
struct scmi_mailbox *smbox = cinfo->transport_info;
shmem_fetch_response(smbox->shmem, xfer);
shmem_fetch_response(smbox->shmem, xfer, smbox->io_ops->fromio);
}
static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
@@ -230,7 +234,8 @@ static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
{
struct scmi_mailbox *smbox = cinfo->transport_info;
shmem_fetch_notification(smbox->shmem, max_len, xfer);
shmem_fetch_notification(smbox->shmem, max_len, xfer,
smbox->io_ops->fromio);
}
static void mailbox_clear_channel(struct scmi_chan_info *cinfo)

View File

@@ -111,6 +111,7 @@ enum scmi_optee_pta_cmd {
* @cinfo: SCMI channel information
* @shmem: Virtual base address of the shared memory
* @req: Shared memory protocol handle for SCMI request and synchronous response
* @io_ops: Transport specific I/O operations
* @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
* @link: Reference in agent's channel list
*/
@@ -125,6 +126,7 @@ struct scmi_optee_channel {
struct scmi_shared_mem __iomem *shmem;
struct scmi_msg_payld *msg;
} req;
struct scmi_shmem_io_ops *io_ops;
struct tee_shm *tee_shm;
struct list_head link;
};
@@ -392,6 +394,8 @@ static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo,
goto out;
}
channel->io_ops = shmem_get_io_ops(np);
ret = 0;
out:
@@ -505,7 +509,8 @@ static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
msg_tx_prepare(channel->req.msg, xfer);
ret = invoke_process_msg_channel(channel, msg_command_size(xfer));
} else {
shmem_tx_prepare(channel->req.shmem, xfer, cinfo);
shmem_tx_prepare(channel->req.shmem, xfer, cinfo,
channel->io_ops->toio);
ret = invoke_process_smt_channel(channel);
}
@@ -523,7 +528,8 @@ static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
if (channel->tee_shm)
msg_fetch_response(channel->req.msg, channel->rx_len, xfer);
else
shmem_fetch_response(channel->req.shmem, xfer);
shmem_fetch_response(channel->req.shmem, xfer,
channel->io_ops->fromio);
}
static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,

View File

@@ -7,6 +7,7 @@
#include <linux/ktime.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/processor.h>
#include <linux/types.h>
@@ -32,8 +33,58 @@ struct scmi_shared_mem {
u8 msg_payload[];
};
static inline void shmem_memcpy_fromio32(void *to,
const void __iomem *from,
size_t count)
{
WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
!IS_ALIGNED((unsigned long)to, 4) ||
count % 4);
__ioread32_copy(to, from, count / 4);
}
static inline void shmem_memcpy_toio32(void __iomem *to,
const void *from,
size_t count)
{
WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
!IS_ALIGNED((unsigned long)to, 4) ||
count % 4);
__iowrite32_copy(to, from, count / 4);
}
static struct scmi_shmem_io_ops shmem_io_ops32 = {
.fromio = shmem_memcpy_fromio32,
.toio = shmem_memcpy_toio32,
};
/* Wrappers are needed for proper memcpy_{from,to}_io expansion by the
* pre-processor.
*/
static inline void shmem_memcpy_fromio(void *to,
const void __iomem *from,
size_t count)
{
memcpy_fromio(to, from, count);
}
static inline void shmem_memcpy_toio(void __iomem *to,
const void *from,
size_t count)
{
memcpy_toio(to, from, count);
}
static struct scmi_shmem_io_ops shmem_io_ops_default = {
.fromio = shmem_memcpy_fromio,
.toio = shmem_memcpy_toio,
};
void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo)
struct scmi_xfer *xfer, struct scmi_chan_info *cinfo,
shmem_copy_toio_t copy_toio)
{
ktime_t stop;
@@ -70,7 +121,7 @@ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
iowrite32(sizeof(shmem->msg_header) + xfer->tx.len, &shmem->length);
iowrite32(pack_scmi_header(&xfer->hdr), &shmem->msg_header);
if (xfer->tx.buf)
memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
copy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
}
u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
@@ -79,7 +130,8 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
}
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer)
struct scmi_xfer *xfer,
shmem_copy_fromio_t copy_fromio)
{
size_t len = ioread32(&shmem->length);
@@ -88,11 +140,12 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
copy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
}
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer)
size_t max_len, struct scmi_xfer *xfer,
shmem_copy_fromio_t copy_fromio)
{
size_t len = ioread32(&shmem->length);
@@ -100,7 +153,7 @@ void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
copy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
}
void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem)
@@ -128,3 +181,16 @@ bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem)
return (ioread32(&shmem->channel_status) &
SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
}
struct scmi_shmem_io_ops *shmem_get_io_ops(struct device_node *shmem)
{
u32 reg_io_width;
of_property_read_u32(shmem, "reg-io-width", &reg_io_width);
switch (reg_io_width) {
case 4:
return &shmem_io_ops32;
}
return &shmem_io_ops_default;
}

View File

@@ -26,6 +26,7 @@
* @irq: An optional IRQ for completion
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
* @io_ops: Transport specific I/O operations
* @shmem_lock: Lock to protect access to Tx/Rx shared memory area.
* Used when NOT operating in atomic mode.
* @inflight: Atomic flag to protect access to Tx/Rx shared memory area.
@@ -37,6 +38,7 @@ struct scmi_smc {
int irq;
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
struct scmi_shmem_io_ops *io_ops;
/* Protect access to shmem area */
struct mutex shmem_lock;
#define INFLIGHT_NONE MSG_TOKEN_MAX
@@ -158,6 +160,8 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
cinfo->no_completion_irq = true;
}
scmi_info->io_ops = shmem_get_io_ops(np);
scmi_info->func_id = func_id;
scmi_info->cinfo = cinfo;
smc_channel_lock_init(scmi_info);
@@ -202,7 +206,8 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
*/
smc_channel_lock_acquire(scmi_info, xfer);
shmem_tx_prepare(scmi_info->shmem, xfer, cinfo);
shmem_tx_prepare(scmi_info->shmem, xfer, cinfo,
scmi_info->io_ops->toio);
arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
@@ -220,7 +225,8 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo,
{
struct scmi_smc *scmi_info = cinfo->transport_info;
shmem_fetch_response(scmi_info->shmem, xfer);
shmem_fetch_response(scmi_info->shmem, xfer,
scmi_info->io_ops->fromio);
}
static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret,

View File

@@ -336,7 +336,7 @@ static int efifb_add_links(struct fwnode_handle *fwnode)
if (!sup_np)
return 0;
fwnode_link_add(fwnode, of_fwnode_handle(sup_np));
fwnode_link_add(fwnode, of_fwnode_handle(sup_np), 0);
of_node_put(sup_np);
return 0;

View File

@@ -679,6 +679,18 @@ config DM_AUDIT
Enables audit logging of several security relevant events in the
particular device-mapper targets, especially the integrity target.
config DM_BOW
tristate "Backup block device"
depends on BLK_DEV_DM
select DM_BUFIO
help
This device-mapper target takes a device and keeps a log of all
changes using free blocks identified by issuing a trim command.
This can then be restored by running a command line utility,
or committed by simply replacing the target.
If unsure, say N.
config DM_USER
tristate "Block device in userspace"
depends on BLK_DEV_DM

View File

@@ -85,6 +85,7 @@ obj-$(CONFIG_DM_INTEGRITY) += dm-integrity.o
obj-$(CONFIG_DM_ZONED) += dm-zoned.o
obj-$(CONFIG_DM_WRITECACHE) += dm-writecache.o
obj-$(CONFIG_SECURITY_LOADPIN_VERITY) += dm-verity-loadpin.o
obj-$(CONFIG_DM_BOW) += dm-bow.o
obj-$(CONFIG_DM_USER) += dm-user.o
ifeq ($(CONFIG_DM_INIT),y)

1309
drivers/md/dm-bow.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1068,8 +1068,10 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
* in that case.
*/
main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
if (err)
if (err) {
trace_android_vh_mmc_blk_reset(host, err);
return err;
}
/* Ensure we switch back to the correct partition */
if (mmc_blk_part_switch(host->card, md->part_type))
/*

View File

@@ -1885,5 +1885,7 @@ err:
pr_err("%s: error %d whilst initialising SD card\n",
mmc_hostname(host), err);
trace_android_vh_mmc_attach_sd(host, err);
return err;
}

View File

@@ -13,6 +13,7 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <trace/hooks/mmc.h>
#include "slot-gpio.h"
@@ -31,6 +32,8 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
struct mmc_host *host = dev_id;
struct mmc_gpio *ctx = host->slot.handler_priv;
trace_android_vh_mmc_gpio_cd_irqt(host);
host->trigger_card_event = true;
mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms));

View File

@@ -31,6 +31,7 @@
#include <linux/mmc/card.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>
#include <trace/hooks/mmc.h>
#include "sdhci.h"
@@ -2502,6 +2503,8 @@ static int sdhci_get_cd(struct mmc_host *mmc)
if (!mmc_card_is_removable(mmc))
return 1;
trace_android_vh_sdhci_get_cd(host);
/*
* Try slot gpio detect, if defined it take precedence
* over build in controller functionality

View File

@@ -1095,7 +1095,8 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np)
}
static void of_link_to_phandle(struct device_node *con_np,
struct device_node *sup_np)
struct device_node *sup_np,
u8 flags)
{
struct device_node *tmp_np = of_node_get(sup_np);
@@ -1114,7 +1115,7 @@ static void of_link_to_phandle(struct device_node *con_np,
tmp_np = of_get_next_parent(tmp_np);
}
fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np), flags);
}
/**
@@ -1227,6 +1228,8 @@ static struct device_node *parse_##fname(struct device_node *np, \
* @node_not_dev: The consumer node containing the property is never converted
* to a struct device. Instead, parse ancestor nodes for the
* compatible property to find a node corresponding to a device.
* @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link
* for this property.
*
* Returns:
* parse_prop() return values are
@@ -1239,6 +1242,7 @@ struct supplier_bindings {
const char *prop_name, int index);
bool optional;
bool node_not_dev;
u8 fwlink_flags;
};
DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")
@@ -1268,6 +1272,7 @@ DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells")
DEFINE_SIMPLE_PROP(leds, "leds", NULL)
DEFINE_SIMPLE_PROP(backlight, "backlight", NULL)
DEFINE_SIMPLE_PROP(panel, "panel", NULL)
DEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL)
DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
@@ -1373,6 +1378,10 @@ static const struct supplier_bindings of_supplier_bindings[] = {
{ .parse_prop = parse_regulators, },
{ .parse_prop = parse_gpio, },
{ .parse_prop = parse_gpios, },
{
.parse_prop = parse_post_init_providers,
.fwlink_flags = FWLINK_FLAG_IGNORE,
},
{}
};
@@ -1417,7 +1426,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
: of_node_get(con_np);
matched = true;
i++;
of_link_to_phandle(con_dev_np, phandle);
of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags);
of_node_put(phandle);
of_node_put(con_dev_np);
}

View File

@@ -73,6 +73,10 @@ int pci_host_common_probe(struct platform_device *pdev)
if (IS_ERR(cfg))
return PTR_ERR(cfg);
/* Do not reassign resources if probe only */
if (!pci_has_flag(PCI_PROBE_ONLY))
pci_add_flags(PCI_REASSIGN_ALL_BUS);
bridge->sysdata = cfg;
bridge->ops = (struct pci_ops *)&ops->pci_ops;
bridge->msi_domain = true;

View File

@@ -486,7 +486,6 @@ void pcie_port_device_remove(struct pci_dev *dev)
{
device_for_each_child(&dev->dev, NULL, remove_iter);
pci_free_irq_vectors(dev);
pci_disable_device(dev);
}
/**

View File

@@ -148,6 +148,19 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
}
pcie_port_device_remove(dev);
pci_disable_device(dev);
}
static void pcie_portdrv_shutdown(struct pci_dev *dev)
{
if (pci_bridge_d3_possible(dev)) {
pm_runtime_forbid(&dev->dev);
pm_runtime_get_noresume(&dev->dev);
pm_runtime_dont_use_autosuspend(&dev->dev);
}
pcie_port_device_remove(dev);
}
static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
@@ -198,7 +211,7 @@ static struct pci_driver pcie_portdriver = {
.probe = pcie_portdrv_probe,
.remove = pcie_portdrv_remove,
.shutdown = pcie_portdrv_remove,
.shutdown = pcie_portdrv_shutdown,
.err_handler = &pcie_portdrv_err_handler,

View File

@@ -3075,18 +3075,20 @@ int pci_host_probe(struct pci_host_bridge *bridge)
bus = bridge->bus;
/* If we must preserve the resource configuration, claim now */
if (bridge->preserve_config)
pci_bus_claim_resources(bus);
/*
* Assign whatever was left unassigned. If we didn't claim above,
* this will reassign everything.
* We insert PCI resources into the iomem_resource and
* ioport_resource trees in either pci_bus_claim_resources()
* or pci_bus_assign_resources().
*/
pci_assign_unassigned_root_bus_resources(bus);
if (pci_has_flag(PCI_PROBE_ONLY)) {
pci_bus_claim_resources(bus);
} else {
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
list_for_each_entry(child, &bus->children, node)
pcie_bus_configure_settings(child);
list_for_each_entry(child, &bus->children, node)
pcie_bus_configure_settings(child);
}
pci_bus_add_devices(bus);
return 0;

View File

@@ -220,6 +220,9 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
/* Set owner */
pindesc->pctldev = pctldev;
#ifdef CONFIG_PINMUX
mutex_init(&pindesc->mux_lock);
#endif
/* Copy basic pin info */
if (pin->name) {

View File

@@ -167,6 +167,7 @@ struct pin_desc {
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
struct mutex mux_lock;
#endif
};

View File

@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "pinmux core: " fmt
#include <linux/ctype.h>
#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -90,6 +91,7 @@ bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin)
if (!desc || !ops)
return true;
guard(mutex)(&desc->mux_lock);
if (ops->strict && desc->mux_usecount)
return false;
@@ -124,29 +126,31 @@ static int pin_request(struct pinctrl_dev *pctldev,
dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n",
pin, desc->name, owner);
if ((!gpio_range || ops->strict) &&
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->mux_owner, owner);
goto out;
}
scoped_guard(mutex, &desc->mux_lock) {
if ((!gpio_range || ops->strict) &&
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->mux_owner, owner);
goto out;
}
if ((gpio_range || ops->strict) && desc->gpio_owner) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->gpio_owner, owner);
goto out;
}
if ((gpio_range || ops->strict) && desc->gpio_owner) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
desc->name, desc->gpio_owner, owner);
goto out;
}
if (gpio_range) {
desc->gpio_owner = owner;
} else {
desc->mux_usecount++;
if (desc->mux_usecount > 1)
return 0;
if (gpio_range) {
desc->gpio_owner = owner;
} else {
desc->mux_usecount++;
if (desc->mux_usecount > 1)
return 0;
desc->mux_owner = owner;
desc->mux_owner = owner;
}
}
/* Let each pin increase references to this module */
@@ -177,12 +181,14 @@ static int pin_request(struct pinctrl_dev *pctldev,
out_free_pin:
if (status) {
if (gpio_range) {
desc->gpio_owner = NULL;
} else {
desc->mux_usecount--;
if (!desc->mux_usecount)
desc->mux_owner = NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (gpio_range) {
desc->gpio_owner = NULL;
} else {
desc->mux_usecount--;
if (!desc->mux_usecount)
desc->mux_owner = NULL;
}
}
}
out:
@@ -218,15 +224,17 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
return NULL;
}
if (!gpio_range) {
/*
* A pin should not be freed more times than allocated.
*/
if (WARN_ON(!desc->mux_usecount))
return NULL;
desc->mux_usecount--;
if (desc->mux_usecount)
return NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (!gpio_range) {
/*
* A pin should not be freed more times than allocated.
*/
if (WARN_ON(!desc->mux_usecount))
return NULL;
desc->mux_usecount--;
if (desc->mux_usecount)
return NULL;
}
}
/*
@@ -238,13 +246,15 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
else if (ops->free)
ops->free(pctldev, pin);
if (gpio_range) {
owner = desc->gpio_owner;
desc->gpio_owner = NULL;
} else {
owner = desc->mux_owner;
desc->mux_owner = NULL;
desc->mux_setting = NULL;
scoped_guard(mutex, &desc->mux_lock) {
if (gpio_range) {
owner = desc->gpio_owner;
desc->gpio_owner = NULL;
} else {
owner = desc->mux_owner;
desc->mux_owner = NULL;
desc->mux_setting = NULL;
}
}
module_put(pctldev->owner);
@@ -458,7 +468,8 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
desc->mux_setting = &(setting->data.mux);
scoped_guard(mutex, &desc->mux_lock)
desc->mux_setting = &(setting->data.mux);
}
ret = ops->set_mux(pctldev, setting->data.mux.func,
@@ -472,8 +483,10 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
err_set_mux:
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc)
desc->mux_setting = NULL;
if (desc) {
scoped_guard(mutex, &desc->mux_lock)
desc->mux_setting = NULL;
}
}
err_pin_request:
/* On error release all taken pins */
@@ -492,6 +505,7 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
unsigned num_pins = 0;
int i;
struct pin_desc *desc;
bool is_equal;
if (pctlops->get_group_pins)
ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
@@ -517,7 +531,10 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
if (desc->mux_setting == &(setting->data.mux)) {
scoped_guard(mutex, &desc->mux_lock)
is_equal = (desc->mux_setting == &(setting->data.mux));
if (is_equal) {
pin_free(pctldev, pins[i], NULL);
} else {
const char *gname;
@@ -609,40 +626,42 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
if (desc->mux_owner &&
!strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
is_hog = true;
scoped_guard(mutex, &desc->mux_lock) {
if (desc->mux_owner &&
!strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
is_hog = true;
if (pmxops->strict) {
if (desc->mux_owner)
seq_printf(s, "pin %d (%s): device %s%s",
pin, desc->name, desc->mux_owner,
if (pmxops->strict) {
if (desc->mux_owner)
seq_printf(s, "pin %d (%s): device %s%s",
pin, desc->name, desc->mux_owner,
is_hog ? " (HOG)" : "");
else if (desc->gpio_owner)
seq_printf(s, "pin %d (%s): GPIO %s",
pin, desc->name, desc->gpio_owner);
else
seq_printf(s, "pin %d (%s): UNCLAIMED",
pin, desc->name);
} else {
/* For non-strict controllers */
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
desc->mux_owner ? desc->mux_owner
: "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner
: "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
else if (desc->gpio_owner)
seq_printf(s, "pin %d (%s): GPIO %s",
pin, desc->name, desc->gpio_owner);
else
seq_printf(s, "pin %d (%s): UNCLAIMED",
pin, desc->name);
} else {
/* For non-strict controllers */
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
desc->mux_owner ? desc->mux_owner
: "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner
: "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
}
}
/* If mux: print function+group claiming the pin */
if (desc->mux_setting)
seq_printf(s, " function %s group %s\n",
pmxops->get_function_name(pctldev,
desc->mux_setting->func),
pctlops->get_group_name(pctldev,
desc->mux_setting->group));
else
seq_putc(s, '\n');
/* If mux: print function+group claiming the pin */
if (desc->mux_setting)
seq_printf(s, " function %s group %s\n",
pmxops->get_function_name(pctldev,
desc->mux_setting->func),
pctlops->get_group_name(pctldev,
desc->mux_setting->group));
else
seq_putc(s, '\n');
}
}
mutex_unlock(&pctldev->mutex);

View File

@@ -3764,6 +3764,9 @@ static int sd_resume_common(struct device *dev)
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
return 0;
if (!sdkp->device->manage_start_stop)
return 0;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1);

View File

@@ -40,6 +40,16 @@
#include "debug.h"
/*
* For type visibility (http://b/236036821)
*/
const struct dwc3 *const ANDROID_GKI_struct_dwc3;
EXPORT_SYMBOL_GPL(ANDROID_GKI_struct_dwc3);
#ifndef __GENKSYMS__
#include "../host/xhci.h"
#endif
#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
/**
@@ -106,23 +116,29 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
u32 reg;
int i;
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
if (enable && !dwc->dis_u3_susphy_quirk)
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
else
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
for (i = 0; i < vdwc->num_usb3_ports; i++) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i));
if (enable && !dwc->dis_u3_susphy_quirk)
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
else
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg);
}
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (enable && !dwc->dis_u2_susphy_quirk)
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
else
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
for (i = 0; i < vdwc->num_usb2_ports; i++) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
if (enable && !dwc->dis_u2_susphy_quirk)
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
else
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
}
}
void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
@@ -140,9 +156,11 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
static void __dwc3_set_mode(struct work_struct *work)
{
struct dwc3 *dwc = work_to_dwc(work);
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
unsigned long flags;
int ret;
u32 reg;
int i;
u32 desired_dr_role;
mutex_lock(&dwc->mutex);
@@ -221,8 +239,14 @@ static void __dwc3_set_mode(struct work_struct *work)
} else {
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_set_mode(vdwc->usb2_generic_phy[i], PHY_MODE_USB_HOST);
phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_set_mode(vdwc->usb3_generic_phy[i], PHY_MODE_USB_HOST);
if (dwc->dis_split_quirk) {
reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_SPLITDISABLE;
@@ -707,19 +731,11 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc)
return ret;
}
/**
* dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
* @dwc: Pointer to our controller context structure
*
* Returns 0 on success. The USB PHY interfaces are configured but not
* initialized. The PHY interfaces and the PHYs get initialized together with
* the core in dwc3_core_init.
*/
static int dwc3_phy_setup(struct dwc3 *dwc)
static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
{
u32 reg;
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(index));
/*
* Make sure UX_EXIT_PX is cleared as that causes issues with some
@@ -766,9 +782,18 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_del_phy_power_chg_quirk)
reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(index), reg);
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
return 0;
}
static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
{
unsigned int hw_mode;
u32 reg;
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index));
/* Select the HS PHY interface */
switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
@@ -780,7 +805,7 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
} else if (dwc->hsphy_interface &&
!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
} else {
/* Relying on default value. */
if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
@@ -828,7 +853,36 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u2_freeclk_exists_quirk || dwc->gfladj_refclk_lpm_sel)
reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
return 0;
}
/**
* dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
* @dwc: Pointer to our controller context structure
*
* Returns 0 on success. The USB PHY interfaces are configured but not
* initialized. The PHY interfaces and the PHYs get initialized together with
* the core in dwc3_core_init.
*/
static int dwc3_phy_setup(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
int i;
int ret;
for (i = 0; i < vdwc->num_usb3_ports; i++) {
ret = dwc3_ss_phy_setup(dwc, i);
if (ret)
return ret;
}
for (i = 0; i < vdwc->num_usb2_ports; i++) {
ret = dwc3_hs_phy_setup(dwc, i);
if (ret)
return ret;
}
return 0;
}
@@ -867,17 +921,30 @@ static void dwc3_clk_disable(struct dwc3 *dwc)
static void dwc3_core_exit(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
int i;
dwc3_event_buffers_cleanup(dwc);
usb_phy_set_suspend(dwc->usb2_phy, 1);
usb_phy_set_suspend(dwc->usb3_phy, 1);
phy_power_off(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_power_off(vdwc->usb2_generic_phy[i]);
phy_power_off(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_power_off(vdwc->usb3_generic_phy[i]);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
phy_exit(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_exit(vdwc->usb2_generic_phy[i]);
phy_exit(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_exit(vdwc->usb3_generic_phy[i]);
dwc3_clk_disable(dwc);
reset_control_assert(dwc->reset);
@@ -1110,9 +1177,11 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
*/
static int dwc3_core_init(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
unsigned int hw_mode;
u32 reg;
int ret;
int i, j;
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
@@ -1147,26 +1216,37 @@ static int dwc3_core_init(struct dwc3 *dwc)
usb_phy_init(dwc->usb2_phy);
usb_phy_init(dwc->usb3_phy);
ret = phy_init(dwc->usb2_generic_phy);
if (ret < 0)
goto err0a;
for (i = 1; i < vdwc->num_usb2_ports; i++) {
ret = phy_init(vdwc->usb2_generic_phy[i]);
if (ret < 0)
goto exit_usb2_phy;
}
ret = phy_init(dwc->usb3_generic_phy);
if (ret < 0) {
phy_exit(dwc->usb2_generic_phy);
goto err0a;
if (ret < 0)
goto exit_usb2_phy;
for (i = 1; i < vdwc->num_usb3_ports; i++) {
ret = phy_init(vdwc->usb3_generic_phy[i]);
if (ret < 0)
goto exit_usb3_phy;
}
ret = dwc3_core_soft_reset(dwc);
if (ret)
goto err1;
goto exit_usb3_phy;
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);
ret = dwc3_setup_scratch_buffers(dwc);
if (ret)
goto err1;
goto exit_usb3_phy;
/* Set power down scale of suspend_clk */
dwc3_set_power_down_clk_scale(dwc);
@@ -1181,18 +1261,31 @@ static int dwc3_core_init(struct dwc3 *dwc)
usb_phy_set_suspend(dwc->usb2_phy, 0);
usb_phy_set_suspend(dwc->usb3_phy, 0);
ret = phy_power_on(dwc->usb2_generic_phy);
if (ret < 0)
goto err2;
goto set_suspend_phy;
for (i = 1; i < vdwc->num_usb2_ports; i++) {
ret = phy_power_on(vdwc->usb2_generic_phy[i]);
if (ret < 0)
goto power_off_usb2_phy;
}
ret = phy_power_on(dwc->usb3_generic_phy);
if (ret < 0)
goto err3;
goto power_off_usb2_phy;
for (i = 1; i < vdwc->num_usb3_ports; i++) {
ret = phy_power_on(vdwc->usb3_generic_phy[i]);
if (ret < 0)
goto power_off_usb3_phy;
}
ret = dwc3_event_buffers_setup(dwc);
if (ret) {
dev_err(dwc->dev, "failed to setup event buffers\n");
goto err4;
goto power_off_usb3_phy;
}
/*
@@ -1323,21 +1416,39 @@ static int dwc3_core_init(struct dwc3 *dwc)
return 0;
err4:
/*
* Modified error handling for multiport phys:
* (http://b/233985973)
*/
power_off_usb3_phy:
for (j = i - 1; j > 0; j--)
phy_power_off(vdwc->usb3_generic_phy[j]);
phy_power_off(dwc->usb3_generic_phy);
i = vdwc->num_usb2_ports;
err3:
power_off_usb2_phy:
for (j = i - 1; j > 0; j--)
phy_power_off(vdwc->usb2_generic_phy[j]);
phy_power_off(dwc->usb2_generic_phy);
i = vdwc->num_usb3_ports;
err2:
set_suspend_phy:
usb_phy_set_suspend(dwc->usb2_phy, 1);
usb_phy_set_suspend(dwc->usb3_phy, 1);
err1:
exit_usb3_phy:
for (j = i - 1; j > 0; j--)
phy_exit(vdwc->usb3_generic_phy[j]);
phy_exit(dwc->usb3_generic_phy);
i = vdwc->num_usb2_ports;
exit_usb2_phy:
for (j = i - 1; j > 0; j--)
phy_exit(vdwc->usb2_generic_phy[j]);
phy_exit(dwc->usb2_generic_phy);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy);
err0a:
dwc3_ulpi_exit(dwc);
@@ -1348,9 +1459,13 @@ err0:
static int dwc3_core_get_phy(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
struct device *dev = dwc->dev;
struct device_node *node = dev->of_node;
struct phy *temp_phy = NULL;
char phy_name[9];
int ret;
int i;
if (node) {
dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
@@ -1376,22 +1491,48 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
return dev_err_probe(dev, ret, "no usb3 phy configured\n");
}
dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
if (IS_ERR(dwc->usb2_generic_phy)) {
ret = PTR_ERR(dwc->usb2_generic_phy);
if (ret == -ENOSYS || ret == -ENODEV)
dwc->usb2_generic_phy = NULL;
for (i = 0; i < vdwc->num_usb2_ports; i++) {
if (vdwc->num_usb2_ports == 1)
snprintf(phy_name, sizeof(phy_name), "usb2-phy");
else
return dev_err_probe(dev, ret, "no usb2 phy configured\n");
snprintf(phy_name, sizeof(phy_name), "usb2-%d", i);
temp_phy = devm_phy_get(dev, phy_name);
if (IS_ERR(temp_phy)) {
ret = PTR_ERR(temp_phy);
if (ret == -ENOSYS || ret == -ENODEV)
temp_phy = NULL;
else
return dev_err_probe(dev, ret, "failed to lookup phy %s\n",
phy_name);
}
if (i == 0)
dwc->usb2_generic_phy = temp_phy;
else
vdwc->usb2_generic_phy[i] = temp_phy;
}
dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
if (IS_ERR(dwc->usb3_generic_phy)) {
ret = PTR_ERR(dwc->usb3_generic_phy);
if (ret == -ENOSYS || ret == -ENODEV)
dwc->usb3_generic_phy = NULL;
for (i = 0; i < vdwc->num_usb3_ports; i++) {
if (vdwc->num_usb3_ports == 1)
snprintf(phy_name, sizeof(phy_name), "usb3-phy");
else
return dev_err_probe(dev, ret, "no usb3 phy configured\n");
snprintf(phy_name, sizeof(phy_name), "usb3-%d", i);
temp_phy = devm_phy_get(dev, phy_name);
if (IS_ERR(temp_phy)) {
ret = PTR_ERR(temp_phy);
if (ret == -ENOSYS || ret == -ENODEV)
temp_phy = NULL;
else
return dev_err_probe(dev, ret, "failed to lookup phy %s\n",
phy_name);
}
if (i == 0)
dwc->usb3_generic_phy = temp_phy;
else
vdwc->usb3_generic_phy[i] = temp_phy;
}
return 0;
@@ -1399,8 +1540,10 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
static int dwc3_core_init_mode(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
struct device *dev = dwc->dev;
int ret;
int i;
switch (dwc->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
@@ -1420,8 +1563,13 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_set_mode(vdwc->usb2_generic_phy[i], PHY_MODE_USB_HOST);
phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_set_mode(vdwc->usb3_generic_phy[i], PHY_MODE_USB_HOST);
ret = dwc3_host_init(dwc);
if (ret)
@@ -1779,20 +1927,73 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
return edev;
}
static int dwc3_get_num_ports(struct dwc3 *dwc)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
void __iomem *base;
u8 major_revision;
u32 offset;
u32 val;
/*
* Remap xHCI address space to access XHCI ext cap regs since it is
* needed to get information on number of ports present.
*/
base = ioremap(dwc->xhci_resources[0].start,
resource_size(&dwc->xhci_resources[0]));
if (!base)
return -ENOMEM;
offset = 0;
do {
offset = xhci_find_next_ext_cap(base, offset,
XHCI_EXT_CAPS_PROTOCOL);
if (!offset)
break;
val = readl(base + offset);
major_revision = XHCI_EXT_PORT_MAJOR(val);
val = readl(base + offset + 0x08);
if (major_revision == 0x03) {
vdwc->num_usb3_ports += XHCI_EXT_PORT_COUNT(val);
} else if (major_revision <= 0x02) {
vdwc->num_usb2_ports += XHCI_EXT_PORT_COUNT(val);
} else {
dev_warn(dwc->dev, "unrecognized port major revision %d\n",
major_revision);
}
} while (1);
dev_dbg(dwc->dev, "hs-ports: %u ss-ports: %u\n",
vdwc->num_usb2_ports, vdwc->num_usb3_ports);
iounmap(base);
if (vdwc->num_usb2_ports > DWC3_USB2_MAX_PORTS ||
vdwc->num_usb3_ports > DWC3_USB3_MAX_PORTS)
return -EINVAL;
return 0;
}
static int dwc3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res, dwc_res;
unsigned int hw_mode;
struct dwc3 *dwc;
struct dwc3_vendor *vdwc;
int ret;
int i;
void __iomem *regs;
dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
if (!dwc)
vdwc = devm_kzalloc(dev, sizeof(*vdwc), GFP_KERNEL);
if (!vdwc)
return -ENOMEM;
dwc = &vdwc->dwc;
dwc->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1909,6 +2110,20 @@ static int dwc3_probe(struct platform_device *pdev)
goto disable_clks;
}
/*
* Currently only DWC3 controllers that are host-only capable
* can have more than one port.
*/
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
if (hw_mode == DWC3_GHWPARAMS0_MODE_HOST) {
ret = dwc3_get_num_ports(dwc);
if (ret)
goto disable_clks;
} else {
vdwc->num_usb2_ports = 1;
vdwc->num_usb3_ports = 1;
}
spin_lock_init(&dwc->lock);
mutex_init(&dwc->mutex);
@@ -1966,13 +2181,25 @@ err5:
usb_phy_set_suspend(dwc->usb2_phy, 1);
usb_phy_set_suspend(dwc->usb3_phy, 1);
phy_power_off(dwc->usb2_generic_phy);
phy_power_off(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_power_off(vdwc->usb3_generic_phy[i]);
phy_power_off(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_power_off(vdwc->usb2_generic_phy[i]);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_exit(vdwc->usb3_generic_phy[i]);
phy_exit(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_exit(vdwc->usb2_generic_phy[i]);
dwc3_ulpi_exit(dwc);
@@ -2058,7 +2285,9 @@ assert_reset:
static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
u32 reg;
int i;
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -2077,17 +2306,22 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
/* Let controller to suspend HSPHY before PHY driver suspends */
if (dwc->dis_u2_susphy_quirk ||
dwc->dis_enblslpm_quirk) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
DWC3_GUSB2PHYCFG_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
for (i = 0; i < vdwc->num_usb2_ports; i++) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
DWC3_GUSB2PHYCFG_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
}
/* Give some time for USB2 PHY to suspend */
usleep_range(5000, 6000);
}
phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_pm_runtime_put_sync(vdwc->usb2_generic_phy[i]);
phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_pm_runtime_put_sync(vdwc->usb3_generic_phy[i]);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* do nothing during runtime_suspend */
@@ -2112,8 +2346,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
{
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
int ret;
u32 reg;
int i;
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -2133,17 +2369,23 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
break;
}
/* Restore GUSB2PHYCFG bits that were modified in suspend */
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (dwc->dis_u2_susphy_quirk)
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
for (i = 0; i < vdwc->num_usb2_ports; i++) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
if (dwc->dis_u2_susphy_quirk)
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
}
phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
for (i = 1; i < vdwc->num_usb2_ports; i++)
phy_pm_runtime_get_sync(vdwc->usb2_generic_phy[i]);
phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
for (i = 1; i < vdwc->num_usb3_ports; i++)
phy_pm_runtime_get_sync(vdwc->usb3_generic_phy[i]);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* nothing to do on runtime_resume */
@@ -2355,12 +2597,6 @@ static struct platform_driver dwc3_driver = {
module_platform_driver(dwc3_driver);
/*
* For type visibility (http://b/236036821)
*/
const struct dwc3 *const ANDROID_GKI_struct_dwc3;
EXPORT_SYMBOL_GPL(ANDROID_GKI_struct_dwc3);
MODULE_ALIAS("platform:dwc3");
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
MODULE_LICENSE("GPL v2");

View File

@@ -36,6 +36,13 @@
#include <linux/android_kabi.h>
/*
* DWC3 Multiport controllers support up to 15 High-Speed PHYs
* and 4 SuperSpeed PHYs.
*/
#define DWC3_USB2_MAX_PORTS 15
#define DWC3_USB3_MAX_PORTS 4
#define DWC3_MSG_MAX 500
/* Global constants */
@@ -1367,6 +1374,23 @@ struct dwc3 {
ANDROID_KABI_RESERVE(4);
};
/**
* struct dwc3_vendor - contains parameters without modifying the format of DWC3 core
* @dwc: contains dwc3 core reference
* @num_usb2_ports: number of USB2 ports
* @num_usb3_ports: number of USB3 ports
* @usb2_generic_phy: pointer to array of USB2 PHYs
* @usb3_generic_phy: pointer to array of USB3 PHYs
*/
struct dwc3_vendor {
struct dwc3 dwc;
u8 num_usb2_ports;
u8 num_usb3_ports;
struct phy *usb2_generic_phy[DWC3_USB2_MAX_PORTS];
struct phy *usb3_generic_phy[DWC3_USB3_MAX_PORTS];
};
#define INCRX_BURST_MODE 0
#define INCRX_UNDEF_LENGTH_BURST_MODE 1

View File

@@ -330,7 +330,9 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
int ret;
u32 reg;
int id;
int i;
unsigned long flags;
struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc);
if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
@@ -386,9 +388,13 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
} else {
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
if (dwc->usb2_generic_phy)
phy_set_mode(dwc->usb2_generic_phy,
PHY_MODE_USB_HOST);
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
for (i = 1; i < vdwc->num_usb2_ports; i++) {
if (vdwc->usb2_generic_phy[i]) {
phy_set_mode(vdwc->usb2_generic_phy[i],
PHY_MODE_USB_HOST);
}
}
}
break;
case DWC3_OTG_ROLE_DEVICE:

View File

@@ -287,6 +287,23 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
*
* Caller should handle locking. This function will issue @cmd with given
* @params to @dep and wait for its completion.
*
* According to the programming guide, if the link state is in L1/L2/U3,
* then sending the Start Transfer command may not complete. The
* programming guide suggested to bring the link state back to ON/U0 by
* performing remote wakeup prior to sending the command. However, don't
* initiate remote wakeup when the user/function does not send wakeup
* request via wakeup ops. Send the command when it's allowed.
*
* Notes:
* For L1 link state, issuing a command requires the clearing of
* GUSB2PHYCFG.SUSPENDUSB2, which turns on the signal required to complete
* the given command (usually within 50us). This should happen within the
* command timeout set by driver. No additional step is needed.
*
* For L2 or U3 link state, the gadget is in USB suspend. Care should be
* taken when sending Start Transfer command to ensure that it's done after
* USB resume.
*/
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
struct dwc3_gadget_ep_cmd_params *params)
@@ -327,30 +344,6 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
}
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
int link_state;
/*
* Initiate remote wakeup if the link state is in U3 when
* operating in SS/SSP or L1/L2 when operating in HS/FS. If the
* link state is in U1/U2, no remote wakeup is needed. The Start
* Transfer command will initiate the link recovery.
*/
link_state = dwc3_gadget_get_link_state(dwc);
switch (link_state) {
case DWC3_LINK_STATE_U2:
if (dwc->gadget->speed >= USB_SPEED_SUPER)
break;
fallthrough;
case DWC3_LINK_STATE_U3:
ret = __dwc3_gadget_wakeup(dwc);
dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
ret);
break;
}
}
/*
* For some commands such as Update Transfer command, DEPCMDPARn
* registers are reserved. Since the driver often sends Update Transfer
@@ -2595,6 +2588,8 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
__dwc3_gadget_stop(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED);
return ret;
}

View File

@@ -797,11 +797,13 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = {
/* -----------------------------------------------------------------------------
* streaming/uncompressed
* streaming/mjpeg
* streaming/framebased
*/
static const char * const uvcg_format_names[] = {
"uncompressed",
"mjpeg",
"framebased",
};
static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
@@ -914,6 +916,9 @@ static int uvcg_streaming_header_allow_link(struct config_item *src,
target_fmt = container_of(to_config_group(target), struct uvcg_format,
group);
if (!target_fmt)
goto out;
uvcg_format_set_indices(to_config_group(target));
format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
@@ -953,6 +958,9 @@ static void uvcg_streaming_header_drop_link(struct config_item *src,
target_fmt = container_of(to_config_group(target), struct uvcg_format,
group);
if (!target_fmt)
goto out;
list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
if (format_ptr->fmt == target_fmt) {
list_del(&format_ptr->entry);
@@ -963,6 +971,7 @@ static void uvcg_streaming_header_drop_link(struct config_item *src,
--target_fmt->linked;
out:
mutex_unlock(&opts->lock);
mutex_unlock(su_mutex);
}
@@ -1159,6 +1168,7 @@ UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32);
#undef UVCG_FRAME_ATTR
@@ -1172,7 +1182,7 @@ static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
int result, i;
char *pg = page;
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
@@ -1293,7 +1303,7 @@ end:
UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
static struct configfs_attribute *uvcg_frame_attrs[] = {
static struct configfs_attribute *uvcg_frame_attrs1[] = {
&uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_bm_capabilities,
&uvcg_frame_attr_w_width,
@@ -1306,12 +1316,31 @@ static struct configfs_attribute *uvcg_frame_attrs[] = {
NULL,
};
static const struct config_item_type uvcg_frame_type = {
static struct configfs_attribute *uvcg_frame_attrs2[] = {
&uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_bm_capabilities,
&uvcg_frame_attr_w_width,
&uvcg_frame_attr_w_height,
&uvcg_frame_attr_dw_min_bit_rate,
&uvcg_frame_attr_dw_max_bit_rate,
&uvcg_frame_attr_dw_default_frame_interval,
&uvcg_frame_attr_dw_frame_interval,
&uvcg_frame_attr_dw_bytes_perline,
NULL,
};
static const struct config_item_type uvcg_frame_type1 = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_attrs = uvcg_frame_attrs,
.ct_attrs = uvcg_frame_attrs1,
.ct_owner = THIS_MODULE,
};
static const struct config_item_type uvcg_frame_type2 = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_attrs = uvcg_frame_attrs2,
.ct_owner = THIS_MODULE,
};
static struct config_item *uvcg_frame_make(struct config_group *group,
const char *name)
{
@@ -1333,6 +1362,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
h->frame.dw_max_bit_rate = 55296000;
h->frame.dw_max_video_frame_buffer_size = 460800;
h->frame.dw_default_frame_interval = 666666;
h->frame.dw_bytes_perline = 0;
opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
@@ -1345,6 +1375,9 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
} else if (fmt->type == UVCG_MJPEG) {
h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
h->fmt_type = UVCG_MJPEG;
} else if (fmt->type == UVCG_FRAMEBASED) {
h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED;
h->fmt_type = UVCG_FRAMEBASED;
} else {
mutex_unlock(&opts->lock);
kfree(h);
@@ -1363,7 +1396,10 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
++fmt->num_frames;
mutex_unlock(&opts->lock);
config_item_init_type_name(&h->item, name, &uvcg_frame_type);
if (fmt->type == UVCG_FRAMEBASED)
config_item_init_type_name(&h->item, name, &uvcg_frame_type2);
else
config_item_init_type_name(&h->item, name, &uvcg_frame_type1);
return &h->item;
}
@@ -1403,9 +1439,6 @@ static void uvcg_format_set_indices(struct config_group *fmt)
list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
struct uvcg_frame *frm;
if (ci->ci_type != &uvcg_frame_type)
continue;
frm = to_uvcg_frame(ci);
frm->frame.b_frame_index = i++;
}
@@ -1836,6 +1869,251 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
.name = "mjpeg",
};
/* -----------------------------------------------------------------------------
* streaming/framebased/<NAME>
*/
static struct configfs_group_operations uvcg_framebased_group_ops = {
.make_item = uvcg_frame_make,
.drop_item = uvcg_frame_drop,
};
#define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits) \
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
char *page) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int result; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
mutex_unlock(&opts->lock); \
\
mutex_unlock(su_mutex); \
return result; \
} \
\
UVC_ATTR_RO(uvcg_framebased_, cname, aname)
#define UVCG_FRAMEBASED_ATTR(cname, aname, bits) \
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
char *page) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int result; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
mutex_unlock(&opts->lock); \
\
mutex_unlock(su_mutex); \
return result; \
} \
\
static ssize_t \
uvcg_framebased_##cname##_store(struct config_item *item, \
const char *page, size_t len) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int ret; \
u8 num; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
if (u->fmt.linked || opts->refcnt) { \
ret = -EBUSY; \
goto end; \
} \
\
ret = kstrtou8(page, 0, &num); \
if (ret) \
goto end; \
\
if (num > 255) { \
ret = -EINVAL; \
goto end; \
} \
u->desc.aname = num; \
ret = len; \
end: \
mutex_unlock(&opts->lock); \
mutex_unlock(su_mutex); \
return ret; \
} \
\
UVC_ATTR(uvcg_framebased_, cname, aname)
UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8);
UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8);
UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
#undef UVCG_FRAMEBASED_ATTR
#undef UVCG_FRAMEBASED_ATTR_RO
static ssize_t uvcg_framebased_guid_format_show(struct config_item *item,
char *page)
{
struct uvcg_framebased *ch = to_uvcg_framebased(item);
struct f_uvc_opts *opts;
struct config_item *opts_item;
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
mutex_lock(&opts->lock);
memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
mutex_unlock(&opts->lock);
mutex_unlock(su_mutex);
return sizeof(ch->desc.guidFormat);
}
static ssize_t uvcg_framebased_guid_format_store(struct config_item *item,
const char *page, size_t len)
{
struct uvcg_framebased *ch = to_uvcg_framebased(item);
struct f_uvc_opts *opts;
struct config_item *opts_item;
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
int ret;
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
mutex_lock(&opts->lock);
if (ch->fmt.linked || opts->refcnt) {
ret = -EBUSY;
goto end;
}
memcpy(ch->desc.guidFormat, page,
min(sizeof(ch->desc.guidFormat), len));
ret = sizeof(ch->desc.guidFormat);
end:
mutex_unlock(&opts->lock);
mutex_unlock(su_mutex);
return ret;
}
UVC_ATTR(uvcg_framebased_, guid_format, guidFormat);
static inline ssize_t
uvcg_framebased_bma_controls_show(struct config_item *item, char *page)
{
struct uvcg_framebased *u = to_uvcg_framebased(item);
return uvcg_format_bma_controls_show(&u->fmt, page);
}
static inline ssize_t
uvcg_framebased_bma_controls_store(struct config_item *item,
const char *page, size_t len)
{
struct uvcg_framebased *u = to_uvcg_framebased(item);
return uvcg_format_bma_controls_store(&u->fmt, page, len);
}
UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls);
static struct configfs_attribute *uvcg_framebased_attrs[] = {
&uvcg_framebased_attr_b_format_index,
&uvcg_framebased_attr_b_default_frame_index,
&uvcg_framebased_attr_b_bits_per_pixel,
&uvcg_framebased_attr_b_aspect_ratio_x,
&uvcg_framebased_attr_b_aspect_ratio_y,
&uvcg_framebased_attr_bm_interface_flags,
&uvcg_framebased_attr_bma_controls,
&uvcg_framebased_attr_guid_format,
NULL,
};
static const struct config_item_type uvcg_framebased_type = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_group_ops = &uvcg_framebased_group_ops,
.ct_attrs = uvcg_framebased_attrs,
.ct_owner = THIS_MODULE,
};
static struct config_group *uvcg_framebased_make(struct config_group *group,
const char *name)
{
static char guid[] = { /*Declear frame based as H264 format*/
'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
};
struct uvcg_framebased *h;
h = kzalloc(sizeof(*h), GFP_KERNEL);
if (!h)
return ERR_PTR(-ENOMEM);
h->desc.bLength = UVC_DT_FORMAT_FRAMEBASED_SIZE;
h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED;
memcpy(h->desc.guidFormat, guid, sizeof(guid));
h->desc.bBitsPerPixel = 0;
h->desc.bDefaultFrameIndex = 1;
h->desc.bAspectRatioX = 0;
h->desc.bAspectRatioY = 0;
h->desc.bmInterfaceFlags = 0;
h->desc.bCopyProtect = 0;
h->desc.bVariableSize = 1;
INIT_LIST_HEAD(&h->fmt.frames);
h->fmt.type = UVCG_FRAMEBASED;
config_group_init_type_name(&h->fmt.group, name,
&uvcg_framebased_type);
return &h->fmt.group;
}
static struct configfs_group_operations uvcg_framebased_grp_ops = {
.make_group = uvcg_framebased_make,
};
static const struct uvcg_config_group_type uvcg_framebased_grp_type = {
.type = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_group_ops = &uvcg_framebased_grp_ops,
.ct_owner = THIS_MODULE,
},
.name = "framebased",
};
/* -----------------------------------------------------------------------------
* streaming/color_matching/default
*/
@@ -1981,6 +2259,7 @@ static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
if (ret)
return ret;
grp = &f->fmt->group;
j = 0;
list_for_each_entry(item, &grp->cg_children, ci_entry) {
frm = to_uvcg_frame(item);
ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
@@ -2029,6 +2308,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
container_of(fmt, struct uvcg_mjpeg, fmt);
*size += sizeof(m->desc);
} else if (fmt->type == UVCG_FRAMEBASED) {
struct uvcg_framebased *f =
container_of(fmt, struct uvcg_framebased, fmt);
*size += sizeof(f->desc);
} else {
return -EINVAL;
}
@@ -2039,6 +2323,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
int sz = sizeof(frm->dw_frame_interval);
*size += sizeof(frm->frame);
/*
* framebased has duplicate member with uncompressed and
* mjpeg, so minus it
*/
*size -= sizeof(u32);
*size += frm->frame.b_frame_interval_type * sz;
}
break;
@@ -2049,6 +2338,27 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
return 0;
}
static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm,
int sz)
{
struct uvc_frame_framebased *desc = dest;
desc->bLength = frm->frame.b_length;
desc->bDescriptorType = frm->frame.b_descriptor_type;
desc->bDescriptorSubType = frm->frame.b_descriptor_subtype;
desc->bFrameIndex = frm->frame.b_frame_index;
desc->bmCapabilities = frm->frame.bm_capabilities;
desc->wWidth = frm->frame.w_width;
desc->wHeight = frm->frame.w_height;
desc->dwMinBitRate = frm->frame.dw_min_bit_rate;
desc->dwMaxBitRate = frm->frame.dw_max_bit_rate;
desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval;
desc->bFrameIntervalType = frm->frame.b_frame_interval_type;
desc->dwBytesPerLine = frm->frame.dw_bytes_perline;
return 0;
}
/*
* Fill an array of streaming descriptors.
*
@@ -2103,6 +2413,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
m->desc.bNumFrameDescriptors = fmt->num_frames;
memcpy(*dest, &m->desc, sizeof(m->desc));
*dest += sizeof(m->desc);
} else if (fmt->type == UVCG_FRAMEBASED) {
struct uvcg_framebased *f =
container_of(fmt, struct uvcg_framebased,
fmt);
f->desc.bFormatIndex = n + 1;
f->desc.bNumFrameDescriptors = fmt->num_frames;
memcpy(*dest, &f->desc, sizeof(f->desc));
*dest += sizeof(f->desc);
} else {
return -EINVAL;
}
@@ -2112,8 +2431,11 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
struct uvcg_frame *frm = priv1;
struct uvc_descriptor_header *h = *dest;
sz = sizeof(frm->frame);
memcpy(*dest, &frm->frame, sz);
sz = sizeof(frm->frame) - 4;
if (frm->fmt_type != UVCG_FRAMEBASED)
memcpy(*dest, &frm->frame, sz);
else
__uvcg_copy_framebased_desc(*dest, frm, sz);
*dest += sz;
sz = frm->frame.b_frame_interval_type *
sizeof(*frm->dw_frame_interval);
@@ -2124,7 +2446,10 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
frm->frame.b_frame_interval_type);
else if (frm->fmt_type == UVCG_MJPEG)
h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
frm->frame.b_frame_interval_type);
frm->frame.b_frame_interval_type);
else if (frm->fmt_type == UVCG_FRAMEBASED)
h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE(
frm->frame.b_frame_interval_type);
}
break;
}
@@ -2337,6 +2662,7 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
&uvcg_streaming_header_grp_type,
&uvcg_uncompressed_grp_type,
&uvcg_mjpeg_grp_type,
&uvcg_framebased_grp_type,
&uvcg_color_matching_grp_type,
&uvcg_streaming_class_grp_type,
NULL,

View File

@@ -40,6 +40,7 @@ static inline struct uvcg_control_header *to_uvcg_control_header(struct config_i
enum uvcg_format_type {
UVCG_UNCOMPRESSED = 0,
UVCG_MJPEG,
UVCG_FRAMEBASED,
};
struct uvcg_format {
@@ -95,6 +96,7 @@ struct uvcg_frame {
u32 dw_max_video_frame_buffer_size;
u32 dw_default_frame_interval;
u8 b_frame_interval_type;
u32 dw_bytes_perline;
} __attribute__((packed)) frame;
u32 *dw_frame_interval;
};
@@ -132,6 +134,20 @@ static inline struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
return container_of(to_uvcg_format(item), struct uvcg_mjpeg, fmt);
}
/* -----------------------------------------------------------------------------
* streaming/framebased/<NAME>
*/
struct uvcg_framebased {
struct uvcg_format fmt;
struct uvc_format_framebased desc;
};
static inline struct uvcg_framebased *to_uvcg_framebased(struct config_item *item)
{
return container_of(to_uvcg_format(item), struct uvcg_framebased, fmt);
}
int uvcg_attach_configfs(struct f_uvc_opts *opts);
#endif /* UVC_CONFIGFS_H */

View File

@@ -31,13 +31,22 @@ static struct uvc_format_desc *to_uvc_format(struct uvcg_format *uformat)
{
char guid[16] = UVC_GUID_FORMAT_MJPEG;
struct uvc_format_desc *format;
struct uvcg_uncompressed *unc;
if (uformat->type == UVCG_UNCOMPRESSED) {
struct uvcg_uncompressed *unc;
unc = to_uvcg_uncompressed(&uformat->group.cg_item);
if (!unc)
return ERR_PTR(-EINVAL);
memcpy(guid, unc->desc.guidFormat, sizeof(guid));
} else if (uformat->type == UVCG_FRAMEBASED) {
struct uvcg_framebased *unc;
unc = to_uvcg_framebased(&uformat->group.cg_item);
if (!unc)
return ERR_PTR(-EINVAL);
memcpy(guid, unc->desc.guidFormat, sizeof(guid));
}

View File

@@ -418,8 +418,9 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
* In the future we should distinguish between -ENODEV and -ETIMEDOUT
* and try to recover a -ETIMEDOUT with a host controller reset.
*/
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
ret = xhci_handshake_check_state(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000,
XHCI_STATE_REMOVING);
if (ret < 0) {
xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
xhci_halt(xhci);

View File

@@ -83,6 +83,29 @@ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us)
return ret;
}
/*
* xhci_handshake_check_state - same as xhci_handshake but takes an additional
* exit_state parameter, and bails out with an error immediately when xhc_state
* has exit_state flag set.
*/
int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec, unsigned int exit_state)
{
u32 result;
int ret;
ret = readl_poll_timeout_atomic(ptr, result,
(result & mask) == done ||
result == U32_MAX ||
xhci->xhc_state & exit_state,
1, usec);
if (result == U32_MAX || xhci->xhc_state & exit_state)
return -ENODEV;
return ret;
}
/*
* Disable interrupts and begin the xHCI halting process.
*/
@@ -203,7 +226,8 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
if (xhci->quirks & XHCI_INTEL_HOST)
udelay(1000);
ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us);
ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command,
CMD_RESET, 0, timeout_us, XHCI_STATE_REMOVING);
if (ret)
return ret;

View File

@@ -2142,6 +2142,8 @@ void xhci_free_container_ctx(struct xhci_hcd *xhci,
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us);
int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec, unsigned int exit_state);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);
int xhci_start(struct xhci_hcd *xhci);

View File

@@ -38,6 +38,9 @@
#include <linux/uio.h>
#include <linux/atomic.h>
#include <linux/prefetch.h>
#ifndef __GENKSYMS__
#include <trace/hooks/mm.h>
#endif
#include "internal.h"
@@ -1053,6 +1056,12 @@ do_holes:
put_page(page);
goto out;
}
trace_android_vh_io_statistics(dio->inode->i_mapping,
sdio->block_in_file >> sdio->blkfactor,
this_chunk_blocks >> sdio->blkfactor,
iov_iter_rw(sdio->iter) == READ, true);
sdio->next_block_for_io += this_chunk_blocks;
sdio->block_in_file += this_chunk_blocks;

View File

@@ -898,14 +898,15 @@ static bool cluster_has_invalid_data(struct compress_ctx *cc)
bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
{
#ifdef CONFIG_F2FS_CHECK_FS
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
bool compressed = dn->data_blkaddr == COMPRESS_ADDR;
int cluster_end = 0;
unsigned int count;
int i;
char *reason = "";
if (!compressed)
if (dn->data_blkaddr != COMPRESS_ADDR)
return false;
/* [..., COMPR_ADDR, ...] */
@@ -914,7 +915,7 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
goto out;
}
for (i = 1; i < cluster_size; i++) {
for (i = 1, count = 1; i < cluster_size; i++, count++) {
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
dn->ofs_in_node + i);
@@ -934,19 +935,42 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
goto out;
}
}
f2fs_bug_on(F2FS_I_SB(dn->inode), count != cluster_size &&
!is_inode_flag_set(dn->inode, FI_COMPRESS_RELEASED));
return false;
out:
f2fs_warn(sbi, "access invalid cluster, ino:%lu, nid:%u, ofs_in_node:%u, reason:%s",
dn->inode->i_ino, dn->nid, dn->ofs_in_node, reason);
set_sbi_flag(sbi, SBI_NEED_FSCK);
return true;
#else
return false;
#endif
}
static int __f2fs_cluster_blocks(struct inode *inode,
unsigned int cluster_idx, bool compr)
static int __f2fs_get_cluster_blocks(struct inode *inode,
struct dnode_of_data *dn)
{
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
int count, i;
for (i = 0, count = 0; i < cluster_size; i++) {
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
dn->ofs_in_node + i);
if (__is_valid_data_blkaddr(blkaddr))
count++;
}
return count;
}
static int __f2fs_cluster_blocks(struct inode *inode, unsigned int cluster_idx,
enum cluster_check_type type)
{
struct dnode_of_data dn;
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
unsigned int start_idx = cluster_idx <<
F2FS_I(inode)->i_log_cluster_size;
int ret;
@@ -961,31 +985,16 @@ static int __f2fs_cluster_blocks(struct inode *inode,
if (f2fs_sanity_check_cluster(&dn)) {
ret = -EFSCORRUPTED;
f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
goto fail;
}
if (dn.data_blkaddr == COMPRESS_ADDR) {
int i;
ret = 1;
for (i = 1; i < cluster_size; i++) {
block_t blkaddr;
blkaddr = data_blkaddr(dn.inode,
dn.node_page, dn.ofs_in_node + i);
if (compr) {
if (__is_valid_data_blkaddr(blkaddr))
ret++;
} else {
if (blkaddr != NULL_ADDR)
ret++;
}
}
f2fs_bug_on(F2FS_I_SB(inode),
!compr && ret != cluster_size &&
!is_inode_flag_set(inode, FI_COMPRESS_RELEASED));
if (type == CLUSTER_COMPR_BLKS)
ret = 1 + __f2fs_get_cluster_blocks(inode, &dn);
else if (type == CLUSTER_IS_COMPR)
ret = 1;
} else if (type == CLUSTER_RAW_BLKS) {
ret = __f2fs_get_cluster_blocks(inode, &dn);
}
fail:
f2fs_put_dnode(&dn);
@@ -995,15 +1004,33 @@ fail:
/* return # of compressed blocks in compressed cluster */
static int f2fs_compressed_blocks(struct compress_ctx *cc)
{
return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx, true);
return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx,
CLUSTER_COMPR_BLKS);
}
/* return # of valid blocks in compressed cluster */
/* return # of raw blocks in non-compressed cluster */
static int f2fs_decompressed_blocks(struct inode *inode,
unsigned int cluster_idx)
{
return __f2fs_cluster_blocks(inode, cluster_idx,
CLUSTER_RAW_BLKS);
}
/* return whether cluster is compressed one or not */
int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
{
return __f2fs_cluster_blocks(inode,
index >> F2FS_I(inode)->i_log_cluster_size,
false);
CLUSTER_IS_COMPR);
}
/* return whether cluster contains non raw blocks or not */
bool f2fs_is_sparse_cluster(struct inode *inode, pgoff_t index)
{
unsigned int cluster_idx = index >> F2FS_I(inode)->i_log_cluster_size;
return f2fs_decompressed_blocks(inode, cluster_idx) !=
F2FS_I(inode)->i_cluster_size;
}
static bool cluster_may_compress(struct compress_ctx *cc)

View File

@@ -1689,9 +1689,7 @@ next_block:
map->m_flags |= F2FS_MAP_NEW;
} else if (is_hole) {
if (f2fs_compressed_file(inode) &&
f2fs_sanity_check_cluster(&dn) &&
(flag != F2FS_GET_BLOCK_FIEMAP ||
IS_ENABLED(CONFIG_F2FS_CHECK_FS))) {
f2fs_sanity_check_cluster(&dn)) {
err = -EFSCORRUPTED;
f2fs_handle_error(sbi,
ERROR_CORRUPTED_CLUSTER);
@@ -1950,25 +1948,6 @@ static int f2fs_xattr_fiemap(struct inode *inode,
return (err < 0 ? err : 0);
}
static loff_t max_inode_blocks(struct inode *inode)
{
loff_t result = ADDRS_PER_INODE(inode);
loff_t leaf_count = ADDRS_PER_BLOCK(inode);
/* two direct node blocks */
result += (leaf_count * 2);
/* two indirect node blocks */
leaf_count *= NIDS_PER_BLOCK;
result += (leaf_count * 2);
/* one double indirect node block */
leaf_count *= NIDS_PER_BLOCK;
result += leaf_count;
return result;
}
int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
@@ -2041,8 +2020,7 @@ next:
if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
start_blk = next_pgofs;
if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
max_inode_blocks(inode)))
if (blks_to_bytes(inode, start_blk) < maxbytes)
goto prep_next;
flags |= FIEMAP_EXTENT_LAST;

View File

@@ -2235,6 +2235,31 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
return false;
}
static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, bool cap)
{
block_t avail_user_block_count;
avail_user_block_count = sbi->user_block_count -
sbi->current_reserved_blocks;
if (!__allow_reserved_blocks(sbi, inode, cap))
avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
if (F2FS_IO_ALIGNED(sbi))
avail_user_block_count -= sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
if (avail_user_block_count > sbi->unusable_block_count)
avail_user_block_count -= sbi->unusable_block_count;
else
avail_user_block_count = 0;
}
return avail_user_block_count;
}
static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, blkcnt_t *count, bool partial)
@@ -2260,22 +2285,8 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
spin_lock(&sbi->stat_lock);
sbi->total_valid_block_count += (block_t)(*count);
avail_user_block_count = sbi->user_block_count -
sbi->current_reserved_blocks;
avail_user_block_count = get_available_block_count(sbi, inode, true);
if (!__allow_reserved_blocks(sbi, inode, true))
avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
if (F2FS_IO_ALIGNED(sbi))
avail_user_block_count -= sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
if (avail_user_block_count > sbi->unusable_block_count)
avail_user_block_count -= sbi->unusable_block_count;
else
avail_user_block_count = 0;
}
if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
if (!partial) {
spin_unlock(&sbi->stat_lock);
@@ -2595,7 +2606,8 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
struct inode *inode, bool is_inode)
{
block_t valid_block_count;
unsigned int valid_node_count, user_block_count;
unsigned int valid_node_count;
unsigned int avail_user_block_count;
int err;
if (is_inode) {
@@ -2615,21 +2627,10 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
spin_lock(&sbi->stat_lock);
valid_block_count = sbi->total_valid_block_count +
sbi->current_reserved_blocks + 1;
valid_block_count = sbi->total_valid_block_count + 1;
avail_user_block_count = get_available_block_count(sbi, inode, false);
if (!__allow_reserved_blocks(sbi, inode, false))
valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;
if (F2FS_IO_ALIGNED(sbi))
valid_block_count += sbi->blocks_per_seg *
SM_I(sbi)->additional_reserved_segments;
user_block_count = sbi->user_block_count;
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
user_block_count -= sbi->unusable_block_count;
if (unlikely(valid_block_count > user_block_count)) {
if (unlikely(valid_block_count > avail_user_block_count)) {
spin_unlock(&sbi->stat_lock);
goto enospc;
}
@@ -4232,6 +4233,11 @@ static inline bool f2fs_meta_inode_gc_required(struct inode *inode)
* compress.c
*/
#ifdef CONFIG_F2FS_FS_COMPRESSION
enum cluster_check_type {
CLUSTER_IS_COMPR, /* check only if compressed cluster */
CLUSTER_COMPR_BLKS, /* return # of compressed blocks in a cluster */
CLUSTER_RAW_BLKS /* return # of raw blocks in a cluster */
};
bool f2fs_is_compressed_page(struct page *page);
struct page *f2fs_compress_control_page(struct page *page);
int f2fs_prepare_compress_overwrite(struct inode *inode,
@@ -4258,6 +4264,7 @@ int f2fs_write_multi_pages(struct compress_ctx *cc,
struct writeback_control *wbc,
enum iostat_type io_type);
int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index);
bool f2fs_is_sparse_cluster(struct inode *inode, pgoff_t index);
void f2fs_update_read_extent_tree_range_compressed(struct inode *inode,
pgoff_t fofs, block_t blkaddr,
unsigned int llen, unsigned int c_len);
@@ -4344,6 +4351,12 @@ static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi,
static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi,
nid_t ino) { }
#define inc_compr_inode_stat(inode) do { } while (0)
static inline int f2fs_is_compressed_cluster(
struct inode *inode,
pgoff_t index) { return 0; }
static inline bool f2fs_is_sparse_cluster(
struct inode *inode,
pgoff_t index) { return true; }
static inline void f2fs_update_read_extent_tree_range_compressed(
struct inode *inode,
pgoff_t fofs, block_t blkaddr,

View File

@@ -57,7 +57,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
struct inode *inode = file_inode(vmf->vma->vm_file);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
bool need_alloc = true;
bool need_alloc = !f2fs_is_pinned_file(inode);
int err = 0;
if (unlikely(IS_IMMUTABLE(inode)))
@@ -111,19 +111,18 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
goto out_sem;
}
set_new_dnode(&dn, inode, NULL, NULL, 0);
if (need_alloc) {
/* block allocation */
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = f2fs_get_block_locked(&dn, page->index);
}
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (!need_alloc) {
set_new_dnode(&dn, inode, NULL, NULL, 0);
} else {
err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
f2fs_put_dnode(&dn);
if (f2fs_is_pinned_file(inode) &&
!__is_valid_data_blkaddr(dn.data_blkaddr))
err = -EIO;
}
#endif
if (err) {
unlock_page(page);
goto out_sem;
@@ -394,9 +393,20 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
return f2fs_do_sync_file(file, start, end, datasync, false);
}
static bool __found_offset(struct address_space *mapping, block_t blkaddr,
pgoff_t index, int whence)
static bool __found_offset(struct address_space *mapping,
struct dnode_of_data *dn, pgoff_t index, int whence)
{
block_t blkaddr = f2fs_data_blkaddr(dn);
struct inode *inode = mapping->host;
bool compressed_cluster = false;
if (f2fs_compressed_file(inode)) {
block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page,
ALIGN_DOWN(dn->ofs_in_node, F2FS_I(inode)->i_cluster_size));
compressed_cluster = first_blkaddr == COMPRESS_ADDR;
}
switch (whence) {
case SEEK_DATA:
if (__is_valid_data_blkaddr(blkaddr))
@@ -404,8 +414,12 @@ static bool __found_offset(struct address_space *mapping, block_t blkaddr,
if (blkaddr == NEW_ADDR &&
xa_get_mark(&mapping->i_pages, index, PAGECACHE_TAG_DIRTY))
return true;
if (compressed_cluster)
return true;
break;
case SEEK_HOLE:
if (compressed_cluster)
return false;
if (blkaddr == NULL_ADDR)
return true;
break;
@@ -474,7 +488,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
goto fail;
}
if (__found_offset(file->f_mapping, blkaddr,
if (__found_offset(file->f_mapping, &dn,
pgofs, whence)) {
f2fs_put_dnode(&dn);
goto found;
@@ -3669,7 +3683,8 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
while (count) {
int compr_blocks = 0;
blkcnt_t reserved;
blkcnt_t reserved = 0;
blkcnt_t to_reserved;
int ret;
for (i = 0; i < cluster_size; i++) {
@@ -3689,20 +3704,26 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
* fails in release_compress_blocks(), so NEW_ADDR
* is a possible case.
*/
if (blkaddr == NEW_ADDR ||
__is_valid_data_blkaddr(blkaddr)) {
if (blkaddr == NEW_ADDR) {
reserved++;
continue;
}
if (__is_valid_data_blkaddr(blkaddr)) {
compr_blocks++;
continue;
}
}
reserved = cluster_size - compr_blocks;
to_reserved = cluster_size - compr_blocks - reserved;
/* for the case all blocks in cluster were reserved */
if (reserved == 1)
if (to_reserved == 1) {
dn->ofs_in_node += cluster_size;
goto next;
}
ret = inc_valid_block_count(sbi, dn->inode, &reserved, false);
ret = inc_valid_block_count(sbi, dn->inode,
&to_reserved, false);
if (unlikely(ret))
return ret;
@@ -3713,7 +3734,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);
*reserved_blocks += reserved;
*reserved_blocks += to_reserved;
next:
count -= cluster_size;
}
@@ -4139,10 +4160,9 @@ static int f2fs_ioc_decompress_file(struct file *filp)
struct inode *inode = file_inode(filp);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
pgoff_t page_idx = 0, last_idx;
pgoff_t page_idx = 0, last_idx, cluster_idx;
unsigned int blk_per_seg = sbi->blocks_per_seg;
int cluster_size = fi->i_cluster_size;
int count, ret;
int ret;
if (!f2fs_sb_has_compression(sbi) ||
F2FS_OPTION(sbi).compress_mode != COMPR_MODE_USER)
@@ -4177,12 +4197,15 @@ static int f2fs_ioc_decompress_file(struct file *filp)
goto out;
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
last_idx >>= fi->i_log_cluster_size;
count = last_idx - page_idx;
while (count) {
int len = min(cluster_size, count);
for (cluster_idx = 0; cluster_idx < last_idx; cluster_idx++) {
page_idx = cluster_idx << fi->i_log_cluster_size;
ret = redirty_blocks(inode, page_idx, len);
if (!f2fs_is_compressed_cluster(inode, page_idx))
continue;
ret = redirty_blocks(inode, page_idx, fi->i_cluster_size);
if (ret < 0)
break;
@@ -4192,8 +4215,11 @@ static int f2fs_ioc_decompress_file(struct file *filp)
break;
}
count -= len;
page_idx += len;
cond_resched();
if (fatal_signal_pending(current)) {
ret = -EINTR;
break;
}
}
if (!ret)
@@ -4214,10 +4240,10 @@ static int f2fs_ioc_compress_file(struct file *filp)
{
struct inode *inode = file_inode(filp);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
pgoff_t page_idx = 0, last_idx;
struct f2fs_inode_info *fi = F2FS_I(inode);
pgoff_t page_idx = 0, last_idx, cluster_idx;
unsigned int blk_per_seg = sbi->blocks_per_seg;
int cluster_size = F2FS_I(inode)->i_cluster_size;
int count, ret;
int ret;
if (!f2fs_sb_has_compression(sbi) ||
F2FS_OPTION(sbi).compress_mode != COMPR_MODE_USER)
@@ -4251,12 +4277,15 @@ static int f2fs_ioc_compress_file(struct file *filp)
set_inode_flag(inode, FI_ENABLE_COMPRESS);
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
last_idx >>= fi->i_log_cluster_size;
count = last_idx - page_idx;
while (count) {
int len = min(cluster_size, count);
for (cluster_idx = 0; cluster_idx < last_idx; cluster_idx++) {
page_idx = cluster_idx << fi->i_log_cluster_size;
ret = redirty_blocks(inode, page_idx, len);
if (f2fs_is_sparse_cluster(inode, page_idx))
continue;
ret = redirty_blocks(inode, page_idx, fi->i_cluster_size);
if (ret < 0)
break;
@@ -4266,8 +4295,11 @@ static int f2fs_ioc_compress_file(struct file *filp)
break;
}
count -= len;
page_idx += len;
cond_resched();
if (fatal_signal_pending(current)) {
ret = -EINTR;
break;
}
}
if (!ret)
@@ -4802,6 +4834,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
bool dio;
bool may_need_sync = true;
int preallocated;
const loff_t pos = iocb->ki_pos;
const ssize_t count = iov_iter_count(from);
ssize_t ret;
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
@@ -4823,6 +4857,12 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
inode_lock(inode);
}
if (f2fs_is_pinned_file(inode) &&
!f2fs_overwrite_io(inode, pos, count)) {
ret = -EIO;
goto out_unlock;
}
ret = f2fs_write_checks(iocb, from);
if (ret <= 0)
goto out_unlock;

View File

@@ -654,12 +654,30 @@ static inline bool has_enough_free_secs(struct f2fs_sb_info *sbi,
return !has_not_enough_free_secs(sbi, freed, needed);
}
static inline bool has_enough_free_blks(struct f2fs_sb_info *sbi)
{
unsigned int total_free_blocks = 0;
unsigned int avail_user_block_count;
spin_lock(&sbi->stat_lock);
avail_user_block_count = get_available_block_count(sbi, NULL, true);
total_free_blocks = avail_user_block_count - (unsigned int)valid_user_blocks(sbi);
spin_unlock(&sbi->stat_lock);
return total_free_blocks > 0;
}
static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)
{
if (likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
return true;
if (likely(has_enough_free_secs(sbi, 0, 0)))
return true;
if (!f2fs_lfs_mode(sbi) &&
likely(has_enough_free_blks(sbi)))
return true;
return false;
}

View File

@@ -2033,7 +2033,6 @@ static long wb_writeback(struct bdi_writeback *wb,
struct blk_plug plug;
blk_start_plug(&plug);
spin_lock(&wb->list_lock);
for (;;) {
/*
* Stop writeback when nr_pages has been consumed
@@ -2058,6 +2057,9 @@ static long wb_writeback(struct bdi_writeback *wb,
if (work->for_background && !wb_over_bg_thresh(wb))
break;
spin_lock(&wb->list_lock);
/*
* Kupdate and background works are special and we want to
* include all inodes that need writing. Livelock avoidance is
@@ -2087,13 +2089,19 @@ static long wb_writeback(struct bdi_writeback *wb,
* mean the overall work is done. So we keep looping as long
* as made some progress on cleaning pages or inodes.
*/
if (progress)
if (progress) {
spin_unlock(&wb->list_lock);
continue;
}
/*
* No more inodes for IO, bail
*/
if (list_empty(&wb->b_more_io))
if (list_empty(&wb->b_more_io)) {
spin_unlock(&wb->list_lock);
break;
}
/*
* Nothing written. Wait for some inode to
* become available for writeback. Otherwise
@@ -2105,9 +2113,7 @@ static long wb_writeback(struct bdi_writeback *wb,
spin_unlock(&wb->list_lock);
/* This function drops i_lock... */
inode_sleep_on_writeback(inode);
spin_lock(&wb->list_lock);
}
spin_unlock(&wb->list_lock);
blk_finish_plug(&plug);
return nr_pages - work->nr_pages;

View File

@@ -12,6 +12,9 @@
#include <linux/backing-dev.h>
#include <linux/uio.h>
#include <linux/task_io_accounting_ops.h>
#ifndef __GENKSYMS__
#include <trace/hooks/mm.h>
#endif
#include "trace.h"
#include "../internal.h"
@@ -320,6 +323,9 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
goto out;
}
trace_android_vh_io_statistics(inode->i_mapping, pos >> inode->i_blkbits,
nr_pages, !(dio->flags & IOMAP_DIO_WRITE), true);
bio = iomap_dio_alloc_bio(iter, dio, nr_pages, bio_opf);
fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
GFP_KERNEL);

View File

@@ -767,7 +767,6 @@ static inline void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
*/
void cgroup_rstat_updated(struct cgroup *cgrp, int cpu);
void cgroup_rstat_flush(struct cgroup *cgrp);
void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp);
void cgroup_rstat_flush_hold(struct cgroup *cgrp);
void cgroup_rstat_flush_release(void);

View File

@@ -215,7 +215,8 @@ static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode,
}
extern bool fw_devlink_is_strict(void);
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup);
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
u8 flags);
void fwnode_links_purge(struct fwnode_handle *fwnode);
void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode);

View File

@@ -1033,7 +1033,7 @@ static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,
}
void mem_cgroup_flush_stats(void);
void mem_cgroup_flush_stats_delayed(void);
void mem_cgroup_flush_stats_ratelimited(void);
void __mod_memcg_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx,
int val);
@@ -1519,7 +1519,7 @@ static inline void mem_cgroup_flush_stats(void)
{
}
static inline void mem_cgroup_flush_stats_delayed(void)
static inline void mem_cgroup_flush_stats_ratelimited(void)
{
}

View File

@@ -18,6 +18,10 @@ DECLARE_RESTRICTED_HOOK(android_rvh_shmem_get_folio,
TP_PROTO(struct shmem_inode_info *info, struct folio **folio),
TP_ARGS(info, folio), 2);
DECLARE_HOOK(android_vh_io_statistics,
TP_PROTO(struct address_space *mapping, unsigned int index,
unsigned int nr_page, bool read, bool direct),
TP_ARGS(mapping, index, nr_page, read, direct));
DECLARE_RESTRICTED_HOOK(android_rvh_set_gfp_zone_flags,
TP_PROTO(unsigned int *flags), /* gfp_t *flags */
TP_ARGS(flags), 1);
@@ -123,6 +127,12 @@ DECLARE_HOOK(android_vh_show_smap,
TP_PROTO(struct seq_file *m, unsigned long writeback,
unsigned long same, unsigned long huge),
TP_ARGS(m, writeback, same, huge));
DECLARE_HOOK(android_vh_slab_alloc_node,
TP_PROTO(void *object, unsigned long addr, struct kmem_cache *s),
TP_ARGS(object, addr, s));
DECLARE_HOOK(android_vh_slab_free,
TP_PROTO(unsigned long addr, struct kmem_cache *s),
TP_ARGS(addr, s));
DECLARE_HOOK(android_vh_meminfo_cache_adjust,
TP_PROTO(unsigned long *cached),
TP_ARGS(cached));

View File

@@ -9,6 +9,7 @@
struct mmc_host;
struct mmc_card;
struct mmc_queue;
struct sdhci_host;
/*
* Following tracepoints are not exported in tracefs and provide a
@@ -34,6 +35,22 @@ DECLARE_HOOK(android_vh_mmc_update_mmc_queue,
TP_PROTO(struct mmc_card *card, struct mmc_queue *mq),
TP_ARGS(card, mq));
DECLARE_HOOK(android_vh_mmc_blk_reset,
TP_PROTO(struct mmc_host *host, int err),
TP_ARGS(host, err));
DECLARE_HOOK(android_vh_mmc_attach_sd,
TP_PROTO(struct mmc_host *host, int err),
TP_ARGS(host, err));
DECLARE_HOOK(android_vh_sdhci_get_cd,
TP_PROTO(struct sdhci_host *host),
TP_ARGS(host));
DECLARE_HOOK(android_vh_mmc_gpio_cd_irqt,
TP_PROTO(struct mmc_host *host),
TP_ARGS(host));
#endif /* _TRACE_HOOK_MMC_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM reboot
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_REBOOT_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_REBOOT_H
#include <trace/hooks/vendor_hooks.h>
DECLARE_RESTRICTED_HOOK(android_rvh_hw_protection_shutdown,
TP_PROTO(const char *reason),
TP_ARGS(reason), 1);
#endif /* _TRACE_HOOK_REBOOT_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@@ -53,6 +53,13 @@ DECLARE_HOOK(android_vh_vmscan_kswapd_done,
TP_PROTO(int node_id, unsigned int highest_zoneidx, unsigned int alloc_order,
unsigned int reclaim_order),
TP_ARGS(node_id, highest_zoneidx, alloc_order, reclaim_order));
DECLARE_RESTRICTED_HOOK(android_rvh_vmscan_kswapd_wake,
TP_PROTO(int node_id, unsigned int highest_zoneidx, unsigned int alloc_order),
TP_ARGS(node_id, highest_zoneidx, alloc_order), 1);
DECLARE_RESTRICTED_HOOK(android_rvh_vmscan_kswapd_done,
TP_PROTO(int node_id, unsigned int highest_zoneidx, unsigned int alloc_order,
unsigned int reclaim_order),
TP_ARGS(node_id, highest_zoneidx, alloc_order, reclaim_order), 1);
DECLARE_HOOK(android_vh_handle_trylock_failed_folio,
TP_PROTO(struct list_head *folio_list),
TP_ARGS(folio_list));

View File

@@ -597,5 +597,63 @@ struct UVC_FRAME_MJPEG(n) { \
__le32 dwFrameInterval[n]; \
} __attribute__ ((packed))
/* Frame Based Payload - 3.1.1. Frame Based Video Format Descriptor */
struct uvc_format_framebased {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFormatIndex;
__u8 bNumFrameDescriptors;
__u8 guidFormat[16];
__u8 bBitsPerPixel;
__u8 bDefaultFrameIndex;
__u8 bAspectRatioX;
__u8 bAspectRatioY;
__u8 bmInterfaceFlags;
__u8 bCopyProtect;
__u8 bVariableSize;
} __attribute__((__packed__));
#define UVC_DT_FORMAT_FRAMEBASED_SIZE 28
/* Frame Based Payload - 3.1.2. Frame Based Video Frame Descriptor */
struct uvc_frame_framebased {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFrameIndex;
__u8 bmCapabilities;
__u16 wWidth;
__u16 wHeight;
__u32 dwMinBitRate;
__u32 dwMaxBitRate;
__u32 dwDefaultFrameInterval;
__u8 bFrameIntervalType;
__u32 dwBytesPerLine;
__u32 dwFrameInterval[];
} __attribute__((__packed__));
#define UVC_DT_FRAME_FRAMEBASED_SIZE(n) (26+4*(n))
#define UVC_FRAME_FRAMEBASED(n) \
uvc_frame_framebased_##n
#define DECLARE_UVC_FRAME_FRAMEBASED(n) \
struct UVC_FRAME_FRAMEBASED(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bFrameIndex; \
__u8 bmCapabilities; \
__u16 wWidth; \
__u16 wHeight; \
__u32 dwMinBitRate; \
__u32 dwMaxBitRate; \
__u32 dwDefaultFrameInterval; \
__u8 bFrameIntervalType; \
__u32 dwBytesPerLine; \
__u32 dwFrameInterval[n]; \
} __attribute__ ((packed))
#endif /* __LINUX_USB_VIDEO_H */

View File

@@ -171,7 +171,7 @@ __weak noinline void bpf_rstat_flush(struct cgroup *cgrp,
__diag_pop();
/* see cgroup_rstat_flush() */
static void cgroup_rstat_flush_locked(struct cgroup *cgrp, bool may_sleep)
static void cgroup_rstat_flush_locked(struct cgroup *cgrp)
__releases(&cgroup_rstat_lock) __acquires(&cgroup_rstat_lock)
{
int cpu;
@@ -207,9 +207,8 @@ static void cgroup_rstat_flush_locked(struct cgroup *cgrp, bool may_sleep)
}
raw_spin_unlock_irqrestore(cpu_lock, flags);
/* if @may_sleep, play nice and yield if necessary */
if (may_sleep && (need_resched() ||
spin_needbreak(&cgroup_rstat_lock))) {
/* play nice and yield if necessary */
if (need_resched() || spin_needbreak(&cgroup_rstat_lock)) {
spin_unlock_irq(&cgroup_rstat_lock);
if (!cond_resched())
cpu_relax();
@@ -236,25 +235,10 @@ void cgroup_rstat_flush(struct cgroup *cgrp)
might_sleep();
spin_lock_irq(&cgroup_rstat_lock);
cgroup_rstat_flush_locked(cgrp, true);
cgroup_rstat_flush_locked(cgrp);
spin_unlock_irq(&cgroup_rstat_lock);
}
/**
* cgroup_rstat_flush_irqsafe - irqsafe version of cgroup_rstat_flush()
* @cgrp: target cgroup
*
* This function can be called from any context.
*/
void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp)
{
unsigned long flags;
spin_lock_irqsave(&cgroup_rstat_lock, flags);
cgroup_rstat_flush_locked(cgrp, false);
spin_unlock_irqrestore(&cgroup_rstat_lock, flags);
}
/**
* cgroup_rstat_flush_hold - flush stats in @cgrp's subtree and hold
* @cgrp: target cgroup
@@ -269,7 +253,7 @@ void cgroup_rstat_flush_hold(struct cgroup *cgrp)
{
might_sleep();
spin_lock_irq(&cgroup_rstat_lock);
cgroup_rstat_flush_locked(cgrp, true);
cgroup_rstat_flush_locked(cgrp);
}
/**

View File

@@ -2813,12 +2813,14 @@ static int load_module(struct load_info *info, const char __user *uargs,
#ifdef CONFIG_MODULE_SIG
mod->sig_ok = info->sig_ok;
#ifndef CONFIG_MODULE_SIG_PROTECT
if (!mod->sig_ok) {
pr_notice_once("%s: module verification failed: signature "
"and/or required key missing - tainting "
"kernel\n", mod->name);
add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);
}
#endif
#else
mod->sig_ok = 0;
#endif

View File

@@ -19,6 +19,8 @@
#include <linux/syscore_ops.h>
#include <linux/uaccess.h>
#include <trace/hooks/reboot.h>
/*
* this indicates whether you can reboot with ctrl-alt-del: the default is yes
*/
@@ -979,6 +981,8 @@ void hw_protection_shutdown(const char *reason, int ms_until_forced)
if (!atomic_dec_and_test(&allow_proceed))
return;
trace_android_rvh_hw_protection_shutdown(reason);
/*
* Queue a backup emergency shutdown in the event of
* orderly_poweroff failure

View File

@@ -551,6 +551,8 @@ static u64 update_triggers(struct psi_group *group, u64 now)
if (now < t->last_event_time + t->win.size)
continue;
trace_android_vh_psi_event(t);
/* Generate an event */
if (cmpxchg(&t->event, 0, 1) == 0)
wake_up_interruptible(&t->event_wait);
@@ -559,6 +561,8 @@ static u64 update_triggers(struct psi_group *group, u64 now)
t->pending_event = false;
}
trace_android_vh_psi_group(group);
if (update_total)
memcpy(group->polling_total, total,
sizeof(group->polling_total));

View File

@@ -4710,6 +4710,7 @@ __weak const char *arch_vma_name(struct vm_area_struct *vma)
{
return NULL;
}
EXPORT_SYMBOL_GPL(arch_vma_name);
static inline void siginfo_buildtime_checks(void)
{

View File

@@ -3892,6 +3892,7 @@ again:
if (unlikely(status < 0))
break;
}
trace_android_vh_io_statistics(mapping, page->index, 1, false, false);
cond_resched();
if (unlikely(status == 0)) {

View File

@@ -2069,6 +2069,7 @@ spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
spin_unlock(ptl);
return NULL;
}
EXPORT_SYMBOL_GPL(__pmd_trans_huge_lock);
/*
* Returns page table lock pointer if a given pud maps a thp, NULL otherwise.

View File

@@ -103,6 +103,7 @@ struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
return vma->anon_name;
}
EXPORT_SYMBOL_GPL(anon_vma_name);
/* mmap_lock should be write-locked */
static int replace_anon_vma_name(struct vm_area_struct *vma,

View File

@@ -583,8 +583,8 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz)
*/
static void flush_memcg_stats_dwork(struct work_struct *w);
static DECLARE_DEFERRABLE_WORK(stats_flush_dwork, flush_memcg_stats_dwork);
static DEFINE_SPINLOCK(stats_flush_lock);
static DEFINE_PER_CPU(unsigned int, stats_updates);
static atomic_t stats_flush_ongoing = ATOMIC_INIT(0);
static atomic_t stats_flush_threshold = ATOMIC_INIT(0);
static u64 flush_next_time;
@@ -616,6 +616,9 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val)
{
unsigned int x;
if (!val)
return;
cgroup_rstat_updated(memcg->css.cgroup, smp_processor_id());
x = __this_cpu_add_return(stats_updates, abs(val));
@@ -632,34 +635,44 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val)
}
}
static void __mem_cgroup_flush_stats(void)
static void do_flush_stats(void)
{
unsigned long flag;
if (!spin_trylock_irqsave(&stats_flush_lock, flag))
/*
* We always flush the entire tree, so concurrent flushers can just
* skip. This avoids a thundering herd problem on the rstat global lock
* from memcg flushers (e.g. reclaim, refault, etc).
*/
if (atomic_read(&stats_flush_ongoing) ||
atomic_xchg(&stats_flush_ongoing, 1))
return;
flush_next_time = jiffies_64 + 2*FLUSH_TIME;
cgroup_rstat_flush_irqsafe(root_mem_cgroup->css.cgroup);
WRITE_ONCE(flush_next_time, jiffies_64 + 2*FLUSH_TIME);
cgroup_rstat_flush(root_mem_cgroup->css.cgroup);
atomic_set(&stats_flush_threshold, 0);
spin_unlock_irqrestore(&stats_flush_lock, flag);
atomic_set(&stats_flush_ongoing, 0);
}
void mem_cgroup_flush_stats(void)
{
if (atomic_read(&stats_flush_threshold) > num_online_cpus())
__mem_cgroup_flush_stats();
do_flush_stats();
}
void mem_cgroup_flush_stats_delayed(void)
void mem_cgroup_flush_stats_ratelimited(void)
{
if (time_after64(jiffies_64, flush_next_time))
if (time_after64(jiffies_64, READ_ONCE(flush_next_time)))
mem_cgroup_flush_stats();
}
static void flush_memcg_stats_dwork(struct work_struct *w)
{
__mem_cgroup_flush_stats();
/*
* Always flush here so that flushing in latency-sensitive paths is
* as cheap as possible.
*/
do_flush_stats();
queue_delayed_work(system_unbound_wq, &stats_flush_dwork, FLUSH_TIME);
}
@@ -3667,11 +3680,14 @@ static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
unsigned long val;
if (mem_cgroup_is_root(memcg)) {
mem_cgroup_flush_stats();
val = memcg_page_state(memcg, NR_FILE_PAGES) +
memcg_page_state(memcg, NR_ANON_MAPPED);
/*
* Approximate root's usage from global state. This isn't
* perfect, but the root usage was always an approximation.
*/
val = global_node_page_state(NR_FILE_PAGES) +
global_node_page_state(NR_ANON_MAPPED);
if (swap)
val += memcg_page_state(memcg, MEMCG_SWAP);
val += total_swap_pages - get_nr_swap_pages();
} else {
if (!swap)
val = page_counter_read(&memcg->memory);

View File

@@ -688,6 +688,7 @@ check_pfn:
out:
return pfn_to_page(pfn);
}
EXPORT_SYMBOL_GPL(vm_normal_page);
struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr,
pte_t pte)

View File

@@ -509,6 +509,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
} while (start = next, start < end);
return err;
}
EXPORT_SYMBOL_GPL(walk_page_range);
/**
* walk_page_range_novma - walk a range of pagetables not backed by a vma

View File

@@ -51,6 +51,7 @@ void pmd_clear_bad(pmd_t *pmd)
pmd_ERROR(*pmd);
pmd_clear(pmd);
}
EXPORT_SYMBOL_GPL(pmd_clear_bad);
#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
/*

View File

@@ -256,6 +256,7 @@ void page_cache_ra_unbounded(struct readahead_control *ractl,
continue;
}
trace_android_vh_io_statistics(mapping, index + i, 1, true, false);
folio = filemap_alloc_folio(gfp_mask, 0);
if (!folio)
break;

View File

@@ -3420,6 +3420,8 @@ redo:
out:
slab_post_alloc_hook(s, objcg, gfpflags, 1, &object, init);
trace_android_vh_slab_alloc_node(object, addr, s);
return object;
}
@@ -3683,6 +3685,9 @@ static __always_inline void slab_free(struct kmem_cache *s, struct slab *slab,
*/
if (slab_free_freelist_hook(s, &head, &tail, &cnt))
do_slab_free(s, slab, head, tail, cnt, addr);
trace_android_vh_slab_free(addr, s);
}
#ifdef CONFIG_KASAN_GENERIC

View File

@@ -2821,12 +2821,12 @@ unsigned long __reclaim_pages(struct list_head *folio_list, void *private)
return nr_reclaimed;
}
EXPORT_SYMBOL_GPL(reclaim_pages);
unsigned long reclaim_pages(struct list_head *folio_list)
{
return __reclaim_pages(folio_list, NULL);
}
EXPORT_SYMBOL_GPL(reclaim_pages);
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
struct lruvec *lruvec, struct scan_control *sc)
@@ -7881,8 +7881,12 @@ kswapd_try_sleep:
*/
trace_mm_vmscan_kswapd_wake(pgdat->node_id, highest_zoneidx,
alloc_order);
trace_android_rvh_vmscan_kswapd_wake(pgdat->node_id, highest_zoneidx,
alloc_order);
reclaim_order = balance_pgdat(pgdat, alloc_order,
highest_zoneidx);
trace_android_rvh_vmscan_kswapd_done(pgdat->node_id, highest_zoneidx,
alloc_order, reclaim_order);
trace_android_vh_vmscan_kswapd_done(pgdat->node_id, highest_zoneidx,
alloc_order, reclaim_order);
if (reclaim_order < alloc_order)

View File

@@ -409,6 +409,9 @@ void workingset_refault(struct folio *folio, void *shadow)
unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset);
eviction <<= bucket_order;
/* Flush stats (and potentially sleep) before holding RCU read lock */
mem_cgroup_flush_stats_ratelimited();
rcu_read_lock();
/*
* Look up the memcg associated with the stored ID. It might
@@ -463,8 +466,6 @@ void workingset_refault(struct folio *folio, void *shadow)
lruvec = mem_cgroup_lruvec(memcg, pgdat);
mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + file, nr);
mem_cgroup_flush_stats_delayed();
/*
* Compare the distance to the existing workingset size. We
* don't activate pages that couldn't stay resident even if