Merge branch 'perf/urgent'
Merge urgent fixes for dependencies. Signed-off-by: Peter Zijlstra <peterz@infradead.org>
This commit is contained in:
@@ -92,6 +92,7 @@ ForEachMacros:
|
||||
- '__rq_for_each_bio'
|
||||
- '__shost_for_each_device'
|
||||
- '__sym_for_each'
|
||||
- '_for_each_counter'
|
||||
- 'apei_estatus_for_each_section'
|
||||
- 'ata_for_each_dev'
|
||||
- 'ata_for_each_link'
|
||||
@@ -141,11 +142,14 @@ ForEachMacros:
|
||||
- 'damon_for_each_target_safe'
|
||||
- 'damos_for_each_filter'
|
||||
- 'damos_for_each_filter_safe'
|
||||
- 'damos_for_each_ops_filter'
|
||||
- 'damos_for_each_ops_filter_safe'
|
||||
- 'damos_for_each_quota_goal'
|
||||
- 'damos_for_each_quota_goal_safe'
|
||||
- 'data__for_each_file'
|
||||
- 'data__for_each_file_new'
|
||||
- 'data__for_each_file_start'
|
||||
- 'def_for_each_cpu'
|
||||
- 'device_for_each_child_node'
|
||||
- 'device_for_each_child_node_scoped'
|
||||
- 'dma_fence_array_for_each'
|
||||
@@ -176,6 +180,7 @@ ForEachMacros:
|
||||
- 'drm_for_each_privobj'
|
||||
- 'drm_gem_for_each_gpuvm_bo'
|
||||
- 'drm_gem_for_each_gpuvm_bo_safe'
|
||||
- 'drm_gpusvm_for_each_range'
|
||||
- 'drm_gpuva_for_each_op'
|
||||
- 'drm_gpuva_for_each_op_from_reverse'
|
||||
- 'drm_gpuva_for_each_op_reverse'
|
||||
@@ -216,8 +221,10 @@ ForEachMacros:
|
||||
- 'for_each_active_dev_scope'
|
||||
- 'for_each_active_drhd_unit'
|
||||
- 'for_each_active_iommu'
|
||||
- 'for_each_active_irq'
|
||||
- 'for_each_active_route'
|
||||
- 'for_each_aggr_pgid'
|
||||
- 'for_each_alloc_capable_rdt_resource'
|
||||
- 'for_each_and_bit'
|
||||
- 'for_each_andnot_bit'
|
||||
- 'for_each_available_child_of_node'
|
||||
@@ -228,6 +235,7 @@ ForEachMacros:
|
||||
- 'for_each_btf_ext_rec'
|
||||
- 'for_each_btf_ext_sec'
|
||||
- 'for_each_bvec'
|
||||
- 'for_each_capable_rdt_resource'
|
||||
- 'for_each_card_auxs'
|
||||
- 'for_each_card_auxs_safe'
|
||||
- 'for_each_card_components'
|
||||
@@ -241,6 +249,7 @@ ForEachMacros:
|
||||
- 'for_each_cgroup_storage_type'
|
||||
- 'for_each_child_of_node'
|
||||
- 'for_each_child_of_node_scoped'
|
||||
- 'for_each_child_of_node_with_prefix'
|
||||
- 'for_each_clear_bit'
|
||||
- 'for_each_clear_bit_from'
|
||||
- 'for_each_clear_bitrange'
|
||||
@@ -296,6 +305,7 @@ ForEachMacros:
|
||||
- 'for_each_group_member_head'
|
||||
- 'for_each_hstate'
|
||||
- 'for_each_hwgpio'
|
||||
- 'for_each_hwgpio_in_range'
|
||||
- 'for_each_if'
|
||||
- 'for_each_inject_fn'
|
||||
- 'for_each_insn'
|
||||
@@ -304,6 +314,7 @@ ForEachMacros:
|
||||
- 'for_each_intid'
|
||||
- 'for_each_iommu'
|
||||
- 'for_each_ip_tunnel_rcu'
|
||||
- 'for_each_irq_desc'
|
||||
- 'for_each_irq_nr'
|
||||
- 'for_each_lang'
|
||||
- 'for_each_link_ch_maps'
|
||||
@@ -324,6 +335,8 @@ ForEachMacros:
|
||||
- 'for_each_missing_reg'
|
||||
- 'for_each_mle_subelement'
|
||||
- 'for_each_mod_mem_type'
|
||||
- 'for_each_mon_capable_rdt_resource'
|
||||
- 'for_each_mp_bvec'
|
||||
- 'for_each_net'
|
||||
- 'for_each_net_continue_reverse'
|
||||
- 'for_each_net_rcu'
|
||||
@@ -351,6 +364,7 @@ ForEachMacros:
|
||||
- 'for_each_node_by_name'
|
||||
- 'for_each_node_by_type'
|
||||
- 'for_each_node_mask'
|
||||
- 'for_each_node_numadist'
|
||||
- 'for_each_node_state'
|
||||
- 'for_each_node_with_cpus'
|
||||
- 'for_each_node_with_property'
|
||||
@@ -359,6 +373,8 @@ ForEachMacros:
|
||||
- 'for_each_of_allnodes'
|
||||
- 'for_each_of_allnodes_from'
|
||||
- 'for_each_of_cpu_node'
|
||||
- 'for_each_of_graph_port'
|
||||
- 'for_each_of_graph_port_endpoint'
|
||||
- 'for_each_of_pci_range'
|
||||
- 'for_each_old_connector_in_state'
|
||||
- 'for_each_old_crtc_in_state'
|
||||
@@ -372,9 +388,11 @@ ForEachMacros:
|
||||
- 'for_each_oldnew_plane_in_state_reverse'
|
||||
- 'for_each_oldnew_private_obj_in_state'
|
||||
- 'for_each_online_cpu'
|
||||
- 'for_each_online_cpu_wrap'
|
||||
- 'for_each_online_node'
|
||||
- 'for_each_online_pgdat'
|
||||
- 'for_each_or_bit'
|
||||
- 'for_each_page_ext'
|
||||
- 'for_each_path'
|
||||
- 'for_each_pci_bridge'
|
||||
- 'for_each_pci_dev'
|
||||
@@ -382,8 +400,10 @@ ForEachMacros:
|
||||
- 'for_each_physmem_range'
|
||||
- 'for_each_populated_zone'
|
||||
- 'for_each_possible_cpu'
|
||||
- 'for_each_possible_cpu_wrap'
|
||||
- 'for_each_present_blessed_reg'
|
||||
- 'for_each_present_cpu'
|
||||
- 'for_each_present_section_nr'
|
||||
- 'for_each_prime_number'
|
||||
- 'for_each_prime_number_from'
|
||||
- 'for_each_probe_cache_entry'
|
||||
@@ -396,6 +416,7 @@ ForEachMacros:
|
||||
- 'for_each_prop_dlc_cpus'
|
||||
- 'for_each_prop_dlc_platforms'
|
||||
- 'for_each_property_of_node'
|
||||
- 'for_each_rdt_resource'
|
||||
- 'for_each_reg'
|
||||
- 'for_each_reg_filtered'
|
||||
- 'for_each_reloc'
|
||||
@@ -434,10 +455,10 @@ ForEachMacros:
|
||||
- 'for_each_subelement_id'
|
||||
- 'for_each_sublist'
|
||||
- 'for_each_subsystem'
|
||||
- 'for_each_suite'
|
||||
- 'for_each_supported_activate_fn'
|
||||
- 'for_each_supported_inject_fn'
|
||||
- 'for_each_sym'
|
||||
- 'for_each_test'
|
||||
- 'for_each_thread'
|
||||
- 'for_each_token'
|
||||
- 'for_each_unicast_dest_pgid'
|
||||
@@ -499,8 +520,10 @@ ForEachMacros:
|
||||
- 'idr_for_each_entry_continue'
|
||||
- 'idr_for_each_entry_continue_ul'
|
||||
- 'idr_for_each_entry_ul'
|
||||
- 'iio_for_each_active_channel'
|
||||
- 'in_dev_for_each_ifa_rcu'
|
||||
- 'in_dev_for_each_ifa_rtnl'
|
||||
- 'in_dev_for_each_ifa_rtnl_net'
|
||||
- 'inet_bind_bucket_for_each'
|
||||
- 'interval_tree_for_each_span'
|
||||
- 'intlist__for_each_entry'
|
||||
@@ -542,7 +565,6 @@ ForEachMacros:
|
||||
- 'list_for_each_prev'
|
||||
- 'list_for_each_prev_safe'
|
||||
- 'list_for_each_rcu'
|
||||
- 'list_for_each_reverse'
|
||||
- 'list_for_each_safe'
|
||||
- 'llist_for_each'
|
||||
- 'llist_for_each_entry'
|
||||
@@ -552,6 +574,7 @@ ForEachMacros:
|
||||
- 'map__for_each_symbol'
|
||||
- 'map__for_each_symbol_by_name'
|
||||
- 'mas_for_each'
|
||||
- 'mas_for_each_rev'
|
||||
- 'mci_for_each_dimm'
|
||||
- 'media_device_for_each_entity'
|
||||
- 'media_device_for_each_intf'
|
||||
@@ -561,10 +584,15 @@ ForEachMacros:
|
||||
- 'media_pipeline_for_each_entity'
|
||||
- 'media_pipeline_for_each_pad'
|
||||
- 'mlx5_lag_for_each_peer_mdev'
|
||||
- 'mptcp_for_each_subflow'
|
||||
- 'msi_domain_for_each_desc'
|
||||
- 'msi_for_each_desc'
|
||||
- 'mt_for_each'
|
||||
- 'nanddev_io_for_each_block'
|
||||
- 'nanddev_io_for_each_page'
|
||||
- 'neigh_for_each_in_bucket'
|
||||
- 'neigh_for_each_in_bucket_rcu'
|
||||
- 'neigh_for_each_in_bucket_safe'
|
||||
- 'netdev_for_each_lower_dev'
|
||||
- 'netdev_for_each_lower_private'
|
||||
- 'netdev_for_each_lower_private_rcu'
|
||||
@@ -604,11 +632,11 @@ ForEachMacros:
|
||||
- 'perf_evlist__for_each_entry_safe'
|
||||
- 'perf_evlist__for_each_evsel'
|
||||
- 'perf_evlist__for_each_mmap'
|
||||
- 'perf_evsel_for_each_per_thread_period_safe'
|
||||
- 'perf_hpp_list__for_each_format'
|
||||
- 'perf_hpp_list__for_each_format_safe'
|
||||
- 'perf_hpp_list__for_each_sort_list'
|
||||
- 'perf_hpp_list__for_each_sort_list_safe'
|
||||
- 'perf_tool_event__for_each_event'
|
||||
- 'plist_for_each'
|
||||
- 'plist_for_each_continue'
|
||||
- 'plist_for_each_entry'
|
||||
@@ -627,7 +655,6 @@ ForEachMacros:
|
||||
- 'rdma_for_each_block'
|
||||
- 'rdma_for_each_port'
|
||||
- 'rdma_umem_for_each_dma_block'
|
||||
- 'resort_rb__for_each_entry'
|
||||
- 'resource_list_for_each_entry'
|
||||
- 'resource_list_for_each_entry_safe'
|
||||
- 'rhl_for_each_entry_rcu'
|
||||
@@ -658,6 +685,7 @@ ForEachMacros:
|
||||
- 'shost_for_each_device'
|
||||
- 'sk_for_each'
|
||||
- 'sk_for_each_bound'
|
||||
- 'sk_for_each_bound_safe'
|
||||
- 'sk_for_each_entry_offset_rcu'
|
||||
- 'sk_for_each_from'
|
||||
- 'sk_for_each_rcu'
|
||||
@@ -680,7 +708,11 @@ ForEachMacros:
|
||||
- 'tb_property_for_each'
|
||||
- 'tcf_act_for_each_action'
|
||||
- 'tcf_exts_for_each_action'
|
||||
- 'test_suite__for_each_test_case'
|
||||
- 'tool_pmu__for_each_event'
|
||||
- 'ttm_bo_lru_for_each_reserved_guarded'
|
||||
- 'ttm_resource_manager_for_each_res'
|
||||
- 'udp_lrpa_for_each_entry_rcu'
|
||||
- 'udp_portaddr_for_each_entry'
|
||||
- 'udp_portaddr_for_each_entry_rcu'
|
||||
- 'usb_hub_for_each_child'
|
||||
@@ -691,6 +723,7 @@ ForEachMacros:
|
||||
- 'v4l2_m2m_for_each_src_buf_safe'
|
||||
- 'virtio_device_for_each_vq'
|
||||
- 'while_for_each_ftrace_op'
|
||||
- 'workloads__for_each'
|
||||
- 'xa_for_each'
|
||||
- 'xa_for_each_marked'
|
||||
- 'xa_for_each_range'
|
||||
|
||||
5
.mailmap
5
.mailmap
@@ -322,6 +322,7 @@ Jayachandran C <c.jayachandran@gmail.com> <jchandra@broadcom.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com>
|
||||
<jean-philippe@linaro.org> <jean-philippe.brucker@arm.com>
|
||||
Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org> <jeanmichel.hautbois@ideasonboard.com>
|
||||
Jean Tourrilhes <jt@hpl.hp.com>
|
||||
Jeevan Shriram <quic_jshriram@quicinc.com> <jshriram@codeaurora.org>
|
||||
Jeff Garzik <jgarzik@pretzel.yyz.us>
|
||||
@@ -438,6 +439,8 @@ Linus Lüssing <linus.luessing@c0d3.blue> <ll@simonwunderlich.de>
|
||||
Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||
Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
|
||||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org>
|
||||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com>
|
||||
Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com>
|
||||
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> <lstoakes@gmail.com>
|
||||
Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net>
|
||||
@@ -685,6 +688,8 @@ Simon Wunderlich <sw@simonwunderlich.de> <simon.wunderlich@saxnet.de>
|
||||
Simon Wunderlich <sw@simonwunderlich.de> <simon@open-mesh.com>
|
||||
Simon Wunderlich <sw@simonwunderlich.de> <siwu@hrz.tu-chemnitz.de>
|
||||
Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org>
|
||||
Srinivas Kandagatla <srini@kernel.org> <srinivas.kandagatla@st.com>
|
||||
Srinivas Kandagatla <srini@kernel.org> <srinivas.kandagatla@linaro.org>
|
||||
Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org>
|
||||
Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org>
|
||||
Sriram Yagnaraman <sriram.yagnaraman@ericsson.com> <sriram.yagnaraman@est.tech>
|
||||
|
||||
4
CREDITS
4
CREDITS
@@ -2071,6 +2071,10 @@ S: 660 Harvard Ave. #7
|
||||
S: Santa Clara, CA 95051
|
||||
S: USA
|
||||
|
||||
N: Joonsoo Kim
|
||||
E: iamjoonsoo.kim@lge.com
|
||||
D: Slab allocators
|
||||
|
||||
N: Kukjin Kim
|
||||
E: kgene@kernel.org
|
||||
D: Samsung S3C, S5P and Exynos ARM architectures
|
||||
|
||||
@@ -77,7 +77,7 @@ Description:
|
||||
|
||||
What: /sys/block/<disk>/diskseq
|
||||
Date: February 2021
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description:
|
||||
The /sys/block/<disk>/diskseq files reports the disk
|
||||
sequence number, which is a monotonically increasing
|
||||
|
||||
@@ -1604,3 +1604,35 @@ Description:
|
||||
prevent the UFS from frequently performing clock gating/ungating.
|
||||
|
||||
The attribute is read/write.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/device_lvl_exception_count
|
||||
What: /sys/bus/platform/devices/*.ufs/device_lvl_exception_count
|
||||
Date: March 2025
|
||||
Contact: Bao D. Nguyen <quic_nguyenb@quicinc.com>
|
||||
Description:
|
||||
This attribute is applicable to ufs devices compliant to the
|
||||
JEDEC specifications version 4.1 or later. The
|
||||
device_lvl_exception_count is a counter indicating the number of
|
||||
times the device level exceptions have occurred since the last
|
||||
time this variable is reset. Writing a 0 value to this
|
||||
attribute will reset the device_lvl_exception_count. If the
|
||||
device_lvl_exception_count reads a positive value, the user
|
||||
application should read the device_lvl_exception_id attribute to
|
||||
know more information about the exception.
|
||||
|
||||
The attribute is read/write.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/device_lvl_exception_id
|
||||
What: /sys/bus/platform/devices/*.ufs/device_lvl_exception_id
|
||||
Date: March 2025
|
||||
Contact: Bao D. Nguyen <quic_nguyenb@quicinc.com>
|
||||
Description:
|
||||
Reading the device_lvl_exception_id returns the
|
||||
qDeviceLevelExceptionID attribute of the ufs device JEDEC
|
||||
specification version 4.1. The definition of the
|
||||
qDeviceLevelExceptionID is the ufs device vendor specific
|
||||
implementation. Refer to the device manufacturer datasheet for
|
||||
more information on the meaning of the qDeviceLevelExceptionID
|
||||
attribute value.
|
||||
|
||||
The attribute is read only.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
What: /sys/kernel/reboot
|
||||
Date: November 2020
|
||||
KernelVersion: 5.11
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description: Interface to set the kernel reboot behavior, similarly to
|
||||
what can be done via the reboot= cmdline option.
|
||||
(see Documentation/admin-guide/kernel-parameters.txt)
|
||||
@@ -9,25 +9,25 @@ Description: Interface to set the kernel reboot behavior, similarly to
|
||||
What: /sys/kernel/reboot/mode
|
||||
Date: November 2020
|
||||
KernelVersion: 5.11
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description: Reboot mode. Valid values are: cold warm hard soft gpio
|
||||
|
||||
What: /sys/kernel/reboot/type
|
||||
Date: November 2020
|
||||
KernelVersion: 5.11
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description: Reboot type. Valid values are: bios acpi kbd triple efi pci
|
||||
|
||||
What: /sys/kernel/reboot/cpu
|
||||
Date: November 2020
|
||||
KernelVersion: 5.11
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description: CPU number to use to reboot.
|
||||
|
||||
What: /sys/kernel/reboot/force
|
||||
Date: November 2020
|
||||
KernelVersion: 5.11
|
||||
Contact: Matteo Croce <mcroce@microsoft.com>
|
||||
Contact: Matteo Croce <teknoraver@meta.com>
|
||||
Description: Don't wait for any other CPUs on reboot and
|
||||
avoid anything that could hang.
|
||||
|
||||
|
||||
@@ -124,6 +124,14 @@ When mounting an XFS filesystem, the following options are accepted.
|
||||
controls the size of each buffer and so is also relevant to
|
||||
this case.
|
||||
|
||||
lifetime (default) or nolifetime
|
||||
Enable data placement based on write life time hints provided
|
||||
by the user. This turns on co-allocation of data of similar
|
||||
life times when statistically favorable to reduce garbage
|
||||
collection cost.
|
||||
|
||||
These options are only available for zoned rt file systems.
|
||||
|
||||
logbsize=value
|
||||
Set the size of each in-memory log buffer. The size may be
|
||||
specified in bytes, or in kilobytes with a "k" suffix.
|
||||
@@ -143,6 +151,14 @@ When mounting an XFS filesystem, the following options are accepted.
|
||||
optional, and the log section can be separate from the data
|
||||
section or contained within it.
|
||||
|
||||
max_open_zones=value
|
||||
Specify the max number of zones to keep open for writing on a
|
||||
zoned rt device. Many open zones aids file data separation
|
||||
but may impact performance on HDDs.
|
||||
|
||||
If ``max_open_zones`` is not specified, the value is determined
|
||||
by the capabilities and the size of the zoned rt device.
|
||||
|
||||
noalign
|
||||
Data allocations will not be aligned at stripe unit
|
||||
boundaries. This is only relevant to filesystems created
|
||||
@@ -542,3 +558,37 @@ The interesting knobs for XFS workqueues are as follows:
|
||||
nice Relative priority of scheduling the threads. These are the
|
||||
same nice levels that can be applied to userspace processes.
|
||||
============ ===========
|
||||
|
||||
Zoned Filesystems
|
||||
=================
|
||||
|
||||
For zoned file systems, the following attribute is exposed in:
|
||||
|
||||
/sys/fs/xfs/<dev>/zoned/
|
||||
|
||||
max_open_zones (Min: 1 Default: Varies Max: UINTMAX)
|
||||
This read-only attribute exposes the maximum number of open zones
|
||||
available for data placement. The value is determined at mount time and
|
||||
is limited by the capabilities of the backing zoned device, file system
|
||||
size and the max_open_zones mount option.
|
||||
|
||||
Zoned Filesystems
|
||||
=================
|
||||
|
||||
For zoned file systems, the following attributes are exposed in:
|
||||
|
||||
/sys/fs/xfs/<dev>/zoned/
|
||||
|
||||
max_open_zones (Min: 1 Default: Varies Max: UINTMAX)
|
||||
This read-only attribute exposes the maximum number of open zones
|
||||
available for data placement. The value is determined at mount time and
|
||||
is limited by the capabilities of the backing zoned device, file system
|
||||
size and the max_open_zones mount option.
|
||||
|
||||
zonegc_low_space (Min: 0 Default: 0 Max: 100)
|
||||
Define a percentage for how much of the unused space that GC should keep
|
||||
available for writing. A high value will reclaim more of the space
|
||||
occupied by unused blocks, creating a larger buffer against write
|
||||
bursts at the cost of increased write amplification. Regardless
|
||||
of this value, garbage collection will always aim to free a minimum
|
||||
amount of blocks to keep max_open_zones open for data placement purposes.
|
||||
|
||||
@@ -51,7 +51,7 @@ The following keys are defined:
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_MARCHID`: Contains the value of ``marchid``, as
|
||||
defined by the RISC-V privileged architecture specification.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_MIMPLID`: Contains the value of ``mimplid``, as
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_MIMPID`: Contains the value of ``mimpid``, as
|
||||
defined by the RISC-V privileged architecture specification.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_BASE_BEHAVIOR`: A bitmask containing the base
|
||||
|
||||
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Ceva AHCI SATA Controller
|
||||
|
||||
maintainers:
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
description: |
|
||||
|
||||
@@ -111,11 +111,27 @@ properties:
|
||||
unevaluatedProperties: false
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
DSI output port node to the panel or the next bridge
|
||||
in the chain
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
description: array of physical DSI data lane indexes.
|
||||
minItems: 1
|
||||
items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
- const: 3
|
||||
- const: 4
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
@@ -12,7 +12,6 @@ description:
|
||||
PS_MODE). Every pin can be configured as input/output.
|
||||
|
||||
maintainers:
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
properties:
|
||||
|
||||
@@ -19,6 +19,7 @@ properties:
|
||||
- fsl,imx8mp-irqsteer
|
||||
- fsl,imx8qm-irqsteer
|
||||
- fsl,imx8qxp-irqsteer
|
||||
- fsl,imx94-irqsteer
|
||||
- const: fsl,imx-irqsteer
|
||||
|
||||
reg:
|
||||
|
||||
@@ -9,15 +9,6 @@ title: Renesas R-Car Timer Pulse Unit PWM Controller
|
||||
maintainers:
|
||||
- Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,tpu
|
||||
required:
|
||||
- compatible
|
||||
- '#pwm-cells'
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
|
||||
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Zynq UltraScale+ MPSoC and Versal reset
|
||||
|
||||
maintainers:
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
description: |
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Freescale Layerscape Reset Registers Module
|
||||
|
||||
maintainers:
|
||||
- Frank Li
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
description:
|
||||
Reset Module includes chip reset, service processor control and Reset Control
|
||||
|
||||
@@ -18,9 +18,14 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nxp,imx95-sysctr-timer
|
||||
- nxp,sysctr-timer
|
||||
oneOf:
|
||||
- enum:
|
||||
- nxp,imx95-sysctr-timer
|
||||
- nxp,sysctr-timer
|
||||
- items:
|
||||
- enum:
|
||||
- nxp,imx94-sysctr-timer
|
||||
- const: nxp,imx95-sysctr-timer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/renesas,tpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas H8/300 Timer Pulse Unit
|
||||
|
||||
maintainers:
|
||||
- Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
|
||||
description:
|
||||
The TPU is a 16bit timer/counter with configurable clock inputs and
|
||||
programmable compare match.
|
||||
This implementation supports only cascade mode.
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,tpu
|
||||
'#pwm-cells': false
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,tpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: First channel
|
||||
- description: Second channel
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: fck
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
tpu: tpu@ffffe0 {
|
||||
compatible = "renesas,tpu";
|
||||
reg = <0xffffe0 16>, <0xfffff0 12>;
|
||||
clocks = <&pclk>;
|
||||
clock-names = "fck";
|
||||
};
|
||||
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Xilinx SuperSpeed DWC3 USB SoC controller
|
||||
|
||||
maintainers:
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
properties:
|
||||
|
||||
@@ -17,7 +17,6 @@ description:
|
||||
|
||||
maintainers:
|
||||
- Michal Simek <michal.simek@amd.com>
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
properties:
|
||||
|
||||
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Xilinx udc controller
|
||||
|
||||
maintainers:
|
||||
- Mubin Sayyed <mubin.sayyed@amd.com>
|
||||
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
|
||||
properties:
|
||||
|
||||
@@ -123,12 +123,12 @@ attribute-sets:
|
||||
|
||||
operations:
|
||||
name-prefix: ovs-vport-cmd-
|
||||
fixed-header: ovs-header
|
||||
list:
|
||||
-
|
||||
name: new
|
||||
doc: Create a new OVS vport
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
@@ -141,7 +141,6 @@ operations:
|
||||
name: del
|
||||
doc: Delete existing OVS vport from a data path
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
@@ -152,7 +151,6 @@ operations:
|
||||
name: get
|
||||
doc: Get / dump OVS vport configuration and state
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do: &vport-get-op
|
||||
request:
|
||||
attributes:
|
||||
|
||||
@@ -1113,11 +1113,10 @@ attribute-sets:
|
||||
-
|
||||
name: prop-list
|
||||
type: nest
|
||||
nested-attributes: link-attrs
|
||||
nested-attributes: prop-list-link-attrs
|
||||
-
|
||||
name: alt-ifname
|
||||
type: string
|
||||
multi-attr: true
|
||||
-
|
||||
name: perm-address
|
||||
type: binary
|
||||
@@ -1163,6 +1162,13 @@ attribute-sets:
|
||||
-
|
||||
name: netns-immutable
|
||||
type: u8
|
||||
-
|
||||
name: prop-list-link-attrs
|
||||
subset-of: link-attrs
|
||||
attributes:
|
||||
-
|
||||
name: alt-ifname
|
||||
multi-attr: true
|
||||
-
|
||||
name: af-spec-attrs
|
||||
attributes:
|
||||
@@ -1585,7 +1591,7 @@ attribute-sets:
|
||||
name: nf-call-iptables
|
||||
type: u8
|
||||
-
|
||||
name: nf-call-ip6-tables
|
||||
name: nf-call-ip6tables
|
||||
type: u8
|
||||
-
|
||||
name: nf-call-arptables
|
||||
@@ -2077,7 +2083,7 @@ attribute-sets:
|
||||
name: id
|
||||
type: u16
|
||||
-
|
||||
name: flag
|
||||
name: flags
|
||||
type: binary
|
||||
struct: ifla-vlan-flags
|
||||
-
|
||||
@@ -2165,7 +2171,7 @@ attribute-sets:
|
||||
type: binary
|
||||
struct: ifla-cacheinfo
|
||||
-
|
||||
name: icmp6-stats
|
||||
name: icmp6stats
|
||||
type: binary
|
||||
struct: ifla-icmp6-stats
|
||||
-
|
||||
@@ -2179,9 +2185,10 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: mctp-attrs
|
||||
name-prefix: ifla-mctp-
|
||||
attributes:
|
||||
-
|
||||
name: mctp-net
|
||||
name: net
|
||||
type: u32
|
||||
-
|
||||
name: phys-binding
|
||||
@@ -2453,7 +2460,6 @@ operations:
|
||||
- min-mtu
|
||||
- max-mtu
|
||||
- prop-list
|
||||
- alt-ifname
|
||||
- perm-address
|
||||
- proto-down-reason
|
||||
- parent-dev-name
|
||||
|
||||
@@ -13,25 +13,25 @@ definitions:
|
||||
type: struct
|
||||
members:
|
||||
-
|
||||
name: family
|
||||
name: ndm-family
|
||||
type: u8
|
||||
-
|
||||
name: pad
|
||||
name: ndm-pad
|
||||
type: pad
|
||||
len: 3
|
||||
-
|
||||
name: ifindex
|
||||
name: ndm-ifindex
|
||||
type: s32
|
||||
-
|
||||
name: state
|
||||
name: ndm-state
|
||||
type: u16
|
||||
enum: nud-state
|
||||
-
|
||||
name: flags
|
||||
name: ndm-flags
|
||||
type: u8
|
||||
enum: ntf-flags
|
||||
-
|
||||
name: type
|
||||
name: ndm-type
|
||||
type: u8
|
||||
enum: rtm-type
|
||||
-
|
||||
@@ -189,7 +189,7 @@ attribute-sets:
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: lladr
|
||||
name: lladdr
|
||||
type: binary
|
||||
display-hint: mac
|
||||
-
|
||||
|
||||
@@ -154,7 +154,7 @@ suspending the device are satisfied) and to queue up a suspend request for the
|
||||
device in that case. If there is no idle callback, or if the callback returns
|
||||
0, then the PM core will attempt to carry out a runtime suspend of the device,
|
||||
also respecting devices configured for autosuspend. In essence this means a
|
||||
call to __pm_runtime_autosuspend() (do note that drivers needs to update the
|
||||
call to pm_runtime_autosuspend() (do note that drivers needs to update the
|
||||
device last busy mark, pm_runtime_mark_last_busy(), to control the delay under
|
||||
this circumstance). To prevent this (for example, if the callback routine has
|
||||
started a delayed suspend), the routine must return a non-zero value. Negative
|
||||
|
||||
@@ -27,7 +27,7 @@ SYSCALL
|
||||
=======
|
||||
mseal syscall signature
|
||||
-----------------------
|
||||
``int mseal(void \* addr, size_t len, unsigned long flags)``
|
||||
``int mseal(void *addr, size_t len, unsigned long flags)``
|
||||
|
||||
**addr**/**len**: virtual memory address range.
|
||||
The address range set by **addr**/**len** must meet:
|
||||
|
||||
@@ -138,6 +138,10 @@ input data, the meaning of which depends on the subfeature being accessed.
|
||||
The output buffer contains a single byte which signals success or failure (``0x00`` on failure)
|
||||
and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.
|
||||
|
||||
.. note::
|
||||
The ACPI control method responsible for handling the WMI method calls is not thread-safe.
|
||||
This is a firmware bug that needs to be handled inside the driver itself.
|
||||
|
||||
WMI method Get_EC()
|
||||
-------------------
|
||||
|
||||
|
||||
68
MAINTAINERS
68
MAINTAINERS
@@ -6335,6 +6335,7 @@ F: Documentation/process/cve.rst
|
||||
|
||||
CW1200 WLAN driver
|
||||
S: Orphan
|
||||
L: linux-wireless@vger.kernel.org
|
||||
F: drivers/net/wireless/st/
|
||||
F: include/linux/platform_data/net-cw1200.h
|
||||
|
||||
@@ -7020,6 +7021,7 @@ L: rust-for-linux@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://rust-for-linux.com
|
||||
T: git https://github.com/Rust-for-Linux/linux.git alloc-next
|
||||
F: rust/helpers/dma.c
|
||||
F: rust/kernel/dma.rs
|
||||
F: samples/rust/rust_dma.rs
|
||||
|
||||
@@ -10956,6 +10958,7 @@ F: include/linux/platform_data/huawei-gaokun-ec.h
|
||||
|
||||
HUGETLB SUBSYSTEM
|
||||
M: Muchun Song <muchun.song@linux.dev>
|
||||
R: Oscar Salvador <osalvador@suse.de>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages
|
||||
@@ -12812,6 +12815,7 @@ F: lib/Kconfig.kcsan
|
||||
F: scripts/Makefile.kcsan
|
||||
|
||||
KDUMP
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Baoquan He <bhe@redhat.com>
|
||||
R: Vivek Goyal <vgoyal@redhat.com>
|
||||
R: Dave Young <dyoung@redhat.com>
|
||||
@@ -13113,6 +13117,8 @@ F: fs/kernfs/
|
||||
F: include/linux/kernfs.h
|
||||
|
||||
KEXEC
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Baoquan He <bhe@redhat.com>
|
||||
L: kexec@lists.infradead.org
|
||||
W: http://kernel.org/pub/linux/utils/kernel/kexec/
|
||||
F: include/linux/kexec.h
|
||||
@@ -14285,6 +14291,7 @@ S: Odd fixes
|
||||
F: drivers/net/ethernet/marvell/sk*
|
||||
|
||||
MARVELL LIBERTAS WIRELESS DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: libertas-dev@lists.infradead.org
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/marvell/libertas/
|
||||
@@ -15510,6 +15517,21 @@ F: mm/numa.c
|
||||
F: mm/numa_emulation.c
|
||||
F: mm/numa_memblks.c
|
||||
|
||||
MEMORY MANAGEMENT - PAGE ALLOCATOR
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
R: Michal Hocko <mhocko@suse.com>
|
||||
R: Brendan Jackman <jackmanb@google.com>
|
||||
R: Johannes Weiner <hannes@cmpxchg.org>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/compaction.c
|
||||
F: mm/page_alloc.c
|
||||
F: include/linux/gfp.h
|
||||
F: include/linux/compaction.h
|
||||
|
||||
MEMORY MANAGEMENT - SECRETMEM
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Mike Rapoport <rppt@kernel.org>
|
||||
@@ -15537,10 +15559,12 @@ M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
R: Pedro Falcato <pfalcato@suse.de>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: include/trace/events/mmap.h
|
||||
F: mm/mlock.c
|
||||
F: mm/mmap.c
|
||||
F: mm/mprotect.c
|
||||
@@ -15551,6 +15575,36 @@ F: mm/vma.h
|
||||
F: mm/vma_internal.h
|
||||
F: tools/testing/vma/
|
||||
|
||||
MEMORY MAPPING - LOCKING
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Suren Baghdasaryan <surenb@google.com>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: Documentation/mm/process_addrs.rst
|
||||
F: include/linux/mmap_lock.h
|
||||
F: include/trace/events/mmap_lock.h
|
||||
F: mm/mmap_lock.c
|
||||
|
||||
MEMORY MAPPING - MADVISE (MEMORY ADVICE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: include/uapi/asm-generic/mman-common.h
|
||||
F: mm/madvise.c
|
||||
|
||||
MEMORY TECHNOLOGY DEVICES (MTD)
|
||||
M: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
M: Richard Weinberger <richard@nod.at>
|
||||
@@ -17370,7 +17424,7 @@ T: git git://git.infradead.org/nvme.git
|
||||
F: drivers/nvme/target/
|
||||
|
||||
NVMEM FRAMEWORK
|
||||
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
M: Srinivas Kandagatla <srini@kernel.org>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git
|
||||
F: Documentation/ABI/stable/sysfs-bus-nvmem
|
||||
@@ -19575,7 +19629,7 @@ S: Supported
|
||||
F: drivers/crypto/intel/qat/
|
||||
|
||||
QCOM AUDIO (ASoC) DRIVERS
|
||||
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
M: Srinivas Kandagatla <srini@kernel.org>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Supported
|
||||
@@ -19748,6 +19802,7 @@ F: drivers/media/tuners/qt1010*
|
||||
|
||||
QUALCOMM ATH12K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath12k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k
|
||||
@@ -19757,6 +19812,7 @@ N: ath12k
|
||||
|
||||
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath10k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
|
||||
@@ -19766,6 +19822,7 @@ N: ath10k
|
||||
|
||||
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath11k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k
|
||||
@@ -19875,7 +19932,7 @@ F: Documentation/devicetree/bindings/net/qcom,ethqos.yaml
|
||||
F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
|
||||
|
||||
QUALCOMM FASTRPC DRIVER
|
||||
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
M: Srinivas Kandagatla <srini@kernel.org>
|
||||
M: Amol Maheshwari <amahesh@qti.qualcomm.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@@ -21923,7 +21980,7 @@ S: Maintained
|
||||
F: drivers/media/rc/serial_ir.c
|
||||
|
||||
SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus)
|
||||
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
M: Srinivas Kandagatla <srini@kernel.org>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/slimbus/
|
||||
@@ -22139,6 +22196,7 @@ F: drivers/platform/x86/touchscreen_dmi.c
|
||||
|
||||
SILICON LABS WIRELESS DRIVERS (for WFxxx series)
|
||||
M: Jérôme Pouiller <jerome.pouiller@silabs.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml
|
||||
F: drivers/net/wireless/silabs/
|
||||
@@ -22239,9 +22297,7 @@ F: drivers/nvmem/layouts/sl28vpd.c
|
||||
|
||||
SLAB ALLOCATOR
|
||||
M: Christoph Lameter <cl@linux.com>
|
||||
M: Pekka Enberg <penberg@kernel.org>
|
||||
M: David Rientjes <rientjes@google.com>
|
||||
M: Joonsoo Kim <iamjoonsoo.kim@lge.com>
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
|
||||
6
Makefile
6
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@@ -477,7 +477,6 @@ export rust_common_flags := --edition=2021 \
|
||||
-Wclippy::ignored_unit_patterns \
|
||||
-Wclippy::mut_mut \
|
||||
-Wclippy::needless_bitwise_bool \
|
||||
-Wclippy::needless_continue \
|
||||
-Aclippy::needless_lifetimes \
|
||||
-Wclippy::no_mangle_with_rust_abi \
|
||||
-Wclippy::undocumented_unsafe_blocks \
|
||||
@@ -1057,6 +1056,9 @@ KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3)
|
||||
KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow)
|
||||
KBUILD_CFLAGS-$(CONFIG_CC_STRINGOP_OVERFLOW) += $(call cc-option, -Wstringop-overflow)
|
||||
|
||||
#Currently, disable -Wunterminated-string-initialization as broken
|
||||
KBUILD_CFLAGS += $(call cc-option, -Wno-unterminated-string-initialization)
|
||||
|
||||
# disable invalid "can't wrap" optimizations for signed / pointers
|
||||
KBUILD_CFLAGS += -fno-strict-overflow
|
||||
|
||||
|
||||
@@ -115,24 +115,19 @@
|
||||
\old_c
|
||||
.endm
|
||||
|
||||
#define _ALTERNATIVE_CFG(old_c, ...) \
|
||||
ALTERNATIVE_CFG old_c
|
||||
|
||||
#define _ALTERNATIVE_CFG_2(old_c, ...) \
|
||||
ALTERNATIVE_CFG old_c
|
||||
#define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c
|
||||
#define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
#define __ALTERNATIVE_CFG(old_c) \
|
||||
old_c "\n"
|
||||
|
||||
#define _ALTERNATIVE_CFG(old_c, ...) \
|
||||
__ALTERNATIVE_CFG(old_c)
|
||||
|
||||
#define _ALTERNATIVE_CFG_2(old_c, ...) \
|
||||
__ALTERNATIVE_CFG(old_c)
|
||||
#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n"
|
||||
#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n"
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c)
|
||||
#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c)
|
||||
|
||||
#endif /* CONFIG_RISCV_ALTERNATIVE */
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,16 +19,9 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
void arch_kgdb_breakpoint(void);
|
||||
extern unsigned long kgdb_compiled_break;
|
||||
|
||||
static inline void arch_kgdb_breakpoint(void)
|
||||
{
|
||||
asm(".global kgdb_compiled_break\n"
|
||||
".option norvc\n"
|
||||
"kgdb_compiled_break: ebreak\n"
|
||||
".option rvc\n");
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define DBG_REG_ZERO "zero"
|
||||
|
||||
@@ -62,8 +62,11 @@ static inline void syscall_get_arguments(struct task_struct *task,
|
||||
unsigned long *args)
|
||||
{
|
||||
args[0] = regs->orig_a0;
|
||||
args++;
|
||||
memcpy(args, ®s->a1, 5 * sizeof(args[0]));
|
||||
args[1] = regs->a1;
|
||||
args[2] = regs->a2;
|
||||
args[3] = regs->a3;
|
||||
args[4] = regs->a4;
|
||||
args[5] = regs->a5;
|
||||
}
|
||||
|
||||
static inline int syscall_get_arch(struct task_struct *task)
|
||||
|
||||
@@ -254,6 +254,12 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
||||
regs->epc = pc;
|
||||
}
|
||||
|
||||
noinline void arch_kgdb_breakpoint(void)
|
||||
{
|
||||
asm(".global kgdb_compiled_break\n"
|
||||
"kgdb_compiled_break: ebreak\n");
|
||||
}
|
||||
|
||||
void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
|
||||
char *remcom_out_buffer)
|
||||
{
|
||||
|
||||
@@ -73,16 +73,17 @@ static bool duplicate_rela(const Elf_Rela *rela, int idx)
|
||||
static void count_max_entries(Elf_Rela *relas, int num,
|
||||
unsigned int *plts, unsigned int *gots)
|
||||
{
|
||||
unsigned int type, i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
type = ELF_RISCV_R_TYPE(relas[i].r_info);
|
||||
if (type == R_RISCV_CALL_PLT) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
switch (ELF_R_TYPE(relas[i].r_info)) {
|
||||
case R_RISCV_CALL_PLT:
|
||||
case R_RISCV_PLT32:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*plts)++;
|
||||
} else if (type == R_RISCV_GOT_HI20) {
|
||||
break;
|
||||
case R_RISCV_GOT_HI20:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*gots)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,7 +648,7 @@ process_accumulated_relocations(struct module *me,
|
||||
kfree(bucket_iter);
|
||||
}
|
||||
|
||||
kfree(*relocation_hashtable);
|
||||
kvfree(*relocation_hashtable);
|
||||
}
|
||||
|
||||
static int add_relocation_to_accumulate(struct module *me, int type,
|
||||
@@ -752,9 +752,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
|
||||
|
||||
hashtable_size <<= should_double_size;
|
||||
|
||||
*relocation_hashtable = kmalloc_array(hashtable_size,
|
||||
sizeof(**relocation_hashtable),
|
||||
GFP_KERNEL);
|
||||
/* Number of relocations may be large, so kvmalloc it */
|
||||
*relocation_hashtable = kvmalloc_array(hashtable_size,
|
||||
sizeof(**relocation_hashtable),
|
||||
GFP_KERNEL);
|
||||
if (!*relocation_hashtable)
|
||||
return 0;
|
||||
|
||||
@@ -859,7 +860,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||
}
|
||||
|
||||
j++;
|
||||
if (j > sechdrs[relsec].sh_size / sizeof(*rel))
|
||||
if (j == num_relocations)
|
||||
j = 0;
|
||||
|
||||
} while (j_idx != j);
|
||||
|
||||
@@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", };
|
||||
static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
|
||||
#endif
|
||||
|
||||
static int num_standard_resources;
|
||||
static struct resource *standard_resources;
|
||||
|
||||
static int __init add_resource(struct resource *parent,
|
||||
struct resource *res)
|
||||
{
|
||||
@@ -139,7 +142,7 @@ static void __init init_resources(void)
|
||||
struct resource *res = NULL;
|
||||
struct resource *mem_res = NULL;
|
||||
size_t mem_res_sz = 0;
|
||||
int num_resources = 0, res_idx = 0;
|
||||
int num_resources = 0, res_idx = 0, non_resv_res = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
|
||||
@@ -193,6 +196,7 @@ static void __init init_resources(void)
|
||||
/* Add /memory regions to the resource tree */
|
||||
for_each_mem_region(region) {
|
||||
res = &mem_res[res_idx--];
|
||||
non_resv_res++;
|
||||
|
||||
if (unlikely(memblock_is_nomap(region))) {
|
||||
res->name = "Reserved";
|
||||
@@ -210,6 +214,9 @@ static void __init init_resources(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
num_standard_resources = non_resv_res;
|
||||
standard_resources = &mem_res[res_idx + 1];
|
||||
|
||||
/* Clean-up any unused pre-allocated resources */
|
||||
if (res_idx >= 0)
|
||||
memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res));
|
||||
@@ -221,6 +228,33 @@ static void __init init_resources(void)
|
||||
memblock_free(mem_res, mem_res_sz);
|
||||
}
|
||||
|
||||
static int __init reserve_memblock_reserved_regions(void)
|
||||
{
|
||||
u64 i, j;
|
||||
|
||||
for (i = 0; i < num_standard_resources; i++) {
|
||||
struct resource *mem = &standard_resources[i];
|
||||
phys_addr_t r_start, r_end, mem_size = resource_size(mem);
|
||||
|
||||
if (!memblock_is_region_reserved(mem->start, mem_size))
|
||||
continue;
|
||||
|
||||
for_each_reserved_mem_range(j, &r_start, &r_end) {
|
||||
resource_size_t start, end;
|
||||
|
||||
start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
|
||||
end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);
|
||||
|
||||
if (start > mem->end || end < mem->start)
|
||||
continue;
|
||||
|
||||
reserve_region_with_split(mem, start, end, "Reserved");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(reserve_memblock_reserved_regions);
|
||||
|
||||
static void __init parse_dtb(void)
|
||||
{
|
||||
|
||||
@@ -439,29 +439,36 @@ static int __init check_unaligned_access_all_cpus(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
if (unaligned_scalar_speed_param == RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN &&
|
||||
!check_unaligned_access_emulated_all_cpus()) {
|
||||
check_unaligned_access_speed_all_cpus();
|
||||
} else {
|
||||
pr_info("scalar unaligned access speed set to '%s' by command line\n",
|
||||
speed_str[unaligned_scalar_speed_param]);
|
||||
if (unaligned_scalar_speed_param != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN) {
|
||||
pr_info("scalar unaligned access speed set to '%s' (%lu) by command line\n",
|
||||
speed_str[unaligned_scalar_speed_param], unaligned_scalar_speed_param);
|
||||
for_each_online_cpu(cpu)
|
||||
per_cpu(misaligned_access_speed, cpu) = unaligned_scalar_speed_param;
|
||||
} else if (!check_unaligned_access_emulated_all_cpus()) {
|
||||
check_unaligned_access_speed_all_cpus();
|
||||
}
|
||||
|
||||
if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) {
|
||||
if (!has_vector() &&
|
||||
unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED) {
|
||||
pr_warn("vector support is not available, ignoring unaligned_vector_speed=%s\n",
|
||||
speed_str[unaligned_vector_speed_param]);
|
||||
} else {
|
||||
pr_info("vector unaligned access speed set to '%s' (%lu) by command line\n",
|
||||
speed_str[unaligned_vector_speed_param], unaligned_vector_speed_param);
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_vector())
|
||||
unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED;
|
||||
|
||||
if (unaligned_vector_speed_param == RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN &&
|
||||
!check_vector_unaligned_access_emulated_all_cpus() &&
|
||||
IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) {
|
||||
kthread_run(vec_check_unaligned_access_speed_all_cpus,
|
||||
NULL, "vec_check_unaligned_access_speed_all_cpus");
|
||||
} else {
|
||||
pr_info("vector unaligned access speed set to '%s' by command line\n",
|
||||
speed_str[unaligned_vector_speed_param]);
|
||||
if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) {
|
||||
for_each_online_cpu(cpu)
|
||||
per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param;
|
||||
} else if (!check_vector_unaligned_access_emulated_all_cpus() &&
|
||||
IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) {
|
||||
kthread_run(vec_check_unaligned_access_speed_all_cpus,
|
||||
NULL, "vec_check_unaligned_access_speed_all_cpus");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,11 +34,14 @@ static bool early_is_tdx_guest(void)
|
||||
|
||||
void arch_accept_memory(phys_addr_t start, phys_addr_t end)
|
||||
{
|
||||
static bool sevsnp;
|
||||
|
||||
/* Platform-specific memory-acceptance call goes here */
|
||||
if (early_is_tdx_guest()) {
|
||||
if (!tdx_accept_memory(start, end))
|
||||
panic("TDX: Failed to accept memory\n");
|
||||
} else if (sev_snp_enabled()) {
|
||||
} else if (sevsnp || (sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) {
|
||||
sevsnp = true;
|
||||
snp_accept_memory(start, end);
|
||||
} else {
|
||||
error("Cannot accept memory: unknown platform\n");
|
||||
|
||||
@@ -164,10 +164,7 @@ bool sev_snp_enabled(void)
|
||||
|
||||
static void __page_state_change(unsigned long paddr, enum psc_op op)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
if (!sev_snp_enabled())
|
||||
return;
|
||||
u64 val, msr;
|
||||
|
||||
/*
|
||||
* If private -> shared then invalidate the page before requesting the
|
||||
@@ -176,6 +173,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
|
||||
if (op == SNP_PAGE_STATE_SHARED)
|
||||
pvalidate_4k_page(paddr, paddr, false);
|
||||
|
||||
/* Save the current GHCB MSR value */
|
||||
msr = sev_es_rd_ghcb_msr();
|
||||
|
||||
/* Issue VMGEXIT to change the page state in RMP table. */
|
||||
sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op));
|
||||
VMGEXIT();
|
||||
@@ -185,6 +185,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
|
||||
if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val))
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
|
||||
|
||||
/* Restore the GHCB MSR value */
|
||||
sev_es_wr_ghcb_msr(msr);
|
||||
|
||||
/*
|
||||
* Now that page state is changed in the RMP table, validate it so that it is
|
||||
* consistent with the RMP entry.
|
||||
@@ -195,11 +198,17 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
|
||||
|
||||
void snp_set_page_private(unsigned long paddr)
|
||||
{
|
||||
if (!sev_snp_enabled())
|
||||
return;
|
||||
|
||||
__page_state_change(paddr, SNP_PAGE_STATE_PRIVATE);
|
||||
}
|
||||
|
||||
void snp_set_page_shared(unsigned long paddr)
|
||||
{
|
||||
if (!sev_snp_enabled())
|
||||
return;
|
||||
|
||||
__page_state_change(paddr, SNP_PAGE_STATE_SHARED);
|
||||
}
|
||||
|
||||
@@ -223,56 +232,10 @@ static bool early_setup_ghcb(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static phys_addr_t __snp_accept_memory(struct snp_psc_desc *desc,
|
||||
phys_addr_t pa, phys_addr_t pa_end)
|
||||
{
|
||||
struct psc_hdr *hdr;
|
||||
struct psc_entry *e;
|
||||
unsigned int i;
|
||||
|
||||
hdr = &desc->hdr;
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
|
||||
e = desc->entries;
|
||||
|
||||
i = 0;
|
||||
while (pa < pa_end && i < VMGEXIT_PSC_MAX_ENTRY) {
|
||||
hdr->end_entry = i;
|
||||
|
||||
e->gfn = pa >> PAGE_SHIFT;
|
||||
e->operation = SNP_PAGE_STATE_PRIVATE;
|
||||
if (IS_ALIGNED(pa, PMD_SIZE) && (pa_end - pa) >= PMD_SIZE) {
|
||||
e->pagesize = RMP_PG_SIZE_2M;
|
||||
pa += PMD_SIZE;
|
||||
} else {
|
||||
e->pagesize = RMP_PG_SIZE_4K;
|
||||
pa += PAGE_SIZE;
|
||||
}
|
||||
|
||||
e++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (vmgexit_psc(boot_ghcb, desc))
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
|
||||
|
||||
pvalidate_pages(desc);
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
void snp_accept_memory(phys_addr_t start, phys_addr_t end)
|
||||
{
|
||||
struct snp_psc_desc desc = {};
|
||||
unsigned int i;
|
||||
phys_addr_t pa;
|
||||
|
||||
if (!boot_ghcb && !early_setup_ghcb())
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
|
||||
|
||||
pa = start;
|
||||
while (pa < end)
|
||||
pa = __snp_accept_memory(&desc, pa, end);
|
||||
for (phys_addr_t pa = start; pa < end; pa += PAGE_SIZE)
|
||||
__page_state_change(pa, SNP_PAGE_STATE_PRIVATE);
|
||||
}
|
||||
|
||||
void sev_es_shutdown_ghcb(void)
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
|
||||
bool sev_snp_enabled(void);
|
||||
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
|
||||
u64 sev_get_status(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool sev_snp_enabled(void) { return false; }
|
||||
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
|
||||
static inline u64 sev_get_status(void) { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -634,7 +634,7 @@ int x86_pmu_hw_config(struct perf_event *event)
|
||||
if (event->attr.type == event->pmu->type)
|
||||
event->hw.config |= x86_pmu_get_event_config(event);
|
||||
|
||||
if (!event->attr.freq && x86_pmu.limit_period) {
|
||||
if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) {
|
||||
s64 left = event->attr.sample_period;
|
||||
x86_pmu.limit_period(event, &left);
|
||||
if (left > event->attr.sample_period)
|
||||
|
||||
@@ -2382,8 +2382,25 @@ __intel_pmu_pebs_last_event(struct perf_event *event,
|
||||
*/
|
||||
intel_pmu_save_and_restart_reload(event, count);
|
||||
}
|
||||
} else
|
||||
intel_pmu_save_and_restart(event);
|
||||
} else {
|
||||
/*
|
||||
* For a non-precise event, it's possible the
|
||||
* counters-snapshotting records a positive value for the
|
||||
* overflowed event. Then the HW auto-reload mechanism
|
||||
* reset the counter to 0 immediately, because the
|
||||
* pebs_event_reset is cleared if the PERF_X86_EVENT_AUTO_RELOAD
|
||||
* is not set. The counter backwards may be observed in a
|
||||
* PMI handler.
|
||||
*
|
||||
* Since the event value has been updated when processing the
|
||||
* counters-snapshotting record, only needs to set the new
|
||||
* period for the counter.
|
||||
*/
|
||||
if (is_pebs_counter_event_group(event))
|
||||
static_call(x86_pmu_set_period)(event);
|
||||
else
|
||||
intel_pmu_save_and_restart(event);
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
|
||||
@@ -110,14 +110,21 @@ static inline bool is_topdown_event(struct perf_event *event)
|
||||
return is_metric_event(event) || is_slots_event(event);
|
||||
}
|
||||
|
||||
int is_x86_event(struct perf_event *event);
|
||||
|
||||
static inline bool check_leader_group(struct perf_event *leader, int flags)
|
||||
{
|
||||
return is_x86_event(leader) ? !!(leader->hw.flags & flags) : false;
|
||||
}
|
||||
|
||||
static inline bool is_branch_counters_group(struct perf_event *event)
|
||||
{
|
||||
return event->group_leader->hw.flags & PERF_X86_EVENT_BRANCH_COUNTERS;
|
||||
return check_leader_group(event->group_leader, PERF_X86_EVENT_BRANCH_COUNTERS);
|
||||
}
|
||||
|
||||
static inline bool is_pebs_counter_event_group(struct perf_event *event)
|
||||
{
|
||||
return event->group_leader->hw.flags & PERF_X86_EVENT_PEBS_CNTR;
|
||||
return check_leader_group(event->group_leader, PERF_X86_EVENT_PEBS_CNTR);
|
||||
}
|
||||
|
||||
static inline bool is_acr_event_group(struct perf_event *event)
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */
|
||||
#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
|
||||
|
||||
#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */
|
||||
|
||||
/* "Hybrid" Processors (P-Core/E-Core) */
|
||||
|
||||
#define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */
|
||||
|
||||
@@ -869,6 +869,16 @@ static void init_amd_zen1(struct cpuinfo_x86 *c)
|
||||
|
||||
pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
|
||||
setup_force_cpu_bug(X86_BUG_DIV0);
|
||||
|
||||
/*
|
||||
* Turn off the Instructions Retired free counter on machines that are
|
||||
* susceptible to erratum #1054 "Instructions Retired Performance
|
||||
* Counter May Be Inaccurate".
|
||||
*/
|
||||
if (c->x86_model < 0x30) {
|
||||
msr_clear_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
|
||||
clear_cpu_cap(c, X86_FEATURE_IRPERF);
|
||||
}
|
||||
}
|
||||
|
||||
static bool cpu_has_zenbleed_microcode(void)
|
||||
@@ -1052,13 +1062,8 @@ static void init_amd(struct cpuinfo_x86 *c)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_XENPV))
|
||||
set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
|
||||
|
||||
/*
|
||||
* Turn on the Instructions Retired free counter on machines not
|
||||
* susceptible to erratum #1054 "Instructions Retired Performance
|
||||
* Counter May Be Inaccurate".
|
||||
*/
|
||||
if (cpu_has(c, X86_FEATURE_IRPERF) &&
|
||||
(boot_cpu_has(X86_FEATURE_ZEN1) && c->x86_model > 0x2f))
|
||||
/* Enable the Instructions Retired free counter */
|
||||
if (cpu_has(c, X86_FEATURE_IRPERF))
|
||||
msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
|
||||
|
||||
check_null_seg_clears_base(c);
|
||||
|
||||
@@ -199,6 +199,12 @@ static bool need_sha_check(u32 cur_rev)
|
||||
case 0xa70c0: return cur_rev <= 0xa70C009; break;
|
||||
case 0xaa001: return cur_rev <= 0xaa00116; break;
|
||||
case 0xaa002: return cur_rev <= 0xaa00218; break;
|
||||
case 0xb0021: return cur_rev <= 0xb002146; break;
|
||||
case 0xb1010: return cur_rev <= 0xb101046; break;
|
||||
case 0xb2040: return cur_rev <= 0xb204031; break;
|
||||
case 0xb4040: return cur_rev <= 0xb404031; break;
|
||||
case 0xb6000: return cur_rev <= 0xb600031; break;
|
||||
case 0xb7000: return cur_rev <= 0xb700031; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -214,8 +220,7 @@ static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsi
|
||||
struct sha256_state s;
|
||||
int i;
|
||||
|
||||
if (x86_family(bsp_cpuid_1_eax) < 0x17 ||
|
||||
x86_family(bsp_cpuid_1_eax) > 0x19)
|
||||
if (x86_family(bsp_cpuid_1_eax) < 0x17)
|
||||
return true;
|
||||
|
||||
if (!need_sha_check(cur_rev))
|
||||
|
||||
@@ -46,7 +46,8 @@ bool __init pit_timer_init(void)
|
||||
* VMMs otherwise steal CPU time just to pointlessly waggle
|
||||
* the (masked) IRQ.
|
||||
*/
|
||||
clockevent_i8253_disable();
|
||||
scoped_guard(irq)
|
||||
clockevent_i8253_disable();
|
||||
return false;
|
||||
}
|
||||
clockevent_i8253_init(true);
|
||||
|
||||
@@ -103,10 +103,6 @@ noinstr void *__xen_hypercall_setfunc(void)
|
||||
void (*func)(void);
|
||||
|
||||
/*
|
||||
* Xen is supported only on CPUs with CPUID, so testing for
|
||||
* X86_FEATURE_CPUID is a test for early_cpu_init() having been
|
||||
* run.
|
||||
*
|
||||
* Note that __xen_hypercall_setfunc() is noinstr only due to a nasty
|
||||
* dependency chain: it is being called via the xen_hypercall static
|
||||
* call when running as a PVH or HVM guest. Hypercalls need to be
|
||||
@@ -118,8 +114,7 @@ noinstr void *__xen_hypercall_setfunc(void)
|
||||
*/
|
||||
instrumentation_begin();
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_CPUID))
|
||||
xen_get_vendor();
|
||||
xen_get_vendor();
|
||||
|
||||
if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
|
||||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
|
||||
|
||||
@@ -54,14 +54,20 @@ struct mc_debug_data {
|
||||
|
||||
static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);
|
||||
static struct mc_debug_data mc_debug_data_early __initdata;
|
||||
static DEFINE_PER_CPU(struct mc_debug_data *, mc_debug_data) =
|
||||
&mc_debug_data_early;
|
||||
static struct mc_debug_data __percpu *mc_debug_data_ptr;
|
||||
DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);
|
||||
|
||||
static struct static_key mc_debug __ro_after_init;
|
||||
static bool mc_debug_enabled __initdata;
|
||||
|
||||
static struct mc_debug_data * __ref get_mc_debug(void)
|
||||
{
|
||||
if (!mc_debug_data_ptr)
|
||||
return &mc_debug_data_early;
|
||||
|
||||
return this_cpu_ptr(mc_debug_data_ptr);
|
||||
}
|
||||
|
||||
static int __init xen_parse_mc_debug(char *arg)
|
||||
{
|
||||
mc_debug_enabled = true;
|
||||
@@ -71,20 +77,16 @@ static int __init xen_parse_mc_debug(char *arg)
|
||||
}
|
||||
early_param("xen_mc_debug", xen_parse_mc_debug);
|
||||
|
||||
void mc_percpu_init(unsigned int cpu)
|
||||
{
|
||||
per_cpu(mc_debug_data, cpu) = per_cpu_ptr(mc_debug_data_ptr, cpu);
|
||||
}
|
||||
|
||||
static int __init mc_debug_enable(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mc_debug_data __percpu *mcdb;
|
||||
|
||||
if (!mc_debug_enabled)
|
||||
return 0;
|
||||
|
||||
mc_debug_data_ptr = alloc_percpu(struct mc_debug_data);
|
||||
if (!mc_debug_data_ptr) {
|
||||
mcdb = alloc_percpu(struct mc_debug_data);
|
||||
if (!mcdb) {
|
||||
pr_err("xen_mc_debug inactive\n");
|
||||
static_key_slow_dec(&mc_debug);
|
||||
return -ENOMEM;
|
||||
@@ -93,7 +95,7 @@ static int __init mc_debug_enable(void)
|
||||
/* Be careful when switching to percpu debug data. */
|
||||
local_irq_save(flags);
|
||||
xen_mc_flush();
|
||||
mc_percpu_init(0);
|
||||
mc_debug_data_ptr = mcdb;
|
||||
local_irq_restore(flags);
|
||||
|
||||
pr_info("xen_mc_debug active\n");
|
||||
@@ -155,7 +157,7 @@ void xen_mc_flush(void)
|
||||
trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
|
||||
|
||||
if (static_key_false(&mc_debug)) {
|
||||
mcdb = __this_cpu_read(mc_debug_data);
|
||||
mcdb = get_mc_debug();
|
||||
memcpy(mcdb->entries, b->entries,
|
||||
b->mcidx * sizeof(struct multicall_entry));
|
||||
}
|
||||
@@ -235,7 +237,7 @@ struct multicall_space __xen_mc_entry(size_t args)
|
||||
|
||||
ret.mc = &b->entries[b->mcidx];
|
||||
if (static_key_false(&mc_debug)) {
|
||||
struct mc_debug_data *mcdb = __this_cpu_read(mc_debug_data);
|
||||
struct mc_debug_data *mcdb = get_mc_debug();
|
||||
|
||||
mcdb->caller[b->mcidx] = __builtin_return_address(0);
|
||||
mcdb->argsz[b->mcidx] = args;
|
||||
|
||||
@@ -305,7 +305,6 @@ static int xen_pv_kick_ap(unsigned int cpu, struct task_struct *idle)
|
||||
return rc;
|
||||
|
||||
xen_pmu_init(cpu);
|
||||
mc_percpu_init(cpu);
|
||||
|
||||
/*
|
||||
* Why is this a BUG? If the hypercall fails then everything can be
|
||||
|
||||
@@ -261,9 +261,6 @@ void xen_mc_callback(void (*fn)(void *), void *data);
|
||||
*/
|
||||
struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
|
||||
|
||||
/* Do percpu data initialization for multicalls. */
|
||||
void mc_percpu_init(unsigned int cpu);
|
||||
|
||||
extern bool is_xen_pmu;
|
||||
|
||||
irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
|
||||
|
||||
@@ -1272,8 +1272,7 @@ void sync_bdevs(bool wait)
|
||||
/*
|
||||
* Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices.
|
||||
*/
|
||||
void bdev_statx(struct path *path, struct kstat *stat,
|
||||
u32 request_mask)
|
||||
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
|
||||
{
|
||||
struct inode *backing_inode;
|
||||
struct block_device *bdev;
|
||||
|
||||
@@ -66,16 +66,12 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
|
||||
}
|
||||
EXPORT_SYMBOL(bio_integrity_alloc);
|
||||
|
||||
static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs,
|
||||
bool dirty)
|
||||
static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_vecs; i++) {
|
||||
if (dirty && !PageCompound(bv[i].bv_page))
|
||||
set_page_dirty_lock(bv[i].bv_page);
|
||||
for (i = 0; i < nr_vecs; i++)
|
||||
unpin_user_page(bv[i].bv_page);
|
||||
}
|
||||
}
|
||||
|
||||
static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip)
|
||||
@@ -91,7 +87,7 @@ static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip)
|
||||
ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter);
|
||||
WARN_ON_ONCE(ret != bytes);
|
||||
|
||||
bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs, true);
|
||||
bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,8 +107,7 @@ void bio_integrity_unmap_user(struct bio *bio)
|
||||
return;
|
||||
}
|
||||
|
||||
bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt,
|
||||
bio_data_dir(bio) == READ);
|
||||
bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +193,7 @@ static int bio_integrity_copy_user(struct bio *bio, struct bio_vec *bvec,
|
||||
}
|
||||
|
||||
if (write)
|
||||
bio_integrity_unpin_bvec(bvec, nr_vecs, false);
|
||||
bio_integrity_unpin_bvec(bvec, nr_vecs);
|
||||
else
|
||||
memcpy(&bip->bip_vec[1], bvec, nr_vecs * sizeof(*bvec));
|
||||
|
||||
@@ -319,7 +314,7 @@ int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter)
|
||||
return 0;
|
||||
|
||||
release_pages:
|
||||
bio_integrity_unpin_bvec(bvec, nr_bvecs, false);
|
||||
bio_integrity_unpin_bvec(bvec, nr_bvecs);
|
||||
free_bvec:
|
||||
if (bvec != stack_vec)
|
||||
kfree(bvec);
|
||||
|
||||
@@ -909,6 +909,8 @@ out_unregister_ia_ranges:
|
||||
out_debugfs_remove:
|
||||
blk_debugfs_remove(disk);
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
if (queue_is_mq(q))
|
||||
blk_mq_sysfs_unregister(disk);
|
||||
out_put_queue_kobj:
|
||||
kobject_put(&disk->queue_kobj);
|
||||
return ret;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef BLK_THROTTLE_H
|
||||
#define BLK_THROTTLE_H
|
||||
|
||||
|
||||
@@ -315,16 +315,7 @@ EXPORT_SYMBOL_GPL(crypto_ahash_setkey);
|
||||
|
||||
static bool ahash_request_hasvirt(struct ahash_request *req)
|
||||
{
|
||||
struct ahash_request *r2;
|
||||
|
||||
if (ahash_request_isvirt(req))
|
||||
return true;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list)
|
||||
if (ahash_request_isvirt(r2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return ahash_request_isvirt(req);
|
||||
}
|
||||
|
||||
static int ahash_reqchain_virt(struct ahash_save_req_state *state,
|
||||
@@ -472,7 +463,6 @@ static int ahash_do_req_chain(struct ahash_request *req,
|
||||
bool update = op == crypto_ahash_alg(tfm)->update;
|
||||
struct ahash_save_req_state *state;
|
||||
struct ahash_save_req_state state0;
|
||||
struct ahash_request *r2;
|
||||
u8 *page = NULL;
|
||||
int err;
|
||||
|
||||
@@ -509,7 +499,6 @@ static int ahash_do_req_chain(struct ahash_request *req,
|
||||
state->offset = 0;
|
||||
state->nbytes = 0;
|
||||
INIT_LIST_HEAD(&state->head);
|
||||
list_splice_init(&req->base.list, &state->head);
|
||||
|
||||
if (page)
|
||||
sg_init_one(&state->sg, page, PAGE_SIZE);
|
||||
@@ -540,9 +529,6 @@ out_free_page:
|
||||
|
||||
out_set_chain:
|
||||
req->base.err = err;
|
||||
list_for_each_entry(r2, &req->base.list, base.list)
|
||||
r2->base.err = err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -551,19 +537,10 @@ int crypto_ahash_init(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
|
||||
if (likely(tfm->using_shash)) {
|
||||
struct ahash_request *r2;
|
||||
int err;
|
||||
|
||||
err = crypto_shash_init(prepare_shash_desc(req, tfm));
|
||||
req->base.err = err;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list) {
|
||||
struct shash_desc *desc;
|
||||
|
||||
desc = prepare_shash_desc(r2, tfm);
|
||||
r2->base.err = crypto_shash_init(desc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -620,19 +597,10 @@ int crypto_ahash_update(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
|
||||
if (likely(tfm->using_shash)) {
|
||||
struct ahash_request *r2;
|
||||
int err;
|
||||
|
||||
err = shash_ahash_update(req, ahash_request_ctx(req));
|
||||
req->base.err = err;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list) {
|
||||
struct shash_desc *desc;
|
||||
|
||||
desc = ahash_request_ctx(r2);
|
||||
r2->base.err = shash_ahash_update(r2, desc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -645,19 +613,10 @@ int crypto_ahash_final(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
|
||||
if (likely(tfm->using_shash)) {
|
||||
struct ahash_request *r2;
|
||||
int err;
|
||||
|
||||
err = crypto_shash_final(ahash_request_ctx(req), req->result);
|
||||
req->base.err = err;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list) {
|
||||
struct shash_desc *desc;
|
||||
|
||||
desc = ahash_request_ctx(r2);
|
||||
r2->base.err = crypto_shash_final(desc, r2->result);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -670,19 +629,10 @@ int crypto_ahash_finup(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
|
||||
if (likely(tfm->using_shash)) {
|
||||
struct ahash_request *r2;
|
||||
int err;
|
||||
|
||||
err = shash_ahash_finup(req, ahash_request_ctx(req));
|
||||
req->base.err = err;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list) {
|
||||
struct shash_desc *desc;
|
||||
|
||||
desc = ahash_request_ctx(r2);
|
||||
r2->base.err = shash_ahash_finup(r2, desc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -757,19 +707,10 @@ int crypto_ahash_digest(struct ahash_request *req)
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
|
||||
if (likely(tfm->using_shash)) {
|
||||
struct ahash_request *r2;
|
||||
int err;
|
||||
|
||||
err = shash_ahash_digest(req, prepare_shash_desc(req, tfm));
|
||||
req->base.err = err;
|
||||
|
||||
list_for_each_entry(r2, &req->base.list, base.list) {
|
||||
struct shash_desc *desc;
|
||||
|
||||
desc = prepare_shash_desc(r2, tfm);
|
||||
r2->base.err = shash_ahash_digest(r2, desc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1133,20 +1074,5 @@ int ahash_register_instance(struct crypto_template *tmpl,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ahash_register_instance);
|
||||
|
||||
void ahash_request_free(struct ahash_request *req)
|
||||
{
|
||||
struct ahash_request *tmp;
|
||||
struct ahash_request *r2;
|
||||
|
||||
if (unlikely(!req))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(r2, tmp, &req->base.list, base.list)
|
||||
kfree_sensitive(r2);
|
||||
|
||||
kfree_sensitive(req);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ahash_request_free);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Asynchronous cryptographic hash type");
|
||||
|
||||
@@ -111,10 +111,14 @@ static void scomp_free_streams(struct scomp_alg *alg)
|
||||
struct crypto_acomp_stream __percpu *stream = alg->stream;
|
||||
int i;
|
||||
|
||||
alg->stream = NULL;
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i);
|
||||
|
||||
if (!ps->ctx)
|
||||
if (IS_ERR_OR_NULL(ps->ctx))
|
||||
break;
|
||||
|
||||
alg->free_ctx(ps->ctx);
|
||||
@@ -132,6 +136,8 @@ static int scomp_alloc_streams(struct scomp_alg *alg)
|
||||
if (!stream)
|
||||
return -ENOMEM;
|
||||
|
||||
alg->stream = stream;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i);
|
||||
|
||||
@@ -143,8 +149,6 @@ static int scomp_alloc_streams(struct scomp_alg *alg)
|
||||
|
||||
spin_lock_init(&ps->lock);
|
||||
}
|
||||
|
||||
alg->stream = stream;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
@@ -164,7 +164,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
|
||||
args->value = vdev->platform;
|
||||
break;
|
||||
case DRM_IVPU_PARAM_CORE_CLOCK_RATE:
|
||||
args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio);
|
||||
args->value = ivpu_hw_dpu_max_freq_get(vdev);
|
||||
break;
|
||||
case DRM_IVPU_PARAM_NUM_CONTEXTS:
|
||||
args->value = ivpu_get_context_count(vdev);
|
||||
@@ -421,9 +421,9 @@ void ivpu_prepare_for_reset(struct ivpu_device *vdev)
|
||||
{
|
||||
ivpu_hw_irq_disable(vdev);
|
||||
disable_irq(vdev->irq);
|
||||
cancel_work_sync(&vdev->irq_ipc_work);
|
||||
cancel_work_sync(&vdev->irq_dct_work);
|
||||
cancel_work_sync(&vdev->context_abort_work);
|
||||
flush_work(&vdev->irq_ipc_work);
|
||||
flush_work(&vdev->irq_dct_work);
|
||||
flush_work(&vdev->context_abort_work);
|
||||
ivpu_ipc_disable(vdev);
|
||||
ivpu_mmu_disable(vdev);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
@@ -233,10 +233,20 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
|
||||
fw->dvfs_mode = 0;
|
||||
|
||||
fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr);
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
|
||||
ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS");
|
||||
|
||||
if (fw_hdr->preemption_buffer_1_max_size)
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size;
|
||||
else
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
|
||||
if (fw_hdr->preemption_buffer_2_max_size)
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size;
|
||||
else
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
|
||||
ivpu_dbg(vdev, FW_BOOT, "Preemption buffer sizes: primary %u, secondary %u\n",
|
||||
fw->primary_preempt_buf_size, fw->secondary_preempt_buf_size);
|
||||
|
||||
if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address,
|
||||
fw_hdr->ro_section_size,
|
||||
fw_hdr->image_load_address,
|
||||
@@ -566,7 +576,6 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
|
||||
|
||||
boot_params->magic = VPU_BOOT_PARAMS_MAGIC;
|
||||
boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
|
||||
boot_params->frequency = ivpu_hw_pll_freq_get(vdev);
|
||||
|
||||
/*
|
||||
* This param is a debug firmware feature. It switches default clock
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_H__
|
||||
@@ -82,9 +82,14 @@ static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
|
||||
return range->end - range->start;
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
static inline u32 ivpu_hw_dpu_max_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_ratio_to_freq(vdev, ratio);
|
||||
return ivpu_hw_btrs_dpu_max_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_dpu_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_dpu_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
|
||||
@@ -92,11 +97,6 @@ static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
|
||||
ivpu_hw_ip_irq_clear(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_pll_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return vdev->hw->pll.profiling_freq;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "ivpu_drv.h"
|
||||
#include "ivpu_hw.h"
|
||||
#include "ivpu_hw_btrs.h"
|
||||
@@ -28,17 +30,13 @@
|
||||
|
||||
#define BTRS_LNL_ALL_IRQ_MASK ((u32)-1)
|
||||
|
||||
#define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3)
|
||||
#define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3)
|
||||
#define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3)
|
||||
#define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3)
|
||||
#define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
|
||||
|
||||
#define PLL_CDYN_DEFAULT 0x80
|
||||
#define PLL_EPP_DEFAULT 0x80
|
||||
#define PLL_CONFIG_DEFAULT 0x0
|
||||
#define PLL_SIMULATION_FREQ 10000000
|
||||
#define PLL_REF_CLK_FREQ 50000000
|
||||
#define PLL_REF_CLK_FREQ 50000000ull
|
||||
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
|
||||
|
||||
#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
|
||||
#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
|
||||
#define TIMEOUT_US (150 * USEC_PER_MSEC)
|
||||
@@ -62,6 +60,8 @@
|
||||
#define DCT_ENABLE 0x1
|
||||
#define DCT_DISABLE 0x0
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio);
|
||||
|
||||
int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, BTRS_MTL_ALL_IRQ_MASK);
|
||||
@@ -156,7 +156,7 @@ static int info_init_mtl(struct ivpu_device *vdev)
|
||||
|
||||
hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH;
|
||||
hw->sku = BTRS_MTL_TILE_SKU_BOTH;
|
||||
hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO;
|
||||
hw->config = WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -334,8 +334,8 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable)
|
||||
|
||||
prepare_wp_request(vdev, &wp, enable);
|
||||
|
||||
ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n",
|
||||
PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn);
|
||||
ivpu_dbg(vdev, PM, "PLL workpoint request: %lu MHz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n",
|
||||
pll_ratio_to_dpu_freq(vdev, wp.target) / HZ_PER_MHZ, wp.cfg, wp.epp, wp.cdyn);
|
||||
|
||||
ret = wp_request_send(vdev, &wp);
|
||||
if (ret) {
|
||||
@@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev)
|
||||
return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
|
||||
}
|
||||
|
||||
static u32 pll_config_get_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
return REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL);
|
||||
}
|
||||
|
||||
static u32 pll_config_get_lnl(struct ivpu_device *vdev)
|
||||
{
|
||||
return REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ);
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq_mtl(u16 ratio)
|
||||
{
|
||||
return (PLL_RATIO_TO_FREQ(ratio) * 2) / 3;
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq_lnl(u16 ratio)
|
||||
{
|
||||
return PLL_RATIO_TO_FREQ(ratio) / 2;
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_dpu_freq_mtl(ratio);
|
||||
else
|
||||
return pll_ratio_to_dpu_freq_lnl(ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return pll_ratio_to_dpu_freq(vdev, vdev->hw->pll.max_ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_dpu_freq_mtl(pll_config_get_mtl(vdev));
|
||||
else
|
||||
return pll_ratio_to_dpu_freq_lnl(pll_config_get_lnl(vdev));
|
||||
}
|
||||
|
||||
/* Handler for IRQs from Buttress core (irqB) */
|
||||
bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
|
||||
{
|
||||
@@ -582,9 +623,12 @@ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status))
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
|
||||
REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL));
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) {
|
||||
u32 pll = pll_config_get_mtl(vdev);
|
||||
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz",
|
||||
pll, pll_ratio_to_dpu_freq_mtl(pll) / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) {
|
||||
ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0));
|
||||
@@ -633,8 +677,12 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
|
||||
queue_work(system_wq, &vdev->irq_dct_work);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status))
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ));
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) {
|
||||
u32 pll = pll_config_get_lnl(vdev);
|
||||
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz",
|
||||
pll, pll_ratio_to_dpu_freq_lnl(pll) / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) {
|
||||
ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
|
||||
@@ -717,60 +765,6 @@ void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 acti
|
||||
REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val);
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config)
|
||||
{
|
||||
u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
|
||||
u32 cpu_clock;
|
||||
|
||||
if ((config & 0xff) == MTL_PLL_RATIO_4_3)
|
||||
cpu_clock = pll_clock * 2 / 4;
|
||||
else
|
||||
cpu_clock = pll_clock * 2 / 5;
|
||||
|
||||
return cpu_clock;
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
{
|
||||
struct ivpu_hw_info *hw = vdev->hw;
|
||||
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_freq_mtl(ratio, hw->config);
|
||||
else
|
||||
return PLL_RATIO_TO_FREQ(ratio);
|
||||
}
|
||||
|
||||
static u32 pll_freq_get_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
u32 pll_curr_ratio;
|
||||
|
||||
pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL);
|
||||
pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK;
|
||||
|
||||
if (!ivpu_is_silicon(vdev))
|
||||
return PLL_SIMULATION_FREQ;
|
||||
|
||||
return pll_ratio_to_freq_mtl(pll_curr_ratio, vdev->hw->config);
|
||||
}
|
||||
|
||||
static u32 pll_freq_get_lnl(struct ivpu_device *vdev)
|
||||
{
|
||||
u32 pll_curr_ratio;
|
||||
|
||||
pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ);
|
||||
pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK;
|
||||
|
||||
return PLL_RATIO_TO_FREQ(pll_curr_ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_freq_get_mtl(vdev);
|
||||
else
|
||||
return pll_freq_get_lnl(vdev);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_BTRS_H__
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#define PLL_PROFILING_FREQ_DEFAULT 38400000
|
||||
#define PLL_PROFILING_FREQ_HIGH 400000000
|
||||
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
|
||||
|
||||
#define DCT_DEFAULT_ACTIVE_PERCENT 15u
|
||||
#define DCT_PERIOD_US 35300u
|
||||
@@ -32,12 +31,12 @@ int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev);
|
||||
bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq);
|
||||
bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq);
|
||||
int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable);
|
||||
void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent);
|
||||
u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio);
|
||||
u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev);
|
||||
|
||||
@@ -470,8 +470,8 @@ static void ivpu_job_destroy(struct ivpu_job *job)
|
||||
struct ivpu_device *vdev = job->vdev;
|
||||
u32 i;
|
||||
|
||||
ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d",
|
||||
job->job_id, job->file_priv->ctx.id, job->engine_idx);
|
||||
ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d cmdq_id %u engine %d",
|
||||
job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx);
|
||||
|
||||
for (i = 0; i < job->bo_count; i++)
|
||||
if (job->bos[i])
|
||||
@@ -564,8 +564,8 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32
|
||||
dma_fence_signal(job->done_fence);
|
||||
|
||||
trace_job("done", job);
|
||||
ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n",
|
||||
job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status);
|
||||
ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d cmdq_id %u engine %d status 0x%x\n",
|
||||
job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, job_status);
|
||||
|
||||
ivpu_job_destroy(job);
|
||||
ivpu_stop_job_timeout_detection(vdev);
|
||||
@@ -664,8 +664,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id)
|
||||
}
|
||||
|
||||
trace_job("submit", job);
|
||||
ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n",
|
||||
job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->priority,
|
||||
ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d cmdq_id %u engine %d prio %d addr 0x%llx next %d\n",
|
||||
job->job_id, file_priv->ctx.id, cmdq->id, job->engine_idx, cmdq->priority,
|
||||
job->cmd_buf_vpu_addr, cmdq->jobq->header.tail);
|
||||
|
||||
mutex_unlock(&file_priv->lock);
|
||||
@@ -777,7 +777,8 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv,
|
||||
goto err_free_handles;
|
||||
}
|
||||
|
||||
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", file_priv->ctx.id, buffer_count);
|
||||
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u cmdq_id %u buf_count %u\n",
|
||||
file_priv->ctx.id, cmdq_id, buffer_count);
|
||||
|
||||
job = ivpu_job_create(file_priv, engine, buffer_count);
|
||||
if (!job) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "ivpu_drv.h"
|
||||
#include "ivpu_gem.h"
|
||||
@@ -90,10 +92,55 @@ sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
||||
static DEVICE_ATTR_RO(sched_mode);
|
||||
|
||||
/**
|
||||
* DOC: npu_max_frequency
|
||||
*
|
||||
* The npu_max_frequency shows maximum frequency in MHz of the NPU's data
|
||||
* processing unit
|
||||
*/
|
||||
static ssize_t
|
||||
npu_max_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
u32 freq = ivpu_hw_dpu_max_freq_get(vdev);
|
||||
|
||||
return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(npu_max_frequency_mhz);
|
||||
|
||||
/**
|
||||
* DOC: npu_current_frequency_mhz
|
||||
*
|
||||
* The npu_current_frequency_mhz shows current frequency in MHz of the NPU's
|
||||
* data processing unit
|
||||
*/
|
||||
static ssize_t
|
||||
npu_current_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
u32 freq = 0;
|
||||
|
||||
/* Read frequency only if device is active, otherwise frequency is 0 */
|
||||
if (pm_runtime_get_if_active(vdev->drm.dev) > 0) {
|
||||
freq = ivpu_hw_dpu_freq_get(vdev);
|
||||
|
||||
pm_runtime_put_autosuspend(vdev->drm.dev);
|
||||
}
|
||||
|
||||
return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(npu_current_frequency_mhz);
|
||||
|
||||
static struct attribute *ivpu_dev_attrs[] = {
|
||||
&dev_attr_npu_busy_time_us.attr,
|
||||
&dev_attr_npu_memory_utilization.attr,
|
||||
&dev_attr_sched_mode.attr,
|
||||
&dev_attr_npu_max_frequency_mhz.attr,
|
||||
&dev_attr_npu_current_frequency_mhz.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
* Resets to 0 if Major version is incremented.
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_MINOR 26
|
||||
#define VPU_BOOT_API_VER_MINOR 28
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@@ -76,8 +76,15 @@ struct vpu_firmware_header {
|
||||
* submission queue size and device capabilities.
|
||||
*/
|
||||
u32 preemption_buffer_2_size;
|
||||
/*
|
||||
* Maximum preemption buffer size that the FW can use: no need for the host
|
||||
* driver to allocate more space than that specified by these fields.
|
||||
* A value of 0 means no declared limit.
|
||||
*/
|
||||
u32 preemption_buffer_1_max_size;
|
||||
u32 preemption_buffer_2_max_size;
|
||||
/* Space reserved for future preemption-related fields. */
|
||||
u32 preemption_reserved[6];
|
||||
u32 preemption_reserved[4];
|
||||
/* FW image read only section start address, 4KB aligned */
|
||||
u64 ro_section_start_address;
|
||||
/* FW image read only section size, 4KB aligned */
|
||||
@@ -134,7 +141,7 @@ enum vpu_trace_destination {
|
||||
/*
|
||||
* Processor bit shifts (for loggable HW components).
|
||||
*/
|
||||
#define VPU_TRACE_PROC_BIT_ARM 0
|
||||
#define VPU_TRACE_PROC_BIT_RESERVED 0
|
||||
#define VPU_TRACE_PROC_BIT_LRT 1
|
||||
#define VPU_TRACE_PROC_BIT_LNN 2
|
||||
#define VPU_TRACE_PROC_BIT_SHV_0 3
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
*/
|
||||
#define VPU_JSM_API_VER_MINOR 25
|
||||
#define VPU_JSM_API_VER_MINOR 29
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@@ -53,8 +53,7 @@
|
||||
* Engine indexes.
|
||||
*/
|
||||
#define VPU_ENGINE_COMPUTE 0
|
||||
#define VPU_ENGINE_COPY 1
|
||||
#define VPU_ENGINE_NB 2
|
||||
#define VPU_ENGINE_NB 1
|
||||
|
||||
/*
|
||||
* VPU status values.
|
||||
@@ -126,11 +125,13 @@ enum {
|
||||
* When set, indicates that job queue uses native fences (as inline commands
|
||||
* in job queue). Such queues may also use legacy fences (as commands in batch buffers).
|
||||
* When cleared, indicates the job queue only uses legacy fences.
|
||||
* NOTE: For queues using native fences, VPU expects that all jobs in the queue
|
||||
* are immediately followed by an inline command object. This object is expected
|
||||
* to be a fence signal command in most cases, but can also be a NOP in case the host
|
||||
* does not need per-job fence signalling. Other inline commands objects can be
|
||||
* inserted between "job and inline command" pairs.
|
||||
* NOTES:
|
||||
* 1. For queues using native fences, VPU expects that all jobs in the queue
|
||||
* are immediately followed by an inline command object. This object is expected
|
||||
* to be a fence signal command in most cases, but can also be a NOP in case the host
|
||||
* does not need per-job fence signalling. Other inline commands objects can be
|
||||
* inserted between "job and inline command" pairs.
|
||||
* 2. Native fence queues are only supported on VPU 40xx onwards.
|
||||
*/
|
||||
VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U),
|
||||
|
||||
@@ -275,6 +276,8 @@ struct vpu_inline_cmd {
|
||||
u64 value;
|
||||
/* User VA of the log buffer in which to add log entry on completion. */
|
||||
u64 log_buffer_va;
|
||||
/* NPU private data. */
|
||||
u64 npu_private_data;
|
||||
} fence;
|
||||
/* Other commands do not have a payload. */
|
||||
/* Payload definition for future inline commands can be inserted here. */
|
||||
@@ -791,12 +794,22 @@ struct vpu_jsm_metric_streamer_update {
|
||||
/** Metric group mask that identifies metric streamer instance. */
|
||||
u64 metric_group_mask;
|
||||
/**
|
||||
* Address and size of the buffer where the VPU will write metric data. If
|
||||
* the buffer address is 0 or same as the currently used buffer the VPU will
|
||||
* continue writing metric data to the current buffer. In this case the
|
||||
* buffer size is ignored and the size of the current buffer is unchanged.
|
||||
* If the address is non-zero and differs from the current buffer address the
|
||||
* VPU will immediately switch data collection to the new buffer.
|
||||
* Address and size of the buffer where the VPU will write metric data.
|
||||
* This member dictates how the update operation should perform:
|
||||
* 1. client needs information about the number of collected samples and the
|
||||
* amount of data written to the current buffer
|
||||
* 2. client wants to switch to a new buffer
|
||||
*
|
||||
* Case 1. is identified by the buffer address being 0 or the same as the
|
||||
* currently used buffer address. In this case the buffer size is ignored and
|
||||
* the size of the current buffer is unchanged. The VPU will return an update
|
||||
* in the vpu_jsm_metric_streamer_done structure. The internal writing position
|
||||
* into the buffer is not changed.
|
||||
*
|
||||
* Case 2. is identified by the address being non-zero and differs from the
|
||||
* current buffer address. The VPU will immediately switch data collection to
|
||||
* the new buffer. Then the VPU will return an update in the
|
||||
* vpu_jsm_metric_streamer_done structure.
|
||||
*/
|
||||
u64 buffer_addr;
|
||||
u64 buffer_size;
|
||||
@@ -934,6 +947,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
|
||||
/*
|
||||
* Default quantum in 100ns units for scheduling across processes
|
||||
* within a priority band
|
||||
* Minimum value supported by NPU is 1ms (10000 in 100ns units).
|
||||
*/
|
||||
u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS];
|
||||
/*
|
||||
@@ -946,8 +960,10 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
|
||||
* in situations when it's starved by the focus band.
|
||||
*/
|
||||
u32 normal_band_percentage;
|
||||
/* Reserved */
|
||||
u32 reserved_0;
|
||||
/*
|
||||
* TDR timeout value in milliseconds. Default value of 0 meaning no timeout.
|
||||
*/
|
||||
u32 tdr_timeout;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1024,7 +1040,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties {
|
||||
s32 in_process_priority;
|
||||
/* Zero padding / Reserved */
|
||||
u32 reserved_1;
|
||||
/* Context quantum relative to other contexts of same priority in the same process */
|
||||
/*
|
||||
* Context quantum relative to other contexts of same priority in the same process
|
||||
* Minimum value supported by NPU is 1ms (10000 in 100ns units).
|
||||
*/
|
||||
u64 context_quantum;
|
||||
/* Grace period when preempting context of the same priority within the same process */
|
||||
u64 grace_period_same_priority;
|
||||
|
||||
@@ -293,7 +293,7 @@ acpi_status (*acpi_internal_method) (struct acpi_walk_state * walk_state);
|
||||
* expected_return_btypes - Allowed type(s) for the return value
|
||||
*/
|
||||
struct acpi_name_info {
|
||||
char name[ACPI_NAMESEG_SIZE];
|
||||
char name[ACPI_NAMESEG_SIZE] __nonstring;
|
||||
u16 argument_list;
|
||||
u8 expected_btypes;
|
||||
};
|
||||
@@ -370,7 +370,7 @@ typedef acpi_status (*acpi_object_converter) (struct acpi_namespace_node *
|
||||
converted_object);
|
||||
|
||||
struct acpi_simple_repair_info {
|
||||
char name[ACPI_NAMESEG_SIZE];
|
||||
char name[ACPI_NAMESEG_SIZE] __nonstring;
|
||||
u32 unexpected_btypes;
|
||||
u32 package_index;
|
||||
acpi_object_converter object_converter;
|
||||
|
||||
@@ -25,7 +25,7 @@ acpi_status (*acpi_repair_function) (struct acpi_evaluate_info * info,
|
||||
return_object_ptr);
|
||||
|
||||
typedef struct acpi_repair_info {
|
||||
char name[ACPI_NAMESEG_SIZE];
|
||||
char name[ACPI_NAMESEG_SIZE] __nonstring;
|
||||
acpi_repair_function repair_function;
|
||||
|
||||
} acpi_repair_info;
|
||||
|
||||
@@ -1510,6 +1510,8 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link)
|
||||
unsigned int err_mask, tag;
|
||||
u8 *sense, sk = 0, asc = 0, ascq = 0;
|
||||
u64 sense_valid, val;
|
||||
u16 extended_sense;
|
||||
bool aux_icc_valid;
|
||||
int ret = 0;
|
||||
|
||||
err_mask = ata_read_log_page(dev, ATA_LOG_SENSE_NCQ, 0, buf, 2);
|
||||
@@ -1529,6 +1531,8 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link)
|
||||
|
||||
sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) |
|
||||
((u64)buf[10] << 16) | ((u64)buf[11] << 24);
|
||||
extended_sense = get_unaligned_le16(&buf[14]);
|
||||
aux_icc_valid = extended_sense & BIT(15);
|
||||
|
||||
ata_qc_for_each_raw(ap, qc, tag) {
|
||||
if (!(qc->flags & ATA_QCFLAG_EH) ||
|
||||
@@ -1556,6 +1560,17 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link)
|
||||
continue;
|
||||
}
|
||||
|
||||
qc->result_tf.nsect = sense[6];
|
||||
qc->result_tf.hob_nsect = sense[7];
|
||||
qc->result_tf.lbal = sense[8];
|
||||
qc->result_tf.lbam = sense[9];
|
||||
qc->result_tf.lbah = sense[10];
|
||||
qc->result_tf.hob_lbal = sense[11];
|
||||
qc->result_tf.hob_lbam = sense[12];
|
||||
qc->result_tf.hob_lbah = sense[13];
|
||||
if (aux_icc_valid)
|
||||
qc->result_tf.auxiliary = get_unaligned_le32(&sense[16]);
|
||||
|
||||
/* Set sense without also setting scsicmd->result */
|
||||
scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE,
|
||||
qc->scsicmd->sense_buffer, sk,
|
||||
|
||||
@@ -388,12 +388,6 @@ config BLK_DEV_UBLK
|
||||
definition isn't finalized yet, and might change according to future
|
||||
requirement, so mark is as experimental now.
|
||||
|
||||
Say Y if you want to get better performance because task_work_add()
|
||||
can be used in IO path for replacing io_uring cmd, which will become
|
||||
shared between IO tasks and ubq daemon, meantime task_work_add() can
|
||||
can handle batch more effectively, but task_work_add() isn't exported
|
||||
for module, so ublk has to be built to kernel.
|
||||
|
||||
config BLKDEV_UBLK_LEGACY_OPCODES
|
||||
bool "Support legacy command opcode"
|
||||
depends on BLK_DEV_UBLK
|
||||
|
||||
@@ -211,72 +211,6 @@ static void loop_set_size(struct loop_device *lo, loff_t size)
|
||||
kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
|
||||
{
|
||||
struct iov_iter i;
|
||||
ssize_t bw;
|
||||
|
||||
iov_iter_bvec(&i, ITER_SOURCE, bvec, 1, bvec->bv_len);
|
||||
|
||||
bw = vfs_iter_write(file, &i, ppos, 0);
|
||||
|
||||
if (likely(bw == bvec->bv_len))
|
||||
return 0;
|
||||
|
||||
printk_ratelimited(KERN_ERR
|
||||
"loop: Write error at byte offset %llu, length %i.\n",
|
||||
(unsigned long long)*ppos, bvec->bv_len);
|
||||
if (bw >= 0)
|
||||
bw = -EIO;
|
||||
return bw;
|
||||
}
|
||||
|
||||
static int lo_write_simple(struct loop_device *lo, struct request *rq,
|
||||
loff_t pos)
|
||||
{
|
||||
struct bio_vec bvec;
|
||||
struct req_iterator iter;
|
||||
int ret = 0;
|
||||
|
||||
rq_for_each_segment(bvec, rq, iter) {
|
||||
ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
|
||||
if (ret < 0)
|
||||
break;
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lo_read_simple(struct loop_device *lo, struct request *rq,
|
||||
loff_t pos)
|
||||
{
|
||||
struct bio_vec bvec;
|
||||
struct req_iterator iter;
|
||||
struct iov_iter i;
|
||||
ssize_t len;
|
||||
|
||||
rq_for_each_segment(bvec, rq, iter) {
|
||||
iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len);
|
||||
len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
flush_dcache_page(bvec.bv_page);
|
||||
|
||||
if (len != bvec.bv_len) {
|
||||
struct bio *bio;
|
||||
|
||||
__rq_for_each_bio(bio, rq)
|
||||
zero_fill_bio(bio);
|
||||
break;
|
||||
}
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void loop_clear_limits(struct loop_device *lo, int mode)
|
||||
{
|
||||
struct queue_limits lim = queue_limits_start_update(lo->lo_queue);
|
||||
@@ -342,7 +276,7 @@ static void lo_complete_rq(struct request *rq)
|
||||
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
||||
blk_status_t ret = BLK_STS_OK;
|
||||
|
||||
if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
|
||||
if (cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
|
||||
req_op(rq) != REQ_OP_READ) {
|
||||
if (cmd->ret < 0)
|
||||
ret = errno_to_blk_status(cmd->ret);
|
||||
@@ -358,14 +292,13 @@ static void lo_complete_rq(struct request *rq)
|
||||
cmd->ret = 0;
|
||||
blk_mq_requeue_request(rq, true);
|
||||
} else {
|
||||
if (cmd->use_aio) {
|
||||
struct bio *bio = rq->bio;
|
||||
struct bio *bio = rq->bio;
|
||||
|
||||
while (bio) {
|
||||
zero_fill_bio(bio);
|
||||
bio = bio->bi_next;
|
||||
}
|
||||
while (bio) {
|
||||
zero_fill_bio(bio);
|
||||
bio = bio->bi_next;
|
||||
}
|
||||
|
||||
ret = BLK_STS_IOERR;
|
||||
end_io:
|
||||
blk_mq_end_request(rq, ret);
|
||||
@@ -445,9 +378,14 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
||||
|
||||
cmd->iocb.ki_pos = pos;
|
||||
cmd->iocb.ki_filp = file;
|
||||
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
||||
cmd->iocb.ki_flags = IOCB_DIRECT;
|
||||
cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
|
||||
cmd->iocb.ki_ioprio = req_get_ioprio(rq);
|
||||
if (cmd->use_aio) {
|
||||
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
||||
cmd->iocb.ki_flags = IOCB_DIRECT;
|
||||
} else {
|
||||
cmd->iocb.ki_complete = NULL;
|
||||
cmd->iocb.ki_flags = 0;
|
||||
}
|
||||
|
||||
if (rw == ITER_SOURCE)
|
||||
ret = file->f_op->write_iter(&cmd->iocb, &iter);
|
||||
@@ -458,7 +396,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
||||
|
||||
if (ret != -EIOCBQUEUED)
|
||||
lo_rw_aio_complete(&cmd->iocb, ret);
|
||||
return 0;
|
||||
return -EIOCBQUEUED;
|
||||
}
|
||||
|
||||
static int do_req_filebacked(struct loop_device *lo, struct request *rq)
|
||||
@@ -466,15 +404,6 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
|
||||
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
||||
loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
|
||||
|
||||
/*
|
||||
* lo_write_simple and lo_read_simple should have been covered
|
||||
* by io submit style function like lo_rw_aio(), one blocker
|
||||
* is that lo_read_simple() need to call flush_dcache_page after
|
||||
* the page is written from kernel, and it isn't easy to handle
|
||||
* this in io submit style function which submits all segments
|
||||
* of the req at one time. And direct read IO doesn't need to
|
||||
* run flush_dcache_page().
|
||||
*/
|
||||
switch (req_op(rq)) {
|
||||
case REQ_OP_FLUSH:
|
||||
return lo_req_flush(lo, rq);
|
||||
@@ -490,15 +419,9 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
|
||||
case REQ_OP_DISCARD:
|
||||
return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE);
|
||||
case REQ_OP_WRITE:
|
||||
if (cmd->use_aio)
|
||||
return lo_rw_aio(lo, cmd, pos, ITER_SOURCE);
|
||||
else
|
||||
return lo_write_simple(lo, rq, pos);
|
||||
return lo_rw_aio(lo, cmd, pos, ITER_SOURCE);
|
||||
case REQ_OP_READ:
|
||||
if (cmd->use_aio)
|
||||
return lo_rw_aio(lo, cmd, pos, ITER_DEST);
|
||||
else
|
||||
return lo_read_simple(lo, rq, pos);
|
||||
return lo_rw_aio(lo, cmd, pos, ITER_DEST);
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return -EIO;
|
||||
@@ -662,19 +585,20 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
||||
* dependency.
|
||||
*/
|
||||
fput(old_file);
|
||||
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
|
||||
if (partscan)
|
||||
loop_reread_partitions(lo);
|
||||
|
||||
error = 0;
|
||||
done:
|
||||
/* enable and uncork uevent now that we are done */
|
||||
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
|
||||
kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
|
||||
return error;
|
||||
|
||||
out_err:
|
||||
loop_global_unlock(lo, is_loop);
|
||||
out_putf:
|
||||
fput(file);
|
||||
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1129,8 +1053,8 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,
|
||||
if (partscan)
|
||||
clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
|
||||
|
||||
/* enable and uncork uevent now that we are done */
|
||||
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
|
||||
kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
|
||||
|
||||
loop_global_unlock(lo, is_loop);
|
||||
if (partscan)
|
||||
@@ -1921,7 +1845,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
|
||||
struct loop_device *lo = rq->q->queuedata;
|
||||
int ret = 0;
|
||||
struct mem_cgroup *old_memcg = NULL;
|
||||
const bool use_aio = cmd->use_aio;
|
||||
|
||||
if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) {
|
||||
ret = -EIO;
|
||||
@@ -1951,7 +1874,7 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
|
||||
}
|
||||
failed:
|
||||
/* complete non-aio request */
|
||||
if (!use_aio || ret) {
|
||||
if (ret != -EIOCBQUEUED) {
|
||||
if (ret == -EOPNOTSUPP)
|
||||
cmd->ret = ret;
|
||||
else
|
||||
|
||||
@@ -122,15 +122,6 @@ struct ublk_uring_cmd_pdu {
|
||||
*/
|
||||
#define UBLK_IO_FLAG_OWNED_BY_SRV 0x02
|
||||
|
||||
/*
|
||||
* IO command is aborted, so this flag is set in case of
|
||||
* !UBLK_IO_FLAG_ACTIVE.
|
||||
*
|
||||
* After this flag is observed, any pending or new incoming request
|
||||
* associated with this io command will be failed immediately
|
||||
*/
|
||||
#define UBLK_IO_FLAG_ABORTED 0x04
|
||||
|
||||
/*
|
||||
* UBLK_IO_FLAG_NEED_GET_DATA is set because IO command requires
|
||||
* get data buffer address from ublksrv.
|
||||
@@ -199,8 +190,6 @@ struct ublk_device {
|
||||
struct completion completion;
|
||||
unsigned int nr_queues_ready;
|
||||
unsigned int nr_privileged_daemon;
|
||||
|
||||
struct work_struct nosrv_work;
|
||||
};
|
||||
|
||||
/* header of ublk_params */
|
||||
@@ -209,8 +198,8 @@ struct ublk_params_header {
|
||||
__u32 types;
|
||||
};
|
||||
|
||||
static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq);
|
||||
|
||||
static void ublk_stop_dev_unlocked(struct ublk_device *ub);
|
||||
static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq);
|
||||
static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub,
|
||||
struct ublk_queue *ubq, int tag, size_t offset);
|
||||
static inline unsigned int ublk_req_build_flags(struct request *req);
|
||||
@@ -1074,7 +1063,7 @@ static inline struct ublk_uring_cmd_pdu *ublk_get_uring_cmd_pdu(
|
||||
|
||||
static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq)
|
||||
{
|
||||
return ubq->ubq_daemon->flags & PF_EXITING;
|
||||
return !ubq->ubq_daemon || ubq->ubq_daemon->flags & PF_EXITING;
|
||||
}
|
||||
|
||||
/* todo: handle partial completion */
|
||||
@@ -1085,12 +1074,6 @@ static inline void __ublk_complete_rq(struct request *req)
|
||||
unsigned int unmapped_bytes;
|
||||
blk_status_t res = BLK_STS_OK;
|
||||
|
||||
/* called from ublk_abort_queue() code path */
|
||||
if (io->flags & UBLK_IO_FLAG_ABORTED) {
|
||||
res = BLK_STS_IOERR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* failed read IO if nothing is read */
|
||||
if (!io->res && req_op(req) == REQ_OP_READ)
|
||||
io->res = -EIO;
|
||||
@@ -1140,47 +1123,6 @@ static void ublk_complete_rq(struct kref *ref)
|
||||
__ublk_complete_rq(req);
|
||||
}
|
||||
|
||||
static void ublk_do_fail_rq(struct request *req)
|
||||
{
|
||||
struct ublk_queue *ubq = req->mq_hctx->driver_data;
|
||||
|
||||
if (ublk_nosrv_should_reissue_outstanding(ubq->dev))
|
||||
blk_mq_requeue_request(req, false);
|
||||
else
|
||||
__ublk_complete_rq(req);
|
||||
}
|
||||
|
||||
static void ublk_fail_rq_fn(struct kref *ref)
|
||||
{
|
||||
struct ublk_rq_data *data = container_of(ref, struct ublk_rq_data,
|
||||
ref);
|
||||
struct request *req = blk_mq_rq_from_pdu(data);
|
||||
|
||||
ublk_do_fail_rq(req);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since ublk_rq_task_work_cb always fails requests immediately during
|
||||
* exiting, __ublk_fail_req() is only called from abort context during
|
||||
* exiting. So lock is unnecessary.
|
||||
*
|
||||
* Also aborting may not be started yet, keep in mind that one failed
|
||||
* request may be issued by block layer again.
|
||||
*/
|
||||
static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
|
||||
struct request *req)
|
||||
{
|
||||
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
|
||||
|
||||
if (ublk_need_req_ref(ubq)) {
|
||||
struct ublk_rq_data *data = blk_mq_rq_to_pdu(req);
|
||||
|
||||
kref_put(&data->ref, ublk_fail_rq_fn);
|
||||
} else {
|
||||
ublk_do_fail_rq(req);
|
||||
}
|
||||
}
|
||||
|
||||
static void ubq_complete_io_cmd(struct ublk_io *io, int res,
|
||||
unsigned issue_flags)
|
||||
{
|
||||
@@ -1336,8 +1278,6 @@ static void ublk_queue_cmd_list(struct ublk_queue *ubq, struct rq_list *l)
|
||||
static enum blk_eh_timer_return ublk_timeout(struct request *rq)
|
||||
{
|
||||
struct ublk_queue *ubq = rq->mq_hctx->driver_data;
|
||||
unsigned int nr_inflight = 0;
|
||||
int i;
|
||||
|
||||
if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) {
|
||||
if (!ubq->timeout) {
|
||||
@@ -1348,26 +1288,6 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq)
|
||||
return BLK_EH_DONE;
|
||||
}
|
||||
|
||||
if (!ubq_daemon_is_dying(ubq))
|
||||
return BLK_EH_RESET_TIMER;
|
||||
|
||||
for (i = 0; i < ubq->q_depth; i++) {
|
||||
struct ublk_io *io = &ubq->ios[i];
|
||||
|
||||
if (!(io->flags & UBLK_IO_FLAG_ACTIVE))
|
||||
nr_inflight++;
|
||||
}
|
||||
|
||||
/* cancelable uring_cmd can't help us if all commands are in-flight */
|
||||
if (nr_inflight == ubq->q_depth) {
|
||||
struct ublk_device *ub = ubq->dev;
|
||||
|
||||
if (ublk_abort_requests(ub, ubq)) {
|
||||
schedule_work(&ub->nosrv_work);
|
||||
}
|
||||
return BLK_EH_DONE;
|
||||
}
|
||||
|
||||
return BLK_EH_RESET_TIMER;
|
||||
}
|
||||
|
||||
@@ -1470,6 +1390,37 @@ static const struct blk_mq_ops ublk_mq_ops = {
|
||||
.timeout = ublk_timeout,
|
||||
};
|
||||
|
||||
static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* All old ioucmds have to be completed */
|
||||
ubq->nr_io_ready = 0;
|
||||
|
||||
/*
|
||||
* old daemon is PF_EXITING, put it now
|
||||
*
|
||||
* It could be NULL in case of closing one quisced device.
|
||||
*/
|
||||
if (ubq->ubq_daemon)
|
||||
put_task_struct(ubq->ubq_daemon);
|
||||
/* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */
|
||||
ubq->ubq_daemon = NULL;
|
||||
ubq->timeout = false;
|
||||
|
||||
for (i = 0; i < ubq->q_depth; i++) {
|
||||
struct ublk_io *io = &ubq->ios[i];
|
||||
|
||||
/*
|
||||
* UBLK_IO_FLAG_CANCELED is kept for avoiding to touch
|
||||
* io->cmd
|
||||
*/
|
||||
io->flags &= UBLK_IO_FLAG_CANCELED;
|
||||
io->cmd = NULL;
|
||||
io->addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ublk_ch_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct ublk_device *ub = container_of(inode->i_cdev,
|
||||
@@ -1481,10 +1432,119 @@ static int ublk_ch_open(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ublk_reset_ch_dev(struct ublk_device *ub)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_queue_reinit(ub, ublk_get_queue(ub, i));
|
||||
|
||||
/* set to NULL, otherwise new ubq_daemon cannot mmap the io_cmd_buf */
|
||||
ub->mm = NULL;
|
||||
ub->nr_queues_ready = 0;
|
||||
ub->nr_privileged_daemon = 0;
|
||||
}
|
||||
|
||||
static struct gendisk *ublk_get_disk(struct ublk_device *ub)
|
||||
{
|
||||
struct gendisk *disk;
|
||||
|
||||
spin_lock(&ub->lock);
|
||||
disk = ub->ub_disk;
|
||||
if (disk)
|
||||
get_device(disk_to_dev(disk));
|
||||
spin_unlock(&ub->lock);
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
static void ublk_put_disk(struct gendisk *disk)
|
||||
{
|
||||
if (disk)
|
||||
put_device(disk_to_dev(disk));
|
||||
}
|
||||
|
||||
static int ublk_ch_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct ublk_device *ub = filp->private_data;
|
||||
struct gendisk *disk;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* disk isn't attached yet, either device isn't live, or it has
|
||||
* been removed already, so we needn't to do anything
|
||||
*/
|
||||
disk = ublk_get_disk(ub);
|
||||
if (!disk)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* All uring_cmd are done now, so abort any request outstanding to
|
||||
* the ublk server
|
||||
*
|
||||
* This can be done in lockless way because ublk server has been
|
||||
* gone
|
||||
*
|
||||
* More importantly, we have to provide forward progress guarantee
|
||||
* without holding ub->mutex, otherwise control task grabbing
|
||||
* ub->mutex triggers deadlock
|
||||
*
|
||||
* All requests may be inflight, so ->canceling may not be set, set
|
||||
* it now.
|
||||
*/
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
|
||||
struct ublk_queue *ubq = ublk_get_queue(ub, i);
|
||||
|
||||
ubq->canceling = true;
|
||||
ublk_abort_queue(ub, ubq);
|
||||
}
|
||||
blk_mq_kick_requeue_list(disk->queue);
|
||||
|
||||
/*
|
||||
* All infligh requests have been completed or requeued and any new
|
||||
* request will be failed or requeued via `->canceling` now, so it is
|
||||
* fine to grab ub->mutex now.
|
||||
*/
|
||||
mutex_lock(&ub->mutex);
|
||||
|
||||
/* double check after grabbing lock */
|
||||
if (!ub->ub_disk)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* Transition the device to the nosrv state. What exactly this
|
||||
* means depends on the recovery flags
|
||||
*/
|
||||
blk_mq_quiesce_queue(disk->queue);
|
||||
if (ublk_nosrv_should_stop_dev(ub)) {
|
||||
/*
|
||||
* Allow any pending/future I/O to pass through quickly
|
||||
* with an error. This is needed because del_gendisk
|
||||
* waits for all pending I/O to complete
|
||||
*/
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_get_queue(ub, i)->force_abort = true;
|
||||
blk_mq_unquiesce_queue(disk->queue);
|
||||
|
||||
ublk_stop_dev_unlocked(ub);
|
||||
} else {
|
||||
if (ublk_nosrv_dev_should_queue_io(ub)) {
|
||||
/* ->canceling is set and all requests are aborted */
|
||||
ub->dev_info.state = UBLK_S_DEV_QUIESCED;
|
||||
} else {
|
||||
ub->dev_info.state = UBLK_S_DEV_FAIL_IO;
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_get_queue(ub, i)->fail_io = true;
|
||||
}
|
||||
blk_mq_unquiesce_queue(disk->queue);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&ub->mutex);
|
||||
ublk_put_disk(disk);
|
||||
|
||||
/* all uring_cmd has been done now, reset device & ubq */
|
||||
ublk_reset_ch_dev(ub);
|
||||
out:
|
||||
clear_bit(UB_STATE_OPEN, &ub->state);
|
||||
return 0;
|
||||
}
|
||||
@@ -1551,10 +1611,26 @@ static void ublk_commit_completion(struct ublk_device *ub,
|
||||
ublk_put_req_ref(ubq, req);
|
||||
}
|
||||
|
||||
static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
|
||||
struct request *req)
|
||||
{
|
||||
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
|
||||
|
||||
if (ublk_nosrv_should_reissue_outstanding(ubq->dev))
|
||||
blk_mq_requeue_request(req, false);
|
||||
else {
|
||||
io->res = -EIO;
|
||||
__ublk_complete_rq(req);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from ubq_daemon context via cancel fn, meantime quiesce ublk
|
||||
* blk-mq queue, so we are called exclusively with blk-mq and ubq_daemon
|
||||
* context, so everything is serialized.
|
||||
* Called from ublk char device release handler, when any uring_cmd is
|
||||
* done, meantime request queue is "quiesced" since all inflight requests
|
||||
* can't be completed because ublk server is dead.
|
||||
*
|
||||
* So no one can hold our request IO reference any more, simply ignore the
|
||||
* reference, and complete the request immediately
|
||||
*/
|
||||
static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
{
|
||||
@@ -1571,46 +1647,29 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
* will do it
|
||||
*/
|
||||
rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i);
|
||||
if (rq && blk_mq_request_started(rq)) {
|
||||
io->flags |= UBLK_IO_FLAG_ABORTED;
|
||||
if (rq && blk_mq_request_started(rq))
|
||||
__ublk_fail_req(ubq, io, rq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Must be called when queue is frozen */
|
||||
static bool ublk_mark_queue_canceling(struct ublk_queue *ubq)
|
||||
static void ublk_mark_queue_canceling(struct ublk_queue *ubq)
|
||||
{
|
||||
bool canceled;
|
||||
|
||||
spin_lock(&ubq->cancel_lock);
|
||||
canceled = ubq->canceling;
|
||||
if (!canceled)
|
||||
if (!ubq->canceling)
|
||||
ubq->canceling = true;
|
||||
spin_unlock(&ubq->cancel_lock);
|
||||
|
||||
return canceled;
|
||||
}
|
||||
|
||||
static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
static void ublk_start_cancel(struct ublk_queue *ubq)
|
||||
{
|
||||
bool was_canceled = ubq->canceling;
|
||||
struct gendisk *disk;
|
||||
|
||||
if (was_canceled)
|
||||
return false;
|
||||
|
||||
spin_lock(&ub->lock);
|
||||
disk = ub->ub_disk;
|
||||
if (disk)
|
||||
get_device(disk_to_dev(disk));
|
||||
spin_unlock(&ub->lock);
|
||||
struct ublk_device *ub = ubq->dev;
|
||||
struct gendisk *disk = ublk_get_disk(ub);
|
||||
|
||||
/* Our disk has been dead */
|
||||
if (!disk)
|
||||
return false;
|
||||
|
||||
return;
|
||||
/*
|
||||
* Now we are serialized with ublk_queue_rq()
|
||||
*
|
||||
@@ -1619,15 +1678,9 @@ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
* touch completed uring_cmd
|
||||
*/
|
||||
blk_mq_quiesce_queue(disk->queue);
|
||||
was_canceled = ublk_mark_queue_canceling(ubq);
|
||||
if (!was_canceled) {
|
||||
/* abort queue is for making forward progress */
|
||||
ublk_abort_queue(ub, ubq);
|
||||
}
|
||||
ublk_mark_queue_canceling(ubq);
|
||||
blk_mq_unquiesce_queue(disk->queue);
|
||||
put_device(disk_to_dev(disk));
|
||||
|
||||
return !was_canceled;
|
||||
ublk_put_disk(disk);
|
||||
}
|
||||
|
||||
static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,
|
||||
@@ -1651,6 +1704,17 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,
|
||||
/*
|
||||
* The ublk char device won't be closed when calling cancel fn, so both
|
||||
* ublk device and queue are guaranteed to be live
|
||||
*
|
||||
* Two-stage cancel:
|
||||
*
|
||||
* - make every active uring_cmd done in ->cancel_fn()
|
||||
*
|
||||
* - aborting inflight ublk IO requests in ublk char device release handler,
|
||||
* which depends on 1st stage because device can only be closed iff all
|
||||
* uring_cmd are done
|
||||
*
|
||||
* Do _not_ try to acquire ub->mutex before all inflight requests are
|
||||
* aborted, otherwise deadlock may be caused.
|
||||
*/
|
||||
static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
||||
unsigned int issue_flags)
|
||||
@@ -1658,8 +1722,6 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
||||
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
|
||||
struct ublk_queue *ubq = pdu->ubq;
|
||||
struct task_struct *task;
|
||||
struct ublk_device *ub;
|
||||
bool need_schedule;
|
||||
struct ublk_io *io;
|
||||
|
||||
if (WARN_ON_ONCE(!ubq))
|
||||
@@ -1672,16 +1734,12 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
||||
if (WARN_ON_ONCE(task && task != ubq->ubq_daemon))
|
||||
return;
|
||||
|
||||
ub = ubq->dev;
|
||||
need_schedule = ublk_abort_requests(ub, ubq);
|
||||
if (!ubq->canceling)
|
||||
ublk_start_cancel(ubq);
|
||||
|
||||
io = &ubq->ios[pdu->tag];
|
||||
WARN_ON_ONCE(io->cmd != cmd);
|
||||
ublk_cancel_cmd(ubq, io, issue_flags);
|
||||
|
||||
if (need_schedule) {
|
||||
schedule_work(&ub->nosrv_work);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool ublk_queue_ready(struct ublk_queue *ubq)
|
||||
@@ -1732,33 +1790,20 @@ static void ublk_wait_tagset_rqs_idle(struct ublk_device *ub)
|
||||
}
|
||||
}
|
||||
|
||||
static void __ublk_quiesce_dev(struct ublk_device *ub)
|
||||
static void ublk_force_abort_dev(struct ublk_device *ub)
|
||||
{
|
||||
pr_devel("%s: quiesce ub: dev_id %d state %s\n",
|
||||
int i;
|
||||
|
||||
pr_devel("%s: force abort ub: dev_id %d state %s\n",
|
||||
__func__, ub->dev_info.dev_id,
|
||||
ub->dev_info.state == UBLK_S_DEV_LIVE ?
|
||||
"LIVE" : "QUIESCED");
|
||||
blk_mq_quiesce_queue(ub->ub_disk->queue);
|
||||
ublk_wait_tagset_rqs_idle(ub);
|
||||
ub->dev_info.state = UBLK_S_DEV_QUIESCED;
|
||||
}
|
||||
if (ub->dev_info.state == UBLK_S_DEV_LIVE)
|
||||
ublk_wait_tagset_rqs_idle(ub);
|
||||
|
||||
static void ublk_unquiesce_dev(struct ublk_device *ub)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_devel("%s: unquiesce ub: dev_id %d state %s\n",
|
||||
__func__, ub->dev_info.dev_id,
|
||||
ub->dev_info.state == UBLK_S_DEV_LIVE ?
|
||||
"LIVE" : "QUIESCED");
|
||||
/* quiesce_work has run. We let requeued rqs be aborted
|
||||
* before running fallback_wq. "force_abort" must be seen
|
||||
* after request queue is unqiuesced. Then del_gendisk()
|
||||
* can move on.
|
||||
*/
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_get_queue(ub, i)->force_abort = true;
|
||||
|
||||
blk_mq_unquiesce_queue(ub->ub_disk->queue);
|
||||
/* We may have requeued some rqs in ublk_quiesce_queue() */
|
||||
blk_mq_kick_requeue_list(ub->ub_disk->queue);
|
||||
@@ -1779,61 +1824,51 @@ static struct gendisk *ublk_detach_disk(struct ublk_device *ub)
|
||||
return disk;
|
||||
}
|
||||
|
||||
static void ublk_stop_dev(struct ublk_device *ub)
|
||||
static void ublk_stop_dev_unlocked(struct ublk_device *ub)
|
||||
__must_hold(&ub->mutex)
|
||||
{
|
||||
struct gendisk *disk;
|
||||
|
||||
mutex_lock(&ub->mutex);
|
||||
if (ub->dev_info.state == UBLK_S_DEV_DEAD)
|
||||
goto unlock;
|
||||
if (ublk_nosrv_dev_should_queue_io(ub)) {
|
||||
if (ub->dev_info.state == UBLK_S_DEV_LIVE)
|
||||
__ublk_quiesce_dev(ub);
|
||||
ublk_unquiesce_dev(ub);
|
||||
}
|
||||
return;
|
||||
|
||||
if (ublk_nosrv_dev_should_queue_io(ub))
|
||||
ublk_force_abort_dev(ub);
|
||||
del_gendisk(ub->ub_disk);
|
||||
disk = ublk_detach_disk(ub);
|
||||
put_disk(disk);
|
||||
unlock:
|
||||
}
|
||||
|
||||
static void ublk_stop_dev(struct ublk_device *ub)
|
||||
{
|
||||
mutex_lock(&ub->mutex);
|
||||
ublk_stop_dev_unlocked(ub);
|
||||
mutex_unlock(&ub->mutex);
|
||||
ublk_cancel_dev(ub);
|
||||
}
|
||||
|
||||
static void ublk_nosrv_work(struct work_struct *work)
|
||||
/* reset ublk io_uring queue & io flags */
|
||||
static void ublk_reset_io_flags(struct ublk_device *ub)
|
||||
{
|
||||
struct ublk_device *ub =
|
||||
container_of(work, struct ublk_device, nosrv_work);
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (ublk_nosrv_should_stop_dev(ub)) {
|
||||
ublk_stop_dev(ub);
|
||||
return;
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
|
||||
struct ublk_queue *ubq = ublk_get_queue(ub, i);
|
||||
|
||||
/* UBLK_IO_FLAG_CANCELED can be cleared now */
|
||||
spin_lock(&ubq->cancel_lock);
|
||||
for (j = 0; j < ubq->q_depth; j++)
|
||||
ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED;
|
||||
spin_unlock(&ubq->cancel_lock);
|
||||
ubq->canceling = false;
|
||||
ubq->fail_io = false;
|
||||
}
|
||||
|
||||
mutex_lock(&ub->mutex);
|
||||
if (ub->dev_info.state != UBLK_S_DEV_LIVE)
|
||||
goto unlock;
|
||||
|
||||
if (ublk_nosrv_dev_should_queue_io(ub)) {
|
||||
__ublk_quiesce_dev(ub);
|
||||
} else {
|
||||
blk_mq_quiesce_queue(ub->ub_disk->queue);
|
||||
ub->dev_info.state = UBLK_S_DEV_FAIL_IO;
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
|
||||
ublk_get_queue(ub, i)->fail_io = true;
|
||||
}
|
||||
blk_mq_unquiesce_queue(ub->ub_disk->queue);
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&ub->mutex);
|
||||
ublk_cancel_dev(ub);
|
||||
}
|
||||
|
||||
/* device can only be started after all IOs are ready */
|
||||
static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
__must_hold(&ub->mutex)
|
||||
{
|
||||
mutex_lock(&ub->mutex);
|
||||
ubq->nr_io_ready++;
|
||||
if (ublk_queue_ready(ubq)) {
|
||||
ubq->ubq_daemon = current;
|
||||
@@ -1843,9 +1878,12 @@ static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
if (capable(CAP_SYS_ADMIN))
|
||||
ub->nr_privileged_daemon++;
|
||||
}
|
||||
if (ub->nr_queues_ready == ub->dev_info.nr_hw_queues)
|
||||
|
||||
if (ub->nr_queues_ready == ub->dev_info.nr_hw_queues) {
|
||||
/* now we are ready for handling ublk io request */
|
||||
ublk_reset_io_flags(ub);
|
||||
complete_all(&ub->completion);
|
||||
mutex_unlock(&ub->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id,
|
||||
@@ -1929,6 +1967,52 @@ static int ublk_unregister_io_buf(struct io_uring_cmd *cmd,
|
||||
return io_buffer_unregister_bvec(cmd, index, issue_flags);
|
||||
}
|
||||
|
||||
static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_queue *ubq,
|
||||
struct ublk_io *io, __u64 buf_addr)
|
||||
{
|
||||
struct ublk_device *ub = ubq->dev;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* When handling FETCH command for setting up ublk uring queue,
|
||||
* ub->mutex is the innermost lock, and we won't block for handling
|
||||
* FETCH, so it is fine even for IO_URING_F_NONBLOCK.
|
||||
*/
|
||||
mutex_lock(&ub->mutex);
|
||||
/* UBLK_IO_FETCH_REQ is only allowed before queue is setup */
|
||||
if (ublk_queue_ready(ubq)) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* allow each command to be FETCHed at most once */
|
||||
if (io->flags & UBLK_IO_FLAG_ACTIVE) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV);
|
||||
|
||||
if (ublk_need_map_io(ubq)) {
|
||||
/*
|
||||
* FETCH_RQ has to provide IO buffer if NEED GET
|
||||
* DATA is not enabled
|
||||
*/
|
||||
if (!buf_addr && !ublk_need_get_data(ubq))
|
||||
goto out;
|
||||
} else if (buf_addr) {
|
||||
/* User copy requires addr to be unset */
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ublk_fill_io_cmd(io, cmd, buf_addr);
|
||||
ublk_mark_io_ready(ub, ubq);
|
||||
out:
|
||||
mutex_unlock(&ub->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
|
||||
unsigned int issue_flags,
|
||||
const struct ublksrv_io_cmd *ub_cmd)
|
||||
@@ -1985,33 +2069,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
|
||||
case UBLK_IO_UNREGISTER_IO_BUF:
|
||||
return ublk_unregister_io_buf(cmd, ub_cmd->addr, issue_flags);
|
||||
case UBLK_IO_FETCH_REQ:
|
||||
/* UBLK_IO_FETCH_REQ is only allowed before queue is setup */
|
||||
if (ublk_queue_ready(ubq)) {
|
||||
ret = -EBUSY;
|
||||
ret = ublk_fetch(cmd, ubq, io, ub_cmd->addr);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* The io is being handled by server, so COMMIT_RQ is expected
|
||||
* instead of FETCH_REQ
|
||||
*/
|
||||
if (io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)
|
||||
goto out;
|
||||
|
||||
if (ublk_need_map_io(ubq)) {
|
||||
/*
|
||||
* FETCH_RQ has to provide IO buffer if NEED GET
|
||||
* DATA is not enabled
|
||||
*/
|
||||
if (!ub_cmd->addr && !ublk_need_get_data(ubq))
|
||||
goto out;
|
||||
} else if (ub_cmd->addr) {
|
||||
/* User copy requires addr to be unset */
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ublk_fill_io_cmd(io, cmd, ub_cmd->addr);
|
||||
ublk_mark_io_ready(ub, ubq);
|
||||
break;
|
||||
case UBLK_IO_COMMIT_AND_FETCH_REQ:
|
||||
req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag);
|
||||
@@ -2411,7 +2471,6 @@ static void ublk_remove(struct ublk_device *ub)
|
||||
bool unprivileged;
|
||||
|
||||
ublk_stop_dev(ub);
|
||||
cancel_work_sync(&ub->nosrv_work);
|
||||
cdev_device_del(&ub->cdev, &ub->cdev_dev);
|
||||
unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV;
|
||||
ublk_put_device(ub);
|
||||
@@ -2696,7 +2755,6 @@ static int ublk_ctrl_add_dev(const struct ublksrv_ctrl_cmd *header)
|
||||
goto out_unlock;
|
||||
mutex_init(&ub->mutex);
|
||||
spin_lock_init(&ub->lock);
|
||||
INIT_WORK(&ub->nosrv_work, ublk_nosrv_work);
|
||||
|
||||
ret = ublk_alloc_dev_number(ub, header->dev_id);
|
||||
if (ret < 0)
|
||||
@@ -2828,7 +2886,6 @@ static inline void ublk_ctrl_cmd_dump(struct io_uring_cmd *cmd)
|
||||
static int ublk_ctrl_stop_dev(struct ublk_device *ub)
|
||||
{
|
||||
ublk_stop_dev(ub);
|
||||
cancel_work_sync(&ub->nosrv_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2932,42 +2989,14 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq)
|
||||
{
|
||||
int i;
|
||||
|
||||
WARN_ON_ONCE(!(ubq->ubq_daemon && ubq_daemon_is_dying(ubq)));
|
||||
|
||||
/* All old ioucmds have to be completed */
|
||||
ubq->nr_io_ready = 0;
|
||||
/* old daemon is PF_EXITING, put it now */
|
||||
put_task_struct(ubq->ubq_daemon);
|
||||
/* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */
|
||||
ubq->ubq_daemon = NULL;
|
||||
ubq->timeout = false;
|
||||
ubq->canceling = false;
|
||||
|
||||
for (i = 0; i < ubq->q_depth; i++) {
|
||||
struct ublk_io *io = &ubq->ios[i];
|
||||
|
||||
/* forget everything now and be ready for new FETCH_REQ */
|
||||
io->flags = 0;
|
||||
io->cmd = NULL;
|
||||
io->addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ublk_ctrl_start_recovery(struct ublk_device *ub,
|
||||
const struct ublksrv_ctrl_cmd *header)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
|
||||
mutex_lock(&ub->mutex);
|
||||
if (ublk_nosrv_should_stop_dev(ub))
|
||||
goto out_unlock;
|
||||
if (!ub->nr_queues_ready)
|
||||
goto out_unlock;
|
||||
/*
|
||||
* START_RECOVERY is only allowd after:
|
||||
*
|
||||
@@ -2991,12 +3020,6 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub,
|
||||
goto out_unlock;
|
||||
}
|
||||
pr_devel("%s: start recovery for dev id %d.\n", __func__, header->dev_id);
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_queue_reinit(ub, ublk_get_queue(ub, i));
|
||||
/* set to NULL, otherwise new ubq_daemon cannot mmap the io_cmd_buf */
|
||||
ub->mm = NULL;
|
||||
ub->nr_queues_ready = 0;
|
||||
ub->nr_privileged_daemon = 0;
|
||||
init_completion(&ub->completion);
|
||||
ret = 0;
|
||||
out_unlock:
|
||||
@@ -3009,7 +3032,6 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
|
||||
{
|
||||
int ublksrv_pid = (int)header->data[0];
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
|
||||
pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n",
|
||||
__func__, ub->dev_info.nr_hw_queues, header->dev_id);
|
||||
@@ -3029,24 +3051,10 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
|
||||
goto out_unlock;
|
||||
}
|
||||
ub->dev_info.ublksrv_pid = ublksrv_pid;
|
||||
ub->dev_info.state = UBLK_S_DEV_LIVE;
|
||||
pr_devel("%s: new ublksrv_pid %d, dev id %d\n",
|
||||
__func__, ublksrv_pid, header->dev_id);
|
||||
|
||||
if (ublk_nosrv_dev_should_queue_io(ub)) {
|
||||
ub->dev_info.state = UBLK_S_DEV_LIVE;
|
||||
blk_mq_unquiesce_queue(ub->ub_disk->queue);
|
||||
pr_devel("%s: queue unquiesced, dev id %d.\n",
|
||||
__func__, header->dev_id);
|
||||
blk_mq_kick_requeue_list(ub->ub_disk->queue);
|
||||
} else {
|
||||
blk_mq_quiesce_queue(ub->ub_disk->queue);
|
||||
ub->dev_info.state = UBLK_S_DEV_LIVE;
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
|
||||
ublk_get_queue(ub, i)->fail_io = false;
|
||||
}
|
||||
blk_mq_unquiesce_queue(ub->ub_disk->queue);
|
||||
}
|
||||
|
||||
blk_mq_kick_requeue_list(ub->ub_disk->queue);
|
||||
ret = 0;
|
||||
out_unlock:
|
||||
mutex_unlock(&ub->mutex);
|
||||
|
||||
@@ -1286,7 +1286,9 @@ static void nxp_coredump(struct hci_dev *hdev)
|
||||
u8 pcmd = 2;
|
||||
|
||||
skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd);
|
||||
if (!IS_ERR(skb))
|
||||
if (IS_ERR(skb))
|
||||
bt_dev_err(hdev, "Failed to trigger FW Dump. (%ld)", PTR_ERR(skb));
|
||||
else
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
@@ -1445,9 +1447,6 @@ static int nxp_shutdown(struct hci_dev *hdev)
|
||||
/* HCI_NXP_IND_RESET command may not returns any response */
|
||||
if (!IS_ERR(skb))
|
||||
kfree_skb(skb);
|
||||
} else if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1799,13 +1798,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
|
||||
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
|
||||
wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
|
||||
}
|
||||
|
||||
if (test_bit(HCI_RUNNING, &hdev->flags)) {
|
||||
/* Ensure shutdown callback is executed before unregistering, so
|
||||
* that baudrate is reset to initial value.
|
||||
} else {
|
||||
/* Restore FW baudrate to fw_init_baudrate if changed.
|
||||
* This will ensure FW baudrate is in sync with
|
||||
* driver baudrate in case this driver is re-inserted.
|
||||
*/
|
||||
nxp_shutdown(hdev);
|
||||
if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ps_cleanup(nxpdev);
|
||||
|
||||
@@ -889,7 +889,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T)
|
||||
variant = "t";
|
||||
else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S)
|
||||
variant = "u";
|
||||
variant = "s";
|
||||
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/cmnv%02x%s.bin", rom_ver, variant);
|
||||
|
||||
@@ -1215,6 +1215,8 @@ next:
|
||||
rtl_dev_err(hdev, "mandatory config file %s not found",
|
||||
btrtl_dev->ic_info->cfg_name);
|
||||
ret = btrtl_dev->cfg_len;
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,18 +289,18 @@ static void vhci_coredump(struct hci_dev *hdev)
|
||||
|
||||
static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
char buf[80];
|
||||
const char *buf;
|
||||
|
||||
snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n");
|
||||
buf = "Controller Name: vhci_ctrl\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n");
|
||||
buf = "Firmware Version: vhci_fw\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Driver: vhci_drv\n");
|
||||
buf = "Driver: vhci_drv\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Vendor: vhci\n");
|
||||
buf = "Vendor: vhci\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
||||
@@ -607,13 +607,16 @@ static void amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
|
||||
union perf_cached perf = READ_ONCE(cpudata->perf);
|
||||
|
||||
perf.max_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->max);
|
||||
perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min);
|
||||
|
||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
||||
perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf);
|
||||
|
||||
WRITE_ONCE(cpudata->max_limit_freq, policy->max);
|
||||
WRITE_ONCE(cpudata->min_limit_freq, policy->min);
|
||||
|
||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf);
|
||||
WRITE_ONCE(cpudata->min_limit_freq, min(cpudata->nominal_freq, cpudata->max_limit_freq));
|
||||
} else {
|
||||
perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min);
|
||||
WRITE_ONCE(cpudata->min_limit_freq, policy->min);
|
||||
}
|
||||
|
||||
WRITE_ONCE(cpudata->perf, perf);
|
||||
}
|
||||
|
||||
@@ -791,16 +794,6 @@ static void amd_perf_ctl_reset(unsigned int cpu)
|
||||
wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks
|
||||
* due to locking, so queue the work for later.
|
||||
*/
|
||||
static void amd_pstste_sched_prefcore_workfn(struct work_struct *work)
|
||||
{
|
||||
sched_set_itmt_support();
|
||||
}
|
||||
static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn);
|
||||
|
||||
#define CPPC_MAX_PERF U8_MAX
|
||||
|
||||
static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)
|
||||
@@ -811,14 +804,8 @@ static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)
|
||||
|
||||
cpudata->hw_prefcore = true;
|
||||
|
||||
/*
|
||||
* The priorities can be set regardless of whether or not
|
||||
* sched_set_itmt_support(true) has been called and it is valid to
|
||||
* update them at any time after it has been called.
|
||||
*/
|
||||
/* Priorities must be initialized before ITMT support can be toggled on. */
|
||||
sched_set_itmt_core_prio((int)READ_ONCE(cpudata->prefcore_ranking), cpudata->cpu);
|
||||
|
||||
schedule_work(&sched_prefcore_work);
|
||||
}
|
||||
|
||||
static void amd_pstate_update_limits(unsigned int cpu)
|
||||
@@ -1193,6 +1180,9 @@ static ssize_t show_energy_performance_preference(
|
||||
|
||||
static void amd_pstate_driver_cleanup(void)
|
||||
{
|
||||
if (amd_pstate_prefcore)
|
||||
sched_clear_itmt_support();
|
||||
|
||||
cppc_state = AMD_PSTATE_DISABLE;
|
||||
current_pstate_driver = NULL;
|
||||
}
|
||||
@@ -1235,6 +1225,10 @@ static int amd_pstate_register_driver(int mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable ITMT support once all CPUs have initialized their asym priorities. */
|
||||
if (amd_pstate_prefcore)
|
||||
sched_set_itmt_support();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -540,8 +540,6 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
target_freq = clamp_val(target_freq, policy->min, policy->max);
|
||||
|
||||
if (!policy->freq_table)
|
||||
return target_freq;
|
||||
|
||||
@@ -565,7 +563,22 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
|
||||
unsigned int min = READ_ONCE(policy->min);
|
||||
unsigned int max = READ_ONCE(policy->max);
|
||||
|
||||
/*
|
||||
* If this function runs in parallel with cpufreq_set_policy(), it may
|
||||
* read policy->min before the update and policy->max after the update
|
||||
* or the other way around, so there is no ordering guarantee.
|
||||
*
|
||||
* Resolve this by always honoring the max (in case it comes from
|
||||
* thermal throttling or similar).
|
||||
*/
|
||||
if (unlikely(min > max))
|
||||
min = max;
|
||||
|
||||
return __resolve_freq(policy, clamp_val(target_freq, min, max),
|
||||
CPUFREQ_RELATION_LE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
|
||||
|
||||
@@ -2384,6 +2397,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
|
||||
if (cpufreq_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
target_freq = clamp_val(target_freq, policy->min, policy->max);
|
||||
target_freq = __resolve_freq(policy, target_freq, relation);
|
||||
|
||||
pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
|
||||
@@ -2708,11 +2722,15 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
||||
* Resolve policy min/max to available frequencies. It ensures
|
||||
* no frequency resolution will neither overshoot the requested maximum
|
||||
* nor undershoot the requested minimum.
|
||||
*
|
||||
* Avoid storing intermediate values in policy->max or policy->min and
|
||||
* compiler optimizations around them because they may be accessed
|
||||
* concurrently by cpufreq_driver_resolve_freq() during the update.
|
||||
*/
|
||||
policy->min = new_data.min;
|
||||
policy->max = new_data.max;
|
||||
policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
|
||||
policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
|
||||
WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, CPUFREQ_RELATION_H));
|
||||
new_data.min = __resolve_freq(policy, new_data.min, CPUFREQ_RELATION_L);
|
||||
WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
|
||||
|
||||
trace_cpu_frequency_limits(policy);
|
||||
|
||||
cpufreq_update_pressure(policy);
|
||||
|
||||
@@ -2209,7 +2209,7 @@ static int knl_get_turbo_pstate(int cpu)
|
||||
static int hwp_get_cpu_scaling(int cpu)
|
||||
{
|
||||
if (hybrid_scaling_factor) {
|
||||
struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
u8 cpu_type = c->topo.intel_type;
|
||||
|
||||
/*
|
||||
|
||||
@@ -122,12 +122,12 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
|
||||
qm_fd_addr_set64(&fd, addr);
|
||||
|
||||
do {
|
||||
refcount_inc(&req->drv_ctx->refcnt);
|
||||
ret = qman_enqueue(req->drv_ctx->req_fq, &fd);
|
||||
if (likely(!ret)) {
|
||||
refcount_inc(&req->drv_ctx->refcnt);
|
||||
if (likely(!ret))
|
||||
return 0;
|
||||
}
|
||||
|
||||
refcount_dec(&req->drv_ctx->refcnt);
|
||||
if (ret != -EBUSY)
|
||||
break;
|
||||
num_retries++;
|
||||
|
||||
@@ -269,7 +269,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
|
||||
unsigned int cmdlen, key1_id, key2_id;
|
||||
int ret;
|
||||
|
||||
rctx->iv = (u32 *)req->iv;
|
||||
rctx->iv = (ctx->alg == SE_ALG_ECB) ? NULL : (u32 *)req->iv;
|
||||
rctx->len = req->cryptlen;
|
||||
key1_id = ctx->key1_id;
|
||||
key2_id = ctx->key2_id;
|
||||
@@ -498,9 +498,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
|
||||
if (!req->cryptlen)
|
||||
return 0;
|
||||
|
||||
if (ctx->alg == SE_ALG_ECB)
|
||||
req->iv = NULL;
|
||||
|
||||
rctx->encrypt = encrypt;
|
||||
|
||||
return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req);
|
||||
|
||||
@@ -438,15 +438,17 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
|
||||
return -EINVAL;
|
||||
|
||||
pt = dma_fence_to_sync_pt(fence);
|
||||
if (!pt)
|
||||
return -EINVAL;
|
||||
if (!pt) {
|
||||
ret = -EINVAL;
|
||||
goto put_fence;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
|
||||
data.deadline_ns = ktime_to_ns(pt->deadline);
|
||||
} else {
|
||||
if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
|
||||
ret = -ENOENT;
|
||||
goto unlock;
|
||||
}
|
||||
data.deadline_ns = ktime_to_ns(pt->deadline);
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
||||
dma_fence_put(fence);
|
||||
@@ -458,6 +460,13 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
unlock:
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
put_fence:
|
||||
dma_fence_put(fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long sw_sync_ioctl(struct file *file, unsigned int cmd,
|
||||
|
||||
@@ -461,36 +461,6 @@ unsigned int cs_dsp_mock_xm_header_get_alg_base_in_words(struct cs_dsp_test *pri
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_alg_base_in_words, "FW_CS_DSP_KUNIT_TEST_UTILS");
|
||||
|
||||
/**
|
||||
* cs_dsp_mock_xm_header_get_fw_version_from_regmap() - Firmware version.
|
||||
*
|
||||
* @priv: Pointer to struct cs_dsp_test.
|
||||
*
|
||||
* Return: Firmware version word value.
|
||||
*/
|
||||
unsigned int cs_dsp_mock_xm_header_get_fw_version_from_regmap(struct cs_dsp_test *priv)
|
||||
{
|
||||
unsigned int xm = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM);
|
||||
union {
|
||||
struct wmfw_id_hdr adsp2;
|
||||
struct wmfw_v3_id_hdr halo;
|
||||
} hdr;
|
||||
|
||||
switch (priv->dsp->type) {
|
||||
case WMFW_ADSP2:
|
||||
regmap_raw_read(priv->dsp->regmap, xm, &hdr.adsp2, sizeof(hdr.adsp2));
|
||||
return be32_to_cpu(hdr.adsp2.ver);
|
||||
case WMFW_HALO:
|
||||
regmap_raw_read(priv->dsp->regmap, xm, &hdr.halo, sizeof(hdr.halo));
|
||||
return be32_to_cpu(hdr.halo.ver);
|
||||
default:
|
||||
KUNIT_FAIL(priv->test, NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_fw_version_from_regmap,
|
||||
"FW_CS_DSP_KUNIT_TEST_UTILS");
|
||||
|
||||
/**
|
||||
* cs_dsp_mock_xm_header_get_fw_version() - Firmware version.
|
||||
*
|
||||
|
||||
@@ -2198,7 +2198,7 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp)
|
||||
|
||||
priv->local->bin_builder =
|
||||
cs_dsp_mock_bin_init(priv, 1,
|
||||
cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv));
|
||||
cs_dsp_mock_xm_header_get_fw_version(xm_hdr));
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder);
|
||||
|
||||
/* We must provide a dummy wmfw to load */
|
||||
|
||||
@@ -451,7 +451,7 @@ static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *ds
|
||||
|
||||
local->bin_builder =
|
||||
cs_dsp_mock_bin_init(priv, 1,
|
||||
cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv));
|
||||
cs_dsp_mock_xm_header_get_fw_version(local->xm_header));
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->bin_builder);
|
||||
|
||||
/* Init cs_dsp */
|
||||
|
||||
@@ -170,4 +170,5 @@ static struct kunit_suite fpga_bridge_suite = {
|
||||
|
||||
kunit_test_suite(fpga_bridge_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit test for the FPGA Bridge");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -330,4 +330,5 @@ static struct kunit_suite fpga_mgr_suite = {
|
||||
|
||||
kunit_test_suite(fpga_mgr_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit test for the FPGA Manager");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -214,4 +214,5 @@ static struct kunit_suite fpga_region_suite = {
|
||||
|
||||
kunit_test_suite(fpga_region_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit test for the FPGA Region");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -105,7 +105,7 @@ static int fwctl_cmd_rpc(struct fwctl_ucmd *ucmd)
|
||||
if (!test_and_set_bit(0, &fwctl_tainted)) {
|
||||
dev_warn(
|
||||
&fwctl->dev,
|
||||
"%s(%d): has requested full access to the physical device device",
|
||||
"%s(%d): has requested full access to the physical device",
|
||||
current->comm, task_pid_nr(current));
|
||||
add_taint(TAINT_FWCTL, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
@@ -105,12 +105,14 @@ static int pdsfc_identify(struct pdsfc_dev *pdsfc)
|
||||
static void pdsfc_free_endpoints(struct pdsfc_dev *pdsfc)
|
||||
{
|
||||
struct device *dev = &pdsfc->fwctl.dev;
|
||||
u32 num_endpoints;
|
||||
int i;
|
||||
|
||||
if (!pdsfc->endpoints)
|
||||
return;
|
||||
|
||||
for (i = 0; pdsfc->endpoint_info && i < pdsfc->endpoints->num_entries; i++)
|
||||
num_endpoints = le32_to_cpu(pdsfc->endpoints->num_entries);
|
||||
for (i = 0; pdsfc->endpoint_info && i < num_endpoints; i++)
|
||||
mutex_destroy(&pdsfc->endpoint_info[i].lock);
|
||||
vfree(pdsfc->endpoint_info);
|
||||
pdsfc->endpoint_info = NULL;
|
||||
@@ -199,7 +201,7 @@ static int pdsfc_init_endpoints(struct pdsfc_dev *pdsfc)
|
||||
ep_entry = (struct pds_fwctl_query_data_endpoint *)pdsfc->endpoints->entries;
|
||||
for (i = 0; i < num_endpoints; i++) {
|
||||
mutex_init(&pdsfc->endpoint_info[i].lock);
|
||||
pdsfc->endpoint_info[i].endpoint = ep_entry[i].id;
|
||||
pdsfc->endpoint_info[i].endpoint = le32_to_cpu(ep_entry[i].id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -214,6 +216,7 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc
|
||||
struct pds_fwctl_query_data *data;
|
||||
union pds_core_adminq_cmd cmd;
|
||||
dma_addr_t data_pa;
|
||||
u32 num_entries;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
@@ -246,8 +249,9 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc
|
||||
*pa = data_pa;
|
||||
|
||||
entries = (struct pds_fwctl_query_data_operation *)data->entries;
|
||||
dev_dbg(dev, "num_entries %d\n", data->num_entries);
|
||||
for (i = 0; i < data->num_entries; i++) {
|
||||
num_entries = le32_to_cpu(data->num_entries);
|
||||
dev_dbg(dev, "num_entries %d\n", num_entries);
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
|
||||
/* Translate FW command attribute to fwctl scope */
|
||||
switch (entries[i].scope) {
|
||||
@@ -267,7 +271,7 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc
|
||||
break;
|
||||
}
|
||||
dev_dbg(dev, "endpoint %d operation: id %x scope %d\n",
|
||||
ep, entries[i].id, entries[i].scope);
|
||||
ep, le32_to_cpu(entries[i].id), entries[i].scope);
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -280,24 +284,26 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc,
|
||||
struct pds_fwctl_query_data_operation *op_entry;
|
||||
struct pdsfc_rpc_endpoint_info *ep_info = NULL;
|
||||
struct device *dev = &pdsfc->fwctl.dev;
|
||||
u32 num_entries;
|
||||
int i;
|
||||
|
||||
/* validate rpc in_len & out_len based
|
||||
* on ident.max_req_sz & max_resp_sz
|
||||
*/
|
||||
if (rpc->in.len > pdsfc->ident.max_req_sz) {
|
||||
if (rpc->in.len > le32_to_cpu(pdsfc->ident.max_req_sz)) {
|
||||
dev_dbg(dev, "Invalid request size %u, max %u\n",
|
||||
rpc->in.len, pdsfc->ident.max_req_sz);
|
||||
rpc->in.len, le32_to_cpu(pdsfc->ident.max_req_sz));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rpc->out.len > pdsfc->ident.max_resp_sz) {
|
||||
if (rpc->out.len > le32_to_cpu(pdsfc->ident.max_resp_sz)) {
|
||||
dev_dbg(dev, "Invalid response size %u, max %u\n",
|
||||
rpc->out.len, pdsfc->ident.max_resp_sz);
|
||||
rpc->out.len, le32_to_cpu(pdsfc->ident.max_resp_sz));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < pdsfc->endpoints->num_entries; i++) {
|
||||
num_entries = le32_to_cpu(pdsfc->endpoints->num_entries);
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
if (pdsfc->endpoint_info[i].endpoint == rpc->in.ep) {
|
||||
ep_info = &pdsfc->endpoint_info[i];
|
||||
break;
|
||||
@@ -326,8 +332,9 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc,
|
||||
|
||||
/* reject unsupported and/or out of scope commands */
|
||||
op_entry = (struct pds_fwctl_query_data_operation *)ep_info->operations->entries;
|
||||
for (i = 0; i < ep_info->operations->num_entries; i++) {
|
||||
if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, op_entry[i].id)) {
|
||||
num_entries = le32_to_cpu(ep_info->operations->num_entries);
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, le32_to_cpu(op_entry[i].id))) {
|
||||
if (scope < op_entry[i].scope)
|
||||
return -EPERM;
|
||||
return 0;
|
||||
@@ -402,7 +409,7 @@ static void *pdsfc_fw_rpc(struct fwctl_uctx *uctx, enum fwctl_rpc_scope scope,
|
||||
cmd = (union pds_core_adminq_cmd) {
|
||||
.fwctl_rpc = {
|
||||
.opcode = PDS_FWCTL_CMD_RPC,
|
||||
.flags = PDS_FWCTL_RPC_IND_REQ | PDS_FWCTL_RPC_IND_RESP,
|
||||
.flags = cpu_to_le16(PDS_FWCTL_RPC_IND_REQ | PDS_FWCTL_RPC_IND_RESP),
|
||||
.ep = cpu_to_le32(rpc->in.ep),
|
||||
.op = cpu_to_le32(rpc->in.op),
|
||||
.req_pa = cpu_to_le64(in_payload_dma_addr),
|
||||
|
||||
@@ -2879,7 +2879,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)
|
||||
* output-only, but if there is then not even a .set() operation it
|
||||
* is pretty tricky to drive the output line.
|
||||
*/
|
||||
if (!guard.gc->set && !guard.gc->direction_output) {
|
||||
if (!guard.gc->set && !guard.gc->set_rv && !guard.gc->direction_output) {
|
||||
gpiod_warn(desc,
|
||||
"%s: missing set() and direction_output() operations\n",
|
||||
__func__);
|
||||
|
||||
@@ -1123,6 +1123,7 @@ struct amdgpu_device {
|
||||
bool in_s3;
|
||||
bool in_s4;
|
||||
bool in_s0ix;
|
||||
suspend_state_t last_suspend_state;
|
||||
|
||||
enum pp_mp1_state mp1_state;
|
||||
struct amdgpu_doorbell_index doorbell_index;
|
||||
|
||||
@@ -3510,6 +3510,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
||||
amdgpu_device_mem_scratch_fini(adev);
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
amdgpu_seq64_fini(adev);
|
||||
amdgpu_doorbell_fini(adev);
|
||||
}
|
||||
if (adev->ip_blocks[i].version->funcs->sw_fini) {
|
||||
r = adev->ip_blocks[i].version->funcs->sw_fini(&adev->ip_blocks[i]);
|
||||
@@ -4858,7 +4859,6 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
||||
|
||||
iounmap(adev->rmmio);
|
||||
adev->rmmio = NULL;
|
||||
amdgpu_doorbell_fini(adev);
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
|
||||
@@ -2548,8 +2548,20 @@ static int amdgpu_pmops_suspend(struct device *dev)
|
||||
adev->in_s0ix = true;
|
||||
else if (amdgpu_acpi_is_s3_active(adev))
|
||||
adev->in_s3 = true;
|
||||
if (!adev->in_s0ix && !adev->in_s3)
|
||||
if (!adev->in_s0ix && !adev->in_s3) {
|
||||
/* don't allow going deep first time followed by s2idle the next time */
|
||||
if (adev->last_suspend_state != PM_SUSPEND_ON &&
|
||||
adev->last_suspend_state != pm_suspend_target_state) {
|
||||
drm_err_once(drm_dev, "Unsupported suspend state %d\n",
|
||||
pm_suspend_target_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* cache the state last used for suspend */
|
||||
adev->last_suspend_state = pm_suspend_target_state;
|
||||
|
||||
return amdgpu_device_suspend(drm_dev, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1438,9 +1438,11 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
struct drm_sched_entity entity;
|
||||
static atomic_t counter;
|
||||
struct dma_fence *f;
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
void *owner;
|
||||
int i, r;
|
||||
|
||||
/* Initialize the scheduler entity */
|
||||
@@ -1451,9 +1453,15 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, &entity, NULL,
|
||||
64, 0,
|
||||
&job);
|
||||
/*
|
||||
* Use some unique dummy value as the owner to make sure we execute
|
||||
* the cleaner shader on each submission. The value just need to change
|
||||
* for each submission and is otherwise meaningless.
|
||||
*/
|
||||
owner = (void *)(unsigned long)atomic_inc_return(&counter);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner,
|
||||
64, 0, &job);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
||||
@@ -6114,7 +6114,7 @@ static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, mmCP_PFP_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0);
|
||||
@@ -6192,7 +6192,7 @@ static int gfx_v10_0_cp_gfx_load_ce_microcode(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, mmCP_CE_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_CE_IC_BASE_CNTL, VMID, 0);
|
||||
@@ -6269,7 +6269,7 @@ static int gfx_v10_0_cp_gfx_load_me_microcode(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, mmCP_ME_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0);
|
||||
@@ -6644,7 +6644,7 @@ static int gfx_v10_0_cp_compute_load_microcode(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, mmCP_CPC_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
|
||||
|
||||
@@ -2428,7 +2428,7 @@ static int gfx_v11_0_config_me_cache(struct amdgpu_device *adev, uint64_t addr)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regCP_ME_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0);
|
||||
@@ -2472,7 +2472,7 @@ static int gfx_v11_0_config_pfp_cache(struct amdgpu_device *adev, uint64_t addr)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0);
|
||||
@@ -2517,7 +2517,7 @@ static int gfx_v11_0_config_mec_cache(struct amdgpu_device *adev, uint64_t addr)
|
||||
}
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
|
||||
@@ -3153,7 +3153,7 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
|
||||
amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj);
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO,
|
||||
lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr));
|
||||
@@ -3371,7 +3371,7 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
|
||||
amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj);
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO,
|
||||
lower_32_bits(adev->gfx.me.me_fw_gpu_addr));
|
||||
@@ -4541,7 +4541,7 @@ static int gfx_v11_0_gfxhub_enable(struct amdgpu_device *adev)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
@@ -2324,7 +2324,7 @@ static int gfx_v12_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
|
||||
amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj);
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO,
|
||||
lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr));
|
||||
@@ -2468,7 +2468,7 @@ static int gfx_v12_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
|
||||
amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj);
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO,
|
||||
lower_32_bits(adev->gfx.me.me_fw_gpu_addr));
|
||||
@@ -3426,7 +3426,7 @@ static int gfx_v12_0_gfxhub_enable(struct amdgpu_device *adev)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
@@ -268,7 +268,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
|
||||
|
||||
/* flush hdp cache */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
/* This is necessary for SRIOV as well as for GFXOFF to function
|
||||
* properly under bare metal
|
||||
@@ -969,7 +969,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
|
||||
adev->hdp.funcs->init_registers(adev);
|
||||
|
||||
/* Flush HDP after it is initialized */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
@@ -229,7 +229,7 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
|
||||
|
||||
/* flush hdp cache */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
/* This is necessary for SRIOV as well as for GFXOFF to function
|
||||
* properly under bare metal
|
||||
@@ -899,7 +899,7 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device *adev)
|
||||
return r;
|
||||
|
||||
/* Flush HDP after it is initialized */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
@@ -297,7 +297,7 @@ static void gmc_v12_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
return;
|
||||
|
||||
/* flush hdp cache */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
/* This is necessary for SRIOV as well as for GFXOFF to function
|
||||
* properly under bare metal
|
||||
@@ -881,7 +881,7 @@ static int gmc_v12_0_gart_enable(struct amdgpu_device *adev)
|
||||
return r;
|
||||
|
||||
/* Flush HDP after it is initialized */
|
||||
adev->hdp.funcs->flush_hdp(adev, NULL);
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user