pci-sim: Add local validation tooling
The pci-sim module is developed out of tree, but it needs to keep following kernel coding conventions as it grows. Developers currently have to know which kernel tools to run and which warnings are expected for this module. Add local validation support for pci-sim. This includes a kernel clang-format baseline, a vendored checkpatch copy with a pci-sim-specific --no-spelling option, and lint and build-test Makefile targets. Spelling remains owned by the repository pre-commit codespell hook. Normalize the existing pci-sim C sources with the kernel clang-format configuration and clean up the current checkpatch baseline where practical. The remaining ignored checkpatch types are limited to clang-format line wrapping, the isolated out-of-tree compatibility header, and the Makefile path list used by the lint target. Document the expected developer workflow so future pci-sim changes can be checked consistently. Assisted-By: pi gpt-5.5 Change-Id: Ic4183133157000bf5bc32e08cc78cc7e3377a648 Signed-off-by: Sean Mooney <work@seanmooney.info>
This commit is contained in:
14 files changed
+9275
-239
No files matched your search
@@ -45,6 +45,7 @@ repos:
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: ['--ignore-words=doc/dictionary.txt']
|
||||
exclude: ^pci-sim/tools/checkpatch\.pl$
|
||||
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
||||
rev: v1.0.0
|
||||
hooks:
|
||||
|
||||
@@ -0,0 +1,805 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# clang-format configuration file. Intended for clang-format >= 11.
|
||||
#
|
||||
# For more information, see:
|
||||
#
|
||||
# Documentation/dev-tools/clang-format.rst
|
||||
# https://clang.llvm.org/docs/ClangFormat.html
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
#
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: false
|
||||
|
||||
# Taken from:
|
||||
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ tools/ \
|
||||
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
|
||||
# | LC_ALL=C sort -u
|
||||
ForEachMacros:
|
||||
- '__ata_qc_for_each'
|
||||
- '__bio_for_each_bvec'
|
||||
- '__bio_for_each_segment'
|
||||
- '__evlist__for_each_entry'
|
||||
- '__evlist__for_each_entry_continue'
|
||||
- '__evlist__for_each_entry_from'
|
||||
- '__evlist__for_each_entry_reverse'
|
||||
- '__evlist__for_each_entry_safe'
|
||||
- '__for_each_mem_range'
|
||||
- '__for_each_mem_range_rev'
|
||||
- '__for_each_thread'
|
||||
- '__hlist_for_each_rcu'
|
||||
- '__map__for_each_symbol_by_name'
|
||||
- '__pci_bus_for_each_res0'
|
||||
- '__pci_bus_for_each_res1'
|
||||
- '__pci_dev_for_each_res0'
|
||||
- '__pci_dev_for_each_res1'
|
||||
- '__perf_evlist__for_each_entry'
|
||||
- '__perf_evlist__for_each_entry_reverse'
|
||||
- '__perf_evlist__for_each_entry_safe'
|
||||
- '__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'
|
||||
- 'ata_qc_for_each'
|
||||
- 'ata_qc_for_each_raw'
|
||||
- 'ata_qc_for_each_with_internal'
|
||||
- 'ax25_for_each'
|
||||
- 'ax25_uid_for_each'
|
||||
- 'bio_for_each_bvec'
|
||||
- 'bio_for_each_bvec_all'
|
||||
- 'bio_for_each_folio_all'
|
||||
- 'bio_for_each_integrity_vec'
|
||||
- 'bio_for_each_segment'
|
||||
- 'bio_for_each_segment_all'
|
||||
- 'bio_list_for_each'
|
||||
- 'bip_for_each_vec'
|
||||
- 'bond_for_each_slave'
|
||||
- 'bond_for_each_slave_rcu'
|
||||
- 'bpf_for_each'
|
||||
- 'bpf_for_each_reg_in_vstate'
|
||||
- 'bpf_for_each_reg_in_vstate_mask'
|
||||
- 'bpf_for_each_spilled_reg'
|
||||
- 'bpf_object__for_each_map'
|
||||
- 'bpf_object__for_each_program'
|
||||
- 'btree_for_each_safe128'
|
||||
- 'btree_for_each_safe32'
|
||||
- 'btree_for_each_safe64'
|
||||
- 'btree_for_each_safel'
|
||||
- 'card_for_each_dev'
|
||||
- 'cgroup_taskset_for_each'
|
||||
- 'cgroup_taskset_for_each_leader'
|
||||
- 'cpu_aggr_map__for_each_idx'
|
||||
- 'cpufreq_for_each_efficient_entry_idx'
|
||||
- 'cpufreq_for_each_entry'
|
||||
- 'cpufreq_for_each_entry_idx'
|
||||
- 'cpufreq_for_each_valid_entry'
|
||||
- 'cpufreq_for_each_valid_entry_idx'
|
||||
- 'css_for_each_child'
|
||||
- 'css_for_each_descendant_post'
|
||||
- 'css_for_each_descendant_pre'
|
||||
- 'damon_for_each_region'
|
||||
- 'damon_for_each_region_from'
|
||||
- 'damon_for_each_region_safe'
|
||||
- 'damon_for_each_scheme'
|
||||
- 'damon_for_each_scheme_safe'
|
||||
- 'damon_for_each_target'
|
||||
- 'damon_for_each_target_safe'
|
||||
- 'damos_for_each_core_filter'
|
||||
- 'damos_for_each_core_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'
|
||||
- 'dma_fence_chain_for_each'
|
||||
- 'dma_fence_unwrap_for_each'
|
||||
- 'dma_resv_for_each_fence'
|
||||
- 'dma_resv_for_each_fence_unlocked'
|
||||
- 'do_for_each_ftrace_op'
|
||||
- 'drm_atomic_crtc_for_each_plane'
|
||||
- 'drm_atomic_crtc_state_for_each_plane'
|
||||
- 'drm_atomic_crtc_state_for_each_plane_state'
|
||||
- 'drm_atomic_for_each_plane_damage'
|
||||
- 'drm_client_for_each_connector_iter'
|
||||
- 'drm_client_for_each_modeset'
|
||||
- 'drm_connector_for_each_possible_encoder'
|
||||
- 'drm_exec_for_each_locked_object'
|
||||
- 'drm_exec_for_each_locked_object_reverse'
|
||||
- 'drm_for_each_bridge_in_chain_scoped'
|
||||
- 'drm_for_each_connector_iter'
|
||||
- 'drm_for_each_crtc'
|
||||
- 'drm_for_each_crtc_reverse'
|
||||
- 'drm_for_each_encoder'
|
||||
- 'drm_for_each_encoder_mask'
|
||||
- 'drm_for_each_fb'
|
||||
- 'drm_for_each_legacy_plane'
|
||||
- 'drm_for_each_plane'
|
||||
- 'drm_for_each_plane_mask'
|
||||
- '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'
|
||||
- 'drm_gpuva_for_each_op_safe'
|
||||
- 'drm_gpuvm_bo_for_each_va'
|
||||
- 'drm_gpuvm_bo_for_each_va_safe'
|
||||
- 'drm_gpuvm_for_each_va'
|
||||
- 'drm_gpuvm_for_each_va_range'
|
||||
- 'drm_gpuvm_for_each_va_range_safe'
|
||||
- 'drm_gpuvm_for_each_va_safe'
|
||||
- 'drm_mm_for_each_hole'
|
||||
- 'drm_mm_for_each_node'
|
||||
- 'drm_mm_for_each_node_in_range'
|
||||
- 'drm_mm_for_each_node_safe'
|
||||
- 'dsa_switch_for_each_available_port'
|
||||
- 'dsa_switch_for_each_cpu_port'
|
||||
- 'dsa_switch_for_each_cpu_port_continue_reverse'
|
||||
- 'dsa_switch_for_each_port'
|
||||
- 'dsa_switch_for_each_port_continue_reverse'
|
||||
- 'dsa_switch_for_each_port_safe'
|
||||
- 'dsa_switch_for_each_user_port'
|
||||
- 'dsa_switch_for_each_user_port_continue_reverse'
|
||||
- 'dsa_tree_for_each_cpu_port'
|
||||
- 'dsa_tree_for_each_user_port'
|
||||
- 'dsa_tree_for_each_user_port_continue_reverse'
|
||||
- 'dso__for_each_symbol'
|
||||
- 'elf_hash_for_each_possible'
|
||||
- 'elf_symtab__for_each_symbol'
|
||||
- 'evlist__for_each_cpu'
|
||||
- 'evlist__for_each_entry'
|
||||
- 'evlist__for_each_entry_continue'
|
||||
- 'evlist__for_each_entry_from'
|
||||
- 'evlist__for_each_entry_reverse'
|
||||
- 'evlist__for_each_entry_safe'
|
||||
- 'flow_action_for_each'
|
||||
- 'for_each_acpi_consumer_dev'
|
||||
- 'for_each_acpi_dev_match'
|
||||
- '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'
|
||||
- 'for_each_available_child_of_node_scoped'
|
||||
- 'for_each_bench'
|
||||
- 'for_each_bio'
|
||||
- 'for_each_board_func_rsrc'
|
||||
- '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'
|
||||
- 'for_each_card_dapms'
|
||||
- 'for_each_card_pre_auxs'
|
||||
- 'for_each_card_prelinks'
|
||||
- 'for_each_card_rtds'
|
||||
- 'for_each_card_rtds_safe'
|
||||
- 'for_each_card_widgets'
|
||||
- 'for_each_card_widgets_safe'
|
||||
- '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'
|
||||
- 'for_each_clear_bitrange_from'
|
||||
- 'for_each_cmd'
|
||||
- 'for_each_cmsghdr'
|
||||
- 'for_each_collection'
|
||||
- 'for_each_comp_order'
|
||||
- 'for_each_compatible_node'
|
||||
- 'for_each_component_dais'
|
||||
- 'for_each_component_dais_safe'
|
||||
- 'for_each_conduit'
|
||||
- 'for_each_console'
|
||||
- 'for_each_console_srcu'
|
||||
- 'for_each_cpu'
|
||||
- 'for_each_cpu_and'
|
||||
- 'for_each_cpu_andnot'
|
||||
- 'for_each_cpu_from'
|
||||
- 'for_each_cpu_or'
|
||||
- 'for_each_cpu_wrap'
|
||||
- 'for_each_dapm_widgets'
|
||||
- 'for_each_dedup_cand'
|
||||
- 'for_each_dev_addr'
|
||||
- 'for_each_dev_scope'
|
||||
- 'for_each_dma_cap_mask'
|
||||
- 'for_each_dpcm_be'
|
||||
- 'for_each_dpcm_be_rollback'
|
||||
- 'for_each_dpcm_be_safe'
|
||||
- 'for_each_dpcm_fe'
|
||||
- 'for_each_drhd_unit'
|
||||
- 'for_each_dss_dev'
|
||||
- 'for_each_efi_memory_desc'
|
||||
- 'for_each_efi_memory_desc_in_map'
|
||||
- 'for_each_element'
|
||||
- 'for_each_element_extid'
|
||||
- 'for_each_element_id'
|
||||
- 'for_each_enabled_cpu'
|
||||
- 'for_each_endpoint_of_node'
|
||||
- 'for_each_event'
|
||||
- 'for_each_event_tps'
|
||||
- 'for_each_evictable_lru'
|
||||
- 'for_each_fib6_node_rt_rcu'
|
||||
- 'for_each_fib6_walker_rt'
|
||||
- 'for_each_file_lock'
|
||||
- 'for_each_free_mem_range'
|
||||
- 'for_each_free_mem_range_reverse'
|
||||
- 'for_each_func_rsrc'
|
||||
- 'for_each_gpiochip_node'
|
||||
- 'for_each_group_evsel'
|
||||
- 'for_each_group_evsel_head'
|
||||
- 'for_each_group_member'
|
||||
- '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'
|
||||
- 'for_each_insn_op_loc'
|
||||
- 'for_each_insn_prefix'
|
||||
- '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'
|
||||
- 'for_each_link_codecs'
|
||||
- 'for_each_link_cpus'
|
||||
- 'for_each_link_platforms'
|
||||
- 'for_each_lru'
|
||||
- 'for_each_matching_node'
|
||||
- 'for_each_matching_node_and_match'
|
||||
- 'for_each_media_entity_data_link'
|
||||
- 'for_each_mem_pfn_range'
|
||||
- 'for_each_mem_range'
|
||||
- 'for_each_mem_range_rev'
|
||||
- 'for_each_mem_region'
|
||||
- 'for_each_member'
|
||||
- 'for_each_memory'
|
||||
- 'for_each_migratetype_order'
|
||||
- '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'
|
||||
- 'for_each_netdev'
|
||||
- 'for_each_netdev_continue'
|
||||
- 'for_each_netdev_continue_rcu'
|
||||
- 'for_each_netdev_continue_reverse'
|
||||
- 'for_each_netdev_dump'
|
||||
- 'for_each_netdev_feature'
|
||||
- 'for_each_netdev_in_bond_rcu'
|
||||
- 'for_each_netdev_rcu'
|
||||
- 'for_each_netdev_reverse'
|
||||
- 'for_each_netdev_safe'
|
||||
- 'for_each_new_connector_in_state'
|
||||
- 'for_each_new_crtc_in_state'
|
||||
- 'for_each_new_mst_mgr_in_state'
|
||||
- 'for_each_new_plane_in_state'
|
||||
- 'for_each_new_plane_in_state_reverse'
|
||||
- 'for_each_new_private_obj_in_state'
|
||||
- 'for_each_new_reg'
|
||||
- 'for_each_nhlt_endpoint'
|
||||
- 'for_each_nhlt_endpoint_fmtcfg'
|
||||
- 'for_each_nhlt_fmtcfg'
|
||||
- 'for_each_node'
|
||||
- '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'
|
||||
- 'for_each_nonreserved_multicast_dest_pgid'
|
||||
- 'for_each_numa_hop_mask'
|
||||
- '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'
|
||||
- 'for_each_old_mst_mgr_in_state'
|
||||
- 'for_each_old_plane_in_state'
|
||||
- 'for_each_old_private_obj_in_state'
|
||||
- 'for_each_oldnew_connector_in_state'
|
||||
- 'for_each_oldnew_crtc_in_state'
|
||||
- 'for_each_oldnew_mst_mgr_in_state'
|
||||
- 'for_each_oldnew_plane_in_state'
|
||||
- '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'
|
||||
- 'for_each_pcm_streams'
|
||||
- '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'
|
||||
- 'for_each_process'
|
||||
- 'for_each_process_thread'
|
||||
- 'for_each_prop_codec_conf'
|
||||
- 'for_each_prop_dai_codec'
|
||||
- 'for_each_prop_dai_cpu'
|
||||
- 'for_each_prop_dlc_codecs'
|
||||
- 'for_each_prop_dlc_cpus'
|
||||
- 'for_each_prop_dlc_platforms'
|
||||
- 'for_each_property_of_node'
|
||||
- 'for_each_pt_level_entry'
|
||||
- 'for_each_rdt_resource'
|
||||
- 'for_each_reg'
|
||||
- 'for_each_reg_filtered'
|
||||
- 'for_each_reloc'
|
||||
- 'for_each_reloc_from'
|
||||
- 'for_each_requested_gpio'
|
||||
- 'for_each_requested_gpio_in_range'
|
||||
- 'for_each_reserved_child_of_node'
|
||||
- 'for_each_reserved_mem_range'
|
||||
- 'for_each_reserved_mem_region'
|
||||
- 'for_each_rtd_ch_maps'
|
||||
- 'for_each_rtd_codec_dais'
|
||||
- 'for_each_rtd_components'
|
||||
- 'for_each_rtd_cpu_dais'
|
||||
- 'for_each_rtd_dais'
|
||||
- 'for_each_rtd_dais_reverse'
|
||||
- 'for_each_sband_iftype_data'
|
||||
- 'for_each_script'
|
||||
- 'for_each_sec'
|
||||
- 'for_each_set_bit'
|
||||
- 'for_each_set_bit_from'
|
||||
- 'for_each_set_bit_wrap'
|
||||
- 'for_each_set_bitrange'
|
||||
- 'for_each_set_bitrange_from'
|
||||
- 'for_each_set_clump8'
|
||||
- 'for_each_sg'
|
||||
- 'for_each_sg_dma_page'
|
||||
- 'for_each_sg_page'
|
||||
- 'for_each_sgtable_dma_page'
|
||||
- 'for_each_sgtable_dma_sg'
|
||||
- 'for_each_sgtable_page'
|
||||
- 'for_each_sgtable_sg'
|
||||
- 'for_each_sibling_event'
|
||||
- 'for_each_sta_active_link'
|
||||
- 'for_each_subelement'
|
||||
- 'for_each_subelement_extid'
|
||||
- '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_thread'
|
||||
- 'for_each_token'
|
||||
- 'for_each_unicast_dest_pgid'
|
||||
- 'for_each_valid_link'
|
||||
- 'for_each_vif_active_link'
|
||||
- 'for_each_vma'
|
||||
- 'for_each_vma_range'
|
||||
- 'for_each_vsi'
|
||||
- 'for_each_wakeup_source'
|
||||
- 'for_each_zone'
|
||||
- 'for_each_zone_zonelist'
|
||||
- 'for_each_zone_zonelist_nodemask'
|
||||
- 'func_for_each_insn'
|
||||
- 'fwnode_for_each_available_child_node'
|
||||
- 'fwnode_for_each_child_node'
|
||||
- 'fwnode_for_each_parent_node'
|
||||
- 'fwnode_graph_for_each_endpoint'
|
||||
- 'gadget_for_each_ep'
|
||||
- 'genradix_for_each'
|
||||
- 'genradix_for_each_from'
|
||||
- 'genradix_for_each_reverse'
|
||||
- 'hash_for_each'
|
||||
- 'hash_for_each_possible'
|
||||
- 'hash_for_each_possible_rcu'
|
||||
- 'hash_for_each_possible_rcu_notrace'
|
||||
- 'hash_for_each_possible_safe'
|
||||
- 'hash_for_each_rcu'
|
||||
- 'hash_for_each_safe'
|
||||
- 'hashmap__for_each_entry'
|
||||
- 'hashmap__for_each_entry_safe'
|
||||
- 'hashmap__for_each_key_entry'
|
||||
- 'hashmap__for_each_key_entry_safe'
|
||||
- 'hctx_for_each_ctx'
|
||||
- 'hists__for_each_format'
|
||||
- 'hists__for_each_sort_list'
|
||||
- 'hlist_bl_for_each_entry'
|
||||
- 'hlist_bl_for_each_entry_rcu'
|
||||
- 'hlist_bl_for_each_entry_safe'
|
||||
- 'hlist_for_each'
|
||||
- 'hlist_for_each_entry'
|
||||
- 'hlist_for_each_entry_continue'
|
||||
- 'hlist_for_each_entry_continue_rcu'
|
||||
- 'hlist_for_each_entry_continue_rcu_bh'
|
||||
- 'hlist_for_each_entry_from'
|
||||
- 'hlist_for_each_entry_from_rcu'
|
||||
- 'hlist_for_each_entry_rcu'
|
||||
- 'hlist_for_each_entry_rcu_bh'
|
||||
- 'hlist_for_each_entry_rcu_notrace'
|
||||
- 'hlist_for_each_entry_safe'
|
||||
- 'hlist_for_each_entry_srcu'
|
||||
- 'hlist_for_each_safe'
|
||||
- 'hlist_nulls_for_each_entry'
|
||||
- 'hlist_nulls_for_each_entry_from'
|
||||
- 'hlist_nulls_for_each_entry_rcu'
|
||||
- 'hlist_nulls_for_each_entry_safe'
|
||||
- 'i3c_bus_for_each_i2cdev'
|
||||
- 'i3c_bus_for_each_i3cdev'
|
||||
- 'idr_for_each_entry'
|
||||
- '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'
|
||||
- 'intlist__for_each_entry_safe'
|
||||
- 'kcore_copy__for_each_phdr'
|
||||
- 'key_for_each'
|
||||
- 'key_for_each_safe'
|
||||
- 'klp_for_each_func'
|
||||
- 'klp_for_each_func_safe'
|
||||
- 'klp_for_each_func_static'
|
||||
- 'klp_for_each_object'
|
||||
- 'klp_for_each_object_safe'
|
||||
- 'klp_for_each_object_static'
|
||||
- 'kunit_suite_for_each_test_case'
|
||||
- 'kvm_for_each_memslot'
|
||||
- 'kvm_for_each_memslot_in_gfn_range'
|
||||
- 'kvm_for_each_vcpu'
|
||||
- 'libbpf_nla_for_each_attr'
|
||||
- 'list_for_each'
|
||||
- 'list_for_each_codec'
|
||||
- 'list_for_each_codec_safe'
|
||||
- 'list_for_each_continue'
|
||||
- 'list_for_each_entry'
|
||||
- 'list_for_each_entry_continue'
|
||||
- 'list_for_each_entry_continue_rcu'
|
||||
- 'list_for_each_entry_continue_reverse'
|
||||
- 'list_for_each_entry_from'
|
||||
- 'list_for_each_entry_from_rcu'
|
||||
- 'list_for_each_entry_from_reverse'
|
||||
- 'list_for_each_entry_lockless'
|
||||
- 'list_for_each_entry_rcu'
|
||||
- 'list_for_each_entry_reverse'
|
||||
- 'list_for_each_entry_safe'
|
||||
- 'list_for_each_entry_safe_continue'
|
||||
- 'list_for_each_entry_safe_from'
|
||||
- 'list_for_each_entry_safe_reverse'
|
||||
- 'list_for_each_entry_srcu'
|
||||
- 'list_for_each_from'
|
||||
- 'list_for_each_prev'
|
||||
- 'list_for_each_prev_safe'
|
||||
- 'list_for_each_rcu'
|
||||
- 'list_for_each_safe'
|
||||
- 'llist_for_each'
|
||||
- 'llist_for_each_entry'
|
||||
- 'llist_for_each_entry_safe'
|
||||
- 'llist_for_each_safe'
|
||||
- 'lwq_for_each_safe'
|
||||
- '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'
|
||||
- 'media_device_for_each_link'
|
||||
- 'media_device_for_each_pad'
|
||||
- 'media_entity_for_each_pad'
|
||||
- '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'
|
||||
- 'netdev_for_each_mc_addr'
|
||||
- 'netdev_for_each_synced_mc_addr'
|
||||
- 'netdev_for_each_synced_uc_addr'
|
||||
- 'netdev_for_each_uc_addr'
|
||||
- 'netdev_for_each_upper_dev_rcu'
|
||||
- 'netdev_hw_addr_list_for_each'
|
||||
- 'nft_rule_for_each_expr'
|
||||
- 'nla_for_each_attr'
|
||||
- 'nla_for_each_attr_type'
|
||||
- 'nla_for_each_nested'
|
||||
- 'nla_for_each_nested_type'
|
||||
- 'nlmsg_for_each_attr'
|
||||
- 'nlmsg_for_each_msg'
|
||||
- 'nr_neigh_for_each'
|
||||
- 'nr_neigh_for_each_safe'
|
||||
- 'nr_node_for_each'
|
||||
- 'nr_node_for_each_safe'
|
||||
- 'of_for_each_phandle'
|
||||
- 'of_property_for_each_string'
|
||||
- 'of_property_for_each_u32'
|
||||
- 'pci_bus_for_each_resource'
|
||||
- 'pci_dev_for_each_resource'
|
||||
- 'pcl_for_each_chunk'
|
||||
- 'pcl_for_each_segment'
|
||||
- 'pcm_for_each_format'
|
||||
- 'perf_config_items__for_each_entry'
|
||||
- 'perf_config_sections__for_each_entry'
|
||||
- 'perf_config_set__for_each_entry'
|
||||
- 'perf_cpu_map__for_each_cpu'
|
||||
- 'perf_cpu_map__for_each_cpu_skip_any'
|
||||
- 'perf_cpu_map__for_each_idx'
|
||||
- 'perf_evlist__for_each_entry'
|
||||
- 'perf_evlist__for_each_entry_reverse'
|
||||
- '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'
|
||||
- 'plist_for_each'
|
||||
- 'plist_for_each_continue'
|
||||
- 'plist_for_each_entry'
|
||||
- 'plist_for_each_entry_continue'
|
||||
- 'plist_for_each_entry_safe'
|
||||
- 'plist_for_each_safe'
|
||||
- 'pnp_for_each_card'
|
||||
- 'pnp_for_each_dev'
|
||||
- 'protocol_for_each_card'
|
||||
- 'protocol_for_each_dev'
|
||||
- 'queue_for_each_hw_ctx'
|
||||
- 'radix_tree_for_each_slot'
|
||||
- 'radix_tree_for_each_tagged'
|
||||
- 'rb_for_each'
|
||||
- 'rbtree_postorder_for_each_entry_safe'
|
||||
- 'rdma_for_each_block'
|
||||
- 'rdma_for_each_port'
|
||||
- 'rdma_umem_for_each_dma_block'
|
||||
- 'resource_list_for_each_entry'
|
||||
- 'resource_list_for_each_entry_safe'
|
||||
- 'rhl_for_each_entry_rcu'
|
||||
- 'rhl_for_each_rcu'
|
||||
- 'rht_for_each'
|
||||
- 'rht_for_each_entry'
|
||||
- 'rht_for_each_entry_from'
|
||||
- 'rht_for_each_entry_rcu'
|
||||
- 'rht_for_each_entry_rcu_from'
|
||||
- 'rht_for_each_entry_safe'
|
||||
- 'rht_for_each_from'
|
||||
- 'rht_for_each_rcu'
|
||||
- 'rht_for_each_rcu_from'
|
||||
- 'rq_for_each_bvec'
|
||||
- 'rq_for_each_segment'
|
||||
- 'rq_list_for_each'
|
||||
- 'rq_list_for_each_safe'
|
||||
- 'sample_read_group__for_each'
|
||||
- 'scsi_for_each_prot_sg'
|
||||
- 'scsi_for_each_sg'
|
||||
- 'sctp_for_each_hentry'
|
||||
- 'sctp_skb_for_each'
|
||||
- 'sec_for_each_insn'
|
||||
- 'sec_for_each_insn_continue'
|
||||
- 'sec_for_each_insn_from'
|
||||
- 'sec_for_each_sym'
|
||||
- 'shdma_for_each_chan'
|
||||
- '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'
|
||||
- 'sk_for_each_safe'
|
||||
- 'sk_nulls_for_each'
|
||||
- 'sk_nulls_for_each_from'
|
||||
- 'sk_nulls_for_each_rcu'
|
||||
- 'snd_array_for_each'
|
||||
- 'snd_pcm_group_for_each_entry'
|
||||
- 'snd_soc_dapm_widget_for_each_path'
|
||||
- 'snd_soc_dapm_widget_for_each_path_safe'
|
||||
- 'snd_soc_dapm_widget_for_each_sink_path'
|
||||
- 'snd_soc_dapm_widget_for_each_source_path'
|
||||
- 'sparsebit_for_each_set_range'
|
||||
- 'strlist__for_each_entry'
|
||||
- 'strlist__for_each_entry_safe'
|
||||
- 'sym_for_each_insn'
|
||||
- 'sym_for_each_insn_continue_reverse'
|
||||
- 'symbols__for_each_entry'
|
||||
- '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'
|
||||
- 'v4l2_device_for_each_subdev'
|
||||
- 'v4l2_m2m_for_each_dst_buf'
|
||||
- 'v4l2_m2m_for_each_dst_buf_safe'
|
||||
- 'v4l2_m2m_for_each_src_buf'
|
||||
- 'v4l2_m2m_for_each_src_buf_safe'
|
||||
- 'virtio_device_for_each_vq'
|
||||
- 'vkms_config_for_each_connector'
|
||||
- 'vkms_config_for_each_crtc'
|
||||
- 'vkms_config_for_each_encoder'
|
||||
- 'vkms_config_for_each_plane'
|
||||
- 'vkms_config_connector_for_each_possible_encoder'
|
||||
- 'vkms_config_encoder_for_each_possible_crtc'
|
||||
- 'vkms_config_plane_for_each_possible_crtc'
|
||||
- 'while_for_each_ftrace_op'
|
||||
- 'workloads__for_each'
|
||||
- 'xa_for_each'
|
||||
- 'xa_for_each_marked'
|
||||
- 'xa_for_each_range'
|
||||
- 'xa_for_each_start'
|
||||
- 'xas_for_each'
|
||||
- 'xas_for_each_conflict'
|
||||
- 'xas_for_each_marked'
|
||||
- 'xbc_array_for_each_value'
|
||||
- 'xbc_for_each_key_value'
|
||||
- 'xbc_node_for_each_array_value'
|
||||
- 'xbc_node_for_each_child'
|
||||
- 'xbc_node_for_each_key_value'
|
||||
- 'xbc_node_for_each_subkey'
|
||||
- 'ynl_attr_for_each'
|
||||
- 'ynl_attr_for_each_nested'
|
||||
- 'ynl_attr_for_each_payload'
|
||||
- 'zorro_for_each_dev'
|
||||
- 'zpci_bus_for_each'
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 8
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 8
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
|
||||
# Taken from git's rules
|
||||
PenaltyBreakAssignment: 10
|
||||
PenaltyBreakBeforeFirstCallParameter: 100000
|
||||
PenaltyBreakComment: 10
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakString: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 8
|
||||
UseTab: Always
|
||||
...
|
||||
+47
-4
@@ -10,9 +10,15 @@ fake_pci_sriov-y := \
|
||||
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(CURDIR)
|
||||
PERL ?= perl
|
||||
LINT_BASE ?= origin/master
|
||||
|
||||
.PHONY: all modules clean install modules_install check-kernel-config \
|
||||
test test-loopback test-multi-pf
|
||||
PCI_SIM_FORMAT_FILES := $(wildcard $(PWD)/*.c) $(wildcard $(PWD)/*.h)
|
||||
PCI_SIM_CHECKPATCH_PATHS := *.c *.h Kconfig Makefile *.rst
|
||||
|
||||
.PHONY: all modules clean install modules_install check check-kernel-config \
|
||||
lint lint-checkpatch lint-format lint-build-warnings test test-build \
|
||||
test-host test-loopback test-multi-pf
|
||||
|
||||
all: modules
|
||||
|
||||
@@ -29,9 +35,46 @@ install modules_install:
|
||||
check-kernel-config:
|
||||
../tools/check-kernel-config.sh
|
||||
|
||||
check: lint lint-build-warnings
|
||||
|
||||
lint:
|
||||
@status=0; \
|
||||
$(MAKE) lint-checkpatch || status=$$?; \
|
||||
$(MAKE) lint-format || status=$$?; \
|
||||
exit $$status
|
||||
|
||||
lint-checkpatch:
|
||||
git diff --no-ext-diff $(LINT_BASE) -- $(PCI_SIM_CHECKPATCH_PATHS) | \
|
||||
$(PERL) $(PWD)/tools/checkpatch.pl --no-signoff --strict \
|
||||
--show-types \
|
||||
--ignore OPEN_ENDED_LINE,CONSTANT_COMPARISON \
|
||||
--ignore LINUX_VERSION_CODE,EMBEDDED_FILENAME,FILE_PATH_CHANGES \
|
||||
--no-tree --no-spelling --patch -
|
||||
|
||||
lint-format:
|
||||
@if ! command -v git-clang-format >/dev/null 2>&1; then \
|
||||
echo "git-clang-format is required for incremental format checks"; \
|
||||
exit 1; \
|
||||
fi
|
||||
git clang-format --extensions c,h $(LINT_BASE) -- \
|
||||
$(PCI_SIM_FORMAT_FILES)
|
||||
@if ! git diff --quiet -- $(PCI_SIM_FORMAT_FILES); then \
|
||||
echo "git clang-format updated files; review and include them"; \
|
||||
git diff -- $(PCI_SIM_FORMAT_FILES); \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
lint-build-warnings:
|
||||
$(MAKE) W=1 test-build
|
||||
$(MAKE) clean
|
||||
|
||||
# Non-privileged build validation for CI and local development.
|
||||
test-build: modules
|
||||
|
||||
# Run host-side tests. Requires sudo and a kernel that supports module loading.
|
||||
# Build the module first with 'make modules'.
|
||||
test: test-loopback test-multi-pf
|
||||
test: test-build test-host
|
||||
|
||||
test-host: test-loopback test-multi-pf
|
||||
|
||||
test-loopback:
|
||||
sudo -n python3 $(PWD)/test_pci_sim_loopback.py --reload --unload \
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
Fake PCI SR-IOV VFIO test fixture
|
||||
=================================
|
||||
|
||||
|
||||
+40
-47
@@ -19,7 +19,6 @@
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/xarray.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/tty.h>
|
||||
@@ -39,48 +38,40 @@
|
||||
#include <linux/pci-ecam.h>
|
||||
#endif
|
||||
|
||||
/* =========================================================================
|
||||
* Device identification
|
||||
* ========================================================================= */
|
||||
/* Device identification */
|
||||
|
||||
#define FAKE_PCI_VENDOR_ID 0x1d55
|
||||
#define FAKE_PCI_PF_DEVICE_ID 0x1000
|
||||
#define FAKE_PCI_VF_DEVICE_ID 0x1001
|
||||
#define FAKE_PCI_SERIAL_CLASS 0x070002 /* Serial controller, 16550 */
|
||||
#define FAKE_PCI_VENDOR_CLASS 0xff0000
|
||||
#define FAKE_PCI_SUBSYS_VENDOR FAKE_PCI_VENDOR_ID
|
||||
#define FAKE_PCI_SUBSYS_ID FAKE_PCI_PF_DEVICE_ID
|
||||
#define FAKE_PCI_VENDOR_ID 0x1d55
|
||||
#define FAKE_PCI_PF_DEVICE_ID 0x1000
|
||||
#define FAKE_PCI_VF_DEVICE_ID 0x1001
|
||||
#define FAKE_PCI_SERIAL_CLASS 0x070002 /* Serial controller, 16550 */
|
||||
#define FAKE_PCI_VENDOR_CLASS 0xff0000
|
||||
#define FAKE_PCI_SUBSYS_VENDOR FAKE_PCI_VENDOR_ID
|
||||
#define FAKE_PCI_SUBSYS_ID FAKE_PCI_PF_DEVICE_ID
|
||||
|
||||
/* =========================================================================
|
||||
* SR-IOV / BAR configuration
|
||||
* ========================================================================= */
|
||||
/* SR-IOV / BAR configuration */
|
||||
|
||||
#define MAX_VFS 7
|
||||
#define FAKE_PCI_MAX_HOSTS 16
|
||||
#define SRIOV_CAP_OFFSET 0x100
|
||||
#define PCIE_CAP_OFFSET 0x40
|
||||
#define MAX_VFS 7
|
||||
#define FAKE_PCI_MAX_HOSTS 16
|
||||
#define SRIOV_CAP_OFFSET 0x100
|
||||
#define PCIE_CAP_OFFSET 0x40
|
||||
|
||||
#define BAR0_SIZE 0x1000
|
||||
#define FAKE_PCI_MEM_BASE 0xd0000000ULL
|
||||
#define FAKE_PCI_MEM_64_BASE 0x100000000ULL
|
||||
#define FAKE_PCI_MEM_STRIDE 0x00100000
|
||||
#define FAKE_PCI_MEM_MIN_SIZE (BAR0_SIZE * (MAX_VFS + 1))
|
||||
#define FAKE_PCI_BAR_FLAGS PCI_BASE_ADDRESS_MEM_TYPE_64
|
||||
#define PCI_SIM_VFIO_BAR0_SIZE 0x40000
|
||||
#define PCI_SIM_SGI_IOC3_UART_OFFSET 0x20178
|
||||
#define BAR0_SIZE 0x1000
|
||||
#define FAKE_PCI_MEM_BASE 0xd0000000ULL
|
||||
#define FAKE_PCI_MEM_64_BASE 0x100000000ULL
|
||||
#define FAKE_PCI_MEM_STRIDE 0x00100000
|
||||
#define FAKE_PCI_MEM_MIN_SIZE (BAR0_SIZE * (MAX_VFS + 1))
|
||||
#define FAKE_PCI_BAR_FLAGS PCI_BASE_ADDRESS_MEM_TYPE_64
|
||||
#define PCI_SIM_VFIO_BAR0_SIZE 0x40000
|
||||
#define PCI_SIM_SGI_IOC3_UART_OFFSET 0x20178
|
||||
|
||||
/* =========================================================================
|
||||
* Host-side TTY loopback
|
||||
* ========================================================================= */
|
||||
/* Host-side TTY loopback */
|
||||
|
||||
#define PCI_SIM_TTY_NAME "ttyPCI_SIM"
|
||||
#define PCI_SIM_MAX_TTYS 256
|
||||
#define PCI_SIM_UART_FIFO_SIZE 4096
|
||||
#define PCI_SIM_UART_CHUNK 256
|
||||
#define PCI_SIM_TTY_NAME "ttyPCI_SIM"
|
||||
#define PCI_SIM_MAX_TTYS 256
|
||||
#define PCI_SIM_UART_FIFO_SIZE 4096
|
||||
#define PCI_SIM_UART_CHUNK 256
|
||||
|
||||
/* =========================================================================
|
||||
* Data structures
|
||||
* ========================================================================= */
|
||||
/* Data structures */
|
||||
|
||||
struct fake_pci_device {
|
||||
u8 config_space[4096];
|
||||
@@ -105,11 +96,11 @@ struct fake_pci_host {
|
||||
struct fake_pci_device vfs[MAX_VFS];
|
||||
int num_vfs_enabled;
|
||||
int domain_nr;
|
||||
struct mutex lock;
|
||||
struct mutex lock; /* Protects VF enable/disable state. */
|
||||
};
|
||||
|
||||
struct pci_sim_uart {
|
||||
spinlock_t lock;
|
||||
spinlock_t lock; /* Protects UART registers and FIFO state. */
|
||||
u8 regs[8];
|
||||
u8 fifo[PCI_SIM_UART_FIFO_SIZE];
|
||||
unsigned int head;
|
||||
@@ -125,7 +116,7 @@ struct pci_sim_uart {
|
||||
struct pci_sim_vf_tty {
|
||||
struct pci_dev *pdev;
|
||||
struct tty_port port;
|
||||
struct mutex state_lock;
|
||||
struct mutex state_lock; /* Protects dead flag and tty writes. */
|
||||
struct pci_sim_uart uart;
|
||||
int id;
|
||||
bool dead;
|
||||
@@ -133,13 +124,11 @@ struct pci_sim_vf_tty {
|
||||
|
||||
struct pci_sim_vfio_vf {
|
||||
struct vfio_pci_core_device core;
|
||||
struct mutex lock;
|
||||
struct mutex lock; /* Serializes VFIO BAR0 access. */
|
||||
struct pci_sim_uart uart;
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* Cross-file globals (defined in the owning .c, declared extern here)
|
||||
* ========================================================================= */
|
||||
/* Cross-file globals (defined in the owning .c, declared extern here) */
|
||||
|
||||
/* fake_pci_sriov_core.c */
|
||||
extern struct list_head fake_hosts;
|
||||
@@ -155,9 +144,7 @@ extern unsigned long mem_stride;
|
||||
extern struct iommu_device fake_iommu_dev;
|
||||
extern struct platform_device *fake_iommu_pdev;
|
||||
|
||||
/* =========================================================================
|
||||
* Cross-file function declarations
|
||||
* ========================================================================= */
|
||||
/* Cross-file function declarations */
|
||||
|
||||
/* fake_pci_sriov_cfg.c */
|
||||
void init_pf_config_space(struct fake_pci_device *dev);
|
||||
@@ -170,7 +157,8 @@ void pci_sim_tty_unregister_driver(void);
|
||||
/* UART primitives also used by vfio.c */
|
||||
void pci_sim_uart_reset(struct pci_sim_uart *uart);
|
||||
void pci_sim_uart_init(struct pci_sim_uart *uart);
|
||||
size_t pci_sim_uart_write_data(struct pci_sim_uart *uart, const u8 *buf, size_t len);
|
||||
size_t pci_sim_uart_write_data(struct pci_sim_uart *uart, const u8 *buf,
|
||||
size_t len);
|
||||
unsigned int pci_sim_uart_write_room(struct pci_sim_uart *uart);
|
||||
unsigned int pci_sim_uart_chars_in_buffer(struct pci_sim_uart *uart);
|
||||
u8 pci_sim_uart_lsr(struct pci_sim_uart *uart);
|
||||
@@ -184,4 +172,9 @@ extern const struct iommu_ops fake_iommu_ops;
|
||||
/* fake_pci_sriov_cfg.c (pci_ops used by core host-probe) */
|
||||
extern struct pci_ops fake_pci_ops;
|
||||
|
||||
/* PCI drivers registered by core init */
|
||||
extern struct pci_driver fake_pci_pf_driver;
|
||||
extern struct pci_driver pci_sim_vf_driver;
|
||||
extern struct pci_driver pci_sim_vfio_driver;
|
||||
|
||||
#endif /* FAKE_PCI_SRIOV_H */
|
||||
@@ -8,9 +8,7 @@
|
||||
|
||||
#include "fake_pci_sriov.h"
|
||||
|
||||
/* =========================================================================
|
||||
* Config-space byte helpers
|
||||
* ========================================================================= */
|
||||
/* Config-space byte helpers */
|
||||
|
||||
static u16 fake_cfg_read16(const u8 *config, int where)
|
||||
{
|
||||
@@ -67,9 +65,7 @@ static int fake_cfg_write(u8 *config, int where, int size, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Host-lookup helpers (used by iommu.c and pci_ops below)
|
||||
* ========================================================================= */
|
||||
/* Host-lookup helpers (used by iommu.c and pci_ops below) */
|
||||
|
||||
struct fake_pci_host *fake_pci_host_from_domain(int domain)
|
||||
{
|
||||
@@ -85,9 +81,7 @@ struct fake_pci_host *fake_pci_host_from_domain(int domain)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* PCI capability initialisation
|
||||
* ========================================================================= */
|
||||
/* PCI capability initialisation */
|
||||
|
||||
static void fake_pci_set_class(u8 *config, u32 class)
|
||||
{
|
||||
@@ -152,7 +146,7 @@ static int fake_pci_write_bar(u8 *config, int where, u32 val, int base)
|
||||
} else {
|
||||
fake_cfg_write32(config, where,
|
||||
(val & ~(BAR0_SIZE - 1)) |
|
||||
FAKE_PCI_BAR_FLAGS);
|
||||
FAKE_PCI_BAR_FLAGS);
|
||||
}
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
@@ -178,7 +172,8 @@ void init_pf_config_space(struct fake_pci_device *dev)
|
||||
fake_cfg_write16(config, PCI_VENDOR_ID, FAKE_PCI_VENDOR_ID);
|
||||
fake_cfg_write16(config, PCI_DEVICE_ID, FAKE_PCI_PF_DEVICE_ID);
|
||||
fake_cfg_write16(config, PCI_COMMAND,
|
||||
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||
PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER);
|
||||
fake_cfg_write16(config, PCI_STATUS, PCI_STATUS_CAP_LIST);
|
||||
|
||||
config[PCI_REVISION_ID] = 0x01;
|
||||
@@ -188,7 +183,8 @@ void init_pf_config_space(struct fake_pci_device *dev)
|
||||
|
||||
fake_cfg_write32(config, PCI_BASE_ADDRESS_0, FAKE_PCI_BAR_FLAGS);
|
||||
fake_cfg_write32(config, PCI_BASE_ADDRESS_1, 0);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_VENDOR_ID, FAKE_PCI_SUBSYS_VENDOR);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
FAKE_PCI_SUBSYS_VENDOR);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_ID, FAKE_PCI_SUBSYS_ID);
|
||||
|
||||
config[PCI_CAPABILITY_LIST] = PCIE_CAP_OFFSET;
|
||||
@@ -211,18 +207,20 @@ static void init_vf_config_space(struct fake_pci_device *dev, int vf_index)
|
||||
fake_cfg_write16(config, PCI_VENDOR_ID, FAKE_PCI_VENDOR_ID);
|
||||
fake_cfg_write16(config, PCI_DEVICE_ID, FAKE_PCI_VF_DEVICE_ID);
|
||||
fake_cfg_write16(config, PCI_COMMAND,
|
||||
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||
PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
|
||||
PCI_COMMAND_MASTER);
|
||||
fake_cfg_write16(config, PCI_STATUS, PCI_STATUS_CAP_LIST);
|
||||
|
||||
config[PCI_REVISION_ID] = 0x01;
|
||||
fake_pci_set_class(config, vf_serial_class ? FAKE_PCI_SERIAL_CLASS :
|
||||
FAKE_PCI_VENDOR_CLASS);
|
||||
FAKE_PCI_VENDOR_CLASS);
|
||||
config[PCI_CACHE_LINE_SIZE] = 64 / 4;
|
||||
config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
|
||||
|
||||
fake_cfg_write32(config, PCI_BASE_ADDRESS_0, FAKE_PCI_BAR_FLAGS);
|
||||
fake_cfg_write32(config, PCI_BASE_ADDRESS_1, 0);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_VENDOR_ID, FAKE_PCI_SUBSYS_VENDOR);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
FAKE_PCI_SUBSYS_VENDOR);
|
||||
fake_cfg_write16(config, PCI_SUBSYSTEM_ID, FAKE_PCI_SUBSYS_ID);
|
||||
|
||||
config[PCI_CAPABILITY_LIST] = PCIE_CAP_OFFSET;
|
||||
@@ -230,9 +228,7 @@ static void init_vf_config_space(struct fake_pci_device *dev, int vf_index)
|
||||
init_pcie_capability(config, false);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* pci_ops: config-space read/write
|
||||
* ========================================================================= */
|
||||
/* pci_ops: config-space read/write */
|
||||
|
||||
static struct fake_pci_device *get_fake_device(struct fake_pci_host *host,
|
||||
unsigned int devfn)
|
||||
@@ -300,7 +296,7 @@ static bool fake_pci_is_sriov_cfg(int where)
|
||||
{
|
||||
return where >= SRIOV_CAP_OFFSET &&
|
||||
where < SRIOV_CAP_OFFSET + PCI_SRIOV_BAR +
|
||||
PCI_SRIOV_NUM_BARS * 4;
|
||||
PCI_SRIOV_NUM_BARS * 4;
|
||||
}
|
||||
|
||||
static int fake_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
@@ -336,7 +332,8 @@ static int fake_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
|
||||
if (size == 4 && where >= PCI_BASE_ADDRESS_0 &&
|
||||
where < PCI_BASE_ADDRESS_5 + 4) {
|
||||
ret = fake_pci_write_bar(config, where, val, PCI_BASE_ADDRESS_0);
|
||||
ret = fake_pci_write_bar(config, where, val,
|
||||
PCI_BASE_ADDRESS_0);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
@@ -348,8 +345,7 @@ static int fake_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
|
||||
if (size == 4 && !dev->is_vf &&
|
||||
where >= SRIOV_CAP_OFFSET + PCI_SRIOV_BAR &&
|
||||
where < SRIOV_CAP_OFFSET + PCI_SRIOV_BAR +
|
||||
PCI_SRIOV_NUM_BARS * 4) {
|
||||
where < SRIOV_CAP_OFFSET + PCI_SRIOV_BAR + PCI_SRIOV_NUM_BARS * 4) {
|
||||
ret = fake_pci_write_bar(config, where, val,
|
||||
SRIOV_CAP_OFFSET + PCI_SRIOV_BAR);
|
||||
goto out_unlock;
|
||||
@@ -382,13 +378,11 @@ out_unlock:
|
||||
}
|
||||
|
||||
struct pci_ops fake_pci_ops = {
|
||||
.read = fake_pci_read_config,
|
||||
.write = fake_pci_write_config,
|
||||
.read = fake_pci_read_config,
|
||||
.write = fake_pci_write_config,
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* SR-IOV VF enable/disable
|
||||
* ========================================================================= */
|
||||
/* SR-IOV VF enable/disable */
|
||||
|
||||
static void handle_sriov_numvfs_write(struct fake_pci_host *host, u16 num_vfs)
|
||||
{
|
||||
@@ -414,14 +408,13 @@ static void handle_sriov_numvfs_write(struct fake_pci_host *host, u16 num_vfs)
|
||||
}
|
||||
|
||||
host->num_vfs_enabled = num_vfs;
|
||||
fake_cfg_write16(pf_config, SRIOV_CAP_OFFSET + PCI_SRIOV_NUM_VF, num_vfs);
|
||||
fake_cfg_write16(pf_config, SRIOV_CAP_OFFSET + PCI_SRIOV_NUM_VF,
|
||||
num_vfs);
|
||||
|
||||
mutex_unlock(&host->lock);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* PF driver
|
||||
* ========================================================================= */
|
||||
/* PF driver */
|
||||
|
||||
static struct fake_pci_host *fake_pci_host_from_pdev(struct pci_dev *pdev)
|
||||
{
|
||||
@@ -495,14 +488,14 @@ static int fake_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||
|
||||
static const struct pci_device_id fake_pci_pf_ids[] = {
|
||||
{ PCI_DEVICE(FAKE_PCI_VENDOR_ID, FAKE_PCI_PF_DEVICE_ID) },
|
||||
{ }
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, fake_pci_pf_ids);
|
||||
|
||||
struct pci_driver fake_pci_pf_driver = {
|
||||
.name = "fake_pci_sriov_pf",
|
||||
.id_table = fake_pci_pf_ids,
|
||||
.probe = fake_pci_pf_probe,
|
||||
.remove = fake_pci_pf_remove,
|
||||
.name = "fake_pci_sriov_pf",
|
||||
.id_table = fake_pci_pf_ids,
|
||||
.probe = fake_pci_pf_probe,
|
||||
.remove = fake_pci_pf_remove,
|
||||
.sriov_configure = fake_pci_sriov_configure,
|
||||
};
|
||||
@@ -15,21 +15,21 @@
|
||||
*/
|
||||
|
||||
/* iommu_domain_ops.attach_dev gained the previous-domain argument later. */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
|
||||
#if KERNEL_VERSION(6, 15, 0) <= LINUX_VERSION_CODE
|
||||
#define PCI_SIM_IOMMU_ATTACH_HAS_OLD_DOMAIN 1
|
||||
#else
|
||||
#define PCI_SIM_IOMMU_ATTACH_HAS_OLD_DOMAIN 0
|
||||
#endif
|
||||
|
||||
/* iommu_ops.domain_alloc_paging_flags and IOMMU_HWPT_ALLOC_PASID are newer. */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
|
||||
#if KERNEL_VERSION(6, 15, 0) <= LINUX_VERSION_CODE
|
||||
#define PCI_SIM_IOMMU_HAS_DOMAIN_ALLOC_PAGING_FLAGS 1
|
||||
#else
|
||||
#define PCI_SIM_IOMMU_HAS_DOMAIN_ALLOC_PAGING_FLAGS 0
|
||||
#endif
|
||||
|
||||
/* VFIO grew optional region-info and PASID/token callbacks after 6.12. */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
|
||||
#if KERNEL_VERSION(6, 15, 0) <= LINUX_VERSION_CODE
|
||||
#define PCI_SIM_VFIO_HAS_GET_REGION_INFO_CAPS 1
|
||||
#define PCI_SIM_VFIO_HAS_MATCH_TOKEN_UUID 1
|
||||
#define PCI_SIM_VFIO_HAS_PASID_IOAS 1
|
||||
|
||||
@@ -10,55 +10,51 @@
|
||||
|
||||
#include "fake_pci_sriov.h"
|
||||
|
||||
/* =========================================================================
|
||||
* Module parameters
|
||||
* ========================================================================= */
|
||||
/* Module parameters */
|
||||
|
||||
bool vf_serial_class;
|
||||
module_param(vf_serial_class, bool, 0644);
|
||||
MODULE_PARM_DESC(vf_serial_class,
|
||||
"Expose host-visible VFs as PCI serial/16550 class devices instead of vendor-specific");
|
||||
MODULE_PARM_DESC(
|
||||
vf_serial_class,
|
||||
"Expose host-visible VFs as PCI serial/16550 class devices instead of vendor-specific");
|
||||
|
||||
bool vfio_guest_8250_compat = true;
|
||||
module_param(vfio_guest_8250_compat, bool, 0644);
|
||||
MODULE_PARM_DESC(vfio_guest_8250_compat,
|
||||
"Overlay VFIO guest config space with an 8250_pci-compatible SGI IOC3 serial identity");
|
||||
MODULE_PARM_DESC(
|
||||
vfio_guest_8250_compat,
|
||||
"Overlay VFIO guest config space with an 8250_pci-compatible SGI IOC3 serial identity");
|
||||
|
||||
bool vfio_uart_trace;
|
||||
module_param(vfio_uart_trace, bool, 0644);
|
||||
MODULE_PARM_DESC(vfio_uart_trace,
|
||||
"Trace VFIO BAR0 UART register accesses");
|
||||
MODULE_PARM_DESC(vfio_uart_trace, "Trace VFIO BAR0 UART register accesses");
|
||||
|
||||
static int fake_intx_irq;
|
||||
module_param(fake_intx_irq, int, 0644);
|
||||
MODULE_PARM_DESC(fake_intx_irq,
|
||||
"Optional host IRQ number to report for fake PCI INTx routing (0 disables)");
|
||||
MODULE_PARM_DESC(
|
||||
fake_intx_irq,
|
||||
"Optional host IRQ number to report for fake PCI INTx routing (0 disables)");
|
||||
|
||||
static unsigned int num_pfs = 1;
|
||||
module_param(num_pfs, uint, 0444);
|
||||
MODULE_PARM_DESC(num_pfs,
|
||||
"Number of fake SR-IOV PFs to create");
|
||||
MODULE_PARM_DESC(num_pfs, "Number of fake SR-IOV PFs to create");
|
||||
|
||||
static unsigned long mem_base;
|
||||
module_param(mem_base, ulong, 0444);
|
||||
MODULE_PARM_DESC(mem_base,
|
||||
"Fixed fake PCI MMIO window base address (0 chooses automatically)");
|
||||
MODULE_PARM_DESC(
|
||||
mem_base,
|
||||
"Fixed fake PCI MMIO window base address (0 chooses automatically)");
|
||||
|
||||
unsigned long mem_stride = FAKE_PCI_MEM_STRIDE;
|
||||
module_param(mem_stride, ulong, 0444);
|
||||
MODULE_PARM_DESC(mem_stride,
|
||||
"Size and alignment of each fake PCI host MMIO window");
|
||||
|
||||
/* =========================================================================
|
||||
* Global host list (also used by cfg.c and iommu.c)
|
||||
* ========================================================================= */
|
||||
/* Global host list (also used by cfg.c and iommu.c) */
|
||||
|
||||
LIST_HEAD(fake_hosts);
|
||||
DEFINE_MUTEX(fake_hosts_lock);
|
||||
DEFINE_MUTEX(fake_hosts_lock); /* Protects fake_hosts. */
|
||||
|
||||
/* =========================================================================
|
||||
* PCI host bridge helpers
|
||||
* ========================================================================= */
|
||||
/* PCI host bridge helpers */
|
||||
|
||||
static void *fake_pci_host_sysdata(struct fake_pci_host *host)
|
||||
{
|
||||
@@ -101,7 +97,7 @@ static void fake_pci_host_release_mem_resource(struct fake_pci_host *host)
|
||||
}
|
||||
|
||||
static int fake_pci_alloc_mem_resource(struct fake_pci_host *host,
|
||||
resource_size_t stride)
|
||||
resource_size_t stride)
|
||||
{
|
||||
static const struct {
|
||||
resource_size_t start;
|
||||
@@ -125,8 +121,8 @@ static int fake_pci_alloc_mem_resource(struct fake_pci_host *host,
|
||||
host->mem_resource.flags |= IORESOURCE_MEM_64;
|
||||
|
||||
ret = allocate_resource(&iomem_resource, &host->mem_resource,
|
||||
stride, regions[i].start, regions[i].end,
|
||||
stride, NULL, NULL);
|
||||
stride, regions[i].start,
|
||||
regions[i].end, stride, NULL, NULL);
|
||||
if (!ret) {
|
||||
host->mem_resource_registered = true;
|
||||
pr_info("fake_pci: allocated %s MMIO window [%#llx-%#llx]\n",
|
||||
@@ -178,7 +174,8 @@ static int fake_pci_host_init_mem_resource(struct fake_pci_host *host,
|
||||
|
||||
ret = fake_pci_alloc_mem_resource(host, stride);
|
||||
if (ret)
|
||||
pr_err("fake_pci: failed to allocate any MMIO window: %d\n", ret);
|
||||
pr_err("fake_pci: failed to allocate any MMIO window: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -286,14 +283,7 @@ static void fake_pci_remove_all_hosts(void)
|
||||
fake_pci_host_remove(host);
|
||||
}
|
||||
|
||||
/* Forward declarations for drivers registered in init */
|
||||
extern struct pci_driver fake_pci_pf_driver;
|
||||
extern struct pci_driver pci_sim_vf_driver;
|
||||
extern struct pci_driver pci_sim_vfio_driver;
|
||||
|
||||
/* =========================================================================
|
||||
* Module init / exit
|
||||
* ========================================================================= */
|
||||
/* Module init / exit */
|
||||
|
||||
static int __init fake_pci_sriov_init(void)
|
||||
{
|
||||
@@ -316,7 +306,8 @@ static int __init fake_pci_sriov_init(void)
|
||||
fake_iommu_pdev = platform_device_register_full(&pdevinfo);
|
||||
if (IS_ERR(fake_iommu_pdev)) {
|
||||
err = PTR_ERR(fake_iommu_pdev);
|
||||
pr_err("fake_pci: Failed to register IOMMU platform device: %d\n", err);
|
||||
pr_err("fake_pci: Failed to register IOMMU platform device: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -344,13 +335,15 @@ static int __init fake_pci_sriov_init(void)
|
||||
|
||||
err = pci_register_driver(&pci_sim_vfio_driver);
|
||||
if (err) {
|
||||
pr_err("fake_pci: Failed to register VFIO UART driver: %d\n", err);
|
||||
pr_err("fake_pci: Failed to register VFIO UART driver: %d\n",
|
||||
err);
|
||||
goto err_tty;
|
||||
}
|
||||
|
||||
err = pci_register_driver(&pci_sim_vf_driver);
|
||||
if (err) {
|
||||
pr_err("fake_pci: Failed to register VF loopback driver: %d\n", err);
|
||||
pr_err("fake_pci: Failed to register VF loopback driver: %d\n",
|
||||
err);
|
||||
goto err_vfio_driver;
|
||||
}
|
||||
|
||||
@@ -387,7 +380,8 @@ static int __init fake_pci_sriov_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("fake_pci: Module loaded successfully with %u PF(s)\n", num_pfs);
|
||||
pr_info("fake_pci: Module loaded successfully with %u PF(s)\n",
|
||||
num_pfs);
|
||||
pr_info("fake_pci: Use 'echo N > /sys/bus/pci/devices/.../sriov_numvfs' to enable VFs\n");
|
||||
|
||||
return 0;
|
||||
@@ -433,4 +427,5 @@ module_exit(fake_pci_sriov_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("OpenStack Contributors");
|
||||
MODULE_DESCRIPTION("Fake PCI Host Controller with Software IOMMU for SR-IOV Testing");
|
||||
MODULE_DESCRIPTION(
|
||||
"Fake PCI Host Controller with Software IOMMU for SR-IOV Testing");
|
||||
@@ -24,9 +24,10 @@ static struct fake_iommu_domain *to_fake_domain(struct iommu_domain *dom)
|
||||
|
||||
static int fake_domain_attach(struct iommu_domain *domain, struct device *dev
|
||||
#if PCI_SIM_IOMMU_ATTACH_HAS_OLD_DOMAIN
|
||||
, struct iommu_domain *old
|
||||
,
|
||||
struct iommu_domain *old
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
dev_dbg(dev, "fake_iommu: attached to domain type %u\n", domain->type);
|
||||
return 0;
|
||||
@@ -129,11 +130,11 @@ static phys_addr_t fake_domain_iova_to_phys(struct iommu_domain *domain,
|
||||
}
|
||||
|
||||
static const struct iommu_domain_ops fake_paging_domain_ops = {
|
||||
.attach_dev = fake_domain_attach,
|
||||
.free = fake_domain_free_paging,
|
||||
.map_pages = fake_domain_map_pages,
|
||||
.unmap_pages = fake_domain_unmap_pages,
|
||||
.iova_to_phys = fake_domain_iova_to_phys,
|
||||
.attach_dev = fake_domain_attach,
|
||||
.free = fake_domain_free_paging,
|
||||
.map_pages = fake_domain_map_pages,
|
||||
.unmap_pages = fake_domain_unmap_pages,
|
||||
.iova_to_phys = fake_domain_iova_to_phys,
|
||||
};
|
||||
|
||||
static struct iommu_domain *fake_domain_alloc_paging_common(void)
|
||||
@@ -227,16 +228,16 @@ static struct iommu_group *fake_iommu_device_group(struct device *dev)
|
||||
}
|
||||
|
||||
const struct iommu_ops fake_iommu_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.default_domain = &fake_blocking_domain,
|
||||
.blocked_domain = &fake_blocking_domain,
|
||||
.capable = fake_iommu_capable,
|
||||
.probe_device = fake_iommu_probe_device,
|
||||
.release_device = fake_iommu_release_device,
|
||||
.device_group = fake_iommu_device_group,
|
||||
.owner = THIS_MODULE,
|
||||
.default_domain = &fake_blocking_domain,
|
||||
.blocked_domain = &fake_blocking_domain,
|
||||
.capable = fake_iommu_capable,
|
||||
.probe_device = fake_iommu_probe_device,
|
||||
.release_device = fake_iommu_release_device,
|
||||
.device_group = fake_iommu_device_group,
|
||||
#if PCI_SIM_IOMMU_HAS_DOMAIN_ALLOC_PAGING_FLAGS
|
||||
.domain_alloc_paging_flags = fake_domain_alloc_paging_flags,
|
||||
.domain_alloc_paging_flags = fake_domain_alloc_paging_flags,
|
||||
#else
|
||||
.domain_alloc_paging = fake_domain_alloc_paging,
|
||||
.domain_alloc_paging = fake_domain_alloc_paging,
|
||||
#endif
|
||||
};
|
||||
@@ -11,13 +11,11 @@
|
||||
|
||||
#include "fake_pci_sriov.h"
|
||||
|
||||
static DEFINE_IDR(pci_sim_tty_idr);
|
||||
static DEFINE_MUTEX(pci_sim_tty_idr_lock);
|
||||
static DEFINE_XARRAY_ALLOC(pci_sim_tty_xa);
|
||||
static DEFINE_MUTEX(pci_sim_tty_xa_lock); /* Serializes TTY ID lookup/removal. */
|
||||
static struct tty_driver *pci_sim_tty_driver;
|
||||
|
||||
/* =========================================================================
|
||||
* 16550-compatible UART emulation
|
||||
* ========================================================================= */
|
||||
/* 16550-compatible UART emulation */
|
||||
|
||||
void pci_sim_uart_reset(struct pci_sim_uart *uart)
|
||||
{
|
||||
@@ -49,8 +47,8 @@ static unsigned int pci_sim_uart_space_locked(struct pci_sim_uart *uart)
|
||||
return PCI_SIM_UART_FIFO_SIZE - uart->count;
|
||||
}
|
||||
|
||||
size_t pci_sim_uart_write_data(struct pci_sim_uart *uart,
|
||||
const u8 *buf, size_t len)
|
||||
size_t pci_sim_uart_write_data(struct pci_sim_uart *uart, const u8 *buf,
|
||||
size_t len)
|
||||
{
|
||||
unsigned long flags;
|
||||
size_t copied, i;
|
||||
@@ -289,9 +287,7 @@ void pci_sim_uart_write_reg(struct pci_sim_uart *uart, u8 reg, u8 val)
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* VF TTY loopback helper
|
||||
* ========================================================================= */
|
||||
/* VF TTY loopback helper */
|
||||
|
||||
static void pci_sim_vf_flush_to_tty(struct pci_sim_vf_tty *vf)
|
||||
{
|
||||
@@ -306,7 +302,8 @@ static void pci_sim_vf_flush_to_tty(struct pci_sim_vf_tty *vf)
|
||||
break;
|
||||
|
||||
pending = pci_sim_uart_peek_data(&vf->uart, buf,
|
||||
min_t(size_t, sizeof(buf), room));
|
||||
min_t(size_t, sizeof(buf),
|
||||
room));
|
||||
if (!pending)
|
||||
break;
|
||||
|
||||
@@ -325,9 +322,7 @@ static void pci_sim_vf_flush_to_tty(struct pci_sim_vf_tty *vf)
|
||||
tty_flip_buffer_push(&vf->port);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* TTY driver operations
|
||||
* ========================================================================= */
|
||||
/* TTY driver operations */
|
||||
|
||||
static int pci_sim_tty_install(struct tty_driver *driver,
|
||||
struct tty_struct *tty)
|
||||
@@ -336,13 +331,13 @@ static int pci_sim_tty_install(struct tty_driver *driver,
|
||||
struct tty_port *port;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&pci_sim_tty_idr_lock);
|
||||
vf = idr_find(&pci_sim_tty_idr, tty->index);
|
||||
mutex_lock(&pci_sim_tty_xa_lock);
|
||||
vf = xa_load(&pci_sim_tty_xa, tty->index);
|
||||
if (vf)
|
||||
port = tty_port_get(&vf->port);
|
||||
else
|
||||
port = NULL;
|
||||
mutex_unlock(&pci_sim_tty_idr_lock);
|
||||
mutex_unlock(&pci_sim_tty_xa_lock);
|
||||
|
||||
if (!port)
|
||||
return -ENODEV;
|
||||
@@ -427,25 +422,25 @@ static void pci_sim_tty_hangup(struct tty_struct *tty)
|
||||
}
|
||||
|
||||
static const struct tty_operations pci_sim_tty_ops = {
|
||||
.install = pci_sim_tty_install,
|
||||
.open = pci_sim_tty_open,
|
||||
.close = pci_sim_tty_close,
|
||||
.write = pci_sim_tty_write,
|
||||
.write_room = pci_sim_tty_write_room,
|
||||
.install = pci_sim_tty_install,
|
||||
.open = pci_sim_tty_open,
|
||||
.close = pci_sim_tty_close,
|
||||
.write = pci_sim_tty_write,
|
||||
.write_room = pci_sim_tty_write_room,
|
||||
.chars_in_buffer = pci_sim_tty_chars_in_buffer,
|
||||
.hangup = pci_sim_tty_hangup,
|
||||
.cleanup = pci_sim_tty_cleanup,
|
||||
.hangup = pci_sim_tty_hangup,
|
||||
.cleanup = pci_sim_tty_cleanup,
|
||||
};
|
||||
|
||||
static void pci_sim_tty_destruct_port(struct tty_port *port)
|
||||
{
|
||||
struct pci_sim_vf_tty *vf = container_of(port, struct pci_sim_vf_tty,
|
||||
port);
|
||||
struct pci_sim_vf_tty *vf =
|
||||
container_of(port, struct pci_sim_vf_tty, port);
|
||||
|
||||
mutex_lock(&pci_sim_tty_idr_lock);
|
||||
mutex_lock(&pci_sim_tty_xa_lock);
|
||||
if (vf->id >= 0)
|
||||
idr_remove(&pci_sim_tty_idr, vf->id);
|
||||
mutex_unlock(&pci_sim_tty_idr_lock);
|
||||
xa_erase(&pci_sim_tty_xa, vf->id);
|
||||
mutex_unlock(&pci_sim_tty_xa_lock);
|
||||
|
||||
kfree(vf);
|
||||
}
|
||||
@@ -454,15 +449,14 @@ static const struct tty_port_operations pci_sim_tty_port_ops = {
|
||||
.destruct = pci_sim_tty_destruct_port,
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* VF PCI driver
|
||||
* ========================================================================= */
|
||||
/* VF PCI driver */
|
||||
|
||||
static int pci_sim_vf_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct pci_sim_vf_tty *vf;
|
||||
struct device *tty_dev;
|
||||
u32 tty_id;
|
||||
int ret;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
@@ -480,12 +474,13 @@ static int pci_sim_vf_probe(struct pci_dev *pdev,
|
||||
mutex_init(&vf->state_lock);
|
||||
pci_sim_uart_init(&vf->uart);
|
||||
|
||||
mutex_lock(&pci_sim_tty_idr_lock);
|
||||
ret = idr_alloc(&pci_sim_tty_idr, vf, 0, PCI_SIM_MAX_TTYS, GFP_KERNEL);
|
||||
mutex_unlock(&pci_sim_tty_idr_lock);
|
||||
if (ret < 0)
|
||||
mutex_lock(&pci_sim_tty_xa_lock);
|
||||
ret = xa_alloc(&pci_sim_tty_xa, &tty_id, vf,
|
||||
XA_LIMIT(0, PCI_SIM_MAX_TTYS - 1), GFP_KERNEL);
|
||||
mutex_unlock(&pci_sim_tty_xa_lock);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
vf->id = ret;
|
||||
vf->id = tty_id;
|
||||
|
||||
tty_port_init(&vf->port);
|
||||
vf->port.ops = &pci_sim_tty_port_ops;
|
||||
@@ -498,8 +493,8 @@ static int pci_sim_vf_probe(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, vf);
|
||||
pci_info(pdev, "registered /dev/%s%d, lsr=0x%02x\n",
|
||||
PCI_SIM_TTY_NAME, vf->id, pci_sim_uart_lsr(&vf->uart));
|
||||
pci_info(pdev, "registered /dev/%s%d, lsr=0x%02x\n", PCI_SIM_TTY_NAME,
|
||||
vf->id, pci_sim_uart_lsr(&vf->uart));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -534,27 +529,26 @@ static void pci_sim_vf_remove(struct pci_dev *pdev)
|
||||
|
||||
static const struct pci_device_id pci_sim_vf_ids[] = {
|
||||
{ PCI_DEVICE(FAKE_PCI_VENDOR_ID, FAKE_PCI_VF_DEVICE_ID) },
|
||||
{ }
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pci_sim_vf_ids);
|
||||
|
||||
struct pci_driver pci_sim_vf_driver = {
|
||||
.name = "pci_sim_loopback_vf",
|
||||
.id_table = pci_sim_vf_ids,
|
||||
.probe = pci_sim_vf_probe,
|
||||
.remove = pci_sim_vf_remove,
|
||||
.name = "pci_sim_loopback_vf",
|
||||
.id_table = pci_sim_vf_ids,
|
||||
.probe = pci_sim_vf_probe,
|
||||
.remove = pci_sim_vf_remove,
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* TTY driver registration (called from core init/exit)
|
||||
* ========================================================================= */
|
||||
/* TTY driver registration (called from core init/exit) */
|
||||
|
||||
int pci_sim_tty_register_driver(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pci_sim_tty_driver = tty_alloc_driver(PCI_SIM_MAX_TTYS,
|
||||
TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
|
||||
pci_sim_tty_driver =
|
||||
tty_alloc_driver(PCI_SIM_MAX_TTYS,
|
||||
TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
|
||||
if (IS_ERR(pci_sim_tty_driver))
|
||||
return PTR_ERR(pci_sim_tty_driver);
|
||||
|
||||
@@ -565,8 +559,8 @@ int pci_sim_tty_register_driver(void)
|
||||
pci_sim_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
pci_sim_tty_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
pci_sim_tty_driver->init_termios = tty_std_termios;
|
||||
pci_sim_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD |
|
||||
HUPCL | CLOCAL;
|
||||
pci_sim_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
|
||||
CLOCAL;
|
||||
pci_sim_tty_driver->init_termios.c_lflag &= ~(ECHO | ICANON);
|
||||
pci_sim_tty_driver->init_termios.c_oflag &= ~(OPOST | ONLCR);
|
||||
|
||||
@@ -589,5 +583,5 @@ void pci_sim_tty_unregister_driver(void)
|
||||
tty_unregister_driver(pci_sim_tty_driver);
|
||||
tty_driver_kref_put(pci_sim_tty_driver);
|
||||
pci_sim_tty_driver = NULL;
|
||||
idr_destroy(&pci_sim_tty_idr);
|
||||
xa_destroy(&pci_sim_tty_xa);
|
||||
}
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
static int pci_sim_vfio_open_device(struct vfio_device *core_vdev)
|
||||
{
|
||||
struct pci_sim_vfio_vf *sim = container_of(core_vdev,
|
||||
struct pci_sim_vfio_vf, core.vdev);
|
||||
struct pci_sim_vfio_vf *sim =
|
||||
container_of(core_vdev, struct pci_sim_vfio_vf, core.vdev);
|
||||
int ret;
|
||||
|
||||
ret = vfio_pci_core_enable(&sim->core);
|
||||
@@ -72,14 +72,17 @@ static ssize_t pci_sim_vfio_bar0_rw(struct pci_sim_vfio_vf *sim,
|
||||
|
||||
if (vfio_uart_trace)
|
||||
pr_info("fake_pci: vfio uart W off=0x%llx reg=%u val=0x%02x\n",
|
||||
(unsigned long long)(pos + done), reg, val);
|
||||
(unsigned long long)(pos + done), reg,
|
||||
val);
|
||||
pci_sim_uart_write_reg(&sim->uart, reg, val);
|
||||
} else {
|
||||
if (pci_sim_vfio_bar0_uart_reg(pos + done, ®)) {
|
||||
val = pci_sim_uart_read_reg(&sim->uart, reg);
|
||||
if (vfio_uart_trace)
|
||||
pr_info("fake_pci: vfio uart R off=0x%llx reg=%u val=0x%02x\n",
|
||||
(unsigned long long)(pos + done), reg, val);
|
||||
(unsigned long long)(pos +
|
||||
done),
|
||||
reg, val);
|
||||
} else {
|
||||
val = 0xff;
|
||||
}
|
||||
@@ -95,17 +98,16 @@ static ssize_t pci_sim_vfio_bar0_rw(struct pci_sim_vfio_vf *sim,
|
||||
return done;
|
||||
}
|
||||
|
||||
static int pci_sim_vfio_copy_config_value(char __user *buf,
|
||||
loff_t pos, size_t count,
|
||||
unsigned int reg, const void *val,
|
||||
size_t val_size)
|
||||
static int pci_sim_vfio_copy_config_value(char __user *buf, loff_t pos,
|
||||
size_t count, unsigned int reg,
|
||||
const void *val, size_t val_size)
|
||||
{
|
||||
loff_t copy_offset;
|
||||
size_t copy_count, register_offset;
|
||||
|
||||
if (!vfio_pci_core_range_intersect_range(pos, count, reg, val_size,
|
||||
©_offset, ©_count,
|
||||
®ister_offset))
|
||||
©_offset, ©_count,
|
||||
®ister_offset))
|
||||
return 0;
|
||||
|
||||
if (copy_to_user(buf + copy_offset, val + register_offset, copy_count))
|
||||
@@ -146,8 +148,8 @@ static ssize_t pci_sim_vfio_read_config(struct vfio_device *core_vdev,
|
||||
|
||||
val16 = cpu_to_le16(0xff00);
|
||||
if (pci_sim_vfio_copy_config_value(buf, pos, done,
|
||||
PCI_SUBSYSTEM_VENDOR_ID,
|
||||
&val16, sizeof(val16)))
|
||||
PCI_SUBSYSTEM_VENDOR_ID, &val16,
|
||||
sizeof(val16)))
|
||||
return -EFAULT;
|
||||
|
||||
val16 = cpu_to_le16(0);
|
||||
@@ -161,8 +163,8 @@ static ssize_t pci_sim_vfio_read_config(struct vfio_device *core_vdev,
|
||||
static ssize_t pci_sim_vfio_read(struct vfio_device *core_vdev,
|
||||
char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct pci_sim_vfio_vf *sim = container_of(core_vdev,
|
||||
struct pci_sim_vfio_vf, core.vdev);
|
||||
struct pci_sim_vfio_vf *sim =
|
||||
container_of(core_vdev, struct pci_sim_vfio_vf, core.vdev);
|
||||
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
|
||||
|
||||
if (!count)
|
||||
@@ -181,8 +183,8 @@ static ssize_t pci_sim_vfio_write(struct vfio_device *core_vdev,
|
||||
const char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct pci_sim_vfio_vf *sim = container_of(core_vdev,
|
||||
struct pci_sim_vfio_vf, core.vdev);
|
||||
struct pci_sim_vfio_vf *sim =
|
||||
container_of(core_vdev, struct pci_sim_vfio_vf, core.vdev);
|
||||
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
|
||||
|
||||
if (!count)
|
||||
@@ -204,7 +206,8 @@ static int pci_sim_vfio_get_region_info(struct vfio_device *core_vdev,
|
||||
return vfio_pci_ioctl_get_region_info(core_vdev, info, caps);
|
||||
|
||||
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
|
||||
info->size = vfio_guest_8250_compat ? PCI_SIM_VFIO_BAR0_SIZE : BAR0_SIZE;
|
||||
info->size = vfio_guest_8250_compat ? PCI_SIM_VFIO_BAR0_SIZE :
|
||||
BAR0_SIZE;
|
||||
info->flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE;
|
||||
return 0;
|
||||
}
|
||||
@@ -242,7 +245,8 @@ static long pci_sim_vfio_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
|
||||
static int pci_sim_vfio_mmap(struct vfio_device *core_vdev,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned int index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
|
||||
unsigned int index = vma->vm_pgoff >>
|
||||
(VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
|
||||
|
||||
if (index == VFIO_PCI_BAR0_REGION_INDEX)
|
||||
return -EINVAL;
|
||||
@@ -251,30 +255,30 @@ static int pci_sim_vfio_mmap(struct vfio_device *core_vdev,
|
||||
}
|
||||
|
||||
static const struct vfio_device_ops pci_sim_vfio_ops = {
|
||||
.name = "pci_sim_vfio_pci",
|
||||
.init = vfio_pci_core_init_dev,
|
||||
.release = vfio_pci_core_release_dev,
|
||||
.open_device = pci_sim_vfio_open_device,
|
||||
.close_device = vfio_pci_core_close_device,
|
||||
.name = "pci_sim_vfio_pci",
|
||||
.init = vfio_pci_core_init_dev,
|
||||
.release = vfio_pci_core_release_dev,
|
||||
.open_device = pci_sim_vfio_open_device,
|
||||
.close_device = vfio_pci_core_close_device,
|
||||
#if PCI_SIM_VFIO_HAS_GET_REGION_INFO_CAPS
|
||||
.ioctl = vfio_pci_core_ioctl,
|
||||
.ioctl = vfio_pci_core_ioctl,
|
||||
.get_region_info_caps = pci_sim_vfio_get_region_info,
|
||||
#else
|
||||
.ioctl = pci_sim_vfio_ioctl,
|
||||
.ioctl = pci_sim_vfio_ioctl,
|
||||
#endif
|
||||
.device_feature = vfio_pci_core_ioctl_feature,
|
||||
.read = pci_sim_vfio_read,
|
||||
.write = pci_sim_vfio_write,
|
||||
.mmap = pci_sim_vfio_mmap,
|
||||
.request = vfio_pci_core_request,
|
||||
.match = vfio_pci_core_match,
|
||||
.device_feature = vfio_pci_core_ioctl_feature,
|
||||
.read = pci_sim_vfio_read,
|
||||
.write = pci_sim_vfio_write,
|
||||
.mmap = pci_sim_vfio_mmap,
|
||||
.request = vfio_pci_core_request,
|
||||
.match = vfio_pci_core_match,
|
||||
#if PCI_SIM_VFIO_HAS_MATCH_TOKEN_UUID
|
||||
.match_token_uuid = vfio_pci_core_match_token_uuid,
|
||||
#endif
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
#if PCI_SIM_VFIO_HAS_PASID_IOAS
|
||||
.pasid_attach_ioas = vfio_iommufd_physical_pasid_attach_ioas,
|
||||
.pasid_detach_ioas = vfio_iommufd_physical_pasid_detach_ioas,
|
||||
@@ -324,15 +328,15 @@ static void pci_sim_vfio_remove(struct pci_dev *pdev)
|
||||
static const struct pci_device_id pci_sim_vfio_ids[] = {
|
||||
{ PCI_DRIVER_OVERRIDE_DEVICE_VFIO(FAKE_PCI_VENDOR_ID,
|
||||
FAKE_PCI_VF_DEVICE_ID) },
|
||||
{ }
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pci_sim_vfio_ids);
|
||||
|
||||
struct pci_driver pci_sim_vfio_driver = {
|
||||
.name = "pci_sim_vfio_pci",
|
||||
.id_table = pci_sim_vfio_ids,
|
||||
.probe = pci_sim_vfio_probe,
|
||||
.remove = pci_sim_vfio_remove,
|
||||
.err_handler = &vfio_pci_core_err_handlers,
|
||||
.driver_managed_dma = true,
|
||||
.name = "pci_sim_vfio_pci",
|
||||
.id_table = pci_sim_vfio_ids,
|
||||
.probe = pci_sim_vfio_probe,
|
||||
.remove = pci_sim_vfio_remove,
|
||||
.err_handler = &vfio_pci_core_err_handlers,
|
||||
.driver_managed_dma = true,
|
||||
};
|
||||
@@ -0,0 +1,202 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
Kernel conventions for pci-sim
|
||||
==============================
|
||||
|
||||
This document defines the local coding conventions and validation checks for
|
||||
``pci-sim``. ``pci-sim`` is an out-of-tree kernel module, but it should be
|
||||
written and reviewed like Linux kernel code so that it remains maintainable and
|
||||
can track upstream PCI, SR-IOV, VFIO, IOMMU, and TTY APIs.
|
||||
|
||||
The Linux kernel documentation and nearby subsystem code are the source of
|
||||
truth. In particular, consult:
|
||||
|
||||
* ``Documentation/process/coding-style.rst``
|
||||
* ``Documentation/process/submit-checklist.rst``
|
||||
* ``Documentation/process/submitting-patches.rst``
|
||||
* ``Documentation/dev-tools/checkpatch.rst``
|
||||
* ``Documentation/dev-tools/clang-format.rst``
|
||||
* ``Documentation/PCI/pci.rst``
|
||||
* ``Documentation/PCI/pci-iov-howto.rst``
|
||||
* ``Documentation/driver-api/vfio.rst``
|
||||
|
||||
Required local checks
|
||||
---------------------
|
||||
|
||||
Run these before posting or merging pci-sim changes.
|
||||
|
||||
Build the module
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
From ``pci-sim/``::
|
||||
|
||||
make test-build
|
||||
make clean
|
||||
|
||||
The build must complete without new warnings. Run ``make clean`` before
|
||||
finishing local validation so generated module artifacts are not left behind.
|
||||
|
||||
Run lint
|
||||
~~~~~~~~
|
||||
|
||||
Run the local pci-sim lint target against the diff from ``origin/master``::
|
||||
|
||||
make lint
|
||||
|
||||
``make lint`` runs the repo-supported style checks for normal review: the
|
||||
vendored Linux ``checkpatch.pl`` in patch mode with ``--no-spelling`` and
|
||||
``git clang-format`` for C and header changes. The format check updates the
|
||||
working tree when formatting changes are needed, then fails so the developer
|
||||
can review and include those formatting updates. The local ``.clang-format``
|
||||
copy is tuned to reduce immediate post-``(" line breaks, but lint still
|
||||
ignores ``OPEN_ENDED_LINE`` because ``clang-format`` can produce that
|
||||
checkpatch advisory for long module metadata macros. It also ignores
|
||||
``CONSTANT_COMPARISON`` and
|
||||
``LINUX_VERSION_CODE`` for the isolated out-of-tree compatibility header,
|
||||
``EMBEDDED_FILENAME`` for the Makefile lint path list, and
|
||||
``FILE_PATH_CHANGES`` because pci-sim ownership is tracked by the Cyborg
|
||||
repository rather than the Linux kernel ``MAINTAINERS`` file. Spelling is
|
||||
handled by the repository's top-level ``codespell`` pre-commit hook, not by
|
||||
checkpatch.
|
||||
|
||||
``checkpatch.pl`` is a guide, not an absolute authority. New errors should be
|
||||
fixed. New warnings and checks should either be fixed or explicitly justified
|
||||
in review.
|
||||
|
||||
The local lint target runs ``checkpatch.pl`` with ``--no-tree``. That keeps
|
||||
the check self-contained and avoids extra Linux-tree helper
|
||||
dependencies, but it means complete SPDX expression validation is not part of
|
||||
the initial lint gate.
|
||||
|
||||
Run full checks
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Before posting pci-sim changes, run::
|
||||
|
||||
make check
|
||||
|
||||
``make check`` runs ``make lint`` and then builds the module with the kernel
|
||||
``W=1`` extra-warning level. It cleans generated module artifacts after the
|
||||
build.
|
||||
|
||||
Run behavior tests for behavior changes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For changes that affect runtime behavior, run the relevant smoke tests, for
|
||||
example::
|
||||
|
||||
make test-loopback
|
||||
make test-multi-pf
|
||||
|
||||
Also run the VFIO, QEMU, or CirrOS helper tests when touching those paths.
|
||||
A style-clean build is not sufficient for PCI, VFIO, or IOMMU behavior
|
||||
changes.
|
||||
|
||||
Formatter policy
|
||||
----------------
|
||||
|
||||
``clang-format`` is useful, but formatting churn must be controlled.
|
||||
|
||||
* A one-time normalization with ``clang-format`` is acceptable if it is a
|
||||
dedicated formatting-only change.
|
||||
* Use the ``.clang-format`` file provided in this repository. It was
|
||||
imported from the Linux kernel formatting configuration so contributors do
|
||||
not need a separate Linux kernel checkout.
|
||||
* Review the resulting diff manually for correctness and readability. The
|
||||
imported ``.clang-format`` approximates kernel style but is not perfect.
|
||||
* Do not mix formatting-only churn with functional changes.
|
||||
* After any normalization commit, format only new or touched code.
|
||||
* Prefer the repository ``clang-format`` output for pci-sim formatting. The
|
||||
goal is close alignment with kernel style, but consistent automated
|
||||
formatting is more important than preserving hand-aligned exceptions.
|
||||
* Do not use ``scripts/Lindent`` as an automated formatter for pci-sim.
|
||||
|
||||
Developer coding conventions
|
||||
----------------------------
|
||||
|
||||
General kernel style
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Use tabs for indentation. Kernel indentation is 8 columns.
|
||||
* Prefer 80-column lines. Do not split user-visible log strings solely to fit
|
||||
the limit because that makes them harder to grep.
|
||||
* Use normal kernel brace style: opening braces stay on the control statement
|
||||
line, while function opening braces go on the next line.
|
||||
* Use lower-case names with underscores. Global symbols should be descriptive;
|
||||
local variables can be short when the scope is small.
|
||||
* Avoid typedefs for structs and pointers.
|
||||
* Prefer inline functions over macros when type checking or single evaluation
|
||||
matters. Keep macros for constants, compile-time constructs, and cases where
|
||||
an inline function cannot work.
|
||||
* Include the header that directly declares the API being used. Do not rely on
|
||||
unrelated headers to include it indirectly.
|
||||
* Keep functions short, focused, and shallowly indented. Split functions that
|
||||
mix setup, emulation, cleanup, and policy decisions.
|
||||
* Use direct returns when no cleanup is required. Use ``goto`` cleanup labels
|
||||
for multi-step allocation or registration paths, and name labels after the
|
||||
cleanup they perform.
|
||||
* Comments should explain purpose, constraints, hardware behavior, locking,
|
||||
ordering, or ABI. Do not restate obvious code.
|
||||
* Document every module parameter with ``MODULE_PARM_DESC()``.
|
||||
|
||||
pci-sim structure
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Keep subsystem ownership clear. PCI config-space emulation, host bridge
|
||||
setup, IOMMU grouping, VFIO behavior, UART emulation, polling threads, and
|
||||
tests should remain separated by responsibility.
|
||||
* Avoid compatibility sprawl. If kernel-version compatibility is required,
|
||||
isolate it in compatibility helpers or headers and keep normal code readable.
|
||||
* Avoid broad abstraction layers that hide Linux kernel APIs without adding a
|
||||
real pci-sim concept.
|
||||
* Treat sysfs files, module parameters, helper-script behavior, and
|
||||
guest-visible device behavior as user-visible interfaces. Keep them stable
|
||||
unless changing them is intentional and documented.
|
||||
|
||||
Ownership, lifetime, and cleanup
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* For every object, identify the owner and release path: host bridge, PCI
|
||||
resource, VF state, IOMMU object, VFIO device, TTY port, backing file,
|
||||
kthread, and allocated memory.
|
||||
* Registration and allocation error paths must unwind in reverse order.
|
||||
* Remove and module-exit paths must tolerate partially initialized state.
|
||||
* Repeated load, test, failure, cleanup, and reload cycles should be reliable.
|
||||
* Helper scripts should be idempotent and safe to run after partial failures.
|
||||
|
||||
Locking and concurrency
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Protect shared mutable state with the narrowest suitable kernel lock.
|
||||
* Document lock ordering where more than one lock can be held.
|
||||
* Review races between module unload, PF removal, VF enable/disable, VFIO MMIO
|
||||
access, TTY operations, kthreads, and cleanup scripts.
|
||||
* Memory barriers and non-obvious ordering rules require comments explaining
|
||||
what they pair with and why they are needed.
|
||||
|
||||
PCI, SR-IOV, VFIO, and IOMMU expectations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Follow the kernel SR-IOV model around ``sriov_numvfs``: validate VF counts,
|
||||
reject invalid transitions, and cleanly remove VFs before disabling state.
|
||||
* Keep VF personalities isolated so adding or changing UART behavior does not
|
||||
destabilize VFIO, IOMMU, or host-bridge behavior.
|
||||
* Preserve VFIO isolation assumptions. Review IOMMU group behavior, DMA
|
||||
mapping assumptions, BAR emulation, interrupt delivery, and reset semantics.
|
||||
* Prefer debuggable correctness over clever emulation shortcuts.
|
||||
|
||||
Review checklist
|
||||
----------------
|
||||
|
||||
Before considering a pci-sim change ready, verify:
|
||||
|
||||
* The change solves one logical problem.
|
||||
* Formatting-only changes are separated from functional changes.
|
||||
* The module builds and generated artifacts have been cleaned.
|
||||
* ``checkpatch.pl`` has no new unhandled errors, warnings, or checks.
|
||||
* Relevant build-warning gaps are reported.
|
||||
* Runtime tests cover the paths affected by the change.
|
||||
* Allocation, registration, error, remove, and unload paths are correct.
|
||||
* Locking and object lifetimes are understandable from the code.
|
||||
* New or changed module parameters, helper behavior, or user-visible behavior
|
||||
are documented.
|
||||
Executable
+7890
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,113 @@
|
||||
acpi_dock_ops
|
||||
address_space_operations
|
||||
backlight_ops
|
||||
bin_attribute
|
||||
block_device_operations
|
||||
bus_type
|
||||
clk_ops
|
||||
comedi_lrange
|
||||
component_ops
|
||||
ctl_table
|
||||
dentry_operations
|
||||
dev_pm_ops
|
||||
device_type
|
||||
dma_map_ops
|
||||
driver_info
|
||||
drm_connector_funcs
|
||||
drm_encoder_funcs
|
||||
drm_encoder_helper_funcs
|
||||
dvb_frontend_ops
|
||||
dvb_tuner_ops
|
||||
ethtool_ops
|
||||
extent_io_ops
|
||||
fb_ops
|
||||
file_lock_operations
|
||||
file_operations
|
||||
hv_ops
|
||||
hwmon_ops
|
||||
ib_device_ops
|
||||
ide_dma_ops
|
||||
ide_port_ops
|
||||
ieee80211_ops
|
||||
iio_buffer_setup_ops
|
||||
inode_operations
|
||||
intel_dvo_dev_ops
|
||||
irq_domain_ops
|
||||
item_operations
|
||||
iwl_cfg
|
||||
iwl_ops
|
||||
kernel_param_ops
|
||||
kgdb_arch
|
||||
kgdb_io
|
||||
kobj_type
|
||||
kset_uevent_ops
|
||||
lcd_ops
|
||||
lock_manager_operations
|
||||
machine_desc
|
||||
microcode_ops
|
||||
mlxsw_reg_info
|
||||
mtd_ooblayout_ops
|
||||
mtrr_ops
|
||||
nand_controller_ops
|
||||
neigh_ops
|
||||
net_device_ops
|
||||
nft_expr_ops
|
||||
nlmsvc_binding
|
||||
nvkm_device_chip
|
||||
of_device_id
|
||||
pci_raw_ops
|
||||
phy_ops
|
||||
pinconf_ops
|
||||
pinctrl_ops
|
||||
pinmux_ops
|
||||
pipe_buf_operations
|
||||
platform_hibernation_ops
|
||||
platform_suspend_ops
|
||||
proc_ops
|
||||
proto_ops
|
||||
pwm_ops
|
||||
reg_default
|
||||
reg_field
|
||||
reg_sequence
|
||||
regmap_access_table
|
||||
regmap_bus
|
||||
regmap_config
|
||||
regmap_irq
|
||||
regmap_irq_chip
|
||||
regmap_irq_sub_irq_map
|
||||
regmap_range
|
||||
regmap_range_cfg
|
||||
regulator_ops
|
||||
reset_control_ops
|
||||
rpc_pipe_ops
|
||||
rtc_class_ops
|
||||
sd_desc
|
||||
sdhci_ops
|
||||
seq_operations
|
||||
sirfsoc_padmux
|
||||
snd_ac97_build_ops
|
||||
snd_pcm_ops
|
||||
snd_rawmidi_ops
|
||||
snd_soc_component_driver
|
||||
snd_soc_dai_ops
|
||||
snd_soc_ops
|
||||
snd_soc_tplg_ops
|
||||
soc_pcmcia_socket_ops
|
||||
stacktrace_ops
|
||||
sysfs_ops
|
||||
tty_operations
|
||||
uart_ops
|
||||
usb_mon_operations
|
||||
v4l2_ctrl_ops
|
||||
v4l2_ioctl_ops
|
||||
v4l2_subdev_core_ops
|
||||
v4l2_subdev_internal_ops
|
||||
v4l2_subdev_ops
|
||||
v4l2_subdev_pad_ops
|
||||
v4l2_subdev_video_ops
|
||||
vb2_ops
|
||||
vm_operations_struct
|
||||
wacom_features
|
||||
watchdog_ops
|
||||
wd_ops
|
||||
xattr_handler
|
||||
Reference in new issue
Block a user