Following patches need the RDMA rc branch since we are past the RC cycle now. Merge conflicts resolved based on Linux-next: - For RXE odp changes keep for-next version and fixup new places that need to call is_odp_mr() https://lore.kernel.org/r/20250422143019.500201bd@canb.auug.org.au https://lore.kernel.org/r/20250514122455.3593b083@canb.auug.org.au - irdma is keeping the while/kfree bugfix from -rc and the pf/cdev_info change from for-next https://lore.kernel.org/r/20250513130630.280ee6c5@canb.auug.org.au
Unified · Split
| @@ -92,6 +92,7 @@ ForEachMacros: · 91 unmodified lines | |||
| 92 | - '__rq_for_each_bio' | 92 | - '__rq_for_each_bio' |
| 93 | - '__shost_for_each_device' | 93 | - '__shost_for_each_device' |
| 94 | - '__sym_for_each' | 94 | - '__sym_for_each' |
| 95 | - '_for_each_counter' | ||
| 95 | - 'apei_estatus_for_each_section' | 96 | - 'apei_estatus_for_each_section' |
| 96 | - 'ata_for_each_dev' | 97 | - 'ata_for_each_dev' |
| 97 | - 'ata_for_each_link' | 98 | - 'ata_for_each_link' |
| @@ -141,11 +142,14 @@ ForEachMacros: · 43 unmodified lines | |||
| 141 | - 'damon_for_each_target_safe' | 142 | - 'damon_for_each_target_safe' |
| 142 | - 'damos_for_each_filter' | 143 | - 'damos_for_each_filter' |
| 143 | - 'damos_for_each_filter_safe' | 144 | - 'damos_for_each_filter_safe' |
| 145 | - 'damos_for_each_ops_filter' | ||
| 146 | - 'damos_for_each_ops_filter_safe' | ||
| 144 | - 'damos_for_each_quota_goal' | 147 | - 'damos_for_each_quota_goal' |
| 145 | - 'damos_for_each_quota_goal_safe' | 148 | - 'damos_for_each_quota_goal_safe' |
| 146 | - 'data__for_each_file' | 149 | - 'data__for_each_file' |
| 147 | - 'data__for_each_file_new' | 150 | - 'data__for_each_file_new' |
| 148 | - 'data__for_each_file_start' | 151 | - 'data__for_each_file_start' |
| 152 | - 'def_for_each_cpu' | ||
| 149 | - 'device_for_each_child_node' | 153 | - 'device_for_each_child_node' |
| 150 | - 'device_for_each_child_node_scoped' | 154 | - 'device_for_each_child_node_scoped' |
| 151 | - 'dma_fence_array_for_each' | 155 | - 'dma_fence_array_for_each' |
| @@ -176,6 +180,7 @@ ForEachMacros: · 24 unmodified lines | |||
| 176 | - 'drm_for_each_privobj' | 180 | - 'drm_for_each_privobj' |
| 177 | - 'drm_gem_for_each_gpuvm_bo' | 181 | - 'drm_gem_for_each_gpuvm_bo' |
| 178 | - 'drm_gem_for_each_gpuvm_bo_safe' | 182 | - 'drm_gem_for_each_gpuvm_bo_safe' |
| 183 | - 'drm_gpusvm_for_each_range' | ||
| 179 | - 'drm_gpuva_for_each_op' | 184 | - 'drm_gpuva_for_each_op' |
| 180 | - 'drm_gpuva_for_each_op_from_reverse' | 185 | - 'drm_gpuva_for_each_op_from_reverse' |
| 181 | - 'drm_gpuva_for_each_op_reverse' | 186 | - 'drm_gpuva_for_each_op_reverse' |
| @@ -216,8 +221,10 @@ ForEachMacros: · 34 unmodified lines | |||
| 216 | - 'for_each_active_dev_scope' | 221 | - 'for_each_active_dev_scope' |
| 217 | - 'for_each_active_drhd_unit' | 222 | - 'for_each_active_drhd_unit' |
| 218 | - 'for_each_active_iommu' | 223 | - 'for_each_active_iommu' |
| 224 | - 'for_each_active_irq' | ||
| 219 | - 'for_each_active_route' | 225 | - 'for_each_active_route' |
| 220 | - 'for_each_aggr_pgid' | 226 | - 'for_each_aggr_pgid' |
| 227 | - 'for_each_alloc_capable_rdt_resource' | ||
| 221 | - 'for_each_and_bit' | 228 | - 'for_each_and_bit' |
| 222 | - 'for_each_andnot_bit' | 229 | - 'for_each_andnot_bit' |
| 223 | - 'for_each_available_child_of_node' | 230 | - 'for_each_available_child_of_node' |
| @@ -228,6 +235,7 @@ ForEachMacros: · 4 unmodified lines | |||
| 228 | - 'for_each_btf_ext_rec' | 235 | - 'for_each_btf_ext_rec' |
| 229 | - 'for_each_btf_ext_sec' | 236 | - 'for_each_btf_ext_sec' |
| 230 | - 'for_each_bvec' | 237 | - 'for_each_bvec' |
| 238 | - 'for_each_capable_rdt_resource' | ||
| 231 | - 'for_each_card_auxs' | 239 | - 'for_each_card_auxs' |
| 232 | - 'for_each_card_auxs_safe' | 240 | - 'for_each_card_auxs_safe' |
| 233 | - 'for_each_card_components' | 241 | - 'for_each_card_components' |
| @@ -241,6 +249,7 @@ ForEachMacros: · 7 unmodified lines | |||
| 241 | - 'for_each_cgroup_storage_type' | 249 | - 'for_each_cgroup_storage_type' |
| 242 | - 'for_each_child_of_node' | 250 | - 'for_each_child_of_node' |
| 243 | - 'for_each_child_of_node_scoped' | 251 | - 'for_each_child_of_node_scoped' |
| 252 | - 'for_each_child_of_node_with_prefix' | ||
| 244 | - 'for_each_clear_bit' | 253 | - 'for_each_clear_bit' |
| 245 | - 'for_each_clear_bit_from' | 254 | - 'for_each_clear_bit_from' |
| 246 | - 'for_each_clear_bitrange' | 255 | - 'for_each_clear_bitrange' |
| @@ -296,6 +305,7 @@ ForEachMacros: · 49 unmodified lines | |||
| 296 | - 'for_each_group_member_head' | 305 | - 'for_each_group_member_head' |
| 297 | - 'for_each_hstate' | 306 | - 'for_each_hstate' |
| 298 | - 'for_each_hwgpio' | 307 | - 'for_each_hwgpio' |
| 308 | - 'for_each_hwgpio_in_range' | ||
| 299 | - 'for_each_if' | 309 | - 'for_each_if' |
| 300 | - 'for_each_inject_fn' | 310 | - 'for_each_inject_fn' |
| 301 | - 'for_each_insn' | 311 | - 'for_each_insn' |
| @@ -304,6 +314,7 @@ ForEachMacros: · 2 unmodified lines | |||
| 304 | - 'for_each_intid' | 314 | - 'for_each_intid' |
| 305 | - 'for_each_iommu' | 315 | - 'for_each_iommu' |
| 306 | - 'for_each_ip_tunnel_rcu' | 316 | - 'for_each_ip_tunnel_rcu' |
| 317 | - 'for_each_irq_desc' | ||
| 307 | - 'for_each_irq_nr' | 318 | - 'for_each_irq_nr' |
| 308 | - 'for_each_lang' | 319 | - 'for_each_lang' |
| 309 | - 'for_each_link_ch_maps' | 320 | - 'for_each_link_ch_maps' |
| @@ -324,6 +335,8 @@ ForEachMacros: · 14 unmodified lines | |||
| 324 | - 'for_each_missing_reg' | 335 | - 'for_each_missing_reg' |
| 325 | - 'for_each_mle_subelement' | 336 | - 'for_each_mle_subelement' |
| 326 | - 'for_each_mod_mem_type' | 337 | - 'for_each_mod_mem_type' |
| 338 | - 'for_each_mon_capable_rdt_resource' | ||
| 339 | - 'for_each_mp_bvec' | ||
| 327 | - 'for_each_net' | 340 | - 'for_each_net' |
| 328 | - 'for_each_net_continue_reverse' | 341 | - 'for_each_net_continue_reverse' |
| 329 | - 'for_each_net_rcu' | 342 | - 'for_each_net_rcu' |
| @@ -351,6 +364,7 @@ ForEachMacros: · 21 unmodified lines | |||
| 351 | - 'for_each_node_by_name' | 364 | - 'for_each_node_by_name' |
| 352 | - 'for_each_node_by_type' | 365 | - 'for_each_node_by_type' |
| 353 | - 'for_each_node_mask' | 366 | - 'for_each_node_mask' |
| 367 | - 'for_each_node_numadist' | ||
| 354 | - 'for_each_node_state' | 368 | - 'for_each_node_state' |
| 355 | - 'for_each_node_with_cpus' | 369 | - 'for_each_node_with_cpus' |
| 356 | - 'for_each_node_with_property' | 370 | - 'for_each_node_with_property' |
| @@ -359,6 +373,8 @@ ForEachMacros: · 2 unmodified lines | |||
| 359 | - 'for_each_of_allnodes' | 373 | - 'for_each_of_allnodes' |
| 360 | - 'for_each_of_allnodes_from' | 374 | - 'for_each_of_allnodes_from' |
| 361 | - 'for_each_of_cpu_node' | 375 | - 'for_each_of_cpu_node' |
| 376 | - 'for_each_of_graph_port' | ||
| 377 | - 'for_each_of_graph_port_endpoint' | ||
| 362 | - 'for_each_of_pci_range' | 378 | - 'for_each_of_pci_range' |
| 363 | - 'for_each_old_connector_in_state' | 379 | - 'for_each_old_connector_in_state' |
| 364 | - 'for_each_old_crtc_in_state' | 380 | - 'for_each_old_crtc_in_state' |
| @@ -372,9 +388,11 @@ ForEachMacros: · 7 unmodified lines | |||
| 372 | - 'for_each_oldnew_plane_in_state_reverse' | 388 | - 'for_each_oldnew_plane_in_state_reverse' |
| 373 | - 'for_each_oldnew_private_obj_in_state' | 389 | - 'for_each_oldnew_private_obj_in_state' |
| 374 | - 'for_each_online_cpu' | 390 | - 'for_each_online_cpu' |
| 391 | - 'for_each_online_cpu_wrap' | ||
| 375 | - 'for_each_online_node' | 392 | - 'for_each_online_node' |
| 376 | - 'for_each_online_pgdat' | 393 | - 'for_each_online_pgdat' |
| 377 | - 'for_each_or_bit' | 394 | - 'for_each_or_bit' |
| 395 | - 'for_each_page_ext' | ||
| 378 | - 'for_each_path' | 396 | - 'for_each_path' |
| 379 | - 'for_each_pci_bridge' | 397 | - 'for_each_pci_bridge' |
| 380 | - 'for_each_pci_dev' | 398 | - 'for_each_pci_dev' |
| @@ -382,8 +400,10 @@ ForEachMacros: · 1 unmodified line | |||
| 382 | - 'for_each_physmem_range' | 400 | - 'for_each_physmem_range' |
| 383 | - 'for_each_populated_zone' | 401 | - 'for_each_populated_zone' |
| 384 | - 'for_each_possible_cpu' | 402 | - 'for_each_possible_cpu' |
| 403 | - 'for_each_possible_cpu_wrap' | ||
| 385 | - 'for_each_present_blessed_reg' | 404 | - 'for_each_present_blessed_reg' |
| 386 | - 'for_each_present_cpu' | 405 | - 'for_each_present_cpu' |
| 406 | - 'for_each_present_section_nr' | ||
| 387 | - 'for_each_prime_number' | 407 | - 'for_each_prime_number' |
| 388 | - 'for_each_prime_number_from' | 408 | - 'for_each_prime_number_from' |
| 389 | - 'for_each_probe_cache_entry' | 409 | - 'for_each_probe_cache_entry' |
| @@ -396,6 +416,7 @@ ForEachMacros: · 6 unmodified lines | |||
| 396 | - 'for_each_prop_dlc_cpus' | 416 | - 'for_each_prop_dlc_cpus' |
| 397 | - 'for_each_prop_dlc_platforms' | 417 | - 'for_each_prop_dlc_platforms' |
| 398 | - 'for_each_property_of_node' | 418 | - 'for_each_property_of_node' |
| 419 | - 'for_each_rdt_resource' | ||
| 399 | - 'for_each_reg' | 420 | - 'for_each_reg' |
| 400 | - 'for_each_reg_filtered' | 421 | - 'for_each_reg_filtered' |
| 401 | - 'for_each_reloc' | 422 | - 'for_each_reloc' |
| @@ -434,10 +455,10 @@ ForEachMacros: · 32 unmodified lines | |||
| 434 | - 'for_each_subelement_id' | 455 | - 'for_each_subelement_id' |
| 435 | - 'for_each_sublist' | 456 | - 'for_each_sublist' |
| 436 | - 'for_each_subsystem' | 457 | - 'for_each_subsystem' |
| 458 | - 'for_each_suite' | ||
| 437 | - 'for_each_supported_activate_fn' | 459 | - 'for_each_supported_activate_fn' |
| 438 | - 'for_each_supported_inject_fn' | 460 | - 'for_each_supported_inject_fn' |
| 439 | - 'for_each_sym' | 461 | - 'for_each_sym' |
| 440 | - 'for_each_test' | ||
| 441 | - 'for_each_thread' | 462 | - 'for_each_thread' |
| 442 | - 'for_each_token' | 463 | - 'for_each_token' |
| 443 | - 'for_each_unicast_dest_pgid' | 464 | - 'for_each_unicast_dest_pgid' |
| @@ -499,8 +520,10 @@ ForEachMacros: · 55 unmodified lines | |||
| 499 | - 'idr_for_each_entry_continue' | 520 | - 'idr_for_each_entry_continue' |
| 500 | - 'idr_for_each_entry_continue_ul' | 521 | - 'idr_for_each_entry_continue_ul' |
| 501 | - 'idr_for_each_entry_ul' | 522 | - 'idr_for_each_entry_ul' |
| 523 | - 'iio_for_each_active_channel' | ||
| 502 | - 'in_dev_for_each_ifa_rcu' | 524 | - 'in_dev_for_each_ifa_rcu' |
| 503 | - 'in_dev_for_each_ifa_rtnl' | 525 | - 'in_dev_for_each_ifa_rtnl' |
| 526 | - 'in_dev_for_each_ifa_rtnl_net' | ||
| 504 | - 'inet_bind_bucket_for_each' | 527 | - 'inet_bind_bucket_for_each' |
| 505 | - 'interval_tree_for_each_span' | 528 | - 'interval_tree_for_each_span' |
| 506 | - 'intlist__for_each_entry' | 529 | - 'intlist__for_each_entry' |
| @@ -542,7 +565,6 @@ ForEachMacros: · 35 unmodified lines | |||
| 542 | - 'list_for_each_prev' | 565 | - 'list_for_each_prev' |
| 543 | - 'list_for_each_prev_safe' | 566 | - 'list_for_each_prev_safe' |
| 544 | - 'list_for_each_rcu' | 567 | - 'list_for_each_rcu' |
| 545 | - 'list_for_each_reverse' | ||
| 546 | - 'list_for_each_safe' | 568 | - 'list_for_each_safe' |
| 547 | - 'llist_for_each' | 569 | - 'llist_for_each' |
| 548 | - 'llist_for_each_entry' | 570 | - 'llist_for_each_entry' |
| @@ -552,6 +574,7 @@ ForEachMacros: · 3 unmodified lines | |||
| 552 | - 'map__for_each_symbol' | 574 | - 'map__for_each_symbol' |
| 553 | - 'map__for_each_symbol_by_name' | 575 | - 'map__for_each_symbol_by_name' |
| 554 | - 'mas_for_each' | 576 | - 'mas_for_each' |
| 577 | - 'mas_for_each_rev' | ||
| 555 | - 'mci_for_each_dimm' | 578 | - 'mci_for_each_dimm' |
| 556 | - 'media_device_for_each_entity' | 579 | - 'media_device_for_each_entity' |
| 557 | - 'media_device_for_each_intf' | 580 | - 'media_device_for_each_intf' |
| @@ -561,10 +584,15 @@ ForEachMacros: · 3 unmodified lines | |||
| 561 | - 'media_pipeline_for_each_entity' | 584 | - 'media_pipeline_for_each_entity' |
| 562 | - 'media_pipeline_for_each_pad' | 585 | - 'media_pipeline_for_each_pad' |
| 563 | - 'mlx5_lag_for_each_peer_mdev' | 586 | - 'mlx5_lag_for_each_peer_mdev' |
| 587 | - 'mptcp_for_each_subflow' | ||
| 564 | - 'msi_domain_for_each_desc' | 588 | - 'msi_domain_for_each_desc' |
| 565 | - 'msi_for_each_desc' | 589 | - 'msi_for_each_desc' |
| 566 | - 'mt_for_each' | 590 | - 'mt_for_each' |
| 591 | - 'nanddev_io_for_each_block' | ||
| 567 | - 'nanddev_io_for_each_page' | 592 | - 'nanddev_io_for_each_page' |
| 593 | - 'neigh_for_each_in_bucket' | ||
| 594 | - 'neigh_for_each_in_bucket_rcu' | ||
| 595 | - 'neigh_for_each_in_bucket_safe' | ||
| 568 | - 'netdev_for_each_lower_dev' | 596 | - 'netdev_for_each_lower_dev' |
| 569 | - 'netdev_for_each_lower_private' | 597 | - 'netdev_for_each_lower_private' |
| 570 | - 'netdev_for_each_lower_private_rcu' | 598 | - 'netdev_for_each_lower_private_rcu' |
| @@ -604,11 +632,11 @@ ForEachMacros: · 33 unmodified lines | |||
| 604 | - 'perf_evlist__for_each_entry_safe' | 632 | - 'perf_evlist__for_each_entry_safe' |
| 605 | - 'perf_evlist__for_each_evsel' | 633 | - 'perf_evlist__for_each_evsel' |
| 606 | - 'perf_evlist__for_each_mmap' | 634 | - 'perf_evlist__for_each_mmap' |
| 635 | - 'perf_evsel_for_each_per_thread_period_safe' | ||
| 607 | - 'perf_hpp_list__for_each_format' | 636 | - 'perf_hpp_list__for_each_format' |
| 608 | - 'perf_hpp_list__for_each_format_safe' | 637 | - 'perf_hpp_list__for_each_format_safe' |
| 609 | - 'perf_hpp_list__for_each_sort_list' | 638 | - 'perf_hpp_list__for_each_sort_list' |
| 610 | - 'perf_hpp_list__for_each_sort_list_safe' | 639 | - 'perf_hpp_list__for_each_sort_list_safe' |
| 611 | - 'perf_tool_event__for_each_event' | ||
| 612 | - 'plist_for_each' | 640 | - 'plist_for_each' |
| 613 | - 'plist_for_each_continue' | 641 | - 'plist_for_each_continue' |
| 614 | - 'plist_for_each_entry' | 642 | - 'plist_for_each_entry' |
| @@ -627,7 +655,6 @@ ForEachMacros: · 12 unmodified lines | |||
| 627 | - 'rdma_for_each_block' | 655 | - 'rdma_for_each_block' |
| 628 | - 'rdma_for_each_port' | 656 | - 'rdma_for_each_port' |
| 629 | - 'rdma_umem_for_each_dma_block' | 657 | - 'rdma_umem_for_each_dma_block' |
| 630 | - 'resort_rb__for_each_entry' | ||
| 631 | - 'resource_list_for_each_entry' | 658 | - 'resource_list_for_each_entry' |
| 632 | - 'resource_list_for_each_entry_safe' | 659 | - 'resource_list_for_each_entry_safe' |
| 633 | - 'rhl_for_each_entry_rcu' | 660 | - 'rhl_for_each_entry_rcu' |
| @@ -658,6 +685,7 @@ ForEachMacros: · 24 unmodified lines | |||
| 658 | - 'shost_for_each_device' | 685 | - 'shost_for_each_device' |
| 659 | - 'sk_for_each' | 686 | - 'sk_for_each' |
| 660 | - 'sk_for_each_bound' | 687 | - 'sk_for_each_bound' |
| 688 | - 'sk_for_each_bound_safe' | ||
| 661 | - 'sk_for_each_entry_offset_rcu' | 689 | - 'sk_for_each_entry_offset_rcu' |
| 662 | - 'sk_for_each_from' | 690 | - 'sk_for_each_from' |
| 663 | - 'sk_for_each_rcu' | 691 | - 'sk_for_each_rcu' |
| @@ -680,7 +708,11 @@ ForEachMacros: · 16 unmodified lines | |||
| 680 | - 'tb_property_for_each' | 708 | - 'tb_property_for_each' |
| 681 | - 'tcf_act_for_each_action' | 709 | - 'tcf_act_for_each_action' |
| 682 | - 'tcf_exts_for_each_action' | 710 | - 'tcf_exts_for_each_action' |
| 711 | - 'test_suite__for_each_test_case' | ||
| 712 | - 'tool_pmu__for_each_event' | ||
| 713 | - 'ttm_bo_lru_for_each_reserved_guarded' | ||
| 683 | - 'ttm_resource_manager_for_each_res' | 714 | - 'ttm_resource_manager_for_each_res' |
| 715 | - 'udp_lrpa_for_each_entry_rcu' | ||
| 684 | - 'udp_portaddr_for_each_entry' | 716 | - 'udp_portaddr_for_each_entry' |
| 685 | - 'udp_portaddr_for_each_entry_rcu' | 717 | - 'udp_portaddr_for_each_entry_rcu' |
| 686 | - 'usb_hub_for_each_child' | 718 | - 'usb_hub_for_each_child' |
| @@ -691,6 +723,7 @@ ForEachMacros: · 4 unmodified lines | |||
| 691 | - 'v4l2_m2m_for_each_src_buf_safe' | 723 | - 'v4l2_m2m_for_each_src_buf_safe' |
| 692 | - 'virtio_device_for_each_vq' | 724 | - 'virtio_device_for_each_vq' |
| 693 | - 'while_for_each_ftrace_op' | 725 | - 'while_for_each_ftrace_op' |
| 726 | - 'workloads__for_each' | ||
| 694 | - 'xa_for_each' | 727 | - 'xa_for_each' |
| 695 | - 'xa_for_each_marked' | 728 | - 'xa_for_each_marked' |
| 696 | - 'xa_for_each_range' | 729 | - 'xa_for_each_range' |
| @@ -7,5 +7,5 @@ check-private-items = true · 6 unmodified lines | |||
| 7 | disallowed-macros = [ | 7 | disallowed-macros = [ |
| 8 | # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate | 8 | # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate |
| 9 | # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303. | 9 | # it here, see: https://github.com/rust-lang/rust-clippy/issues/11303. |
| 10 | { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" }, | 10 | { path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool", allow-invalid = true }, |
| 11 | ] | 11 | ] |
| @@ -102,6 +102,7 @@ Ard Biesheuvel <ardb@kernel.org> <ard.biesheuvel@linaro.org> · 101 unmodified lines | |||
| 102 | Arnaud Patard <arnaud.patard@rtp-net.org> | 102 | Arnaud Patard <arnaud.patard@rtp-net.org> |
| 103 | Arnd Bergmann <arnd@arndb.de> | 103 | Arnd Bergmann <arnd@arndb.de> |
| 104 | Arun Kumar Neelakantam <quic_aneela@quicinc.com> <aneela@codeaurora.org> | 104 | Arun Kumar Neelakantam <quic_aneela@quicinc.com> <aneela@codeaurora.org> |
| 105 | Asahi Lina <lina+kernel@asahilina.net> <lina@asahilina.net> | ||
| 105 | Ashok Raj Nagarajan <quic_arnagara@quicinc.com> <arnagara@codeaurora.org> | 106 | Ashok Raj Nagarajan <quic_arnagara@quicinc.com> <arnagara@codeaurora.org> |
| 106 | Ashwin Chaugule <quic_ashwinc@quicinc.com> <ashwinc@codeaurora.org> | 107 | Ashwin Chaugule <quic_ashwinc@quicinc.com> <ashwinc@codeaurora.org> |
| 107 | Asutosh Das <quic_asutoshd@quicinc.com> <asutoshd@codeaurora.org> | 108 | Asutosh Das <quic_asutoshd@quicinc.com> <asutoshd@codeaurora.org> |
| @@ -312,6 +313,7 @@ Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com> · 204 unmodified lines | |||
| 312 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> | 313 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> |
| 313 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> | 314 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 314 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> | 315 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> |
| 316 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@opinsys.com> | ||
| 315 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> | 317 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 316 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> | 318 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 317 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> | 319 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> |
| @@ -322,6 +324,7 @@ Jayachandran C <c.jayachandran@gmail.com> <jchandra@broadcom.com> · 4 unmodified lines | |||
| 322 | Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com> | 324 | Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com> |
| 323 | Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com> | 325 | Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com> |
| 324 | <jean-philippe@linaro.org> <jean-philippe.brucker@arm.com> | 326 | <jean-philippe@linaro.org> <jean-philippe.brucker@arm.com> |
| 327 | Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org> <jeanmichel.hautbois@ideasonboard.com> | ||
| 325 | Jean Tourrilhes <jt@hpl.hp.com> | 328 | Jean Tourrilhes <jt@hpl.hp.com> |
| 326 | Jeevan Shriram <quic_jshriram@quicinc.com> <jshriram@codeaurora.org> | 329 | Jeevan Shriram <quic_jshriram@quicinc.com> <jshriram@codeaurora.org> |
| 327 | Jeff Garzik <jgarzik@pretzel.yyz.us> | 330 | Jeff Garzik <jgarzik@pretzel.yyz.us> |
| @@ -438,12 +441,16 @@ Linus Lüssing <linus.luessing@c0d3.blue> <ll@simonwunderlich.de> · 110 unmodified lines | |||
| 438 | Li Yang <leoyang.li@nxp.com> <leoli@freescale.com> | 441 | Li Yang <leoyang.li@nxp.com> <leoli@freescale.com> |
| 439 | Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org> | 442 | Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org> |
| 440 | Lior David <quic_liord@quicinc.com> <liord@codeaurora.org> | 443 | Lior David <quic_liord@quicinc.com> <liord@codeaurora.org> |
| 444 | Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org> | ||
| 445 | Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com> | ||
| 441 | Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com> | 446 | Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com> |
| 442 | Lorenzo Stoakes <lorenzo.stoakes@oracle.com> <lstoakes@gmail.com> | 447 | Lorenzo Stoakes <lorenzo.stoakes@oracle.com> <lstoakes@gmail.com> |
| 443 | Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net> | 448 | Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net> |
| 444 | Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz> | 449 | Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz> |
| 445 | Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com> | 450 | Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com> |
| 446 | Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org> | 451 | Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org> |
| 452 | Lance Yang <lance.yang@linux.dev> <ioworker0@gmail.com> | ||
| 453 | Lance Yang <lance.yang@linux.dev> <mingzhe.yang@ly.com> | ||
| 447 | Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com> | 454 | Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com> |
| 448 | Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org> | 455 | Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org> |
| 449 | Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org> | 456 | Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org> |
| @@ -480,6 +487,7 @@ Matthias Fuchs <socketcan@esd.eu> <matthias.fuchs@esd.eu> · 30 unmodified lines | |||
| 480 | Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net> | 487 | Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net> |
| 481 | Matthieu CASTET <castet.matthieu@free.fr> | 488 | Matthieu CASTET <castet.matthieu@free.fr> |
| 482 | Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com> | 489 | Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com> |
| 490 | Mattijs Korpershoek <mkorpershoek@kernel.org> <mkorpershoek@baylibre.com> | ||
| 483 | Matt Ranostay <matt@ranostay.sg> <matt.ranostay@konsulko.com> | 491 | Matt Ranostay <matt@ranostay.sg> <matt.ranostay@konsulko.com> |
| 484 | Matt Ranostay <matt@ranostay.sg> <matt@ranostay.consulting> | 492 | Matt Ranostay <matt@ranostay.sg> <matt@ranostay.consulting> |
| 485 | Matt Ranostay <matt@ranostay.sg> Matthew Ranostay <mranostay@embeddedalley.com> | 493 | Matt Ranostay <matt@ranostay.sg> Matthew Ranostay <mranostay@embeddedalley.com> |
| @@ -685,6 +693,8 @@ Simon Wunderlich <sw@simonwunderlich.de> <simon.wunderlich@saxnet.de> · 199 unmodified lines | |||
| 685 | Simon Wunderlich <sw@simonwunderlich.de> <simon@open-mesh.com> | 693 | Simon Wunderlich <sw@simonwunderlich.de> <simon@open-mesh.com> |
| 686 | Simon Wunderlich <sw@simonwunderlich.de> <siwu@hrz.tu-chemnitz.de> | 694 | Simon Wunderlich <sw@simonwunderlich.de> <siwu@hrz.tu-chemnitz.de> |
| 687 | Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org> | 695 | Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org> |
| 696 | Srinivas Kandagatla <srini@kernel.org> <srinivas.kandagatla@st.com> | ||
| 697 | Srinivas Kandagatla <srini@kernel.org> <srinivas.kandagatla@linaro.org> | ||
| 688 | Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org> | 698 | Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org> |
| 689 | Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org> | 699 | Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org> |
| 690 | Sriram Yagnaraman <sriram.yagnaraman@ericsson.com> <sriram.yagnaraman@est.tech> | 700 | Sriram Yagnaraman <sriram.yagnaraman@ericsson.com> <sriram.yagnaraman@est.tech> |
| @@ -744,6 +754,7 @@ Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko@ursulin.net> · 53 unmodified lines | |||
| 744 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> | 754 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> |
| 745 | Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> | 755 | Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> |
| 746 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> | 756 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> |
| 757 | Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com> | ||
| 747 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 758 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> |
| 748 | Uwe Kleine-König <ukleinek@strlen.de> | 759 | Uwe Kleine-König <ukleinek@strlen.de> |
| 749 | Uwe Kleine-König <ukl@pengutronix.de> | 760 | Uwe Kleine-König <ukl@pengutronix.de> |
| @@ -2071,6 +2071,10 @@ S: 660 Harvard Ave. #7 · 2070 unmodified lines | |||
| 2071 | S: Santa Clara, CA 95051 | 2071 | S: Santa Clara, CA 95051 |
| 2072 | S: USA | 2072 | S: USA |
| 2073 | 2073 | ||
| 2074 | N: Joonsoo Kim | ||
| 2075 | E: iamjoonsoo.kim@lge.com | ||
| 2076 | D: Slab allocators | ||
| 2077 | |||
| 2074 | N: Kukjin Kim | 2078 | N: Kukjin Kim |
| 2075 | E: kgene@kernel.org | 2079 | E: kgene@kernel.org |
| 2076 | D: Samsung S3C, S5P and Exynos ARM architectures | 2080 | D: Samsung S3C, S5P and Exynos ARM architectures |
| @@ -77,7 +77,7 @@ Description: · 76 unmodified lines | |||
| 77 | 77 | ||
| 78 | What: /sys/block/<disk>/diskseq | 78 | What: /sys/block/<disk>/diskseq |
| 79 | Date: February 2021 | 79 | Date: February 2021 |
| 80 | Contact: Matteo Croce <mcroce@microsoft.com> | 80 | Contact: Matteo Croce <teknoraver@meta.com> |
| 81 | Description: | 81 | Description: |
| 82 | The /sys/block/<disk>/diskseq files reports the disk | 82 | The /sys/block/<disk>/diskseq files reports the disk |
| 83 | sequence number, which is a monotonically increasing | 83 | sequence number, which is a monotonically increasing |
| @@ -511,6 +511,7 @@ Description: information about CPUs heterogeneity. · 510 unmodified lines | |||
| 511 | 511 | ||
| 512 | What: /sys/devices/system/cpu/vulnerabilities | 512 | What: /sys/devices/system/cpu/vulnerabilities |
| 513 | /sys/devices/system/cpu/vulnerabilities/gather_data_sampling | 513 | /sys/devices/system/cpu/vulnerabilities/gather_data_sampling |
| 514 | /sys/devices/system/cpu/vulnerabilities/indirect_target_selection | ||
| 514 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit | 515 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit |
| 515 | /sys/devices/system/cpu/vulnerabilities/l1tf | 516 | /sys/devices/system/cpu/vulnerabilities/l1tf |
| 516 | /sys/devices/system/cpu/vulnerabilities/mds | 517 | /sys/devices/system/cpu/vulnerabilities/mds |
| @@ -1,6 +1,6 @@ | |||
| 1 | What: /sys/bus/hid/drivers/hid-appletb-kbd/<dev>/mode | 1 | What: /sys/bus/hid/drivers/hid-appletb-kbd/<dev>/mode |
| 2 | Date: September, 2023 | 2 | Date: March, 2025 |
| 3 | KernelVersion: 6.5 | 3 | KernelVersion: 6.15 |
| 4 | Contact: linux-input@vger.kernel.org | 4 | Contact: linux-input@vger.kernel.org |
| 5 | Description: | 5 | Description: |
| 6 | The set of keys displayed on the Touch Bar. | 6 | The set of keys displayed on the Touch Bar. |
| @@ -111,7 +111,7 @@ Description: RO. Package current voltage in millivolt. · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_input | 112 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_input |
| 113 | Date: March 2025 | 113 | Date: March 2025 |
| 114 | KernelVersion: 6.14 | 114 | KernelVersion: 6.15 |
| 115 | Contact: intel-xe@lists.freedesktop.org | 115 | Contact: intel-xe@lists.freedesktop.org |
| 116 | Description: RO. Package temperature in millidegree Celsius. | 116 | Description: RO. Package temperature in millidegree Celsius. |
| 117 | 117 | ||
| @@ -119,7 +119,7 @@ Description: RO. Package temperature in millidegree Celsius. · 1 unmodified line | |||
| 119 | 119 | ||
| 120 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_input | 120 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_input |
| 121 | Date: March 2025 | 121 | Date: March 2025 |
| 122 | KernelVersion: 6.14 | 122 | KernelVersion: 6.15 |
| 123 | Contact: intel-xe@lists.freedesktop.org | 123 | Contact: intel-xe@lists.freedesktop.org |
| 124 | Description: RO. VRAM temperature in millidegree Celsius. | 124 | Description: RO. VRAM temperature in millidegree Celsius. |
| 125 | 125 | ||
| @@ -1604,3 +1604,35 @@ Description: · 1603 unmodified lines | |||
| 1604 | prevent the UFS from frequently performing clock gating/ungating. | 1604 | prevent the UFS from frequently performing clock gating/ungating. |
| 1605 | 1605 | ||
| 1606 | The attribute is read/write. | 1606 | The attribute is read/write. |
| 1607 | |||
| 1608 | What: /sys/bus/platform/drivers/ufshcd/*/device_lvl_exception_count | ||
| 1609 | What: /sys/bus/platform/devices/*.ufs/device_lvl_exception_count | ||
| 1610 | Date: March 2025 | ||
| 1611 | Contact: Bao D. Nguyen <quic_nguyenb@quicinc.com> | ||
| 1612 | Description: | ||
| 1613 | This attribute is applicable to ufs devices compliant to the | ||
| 1614 | JEDEC specifications version 4.1 or later. The | ||
| 1615 | device_lvl_exception_count is a counter indicating the number of | ||
| 1616 | times the device level exceptions have occurred since the last | ||
| 1617 | time this variable is reset. Writing a 0 value to this | ||
| 1618 | attribute will reset the device_lvl_exception_count. If the | ||
| 1619 | device_lvl_exception_count reads a positive value, the user | ||
| 1620 | application should read the device_lvl_exception_id attribute to | ||
| 1621 | know more information about the exception. | ||
| 1622 | |||
| 1623 | The attribute is read/write. | ||
| 1624 | |||
| 1625 | What: /sys/bus/platform/drivers/ufshcd/*/device_lvl_exception_id | ||
| 1626 | What: /sys/bus/platform/devices/*.ufs/device_lvl_exception_id | ||
| 1627 | Date: March 2025 | ||
| 1628 | Contact: Bao D. Nguyen <quic_nguyenb@quicinc.com> | ||
| 1629 | Description: | ||
| 1630 | Reading the device_lvl_exception_id returns the | ||
| 1631 | qDeviceLevelExceptionID attribute of the ufs device JEDEC | ||
| 1632 | specification version 4.1. The definition of the | ||
| 1633 | qDeviceLevelExceptionID is the ufs device vendor specific | ||
| 1634 | implementation. Refer to the device manufacturer datasheet for | ||
| 1635 | more information on the meaning of the qDeviceLevelExceptionID | ||
| 1636 | attribute value. | ||
| 1637 | |||
| 1638 | The attribute is read only. | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | What: /sys/kernel/reboot | 1 | What: /sys/kernel/reboot |
| 2 | Date: November 2020 | 2 | Date: November 2020 |
| 3 | KernelVersion: 5.11 | 3 | KernelVersion: 5.11 |
| 4 | Contact: Matteo Croce <mcroce@microsoft.com> | 4 | Contact: Matteo Croce <teknoraver@meta.com> |
| 5 | Description: Interface to set the kernel reboot behavior, similarly to | 5 | Description: Interface to set the kernel reboot behavior, similarly to |
| 6 | what can be done via the reboot= cmdline option. | 6 | what can be done via the reboot= cmdline option. |
| 7 | (see Documentation/admin-guide/kernel-parameters.txt) | 7 | (see Documentation/admin-guide/kernel-parameters.txt) |
| @@ -9,25 +9,25 @@ Description: Interface to set the kernel reboot behavior, similarly to · 1 unmodified line | |||
| 9 | What: /sys/kernel/reboot/mode | 9 | What: /sys/kernel/reboot/mode |
| 10 | Date: November 2020 | 10 | Date: November 2020 |
| 11 | KernelVersion: 5.11 | 11 | KernelVersion: 5.11 |
| 12 | Contact: Matteo Croce <mcroce@microsoft.com> | 12 | Contact: Matteo Croce <teknoraver@meta.com> |
| 13 | Description: Reboot mode. Valid values are: cold warm hard soft gpio | 13 | Description: Reboot mode. Valid values are: cold warm hard soft gpio |
| 14 | 14 | ||
| 15 | What: /sys/kernel/reboot/type | 15 | What: /sys/kernel/reboot/type |
| 16 | Date: November 2020 | 16 | Date: November 2020 |
| 17 | KernelVersion: 5.11 | 17 | KernelVersion: 5.11 |
| 18 | Contact: Matteo Croce <mcroce@microsoft.com> | 18 | Contact: Matteo Croce <teknoraver@meta.com> |
| 19 | Description: Reboot type. Valid values are: bios acpi kbd triple efi pci | 19 | Description: Reboot type. Valid values are: bios acpi kbd triple efi pci |
| 20 | 20 | ||
| 21 | What: /sys/kernel/reboot/cpu | 21 | What: /sys/kernel/reboot/cpu |
| 22 | Date: November 2020 | 22 | Date: November 2020 |
| 23 | KernelVersion: 5.11 | 23 | KernelVersion: 5.11 |
| 24 | Contact: Matteo Croce <mcroce@microsoft.com> | 24 | Contact: Matteo Croce <teknoraver@meta.com> |
| 25 | Description: CPU number to use to reboot. | 25 | Description: CPU number to use to reboot. |
| 26 | 26 | ||
| 27 | What: /sys/kernel/reboot/force | 27 | What: /sys/kernel/reboot/force |
| 28 | Date: November 2020 | 28 | Date: November 2020 |
| 29 | KernelVersion: 5.11 | 29 | KernelVersion: 5.11 |
| 30 | Contact: Matteo Croce <mcroce@microsoft.com> | 30 | Contact: Matteo Croce <teknoraver@meta.com> |
| 31 | Description: Don't wait for any other CPUs on reboot and | 31 | Description: Don't wait for any other CPUs on reboot and |
| 32 | avoid anything that could hang. | 32 | avoid anything that could hang. |
| 33 | 33 | ||
| @@ -22,3 +22,5 @@ are configurable at compile, boot or run time. · 21 unmodified lines | |||
| 22 | srso | 22 | srso |
| 23 | gather_data_sampling | 23 | gather_data_sampling |
| 24 | reg-file-data-sampling | 24 | reg-file-data-sampling |
| 25 | rsb | ||
| 26 | indirect-target-selection | ||
| @@ -0,0 +1,168 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | Indirect Target Selection (ITS) | ||
| 4 | =============================== | ||
| 5 | |||
| 6 | ITS is a vulnerability in some Intel CPUs that support Enhanced IBRS and were | ||
| 7 | released before Alder Lake. ITS may allow an attacker to control the prediction | ||
| 8 | of indirect branches and RETs located in the lower half of a cacheline. | ||
| 9 | |||
| 10 | ITS is assigned CVE-2024-28956 with a CVSS score of 4.7 (Medium). | ||
| 11 | |||
| 12 | Scope of Impact | ||
| 13 | --------------- | ||
| 14 | - **eIBRS Guest/Host Isolation**: Indirect branches in KVM/kernel may still be | ||
| 15 | predicted with unintended target corresponding to a branch in the guest. | ||
| 16 | |||
| 17 | - **Intra-Mode BTI**: In-kernel training such as through cBPF or other native | ||
| 18 | gadgets. | ||
| 19 | |||
| 20 | - **Indirect Branch Prediction Barrier (IBPB)**: After an IBPB, indirect | ||
| 21 | branches may still be predicted with targets corresponding to direct branches | ||
| 22 | executed prior to the IBPB. This is fixed by the IPU 2025.1 microcode, which | ||
| 23 | should be available via distro updates. Alternatively microcode can be | ||
| 24 | obtained from Intel's github repository [#f1]_. | ||
| 25 | |||
| 26 | Affected CPUs | ||
| 27 | ------------- | ||
| 28 | Below is the list of ITS affected CPUs [#f2]_ [#f3]_: | ||
| 29 | |||
| 30 | ======================== ============ ==================== =============== | ||
| 31 | Common name Family_Model eIBRS Intra-mode BTI | ||
| 32 | Guest/Host Isolation | ||
| 33 | ======================== ============ ==================== =============== | ||
| 34 | SKYLAKE_X (step >= 6) 06_55H Affected Affected | ||
| 35 | ICELAKE_X 06_6AH Not affected Affected | ||
| 36 | ICELAKE_D 06_6CH Not affected Affected | ||
| 37 | ICELAKE_L 06_7EH Not affected Affected | ||
| 38 | TIGERLAKE_L 06_8CH Not affected Affected | ||
| 39 | TIGERLAKE 06_8DH Not affected Affected | ||
| 40 | KABYLAKE_L (step >= 12) 06_8EH Affected Affected | ||
| 41 | KABYLAKE (step >= 13) 06_9EH Affected Affected | ||
| 42 | COMETLAKE 06_A5H Affected Affected | ||
| 43 | COMETLAKE_L 06_A6H Affected Affected | ||
| 44 | ROCKETLAKE 06_A7H Not affected Affected | ||
| 45 | ======================== ============ ==================== =============== | ||
| 46 | |||
| 47 | - All affected CPUs enumerate Enhanced IBRS feature. | ||
| 48 | - IBPB isolation is affected on all ITS affected CPUs, and need a microcode | ||
| 49 | update for mitigation. | ||
| 50 | - None of the affected CPUs enumerate BHI_CTRL which was introduced in Golden | ||
| 51 | Cove (Alder Lake and Sapphire Rapids). This can help guests to determine the | ||
| 52 | host's affected status. | ||
| 53 | - Intel Atom CPUs are not affected by ITS. | ||
| 54 | |||
| 55 | Mitigation | ||
| 56 | ---------- | ||
| 57 | As only the indirect branches and RETs that have their last byte of instruction | ||
| 58 | in the lower half of the cacheline are vulnerable to ITS, the basic idea behind | ||
| 59 | the mitigation is to not allow indirect branches in the lower half. | ||
| 60 | |||
| 61 | This is achieved by relying on existing retpoline support in the kernel, and in | ||
| 62 | compilers. ITS-vulnerable retpoline sites are runtime patched to point to newly | ||
| 63 | added ITS-safe thunks. These safe thunks consists of indirect branch in the | ||
| 64 | second half of the cacheline. Not all retpoline sites are patched to thunks, if | ||
| 65 | a retpoline site is evaluated to be ITS-safe, it is replaced with an inline | ||
| 66 | indirect branch. | ||
| 67 | |||
| 68 | Dynamic thunks | ||
| 69 | ~~~~~~~~~~~~~~ | ||
| 70 | From a dynamically allocated pool of safe-thunks, each vulnerable site is | ||
| 71 | replaced with a new thunk, such that they get a unique address. This could | ||
| 72 | improve the branch prediction accuracy. Also, it is a defense-in-depth measure | ||
| 73 | against aliasing. | ||
| 74 | |||
| 75 | Note, for simplicity, indirect branches in eBPF programs are always replaced | ||
| 76 | with a jump to a static thunk in __x86_indirect_its_thunk_array. If required, | ||
| 77 | in future this can be changed to use dynamic thunks. | ||
| 78 | |||
| 79 | All vulnerable RETs are replaced with a static thunk, they do not use dynamic | ||
| 80 | thunks. This is because RETs get their prediction from RSB mostly that does not | ||
| 81 | depend on source address. RETs that underflow RSB may benefit from dynamic | ||
| 82 | thunks. But, RETs significantly outnumber indirect branches, and any benefit | ||
| 83 | from a unique source address could be outweighed by the increased icache | ||
| 84 | footprint and iTLB pressure. | ||
| 85 | |||
| 86 | Retpoline | ||
| 87 | ~~~~~~~~~ | ||
| 88 | Retpoline sequence also mitigates ITS-unsafe indirect branches. For this | ||
| 89 | reason, when retpoline is enabled, ITS mitigation only relocates the RETs to | ||
| 90 | safe thunks. Unless user requested the RSB-stuffing mitigation. | ||
| 91 | |||
| 92 | RSB Stuffing | ||
| 93 | ~~~~~~~~~~~~ | ||
| 94 | RSB-stuffing via Call Depth Tracking is a mitigation for Retbleed RSB-underflow | ||
| 95 | attacks. And it also mitigates RETs that are vulnerable to ITS. | ||
| 96 | |||
| 97 | Mitigation in guests | ||
| 98 | ^^^^^^^^^^^^^^^^^^^^ | ||
| 99 | All guests deploy ITS mitigation by default, irrespective of eIBRS enumeration | ||
| 100 | and Family/Model of the guest. This is because eIBRS feature could be hidden | ||
| 101 | from a guest. One exception to this is when a guest enumerates BHI_DIS_S, which | ||
| 102 | indicates that the guest is running on an unaffected host. | ||
| 103 | |||
| 104 | To prevent guests from unnecessarily deploying the mitigation on unaffected | ||
| 105 | platforms, Intel has defined ITS_NO bit(62) in MSR IA32_ARCH_CAPABILITIES. When | ||
| 106 | a guest sees this bit set, it should not enumerate the ITS bug. Note, this bit | ||
| 107 | is not set by any hardware, but is **intended for VMMs to synthesize** it for | ||
| 108 | guests as per the host's affected status. | ||
| 109 | |||
| 110 | Mitigation options | ||
| 111 | ^^^^^^^^^^^^^^^^^^ | ||
| 112 | The ITS mitigation can be controlled using the "indirect_target_selection" | ||
| 113 | kernel parameter. The available options are: | ||
| 114 | |||
| 115 | ======== =================================================================== | ||
| 116 | on (default) Deploy the "Aligned branch/return thunks" mitigation. | ||
| 117 | If spectre_v2 mitigation enables retpoline, aligned-thunks are only | ||
| 118 | deployed for the affected RET instructions. Retpoline mitigates | ||
| 119 | indirect branches. | ||
| 120 | |||
| 121 | off Disable ITS mitigation. | ||
| 122 | |||
| 123 | vmexit Equivalent to "=on" if the CPU is affected by guest/host isolation | ||
| 124 | part of ITS. Otherwise, mitigation is not deployed. This option is | ||
| 125 | useful when host userspace is not in the threat model, and only | ||
| 126 | attacks from guest to host are considered. | ||
| 127 | |||
| 128 | stuff Deploy RSB-fill mitigation when retpoline is also deployed. | ||
| 129 | Otherwise, deploy the default mitigation. When retpoline mitigation | ||
| 130 | is enabled, RSB-stuffing via Call-Depth-Tracking also mitigates | ||
| 131 | ITS. | ||
| 132 | |||
| 133 | force Force the ITS bug and deploy the default mitigation. | ||
| 134 | ======== =================================================================== | ||
| 135 | |||
| 136 | Sysfs reporting | ||
| 137 | --------------- | ||
| 138 | |||
| 139 | The sysfs file showing ITS mitigation status is: | ||
| 140 | |||
| 141 | /sys/devices/system/cpu/vulnerabilities/indirect_target_selection | ||
| 142 | |||
| 143 | Note, microcode mitigation status is not reported in this file. | ||
| 144 | |||
| 145 | The possible values in this file are: | ||
| 146 | |||
| 147 | .. list-table:: | ||
| 148 | |||
| 149 | * - Not affected | ||
| 150 | - The processor is not vulnerable. | ||
| 151 | * - Vulnerable | ||
| 152 | - System is vulnerable and no mitigation has been applied. | ||
| 153 | * - Vulnerable, KVM: Not affected | ||
| 154 | - System is vulnerable to intra-mode BTI, but not affected by eIBRS | ||
| 155 | guest/host isolation. | ||
| 156 | * - Mitigation: Aligned branch/return thunks | ||
| 157 | - The mitigation is enabled, affected indirect branches and RETs are | ||
| 158 | relocated to safe thunks. | ||
| 159 | * - Mitigation: Retpolines, Stuffing RSB | ||
| 160 | - The mitigation is enabled using retpoline and RSB stuffing. | ||
| 161 | |||
| 162 | References | ||
| 163 | ---------- | ||
| 164 | .. [#f1] Microcode repository - https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files | ||
| 165 | |||
| 166 | .. [#f2] Affected Processors list - https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html | ||
| 167 | |||
| 168 | .. [#f3] Affected Processors list (machine readable) - https://github.com/intel/Intel-affected-processor-list | ||
| @@ -0,0 +1,268 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | ======================= | ||
| 4 | RSB-related mitigations | ||
| 5 | ======================= | ||
| 6 | |||
| 7 | .. warning:: | ||
| 8 | Please keep this document up-to-date, otherwise you will be | ||
| 9 | volunteered to update it and convert it to a very long comment in | ||
| 10 | bugs.c! | ||
| 11 | |||
| 12 | Since 2018 there have been many Spectre CVEs related to the Return Stack | ||
| 13 | Buffer (RSB) (sometimes referred to as the Return Address Stack (RAS) or | ||
| 14 | Return Address Predictor (RAP) on AMD). | ||
| 15 | |||
| 16 | Information about these CVEs and how to mitigate them is scattered | ||
| 17 | amongst a myriad of microarchitecture-specific documents. | ||
| 18 | |||
| 19 | This document attempts to consolidate all the relevant information in | ||
| 20 | once place and clarify the reasoning behind the current RSB-related | ||
| 21 | mitigations. It's meant to be as concise as possible, focused only on | ||
| 22 | the current kernel mitigations: what are the RSB-related attack vectors | ||
| 23 | and how are they currently being mitigated? | ||
| 24 | |||
| 25 | It's *not* meant to describe how the RSB mechanism operates or how the | ||
| 26 | exploits work. More details about those can be found in the references | ||
| 27 | below. | ||
| 28 | |||
| 29 | Rather, this is basically a glorified comment, but too long to actually | ||
| 30 | be one. So when the next CVE comes along, a kernel developer can | ||
| 31 | quickly refer to this as a refresher to see what we're actually doing | ||
| 32 | and why. | ||
| 33 | |||
| 34 | At a high level, there are two classes of RSB attacks: RSB poisoning | ||
| 35 | (Intel and AMD) and RSB underflow (Intel only). They must each be | ||
| 36 | considered individually for each attack vector (and microarchitecture | ||
| 37 | where applicable). | ||
| 38 | |||
| 39 | ---- | ||
| 40 | |||
| 41 | RSB poisoning (Intel and AMD) | ||
| 42 | ============================= | ||
| 43 | |||
| 44 | SpectreRSB | ||
| 45 | ~~~~~~~~~~ | ||
| 46 | |||
| 47 | RSB poisoning is a technique used by SpectreRSB [#spectre-rsb]_ where | ||
| 48 | an attacker poisons an RSB entry to cause a victim's return instruction | ||
| 49 | to speculate to an attacker-controlled address. This can happen when | ||
| 50 | there are unbalanced CALLs/RETs after a context switch or VMEXIT. | ||
| 51 | |||
| 52 | * All attack vectors can potentially be mitigated by flushing out any | ||
| 53 | poisoned RSB entries using an RSB filling sequence | ||
| 54 | [#intel-rsb-filling]_ [#amd-rsb-filling]_ when transitioning between | ||
| 55 | untrusted and trusted domains. But this has a performance impact and | ||
| 56 | should be avoided whenever possible. | ||
| 57 | |||
| 58 | .. DANGER:: | ||
| 59 | **FIXME**: Currently we're flushing 32 entries. However, some CPU | ||
| 60 | models have more than 32 entries. The loop count needs to be | ||
| 61 | increased for those. More detailed information is needed about RSB | ||
| 62 | sizes. | ||
| 63 | |||
| 64 | * On context switch, the user->user mitigation requires ensuring the | ||
| 65 | RSB gets filled or cleared whenever IBPB gets written [#cond-ibpb]_ | ||
| 66 | during a context switch: | ||
| 67 | |||
| 68 | * AMD: | ||
| 69 | On Zen 4+, IBPB (or SBPB [#amd-sbpb]_ if used) clears the RSB. | ||
| 70 | This is indicated by IBPB_RET in CPUID [#amd-ibpb-rsb]_. | ||
| 71 | |||
| 72 | On Zen < 4, the RSB filling sequence [#amd-rsb-filling]_ must be | ||
| 73 | always be done in addition to IBPB [#amd-ibpb-no-rsb]_. This is | ||
| 74 | indicated by X86_BUG_IBPB_NO_RET. | ||
| 75 | |||
| 76 | * Intel: | ||
| 77 | IBPB always clears the RSB: | ||
| 78 | |||
| 79 | "Software that executed before the IBPB command cannot control | ||
| 80 | the predicted targets of indirect branches executed after the | ||
| 81 | command on the same logical processor. The term indirect branch | ||
| 82 | in this context includes near return instructions, so these | ||
| 83 | predicted targets may come from the RSB." [#intel-ibpb-rsb]_ | ||
| 84 | |||
| 85 | * On context switch, user->kernel attacks are prevented by SMEP. User | ||
| 86 | space can only insert user space addresses into the RSB. Even | ||
| 87 | non-canonical addresses can't be inserted due to the page gap at the | ||
| 88 | end of the user canonical address space reserved by TASK_SIZE_MAX. | ||
| 89 | A SMEP #PF at instruction fetch prevents the kernel from speculatively | ||
| 90 | executing user space. | ||
| 91 | |||
| 92 | * AMD: | ||
| 93 | "Finally, branches that are predicted as 'ret' instructions get | ||
| 94 | their predicted targets from the Return Address Predictor (RAP). | ||
| 95 | AMD recommends software use a RAP stuffing sequence (mitigation | ||
| 96 | V2-3 in [2]) and/or Supervisor Mode Execution Protection (SMEP) | ||
| 97 | to ensure that the addresses in the RAP are safe for | ||
| 98 | speculation. Collectively, we refer to these mitigations as "RAP | ||
| 99 | Protection"." [#amd-smep-rsb]_ | ||
| 100 | |||
| 101 | * Intel: | ||
| 102 | "On processors with enhanced IBRS, an RSB overwrite sequence may | ||
| 103 | not suffice to prevent the predicted target of a near return | ||
| 104 | from using an RSB entry created in a less privileged predictor | ||
| 105 | mode. Software can prevent this by enabling SMEP (for | ||
| 106 | transitions from user mode to supervisor mode) and by having | ||
| 107 | IA32_SPEC_CTRL.IBRS set during VM exits." [#intel-smep-rsb]_ | ||
| 108 | |||
| 109 | * On VMEXIT, guest->host attacks are mitigated by eIBRS (and PBRSB | ||
| 110 | mitigation if needed): | ||
| 111 | |||
| 112 | * AMD: | ||
| 113 | "When Automatic IBRS is enabled, the internal return address | ||
| 114 | stack used for return address predictions is cleared on VMEXIT." | ||
| 115 | [#amd-eibrs-vmexit]_ | ||
| 116 | |||
| 117 | * Intel: | ||
| 118 | "On processors with enhanced IBRS, an RSB overwrite sequence may | ||
| 119 | not suffice to prevent the predicted target of a near return | ||
| 120 | from using an RSB entry created in a less privileged predictor | ||
| 121 | mode. Software can prevent this by enabling SMEP (for | ||
| 122 | transitions from user mode to supervisor mode) and by having | ||
| 123 | IA32_SPEC_CTRL.IBRS set during VM exits. Processors with | ||
| 124 | enhanced IBRS still support the usage model where IBRS is set | ||
| 125 | only in the OS/VMM for OSes that enable SMEP. To do this, such | ||
| 126 | processors will ensure that guest behavior cannot control the | ||
| 127 | RSB after a VM exit once IBRS is set, even if IBRS was not set | ||
| 128 | at the time of the VM exit." [#intel-eibrs-vmexit]_ | ||
| 129 | |||
| 130 | Note that some Intel CPUs are susceptible to Post-barrier Return | ||
| 131 | Stack Buffer Predictions (PBRSB) [#intel-pbrsb]_, where the last | ||
| 132 | CALL from the guest can be used to predict the first unbalanced RET. | ||
| 133 | In this case the PBRSB mitigation is needed in addition to eIBRS. | ||
| 134 | |||
| 135 | AMD RETBleed / SRSO / Branch Type Confusion | ||
| 136 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 137 | |||
| 138 | On AMD, poisoned RSB entries can also be created by the AMD RETBleed | ||
| 139 | variant [#retbleed-paper]_ [#amd-btc]_ or by Speculative Return Stack | ||
| 140 | Overflow [#amd-srso]_ (Inception [#inception-paper]_). The kernel | ||
| 141 | protects itself by replacing every RET in the kernel with a branch to a | ||
| 142 | single safe RET. | ||
| 143 | |||
| 144 | ---- | ||
| 145 | |||
| 146 | RSB underflow (Intel only) | ||
| 147 | ========================== | ||
| 148 | |||
| 149 | RSB Alternate (RSBA) ("Intel Retbleed") | ||
| 150 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 151 | |||
| 152 | Some Intel Skylake-generation CPUs are susceptible to the Intel variant | ||
| 153 | of RETBleed [#retbleed-paper]_ (Return Stack Buffer Underflow | ||
| 154 | [#intel-rsbu]_). If a RET is executed when the RSB buffer is empty due | ||
| 155 | to mismatched CALLs/RETs or returning from a deep call stack, the branch | ||
| 156 | predictor can fall back to using the Branch Target Buffer (BTB). If a | ||
| 157 | user forces a BTB collision then the RET can speculatively branch to a | ||
| 158 | user-controlled address. | ||
| 159 | |||
| 160 | * Note that RSB filling doesn't fully mitigate this issue. If there | ||
| 161 | are enough unbalanced RETs, the RSB may still underflow and fall back | ||
| 162 | to using a poisoned BTB entry. | ||
| 163 | |||
| 164 | * On context switch, user->user underflow attacks are mitigated by the | ||
| 165 | conditional IBPB [#cond-ibpb]_ on context switch which effectively | ||
| 166 | clears the BTB: | ||
| 167 | |||
| 168 | * "The indirect branch predictor barrier (IBPB) is an indirect branch | ||
| 169 | control mechanism that establishes a barrier, preventing software | ||
| 170 | that executed before the barrier from controlling the predicted | ||
| 171 | targets of indirect branches executed after the barrier on the same | ||
| 172 | logical processor." [#intel-ibpb-btb]_ | ||
| 173 | |||
| 174 | * On context switch and VMEXIT, user->kernel and guest->host RSB | ||
| 175 | underflows are mitigated by IBRS or eIBRS: | ||
| 176 | |||
| 177 | * "Enabling IBRS (including enhanced IBRS) will mitigate the "RSBU" | ||
| 178 | attack demonstrated by the researchers. As previously documented, | ||
| 179 | Intel recommends the use of enhanced IBRS, where supported. This | ||
| 180 | includes any processor that enumerates RRSBA but not RRSBA_DIS_S." | ||
| 181 | [#intel-rsbu]_ | ||
| 182 | |||
| 183 | However, note that eIBRS and IBRS do not mitigate intra-mode attacks. | ||
| 184 | Like RRSBA below, this is mitigated by clearing the BHB on kernel | ||
| 185 | entry. | ||
| 186 | |||
| 187 | As an alternative to classic IBRS, call depth tracking (combined with | ||
| 188 | retpolines) can be used to track kernel returns and fill the RSB when | ||
| 189 | it gets close to being empty. | ||
| 190 | |||
| 191 | Restricted RSB Alternate (RRSBA) | ||
| 192 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 193 | |||
| 194 | Some newer Intel CPUs have Restricted RSB Alternate (RRSBA) behavior, | ||
| 195 | which, similar to RSBA described above, also falls back to using the BTB | ||
| 196 | on RSB underflow. The only difference is that the predicted targets are | ||
| 197 | restricted to the current domain when eIBRS is enabled: | ||
| 198 | |||
| 199 | * "Restricted RSB Alternate (RRSBA) behavior allows alternate branch | ||
| 200 | predictors to be used by near RET instructions when the RSB is | ||
| 201 | empty. When eIBRS is enabled, the predicted targets of these | ||
| 202 | alternate predictors are restricted to those belonging to the | ||
| 203 | indirect branch predictor entries of the current prediction domain. | ||
| 204 | [#intel-eibrs-rrsba]_ | ||
| 205 | |||
| 206 | When a CPU with RRSBA is vulnerable to Branch History Injection | ||
| 207 | [#bhi-paper]_ [#intel-bhi]_, an RSB underflow could be used for an | ||
| 208 | intra-mode BTI attack. This is mitigated by clearing the BHB on | ||
| 209 | kernel entry. | ||
| 210 | |||
| 211 | However if the kernel uses retpolines instead of eIBRS, it needs to | ||
| 212 | disable RRSBA: | ||
| 213 | |||
| 214 | * "Where software is using retpoline as a mitigation for BHI or | ||
| 215 | intra-mode BTI, and the processor both enumerates RRSBA and | ||
| 216 | enumerates RRSBA_DIS controls, it should disable this behavior." | ||
| 217 | [#intel-retpoline-rrsba]_ | ||
| 218 | |||
| 219 | ---- | ||
| 220 | |||
| 221 | References | ||
| 222 | ========== | ||
| 223 | |||
| 224 | .. [#spectre-rsb] `Spectre Returns! Speculation Attacks using the Return Stack Buffer <https://arxiv.org/pdf/1807.07940.pdf>`_ | ||
| 225 | |||
| 226 | .. [#intel-rsb-filling] "Empty RSB Mitigation on Skylake-generation" in `Retpoline: A Branch Target Injection Mitigation <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/retpoline-branch-target-injection-mitigation.html#inpage-nav-5-1>`_ | ||
| 227 | |||
| 228 | .. [#amd-rsb-filling] "Mitigation V2-3" in `Software Techniques for Managing Speculation <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/software-techniques-for-managing-speculation.pdf>`_ | ||
| 229 | |||
| 230 | .. [#cond-ibpb] Whether IBPB is written depends on whether the prev and/or next task is protected from Spectre attacks. It typically requires opting in per task or system-wide. For more details see the documentation for the ``spectre_v2_user`` cmdline option in Documentation/admin-guide/kernel-parameters.txt. | ||
| 231 | |||
| 232 | .. [#amd-sbpb] IBPB without flushing of branch type predictions. Only exists for AMD. | ||
| 233 | |||
| 234 | .. [#amd-ibpb-rsb] "Function 8000_0008h -- Processor Capacity Parameters and Extended Feature Identification" in `AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24594.pdf>`_. SBPB behaves the same way according to `this email <https://lore.kernel.org/5175b163a3736ca5fd01cedf406735636c99a>`_. | ||
| 235 | |||
| 236 | .. [#amd-ibpb-no-rsb] `Spectre Attacks: Exploiting Speculative Execution <https://comsec.ethz.ch/wp-content/files/ibpb_sp25.pdf>`_ | ||
| 237 | |||
| 238 | .. [#intel-ibpb-rsb] "Introduction" in `Post-barrier Return Stack Buffer Predictions / CVE-2022-26373 / INTEL-SA-00706 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/post-barrier-return-stack-buffer-predictions.html>`_ | ||
| 239 | |||
| 240 | .. [#amd-smep-rsb] "Existing Mitigations" in `Technical Guidance for Mitigating Branch Type Confusion <https://www.amd.com/content/dam/amd/en/documents/resources/technical-guidance-for-mitigating-branch-type-confusion.pdf>`_ | ||
| 241 | |||
| 242 | .. [#intel-smep-rsb] "Enhanced IBRS" in `Indirect Branch Restricted Speculation <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/indirect-branch-restricted-speculation.html>`_ | ||
| 243 | |||
| 244 | .. [#amd-eibrs-vmexit] "Extended Feature Enable Register (EFER)" in `AMD64 Architecture Programmer's Manual Volume 2: System Programming <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf>`_ | ||
| 245 | |||
| 246 | .. [#intel-eibrs-vmexit] "Enhanced IBRS" in `Indirect Branch Restricted Speculation <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/indirect-branch-restricted-speculation.html>`_ | ||
| 247 | |||
| 248 | .. [#intel-pbrsb] `Post-barrier Return Stack Buffer Predictions / CVE-2022-26373 / INTEL-SA-00706 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/post-barrier-return-stack-buffer-predictions.html>`_ | ||
| 249 | |||
| 250 | .. [#retbleed-paper] `RETBleed: Arbitrary Speculative Code Execution with Return Instruction <https://comsec.ethz.ch/wp-content/files/retbleed_sec22.pdf>`_ | ||
| 251 | |||
| 252 | .. [#amd-btc] `Technical Guidance for Mitigating Branch Type Confusion <https://www.amd.com/content/dam/amd/en/documents/resources/technical-guidance-for-mitigating-branch-type-confusion.pdf>`_ | ||
| 253 | |||
| 254 | .. [#amd-srso] `Technical Update Regarding Speculative Return Stack Overflow <https://www.amd.com/content/dam/amd/en/documents/corporate/cr/speculative-return-stack-overflow-whitepaper.pdf>`_ | ||
| 255 | |||
| 256 | .. [#inception-paper] `Inception: Exposing New Attack Surfaces with Training in Transient Execution <https://comsec.ethz.ch/wp-content/files/inception_sec23.pdf>`_ | ||
| 257 | |||
| 258 | .. [#intel-rsbu] `Return Stack Buffer Underflow / Return Stack Buffer Underflow / CVE-2022-29901, CVE-2022-28693 / INTEL-SA-00702 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/return-stack-buffer-underflow.html>`_ | ||
| 259 | |||
| 260 | .. [#intel-ibpb-btb] `Indirect Branch Predictor Barrier' <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/indirect-branch-predictor-barrier.html>`_ | ||
| 261 | |||
| 262 | .. [#intel-eibrs-rrsba] "Guidance for RSBU" in `Return Stack Buffer Underflow / Return Stack Buffer Underflow / CVE-2022-29901, CVE-2022-28693 / INTEL-SA-00702 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/return-stack-buffer-underflow.html>`_ | ||
| 263 | |||
| 264 | .. [#bhi-paper] `Branch History Injection: On the Effectiveness of Hardware Mitigations Against Cross-Privilege Spectre-v2 Attacks <http://download.vusec.net/papers/bhi-spectre-bhb_sec22.pdf>`_ | ||
| 265 | |||
| 266 | .. [#intel-bhi] `Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html>`_ | ||
| 267 | |||
| 268 | .. [#intel-retpoline-rrsba] "Retpoline" in `Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598 <https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html>`_ | ||
| @@ -1407,18 +1407,15 @@ · 1406 unmodified lines | |||
| 1407 | earlyprintk=serial[,0x...[,baudrate]] | 1407 | earlyprintk=serial[,0x...[,baudrate]] |
| 1408 | earlyprintk=ttySn[,baudrate] | 1408 | earlyprintk=ttySn[,baudrate] |
| 1409 | earlyprintk=dbgp[debugController#] | 1409 | earlyprintk=dbgp[debugController#] |
| 1410 | earlyprintk=mmio32,membase[,{nocfg|baudrate}] | ||
| 1410 | earlyprintk=pciserial[,force],bus:device.function[,{nocfg|baudrate}] | 1411 | earlyprintk=pciserial[,force],bus:device.function[,{nocfg|baudrate}] |
| 1411 | earlyprintk=xdbc[xhciController#] | 1412 | earlyprintk=xdbc[xhciController#] |
| 1412 | earlyprintk=bios | 1413 | earlyprintk=bios |
| 1413 | earlyprintk=mmio,membase[,{nocfg|baudrate}] | ||
| 1414 | 1414 | ||
| 1415 | earlyprintk is useful when the kernel crashes before | 1415 | earlyprintk is useful when the kernel crashes before |
| 1416 | the normal console is initialized. It is not enabled by | 1416 | the normal console is initialized. It is not enabled by |
| 1417 | default because it has some cosmetic problems. | 1417 | default because it has some cosmetic problems. |
| 1418 | 1418 | ||
| 1419 | Only 32-bit memory addresses are supported for "mmio" | ||
| 1420 | and "pciserial" devices. | ||
| 1421 | |||
| 1422 | Use "nocfg" to skip UART configuration, assume | 1419 | Use "nocfg" to skip UART configuration, assume |
| 1423 | BIOS/firmware has configured UART correctly. | 1420 | BIOS/firmware has configured UART correctly. |
| 1424 | 1421 | ||
| @@ -2205,6 +2202,23 @@ · 780 unmodified lines | |||
| 2205 | different crypto accelerators. This option can be used | 2202 | different crypto accelerators. This option can be used |
| 2206 | to achieve best performance for particular HW. | 2203 | to achieve best performance for particular HW. |
| 2207 | 2204 | ||
| 2205 | indirect_target_selection= [X86,Intel] Mitigation control for Indirect | ||
| 2206 | Target Selection(ITS) bug in Intel CPUs. Updated | ||
| 2207 | microcode is also required for a fix in IBPB. | ||
| 2208 | |||
| 2209 | on: Enable mitigation (default). | ||
| 2210 | off: Disable mitigation. | ||
| 2211 | force: Force the ITS bug and deploy default | ||
| 2212 | mitigation. | ||
| 2213 | vmexit: Only deploy mitigation if CPU is affected by | ||
| 2214 | guest/host isolation part of ITS. | ||
| 2215 | stuff: Deploy RSB-fill mitigation when retpoline is | ||
| 2216 | also deployed. Otherwise, deploy the default | ||
| 2217 | mitigation. | ||
| 2218 | |||
| 2219 | For details see: | ||
| 2220 | Documentation/admin-guide/hw-vuln/indirect-target-selection.rst | ||
| 2221 | |||
| 2208 | init= [KNL] | 2222 | init= [KNL] |
| 2209 | Format: <full_path> | 2223 | Format: <full_path> |
| 2210 | Run specified binary instead of /sbin/init as init | 2224 | Run specified binary instead of /sbin/init as init |
| @@ -3696,6 +3710,7 @@ · 1485 unmodified lines | |||
| 3696 | expose users to several CPU vulnerabilities. | 3710 | expose users to several CPU vulnerabilities. |
| 3697 | Equivalent to: if nokaslr then kpti=0 [ARM64] | 3711 | Equivalent to: if nokaslr then kpti=0 [ARM64] |
| 3698 | gather_data_sampling=off [X86] | 3712 | gather_data_sampling=off [X86] |
| 3713 | indirect_target_selection=off [X86] | ||
| 3699 | kvm.nx_huge_pages=off [X86] | 3714 | kvm.nx_huge_pages=off [X86] |
| 3700 | l1tf=off [X86] | 3715 | l1tf=off [X86] |
| 3701 | mds=off [X86] | 3716 | mds=off [X86] |
| @@ -124,6 +124,14 @@ When mounting an XFS filesystem, the following options are accepted. · 123 unmodified lines | |||
| 124 | controls the size of each buffer and so is also relevant to | 124 | controls the size of each buffer and so is also relevant to |
| 125 | this case. | 125 | this case. |
| 126 | 126 | ||
| 127 | lifetime (default) or nolifetime | ||
| 128 | Enable data placement based on write life time hints provided | ||
| 129 | by the user. This turns on co-allocation of data of similar | ||
| 130 | life times when statistically favorable to reduce garbage | ||
| 131 | collection cost. | ||
| 132 | |||
| 133 | These options are only available for zoned rt file systems. | ||
| 134 | |||
| 127 | logbsize=value | 135 | logbsize=value |
| 128 | Set the size of each in-memory log buffer. The size may be | 136 | Set the size of each in-memory log buffer. The size may be |
| 129 | specified in bytes, or in kilobytes with a "k" suffix. | 137 | specified in bytes, or in kilobytes with a "k" suffix. |
| @@ -143,6 +151,14 @@ When mounting an XFS filesystem, the following options are accepted. · 13 unmodified lines | |||
| 143 | optional, and the log section can be separate from the data | 151 | optional, and the log section can be separate from the data |
| 144 | section or contained within it. | 152 | section or contained within it. |
| 145 | 153 | ||
| 154 | max_open_zones=value | ||
| 155 | Specify the max number of zones to keep open for writing on a | ||
| 156 | zoned rt device. Many open zones aids file data separation | ||
| 157 | but may impact performance on HDDs. | ||
| 158 | |||
| 159 | If ``max_open_zones`` is not specified, the value is determined | ||
| 160 | by the capabilities and the size of the zoned rt device. | ||
| 161 | |||
| 146 | noalign | 162 | noalign |
| 147 | Data allocations will not be aligned at stripe unit | 163 | Data allocations will not be aligned at stripe unit |
| 148 | boundaries. This is only relevant to filesystems created | 164 | boundaries. This is only relevant to filesystems created |
| @@ -542,3 +558,24 @@ The interesting knobs for XFS workqueues are as follows: · 393 unmodified lines | |||
| 542 | nice Relative priority of scheduling the threads. These are the | 558 | nice Relative priority of scheduling the threads. These are the |
| 543 | same nice levels that can be applied to userspace processes. | 559 | same nice levels that can be applied to userspace processes. |
| 544 | ============ =========== | 560 | ============ =========== |
| 561 | |||
| 562 | Zoned Filesystems | ||
| 563 | ================= | ||
| 564 | |||
| 565 | For zoned file systems, the following attributes are exposed in: | ||
| 566 | |||
| 567 | /sys/fs/xfs/<dev>/zoned/ | ||
| 568 | |||
| 569 | max_open_zones (Min: 1 Default: Varies Max: UINTMAX) | ||
| 570 | This read-only attribute exposes the maximum number of open zones | ||
| 571 | available for data placement. The value is determined at mount time and | ||
| 572 | is limited by the capabilities of the backing zoned device, file system | ||
| 573 | size and the max_open_zones mount option. | ||
| 574 | |||
| 575 | zonegc_low_space (Min: 0 Default: 0 Max: 100) | ||
| 576 | Define a percentage for how much of the unused space that GC should keep | ||
| 577 | available for writing. A high value will reclaim more of the space | ||
| 578 | occupied by unused blocks, creating a larger buffer against write | ||
| 579 | bursts at the cost of increased write amplification. Regardless | ||
| 580 | of this value, garbage collection will always aim to free a minimum | ||
| 581 | amount of blocks to keep max_open_zones open for data placement purposes. | ||
| @@ -7,10 +7,10 @@ target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k). · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | For information about OpenRISC processors and ongoing development: | 8 | For information about OpenRISC processors and ongoing development: |
| 9 | 9 | ||
| 10 | ======= ============================= | 10 | ======= ============================== |
| 11 | website https://openrisc.io | 11 | website https://openrisc.io |
| 12 | email openrisc@lists.librecores.org | 12 | email linux-openrisc@vger.kernel.org |
| 13 | ======= ============================= | 13 | ======= ============================== |
| 14 | 14 | ||
| 15 | --------------------------------------------------------------------- | 15 | --------------------------------------------------------------------- |
| 16 | 16 | ||
| @@ -27,11 +27,11 @@ Toolchain binaries can be obtained from openrisc.io or our github releases page. · 10 unmodified lines | |||
| 27 | Instructions for building the different toolchains can be found on openrisc.io | 27 | Instructions for building the different toolchains can be found on openrisc.io |
| 28 | or Stafford's toolchain build and release scripts. | 28 | or Stafford's toolchain build and release scripts. |
| 29 | 29 | ||
| 30 | ========== ================================================= | 30 | ========== ========================================================== |
| 31 | binaries https://github.com/openrisc/or1k-gcc/releases | 31 | binaries https://github.com/stffrdhrn/or1k-toolchain-build/releases |
| 32 | toolchains https://openrisc.io/software | 32 | toolchains https://openrisc.io/software |
| 33 | building https://github.com/stffrdhrn/or1k-toolchain-build | 33 | building https://github.com/stffrdhrn/or1k-toolchain-build |
| 34 | ========== ================================================= | 34 | ========== ========================================================== |
| 35 | 35 | ||
| 36 | 2) Building | 36 | 2) Building |
| 37 | 37 | ||
| @@ -51,7 +51,7 @@ The following keys are defined: · 50 unmodified lines | |||
| 51 | * :c:macro:`RISCV_HWPROBE_KEY_MARCHID`: Contains the value of ``marchid``, as | 51 | * :c:macro:`RISCV_HWPROBE_KEY_MARCHID`: Contains the value of ``marchid``, as |
| 52 | defined by the RISC-V privileged architecture specification. | 52 | defined by the RISC-V privileged architecture specification. |
| 53 | 53 | ||
| 54 | * :c:macro:`RISCV_HWPROBE_KEY_MIMPLID`: Contains the value of ``mimplid``, as | 54 | * :c:macro:`RISCV_HWPROBE_KEY_MIMPID`: Contains the value of ``mimpid``, as |
| 55 | defined by the RISC-V privileged architecture specification. | 55 | defined by the RISC-V privileged architecture specification. |
| 56 | 56 | ||
| 57 | * :c:macro:`RISCV_HWPROBE_KEY_BASE_BEHAVIOR`: A bitmask containing the base | 57 | * :c:macro:`RISCV_HWPROBE_KEY_BASE_BEHAVIOR`: A bitmask containing the base |
| @@ -79,8 +79,9 @@ feature flags. · 78 unmodified lines | |||
| 79 | How are feature flags created? | 79 | How are feature flags created? |
| 80 | ============================== | 80 | ============================== |
| 81 | 81 | ||
| 82 | a: Feature flags can be derived from the contents of CPUID leaves. | 82 | Feature flags can be derived from the contents of CPUID leaves |
| 83 | ------------------------------------------------------------------ | 83 | -------------------------------------------------------------- |
| 84 | |||
| 84 | These feature definitions are organized mirroring the layout of CPUID | 85 | These feature definitions are organized mirroring the layout of CPUID |
| 85 | leaves and grouped in words with offsets as mapped in enum cpuid_leafs | 86 | leaves and grouped in words with offsets as mapped in enum cpuid_leafs |
| 86 | in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details). | 87 | in cpufeatures.h (see arch/x86/include/asm/cpufeatures.h for details). |
| @@ -89,8 +90,9 @@ cpufeatures.h, and if it is detected at run time, the flags will be · 2 unmodified lines | |||
| 89 | displayed accordingly in /proc/cpuinfo. For example, the flag "avx2" | 90 | displayed accordingly in /proc/cpuinfo. For example, the flag "avx2" |
| 90 | comes from X86_FEATURE_AVX2 in cpufeatures.h. | 91 | comes from X86_FEATURE_AVX2 in cpufeatures.h. |
| 91 | 92 | ||
| 92 | b: Flags can be from scattered CPUID-based features. | 93 | Flags can be from scattered CPUID-based features |
| 93 | ---------------------------------------------------- | 94 | ------------------------------------------------ |
| 95 | |||
| 94 | Hardware features enumerated in sparsely populated CPUID leaves get | 96 | Hardware features enumerated in sparsely populated CPUID leaves get |
| 95 | software-defined values. Still, CPUID needs to be queried to determine | 97 | software-defined values. Still, CPUID needs to be queried to determine |
| 96 | if a given feature is present. This is done in init_scattered_cpuid_features(). | 98 | if a given feature is present. This is done in init_scattered_cpuid_features(). |
| @@ -104,8 +106,9 @@ has only one feature and would waste 31 bits of space in the x86_capability[] · 7 unmodified lines | |||
| 104 | array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted | 106 | array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted |
| 105 | memory is not trivial. | 107 | memory is not trivial. |
| 106 | 108 | ||
| 107 | c: Flags can be created synthetically under certain conditions for hardware features. | 109 | Flags can be created synthetically under certain conditions for hardware features |
| 108 | ------------------------------------------------------------------------------------- | 110 | --------------------------------------------------------------------------------- |
| 111 | |||
| 109 | Examples of conditions include whether certain features are present in | 112 | Examples of conditions include whether certain features are present in |
| 110 | MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed | 113 | MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed |
| 111 | conditions are met, the features are enabled by the set_cpu_cap or | 114 | conditions are met, the features are enabled by the set_cpu_cap or |
| @@ -114,8 +117,8 @@ the feature X86_FEATURE_SPLIT_LOCK_DETECT will be enabled and · 2 unmodified lines | |||
| 114 | "split_lock_detect" will be displayed. The flag "ring3mwait" will be | 117 | "split_lock_detect" will be displayed. The flag "ring3mwait" will be |
| 115 | displayed only when running on INTEL_XEON_PHI_[KNL|KNM] processors. | 118 | displayed only when running on INTEL_XEON_PHI_[KNL|KNM] processors. |
| 116 | 119 | ||
| 117 | d: Flags can represent purely software features. | 120 | Flags can represent purely software features |
| 118 | ------------------------------------------------ | 121 | -------------------------------------------- |
| 119 | These flags do not represent hardware features. Instead, they represent a | 122 | These flags do not represent hardware features. Instead, they represent a |
| 120 | software feature implemented in the kernel. For example, Kernel Page Table | 123 | software feature implemented in the kernel. For example, Kernel Page Table |
| 121 | Isolation is purely software feature and its feature flag X86_FEATURE_PTI is | 124 | Isolation is purely software feature and its feature flag X86_FEATURE_PTI is |
| @@ -130,14 +133,18 @@ x86_cap/bug_flags[] arrays in kernel/cpu/capflags.c. The names in the · 8 unmodified lines | |||
| 130 | resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming | 133 | resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming |
| 131 | of flags in the x86_cap/bug_flags[] are as follows: | 134 | of flags in the x86_cap/bug_flags[] are as follows: |
| 132 | 135 | ||
| 133 | a: The name of the flag is from the string in X86_FEATURE_<name> by default. | 136 | Flags do not appear by default in /proc/cpuinfo |
| 134 | ---------------------------------------------------------------------------- | 137 | ----------------------------------------------- |
| 135 | By default, the flag <name> in /proc/cpuinfo is extracted from the respective | 138 | |
| 136 | X86_FEATURE_<name> in cpufeatures.h. For example, the flag "avx2" is from | 139 | Feature flags are omitted by default from /proc/cpuinfo as it does not make |
| 137 | X86_FEATURE_AVX2. | 140 | sense for the feature to be exposed to userspace in most cases. For example, |
| 141 | X86_FEATURE_ALWAYS is defined in cpufeatures.h but that flag is an internal | ||
| 142 | kernel feature used in the alternative runtime patching functionality. So the | ||
| 143 | flag does not appear in /proc/cpuinfo. | ||
| 144 | |||
| 145 | Specify a flag name if absolutely needed | ||
| 146 | ---------------------------------------- | ||
| 138 | 147 | ||
| 139 | b: The naming can be overridden. | ||
| 140 | -------------------------------- | ||
| 141 | If the comment on the line for the #define X86_FEATURE_* starts with a | 148 | If the comment on the line for the #define X86_FEATURE_* starts with a |
| 142 | double-quote character (""), the string inside the double-quote characters | 149 | double-quote character (""), the string inside the double-quote characters |
| 143 | will be the name of the flags. For example, the flag "sse4_1" comes from | 150 | will be the name of the flags. For example, the flag "sse4_1" comes from |
| @@ -148,36 +155,31 @@ needed. For instance, /proc/cpuinfo is a userspace interface and must remain · 4 unmodified lines | |||
| 148 | constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one | 155 | constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one |
| 149 | shall override the new naming with the name already used in /proc/cpuinfo. | 156 | shall override the new naming with the name already used in /proc/cpuinfo. |
| 150 | 157 | ||
| 151 | c: The naming override can be "", which means it will not appear in /proc/cpuinfo. | ||
| 152 | ---------------------------------------------------------------------------------- | ||
| 153 | The feature shall be omitted from /proc/cpuinfo if it does not make sense for | ||
| 154 | the feature to be exposed to userspace. For example, X86_FEATURE_ALWAYS is | ||
| 155 | defined in cpufeatures.h but that flag is an internal kernel feature used | ||
| 156 | in the alternative runtime patching functionality. So, its name is overridden | ||
| 157 | with "". Its flag will not appear in /proc/cpuinfo. | ||
| 158 | |||
| 159 | Flags are missing when one or more of these happen | 158 | Flags are missing when one or more of these happen |
| 160 | ================================================== | 159 | ================================================== |
| 161 | 160 | ||
| 162 | a: The hardware does not enumerate support for it. | 161 | The hardware does not enumerate support for it |
| 163 | -------------------------------------------------- | 162 | ---------------------------------------------- |
| 163 | |||
| 164 | For example, when a new kernel is running on old hardware or the feature is | 164 | For example, when a new kernel is running on old hardware or the feature is |
| 165 | not enabled by boot firmware. Even if the hardware is new, there might be a | 165 | not enabled by boot firmware. Even if the hardware is new, there might be a |
| 166 | problem enabling the feature at run time, the flag will not be displayed. | 166 | problem enabling the feature at run time, the flag will not be displayed. |
| 167 | 167 | ||
| 168 | b: The kernel does not know about the flag. | 168 | The kernel does not know about the flag |
| 169 | ------------------------------------------- | 169 | --------------------------------------- |
| 170 | |||
| 170 | For example, when an old kernel is running on new hardware. | 171 | For example, when an old kernel is running on new hardware. |
| 171 | 172 | ||
| 172 | c: The kernel disabled support for it at compile-time. | 173 | The kernel disabled support for it at compile-time |
| 173 | ------------------------------------------------------ | 174 | -------------------------------------------------- |
| 175 | |||
| 174 | For example, if 5-level-paging is not enabled when building (i.e., | 176 | For example, if 5-level-paging is not enabled when building (i.e., |
| 175 | CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_. | 177 | CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_. |
| 176 | Even though the feature will still be detected via CPUID, the kernel disables | 178 | Even though the feature will still be detected via CPUID, the kernel disables |
| 177 | it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57). | 179 | it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57). |
| 178 | 180 | ||
| 179 | d: The feature is disabled at boot-time. | 181 | The feature is disabled at boot-time |
| 180 | ---------------------------------------- | 182 | ------------------------------------ |
| 181 | A feature can be disabled either using a command-line parameter or because | 183 | A feature can be disabled either using a command-line parameter or because |
| 182 | it failed to be enabled. The command-line parameter clearcpuid= can be used | 184 | it failed to be enabled. The command-line parameter clearcpuid= can be used |
| 183 | to disable features using the feature number as defined in | 185 | to disable features using the feature number as defined in |
| @@ -190,8 +192,9 @@ disable specific features. The list of parameters includes, but is not limited · 6 unmodified lines | |||
| 190 | to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using | 192 | to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using |
| 191 | "no5lvl". | 193 | "no5lvl". |
| 192 | 194 | ||
| 193 | e: The feature was known to be non-functional. | 195 | The feature was known to be non-functional |
| 194 | ---------------------------------------------- | 196 | ------------------------------------------ |
| 197 | |||
| 195 | The feature was known to be non-functional because a dependency was | 198 | The feature was known to be non-functional because a dependency was |
| 196 | missing at runtime. For example, AVX flags will not show up if XSAVE feature | 199 | missing at runtime. For example, AVX flags will not show up if XSAVE feature |
| 197 | is disabled since they depend on XSAVE feature. Another example would be broken | 200 | is disabled since they depend on XSAVE feature. Another example would be broken |
| @@ -382,6 +382,14 @@ In case of new BPF instructions, once the changes have been accepted · 381 unmodified lines | |||
| 382 | into the Linux kernel, please implement support into LLVM's BPF back | 382 | into the Linux kernel, please implement support into LLVM's BPF back |
| 383 | end. See LLVM_ section below for further information. | 383 | end. See LLVM_ section below for further information. |
| 384 | 384 | ||
| 385 | Q: What "BPF_INTERNAL" symbol namespace is for? | ||
| 386 | ----------------------------------------------- | ||
| 387 | A: Symbols exported as BPF_INTERNAL can only be used by BPF infrastructure | ||
| 388 | like preload kernel modules with light skeleton. Most symbols outside | ||
| 389 | of BPF_INTERNAL are not expected to be used by code outside of BPF either. | ||
| 390 | Symbols may lack the designation because they predate the namespaces, | ||
| 391 | or due to an oversight. | ||
| 392 | |||
| 385 | Stable submission | 393 | Stable submission |
| 386 | ================= | 394 | ================= |
| 387 | 395 | ||
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Ceva AHCI SATA Controller | 7 | title: Ceva AHCI SATA Controller |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 11 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | ||
| 13 | description: | | 12 | description: | |
| @@ -111,11 +111,27 @@ properties: · 110 unmodified lines | |||
| 111 | unevaluatedProperties: false | 111 | unevaluatedProperties: false |
| 112 | 112 | ||
| 113 | port@1: | 113 | port@1: |
| 114 | $ref: /schemas/graph.yaml#/properties/port | 114 | $ref: /schemas/graph.yaml#/$defs/port-base |
| 115 | unevaluatedProperties: false | ||
| 115 | description: | 116 | description: |
| 116 | DSI output port node to the panel or the next bridge | 117 | DSI output port node to the panel or the next bridge |
| 117 | in the chain | 118 | in the chain |
| 118 | 119 | ||
| 120 | properties: | ||
| 121 | endpoint: | ||
| 122 | $ref: /schemas/media/video-interfaces.yaml# | ||
| 123 | unevaluatedProperties: false | ||
| 124 | |||
| 125 | properties: | ||
| 126 | data-lanes: | ||
| 127 | description: array of physical DSI data lane indexes. | ||
| 128 | minItems: 1 | ||
| 129 | items: | ||
| 130 | - const: 1 | ||
| 131 | - const: 2 | ||
| 132 | - const: 3 | ||
| 133 | - const: 4 | ||
| 134 | |||
| 119 | required: | 135 | required: |
| 120 | - port@0 | 136 | - port@0 |
| 121 | - port@1 | 137 | - port@1 |
| @@ -12,7 +12,6 @@ description: · 11 unmodified lines | |||
| 12 | PS_MODE). Every pin can be configured as input/output. | 12 | PS_MODE). Every pin can be configured as input/output. |
| 13 | 13 | ||
| 14 | maintainers: | 14 | maintainers: |
| 15 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 16 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 15 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 17 | 16 | ||
| 18 | properties: | 17 | properties: |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Mediatek's Keypad Controller | 7 | title: Mediatek's Keypad Controller |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Mattijs Korpershoek <mkorpershoek@baylibre.com> | 10 | - Mattijs Korpershoek <mkorpershoek@kernel.org> |
| 11 | 11 | ||
| 12 | allOf: | 12 | allOf: |
| 13 | - $ref: /schemas/input/matrix-keymap.yaml# | 13 | - $ref: /schemas/input/matrix-keymap.yaml# |
| @@ -19,6 +19,7 @@ properties: · 18 unmodified lines | |||
| 19 | - fsl,imx8mp-irqsteer | 19 | - fsl,imx8mp-irqsteer |
| 20 | - fsl,imx8qm-irqsteer | 20 | - fsl,imx8qm-irqsteer |
| 21 | - fsl,imx8qxp-irqsteer | 21 | - fsl,imx8qxp-irqsteer |
| 22 | - fsl,imx94-irqsteer | ||
| 22 | - const: fsl,imx-irqsteer | 23 | - const: fsl,imx-irqsteer |
| 23 | 24 | ||
| 24 | reg: | 25 | reg: |
| @@ -1,7 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: http://devicetree.org/schemas/can/microchip,mcp2510.yaml# | 4 | $id: http://devicetree.org/schemas/net/can/microchip,mcp2510.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Microchip MCP251X stand-alone CAN controller | 7 | title: Microchip MCP251X stand-alone CAN controller |
| @@ -74,19 +74,17 @@ properties: · 73 unmodified lines | |||
| 74 | - rev-rmii | 74 | - rev-rmii |
| 75 | - moca | 75 | - moca |
| 76 | 76 | ||
| 77 | # RX and TX delays are added by the MAC when required | 77 | # RX and TX delays are provided by the PCB. See below |
| 78 | - rgmii | 78 | - rgmii |
| 79 | 79 | ||
| 80 | # RGMII with internal RX and TX delays provided by the PHY, | 80 | # RX and TX delays are not provided by the PCB. This is the most |
| 81 | # the MAC should not add the RX or TX delays in this case | 81 | # frequent case. See below |
| 82 | - rgmii-id | 82 | - rgmii-id |
| 83 | 83 | ||
| 84 | # RGMII with internal RX delay provided by the PHY, the MAC | 84 | # TX delay is provided by the PCB. See below |
| 85 | # should not add an RX delay in this case | ||
| 86 | - rgmii-rxid | 85 | - rgmii-rxid |
| 87 | 86 | ||
| 88 | # RGMII with internal TX delay provided by the PHY, the MAC | 87 | # RX delay is provided by the PCB. See below |
| 89 | # should not add an TX delay in this case | ||
| 90 | - rgmii-txid | 88 | - rgmii-txid |
| 91 | - rtbi | 89 | - rtbi |
| 92 | - smii | 90 | - smii |
| @@ -286,4 +284,89 @@ allOf: · 193 unmodified lines | |||
| 286 | 284 | ||
| 287 | additionalProperties: true | 285 | additionalProperties: true |
| 288 | 286 | ||
| 287 | # Informative | ||
| 288 | # =========== | ||
| 289 | # | ||
| 290 | # 'phy-modes' & 'phy-connection-type' properties 'rgmii', 'rgmii-id', | ||
| 291 | # 'rgmii-rxid', and 'rgmii-txid' are frequently used wrongly by | ||
| 292 | # developers. This informative section clarifies their usage. | ||
| 293 | # | ||
| 294 | # The RGMII specification requires a 2ns delay between the data and | ||
| 295 | # clock signals on the RGMII bus. How this delay is implemented is not | ||
| 296 | # specified. | ||
| 297 | # | ||
| 298 | # One option is to make the clock traces on the PCB longer than the | ||
| 299 | # data traces. A sufficiently difference in length can provide the 2ns | ||
| 300 | # delay. If both the RX and TX delays are implemented in this manner, | ||
| 301 | # 'rgmii' should be used, so indicating the PCB adds the delays. | ||
| 302 | # | ||
| 303 | # If the PCB does not add these delays via extra long traces, | ||
| 304 | # 'rgmii-id' should be used. Here, 'id' refers to 'internal delay', | ||
| 305 | # where either the MAC or PHY adds the delay. | ||
| 306 | # | ||
| 307 | # If only one of the two delays are implemented via extra long clock | ||
| 308 | # lines, either 'rgmii-rxid' or 'rgmii-txid' should be used, | ||
| 309 | # indicating the MAC or PHY should implement one of the delays | ||
| 310 | # internally, while the PCB implements the other delay. | ||
| 311 | # | ||
| 312 | # Device Tree describes hardware, and in this case, it describes the | ||
| 313 | # PCB between the MAC and the PHY, if the PCB implements delays or | ||
| 314 | # not. | ||
| 315 | # | ||
| 316 | # In practice, very few PCBs make use of extra long clock lines. Hence | ||
| 317 | # any RGMII phy mode other than 'rgmii-id' is probably wrong, and is | ||
| 318 | # unlikely to be accepted during review without details provided in | ||
| 319 | # the commit description and comments in the .dts file. | ||
| 320 | # | ||
| 321 | # When the PCB does not implement the delays, the MAC or PHY must. As | ||
| 322 | # such, this is software configuration, and so not described in Device | ||
| 323 | # Tree. | ||
| 324 | # | ||
| 325 | # The following describes how Linux implements the configuration of | ||
| 326 | # the MAC and PHY to add these delays when the PCB does not. As stated | ||
| 327 | # above, developers often get this wrong, and the aim of this section | ||
| 328 | # is reduce the frequency of these errors by Linux developers. Other | ||
| 329 | # users of the Device Tree may implement it differently, and still be | ||
| 330 | # consistent with both the normative and informative description | ||
| 331 | # above. | ||
| 332 | # | ||
| 333 | # By default in Linux, when using phylib/phylink, the MAC is expected | ||
| 334 | # to read the 'phy-mode' from Device Tree, not implement any delays, | ||
| 335 | # and pass the value to the PHY. The PHY will then implement delays as | ||
| 336 | # specified by the 'phy-mode'. The PHY should always be reconfigured | ||
| 337 | # to implement the needed delays, replacing any setting performed by | ||
| 338 | # strapping or the bootloader, etc. | ||
| 339 | # | ||
| 340 | # Experience to date is that all PHYs which implement RGMII also | ||
| 341 | # implement the ability to add or not add the needed delays. Hence | ||
| 342 | # this default is expected to work in all cases. Ignoring this default | ||
| 343 | # is likely to be questioned by Reviews, and require a strong argument | ||
| 344 | # to be accepted. | ||
| 345 | # | ||
| 346 | # There are a small number of cases where the MAC has hard coded | ||
| 347 | # delays which cannot be disabled. The 'phy-mode' only describes the | ||
| 348 | # PCB. The inability to disable the delays in the MAC does not change | ||
| 349 | # the meaning of 'phy-mode'. It does however mean that a 'phy-mode' of | ||
| 350 | # 'rgmii' is now invalid, it cannot be supported, since both the PCB | ||
| 351 | # and the MAC and PHY adding delays cannot result in a functional | ||
| 352 | # link. Thus the MAC should report a fatal error for any modes which | ||
| 353 | # cannot be supported. When the MAC implements the delay, it must | ||
| 354 | # ensure that the PHY does not also implement the same delay. So it | ||
| 355 | # must modify the phy-mode it passes to the PHY, removing the delay it | ||
| 356 | # has added. Failure to remove the delay will result in a | ||
| 357 | # non-functioning link. | ||
| 358 | # | ||
| 359 | # Sometimes there is a need to fine tune the delays. Often the MAC or | ||
| 360 | # PHY can perform this fine tuning. In the MAC node, the Device Tree | ||
| 361 | # properties 'rx-internal-delay-ps' and 'tx-internal-delay-ps' should | ||
| 362 | # be used to indicate fine tuning performed by the MAC. The values | ||
| 363 | # expected here are small. A value of 2000ps, i.e 2ns, and a phy-mode | ||
| 364 | # of 'rgmii' will not be accepted by Reviewers. | ||
| 365 | # | ||
| 366 | # If the PHY is to perform fine tuning, the properties | ||
| 367 | # 'rx-internal-delay-ps' and 'tx-internal-delay-ps' in the PHY node | ||
| 368 | # should be used. When the PHY is implementing delays, e.g. 'rgmii-id' | ||
| 369 | # these properties should have a value near to 2000ps. If the PCB is | ||
| 370 | # implementing delays, e.g. 'rgmii', a small value can be used to fine | ||
| 371 | # tune the delay added by the PCB. | ||
| 289 | ... | 372 | ... |
| @@ -27,7 +27,7 @@ properties: · 26 unmodified lines | |||
| 27 | $ref: /schemas/types.yaml#/definitions/uint32-array | 27 | $ref: /schemas/types.yaml#/definitions/uint32-array |
| 28 | items: | 28 | items: |
| 29 | - minimum: 0 | 29 | - minimum: 0 |
| 30 | maximum: 7 | 30 | maximum: 31 |
| 31 | description: | 31 | description: |
| 32 | Offset in bit within the address range specified by reg. | 32 | Offset in bit within the address range specified by reg. |
| 33 | - minimum: 1 | 33 | - minimum: 1 |
| @@ -19,6 +19,7 @@ properties: · 18 unmodified lines | |||
| 19 | - enum: | 19 | - enum: |
| 20 | - qcom,apq8064-qfprom | 20 | - qcom,apq8064-qfprom |
| 21 | - qcom,apq8084-qfprom | 21 | - qcom,apq8084-qfprom |
| 22 | - qcom,ipq5018-qfprom | ||
| 22 | - qcom,ipq5332-qfprom | 23 | - qcom,ipq5332-qfprom |
| 23 | - qcom,ipq5424-qfprom | 24 | - qcom,ipq5424-qfprom |
| 24 | - qcom,ipq6018-qfprom | 25 | - qcom,ipq6018-qfprom |
| @@ -28,6 +29,8 @@ properties: · 3 unmodified lines | |||
| 28 | - qcom,msm8226-qfprom | 29 | - qcom,msm8226-qfprom |
| 29 | - qcom,msm8916-qfprom | 30 | - qcom,msm8916-qfprom |
| 30 | - qcom,msm8917-qfprom | 31 | - qcom,msm8917-qfprom |
| 32 | - qcom,msm8937-qfprom | ||
| 33 | - qcom,msm8960-qfprom | ||
| 31 | - qcom,msm8974-qfprom | 34 | - qcom,msm8974-qfprom |
| 32 | - qcom,msm8976-qfprom | 35 | - qcom,msm8976-qfprom |
| 33 | - qcom,msm8996-qfprom | 36 | - qcom,msm8996-qfprom |
| @@ -51,6 +54,7 @@ properties: · 17 unmodified lines | |||
| 51 | - qcom,sm8450-qfprom | 54 | - qcom,sm8450-qfprom |
| 52 | - qcom,sm8550-qfprom | 55 | - qcom,sm8550-qfprom |
| 53 | - qcom,sm8650-qfprom | 56 | - qcom,sm8650-qfprom |
| 57 | - qcom,x1e80100-qfprom | ||
| 54 | - const: qcom,qfprom | 58 | - const: qcom,qfprom |
| 55 | 59 | ||
| 56 | reg: | 60 | reg: |
| @@ -14,6 +14,7 @@ properties: · 13 unmodified lines | |||
| 14 | enum: | 14 | enum: |
| 15 | - rockchip,px30-otp | 15 | - rockchip,px30-otp |
| 16 | - rockchip,rk3308-otp | 16 | - rockchip,rk3308-otp |
| 17 | - rockchip,rk3576-otp | ||
| 17 | - rockchip,rk3588-otp | 18 | - rockchip,rk3588-otp |
| 18 | 19 | ||
| 19 | reg: | 20 | reg: |
| @@ -62,12 +63,34 @@ allOf: · 42 unmodified lines | |||
| 62 | properties: | 63 | properties: |
| 63 | clocks: | 64 | clocks: |
| 64 | maxItems: 3 | 65 | maxItems: 3 |
| 66 | clock-names: | ||
| 67 | maxItems: 3 | ||
| 65 | resets: | 68 | resets: |
| 66 | maxItems: 1 | 69 | maxItems: 1 |
| 67 | reset-names: | 70 | reset-names: |
| 68 | items: | 71 | items: |
| 69 | - const: phy | 72 | - const: phy |
| 70 | 73 | ||
| 74 | - if: | ||
| 75 | properties: | ||
| 76 | compatible: | ||
| 77 | contains: | ||
| 78 | enum: | ||
| 79 | - rockchip,rk3576-otp | ||
| 80 | then: | ||
| 81 | properties: | ||
| 82 | clocks: | ||
| 83 | maxItems: 3 | ||
| 84 | clock-names: | ||
| 85 | maxItems: 3 | ||
| 86 | resets: | ||
| 87 | minItems: 2 | ||
| 88 | maxItems: 2 | ||
| 89 | reset-names: | ||
| 90 | items: | ||
| 91 | - const: otp | ||
| 92 | - const: apb | ||
| 93 | |||
| 71 | - if: | 94 | - if: |
| 72 | properties: | 95 | properties: |
| 73 | compatible: | 96 | compatible: |
| @@ -78,6 +101,8 @@ allOf: · 4 unmodified lines | |||
| 78 | properties: | 101 | properties: |
| 79 | clocks: | 102 | clocks: |
| 80 | minItems: 4 | 103 | minItems: 4 |
| 104 | clock-names: | ||
| 105 | minItems: 4 | ||
| 81 | resets: | 106 | resets: |
| 82 | minItems: 3 | 107 | minItems: 3 |
| 83 | reset-names: | 108 | reset-names: |
| @@ -9,15 +9,6 @@ title: Renesas R-Car Timer Pulse Unit PWM Controller · 8 unmodified lines | |||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 10 | - Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| 11 | 11 | ||
| 12 | select: | ||
| 13 | properties: | ||
| 14 | compatible: | ||
| 15 | contains: | ||
| 16 | const: renesas,tpu | ||
| 17 | required: | ||
| 18 | - compatible | ||
| 19 | - '#pwm-cells' | ||
| 20 | |||
| 21 | properties: | 12 | properties: |
| 22 | compatible: | 13 | compatible: |
| 23 | items: | 14 | items: |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Zynq UltraScale+ MPSoC and Versal reset | 7 | title: Zynq UltraScale+ MPSoC and Versal reset |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 11 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | ||
| 13 | description: | | 12 | description: | |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Freescale Layerscape Reset Registers Module | 7 | title: Freescale Layerscape Reset Registers Module |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Frank Li | 10 | - Frank Li <Frank.Li@nxp.com> |
| 11 | 11 | ||
| 12 | description: | 12 | description: |
| 13 | Reset Module includes chip reset, service processor control and Reset Control | 13 | Reset Module includes chip reset, service processor control and Reset Control |
| @@ -56,19 +56,18 @@ properties: · 55 unmodified lines | |||
| 56 | enum: | 56 | enum: |
| 57 | - snps,dw-apb-ssi | 57 | - snps,dw-apb-ssi |
| 58 | - snps,dwc-ssi-1.01a | 58 | - snps,dwc-ssi-1.01a |
| 59 | - description: Microsemi Ocelot/Jaguar2 SoC SPI Controller | ||
| 60 | items: | ||
| 61 | - enum: | ||
| 62 | - mscc,ocelot-spi | ||
| 63 | - mscc,jaguar2-spi | ||
| 64 | - const: snps,dw-apb-ssi | ||
| 65 | - description: Microchip Sparx5 SoC SPI Controller | 59 | - description: Microchip Sparx5 SoC SPI Controller |
| 66 | const: microchip,sparx5-spi | 60 | const: microchip,sparx5-spi |
| 67 | - description: Amazon Alpine SPI Controller | 61 | - description: Amazon Alpine SPI Controller |
| 68 | const: amazon,alpine-dw-apb-ssi | 62 | const: amazon,alpine-dw-apb-ssi |
| 69 | - description: Renesas RZ/N1 SPI Controller | 63 | - description: Vendor controllers which use snps,dw-apb-ssi as fallback |
| 70 | items: | 64 | items: |
| 71 | - const: renesas,rzn1-spi | 65 | - enum: |
| 66 | - mscc,ocelot-spi | ||
| 67 | - mscc,jaguar2-spi | ||
| 68 | - renesas,rzn1-spi | ||
| 69 | - sophgo,sg2042-spi | ||
| 70 | - thead,th1520-spi | ||
| 72 | - const: snps,dw-apb-ssi | 71 | - const: snps,dw-apb-ssi |
| 73 | - description: Intel Keem Bay SPI Controller | 72 | - description: Intel Keem Bay SPI Controller |
| 74 | const: intel,keembay-ssi | 73 | const: intel,keembay-ssi |
| @@ -88,10 +87,6 @@ properties: · 13 unmodified lines | |||
| 88 | - renesas,r9a06g032-spi # RZ/N1D | 87 | - renesas,r9a06g032-spi # RZ/N1D |
| 89 | - renesas,r9a06g033-spi # RZ/N1S | 88 | - renesas,r9a06g033-spi # RZ/N1S |
| 90 | - const: renesas,rzn1-spi # RZ/N1 | 89 | - const: renesas,rzn1-spi # RZ/N1 |
| 91 | - description: T-HEAD TH1520 SoC SPI Controller | ||
| 92 | items: | ||
| 93 | - const: thead,th1520-spi | ||
| 94 | - const: snps,dw-apb-ssi | ||
| 95 | 90 | ||
| 96 | reg: | 91 | reg: |
| 97 | minItems: 1 | 92 | minItems: 1 |
| @@ -18,9 +18,14 @@ description: | · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | properties: | 19 | properties: |
| 20 | compatible: | 20 | compatible: |
| 21 | enum: | 21 | oneOf: |
| 22 | - nxp,imx95-sysctr-timer | 22 | - enum: |
| 23 | - nxp,sysctr-timer | 23 | - nxp,imx95-sysctr-timer |
| 24 | - nxp,sysctr-timer | ||
| 25 | - items: | ||
| 26 | - enum: | ||
| 27 | - nxp,imx94-sysctr-timer | ||
| 28 | - const: nxp,imx95-sysctr-timer | ||
| 24 | 29 | ||
| 25 | reg: | 30 | reg: |
| 26 | maxItems: 1 | 31 | maxItems: 1 |
| @@ -1,56 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/timer/renesas,tpu.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Renesas H8/300 Timer Pulse Unit | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Yoshinori Sato <ysato@users.sourceforge.jp> | ||
| 11 | |||
| 12 | description: | ||
| 13 | The TPU is a 16bit timer/counter with configurable clock inputs and | ||
| 14 | programmable compare match. | ||
| 15 | This implementation supports only cascade mode. | ||
| 16 | |||
| 17 | select: | ||
| 18 | properties: | ||
| 19 | compatible: | ||
| 20 | contains: | ||
| 21 | const: renesas,tpu | ||
| 22 | '#pwm-cells': false | ||
| 23 | required: | ||
| 24 | - compatible | ||
| 25 | |||
| 26 | properties: | ||
| 27 | compatible: | ||
| 28 | const: renesas,tpu | ||
| 29 | |||
| 30 | reg: | ||
| 31 | items: | ||
| 32 | - description: First channel | ||
| 33 | - description: Second channel | ||
| 34 | |||
| 35 | clocks: | ||
| 36 | maxItems: 1 | ||
| 37 | |||
| 38 | clock-names: | ||
| 39 | const: fck | ||
| 40 | |||
| 41 | required: | ||
| 42 | - compatible | ||
| 43 | - reg | ||
| 44 | - clocks | ||
| 45 | - clock-names | ||
| 46 | |||
| 47 | additionalProperties: false | ||
| 48 | |||
| 49 | examples: | ||
| 50 | - | | ||
| 51 | tpu: tpu@ffffe0 { | ||
| 52 | compatible = "renesas,tpu"; | ||
| 53 | reg = <0xffffe0 16>, <0xfffff0 12>; | ||
| 54 | clocks = <&pclk>; | ||
| 55 | clock-names = "fck"; | ||
| 56 | }; | ||
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Xilinx SuperSpeed DWC3 USB SoC controller | 7 | title: Xilinx SuperSpeed DWC3 USB SoC controller |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 11 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | ||
| 13 | properties: | 12 | properties: |
| @@ -17,7 +17,6 @@ description: · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | maintainers: | 18 | maintainers: |
| 19 | - Michal Simek <michal.simek@amd.com> | 19 | - Michal Simek <michal.simek@amd.com> |
| 20 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 21 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 20 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 22 | 21 | ||
| 23 | properties: | 22 | properties: |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Xilinx udc controller | 7 | title: Xilinx udc controller |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Mubin Sayyed <mubin.sayyed@amd.com> | ||
| 11 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | ||
| 13 | properties: | 12 | properties: |
| @@ -328,9 +328,13 @@ The ext4 superblock is laid out as follows in · 327 unmodified lines | |||
| 328 | - s_checksum_type | 328 | - s_checksum_type |
| 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). | 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). |
| 330 | * - 0x176 | 330 | * - 0x176 |
| 331 | - __le16 | 331 | - \_\_u8 |
| 332 | - s_reserved_pad | 332 | - s\_encryption\_level |
| 333 | - | 333 | - Versioning level for encryption. |
| 334 | * - 0x177 | ||
| 335 | - \_\_u8 | ||
| 336 | - s\_reserved\_pad | ||
| 337 | - Padding to next 32bits. | ||
| 334 | * - 0x178 | 338 | * - 0x178 |
| 335 | - __le64 | 339 | - __le64 |
| 336 | - s_kbytes_written | 340 | - s_kbytes_written |
| @@ -466,9 +470,13 @@ The ext4 superblock is laid out as follows in · 129 unmodified lines | |||
| 466 | - s_last_error_time_hi | 470 | - s_last_error_time_hi |
| 467 | - Upper 8 bits of the s_last_error_time field. | 471 | - Upper 8 bits of the s_last_error_time field. |
| 468 | * - 0x27A | 472 | * - 0x27A |
| 469 | - __u8 | 473 | - \_\_u8 |
| 470 | - s_pad[2] | 474 | - s\_first\_error\_errcode |
| 471 | - Zero padding. | 475 | - |
| 476 | * - 0x27B | ||
| 477 | - \_\_u8 | ||
| 478 | - s\_last\_error\_errcode | ||
| 479 | - | ||
| 472 | * - 0x27C | 480 | * - 0x27C |
| 473 | - __le16 | 481 | - __le16 |
| 474 | - s_encoding | 482 | - s_encoding |
| @@ -46,6 +46,21 @@ The kernel embeds the building user and host names in · 45 unmodified lines | |||
| 46 | `KBUILD_BUILD_USER and KBUILD_BUILD_HOST`_ variables. If you are | 46 | `KBUILD_BUILD_USER and KBUILD_BUILD_HOST`_ variables. If you are |
| 47 | building from a git commit, you could use its committer address. | 47 | building from a git commit, you could use its committer address. |
| 48 | 48 | ||
| 49 | Absolute filenames | ||
| 50 | ------------------ | ||
| 51 | |||
| 52 | When the kernel is built out-of-tree, debug information may include | ||
| 53 | absolute filenames for the source files. This must be overridden by | ||
| 54 | including the ``-fdebug-prefix-map`` option in the `KCFLAGS`_ variable. | ||
| 55 | |||
| 56 | Depending on the compiler used, the ``__FILE__`` macro may also expand | ||
| 57 | to an absolute filename in an out-of-tree build. Kbuild automatically | ||
| 58 | uses the ``-fmacro-prefix-map`` option to prevent this, if it is | ||
| 59 | supported. | ||
| 60 | |||
| 61 | The Reproducible Builds web site has more information about these | ||
| 62 | `prefix-map options`_. | ||
| 63 | |||
| 49 | Generated files in source packages | 64 | Generated files in source packages |
| 50 | ---------------------------------- | 65 | ---------------------------------- |
| 51 | 66 | ||
| @@ -116,5 +131,7 @@ See ``scripts/setlocalversion`` for details. · 64 unmodified lines | |||
| 116 | 131 | ||
| 117 | .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp | 132 | .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp |
| 118 | .. _KBUILD_BUILD_USER and KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host | 133 | .. _KBUILD_BUILD_USER and KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host |
| 134 | .. _KCFLAGS: kbuild.html#kcflags | ||
| 135 | .. _prefix-map options: https://reproducible-builds.org/docs/build-path/ | ||
| 119 | .. _Reproducible Builds project: https://reproducible-builds.org/ | 136 | .. _Reproducible Builds project: https://reproducible-builds.org/ |
| 120 | .. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/ | 137 | .. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/ |
| @@ -89,8 +89,10 @@ definitions: · 88 unmodified lines | |||
| 89 | doc: Group of short_detected states | 89 | doc: Group of short_detected states |
| 90 | - | 90 | - |
| 91 | name: phy-upstream-type | 91 | name: phy-upstream-type |
| 92 | enum-name: | 92 | enum-name: phy-upstream |
| 93 | header: linux/ethtool.h | ||
| 93 | type: enum | 94 | type: enum |
| 95 | name-prefix: phy-upstream | ||
| 94 | entries: [ mac, phy ] | 96 | entries: [ mac, phy ] |
| 95 | - | 97 | - |
| 96 | name: tcp-data-split | 98 | name: tcp-data-split |
| @@ -123,12 +123,12 @@ attribute-sets: · 122 unmodified lines | |||
| 123 | 123 | ||
| 124 | operations: | 124 | operations: |
| 125 | name-prefix: ovs-vport-cmd- | 125 | name-prefix: ovs-vport-cmd- |
| 126 | fixed-header: ovs-header | ||
| 126 | list: | 127 | list: |
| 127 | - | 128 | - |
| 128 | name: new | 129 | name: new |
| 129 | doc: Create a new OVS vport | 130 | doc: Create a new OVS vport |
| 130 | attribute-set: vport | 131 | attribute-set: vport |
| 131 | fixed-header: ovs-header | ||
| 132 | do: | 132 | do: |
| 133 | request: | 133 | request: |
| 134 | attributes: | 134 | attributes: |
| @@ -141,7 +141,6 @@ operations: · 6 unmodified lines | |||
| 141 | name: del | 141 | name: del |
| 142 | doc: Delete existing OVS vport from a data path | 142 | doc: Delete existing OVS vport from a data path |
| 143 | attribute-set: vport | 143 | attribute-set: vport |
| 144 | fixed-header: ovs-header | ||
| 145 | do: | 144 | do: |
| 146 | request: | 145 | request: |
| 147 | attributes: | 146 | attributes: |
| @@ -152,7 +151,6 @@ operations: · 4 unmodified lines | |||
| 152 | name: get | 151 | name: get |
| 153 | doc: Get / dump OVS vport configuration and state | 152 | doc: Get / dump OVS vport configuration and state |
| 154 | attribute-set: vport | 153 | attribute-set: vport |
| 155 | fixed-header: ovs-header | ||
| 156 | do: &vport-get-op | 154 | do: &vport-get-op |
| 157 | request: | 155 | request: |
| 158 | attributes: | 156 | attributes: |
| @@ -1113,11 +1113,10 @@ attribute-sets: · 1112 unmodified lines | |||
| 1113 | - | 1113 | - |
| 1114 | name: prop-list | 1114 | name: prop-list |
| 1115 | type: nest | 1115 | type: nest |
| 1116 | nested-attributes: link-attrs | 1116 | nested-attributes: prop-list-link-attrs |
| 1117 | - | 1117 | - |
| 1118 | name: alt-ifname | 1118 | name: alt-ifname |
| 1119 | type: string | 1119 | type: string |
| 1120 | multi-attr: true | ||
| 1121 | - | 1120 | - |
| 1122 | name: perm-address | 1121 | name: perm-address |
| 1123 | type: binary | 1122 | type: binary |
| @@ -1163,6 +1162,13 @@ attribute-sets: · 39 unmodified lines | |||
| 1163 | - | 1162 | - |
| 1164 | name: netns-immutable | 1163 | name: netns-immutable |
| 1165 | type: u8 | 1164 | type: u8 |
| 1165 | - | ||
| 1166 | name: prop-list-link-attrs | ||
| 1167 | subset-of: link-attrs | ||
| 1168 | attributes: | ||
| 1169 | - | ||
| 1170 | name: alt-ifname | ||
| 1171 | multi-attr: true | ||
| 1166 | - | 1172 | - |
| 1167 | name: af-spec-attrs | 1173 | name: af-spec-attrs |
| 1168 | attributes: | 1174 | attributes: |
| @@ -1585,7 +1591,7 @@ attribute-sets: · 416 unmodified lines | |||
| 1585 | name: nf-call-iptables | 1591 | name: nf-call-iptables |
| 1586 | type: u8 | 1592 | type: u8 |
| 1587 | - | 1593 | - |
| 1588 | name: nf-call-ip6-tables | 1594 | name: nf-call-ip6tables |
| 1589 | type: u8 | 1595 | type: u8 |
| 1590 | - | 1596 | - |
| 1591 | name: nf-call-arptables | 1597 | name: nf-call-arptables |
| @@ -2077,7 +2083,7 @@ attribute-sets: · 485 unmodified lines | |||
| 2077 | name: id | 2083 | name: id |
| 2078 | type: u16 | 2084 | type: u16 |
| 2079 | - | 2085 | - |
| 2080 | name: flag | 2086 | name: flags |
| 2081 | type: binary | 2087 | type: binary |
| 2082 | struct: ifla-vlan-flags | 2088 | struct: ifla-vlan-flags |
| 2083 | - | 2089 | - |
| @@ -2165,7 +2171,7 @@ attribute-sets: · 81 unmodified lines | |||
| 2165 | type: binary | 2171 | type: binary |
| 2166 | struct: ifla-cacheinfo | 2172 | struct: ifla-cacheinfo |
| 2167 | - | 2173 | - |
| 2168 | name: icmp6-stats | 2174 | name: icmp6stats |
| 2169 | type: binary | 2175 | type: binary |
| 2170 | struct: ifla-icmp6-stats | 2176 | struct: ifla-icmp6-stats |
| 2171 | - | 2177 | - |
| @@ -2179,9 +2185,10 @@ attribute-sets: · 7 unmodified lines | |||
| 2179 | type: u32 | 2185 | type: u32 |
| 2180 | - | 2186 | - |
| 2181 | name: mctp-attrs | 2187 | name: mctp-attrs |
| 2188 | name-prefix: ifla-mctp- | ||
| 2182 | attributes: | 2189 | attributes: |
| 2183 | - | 2190 | - |
| 2184 | name: mctp-net | 2191 | name: net |
| 2185 | type: u32 | 2192 | type: u32 |
| 2186 | - | 2193 | - |
| 2187 | name: phys-binding | 2194 | name: phys-binding |
| @@ -2453,7 +2460,6 @@ operations: · 265 unmodified lines | |||
| 2453 | - min-mtu | 2460 | - min-mtu |
| 2454 | - max-mtu | 2461 | - max-mtu |
| 2455 | - prop-list | 2462 | - prop-list |
| 2456 | - alt-ifname | ||
| 2457 | - perm-address | 2463 | - perm-address |
| 2458 | - proto-down-reason | 2464 | - proto-down-reason |
| 2459 | - parent-dev-name | 2465 | - parent-dev-name |
| @@ -13,25 +13,25 @@ definitions: · 12 unmodified lines | |||
| 13 | type: struct | 13 | type: struct |
| 14 | members: | 14 | members: |
| 15 | - | 15 | - |
| 16 | name: family | 16 | name: ndm-family |
| 17 | type: u8 | 17 | type: u8 |
| 18 | - | 18 | - |
| 19 | name: pad | 19 | name: ndm-pad |
| 20 | type: pad | 20 | type: pad |
| 21 | len: 3 | 21 | len: 3 |
| 22 | - | 22 | - |
| 23 | name: ifindex | 23 | name: ndm-ifindex |
| 24 | type: s32 | 24 | type: s32 |
| 25 | - | 25 | - |
| 26 | name: state | 26 | name: ndm-state |
| 27 | type: u16 | 27 | type: u16 |
| 28 | enum: nud-state | 28 | enum: nud-state |
| 29 | - | 29 | - |
| 30 | name: flags | 30 | name: ndm-flags |
| 31 | type: u8 | 31 | type: u8 |
| 32 | enum: ntf-flags | 32 | enum: ntf-flags |
| 33 | - | 33 | - |
| 34 | name: type | 34 | name: ndm-type |
| 35 | type: u8 | 35 | type: u8 |
| 36 | enum: rtm-type | 36 | enum: rtm-type |
| 37 | - | 37 | - |
| @@ -189,7 +189,7 @@ attribute-sets: · 151 unmodified lines | |||
| 189 | type: binary | 189 | type: binary |
| 190 | display-hint: ipv4 | 190 | display-hint: ipv4 |
| 191 | - | 191 | - |
| 192 | name: lladr | 192 | name: lladdr |
| 193 | type: binary | 193 | type: binary |
| 194 | display-hint: mac | 194 | display-hint: mac |
| 195 | - | 195 | - |
| @@ -2017,7 +2017,8 @@ attribute-sets: · 2016 unmodified lines | |||
| 2017 | attributes: | 2017 | attributes: |
| 2018 | - | 2018 | - |
| 2019 | name: act | 2019 | name: act |
| 2020 | type: nest | 2020 | type: indexed-array |
| 2021 | sub-type: nest | ||
| 2021 | nested-attributes: tc-act-attrs | 2022 | nested-attributes: tc-act-attrs |
| 2022 | - | 2023 | - |
| 2023 | name: police | 2024 | name: police |
| @@ -2250,7 +2251,8 @@ attribute-sets: · 226 unmodified lines | |||
| 2250 | attributes: | 2251 | attributes: |
| 2251 | - | 2252 | - |
| 2252 | name: act | 2253 | name: act |
| 2253 | type: nest | 2254 | type: indexed-array |
| 2255 | sub-type: nest | ||
| 2254 | nested-attributes: tc-act-attrs | 2256 | nested-attributes: tc-act-attrs |
| 2255 | - | 2257 | - |
| 2256 | name: police | 2258 | name: police |
| @@ -2745,7 +2747,7 @@ attribute-sets: · 488 unmodified lines | |||
| 2745 | type: u16 | 2747 | type: u16 |
| 2746 | byte-order: big-endian | 2748 | byte-order: big-endian |
| 2747 | - | 2749 | - |
| 2748 | name: key-l2-tpv3-sid | 2750 | name: key-l2tpv3-sid |
| 2749 | type: u32 | 2751 | type: u32 |
| 2750 | byte-order: big-endian | 2752 | byte-order: big-endian |
| 2751 | - | 2753 | - |
| @@ -3504,7 +3506,7 @@ attribute-sets: · 752 unmodified lines | |||
| 3504 | name: rate64 | 3506 | name: rate64 |
| 3505 | type: u64 | 3507 | type: u64 |
| 3506 | - | 3508 | - |
| 3507 | name: prate4 | 3509 | name: prate64 |
| 3508 | type: u64 | 3510 | type: u64 |
| 3509 | - | 3511 | - |
| 3510 | name: burst | 3512 | name: burst |
| @@ -338,10 +338,11 @@ operations directly under the netdev instance lock. · 337 unmodified lines | |||
| 338 | Devices drivers are encouraged to rely on the instance lock where possible. | 338 | Devices drivers are encouraged to rely on the instance lock where possible. |
| 339 | 339 | ||
| 340 | For the (mostly software) drivers that need to interact with the core stack, | 340 | For the (mostly software) drivers that need to interact with the core stack, |
| 341 | there are two sets of interfaces: ``dev_xxx`` and ``netif_xxx`` (e.g., | 341 | there are two sets of interfaces: ``dev_xxx``/``netdev_xxx`` and ``netif_xxx`` |
| 342 | ``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx`` functions handle | 342 | (e.g., ``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx``/``netdev_xxx`` |
| 343 | acquiring the instance lock themselves, while the ``netif_xxx`` functions | 343 | functions handle acquiring the instance lock themselves, while the |
| 344 | assume that the driver has already acquired the instance lock. | 344 | ``netif_xxx`` functions assume that the driver has already acquired |
| 345 | the instance lock. | ||
| 345 | 346 | ||
| 346 | Notifiers and netdev instance lock | 347 | Notifiers and netdev instance lock |
| 347 | ================================== | 348 | ================================== |
| @@ -354,6 +355,7 @@ For devices with locked ops, currently only the following notifiers are · 6 unmodified lines | |||
| 354 | running under the lock: | 355 | running under the lock: |
| 355 | * ``NETDEV_REGISTER`` | 356 | * ``NETDEV_REGISTER`` |
| 356 | * ``NETDEV_UP`` | 357 | * ``NETDEV_UP`` |
| 358 | * ``NETDEV_CHANGE`` | ||
| 357 | 359 | ||
| 358 | The following notifiers are running without the lock: | 360 | The following notifiers are running without the lock: |
| 359 | * ``NETDEV_UNREGISTER`` | 361 | * ``NETDEV_UNREGISTER`` |
| @@ -811,11 +811,9 @@ Documentation/devicetree/bindings/ptp/timestamper.txt for more details. · 810 unmodified lines | |||
| 811 | 3.2.4 Other caveats for MAC drivers | 811 | 3.2.4 Other caveats for MAC drivers |
| 812 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 812 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 813 | 813 | ||
| 814 | Stacked PHCs, especially DSA (but not only) - since that doesn't require any | 814 | The use of stacked PHCs may uncover MAC driver bugs which were impossible to |
| 815 | modification to MAC drivers, so it is more difficult to ensure correctness of | 815 | trigger without them. One example has to do with this line of code, already |
| 816 | all possible code paths - is that they uncover bugs which were impossible to | 816 | presented earlier:: |
| 817 | trigger before the existence of stacked PTP clocks. One example has to do with | ||
| 818 | this line of code, already presented earlier:: | ||
| 819 | 817 | ||
| 820 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | 818 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
| 821 | 819 | ||
| @@ -154,7 +154,7 @@ suspending the device are satisfied) and to queue up a suspend request for the · 153 unmodified lines | |||
| 154 | device in that case. If there is no idle callback, or if the callback returns | 154 | device in that case. If there is no idle callback, or if the callback returns |
| 155 | 0, then the PM core will attempt to carry out a runtime suspend of the device, | 155 | 0, then the PM core will attempt to carry out a runtime suspend of the device, |
| 156 | also respecting devices configured for autosuspend. In essence this means a | 156 | also respecting devices configured for autosuspend. In essence this means a |
| 157 | call to __pm_runtime_autosuspend() (do note that drivers needs to update the | 157 | call to pm_runtime_autosuspend() (do note that drivers needs to update the |
| 158 | device last busy mark, pm_runtime_mark_last_busy(), to control the delay under | 158 | device last busy mark, pm_runtime_mark_last_busy(), to control the delay under |
| 159 | this circumstance). To prevent this (for example, if the callback routine has | 159 | this circumstance). To prevent this (for example, if the callback routine has |
| 160 | started a delayed suspend), the routine must return a non-zero value. Negative | 160 | started a delayed suspend), the routine must return a non-zero value. Negative |
| @@ -17,10 +17,10 @@ OpenRISC 1000系列(或1k)。 · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | 关于OpenRISC处理器和正在进行中的开发的信息: | 18 | 关于OpenRISC处理器和正在进行中的开发的信息: |
| 19 | 19 | ||
| 20 | ======= ============================= | 20 | ======= ============================== |
| 21 | 网站 https://openrisc.io | 21 | 网站 https://openrisc.io |
| 22 | 邮箱 openrisc@lists.librecores.org | 22 | 邮箱 linux-openrisc@vger.kernel.org |
| 23 | ======= ============================= | 23 | ======= ============================== |
| 24 | 24 | ||
| 25 | --------------------------------------------------------------------- | 25 | --------------------------------------------------------------------- |
| 26 | 26 | ||
| @@ -36,11 +36,11 @@ OpenRISC工具链和Linux的构建指南 · 9 unmodified lines | |||
| 36 | 工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本 | 36 | 工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本 |
| 37 | 中找到。 | 37 | 中找到。 |
| 38 | 38 | ||
| 39 | ====== ================================================= | 39 | ====== ========================================================== |
| 40 | 二进制 https://github.com/openrisc/or1k-gcc/releases | 40 | 二进制 https://github.com/stffrdhrn/or1k-toolchain-build/releases |
| 41 | 工具链 https://openrisc.io/software | 41 | 工具链 https://openrisc.io/software |
| 42 | 构建 https://github.com/stffrdhrn/or1k-toolchain-build | 42 | 构建 https://github.com/stffrdhrn/or1k-toolchain-build |
| 43 | ====== ================================================= | 43 | ====== ========================================================== |
| 44 | 44 | ||
| 45 | 2) 构建 | 45 | 2) 构建 |
| 46 | 46 | ||
| @@ -17,10 +17,10 @@ OpenRISC 1000系列(或1k)。 · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | 關於OpenRISC處理器和正在進行中的開發的信息: | 18 | 關於OpenRISC處理器和正在進行中的開發的信息: |
| 19 | 19 | ||
| 20 | ======= ============================= | 20 | ======= ============================== |
| 21 | 網站 https://openrisc.io | 21 | 網站 https://openrisc.io |
| 22 | 郵箱 openrisc@lists.librecores.org | 22 | 郵箱 linux-openrisc@vger.kernel.org |
| 23 | ======= ============================= | 23 | ======= ============================== |
| 24 | 24 | ||
| 25 | --------------------------------------------------------------------- | 25 | --------------------------------------------------------------------- |
| 26 | 26 | ||
| @@ -36,11 +36,11 @@ OpenRISC工具鏈和Linux的構建指南 · 9 unmodified lines | |||
| 36 | 工具鏈的構建指南可以在openrisc.io或Stafford的工具鏈構建和發佈腳本 | 36 | 工具鏈的構建指南可以在openrisc.io或Stafford的工具鏈構建和發佈腳本 |
| 37 | 中找到。 | 37 | 中找到。 |
| 38 | 38 | ||
| 39 | ====== ================================================= | 39 | ====== ========================================================== |
| 40 | 二進制 https://github.com/openrisc/or1k-gcc/releases | 40 | 二進制 https://github.com/stffrdhrn/or1k-toolchain-build/releases |
| 41 | 工具鏈 https://openrisc.io/software | 41 | 工具鏈 https://openrisc.io/software |
| 42 | 構建 https://github.com/stffrdhrn/or1k-toolchain-build | 42 | 構建 https://github.com/stffrdhrn/or1k-toolchain-build |
| 43 | ====== ================================================= | 43 | ====== ========================================================== |
| 44 | 44 | ||
| 45 | 2) 構建 | 45 | 2) 構建 |
| 46 | 46 | ||
| @@ -27,7 +27,7 @@ SYSCALL · 26 unmodified lines | |||
| 27 | ======= | 27 | ======= |
| 28 | mseal syscall signature | 28 | mseal syscall signature |
| 29 | ----------------------- | 29 | ----------------------- |
| 30 | ``int mseal(void \* addr, size_t len, unsigned long flags)`` | 30 | ``int mseal(void *addr, size_t len, unsigned long flags)`` |
| 31 | 31 | ||
| 32 | **addr**/**len**: virtual memory address range. | 32 | **addr**/**len**: virtual memory address range. |
| 33 | The address range set by **addr**/**len** must meet: | 33 | The address range set by **addr**/**len** must meet: |
| @@ -7447,6 +7447,75 @@ Unused bitfields in the bitarrays must be set to zero. · 7446 unmodified lines | |||
| 7447 | 7447 | ||
| 7448 | This capability connects the vcpu to an in-kernel XIVE device. | 7448 | This capability connects the vcpu to an in-kernel XIVE device. |
| 7449 | 7449 | ||
| 7450 | 6.76 KVM_CAP_HYPERV_SYNIC | ||
| 7451 | ------------------------- | ||
| 7452 | |||
| 7453 | :Architectures: x86 | ||
| 7454 | :Target: vcpu | ||
| 7455 | |||
| 7456 | This capability, if KVM_CHECK_EXTENSION indicates that it is | ||
| 7457 | available, means that the kernel has an implementation of the | ||
| 7458 | Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is | ||
| 7459 | used to support Windows Hyper-V based guest paravirt drivers(VMBus). | ||
| 7460 | |||
| 7461 | In order to use SynIC, it has to be activated by setting this | ||
| 7462 | capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this | ||
| 7463 | will disable the use of APIC hardware virtualization even if supported | ||
| 7464 | by the CPU, as it's incompatible with SynIC auto-EOI behavior. | ||
| 7465 | |||
| 7466 | 6.77 KVM_CAP_HYPERV_SYNIC2 | ||
| 7467 | -------------------------- | ||
| 7468 | |||
| 7469 | :Architectures: x86 | ||
| 7470 | :Target: vcpu | ||
| 7471 | |||
| 7472 | This capability enables a newer version of Hyper-V Synthetic interrupt | ||
| 7473 | controller (SynIC). The only difference with KVM_CAP_HYPERV_SYNIC is that KVM | ||
| 7474 | doesn't clear SynIC message and event flags pages when they are enabled by | ||
| 7475 | writing to the respective MSRs. | ||
| 7476 | |||
| 7477 | 6.78 KVM_CAP_HYPERV_DIRECT_TLBFLUSH | ||
| 7478 | ----------------------------------- | ||
| 7479 | |||
| 7480 | :Architectures: x86 | ||
| 7481 | :Target: vcpu | ||
| 7482 | |||
| 7483 | This capability indicates that KVM running on top of Hyper-V hypervisor | ||
| 7484 | enables Direct TLB flush for its guests meaning that TLB flush | ||
| 7485 | hypercalls are handled by Level 0 hypervisor (Hyper-V) bypassing KVM. | ||
| 7486 | Due to the different ABI for hypercall parameters between Hyper-V and | ||
| 7487 | KVM, enabling this capability effectively disables all hypercall | ||
| 7488 | handling by KVM (as some KVM hypercall may be mistakenly treated as TLB | ||
| 7489 | flush hypercalls by Hyper-V) so userspace should disable KVM identification | ||
| 7490 | in CPUID and only exposes Hyper-V identification. In this case, guest | ||
| 7491 | thinks it's running on Hyper-V and only use Hyper-V hypercalls. | ||
| 7492 | |||
| 7493 | 6.79 KVM_CAP_HYPERV_ENFORCE_CPUID | ||
| 7494 | --------------------------------- | ||
| 7495 | |||
| 7496 | :Architectures: x86 | ||
| 7497 | :Target: vcpu | ||
| 7498 | |||
| 7499 | When enabled, KVM will disable emulated Hyper-V features provided to the | ||
| 7500 | guest according to the bits Hyper-V CPUID feature leaves. Otherwise, all | ||
| 7501 | currently implemented Hyper-V features are provided unconditionally when | ||
| 7502 | Hyper-V identification is set in the HYPERV_CPUID_INTERFACE (0x40000001) | ||
| 7503 | leaf. | ||
| 7504 | |||
| 7505 | 6.80 KVM_CAP_ENFORCE_PV_FEATURE_CPUID | ||
| 7506 | ------------------------------------- | ||
| 7507 | |||
| 7508 | :Architectures: x86 | ||
| 7509 | :Target: vcpu | ||
| 7510 | |||
| 7511 | When enabled, KVM will disable paravirtual features provided to the | ||
| 7512 | guest according to the bits in the KVM_CPUID_FEATURES CPUID leaf | ||
| 7513 | (0x40000001). Otherwise, a guest may use the paravirtual features | ||
| 7514 | regardless of what has actually been exposed through the CPUID leaf. | ||
| 7515 | |||
| 7516 | .. _KVM_CAP_DIRTY_LOG_RING: | ||
| 7517 | |||
| 7518 | |||
| 7450 | .. _cap_enable_vm: | 7519 | .. _cap_enable_vm: |
| 7451 | 7520 | ||
| 7452 | 7. Capabilities that can be enabled on VMs | 7521 | 7. Capabilities that can be enabled on VMs |
| @@ -7927,10 +7996,10 @@ by POWER10 processor. · 474 unmodified lines | |||
| 7927 | 7.24 KVM_CAP_VM_COPY_ENC_CONTEXT_FROM | 7996 | 7.24 KVM_CAP_VM_COPY_ENC_CONTEXT_FROM |
| 7928 | ------------------------------------- | 7997 | ------------------------------------- |
| 7929 | 7998 | ||
| 7930 | Architectures: x86 SEV enabled | 7999 | :Architectures: x86 SEV enabled |
| 7931 | Type: vm | 8000 | :Type: vm |
| 7932 | Parameters: args[0] is the fd of the source vm | 8001 | :Parameters: args[0] is the fd of the source vm |
| 7933 | Returns: 0 on success; ENOTTY on error | 8002 | :Returns: 0 on success; ENOTTY on error |
| 7934 | 8003 | ||
| 7935 | This capability enables userspace to copy encryption context from the vm | 8004 | This capability enables userspace to copy encryption context from the vm |
| 7936 | indicated by the fd to the vm this is called on. | 8005 | indicated by the fd to the vm this is called on. |
| @@ -7963,24 +8032,6 @@ default. · 26 unmodified lines | |||
| 7963 | 8032 | ||
| 7964 | See Documentation/arch/x86/sgx.rst for more details. | 8033 | See Documentation/arch/x86/sgx.rst for more details. |
| 7965 | 8034 | ||
| 7966 | 7.26 KVM_CAP_PPC_RPT_INVALIDATE | ||
| 7967 | ------------------------------- | ||
| 7968 | |||
| 7969 | :Capability: KVM_CAP_PPC_RPT_INVALIDATE | ||
| 7970 | :Architectures: ppc | ||
| 7971 | :Type: vm | ||
| 7972 | |||
| 7973 | This capability indicates that the kernel is capable of handling | ||
| 7974 | H_RPT_INVALIDATE hcall. | ||
| 7975 | |||
| 7976 | In order to enable the use of H_RPT_INVALIDATE in the guest, | ||
| 7977 | user space might have to advertise it for the guest. For example, | ||
| 7978 | IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is | ||
| 7979 | present in the "ibm,hypertas-functions" device-tree property. | ||
| 7980 | |||
| 7981 | This capability is enabled for hypervisors on platforms like POWER9 | ||
| 7982 | that support radix MMU. | ||
| 7983 | |||
| 7984 | 7.27 KVM_CAP_EXIT_ON_EMULATION_FAILURE | 8035 | 7.27 KVM_CAP_EXIT_ON_EMULATION_FAILURE |
| 7985 | -------------------------------------- | 8036 | -------------------------------------- |
| 7986 | 8037 | ||
| @@ -8038,24 +8089,9 @@ indicated by the fd to the VM this is called on. · 51 unmodified lines | |||
| 8038 | This is intended to support intra-host migration of VMs between userspace VMMs, | 8089 | This is intended to support intra-host migration of VMs between userspace VMMs, |
| 8039 | upgrading the VMM process without interrupting the guest. | 8090 | upgrading the VMM process without interrupting the guest. |
| 8040 | 8091 | ||
| 8041 | 7.30 KVM_CAP_PPC_AIL_MODE_3 | ||
| 8042 | ------------------------------- | ||
| 8043 | |||
| 8044 | :Capability: KVM_CAP_PPC_AIL_MODE_3 | ||
| 8045 | :Architectures: ppc | ||
| 8046 | :Type: vm | ||
| 8047 | |||
| 8048 | This capability indicates that the kernel supports the mode 3 setting for the | ||
| 8049 | "Address Translation Mode on Interrupt" aka "Alternate Interrupt Location" | ||
| 8050 | resource that is controlled with the H_SET_MODE hypercall. | ||
| 8051 | |||
| 8052 | This capability allows a guest kernel to use a better-performance mode for | ||
| 8053 | handling interrupts and system calls. | ||
| 8054 | |||
| 8055 | 7.31 KVM_CAP_DISABLE_QUIRKS2 | 8092 | 7.31 KVM_CAP_DISABLE_QUIRKS2 |
| 8056 | ---------------------------- | 8093 | ---------------------------- |
| 8057 | 8094 | ||
| 8058 | :Capability: KVM_CAP_DISABLE_QUIRKS2 | ||
| 8059 | :Parameters: args[0] - set of KVM quirks to disable | 8095 | :Parameters: args[0] - set of KVM quirks to disable |
| 8060 | :Architectures: x86 | 8096 | :Architectures: x86 |
| 8061 | :Type: vm | 8097 | :Type: vm |
| @@ -8210,27 +8246,6 @@ This capability is aimed to mitigate the threat that malicious VMs can · 148 unmodified lines | |||
| 8210 | cause CPU stuck (due to event windows don't open up) and make the CPU | 8246 | cause CPU stuck (due to event windows don't open up) and make the CPU |
| 8211 | unavailable to host or other VMs. | 8247 | unavailable to host or other VMs. |
| 8212 | 8248 | ||
| 8213 | 7.34 KVM_CAP_MEMORY_FAULT_INFO | ||
| 8214 | ------------------------------ | ||
| 8215 | |||
| 8216 | :Architectures: x86 | ||
| 8217 | :Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP. | ||
| 8218 | |||
| 8219 | The presence of this capability indicates that KVM_RUN will fill | ||
| 8220 | kvm_run.memory_fault if KVM cannot resolve a guest page fault VM-Exit, e.g. if | ||
| 8221 | there is a valid memslot but no backing VMA for the corresponding host virtual | ||
| 8222 | address. | ||
| 8223 | |||
| 8224 | The information in kvm_run.memory_fault is valid if and only if KVM_RUN returns | ||
| 8225 | an error with errno=EFAULT or errno=EHWPOISON *and* kvm_run.exit_reason is set | ||
| 8226 | to KVM_EXIT_MEMORY_FAULT. | ||
| 8227 | |||
| 8228 | Note: Userspaces which attempt to resolve memory faults so that they can retry | ||
| 8229 | KVM_RUN are encouraged to guard against repeatedly receiving the same | ||
| 8230 | error/annotated fault. | ||
| 8231 | |||
| 8232 | See KVM_EXIT_MEMORY_FAULT for more information. | ||
| 8233 | |||
| 8234 | 7.35 KVM_CAP_X86_APIC_BUS_CYCLES_NS | 8249 | 7.35 KVM_CAP_X86_APIC_BUS_CYCLES_NS |
| 8235 | ----------------------------------- | 8250 | ----------------------------------- |
| 8236 | 8251 | ||
| @@ -8248,82 +8263,268 @@ by KVM_CHECK_EXTENSION. · 11 unmodified lines | |||
| 8248 | Note: Userspace is responsible for correctly configuring CPUID 0x15, a.k.a. the | 8263 | Note: Userspace is responsible for correctly configuring CPUID 0x15, a.k.a. the |
| 8249 | core crystal clock frequency, if a non-zero CPUID 0x15 is exposed to the guest. | 8264 | core crystal clock frequency, if a non-zero CPUID 0x15 is exposed to the guest. |
| 8250 | 8265 | ||
| 8251 | 7.36 KVM_CAP_X86_GUEST_MODE | 8266 | 7.36 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL |
| 8252 | ------------------------------ | 8267 | ---------------------------------------------------------- |
| 8253 | |||
| 8254 | :Architectures: x86 | ||
| 8255 | :Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP. | ||
| 8256 | 8268 | ||
| 8257 | The presence of this capability indicates that KVM_RUN will update the | 8269 | :Architectures: x86, arm64 |
| 8258 | KVM_RUN_X86_GUEST_MODE bit in kvm_run.flags to indicate whether the | 8270 | :Type: vm |
| 8259 | vCPU was executing nested guest code when it exited. | 8271 | :Parameters: args[0] - size of the dirty log ring |
| 8260 | 8272 | ||
| 8261 | KVM exits with the register state of either the L1 or L2 guest | 8273 | KVM is capable of tracking dirty memory using ring buffers that are |
| 8262 | depending on which executed at the time of an exit. Userspace must | 8274 | mmapped into userspace; there is one dirty ring per vcpu. |
| 8263 | take care to differentiate between these cases. | ||
| 8264 | 8275 | ||
| 8265 | 7.37 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS | 8276 | The dirty ring is available to userspace as an array of |
| 8266 | ------------------------------------- | 8277 | ``struct kvm_dirty_gfn``. Each dirty entry is defined as:: |
| 8267 | 8278 | ||
| 8268 | :Architectures: arm64 | 8279 | struct kvm_dirty_gfn { |
| 8269 | :Target: VM | 8280 | __u32 flags; |
| 8270 | :Parameters: None | 8281 | __u32 slot; /* as_id | slot_id */ |
| 8271 | :Returns: 0 on success, -EINVAL if vCPUs have been created before enabling this | 8282 | __u64 offset; |
| 8272 | capability. | 8283 | }; |
| 8273 | 8284 | ||
| 8274 | This capability changes the behavior of the registers that identify a PE | 8285 | The following values are defined for the flags field to define the |
| 8275 | implementation of the Arm architecture: MIDR_EL1, REVIDR_EL1, and AIDR_EL1. | 8286 | current state of the entry:: |
| 8276 | By default, these registers are visible to userspace but treated as invariant. | ||
| 8277 | 8287 | ||
| 8278 | When this capability is enabled, KVM allows userspace to change the | 8288 | #define KVM_DIRTY_GFN_F_DIRTY BIT(0) |
| 8279 | aforementioned registers before the first KVM_RUN. These registers are VM | 8289 | #define KVM_DIRTY_GFN_F_RESET BIT(1) |
| 8280 | scoped, meaning that the same set of values are presented on all vCPUs in a | 8290 | #define KVM_DIRTY_GFN_F_MASK 0x3 |
| 8281 | given VM. | ||
| 8282 | 8291 | ||
| 8283 | 8. Other capabilities. | 8292 | Userspace should call KVM_ENABLE_CAP ioctl right after KVM_CREATE_VM |
| 8284 | ====================== | 8293 | ioctl to enable this capability for the new guest and set the size of |
| 8294 | the rings. Enabling the capability is only allowed before creating any | ||
| 8295 | vCPU, and the size of the ring must be a power of two. The larger the | ||
| 8296 | ring buffer, the less likely the ring is full and the VM is forced to | ||
| 8297 | exit to userspace. The optimal size depends on the workload, but it is | ||
| 8298 | recommended that it be at least 64 KiB (4096 entries). | ||
| 8285 | 8299 | ||
| 8286 | This section lists capabilities that give information about other | 8300 | Just like for dirty page bitmaps, the buffer tracks writes to |
| 8287 | features of the KVM implementation. | 8301 | all user memory regions for which the KVM_MEM_LOG_DIRTY_PAGES flag was |
| 8302 | set in KVM_SET_USER_MEMORY_REGION. Once a memory region is registered | ||
| 8303 | with the flag set, userspace can start harvesting dirty pages from the | ||
| 8304 | ring buffer. | ||
| 8288 | 8305 | ||
| 8289 | 8.1 KVM_CAP_PPC_HWRNG | 8306 | An entry in the ring buffer can be unused (flag bits ``00``), |
| 8290 | --------------------- | 8307 | dirty (flag bits ``01``) or harvested (flag bits ``1X``). The |
| 8308 | state machine for the entry is as follows:: | ||
| 8291 | 8309 | ||
| 8292 | :Architectures: ppc | 8310 | dirtied harvested reset |
| 8311 | 00 -----------> 01 -------------> 1X -------+ | ||
| 8312 | ^ | | ||
| 8313 | | | | ||
| 8314 | +------------------------------------------+ | ||
| 8293 | 8315 | ||
| 8294 | This capability, if KVM_CHECK_EXTENSION indicates that it is | 8316 | To harvest the dirty pages, userspace accesses the mmapped ring buffer |
| 8295 | available, means that the kernel has an implementation of the | 8317 | to read the dirty GFNs. If the flags has the DIRTY bit set (at this stage |
| 8296 | H_RANDOM hypercall backed by a hardware random-number generator. | 8318 | the RESET bit must be cleared), then it means this GFN is a dirty GFN. |
| 8297 | If present, the kernel H_RANDOM handler can be enabled for guest use | 8319 | The userspace should harvest this GFN and mark the flags from state |
| 8298 | with the KVM_CAP_PPC_ENABLE_HCALL capability. | 8320 | ``01b`` to ``1Xb`` (bit 0 will be ignored by KVM, but bit 1 must be set |
| 8321 | to show that this GFN is harvested and waiting for a reset), and move | ||
| 8322 | on to the next GFN. The userspace should continue to do this until the | ||
| 8323 | flags of a GFN have the DIRTY bit cleared, meaning that it has harvested | ||
| 8324 | all the dirty GFNs that were available. | ||
| 8299 | 8325 | ||
| 8300 | 8.2 KVM_CAP_HYPERV_SYNIC | 8326 | Note that on weakly ordered architectures, userspace accesses to the |
| 8301 | ------------------------ | 8327 | ring buffer (and more specifically the 'flags' field) must be ordered, |
| 8328 | using load-acquire/store-release accessors when available, or any | ||
| 8329 | other memory barrier that will ensure this ordering. | ||
| 8302 | 8330 | ||
| 8303 | :Architectures: x86 | 8331 | It's not necessary for userspace to harvest the all dirty GFNs at once. |
| 8332 | However it must collect the dirty GFNs in sequence, i.e., the userspace | ||
| 8333 | program cannot skip one dirty GFN to collect the one next to it. | ||
| 8304 | 8334 | ||
| 8305 | This capability, if KVM_CHECK_EXTENSION indicates that it is | 8335 | After processing one or more entries in the ring buffer, userspace |
| 8306 | available, means that the kernel has an implementation of the | 8336 | calls the VM ioctl KVM_RESET_DIRTY_RINGS to notify the kernel about |
| 8307 | Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is | 8337 | it, so that the kernel will reprotect those collected GFNs. |
| 8308 | used to support Windows Hyper-V based guest paravirt drivers(VMBus). | 8338 | Therefore, the ioctl must be called *before* reading the content of |
| 8339 | the dirty pages. | ||
| 8309 | 8340 | ||
| 8310 | In order to use SynIC, it has to be activated by setting this | 8341 | The dirty ring can get full. When it happens, the KVM_RUN of the |
| 8311 | capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this | 8342 | vcpu will return with exit reason KVM_EXIT_DIRTY_LOG_FULL. |
| 8312 | will disable the use of APIC hardware virtualization even if supported | ||
| 8313 | by the CPU, as it's incompatible with SynIC auto-EOI behavior. | ||
| 8314 | 8343 | ||
| 8315 | 8.3 KVM_CAP_PPC_MMU_RADIX | 8344 | The dirty ring interface has a major difference comparing to the |
| 8316 | ------------------------- | 8345 | KVM_GET_DIRTY_LOG interface in that, when reading the dirty ring from |
| 8346 | userspace, it's still possible that the kernel has not yet flushed the | ||
| 8347 | processor's dirty page buffers into the kernel buffer (with dirty bitmaps, the | ||
| 8348 | flushing is done by the KVM_GET_DIRTY_LOG ioctl). To achieve that, one | ||
| 8349 | needs to kick the vcpu out of KVM_RUN using a signal. The resulting | ||
| 8350 | vmexit ensures that all dirty GFNs are flushed to the dirty rings. | ||
| 8317 | 8351 | ||
| 8318 | :Architectures: ppc | 8352 | NOTE: KVM_CAP_DIRTY_LOG_RING_ACQ_REL is the only capability that |
| 8353 | should be exposed by weakly ordered architecture, in order to indicate | ||
| 8354 | the additional memory ordering requirements imposed on userspace when | ||
| 8355 | reading the state of an entry and mutating it from DIRTY to HARVESTED. | ||
| 8356 | Architecture with TSO-like ordering (such as x86) are allowed to | ||
| 8357 | expose both KVM_CAP_DIRTY_LOG_RING and KVM_CAP_DIRTY_LOG_RING_ACQ_REL | ||
| 8358 | to userspace. | ||
| 8319 | 8359 | ||
| 8320 | This capability, if KVM_CHECK_EXTENSION indicates that it is | 8360 | After enabling the dirty rings, the userspace needs to detect the |
| 8321 | available, means that the kernel can support guests using the | 8361 | capability of KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP to see whether the |
| 8322 | radix MMU defined in Power ISA V3.00 (as implemented in the POWER9 | 8362 | ring structures can be backed by per-slot bitmaps. With this capability |
| 8323 | processor). | 8363 | advertised, it means the architecture can dirty guest pages without |
| 8364 | vcpu/ring context, so that some of the dirty information will still be | ||
| 8365 | maintained in the bitmap structure. KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP | ||
| 8366 | can't be enabled if the capability of KVM_CAP_DIRTY_LOG_RING_ACQ_REL | ||
| 8367 | hasn't been enabled, or any memslot has been existing. | ||
| 8324 | 8368 | ||
| 8325 | 8.4 KVM_CAP_PPC_MMU_HASH_V3 | 8369 | Note that the bitmap here is only a backup of the ring structure. The |
| 8326 | --------------------------- | 8370 | use of the ring and bitmap combination is only beneficial if there is |
| 8371 | only a very small amount of memory that is dirtied out of vcpu/ring | ||
| 8372 | context. Otherwise, the stand-alone per-slot bitmap mechanism needs to | ||
| 8373 | be considered. | ||
| 8374 | |||
| 8375 | To collect dirty bits in the backup bitmap, userspace can use the same | ||
| 8376 | KVM_GET_DIRTY_LOG ioctl. KVM_CLEAR_DIRTY_LOG isn't needed as long as all | ||
| 8377 | the generation of the dirty bits is done in a single pass. Collecting | ||
| 8378 | the dirty bitmap should be the very last thing that the VMM does before | ||
| 8379 | considering the state as complete. VMM needs to ensure that the dirty | ||
| 8380 | state is final and avoid missing dirty pages from another ioctl ordered | ||
| 8381 | after the bitmap collection. | ||
| 8382 | |||
| 8383 | NOTE: Multiple examples of using the backup bitmap: (1) save vgic/its | ||
| 8384 | tables through command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} on | ||
| 8385 | KVM device "kvm-arm-vgic-its". (2) restore vgic/its tables through | ||
| 8386 | command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_RESTORE_TABLES} on KVM device | ||
| 8387 | "kvm-arm-vgic-its". VGICv3 LPI pending status is restored. (3) save | ||
| 8388 | vgic3 pending table through KVM_DEV_ARM_VGIC_{GRP_CTRL, SAVE_PENDING_TABLES} | ||
| 8389 | command on KVM device "kvm-arm-vgic-v3". | ||
| 8390 | |||
| 8391 | 7.37 KVM_CAP_PMU_CAPABILITY | ||
| 8392 | --------------------------- | ||
| 8393 | |||
| 8394 | :Architectures: x86 | ||
| 8395 | :Type: vm | ||
| 8396 | :Parameters: arg[0] is bitmask of PMU virtualization capabilities. | ||
| 8397 | :Returns: 0 on success, -EINVAL when arg[0] contains invalid bits | ||
| 8398 | |||
| 8399 | This capability alters PMU virtualization in KVM. | ||
| 8400 | |||
| 8401 | Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of | ||
| 8402 | PMU virtualization capabilities that can be adjusted on a VM. | ||
| 8403 | |||
| 8404 | The argument to KVM_ENABLE_CAP is also a bitmask and selects specific | ||
| 8405 | PMU virtualization capabilities to be applied to the VM. This can | ||
| 8406 | only be invoked on a VM prior to the creation of VCPUs. | ||
| 8407 | |||
| 8408 | At this time, KVM_PMU_CAP_DISABLE is the only capability. Setting | ||
| 8409 | this capability will disable PMU virtualization for that VM. Usermode | ||
| 8410 | should adjust CPUID leaf 0xA to reflect that the PMU is disabled. | ||
| 8411 | |||
| 8412 | 7.38 KVM_CAP_VM_DISABLE_NX_HUGE_PAGES | ||
| 8413 | ------------------------------------- | ||
| 8414 | |||
| 8415 | :Architectures: x86 | ||
| 8416 | :Type: vm | ||
| 8417 | :Parameters: arg[0] must be 0. | ||
| 8418 | :Returns: 0 on success, -EPERM if the userspace process does not | ||
| 8419 | have CAP_SYS_BOOT, -EINVAL if args[0] is not 0 or any vCPUs have been | ||
| 8420 | created. | ||
| 8421 | |||
| 8422 | This capability disables the NX huge pages mitigation for iTLB MULTIHIT. | ||
| 8423 | |||
| 8424 | The capability has no effect if the nx_huge_pages module parameter is not set. | ||
| 8425 | |||
| 8426 | This capability may only be set before any vCPUs are created. | ||
| 8427 | |||
| 8428 | 7.39 KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE | ||
| 8429 | --------------------------------------- | ||
| 8430 | |||
| 8431 | :Architectures: arm64 | ||
| 8432 | :Type: vm | ||
| 8433 | :Parameters: arg[0] is the new split chunk size. | ||
| 8434 | :Returns: 0 on success, -EINVAL if any memslot was already created. | ||
| 8435 | |||
| 8436 | This capability sets the chunk size used in Eager Page Splitting. | ||
| 8437 | |||
| 8438 | Eager Page Splitting improves the performance of dirty-logging (used | ||
| 8439 | in live migrations) when guest memory is backed by huge-pages. It | ||
| 8440 | avoids splitting huge-pages (into PAGE_SIZE pages) on fault, by doing | ||
| 8441 | it eagerly when enabling dirty logging (with the | ||
| 8442 | KVM_MEM_LOG_DIRTY_PAGES flag for a memory region), or when using | ||
| 8443 | KVM_CLEAR_DIRTY_LOG. | ||
| 8444 | |||
| 8445 | The chunk size specifies how many pages to break at a time, using a | ||
| 8446 | single allocation for each chunk. Bigger the chunk size, more pages | ||
| 8447 | need to be allocated ahead of time. | ||
| 8448 | |||
| 8449 | The chunk size needs to be a valid block size. The list of acceptable | ||
| 8450 | block sizes is exposed in KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES as a | ||
| 8451 | 64-bit bitmap (each bit describing a block size). The default value is | ||
| 8452 | 0, to disable the eager page splitting. | ||
| 8453 | |||
| 8454 | 7.40 KVM_CAP_EXIT_HYPERCALL | ||
| 8455 | --------------------------- | ||
| 8456 | |||
| 8457 | :Architectures: x86 | ||
| 8458 | :Type: vm | ||
| 8459 | |||
| 8460 | This capability, if enabled, will cause KVM to exit to userspace | ||
| 8461 | with KVM_EXIT_HYPERCALL exit reason to process some hypercalls. | ||
| 8462 | |||
| 8463 | Calling KVM_CHECK_EXTENSION for this capability will return a bitmask | ||
| 8464 | of hypercalls that can be configured to exit to userspace. | ||
| 8465 | Right now, the only such hypercall is KVM_HC_MAP_GPA_RANGE. | ||
| 8466 | |||
| 8467 | The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset | ||
| 8468 | of the result of KVM_CHECK_EXTENSION. KVM will forward to userspace | ||
| 8469 | the hypercalls whose corresponding bit is in the argument, and return | ||
| 8470 | ENOSYS for the others. | ||
| 8471 | |||
| 8472 | 7.41 KVM_CAP_ARM_SYSTEM_SUSPEND | ||
| 8473 | ------------------------------- | ||
| 8474 | |||
| 8475 | :Architectures: arm64 | ||
| 8476 | :Type: vm | ||
| 8477 | |||
| 8478 | When enabled, KVM will exit to userspace with KVM_EXIT_SYSTEM_EVENT of | ||
| 8479 | type KVM_SYSTEM_EVENT_SUSPEND to process the guest suspend request. | ||
| 8480 | |||
| 8481 | 7.37 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS | ||
| 8482 | ------------------------------------- | ||
| 8483 | |||
| 8484 | :Architectures: arm64 | ||
| 8485 | :Target: VM | ||
| 8486 | :Parameters: None | ||
| 8487 | :Returns: 0 on success, -EINVAL if vCPUs have been created before enabling this | ||
| 8488 | capability. | ||
| 8489 | |||
| 8490 | This capability changes the behavior of the registers that identify a PE | ||
| 8491 | implementation of the Arm architecture: MIDR_EL1, REVIDR_EL1, and AIDR_EL1. | ||
| 8492 | By default, these registers are visible to userspace but treated as invariant. | ||
| 8493 | |||
| 8494 | When this capability is enabled, KVM allows userspace to change the | ||
| 8495 | aforementioned registers before the first KVM_RUN. These registers are VM | ||
| 8496 | scoped, meaning that the same set of values are presented on all vCPUs in a | ||
| 8497 | given VM. | ||
| 8498 | |||
| 8499 | 8. Other capabilities. | ||
| 8500 | ====================== | ||
| 8501 | |||
| 8502 | This section lists capabilities that give information about other | ||
| 8503 | features of the KVM implementation. | ||
| 8504 | |||
| 8505 | 8.1 KVM_CAP_PPC_HWRNG | ||
| 8506 | --------------------- | ||
| 8507 | |||
| 8508 | :Architectures: ppc | ||
| 8509 | |||
| 8510 | This capability, if KVM_CHECK_EXTENSION indicates that it is | ||
| 8511 | available, means that the kernel has an implementation of the | ||
| 8512 | H_RANDOM hypercall backed by a hardware random-number generator. | ||
| 8513 | If present, the kernel H_RANDOM handler can be enabled for guest use | ||
| 8514 | with the KVM_CAP_PPC_ENABLE_HCALL capability. | ||
| 8515 | |||
| 8516 | 8.3 KVM_CAP_PPC_MMU_RADIX | ||
| 8517 | ------------------------- | ||
| 8518 | |||
| 8519 | :Architectures: ppc | ||
| 8520 | |||
| 8521 | This capability, if KVM_CHECK_EXTENSION indicates that it is | ||
| 8522 | available, means that the kernel can support guests using the | ||
| 8523 | radix MMU defined in Power ISA V3.00 (as implemented in the POWER9 | ||
| 8524 | processor). | ||
| 8525 | |||
| 8526 | 8.4 KVM_CAP_PPC_MMU_HASH_V3 | ||
| 8527 | --------------------------- | ||
| 8327 | 8528 | ||
| 8328 | :Architectures: ppc | 8529 | :Architectures: ppc |
| 8329 | 8530 | ||
| @@ -8362,20 +8563,6 @@ may be incompatible with the MIPS VZ ASE. · 32 unmodified lines | |||
| 8362 | virtualization, including standard guest virtual memory segments. | 8563 | virtualization, including standard guest virtual memory segments. |
| 8363 | == ========================================================================== | 8564 | == ========================================================================== |
| 8364 | 8565 | ||
| 8365 | 8.6 KVM_CAP_MIPS_TE | ||
| 8366 | ------------------- | ||
| 8367 | |||
| 8368 | :Architectures: mips | ||
| 8369 | |||
| 8370 | This capability, if KVM_CHECK_EXTENSION on the main kvm handle indicates that | ||
| 8371 | it is available, means that the trap & emulate implementation is available to | ||
| 8372 | run guest code in user mode, even if KVM_CAP_MIPS_VZ indicates that hardware | ||
| 8373 | assisted virtualisation is also available. KVM_VM_MIPS_TE (0) must be passed | ||
| 8374 | to KVM_CREATE_VM to create a VM which utilises it. | ||
| 8375 | |||
| 8376 | If KVM_CHECK_EXTENSION on a kvm VM handle indicates that this capability is | ||
| 8377 | available, it means that the VM is using trap & emulate. | ||
| 8378 | |||
| 8379 | 8.7 KVM_CAP_MIPS_64BIT | 8566 | 8.7 KVM_CAP_MIPS_64BIT |
| 8380 | ---------------------- | 8567 | ---------------------- |
| 8381 | 8568 | ||
| @@ -8457,16 +8644,6 @@ virtual SMT modes that can be set using KVM_CAP_PPC_SMT. If bit N · 75 unmodified lines | |||
| 8457 | (counting from the right) is set, then a virtual SMT mode of 2^N is | 8644 | (counting from the right) is set, then a virtual SMT mode of 2^N is |
| 8458 | available. | 8645 | available. |
| 8459 | 8646 | ||
| 8460 | 8.11 KVM_CAP_HYPERV_SYNIC2 | ||
| 8461 | -------------------------- | ||
| 8462 | |||
| 8463 | :Architectures: x86 | ||
| 8464 | |||
| 8465 | This capability enables a newer version of Hyper-V Synthetic interrupt | ||
| 8466 | controller (SynIC). The only difference with KVM_CAP_HYPERV_SYNIC is that KVM | ||
| 8467 | doesn't clear SynIC message and event flags pages when they are enabled by | ||
| 8468 | writing to the respective MSRs. | ||
| 8469 | |||
| 8470 | 8.12 KVM_CAP_HYPERV_VP_INDEX | 8647 | 8.12 KVM_CAP_HYPERV_VP_INDEX |
| 8471 | ---------------------------- | 8648 | ---------------------------- |
| 8472 | 8649 | ||
| @@ -8481,7 +8658,6 @@ capability is absent, userspace can still query this msr's value. · 8 unmodified lines | |||
| 8481 | ------------------------------- | 8658 | ------------------------------- |
| 8482 | 8659 | ||
| 8483 | :Architectures: s390 | 8660 | :Architectures: s390 |
| 8484 | :Parameters: none | ||
| 8485 | 8661 | ||
| 8486 | This capability indicates if the flic device will be able to get/set the | 8662 | This capability indicates if the flic device will be able to get/set the |
| 8487 | AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows | 8663 | AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows |
| @@ -8555,21 +8731,6 @@ This capability indicates that KVM supports paravirtualized Hyper-V IPI send · 67 unmodified lines | |||
| 8555 | hypercalls: | 8731 | hypercalls: |
| 8556 | HvCallSendSyntheticClusterIpi, HvCallSendSyntheticClusterIpiEx. | 8732 | HvCallSendSyntheticClusterIpi, HvCallSendSyntheticClusterIpiEx. |
| 8557 | 8733 | ||
| 8558 | 8.21 KVM_CAP_HYPERV_DIRECT_TLBFLUSH | ||
| 8559 | ----------------------------------- | ||
| 8560 | |||
| 8561 | :Architectures: x86 | ||
| 8562 | |||
| 8563 | This capability indicates that KVM running on top of Hyper-V hypervisor | ||
| 8564 | enables Direct TLB flush for its guests meaning that TLB flush | ||
| 8565 | hypercalls are handled by Level 0 hypervisor (Hyper-V) bypassing KVM. | ||
| 8566 | Due to the different ABI for hypercall parameters between Hyper-V and | ||
| 8567 | KVM, enabling this capability effectively disables all hypercall | ||
| 8568 | handling by KVM (as some KVM hypercall may be mistakenly treated as TLB | ||
| 8569 | flush hypercalls by Hyper-V) so userspace should disable KVM identification | ||
| 8570 | in CPUID and only exposes Hyper-V identification. In this case, guest | ||
| 8571 | thinks it's running on Hyper-V and only use Hyper-V hypercalls. | ||
| 8572 | |||
| 8573 | 8.22 KVM_CAP_S390_VCPU_RESETS | 8734 | 8.22 KVM_CAP_S390_VCPU_RESETS |
| 8574 | ----------------------------- | 8735 | ----------------------------- |
| 8575 | 8736 | ||
| @@ -8647,142 +8808,6 @@ In combination with KVM_CAP_X86_USER_SPACE_MSR, this allows user space to · 71 unmodified lines | |||
| 8647 | trap and emulate MSRs that are outside of the scope of KVM as well as | 8808 | trap and emulate MSRs that are outside of the scope of KVM as well as |
| 8648 | limit the attack surface on KVM's MSR emulation code. | 8809 | limit the attack surface on KVM's MSR emulation code. |
| 8649 | 8810 | ||
| 8650 | 8.28 KVM_CAP_ENFORCE_PV_FEATURE_CPUID | ||
| 8651 | ------------------------------------- | ||
| 8652 | |||
| 8653 | Architectures: x86 | ||
| 8654 | |||
| 8655 | When enabled, KVM will disable paravirtual features provided to the | ||
| 8656 | guest according to the bits in the KVM_CPUID_FEATURES CPUID leaf | ||
| 8657 | (0x40000001). Otherwise, a guest may use the paravirtual features | ||
| 8658 | regardless of what has actually been exposed through the CPUID leaf. | ||
| 8659 | |||
| 8660 | .. _KVM_CAP_DIRTY_LOG_RING: | ||
| 8661 | |||
| 8662 | 8.29 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL | ||
| 8663 | ---------------------------------------------------------- | ||
| 8664 | |||
| 8665 | :Architectures: x86, arm64 | ||
| 8666 | :Parameters: args[0] - size of the dirty log ring | ||
| 8667 | |||
| 8668 | KVM is capable of tracking dirty memory using ring buffers that are | ||
| 8669 | mmapped into userspace; there is one dirty ring per vcpu. | ||
| 8670 | |||
| 8671 | The dirty ring is available to userspace as an array of | ||
| 8672 | ``struct kvm_dirty_gfn``. Each dirty entry is defined as:: | ||
| 8673 | |||
| 8674 | struct kvm_dirty_gfn { | ||
| 8675 | __u32 flags; | ||
| 8676 | __u32 slot; /* as_id | slot_id */ | ||
| 8677 | __u64 offset; | ||
| 8678 | }; | ||
| 8679 | |||
| 8680 | The following values are defined for the flags field to define the | ||
| 8681 | current state of the entry:: | ||
| 8682 | |||
| 8683 | #define KVM_DIRTY_GFN_F_DIRTY BIT(0) | ||
| 8684 | #define KVM_DIRTY_GFN_F_RESET BIT(1) | ||
| 8685 | #define KVM_DIRTY_GFN_F_MASK 0x3 | ||
| 8686 | |||
| 8687 | Userspace should call KVM_ENABLE_CAP ioctl right after KVM_CREATE_VM | ||
| 8688 | ioctl to enable this capability for the new guest and set the size of | ||
| 8689 | the rings. Enabling the capability is only allowed before creating any | ||
| 8690 | vCPU, and the size of the ring must be a power of two. The larger the | ||
| 8691 | ring buffer, the less likely the ring is full and the VM is forced to | ||
| 8692 | exit to userspace. The optimal size depends on the workload, but it is | ||
| 8693 | recommended that it be at least 64 KiB (4096 entries). | ||
| 8694 | |||
| 8695 | Just like for dirty page bitmaps, the buffer tracks writes to | ||
| 8696 | all user memory regions for which the KVM_MEM_LOG_DIRTY_PAGES flag was | ||
| 8697 | set in KVM_SET_USER_MEMORY_REGION. Once a memory region is registered | ||
| 8698 | with the flag set, userspace can start harvesting dirty pages from the | ||
| 8699 | ring buffer. | ||
| 8700 | |||
| 8701 | An entry in the ring buffer can be unused (flag bits ``00``), | ||
| 8702 | dirty (flag bits ``01``) or harvested (flag bits ``1X``). The | ||
| 8703 | state machine for the entry is as follows:: | ||
| 8704 | |||
| 8705 | dirtied harvested reset | ||
| 8706 | 00 -----------> 01 -------------> 1X -------+ | ||
| 8707 | ^ | | ||
| 8708 | | | | ||
| 8709 | +------------------------------------------+ | ||
| 8710 | |||
| 8711 | To harvest the dirty pages, userspace accesses the mmapped ring buffer | ||
| 8712 | to read the dirty GFNs. If the flags has the DIRTY bit set (at this stage | ||
| 8713 | the RESET bit must be cleared), then it means this GFN is a dirty GFN. | ||
| 8714 | The userspace should harvest this GFN and mark the flags from state | ||
| 8715 | ``01b`` to ``1Xb`` (bit 0 will be ignored by KVM, but bit 1 must be set | ||
| 8716 | to show that this GFN is harvested and waiting for a reset), and move | ||
| 8717 | on to the next GFN. The userspace should continue to do this until the | ||
| 8718 | flags of a GFN have the DIRTY bit cleared, meaning that it has harvested | ||
| 8719 | all the dirty GFNs that were available. | ||
| 8720 | |||
| 8721 | Note that on weakly ordered architectures, userspace accesses to the | ||
| 8722 | ring buffer (and more specifically the 'flags' field) must be ordered, | ||
| 8723 | using load-acquire/store-release accessors when available, or any | ||
| 8724 | other memory barrier that will ensure this ordering. | ||
| 8725 | |||
| 8726 | It's not necessary for userspace to harvest the all dirty GFNs at once. | ||
| 8727 | However it must collect the dirty GFNs in sequence, i.e., the userspace | ||
| 8728 | program cannot skip one dirty GFN to collect the one next to it. | ||
| 8729 | |||
| 8730 | After processing one or more entries in the ring buffer, userspace | ||
| 8731 | calls the VM ioctl KVM_RESET_DIRTY_RINGS to notify the kernel about | ||
| 8732 | it, so that the kernel will reprotect those collected GFNs. | ||
| 8733 | Therefore, the ioctl must be called *before* reading the content of | ||
| 8734 | the dirty pages. | ||
| 8735 | |||
| 8736 | The dirty ring can get full. When it happens, the KVM_RUN of the | ||
| 8737 | vcpu will return with exit reason KVM_EXIT_DIRTY_LOG_FULL. | ||
| 8738 | |||
| 8739 | The dirty ring interface has a major difference comparing to the | ||
| 8740 | KVM_GET_DIRTY_LOG interface in that, when reading the dirty ring from | ||
| 8741 | userspace, it's still possible that the kernel has not yet flushed the | ||
| 8742 | processor's dirty page buffers into the kernel buffer (with dirty bitmaps, the | ||
| 8743 | flushing is done by the KVM_GET_DIRTY_LOG ioctl). To achieve that, one | ||
| 8744 | needs to kick the vcpu out of KVM_RUN using a signal. The resulting | ||
| 8745 | vmexit ensures that all dirty GFNs are flushed to the dirty rings. | ||
| 8746 | |||
| 8747 | NOTE: KVM_CAP_DIRTY_LOG_RING_ACQ_REL is the only capability that | ||
| 8748 | should be exposed by weakly ordered architecture, in order to indicate | ||
| 8749 | the additional memory ordering requirements imposed on userspace when | ||
| 8750 | reading the state of an entry and mutating it from DIRTY to HARVESTED. | ||
| 8751 | Architecture with TSO-like ordering (such as x86) are allowed to | ||
| 8752 | expose both KVM_CAP_DIRTY_LOG_RING and KVM_CAP_DIRTY_LOG_RING_ACQ_REL | ||
| 8753 | to userspace. | ||
| 8754 | |||
| 8755 | After enabling the dirty rings, the userspace needs to detect the | ||
| 8756 | capability of KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP to see whether the | ||
| 8757 | ring structures can be backed by per-slot bitmaps. With this capability | ||
| 8758 | advertised, it means the architecture can dirty guest pages without | ||
| 8759 | vcpu/ring context, so that some of the dirty information will still be | ||
| 8760 | maintained in the bitmap structure. KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP | ||
| 8761 | can't be enabled if the capability of KVM_CAP_DIRTY_LOG_RING_ACQ_REL | ||
| 8762 | hasn't been enabled, or any memslot has been existing. | ||
| 8763 | |||
| 8764 | Note that the bitmap here is only a backup of the ring structure. The | ||
| 8765 | use of the ring and bitmap combination is only beneficial if there is | ||
| 8766 | only a very small amount of memory that is dirtied out of vcpu/ring | ||
| 8767 | context. Otherwise, the stand-alone per-slot bitmap mechanism needs to | ||
| 8768 | be considered. | ||
| 8769 | |||
| 8770 | To collect dirty bits in the backup bitmap, userspace can use the same | ||
| 8771 | KVM_GET_DIRTY_LOG ioctl. KVM_CLEAR_DIRTY_LOG isn't needed as long as all | ||
| 8772 | the generation of the dirty bits is done in a single pass. Collecting | ||
| 8773 | the dirty bitmap should be the very last thing that the VMM does before | ||
| 8774 | considering the state as complete. VMM needs to ensure that the dirty | ||
| 8775 | state is final and avoid missing dirty pages from another ioctl ordered | ||
| 8776 | after the bitmap collection. | ||
| 8777 | |||
| 8778 | NOTE: Multiple examples of using the backup bitmap: (1) save vgic/its | ||
| 8779 | tables through command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} on | ||
| 8780 | KVM device "kvm-arm-vgic-its". (2) restore vgic/its tables through | ||
| 8781 | command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_RESTORE_TABLES} on KVM device | ||
| 8782 | "kvm-arm-vgic-its". VGICv3 LPI pending status is restored. (3) save | ||
| 8783 | vgic3 pending table through KVM_DEV_ARM_VGIC_{GRP_CTRL, SAVE_PENDING_TABLES} | ||
| 8784 | command on KVM device "kvm-arm-vgic-v3". | ||
| 8785 | |||
| 8786 | 8.30 KVM_CAP_XEN_HVM | 8811 | 8.30 KVM_CAP_XEN_HVM |
| 8787 | -------------------- | 8812 | -------------------- |
| 8788 | 8813 | ||
| @@ -8847,10 +8872,9 @@ clearing the PVCLOCK_TSC_STABLE_BIT flag in Xen pvclock sources. This will be · 58 unmodified lines | |||
| 8847 | done when the KVM_CAP_XEN_HVM ioctl sets the | 8872 | done when the KVM_CAP_XEN_HVM ioctl sets the |
| 8848 | KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag. | 8873 | KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag. |
| 8849 | 8874 | ||
| 8850 | 8.31 KVM_CAP_PPC_MULTITCE | 8875 | 8.31 KVM_CAP_SPAPR_MULTITCE |
| 8851 | ------------------------- | 8876 | --------------------------- |
| 8852 | 8877 | ||
| 8853 | :Capability: KVM_CAP_PPC_MULTITCE | ||
| 8854 | :Architectures: ppc | 8878 | :Architectures: ppc |
| 8855 | :Type: vm | 8879 | :Type: vm |
| 8856 | 8880 | ||
| @@ -8882,72 +8906,9 @@ This capability indicates that the KVM virtual PTP service is · 25 unmodified lines | |||
| 8882 | supported in the host. A VMM can check whether the service is | 8906 | supported in the host. A VMM can check whether the service is |
| 8883 | available to the guest on migration. | 8907 | available to the guest on migration. |
| 8884 | 8908 | ||
| 8885 | 8.33 KVM_CAP_HYPERV_ENFORCE_CPUID | ||
| 8886 | --------------------------------- | ||
| 8887 | |||
| 8888 | Architectures: x86 | ||
| 8889 | |||
| 8890 | When enabled, KVM will disable emulated Hyper-V features provided to the | ||
| 8891 | guest according to the bits Hyper-V CPUID feature leaves. Otherwise, all | ||
| 8892 | currently implemented Hyper-V features are provided unconditionally when | ||
| 8893 | Hyper-V identification is set in the HYPERV_CPUID_INTERFACE (0x40000001) | ||
| 8894 | leaf. | ||
| 8895 | |||
| 8896 | 8.34 KVM_CAP_EXIT_HYPERCALL | ||
| 8897 | --------------------------- | ||
| 8898 | |||
| 8899 | :Capability: KVM_CAP_EXIT_HYPERCALL | ||
| 8900 | :Architectures: x86 | ||
| 8901 | :Type: vm | ||
| 8902 | |||
| 8903 | This capability, if enabled, will cause KVM to exit to userspace | ||
| 8904 | with KVM_EXIT_HYPERCALL exit reason to process some hypercalls. | ||
| 8905 | |||
| 8906 | Calling KVM_CHECK_EXTENSION for this capability will return a bitmask | ||
| 8907 | of hypercalls that can be configured to exit to userspace. | ||
| 8908 | Right now, the only such hypercall is KVM_HC_MAP_GPA_RANGE. | ||
| 8909 | |||
| 8910 | The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset | ||
| 8911 | of the result of KVM_CHECK_EXTENSION. KVM will forward to userspace | ||
| 8912 | the hypercalls whose corresponding bit is in the argument, and return | ||
| 8913 | ENOSYS for the others. | ||
| 8914 | |||
| 8915 | 8.35 KVM_CAP_PMU_CAPABILITY | ||
| 8916 | --------------------------- | ||
| 8917 | |||
| 8918 | :Capability: KVM_CAP_PMU_CAPABILITY | ||
| 8919 | :Architectures: x86 | ||
| 8920 | :Type: vm | ||
| 8921 | :Parameters: arg[0] is bitmask of PMU virtualization capabilities. | ||
| 8922 | :Returns: 0 on success, -EINVAL when arg[0] contains invalid bits | ||
| 8923 | |||
| 8924 | This capability alters PMU virtualization in KVM. | ||
| 8925 | |||
| 8926 | Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of | ||
| 8927 | PMU virtualization capabilities that can be adjusted on a VM. | ||
| 8928 | |||
| 8929 | The argument to KVM_ENABLE_CAP is also a bitmask and selects specific | ||
| 8930 | PMU virtualization capabilities to be applied to the VM. This can | ||
| 8931 | only be invoked on a VM prior to the creation of VCPUs. | ||
| 8932 | |||
| 8933 | At this time, KVM_PMU_CAP_DISABLE is the only capability. Setting | ||
| 8934 | this capability will disable PMU virtualization for that VM. Usermode | ||
| 8935 | should adjust CPUID leaf 0xA to reflect that the PMU is disabled. | ||
| 8936 | |||
| 8937 | 8.36 KVM_CAP_ARM_SYSTEM_SUSPEND | ||
| 8938 | ------------------------------- | ||
| 8939 | |||
| 8940 | :Capability: KVM_CAP_ARM_SYSTEM_SUSPEND | ||
| 8941 | :Architectures: arm64 | ||
| 8942 | :Type: vm | ||
| 8943 | |||
| 8944 | When enabled, KVM will exit to userspace with KVM_EXIT_SYSTEM_EVENT of | ||
| 8945 | type KVM_SYSTEM_EVENT_SUSPEND to process the guest suspend request. | ||
| 8946 | |||
| 8947 | 8.37 KVM_CAP_S390_PROTECTED_DUMP | 8909 | 8.37 KVM_CAP_S390_PROTECTED_DUMP |
| 8948 | -------------------------------- | 8910 | -------------------------------- |
| 8949 | 8911 | ||
| 8950 | :Capability: KVM_CAP_S390_PROTECTED_DUMP | ||
| 8951 | :Architectures: s390 | 8912 | :Architectures: s390 |
| 8952 | :Type: vm | 8913 | :Type: vm |
| 8953 | 8914 | ||
| @@ -8957,27 +8918,9 @@ PV guests. The `KVM_PV_DUMP` command is available for the · 3 unmodified lines | |||
| 8957 | dump related UV data. Also the vcpu ioctl `KVM_S390_PV_CPU_COMMAND` is | 8918 | dump related UV data. Also the vcpu ioctl `KVM_S390_PV_CPU_COMMAND` is |
| 8958 | available and supports the `KVM_PV_DUMP_CPU` subcommand. | 8919 | available and supports the `KVM_PV_DUMP_CPU` subcommand. |
| 8959 | 8920 | ||
| 8960 | 8.38 KVM_CAP_VM_DISABLE_NX_HUGE_PAGES | ||
| 8961 | ------------------------------------- | ||
| 8962 | |||
| 8963 | :Capability: KVM_CAP_VM_DISABLE_NX_HUGE_PAGES | ||
| 8964 | :Architectures: x86 | ||
| 8965 | :Type: vm | ||
| 8966 | :Parameters: arg[0] must be 0. | ||
| 8967 | :Returns: 0 on success, -EPERM if the userspace process does not | ||
| 8968 | have CAP_SYS_BOOT, -EINVAL if args[0] is not 0 or any vCPUs have been | ||
| 8969 | created. | ||
| 8970 | |||
| 8971 | This capability disables the NX huge pages mitigation for iTLB MULTIHIT. | ||
| 8972 | |||
| 8973 | The capability has no effect if the nx_huge_pages module parameter is not set. | ||
| 8974 | |||
| 8975 | This capability may only be set before any vCPUs are created. | ||
| 8976 | |||
| 8977 | 8.39 KVM_CAP_S390_CPU_TOPOLOGY | 8921 | 8.39 KVM_CAP_S390_CPU_TOPOLOGY |
| 8978 | ------------------------------ | 8922 | ------------------------------ |
| 8979 | 8923 | ||
| 8980 | :Capability: KVM_CAP_S390_CPU_TOPOLOGY | ||
| 8981 | :Architectures: s390 | 8924 | :Architectures: s390 |
| 8982 | :Type: vm | 8925 | :Type: vm |
| 8983 | 8926 | ||
| @@ -8999,37 +8942,9 @@ structure. · 15 unmodified lines | |||
| 8999 | When getting the Modified Change Topology Report value, the attr->addr | 8942 | When getting the Modified Change Topology Report value, the attr->addr |
| 9000 | must point to a byte where the value will be stored or retrieved from. | 8943 | must point to a byte where the value will be stored or retrieved from. |
| 9001 | 8944 | ||
| 9002 | 8.40 KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE | ||
| 9003 | --------------------------------------- | ||
| 9004 | |||
| 9005 | :Capability: KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE | ||
| 9006 | :Architectures: arm64 | ||
| 9007 | :Type: vm | ||
| 9008 | :Parameters: arg[0] is the new split chunk size. | ||
| 9009 | :Returns: 0 on success, -EINVAL if any memslot was already created. | ||
| 9010 | |||
| 9011 | This capability sets the chunk size used in Eager Page Splitting. | ||
| 9012 | |||
| 9013 | Eager Page Splitting improves the performance of dirty-logging (used | ||
| 9014 | in live migrations) when guest memory is backed by huge-pages. It | ||
| 9015 | avoids splitting huge-pages (into PAGE_SIZE pages) on fault, by doing | ||
| 9016 | it eagerly when enabling dirty logging (with the | ||
| 9017 | KVM_MEM_LOG_DIRTY_PAGES flag for a memory region), or when using | ||
| 9018 | KVM_CLEAR_DIRTY_LOG. | ||
| 9019 | |||
| 9020 | The chunk size specifies how many pages to break at a time, using a | ||
| 9021 | single allocation for each chunk. Bigger the chunk size, more pages | ||
| 9022 | need to be allocated ahead of time. | ||
| 9023 | |||
| 9024 | The chunk size needs to be a valid block size. The list of acceptable | ||
| 9025 | block sizes is exposed in KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES as a | ||
| 9026 | 64-bit bitmap (each bit describing a block size). The default value is | ||
| 9027 | 0, to disable the eager page splitting. | ||
| 9028 | |||
| 9029 | 8.41 KVM_CAP_VM_TYPES | 8945 | 8.41 KVM_CAP_VM_TYPES |
| 9030 | --------------------- | 8946 | --------------------- |
| 9031 | 8947 | ||
| 9032 | :Capability: KVM_CAP_MEMORY_ATTRIBUTES | ||
| 9033 | :Architectures: x86 | 8948 | :Architectures: x86 |
| 9034 | :Type: system ioctl | 8949 | :Type: system ioctl |
| 9035 | 8950 | ||
| @@ -9046,6 +8961,67 @@ Do not use KVM_X86_SW_PROTECTED_VM for "real" VMs, and especially not in · 10 unmodified lines | |||
| 9046 | production. The behavior and effective ABI for software-protected VMs is | 8961 | production. The behavior and effective ABI for software-protected VMs is |
| 9047 | unstable. | 8962 | unstable. |
| 9048 | 8963 | ||
| 8964 | 8.42 KVM_CAP_PPC_RPT_INVALIDATE | ||
| 8965 | ------------------------------- | ||
| 8966 | |||
| 8967 | :Architectures: ppc | ||
| 8968 | |||
| 8969 | This capability indicates that the kernel is capable of handling | ||
| 8970 | H_RPT_INVALIDATE hcall. | ||
| 8971 | |||
| 8972 | In order to enable the use of H_RPT_INVALIDATE in the guest, | ||
| 8973 | user space might have to advertise it for the guest. For example, | ||
| 8974 | IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is | ||
| 8975 | present in the "ibm,hypertas-functions" device-tree property. | ||
| 8976 | |||
| 8977 | This capability is enabled for hypervisors on platforms like POWER9 | ||
| 8978 | that support radix MMU. | ||
| 8979 | |||
| 8980 | 8.43 KVM_CAP_PPC_AIL_MODE_3 | ||
| 8981 | --------------------------- | ||
| 8982 | |||
| 8983 | :Architectures: ppc | ||
| 8984 | |||
| 8985 | This capability indicates that the kernel supports the mode 3 setting for the | ||
| 8986 | "Address Translation Mode on Interrupt" aka "Alternate Interrupt Location" | ||
| 8987 | resource that is controlled with the H_SET_MODE hypercall. | ||
| 8988 | |||
| 8989 | This capability allows a guest kernel to use a better-performance mode for | ||
| 8990 | handling interrupts and system calls. | ||
| 8991 | |||
| 8992 | 8.44 KVM_CAP_MEMORY_FAULT_INFO | ||
| 8993 | ------------------------------ | ||
| 8994 | |||
| 8995 | :Architectures: x86 | ||
| 8996 | |||
| 8997 | The presence of this capability indicates that KVM_RUN will fill | ||
| 8998 | kvm_run.memory_fault if KVM cannot resolve a guest page fault VM-Exit, e.g. if | ||
| 8999 | there is a valid memslot but no backing VMA for the corresponding host virtual | ||
| 9000 | address. | ||
| 9001 | |||
| 9002 | The information in kvm_run.memory_fault is valid if and only if KVM_RUN returns | ||
| 9003 | an error with errno=EFAULT or errno=EHWPOISON *and* kvm_run.exit_reason is set | ||
| 9004 | to KVM_EXIT_MEMORY_FAULT. | ||
| 9005 | |||
| 9006 | Note: Userspaces which attempt to resolve memory faults so that they can retry | ||
| 9007 | KVM_RUN are encouraged to guard against repeatedly receiving the same | ||
| 9008 | error/annotated fault. | ||
| 9009 | |||
| 9010 | See KVM_EXIT_MEMORY_FAULT for more information. | ||
| 9011 | |||
| 9012 | 8.45 KVM_CAP_X86_GUEST_MODE | ||
| 9013 | --------------------------- | ||
| 9014 | |||
| 9015 | :Architectures: x86 | ||
| 9016 | |||
| 9017 | The presence of this capability indicates that KVM_RUN will update the | ||
| 9018 | KVM_RUN_X86_GUEST_MODE bit in kvm_run.flags to indicate whether the | ||
| 9019 | vCPU was executing nested guest code when it exited. | ||
| 9020 | |||
| 9021 | KVM exits with the register state of either the L1 or L2 guest | ||
| 9022 | depending on which executed at the time of an exit. Userspace must | ||
| 9023 | take care to differentiate between these cases. | ||
| 9024 | |||
| 9049 | 9. Known KVM API problems | 9025 | 9. Known KVM API problems |
| 9050 | ========================= | 9026 | ========================= |
| 9051 | 9027 | ||
| @@ -9076,9 +9052,10 @@ the local APIC. · 24 unmodified lines | |||
| 9076 | 9052 | ||
| 9077 | The same is true for the ``KVM_FEATURE_PV_UNHALT`` paravirtualized feature. | 9053 | The same is true for the ``KVM_FEATURE_PV_UNHALT`` paravirtualized feature. |
| 9078 | 9054 | ||
| 9079 | CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by ``KVM_GET_SUPPORTED_CPUID``. | 9055 | On older versions of Linux, CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by |
| 9080 | It can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` is present and the kernel | 9056 | ``KVM_GET_SUPPORTED_CPUID``, but it can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` |
| 9081 | has enabled in-kernel emulation of the local APIC. | 9057 | is present and the kernel has enabled in-kernel emulation of the local APIC. |
| 9058 | On newer versions, ``KVM_GET_SUPPORTED_CPUID`` does report the bit as available. | ||
| 9082 | 9059 | ||
| 9083 | CPU topology | 9060 | CPU topology |
| 9084 | ~~~~~~~~~~~~ | 9061 | ~~~~~~~~~~~~ |
| @@ -138,6 +138,10 @@ input data, the meaning of which depends on the subfeature being accessed. · 137 unmodified lines | |||
| 138 | The output buffer contains a single byte which signals success or failure (``0x00`` on failure) | 138 | The output buffer contains a single byte which signals success or failure (``0x00`` on failure) |
| 139 | and 31 bytes of output data, the meaning if which depends on the subfeature being accessed. | 139 | and 31 bytes of output data, the meaning if which depends on the subfeature being accessed. |
| 140 | 140 | ||
| 141 | .. note:: | ||
| 142 | The ACPI control method responsible for handling the WMI method calls is not thread-safe. | ||
| 143 | This is a firmware bug that needs to be handled inside the driver itself. | ||
| 144 | |||
| 141 | WMI method Get_EC() | 145 | WMI method Get_EC() |
| 142 | ------------------- | 146 | ------------------- |
| 143 | 147 | ||
| @@ -2519,6 +2519,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git · 2518 unmodified lines | |||
| 2519 | F: arch/arm/boot/dts/nxp/imx/ | 2519 | F: arch/arm/boot/dts/nxp/imx/ |
| 2520 | F: arch/arm/boot/dts/nxp/mxs/ | 2520 | F: arch/arm/boot/dts/nxp/mxs/ |
| 2521 | F: arch/arm64/boot/dts/freescale/ | 2521 | F: arch/arm64/boot/dts/freescale/ |
| 2522 | X: Documentation/devicetree/bindings/media/i2c/ | ||
| 2522 | X: arch/arm64/boot/dts/freescale/fsl-* | 2523 | X: arch/arm64/boot/dts/freescale/fsl-* |
| 2523 | X: arch/arm64/boot/dts/freescale/qoriq-* | 2524 | X: arch/arm64/boot/dts/freescale/qoriq-* |
| 2524 | X: drivers/media/i2c/ | 2525 | X: drivers/media/i2c/ |
| @@ -3191,6 +3192,12 @@ M: Dinh Nguyen <dinguyen@kernel.org> · 666 unmodified lines | |||
| 3191 | S: Maintained | 3192 | S: Maintained |
| 3192 | F: drivers/clk/socfpga/ | 3193 | F: drivers/clk/socfpga/ |
| 3193 | 3194 | ||
| 3195 | ARM/SOCFPGA DWMAC GLUE LAYER | ||
| 3196 | M: Maxime Chevallier <maxime.chevallier@bootlin.com> | ||
| 3197 | S: Maintained | ||
| 3198 | F: Documentation/devicetree/bindings/net/socfpga-dwmac.txt | ||
| 3199 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | ||
| 3200 | |||
| 3194 | ARM/SOCFPGA EDAC BINDINGS | 3201 | ARM/SOCFPGA EDAC BINDINGS |
| 3195 | M: Matthew Gerlach <matthew.gerlach@altera.com> | 3202 | M: Matthew Gerlach <matthew.gerlach@altera.com> |
| 3196 | S: Maintained | 3203 | S: Maintained |
| @@ -3867,8 +3874,9 @@ AUXILIARY BUS DRIVER · 670 unmodified lines | |||
| 3867 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 3874 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 3868 | R: Dave Ertman <david.m.ertman@intel.com> | 3875 | R: Dave Ertman <david.m.ertman@intel.com> |
| 3869 | R: Ira Weiny <ira.weiny@intel.com> | 3876 | R: Ira Weiny <ira.weiny@intel.com> |
| 3877 | R: Leon Romanovsky <leon@kernel.org> | ||
| 3870 | S: Supported | 3878 | S: Supported |
| 3871 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git | 3879 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git |
| 3872 | F: Documentation/driver-api/auxiliary_bus.rst | 3880 | F: Documentation/driver-api/auxiliary_bus.rst |
| 3873 | F: drivers/base/auxiliary.c | 3881 | F: drivers/base/auxiliary.c |
| 3874 | F: include/linux/auxiliary_bus.h | 3882 | F: include/linux/auxiliary_bus.h |
| @@ -6335,6 +6343,7 @@ F: Documentation/process/cve.rst · 2460 unmodified lines | |||
| 6335 | 6343 | ||
| 6336 | CW1200 WLAN driver | 6344 | CW1200 WLAN driver |
| 6337 | S: Orphan | 6345 | S: Orphan |
| 6346 | L: linux-wireless@vger.kernel.org | ||
| 6338 | F: drivers/net/wireless/st/ | 6347 | F: drivers/net/wireless/st/ |
| 6339 | F: include/linux/platform_data/net-cw1200.h | 6348 | F: include/linux/platform_data/net-cw1200.h |
| 6340 | 6349 | ||
| @@ -7020,6 +7029,7 @@ L: rust-for-linux@vger.kernel.org · 679 unmodified lines | |||
| 7020 | S: Supported | 7029 | S: Supported |
| 7021 | W: https://rust-for-linux.com | 7030 | W: https://rust-for-linux.com |
| 7022 | T: git https://github.com/Rust-for-Linux/linux.git alloc-next | 7031 | T: git https://github.com/Rust-for-Linux/linux.git alloc-next |
| 7032 | F: rust/helpers/dma.c | ||
| 7023 | F: rust/kernel/dma.rs | 7033 | F: rust/kernel/dma.rs |
| 7024 | F: samples/rust/rust_dma.rs | 7034 | F: samples/rust/rust_dma.rs |
| 7025 | 7035 | ||
| @@ -7225,7 +7235,7 @@ M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> · 199 unmodified lines | |||
| 7225 | M: "Rafael J. Wysocki" <rafael@kernel.org> | 7235 | M: "Rafael J. Wysocki" <rafael@kernel.org> |
| 7226 | M: Danilo Krummrich <dakr@kernel.org> | 7236 | M: Danilo Krummrich <dakr@kernel.org> |
| 7227 | S: Supported | 7237 | S: Supported |
| 7228 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git | 7238 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git |
| 7229 | F: Documentation/core-api/kobject.rst | 7239 | F: Documentation/core-api/kobject.rst |
| 7230 | F: drivers/base/ | 7240 | F: drivers/base/ |
| 7231 | F: fs/debugfs/ | 7241 | F: fs/debugfs/ |
| @@ -8717,6 +8727,7 @@ M: Chao Yu <chao@kernel.org> · 1485 unmodified lines | |||
| 8717 | R: Yue Hu <zbestahu@gmail.com> | 8727 | R: Yue Hu <zbestahu@gmail.com> |
| 8718 | R: Jeffle Xu <jefflexu@linux.alibaba.com> | 8728 | R: Jeffle Xu <jefflexu@linux.alibaba.com> |
| 8719 | R: Sandeep Dhavale <dhavale@google.com> | 8729 | R: Sandeep Dhavale <dhavale@google.com> |
| 8730 | R: Hongbo Li <lihongbo22@huawei.com> | ||
| 8720 | L: linux-erofs@lists.ozlabs.org | 8731 | L: linux-erofs@lists.ozlabs.org |
| 8721 | S: Maintained | 8732 | S: Maintained |
| 8722 | W: https://erofs.docs.kernel.org | 8733 | W: https://erofs.docs.kernel.org |
| @@ -10136,6 +10147,13 @@ F: drivers/gpio/gpio-regmap.c · 1413 unmodified lines | |||
| 10136 | F: include/linux/gpio/regmap.h | 10147 | F: include/linux/gpio/regmap.h |
| 10137 | K: (devm_)?gpio_regmap_(un)?register | 10148 | K: (devm_)?gpio_regmap_(un)?register |
| 10138 | 10149 | ||
| 10150 | GPIO SLOPPY LOGIC ANALYZER | ||
| 10151 | M: Wolfram Sang <wsa+renesas@sang-engineering.com> | ||
| 10152 | S: Supported | ||
| 10153 | F: Documentation/dev-tools/gpio-sloppy-logic-analyzer.rst | ||
| 10154 | F: drivers/gpio/gpio-sloppy-logic-analyzer.c | ||
| 10155 | F: tools/gpio/gpio-sloppy-logic-analyzer.sh | ||
| 10156 | |||
| 10139 | GPIO SUBSYSTEM | 10157 | GPIO SUBSYSTEM |
| 10140 | M: Linus Walleij <linus.walleij@linaro.org> | 10158 | M: Linus Walleij <linus.walleij@linaro.org> |
| 10141 | M: Bartosz Golaszewski <brgl@bgdev.pl> | 10159 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -10151,6 +10169,8 @@ F: include/linux/gpio.h · 9 unmodified lines | |||
| 10151 | F: include/linux/gpio/ | 10169 | F: include/linux/gpio/ |
| 10152 | F: include/linux/of_gpio.h | 10170 | F: include/linux/of_gpio.h |
| 10153 | K: (devm_)?gpio_(request|free|direction|get|set) | 10171 | K: (devm_)?gpio_(request|free|direction|get|set) |
| 10172 | K: GPIOD_FLAGS_BIT_NONEXCLUSIVE | ||
| 10173 | K: devm_gpiod_unhinge | ||
| 10154 | 10174 | ||
| 10155 | GPIO UAPI | 10175 | GPIO UAPI |
| 10156 | M: Bartosz Golaszewski <brgl@bgdev.pl> | 10176 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -10453,14 +10473,20 @@ S: Supported · 296 unmodified lines | |||
| 10453 | F: drivers/infiniband/hw/hfi1 | 10473 | F: drivers/infiniband/hw/hfi1 |
| 10454 | 10474 | ||
| 10455 | HFS FILESYSTEM | 10475 | HFS FILESYSTEM |
| 10476 | M: Viacheslav Dubeyko <slava@dubeyko.com> | ||
| 10477 | M: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> | ||
| 10478 | M: Yangtao Li <frank.li@vivo.com> | ||
| 10456 | L: linux-fsdevel@vger.kernel.org | 10479 | L: linux-fsdevel@vger.kernel.org |
| 10457 | S: Orphan | 10480 | S: Maintained |
| 10458 | F: Documentation/filesystems/hfs.rst | 10481 | F: Documentation/filesystems/hfs.rst |
| 10459 | F: fs/hfs/ | 10482 | F: fs/hfs/ |
| 10460 | 10483 | ||
| 10461 | HFSPLUS FILESYSTEM | 10484 | HFSPLUS FILESYSTEM |
| 10485 | M: Viacheslav Dubeyko <slava@dubeyko.com> | ||
| 10486 | M: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> | ||
| 10487 | M: Yangtao Li <frank.li@vivo.com> | ||
| 10462 | L: linux-fsdevel@vger.kernel.org | 10488 | L: linux-fsdevel@vger.kernel.org |
| 10463 | S: Orphan | 10489 | S: Maintained |
| 10464 | F: Documentation/filesystems/hfsplus.rst | 10490 | F: Documentation/filesystems/hfsplus.rst |
| 10465 | F: fs/hfsplus/ | 10491 | F: fs/hfsplus/ |
| 10466 | 10492 | ||
| @@ -10954,6 +10980,7 @@ F: include/linux/platform_data/huawei-gaokun-ec.h · 487 unmodified lines | |||
| 10954 | 10980 | ||
| 10955 | HUGETLB SUBSYSTEM | 10981 | HUGETLB SUBSYSTEM |
| 10956 | M: Muchun Song <muchun.song@linux.dev> | 10982 | M: Muchun Song <muchun.song@linux.dev> |
| 10983 | R: Oscar Salvador <osalvador@suse.de> | ||
| 10957 | L: linux-mm@kvack.org | 10984 | L: linux-mm@kvack.org |
| 10958 | S: Maintained | 10985 | S: Maintained |
| 10959 | F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages | 10986 | F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages |
| @@ -11079,6 +11106,14 @@ L: linuxppc-dev@lists.ozlabs.org · 119 unmodified lines | |||
| 11079 | S: Odd Fixes | 11106 | S: Odd Fixes |
| 11080 | F: drivers/tty/hvc/ | 11107 | F: drivers/tty/hvc/ |
| 11081 | 11108 | ||
| 11109 | HUNG TASK DETECTOR | ||
| 11110 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 11111 | R: Lance Yang <lance.yang@linux.dev> | ||
| 11112 | L: linux-kernel@vger.kernel.org | ||
| 11113 | S: Maintained | ||
| 11114 | F: include/linux/hung_task.h | ||
| 11115 | F: kernel/hung_task.c | ||
| 11116 | |||
| 11082 | I2C ACPI SUPPORT | 11117 | I2C ACPI SUPPORT |
| 11083 | M: Mika Westerberg <westeri@kernel.org> | 11118 | M: Mika Westerberg <westeri@kernel.org> |
| 11084 | L: linux-i2c@vger.kernel.org | 11119 | L: linux-i2c@vger.kernel.org |
| @@ -11217,7 +11252,6 @@ S: Maintained · 132 unmodified lines | |||
| 11217 | F: drivers/i2c/busses/i2c-cht-wc.c | 11252 | F: drivers/i2c/busses/i2c-cht-wc.c |
| 11218 | 11253 | ||
| 11219 | I2C/SMBUS ISMT DRIVER | 11254 | I2C/SMBUS ISMT DRIVER |
| 11220 | M: Seth Heasley <seth.heasley@intel.com> | ||
| 11221 | M: Neil Horman <nhorman@tuxdriver.com> | 11255 | M: Neil Horman <nhorman@tuxdriver.com> |
| 11222 | L: linux-i2c@vger.kernel.org | 11256 | L: linux-i2c@vger.kernel.org |
| 11223 | F: Documentation/i2c/busses/i2c-ismt.rst | 11257 | F: Documentation/i2c/busses/i2c-ismt.rst |
| @@ -12810,6 +12844,7 @@ F: lib/Kconfig.kcsan · 1586 unmodified lines | |||
| 12810 | F: scripts/Makefile.kcsan | 12844 | F: scripts/Makefile.kcsan |
| 12811 | 12845 | ||
| 12812 | KDUMP | 12846 | KDUMP |
| 12847 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 12813 | M: Baoquan He <bhe@redhat.com> | 12848 | M: Baoquan He <bhe@redhat.com> |
| 12814 | R: Vivek Goyal <vgoyal@redhat.com> | 12849 | R: Vivek Goyal <vgoyal@redhat.com> |
| 12815 | R: Dave Young <dyoung@redhat.com> | 12850 | R: Dave Young <dyoung@redhat.com> |
| @@ -13106,11 +13141,13 @@ KERNFS · 290 unmodified lines | |||
| 13106 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 13141 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 13107 | M: Tejun Heo <tj@kernel.org> | 13142 | M: Tejun Heo <tj@kernel.org> |
| 13108 | S: Supported | 13143 | S: Supported |
| 13109 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git | 13144 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git |
| 13110 | F: fs/kernfs/ | 13145 | F: fs/kernfs/ |
| 13111 | F: include/linux/kernfs.h | 13146 | F: include/linux/kernfs.h |
| 13112 | 13147 | ||
| 13113 | KEXEC | 13148 | KEXEC |
| 13149 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 13150 | M: Baoquan He <bhe@redhat.com> | ||
| 13114 | L: kexec@lists.infradead.org | 13151 | L: kexec@lists.infradead.org |
| 13115 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ | 13152 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ |
| 13116 | F: include/linux/kexec.h | 13153 | F: include/linux/kexec.h |
| @@ -14283,6 +14320,7 @@ S: Odd fixes · 1166 unmodified lines | |||
| 14283 | F: drivers/net/ethernet/marvell/sk* | 14320 | F: drivers/net/ethernet/marvell/sk* |
| 14284 | 14321 | ||
| 14285 | MARVELL LIBERTAS WIRELESS DRIVER | 14322 | MARVELL LIBERTAS WIRELESS DRIVER |
| 14323 | L: linux-wireless@vger.kernel.org | ||
| 14286 | L: libertas-dev@lists.infradead.org | 14324 | L: libertas-dev@lists.infradead.org |
| 14287 | S: Orphan | 14325 | S: Orphan |
| 14288 | F: drivers/net/wireless/marvell/libertas/ | 14326 | F: drivers/net/wireless/marvell/libertas/ |
| @@ -15049,7 +15087,7 @@ F: Documentation/devicetree/bindings/media/mediatek-jpeg-*.yaml · 760 unmodified lines | |||
| 15049 | F: drivers/media/platform/mediatek/jpeg/ | 15087 | F: drivers/media/platform/mediatek/jpeg/ |
| 15050 | 15088 | ||
| 15051 | MEDIATEK KEYPAD DRIVER | 15089 | MEDIATEK KEYPAD DRIVER |
| 15052 | M: Mattijs Korpershoek <mkorpershoek@baylibre.com> | 15090 | M: Mattijs Korpershoek <mkorpershoek@kernel.org> |
| 15053 | S: Supported | 15091 | S: Supported |
| 15054 | F: Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml | 15092 | F: Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml |
| 15055 | F: drivers/input/keyboard/mt6779-keypad.c | 15093 | F: drivers/input/keyboard/mt6779-keypad.c |
| @@ -15472,24 +15510,45 @@ F: Documentation/mm/ · 416 unmodified lines | |||
| 15472 | F: include/linux/gfp.h | 15510 | F: include/linux/gfp.h |
| 15473 | F: include/linux/gfp_types.h | 15511 | F: include/linux/gfp_types.h |
| 15474 | F: include/linux/memfd.h | 15512 | F: include/linux/memfd.h |
| 15475 | F: include/linux/memory.h | ||
| 15476 | F: include/linux/memory_hotplug.h | 15513 | F: include/linux/memory_hotplug.h |
| 15477 | F: include/linux/memory-tiers.h | 15514 | F: include/linux/memory-tiers.h |
| 15478 | F: include/linux/mempolicy.h | 15515 | F: include/linux/mempolicy.h |
| 15479 | F: include/linux/mempool.h | 15516 | F: include/linux/mempool.h |
| 15480 | F: include/linux/memremap.h | 15517 | F: include/linux/memremap.h |
| 15481 | F: include/linux/mm.h | ||
| 15482 | F: include/linux/mm_*.h | ||
| 15483 | F: include/linux/mmzone.h | 15518 | F: include/linux/mmzone.h |
| 15484 | F: include/linux/mmu_notifier.h | 15519 | F: include/linux/mmu_notifier.h |
| 15485 | F: include/linux/pagewalk.h | 15520 | F: include/linux/pagewalk.h |
| 15486 | F: include/linux/rmap.h | ||
| 15487 | F: include/trace/events/ksm.h | 15521 | F: include/trace/events/ksm.h |
| 15488 | F: mm/ | 15522 | F: mm/ |
| 15489 | F: tools/mm/ | 15523 | F: tools/mm/ |
| 15490 | F: tools/testing/selftests/mm/ | 15524 | F: tools/testing/selftests/mm/ |
| 15491 | N: include/linux/page[-_]* | 15525 | N: include/linux/page[-_]* |
| 15492 | 15526 | ||
| 15527 | MEMORY MANAGEMENT - CORE | ||
| 15528 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15529 | M: David Hildenbrand <david@redhat.com> | ||
| 15530 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15531 | R: Liam R. Howlett <Liam.Howlett@oracle.com> | ||
| 15532 | R: Vlastimil Babka <vbabka@suse.cz> | ||
| 15533 | R: Mike Rapoport <rppt@kernel.org> | ||
| 15534 | R: Suren Baghdasaryan <surenb@google.com> | ||
| 15535 | R: Michal Hocko <mhocko@suse.com> | ||
| 15536 | L: linux-mm@kvack.org | ||
| 15537 | S: Maintained | ||
| 15538 | W: http://www.linux-mm.org | ||
| 15539 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15540 | F: include/linux/memory.h | ||
| 15541 | F: include/linux/mm.h | ||
| 15542 | F: include/linux/mm_*.h | ||
| 15543 | F: include/linux/mmdebug.h | ||
| 15544 | F: include/linux/pagewalk.h | ||
| 15545 | F: mm/Kconfig | ||
| 15546 | F: mm/debug.c | ||
| 15547 | F: mm/init-mm.c | ||
| 15548 | F: mm/memory.c | ||
| 15549 | F: mm/pagewalk.c | ||
| 15550 | F: mm/util.c | ||
| 15551 | |||
| 15493 | MEMORY MANAGEMENT - EXECMEM | 15552 | MEMORY MANAGEMENT - EXECMEM |
| 15494 | M: Andrew Morton <akpm@linux-foundation.org> | 15553 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15495 | M: Mike Rapoport <rppt@kernel.org> | 15554 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15498,6 +15557,53 @@ S: Maintained · 2 unmodified lines | |||
| 15498 | F: include/linux/execmem.h | 15557 | F: include/linux/execmem.h |
| 15499 | F: mm/execmem.c | 15558 | F: mm/execmem.c |
| 15500 | 15559 | ||
| 15560 | MEMORY MANAGEMENT - GUP (GET USER PAGES) | ||
| 15561 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15562 | M: David Hildenbrand <david@redhat.com> | ||
| 15563 | R: Jason Gunthorpe <jgg@nvidia.com> | ||
| 15564 | R: John Hubbard <jhubbard@nvidia.com> | ||
| 15565 | R: Peter Xu <peterx@redhat.com> | ||
| 15566 | L: linux-mm@kvack.org | ||
| 15567 | S: Maintained | ||
| 15568 | W: http://www.linux-mm.org | ||
| 15569 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15570 | F: mm/gup.c | ||
| 15571 | |||
| 15572 | MEMORY MANAGEMENT - KSM (Kernel Samepage Merging) | ||
| 15573 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15574 | M: David Hildenbrand <david@redhat.com> | ||
| 15575 | R: Xu Xin <xu.xin16@zte.com.cn> | ||
| 15576 | R: Chengming Zhou <chengming.zhou@linux.dev> | ||
| 15577 | L: linux-mm@kvack.org | ||
| 15578 | S: Maintained | ||
| 15579 | W: http://www.linux-mm.org | ||
| 15580 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15581 | F: Documentation/admin-guide/mm/ksm.rst | ||
| 15582 | F: Documentation/mm/ksm.rst | ||
| 15583 | F: include/linux/ksm.h | ||
| 15584 | F: include/trace/events/ksm.h | ||
| 15585 | F: mm/ksm.c | ||
| 15586 | |||
| 15587 | MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION | ||
| 15588 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15589 | M: David Hildenbrand <david@redhat.com> | ||
| 15590 | R: Zi Yan <ziy@nvidia.com> | ||
| 15591 | R: Matthew Brost <matthew.brost@intel.com> | ||
| 15592 | R: Joshua Hahn <joshua.hahnjy@gmail.com> | ||
| 15593 | R: Rakie Kim <rakie.kim@sk.com> | ||
| 15594 | R: Byungchul Park <byungchul@sk.com> | ||
| 15595 | R: Gregory Price <gourry@gourry.net> | ||
| 15596 | R: Ying Huang <ying.huang@linux.alibaba.com> | ||
| 15597 | L: linux-mm@kvack.org | ||
| 15598 | S: Maintained | ||
| 15599 | W: http://www.linux-mm.org | ||
| 15600 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15601 | F: include/linux/mempolicy.h | ||
| 15602 | F: include/linux/migrate.h | ||
| 15603 | F: mm/mempolicy.c | ||
| 15604 | F: mm/migrate.c | ||
| 15605 | F: mm/migrate_device.c | ||
| 15606 | |||
| 15501 | MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION | 15607 | MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION |
| 15502 | M: Andrew Morton <akpm@linux-foundation.org> | 15608 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15503 | M: Mike Rapoport <rppt@kernel.org> | 15609 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15508,6 +15614,49 @@ F: mm/numa.c · 4 unmodified lines | |||
| 15508 | F: mm/numa_emulation.c | 15614 | F: mm/numa_emulation.c |
| 15509 | F: mm/numa_memblks.c | 15615 | F: mm/numa_memblks.c |
| 15510 | 15616 | ||
| 15617 | MEMORY MANAGEMENT - PAGE ALLOCATOR | ||
| 15618 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15619 | M: Vlastimil Babka <vbabka@suse.cz> | ||
| 15620 | R: Suren Baghdasaryan <surenb@google.com> | ||
| 15621 | R: Michal Hocko <mhocko@suse.com> | ||
| 15622 | R: Brendan Jackman <jackmanb@google.com> | ||
| 15623 | R: Johannes Weiner <hannes@cmpxchg.org> | ||
| 15624 | R: Zi Yan <ziy@nvidia.com> | ||
| 15625 | L: linux-mm@kvack.org | ||
| 15626 | S: Maintained | ||
| 15627 | F: include/linux/compaction.h | ||
| 15628 | F: include/linux/gfp.h | ||
| 15629 | F: include/linux/page-isolation.h | ||
| 15630 | F: mm/compaction.c | ||
| 15631 | F: mm/page_alloc.c | ||
| 15632 | F: mm/page_isolation.c | ||
| 15633 | |||
| 15634 | MEMORY MANAGEMENT - RECLAIM | ||
| 15635 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15636 | M: Johannes Weiner <hannes@cmpxchg.org> | ||
| 15637 | R: David Hildenbrand <david@redhat.com> | ||
| 15638 | R: Michal Hocko <mhocko@kernel.org> | ||
| 15639 | R: Qi Zheng <zhengqi.arch@bytedance.com> | ||
| 15640 | R: Shakeel Butt <shakeel.butt@linux.dev> | ||
| 15641 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15642 | L: linux-mm@kvack.org | ||
| 15643 | S: Maintained | ||
| 15644 | F: mm/pt_reclaim.c | ||
| 15645 | F: mm/vmscan.c | ||
| 15646 | |||
| 15647 | MEMORY MANAGEMENT - RMAP (REVERSE MAPPING) | ||
| 15648 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15649 | M: David Hildenbrand <david@redhat.com> | ||
| 15650 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15651 | R: Rik van Riel <riel@surriel.com> | ||
| 15652 | R: Liam R. Howlett <Liam.Howlett@oracle.com> | ||
| 15653 | R: Vlastimil Babka <vbabka@suse.cz> | ||
| 15654 | R: Harry Yoo <harry.yoo@oracle.com> | ||
| 15655 | L: linux-mm@kvack.org | ||
| 15656 | S: Maintained | ||
| 15657 | F: include/linux/rmap.h | ||
| 15658 | F: mm/rmap.c | ||
| 15659 | |||
| 15511 | MEMORY MANAGEMENT - SECRETMEM | 15660 | MEMORY MANAGEMENT - SECRETMEM |
| 15512 | M: Andrew Morton <akpm@linux-foundation.org> | 15661 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15513 | M: Mike Rapoport <rppt@kernel.org> | 15662 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15516,6 +15665,30 @@ S: Maintained · 2 unmodified lines | |||
| 15516 | F: include/linux/secretmem.h | 15665 | F: include/linux/secretmem.h |
| 15517 | F: mm/secretmem.c | 15666 | F: mm/secretmem.c |
| 15518 | 15667 | ||
| 15668 | MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE) | ||
| 15669 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15670 | M: David Hildenbrand <david@redhat.com> | ||
| 15671 | R: Zi Yan <ziy@nvidia.com> | ||
| 15672 | R: Baolin Wang <baolin.wang@linux.alibaba.com> | ||
| 15673 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15674 | R: Liam R. Howlett <Liam.Howlett@oracle.com> | ||
| 15675 | R: Nico Pache <npache@redhat.com> | ||
| 15676 | R: Ryan Roberts <ryan.roberts@arm.com> | ||
| 15677 | R: Dev Jain <dev.jain@arm.com> | ||
| 15678 | L: linux-mm@kvack.org | ||
| 15679 | S: Maintained | ||
| 15680 | W: http://www.linux-mm.org | ||
| 15681 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15682 | F: Documentation/admin-guide/mm/transhuge.rst | ||
| 15683 | F: include/linux/huge_mm.h | ||
| 15684 | F: include/linux/khugepaged.h | ||
| 15685 | F: include/trace/events/huge_memory.h | ||
| 15686 | F: mm/huge_memory.c | ||
| 15687 | F: mm/khugepaged.c | ||
| 15688 | F: tools/testing/selftests/mm/khugepaged.c | ||
| 15689 | F: tools/testing/selftests/mm/split_huge_page_test.c | ||
| 15690 | F: tools/testing/selftests/mm/transhuge-stress.c | ||
| 15691 | |||
| 15519 | MEMORY MANAGEMENT - USERFAULTFD | 15692 | MEMORY MANAGEMENT - USERFAULTFD |
| 15520 | M: Andrew Morton <akpm@linux-foundation.org> | 15693 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15521 | R: Peter Xu <peterx@redhat.com> | 15694 | R: Peter Xu <peterx@redhat.com> |
| @@ -15535,10 +15708,12 @@ M: Liam R. Howlett <Liam.Howlett@oracle.com> · 13 unmodified lines | |||
| 15535 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | 15708 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> |
| 15536 | R: Vlastimil Babka <vbabka@suse.cz> | 15709 | R: Vlastimil Babka <vbabka@suse.cz> |
| 15537 | R: Jann Horn <jannh@google.com> | 15710 | R: Jann Horn <jannh@google.com> |
| 15711 | R: Pedro Falcato <pfalcato@suse.de> | ||
| 15538 | L: linux-mm@kvack.org | 15712 | L: linux-mm@kvack.org |
| 15539 | S: Maintained | 15713 | S: Maintained |
| 15540 | W: http://www.linux-mm.org | 15714 | W: http://www.linux-mm.org |
| 15541 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | 15715 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm |
| 15716 | F: include/trace/events/mmap.h | ||
| 15542 | F: mm/mlock.c | 15717 | F: mm/mlock.c |
| 15543 | F: mm/mmap.c | 15718 | F: mm/mmap.c |
| 15544 | F: mm/mprotect.c | 15719 | F: mm/mprotect.c |
| @@ -15549,6 +15724,36 @@ F: mm/vma.h · 4 unmodified lines | |||
| 15549 | F: mm/vma_internal.h | 15724 | F: mm/vma_internal.h |
| 15550 | F: tools/testing/vma/ | 15725 | F: tools/testing/vma/ |
| 15551 | 15726 | ||
| 15727 | MEMORY MAPPING - LOCKING | ||
| 15728 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15729 | M: Suren Baghdasaryan <surenb@google.com> | ||
| 15730 | M: Liam R. Howlett <Liam.Howlett@oracle.com> | ||
| 15731 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15732 | R: Vlastimil Babka <vbabka@suse.cz> | ||
| 15733 | R: Shakeel Butt <shakeel.butt@linux.dev> | ||
| 15734 | L: linux-mm@kvack.org | ||
| 15735 | S: Maintained | ||
| 15736 | W: http://www.linux-mm.org | ||
| 15737 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15738 | F: Documentation/mm/process_addrs.rst | ||
| 15739 | F: include/linux/mmap_lock.h | ||
| 15740 | F: include/trace/events/mmap_lock.h | ||
| 15741 | F: mm/mmap_lock.c | ||
| 15742 | |||
| 15743 | MEMORY MAPPING - MADVISE (MEMORY ADVICE) | ||
| 15744 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 15745 | M: Liam R. Howlett <Liam.Howlett@oracle.com> | ||
| 15746 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | ||
| 15747 | M: David Hildenbrand <david@redhat.com> | ||
| 15748 | R: Vlastimil Babka <vbabka@suse.cz> | ||
| 15749 | R: Jann Horn <jannh@google.com> | ||
| 15750 | L: linux-mm@kvack.org | ||
| 15751 | S: Maintained | ||
| 15752 | W: http://www.linux-mm.org | ||
| 15753 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 15754 | F: include/uapi/asm-generic/mman-common.h | ||
| 15755 | F: mm/madvise.c | ||
| 15756 | |||
| 15552 | MEMORY TECHNOLOGY DEVICES (MTD) | 15757 | MEMORY TECHNOLOGY DEVICES (MTD) |
| 15553 | M: Miquel Raynal <miquel.raynal@bootlin.com> | 15758 | M: Miquel Raynal <miquel.raynal@bootlin.com> |
| 15554 | M: Richard Weinberger <richard@nod.at> | 15759 | M: Richard Weinberger <richard@nod.at> |
| @@ -16756,6 +16961,7 @@ F: Documentation/networking/net_cachelines/net_device.rst · 1201 unmodified lines | |||
| 16756 | F: drivers/connector/ | 16961 | F: drivers/connector/ |
| 16757 | F: drivers/net/ | 16962 | F: drivers/net/ |
| 16758 | F: drivers/ptp/ | 16963 | F: drivers/ptp/ |
| 16964 | F: drivers/s390/net/ | ||
| 16759 | F: include/dt-bindings/net/ | 16965 | F: include/dt-bindings/net/ |
| 16760 | F: include/linux/cn_proc.h | 16966 | F: include/linux/cn_proc.h |
| 16761 | F: include/linux/etherdevice.h | 16967 | F: include/linux/etherdevice.h |
| @@ -16765,6 +16971,7 @@ F: include/linux/fddidevice.h · 3 unmodified lines | |||
| 16765 | F: include/linux/hippidevice.h | 16971 | F: include/linux/hippidevice.h |
| 16766 | F: include/linux/if_* | 16972 | F: include/linux/if_* |
| 16767 | F: include/linux/inetdevice.h | 16973 | F: include/linux/inetdevice.h |
| 16974 | F: include/linux/ism.h | ||
| 16768 | F: include/linux/netdev* | 16975 | F: include/linux/netdev* |
| 16769 | F: include/linux/platform_data/wiznet.h | 16976 | F: include/linux/platform_data/wiznet.h |
| 16770 | F: include/uapi/linux/cn_proc.h | 16977 | F: include/uapi/linux/cn_proc.h |
| @@ -17368,7 +17575,7 @@ T: git git://git.infradead.org/nvme.git · 597 unmodified lines | |||
| 17368 | F: drivers/nvme/target/ | 17575 | F: drivers/nvme/target/ |
| 17369 | 17576 | ||
| 17370 | NVMEM FRAMEWORK | 17577 | NVMEM FRAMEWORK |
| 17371 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 17578 | M: Srinivas Kandagatla <srini@kernel.org> |
| 17372 | S: Maintained | 17579 | S: Maintained |
| 17373 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git | 17580 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git |
| 17374 | F: Documentation/ABI/stable/sysfs-bus-nvmem | 17581 | F: Documentation/ABI/stable/sysfs-bus-nvmem |
| @@ -18302,7 +18509,7 @@ F: include/uapi/linux/ppdev.h · 927 unmodified lines | |||
| 18302 | PARAVIRT_OPS INTERFACE | 18509 | PARAVIRT_OPS INTERFACE |
| 18303 | M: Juergen Gross <jgross@suse.com> | 18510 | M: Juergen Gross <jgross@suse.com> |
| 18304 | R: Ajay Kaher <ajay.kaher@broadcom.com> | 18511 | R: Ajay Kaher <ajay.kaher@broadcom.com> |
| 18305 | R: Alexey Makhalov <alexey.amakhalov@broadcom.com> | 18512 | R: Alexey Makhalov <alexey.makhalov@broadcom.com> |
| 18306 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 18513 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 18307 | L: virtualization@lists.linux.dev | 18514 | L: virtualization@lists.linux.dev |
| 18308 | L: x86@kernel.org | 18515 | L: x86@kernel.org |
| @@ -18633,7 +18840,7 @@ F: drivers/pci/controller/pci-xgene-msi.c · 324 unmodified lines | |||
| 18633 | PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS | 18840 | PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS |
| 18634 | M: Lorenzo Pieralisi <lpieralisi@kernel.org> | 18841 | M: Lorenzo Pieralisi <lpieralisi@kernel.org> |
| 18635 | M: Krzysztof Wilczyński <kw@linux.com> | 18842 | M: Krzysztof Wilczyński <kw@linux.com> |
| 18636 | R: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 18843 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 18637 | R: Rob Herring <robh@kernel.org> | 18844 | R: Rob Herring <robh@kernel.org> |
| 18638 | L: linux-pci@vger.kernel.org | 18845 | L: linux-pci@vger.kernel.org |
| 18639 | S: Supported | 18846 | S: Supported |
| @@ -18686,6 +18893,16 @@ F: include/asm-generic/pci* · 46 unmodified lines | |||
| 18686 | F: include/linux/of_pci.h | 18893 | F: include/linux/of_pci.h |
| 18687 | F: include/linux/pci* | 18894 | F: include/linux/pci* |
| 18688 | F: include/uapi/linux/pci* | 18895 | F: include/uapi/linux/pci* |
| 18896 | |||
| 18897 | PCI SUBSYSTEM [RUST] | ||
| 18898 | M: Danilo Krummrich <dakr@kernel.org> | ||
| 18899 | R: Bjorn Helgaas <bhelgaas@google.com> | ||
| 18900 | R: Krzysztof Wilczyński <kwilczynski@kernel.org> | ||
| 18901 | L: linux-pci@vger.kernel.org | ||
| 18902 | S: Maintained | ||
| 18903 | C: irc://irc.oftc.net/linux-pci | ||
| 18904 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git | ||
| 18905 | F: rust/helpers/pci.c | ||
| 18689 | F: rust/kernel/pci.rs | 18906 | F: rust/kernel/pci.rs |
| 18690 | F: samples/rust/rust_driver_pci.rs | 18907 | F: samples/rust/rust_driver_pci.rs |
| 18691 | 18908 | ||
| @@ -19573,7 +19790,7 @@ S: Supported · 881 unmodified lines | |||
| 19573 | F: drivers/crypto/intel/qat/ | 19790 | F: drivers/crypto/intel/qat/ |
| 19574 | 19791 | ||
| 19575 | QCOM AUDIO (ASoC) DRIVERS | 19792 | QCOM AUDIO (ASoC) DRIVERS |
| 19576 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 19793 | M: Srinivas Kandagatla <srini@kernel.org> |
| 19577 | L: linux-sound@vger.kernel.org | 19794 | L: linux-sound@vger.kernel.org |
| 19578 | L: linux-arm-msm@vger.kernel.org | 19795 | L: linux-arm-msm@vger.kernel.org |
| 19579 | S: Supported | 19796 | S: Supported |
| @@ -19746,6 +19963,7 @@ F: drivers/media/tuners/qt1010* · 166 unmodified lines | |||
| 19746 | 19963 | ||
| 19747 | QUALCOMM ATH12K WIRELESS DRIVER | 19964 | QUALCOMM ATH12K WIRELESS DRIVER |
| 19748 | M: Jeff Johnson <jjohnson@kernel.org> | 19965 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19966 | L: linux-wireless@vger.kernel.org | ||
| 19749 | L: ath12k@lists.infradead.org | 19967 | L: ath12k@lists.infradead.org |
| 19750 | S: Supported | 19968 | S: Supported |
| 19751 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k | 19969 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k |
| @@ -19755,6 +19973,7 @@ N: ath12k · 3 unmodified lines | |||
| 19755 | 19973 | ||
| 19756 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER | 19974 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER |
| 19757 | M: Jeff Johnson <jjohnson@kernel.org> | 19975 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19976 | L: linux-wireless@vger.kernel.org | ||
| 19758 | L: ath10k@lists.infradead.org | 19977 | L: ath10k@lists.infradead.org |
| 19759 | S: Supported | 19978 | S: Supported |
| 19760 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k | 19979 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k |
| @@ -19764,6 +19983,7 @@ N: ath10k · 3 unmodified lines | |||
| 19764 | 19983 | ||
| 19765 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER | 19984 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER |
| 19766 | M: Jeff Johnson <jjohnson@kernel.org> | 19985 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19986 | L: linux-wireless@vger.kernel.org | ||
| 19767 | L: ath11k@lists.infradead.org | 19987 | L: ath11k@lists.infradead.org |
| 19768 | S: Supported | 19988 | S: Supported |
| 19769 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k | 19989 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k |
| @@ -19873,7 +20093,7 @@ F: Documentation/devicetree/bindings/net/qcom,ethqos.yaml · 103 unmodified lines | |||
| 19873 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 20093 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
| 19874 | 20094 | ||
| 19875 | QUALCOMM FASTRPC DRIVER | 20095 | QUALCOMM FASTRPC DRIVER |
| 19876 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 20096 | M: Srinivas Kandagatla <srini@kernel.org> |
| 19877 | M: Amol Maheshwari <amahesh@qti.qualcomm.com> | 20097 | M: Amol Maheshwari <amahesh@qti.qualcomm.com> |
| 19878 | L: linux-arm-msm@vger.kernel.org | 20098 | L: linux-arm-msm@vger.kernel.org |
| 19879 | L: dri-devel@lists.freedesktop.org | 20099 | L: dri-devel@lists.freedesktop.org |
| @@ -20451,8 +20671,8 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml · 571 unmodified lines | |||
| 20451 | F: drivers/i2c/busses/i2c-emev2.c | 20671 | F: drivers/i2c/busses/i2c-emev2.c |
| 20452 | 20672 | ||
| 20453 | RENESAS ETHERNET AVB DRIVER | 20673 | RENESAS ETHERNET AVB DRIVER |
| 20454 | M: Paul Barker <paul.barker.ct@bp.renesas.com> | ||
| 20455 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> | 20674 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 20675 | R: Paul Barker <paul@pbarker.dev> | ||
| 20456 | L: netdev@vger.kernel.org | 20676 | L: netdev@vger.kernel.org |
| 20457 | L: linux-renesas-soc@vger.kernel.org | 20677 | L: linux-renesas-soc@vger.kernel.org |
| 20458 | S: Maintained | 20678 | S: Maintained |
| @@ -21253,6 +21473,7 @@ L: linux-s390@vger.kernel.org · 794 unmodified lines | |||
| 21253 | L: netdev@vger.kernel.org | 21473 | L: netdev@vger.kernel.org |
| 21254 | S: Supported | 21474 | S: Supported |
| 21255 | F: drivers/s390/net/ | 21475 | F: drivers/s390/net/ |
| 21476 | F: include/linux/ism.h | ||
| 21256 | 21477 | ||
| 21257 | S390 PCI SUBSYSTEM | 21478 | S390 PCI SUBSYSTEM |
| 21258 | M: Niklas Schnelle <schnelle@linux.ibm.com> | 21479 | M: Niklas Schnelle <schnelle@linux.ibm.com> |
| @@ -21921,7 +22142,7 @@ S: Maintained · 662 unmodified lines | |||
| 21921 | F: drivers/media/rc/serial_ir.c | 22142 | F: drivers/media/rc/serial_ir.c |
| 21922 | 22143 | ||
| 21923 | SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) | 22144 | SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) |
| 21924 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 22145 | M: Srinivas Kandagatla <srini@kernel.org> |
| 21925 | L: linux-sound@vger.kernel.org | 22146 | L: linux-sound@vger.kernel.org |
| 21926 | S: Maintained | 22147 | S: Maintained |
| 21927 | F: Documentation/devicetree/bindings/slimbus/ | 22148 | F: Documentation/devicetree/bindings/slimbus/ |
| @@ -22137,6 +22358,7 @@ F: drivers/platform/x86/touchscreen_dmi.c · 209 unmodified lines | |||
| 22137 | 22358 | ||
| 22138 | SILICON LABS WIRELESS DRIVERS (for WFxxx series) | 22359 | SILICON LABS WIRELESS DRIVERS (for WFxxx series) |
| 22139 | M: Jérôme Pouiller <jerome.pouiller@silabs.com> | 22360 | M: Jérôme Pouiller <jerome.pouiller@silabs.com> |
| 22361 | L: linux-wireless@vger.kernel.org | ||
| 22140 | S: Supported | 22362 | S: Supported |
| 22141 | F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml | 22363 | F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml |
| 22142 | F: drivers/net/wireless/silabs/ | 22364 | F: drivers/net/wireless/silabs/ |
| @@ -22237,9 +22459,7 @@ F: drivers/nvmem/layouts/sl28vpd.c · 94 unmodified lines | |||
| 22237 | 22459 | ||
| 22238 | SLAB ALLOCATOR | 22460 | SLAB ALLOCATOR |
| 22239 | M: Christoph Lameter <cl@linux.com> | 22461 | M: Christoph Lameter <cl@linux.com> |
| 22240 | M: Pekka Enberg <penberg@kernel.org> | ||
| 22241 | M: David Rientjes <rientjes@google.com> | 22462 | M: David Rientjes <rientjes@google.com> |
| 22242 | M: Joonsoo Kim <iamjoonsoo.kim@lge.com> | ||
| 22243 | M: Andrew Morton <akpm@linux-foundation.org> | 22463 | M: Andrew Morton <akpm@linux-foundation.org> |
| 22244 | M: Vlastimil Babka <vbabka@suse.cz> | 22464 | M: Vlastimil Babka <vbabka@suse.cz> |
| 22245 | R: Roman Gushchin <roman.gushchin@linux.dev> | 22465 | R: Roman Gushchin <roman.gushchin@linux.dev> |
| @@ -22654,9 +22874,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git · 408 unmodified lines | |||
| 22654 | F: Documentation/devicetree/bindings/sound/ | 22874 | F: Documentation/devicetree/bindings/sound/ |
| 22655 | F: Documentation/sound/soc/ | 22875 | F: Documentation/sound/soc/ |
| 22656 | F: include/dt-bindings/sound/ | 22876 | F: include/dt-bindings/sound/ |
| 22877 | F: include/sound/cs-amp-lib.h | ||
| 22878 | F: include/sound/cs35l* | ||
| 22879 | F: include/sound/cs4271.h | ||
| 22880 | F: include/sound/cs42l* | ||
| 22881 | F: include/sound/madera-pdata.h | ||
| 22657 | F: include/sound/soc* | 22882 | F: include/sound/soc* |
| 22658 | F: include/sound/sof.h | 22883 | F: include/sound/sof.h |
| 22659 | F: include/sound/sof/ | 22884 | F: include/sound/sof/ |
| 22885 | F: include/sound/wm*.h | ||
| 22660 | F: include/trace/events/sof*.h | 22886 | F: include/trace/events/sof*.h |
| 22661 | F: include/uapi/sound/asoc.h | 22887 | F: include/uapi/sound/asoc.h |
| 22662 | F: sound/soc/ | 22888 | F: sound/soc/ |
| @@ -22767,7 +22993,6 @@ F: drivers/accessibility/speakup/ · 104 unmodified lines | |||
| 22767 | 22993 | ||
| 22768 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT | 22994 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 22769 | M: Viresh Kumar <vireshk@kernel.org> | 22995 | M: Viresh Kumar <vireshk@kernel.org> |
| 22770 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> | ||
| 22771 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 22996 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 22772 | L: soc@lists.linux.dev | 22997 | L: soc@lists.linux.dev |
| 22773 | S: Maintained | 22998 | S: Maintained |
| @@ -25126,9 +25351,13 @@ S: Maintained · 2352 unmodified lines | |||
| 25126 | F: drivers/usb/typec/mux/pi3usb30532.c | 25351 | F: drivers/usb/typec/mux/pi3usb30532.c |
| 25127 | 25352 | ||
| 25128 | USB TYPEC PORT CONTROLLER DRIVERS | 25353 | USB TYPEC PORT CONTROLLER DRIVERS |
| 25354 | M: Badhri Jagan Sridharan <badhri@google.com> | ||
| 25129 | L: linux-usb@vger.kernel.org | 25355 | L: linux-usb@vger.kernel.org |
| 25130 | S: Orphan | 25356 | S: Maintained |
| 25131 | F: drivers/usb/typec/tcpm/ | 25357 | F: drivers/usb/typec/tcpm/tcpci.c |
| 25358 | F: drivers/usb/typec/tcpm/tcpm.c | ||
| 25359 | F: include/linux/usb/tcpci.h | ||
| 25360 | F: include/linux/usb/tcpm.h | ||
| 25132 | 25361 | ||
| 25133 | USB TYPEC TUSB1046 MUX DRIVER | 25362 | USB TYPEC TUSB1046 MUX DRIVER |
| 25134 | M: Romain Gantois <romain.gantois@bootlin.com> | 25363 | M: Romain Gantois <romain.gantois@bootlin.com> |
| @@ -25741,7 +25970,7 @@ F: tools/testing/vsock/ · 606 unmodified lines | |||
| 25741 | 25970 | ||
| 25742 | VMALLOC | 25971 | VMALLOC |
| 25743 | M: Andrew Morton <akpm@linux-foundation.org> | 25972 | M: Andrew Morton <akpm@linux-foundation.org> |
| 25744 | R: Uladzislau Rezki <urezki@gmail.com> | 25973 | M: Uladzislau Rezki <urezki@gmail.com> |
| 25745 | L: linux-mm@kvack.org | 25974 | L: linux-mm@kvack.org |
| 25746 | S: Maintained | 25975 | S: Maintained |
| 25747 | W: http://www.linux-mm.org | 25976 | W: http://www.linux-mm.org |
| @@ -25765,7 +25994,7 @@ F: drivers/misc/vmw_balloon.c · 17 unmodified lines | |||
| 25765 | 25994 | ||
| 25766 | VMWARE HYPERVISOR INTERFACE | 25995 | VMWARE HYPERVISOR INTERFACE |
| 25767 | M: Ajay Kaher <ajay.kaher@broadcom.com> | 25996 | M: Ajay Kaher <ajay.kaher@broadcom.com> |
| 25768 | M: Alexey Makhalov <alexey.amakhalov@broadcom.com> | 25997 | M: Alexey Makhalov <alexey.makhalov@broadcom.com> |
| 25769 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 25998 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 25770 | L: virtualization@lists.linux.dev | 25999 | L: virtualization@lists.linux.dev |
| 25771 | L: x86@kernel.org | 26000 | L: x86@kernel.org |
| @@ -25793,7 +26022,7 @@ F: drivers/scsi/vmw_pvscsi.h · 21 unmodified lines | |||
| 25793 | VMWARE VIRTUAL PTP CLOCK DRIVER | 26022 | VMWARE VIRTUAL PTP CLOCK DRIVER |
| 25794 | M: Nick Shi <nick.shi@broadcom.com> | 26023 | M: Nick Shi <nick.shi@broadcom.com> |
| 25795 | R: Ajay Kaher <ajay.kaher@broadcom.com> | 26024 | R: Ajay Kaher <ajay.kaher@broadcom.com> |
| 25796 | R: Alexey Makhalov <alexey.amakhalov@broadcom.com> | 26025 | R: Alexey Makhalov <alexey.makhalov@broadcom.com> |
| 25797 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 26026 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 25798 | L: netdev@vger.kernel.org | 26027 | L: netdev@vger.kernel.org |
| 25799 | S: Supported | 26028 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 15 | 3 | PATCHLEVEL = 15 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = |
| 6 | NAME = Baby Opossum Posse | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -477,7 +477,6 @@ export rust_common_flags := --edition=2021 \ · 468 unmodified lines | |||
| 477 | -Wclippy::ignored_unit_patterns \ | 477 | -Wclippy::ignored_unit_patterns \ |
| 478 | -Wclippy::mut_mut \ | 478 | -Wclippy::mut_mut \ |
| 479 | -Wclippy::needless_bitwise_bool \ | 479 | -Wclippy::needless_bitwise_bool \ |
| 480 | -Wclippy::needless_continue \ | ||
| 481 | -Aclippy::needless_lifetimes \ | 480 | -Aclippy::needless_lifetimes \ |
| 482 | -Wclippy::no_mangle_with_rust_abi \ | 481 | -Wclippy::no_mangle_with_rust_abi \ |
| 483 | -Wclippy::undocumented_unsafe_blocks \ | 482 | -Wclippy::undocumented_unsafe_blocks \ |
| @@ -1053,10 +1052,6 @@ NOSTDINC_FLAGS += -nostdinc · 569 unmodified lines | |||
| 1053 | # perform bounds checking. | 1052 | # perform bounds checking. |
| 1054 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) | 1053 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) |
| 1055 | 1054 | ||
| 1056 | #Currently, disable -Wstringop-overflow for GCC 11, globally. | ||
| 1057 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) | ||
| 1058 | KBUILD_CFLAGS-$(CONFIG_CC_STRINGOP_OVERFLOW) += $(call cc-option, -Wstringop-overflow) | ||
| 1059 | |||
| 1060 | # disable invalid "can't wrap" optimizations for signed / pointers | 1055 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 1061 | KBUILD_CFLAGS += -fno-strict-overflow | 1056 | KBUILD_CFLAGS += -fno-strict-overflow |
| 1062 | 1057 | ||
| @@ -1068,10 +1063,12 @@ ifdef CONFIG_CC_IS_GCC · 5 unmodified lines | |||
| 1068 | KBUILD_CFLAGS += -fconserve-stack | 1063 | KBUILD_CFLAGS += -fconserve-stack |
| 1069 | endif | 1064 | endif |
| 1070 | 1065 | ||
| 1066 | # Ensure compilers do not transform certain loops into calls to wcslen() | ||
| 1067 | KBUILD_CFLAGS += -fno-builtin-wcslen | ||
| 1068 | |||
| 1071 | # change __FILE__ to the relative path to the source directory | 1069 | # change __FILE__ to the relative path to the source directory |
| 1072 | ifdef building_out_of_srctree | 1070 | ifdef building_out_of_srctree |
| 1073 | KBUILD_CPPFLAGS += $(call cc-option,-ffile-prefix-map=$(srcroot)/=) | 1071 | KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) |
| 1074 | KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= | ||
| 1075 | endif | 1072 | endif |
| 1076 | 1073 | ||
| 1077 | # include additional Makefiles when needed | 1074 | # include additional Makefiles when needed |
| @@ -451,7 +451,7 @@ · 450 unmodified lines | |||
| 451 | pwm_ef: pwm@86c0 { | 451 | pwm_ef: pwm@86c0 { |
| 452 | compatible = "amlogic,meson8-pwm-v2"; | 452 | compatible = "amlogic,meson8-pwm-v2"; |
| 453 | clocks = <&xtal>, | 453 | clocks = <&xtal>, |
| 454 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 454 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 455 | <&clkc CLKID_FCLK_DIV4>, | 455 | <&clkc CLKID_FCLK_DIV4>, |
| 456 | <&clkc CLKID_FCLK_DIV3>; | 456 | <&clkc CLKID_FCLK_DIV3>; |
| 457 | reg = <0x86c0 0x10>; | 457 | reg = <0x86c0 0x10>; |
| @@ -705,7 +705,7 @@ · 247 unmodified lines | |||
| 705 | &pwm_ab { | 705 | &pwm_ab { |
| 706 | compatible = "amlogic,meson8-pwm-v2"; | 706 | compatible = "amlogic,meson8-pwm-v2"; |
| 707 | clocks = <&xtal>, | 707 | clocks = <&xtal>, |
| 708 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 708 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 709 | <&clkc CLKID_FCLK_DIV4>, | 709 | <&clkc CLKID_FCLK_DIV4>, |
| 710 | <&clkc CLKID_FCLK_DIV3>; | 710 | <&clkc CLKID_FCLK_DIV3>; |
| 711 | }; | 711 | }; |
| @@ -713,7 +713,7 @@ · 1 unmodified line | |||
| 713 | &pwm_cd { | 713 | &pwm_cd { |
| 714 | compatible = "amlogic,meson8-pwm-v2"; | 714 | compatible = "amlogic,meson8-pwm-v2"; |
| 715 | clocks = <&xtal>, | 715 | clocks = <&xtal>, |
| 716 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 716 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 717 | <&clkc CLKID_FCLK_DIV4>, | 717 | <&clkc CLKID_FCLK_DIV4>, |
| 718 | <&clkc CLKID_FCLK_DIV3>; | 718 | <&clkc CLKID_FCLK_DIV3>; |
| 719 | }; | 719 | }; |
| @@ -406,7 +406,7 @@ · 405 unmodified lines | |||
| 406 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; | 406 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 407 | reg = <0x86c0 0x10>; | 407 | reg = <0x86c0 0x10>; |
| 408 | clocks = <&xtal>, | 408 | clocks = <&xtal>, |
| 409 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 409 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 410 | <&clkc CLKID_FCLK_DIV4>, | 410 | <&clkc CLKID_FCLK_DIV4>, |
| 411 | <&clkc CLKID_FCLK_DIV3>; | 411 | <&clkc CLKID_FCLK_DIV3>; |
| 412 | #pwm-cells = <3>; | 412 | #pwm-cells = <3>; |
| @@ -680,7 +680,7 @@ · 267 unmodified lines | |||
| 680 | &pwm_ab { | 680 | &pwm_ab { |
| 681 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; | 681 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 682 | clocks = <&xtal>, | 682 | clocks = <&xtal>, |
| 683 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 683 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 684 | <&clkc CLKID_FCLK_DIV4>, | 684 | <&clkc CLKID_FCLK_DIV4>, |
| 685 | <&clkc CLKID_FCLK_DIV3>; | 685 | <&clkc CLKID_FCLK_DIV3>; |
| 686 | }; | 686 | }; |
| @@ -688,7 +688,7 @@ · 1 unmodified line | |||
| 688 | &pwm_cd { | 688 | &pwm_cd { |
| 689 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; | 689 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 690 | clocks = <&xtal>, | 690 | clocks = <&xtal>, |
| 691 | <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | 691 | <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ |
| 692 | <&clkc CLKID_FCLK_DIV4>, | 692 | <&clkc CLKID_FCLK_DIV4>, |
| 693 | <&clkc CLKID_FCLK_DIV3>; | 693 | <&clkc CLKID_FCLK_DIV3>; |
| 694 | }; | 694 | }; |
| @@ -40,6 +40,9 @@ · 39 unmodified lines | |||
| 40 | reg = <1>; | 40 | reg = <1>; |
| 41 | interrupt-parent = <&gpio4>; | 41 | interrupt-parent = <&gpio4>; |
| 42 | interrupts = <16 IRQ_TYPE_LEVEL_LOW>; | 42 | interrupts = <16 IRQ_TYPE_LEVEL_LOW>; |
| 43 | micrel,led-mode = <1>; | ||
| 44 | clocks = <&clks IMX6UL_CLK_ENET_REF>; | ||
| 45 | clock-names = "rmii-ref"; | ||
| 43 | status = "okay"; | 46 | status = "okay"; |
| 44 | }; | 47 | }; |
| 45 | }; | 48 | }; |
| @@ -232,7 +232,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 231 unmodified lines | |||
| 232 | CONFIG_CRYPTO_DEV_ATMEL_AES=y | 232 | CONFIG_CRYPTO_DEV_ATMEL_AES=y |
| 233 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y | 233 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y |
| 234 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y | 234 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y |
| 235 | CONFIG_CRC_CCITT=y | ||
| 236 | CONFIG_FONTS=y | 235 | CONFIG_FONTS=y |
| 237 | CONFIG_FONT_8x8=y | 236 | CONFIG_FONT_8x8=y |
| 238 | CONFIG_FONT_ACORN_8x8=y | 237 | CONFIG_FONT_ACORN_8x8=y |
| @@ -78,7 +78,6 @@ CONFIG_ROMFS_FS=y · 77 unmodified lines | |||
| 78 | CONFIG_NLS_DEFAULT="cp437" | 78 | CONFIG_NLS_DEFAULT="cp437" |
| 79 | CONFIG_NLS_CODEPAGE_437=y | 79 | CONFIG_NLS_CODEPAGE_437=y |
| 80 | CONFIG_NLS_ISO8859_1=y | 80 | CONFIG_NLS_ISO8859_1=y |
| 81 | CONFIG_CRC_CCITT=y | ||
| 82 | CONFIG_FONTS=y | 81 | CONFIG_FONTS=y |
| 83 | CONFIG_FONT_MINI_4x6=y | 82 | CONFIG_FONT_MINI_4x6=y |
| 84 | # CONFIG_DEBUG_BUGVERBOSE is not set | 83 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| @@ -249,7 +249,6 @@ CONFIG_NLS_ASCII=m · 248 unmodified lines | |||
| 249 | CONFIG_NLS_ISO8859_1=y | 249 | CONFIG_NLS_ISO8859_1=y |
| 250 | CONFIG_NLS_UTF8=m | 250 | CONFIG_NLS_UTF8=m |
| 251 | # CONFIG_CRYPTO_HW is not set | 251 | # CONFIG_CRYPTO_HW is not set |
| 252 | CONFIG_CRC_T10DIF=m | ||
| 253 | CONFIG_DMA_CMA=y | 252 | CONFIG_DMA_CMA=y |
| 254 | CONFIG_DEBUG_FS=y | 253 | CONFIG_DEBUG_FS=y |
| 255 | CONFIG_DEBUG_RT_MUTEXES=y | 254 | CONFIG_DEBUG_RT_MUTEXES=y |
| @@ -128,7 +128,6 @@ CONFIG_CRYPTO_DEFLATE=y · 127 unmodified lines | |||
| 128 | CONFIG_CRYPTO_LZO=y | 128 | CONFIG_CRYPTO_LZO=y |
| 129 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 129 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 130 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y | 130 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 131 | CONFIG_CRC_CCITT=y | ||
| 132 | CONFIG_PRINTK_TIME=y | 131 | CONFIG_PRINTK_TIME=y |
| 133 | # CONFIG_DEBUG_BUGVERBOSE is not set | 132 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 134 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 133 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -370,7 +370,6 @@ CONFIG_CRYPTO_AES_ARM_BS=m · 369 unmodified lines | |||
| 370 | CONFIG_CRYPTO_CHACHA20_NEON=m | 370 | CONFIG_CRYPTO_CHACHA20_NEON=m |
| 371 | CONFIG_CRYPTO_DEV_EXYNOS_RNG=y | 371 | CONFIG_CRYPTO_DEV_EXYNOS_RNG=y |
| 372 | CONFIG_CRYPTO_DEV_S5P=y | 372 | CONFIG_CRYPTO_DEV_S5P=y |
| 373 | CONFIG_CRC_CCITT=y | ||
| 374 | CONFIG_DMA_CMA=y | 373 | CONFIG_DMA_CMA=y |
| 375 | CONFIG_CMA_SIZE_MBYTES=96 | 374 | CONFIG_CMA_SIZE_MBYTES=96 |
| 376 | CONFIG_FONTS=y | 375 | CONFIG_FONTS=y |
| @@ -481,8 +481,6 @@ CONFIG_SECURITYFS=y · 480 unmodified lines | |||
| 481 | CONFIG_CRYPTO_DEV_FSL_CAAM=y | 481 | CONFIG_CRYPTO_DEV_FSL_CAAM=y |
| 482 | CONFIG_CRYPTO_DEV_SAHARA=y | 482 | CONFIG_CRYPTO_DEV_SAHARA=y |
| 483 | CONFIG_CRYPTO_DEV_MXS_DCP=y | 483 | CONFIG_CRYPTO_DEV_MXS_DCP=y |
| 484 | CONFIG_CRC_CCITT=m | ||
| 485 | CONFIG_CRC_T10DIF=y | ||
| 486 | CONFIG_CMA_SIZE_MBYTES=64 | 484 | CONFIG_CMA_SIZE_MBYTES=64 |
| 487 | CONFIG_FONTS=y | 485 | CONFIG_FONTS=y |
| 488 | CONFIG_FONT_8x8=y | 486 | CONFIG_FONT_8x8=y |
| @@ -147,7 +147,6 @@ CONFIG_EXT2_FS=y · 146 unmodified lines | |||
| 147 | # CONFIG_INOTIFY_USER is not set | 147 | # CONFIG_INOTIFY_USER is not set |
| 148 | CONFIG_JFFS2_FS=y | 148 | CONFIG_JFFS2_FS=y |
| 149 | # CONFIG_NETWORK_FILESYSTEMS is not set | 149 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 150 | CONFIG_CRC_ITU_T=y | ||
| 151 | CONFIG_PRINTK_TIME=y | 150 | CONFIG_PRINTK_TIME=y |
| 152 | # CONFIG_ENABLE_MUST_CHECK is not set | 151 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 153 | # CONFIG_DEBUG_BUGVERBOSE is not set | 152 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| @@ -179,7 +179,6 @@ CONFIG_NLS_ISO8859_1=y · 178 unmodified lines | |||
| 179 | CONFIG_NLS_UTF8=y | 179 | CONFIG_NLS_UTF8=y |
| 180 | CONFIG_CRYPTO_ANSI_CPRNG=y | 180 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 181 | # CONFIG_CRYPTO_HW is not set | 181 | # CONFIG_CRYPTO_HW is not set |
| 182 | CONFIG_CRC_CCITT=y | ||
| 183 | CONFIG_PRINTK_TIME=y | 182 | CONFIG_PRINTK_TIME=y |
| 184 | CONFIG_DYNAMIC_DEBUG=y | 183 | CONFIG_DYNAMIC_DEBUG=y |
| 185 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 184 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -108,8 +108,6 @@ CONFIG_CRYPTO_AES_ARM_BS=m · 107 unmodified lines | |||
| 108 | CONFIG_CRYPTO_AES_ARM_CE=m | 108 | CONFIG_CRYPTO_AES_ARM_CE=m |
| 109 | CONFIG_CRYPTO_CHACHA20_NEON=m | 109 | CONFIG_CRYPTO_CHACHA20_NEON=m |
| 110 | # CONFIG_CRYPTO_HW is not set | 110 | # CONFIG_CRYPTO_HW is not set |
| 111 | CONFIG_CRC_CCITT=m | ||
| 112 | CONFIG_CRC_ITU_T=m | ||
| 113 | CONFIG_DMA_CMA=y | 111 | CONFIG_DMA_CMA=y |
| 114 | CONFIG_CMA_SIZE_MBYTES=64 | 112 | CONFIG_CMA_SIZE_MBYTES=64 |
| 115 | CONFIG_PRINTK_TIME=y | 113 | CONFIG_PRINTK_TIME=y |
| @@ -67,7 +67,6 @@ CONFIG_NFS_V3=y · 66 unmodified lines | |||
| 67 | CONFIG_NFS_V3_ACL=y | 67 | CONFIG_NFS_V3_ACL=y |
| 68 | CONFIG_NFS_V4=y | 68 | CONFIG_NFS_V4=y |
| 69 | CONFIG_ROOT_NFS=y | 69 | CONFIG_ROOT_NFS=y |
| 70 | CONFIG_CRC_CCITT=y | ||
| 71 | CONFIG_PRINTK_TIME=y | 70 | CONFIG_PRINTK_TIME=y |
| 72 | CONFIG_DEBUG_KERNEL=y | 71 | CONFIG_DEBUG_KERNEL=y |
| 73 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 72 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -91,6 +91,5 @@ CONFIG_MSDOS_FS=y · 90 unmodified lines | |||
| 91 | CONFIG_VFAT_FS=y | 91 | CONFIG_VFAT_FS=y |
| 92 | CONFIG_CRAMFS=y | 92 | CONFIG_CRAMFS=y |
| 93 | CONFIG_MINIX_FS=y | 93 | CONFIG_MINIX_FS=y |
| 94 | CONFIG_CRC_CCITT=y | ||
| 95 | # CONFIG_FTRACE is not set | 94 | # CONFIG_FTRACE is not set |
| 96 | CONFIG_DEBUG_USER=y | 95 | CONFIG_DEBUG_USER=y |
| @@ -289,7 +289,6 @@ CONFIG_NLS_UTF8=y · 288 unmodified lines | |||
| 289 | CONFIG_CRYPTO_CBC=m | 289 | CONFIG_CRYPTO_CBC=m |
| 290 | CONFIG_CRYPTO_PCBC=m | 290 | CONFIG_CRYPTO_PCBC=m |
| 291 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y | 291 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 292 | CONFIG_CRC_CCITT=y | ||
| 293 | CONFIG_DEBUG_KERNEL=y | 292 | CONFIG_DEBUG_KERNEL=y |
| 294 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 293 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 295 | CONFIG_MAGIC_SYSRQ=y | 294 | CONFIG_MAGIC_SYSRQ=y |
| @@ -187,7 +187,6 @@ CONFIG_NLS_UTF8=y · 186 unmodified lines | |||
| 187 | CONFIG_CRYPTO_CBC=m | 187 | CONFIG_CRYPTO_CBC=m |
| 188 | CONFIG_CRYPTO_PCBC=m | 188 | CONFIG_CRYPTO_PCBC=m |
| 189 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y | 189 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 190 | CONFIG_CRC_CCITT=y | ||
| 191 | CONFIG_DEBUG_KERNEL=y | 190 | CONFIG_DEBUG_KERNEL=y |
| 192 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 191 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 193 | CONFIG_MAGIC_SYSRQ=y | 192 | CONFIG_MAGIC_SYSRQ=y |
| @@ -160,7 +160,6 @@ CONFIG_NLS_CODEPAGE_850=y · 159 unmodified lines | |||
| 160 | CONFIG_NLS_ISO8859_1=y | 160 | CONFIG_NLS_ISO8859_1=y |
| 161 | CONFIG_NLS_ISO8859_15=y | 161 | CONFIG_NLS_ISO8859_15=y |
| 162 | CONFIG_CRYPTO_DEV_MXS_DCP=y | 162 | CONFIG_CRYPTO_DEV_MXS_DCP=y |
| 163 | CONFIG_CRC_ITU_T=m | ||
| 164 | CONFIG_FONTS=y | 163 | CONFIG_FONTS=y |
| 165 | CONFIG_PRINTK_TIME=y | 164 | CONFIG_PRINTK_TIME=y |
| 166 | CONFIG_DEBUG_KERNEL=y | 165 | CONFIG_DEBUG_KERNEL=y |
| @@ -706,9 +706,6 @@ CONFIG_CRYPTO_DEV_OMAP=m · 705 unmodified lines | |||
| 706 | CONFIG_CRYPTO_DEV_OMAP_SHAM=m | 706 | CONFIG_CRYPTO_DEV_OMAP_SHAM=m |
| 707 | CONFIG_CRYPTO_DEV_OMAP_AES=m | 707 | CONFIG_CRYPTO_DEV_OMAP_AES=m |
| 708 | CONFIG_CRYPTO_DEV_OMAP_DES=m | 708 | CONFIG_CRYPTO_DEV_OMAP_DES=m |
| 709 | CONFIG_CRC_CCITT=y | ||
| 710 | CONFIG_CRC_T10DIF=y | ||
| 711 | CONFIG_CRC_ITU_T=y | ||
| 712 | CONFIG_DMA_CMA=y | 709 | CONFIG_DMA_CMA=y |
| 713 | CONFIG_FONTS=y | 710 | CONFIG_FONTS=y |
| 714 | CONFIG_FONT_8x8=y | 711 | CONFIG_FONT_8x8=y |
| @@ -136,7 +136,6 @@ CONFIG_CRYPTO_CBC=m · 135 unmodified lines | |||
| 136 | CONFIG_CRYPTO_ECB=m | 136 | CONFIG_CRYPTO_ECB=m |
| 137 | CONFIG_CRYPTO_PCBC=m | 137 | CONFIG_CRYPTO_PCBC=m |
| 138 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y | 138 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 139 | CONFIG_CRC_T10DIF=y | ||
| 140 | # CONFIG_DEBUG_BUGVERBOSE is not set | 139 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 141 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 140 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 142 | CONFIG_MAGIC_SYSRQ=y | 141 | CONFIG_MAGIC_SYSRQ=y |
| @@ -41,7 +41,6 @@ CONFIG_NFS_V3=y · 40 unmodified lines | |||
| 41 | CONFIG_NFS_V3_ACL=y | 41 | CONFIG_NFS_V3_ACL=y |
| 42 | CONFIG_NFS_V4=y | 42 | CONFIG_NFS_V4=y |
| 43 | CONFIG_ROOT_NFS=y | 43 | CONFIG_ROOT_NFS=y |
| 44 | CONFIG_CRC_CCITT=y | ||
| 45 | CONFIG_PRINTK_TIME=y | 44 | CONFIG_PRINTK_TIME=y |
| 46 | CONFIG_DEBUG_KERNEL=y | 45 | CONFIG_DEBUG_KERNEL=y |
| 47 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 46 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -50,7 +50,6 @@ CONFIG_NFS_V3=y · 49 unmodified lines | |||
| 50 | CONFIG_NFS_V3_ACL=y | 50 | CONFIG_NFS_V3_ACL=y |
| 51 | CONFIG_NFS_V4=y | 51 | CONFIG_NFS_V4=y |
| 52 | CONFIG_ROOT_NFS=y | 52 | CONFIG_ROOT_NFS=y |
| 53 | CONFIG_CRC_CCITT=y | ||
| 54 | CONFIG_PRINTK_TIME=y | 53 | CONFIG_PRINTK_TIME=y |
| 55 | CONFIG_DEBUG_KERNEL=y | 54 | CONFIG_DEBUG_KERNEL=y |
| 56 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 55 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -663,8 +663,6 @@ CONFIG_CRYPTO_SHA1_ARM=m · 662 unmodified lines | |||
| 663 | CONFIG_CRYPTO_SHA256_ARM=m | 663 | CONFIG_CRYPTO_SHA256_ARM=m |
| 664 | CONFIG_CRYPTO_SHA512_ARM=m | 664 | CONFIG_CRYPTO_SHA512_ARM=m |
| 665 | CONFIG_CRYPTO_AES_ARM=m | 665 | CONFIG_CRYPTO_AES_ARM=m |
| 666 | CONFIG_CRC_CCITT=y | ||
| 667 | CONFIG_CRC_T10DIF=m | ||
| 668 | CONFIG_FONTS=y | 666 | CONFIG_FONTS=y |
| 669 | CONFIG_FONT_8x8=y | 667 | CONFIG_FONT_8x8=y |
| 670 | CONFIG_FONT_8x16=y | 668 | CONFIG_FONT_8x16=y |
| @@ -113,7 +113,6 @@ CONFIG_NLS_CODEPAGE_437=y · 112 unmodified lines | |||
| 113 | CONFIG_NLS_ASCII=y | 113 | CONFIG_NLS_ASCII=y |
| 114 | CONFIG_NLS_ISO8859_1=y | 114 | CONFIG_NLS_ISO8859_1=y |
| 115 | CONFIG_NLS_UTF8=y | 115 | CONFIG_NLS_UTF8=y |
| 116 | CONFIG_CRC_CCITT=y | ||
| 117 | CONFIG_DEBUG_KERNEL=y | 116 | CONFIG_DEBUG_KERNEL=y |
| 118 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 117 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 119 | CONFIG_MAGIC_SYSRQ=y | 118 | CONFIG_MAGIC_SYSRQ=y |
| @@ -227,8 +227,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 226 unmodified lines | |||
| 227 | CONFIG_CRYPTO_DEV_ATMEL_AES=y | 227 | CONFIG_CRYPTO_DEV_ATMEL_AES=y |
| 228 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y | 228 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y |
| 229 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y | 229 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y |
| 230 | CONFIG_CRC_CCITT=y | ||
| 231 | CONFIG_CRC_ITU_T=y | ||
| 232 | CONFIG_DMA_CMA=y | 230 | CONFIG_DMA_CMA=y |
| 233 | CONFIG_CMA_SIZE_MBYTES=32 | 231 | CONFIG_CMA_SIZE_MBYTES=32 |
| 234 | CONFIG_CMA_ALIGNMENT=9 | 232 | CONFIG_CMA_ALIGNMENT=9 |
| @@ -234,7 +234,6 @@ CONFIG_CRYPTO_MD4=m · 233 unmodified lines | |||
| 234 | CONFIG_CRYPTO_MICHAEL_MIC=m | 234 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 235 | CONFIG_CRYPTO_SHA512=m | 235 | CONFIG_CRYPTO_SHA512=m |
| 236 | CONFIG_CRYPTO_WP512=m | 236 | CONFIG_CRYPTO_WP512=m |
| 237 | CONFIG_CRC_CCITT=y | ||
| 238 | CONFIG_FONTS=y | 237 | CONFIG_FONTS=y |
| 239 | CONFIG_FONT_8x8=y | 238 | CONFIG_FONT_8x8=y |
| 240 | CONFIG_FONT_8x16=y | 239 | CONFIG_FONT_8x16=y |
| @@ -74,7 +74,6 @@ CONFIG_EXT3_FS=y · 73 unmodified lines | |||
| 74 | # CONFIG_DNOTIFY is not set | 74 | # CONFIG_DNOTIFY is not set |
| 75 | # CONFIG_INOTIFY_USER is not set | 75 | # CONFIG_INOTIFY_USER is not set |
| 76 | CONFIG_NLS=y | 76 | CONFIG_NLS=y |
| 77 | CONFIG_CRC_ITU_T=y | ||
| 78 | CONFIG_PRINTK_TIME=y | 77 | CONFIG_PRINTK_TIME=y |
| 79 | # CONFIG_DEBUG_BUGVERBOSE is not set | 78 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 80 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 79 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -191,8 +191,6 @@ CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y · 190 unmodified lines | |||
| 191 | CONFIG_X509_CERTIFICATE_PARSER=y | 191 | CONFIG_X509_CERTIFICATE_PARSER=y |
| 192 | CONFIG_PKCS7_MESSAGE_PARSER=y | 192 | CONFIG_PKCS7_MESSAGE_PARSER=y |
| 193 | CONFIG_SYSTEM_TRUSTED_KEYRING=y | 193 | CONFIG_SYSTEM_TRUSTED_KEYRING=y |
| 194 | CONFIG_CRC_CCITT=y | ||
| 195 | CONFIG_CRC_ITU_T=m | ||
| 196 | CONFIG_PRINTK_TIME=y | 194 | CONFIG_PRINTK_TIME=y |
| 197 | CONFIG_DEBUG_KERNEL=y | 195 | CONFIG_DEBUG_KERNEL=y |
| 198 | CONFIG_MAGIC_SYSRQ=y | 196 | CONFIG_MAGIC_SYSRQ=y |
| @@ -152,28 +152,12 @@ · 151 unmodified lines | |||
| 152 | vcc-pg-supply = <®_aldo1>; | 152 | vcc-pg-supply = <®_aldo1>; |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | &r_ir { | 155 | &r_i2c { |
| 156 | linux,rc-map-name = "rc-beelink-gs1"; | ||
| 157 | status = "okay"; | ||
| 158 | }; | ||
| 159 | |||
| 160 | &r_pio { | ||
| 161 | /* | ||
| 162 | * FIXME: We can't add that supply for now since it would | ||
| 163 | * create a circular dependency between pinctrl, the regulator | ||
| 164 | * and the RSB Bus. | ||
| 165 | * | ||
| 166 | * vcc-pl-supply = <®_aldo1>; | ||
| 167 | */ | ||
| 168 | vcc-pm-supply = <®_aldo1>; | ||
| 169 | }; | ||
| 170 | |||
| 171 | &r_rsb { | ||
| 172 | status = "okay"; | 156 | status = "okay"; |
| 173 | 157 | ||
| 174 | axp805: pmic@745 { | 158 | axp805: pmic@36 { |
| 175 | compatible = "x-powers,axp805", "x-powers,axp806"; | 159 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 176 | reg = <0x745>; | 160 | reg = <0x36>; |
| 177 | interrupt-parent = <&r_intc>; | 161 | interrupt-parent = <&r_intc>; |
| 178 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; | 162 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 179 | interrupt-controller; | 163 | interrupt-controller; |
| @@ -291,6 +275,22 @@ · 111 unmodified lines | |||
| 291 | }; | 275 | }; |
| 292 | }; | 276 | }; |
| 293 | 277 | ||
| 278 | &r_ir { | ||
| 279 | linux,rc-map-name = "rc-beelink-gs1"; | ||
| 280 | status = "okay"; | ||
| 281 | }; | ||
| 282 | |||
| 283 | &r_pio { | ||
| 284 | /* | ||
| 285 | * PL0 and PL1 are used for PMIC I2C | ||
| 286 | * don't enable the pl-supply else | ||
| 287 | * it will fail at boot | ||
| 288 | * | ||
| 289 | * vcc-pl-supply = <®_aldo1>; | ||
| 290 | */ | ||
| 291 | vcc-pm-supply = <®_aldo1>; | ||
| 292 | }; | ||
| 293 | |||
| 294 | &spdif { | 294 | &spdif { |
| 295 | pinctrl-names = "default"; | 295 | pinctrl-names = "default"; |
| 296 | pinctrl-0 = <&spdif_tx_pin>; | 296 | pinctrl-0 = <&spdif_tx_pin>; |
| @@ -176,16 +176,12 @@ · 175 unmodified lines | |||
| 176 | vcc-pg-supply = <®_vcc_wifi_io>; | 176 | vcc-pg-supply = <®_vcc_wifi_io>; |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | &r_ir { | 179 | &r_i2c { |
| 180 | status = "okay"; | ||
| 181 | }; | ||
| 182 | |||
| 183 | &r_rsb { | ||
| 184 | status = "okay"; | 180 | status = "okay"; |
| 185 | 181 | ||
| 186 | axp805: pmic@745 { | 182 | axp805: pmic@36 { |
| 187 | compatible = "x-powers,axp805", "x-powers,axp806"; | 183 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 188 | reg = <0x745>; | 184 | reg = <0x36>; |
| 189 | interrupt-parent = <&r_intc>; | 185 | interrupt-parent = <&r_intc>; |
| 190 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; | 186 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 191 | interrupt-controller; | 187 | interrupt-controller; |
| @@ -296,6 +292,10 @@ · 104 unmodified lines | |||
| 296 | }; | 292 | }; |
| 297 | }; | 293 | }; |
| 298 | 294 | ||
| 295 | &r_ir { | ||
| 296 | status = "okay"; | ||
| 297 | }; | ||
| 298 | |||
| 299 | &rtc { | 299 | &rtc { |
| 300 | clocks = <&ext_osc32k>; | 300 | clocks = <&ext_osc32k>; |
| 301 | }; | 301 | }; |
| @@ -113,20 +113,12 @@ · 112 unmodified lines | |||
| 113 | vcc-pg-supply = <®_aldo1>; | 113 | vcc-pg-supply = <®_aldo1>; |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | &r_ir { | 116 | &r_i2c { |
| 117 | status = "okay"; | ||
| 118 | }; | ||
| 119 | |||
| 120 | &r_pio { | ||
| 121 | vcc-pm-supply = <®_bldo3>; | ||
| 122 | }; | ||
| 123 | |||
| 124 | &r_rsb { | ||
| 125 | status = "okay"; | 117 | status = "okay"; |
| 126 | 118 | ||
| 127 | axp805: pmic@745 { | 119 | axp805: pmic@36 { |
| 128 | compatible = "x-powers,axp805", "x-powers,axp806"; | 120 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 129 | reg = <0x745>; | 121 | reg = <0x36>; |
| 130 | interrupt-parent = <&r_intc>; | 122 | interrupt-parent = <&r_intc>; |
| 131 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; | 123 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 132 | interrupt-controller; | 124 | interrupt-controller; |
| @@ -241,6 +233,14 @@ · 108 unmodified lines | |||
| 241 | }; | 233 | }; |
| 242 | }; | 234 | }; |
| 243 | 235 | ||
| 236 | &r_ir { | ||
| 237 | status = "okay"; | ||
| 238 | }; | ||
| 239 | |||
| 240 | &r_pio { | ||
| 241 | vcc-pm-supply = <®_bldo3>; | ||
| 242 | }; | ||
| 243 | |||
| 244 | &rtc { | 244 | &rtc { |
| 245 | clocks = <&ext_osc32k>; | 245 | clocks = <&ext_osc32k>; |
| 246 | }; | 246 | }; |
| @@ -151,7 +151,7 @@ · 150 unmodified lines | |||
| 151 | al,msi-num-spis = <160>; | 151 | al,msi-num-spis = <160>; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | io-fabric@fc000000 { | 154 | io-bus@fc000000 { |
| 155 | compatible = "simple-bus"; | 155 | compatible = "simple-bus"; |
| 156 | #address-cells = <1>; | 156 | #address-cells = <1>; |
| 157 | #size-cells = <1>; | 157 | #size-cells = <1>; |
| @@ -361,7 +361,7 @@ · 360 unmodified lines | |||
| 361 | interrupt-parent = <&gic>; | 361 | interrupt-parent = <&gic>; |
| 362 | }; | 362 | }; |
| 363 | 363 | ||
| 364 | io-fabric@fc000000 { | 364 | io-bus@fc000000 { |
| 365 | compatible = "simple-bus"; | 365 | compatible = "simple-bus"; |
| 366 | #address-cells = <1>; | 366 | #address-cells = <1>; |
| 367 | #size-cells = <1>; | 367 | #size-cells = <1>; |
| @@ -2313,7 +2313,7 @@ · 2312 unmodified lines | |||
| 2313 | "amlogic,meson8-pwm-v2"; | 2313 | "amlogic,meson8-pwm-v2"; |
| 2314 | reg = <0x0 0x19000 0x0 0x20>; | 2314 | reg = <0x0 0x19000 0x0 0x20>; |
| 2315 | clocks = <&xtal>, | 2315 | clocks = <&xtal>, |
| 2316 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 2316 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 2317 | <&clkc CLKID_FCLK_DIV4>, | 2317 | <&clkc CLKID_FCLK_DIV4>, |
| 2318 | <&clkc CLKID_FCLK_DIV3>; | 2318 | <&clkc CLKID_FCLK_DIV3>; |
| 2319 | #pwm-cells = <3>; | 2319 | #pwm-cells = <3>; |
| @@ -2325,7 +2325,7 @@ · 5 unmodified lines | |||
| 2325 | "amlogic,meson8-pwm-v2"; | 2325 | "amlogic,meson8-pwm-v2"; |
| 2326 | reg = <0x0 0x1a000 0x0 0x20>; | 2326 | reg = <0x0 0x1a000 0x0 0x20>; |
| 2327 | clocks = <&xtal>, | 2327 | clocks = <&xtal>, |
| 2328 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 2328 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 2329 | <&clkc CLKID_FCLK_DIV4>, | 2329 | <&clkc CLKID_FCLK_DIV4>, |
| 2330 | <&clkc CLKID_FCLK_DIV3>; | 2330 | <&clkc CLKID_FCLK_DIV3>; |
| 2331 | #pwm-cells = <3>; | 2331 | #pwm-cells = <3>; |
| @@ -2337,7 +2337,7 @@ · 5 unmodified lines | |||
| 2337 | "amlogic,meson8-pwm-v2"; | 2337 | "amlogic,meson8-pwm-v2"; |
| 2338 | reg = <0x0 0x1b000 0x0 0x20>; | 2338 | reg = <0x0 0x1b000 0x0 0x20>; |
| 2339 | clocks = <&xtal>, | 2339 | clocks = <&xtal>, |
| 2340 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 2340 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 2341 | <&clkc CLKID_FCLK_DIV4>, | 2341 | <&clkc CLKID_FCLK_DIV4>, |
| 2342 | <&clkc CLKID_FCLK_DIV3>; | 2342 | <&clkc CLKID_FCLK_DIV3>; |
| 2343 | #pwm-cells = <3>; | 2343 | #pwm-cells = <3>; |
| @@ -116,6 +116,10 @@ · 115 unmodified lines | |||
| 116 | status = "okay"; | 116 | status = "okay"; |
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | &clkc_audio { | ||
| 120 | status = "okay"; | ||
| 121 | }; | ||
| 122 | |||
| 119 | &frddr_a { | 123 | &frddr_a { |
| 120 | status = "okay"; | 124 | status = "okay"; |
| 121 | }; | 125 | }; |
| @@ -741,7 +741,7 @@ · 740 unmodified lines | |||
| 741 | 741 | ||
| 742 | &pwm_ab { | 742 | &pwm_ab { |
| 743 | clocks = <&xtal>, | 743 | clocks = <&xtal>, |
| 744 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 744 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 745 | <&clkc CLKID_FCLK_DIV4>, | 745 | <&clkc CLKID_FCLK_DIV4>, |
| 746 | <&clkc CLKID_FCLK_DIV3>; | 746 | <&clkc CLKID_FCLK_DIV3>; |
| 747 | }; | 747 | }; |
| @@ -752,14 +752,14 @@ · 4 unmodified lines | |||
| 752 | 752 | ||
| 753 | &pwm_cd { | 753 | &pwm_cd { |
| 754 | clocks = <&xtal>, | 754 | clocks = <&xtal>, |
| 755 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 755 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 756 | <&clkc CLKID_FCLK_DIV4>, | 756 | <&clkc CLKID_FCLK_DIV4>, |
| 757 | <&clkc CLKID_FCLK_DIV3>; | 757 | <&clkc CLKID_FCLK_DIV3>; |
| 758 | }; | 758 | }; |
| 759 | 759 | ||
| 760 | &pwm_ef { | 760 | &pwm_ef { |
| 761 | clocks = <&xtal>, | 761 | clocks = <&xtal>, |
| 762 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 762 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 763 | <&clkc CLKID_FCLK_DIV4>, | 763 | <&clkc CLKID_FCLK_DIV4>, |
| 764 | <&clkc CLKID_FCLK_DIV3>; | 764 | <&clkc CLKID_FCLK_DIV3>; |
| 765 | }; | 765 | }; |
| @@ -811,7 +811,7 @@ · 810 unmodified lines | |||
| 811 | 811 | ||
| 812 | &pwm_ab { | 812 | &pwm_ab { |
| 813 | clocks = <&xtal>, | 813 | clocks = <&xtal>, |
| 814 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 814 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 815 | <&clkc CLKID_FCLK_DIV4>, | 815 | <&clkc CLKID_FCLK_DIV4>, |
| 816 | <&clkc CLKID_FCLK_DIV3>; | 816 | <&clkc CLKID_FCLK_DIV3>; |
| 817 | }; | 817 | }; |
| @@ -822,14 +822,14 @@ · 4 unmodified lines | |||
| 822 | 822 | ||
| 823 | &pwm_cd { | 823 | &pwm_cd { |
| 824 | clocks = <&xtal>, | 824 | clocks = <&xtal>, |
| 825 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 825 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 826 | <&clkc CLKID_FCLK_DIV4>, | 826 | <&clkc CLKID_FCLK_DIV4>, |
| 827 | <&clkc CLKID_FCLK_DIV3>; | 827 | <&clkc CLKID_FCLK_DIV3>; |
| 828 | }; | 828 | }; |
| 829 | 829 | ||
| 830 | &pwm_ef { | 830 | &pwm_ef { |
| 831 | clocks = <&xtal>, | 831 | clocks = <&xtal>, |
| 832 | <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | 832 | <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ |
| 833 | <&clkc CLKID_FCLK_DIV4>, | 833 | <&clkc CLKID_FCLK_DIV4>, |
| 834 | <&clkc CLKID_FCLK_DIV3>; | 834 | <&clkc CLKID_FCLK_DIV3>; |
| 835 | }; | 835 | }; |
| @@ -77,6 +77,16 @@ · 76 unmodified lines | |||
| 77 | }; | 77 | }; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | /* | ||
| 81 | * The driver depends on boot loader initialized state which resets when this | ||
| 82 | * power-domain is powered off. This happens on suspend or when the driver is | ||
| 83 | * missing during boot. Mark the domain as always on until the driver can | ||
| 84 | * handle this. | ||
| 85 | */ | ||
| 86 | &ps_dispdfr_be { | ||
| 87 | apple,always-on; | ||
| 88 | }; | ||
| 89 | |||
| 80 | &display_dfr { | 90 | &display_dfr { |
| 81 | status = "okay"; | 91 | status = "okay"; |
| 82 | }; | 92 | }; |
| @@ -40,6 +40,16 @@ · 39 unmodified lines | |||
| 40 | }; | 40 | }; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | /* | ||
| 44 | * The driver depends on boot loader initialized state which resets when this | ||
| 45 | * power-domain is powered off. This happens on suspend or when the driver is | ||
| 46 | * missing during boot. Mark the domain as always on until the driver can | ||
| 47 | * handle this. | ||
| 48 | */ | ||
| 49 | &ps_dispdfr_be { | ||
| 50 | apple,always-on; | ||
| 51 | }; | ||
| 52 | |||
| 43 | &display_dfr { | 53 | &display_dfr { |
| 44 | status = "okay"; | 54 | status = "okay"; |
| 45 | }; | 55 | }; |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | |||
| 44 | next-level-cache = <&l2_0>; | 44 | next-level-cache = <&l2_0>; |
| 45 | clocks = <&scmi_dvfs 0>; | 45 | clocks = <&scmi_dvfs 0>; |
| 46 | 46 | ||
| 47 | l2_0: l2-cache-0 { | 47 | l2_0: l2-cache { |
| 48 | compatible = "cache"; | 48 | compatible = "cache"; |
| 49 | cache-level = <2>; | 49 | cache-level = <2>; |
| 50 | /* 8 ways set associative */ | 50 | /* 8 ways set associative */ |
| @@ -53,13 +53,6 @@ · 2 unmodified lines | |||
| 53 | cache-sets = <2048>; | 53 | cache-sets = <2048>; |
| 54 | cache-unified; | 54 | cache-unified; |
| 55 | next-level-cache = <&l3_0>; | 55 | next-level-cache = <&l3_0>; |
| 56 | |||
| 57 | l3_0: l3-cache { | ||
| 58 | compatible = "cache"; | ||
| 59 | cache-level = <3>; | ||
| 60 | cache-size = <0x100000>; | ||
| 61 | cache-unified; | ||
| 62 | }; | ||
| 63 | }; | 56 | }; |
| 64 | }; | 57 | }; |
| 65 | 58 | ||
| @@ -78,7 +71,7 @@ · 12 unmodified lines | |||
| 78 | next-level-cache = <&l2_1>; | 71 | next-level-cache = <&l2_1>; |
| 79 | clocks = <&scmi_dvfs 0>; | 72 | clocks = <&scmi_dvfs 0>; |
| 80 | 73 | ||
| 81 | l2_1: l2-cache-1 { | 74 | l2_1: l2-cache { |
| 82 | compatible = "cache"; | 75 | compatible = "cache"; |
| 83 | cache-level = <2>; | 76 | cache-level = <2>; |
| 84 | /* 8 ways set associative */ | 77 | /* 8 ways set associative */ |
| @@ -105,7 +98,7 @@ · 20 unmodified lines | |||
| 105 | next-level-cache = <&l2_2>; | 98 | next-level-cache = <&l2_2>; |
| 106 | clocks = <&scmi_dvfs 1>; | 99 | clocks = <&scmi_dvfs 1>; |
| 107 | 100 | ||
| 108 | l2_2: l2-cache-2 { | 101 | l2_2: l2-cache { |
| 109 | compatible = "cache"; | 102 | compatible = "cache"; |
| 110 | cache-level = <2>; | 103 | cache-level = <2>; |
| 111 | /* 8 ways set associative */ | 104 | /* 8 ways set associative */ |
| @@ -132,7 +125,7 @@ · 20 unmodified lines | |||
| 132 | next-level-cache = <&l2_3>; | 125 | next-level-cache = <&l2_3>; |
| 133 | clocks = <&scmi_dvfs 1>; | 126 | clocks = <&scmi_dvfs 1>; |
| 134 | 127 | ||
| 135 | l2_3: l2-cache-3 { | 128 | l2_3: l2-cache { |
| 136 | compatible = "cache"; | 129 | compatible = "cache"; |
| 137 | cache-level = <2>; | 130 | cache-level = <2>; |
| 138 | /* 8 ways set associative */ | 131 | /* 8 ways set associative */ |
| @@ -143,6 +136,13 @@ · 4 unmodified lines | |||
| 143 | next-level-cache = <&l3_0>; | 136 | next-level-cache = <&l3_0>; |
| 144 | }; | 137 | }; |
| 145 | }; | 138 | }; |
| 139 | |||
| 140 | l3_0: l3-cache { | ||
| 141 | compatible = "cache"; | ||
| 142 | cache-level = <3>; | ||
| 143 | cache-size = <0x100000>; | ||
| 144 | cache-unified; | ||
| 145 | }; | ||
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | firmware { | 148 | firmware { |
| @@ -144,6 +144,19 @@ · 143 unmodified lines | |||
| 144 | startup-delay-us = <20000>; | 144 | startup-delay-us = <20000>; |
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc { | ||
| 148 | compatible = "regulator-gpio"; | ||
| 149 | pinctrl-names = "default"; | ||
| 150 | pinctrl-0 = <&pinctrl_usdhc2_vsel>; | ||
| 151 | gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; | ||
| 152 | regulator-max-microvolt = <3300000>; | ||
| 153 | regulator-min-microvolt = <1800000>; | ||
| 154 | states = <1800000 0x1>, | ||
| 155 | <3300000 0x0>; | ||
| 156 | regulator-name = "PMIC_USDHC_VSELECT"; | ||
| 157 | vin-supply = <®_nvcc_sd>; | ||
| 158 | }; | ||
| 159 | |||
| 147 | reserved-memory { | 160 | reserved-memory { |
| 148 | #address-cells = <2>; | 161 | #address-cells = <2>; |
| 149 | #size-cells = <2>; | 162 | #size-cells = <2>; |
| @@ -269,7 +282,7 @@ · 119 unmodified lines | |||
| 269 | "SODIMM_19", | 282 | "SODIMM_19", |
| 270 | "", | 283 | "", |
| 271 | "", | 284 | "", |
| 272 | "", | 285 | "PMIC_USDHC_VSELECT", |
| 273 | "", | 286 | "", |
| 274 | "", | 287 | "", |
| 275 | "", | 288 | "", |
| @@ -785,6 +798,7 @@ · 509 unmodified lines | |||
| 785 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>; | 798 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>; |
| 786 | pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>; | 799 | pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>; |
| 787 | vmmc-supply = <®_usdhc2_vmmc>; | 800 | vmmc-supply = <®_usdhc2_vmmc>; |
| 801 | vqmmc-supply = <®_usdhc2_vqmmc>; | ||
| 788 | }; | 802 | }; |
| 789 | 803 | ||
| 790 | &wdog1 { | 804 | &wdog1 { |
| @@ -1206,13 +1220,17 @@ · 415 unmodified lines | |||
| 1206 | <MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6>; /* SODIMM 76 */ | 1220 | <MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x6>; /* SODIMM 76 */ |
| 1207 | }; | 1221 | }; |
| 1208 | 1222 | ||
| 1223 | pinctrl_usdhc2_vsel: usdhc2vselgrp { | ||
| 1224 | fsl,pins = | ||
| 1225 | <MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x10>; /* PMIC_USDHC_VSELECT */ | ||
| 1226 | }; | ||
| 1227 | |||
| 1209 | /* | 1228 | /* |
| 1210 | * Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the | 1229 | * Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the |
| 1211 | * on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here. | 1230 | * on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here. |
| 1212 | */ | 1231 | */ |
| 1213 | pinctrl_usdhc2: usdhc2grp { | 1232 | pinctrl_usdhc2: usdhc2grp { |
| 1214 | fsl,pins = | 1233 | fsl,pins = |
| 1215 | <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | ||
| 1216 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */ | 1234 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */ |
| 1217 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */ | 1235 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */ |
| 1218 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */ | 1236 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */ |
| @@ -1223,7 +1241,6 @@ · 4 unmodified lines | |||
| 1223 | 1241 | ||
| 1224 | pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { | 1242 | pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { |
| 1225 | fsl,pins = | 1243 | fsl,pins = |
| 1226 | <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | ||
| 1227 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>, | 1244 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>, |
| 1228 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>, | 1245 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>, |
| 1229 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>, | 1246 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>, |
| @@ -1234,7 +1251,6 @@ · 4 unmodified lines | |||
| 1234 | 1251 | ||
| 1235 | pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { | 1252 | pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { |
| 1236 | fsl,pins = | 1253 | fsl,pins = |
| 1237 | <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | ||
| 1238 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>, | 1254 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>, |
| 1239 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>, | 1255 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>, |
| 1240 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>, | 1256 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>, |
| @@ -1246,7 +1262,6 @@ · 5 unmodified lines | |||
| 1246 | /* Avoid backfeeding with removed card power */ | 1262 | /* Avoid backfeeding with removed card power */ |
| 1247 | pinctrl_usdhc2_sleep: usdhc2slpgrp { | 1263 | pinctrl_usdhc2_sleep: usdhc2slpgrp { |
| 1248 | fsl,pins = | 1264 | fsl,pins = |
| 1249 | <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x0>, | ||
| 1250 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>, | 1265 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>, |
| 1251 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>, | 1266 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>, |
| 1252 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>, | 1267 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>, |
| @@ -24,6 +24,20 @@ · 23 unmodified lines | |||
| 24 | fsl,operating-mode = "nominal"; | 24 | fsl,operating-mode = "nominal"; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | &gpu2d { | ||
| 28 | assigned-clocks = <&clk IMX8MP_CLK_GPU2D_CORE>; | ||
| 29 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>; | ||
| 30 | assigned-clock-rates = <800000000>; | ||
| 31 | }; | ||
| 32 | |||
| 33 | &gpu3d { | ||
| 34 | assigned-clocks = <&clk IMX8MP_CLK_GPU3D_CORE>, | ||
| 35 | <&clk IMX8MP_CLK_GPU3D_SHADER_CORE>; | ||
| 36 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, | ||
| 37 | <&clk IMX8MP_SYS_PLL1_800M>; | ||
| 38 | assigned-clock-rates = <800000000>, <800000000>; | ||
| 39 | }; | ||
| 40 | |||
| 27 | &pgc_hdmimix { | 41 | &pgc_hdmimix { |
| 28 | assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>, | 42 | assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>, |
| 29 | <&clk IMX8MP_CLK_HDMI_APB>; | 43 | <&clk IMX8MP_CLK_HDMI_APB>; |
| @@ -46,6 +60,18 @@ · 16 unmodified lines | |||
| 46 | assigned-clock-rates = <600000000>, <300000000>; | 60 | assigned-clock-rates = <600000000>, <300000000>; |
| 47 | }; | 61 | }; |
| 48 | 62 | ||
| 63 | &pgc_mlmix { | ||
| 64 | assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>, | ||
| 65 | <&clk IMX8MP_CLK_ML_AXI>, | ||
| 66 | <&clk IMX8MP_CLK_ML_AHB>; | ||
| 67 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, | ||
| 68 | <&clk IMX8MP_SYS_PLL1_800M>, | ||
| 69 | <&clk IMX8MP_SYS_PLL1_800M>; | ||
| 70 | assigned-clock-rates = <800000000>, | ||
| 71 | <800000000>, | ||
| 72 | <300000000>; | ||
| 73 | }; | ||
| 74 | |||
| 49 | &media_blk_ctrl { | 75 | &media_blk_ctrl { |
| 50 | assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI>, | 76 | assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI>, |
| 51 | <&clk IMX8MP_CLK_MEDIA_APB>, | 77 | <&clk IMX8MP_CLK_MEDIA_APB>, |
| @@ -62,3 +88,5 @@ · 10 unmodified lines | |||
| 62 | <0>, <0>, <400000000>, | 88 | <0>, <0>, <400000000>, |
| 63 | <1039500000>; | 89 | <1039500000>; |
| 64 | }; | 90 | }; |
| 91 | |||
| 92 | /delete-node/ &{noc_opp_table/opp-1000000000}; | ||
| @@ -35,7 +35,6 @@ · 34 unmodified lines | |||
| 35 | <0x1 0x00000000 0 0xc0000000>; | 35 | <0x1 0x00000000 0 0xc0000000>; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | |||
| 39 | reg_usdhc2_vmmc: regulator-usdhc2-vmmc { | 38 | reg_usdhc2_vmmc: regulator-usdhc2-vmmc { |
| 40 | compatible = "regulator-fixed"; | 39 | compatible = "regulator-fixed"; |
| 41 | regulator-name = "VSD_3V3"; | 40 | regulator-name = "VSD_3V3"; |
| @@ -46,6 +45,16 @@ · 4 unmodified lines | |||
| 46 | startup-delay-us = <100>; | 45 | startup-delay-us = <100>; |
| 47 | off-on-delay-us = <12000>; | 46 | off-on-delay-us = <12000>; |
| 48 | }; | 47 | }; |
| 48 | |||
| 49 | reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc { | ||
| 50 | compatible = "regulator-gpio"; | ||
| 51 | regulator-name = "VSD_VSEL"; | ||
| 52 | regulator-min-microvolt = <1800000>; | ||
| 53 | regulator-max-microvolt = <3300000>; | ||
| 54 | gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>; | ||
| 55 | states = <3300000 0x0 1800000 0x1>; | ||
| 56 | vin-supply = <&ldo5>; | ||
| 57 | }; | ||
| 49 | }; | 58 | }; |
| 50 | 59 | ||
| 51 | &A53_0 { | 60 | &A53_0 { |
| @@ -205,6 +214,7 @@ · 153 unmodified lines | |||
| 205 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; | 214 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; |
| 206 | cd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; | 215 | cd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; |
| 207 | vmmc-supply = <®_usdhc2_vmmc>; | 216 | vmmc-supply = <®_usdhc2_vmmc>; |
| 217 | vqmmc-supply = <®_usdhc2_vqmmc>; | ||
| 208 | bus-width = <4>; | 218 | bus-width = <4>; |
| 209 | status = "okay"; | 219 | status = "okay"; |
| 210 | }; | 220 | }; |
| @@ -1645,6 +1645,12 @@ · 1644 unmodified lines | |||
| 1645 | opp-hz = /bits/ 64 <200000000>; | 1645 | opp-hz = /bits/ 64 <200000000>; |
| 1646 | }; | 1646 | }; |
| 1647 | 1647 | ||
| 1648 | /* Nominal drive mode maximum */ | ||
| 1649 | opp-800000000 { | ||
| 1650 | opp-hz = /bits/ 64 <800000000>; | ||
| 1651 | }; | ||
| 1652 | |||
| 1653 | /* Overdrive mode maximum */ | ||
| 1648 | opp-1000000000 { | 1654 | opp-1000000000 { |
| 1649 | opp-hz = /bits/ 64 <1000000000>; | 1655 | opp-hz = /bits/ 64 <1000000000>; |
| 1650 | }; | 1656 | }; |
| @@ -1626,7 +1626,7 @@ · 1625 unmodified lines | |||
| 1626 | reg = <0 0x4c300000 0 0x10000>, | 1626 | reg = <0 0x4c300000 0 0x10000>, |
| 1627 | <0 0x60100000 0 0xfe00000>, | 1627 | <0 0x60100000 0 0xfe00000>, |
| 1628 | <0 0x4c360000 0 0x10000>, | 1628 | <0 0x4c360000 0 0x10000>, |
| 1629 | <0 0x4c340000 0 0x2000>; | 1629 | <0 0x4c340000 0 0x4000>; |
| 1630 | reg-names = "dbi", "config", "atu", "app"; | 1630 | reg-names = "dbi", "config", "atu", "app"; |
| 1631 | ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>, | 1631 | ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>, |
| 1632 | <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>; | 1632 | <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>; |
| @@ -1673,7 +1673,7 @@ · 40 unmodified lines | |||
| 1673 | reg = <0 0x4c300000 0 0x10000>, | 1673 | reg = <0 0x4c300000 0 0x10000>, |
| 1674 | <0 0x4c360000 0 0x1000>, | 1674 | <0 0x4c360000 0 0x1000>, |
| 1675 | <0 0x4c320000 0 0x1000>, | 1675 | <0 0x4c320000 0 0x1000>, |
| 1676 | <0 0x4c340000 0 0x2000>, | 1676 | <0 0x4c340000 0 0x4000>, |
| 1677 | <0 0x4c370000 0 0x10000>, | 1677 | <0 0x4c370000 0 0x10000>, |
| 1678 | <0x9 0 1 0>; | 1678 | <0x9 0 1 0>; |
| 1679 | reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space"; | 1679 | reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space"; |
| @@ -1700,7 +1700,7 @@ · 20 unmodified lines | |||
| 1700 | reg = <0 0x4c380000 0 0x10000>, | 1700 | reg = <0 0x4c380000 0 0x10000>, |
| 1701 | <8 0x80100000 0 0xfe00000>, | 1701 | <8 0x80100000 0 0xfe00000>, |
| 1702 | <0 0x4c3e0000 0 0x10000>, | 1702 | <0 0x4c3e0000 0 0x10000>, |
| 1703 | <0 0x4c3c0000 0 0x2000>; | 1703 | <0 0x4c3c0000 0 0x4000>; |
| 1704 | reg-names = "dbi", "config", "atu", "app"; | 1704 | reg-names = "dbi", "config", "atu", "app"; |
| 1705 | ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>, | 1705 | ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>, |
| 1706 | <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>; | 1706 | <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>; |
| @@ -1749,7 +1749,7 @@ · 42 unmodified lines | |||
| 1749 | reg = <0 0x4c380000 0 0x10000>, | 1749 | reg = <0 0x4c380000 0 0x10000>, |
| 1750 | <0 0x4c3e0000 0 0x1000>, | 1750 | <0 0x4c3e0000 0 0x1000>, |
| 1751 | <0 0x4c3a0000 0 0x1000>, | 1751 | <0 0x4c3a0000 0 0x1000>, |
| 1752 | <0 0x4c3c0000 0 0x2000>, | 1752 | <0 0x4c3c0000 0 0x4000>, |
| 1753 | <0 0x4c3f0000 0 0x10000>, | 1753 | <0 0x4c3f0000 0 0x10000>, |
| 1754 | <0xa 0 1 0>; | 1754 | <0xa 0 1 0>; |
| 1755 | reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space"; | 1755 | reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space"; |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | leds { | 27 | leds { |
| 28 | compatible = "gpio-leds"; | 28 | compatible = "gpio-leds"; |
| 29 | pinctrl-names = "default"; | ||
| 30 | pinctrl-0 = <&spi_quad_pins>; | ||
| 29 | 31 | ||
| 30 | led-power1 { | 32 | led-power1 { |
| 31 | label = "udpu:green:power"; | 33 | label = "udpu:green:power"; |
| @@ -82,8 +84,6 @@ · 50 unmodified lines | |||
| 82 | 84 | ||
| 83 | &spi0 { | 85 | &spi0 { |
| 84 | status = "okay"; | 86 | status = "okay"; |
| 85 | pinctrl-names = "default"; | ||
| 86 | pinctrl-0 = <&spi_quad_pins>; | ||
| 87 | 87 | ||
| 88 | flash@0 { | 88 | flash@0 { |
| 89 | compatible = "jedec,spi-nor"; | 89 | compatible = "jedec,spi-nor"; |
| @@ -108,6 +108,10 @@ · 18 unmodified lines | |||
| 108 | }; | 108 | }; |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | &spi_quad_pins { | ||
| 112 | function = "gpio"; | ||
| 113 | }; | ||
| 114 | |||
| 111 | &pinctrl_nb { | 115 | &pinctrl_nb { |
| 112 | i2c2_recovery_pins: i2c2-recovery-pins { | 116 | i2c2_recovery_pins: i2c2-recovery-pins { |
| 113 | groups = "i2c2"; | 117 | groups = "i2c2"; |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | |||
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | vcc3v3_btreg: vcc3v3-btreg { | 33 | vcc3v3_btreg: vcc3v3-btreg { |
| 34 | compatible = "regulator-gpio"; | 34 | compatible = "regulator-fixed"; |
| 35 | enable-active-high; | 35 | enable-active-high; |
| 36 | pinctrl-names = "default"; | 36 | pinctrl-names = "default"; |
| 37 | pinctrl-0 = <&bt_enable_h>; | 37 | pinctrl-0 = <&bt_enable_h>; |
| @@ -39,7 +39,6 @@ · 1 unmodified line | |||
| 39 | regulator-min-microvolt = <3300000>; | 39 | regulator-min-microvolt = <3300000>; |
| 40 | regulator-max-microvolt = <3300000>; | 40 | regulator-max-microvolt = <3300000>; |
| 41 | regulator-always-on; | 41 | regulator-always-on; |
| 42 | states = <3300000 0x0>; | ||
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | vcc3v3_rf_aux_mod: regulator-vcc3v3-rf-aux-mod { | 44 | vcc3v3_rf_aux_mod: regulator-vcc3v3-rf-aux-mod { |
| @@ -26,5 +26,5 @@ · 25 unmodified lines | |||
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | &vcc3v3_btreg { | 28 | &vcc3v3_btreg { |
| 29 | enable-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; | 29 | gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; |
| 30 | }; | 30 | }; |
| @@ -39,5 +39,5 @@ · 38 unmodified lines | |||
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | &vcc3v3_btreg { | 41 | &vcc3v3_btreg { |
| 42 | enable-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; | 42 | gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; |
| 43 | }; | 43 | }; |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | |||
| 43 | sdio_pwrseq: sdio-pwrseq { | 43 | sdio_pwrseq: sdio-pwrseq { |
| 44 | compatible = "mmc-pwrseq-simple"; | 44 | compatible = "mmc-pwrseq-simple"; |
| 45 | clocks = <&rk808 1>; | 45 | clocks = <&rk808 1>; |
| 46 | clock-names = "lpo"; | 46 | clock-names = "ext_clock"; |
| 47 | pinctrl-names = "default"; | 47 | pinctrl-names = "default"; |
| 48 | pinctrl-0 = <&wifi_enable_h>; | 48 | pinctrl-0 = <&wifi_enable_h>; |
| 49 | reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; | 49 | reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; |
| @@ -775,7 +775,7 @@ · 774 unmodified lines | |||
| 775 | rockchip,default-sample-phase = <90>; | 775 | rockchip,default-sample-phase = <90>; |
| 776 | status = "okay"; | 776 | status = "okay"; |
| 777 | 777 | ||
| 778 | sdio-wifi@1 { | 778 | wifi@1 { |
| 779 | compatible = "brcm,bcm4329-fmac"; | 779 | compatible = "brcm,bcm4329-fmac"; |
| 780 | reg = <1>; | 780 | reg = <1>; |
| 781 | interrupt-parent = <&gpio2>; | 781 | interrupt-parent = <&gpio2>; |
| @@ -619,6 +619,8 @@ · 618 unmodified lines | |||
| 619 | bus-width = <8>; | 619 | bus-width = <8>; |
| 620 | max-frequency = <200000000>; | 620 | max-frequency = <200000000>; |
| 621 | non-removable; | 621 | non-removable; |
| 622 | pinctrl-names = "default"; | ||
| 623 | pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; | ||
| 622 | status = "okay"; | 624 | status = "okay"; |
| 623 | }; | 625 | }; |
| 624 | 626 | ||
| @@ -610,7 +610,7 @@ · 609 unmodified lines | |||
| 610 | reg = <0x51>; | 610 | reg = <0x51>; |
| 611 | clock-output-names = "hym8563"; | 611 | clock-output-names = "hym8563"; |
| 612 | interrupt-parent = <&gpio0>; | 612 | interrupt-parent = <&gpio0>; |
| 613 | interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; | 613 | interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>; |
| 614 | pinctrl-names = "default"; | 614 | pinctrl-names = "default"; |
| 615 | pinctrl-0 = <&hym8563_int>; | 615 | pinctrl-0 = <&hym8563_int>; |
| 616 | wakeup-source; | 616 | wakeup-source; |
| @@ -222,6 +222,10 @@ · 221 unmodified lines | |||
| 222 | compatible = "realtek,rt5616"; | 222 | compatible = "realtek,rt5616"; |
| 223 | reg = <0x1b>; | 223 | reg = <0x1b>; |
| 224 | #sound-dai-cells = <0>; | 224 | #sound-dai-cells = <0>; |
| 225 | assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; | ||
| 226 | assigned-clock-rates = <12288000>; | ||
| 227 | clocks = <&cru I2S0_8CH_MCLKOUT>; | ||
| 228 | clock-names = "mclk"; | ||
| 225 | }; | 229 | }; |
| 226 | }; | 230 | }; |
| 227 | 231 | ||
| @@ -214,6 +214,8 @@ · 213 unmodified lines | |||
| 214 | }; | 214 | }; |
| 215 | 215 | ||
| 216 | &package_thermal { | 216 | &package_thermal { |
| 217 | polling-delay = <1000>; | ||
| 218 | |||
| 217 | trips { | 219 | trips { |
| 218 | package_active1: trip-active1 { | 220 | package_active1: trip-active1 { |
| 219 | temperature = <45000>; | 221 | temperature = <45000>; |
| @@ -11,20 +11,15 @@ · 10 unmodified lines | |||
| 11 | compatible = "operating-points-v2"; | 11 | compatible = "operating-points-v2"; |
| 12 | opp-shared; | 12 | opp-shared; |
| 13 | 13 | ||
| 14 | opp-1416000000 { | 14 | opp-1200000000 { |
| 15 | opp-hz = /bits/ 64 <1416000000>; | 15 | opp-hz = /bits/ 64 <1200000000>; |
| 16 | opp-microvolt = <750000 750000 950000>; | 16 | opp-microvolt = <750000 750000 950000>; |
| 17 | clock-latency-ns = <40000>; | 17 | clock-latency-ns = <40000>; |
| 18 | opp-suspend; | 18 | opp-suspend; |
| 19 | }; | 19 | }; |
| 20 | opp-1608000000 { | 20 | opp-1296000000 { |
| 21 | opp-hz = /bits/ 64 <1608000000>; | 21 | opp-hz = /bits/ 64 <1296000000>; |
| 22 | opp-microvolt = <887500 887500 950000>; | 22 | opp-microvolt = <775000 775000 950000>; |
| 23 | clock-latency-ns = <40000>; | ||
| 24 | }; | ||
| 25 | opp-1704000000 { | ||
| 26 | opp-hz = /bits/ 64 <1704000000>; | ||
| 27 | opp-microvolt = <937500 937500 950000>; | ||
| 28 | clock-latency-ns = <40000>; | 23 | clock-latency-ns = <40000>; |
| 29 | }; | 24 | }; |
| 30 | }; | 25 | }; |
| @@ -33,9 +28,14 @@ · 2 unmodified lines | |||
| 33 | compatible = "operating-points-v2"; | 28 | compatible = "operating-points-v2"; |
| 34 | opp-shared; | 29 | opp-shared; |
| 35 | 30 | ||
| 31 | opp-1200000000{ | ||
| 32 | opp-hz = /bits/ 64 <1200000000>; | ||
| 33 | opp-microvolt = <750000 750000 950000>; | ||
| 34 | clock-latency-ns = <40000>; | ||
| 35 | }; | ||
| 36 | opp-1416000000 { | 36 | opp-1416000000 { |
| 37 | opp-hz = /bits/ 64 <1416000000>; | 37 | opp-hz = /bits/ 64 <1416000000>; |
| 38 | opp-microvolt = <750000 750000 950000>; | 38 | opp-microvolt = <762500 762500 950000>; |
| 39 | clock-latency-ns = <40000>; | 39 | clock-latency-ns = <40000>; |
| 40 | }; | 40 | }; |
| 41 | opp-1608000000 { | 41 | opp-1608000000 { |
| @@ -43,25 +43,20 @@ · 1 unmodified line | |||
| 43 | opp-microvolt = <787500 787500 950000>; | 43 | opp-microvolt = <787500 787500 950000>; |
| 44 | clock-latency-ns = <40000>; | 44 | clock-latency-ns = <40000>; |
| 45 | }; | 45 | }; |
| 46 | opp-1800000000 { | ||
| 47 | opp-hz = /bits/ 64 <1800000000>; | ||
| 48 | opp-microvolt = <875000 875000 950000>; | ||
| 49 | clock-latency-ns = <40000>; | ||
| 50 | }; | ||
| 51 | opp-2016000000 { | ||
| 52 | opp-hz = /bits/ 64 <2016000000>; | ||
| 53 | opp-microvolt = <950000 950000 950000>; | ||
| 54 | clock-latency-ns = <40000>; | ||
| 55 | }; | ||
| 56 | }; | 46 | }; |
| 57 | 47 | ||
| 58 | cluster2_opp_table: opp-table-cluster2 { | 48 | cluster2_opp_table: opp-table-cluster2 { |
| 59 | compatible = "operating-points-v2"; | 49 | compatible = "operating-points-v2"; |
| 60 | opp-shared; | 50 | opp-shared; |
| 61 | 51 | ||
| 52 | opp-1200000000{ | ||
| 53 | opp-hz = /bits/ 64 <1200000000>; | ||
| 54 | opp-microvolt = <750000 750000 950000>; | ||
| 55 | clock-latency-ns = <40000>; | ||
| 56 | }; | ||
| 62 | opp-1416000000 { | 57 | opp-1416000000 { |
| 63 | opp-hz = /bits/ 64 <1416000000>; | 58 | opp-hz = /bits/ 64 <1416000000>; |
| 64 | opp-microvolt = <750000 750000 950000>; | 59 | opp-microvolt = <762500 762500 950000>; |
| 65 | clock-latency-ns = <40000>; | 60 | clock-latency-ns = <40000>; |
| 66 | }; | 61 | }; |
| 67 | opp-1608000000 { | 62 | opp-1608000000 { |
| @@ -69,16 +64,6 @@ · 1 unmodified line | |||
| 69 | opp-microvolt = <787500 787500 950000>; | 64 | opp-microvolt = <787500 787500 950000>; |
| 70 | clock-latency-ns = <40000>; | 65 | clock-latency-ns = <40000>; |
| 71 | }; | 66 | }; |
| 72 | opp-1800000000 { | ||
| 73 | opp-hz = /bits/ 64 <1800000000>; | ||
| 74 | opp-microvolt = <875000 875000 950000>; | ||
| 75 | clock-latency-ns = <40000>; | ||
| 76 | }; | ||
| 77 | opp-2016000000 { | ||
| 78 | opp-hz = /bits/ 64 <2016000000>; | ||
| 79 | opp-microvolt = <950000 950000 950000>; | ||
| 80 | clock-latency-ns = <40000>; | ||
| 81 | }; | ||
| 82 | }; | 67 | }; |
| 83 | 68 | ||
| 84 | gpu_opp_table: opp-table { | 69 | gpu_opp_table: opp-table { |
| @@ -104,10 +89,6 @@ · 19 unmodified lines | |||
| 104 | opp-hz = /bits/ 64 <700000000>; | 89 | opp-hz = /bits/ 64 <700000000>; |
| 105 | opp-microvolt = <750000 750000 850000>; | 90 | opp-microvolt = <750000 750000 850000>; |
| 106 | }; | 91 | }; |
| 107 | opp-850000000 { | ||
| 108 | opp-hz = /bits/ 64 <800000000>; | ||
| 109 | opp-microvolt = <787500 787500 850000>; | ||
| 110 | }; | ||
| 111 | }; | 92 | }; |
| 112 | }; | 93 | }; |
| 113 | 94 | ||
| @@ -116,11 +116,11 @@ · 115 unmodified lines | |||
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | intc: interrupt-controller@4ac10000 { | 118 | intc: interrupt-controller@4ac10000 { |
| 119 | compatible = "arm,cortex-a7-gic"; | 119 | compatible = "arm,gic-400"; |
| 120 | reg = <0x4ac10000 0x0 0x1000>, | 120 | reg = <0x4ac10000 0x0 0x1000>, |
| 121 | <0x4ac20000 0x0 0x2000>, | 121 | <0x4ac20000 0x0 0x20000>, |
| 122 | <0x4ac40000 0x0 0x2000>, | 122 | <0x4ac40000 0x0 0x20000>, |
| 123 | <0x4ac60000 0x0 0x2000>; | 123 | <0x4ac60000 0x0 0x20000>; |
| 124 | #interrupt-cells = <3>; | 124 | #interrupt-cells = <3>; |
| 125 | interrupt-controller; | 125 | interrupt-controller; |
| 126 | }; | 126 | }; |
| @@ -1201,13 +1201,12 @@ · 1200 unmodified lines | |||
| 1201 | }; | 1201 | }; |
| 1202 | 1202 | ||
| 1203 | intc: interrupt-controller@4ac10000 { | 1203 | intc: interrupt-controller@4ac10000 { |
| 1204 | compatible = "arm,cortex-a7-gic"; | 1204 | compatible = "arm,gic-400"; |
| 1205 | reg = <0x4ac10000 0x1000>, | 1205 | reg = <0x4ac10000 0x1000>, |
| 1206 | <0x4ac20000 0x2000>, | 1206 | <0x4ac20000 0x20000>, |
| 1207 | <0x4ac40000 0x2000>, | 1207 | <0x4ac40000 0x20000>, |
| 1208 | <0x4ac60000 0x2000>; | 1208 | <0x4ac60000 0x20000>; |
| 1209 | #interrupt-cells = <3>; | 1209 | #interrupt-cells = <3>; |
| 1210 | #address-cells = <1>; | ||
| 1211 | interrupt-controller; | 1210 | interrupt-controller; |
| 1212 | }; | 1211 | }; |
| 1213 | }; | 1212 | }; |
| @@ -115,14 +115,13 @@ · 114 unmodified lines | |||
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | intc: interrupt-controller@4ac00000 { | 117 | intc: interrupt-controller@4ac00000 { |
| 118 | compatible = "arm,cortex-a7-gic"; | 118 | compatible = "arm,gic-400"; |
| 119 | #interrupt-cells = <3>; | 119 | #interrupt-cells = <3>; |
| 120 | #address-cells = <1>; | ||
| 121 | interrupt-controller; | 120 | interrupt-controller; |
| 122 | reg = <0x0 0x4ac10000 0x0 0x1000>, | 121 | reg = <0x0 0x4ac10000 0x0 0x1000>, |
| 123 | <0x0 0x4ac20000 0x0 0x2000>, | 122 | <0x0 0x4ac20000 0x0 0x20000>, |
| 124 | <0x0 0x4ac40000 0x0 0x2000>, | 123 | <0x0 0x4ac40000 0x0 0x20000>, |
| 125 | <0x0 0x4ac60000 0x0 0x2000>; | 124 | <0x0 0x4ac60000 0x0 0x20000>; |
| 126 | }; | 125 | }; |
| 127 | 126 | ||
| 128 | psci { | 127 | psci { |
| @@ -1729,12 +1729,12 @@ CONFIG_NLS_CODEPAGE_437=y · 1728 unmodified lines | |||
| 1729 | CONFIG_NLS_ISO8859_1=y | 1729 | CONFIG_NLS_ISO8859_1=y |
| 1730 | CONFIG_SECURITY=y | 1730 | CONFIG_SECURITY=y |
| 1731 | CONFIG_CRYPTO_USER=y | 1731 | CONFIG_CRYPTO_USER=y |
| 1732 | CONFIG_CRYPTO_CHACHA20=m | ||
| 1732 | CONFIG_CRYPTO_TEST=m | 1733 | CONFIG_CRYPTO_TEST=m |
| 1733 | CONFIG_CRYPTO_ECHAINIV=y | 1734 | CONFIG_CRYPTO_ECHAINIV=y |
| 1734 | CONFIG_CRYPTO_MICHAEL_MIC=m | 1735 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 1735 | CONFIG_CRYPTO_ANSI_CPRNG=y | 1736 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 1736 | CONFIG_CRYPTO_USER_API_RNG=m | 1737 | CONFIG_CRYPTO_USER_API_RNG=m |
| 1737 | CONFIG_CRYPTO_CHACHA20_NEON=m | ||
| 1738 | CONFIG_CRYPTO_GHASH_ARM64_CE=y | 1738 | CONFIG_CRYPTO_GHASH_ARM64_CE=y |
| 1739 | CONFIG_CRYPTO_SHA1_ARM64_CE=y | 1739 | CONFIG_CRYPTO_SHA1_ARM64_CE=y |
| 1740 | CONFIG_CRYPTO_SHA2_ARM64_CE=y | 1740 | CONFIG_CRYPTO_SHA2_ARM64_CE=y |
| @@ -81,6 +81,7 @@ · 80 unmodified lines | |||
| 81 | #define ARM_CPU_PART_CORTEX_A78AE 0xD42 | 81 | #define ARM_CPU_PART_CORTEX_A78AE 0xD42 |
| 82 | #define ARM_CPU_PART_CORTEX_X1 0xD44 | 82 | #define ARM_CPU_PART_CORTEX_X1 0xD44 |
| 83 | #define ARM_CPU_PART_CORTEX_A510 0xD46 | 83 | #define ARM_CPU_PART_CORTEX_A510 0xD46 |
| 84 | #define ARM_CPU_PART_CORTEX_X1C 0xD4C | ||
| 84 | #define ARM_CPU_PART_CORTEX_A520 0xD80 | 85 | #define ARM_CPU_PART_CORTEX_A520 0xD80 |
| 85 | #define ARM_CPU_PART_CORTEX_A710 0xD47 | 86 | #define ARM_CPU_PART_CORTEX_A710 0xD47 |
| 86 | #define ARM_CPU_PART_CORTEX_A715 0xD4D | 87 | #define ARM_CPU_PART_CORTEX_A715 0xD4D |
| @@ -168,6 +169,7 @@ · 81 unmodified lines | |||
| 168 | #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) | 169 | #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) |
| 169 | #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) | 170 | #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) |
| 170 | #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) | 171 | #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) |
| 172 | #define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C) | ||
| 171 | #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) | 173 | #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) |
| 172 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) | 174 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) |
| 173 | #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) | 175 | #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | |||
| 52 | mrs x0, id_aa64mmfr1_el1 | 52 | mrs x0, id_aa64mmfr1_el1 |
| 53 | ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 | 53 | ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 |
| 54 | cbz x0, .Lskip_hcrx_\@ | 54 | cbz x0, .Lskip_hcrx_\@ |
| 55 | mov_q x0, HCRX_HOST_FLAGS | 55 | mov_q x0, (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM) |
| 56 | 56 | ||
| 57 | /* Enable GCS if supported */ | 57 | /* Enable GCS if supported */ |
| 58 | mrs_s x1, SYS_ID_AA64PFR1_EL1 | 58 | mrs_s x1, SYS_ID_AA64PFR1_EL1 |
| @@ -121,6 +121,15 @@ · 120 unmodified lines | |||
| 121 | #define ESR_ELx_FSC_SEA_TTW(n) (0x14 + (n)) | 121 | #define ESR_ELx_FSC_SEA_TTW(n) (0x14 + (n)) |
| 122 | #define ESR_ELx_FSC_SECC (0x18) | 122 | #define ESR_ELx_FSC_SECC (0x18) |
| 123 | #define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n)) | 123 | #define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n)) |
| 124 | #define ESR_ELx_FSC_ADDRSZ (0x00) | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Annoyingly, the negative levels for Address size faults aren't laid out | ||
| 128 | * contiguously (or in the desired order) | ||
| 129 | */ | ||
| 130 | #define ESR_ELx_FSC_ADDRSZ_nL(n) ((n) == -1 ? 0x25 : 0x2C) | ||
| 131 | #define ESR_ELx_FSC_ADDRSZ_L(n) ((n) < 0 ? ESR_ELx_FSC_ADDRSZ_nL(n) : \ | ||
| 132 | (ESR_ELx_FSC_ADDRSZ + (n))) | ||
| 124 | 133 | ||
| 125 | /* Status codes for individual page table levels */ | 134 | /* Status codes for individual page table levels */ |
| 126 | #define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + (n)) | 135 | #define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + (n)) |
| @@ -161,8 +170,6 @@ · 34 unmodified lines | |||
| 161 | #define ESR_ELx_Xs_MASK (GENMASK_ULL(4, 0)) | 170 | #define ESR_ELx_Xs_MASK (GENMASK_ULL(4, 0)) |
| 162 | 171 | ||
| 163 | /* ISS field definitions for exceptions taken in to Hyp */ | 172 | /* ISS field definitions for exceptions taken in to Hyp */ |
| 164 | #define ESR_ELx_FSC_ADDRSZ (0x00) | ||
| 165 | #define ESR_ELx_FSC_ADDRSZ_L(n) (ESR_ELx_FSC_ADDRSZ + (n)) | ||
| 166 | #define ESR_ELx_CV (UL(1) << 24) | 173 | #define ESR_ELx_CV (UL(1) << 24) |
| 167 | #define ESR_ELx_COND_SHIFT (20) | 174 | #define ESR_ELx_COND_SHIFT (20) |
| 168 | #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) | 175 | #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) |
| @@ -464,6 +471,39 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr) · 295 unmodified lines | |||
| 464 | (esr == ESR_ELx_FSC_ACCESS_L(0)); | 471 | (esr == ESR_ELx_FSC_ACCESS_L(0)); |
| 465 | } | 472 | } |
| 466 | 473 | ||
| 474 | static inline bool esr_fsc_is_addr_sz_fault(unsigned long esr) | ||
| 475 | { | ||
| 476 | esr &= ESR_ELx_FSC; | ||
| 477 | |||
| 478 | return (esr == ESR_ELx_FSC_ADDRSZ_L(3)) || | ||
| 479 | (esr == ESR_ELx_FSC_ADDRSZ_L(2)) || | ||
| 480 | (esr == ESR_ELx_FSC_ADDRSZ_L(1)) || | ||
| 481 | (esr == ESR_ELx_FSC_ADDRSZ_L(0)) || | ||
| 482 | (esr == ESR_ELx_FSC_ADDRSZ_L(-1)); | ||
| 483 | } | ||
| 484 | |||
| 485 | static inline bool esr_fsc_is_sea_ttw(unsigned long esr) | ||
| 486 | { | ||
| 487 | esr = esr & ESR_ELx_FSC; | ||
| 488 | |||
| 489 | return (esr == ESR_ELx_FSC_SEA_TTW(3)) || | ||
| 490 | (esr == ESR_ELx_FSC_SEA_TTW(2)) || | ||
| 491 | (esr == ESR_ELx_FSC_SEA_TTW(1)) || | ||
| 492 | (esr == ESR_ELx_FSC_SEA_TTW(0)) || | ||
| 493 | (esr == ESR_ELx_FSC_SEA_TTW(-1)); | ||
| 494 | } | ||
| 495 | |||
| 496 | static inline bool esr_fsc_is_secc_ttw(unsigned long esr) | ||
| 497 | { | ||
| 498 | esr = esr & ESR_ELx_FSC; | ||
| 499 | |||
| 500 | return (esr == ESR_ELx_FSC_SECC_TTW(3)) || | ||
| 501 | (esr == ESR_ELx_FSC_SECC_TTW(2)) || | ||
| 502 | (esr == ESR_ELx_FSC_SECC_TTW(1)) || | ||
| 503 | (esr == ESR_ELx_FSC_SECC_TTW(0)) || | ||
| 504 | (esr == ESR_ELx_FSC_SECC_TTW(-1)); | ||
| 505 | } | ||
| 506 | |||
| 467 | /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */ | 507 | /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */ |
| 468 | static inline bool esr_iss_is_eretax(unsigned long esr) | 508 | static inline bool esr_iss_is_eretax(unsigned long esr) |
| 469 | { | 509 | { |
| @@ -706,6 +706,7 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result, · 705 unmodified lines | |||
| 706 | } | 706 | } |
| 707 | #endif | 707 | #endif |
| 708 | u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type); | 708 | u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type); |
| 709 | u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type); | ||
| 709 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, | 710 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, |
| 710 | enum aarch64_insn_system_register sysreg); | 711 | enum aarch64_insn_system_register sysreg); |
| 711 | 712 | ||
| @@ -100,9 +100,8 @@ · 99 unmodified lines | |||
| 100 | HCR_FMO | HCR_IMO | HCR_PTW | HCR_TID3 | HCR_TID1) | 100 | HCR_FMO | HCR_IMO | HCR_PTW | HCR_TID3 | HCR_TID1) |
| 101 | #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA) | 101 | #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA) |
| 102 | #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC) | 102 | #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC) |
| 103 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) | 103 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H | HCR_AMO | HCR_IMO | HCR_FMO) |
| 104 | 104 | ||
| 105 | #define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM) | ||
| 106 | #define MPAMHCR_HOST_FLAGS 0 | 105 | #define MPAMHCR_HOST_FLAGS 0 |
| 107 | 106 | ||
| 108 | /* TCR_EL2 Registers bits */ | 107 | /* TCR_EL2 Registers bits */ |
| @@ -305,7 +305,12 @@ static __always_inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vc · 304 unmodified lines | |||
| 305 | 305 | ||
| 306 | static __always_inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu) | 306 | static __always_inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu) |
| 307 | { | 307 | { |
| 308 | return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8; | 308 | u64 hpfar = vcpu->arch.fault.hpfar_el2; |
| 309 | |||
| 310 | if (unlikely(!(hpfar & HPFAR_EL2_NS))) | ||
| 311 | return INVALID_GPA; | ||
| 312 | |||
| 313 | return FIELD_GET(HPFAR_EL2_FIPA, hpfar) << 12; | ||
| 309 | } | 314 | } |
| 310 | 315 | ||
| 311 | static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu) | 316 | static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu) |
| @@ -1588,4 +1588,9 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); · 1587 unmodified lines | |||
| 1588 | #define kvm_has_s1poe(k) \ | 1588 | #define kvm_has_s1poe(k) \ |
| 1589 | (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) | 1589 | (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) |
| 1590 | 1590 | ||
| 1591 | static inline bool kvm_arch_has_irq_bypass(void) | ||
| 1592 | { | ||
| 1593 | return true; | ||
| 1594 | } | ||
| 1595 | |||
| 1591 | #endif /* __ARM64_KVM_HOST_H__ */ | 1596 | #endif /* __ARM64_KVM_HOST_H__ */ |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | * Was this synchronous external abort a RAS notification? | 14 | * Was this synchronous external abort a RAS notification? |
| 15 | * Returns '0' for errors handled by some RAS subsystem, or -ENOENT. | 15 | * Returns '0' for errors handled by some RAS subsystem, or -ENOENT. |
| 16 | */ | 16 | */ |
| 17 | static inline int kvm_handle_guest_sea(phys_addr_t addr, u64 esr) | 17 | static inline int kvm_handle_guest_sea(void) |
| 18 | { | 18 | { |
| 19 | /* apei_claim_sea(NULL) expects to mask interrupts itself */ | 19 | /* apei_claim_sea(NULL) expects to mask interrupts itself */ |
| 20 | lockdep_assert_irqs_enabled(); | 20 | lockdep_assert_irqs_enabled(); |
| @@ -94,17 +94,6 @@ static inline bool kaslr_requires_kpti(void) · 93 unmodified lines | |||
| 94 | return false; | 94 | return false; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | /* | ||
| 98 | * Systems affected by Cavium erratum 24756 are incompatible | ||
| 99 | * with KPTI. | ||
| 100 | */ | ||
| 101 | if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) { | ||
| 102 | extern const struct midr_range cavium_erratum_27456_cpus[]; | ||
| 103 | |||
| 104 | if (is_midr_in_range_list(cavium_erratum_27456_cpus)) | ||
| 105 | return false; | ||
| 106 | } | ||
| 107 | |||
| 108 | return true; | 97 | return true; |
| 109 | } | 98 | } |
| 110 | 99 | ||
| @@ -86,7 +86,7 @@ · 85 unmodified lines | |||
| 86 | 86 | ||
| 87 | #endif | 87 | #endif |
| 88 | 88 | ||
| 89 | #define res_smp_cond_load_acquire_timewait(v, c) smp_cond_load_acquire_timewait(v, c, 0, 1) | 89 | #define res_smp_cond_load_acquire(v, c) smp_cond_load_acquire_timewait(v, c, 0, 1) |
| 90 | 90 | ||
| 91 | #include <asm-generic/rqspinlock.h> | 91 | #include <asm-generic/rqspinlock.h> |
| 92 | 92 | ||
| @@ -97,6 +97,9 @@ enum mitigation_state arm64_get_meltdown_state(void); · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | enum mitigation_state arm64_get_spectre_bhb_state(void); | 98 | enum mitigation_state arm64_get_spectre_bhb_state(void); |
| 99 | bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope); | 99 | bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope); |
| 100 | extern bool __nospectre_bhb; | ||
| 101 | u8 get_spectre_bhb_loop_value(void); | ||
| 102 | bool is_spectre_bhb_fw_mitigated(void); | ||
| 100 | void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused); | 103 | void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused); |
| 101 | bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr); | 104 | bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr); |
| 102 | 105 | ||
| @@ -99,6 +99,19 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, · 98 unmodified lines | |||
| 99 | return res; | 99 | return res; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | #if IS_ENABLED(CONFIG_CC_IS_GCC) && IS_ENABLED(CONFIG_PAGE_SIZE_64KB) | ||
| 103 | static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void) | ||
| 104 | { | ||
| 105 | const struct vdso_time_data *ret = &vdso_u_time_data; | ||
| 106 | |||
| 107 | /* Work around invalid absolute relocations */ | ||
| 108 | OPTIMIZER_HIDE_VAR(ret); | ||
| 109 | |||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | #define __arch_get_vdso_u_time_data __arch_get_vdso_u_time_data | ||
| 113 | #endif /* IS_ENABLED(CONFIG_CC_IS_GCC) && IS_ENABLED(CONFIG_PAGE_SIZE_64KB) */ | ||
| 114 | |||
| 102 | #endif /* !__ASSEMBLY__ */ | 115 | #endif /* !__ASSEMBLY__ */ |
| 103 | 116 | ||
| 104 | #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ | 117 | #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ |
| @@ -335,7 +335,7 @@ static const struct midr_range cavium_erratum_23154_cpus[] = { · 334 unmodified lines | |||
| 335 | #endif | 335 | #endif |
| 336 | 336 | ||
| 337 | #ifdef CONFIG_CAVIUM_ERRATUM_27456 | 337 | #ifdef CONFIG_CAVIUM_ERRATUM_27456 |
| 338 | const struct midr_range cavium_erratum_27456_cpus[] = { | 338 | static const struct midr_range cavium_erratum_27456_cpus[] = { |
| 339 | /* Cavium ThunderX, T88 pass 1.x - 2.1 */ | 339 | /* Cavium ThunderX, T88 pass 1.x - 2.1 */ |
| 340 | MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), | 340 | MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), |
| 341 | /* Cavium ThunderX, T81 pass 1.0 */ | 341 | /* Cavium ThunderX, T81 pass 1.0 */ |
| @@ -114,7 +114,14 @@ static struct arm64_cpu_capabilities const __ro_after_init *cpucap_ptrs[ARM64_NC · 113 unmodified lines | |||
| 114 | 114 | ||
| 115 | DECLARE_BITMAP(boot_cpucaps, ARM64_NCAPS); | 115 | DECLARE_BITMAP(boot_cpucaps, ARM64_NCAPS); |
| 116 | 116 | ||
| 117 | bool arm64_use_ng_mappings = false; | 117 | /* |
| 118 | * arm64_use_ng_mappings must be placed in the .data section, otherwise it | ||
| 119 | * ends up in the .bss section where it is initialized in early_map_kernel() | ||
| 120 | * after the MMU (with the idmap) was enabled. create_init_idmap() - which | ||
| 121 | * runs before early_map_kernel() and reads the variable via PTE_MAYBE_NG - | ||
| 122 | * may end up generating an incorrect idmap page table attributes. | ||
| 123 | */ | ||
| 124 | bool arm64_use_ng_mappings __read_mostly = false; | ||
| 118 | EXPORT_SYMBOL(arm64_use_ng_mappings); | 125 | EXPORT_SYMBOL(arm64_use_ng_mappings); |
| 119 | 126 | ||
| 120 | DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors; | 127 | DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors; |
| @@ -47,10 +47,6 @@ PROVIDE(__pi_id_aa64smfr0_override = id_aa64smfr0_override); · 46 unmodified lines | |||
| 47 | PROVIDE(__pi_id_aa64zfr0_override = id_aa64zfr0_override); | 47 | PROVIDE(__pi_id_aa64zfr0_override = id_aa64zfr0_override); |
| 48 | PROVIDE(__pi_arm64_sw_feature_override = arm64_sw_feature_override); | 48 | PROVIDE(__pi_arm64_sw_feature_override = arm64_sw_feature_override); |
| 49 | PROVIDE(__pi_arm64_use_ng_mappings = arm64_use_ng_mappings); | 49 | PROVIDE(__pi_arm64_use_ng_mappings = arm64_use_ng_mappings); |
| 50 | #ifdef CONFIG_CAVIUM_ERRATUM_27456 | ||
| 51 | PROVIDE(__pi_cavium_erratum_27456_cpus = cavium_erratum_27456_cpus); | ||
| 52 | PROVIDE(__pi_is_midr_in_range_list = is_midr_in_range_list); | ||
| 53 | #endif | ||
| 54 | PROVIDE(__pi__ctype = _ctype); | 50 | PROVIDE(__pi__ctype = _ctype); |
| 55 | PROVIDE(__pi_memstart_offset_seed = memstart_offset_seed); | 51 | PROVIDE(__pi_memstart_offset_seed = memstart_offset_seed); |
| 56 | 52 | ||
| @@ -207,6 +207,29 @@ static void __init map_fdt(u64 fdt) · 206 unmodified lines | |||
| 207 | dsb(ishst); | 207 | dsb(ishst); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | /* | ||
| 211 | * PI version of the Cavium Eratum 27456 detection, which makes it | ||
| 212 | * impossible to use non-global mappings. | ||
| 213 | */ | ||
| 214 | static bool __init ng_mappings_allowed(void) | ||
| 215 | { | ||
| 216 | static const struct midr_range cavium_erratum_27456_cpus[] __initconst = { | ||
| 217 | /* Cavium ThunderX, T88 pass 1.x - 2.1 */ | ||
| 218 | MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), | ||
| 219 | /* Cavium ThunderX, T81 pass 1.0 */ | ||
| 220 | MIDR_REV(MIDR_THUNDERX_81XX, 0, 0), | ||
| 221 | {}, | ||
| 222 | }; | ||
| 223 | |||
| 224 | for (const struct midr_range *r = cavium_erratum_27456_cpus; r->model; r++) { | ||
| 225 | if (midr_is_cpu_model_range(read_cpuid_id(), r->model, | ||
| 226 | r->rv_min, r->rv_max)) | ||
| 227 | return false; | ||
| 228 | } | ||
| 229 | |||
| 230 | return true; | ||
| 231 | } | ||
| 232 | |||
| 210 | asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt) | 233 | asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt) |
| 211 | { | 234 | { |
| 212 | static char const chosen_str[] __initconst = "/chosen"; | 235 | static char const chosen_str[] __initconst = "/chosen"; |
| @@ -246,7 +269,7 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt) · 33 unmodified lines | |||
| 246 | u64 kaslr_seed = kaslr_early_init(fdt, chosen); | 269 | u64 kaslr_seed = kaslr_early_init(fdt, chosen); |
| 247 | 270 | ||
| 248 | if (kaslr_seed && kaslr_requires_kpti()) | 271 | if (kaslr_seed && kaslr_requires_kpti()) |
| 249 | arm64_use_ng_mappings = true; | 272 | arm64_use_ng_mappings = ng_mappings_allowed(); |
| 250 | 273 | ||
| 251 | kaslr_offset |= kaslr_seed & ~(MIN_KIMG_ALIGN - 1); | 274 | kaslr_offset |= kaslr_seed & ~(MIN_KIMG_ALIGN - 1); |
| 252 | } | 275 | } |
| @@ -879,16 +879,19 @@ static u8 spectre_bhb_loop_affected(void) · 878 unmodified lines | |||
| 879 | static const struct midr_range spectre_bhb_k132_list[] = { | 879 | static const struct midr_range spectre_bhb_k132_list[] = { |
| 880 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), | 880 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), |
| 881 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), | 881 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), |
| 882 | {}, | ||
| 882 | }; | 883 | }; |
| 883 | static const struct midr_range spectre_bhb_k38_list[] = { | 884 | static const struct midr_range spectre_bhb_k38_list[] = { |
| 884 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), | 885 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), |
| 885 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), | 886 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), |
| 887 | {}, | ||
| 886 | }; | 888 | }; |
| 887 | static const struct midr_range spectre_bhb_k32_list[] = { | 889 | static const struct midr_range spectre_bhb_k32_list[] = { |
| 888 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), | 890 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), |
| 889 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE), | 891 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE), |
| 890 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), | 892 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), |
| 891 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), | 893 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), |
| 894 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), | ||
| 892 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), | 895 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 893 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), | 896 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), |
| 894 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), | 897 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), |
| @@ -997,6 +1000,11 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, · 102 unmodified lines | |||
| 997 | return true; | 1000 | return true; |
| 998 | } | 1001 | } |
| 999 | 1002 | ||
| 1003 | u8 get_spectre_bhb_loop_value(void) | ||
| 1004 | { | ||
| 1005 | return max_bhb_k; | ||
| 1006 | } | ||
| 1007 | |||
| 1000 | static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) | 1008 | static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) |
| 1001 | { | 1009 | { |
| 1002 | const char *v = arm64_get_bp_hardening_vector(slot); | 1010 | const char *v = arm64_get_bp_hardening_vector(slot); |
| @@ -1014,7 +1022,7 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) · 11 unmodified lines | |||
| 1014 | isb(); | 1022 | isb(); |
| 1015 | } | 1023 | } |
| 1016 | 1024 | ||
| 1017 | static bool __read_mostly __nospectre_bhb; | 1025 | bool __read_mostly __nospectre_bhb; |
| 1018 | static int __init parse_spectre_bhb_param(char *str) | 1026 | static int __init parse_spectre_bhb_param(char *str) |
| 1019 | { | 1027 | { |
| 1020 | __nospectre_bhb = true; | 1028 | __nospectre_bhb = true; |
| @@ -1092,6 +1100,11 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry) · 71 unmodified lines | |||
| 1092 | update_mitigation_state(&spectre_bhb_state, state); | 1100 | update_mitigation_state(&spectre_bhb_state, state); |
| 1093 | } | 1101 | } |
| 1094 | 1102 | ||
| 1103 | bool is_spectre_bhb_fw_mitigated(void) | ||
| 1104 | { | ||
| 1105 | return test_bit(BHB_FW, &system_bhb_mitigations); | ||
| 1106 | } | ||
| 1107 | |||
| 1095 | /* Patched to NOP when enabled */ | 1108 | /* Patched to NOP when enabled */ |
| 1096 | void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt, | 1109 | void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt, |
| 1097 | __le32 *origptr, | 1110 | __le32 *origptr, |
| @@ -2743,11 +2743,6 @@ bool kvm_arch_irqchip_in_kernel(struct kvm *kvm) · 2742 unmodified lines | |||
| 2743 | return irqchip_in_kernel(kvm); | 2743 | return irqchip_in_kernel(kvm); |
| 2744 | } | 2744 | } |
| 2745 | 2745 | ||
| 2746 | bool kvm_arch_has_irq_bypass(void) | ||
| 2747 | { | ||
| 2748 | return true; | ||
| 2749 | } | ||
| 2750 | |||
| 2751 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, | 2746 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, |
| 2752 | struct irq_bypass_producer *prod) | 2747 | struct irq_bypass_producer *prod) |
| 2753 | { | 2748 | { |
| @@ -12,6 +12,16 @@ · 11 unmodified lines | |||
| 12 | #include <asm/kvm_hyp.h> | 12 | #include <asm/kvm_hyp.h> |
| 13 | #include <asm/kvm_mmu.h> | 13 | #include <asm/kvm_mmu.h> |
| 14 | 14 | ||
| 15 | static inline bool __fault_safe_to_translate(u64 esr) | ||
| 16 | { | ||
| 17 | u64 fsc = esr & ESR_ELx_FSC; | ||
| 18 | |||
| 19 | if (esr_fsc_is_sea_ttw(esr) || esr_fsc_is_secc_ttw(esr)) | ||
| 20 | return false; | ||
| 21 | |||
| 22 | return !(fsc == ESR_ELx_FSC_EXTABT && (esr & ESR_ELx_FnV)); | ||
| 23 | } | ||
| 24 | |||
| 15 | static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) | 25 | static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) |
| 16 | { | 26 | { |
| 17 | int ret; | 27 | int ret; |
| @@ -44,34 +54,50 @@ static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) · 26 unmodified lines | |||
| 44 | return true; | 54 | return true; |
| 45 | } | 55 | } |
| 46 | 56 | ||
| 47 | static inline bool __get_fault_info(u64 esr, struct kvm_vcpu_fault_info *fault) | 57 | /* |
| 58 | * Checks for the conditions when HPFAR_EL2 is written, per ARM ARM R_FKLWR. | ||
| 59 | */ | ||
| 60 | static inline bool __hpfar_valid(u64 esr) | ||
| 48 | { | 61 | { |
| 49 | u64 hpfar, far; | ||
| 50 | |||
| 51 | far = read_sysreg_el2(SYS_FAR); | ||
| 52 | |||
| 53 | /* | 62 | /* |
| 54 | * The HPFAR can be invalid if the stage 2 fault did not | 63 | * CPUs affected by ARM erratum #834220 may incorrectly report a |
| 55 | * happen during a stage 1 page table walk (the ESR_EL2.S1PTW | 64 | * stage-2 translation fault when a stage-1 permission fault occurs. |
| 56 | * bit is clear) and one of the two following cases are true: | ||
| 57 | * 1. The fault was due to a permission fault | ||
| 58 | * 2. The processor carries errata 834220 | ||
| 59 | * | 65 | * |
| 60 | * Therefore, for all non S1PTW faults where we either have a | 66 | * Re-walk the page tables to determine if a stage-1 fault actually |
| 61 | * permission fault or the errata workaround is enabled, we | 67 | * occurred. |
| 62 | * resolve the IPA using the AT instruction. | ||
| 63 | */ | 68 | */ |
| 64 | if (!(esr & ESR_ELx_S1PTW) && | 69 | if (cpus_have_final_cap(ARM64_WORKAROUND_834220) && |
| 65 | (cpus_have_final_cap(ARM64_WORKAROUND_834220) || | 70 | esr_fsc_is_translation_fault(esr)) |
| 66 | esr_fsc_is_permission_fault(esr))) { | 71 | return false; |
| 67 | if (!__translate_far_to_hpfar(far, &hpfar)) | 72 | |
| 68 | return false; | 73 | if (esr_fsc_is_translation_fault(esr) || esr_fsc_is_access_flag_fault(esr)) |
| 69 | } else { | 74 | return true; |
| 75 | |||
| 76 | if ((esr & ESR_ELx_S1PTW) && esr_fsc_is_permission_fault(esr)) | ||
| 77 | return true; | ||
| 78 | |||
| 79 | return esr_fsc_is_addr_sz_fault(esr); | ||
| 80 | } | ||
| 81 | |||
| 82 | static inline bool __get_fault_info(u64 esr, struct kvm_vcpu_fault_info *fault) | ||
| 83 | { | ||
| 84 | u64 hpfar; | ||
| 85 | |||
| 86 | fault->far_el2 = read_sysreg_el2(SYS_FAR); | ||
| 87 | fault->hpfar_el2 = 0; | ||
| 88 | |||
| 89 | if (__hpfar_valid(esr)) | ||
| 70 | hpfar = read_sysreg(hpfar_el2); | 90 | hpfar = read_sysreg(hpfar_el2); |
| 71 | } | 91 | else if (unlikely(!__fault_safe_to_translate(esr))) |
| 92 | return true; | ||
| 93 | else if (!__translate_far_to_hpfar(fault->far_el2, &hpfar)) | ||
| 94 | return false; | ||
| 72 | 95 | ||
| 73 | fault->far_el2 = far; | 96 | /* |
| 74 | fault->hpfar_el2 = hpfar; | 97 | * Hijack HPFAR_EL2.NS (RES0 in Non-secure) to indicate a valid |
| 98 | * HPFAR value. | ||
| 99 | */ | ||
| 100 | fault->hpfar_el2 = hpfar | HPFAR_EL2_NS; | ||
| 75 | return true; | 101 | return true; |
| 76 | } | 102 | } |
| 77 | 103 | ||
| @@ -235,6 +235,8 @@ static inline void __deactivate_traps_mpam(void) · 234 unmodified lines | |||
| 235 | 235 | ||
| 236 | static inline void __activate_traps_common(struct kvm_vcpu *vcpu) | 236 | static inline void __activate_traps_common(struct kvm_vcpu *vcpu) |
| 237 | { | 237 | { |
| 238 | struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt); | ||
| 239 | |||
| 238 | /* Trap on AArch32 cp15 c15 (impdef sysregs) accesses (EL1 or EL0) */ | 240 | /* Trap on AArch32 cp15 c15 (impdef sysregs) accesses (EL1 or EL0) */ |
| 239 | write_sysreg(1 << 15, hstr_el2); | 241 | write_sysreg(1 << 15, hstr_el2); |
| 240 | 242 | ||
| @@ -245,11 +247,8 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 4 unmodified lines | |||
| 245 | * EL1 instead of being trapped to EL2. | 247 | * EL1 instead of being trapped to EL2. |
| 246 | */ | 248 | */ |
| 247 | if (system_supports_pmuv3()) { | 249 | if (system_supports_pmuv3()) { |
| 248 | struct kvm_cpu_context *hctxt; | ||
| 249 | |||
| 250 | write_sysreg(0, pmselr_el0); | 250 | write_sysreg(0, pmselr_el0); |
| 251 | 251 | ||
| 252 | hctxt = host_data_ptr(host_ctxt); | ||
| 253 | ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0); | 252 | ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0); |
| 254 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); | 253 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); |
| 255 | vcpu_set_flag(vcpu, PMUSERENR_ON_CPU); | 254 | vcpu_set_flag(vcpu, PMUSERENR_ON_CPU); |
| @@ -269,6 +268,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 13 unmodified lines | |||
| 269 | hcrx &= ~clr; | 268 | hcrx &= ~clr; |
| 270 | } | 269 | } |
| 271 | 270 | ||
| 271 | ctxt_sys_reg(hctxt, HCRX_EL2) = read_sysreg_s(SYS_HCRX_EL2); | ||
| 272 | write_sysreg_s(hcrx, SYS_HCRX_EL2); | 272 | write_sysreg_s(hcrx, SYS_HCRX_EL2); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| @@ -278,19 +278,18 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 3 unmodified lines | |||
| 278 | 278 | ||
| 279 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) | 279 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) |
| 280 | { | 280 | { |
| 281 | struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt); | ||
| 282 | |||
| 281 | write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2); | 283 | write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2); |
| 282 | 284 | ||
| 283 | write_sysreg(0, hstr_el2); | 285 | write_sysreg(0, hstr_el2); |
| 284 | if (system_supports_pmuv3()) { | 286 | if (system_supports_pmuv3()) { |
| 285 | struct kvm_cpu_context *hctxt; | ||
| 286 | |||
| 287 | hctxt = host_data_ptr(host_ctxt); | ||
| 288 | write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0); | 287 | write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0); |
| 289 | vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU); | 288 | vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU); |
| 290 | } | 289 | } |
| 291 | 290 | ||
| 292 | if (cpus_have_final_cap(ARM64_HAS_HCX)) | 291 | if (cpus_have_final_cap(ARM64_HAS_HCX)) |
| 293 | write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2); | 292 | write_sysreg_s(ctxt_sys_reg(hctxt, HCRX_EL2), SYS_HCRX_EL2); |
| 294 | 293 | ||
| 295 | __deactivate_traps_hfgxtr(vcpu); | 294 | __deactivate_traps_hfgxtr(vcpu); |
| 296 | __deactivate_traps_mpam(); | 295 | __deactivate_traps_mpam(); |
| @@ -730,10 +730,10 @@ static void do_ffa_version(struct arm_smccc_res *res, · 729 unmodified lines | |||
| 730 | hyp_ffa_version = ffa_req_version; | 730 | hyp_ffa_version = ffa_req_version; |
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | if (hyp_ffa_post_init()) | 733 | if (hyp_ffa_post_init()) { |
| 734 | res->a0 = FFA_RET_NOT_SUPPORTED; | 734 | res->a0 = FFA_RET_NOT_SUPPORTED; |
| 735 | else { | 735 | } else { |
| 736 | has_version_negotiated = true; | 736 | smp_store_release(&has_version_negotiated, true); |
| 737 | res->a0 = hyp_ffa_version; | 737 | res->a0 = hyp_ffa_version; |
| 738 | } | 738 | } |
| 739 | unlock: | 739 | unlock: |
| @@ -809,7 +809,8 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) · 69 unmodified lines | |||
| 809 | if (!is_ffa_call(func_id)) | 809 | if (!is_ffa_call(func_id)) |
| 810 | return false; | 810 | return false; |
| 811 | 811 | ||
| 812 | if (!has_version_negotiated && func_id != FFA_VERSION) { | 812 | if (func_id != FFA_VERSION && |
| 813 | !smp_load_acquire(&has_version_negotiated)) { | ||
| 813 | ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS); | 814 | ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS); |
| 814 | goto out_handled; | 815 | goto out_handled; |
| 815 | } | 816 | } |
| @@ -503,7 +503,7 @@ int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) · 502 unmodified lines | |||
| 503 | { | 503 | { |
| 504 | int ret; | 504 | int ret; |
| 505 | 505 | ||
| 506 | if (!addr_is_memory(addr)) | 506 | if (!range_is_memory(addr, addr + size)) |
| 507 | return -EPERM; | 507 | return -EPERM; |
| 508 | 508 | ||
| 509 | ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt, | 509 | ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt, |
| @@ -578,7 +578,14 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) · 68 unmodified lines | |||
| 578 | return; | 578 | return; |
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | addr = (fault.hpfar_el2 & HPFAR_MASK) << 8; | 581 | |
| 582 | /* | ||
| 583 | * Yikes, we couldn't resolve the fault IPA. This should reinject an | ||
| 584 | * abort into the host when we figure out how to do that. | ||
| 585 | */ | ||
| 586 | BUG_ON(!(fault.hpfar_el2 & HPFAR_EL2_NS)); | ||
| 587 | addr = FIELD_GET(HPFAR_EL2_FIPA, fault.hpfar_el2) << 12; | ||
| 588 | |||
| 582 | ret = host_stage2_idmap(addr); | 589 | ret = host_stage2_idmap(addr); |
| 583 | BUG_ON(ret && ret != -EAGAIN); | 590 | BUG_ON(ret && ret != -EAGAIN); |
| 584 | } | 591 | } |
| @@ -429,23 +429,27 @@ u64 __vgic_v3_get_gic_config(void) · 428 unmodified lines | |||
| 429 | /* | 429 | /* |
| 430 | * To check whether we have a MMIO-based (GICv2 compatible) | 430 | * To check whether we have a MMIO-based (GICv2 compatible) |
| 431 | * CPU interface, we need to disable the system register | 431 | * CPU interface, we need to disable the system register |
| 432 | * view. To do that safely, we have to prevent any interrupt | 432 | * view. |
| 433 | * from firing (which would be deadly). | ||
| 434 | * | 433 | * |
| 435 | * Note that this only makes sense on VHE, as interrupts are | ||
| 436 | * already masked for nVHE as part of the exception entry to | ||
| 437 | * EL2. | ||
| 438 | */ | ||
| 439 | if (has_vhe()) | ||
| 440 | flags = local_daif_save(); | ||
| 441 | |||
| 442 | /* | ||
| 443 | * Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates | 434 | * Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates |
| 444 | * that to be able to set ICC_SRE_EL1.SRE to 0, all the | 435 | * that to be able to set ICC_SRE_EL1.SRE to 0, all the |
| 445 | * interrupt overrides must be set. You've got to love this. | 436 | * interrupt overrides must be set. You've got to love this. |
| 437 | * | ||
| 438 | * As we always run VHE with HCR_xMO set, no extra xMO | ||
| 439 | * manipulation is required in that case. | ||
| 440 | * | ||
| 441 | * To safely disable SRE, we have to prevent any interrupt | ||
| 442 | * from firing (which would be deadly). This only makes sense | ||
| 443 | * on VHE, as interrupts are already masked for nVHE as part | ||
| 444 | * of the exception entry to EL2. | ||
| 446 | */ | 445 | */ |
| 447 | sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO); | 446 | if (has_vhe()) { |
| 448 | isb(); | 447 | flags = local_daif_save(); |
| 448 | } else { | ||
| 449 | sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO); | ||
| 450 | isb(); | ||
| 451 | } | ||
| 452 | |||
| 449 | write_gicreg(0, ICC_SRE_EL1); | 453 | write_gicreg(0, ICC_SRE_EL1); |
| 450 | isb(); | 454 | isb(); |
| 451 | 455 | ||
| @@ -453,11 +457,13 @@ u64 __vgic_v3_get_gic_config(void) · 1 unmodified line | |||
| 453 | 457 | ||
| 454 | write_gicreg(sre, ICC_SRE_EL1); | 458 | write_gicreg(sre, ICC_SRE_EL1); |
| 455 | isb(); | 459 | isb(); |
| 456 | sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0); | ||
| 457 | isb(); | ||
| 458 | 460 | ||
| 459 | if (has_vhe()) | 461 | if (has_vhe()) { |
| 460 | local_daif_restore(flags); | 462 | local_daif_restore(flags); |
| 463 | } else { | ||
| 464 | sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0); | ||
| 465 | isb(); | ||
| 466 | } | ||
| 461 | 467 | ||
| 462 | val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63); | 468 | val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63); |
| 463 | val |= read_gicreg(ICH_VTR_EL2); | 469 | val |= read_gicreg(ICH_VTR_EL2); |
| @@ -1501,6 +1501,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, · 1500 unmodified lines | |||
| 1501 | return -EFAULT; | 1501 | return -EFAULT; |
| 1502 | } | 1502 | } |
| 1503 | 1503 | ||
| 1504 | if (!is_protected_kvm_enabled()) | ||
| 1505 | memcache = &vcpu->arch.mmu_page_cache; | ||
| 1506 | else | ||
| 1507 | memcache = &vcpu->arch.pkvm_memcache; | ||
| 1508 | |||
| 1504 | /* | 1509 | /* |
| 1505 | * Permission faults just need to update the existing leaf entry, | 1510 | * Permission faults just need to update the existing leaf entry, |
| 1506 | * and so normally don't require allocations from the memcache. The | 1511 | * and so normally don't require allocations from the memcache. The |
| @@ -1510,13 +1515,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, · 3 unmodified lines | |||
| 1510 | if (!fault_is_perm || (logging_active && write_fault)) { | 1515 | if (!fault_is_perm || (logging_active && write_fault)) { |
| 1511 | int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu); | 1516 | int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu); |
| 1512 | 1517 | ||
| 1513 | if (!is_protected_kvm_enabled()) { | 1518 | if (!is_protected_kvm_enabled()) |
| 1514 | memcache = &vcpu->arch.mmu_page_cache; | ||
| 1515 | ret = kvm_mmu_topup_memory_cache(memcache, min_pages); | 1519 | ret = kvm_mmu_topup_memory_cache(memcache, min_pages); |
| 1516 | } else { | 1520 | else |
| 1517 | memcache = &vcpu->arch.pkvm_memcache; | ||
| 1518 | ret = topup_hyp_memcache(memcache, min_pages); | 1521 | ret = topup_hyp_memcache(memcache, min_pages); |
| 1519 | } | 1522 | |
| 1520 | if (ret) | 1523 | if (ret) |
| 1521 | return ret; | 1524 | return ret; |
| 1522 | } | 1525 | } |
| @@ -1794,9 +1797,28 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) · 271 unmodified lines | |||
| 1794 | gfn_t gfn; | 1797 | gfn_t gfn; |
| 1795 | int ret, idx; | 1798 | int ret, idx; |
| 1796 | 1799 | ||
| 1800 | /* Synchronous External Abort? */ | ||
| 1801 | if (kvm_vcpu_abt_issea(vcpu)) { | ||
| 1802 | /* | ||
| 1803 | * For RAS the host kernel may handle this abort. | ||
| 1804 | * There is no need to pass the error into the guest. | ||
| 1805 | */ | ||
| 1806 | if (kvm_handle_guest_sea()) | ||
| 1807 | kvm_inject_vabt(vcpu); | ||
| 1808 | |||
| 1809 | return 1; | ||
| 1810 | } | ||
| 1811 | |||
| 1797 | esr = kvm_vcpu_get_esr(vcpu); | 1812 | esr = kvm_vcpu_get_esr(vcpu); |
| 1798 | 1813 | ||
| 1814 | /* | ||
| 1815 | * The fault IPA should be reliable at this point as we're not dealing | ||
| 1816 | * with an SEA. | ||
| 1817 | */ | ||
| 1799 | ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); | 1818 | ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); |
| 1819 | if (KVM_BUG_ON(ipa == INVALID_GPA, vcpu->kvm)) | ||
| 1820 | return -EFAULT; | ||
| 1821 | |||
| 1800 | is_iabt = kvm_vcpu_trap_is_iabt(vcpu); | 1822 | is_iabt = kvm_vcpu_trap_is_iabt(vcpu); |
| 1801 | 1823 | ||
| 1802 | if (esr_fsc_is_translation_fault(esr)) { | 1824 | if (esr_fsc_is_translation_fault(esr)) { |
| @@ -1818,18 +1840,6 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) · 15 unmodified lines | |||
| 1818 | } | 1840 | } |
| 1819 | } | 1841 | } |
| 1820 | 1842 | ||
| 1821 | /* Synchronous External Abort? */ | ||
| 1822 | if (kvm_vcpu_abt_issea(vcpu)) { | ||
| 1823 | /* | ||
| 1824 | * For RAS the host kernel may handle this abort. | ||
| 1825 | * There is no need to pass the error into the guest. | ||
| 1826 | */ | ||
| 1827 | if (kvm_handle_guest_sea(fault_ipa, kvm_vcpu_get_esr(vcpu))) | ||
| 1828 | kvm_inject_vabt(vcpu); | ||
| 1829 | |||
| 1830 | return 1; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu), | 1843 | trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu), |
| 1834 | kvm_vcpu_get_hfar(vcpu), fault_ipa); | 1844 | kvm_vcpu_get_hfar(vcpu), fault_ipa); |
| 1835 | 1845 | ||
| @@ -1945,6 +1945,12 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, · 1944 unmodified lines | |||
| 1945 | if ((hw_val & mpam_mask) == (user_val & mpam_mask)) | 1945 | if ((hw_val & mpam_mask) == (user_val & mpam_mask)) |
| 1946 | user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK; | 1946 | user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK; |
| 1947 | 1947 | ||
| 1948 | /* Fail the guest's request to disable the AA64 ISA at EL{0,1,2} */ | ||
| 1949 | if (!FIELD_GET(ID_AA64PFR0_EL1_EL0, user_val) || | ||
| 1950 | !FIELD_GET(ID_AA64PFR0_EL1_EL1, user_val) || | ||
| 1951 | (vcpu_has_nv(vcpu) && !FIELD_GET(ID_AA64PFR0_EL1_EL2, user_val))) | ||
| 1952 | return -EINVAL; | ||
| 1953 | |||
| 1948 | return set_id_reg(vcpu, rd, user_val); | 1954 | return set_id_reg(vcpu, rd, user_val); |
| 1949 | } | 1955 | } |
| 1950 | 1956 | ||
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> | 6 | * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> |
| 7 | */ | 7 | */ |
| 8 | #include <linux/bitfield.h> | ||
| 8 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
| 9 | #include <linux/bug.h> | 10 | #include <linux/bug.h> |
| 10 | #include <linux/printk.h> | 11 | #include <linux/printk.h> |
| @@ -1500,43 +1501,41 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant, · 1489 unmodified lines | |||
| 1500 | return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm); | 1501 | return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm); |
| 1501 | } | 1502 | } |
| 1502 | 1503 | ||
| 1503 | u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type) | 1504 | static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type) |
| 1504 | { | 1505 | { |
| 1505 | u32 opt; | ||
| 1506 | u32 insn; | ||
| 1507 | |||
| 1508 | switch (type) { | 1506 | switch (type) { |
| 1509 | case AARCH64_INSN_MB_SY: | 1507 | case AARCH64_INSN_MB_SY: |
| 1510 | opt = 0xf; | 1508 | return 0xf; |
| 1511 | break; | ||
| 1512 | case AARCH64_INSN_MB_ST: | 1509 | case AARCH64_INSN_MB_ST: |
| 1513 | opt = 0xe; | 1510 | return 0xe; |
| 1514 | break; | ||
| 1515 | case AARCH64_INSN_MB_LD: | 1511 | case AARCH64_INSN_MB_LD: |
| 1516 | opt = 0xd; | 1512 | return 0xd; |
| 1517 | break; | ||
| 1518 | case AARCH64_INSN_MB_ISH: | 1513 | case AARCH64_INSN_MB_ISH: |
| 1519 | opt = 0xb; | 1514 | return 0xb; |
| 1520 | break; | ||
| 1521 | case AARCH64_INSN_MB_ISHST: | 1515 | case AARCH64_INSN_MB_ISHST: |
| 1522 | opt = 0xa; | 1516 | return 0xa; |
| 1523 | break; | ||
| 1524 | case AARCH64_INSN_MB_ISHLD: | 1517 | case AARCH64_INSN_MB_ISHLD: |
| 1525 | opt = 0x9; | 1518 | return 0x9; |
| 1526 | break; | ||
| 1527 | case AARCH64_INSN_MB_NSH: | 1519 | case AARCH64_INSN_MB_NSH: |
| 1528 | opt = 0x7; | 1520 | return 0x7; |
| 1529 | break; | ||
| 1530 | case AARCH64_INSN_MB_NSHST: | 1521 | case AARCH64_INSN_MB_NSHST: |
| 1531 | opt = 0x6; | 1522 | return 0x6; |
| 1532 | break; | ||
| 1533 | case AARCH64_INSN_MB_NSHLD: | 1523 | case AARCH64_INSN_MB_NSHLD: |
| 1534 | opt = 0x5; | 1524 | return 0x5; |
| 1535 | break; | ||
| 1536 | default: | 1525 | default: |
| 1537 | pr_err("%s: unknown dmb type %d\n", __func__, type); | 1526 | pr_err("%s: unknown barrier type %d\n", __func__, type); |
| 1538 | return AARCH64_BREAK_FAULT; | 1527 | return AARCH64_BREAK_FAULT; |
| 1539 | } | 1528 | } |
| 1529 | } | ||
| 1530 | |||
| 1531 | u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type) | ||
| 1532 | { | ||
| 1533 | u32 opt; | ||
| 1534 | u32 insn; | ||
| 1535 | |||
| 1536 | opt = __get_barrier_crm_val(type); | ||
| 1537 | if (opt == AARCH64_BREAK_FAULT) | ||
| 1538 | return AARCH64_BREAK_FAULT; | ||
| 1540 | 1539 | ||
| 1541 | insn = aarch64_insn_get_dmb_value(); | 1540 | insn = aarch64_insn_get_dmb_value(); |
| 1542 | insn &= ~GENMASK(11, 8); | 1541 | insn &= ~GENMASK(11, 8); |
| @@ -1545,6 +1544,21 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type) · 2 unmodified lines | |||
| 1545 | return insn; | 1544 | return insn; |
| 1546 | } | 1545 | } |
| 1547 | 1546 | ||
| 1547 | u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type) | ||
| 1548 | { | ||
| 1549 | u32 opt, insn; | ||
| 1550 | |||
| 1551 | opt = __get_barrier_crm_val(type); | ||
| 1552 | if (opt == AARCH64_BREAK_FAULT) | ||
| 1553 | return AARCH64_BREAK_FAULT; | ||
| 1554 | |||
| 1555 | insn = aarch64_insn_get_dsb_base_value(); | ||
| 1556 | insn &= ~GENMASK(11, 8); | ||
| 1557 | insn |= (opt << 8); | ||
| 1558 | |||
| 1559 | return insn; | ||
| 1560 | } | ||
| 1561 | |||
| 1548 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, | 1562 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, |
| 1549 | enum aarch64_insn_system_register sysreg) | 1563 | enum aarch64_insn_system_register sysreg) |
| 1550 | { | 1564 | { |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #define pr_fmt(fmt) "bpf_jit: " fmt | 8 | #define pr_fmt(fmt) "bpf_jit: " fmt |
| 9 | 9 | ||
| 10 | #include <linux/arm-smccc.h> | ||
| 10 | #include <linux/bitfield.h> | 11 | #include <linux/bitfield.h> |
| 11 | #include <linux/bpf.h> | 12 | #include <linux/bpf.h> |
| 12 | #include <linux/filter.h> | 13 | #include <linux/filter.h> |
| @@ -17,6 +18,7 @@ · 4 unmodified lines | |||
| 17 | #include <asm/asm-extable.h> | 18 | #include <asm/asm-extable.h> |
| 18 | #include <asm/byteorder.h> | 19 | #include <asm/byteorder.h> |
| 19 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
| 21 | #include <asm/cpufeature.h> | ||
| 20 | #include <asm/debug-monitors.h> | 22 | #include <asm/debug-monitors.h> |
| 21 | #include <asm/insn.h> | 23 | #include <asm/insn.h> |
| 22 | #include <asm/text-patching.h> | 24 | #include <asm/text-patching.h> |
| @@ -939,7 +941,51 @@ static void build_plt(struct jit_ctx *ctx) · 916 unmodified lines | |||
| 939 | plt->target = (u64)&dummy_tramp; | 941 | plt->target = (u64)&dummy_tramp; |
| 940 | } | 942 | } |
| 941 | 943 | ||
| 942 | static void build_epilogue(struct jit_ctx *ctx) | 944 | /* Clobbers BPF registers 1-4, aka x0-x3 */ |
| 945 | static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) | ||
| 946 | { | ||
| 947 | const u8 r1 = bpf2a64[BPF_REG_1]; /* aka x0 */ | ||
| 948 | u8 k = get_spectre_bhb_loop_value(); | ||
| 949 | |||
| 950 | if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY) || | ||
| 951 | cpu_mitigations_off() || __nospectre_bhb || | ||
| 952 | arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) | ||
| 953 | return; | ||
| 954 | |||
| 955 | if (capable(CAP_SYS_ADMIN)) | ||
| 956 | return; | ||
| 957 | |||
| 958 | if (supports_clearbhb(SCOPE_SYSTEM)) { | ||
| 959 | emit(aarch64_insn_gen_hint(AARCH64_INSN_HINT_CLEARBHB), ctx); | ||
| 960 | return; | ||
| 961 | } | ||
| 962 | |||
| 963 | if (k) { | ||
| 964 | emit_a64_mov_i64(r1, k, ctx); | ||
| 965 | emit(A64_B(1), ctx); | ||
| 966 | emit(A64_SUBS_I(true, r1, r1, 1), ctx); | ||
| 967 | emit(A64_B_(A64_COND_NE, -2), ctx); | ||
| 968 | emit(aarch64_insn_gen_dsb(AARCH64_INSN_MB_ISH), ctx); | ||
| 969 | emit(aarch64_insn_get_isb_value(), ctx); | ||
| 970 | } | ||
| 971 | |||
| 972 | if (is_spectre_bhb_fw_mitigated()) { | ||
| 973 | emit(A64_ORR_I(false, r1, AARCH64_INSN_REG_ZR, | ||
| 974 | ARM_SMCCC_ARCH_WORKAROUND_3), ctx); | ||
| 975 | switch (arm_smccc_1_1_get_conduit()) { | ||
| 976 | case SMCCC_CONDUIT_HVC: | ||
| 977 | emit(aarch64_insn_get_hvc_value(), ctx); | ||
| 978 | break; | ||
| 979 | case SMCCC_CONDUIT_SMC: | ||
| 980 | emit(aarch64_insn_get_smc_value(), ctx); | ||
| 981 | break; | ||
| 982 | default: | ||
| 983 | pr_err_once("Firmware mitigation enabled with unknown conduit\n"); | ||
| 984 | } | ||
| 985 | } | ||
| 986 | } | ||
| 987 | |||
| 988 | static void build_epilogue(struct jit_ctx *ctx, bool was_classic) | ||
| 943 | { | 989 | { |
| 944 | const u8 r0 = bpf2a64[BPF_REG_0]; | 990 | const u8 r0 = bpf2a64[BPF_REG_0]; |
| 945 | const u8 ptr = bpf2a64[TCCNT_PTR]; | 991 | const u8 ptr = bpf2a64[TCCNT_PTR]; |
| @@ -952,10 +998,13 @@ static void build_epilogue(struct jit_ctx *ctx) · 6 unmodified lines | |||
| 952 | 998 | ||
| 953 | emit(A64_POP(A64_ZR, ptr, A64_SP), ctx); | 999 | emit(A64_POP(A64_ZR, ptr, A64_SP), ctx); |
| 954 | 1000 | ||
| 1001 | if (was_classic) | ||
| 1002 | build_bhb_mitigation(ctx); | ||
| 1003 | |||
| 955 | /* Restore FP/LR registers */ | 1004 | /* Restore FP/LR registers */ |
| 956 | emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx); | 1005 | emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx); |
| 957 | 1006 | ||
| 958 | /* Set return value */ | 1007 | /* Move the return value from bpf:r0 (aka x7) to x0 */ |
| 959 | emit(A64_MOV(1, A64_R(0), r0), ctx); | 1008 | emit(A64_MOV(1, A64_R(0), r0), ctx); |
| 960 | 1009 | ||
| 961 | /* Authenticate lr */ | 1010 | /* Authenticate lr */ |
| @@ -1898,7 +1947,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 936 unmodified lines | |||
| 1898 | } | 1947 | } |
| 1899 | 1948 | ||
| 1900 | ctx.epilogue_offset = ctx.idx; | 1949 | ctx.epilogue_offset = ctx.idx; |
| 1901 | build_epilogue(&ctx); | 1950 | build_epilogue(&ctx, was_classic); |
| 1902 | build_plt(&ctx); | 1951 | build_plt(&ctx); |
| 1903 | 1952 | ||
| 1904 | extable_align = __alignof__(struct exception_table_entry); | 1953 | extable_align = __alignof__(struct exception_table_entry); |
| @@ -1961,7 +2010,7 @@ skip_init_ctx: · 56 unmodified lines | |||
| 1961 | goto out_free_hdr; | 2010 | goto out_free_hdr; |
| 1962 | } | 2011 | } |
| 1963 | 2012 | ||
| 1964 | build_epilogue(&ctx); | 2013 | build_epilogue(&ctx, was_classic); |
| 1965 | build_plt(&ctx); | 2014 | build_plt(&ctx); |
| 1966 | 2015 | ||
| 1967 | /* Extra pass to validate JITed code. */ | 2016 | /* Extra pass to validate JITed code. */ |
| @@ -3536,3 +3536,10 @@ Field 5 F · 3535 unmodified lines | |||
| 3536 | Field 4 P | 3536 | Field 4 P |
| 3537 | Field 3:0 Align | 3537 | Field 3:0 Align |
| 3538 | EndSysreg | 3538 | EndSysreg |
| 3539 | |||
| 3540 | Sysreg HPFAR_EL2 3 4 6 0 4 | ||
| 3541 | Field 63 NS | ||
| 3542 | Res0 62:48 | ||
| 3543 | Field 47:4 FIPA | ||
| 3544 | Res0 3:0 | ||
| 3545 | EndSysreg | ||
| @@ -72,9 +72,6 @@ CONFIG_INET=y · 71 unmodified lines | |||
| 72 | CONFIG_CRYPTO_MD5=y | 72 | CONFIG_CRYPTO_MD5=y |
| 73 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 73 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 74 | # CONFIG_CRYPTO_HW is not set | 74 | # CONFIG_CRYPTO_HW is not set |
| 75 | CONFIG_CRC_CCITT=y | ||
| 76 | CONFIG_CRC16=y | ||
| 77 | CONFIG_CRC_T10DIF=y | ||
| 78 | CONFIG_FRAME_WARN=0 | 75 | CONFIG_FRAME_WARN=0 |
| 79 | CONFIG_MAGIC_SYSRQ=y | 76 | CONFIG_MAGIC_SYSRQ=y |
| 80 | CONFIG_DEBUG_FS=y | 77 | CONFIG_DEBUG_FS=y |
| @@ -73,6 +73,7 @@ config LOONGARCH · 72 unmodified lines | |||
| 73 | select ARCH_SUPPORTS_RT | 73 | select ARCH_SUPPORTS_RT |
| 74 | select ARCH_USE_BUILTIN_BSWAP | 74 | select ARCH_USE_BUILTIN_BSWAP |
| 75 | select ARCH_USE_CMPXCHG_LOCKREF | 75 | select ARCH_USE_CMPXCHG_LOCKREF |
| 76 | select ARCH_USE_MEMTEST | ||
| 76 | select ARCH_USE_QUEUED_RWLOCKS | 77 | select ARCH_USE_QUEUED_RWLOCKS |
| 77 | select ARCH_USE_QUEUED_SPINLOCKS | 78 | select ARCH_USE_QUEUED_SPINLOCKS |
| 78 | select ARCH_WANT_DEFAULT_BPF_JIT | 79 | select ARCH_WANT_DEFAULT_BPF_JIT |
| @@ -22,22 +22,29 @@ · 21 unmodified lines | |||
| 22 | struct sigcontext; | 22 | struct sigcontext; |
| 23 | 23 | ||
| 24 | #define kernel_fpu_available() cpu_has_fpu | 24 | #define kernel_fpu_available() cpu_has_fpu |
| 25 | extern void kernel_fpu_begin(void); | 25 | |
| 26 | extern void kernel_fpu_end(void); | 26 | void kernel_fpu_begin(void); |
| 27 | 27 | void kernel_fpu_end(void); | |
| 28 | extern void _init_fpu(unsigned int); | 28 | |
| 29 | extern void _save_fp(struct loongarch_fpu *); | 29 | asmlinkage void _init_fpu(unsigned int); |
| 30 | extern void _restore_fp(struct loongarch_fpu *); | 30 | asmlinkage void _save_fp(struct loongarch_fpu *); |
| 31 | 31 | asmlinkage void _restore_fp(struct loongarch_fpu *); | |
| 32 | extern void _save_lsx(struct loongarch_fpu *fpu); | 32 | asmlinkage int _save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); |
| 33 | extern void _restore_lsx(struct loongarch_fpu *fpu); | 33 | asmlinkage int _restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); |
| 34 | extern void _init_lsx_upper(void); | 34 | |
| 35 | extern void _restore_lsx_upper(struct loongarch_fpu *fpu); | 35 | asmlinkage void _save_lsx(struct loongarch_fpu *fpu); |
| 36 | 36 | asmlinkage void _restore_lsx(struct loongarch_fpu *fpu); | |
| 37 | extern void _save_lasx(struct loongarch_fpu *fpu); | 37 | asmlinkage void _init_lsx_upper(void); |
| 38 | extern void _restore_lasx(struct loongarch_fpu *fpu); | 38 | asmlinkage void _restore_lsx_upper(struct loongarch_fpu *fpu); |
| 39 | extern void _init_lasx_upper(void); | 39 | asmlinkage int _save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); |
| 40 | extern void _restore_lasx_upper(struct loongarch_fpu *fpu); | 40 | asmlinkage int _restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); |
| 41 | |||
| 42 | asmlinkage void _save_lasx(struct loongarch_fpu *fpu); | ||
| 43 | asmlinkage void _restore_lasx(struct loongarch_fpu *fpu); | ||
| 44 | asmlinkage void _init_lasx_upper(void); | ||
| 45 | asmlinkage void _restore_lasx_upper(struct loongarch_fpu *fpu); | ||
| 46 | asmlinkage int _save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 47 | asmlinkage int _restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 41 | 48 | ||
| 42 | static inline void enable_lsx(void); | 49 | static inline void enable_lsx(void); |
| 43 | static inline void disable_lsx(void); | 50 | static inline void disable_lsx(void); |
| @@ -12,9 +12,13 @@ · 11 unmodified lines | |||
| 12 | #include <asm/loongarch.h> | 12 | #include <asm/loongarch.h> |
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | 14 | ||
| 15 | extern void _init_lbt(void); | 15 | asmlinkage void _init_lbt(void); |
| 16 | extern void _save_lbt(struct loongarch_lbt *); | 16 | asmlinkage void _save_lbt(struct loongarch_lbt *); |
| 17 | extern void _restore_lbt(struct loongarch_lbt *); | 17 | asmlinkage void _restore_lbt(struct loongarch_lbt *); |
| 18 | asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags); | ||
| 19 | asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags); | ||
| 20 | asmlinkage int _save_ftop_context(void __user *ftop); | ||
| 21 | asmlinkage int _restore_ftop_context(void __user *ftop); | ||
| 18 | 22 | ||
| 19 | static inline int is_lbt_enabled(void) | 23 | static inline int is_lbt_enabled(void) |
| 20 | { | 24 | { |
| @@ -33,9 +33,9 @@ struct pt_regs { · 32 unmodified lines | |||
| 33 | unsigned long __last[]; | 33 | unsigned long __last[]; |
| 34 | } __aligned(8); | 34 | } __aligned(8); |
| 35 | 35 | ||
| 36 | static inline int regs_irqs_disabled(struct pt_regs *regs) | 36 | static __always_inline bool regs_irqs_disabled(struct pt_regs *regs) |
| 37 | { | 37 | { |
| 38 | return arch_irqs_disabled_flags(regs->csr_prmd); | 38 | return !(regs->csr_prmd & CSR_PRMD_PIE); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | 41 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
| @@ -55,7 +55,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long v · 13 unmodified lines | |||
| 55 | 55 | ||
| 56 | /* Query offset/name of register from its name/offset */ | 56 | /* Query offset/name of register from its name/offset */ |
| 57 | extern int regs_query_register_offset(const char *name); | 57 | extern int regs_query_register_offset(const char *name); |
| 58 | #define MAX_REG_OFFSET (offsetof(struct pt_regs, __last)) | 58 | #define MAX_REG_OFFSET (offsetof(struct pt_regs, __last) - sizeof(unsigned long)) |
| 59 | 59 | ||
| 60 | /** | 60 | /** |
| 61 | * regs_get_register() - get register value from its offset | 61 | * regs_get_register() - get register value from its offset |
| @@ -15,7 +15,6 @@ typedef u32 uprobe_opcode_t; · 14 unmodified lines | |||
| 15 | #define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP) | 15 | #define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP) |
| 16 | 16 | ||
| 17 | struct arch_uprobe { | 17 | struct arch_uprobe { |
| 18 | unsigned long resume_era; | ||
| 19 | u32 insn[2]; | 18 | u32 insn[2]; |
| 20 | u32 ixol[2]; | 19 | u32 ixol[2]; |
| 21 | bool simulate; | 20 | bool simulate; |
| @@ -21,10 +21,10 @@ obj-$(CONFIG_CPU_HAS_LBT) += lbt.o · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o | 22 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o |
| 23 | 23 | ||
| 24 | CFLAGS_module.o += $(call cc-option,-Wno-override-init,) | 24 | CFLAGS_module.o += $(call cc-disable-warning, override-init) |
| 25 | CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,) | 25 | CFLAGS_syscall.o += $(call cc-disable-warning, override-init) |
| 26 | CFLAGS_traps.o += $(call cc-option,-Wno-override-init,) | 26 | CFLAGS_traps.o += $(call cc-disable-warning, override-init) |
| 27 | CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,) | 27 | CFLAGS_perf_event.o += $(call cc-disable-warning, override-init) |
| 28 | 28 | ||
| 29 | ifdef CONFIG_FUNCTION_TRACER | 29 | ifdef CONFIG_FUNCTION_TRACER |
| 30 | ifndef CONFIG_DYNAMIC_FTRACE | 30 | ifndef CONFIG_DYNAMIC_FTRACE |
| @@ -458,6 +458,7 @@ SYM_FUNC_START(_save_fp_context) · 457 unmodified lines | |||
| 458 | li.w a0, 0 # success | 458 | li.w a0, 0 # success |
| 459 | jr ra | 459 | jr ra |
| 460 | SYM_FUNC_END(_save_fp_context) | 460 | SYM_FUNC_END(_save_fp_context) |
| 461 | EXPORT_SYMBOL_GPL(_save_fp_context) | ||
| 461 | 462 | ||
| 462 | /* | 463 | /* |
| 463 | * a0: fpregs | 464 | * a0: fpregs |
| @@ -471,6 +472,7 @@ SYM_FUNC_START(_restore_fp_context) · 7 unmodified lines | |||
| 471 | li.w a0, 0 # success | 472 | li.w a0, 0 # success |
| 472 | jr ra | 473 | jr ra |
| 473 | SYM_FUNC_END(_restore_fp_context) | 474 | SYM_FUNC_END(_restore_fp_context) |
| 475 | EXPORT_SYMBOL_GPL(_restore_fp_context) | ||
| 474 | 476 | ||
| 475 | /* | 477 | /* |
| 476 | * a0: fpregs | 478 | * a0: fpregs |
| @@ -484,6 +486,7 @@ SYM_FUNC_START(_save_lsx_context) · 7 unmodified lines | |||
| 484 | li.w a0, 0 # success | 486 | li.w a0, 0 # success |
| 485 | jr ra | 487 | jr ra |
| 486 | SYM_FUNC_END(_save_lsx_context) | 488 | SYM_FUNC_END(_save_lsx_context) |
| 489 | EXPORT_SYMBOL_GPL(_save_lsx_context) | ||
| 487 | 490 | ||
| 488 | /* | 491 | /* |
| 489 | * a0: fpregs | 492 | * a0: fpregs |
| @@ -497,6 +500,7 @@ SYM_FUNC_START(_restore_lsx_context) · 7 unmodified lines | |||
| 497 | li.w a0, 0 # success | 500 | li.w a0, 0 # success |
| 498 | jr ra | 501 | jr ra |
| 499 | SYM_FUNC_END(_restore_lsx_context) | 502 | SYM_FUNC_END(_restore_lsx_context) |
| 503 | EXPORT_SYMBOL_GPL(_restore_lsx_context) | ||
| 500 | 504 | ||
| 501 | /* | 505 | /* |
| 502 | * a0: fpregs | 506 | * a0: fpregs |
| @@ -510,6 +514,7 @@ SYM_FUNC_START(_save_lasx_context) · 7 unmodified lines | |||
| 510 | li.w a0, 0 # success | 514 | li.w a0, 0 # success |
| 511 | jr ra | 515 | jr ra |
| 512 | SYM_FUNC_END(_save_lasx_context) | 516 | SYM_FUNC_END(_save_lasx_context) |
| 517 | EXPORT_SYMBOL_GPL(_save_lasx_context) | ||
| 513 | 518 | ||
| 514 | /* | 519 | /* |
| 515 | * a0: fpregs | 520 | * a0: fpregs |
| @@ -523,6 +528,7 @@ SYM_FUNC_START(_restore_lasx_context) · 7 unmodified lines | |||
| 523 | li.w a0, 0 # success | 528 | li.w a0, 0 # success |
| 524 | jr ra | 529 | jr ra |
| 525 | SYM_FUNC_END(_restore_lasx_context) | 530 | SYM_FUNC_END(_restore_lasx_context) |
| 531 | EXPORT_SYMBOL_GPL(_restore_lasx_context) | ||
| 526 | 532 | ||
| 527 | .L_fpu_fault: | 533 | .L_fpu_fault: |
| 528 | li.w a0, -EFAULT # failure | 534 | li.w a0, -EFAULT # failure |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <asm/stackframe.h> | 16 | #include <asm/stackframe.h> |
| 17 | #include <asm/thread_info.h> | 17 | #include <asm/thread_info.h> |
| 18 | 18 | ||
| 19 | .section .cpuidle.text, "ax" | ||
| 19 | .align 5 | 20 | .align 5 |
| 20 | SYM_FUNC_START(__arch_cpu_idle) | 21 | SYM_FUNC_START(__arch_cpu_idle) |
| 21 | /* start of idle interrupt region */ | 22 | /* start of idle interrupt region */ |
| @@ -31,14 +32,16 @@ SYM_FUNC_START(__arch_cpu_idle) · 9 unmodified lines | |||
| 31 | */ | 32 | */ |
| 32 | idle 0 | 33 | idle 0 |
| 33 | /* end of idle interrupt region */ | 34 | /* end of idle interrupt region */ |
| 34 | 1: jr ra | 35 | idle_exit: |
| 36 | jr ra | ||
| 35 | SYM_FUNC_END(__arch_cpu_idle) | 37 | SYM_FUNC_END(__arch_cpu_idle) |
| 38 | .previous | ||
| 36 | 39 | ||
| 37 | SYM_CODE_START(handle_vint) | 40 | SYM_CODE_START(handle_vint) |
| 38 | UNWIND_HINT_UNDEFINED | 41 | UNWIND_HINT_UNDEFINED |
| 39 | BACKUP_T0T1 | 42 | BACKUP_T0T1 |
| 40 | SAVE_ALL | 43 | SAVE_ALL |
| 41 | la_abs t1, 1b | 44 | la_abs t1, idle_exit |
| 42 | LONG_L t0, sp, PT_ERA | 45 | LONG_L t0, sp, PT_ERA |
| 43 | /* 3 instructions idle interrupt region */ | 46 | /* 3 instructions idle interrupt region */ |
| 44 | ori t0, t0, 0b1100 | 47 | ori t0, t0, 0b1100 |
| @@ -18,11 +18,28 @@ static unsigned int euen_mask = CSR_EUEN_FPEN; · 17 unmodified lines | |||
| 18 | static DEFINE_PER_CPU(bool, in_kernel_fpu); | 18 | static DEFINE_PER_CPU(bool, in_kernel_fpu); |
| 19 | static DEFINE_PER_CPU(unsigned int, euen_current); | 19 | static DEFINE_PER_CPU(unsigned int, euen_current); |
| 20 | 20 | ||
| 21 | static inline void fpregs_lock(void) | ||
| 22 | { | ||
| 23 | if (IS_ENABLED(CONFIG_PREEMPT_RT)) | ||
| 24 | preempt_disable(); | ||
| 25 | else | ||
| 26 | local_bh_disable(); | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline void fpregs_unlock(void) | ||
| 30 | { | ||
| 31 | if (IS_ENABLED(CONFIG_PREEMPT_RT)) | ||
| 32 | preempt_enable(); | ||
| 33 | else | ||
| 34 | local_bh_enable(); | ||
| 35 | } | ||
| 36 | |||
| 21 | void kernel_fpu_begin(void) | 37 | void kernel_fpu_begin(void) |
| 22 | { | 38 | { |
| 23 | unsigned int *euen_curr; | 39 | unsigned int *euen_curr; |
| 24 | 40 | ||
| 25 | preempt_disable(); | 41 | if (!irqs_disabled()) |
| 42 | fpregs_lock(); | ||
| 26 | 43 | ||
| 27 | WARN_ON(this_cpu_read(in_kernel_fpu)); | 44 | WARN_ON(this_cpu_read(in_kernel_fpu)); |
| 28 | 45 | ||
| @@ -73,7 +90,8 @@ void kernel_fpu_end(void) · 44 unmodified lines | |||
| 73 | 90 | ||
| 74 | this_cpu_write(in_kernel_fpu, false); | 91 | this_cpu_write(in_kernel_fpu, false); |
| 75 | 92 | ||
| 76 | preempt_enable(); | 93 | if (!irqs_disabled()) |
| 94 | fpregs_unlock(); | ||
| 77 | } | 95 | } |
| 78 | EXPORT_SYMBOL_GPL(kernel_fpu_end); | 96 | EXPORT_SYMBOL_GPL(kernel_fpu_end); |
| 79 | 97 | ||
| @@ -90,6 +90,7 @@ SYM_FUNC_START(_save_lbt_context) · 89 unmodified lines | |||
| 90 | li.w a0, 0 # success | 90 | li.w a0, 0 # success |
| 91 | jr ra | 91 | jr ra |
| 92 | SYM_FUNC_END(_save_lbt_context) | 92 | SYM_FUNC_END(_save_lbt_context) |
| 93 | EXPORT_SYMBOL_GPL(_save_lbt_context) | ||
| 93 | 94 | ||
| 94 | /* | 95 | /* |
| 95 | * a0: scr | 96 | * a0: scr |
| @@ -110,6 +111,7 @@ SYM_FUNC_START(_restore_lbt_context) · 14 unmodified lines | |||
| 110 | li.w a0, 0 # success | 111 | li.w a0, 0 # success |
| 111 | jr ra | 112 | jr ra |
| 112 | SYM_FUNC_END(_restore_lbt_context) | 113 | SYM_FUNC_END(_restore_lbt_context) |
| 114 | EXPORT_SYMBOL_GPL(_restore_lbt_context) | ||
| 113 | 115 | ||
| 114 | /* | 116 | /* |
| 115 | * a0: ftop | 117 | * a0: ftop |
| @@ -120,6 +122,7 @@ SYM_FUNC_START(_save_ftop_context) · 4 unmodified lines | |||
| 120 | li.w a0, 0 # success | 122 | li.w a0, 0 # success |
| 121 | jr ra | 123 | jr ra |
| 122 | SYM_FUNC_END(_save_ftop_context) | 124 | SYM_FUNC_END(_save_ftop_context) |
| 125 | EXPORT_SYMBOL_GPL(_save_ftop_context) | ||
| 123 | 126 | ||
| 124 | /* | 127 | /* |
| 125 | * a0: ftop | 128 | * a0: ftop |
| @@ -150,6 +153,7 @@ SYM_FUNC_START(_restore_ftop_context) · 24 unmodified lines | |||
| 150 | li.w a0, 0 # success | 153 | li.w a0, 0 # success |
| 151 | jr ra | 154 | jr ra |
| 152 | SYM_FUNC_END(_restore_ftop_context) | 155 | SYM_FUNC_END(_restore_ftop_context) |
| 156 | EXPORT_SYMBOL_GPL(_restore_ftop_context) | ||
| 153 | 157 | ||
| 154 | .L_lbt_fault: | 158 | .L_lbt_fault: |
| 155 | li.w a0, -EFAULT # failure | 159 | li.w a0, -EFAULT # failure |
| @@ -51,27 +51,6 @@ · 50 unmodified lines | |||
| 51 | #define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); }) | 51 | #define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); }) |
| 52 | #define unlock_lbt_owner() ({ pagefault_enable(); preempt_enable(); }) | 52 | #define unlock_lbt_owner() ({ pagefault_enable(); preempt_enable(); }) |
| 53 | 53 | ||
| 54 | /* Assembly functions to move context to/from the FPU */ | ||
| 55 | extern asmlinkage int | ||
| 56 | _save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); | ||
| 57 | extern asmlinkage int | ||
| 58 | _restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); | ||
| 59 | extern asmlinkage int | ||
| 60 | _save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 61 | extern asmlinkage int | ||
| 62 | _restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 63 | extern asmlinkage int | ||
| 64 | _save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 65 | extern asmlinkage int | ||
| 66 | _restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | ||
| 67 | |||
| 68 | #ifdef CONFIG_CPU_HAS_LBT | ||
| 69 | extern asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags); | ||
| 70 | extern asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags); | ||
| 71 | extern asmlinkage int _save_ftop_context(void __user *ftop); | ||
| 72 | extern asmlinkage int _restore_ftop_context(void __user *ftop); | ||
| 73 | #endif | ||
| 74 | |||
| 75 | struct rt_sigframe { | 54 | struct rt_sigframe { |
| 76 | struct siginfo rs_info; | 55 | struct siginfo rs_info; |
| 77 | struct ucontext rs_uctx; | 56 | struct ucontext rs_uctx; |
| @@ -111,7 +111,7 @@ static unsigned long __init get_loops_per_jiffy(void) · 110 unmodified lines | |||
| 111 | return lpj; | 111 | return lpj; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static long init_offset __nosavedata; | 114 | static long init_offset; |
| 115 | 115 | ||
| 116 | void save_counter(void) | 116 | void save_counter(void) |
| 117 | { | 117 | { |
| @@ -553,9 +553,10 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) · 552 unmodified lines | |||
| 553 | die_if_kernel("Kernel ale access", regs); | 553 | die_if_kernel("Kernel ale access", regs); |
| 554 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); | 554 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 555 | #else | 555 | #else |
| 556 | bool pie = regs_irqs_disabled(regs); | ||
| 556 | unsigned int *pc; | 557 | unsigned int *pc; |
| 557 | 558 | ||
| 558 | if (regs->csr_prmd & CSR_PRMD_PIE) | 559 | if (!pie) |
| 559 | local_irq_enable(); | 560 | local_irq_enable(); |
| 560 | 561 | ||
| 561 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); | 562 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); |
| @@ -582,7 +583,7 @@ sigbus: · 20 unmodified lines | |||
| 582 | die_if_kernel("Kernel ale access", regs); | 583 | die_if_kernel("Kernel ale access", regs); |
| 583 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); | 584 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 584 | out: | 585 | out: |
| 585 | if (regs->csr_prmd & CSR_PRMD_PIE) | 586 | if (!pie) |
| 586 | local_irq_disable(); | 587 | local_irq_disable(); |
| 587 | #endif | 588 | #endif |
| 588 | irqentry_exit(regs, state); | 589 | irqentry_exit(regs, state); |
| @@ -621,12 +622,13 @@ static void bug_handler(struct pt_regs *regs) · 32 unmodified lines | |||
| 621 | asmlinkage void noinstr do_bce(struct pt_regs *regs) | 622 | asmlinkage void noinstr do_bce(struct pt_regs *regs) |
| 622 | { | 623 | { |
| 623 | bool user = user_mode(regs); | 624 | bool user = user_mode(regs); |
| 625 | bool pie = regs_irqs_disabled(regs); | ||
| 624 | unsigned long era = exception_era(regs); | 626 | unsigned long era = exception_era(regs); |
| 625 | u64 badv = 0, lower = 0, upper = ULONG_MAX; | 627 | u64 badv = 0, lower = 0, upper = ULONG_MAX; |
| 626 | union loongarch_instruction insn; | 628 | union loongarch_instruction insn; |
| 627 | irqentry_state_t state = irqentry_enter(regs); | 629 | irqentry_state_t state = irqentry_enter(regs); |
| 628 | 630 | ||
| 629 | if (regs->csr_prmd & CSR_PRMD_PIE) | 631 | if (!pie) |
| 630 | local_irq_enable(); | 632 | local_irq_enable(); |
| 631 | 633 | ||
| 632 | current->thread.trap_nr = read_csr_excode(); | 634 | current->thread.trap_nr = read_csr_excode(); |
| @@ -692,7 +694,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs) · 59 unmodified lines | |||
| 692 | force_sig_bnderr((void __user *)badv, (void __user *)lower, (void __user *)upper); | 694 | force_sig_bnderr((void __user *)badv, (void __user *)lower, (void __user *)upper); |
| 693 | 695 | ||
| 694 | out: | 696 | out: |
| 695 | if (regs->csr_prmd & CSR_PRMD_PIE) | 697 | if (!pie) |
| 696 | local_irq_disable(); | 698 | local_irq_disable(); |
| 697 | 699 | ||
| 698 | irqentry_exit(regs, state); | 700 | irqentry_exit(regs, state); |
| @@ -710,11 +712,12 @@ bad_era: · 11 unmodified lines | |||
| 710 | asmlinkage void noinstr do_bp(struct pt_regs *regs) | 712 | asmlinkage void noinstr do_bp(struct pt_regs *regs) |
| 711 | { | 713 | { |
| 712 | bool user = user_mode(regs); | 714 | bool user = user_mode(regs); |
| 715 | bool pie = regs_irqs_disabled(regs); | ||
| 713 | unsigned int opcode, bcode; | 716 | unsigned int opcode, bcode; |
| 714 | unsigned long era = exception_era(regs); | 717 | unsigned long era = exception_era(regs); |
| 715 | irqentry_state_t state = irqentry_enter(regs); | 718 | irqentry_state_t state = irqentry_enter(regs); |
| 716 | 719 | ||
| 717 | if (regs->csr_prmd & CSR_PRMD_PIE) | 720 | if (!pie) |
| 718 | local_irq_enable(); | 721 | local_irq_enable(); |
| 719 | 722 | ||
| 720 | if (__get_inst(&opcode, (u32 *)era, user)) | 723 | if (__get_inst(&opcode, (u32 *)era, user)) |
| @@ -780,7 +783,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs) · 59 unmodified lines | |||
| 780 | } | 783 | } |
| 781 | 784 | ||
| 782 | out: | 785 | out: |
| 783 | if (regs->csr_prmd & CSR_PRMD_PIE) | 786 | if (!pie) |
| 784 | local_irq_disable(); | 787 | local_irq_disable(); |
| 785 | 788 | ||
| 786 | irqentry_exit(regs, state); | 789 | irqentry_exit(regs, state); |
| @@ -1015,6 +1018,7 @@ static void init_restore_lbt(void) · 228 unmodified lines | |||
| 1015 | 1018 | ||
| 1016 | asmlinkage void noinstr do_lbt(struct pt_regs *regs) | 1019 | asmlinkage void noinstr do_lbt(struct pt_regs *regs) |
| 1017 | { | 1020 | { |
| 1021 | bool pie = regs_irqs_disabled(regs); | ||
| 1018 | irqentry_state_t state = irqentry_enter(regs); | 1022 | irqentry_state_t state = irqentry_enter(regs); |
| 1019 | 1023 | ||
| 1020 | /* | 1024 | /* |
| @@ -1024,7 +1028,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs) · 3 unmodified lines | |||
| 1024 | * (including the user using 'MOVGR2GCSR' to turn on TM, which | 1028 | * (including the user using 'MOVGR2GCSR' to turn on TM, which |
| 1025 | * will not trigger the BTE), we need to check PRMD first. | 1029 | * will not trigger the BTE), we need to check PRMD first. |
| 1026 | */ | 1030 | */ |
| 1027 | if (regs->csr_prmd & CSR_PRMD_PIE) | 1031 | if (!pie) |
| 1028 | local_irq_enable(); | 1032 | local_irq_enable(); |
| 1029 | 1033 | ||
| 1030 | if (!cpu_has_lbt) { | 1034 | if (!cpu_has_lbt) { |
| @@ -1038,7 +1042,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs) · 7 unmodified lines | |||
| 1038 | preempt_enable(); | 1042 | preempt_enable(); |
| 1039 | 1043 | ||
| 1040 | out: | 1044 | out: |
| 1041 | if (regs->csr_prmd & CSR_PRMD_PIE) | 1045 | if (!pie) |
| 1042 | local_irq_disable(); | 1046 | local_irq_disable(); |
| 1043 | 1047 | ||
| 1044 | irqentry_exit(regs, state); | 1048 | irqentry_exit(regs, state); |
| @@ -42,7 +42,6 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) · 41 unmodified lines | |||
| 42 | utask->autask.saved_trap_nr = current->thread.trap_nr; | 42 | utask->autask.saved_trap_nr = current->thread.trap_nr; |
| 43 | current->thread.trap_nr = UPROBE_TRAP_NR; | 43 | current->thread.trap_nr = UPROBE_TRAP_NR; |
| 44 | instruction_pointer_set(regs, utask->xol_vaddr); | 44 | instruction_pointer_set(regs, utask->xol_vaddr); |
| 45 | user_enable_single_step(current); | ||
| 46 | 45 | ||
| 47 | return 0; | 46 | return 0; |
| 48 | } | 47 | } |
| @@ -53,13 +52,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) · 4 unmodified lines | |||
| 53 | 52 | ||
| 54 | WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR); | 53 | WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR); |
| 55 | current->thread.trap_nr = utask->autask.saved_trap_nr; | 54 | current->thread.trap_nr = utask->autask.saved_trap_nr; |
| 56 | 55 | instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE); | |
| 57 | if (auprobe->simulate) | ||
| 58 | instruction_pointer_set(regs, auprobe->resume_era); | ||
| 59 | else | ||
| 60 | instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE); | ||
| 61 | |||
| 62 | user_disable_single_step(current); | ||
| 63 | 56 | ||
| 64 | return 0; | 57 | return 0; |
| 65 | } | 58 | } |
| @@ -70,7 +63,6 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) · 4 unmodified lines | |||
| 70 | 63 | ||
| 71 | current->thread.trap_nr = utask->autask.saved_trap_nr; | 64 | current->thread.trap_nr = utask->autask.saved_trap_nr; |
| 72 | instruction_pointer_set(regs, utask->vaddr); | 65 | instruction_pointer_set(regs, utask->vaddr); |
| 73 | user_disable_single_step(current); | ||
| 74 | } | 66 | } |
| 75 | 67 | ||
| 76 | bool arch_uprobe_xol_was_trapped(struct task_struct *t) | 68 | bool arch_uprobe_xol_was_trapped(struct task_struct *t) |
| @@ -90,7 +82,6 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) · 13 unmodified lines | |||
| 90 | 82 | ||
| 91 | insn.word = auprobe->insn[0]; | 83 | insn.word = auprobe->insn[0]; |
| 92 | arch_simulate_insn(insn, regs); | 84 | arch_simulate_insn(insn, regs); |
| 93 | auprobe->resume_era = regs->csr_era; | ||
| 94 | 85 | ||
| 95 | return true; | 86 | return true; |
| 96 | } | 87 | } |
| @@ -21,4 +21,4 @@ kvm-y += intc/eiointc.o · 20 unmodified lines | |||
| 21 | kvm-y += intc/pch_pic.o | 21 | kvm-y += intc/pch_pic.o |
| 22 | kvm-y += irqfd.o | 22 | kvm-y += irqfd.o |
| 23 | 23 | ||
| 24 | CFLAGS_exit.o += $(call cc-option,-Wno-override-init,) | 24 | CFLAGS_exit.o += $(call cc-disable-warning, override-init) |
| @@ -111,7 +111,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) · 110 unmodified lines | |||
| 111 | ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); | 111 | ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); |
| 112 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 112 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
| 113 | if (unlikely(ret)) { | 113 | if (unlikely(ret)) { |
| 114 | kvm_err("%s: : read date from addr %llx failed\n", __func__, addr); | 114 | kvm_err("%s: : read data from addr %llx failed\n", __func__, addr); |
| 115 | return ret; | 115 | return ret; |
| 116 | } | 116 | } |
| 117 | /* Construct the mask by scanning the bit 27-30 */ | 117 | /* Construct the mask by scanning the bit 27-30 */ |
| @@ -127,7 +127,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) · 9 unmodified lines | |||
| 127 | ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); | 127 | ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); |
| 128 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 128 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
| 129 | if (unlikely(ret)) | 129 | if (unlikely(ret)) |
| 130 | kvm_err("%s: : write date to addr %llx failed\n", __func__, addr); | 130 | kvm_err("%s: : write data to addr %llx failed\n", __func__, addr); |
| 131 | 131 | ||
| 132 | return ret; | 132 | return ret; |
| 133 | } | 133 | } |
| @@ -296,10 +296,10 @@ int kvm_arch_enable_virtualization_cpu(void) · 295 unmodified lines | |||
| 296 | /* | 296 | /* |
| 297 | * Enable virtualization features granting guest direct control of | 297 | * Enable virtualization features granting guest direct control of |
| 298 | * certain features: | 298 | * certain features: |
| 299 | * GCI=2: Trap on init or unimplement cache instruction. | 299 | * GCI=2: Trap on init or unimplemented cache instruction. |
| 300 | * TORU=0: Trap on Root Unimplement. | 300 | * TORU=0: Trap on Root Unimplement. |
| 301 | * CACTRL=1: Root control cache. | 301 | * CACTRL=1: Root control cache. |
| 302 | * TOP=0: Trap on Previlege. | 302 | * TOP=0: Trap on Privilege. |
| 303 | * TOE=0: Trap on Exception. | 303 | * TOE=0: Trap on Exception. |
| 304 | * TIT=0: Trap on Timer. | 304 | * TIT=0: Trap on Timer. |
| 305 | */ | 305 | */ |
| @@ -294,6 +294,7 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu) · 293 unmodified lines | |||
| 294 | vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST; | 294 | vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST; |
| 295 | 295 | ||
| 296 | if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) { | 296 | if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) { |
| 297 | kvm_lose_pmu(vcpu); | ||
| 297 | /* make sure the vcpu mode has been written */ | 298 | /* make sure the vcpu mode has been written */ |
| 298 | smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE); | 299 | smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE); |
| 299 | local_irq_enable(); | 300 | local_irq_enable(); |
| @@ -902,6 +903,13 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu, · 602 unmodified lines | |||
| 902 | vcpu->arch.st.guest_addr = 0; | 903 | vcpu->arch.st.guest_addr = 0; |
| 903 | memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending)); | 904 | memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending)); |
| 904 | memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear)); | 905 | memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear)); |
| 906 | |||
| 907 | /* | ||
| 908 | * When vCPU reset, clear the ESTAT and GINTC registers | ||
| 909 | * Other CSR registers are cleared with function _kvm_setcsr(). | ||
| 910 | */ | ||
| 911 | kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_GINTC, 0); | ||
| 912 | kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_ESTAT, 0); | ||
| 905 | break; | 913 | break; |
| 906 | default: | 914 | default: |
| 907 | ret = -EINVAL; | 915 | ret = -EINVAL; |
| @@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, · 46 unmodified lines | |||
| 47 | pmd = pmd_offset(pud, addr); | 47 | pmd = pmd_offset(pud, addr); |
| 48 | } | 48 | } |
| 49 | } | 49 | } |
| 50 | return (pte_t *) pmd; | 50 | return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | uint64_t pmd_to_entrylo(unsigned long pmd_val) | 53 | uint64_t pmd_to_entrylo(unsigned long pmd_val) |
| @@ -65,9 +65,6 @@ void __init paging_init(void) · 64 unmodified lines | |||
| 65 | { | 65 | { |
| 66 | unsigned long max_zone_pfns[MAX_NR_ZONES]; | 66 | unsigned long max_zone_pfns[MAX_NR_ZONES]; |
| 67 | 67 | ||
| 68 | #ifdef CONFIG_ZONE_DMA | ||
| 69 | max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; | ||
| 70 | #endif | ||
| 71 | #ifdef CONFIG_ZONE_DMA32 | 68 | #ifdef CONFIG_ZONE_DMA32 |
| 72 | max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; | 69 | max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; |
| 73 | #endif | 70 | #endif |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #include <asm/fpu.h> | 2 | #include <asm/fpu.h> |
| 3 | #include <asm/loongson.h> | 3 | #include <asm/loongson.h> |
| 4 | #include <asm/sections.h> | 4 | #include <asm/sections.h> |
| 5 | #include <asm/time.h> | ||
| 5 | #include <asm/tlbflush.h> | 6 | #include <asm/tlbflush.h> |
| 6 | #include <linux/suspend.h> | 7 | #include <linux/suspend.h> |
| 7 | 8 | ||
| @@ -14,6 +15,7 @@ struct pt_regs saved_regs; · 6 unmodified lines | |||
| 14 | 15 | ||
| 15 | void save_processor_state(void) | 16 | void save_processor_state(void) |
| 16 | { | 17 | { |
| 18 | save_counter(); | ||
| 17 | saved_crmd = csr_read32(LOONGARCH_CSR_CRMD); | 19 | saved_crmd = csr_read32(LOONGARCH_CSR_CRMD); |
| 18 | saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); | 20 | saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); |
| 19 | saved_euen = csr_read32(LOONGARCH_CSR_EUEN); | 21 | saved_euen = csr_read32(LOONGARCH_CSR_EUEN); |
| @@ -26,6 +28,7 @@ void save_processor_state(void) · 6 unmodified lines | |||
| 26 | 28 | ||
| 27 | void restore_processor_state(void) | 29 | void restore_processor_state(void) |
| 28 | { | 30 | { |
| 31 | sync_counter(); | ||
| 29 | csr_write32(saved_crmd, LOONGARCH_CSR_CRMD); | 32 | csr_write32(saved_crmd, LOONGARCH_CSR_CRMD); |
| 30 | csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); | 33 | csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); |
| 31 | csr_write32(saved_euen, LOONGARCH_CSR_EUEN); | 34 | csr_write32(saved_euen, LOONGARCH_CSR_EUEN); |
| @@ -89,4 +89,3 @@ CONFIG_PANIC_ON_OOPS=y · 88 unmodified lines | |||
| 89 | # CONFIG_CRYPTO_ECHAINIV is not set | 89 | # CONFIG_CRYPTO_ECHAINIV is not set |
| 90 | CONFIG_CRYPTO_ANSI_CPRNG=y | 90 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 91 | # CONFIG_CRYPTO_HW is not set | 91 | # CONFIG_CRYPTO_HW is not set |
| 92 | CONFIG_CRC16=y | ||
| @@ -82,7 +82,6 @@ CONFIG_LEDS_GPIO=y · 81 unmodified lines | |||
| 82 | # CONFIG_IOMMU_SUPPORT is not set | 82 | # CONFIG_IOMMU_SUPPORT is not set |
| 83 | # CONFIG_DNOTIFY is not set | 83 | # CONFIG_DNOTIFY is not set |
| 84 | # CONFIG_PROC_PAGE_MONITOR is not set | 84 | # CONFIG_PROC_PAGE_MONITOR is not set |
| 85 | CONFIG_CRC_ITU_T=m | ||
| 86 | CONFIG_STRIP_ASM_SYMS=y | 85 | CONFIG_STRIP_ASM_SYMS=y |
| 87 | CONFIG_DEBUG_FS=y | 86 | CONFIG_DEBUG_FS=y |
| 88 | # CONFIG_SCHED_DEBUG is not set | 87 | # CONFIG_SCHED_DEBUG is not set |
| @@ -238,7 +238,6 @@ CONFIG_CRYPTO_SERPENT=m · 237 unmodified lines | |||
| 238 | CONFIG_CRYPTO_TEA=m | 238 | CONFIG_CRYPTO_TEA=m |
| 239 | CONFIG_CRYPTO_TWOFISH=m | 239 | CONFIG_CRYPTO_TWOFISH=m |
| 240 | CONFIG_CRYPTO_LZO=m | 240 | CONFIG_CRYPTO_LZO=m |
| 241 | CONFIG_CRC_T10DIF=m | ||
| 242 | CONFIG_MAGIC_SYSRQ=y | 241 | CONFIG_MAGIC_SYSRQ=y |
| 243 | CONFIG_DEBUG_MEMORY_INIT=y | 242 | CONFIG_DEBUG_MEMORY_INIT=y |
| 244 | CONFIG_DETECT_HUNG_TASK=y | 243 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -218,4 +218,3 @@ CONFIG_CRYPTO_SEED=m · 217 unmodified lines | |||
| 218 | CONFIG_CRYPTO_DEFLATE=m | 218 | CONFIG_CRYPTO_DEFLATE=m |
| 219 | CONFIG_CRYPTO_LZO=m | 219 | CONFIG_CRYPTO_LZO=m |
| 220 | # CONFIG_CRYPTO_HW is not set | 220 | # CONFIG_CRYPTO_HW is not set |
| 221 | CONFIG_CRC_CCITT=y | ||
| @@ -326,5 +326,4 @@ CONFIG_CRYPTO_TEA=m · 325 unmodified lines | |||
| 326 | CONFIG_CRYPTO_TWOFISH=m | 326 | CONFIG_CRYPTO_TWOFISH=m |
| 327 | CONFIG_CRYPTO_LZO=m | 327 | CONFIG_CRYPTO_LZO=m |
| 328 | # CONFIG_CRYPTO_HW is not set | 328 | # CONFIG_CRYPTO_HW is not set |
| 329 | CONFIG_CRC_T10DIF=m | ||
| 330 | CONFIG_DEBUG_MEMORY_INIT=y | 329 | CONFIG_DEBUG_MEMORY_INIT=y |
| @@ -317,4 +317,3 @@ CONFIG_CRYPTO_SERPENT=m · 316 unmodified lines | |||
| 317 | CONFIG_CRYPTO_TEA=m | 317 | CONFIG_CRYPTO_TEA=m |
| 318 | CONFIG_CRYPTO_TWOFISH=m | 318 | CONFIG_CRYPTO_TWOFISH=m |
| 319 | CONFIG_CRYPTO_LZO=m | 319 | CONFIG_CRYPTO_LZO=m |
| 320 | CONFIG_CRC_T10DIF=m | ||
| @@ -179,4 +179,3 @@ CONFIG_CRYPTO_RMD160=m · 178 unmodified lines | |||
| 179 | CONFIG_CRYPTO_WP512=m | 179 | CONFIG_CRYPTO_WP512=m |
| 180 | CONFIG_CRYPTO_XCBC=m | 180 | CONFIG_CRYPTO_XCBC=m |
| 181 | CONFIG_CRYPTO_LZO=m | 181 | CONFIG_CRYPTO_LZO=m |
| 182 | CONFIG_CRC_T10DIF=m | ||
| @@ -177,7 +177,6 @@ CONFIG_CRYPTO_SERPENT=y · 176 unmodified lines | |||
| 177 | CONFIG_CRYPTO_TEA=y | 177 | CONFIG_CRYPTO_TEA=y |
| 178 | CONFIG_CRYPTO_TWOFISH=y | 178 | CONFIG_CRYPTO_TWOFISH=y |
| 179 | CONFIG_CRYPTO_DEFLATE=y | 179 | CONFIG_CRYPTO_DEFLATE=y |
| 180 | CONFIG_CRC_T10DIF=y | ||
| 181 | CONFIG_FONTS=y | 180 | CONFIG_FONTS=y |
| 182 | CONFIG_FONT_8x8=y | 181 | CONFIG_FONT_8x8=y |
| 183 | CONFIG_FONT_8x16=y | 182 | CONFIG_FONT_8x16=y |
| @@ -111,7 +111,6 @@ CONFIG_NLS_KOI8_U=y · 110 unmodified lines | |||
| 111 | CONFIG_NLS_UTF8=y | 111 | CONFIG_NLS_UTF8=y |
| 112 | CONFIG_CRYPTO_DEFLATE=y | 112 | CONFIG_CRYPTO_DEFLATE=y |
| 113 | CONFIG_CRYPTO_LZO=y | 113 | CONFIG_CRYPTO_LZO=y |
| 114 | CONFIG_CRC16=y | ||
| 115 | CONFIG_XZ_DEC=y | 114 | CONFIG_XZ_DEC=y |
| 116 | CONFIG_PRINTK_TIME=y | 115 | CONFIG_PRINTK_TIME=y |
| 117 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 116 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -155,5 +155,4 @@ CONFIG_JFFS2_COMPRESSION_OPTIONS=y · 154 unmodified lines | |||
| 155 | CONFIG_SQUASHFS=y | 155 | CONFIG_SQUASHFS=y |
| 156 | CONFIG_CRYPTO_TEST=m | 156 | CONFIG_CRYPTO_TEST=m |
| 157 | # CONFIG_CRYPTO_HW is not set | 157 | # CONFIG_CRYPTO_HW is not set |
| 158 | CONFIG_CRC16=m | ||
| 159 | CONFIG_STRIP_ASM_SYMS=y | 158 | CONFIG_STRIP_ASM_SYMS=y |
| @@ -128,7 +128,6 @@ CONFIG_SQUASHFS=y · 127 unmodified lines | |||
| 128 | # CONFIG_SQUASHFS_ZLIB is not set | 128 | # CONFIG_SQUASHFS_ZLIB is not set |
| 129 | CONFIG_SQUASHFS_XZ=y | 129 | CONFIG_SQUASHFS_XZ=y |
| 130 | CONFIG_CRYPTO_ARC4=m | 130 | CONFIG_CRYPTO_ARC4=m |
| 131 | CONFIG_CRC_ITU_T=m | ||
| 132 | # CONFIG_XZ_DEC_X86 is not set | 131 | # CONFIG_XZ_DEC_X86 is not set |
| 133 | # CONFIG_XZ_DEC_POWERPC is not set | 132 | # CONFIG_XZ_DEC_POWERPC is not set |
| 134 | # CONFIG_XZ_DEC_IA64 is not set | 133 | # CONFIG_XZ_DEC_IA64 is not set |
| @@ -99,4 +99,3 @@ CONFIG_CRYPTO_TWOFISH=m · 98 unmodified lines | |||
| 99 | CONFIG_CRYPTO_DEFLATE=m | 99 | CONFIG_CRYPTO_DEFLATE=m |
| 100 | CONFIG_CRYPTO_LZO=m | 100 | CONFIG_CRYPTO_LZO=m |
| 101 | # CONFIG_CRYPTO_HW is not set | 101 | # CONFIG_CRYPTO_HW is not set |
| 102 | CONFIG_CRC16=m | ||
| @@ -111,7 +111,6 @@ CONFIG_NLS_KOI8_U=y · 110 unmodified lines | |||
| 111 | CONFIG_NLS_UTF8=y | 111 | CONFIG_NLS_UTF8=y |
| 112 | CONFIG_CRYPTO_DEFLATE=y | 112 | CONFIG_CRYPTO_DEFLATE=y |
| 113 | CONFIG_CRYPTO_LZO=y | 113 | CONFIG_CRYPTO_LZO=y |
| 114 | CONFIG_CRC16=y | ||
| 115 | CONFIG_XZ_DEC=y | 114 | CONFIG_XZ_DEC=y |
| 116 | CONFIG_PRINTK_TIME=y | 115 | CONFIG_PRINTK_TIME=y |
| 117 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 116 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -140,7 +140,6 @@ CONFIG_SQUASHFS=y · 139 unmodified lines | |||
| 140 | # CONFIG_SQUASHFS_ZLIB is not set | 140 | # CONFIG_SQUASHFS_ZLIB is not set |
| 141 | CONFIG_SQUASHFS_XZ=y | 141 | CONFIG_SQUASHFS_XZ=y |
| 142 | CONFIG_CRYPTO_ARC4=m | 142 | CONFIG_CRYPTO_ARC4=m |
| 143 | CONFIG_CRC_ITU_T=m | ||
| 144 | CONFIG_PRINTK_TIME=y | 143 | CONFIG_PRINTK_TIME=y |
| 145 | CONFIG_STRIP_ASM_SYMS=y | 144 | CONFIG_STRIP_ASM_SYMS=y |
| 146 | CONFIG_DEBUG_FS=y | 145 | CONFIG_DEBUG_FS=y |
| @@ -6,11 +6,10 @@ · 5 unmodified lines | |||
| 6 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
| 7 | 7 | ||
| 8 | extern void (*cpu_wait)(void); | 8 | extern void (*cpu_wait)(void); |
| 9 | extern void r4k_wait(void); | 9 | extern asmlinkage void r4k_wait(void); |
| 10 | extern asmlinkage void __r4k_wait(void); | ||
| 11 | extern void r4k_wait_irqoff(void); | 10 | extern void r4k_wait_irqoff(void); |
| 12 | 11 | ||
| 13 | static inline int using_rollback_handler(void) | 12 | static inline int using_skipover_handler(void) |
| 14 | { | 13 | { |
| 15 | return cpu_wait == r4k_wait; | 14 | return cpu_wait == r4k_wait; |
| 16 | } | 15 | } |
| @@ -65,7 +65,8 @@ static inline void instruction_pointer_set(struct pt_regs *regs, · 64 unmodified lines | |||
| 65 | 65 | ||
| 66 | /* Query offset/name of register from its name/offset */ | 66 | /* Query offset/name of register from its name/offset */ |
| 67 | extern int regs_query_register_offset(const char *name); | 67 | extern int regs_query_register_offset(const char *name); |
| 68 | #define MAX_REG_OFFSET (offsetof(struct pt_regs, __last)) | 68 | #define MAX_REG_OFFSET \ |
| 69 | (offsetof(struct pt_regs, __last) - sizeof(unsigned long)) | ||
| 69 | 70 | ||
| 70 | /** | 71 | /** |
| 71 | * regs_get_register() - get register value from its offset | 72 | * regs_get_register() - get register value from its offset |
| @@ -104,48 +104,59 @@ handle_vcei: · 103 unmodified lines | |||
| 104 | 104 | ||
| 105 | __FINIT | 105 | __FINIT |
| 106 | 106 | ||
| 107 | .align 5 /* 32 byte rollback region */ | 107 | .section .cpuidle.text,"ax" |
| 108 | LEAF(__r4k_wait) | 108 | /* Align to 32 bytes for the maximum idle interrupt region size. */ |
| 109 | .set push | 109 | .align 5 |
| 110 | .set noreorder | 110 | LEAF(r4k_wait) |
| 111 | /* start of rollback region */ | 111 | /* Keep the ISA bit clear for calculations on local labels here. */ |
| 112 | LONG_L t0, TI_FLAGS($28) | 112 | 0: .fill 0 |
| 113 | nop | 113 | /* Start of idle interrupt region. */ |
| 114 | andi t0, _TIF_NEED_RESCHED | 114 | local_irq_enable |
| 115 | bnez t0, 1f | 115 | /* |
| 116 | nop | 116 | * If an interrupt lands here, before going idle on the next |
| 117 | nop | 117 | * instruction, we must *NOT* go idle since the interrupt could |
| 118 | nop | 118 | * have set TIF_NEED_RESCHED or caused a timer to need resched. |
| 119 | #ifdef CONFIG_CPU_MICROMIPS | 119 | * Fall through -- see skipover_handler below -- and have the |
| 120 | nop | 120 | * idle loop take care of things. |
| 121 | nop | 121 | */ |
| 122 | nop | 122 | 1: .fill 0 |
| 123 | nop | 123 | /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */ |
| 124 | #endif | 124 | .if 1b - 0b > 32 |
| 125 | .error "overlong idle interrupt region" | ||
| 126 | .elseif 1b - 0b > 8 | ||
| 127 | .align 4 | ||
| 128 | .endif | ||
| 129 | 2: .fill 0 | ||
| 130 | .equ r4k_wait_idle_size, 2b - 0b | ||
| 131 | /* End of idle interrupt region; size has to be a power of 2. */ | ||
| 125 | .set MIPS_ISA_ARCH_LEVEL_RAW | 132 | .set MIPS_ISA_ARCH_LEVEL_RAW |
| 133 | r4k_wait_insn: | ||
| 126 | wait | 134 | wait |
| 127 | /* end of rollback region (the region size must be power of two) */ | 135 | r4k_wait_exit: |
| 128 | 1: | 136 | .set mips0 |
| 137 | local_irq_disable | ||
| 129 | jr ra | 138 | jr ra |
| 130 | nop | 139 | END(r4k_wait) |
| 131 | .set pop | 140 | .previous |
| 132 | END(__r4k_wait) | ||
| 133 | 141 | ||
| 134 | .macro BUILD_ROLLBACK_PROLOGUE handler | 142 | .macro BUILD_SKIPOVER_PROLOGUE handler |
| 135 | FEXPORT(rollback_\handler) | 143 | FEXPORT(skipover_\handler) |
| 136 | .set push | 144 | .set push |
| 137 | .set noat | 145 | .set noat |
| 138 | MFC0 k0, CP0_EPC | 146 | MFC0 k0, CP0_EPC |
| 139 | PTR_LA k1, __r4k_wait | 147 | /* Subtract/add 2 to let the ISA bit propagate through the mask. */ |
| 140 | ori k0, 0x1f /* 32 byte rollback region */ | 148 | PTR_LA k1, r4k_wait_insn - 2 |
| 141 | xori k0, 0x1f | 149 | ori k0, r4k_wait_idle_size - 2 |
| 150 | .set noreorder | ||
| 142 | bne k0, k1, \handler | 151 | bne k0, k1, \handler |
| 152 | PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 | ||
| 153 | .set reorder | ||
| 143 | MTC0 k0, CP0_EPC | 154 | MTC0 k0, CP0_EPC |
| 144 | .set pop | 155 | .set pop |
| 145 | .endm | 156 | .endm |
| 146 | 157 | ||
| 147 | .align 5 | 158 | .align 5 |
| 148 | BUILD_ROLLBACK_PROLOGUE handle_int | 159 | BUILD_SKIPOVER_PROLOGUE handle_int |
| 149 | NESTED(handle_int, PT_SIZE, sp) | 160 | NESTED(handle_int, PT_SIZE, sp) |
| 150 | .cfi_signal_frame | 161 | .cfi_signal_frame |
| 151 | #ifdef CONFIG_TRACE_IRQFLAGS | 162 | #ifdef CONFIG_TRACE_IRQFLAGS |
| @@ -265,7 +276,7 @@ NESTED(except_vec_ejtag_debug, 0, sp) · 113 unmodified lines | |||
| 265 | * This prototype is copied to ebase + n*IntCtl.VS and patched | 276 | * This prototype is copied to ebase + n*IntCtl.VS and patched |
| 266 | * to invoke the handler | 277 | * to invoke the handler |
| 267 | */ | 278 | */ |
| 268 | BUILD_ROLLBACK_PROLOGUE except_vec_vi | 279 | BUILD_SKIPOVER_PROLOGUE except_vec_vi |
| 269 | NESTED(except_vec_vi, 0, sp) | 280 | NESTED(except_vec_vi, 0, sp) |
| 270 | SAVE_SOME docfi=1 | 281 | SAVE_SOME docfi=1 |
| 271 | SAVE_AT docfi=1 | 282 | SAVE_AT docfi=1 |
| @@ -35,13 +35,6 @@ static void __cpuidle r3081_wait(void) · 34 unmodified lines | |||
| 35 | write_c0_conf(cfg | R30XX_CONF_HALT); | 35 | write_c0_conf(cfg | R30XX_CONF_HALT); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void __cpuidle r4k_wait(void) | ||
| 39 | { | ||
| 40 | raw_local_irq_enable(); | ||
| 41 | __r4k_wait(); | ||
| 42 | raw_local_irq_disable(); | ||
| 43 | } | ||
| 44 | |||
| 45 | /* | 38 | /* |
| 46 | * This variant is preferable as it allows testing need_resched and going to | 39 | * This variant is preferable as it allows testing need_resched and going to |
| 47 | * sleep depending on the outcome atomically. Unfortunately the "It is | 40 | * sleep depending on the outcome atomically. Unfortunately the "It is |
| @@ -332,6 +332,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) · 331 unmodified lines | |||
| 332 | mips_cps_cluster_bootcfg = kcalloc(nclusters, | 332 | mips_cps_cluster_bootcfg = kcalloc(nclusters, |
| 333 | sizeof(*mips_cps_cluster_bootcfg), | 333 | sizeof(*mips_cps_cluster_bootcfg), |
| 334 | GFP_KERNEL); | 334 | GFP_KERNEL); |
| 335 | if (!mips_cps_cluster_bootcfg) | ||
| 336 | goto err_out; | ||
| 335 | 337 | ||
| 336 | if (nclusters > 1) | 338 | if (nclusters > 1) |
| 337 | mips_cm_update_property(); | 339 | mips_cm_update_property(); |
| @@ -348,6 +350,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) · 10 unmodified lines | |||
| 348 | mips_cps_cluster_bootcfg[cl].core_power = | 350 | mips_cps_cluster_bootcfg[cl].core_power = |
| 349 | kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long), | 351 | kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long), |
| 350 | GFP_KERNEL); | 352 | GFP_KERNEL); |
| 353 | if (!mips_cps_cluster_bootcfg[cl].core_power) | ||
| 354 | goto err_out; | ||
| 351 | 355 | ||
| 352 | /* Allocate VPE boot configuration structs */ | 356 | /* Allocate VPE boot configuration structs */ |
| 353 | for (c = 0; c < ncores; c++) { | 357 | for (c = 0; c < ncores; c++) { |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | |||
| 77 | #include "access-helper.h" | 77 | #include "access-helper.h" |
| 78 | 78 | ||
| 79 | extern void check_wait(void); | 79 | extern void check_wait(void); |
| 80 | extern asmlinkage void rollback_handle_int(void); | 80 | extern asmlinkage void skipover_handle_int(void); |
| 81 | extern asmlinkage void handle_int(void); | 81 | extern asmlinkage void handle_int(void); |
| 82 | extern asmlinkage void handle_adel(void); | 82 | extern asmlinkage void handle_adel(void); |
| 83 | extern asmlinkage void handle_ades(void); | 83 | extern asmlinkage void handle_ades(void); |
| @@ -2066,7 +2066,7 @@ void *set_vi_handler(int n, vi_handler_t addr) · 1982 unmodified lines | |||
| 2066 | { | 2066 | { |
| 2067 | extern const u8 except_vec_vi[]; | 2067 | extern const u8 except_vec_vi[]; |
| 2068 | extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; | 2068 | extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; |
| 2069 | extern const u8 rollback_except_vec_vi[]; | 2069 | extern const u8 skipover_except_vec_vi[]; |
| 2070 | unsigned long handler; | 2070 | unsigned long handler; |
| 2071 | unsigned long old_handler = vi_handlers[n]; | 2071 | unsigned long old_handler = vi_handlers[n]; |
| 2072 | int srssets = current_cpu_data.srsets; | 2072 | int srssets = current_cpu_data.srsets; |
| @@ -2095,7 +2095,7 @@ void *set_vi_handler(int n, vi_handler_t addr) · 22 unmodified lines | |||
| 2095 | change_c0_srsmap(0xf << n*4, 0 << n*4); | 2095 | change_c0_srsmap(0xf << n*4, 0 << n*4); |
| 2096 | } | 2096 | } |
| 2097 | 2097 | ||
| 2098 | vec_start = using_rollback_handler() ? rollback_except_vec_vi : | 2098 | vec_start = using_skipover_handler() ? skipover_except_vec_vi : |
| 2099 | except_vec_vi; | 2099 | except_vec_vi; |
| 2100 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) | 2100 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) |
| 2101 | ori_offset = except_vec_vi_ori - vec_start + 2; | 2101 | ori_offset = except_vec_vi_ori - vec_start + 2; |
| @@ -2426,8 +2426,8 @@ void __init trap_init(void) · 324 unmodified lines | |||
| 2426 | if (board_be_init) | 2426 | if (board_be_init) |
| 2427 | board_be_init(); | 2427 | board_be_init(); |
| 2428 | 2428 | ||
| 2429 | set_except_vector(EXCCODE_INT, using_rollback_handler() ? | 2429 | set_except_vector(EXCCODE_INT, using_skipover_handler() ? |
| 2430 | rollback_handle_int : handle_int); | 2430 | skipover_handle_int : handle_int); |
| 2431 | set_except_vector(EXCCODE_MOD, handle_tlbm); | 2431 | set_except_vector(EXCCODE_MOD, handle_tlbm); |
| 2432 | set_except_vector(EXCCODE_TLBL, handle_tlbl); | 2432 | set_except_vector(EXCCODE_TLBL, handle_tlbl); |
| 2433 | set_except_vector(EXCCODE_TLBS, handle_tlbs); | 2433 | set_except_vector(EXCCODE_TLBS, handle_tlbs); |
| @@ -23,6 +23,9 @@ · 22 unmodified lines | |||
| 23 | */ | 23 | */ |
| 24 | extern void local_dcache_page_flush(struct page *page); | 24 | extern void local_dcache_page_flush(struct page *page); |
| 25 | extern void local_icache_page_inv(struct page *page); | 25 | extern void local_icache_page_inv(struct page *page); |
| 26 | extern void local_dcache_range_flush(unsigned long start, unsigned long end); | ||
| 27 | extern void local_dcache_range_inv(unsigned long start, unsigned long end); | ||
| 28 | extern void local_icache_range_inv(unsigned long start, unsigned long end); | ||
| 26 | 29 | ||
| 27 | /* | 30 | /* |
| 28 | * Data cache flushing always happen on the local cpu. Instruction cache | 31 | * Data cache flushing always happen on the local cpu. Instruction cache |
| @@ -38,6 +41,20 @@ extern void local_icache_page_inv(struct page *page); · 9 unmodified lines | |||
| 38 | extern void smp_icache_page_inv(struct page *page); | 41 | extern void smp_icache_page_inv(struct page *page); |
| 39 | #endif /* CONFIG_SMP */ | 42 | #endif /* CONFIG_SMP */ |
| 40 | 43 | ||
| 44 | /* | ||
| 45 | * Even if the actual block size is larger than L1_CACHE_BYTES, paddr | ||
| 46 | * can be incremented by L1_CACHE_BYTES. When paddr is written to the | ||
| 47 | * invalidate register, the entire cache line encompassing this address | ||
| 48 | * is invalidated. Each subsequent reference to the same cache line will | ||
| 49 | * not affect the invalidation process. | ||
| 50 | */ | ||
| 51 | #define local_dcache_block_flush(addr) \ | ||
| 52 | local_dcache_range_flush(addr, addr + L1_CACHE_BYTES) | ||
| 53 | #define local_dcache_block_inv(addr) \ | ||
| 54 | local_dcache_range_inv(addr, addr + L1_CACHE_BYTES) | ||
| 55 | #define local_icache_block_inv(addr) \ | ||
| 56 | local_icache_range_inv(addr, addr + L1_CACHE_BYTES) | ||
| 57 | |||
| 41 | /* | 58 | /* |
| 42 | * Synchronizes caches. Whenever a cpu writes executable code to memory, this | 59 | * Synchronizes caches. Whenever a cpu writes executable code to memory, this |
| 43 | * should be called to make sure the processor sees the newly written code. | 60 | * should be called to make sure the processor sees the newly written code. |
| @@ -15,16 +15,21 @@ · 14 unmodified lines | |||
| 15 | #ifndef __ASM_OPENRISC_CPUINFO_H | 15 | #ifndef __ASM_OPENRISC_CPUINFO_H |
| 16 | #define __ASM_OPENRISC_CPUINFO_H | 16 | #define __ASM_OPENRISC_CPUINFO_H |
| 17 | 17 | ||
| 18 | #include <asm/spr.h> | ||
| 19 | #include <asm/spr_defs.h> | ||
| 20 | |||
| 21 | struct cache_desc { | ||
| 22 | u32 size; | ||
| 23 | u32 sets; | ||
| 24 | u32 block_size; | ||
| 25 | u32 ways; | ||
| 26 | }; | ||
| 27 | |||
| 18 | struct cpuinfo_or1k { | 28 | struct cpuinfo_or1k { |
| 19 | u32 clock_frequency; | 29 | u32 clock_frequency; |
| 20 | 30 | ||
| 21 | u32 icache_size; | 31 | struct cache_desc icache; |
| 22 | u32 icache_block_size; | 32 | struct cache_desc dcache; |
| 23 | u32 icache_ways; | ||
| 24 | |||
| 25 | u32 dcache_size; | ||
| 26 | u32 dcache_block_size; | ||
| 27 | u32 dcache_ways; | ||
| 28 | 33 | ||
| 29 | u16 coreid; | 34 | u16 coreid; |
| 30 | }; | 35 | }; |
| @@ -32,4 +37,9 @@ struct cpuinfo_or1k { · 1 unmodified line | |||
| 32 | extern struct cpuinfo_or1k cpuinfo_or1k[NR_CPUS]; | 37 | extern struct cpuinfo_or1k cpuinfo_or1k[NR_CPUS]; |
| 33 | extern void setup_cpuinfo(void); | 38 | extern void setup_cpuinfo(void); |
| 34 | 39 | ||
| 40 | /* | ||
| 41 | * Check if the cache component exists. | ||
| 42 | */ | ||
| 43 | extern bool cpu_cache_is_present(const unsigned int cache_type); | ||
| 44 | |||
| 35 | #endif /* __ASM_OPENRISC_CPUINFO_H */ | 45 | #endif /* __ASM_OPENRISC_CPUINFO_H */ |
| @@ -7,7 +7,7 @@ extra-y := vmlinux.lds · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | obj-y := head.o setup.o or32_ksyms.o process.o dma.o \ | 8 | obj-y := head.o setup.o or32_ksyms.o process.o dma.o \ |
| 9 | traps.o time.o irq.o entry.o ptrace.o signal.o \ | 9 | traps.o time.o irq.o entry.o ptrace.o signal.o \ |
| 10 | sys_call_table.o unwinder.o | 10 | sys_call_table.o unwinder.o cacheinfo.o |
| 11 | 11 | ||
| 12 | obj-$(CONFIG_SMP) += smp.o sync-timer.o | 12 | obj-$(CONFIG_SMP) += smp.o sync-timer.o |
| 13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
| @@ -0,0 +1,104 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | /* | ||
| 3 | * OpenRISC cacheinfo support | ||
| 4 | * | ||
| 5 | * Based on work done for MIPS and LoongArch. All original copyrights | ||
| 6 | * apply as per the original source declaration. | ||
| 7 | * | ||
| 8 | * OpenRISC implementation: | ||
| 9 | * Copyright (C) 2025 Sahil Siddiq <sahilcdq@proton.me> | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/cacheinfo.h> | ||
| 13 | #include <asm/cpuinfo.h> | ||
| 14 | #include <asm/spr.h> | ||
| 15 | #include <asm/spr_defs.h> | ||
| 16 | |||
| 17 | static inline void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type, | ||
| 18 | unsigned int level, struct cache_desc *cache, int cpu) | ||
| 19 | { | ||
| 20 | this_leaf->type = type; | ||
| 21 | this_leaf->level = level; | ||
| 22 | this_leaf->coherency_line_size = cache->block_size; | ||
| 23 | this_leaf->number_of_sets = cache->sets; | ||
| 24 | this_leaf->ways_of_associativity = cache->ways; | ||
| 25 | this_leaf->size = cache->size; | ||
| 26 | cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); | ||
| 27 | } | ||
| 28 | |||
| 29 | int init_cache_level(unsigned int cpu) | ||
| 30 | { | ||
| 31 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; | ||
| 32 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
| 33 | int leaves = 0, levels = 0; | ||
| 34 | unsigned long upr = mfspr(SPR_UPR); | ||
| 35 | unsigned long iccfgr, dccfgr; | ||
| 36 | |||
| 37 | if (!(upr & SPR_UPR_UP)) { | ||
| 38 | printk(KERN_INFO | ||
| 39 | "-- no UPR register... unable to detect configuration\n"); | ||
| 40 | return -ENOENT; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (cpu_cache_is_present(SPR_UPR_DCP)) { | ||
| 44 | dccfgr = mfspr(SPR_DCCFGR); | ||
| 45 | cpuinfo->dcache.ways = 1 << (dccfgr & SPR_DCCFGR_NCW); | ||
| 46 | cpuinfo->dcache.sets = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); | ||
| 47 | cpuinfo->dcache.block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7); | ||
| 48 | cpuinfo->dcache.size = | ||
| 49 | cpuinfo->dcache.sets * cpuinfo->dcache.ways * cpuinfo->dcache.block_size; | ||
| 50 | leaves += 1; | ||
| 51 | printk(KERN_INFO | ||
| 52 | "-- dcache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n", | ||
| 53 | cpuinfo->dcache.size, cpuinfo->dcache.block_size, | ||
| 54 | cpuinfo->dcache.sets, cpuinfo->dcache.ways); | ||
| 55 | } else | ||
| 56 | printk(KERN_INFO "-- dcache disabled\n"); | ||
| 57 | |||
| 58 | if (cpu_cache_is_present(SPR_UPR_ICP)) { | ||
| 59 | iccfgr = mfspr(SPR_ICCFGR); | ||
| 60 | cpuinfo->icache.ways = 1 << (iccfgr & SPR_ICCFGR_NCW); | ||
| 61 | cpuinfo->icache.sets = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); | ||
| 62 | cpuinfo->icache.block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7); | ||
| 63 | cpuinfo->icache.size = | ||
| 64 | cpuinfo->icache.sets * cpuinfo->icache.ways * cpuinfo->icache.block_size; | ||
| 65 | leaves += 1; | ||
| 66 | printk(KERN_INFO | ||
| 67 | "-- icache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n", | ||
| 68 | cpuinfo->icache.size, cpuinfo->icache.block_size, | ||
| 69 | cpuinfo->icache.sets, cpuinfo->icache.ways); | ||
| 70 | } else | ||
| 71 | printk(KERN_INFO "-- icache disabled\n"); | ||
| 72 | |||
| 73 | if (!leaves) | ||
| 74 | return -ENOENT; | ||
| 75 | |||
| 76 | levels = 1; | ||
| 77 | |||
| 78 | this_cpu_ci->num_leaves = leaves; | ||
| 79 | this_cpu_ci->num_levels = levels; | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | int populate_cache_leaves(unsigned int cpu) | ||
| 85 | { | ||
| 86 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; | ||
| 87 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
| 88 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | ||
| 89 | int level = 1; | ||
| 90 | |||
| 91 | if (cpu_cache_is_present(SPR_UPR_DCP)) { | ||
| 92 | ci_leaf_init(this_leaf, CACHE_TYPE_DATA, level, &cpuinfo->dcache, cpu); | ||
| 93 | this_leaf->attributes = ((mfspr(SPR_DCCFGR) & SPR_DCCFGR_CWS) >> 8) ? | ||
| 94 | CACHE_WRITE_BACK : CACHE_WRITE_THROUGH; | ||
| 95 | this_leaf++; | ||
| 96 | } | ||
| 97 | |||
| 98 | if (cpu_cache_is_present(SPR_UPR_ICP)) | ||
| 99 | ci_leaf_init(this_leaf, CACHE_TYPE_INST, level, &cpuinfo->icache, cpu); | ||
| 100 | |||
| 101 | this_cpu_ci->cpu_map_populated = true; | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/pagewalk.h> | 17 | #include <linux/pagewalk.h> |
| 18 | 18 | ||
| 19 | #include <asm/cpuinfo.h> | 19 | #include <asm/cpuinfo.h> |
| 20 | #include <asm/cacheflush.h> | ||
| 20 | #include <asm/spr_defs.h> | 21 | #include <asm/spr_defs.h> |
| 21 | #include <asm/tlbflush.h> | 22 | #include <asm/tlbflush.h> |
| 22 | 23 | ||
| @@ -24,9 +25,6 @@ static int · 1 unmodified line | |||
| 24 | page_set_nocache(pte_t *pte, unsigned long addr, | 25 | page_set_nocache(pte_t *pte, unsigned long addr, |
| 25 | unsigned long next, struct mm_walk *walk) | 26 | unsigned long next, struct mm_walk *walk) |
| 26 | { | 27 | { |
| 27 | unsigned long cl; | ||
| 28 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; | ||
| 29 | |||
| 30 | pte_val(*pte) |= _PAGE_CI; | 28 | pte_val(*pte) |= _PAGE_CI; |
| 31 | 29 | ||
| 32 | /* | 30 | /* |
| @@ -36,8 +34,7 @@ page_set_nocache(pte_t *pte, unsigned long addr, · 3 unmodified lines | |||
| 36 | flush_tlb_kernel_range(addr, addr + PAGE_SIZE); | 34 | flush_tlb_kernel_range(addr, addr + PAGE_SIZE); |
| 37 | 35 | ||
| 38 | /* Flush page out of dcache */ | 36 | /* Flush page out of dcache */ |
| 39 | for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo->dcache_block_size) | 37 | local_dcache_range_flush(__pa(addr), __pa(next)); |
| 40 | mtspr(SPR_DCBFR, cl); | ||
| 41 | 38 | ||
| 42 | return 0; | 39 | return 0; |
| 43 | } | 40 | } |
| @@ -98,21 +95,14 @@ void arch_dma_clear_uncached(void *cpu_addr, size_t size) · 54 unmodified lines | |||
| 98 | void arch_sync_dma_for_device(phys_addr_t addr, size_t size, | 95 | void arch_sync_dma_for_device(phys_addr_t addr, size_t size, |
| 99 | enum dma_data_direction dir) | 96 | enum dma_data_direction dir) |
| 100 | { | 97 | { |
| 101 | unsigned long cl; | ||
| 102 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; | ||
| 103 | |||
| 104 | switch (dir) { | 98 | switch (dir) { |
| 105 | case DMA_TO_DEVICE: | 99 | case DMA_TO_DEVICE: |
| 106 | /* Flush the dcache for the requested range */ | 100 | /* Flush the dcache for the requested range */ |
| 107 | for (cl = addr; cl < addr + size; | 101 | local_dcache_range_flush(addr, addr + size); |
| 108 | cl += cpuinfo->dcache_block_size) | ||
| 109 | mtspr(SPR_DCBFR, cl); | ||
| 110 | break; | 102 | break; |
| 111 | case DMA_FROM_DEVICE: | 103 | case DMA_FROM_DEVICE: |
| 112 | /* Invalidate the dcache for the requested range */ | 104 | /* Invalidate the dcache for the requested range */ |
| 113 | for (cl = addr; cl < addr + size; | 105 | local_dcache_range_inv(addr, addr + size); |
| 114 | cl += cpuinfo->dcache_block_size) | ||
| 115 | mtspr(SPR_DCBIR, cl); | ||
| 116 | break; | 106 | break; |
| 117 | default: | 107 | default: |
| 118 | /* | 108 | /* |
| @@ -113,21 +113,6 @@ static void print_cpuinfo(void) · 112 unmodified lines | |||
| 113 | return; | 113 | return; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (upr & SPR_UPR_DCP) | ||
| 117 | printk(KERN_INFO | ||
| 118 | "-- dcache: %4d bytes total, %2d bytes/line, %d way(s)\n", | ||
| 119 | cpuinfo->dcache_size, cpuinfo->dcache_block_size, | ||
| 120 | cpuinfo->dcache_ways); | ||
| 121 | else | ||
| 122 | printk(KERN_INFO "-- dcache disabled\n"); | ||
| 123 | if (upr & SPR_UPR_ICP) | ||
| 124 | printk(KERN_INFO | ||
| 125 | "-- icache: %4d bytes total, %2d bytes/line, %d way(s)\n", | ||
| 126 | cpuinfo->icache_size, cpuinfo->icache_block_size, | ||
| 127 | cpuinfo->icache_ways); | ||
| 128 | else | ||
| 129 | printk(KERN_INFO "-- icache disabled\n"); | ||
| 130 | |||
| 131 | if (upr & SPR_UPR_DMP) | 116 | if (upr & SPR_UPR_DMP) |
| 132 | printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n", | 117 | printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n", |
| 133 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), | 118 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), |
| @@ -155,8 +140,6 @@ static void print_cpuinfo(void) · 21 unmodified lines | |||
| 155 | void __init setup_cpuinfo(void) | 140 | void __init setup_cpuinfo(void) |
| 156 | { | 141 | { |
| 157 | struct device_node *cpu; | 142 | struct device_node *cpu; |
| 158 | unsigned long iccfgr, dccfgr; | ||
| 159 | unsigned long cache_set_size; | ||
| 160 | int cpu_id = smp_processor_id(); | 143 | int cpu_id = smp_processor_id(); |
| 161 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[cpu_id]; | 144 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[cpu_id]; |
| 162 | 145 | ||
| @@ -164,20 +147,6 @@ void __init setup_cpuinfo(void) · 1 unmodified line | |||
| 164 | if (!cpu) | 147 | if (!cpu) |
| 165 | panic("Couldn't find CPU%d in device tree...\n", cpu_id); | 148 | panic("Couldn't find CPU%d in device tree...\n", cpu_id); |
| 166 | 149 | ||
| 167 | iccfgr = mfspr(SPR_ICCFGR); | ||
| 168 | cpuinfo->icache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW); | ||
| 169 | cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); | ||
| 170 | cpuinfo->icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7); | ||
| 171 | cpuinfo->icache_size = | ||
| 172 | cache_set_size * cpuinfo->icache_ways * cpuinfo->icache_block_size; | ||
| 173 | |||
| 174 | dccfgr = mfspr(SPR_DCCFGR); | ||
| 175 | cpuinfo->dcache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW); | ||
| 176 | cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); | ||
| 177 | cpuinfo->dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7); | ||
| 178 | cpuinfo->dcache_size = | ||
| 179 | cache_set_size * cpuinfo->dcache_ways * cpuinfo->dcache_block_size; | ||
| 180 | |||
| 181 | if (of_property_read_u32(cpu, "clock-frequency", | 150 | if (of_property_read_u32(cpu, "clock-frequency", |
| 182 | &cpuinfo->clock_frequency)) { | 151 | &cpuinfo->clock_frequency)) { |
| 183 | printk(KERN_WARNING | 152 | printk(KERN_WARNING |
| @@ -294,14 +263,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 110 unmodified lines | |||
| 294 | unsigned int vr, cpucfgr; | 263 | unsigned int vr, cpucfgr; |
| 295 | unsigned int avr; | 264 | unsigned int avr; |
| 296 | unsigned int version; | 265 | unsigned int version; |
| 266 | #ifdef CONFIG_SMP | ||
| 297 | struct cpuinfo_or1k *cpuinfo = v; | 267 | struct cpuinfo_or1k *cpuinfo = v; |
| 268 | seq_printf(m, "processor\t\t: %d\n", cpuinfo->coreid); | ||
| 269 | #endif | ||
| 298 | 270 | ||
| 299 | vr = mfspr(SPR_VR); | 271 | vr = mfspr(SPR_VR); |
| 300 | cpucfgr = mfspr(SPR_CPUCFGR); | 272 | cpucfgr = mfspr(SPR_CPUCFGR); |
| 301 | 273 | ||
| 302 | #ifdef CONFIG_SMP | ||
| 303 | seq_printf(m, "processor\t\t: %d\n", cpuinfo->coreid); | ||
| 304 | #endif | ||
| 305 | if (vr & SPR_VR_UVRP) { | 274 | if (vr & SPR_VR_UVRP) { |
| 306 | vr = mfspr(SPR_VR2); | 275 | vr = mfspr(SPR_VR2); |
| 307 | version = vr & SPR_VR2_VER; | 276 | version = vr & SPR_VR2_VER; |
| @@ -320,14 +289,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 12 unmodified lines | |||
| 320 | seq_printf(m, "revision\t\t: %d\n", vr & SPR_VR_REV); | 289 | seq_printf(m, "revision\t\t: %d\n", vr & SPR_VR_REV); |
| 321 | } | 290 | } |
| 322 | seq_printf(m, "frequency\t\t: %ld\n", loops_per_jiffy * HZ); | 291 | seq_printf(m, "frequency\t\t: %ld\n", loops_per_jiffy * HZ); |
| 323 | seq_printf(m, "dcache size\t\t: %d bytes\n", cpuinfo->dcache_size); | ||
| 324 | seq_printf(m, "dcache block size\t: %d bytes\n", | ||
| 325 | cpuinfo->dcache_block_size); | ||
| 326 | seq_printf(m, "dcache ways\t\t: %d\n", cpuinfo->dcache_ways); | ||
| 327 | seq_printf(m, "icache size\t\t: %d bytes\n", cpuinfo->icache_size); | ||
| 328 | seq_printf(m, "icache block size\t: %d bytes\n", | ||
| 329 | cpuinfo->icache_block_size); | ||
| 330 | seq_printf(m, "icache ways\t\t: %d\n", cpuinfo->icache_ways); | ||
| 331 | seq_printf(m, "immu\t\t\t: %d entries, %lu ways\n", | 292 | seq_printf(m, "immu\t\t\t: %d entries, %lu ways\n", |
| 332 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), | 293 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), |
| 333 | 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW)); | 294 | 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW)); |
| @@ -14,31 +14,70 @@ · 13 unmodified lines | |||
| 14 | #include <asm/spr_defs.h> | 14 | #include <asm/spr_defs.h> |
| 15 | #include <asm/cache.h> | 15 | #include <asm/cache.h> |
| 16 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
| 17 | #include <asm/cpuinfo.h> | ||
| 17 | #include <asm/tlbflush.h> | 18 | #include <asm/tlbflush.h> |
| 18 | 19 | ||
| 19 | static __always_inline void cache_loop(struct page *page, const unsigned int reg) | 20 | /* |
| 21 | * Check if the cache component exists. | ||
| 22 | */ | ||
| 23 | bool cpu_cache_is_present(const unsigned int cache_type) | ||
| 20 | { | 24 | { |
| 21 | unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT; | 25 | unsigned long upr = mfspr(SPR_UPR); |
| 22 | unsigned long line = paddr & ~(L1_CACHE_BYTES - 1); | 26 | unsigned long mask = SPR_UPR_UP | cache_type; |
| 27 | |||
| 28 | return !((upr & mask) ^ mask); | ||
| 29 | } | ||
| 30 | |||
| 31 | static __always_inline void cache_loop(unsigned long paddr, unsigned long end, | ||
| 32 | const unsigned short reg, const unsigned int cache_type) | ||
| 33 | { | ||
| 34 | if (!cpu_cache_is_present(cache_type)) | ||
| 35 | return; | ||
| 23 | 36 | ||
| 24 | while (line < paddr + PAGE_SIZE) { | 37 | while (paddr < end) { |
| 25 | mtspr(reg, line); | 38 | mtspr(reg, paddr); |
| 26 | line += L1_CACHE_BYTES; | 39 | paddr += L1_CACHE_BYTES; |
| 27 | } | 40 | } |
| 28 | } | 41 | } |
| 29 | 42 | ||
| 43 | static __always_inline void cache_loop_page(struct page *page, const unsigned short reg, | ||
| 44 | const unsigned int cache_type) | ||
| 45 | { | ||
| 46 | unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT; | ||
| 47 | unsigned long end = paddr + PAGE_SIZE; | ||
| 48 | |||
| 49 | paddr &= ~(L1_CACHE_BYTES - 1); | ||
| 50 | |||
| 51 | cache_loop(paddr, end, reg, cache_type); | ||
| 52 | } | ||
| 53 | |||
| 30 | void local_dcache_page_flush(struct page *page) | 54 | void local_dcache_page_flush(struct page *page) |
| 31 | { | 55 | { |
| 32 | cache_loop(page, SPR_DCBFR); | 56 | cache_loop_page(page, SPR_DCBFR, SPR_UPR_DCP); |
| 33 | } | 57 | } |
| 34 | EXPORT_SYMBOL(local_dcache_page_flush); | 58 | EXPORT_SYMBOL(local_dcache_page_flush); |
| 35 | 59 | ||
| 36 | void local_icache_page_inv(struct page *page) | 60 | void local_icache_page_inv(struct page *page) |
| 37 | { | 61 | { |
| 38 | cache_loop(page, SPR_ICBIR); | 62 | cache_loop_page(page, SPR_ICBIR, SPR_UPR_ICP); |
| 39 | } | 63 | } |
| 40 | EXPORT_SYMBOL(local_icache_page_inv); | 64 | EXPORT_SYMBOL(local_icache_page_inv); |
| 41 | 65 | ||
| 66 | void local_dcache_range_flush(unsigned long start, unsigned long end) | ||
| 67 | { | ||
| 68 | cache_loop(start, end, SPR_DCBFR, SPR_UPR_DCP); | ||
| 69 | } | ||
| 70 | |||
| 71 | void local_dcache_range_inv(unsigned long start, unsigned long end) | ||
| 72 | { | ||
| 73 | cache_loop(start, end, SPR_DCBIR, SPR_UPR_DCP); | ||
| 74 | } | ||
| 75 | |||
| 76 | void local_icache_range_inv(unsigned long start, unsigned long end) | ||
| 77 | { | ||
| 78 | cache_loop(start, end, SPR_ICBIR, SPR_UPR_ICP); | ||
| 79 | } | ||
| 80 | |||
| 42 | void update_cache(struct vm_area_struct *vma, unsigned long address, | 81 | void update_cache(struct vm_area_struct *vma, unsigned long address, |
| 43 | pte_t *pte) | 82 | pte_t *pte) |
| 44 | { | 83 | { |
| @@ -58,4 +97,3 @@ void update_cache(struct vm_area_struct *vma, unsigned long address, · 13 unmodified lines | |||
| 58 | sync_icache_dcache(folio_page(folio, nr)); | 97 | sync_icache_dcache(folio_page(folio, nr)); |
| 59 | } | 98 | } |
| 60 | } | 99 | } |
| 61 | |||
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <asm/fixmap.h> | 35 | #include <asm/fixmap.h> |
| 36 | #include <asm/tlbflush.h> | 36 | #include <asm/tlbflush.h> |
| 37 | #include <asm/sections.h> | 37 | #include <asm/sections.h> |
| 38 | #include <asm/cacheflush.h> | ||
| 38 | 39 | ||
| 39 | int mem_init_done; | 40 | int mem_init_done; |
| 40 | 41 | ||
| @@ -176,8 +177,8 @@ void __init paging_init(void) · 135 unmodified lines | |||
| 176 | barrier(); | 177 | barrier(); |
| 177 | 178 | ||
| 178 | /* Invalidate instruction caches after code modification */ | 179 | /* Invalidate instruction caches after code modification */ |
| 179 | mtspr(SPR_ICBIR, 0x900); | 180 | local_icache_block_inv(0x900); |
| 180 | mtspr(SPR_ICBIR, 0xa00); | 181 | local_icache_block_inv(0xa00); |
| 181 | 182 | ||
| 182 | /* New TLB miss handlers and kernel page tables are in now place. | 183 | /* New TLB miss handlers and kernel page tables are in now place. |
| 183 | * Make sure that page flags get updated for all pages in TLB by | 184 | * Make sure that page flags get updated for all pages in TLB by |
| @@ -264,8 +264,6 @@ CONFIG_CRYPTO_MICHAEL_MIC=m · 263 unmodified lines | |||
| 264 | CONFIG_CRYPTO_SHA1=y | 264 | CONFIG_CRYPTO_SHA1=y |
| 265 | CONFIG_CRYPTO_WP512=m | 265 | CONFIG_CRYPTO_WP512=m |
| 266 | CONFIG_CRYPTO_DEFLATE=y | 266 | CONFIG_CRYPTO_DEFLATE=y |
| 267 | CONFIG_CRC_CCITT=m | ||
| 268 | CONFIG_CRC_T10DIF=y | ||
| 269 | CONFIG_FONTS=y | 267 | CONFIG_FONTS=y |
| 270 | CONFIG_PRINTK_TIME=y | 268 | CONFIG_PRINTK_TIME=y |
| 271 | CONFIG_MAGIC_SYSRQ=y | 269 | CONFIG_MAGIC_SYSRQ=y |
| @@ -292,7 +292,6 @@ CONFIG_CRYPTO_MD5=y · 291 unmodified lines | |||
| 292 | CONFIG_CRYPTO_MICHAEL_MIC=m | 292 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 293 | CONFIG_CRYPTO_DEFLATE=m | 293 | CONFIG_CRYPTO_DEFLATE=m |
| 294 | # CONFIG_CRYPTO_HW is not set | 294 | # CONFIG_CRYPTO_HW is not set |
| 295 | CONFIG_CRC_CCITT=m | ||
| 296 | CONFIG_PRINTK_TIME=y | 295 | CONFIG_PRINTK_TIME=y |
| 297 | CONFIG_DEBUG_KERNEL=y | 296 | CONFIG_DEBUG_KERNEL=y |
| 298 | CONFIG_STRIP_ASM_SYMS=y | 297 | CONFIG_STRIP_ASM_SYMS=y |
| @@ -97,9 +97,19 @@ handle_fpe(struct pt_regs *regs) · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | memcpy(regs->fr, frcopy, sizeof regs->fr); | 98 | memcpy(regs->fr, frcopy, sizeof regs->fr); |
| 99 | if (signalcode != 0) { | 99 | if (signalcode != 0) { |
| 100 | force_sig_fault(signalcode >> 24, signalcode & 0xffffff, | 100 | int sig = signalcode >> 24; |
| 101 | (void __user *) regs->iaoq[0]); | 101 | |
| 102 | return -1; | 102 | if (sig == SIGFPE) { |
| 103 | /* | ||
| 104 | * Clear floating point trap bit to avoid trapping | ||
| 105 | * again on the first floating-point instruction in | ||
| 106 | * the userspace signal handler. | ||
| 107 | */ | ||
| 108 | regs->fr[0] &= ~(1ULL << 38); | ||
| 109 | } | ||
| 110 | force_sig_fault(sig, signalcode & 0xffffff, | ||
| 111 | (void __user *) regs->iaoq[0]); | ||
| 112 | return -1; | ||
| 103 | } | 113 | } |
| 104 | 114 | ||
| 105 | return signalcode ? -1 : 0; | 115 | return signalcode ? -1 : 0; |
| @@ -234,10 +234,8 @@ fi · 233 unmodified lines | |||
| 234 | 234 | ||
| 235 | # suppress some warnings in recent ld versions | 235 | # suppress some warnings in recent ld versions |
| 236 | nowarn="-z noexecstack" | 236 | nowarn="-z noexecstack" |
| 237 | if ! ld_is_lld; then | 237 | if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then |
| 238 | if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then | 238 | nowarn="$nowarn --no-warn-rwx-segments" |
| 239 | nowarn="$nowarn --no-warn-rwx-segments" | ||
| 240 | fi | ||
| 241 | fi | 239 | fi |
| 242 | 240 | ||
| 243 | platformo=$object/"$platform".o | 241 | platformo=$object/"$platform".o |
| @@ -91,5 +91,4 @@ CONFIG_AFFS_FS=m · 90 unmodified lines | |||
| 91 | # CONFIG_NETWORK_FILESYSTEMS is not set | 91 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 92 | CONFIG_NLS_CODEPAGE_437=y | 92 | CONFIG_NLS_CODEPAGE_437=y |
| 93 | CONFIG_NLS_ISO8859_1=y | 93 | CONFIG_NLS_ISO8859_1=y |
| 94 | CONFIG_CRC_T10DIF=y | ||
| 95 | CONFIG_MAGIC_SYSRQ=y | 94 | CONFIG_MAGIC_SYSRQ=y |
| @@ -85,8 +85,6 @@ CONFIG_NLS_ASCII=y · 84 unmodified lines | |||
| 85 | CONFIG_NLS_ISO8859_1=y | 85 | CONFIG_NLS_ISO8859_1=y |
| 86 | CONFIG_NLS_ISO8859_15=y | 86 | CONFIG_NLS_ISO8859_15=y |
| 87 | CONFIG_NLS_UTF8=y | 87 | CONFIG_NLS_UTF8=y |
| 88 | CONFIG_CRC_CCITT=y | ||
| 89 | CONFIG_CRC_T10DIF=y | ||
| 90 | CONFIG_PRINTK_TIME=y | 88 | CONFIG_PRINTK_TIME=y |
| 91 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 89 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 92 | CONFIG_DEBUG_FS=y | 90 | CONFIG_DEBUG_FS=y |
| @@ -73,6 +73,5 @@ CONFIG_NLS_CODEPAGE_437=y · 72 unmodified lines | |||
| 73 | CONFIG_NLS_CODEPAGE_932=y | 73 | CONFIG_NLS_CODEPAGE_932=y |
| 74 | CONFIG_NLS_ISO8859_8=y | 74 | CONFIG_NLS_ISO8859_8=y |
| 75 | CONFIG_NLS_ISO8859_1=y | 75 | CONFIG_NLS_ISO8859_1=y |
| 76 | CONFIG_CRC_T10DIF=y | ||
| 77 | CONFIG_CRYPTO_ECB=m | 76 | CONFIG_CRYPTO_ECB=m |
| 78 | CONFIG_CRYPTO_PCBC=m | 77 | CONFIG_CRYPTO_PCBC=m |
| @@ -80,5 +80,4 @@ CONFIG_TMPFS=y · 79 unmodified lines | |||
| 80 | CONFIG_NFS_FS=y | 80 | CONFIG_NFS_FS=y |
| 81 | CONFIG_NFS_V4=y | 81 | CONFIG_NFS_V4=y |
| 82 | CONFIG_ROOT_NFS=y | 82 | CONFIG_ROOT_NFS=y |
| 83 | CONFIG_CRC_T10DIF=y | ||
| 84 | CONFIG_CRYPTO_PCBC=m | 83 | CONFIG_CRYPTO_PCBC=m |
| @@ -72,5 +72,4 @@ CONFIG_TMPFS=y · 71 unmodified lines | |||
| 72 | CONFIG_NFS_FS=y | 72 | CONFIG_NFS_FS=y |
| 73 | CONFIG_NFS_V4=y | 73 | CONFIG_NFS_V4=y |
| 74 | CONFIG_ROOT_NFS=y | 74 | CONFIG_ROOT_NFS=y |
| 75 | CONFIG_CRC_T10DIF=y | ||
| 76 | CONFIG_CRYPTO_PCBC=m | 75 | CONFIG_CRYPTO_PCBC=m |
| @@ -75,6 +75,5 @@ CONFIG_TMPFS=y · 74 unmodified lines | |||
| 75 | CONFIG_NFS_FS=y | 75 | CONFIG_NFS_FS=y |
| 76 | CONFIG_NFS_V4=y | 76 | CONFIG_NFS_V4=y |
| 77 | CONFIG_ROOT_NFS=y | 77 | CONFIG_ROOT_NFS=y |
| 78 | CONFIG_CRC_T10DIF=y | ||
| 79 | CONFIG_CRYPTO_ECB=m | 78 | CONFIG_CRYPTO_ECB=m |
| 80 | CONFIG_CRYPTO_PCBC=m | 79 | CONFIG_CRYPTO_PCBC=m |
| @@ -221,8 +221,6 @@ CONFIG_NLS_ISO8859_15=y · 220 unmodified lines | |||
| 221 | CONFIG_NLS_KOI8_R=m | 221 | CONFIG_NLS_KOI8_R=m |
| 222 | CONFIG_NLS_KOI8_U=m | 222 | CONFIG_NLS_KOI8_U=m |
| 223 | CONFIG_NLS_UTF8=y | 223 | CONFIG_NLS_UTF8=y |
| 224 | CONFIG_CRC_CCITT=y | ||
| 225 | CONFIG_CRC_T10DIF=y | ||
| 226 | CONFIG_MAGIC_SYSRQ=y | 224 | CONFIG_MAGIC_SYSRQ=y |
| 227 | CONFIG_CRYPTO_CBC=y | 225 | CONFIG_CRYPTO_CBC=y |
| 228 | CONFIG_CRYPTO_MD5=y | 226 | CONFIG_CRYPTO_MD5=y |
| @@ -60,8 +60,6 @@ CONFIG_CRAMFS=m · 59 unmodified lines | |||
| 60 | CONFIG_NFS_FS=y | 60 | CONFIG_NFS_FS=y |
| 61 | CONFIG_ROOT_NFS=y | 61 | CONFIG_ROOT_NFS=y |
| 62 | CONFIG_NLS=y | 62 | CONFIG_NLS=y |
| 63 | CONFIG_CRC_CCITT=y | ||
| 64 | CONFIG_CRC_T10DIF=m | ||
| 65 | CONFIG_DETECT_HUNG_TASK=y | 63 | CONFIG_DETECT_HUNG_TASK=y |
| 66 | # CONFIG_DEBUG_BUGVERBOSE is not set | 64 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 67 | CONFIG_BDI_SWITCH=y | 65 | CONFIG_BDI_SWITCH=y |
| @@ -132,7 +132,6 @@ CONFIG_ROOT_NFS=y · 131 unmodified lines | |||
| 132 | CONFIG_NFSD=y | 132 | CONFIG_NFSD=y |
| 133 | CONFIG_NLS_CODEPAGE_437=y | 133 | CONFIG_NLS_CODEPAGE_437=y |
| 134 | CONFIG_NLS_ISO8859_1=y | 134 | CONFIG_NLS_ISO8859_1=y |
| 135 | CONFIG_CRC_T10DIF=y | ||
| 136 | CONFIG_DETECT_HUNG_TASK=y | 135 | CONFIG_DETECT_HUNG_TASK=y |
| 137 | # CONFIG_DEBUG_BUGVERBOSE is not set | 136 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 138 | CONFIG_CRYPTO_HMAC=y | 137 | CONFIG_CRYPTO_HMAC=y |
| @@ -5,7 +5,6 @@ CONFIG_BROADCOM_PHY=y · 4 unmodified lines | |||
| 5 | # CONFIG_CARDBUS is not set | 5 | # CONFIG_CARDBUS is not set |
| 6 | CONFIG_CHR_DEV_SG=y | 6 | CONFIG_CHR_DEV_SG=y |
| 7 | CONFIG_CHR_DEV_ST=y | 7 | CONFIG_CHR_DEV_ST=y |
| 8 | CONFIG_CRC_T10DIF=y | ||
| 9 | CONFIG_CRYPTO_HMAC=y | 8 | CONFIG_CRYPTO_HMAC=y |
| 10 | CONFIG_DS1682=y | 9 | CONFIG_DS1682=y |
| 11 | CONFIG_EEPROM_LEGACY=y | 10 | CONFIG_EEPROM_LEGACY=y |
| @@ -106,7 +106,6 @@ CONFIG_TMPFS=y · 105 unmodified lines | |||
| 106 | CONFIG_AFFS_FS=m | 106 | CONFIG_AFFS_FS=m |
| 107 | CONFIG_NLS_ASCII=y | 107 | CONFIG_NLS_ASCII=y |
| 108 | CONFIG_NLS_ISO8859_1=m | 108 | CONFIG_NLS_ISO8859_1=m |
| 109 | CONFIG_CRC_T10DIF=y | ||
| 110 | CONFIG_MAGIC_SYSRQ=y | 109 | CONFIG_MAGIC_SYSRQ=y |
| 111 | CONFIG_DEBUG_KERNEL=y | 110 | CONFIG_DEBUG_KERNEL=y |
| 112 | CONFIG_DEBUG_MUTEXES=y | 111 | CONFIG_DEBUG_MUTEXES=y |
| @@ -110,7 +110,6 @@ CONFIG_PROC_KCORE=y · 109 unmodified lines | |||
| 110 | CONFIG_TMPFS=y | 110 | CONFIG_TMPFS=y |
| 111 | CONFIG_NLS_ASCII=y | 111 | CONFIG_NLS_ASCII=y |
| 112 | CONFIG_NLS_ISO8859_1=m | 112 | CONFIG_NLS_ISO8859_1=m |
| 113 | CONFIG_CRC_T10DIF=y | ||
| 114 | CONFIG_MAGIC_SYSRQ=y | 113 | CONFIG_MAGIC_SYSRQ=y |
| 115 | CONFIG_DEBUG_KERNEL=y | 114 | CONFIG_DEBUG_KERNEL=y |
| 116 | CONFIG_DEBUG_MUTEXES=y | 115 | CONFIG_DEBUG_MUTEXES=y |
| @@ -15,7 +15,6 @@ CONFIG_CGROUP_CPUACCT=y · 14 unmodified lines | |||
| 15 | CONFIG_CGROUP_SCHED=y | 15 | CONFIG_CGROUP_SCHED=y |
| 16 | CONFIG_CGROUPS=y | 16 | CONFIG_CGROUPS=y |
| 17 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 17 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 18 | CONFIG_CRC_T10DIF=y | ||
| 19 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
| 20 | CONFIG_CRAMFS=y | 19 | CONFIG_CRAMFS=y |
| 21 | CONFIG_CRYPTO_MD4=y | 20 | CONFIG_CRYPTO_MD4=y |
| @@ -231,7 +231,6 @@ CONFIG_NLS_ASCII=y · 230 unmodified lines | |||
| 231 | CONFIG_NLS_ISO8859_1=y | 231 | CONFIG_NLS_ISO8859_1=y |
| 232 | CONFIG_NLS_ISO8859_15=y | 232 | CONFIG_NLS_ISO8859_15=y |
| 233 | CONFIG_NLS_UTF8=y | 233 | CONFIG_NLS_UTF8=y |
| 234 | CONFIG_CRC_T10DIF=y | ||
| 235 | CONFIG_MAGIC_SYSRQ=y | 234 | CONFIG_MAGIC_SYSRQ=y |
| 236 | CONFIG_DEBUG_KERNEL=y | 235 | CONFIG_DEBUG_KERNEL=y |
| 237 | CONFIG_DEBUG_MUTEXES=y | 236 | CONFIG_DEBUG_MUTEXES=y |
| @@ -82,7 +82,6 @@ CONFIG_ROOT_NFS=y · 81 unmodified lines | |||
| 82 | CONFIG_CIFS=y | 82 | CONFIG_CIFS=y |
| 83 | CONFIG_NLS_CODEPAGE_437=y | 83 | CONFIG_NLS_CODEPAGE_437=y |
| 84 | CONFIG_NLS_ISO8859_1=y | 84 | CONFIG_NLS_ISO8859_1=y |
| 85 | CONFIG_CRC_CCITT=y | ||
| 86 | CONFIG_PRINTK_TIME=y | 85 | CONFIG_PRINTK_TIME=y |
| 87 | CONFIG_DEBUG_SPINLOCK=y | 86 | CONFIG_DEBUG_SPINLOCK=y |
| 88 | CONFIG_DEBUG_MUTEXES=y | 87 | CONFIG_DEBUG_MUTEXES=y |
| @@ -125,8 +125,6 @@ CONFIG_NLS_CODEPAGE_437=m · 124 unmodified lines | |||
| 125 | CONFIG_NLS_CODEPAGE_932=m | 125 | CONFIG_NLS_CODEPAGE_932=m |
| 126 | CONFIG_NLS_ISO8859_1=m | 126 | CONFIG_NLS_ISO8859_1=m |
| 127 | CONFIG_NLS_UTF8=m | 127 | CONFIG_NLS_UTF8=m |
| 128 | CONFIG_CRC_CCITT=m | ||
| 129 | CONFIG_CRC_T10DIF=y | ||
| 130 | CONFIG_MAGIC_SYSRQ=y | 128 | CONFIG_MAGIC_SYSRQ=y |
| 131 | CONFIG_DEBUG_KERNEL=y | 129 | CONFIG_DEBUG_KERNEL=y |
| 132 | CONFIG_DETECT_HUNG_TASK=y | 130 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -97,7 +97,6 @@ CONFIG_TMPFS=y · 96 unmodified lines | |||
| 97 | CONFIG_NFS_FS=y | 97 | CONFIG_NFS_FS=y |
| 98 | CONFIG_NFS_V4=y | 98 | CONFIG_NFS_V4=y |
| 99 | CONFIG_ROOT_NFS=y | 99 | CONFIG_ROOT_NFS=y |
| 100 | CONFIG_CRC_T10DIF=y | ||
| 101 | CONFIG_CRYPTO_ECB=m | 100 | CONFIG_CRYPTO_ECB=m |
| 102 | CONFIG_CRYPTO_PCBC=m | 101 | CONFIG_CRYPTO_PCBC=m |
| 103 | CONFIG_CRYPTO_SHA512=y | 102 | CONFIG_CRYPTO_SHA512=y |
| @@ -38,4 +38,3 @@ CONFIG_TMPFS=y · 37 unmodified lines | |||
| 38 | CONFIG_CRAMFS=y | 38 | CONFIG_CRAMFS=y |
| 39 | CONFIG_NFS_FS=y | 39 | CONFIG_NFS_FS=y |
| 40 | CONFIG_ROOT_NFS=y | 40 | CONFIG_ROOT_NFS=y |
| 41 | CONFIG_CRC_CCITT=y | ||
| @@ -107,8 +107,6 @@ CONFIG_NLS_CODEPAGE_437=m · 106 unmodified lines | |||
| 107 | CONFIG_NLS_CODEPAGE_932=m | 107 | CONFIG_NLS_CODEPAGE_932=m |
| 108 | CONFIG_NLS_ISO8859_1=m | 108 | CONFIG_NLS_ISO8859_1=m |
| 109 | CONFIG_NLS_UTF8=m | 109 | CONFIG_NLS_UTF8=m |
| 110 | CONFIG_CRC_CCITT=m | ||
| 111 | CONFIG_CRC_T10DIF=y | ||
| 112 | CONFIG_XZ_DEC=y | 110 | CONFIG_XZ_DEC=y |
| 113 | CONFIG_MAGIC_SYSRQ=y | 111 | CONFIG_MAGIC_SYSRQ=y |
| 114 | CONFIG_DEBUG_KERNEL=y | 112 | CONFIG_DEBUG_KERNEL=y |
| @@ -159,7 +159,6 @@ CONFIG_NFSD=y · 158 unmodified lines | |||
| 159 | CONFIG_NFSD_V4=y | 159 | CONFIG_NFSD_V4=y |
| 160 | CONFIG_NLS_CODEPAGE_437=y | 160 | CONFIG_NLS_CODEPAGE_437=y |
| 161 | CONFIG_NLS_ISO8859_1=y | 161 | CONFIG_NLS_ISO8859_1=y |
| 162 | CONFIG_CRC_CCITT=y | ||
| 163 | CONFIG_PRINTK_TIME=y | 162 | CONFIG_PRINTK_TIME=y |
| 164 | CONFIG_MAGIC_SYSRQ=y | 163 | CONFIG_MAGIC_SYSRQ=y |
| 165 | CONFIG_DEBUG_KERNEL=y | 164 | CONFIG_DEBUG_KERNEL=y |
| @@ -276,7 +276,6 @@ CONFIG_NFSD_V3_ACL=y · 275 unmodified lines | |||
| 276 | CONFIG_NFSD_V4=y | 276 | CONFIG_NFSD_V4=y |
| 277 | CONFIG_NLS_CODEPAGE_437=m | 277 | CONFIG_NLS_CODEPAGE_437=m |
| 278 | CONFIG_NLS_ISO8859_1=m | 278 | CONFIG_NLS_ISO8859_1=m |
| 279 | CONFIG_CRC_T10DIF=y | ||
| 280 | CONFIG_MAGIC_SYSRQ=y | 279 | CONFIG_MAGIC_SYSRQ=y |
| 281 | CONFIG_DEBUG_KERNEL=y | 280 | CONFIG_DEBUG_KERNEL=y |
| 282 | CONFIG_DETECT_HUNG_TASK=y | 281 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -90,7 +90,6 @@ CONFIG_NFS_FS=y · 89 unmodified lines | |||
| 90 | CONFIG_ROOT_NFS=y | 90 | CONFIG_ROOT_NFS=y |
| 91 | CONFIG_NLS_CODEPAGE_437=m | 91 | CONFIG_NLS_CODEPAGE_437=m |
| 92 | CONFIG_NLS_ISO8859_1=m | 92 | CONFIG_NLS_ISO8859_1=m |
| 93 | CONFIG_CRC_T10DIF=m | ||
| 94 | CONFIG_MAGIC_SYSRQ=y | 93 | CONFIG_MAGIC_SYSRQ=y |
| 95 | CONFIG_DETECT_HUNG_TASK=y | 94 | CONFIG_DETECT_HUNG_TASK=y |
| 96 | CONFIG_CRYPTO_ECB=y | 95 | CONFIG_CRYPTO_ECB=y |
| @@ -207,7 +207,6 @@ CONFIG_NLS_CODEPAGE_437=y · 206 unmodified lines | |||
| 207 | CONFIG_NLS_ASCII=y | 207 | CONFIG_NLS_ASCII=y |
| 208 | CONFIG_NLS_ISO8859_1=y | 208 | CONFIG_NLS_ISO8859_1=y |
| 209 | CONFIG_NLS_UTF8=y | 209 | CONFIG_NLS_UTF8=y |
| 210 | CONFIG_CRC_T10DIF=y | ||
| 211 | CONFIG_MAGIC_SYSRQ=y | 210 | CONFIG_MAGIC_SYSRQ=y |
| 212 | CONFIG_DEBUG_KERNEL=y | 211 | CONFIG_DEBUG_KERNEL=y |
| 213 | CONFIG_DEBUG_STACK_USAGE=y | 212 | CONFIG_DEBUG_STACK_USAGE=y |
| @@ -148,8 +148,6 @@ CONFIG_NLS_ISO8859_1=y · 147 unmodified lines | |||
| 148 | CONFIG_CRYPTO_PCBC=m | 148 | CONFIG_CRYPTO_PCBC=m |
| 149 | CONFIG_CRYPTO_MICHAEL_MIC=m | 149 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 150 | CONFIG_CRYPTO_LZO=m | 150 | CONFIG_CRYPTO_LZO=m |
| 151 | CONFIG_CRC_CCITT=m | ||
| 152 | CONFIG_CRC_T10DIF=y | ||
| 153 | CONFIG_PRINTK_TIME=y | 151 | CONFIG_PRINTK_TIME=y |
| 154 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 152 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 155 | CONFIG_MAGIC_SYSRQ=y | 153 | CONFIG_MAGIC_SYSRQ=y |
| @@ -278,8 +278,6 @@ CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY=y · 277 unmodified lines | |||
| 278 | # CONFIG_INTEGRITY is not set | 278 | # CONFIG_INTEGRITY is not set |
| 279 | CONFIG_LSM="yama,loadpin,safesetid,integrity" | 279 | CONFIG_LSM="yama,loadpin,safesetid,integrity" |
| 280 | # CONFIG_CRYPTO_HW is not set | 280 | # CONFIG_CRYPTO_HW is not set |
| 281 | CONFIG_CRC16=y | ||
| 282 | CONFIG_CRC_ITU_T=y | ||
| 283 | # CONFIG_XZ_DEC_X86 is not set | 281 | # CONFIG_XZ_DEC_X86 is not set |
| 284 | # CONFIG_XZ_DEC_IA64 is not set | 282 | # CONFIG_XZ_DEC_IA64 is not set |
| 285 | # CONFIG_XZ_DEC_ARM is not set | 283 | # CONFIG_XZ_DEC_ARM is not set |
| @@ -75,4 +75,3 @@ CONFIG_NLS_DEFAULT="utf8" · 74 unmodified lines | |||
| 75 | CONFIG_NLS_CODEPAGE_437=y | 75 | CONFIG_NLS_CODEPAGE_437=y |
| 76 | CONFIG_NLS_ISO8859_1=y | 76 | CONFIG_NLS_ISO8859_1=y |
| 77 | CONFIG_NLS_UTF8=y | 77 | CONFIG_NLS_UTF8=y |
| 78 | CONFIG_CRC_T10DIF=y | ||
| @@ -114,7 +114,6 @@ CONFIG_ROOT_NFS=y · 113 unmodified lines | |||
| 114 | CONFIG_CIFS=m | 114 | CONFIG_CIFS=m |
| 115 | CONFIG_NLS_CODEPAGE_437=y | 115 | CONFIG_NLS_CODEPAGE_437=y |
| 116 | CONFIG_NLS_ISO8859_1=y | 116 | CONFIG_NLS_ISO8859_1=y |
| 117 | CONFIG_CRC_CCITT=y | ||
| 118 | CONFIG_PRINTK_TIME=y | 117 | CONFIG_PRINTK_TIME=y |
| 119 | CONFIG_MAGIC_SYSRQ=y | 118 | CONFIG_MAGIC_SYSRQ=y |
| 120 | CONFIG_DEBUG_SPINLOCK=y | 119 | CONFIG_DEBUG_SPINLOCK=y |
| @@ -258,10 +258,6 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, · 257 unmodified lines | |||
| 258 | break; | 258 | break; |
| 259 | } | 259 | } |
| 260 | } | 260 | } |
| 261 | if (i == hdr->e_shnum) { | ||
| 262 | pr_err("%s: doesn't contain __patchable_function_entries.\n", me->name); | ||
| 263 | return -ENOEXEC; | ||
| 264 | } | ||
| 265 | #endif | 261 | #endif |
| 266 | 262 | ||
| 267 | pr_debug("Looks like a total of %lu stubs, max\n", relocs); | 263 | pr_debug("Looks like a total of %lu stubs, max\n", relocs); |
| @@ -976,7 +976,7 @@ int __meminit radix__vmemmap_create_mapping(unsigned long start, · 975 unmodified lines | |||
| 976 | return 0; | 976 | return 0; |
| 977 | } | 977 | } |
| 978 | 978 | ||
| 979 | 979 | #ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP | |
| 980 | bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) | 980 | bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) |
| 981 | { | 981 | { |
| 982 | if (radix_enabled()) | 982 | if (radix_enabled()) |
| @@ -984,6 +984,7 @@ bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) · 1 unmodified line | |||
| 984 | 984 | ||
| 985 | return false; | 985 | return false; |
| 986 | } | 986 | } |
| 987 | #endif | ||
| 987 | 988 | ||
| 988 | int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, | 989 | int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, |
| 989 | unsigned long addr, unsigned long next) | 990 | unsigned long addr, unsigned long next) |
| @@ -1120,6 +1121,19 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in · 130 unmodified lines | |||
| 1120 | pmd_t *pmd; | 1121 | pmd_t *pmd; |
| 1121 | pte_t *pte; | 1122 | pte_t *pte; |
| 1122 | 1123 | ||
| 1124 | /* | ||
| 1125 | * Make sure we align the start vmemmap addr so that we calculate | ||
| 1126 | * the correct start_pfn in altmap boundary check to decided whether | ||
| 1127 | * we should use altmap or RAM based backing memory allocation. Also | ||
| 1128 | * the address need to be aligned for set_pte operation. | ||
| 1129 | |||
| 1130 | * If the start addr is already PMD_SIZE aligned we will try to use | ||
| 1131 | * a pmd mapping. We don't want to be too aggressive here beacause | ||
| 1132 | * that will cause more allocations in RAM. So only if the namespace | ||
| 1133 | * vmemmap start addr is PMD_SIZE aligned we will use PMD mapping. | ||
| 1134 | */ | ||
| 1135 | |||
| 1136 | start = ALIGN_DOWN(start, PAGE_SIZE); | ||
| 1123 | for (addr = start; addr < end; addr = next) { | 1137 | for (addr = start; addr < end; addr = next) { |
| 1124 | next = pmd_addr_end(addr, end); | 1138 | next = pmd_addr_end(addr, end); |
| 1125 | 1139 | ||
| @@ -1145,8 +1159,8 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in · 19 unmodified lines | |||
| 1145 | * in altmap block allocation failures, in which case | 1159 | * in altmap block allocation failures, in which case |
| 1146 | * we fallback to RAM for vmemmap allocation. | 1160 | * we fallback to RAM for vmemmap allocation. |
| 1147 | */ | 1161 | */ |
| 1148 | if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) || | 1162 | if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap && |
| 1149 | altmap_cross_boundary(altmap, addr, PMD_SIZE))) { | 1163 | altmap_cross_boundary(altmap, addr, PMD_SIZE))) { |
| 1150 | /* | 1164 | /* |
| 1151 | * make sure we don't create altmap mappings | 1165 | * make sure we don't create altmap mappings |
| 1152 | * covering things outside the device. | 1166 | * covering things outside the device. |
| @@ -17,7 +17,7 @@ config PPC_POWERNV · 16 unmodified lines | |||
| 17 | select MMU_NOTIFIER | 17 | select MMU_NOTIFIER |
| 18 | select FORCE_SMP | 18 | select FORCE_SMP |
| 19 | select ARCH_SUPPORTS_PER_VMA_LOCK | 19 | select ARCH_SUPPORTS_PER_VMA_LOCK |
| 20 | select PPC_RADIX_BROADCAST_TLBIE | 20 | select PPC_RADIX_BROADCAST_TLBIE if PPC_RADIX_MMU |
| 21 | default y | 21 | default y |
| 22 | 22 | ||
| 23 | config OPAL_PRD | 23 | config OPAL_PRD |
| @@ -23,7 +23,7 @@ config PPC_PSERIES · 22 unmodified lines | |||
| 23 | select FORCE_SMP | 23 | select FORCE_SMP |
| 24 | select SWIOTLB | 24 | select SWIOTLB |
| 25 | select ARCH_SUPPORTS_PER_VMA_LOCK | 25 | select ARCH_SUPPORTS_PER_VMA_LOCK |
| 26 | select PPC_RADIX_BROADCAST_TLBIE | 26 | select PPC_RADIX_BROADCAST_TLBIE if PPC_RADIX_MMU |
| 27 | default y | 27 | default y |
| 28 | 28 | ||
| 29 | config PARAVIRT | 29 | config PARAVIRT |
| @@ -341,7 +341,7 @@ · 340 unmodified lines | |||
| 341 | 1024 1024 1024 1024>; | 341 | 1024 1024 1024 1024>; |
| 342 | snps,priority = <0 1 2 3 4 5 6 7>; | 342 | snps,priority = <0 1 2 3 4 5 6 7>; |
| 343 | snps,dma-masters = <2>; | 343 | snps,dma-masters = <2>; |
| 344 | snps,data-width = <4>; | 344 | snps,data-width = <2>; |
| 345 | status = "disabled"; | 345 | status = "disabled"; |
| 346 | }; | 346 | }; |
| 347 | 347 | ||
| @@ -115,24 +115,19 @@ · 114 unmodified lines | |||
| 115 | \old_c | 115 | \old_c |
| 116 | .endm | 116 | .endm |
| 117 | 117 | ||
| 118 | #define _ALTERNATIVE_CFG(old_c, ...) \ | 118 | #define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c |
| 119 | ALTERNATIVE_CFG old_c | 119 | #define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c |
| 120 | |||
| 121 | #define _ALTERNATIVE_CFG_2(old_c, ...) \ | ||
| 122 | ALTERNATIVE_CFG old_c | ||
| 123 | 120 | ||
| 124 | #else /* !__ASSEMBLY__ */ | 121 | #else /* !__ASSEMBLY__ */ |
| 125 | 122 | ||
| 126 | #define __ALTERNATIVE_CFG(old_c) \ | 123 | #define __ALTERNATIVE_CFG(old_c, ...) old_c "\n" |
| 127 | old_c "\n" | 124 | #define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n" |
| 128 | 125 | ||
| 129 | #define _ALTERNATIVE_CFG(old_c, ...) \ | 126 | #endif /* __ASSEMBLY__ */ |
| 130 | __ALTERNATIVE_CFG(old_c) | ||
| 131 | 127 | ||
| 132 | #define _ALTERNATIVE_CFG_2(old_c, ...) \ | 128 | #define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c) |
| 133 | __ALTERNATIVE_CFG(old_c) | 129 | #define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c) |
| 134 | 130 | ||
| 135 | #endif /* __ASSEMBLY__ */ | ||
| 136 | #endif /* CONFIG_RISCV_ALTERNATIVE */ | 131 | #endif /* CONFIG_RISCV_ALTERNATIVE */ |
| 137 | 132 | ||
| 138 | /* | 133 | /* |
| @@ -34,11 +34,6 @@ static inline void flush_dcache_page(struct page *page) · 33 unmodified lines | |||
| 34 | flush_dcache_folio(page_folio(page)); | 34 | flush_dcache_folio(page_folio(page)); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | /* | ||
| 38 | * RISC-V doesn't have an instruction to flush parts of the instruction cache, | ||
| 39 | * so instead we just flush the whole thing. | ||
| 40 | */ | ||
| 41 | #define flush_icache_range(start, end) flush_icache_all() | ||
| 42 | #define flush_icache_user_page(vma, pg, addr, len) \ | 37 | #define flush_icache_user_page(vma, pg, addr, len) \ |
| 43 | do { \ | 38 | do { \ |
| 44 | if (vma->vm_flags & VM_EXEC) \ | 39 | if (vma->vm_flags & VM_EXEC) \ |
| @@ -78,6 +73,16 @@ void flush_icache_mm(struct mm_struct *mm, bool local); · 33 unmodified lines | |||
| 78 | 73 | ||
| 79 | #endif /* CONFIG_SMP */ | 74 | #endif /* CONFIG_SMP */ |
| 80 | 75 | ||
| 76 | /* | ||
| 77 | * RISC-V doesn't have an instruction to flush parts of the instruction cache, | ||
| 78 | * so instead we just flush the whole thing. | ||
| 79 | */ | ||
| 80 | #define flush_icache_range flush_icache_range | ||
| 81 | static inline void flush_icache_range(unsigned long start, unsigned long end) | ||
| 82 | { | ||
| 83 | flush_icache_all(); | ||
| 84 | } | ||
| 85 | |||
| 81 | extern unsigned int riscv_cbom_block_size; | 86 | extern unsigned int riscv_cbom_block_size; |
| 82 | extern unsigned int riscv_cboz_block_size; | 87 | extern unsigned int riscv_cboz_block_size; |
| 83 | void riscv_init_cbo_blocksizes(void); | 88 | void riscv_init_cbo_blocksizes(void); |
| @@ -19,16 +19,9 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #ifndef __ASSEMBLY__ | 20 | #ifndef __ASSEMBLY__ |
| 21 | 21 | ||
| 22 | void arch_kgdb_breakpoint(void); | ||
| 22 | extern unsigned long kgdb_compiled_break; | 23 | extern unsigned long kgdb_compiled_break; |
| 23 | 24 | ||
| 24 | static inline void arch_kgdb_breakpoint(void) | ||
| 25 | { | ||
| 26 | asm(".global kgdb_compiled_break\n" | ||
| 27 | ".option norvc\n" | ||
| 28 | "kgdb_compiled_break: ebreak\n" | ||
| 29 | ".option rvc\n"); | ||
| 30 | } | ||
| 31 | |||
| 32 | #endif /* !__ASSEMBLY__ */ | 25 | #endif /* !__ASSEMBLY__ */ |
| 33 | 26 | ||
| 34 | #define DBG_REG_ZERO "zero" | 27 | #define DBG_REG_ZERO "zero" |
| @@ -62,8 +62,11 @@ static inline void syscall_get_arguments(struct task_struct *task, · 61 unmodified lines | |||
| 62 | unsigned long *args) | 62 | unsigned long *args) |
| 63 | { | 63 | { |
| 64 | args[0] = regs->orig_a0; | 64 | args[0] = regs->orig_a0; |
| 65 | args++; | 65 | args[1] = regs->a1; |
| 66 | memcpy(args, ®s->a1, 5 * sizeof(args[0])); | 66 | args[2] = regs->a2; |
| 67 | args[3] = regs->a3; | ||
| 68 | args[4] = regs->a4; | ||
| 69 | args[5] = regs->a5; | ||
| 67 | } | 70 | } |
| 68 | 71 | ||
| 69 | static inline int syscall_get_arch(struct task_struct *task) | 72 | static inline int syscall_get_arch(struct task_struct *task) |
| @@ -9,8 +9,8 @@ CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) · 8 unmodified lines | |||
| 9 | CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) | 9 | CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) |
| 10 | CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) | 10 | CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) |
| 11 | endif | 11 | endif |
| 12 | CFLAGS_syscall_table.o += $(call cc-option,-Wno-override-init,) | 12 | CFLAGS_syscall_table.o += $(call cc-disable-warning, override-init) |
| 13 | CFLAGS_compat_syscall_table.o += $(call cc-option,-Wno-override-init,) | 13 | CFLAGS_compat_syscall_table.o += $(call cc-disable-warning, override-init) |
| 14 | 14 | ||
| 15 | ifdef CONFIG_KEXEC_CORE | 15 | ifdef CONFIG_KEXEC_CORE |
| 16 | AFLAGS_kexec_relocate.o := -mcmodel=medany $(call cc-option,-mno-relax) | 16 | AFLAGS_kexec_relocate.o := -mcmodel=medany $(call cc-option,-mno-relax) |
| @@ -254,6 +254,12 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) · 253 unmodified lines | |||
| 254 | regs->epc = pc; | 254 | regs->epc = pc; |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | noinline void arch_kgdb_breakpoint(void) | ||
| 258 | { | ||
| 259 | asm(".global kgdb_compiled_break\n" | ||
| 260 | "kgdb_compiled_break: ebreak\n"); | ||
| 261 | } | ||
| 262 | |||
| 257 | void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer, | 263 | void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer, |
| 258 | char *remcom_out_buffer) | 264 | char *remcom_out_buffer) |
| 259 | { | 265 | { |
| @@ -73,16 +73,17 @@ static bool duplicate_rela(const Elf_Rela *rela, int idx) · 72 unmodified lines | |||
| 73 | static void count_max_entries(Elf_Rela *relas, int num, | 73 | static void count_max_entries(Elf_Rela *relas, int num, |
| 74 | unsigned int *plts, unsigned int *gots) | 74 | unsigned int *plts, unsigned int *gots) |
| 75 | { | 75 | { |
| 76 | unsigned int type, i; | 76 | for (int i = 0; i < num; i++) { |
| 77 | 77 | switch (ELF_R_TYPE(relas[i].r_info)) { | |
| 78 | for (i = 0; i < num; i++) { | 78 | case R_RISCV_CALL_PLT: |
| 79 | type = ELF_RISCV_R_TYPE(relas[i].r_info); | 79 | case R_RISCV_PLT32: |
| 80 | if (type == R_RISCV_CALL_PLT) { | ||
| 81 | if (!duplicate_rela(relas, i)) | 80 | if (!duplicate_rela(relas, i)) |
| 82 | (*plts)++; | 81 | (*plts)++; |
| 83 | } else if (type == R_RISCV_GOT_HI20) { | 82 | break; |
| 83 | case R_RISCV_GOT_HI20: | ||
| 84 | if (!duplicate_rela(relas, i)) | 84 | if (!duplicate_rela(relas, i)) |
| 85 | (*gots)++; | 85 | (*gots)++; |
| 86 | break; | ||
| 86 | } | 87 | } |
| 87 | } | 88 | } |
| 88 | } | 89 | } |
| @@ -648,7 +648,7 @@ process_accumulated_relocations(struct module *me, · 647 unmodified lines | |||
| 648 | kfree(bucket_iter); | 648 | kfree(bucket_iter); |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | kfree(*relocation_hashtable); | 651 | kvfree(*relocation_hashtable); |
| 652 | } | 652 | } |
| 653 | 653 | ||
| 654 | static int add_relocation_to_accumulate(struct module *me, int type, | 654 | static int add_relocation_to_accumulate(struct module *me, int type, |
| @@ -752,9 +752,10 @@ initialize_relocation_hashtable(unsigned int num_relocations, · 97 unmodified lines | |||
| 752 | 752 | ||
| 753 | hashtable_size <<= should_double_size; | 753 | hashtable_size <<= should_double_size; |
| 754 | 754 | ||
| 755 | *relocation_hashtable = kmalloc_array(hashtable_size, | 755 | /* Number of relocations may be large, so kvmalloc it */ |
| 756 | sizeof(**relocation_hashtable), | 756 | *relocation_hashtable = kvmalloc_array(hashtable_size, |
| 757 | GFP_KERNEL); | 757 | sizeof(**relocation_hashtable), |
| 758 | GFP_KERNEL); | ||
| 758 | if (!*relocation_hashtable) | 759 | if (!*relocation_hashtable) |
| 759 | return 0; | 760 | return 0; |
| 760 | 761 | ||
| @@ -859,7 +860,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, · 98 unmodified lines | |||
| 859 | } | 860 | } |
| 860 | 861 | ||
| 861 | j++; | 862 | j++; |
| 862 | if (j > sechdrs[relsec].sh_size / sizeof(*rel)) | 863 | if (j == num_relocations) |
| 863 | j = 0; | 864 | j = 0; |
| 864 | 865 | ||
| 865 | } while (j_idx != j); | 866 | } while (j_idx != j); |
| @@ -167,6 +167,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, · 166 unmodified lines | |||
| 167 | /* Initialize the slot */ | 167 | /* Initialize the slot */ |
| 168 | void *kaddr = kmap_atomic(page); | 168 | void *kaddr = kmap_atomic(page); |
| 169 | void *dst = kaddr + (vaddr & ~PAGE_MASK); | 169 | void *dst = kaddr + (vaddr & ~PAGE_MASK); |
| 170 | unsigned long start = (unsigned long)dst; | ||
| 170 | 171 | ||
| 171 | memcpy(dst, src, len); | 172 | memcpy(dst, src, len); |
| 172 | 173 | ||
| @@ -176,13 +177,6 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, · 3 unmodified lines | |||
| 176 | *(uprobe_opcode_t *)dst = __BUG_INSN_32; | 177 | *(uprobe_opcode_t *)dst = __BUG_INSN_32; |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 180 | flush_icache_range(start, start + len); | ||
| 179 | kunmap_atomic(kaddr); | 181 | kunmap_atomic(kaddr); |
| 180 | |||
| 181 | /* | ||
| 182 | * We probably need flush_icache_user_page() but it needs vma. | ||
| 183 | * This should work on most of architectures by default. If | ||
| 184 | * architecture needs to do something different it can define | ||
| 185 | * its own version of the function. | ||
| 186 | */ | ||
| 187 | flush_dcache_page(page); | ||
| 188 | } | 182 | } |
| @@ -275,6 +275,9 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg) · 274 unmodified lines | |||
| 275 | unsigned long pmm; | 275 | unsigned long pmm; |
| 276 | u8 pmlen; | 276 | u8 pmlen; |
| 277 | 277 | ||
| 278 | if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) | ||
| 279 | return -EINVAL; | ||
| 280 | |||
| 278 | if (is_compat_thread(ti)) | 281 | if (is_compat_thread(ti)) |
| 279 | return -EINVAL; | 282 | return -EINVAL; |
| 280 | 283 | ||
| @@ -330,6 +333,9 @@ long get_tagged_addr_ctrl(struct task_struct *task) · 49 unmodified lines | |||
| 330 | struct thread_info *ti = task_thread_info(task); | 333 | struct thread_info *ti = task_thread_info(task); |
| 331 | long ret = 0; | 334 | long ret = 0; |
| 332 | 335 | ||
| 336 | if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) | ||
| 337 | return -EINVAL; | ||
| 338 | |||
| 333 | if (is_compat_thread(ti)) | 339 | if (is_compat_thread(ti)) |
| 334 | return -EINVAL; | 340 | return -EINVAL; |
| 335 | 341 | ||
| @@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", }; · 65 unmodified lines | |||
| 66 | static struct resource elfcorehdr_res = { .name = "ELF Core hdr", }; | 66 | static struct resource elfcorehdr_res = { .name = "ELF Core hdr", }; |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| 69 | static int num_standard_resources; | ||
| 70 | static struct resource *standard_resources; | ||
| 71 | |||
| 69 | static int __init add_resource(struct resource *parent, | 72 | static int __init add_resource(struct resource *parent, |
| 70 | struct resource *res) | 73 | struct resource *res) |
| 71 | { | 74 | { |
| @@ -139,7 +142,7 @@ static void __init init_resources(void) · 67 unmodified lines | |||
| 139 | struct resource *res = NULL; | 142 | struct resource *res = NULL; |
| 140 | struct resource *mem_res = NULL; | 143 | struct resource *mem_res = NULL; |
| 141 | size_t mem_res_sz = 0; | 144 | size_t mem_res_sz = 0; |
| 142 | int num_resources = 0, res_idx = 0; | 145 | int num_resources = 0, res_idx = 0, non_resv_res = 0; |
| 143 | int ret = 0; | 146 | int ret = 0; |
| 144 | 147 | ||
| 145 | /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */ | 148 | /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */ |
| @@ -193,6 +196,7 @@ static void __init init_resources(void) · 47 unmodified lines | |||
| 193 | /* Add /memory regions to the resource tree */ | 196 | /* Add /memory regions to the resource tree */ |
| 194 | for_each_mem_region(region) { | 197 | for_each_mem_region(region) { |
| 195 | res = &mem_res[res_idx--]; | 198 | res = &mem_res[res_idx--]; |
| 199 | non_resv_res++; | ||
| 196 | 200 | ||
| 197 | if (unlikely(memblock_is_nomap(region))) { | 201 | if (unlikely(memblock_is_nomap(region))) { |
| 198 | res->name = "Reserved"; | 202 | res->name = "Reserved"; |
| @@ -210,6 +214,9 @@ static void __init init_resources(void) · 11 unmodified lines | |||
| 210 | goto error; | 214 | goto error; |
| 211 | } | 215 | } |
| 212 | 216 | ||
| 217 | num_standard_resources = non_resv_res; | ||
| 218 | standard_resources = &mem_res[res_idx + 1]; | ||
| 219 | |||
| 213 | /* Clean-up any unused pre-allocated resources */ | 220 | /* Clean-up any unused pre-allocated resources */ |
| 214 | if (res_idx >= 0) | 221 | if (res_idx >= 0) |
| 215 | memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res)); | 222 | memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res)); |
| @@ -221,6 +228,33 @@ static void __init init_resources(void) · 5 unmodified lines | |||
| 221 | memblock_free(mem_res, mem_res_sz); | 228 | memblock_free(mem_res, mem_res_sz); |
| 222 | } | 229 | } |
| 223 | 230 | ||
| 231 | static int __init reserve_memblock_reserved_regions(void) | ||
| 232 | { | ||
| 233 | u64 i, j; | ||
| 234 | |||
| 235 | for (i = 0; i < num_standard_resources; i++) { | ||
| 236 | struct resource *mem = &standard_resources[i]; | ||
| 237 | phys_addr_t r_start, r_end, mem_size = resource_size(mem); | ||
| 238 | |||
| 239 | if (!memblock_is_region_reserved(mem->start, mem_size)) | ||
| 240 | continue; | ||
| 241 | |||
| 242 | for_each_reserved_mem_range(j, &r_start, &r_end) { | ||
| 243 | resource_size_t start, end; | ||
| 244 | |||
| 245 | start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start); | ||
| 246 | end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end); | ||
| 247 | |||
| 248 | if (start > mem->end || end < mem->start) | ||
| 249 | continue; | ||
| 250 | |||
| 251 | reserve_region_with_split(mem, start, end, "Reserved"); | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | arch_initcall(reserve_memblock_reserved_regions); | ||
| 224 | 258 | ||
| 225 | static void __init parse_dtb(void) | 259 | static void __init parse_dtb(void) |
| 226 | { | 260 | { |
| @@ -198,47 +198,57 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re · 197 unmodified lines | |||
| 198 | DO_ERROR_INFO(do_trap_load_fault, | 198 | DO_ERROR_INFO(do_trap_load_fault, |
| 199 | SIGSEGV, SEGV_ACCERR, "load access fault"); | 199 | SIGSEGV, SEGV_ACCERR, "load access fault"); |
| 200 | 200 | ||
| 201 | asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs) | 201 | enum misaligned_access_type { |
| 202 | MISALIGNED_STORE, | ||
| 203 | MISALIGNED_LOAD, | ||
| 204 | }; | ||
| 205 | static const struct { | ||
| 206 | const char *type_str; | ||
| 207 | int (*handler)(struct pt_regs *regs); | ||
| 208 | } misaligned_handler[] = { | ||
| 209 | [MISALIGNED_STORE] = { | ||
| 210 | .type_str = "Oops - store (or AMO) address misaligned", | ||
| 211 | .handler = handle_misaligned_store, | ||
| 212 | }, | ||
| 213 | [MISALIGNED_LOAD] = { | ||
| 214 | .type_str = "Oops - load address misaligned", | ||
| 215 | .handler = handle_misaligned_load, | ||
| 216 | }, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type type) | ||
| 202 | { | 220 | { |
| 221 | irqentry_state_t state; | ||
| 222 | |||
| 203 | if (user_mode(regs)) { | 223 | if (user_mode(regs)) { |
| 204 | irqentry_enter_from_user_mode(regs); | 224 | irqentry_enter_from_user_mode(regs); |
| 225 | local_irq_enable(); | ||
| 226 | } else { | ||
| 227 | state = irqentry_nmi_enter(regs); | ||
| 228 | } | ||
| 205 | 229 | ||
| 206 | if (handle_misaligned_load(regs)) | 230 | if (misaligned_handler[type].handler(regs)) |
| 207 | do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | 231 | do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, |
| 208 | "Oops - load address misaligned"); | 232 | misaligned_handler[type].type_str); |
| 209 | 233 | ||
| 234 | if (user_mode(regs)) { | ||
| 235 | local_irq_disable(); | ||
| 210 | irqentry_exit_to_user_mode(regs); | 236 | irqentry_exit_to_user_mode(regs); |
| 211 | } else { | 237 | } else { |
| 212 | irqentry_state_t state = irqentry_nmi_enter(regs); | ||
| 213 | |||
| 214 | if (handle_misaligned_load(regs)) | ||
| 215 | do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | ||
| 216 | "Oops - load address misaligned"); | ||
| 217 | |||
| 218 | irqentry_nmi_exit(regs, state); | 238 | irqentry_nmi_exit(regs, state); |
| 219 | } | 239 | } |
| 220 | } | 240 | } |
| 221 | 241 | ||
| 222 | asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs) | 242 | asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs) |
| 223 | { | 243 | { |
| 224 | if (user_mode(regs)) { | 244 | do_trap_misaligned(regs, MISALIGNED_LOAD); |
| 225 | irqentry_enter_from_user_mode(regs); | 245 | } |
| 226 | |||
| 227 | if (handle_misaligned_store(regs)) | ||
| 228 | do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | ||
| 229 | "Oops - store (or AMO) address misaligned"); | ||
| 230 | |||
| 231 | irqentry_exit_to_user_mode(regs); | ||
| 232 | } else { | ||
| 233 | irqentry_state_t state = irqentry_nmi_enter(regs); | ||
| 234 | |||
| 235 | if (handle_misaligned_store(regs)) | ||
| 236 | do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | ||
| 237 | "Oops - store (or AMO) address misaligned"); | ||
| 238 | 246 | ||
| 239 | irqentry_nmi_exit(regs, state); | 247 | asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs) |
| 240 | } | 248 | { |
| 249 | do_trap_misaligned(regs, MISALIGNED_STORE); | ||
| 241 | } | 250 | } |
| 251 | |||
| 242 | DO_ERROR_INFO(do_trap_store_fault, | 252 | DO_ERROR_INFO(do_trap_store_fault, |
| 243 | SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); | 253 | SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); |
| 244 | DO_ERROR_INFO(do_trap_ecall_s, | 254 | DO_ERROR_INFO(do_trap_ecall_s, |
| @@ -88,6 +88,13 @@ · 87 unmodified lines | |||
| 88 | #define INSN_MATCH_C_FSWSP 0xe002 | 88 | #define INSN_MATCH_C_FSWSP 0xe002 |
| 89 | #define INSN_MASK_C_FSWSP 0xe003 | 89 | #define INSN_MASK_C_FSWSP 0xe003 |
| 90 | 90 | ||
| 91 | #define INSN_MATCH_C_LHU 0x8400 | ||
| 92 | #define INSN_MASK_C_LHU 0xfc43 | ||
| 93 | #define INSN_MATCH_C_LH 0x8440 | ||
| 94 | #define INSN_MASK_C_LH 0xfc43 | ||
| 95 | #define INSN_MATCH_C_SH 0x8c00 | ||
| 96 | #define INSN_MASK_C_SH 0xfc43 | ||
| 97 | |||
| 91 | #define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4) | 98 | #define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4) |
| 92 | 99 | ||
| 93 | #if defined(CONFIG_64BIT) | 100 | #if defined(CONFIG_64BIT) |
| @@ -268,7 +275,7 @@ static unsigned long get_f32_rs(unsigned long insn, u8 fp_reg_offset, · 174 unmodified lines | |||
| 268 | int __ret; \ | 275 | int __ret; \ |
| 269 | \ | 276 | \ |
| 270 | if (user_mode(regs)) { \ | 277 | if (user_mode(regs)) { \ |
| 271 | __ret = __get_user(insn, (type __user *) insn_addr); \ | 278 | __ret = get_user(insn, (type __user *) insn_addr); \ |
| 272 | } else { \ | 279 | } else { \ |
| 273 | insn = *(type *)insn_addr; \ | 280 | insn = *(type *)insn_addr; \ |
| 274 | __ret = 0; \ | 281 | __ret = 0; \ |
| @@ -431,6 +438,13 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs) · 156 unmodified lines | |||
| 431 | fp = 1; | 438 | fp = 1; |
| 432 | len = 4; | 439 | len = 4; |
| 433 | #endif | 440 | #endif |
| 441 | } else if ((insn & INSN_MASK_C_LHU) == INSN_MATCH_C_LHU) { | ||
| 442 | len = 2; | ||
| 443 | insn = RVC_RS2S(insn) << SH_RD; | ||
| 444 | } else if ((insn & INSN_MASK_C_LH) == INSN_MATCH_C_LH) { | ||
| 445 | len = 2; | ||
| 446 | shift = 8 * (sizeof(ulong) - len); | ||
| 447 | insn = RVC_RS2S(insn) << SH_RD; | ||
| 434 | } else { | 448 | } else { |
| 435 | regs->epc = epc; | 449 | regs->epc = epc; |
| 436 | return -1; | 450 | return -1; |
| @@ -530,6 +544,9 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs) · 93 unmodified lines | |||
| 530 | len = 4; | 544 | len = 4; |
| 531 | val.data_ulong = GET_F32_RS2C(insn, regs); | 545 | val.data_ulong = GET_F32_RS2C(insn, regs); |
| 532 | #endif | 546 | #endif |
| 547 | } else if ((insn & INSN_MASK_C_SH) == INSN_MATCH_C_SH) { | ||
| 548 | len = 2; | ||
| 549 | val.data_ulong = GET_RS2S(insn, regs); | ||
| 533 | } else { | 550 | } else { |
| 534 | regs->epc = epc; | 551 | regs->epc = epc; |
| 535 | return -1; | 552 | return -1; |
| @@ -439,29 +439,36 @@ static int __init check_unaligned_access_all_cpus(void) · 438 unmodified lines | |||
| 439 | { | 439 | { |
| 440 | int cpu; | 440 | int cpu; |
| 441 | 441 | ||
| 442 | if (unaligned_scalar_speed_param == RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN && | 442 | if (unaligned_scalar_speed_param != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN) { |
| 443 | !check_unaligned_access_emulated_all_cpus()) { | 443 | pr_info("scalar unaligned access speed set to '%s' (%lu) by command line\n", |
| 444 | check_unaligned_access_speed_all_cpus(); | 444 | speed_str[unaligned_scalar_speed_param], unaligned_scalar_speed_param); |
| 445 | } else { | ||
| 446 | pr_info("scalar unaligned access speed set to '%s' by command line\n", | ||
| 447 | speed_str[unaligned_scalar_speed_param]); | ||
| 448 | for_each_online_cpu(cpu) | 445 | for_each_online_cpu(cpu) |
| 449 | per_cpu(misaligned_access_speed, cpu) = unaligned_scalar_speed_param; | 446 | per_cpu(misaligned_access_speed, cpu) = unaligned_scalar_speed_param; |
| 447 | } else if (!check_unaligned_access_emulated_all_cpus()) { | ||
| 448 | check_unaligned_access_speed_all_cpus(); | ||
| 449 | } | ||
| 450 | |||
| 451 | if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) { | ||
| 452 | if (!has_vector() && | ||
| 453 | unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED) { | ||
| 454 | pr_warn("vector support is not available, ignoring unaligned_vector_speed=%s\n", | ||
| 455 | speed_str[unaligned_vector_speed_param]); | ||
| 456 | } else { | ||
| 457 | pr_info("vector unaligned access speed set to '%s' (%lu) by command line\n", | ||
| 458 | speed_str[unaligned_vector_speed_param], unaligned_vector_speed_param); | ||
| 459 | } | ||
| 450 | } | 460 | } |
| 451 | 461 | ||
| 452 | if (!has_vector()) | 462 | if (!has_vector()) |
| 453 | unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED; | 463 | unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED; |
| 454 | 464 | ||
| 455 | if (unaligned_vector_speed_param == RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN && | 465 | if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) { |
| 456 | !check_vector_unaligned_access_emulated_all_cpus() && | ||
| 457 | IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) { | ||
| 458 | kthread_run(vec_check_unaligned_access_speed_all_cpus, | ||
| 459 | NULL, "vec_check_unaligned_access_speed_all_cpus"); | ||
| 460 | } else { | ||
| 461 | pr_info("vector unaligned access speed set to '%s' by command line\n", | ||
| 462 | speed_str[unaligned_vector_speed_param]); | ||
| 463 | for_each_online_cpu(cpu) | 466 | for_each_online_cpu(cpu) |
| 464 | per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param; | 467 | per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param; |
| 468 | } else if (!check_vector_unaligned_access_emulated_all_cpus() && | ||
| 469 | IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) { | ||
| 470 | kthread_run(vec_check_unaligned_access_speed_all_cpus, | ||
| 471 | NULL, "vec_check_unaligned_access_speed_all_cpus"); | ||
| 465 | } | 472 | } |
| 466 | 473 | ||
| 467 | /* | 474 | /* |
| @@ -77,6 +77,8 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) · 76 unmodified lines | |||
| 77 | memcpy(cntx, reset_cntx, sizeof(*cntx)); | 77 | memcpy(cntx, reset_cntx, sizeof(*cntx)); |
| 78 | spin_unlock(&vcpu->arch.reset_cntx_lock); | 78 | spin_unlock(&vcpu->arch.reset_cntx_lock); |
| 79 | 79 | ||
| 80 | memset(&vcpu->arch.smstateen_csr, 0, sizeof(vcpu->arch.smstateen_csr)); | ||
| 81 | |||
| 80 | kvm_riscv_vcpu_fp_reset(vcpu); | 82 | kvm_riscv_vcpu_fp_reset(vcpu); |
| 81 | 83 | ||
| 82 | kvm_riscv_vcpu_vector_reset(vcpu); | 84 | kvm_riscv_vcpu_vector_reset(vcpu); |
| @@ -332,6 +332,10 @@ config HAVE_MARCH_Z16_FEATURES · 331 unmodified lines | |||
| 332 | def_bool n | 332 | def_bool n |
| 333 | select HAVE_MARCH_Z15_FEATURES | 333 | select HAVE_MARCH_Z15_FEATURES |
| 334 | 334 | ||
| 335 | config HAVE_MARCH_Z17_FEATURES | ||
| 336 | def_bool n | ||
| 337 | select HAVE_MARCH_Z16_FEATURES | ||
| 338 | |||
| 335 | choice | 339 | choice |
| 336 | prompt "Processor type" | 340 | prompt "Processor type" |
| 337 | default MARCH_Z196 | 341 | default MARCH_Z196 |
| @@ -397,6 +401,14 @@ config MARCH_Z16 · 59 unmodified lines | |||
| 397 | Select this to enable optimizations for IBM z16 (3931 and | 401 | Select this to enable optimizations for IBM z16 (3931 and |
| 398 | 3932 series). | 402 | 3932 series). |
| 399 | 403 | ||
| 404 | config MARCH_Z17 | ||
| 405 | bool "IBM z17" | ||
| 406 | select HAVE_MARCH_Z17_FEATURES | ||
| 407 | depends on $(cc-option,-march=z17) | ||
| 408 | help | ||
| 409 | Select this to enable optimizations for IBM z17 (9175 and | ||
| 410 | 9176 series). | ||
| 411 | |||
| 400 | endchoice | 412 | endchoice |
| 401 | 413 | ||
| 402 | config MARCH_Z10_TUNE | 414 | config MARCH_Z10_TUNE |
| @@ -420,6 +432,9 @@ config MARCH_Z15_TUNE · 17 unmodified lines | |||
| 420 | config MARCH_Z16_TUNE | 432 | config MARCH_Z16_TUNE |
| 421 | def_bool TUNE_Z16 || MARCH_Z16 && TUNE_DEFAULT | 433 | def_bool TUNE_Z16 || MARCH_Z16 && TUNE_DEFAULT |
| 422 | 434 | ||
| 435 | config MARCH_Z17_TUNE | ||
| 436 | def_bool TUNE_Z17 || MARCH_Z17 && TUNE_DEFAULT | ||
| 437 | |||
| 423 | choice | 438 | choice |
| 424 | prompt "Tune code generation" | 439 | prompt "Tune code generation" |
| 425 | default TUNE_DEFAULT | 440 | default TUNE_DEFAULT |
| @@ -464,6 +479,10 @@ config TUNE_Z16 · 38 unmodified lines | |||
| 464 | bool "IBM z16" | 479 | bool "IBM z16" |
| 465 | depends on $(cc-option,-mtune=z16) | 480 | depends on $(cc-option,-mtune=z16) |
| 466 | 481 | ||
| 482 | config TUNE_Z17 | ||
| 483 | bool "IBM z17" | ||
| 484 | depends on $(cc-option,-mtune=z17) | ||
| 485 | |||
| 467 | endchoice | 486 | endchoice |
| 468 | 487 | ||
| 469 | config 64BIT | 488 | config 64BIT |
| @@ -48,6 +48,7 @@ mflags-$(CONFIG_MARCH_Z13) := -march=z13 · 47 unmodified lines | |||
| 48 | mflags-$(CONFIG_MARCH_Z14) := -march=z14 | 48 | mflags-$(CONFIG_MARCH_Z14) := -march=z14 |
| 49 | mflags-$(CONFIG_MARCH_Z15) := -march=z15 | 49 | mflags-$(CONFIG_MARCH_Z15) := -march=z15 |
| 50 | mflags-$(CONFIG_MARCH_Z16) := -march=z16 | 50 | mflags-$(CONFIG_MARCH_Z16) := -march=z16 |
| 51 | mflags-$(CONFIG_MARCH_Z17) := -march=z17 | ||
| 51 | 52 | ||
| 52 | export CC_FLAGS_MARCH := $(mflags-y) | 53 | export CC_FLAGS_MARCH := $(mflags-y) |
| 53 | 54 | ||
| @@ -61,6 +62,7 @@ cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 · 7 unmodified lines | |||
| 61 | cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 | 62 | cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 |
| 62 | cflags-$(CONFIG_MARCH_Z15_TUNE) += -mtune=z15 | 63 | cflags-$(CONFIG_MARCH_Z15_TUNE) += -mtune=z15 |
| 63 | cflags-$(CONFIG_MARCH_Z16_TUNE) += -mtune=z16 | 64 | cflags-$(CONFIG_MARCH_Z16_TUNE) += -mtune=z16 |
| 65 | cflags-$(CONFIG_MARCH_Z17_TUNE) += -mtune=z17 | ||
| 64 | 66 | ||
| 65 | cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include | 67 | cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include |
| 66 | 68 | ||
| @@ -38,7 +38,6 @@ CONFIG_USER_NS=y · 37 unmodified lines | |||
| 38 | CONFIG_CHECKPOINT_RESTORE=y | 38 | CONFIG_CHECKPOINT_RESTORE=y |
| 39 | CONFIG_SCHED_AUTOGROUP=y | 39 | CONFIG_SCHED_AUTOGROUP=y |
| 40 | CONFIG_EXPERT=y | 40 | CONFIG_EXPERT=y |
| 41 | # CONFIG_SYSFS_SYSCALL is not set | ||
| 42 | CONFIG_PROFILING=y | 41 | CONFIG_PROFILING=y |
| 43 | CONFIG_KEXEC=y | 42 | CONFIG_KEXEC=y |
| 44 | CONFIG_KEXEC_FILE=y | 43 | CONFIG_KEXEC_FILE=y |
| @@ -92,7 +91,6 @@ CONFIG_UNIXWARE_DISKLABEL=y · 47 unmodified lines | |||
| 92 | CONFIG_IOSCHED_BFQ=y | 91 | CONFIG_IOSCHED_BFQ=y |
| 93 | CONFIG_BINFMT_MISC=m | 92 | CONFIG_BINFMT_MISC=m |
| 94 | CONFIG_ZSWAP=y | 93 | CONFIG_ZSWAP=y |
| 95 | CONFIG_ZSMALLOC=y | ||
| 96 | CONFIG_ZSMALLOC_STAT=y | 94 | CONFIG_ZSMALLOC_STAT=y |
| 97 | CONFIG_SLAB_BUCKETS=y | 95 | CONFIG_SLAB_BUCKETS=y |
| 98 | CONFIG_SLUB_STATS=y | 96 | CONFIG_SLUB_STATS=y |
| @@ -395,6 +393,9 @@ CONFIG_CLS_U32_MARK=y · 296 unmodified lines | |||
| 395 | CONFIG_NET_CLS_FLOW=m | 393 | CONFIG_NET_CLS_FLOW=m |
| 396 | CONFIG_NET_CLS_CGROUP=y | 394 | CONFIG_NET_CLS_CGROUP=y |
| 397 | CONFIG_NET_CLS_BPF=m | 395 | CONFIG_NET_CLS_BPF=m |
| 396 | CONFIG_NET_CLS_FLOWER=m | ||
| 397 | CONFIG_NET_CLS_MATCHALL=m | ||
| 398 | CONFIG_NET_EMATCH=y | ||
| 398 | CONFIG_NET_CLS_ACT=y | 399 | CONFIG_NET_CLS_ACT=y |
| 399 | CONFIG_NET_ACT_POLICE=m | 400 | CONFIG_NET_ACT_POLICE=m |
| 400 | CONFIG_NET_ACT_GACT=m | 401 | CONFIG_NET_ACT_GACT=m |
| @@ -405,6 +406,9 @@ CONFIG_NET_ACT_PEDIT=m · 4 unmodified lines | |||
| 405 | CONFIG_NET_ACT_SIMP=m | 406 | CONFIG_NET_ACT_SIMP=m |
| 406 | CONFIG_NET_ACT_SKBEDIT=m | 407 | CONFIG_NET_ACT_SKBEDIT=m |
| 407 | CONFIG_NET_ACT_CSUM=m | 408 | CONFIG_NET_ACT_CSUM=m |
| 409 | CONFIG_NET_ACT_VLAN=m | ||
| 410 | CONFIG_NET_ACT_TUNNEL_KEY=m | ||
| 411 | CONFIG_NET_ACT_CT=m | ||
| 408 | CONFIG_NET_ACT_GATE=m | 412 | CONFIG_NET_ACT_GATE=m |
| 409 | CONFIG_NET_TC_SKB_EXT=y | 413 | CONFIG_NET_TC_SKB_EXT=y |
| 410 | CONFIG_DNS_RESOLVER=y | 414 | CONFIG_DNS_RESOLVER=y |
| @@ -628,8 +632,16 @@ CONFIG_VIRTIO_PCI=m · 217 unmodified lines | |||
| 628 | CONFIG_VIRTIO_BALLOON=m | 632 | CONFIG_VIRTIO_BALLOON=m |
| 629 | CONFIG_VIRTIO_MEM=m | 633 | CONFIG_VIRTIO_MEM=m |
| 630 | CONFIG_VIRTIO_INPUT=y | 634 | CONFIG_VIRTIO_INPUT=y |
| 635 | CONFIG_VDPA=m | ||
| 636 | CONFIG_VDPA_SIM=m | ||
| 637 | CONFIG_VDPA_SIM_NET=m | ||
| 638 | CONFIG_VDPA_SIM_BLOCK=m | ||
| 639 | CONFIG_VDPA_USER=m | ||
| 640 | CONFIG_MLX5_VDPA_NET=m | ||
| 641 | CONFIG_VP_VDPA=m | ||
| 631 | CONFIG_VHOST_NET=m | 642 | CONFIG_VHOST_NET=m |
| 632 | CONFIG_VHOST_VSOCK=m | 643 | CONFIG_VHOST_VSOCK=m |
| 644 | CONFIG_VHOST_VDPA=m | ||
| 633 | CONFIG_EXT4_FS=y | 645 | CONFIG_EXT4_FS=y |
| 634 | CONFIG_EXT4_FS_POSIX_ACL=y | 646 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 635 | CONFIG_EXT4_FS_SECURITY=y | 647 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -654,7 +666,6 @@ CONFIG_NILFS2_FS=m · 18 unmodified lines | |||
| 654 | CONFIG_BCACHEFS_FS=y | 666 | CONFIG_BCACHEFS_FS=y |
| 655 | CONFIG_BCACHEFS_QUOTA=y | 667 | CONFIG_BCACHEFS_QUOTA=y |
| 656 | CONFIG_BCACHEFS_POSIX_ACL=y | 668 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 657 | CONFIG_FS_DAX=y | ||
| 658 | CONFIG_EXPORTFS_BLOCK_OPS=y | 669 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 659 | CONFIG_FS_ENCRYPTION=y | 670 | CONFIG_FS_ENCRYPTION=y |
| 660 | CONFIG_FS_VERITY=y | 671 | CONFIG_FS_VERITY=y |
| @@ -724,11 +735,10 @@ CONFIG_NLS_UTF8=m · 63 unmodified lines | |||
| 724 | CONFIG_DLM=m | 735 | CONFIG_DLM=m |
| 725 | CONFIG_UNICODE=y | 736 | CONFIG_UNICODE=y |
| 726 | CONFIG_PERSISTENT_KEYRINGS=y | 737 | CONFIG_PERSISTENT_KEYRINGS=y |
| 738 | CONFIG_BIG_KEYS=y | ||
| 727 | CONFIG_ENCRYPTED_KEYS=m | 739 | CONFIG_ENCRYPTED_KEYS=m |
| 728 | CONFIG_KEY_NOTIFICATIONS=y | 740 | CONFIG_KEY_NOTIFICATIONS=y |
| 729 | CONFIG_SECURITY=y | 741 | CONFIG_SECURITY=y |
| 730 | CONFIG_HARDENED_USERCOPY=y | ||
| 731 | CONFIG_FORTIFY_SOURCE=y | ||
| 732 | CONFIG_SECURITY_SELINUX=y | 742 | CONFIG_SECURITY_SELINUX=y |
| 733 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y | 743 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y |
| 734 | CONFIG_SECURITY_LOCKDOWN_LSM=y | 744 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| @@ -741,6 +751,8 @@ CONFIG_IMA=y · 6 unmodified lines | |||
| 741 | CONFIG_IMA_DEFAULT_HASH_SHA256=y | 751 | CONFIG_IMA_DEFAULT_HASH_SHA256=y |
| 742 | CONFIG_IMA_WRITE_POLICY=y | 752 | CONFIG_IMA_WRITE_POLICY=y |
| 743 | CONFIG_IMA_APPRAISE=y | 753 | CONFIG_IMA_APPRAISE=y |
| 754 | CONFIG_FORTIFY_SOURCE=y | ||
| 755 | CONFIG_HARDENED_USERCOPY=y | ||
| 744 | CONFIG_BUG_ON_DATA_CORRUPTION=y | 756 | CONFIG_BUG_ON_DATA_CORRUPTION=y |
| 745 | CONFIG_CRYPTO_USER=m | 757 | CONFIG_CRYPTO_USER=m |
| 746 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | 758 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| @@ -756,7 +768,6 @@ CONFIG_CRYPTO_AES_TI=m · 9 unmodified lines | |||
| 756 | CONFIG_CRYPTO_ANUBIS=m | 768 | CONFIG_CRYPTO_ANUBIS=m |
| 757 | CONFIG_CRYPTO_ARIA=m | 769 | CONFIG_CRYPTO_ARIA=m |
| 758 | CONFIG_CRYPTO_BLOWFISH=m | 770 | CONFIG_CRYPTO_BLOWFISH=m |
| 759 | CONFIG_CRYPTO_CAMELLIA=m | ||
| 760 | CONFIG_CRYPTO_CAST5=m | 771 | CONFIG_CRYPTO_CAST5=m |
| 761 | CONFIG_CRYPTO_CAST6=m | 772 | CONFIG_CRYPTO_CAST6=m |
| 762 | CONFIG_CRYPTO_DES=m | 773 | CONFIG_CRYPTO_DES=m |
| @@ -801,7 +812,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m · 38 unmodified lines | |||
| 801 | CONFIG_CRYPTO_GHASH_S390=m | 812 | CONFIG_CRYPTO_GHASH_S390=m |
| 802 | CONFIG_CRYPTO_AES_S390=m | 813 | CONFIG_CRYPTO_AES_S390=m |
| 803 | CONFIG_CRYPTO_DES_S390=m | 814 | CONFIG_CRYPTO_DES_S390=m |
| 804 | CONFIG_CRYPTO_CHACHA_S390=m | ||
| 805 | CONFIG_CRYPTO_HMAC_S390=m | 815 | CONFIG_CRYPTO_HMAC_S390=m |
| 806 | CONFIG_ZCRYPT=m | 816 | CONFIG_ZCRYPT=m |
| 807 | CONFIG_PKEY=m | 817 | CONFIG_PKEY=m |
| @@ -812,9 +822,9 @@ CONFIG_PKEY_UV=m · 4 unmodified lines | |||
| 812 | CONFIG_CRYPTO_PAES_S390=m | 822 | CONFIG_CRYPTO_PAES_S390=m |
| 813 | CONFIG_CRYPTO_DEV_VIRTIO=m | 823 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 814 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y | 824 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
| 825 | CONFIG_CRYPTO_KRB5=m | ||
| 826 | CONFIG_CRYPTO_KRB5_SELFTESTS=y | ||
| 815 | CONFIG_CORDIC=m | 827 | CONFIG_CORDIC=m |
| 816 | CONFIG_CRYPTO_LIB_CURVE25519=m | ||
| 817 | CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | ||
| 818 | CONFIG_RANDOM32_SELFTEST=y | 828 | CONFIG_RANDOM32_SELFTEST=y |
| 819 | CONFIG_XZ_DEC_MICROLZMA=y | 829 | CONFIG_XZ_DEC_MICROLZMA=y |
| 820 | CONFIG_DMA_CMA=y | 830 | CONFIG_DMA_CMA=y |
| @@ -36,7 +36,6 @@ CONFIG_USER_NS=y · 35 unmodified lines | |||
| 36 | CONFIG_CHECKPOINT_RESTORE=y | 36 | CONFIG_CHECKPOINT_RESTORE=y |
| 37 | CONFIG_SCHED_AUTOGROUP=y | 37 | CONFIG_SCHED_AUTOGROUP=y |
| 38 | CONFIG_EXPERT=y | 38 | CONFIG_EXPERT=y |
| 39 | # CONFIG_SYSFS_SYSCALL is not set | ||
| 40 | CONFIG_PROFILING=y | 39 | CONFIG_PROFILING=y |
| 41 | CONFIG_KEXEC=y | 40 | CONFIG_KEXEC=y |
| 42 | CONFIG_KEXEC_FILE=y | 41 | CONFIG_KEXEC_FILE=y |
| @@ -86,7 +85,6 @@ CONFIG_UNIXWARE_DISKLABEL=y · 43 unmodified lines | |||
| 86 | CONFIG_IOSCHED_BFQ=y | 85 | CONFIG_IOSCHED_BFQ=y |
| 87 | CONFIG_BINFMT_MISC=m | 86 | CONFIG_BINFMT_MISC=m |
| 88 | CONFIG_ZSWAP=y | 87 | CONFIG_ZSWAP=y |
| 89 | CONFIG_ZSMALLOC=y | ||
| 90 | CONFIG_ZSMALLOC_STAT=y | 88 | CONFIG_ZSMALLOC_STAT=y |
| 91 | CONFIG_SLAB_BUCKETS=y | 89 | CONFIG_SLAB_BUCKETS=y |
| 92 | # CONFIG_COMPAT_BRK is not set | 90 | # CONFIG_COMPAT_BRK is not set |
| @@ -385,6 +383,9 @@ CONFIG_CLS_U32_MARK=y · 292 unmodified lines | |||
| 385 | CONFIG_NET_CLS_FLOW=m | 383 | CONFIG_NET_CLS_FLOW=m |
| 386 | CONFIG_NET_CLS_CGROUP=y | 384 | CONFIG_NET_CLS_CGROUP=y |
| 387 | CONFIG_NET_CLS_BPF=m | 385 | CONFIG_NET_CLS_BPF=m |
| 386 | CONFIG_NET_CLS_FLOWER=m | ||
| 387 | CONFIG_NET_CLS_MATCHALL=m | ||
| 388 | CONFIG_NET_EMATCH=y | ||
| 388 | CONFIG_NET_CLS_ACT=y | 389 | CONFIG_NET_CLS_ACT=y |
| 389 | CONFIG_NET_ACT_POLICE=m | 390 | CONFIG_NET_ACT_POLICE=m |
| 390 | CONFIG_NET_ACT_GACT=m | 391 | CONFIG_NET_ACT_GACT=m |
| @@ -395,6 +396,9 @@ CONFIG_NET_ACT_PEDIT=m · 4 unmodified lines | |||
| 395 | CONFIG_NET_ACT_SIMP=m | 396 | CONFIG_NET_ACT_SIMP=m |
| 396 | CONFIG_NET_ACT_SKBEDIT=m | 397 | CONFIG_NET_ACT_SKBEDIT=m |
| 397 | CONFIG_NET_ACT_CSUM=m | 398 | CONFIG_NET_ACT_CSUM=m |
| 399 | CONFIG_NET_ACT_VLAN=m | ||
| 400 | CONFIG_NET_ACT_TUNNEL_KEY=m | ||
| 401 | CONFIG_NET_ACT_CT=m | ||
| 398 | CONFIG_NET_ACT_GATE=m | 402 | CONFIG_NET_ACT_GATE=m |
| 399 | CONFIG_NET_TC_SKB_EXT=y | 403 | CONFIG_NET_TC_SKB_EXT=y |
| 400 | CONFIG_DNS_RESOLVER=y | 404 | CONFIG_DNS_RESOLVER=y |
| @@ -618,8 +622,16 @@ CONFIG_VIRTIO_PCI=m · 217 unmodified lines | |||
| 618 | CONFIG_VIRTIO_BALLOON=m | 622 | CONFIG_VIRTIO_BALLOON=m |
| 619 | CONFIG_VIRTIO_MEM=m | 623 | CONFIG_VIRTIO_MEM=m |
| 620 | CONFIG_VIRTIO_INPUT=y | 624 | CONFIG_VIRTIO_INPUT=y |
| 625 | CONFIG_VDPA=m | ||
| 626 | CONFIG_VDPA_SIM=m | ||
| 627 | CONFIG_VDPA_SIM_NET=m | ||
| 628 | CONFIG_VDPA_SIM_BLOCK=m | ||
| 629 | CONFIG_VDPA_USER=m | ||
| 630 | CONFIG_MLX5_VDPA_NET=m | ||
| 631 | CONFIG_VP_VDPA=m | ||
| 621 | CONFIG_VHOST_NET=m | 632 | CONFIG_VHOST_NET=m |
| 622 | CONFIG_VHOST_VSOCK=m | 633 | CONFIG_VHOST_VSOCK=m |
| 634 | CONFIG_VHOST_VDPA=m | ||
| 623 | CONFIG_EXT4_FS=y | 635 | CONFIG_EXT4_FS=y |
| 624 | CONFIG_EXT4_FS_POSIX_ACL=y | 636 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 625 | CONFIG_EXT4_FS_SECURITY=y | 637 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -641,7 +653,6 @@ CONFIG_NILFS2_FS=m · 15 unmodified lines | |||
| 641 | CONFIG_BCACHEFS_FS=m | 653 | CONFIG_BCACHEFS_FS=m |
| 642 | CONFIG_BCACHEFS_QUOTA=y | 654 | CONFIG_BCACHEFS_QUOTA=y |
| 643 | CONFIG_BCACHEFS_POSIX_ACL=y | 655 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 644 | CONFIG_FS_DAX=y | ||
| 645 | CONFIG_EXPORTFS_BLOCK_OPS=y | 656 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 646 | CONFIG_FS_ENCRYPTION=y | 657 | CONFIG_FS_ENCRYPTION=y |
| 647 | CONFIG_FS_VERITY=y | 658 | CONFIG_FS_VERITY=y |
| @@ -711,6 +722,7 @@ CONFIG_NLS_UTF8=m · 63 unmodified lines | |||
| 711 | CONFIG_DLM=m | 722 | CONFIG_DLM=m |
| 712 | CONFIG_UNICODE=y | 723 | CONFIG_UNICODE=y |
| 713 | CONFIG_PERSISTENT_KEYRINGS=y | 724 | CONFIG_PERSISTENT_KEYRINGS=y |
| 725 | CONFIG_BIG_KEYS=y | ||
| 714 | CONFIG_ENCRYPTED_KEYS=m | 726 | CONFIG_ENCRYPTED_KEYS=m |
| 715 | CONFIG_KEY_NOTIFICATIONS=y | 727 | CONFIG_KEY_NOTIFICATIONS=y |
| 716 | CONFIG_SECURITY=y | 728 | CONFIG_SECURITY=y |
| @@ -742,7 +754,6 @@ CONFIG_CRYPTO_AES_TI=m · 25 unmodified lines | |||
| 742 | CONFIG_CRYPTO_ANUBIS=m | 754 | CONFIG_CRYPTO_ANUBIS=m |
| 743 | CONFIG_CRYPTO_ARIA=m | 755 | CONFIG_CRYPTO_ARIA=m |
| 744 | CONFIG_CRYPTO_BLOWFISH=m | 756 | CONFIG_CRYPTO_BLOWFISH=m |
| 745 | CONFIG_CRYPTO_CAMELLIA=m | ||
| 746 | CONFIG_CRYPTO_CAST5=m | 757 | CONFIG_CRYPTO_CAST5=m |
| 747 | CONFIG_CRYPTO_CAST6=m | 758 | CONFIG_CRYPTO_CAST6=m |
| 748 | CONFIG_CRYPTO_DES=m | 759 | CONFIG_CRYPTO_DES=m |
| @@ -788,7 +799,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m · 39 unmodified lines | |||
| 788 | CONFIG_CRYPTO_GHASH_S390=m | 799 | CONFIG_CRYPTO_GHASH_S390=m |
| 789 | CONFIG_CRYPTO_AES_S390=m | 800 | CONFIG_CRYPTO_AES_S390=m |
| 790 | CONFIG_CRYPTO_DES_S390=m | 801 | CONFIG_CRYPTO_DES_S390=m |
| 791 | CONFIG_CRYPTO_CHACHA_S390=m | ||
| 792 | CONFIG_CRYPTO_HMAC_S390=m | 802 | CONFIG_CRYPTO_HMAC_S390=m |
| 793 | CONFIG_ZCRYPT=m | 803 | CONFIG_ZCRYPT=m |
| 794 | CONFIG_PKEY=m | 804 | CONFIG_PKEY=m |
| @@ -799,10 +809,10 @@ CONFIG_PKEY_UV=m · 4 unmodified lines | |||
| 799 | CONFIG_CRYPTO_PAES_S390=m | 809 | CONFIG_CRYPTO_PAES_S390=m |
| 800 | CONFIG_CRYPTO_DEV_VIRTIO=m | 810 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 801 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y | 811 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
| 812 | CONFIG_CRYPTO_KRB5=m | ||
| 813 | CONFIG_CRYPTO_KRB5_SELFTESTS=y | ||
| 802 | CONFIG_CORDIC=m | 814 | CONFIG_CORDIC=m |
| 803 | CONFIG_PRIME_NUMBERS=m | 815 | CONFIG_PRIME_NUMBERS=m |
| 804 | CONFIG_CRYPTO_LIB_CURVE25519=m | ||
| 805 | CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | ||
| 806 | CONFIG_XZ_DEC_MICROLZMA=y | 816 | CONFIG_XZ_DEC_MICROLZMA=y |
| 807 | CONFIG_DMA_CMA=y | 817 | CONFIG_DMA_CMA=y |
| 808 | CONFIG_CMA_SIZE_MBYTES=0 | 818 | CONFIG_CMA_SIZE_MBYTES=0 |
| @@ -70,7 +70,6 @@ CONFIG_DEBUG_KERNEL=y · 69 unmodified lines | |||
| 70 | CONFIG_DEBUG_INFO_DWARF4=y | 70 | CONFIG_DEBUG_INFO_DWARF4=y |
| 71 | CONFIG_DEBUG_FS=y | 71 | CONFIG_DEBUG_FS=y |
| 72 | CONFIG_PANIC_ON_OOPS=y | 72 | CONFIG_PANIC_ON_OOPS=y |
| 73 | # CONFIG_SCHED_DEBUG is not set | ||
| 74 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 73 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
| 75 | # CONFIG_RCU_TRACE is not set | 74 | # CONFIG_RCU_TRACE is not set |
| 76 | # CONFIG_FTRACE is not set | 75 | # CONFIG_FTRACE is not set |
| @@ -33,6 +33,10 @@ · 32 unmodified lines | |||
| 33 | #define MARCH_HAS_Z16_FEATURES 1 | 33 | #define MARCH_HAS_Z16_FEATURES 1 |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | #ifdef CONFIG_HAVE_MARCH_Z17_FEATURES | ||
| 37 | #define MARCH_HAS_Z17_FEATURES 1 | ||
| 38 | #endif | ||
| 39 | |||
| 36 | #endif /* __DECOMPRESSOR */ | 40 | #endif /* __DECOMPRESSOR */ |
| 37 | 41 | ||
| 38 | #endif /* __ASM_S390_MARCH_H */ | 42 | #endif /* __ASM_S390_MARCH_H */ |
| @@ -602,7 +602,8 @@ SYM_CODE_START(stack_invalid) · 601 unmodified lines | |||
| 602 | stmg %r0,%r7,__PT_R0(%r11) | 602 | stmg %r0,%r7,__PT_R0(%r11) |
| 603 | stmg %r8,%r9,__PT_PSW(%r11) | 603 | stmg %r8,%r9,__PT_PSW(%r11) |
| 604 | mvc __PT_R8(64,%r11),0(%r14) | 604 | mvc __PT_R8(64,%r11),0(%r14) |
| 605 | stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 | 605 | GET_LC %r2 |
| 606 | mvc __PT_ORIG_GPR2(8,%r11),__LC_PGM_LAST_BREAK(%r2) | ||
| 606 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 607 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
| 607 | lgr %r2,%r11 # pass pointer to pt_regs | 608 | lgr %r2,%r11 # pass pointer to pt_regs |
| 608 | jg kernel_stack_invalid | 609 | jg kernel_stack_invalid |
| @@ -442,7 +442,7 @@ static void cpum_cf_make_setsize(enum cpumf_ctr_set ctrset) · 441 unmodified lines | |||
| 442 | ctrset_size = 48; | 442 | ctrset_size = 48; |
| 443 | else if (cpumf_ctr_info.csvn >= 3 && cpumf_ctr_info.csvn <= 5) | 443 | else if (cpumf_ctr_info.csvn >= 3 && cpumf_ctr_info.csvn <= 5) |
| 444 | ctrset_size = 128; | 444 | ctrset_size = 128; |
| 445 | else if (cpumf_ctr_info.csvn == 6 || cpumf_ctr_info.csvn == 7) | 445 | else if (cpumf_ctr_info.csvn >= 6 && cpumf_ctr_info.csvn <= 8) |
| 446 | ctrset_size = 160; | 446 | ctrset_size = 160; |
| 447 | break; | 447 | break; |
| 448 | case CPUMF_CTR_SET_MT_DIAG: | 448 | case CPUMF_CTR_SET_MT_DIAG: |
| @@ -858,18 +858,13 @@ static int cpumf_pmu_event_type(struct perf_event *event) · 409 unmodified lines | |||
| 858 | static int cpumf_pmu_event_init(struct perf_event *event) | 858 | static int cpumf_pmu_event_init(struct perf_event *event) |
| 859 | { | 859 | { |
| 860 | unsigned int type = event->attr.type; | 860 | unsigned int type = event->attr.type; |
| 861 | int err; | 861 | int err = -ENOENT; |
| 862 | 862 | ||
| 863 | if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) | 863 | if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) |
| 864 | err = __hw_perf_event_init(event, type); | 864 | err = __hw_perf_event_init(event, type); |
| 865 | else if (event->pmu->type == type) | 865 | else if (event->pmu->type == type) |
| 866 | /* Registered as unknown PMU */ | 866 | /* Registered as unknown PMU */ |
| 867 | err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); | 867 | err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); |
| 868 | else | ||
| 869 | return -ENOENT; | ||
| 870 | |||
| 871 | if (unlikely(err) && event->destroy) | ||
| 872 | event->destroy(event); | ||
| 873 | 868 | ||
| 874 | return err; | 869 | return err; |
| 875 | } | 870 | } |
| @@ -1819,8 +1814,6 @@ static int cfdiag_event_init(struct perf_event *event) · 943 unmodified lines | |||
| 1819 | event->destroy = hw_perf_event_destroy; | 1814 | event->destroy = hw_perf_event_destroy; |
| 1820 | 1815 | ||
| 1821 | err = cfdiag_event_init2(event); | 1816 | err = cfdiag_event_init2(event); |
| 1822 | if (unlikely(err)) | ||
| 1823 | event->destroy(event); | ||
| 1824 | out: | 1817 | out: |
| 1825 | return err; | 1818 | return err; |
| 1826 | } | 1819 | } |
| @@ -237,7 +237,6 @@ CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_NO_SPECIAL, 0x00f4); · 236 unmodified lines | |||
| 237 | CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_SPECIAL, 0x00f5); | 237 | CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_SPECIAL, 0x00f5); |
| 238 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); | 238 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 239 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); | 239 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); |
| 240 | |||
| 241 | CPUMF_EVENT_ATTR(cf_z15, L1D_RO_EXCL_WRITES, 0x0080); | 240 | CPUMF_EVENT_ATTR(cf_z15, L1D_RO_EXCL_WRITES, 0x0080); |
| 242 | CPUMF_EVENT_ATTR(cf_z15, DTLB2_WRITES, 0x0081); | 241 | CPUMF_EVENT_ATTR(cf_z15, DTLB2_WRITES, 0x0081); |
| 243 | CPUMF_EVENT_ATTR(cf_z15, DTLB2_MISSES, 0x0082); | 242 | CPUMF_EVENT_ATTR(cf_z15, DTLB2_MISSES, 0x0082); |
| @@ -365,6 +364,83 @@ CPUMF_EVENT_ATTR(cf_z16, NNPA_WAIT_LOCK, 0x010d); · 121 unmodified lines | |||
| 365 | CPUMF_EVENT_ATTR(cf_z16, NNPA_HOLD_LOCK, 0x010e); | 364 | CPUMF_EVENT_ATTR(cf_z16, NNPA_HOLD_LOCK, 0x010e); |
| 366 | CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); | 365 | CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 367 | CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); | 366 | CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); |
| 367 | CPUMF_EVENT_ATTR(cf_z17, L1D_RO_EXCL_WRITES, 0x0080); | ||
| 368 | CPUMF_EVENT_ATTR(cf_z17, DTLB2_WRITES, 0x0081); | ||
| 369 | CPUMF_EVENT_ATTR(cf_z17, DTLB2_MISSES, 0x0082); | ||
| 370 | CPUMF_EVENT_ATTR(cf_z17, CRSTE_1MB_WRITES, 0x0083); | ||
| 371 | CPUMF_EVENT_ATTR(cf_z17, DTLB2_GPAGE_WRITES, 0x0084); | ||
| 372 | CPUMF_EVENT_ATTR(cf_z17, ITLB2_WRITES, 0x0086); | ||
| 373 | CPUMF_EVENT_ATTR(cf_z17, ITLB2_MISSES, 0x0087); | ||
| 374 | CPUMF_EVENT_ATTR(cf_z17, TLB2_PTE_WRITES, 0x0089); | ||
| 375 | CPUMF_EVENT_ATTR(cf_z17, TLB2_CRSTE_WRITES, 0x008a); | ||
| 376 | CPUMF_EVENT_ATTR(cf_z17, TLB2_ENGINES_BUSY, 0x008b); | ||
| 377 | CPUMF_EVENT_ATTR(cf_z17, TX_C_TEND, 0x008c); | ||
| 378 | CPUMF_EVENT_ATTR(cf_z17, TX_NC_TEND, 0x008d); | ||
| 379 | CPUMF_EVENT_ATTR(cf_z17, L1C_TLB2_MISSES, 0x008f); | ||
| 380 | CPUMF_EVENT_ATTR(cf_z17, DCW_REQ, 0x0091); | ||
| 381 | CPUMF_EVENT_ATTR(cf_z17, DCW_REQ_IV, 0x0092); | ||
| 382 | CPUMF_EVENT_ATTR(cf_z17, DCW_REQ_CHIP_HIT, 0x0093); | ||
| 383 | CPUMF_EVENT_ATTR(cf_z17, DCW_REQ_DRAWER_HIT, 0x0094); | ||
| 384 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_CHIP, 0x0095); | ||
| 385 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_CHIP_IV, 0x0096); | ||
| 386 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_CHIP_CHIP_HIT, 0x0097); | ||
| 387 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_CHIP_DRAWER_HIT, 0x0098); | ||
| 388 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_MODULE, 0x0099); | ||
| 389 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_DRAWER, 0x009a); | ||
| 390 | CPUMF_EVENT_ATTR(cf_z17, DCW_OFF_DRAWER, 0x009b); | ||
| 391 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_CHIP_MEMORY, 0x009c); | ||
| 392 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_MODULE_MEMORY, 0x009d); | ||
| 393 | CPUMF_EVENT_ATTR(cf_z17, DCW_ON_DRAWER_MEMORY, 0x009e); | ||
| 394 | CPUMF_EVENT_ATTR(cf_z17, DCW_OFF_DRAWER_MEMORY, 0x009f); | ||
| 395 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_MODULE_IV, 0x00a0); | ||
| 396 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_MODULE_CHIP_HIT, 0x00a1); | ||
| 397 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_MODULE_DRAWER_HIT, 0x00a2); | ||
| 398 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_DRAWER_IV, 0x00a3); | ||
| 399 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_DRAWER_CHIP_HIT, 0x00a4); | ||
| 400 | CPUMF_EVENT_ATTR(cf_z17, IDCW_ON_DRAWER_DRAWER_HIT, 0x00a5); | ||
| 401 | CPUMF_EVENT_ATTR(cf_z17, IDCW_OFF_DRAWER_IV, 0x00a6); | ||
| 402 | CPUMF_EVENT_ATTR(cf_z17, IDCW_OFF_DRAWER_CHIP_HIT, 0x00a7); | ||
| 403 | CPUMF_EVENT_ATTR(cf_z17, IDCW_OFF_DRAWER_DRAWER_HIT, 0x00a8); | ||
| 404 | CPUMF_EVENT_ATTR(cf_z17, ICW_REQ, 0x00a9); | ||
| 405 | CPUMF_EVENT_ATTR(cf_z17, ICW_REQ_IV, 0x00aa); | ||
| 406 | CPUMF_EVENT_ATTR(cf_z17, ICW_REQ_CHIP_HIT, 0x00ab); | ||
| 407 | CPUMF_EVENT_ATTR(cf_z17, ICW_REQ_DRAWER_HIT, 0x00ac); | ||
| 408 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_CHIP, 0x00ad); | ||
| 409 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_CHIP_IV, 0x00ae); | ||
| 410 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_CHIP_CHIP_HIT, 0x00af); | ||
| 411 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_CHIP_DRAWER_HIT, 0x00b0); | ||
| 412 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_MODULE, 0x00b1); | ||
| 413 | CPUMF_EVENT_ATTR(cf_z17, ICW_ON_DRAWER, 0x00b2); | ||
| 414 | CPUMF_EVENT_ATTR(cf_z17, ICW_OFF_DRAWER, 0x00b3); | ||
| 415 | CPUMF_EVENT_ATTR(cf_z17, CYCLES_SAMETHRD, 0x00ca); | ||
| 416 | CPUMF_EVENT_ATTR(cf_z17, CYCLES_DIFFTHRD, 0x00cb); | ||
| 417 | CPUMF_EVENT_ATTR(cf_z17, INST_SAMETHRD, 0x00cc); | ||
| 418 | CPUMF_EVENT_ATTR(cf_z17, INST_DIFFTHRD, 0x00cd); | ||
| 419 | CPUMF_EVENT_ATTR(cf_z17, WRONG_BRANCH_PREDICTION, 0x00ce); | ||
| 420 | CPUMF_EVENT_ATTR(cf_z17, VX_BCD_EXECUTION_SLOTS, 0x00e1); | ||
| 421 | CPUMF_EVENT_ATTR(cf_z17, DECIMAL_INSTRUCTIONS, 0x00e2); | ||
| 422 | CPUMF_EVENT_ATTR(cf_z17, LAST_HOST_TRANSLATIONS, 0x00e8); | ||
| 423 | CPUMF_EVENT_ATTR(cf_z17, TX_NC_TABORT, 0x00f4); | ||
| 424 | CPUMF_EVENT_ATTR(cf_z17, TX_C_TABORT_NO_SPECIAL, 0x00f5); | ||
| 425 | CPUMF_EVENT_ATTR(cf_z17, TX_C_TABORT_SPECIAL, 0x00f6); | ||
| 426 | CPUMF_EVENT_ATTR(cf_z17, DFLT_ACCESS, 0x00f8); | ||
| 427 | CPUMF_EVENT_ATTR(cf_z17, DFLT_CYCLES, 0x00fd); | ||
| 428 | CPUMF_EVENT_ATTR(cf_z17, SORTL, 0x0100); | ||
| 429 | CPUMF_EVENT_ATTR(cf_z17, DFLT_CC, 0x0109); | ||
| 430 | CPUMF_EVENT_ATTR(cf_z17, DFLT_CCFINISH, 0x010a); | ||
| 431 | CPUMF_EVENT_ATTR(cf_z17, NNPA_INVOCATIONS, 0x010b); | ||
| 432 | CPUMF_EVENT_ATTR(cf_z17, NNPA_COMPLETIONS, 0x010c); | ||
| 433 | CPUMF_EVENT_ATTR(cf_z17, NNPA_WAIT_LOCK, 0x010d); | ||
| 434 | CPUMF_EVENT_ATTR(cf_z17, NNPA_HOLD_LOCK, 0x010e); | ||
| 435 | CPUMF_EVENT_ATTR(cf_z17, NNPA_INST_ONCHIP, 0x0110); | ||
| 436 | CPUMF_EVENT_ATTR(cf_z17, NNPA_INST_OFFCHIP, 0x0111); | ||
| 437 | CPUMF_EVENT_ATTR(cf_z17, NNPA_INST_DIFF, 0x0112); | ||
| 438 | CPUMF_EVENT_ATTR(cf_z17, NNPA_4K_PREFETCH, 0x0114); | ||
| 439 | CPUMF_EVENT_ATTR(cf_z17, NNPA_COMPL_LOCK, 0x0115); | ||
| 440 | CPUMF_EVENT_ATTR(cf_z17, NNPA_RETRY_LOCK, 0x0116); | ||
| 441 | CPUMF_EVENT_ATTR(cf_z17, NNPA_RETRY_LOCK_WITH_PLO, 0x0117); | ||
| 442 | CPUMF_EVENT_ATTR(cf_z17, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); | ||
| 443 | CPUMF_EVENT_ATTR(cf_z17, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); | ||
| 368 | 444 | ||
| 369 | static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = { | 445 | static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = { |
| 370 | CPUMF_EVENT_PTR(cf_fvn1, CPU_CYCLES), | 446 | CPUMF_EVENT_PTR(cf_fvn1, CPU_CYCLES), |
| @@ -414,7 +490,7 @@ static struct attribute *cpumcf_svn_12345_pmu_event_attr[] __initdata = { · 43 unmodified lines | |||
| 414 | NULL, | 490 | NULL, |
| 415 | }; | 491 | }; |
| 416 | 492 | ||
| 417 | static struct attribute *cpumcf_svn_67_pmu_event_attr[] __initdata = { | 493 | static struct attribute *cpumcf_svn_678_pmu_event_attr[] __initdata = { |
| 418 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS), | 494 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS), |
| 419 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES), | 495 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES), |
| 420 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS), | 496 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS), |
| @@ -779,6 +855,87 @@ static struct attribute *cpumcf_z16_pmu_event_attr[] __initdata = { · 358 unmodified lines | |||
| 779 | NULL, | 855 | NULL, |
| 780 | }; | 856 | }; |
| 781 | 857 | ||
| 858 | static struct attribute *cpumcf_z17_pmu_event_attr[] __initdata = { | ||
| 859 | CPUMF_EVENT_PTR(cf_z17, L1D_RO_EXCL_WRITES), | ||
| 860 | CPUMF_EVENT_PTR(cf_z17, DTLB2_WRITES), | ||
| 861 | CPUMF_EVENT_PTR(cf_z17, DTLB2_MISSES), | ||
| 862 | CPUMF_EVENT_PTR(cf_z17, CRSTE_1MB_WRITES), | ||
| 863 | CPUMF_EVENT_PTR(cf_z17, DTLB2_GPAGE_WRITES), | ||
| 864 | CPUMF_EVENT_PTR(cf_z17, ITLB2_WRITES), | ||
| 865 | CPUMF_EVENT_PTR(cf_z17, ITLB2_MISSES), | ||
| 866 | CPUMF_EVENT_PTR(cf_z17, TLB2_PTE_WRITES), | ||
| 867 | CPUMF_EVENT_PTR(cf_z17, TLB2_CRSTE_WRITES), | ||
| 868 | CPUMF_EVENT_PTR(cf_z17, TLB2_ENGINES_BUSY), | ||
| 869 | CPUMF_EVENT_PTR(cf_z17, TX_C_TEND), | ||
| 870 | CPUMF_EVENT_PTR(cf_z17, TX_NC_TEND), | ||
| 871 | CPUMF_EVENT_PTR(cf_z17, L1C_TLB2_MISSES), | ||
| 872 | CPUMF_EVENT_PTR(cf_z17, DCW_REQ), | ||
| 873 | CPUMF_EVENT_PTR(cf_z17, DCW_REQ_IV), | ||
| 874 | CPUMF_EVENT_PTR(cf_z17, DCW_REQ_CHIP_HIT), | ||
| 875 | CPUMF_EVENT_PTR(cf_z17, DCW_REQ_DRAWER_HIT), | ||
| 876 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_CHIP), | ||
| 877 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_CHIP_IV), | ||
| 878 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_CHIP_CHIP_HIT), | ||
| 879 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_CHIP_DRAWER_HIT), | ||
| 880 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_MODULE), | ||
| 881 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_DRAWER), | ||
| 882 | CPUMF_EVENT_PTR(cf_z17, DCW_OFF_DRAWER), | ||
| 883 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_CHIP_MEMORY), | ||
| 884 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_MODULE_MEMORY), | ||
| 885 | CPUMF_EVENT_PTR(cf_z17, DCW_ON_DRAWER_MEMORY), | ||
| 886 | CPUMF_EVENT_PTR(cf_z17, DCW_OFF_DRAWER_MEMORY), | ||
| 887 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_MODULE_IV), | ||
| 888 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_MODULE_CHIP_HIT), | ||
| 889 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_MODULE_DRAWER_HIT), | ||
| 890 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_DRAWER_IV), | ||
| 891 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_DRAWER_CHIP_HIT), | ||
| 892 | CPUMF_EVENT_PTR(cf_z17, IDCW_ON_DRAWER_DRAWER_HIT), | ||
| 893 | CPUMF_EVENT_PTR(cf_z17, IDCW_OFF_DRAWER_IV), | ||
| 894 | CPUMF_EVENT_PTR(cf_z17, IDCW_OFF_DRAWER_CHIP_HIT), | ||
| 895 | CPUMF_EVENT_PTR(cf_z17, IDCW_OFF_DRAWER_DRAWER_HIT), | ||
| 896 | CPUMF_EVENT_PTR(cf_z17, ICW_REQ), | ||
| 897 | CPUMF_EVENT_PTR(cf_z17, ICW_REQ_IV), | ||
| 898 | CPUMF_EVENT_PTR(cf_z17, ICW_REQ_CHIP_HIT), | ||
| 899 | CPUMF_EVENT_PTR(cf_z17, ICW_REQ_DRAWER_HIT), | ||
| 900 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_CHIP), | ||
| 901 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_CHIP_IV), | ||
| 902 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_CHIP_CHIP_HIT), | ||
| 903 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_CHIP_DRAWER_HIT), | ||
| 904 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_MODULE), | ||
| 905 | CPUMF_EVENT_PTR(cf_z17, ICW_ON_DRAWER), | ||
| 906 | CPUMF_EVENT_PTR(cf_z17, ICW_OFF_DRAWER), | ||
| 907 | CPUMF_EVENT_PTR(cf_z17, CYCLES_SAMETHRD), | ||
| 908 | CPUMF_EVENT_PTR(cf_z17, CYCLES_DIFFTHRD), | ||
| 909 | CPUMF_EVENT_PTR(cf_z17, INST_SAMETHRD), | ||
| 910 | CPUMF_EVENT_PTR(cf_z17, INST_DIFFTHRD), | ||
| 911 | CPUMF_EVENT_PTR(cf_z17, WRONG_BRANCH_PREDICTION), | ||
| 912 | CPUMF_EVENT_PTR(cf_z17, VX_BCD_EXECUTION_SLOTS), | ||
| 913 | CPUMF_EVENT_PTR(cf_z17, DECIMAL_INSTRUCTIONS), | ||
| 914 | CPUMF_EVENT_PTR(cf_z17, LAST_HOST_TRANSLATIONS), | ||
| 915 | CPUMF_EVENT_PTR(cf_z17, TX_NC_TABORT), | ||
| 916 | CPUMF_EVENT_PTR(cf_z17, TX_C_TABORT_NO_SPECIAL), | ||
| 917 | CPUMF_EVENT_PTR(cf_z17, TX_C_TABORT_SPECIAL), | ||
| 918 | CPUMF_EVENT_PTR(cf_z17, DFLT_ACCESS), | ||
| 919 | CPUMF_EVENT_PTR(cf_z17, DFLT_CYCLES), | ||
| 920 | CPUMF_EVENT_PTR(cf_z17, SORTL), | ||
| 921 | CPUMF_EVENT_PTR(cf_z17, DFLT_CC), | ||
| 922 | CPUMF_EVENT_PTR(cf_z17, DFLT_CCFINISH), | ||
| 923 | CPUMF_EVENT_PTR(cf_z17, NNPA_INVOCATIONS), | ||
| 924 | CPUMF_EVENT_PTR(cf_z17, NNPA_COMPLETIONS), | ||
| 925 | CPUMF_EVENT_PTR(cf_z17, NNPA_WAIT_LOCK), | ||
| 926 | CPUMF_EVENT_PTR(cf_z17, NNPA_HOLD_LOCK), | ||
| 927 | CPUMF_EVENT_PTR(cf_z17, NNPA_INST_ONCHIP), | ||
| 928 | CPUMF_EVENT_PTR(cf_z17, NNPA_INST_OFFCHIP), | ||
| 929 | CPUMF_EVENT_PTR(cf_z17, NNPA_INST_DIFF), | ||
| 930 | CPUMF_EVENT_PTR(cf_z17, NNPA_4K_PREFETCH), | ||
| 931 | CPUMF_EVENT_PTR(cf_z17, NNPA_COMPL_LOCK), | ||
| 932 | CPUMF_EVENT_PTR(cf_z17, NNPA_RETRY_LOCK), | ||
| 933 | CPUMF_EVENT_PTR(cf_z17, NNPA_RETRY_LOCK_WITH_PLO), | ||
| 934 | CPUMF_EVENT_PTR(cf_z17, MT_DIAG_CYCLES_ONE_THR_ACTIVE), | ||
| 935 | CPUMF_EVENT_PTR(cf_z17, MT_DIAG_CYCLES_TWO_THR_ACTIVE), | ||
| 936 | NULL, | ||
| 937 | }; | ||
| 938 | |||
| 782 | /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ | 939 | /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ |
| 783 | 940 | ||
| 784 | static struct attribute_group cpumcf_pmu_events_group = { | 941 | static struct attribute_group cpumcf_pmu_events_group = { |
| @@ -859,7 +1016,7 @@ __init const struct attribute_group **cpumf_cf_event_group(void) · 74 unmodified lines | |||
| 859 | if (ci.csvn >= 1 && ci.csvn <= 5) | 1016 | if (ci.csvn >= 1 && ci.csvn <= 5) |
| 860 | csvn = cpumcf_svn_12345_pmu_event_attr; | 1017 | csvn = cpumcf_svn_12345_pmu_event_attr; |
| 861 | else if (ci.csvn >= 6) | 1018 | else if (ci.csvn >= 6) |
| 862 | csvn = cpumcf_svn_67_pmu_event_attr; | 1019 | csvn = cpumcf_svn_678_pmu_event_attr; |
| 863 | 1020 | ||
| 864 | /* Determine model-specific counter set(s) */ | 1021 | /* Determine model-specific counter set(s) */ |
| 865 | get_cpu_id(&cpu_id); | 1022 | get_cpu_id(&cpu_id); |
| @@ -892,6 +1049,10 @@ __init const struct attribute_group **cpumf_cf_event_group(void) · 26 unmodified lines | |||
| 892 | case 0x3932: | 1049 | case 0x3932: |
| 893 | model = cpumcf_z16_pmu_event_attr; | 1050 | model = cpumcf_z16_pmu_event_attr; |
| 894 | break; | 1051 | break; |
| 1052 | case 0x9175: | ||
| 1053 | case 0x9176: | ||
| 1054 | model = cpumcf_z17_pmu_event_attr; | ||
| 1055 | break; | ||
| 895 | default: | 1056 | default: |
| 896 | model = none; | 1057 | model = none; |
| 897 | break; | 1058 | break; |
| @@ -885,9 +885,6 @@ static int cpumsf_pmu_event_init(struct perf_event *event) · 884 unmodified lines | |||
| 885 | event->attr.exclude_idle = 0; | 885 | event->attr.exclude_idle = 0; |
| 886 | 886 | ||
| 887 | err = __hw_perf_event_init(event); | 887 | err = __hw_perf_event_init(event); |
| 888 | if (unlikely(err)) | ||
| 889 | if (event->destroy) | ||
| 890 | event->destroy(event); | ||
| 891 | return err; | 888 | return err; |
| 892 | } | 889 | } |
| 893 | 890 | ||
| @@ -294,6 +294,10 @@ static int __init setup_elf_platform(void) · 293 unmodified lines | |||
| 294 | case 0x3932: | 294 | case 0x3932: |
| 295 | strcpy(elf_platform, "z16"); | 295 | strcpy(elf_platform, "z16"); |
| 296 | break; | 296 | break; |
| 297 | case 0x9175: | ||
| 298 | case 0x9176: | ||
| 299 | strcpy(elf_platform, "z17"); | ||
| 300 | break; | ||
| 297 | } | 301 | } |
| 298 | return 0; | 302 | return 0; |
| 299 | } | 303 | } |
| @@ -95,7 +95,7 @@ static int handle_validity(struct kvm_vcpu *vcpu) · 94 unmodified lines | |||
| 95 | 95 | ||
| 96 | vcpu->stat.exit_validity++; | 96 | vcpu->stat.exit_validity++; |
| 97 | trace_kvm_s390_intercept_validity(vcpu, viwhy); | 97 | trace_kvm_s390_intercept_validity(vcpu, viwhy); |
| 98 | KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy, | 98 | KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%p)", viwhy, |
| 99 | current->pid, vcpu->kvm); | 99 | current->pid, vcpu->kvm); |
| 100 | 100 | ||
| 101 | /* do not warn on invalid runtime instrumentation mode */ | 101 | /* do not warn on invalid runtime instrumentation mode */ |
| @@ -3161,7 +3161,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm) · 3160 unmodified lines | |||
| 3161 | if (!gi->origin) | 3161 | if (!gi->origin) |
| 3162 | return; | 3162 | return; |
| 3163 | gisa_clear_ipm(gi->origin); | 3163 | gisa_clear_ipm(gi->origin); |
| 3164 | VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin); | 3164 | VM_EVENT(kvm, 3, "gisa 0x%p cleared", gi->origin); |
| 3165 | } | 3165 | } |
| 3166 | 3166 | ||
| 3167 | void kvm_s390_gisa_init(struct kvm *kvm) | 3167 | void kvm_s390_gisa_init(struct kvm *kvm) |
| @@ -3177,7 +3177,7 @@ void kvm_s390_gisa_init(struct kvm *kvm) · 9 unmodified lines | |||
| 3177 | hrtimer_setup(&gi->timer, gisa_vcpu_kicker, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 3177 | hrtimer_setup(&gi->timer, gisa_vcpu_kicker, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 3178 | memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); | 3178 | memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); |
| 3179 | gi->origin->next_alert = (u32)virt_to_phys(gi->origin); | 3179 | gi->origin->next_alert = (u32)virt_to_phys(gi->origin); |
| 3180 | VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin); | 3180 | VM_EVENT(kvm, 3, "gisa 0x%p initialized", gi->origin); |
| 3181 | } | 3181 | } |
| 3182 | 3182 | ||
| 3183 | void kvm_s390_gisa_enable(struct kvm *kvm) | 3183 | void kvm_s390_gisa_enable(struct kvm *kvm) |
| @@ -3218,7 +3218,7 @@ void kvm_s390_gisa_destroy(struct kvm *kvm) · 34 unmodified lines | |||
| 3218 | process_gib_alert_list(); | 3218 | process_gib_alert_list(); |
| 3219 | hrtimer_cancel(&gi->timer); | 3219 | hrtimer_cancel(&gi->timer); |
| 3220 | gi->origin = NULL; | 3220 | gi->origin = NULL; |
| 3221 | VM_EVENT(kvm, 3, "gisa 0x%pK destroyed", gisa); | 3221 | VM_EVENT(kvm, 3, "gisa 0x%p destroyed", gisa); |
| 3222 | } | 3222 | } |
| 3223 | 3223 | ||
| 3224 | void kvm_s390_gisa_disable(struct kvm *kvm) | 3224 | void kvm_s390_gisa_disable(struct kvm *kvm) |
| @@ -3467,7 +3467,7 @@ int __init kvm_s390_gib_init(u8 nisc) · 242 unmodified lines | |||
| 3467 | } | 3467 | } |
| 3468 | } | 3468 | } |
| 3469 | 3469 | ||
| 3470 | KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc); | 3470 | KVM_EVENT(3, "gib 0x%p (nisc=%d) initialized", gib, gib->nisc); |
| 3471 | goto out; | 3471 | goto out; |
| 3472 | 3472 | ||
| 3473 | out_unreg_gal: | 3473 | out_unreg_gal: |
| @@ -1022,7 +1022,7 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att · 1021 unmodified lines | |||
| 1022 | } | 1022 | } |
| 1023 | mutex_unlock(&kvm->lock); | 1023 | mutex_unlock(&kvm->lock); |
| 1024 | VM_EVENT(kvm, 3, "SET: max guest address: %lu", new_limit); | 1024 | VM_EVENT(kvm, 3, "SET: max guest address: %lu", new_limit); |
| 1025 | VM_EVENT(kvm, 3, "New guest asce: 0x%pK", | 1025 | VM_EVENT(kvm, 3, "New guest asce: 0x%p", |
| 1026 | (void *) kvm->arch.gmap->asce); | 1026 | (void *) kvm->arch.gmap->asce); |
| 1027 | break; | 1027 | break; |
| 1028 | } | 1028 | } |
| @@ -3466,7 +3466,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 2437 unmodified lines | |||
| 3466 | kvm_s390_gisa_init(kvm); | 3466 | kvm_s390_gisa_init(kvm); |
| 3467 | INIT_LIST_HEAD(&kvm->arch.pv.need_cleanup); | 3467 | INIT_LIST_HEAD(&kvm->arch.pv.need_cleanup); |
| 3468 | kvm->arch.pv.set_aside = NULL; | 3468 | kvm->arch.pv.set_aside = NULL; |
| 3469 | KVM_EVENT(3, "vm 0x%pK created by pid %u", kvm, current->pid); | 3469 | KVM_EVENT(3, "vm 0x%p created by pid %u", kvm, current->pid); |
| 3470 | 3470 | ||
| 3471 | return 0; | 3471 | return 0; |
| 3472 | out_err: | 3472 | out_err: |
| @@ -3529,7 +3529,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) · 56 unmodified lines | |||
| 3529 | kvm_s390_destroy_adapters(kvm); | 3529 | kvm_s390_destroy_adapters(kvm); |
| 3530 | kvm_s390_clear_float_irqs(kvm); | 3530 | kvm_s390_clear_float_irqs(kvm); |
| 3531 | kvm_s390_vsie_destroy(kvm); | 3531 | kvm_s390_vsie_destroy(kvm); |
| 3532 | KVM_EVENT(3, "vm 0x%pK destroyed", kvm); | 3532 | KVM_EVENT(3, "vm 0x%p destroyed", kvm); |
| 3533 | } | 3533 | } |
| 3534 | 3534 | ||
| 3535 | /* Section: vcpu related */ | 3535 | /* Section: vcpu related */ |
| @@ -3650,7 +3650,7 @@ static int sca_switch_to_extended(struct kvm *kvm) · 114 unmodified lines | |||
| 3650 | 3650 | ||
| 3651 | free_page((unsigned long)old_sca); | 3651 | free_page((unsigned long)old_sca); |
| 3652 | 3652 | ||
| 3653 | VM_EVENT(kvm, 2, "Switched to ESCA (0x%pK -> 0x%pK)", | 3653 | VM_EVENT(kvm, 2, "Switched to ESCA (0x%p -> 0x%p)", |
| 3654 | old_sca, kvm->arch.sca); | 3654 | old_sca, kvm->arch.sca); |
| 3655 | return 0; | 3655 | return 0; |
| 3656 | } | 3656 | } |
| @@ -4027,7 +4027,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 370 unmodified lines | |||
| 4027 | goto out_free_sie_block; | 4027 | goto out_free_sie_block; |
| 4028 | } | 4028 | } |
| 4029 | 4029 | ||
| 4030 | VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%pK, sie block at 0x%pK", | 4030 | VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%p, sie block at 0x%p", |
| 4031 | vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); | 4031 | vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); |
| 4032 | trace_kvm_s390_create_vcpu(vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); | 4032 | trace_kvm_s390_create_vcpu(vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); |
| 4033 | 4033 | ||
| @@ -56,7 +56,7 @@ TRACE_EVENT(kvm_s390_create_vcpu, · 55 unmodified lines | |||
| 56 | __entry->sie_block = sie_block; | 56 | __entry->sie_block = sie_block; |
| 57 | ), | 57 | ), |
| 58 | 58 | ||
| 59 | TP_printk("create cpu %d at 0x%pK, sie block at 0x%pK", | 59 | TP_printk("create cpu %d at 0x%p, sie block at 0x%p", |
| 60 | __entry->id, __entry->vcpu, __entry->sie_block) | 60 | __entry->id, __entry->vcpu, __entry->sie_block) |
| 61 | ); | 61 | ); |
| 62 | 62 | ||
| @@ -255,7 +255,7 @@ TRACE_EVENT(kvm_s390_enable_css, · 192 unmodified lines | |||
| 255 | __entry->kvm = kvm; | 255 | __entry->kvm = kvm; |
| 256 | ), | 256 | ), |
| 257 | 257 | ||
| 258 | TP_printk("enabling channel I/O support (kvm @ %pK)\n", | 258 | TP_printk("enabling channel I/O support (kvm @ %p)\n", |
| 259 | __entry->kvm) | 259 | __entry->kvm) |
| 260 | ); | 260 | ); |
| 261 | 261 | ||
| @@ -428,6 +428,8 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data) · 427 unmodified lines | |||
| 428 | return; | 428 | return; |
| 429 | } | 429 | } |
| 430 | zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state); | 430 | zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state); |
| 431 | if (IS_ERR(zdev)) | ||
| 432 | return; | ||
| 431 | list_add_tail(&zdev->entry, scan_list); | 433 | list_add_tail(&zdev->entry, scan_list); |
| 432 | } | 434 | } |
| 433 | 435 | ||
| @@ -53,6 +53,9 @@ static struct facility_def facility_defs[] = { · 52 unmodified lines | |||
| 53 | #endif | 53 | #endif |
| 54 | #ifdef CONFIG_HAVE_MARCH_Z15_FEATURES | 54 | #ifdef CONFIG_HAVE_MARCH_Z15_FEATURES |
| 55 | 61, /* miscellaneous-instruction-extension 3 */ | 55 | 61, /* miscellaneous-instruction-extension 3 */ |
| 56 | #endif | ||
| 57 | #ifdef CONFIG_HAVE_MARCH_Z17_FEATURES | ||
| 58 | 84, /* miscellaneous-instruction-extension 4 */ | ||
| 56 | #endif | 59 | #endif |
| 57 | -1 /* END */ | 60 | -1 /* END */ |
| 58 | } | 61 | } |
| @@ -99,4 +99,3 @@ CONFIG_NLS_ISO8859_1=y · 98 unmodified lines | |||
| 99 | CONFIG_CRYPTO=y | 99 | CONFIG_CRYPTO=y |
| 100 | CONFIG_CRYPTO_CBC=y | 100 | CONFIG_CRYPTO_CBC=y |
| 101 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 101 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 102 | CONFIG_CRC_T10DIF=y | ||
| @@ -128,4 +128,3 @@ CONFIG_DEBUG_FS=y · 127 unmodified lines | |||
| 128 | CONFIG_CRYPTO=y | 128 | CONFIG_CRYPTO=y |
| 129 | CONFIG_CRYPTO_CBC=y | 129 | CONFIG_CRYPTO_CBC=y |
| 130 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 130 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 131 | CONFIG_CRC_T10DIF=y | ||
| @@ -33,4 +33,3 @@ CONFIG_CMDLINE_FROM_BOOTLOADER=y · 32 unmodified lines | |||
| 33 | # CONFIG_PROC_FS is not set | 33 | # CONFIG_PROC_FS is not set |
| 34 | # CONFIG_SYSFS is not set | 34 | # CONFIG_SYSFS is not set |
| 35 | # CONFIG_ENABLE_MUST_CHECK is not set | 35 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 36 | # CONFIG_CRC32 is not set | ||
| @@ -110,4 +110,3 @@ CONFIG_NLS_UTF8=y · 109 unmodified lines | |||
| 110 | # CONFIG_ENABLE_MUST_CHECK is not set | 110 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 111 | CONFIG_DEBUG_FS=y | 111 | CONFIG_DEBUG_FS=y |
| 112 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 112 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 113 | CONFIG_CRC_T10DIF=y | ||
| @@ -56,5 +56,3 @@ CONFIG_CRYPTO_PCBC=y · 55 unmodified lines | |||
| 56 | CONFIG_CRYPTO_MD5=y | 56 | CONFIG_CRYPTO_MD5=y |
| 57 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 57 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 58 | # CONFIG_CRYPTO_HW is not set | 58 | # CONFIG_CRYPTO_HW is not set |
| 59 | CONFIG_CRC16=y | ||
| 60 | CONFIG_CRC_T10DIF=y | ||
| @@ -49,4 +49,3 @@ CONFIG_TMPFS=y · 48 unmodified lines | |||
| 49 | # CONFIG_NETWORK_FILESYSTEMS is not set | 49 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 50 | # CONFIG_ENABLE_MUST_CHECK is not set | 50 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 51 | CONFIG_DEBUG_FS=y | 51 | CONFIG_DEBUG_FS=y |
| 52 | # CONFIG_CRC32 is not set | ||
| @@ -111,4 +111,3 @@ CONFIG_NLS_CODEPAGE_437=y · 110 unmodified lines | |||
| 111 | CONFIG_NLS_CODEPAGE_932=y | 111 | CONFIG_NLS_CODEPAGE_932=y |
| 112 | CONFIG_SH_STANDARD_BIOS=y | 112 | CONFIG_SH_STANDARD_BIOS=y |
| 113 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 113 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 114 | CONFIG_CRC_T10DIF=y | ||
| @@ -58,4 +58,3 @@ CONFIG_ROMFS_FS=y · 57 unmodified lines | |||
| 58 | CONFIG_NLS_CODEPAGE_437=y | 58 | CONFIG_NLS_CODEPAGE_437=y |
| 59 | CONFIG_SH_STANDARD_BIOS=y | 59 | CONFIG_SH_STANDARD_BIOS=y |
| 60 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 60 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 61 | CONFIG_CRC_T10DIF=y | ||
| @@ -86,5 +86,3 @@ CONFIG_DEBUG_KERNEL=y · 85 unmodified lines | |||
| 86 | CONFIG_DEBUG_KOBJECT=y | 86 | CONFIG_DEBUG_KOBJECT=y |
| 87 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 87 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 88 | CONFIG_FRAME_POINTER=y | 88 | CONFIG_FRAME_POINTER=y |
| 89 | CONFIG_CRC_CCITT=m | ||
| 90 | CONFIG_CRC16=m | ||
| @@ -90,4 +90,3 @@ CONFIG_DEBUG_FS=y · 89 unmodified lines | |||
| 90 | CONFIG_CRYPTO_MANAGER=y | 90 | CONFIG_CRYPTO_MANAGER=y |
| 91 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 91 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 92 | # CONFIG_CRYPTO_HW is not set | 92 | # CONFIG_CRYPTO_HW is not set |
| 93 | CONFIG_CRC_T10DIF=y | ||
| @@ -105,4 +105,3 @@ CONFIG_CRYPTO_ECB=m · 104 unmodified lines | |||
| 105 | CONFIG_CRYPTO_PCBC=m | 105 | CONFIG_CRYPTO_PCBC=m |
| 106 | CONFIG_CRYPTO_HMAC=y | 106 | CONFIG_CRYPTO_HMAC=y |
| 107 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 107 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 108 | CONFIG_CRC_T10DIF=y | ||
| @@ -103,4 +103,3 @@ CONFIG_CRYPTO_ECB=m · 102 unmodified lines | |||
| 103 | CONFIG_CRYPTO_PCBC=m | 103 | CONFIG_CRYPTO_PCBC=m |
| 104 | CONFIG_CRYPTO_HMAC=y | 104 | CONFIG_CRYPTO_HMAC=y |
| 105 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 105 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 106 | CONFIG_CRC_T10DIF=y | ||
| @@ -87,4 +87,3 @@ CONFIG_MINIX_FS=y · 86 unmodified lines | |||
| 87 | CONFIG_NLS_CODEPAGE_932=y | 87 | CONFIG_NLS_CODEPAGE_932=y |
| 88 | CONFIG_DEBUG_FS=y | 88 | CONFIG_DEBUG_FS=y |
| 89 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 89 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 90 | CONFIG_CRC_T10DIF=y | ||
| @@ -92,4 +92,3 @@ CONFIG_MINIX_FS=y · 91 unmodified lines | |||
| 92 | CONFIG_NLS_CODEPAGE_932=y | 92 | CONFIG_NLS_CODEPAGE_932=y |
| 93 | CONFIG_DEBUG_FS=y | 93 | CONFIG_DEBUG_FS=y |
| 94 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 94 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 95 | CONFIG_CRC_T10DIF=y | ||
| @@ -136,4 +136,3 @@ CONFIG_SH_STANDARD_BIOS=y · 135 unmodified lines | |||
| 136 | CONFIG_CRYPTO_MD5=y | 136 | CONFIG_CRYPTO_MD5=y |
| 137 | CONFIG_CRYPTO_DES=y | 137 | CONFIG_CRYPTO_DES=y |
| 138 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 138 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 139 | CONFIG_CRC_T10DIF=y | ||
| @@ -101,6 +101,3 @@ CONFIG_CRYPTO_DEFLATE=y · 100 unmodified lines | |||
| 101 | CONFIG_CRYPTO_LZO=y | 101 | CONFIG_CRYPTO_LZO=y |
| 102 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 102 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 103 | # CONFIG_CRYPTO_HW is not set | 103 | # CONFIG_CRYPTO_HW is not set |
| 104 | CONFIG_CRC_CCITT=y | ||
| 105 | CONFIG_CRC16=y | ||
| 106 | CONFIG_CRC_ITU_T=y | ||
| @@ -96,4 +96,3 @@ CONFIG_FRAME_POINTER=y · 95 unmodified lines | |||
| 96 | CONFIG_CRYPTO_ECB=m | 96 | CONFIG_CRYPTO_ECB=m |
| 97 | CONFIG_CRYPTO_PCBC=m | 97 | CONFIG_CRYPTO_PCBC=m |
| 98 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 98 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 99 | CONFIG_CRC_CCITT=y | ||
| @@ -122,4 +122,3 @@ CONFIG_DEBUG_KERNEL=y · 121 unmodified lines | |||
| 122 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | 122 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 123 | CONFIG_FRAME_POINTER=y | 123 | CONFIG_FRAME_POINTER=y |
| 124 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 124 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 125 | CONFIG_CRC_CCITT=y | ||
| @@ -128,4 +128,3 @@ CONFIG_NLS_ISO8859_1=y · 127 unmodified lines | |||
| 128 | CONFIG_CRYPTO=y | 128 | CONFIG_CRYPTO=y |
| 129 | CONFIG_CRYPTO_CBC=y | 129 | CONFIG_CRYPTO_CBC=y |
| 130 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 130 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 131 | CONFIG_CRC_T10DIF=y | ||
| @@ -120,6 +120,5 @@ CONFIG_CRYPTO_HMAC=y · 119 unmodified lines | |||
| 120 | CONFIG_CRYPTO_SHA1=y | 120 | CONFIG_CRYPTO_SHA1=y |
| 121 | CONFIG_CRYPTO_DEFLATE=y | 121 | CONFIG_CRYPTO_DEFLATE=y |
| 122 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 122 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 123 | CONFIG_CRC_CCITT=y | ||
| 124 | CONFIG_RTC_CLASS=y | 123 | CONFIG_RTC_CLASS=y |
| 125 | CONFIG_RTC_DRV_GENERIC=y | 124 | CONFIG_RTC_DRV_GENERIC=y |
| @@ -193,5 +193,3 @@ CONFIG_CRYPTO_DEFLATE=y · 192 unmodified lines | |||
| 193 | CONFIG_CRYPTO_LZO=y | 193 | CONFIG_CRYPTO_LZO=y |
| 194 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 194 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 195 | # CONFIG_CRYPTO_HW is not set | 195 | # CONFIG_CRYPTO_HW is not set |
| 196 | CONFIG_CRC_CCITT=y | ||
| 197 | CONFIG_CRC16=y | ||
| @@ -39,4 +39,3 @@ CONFIG_UIO_PDRV_GENIRQ=y · 38 unmodified lines | |||
| 39 | # CONFIG_SYSFS is not set | 39 | # CONFIG_SYSFS is not set |
| 40 | # CONFIG_MISC_FILESYSTEMS is not set | 40 | # CONFIG_MISC_FILESYSTEMS is not set |
| 41 | # CONFIG_ENABLE_MUST_CHECK is not set | 41 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 42 | # CONFIG_CRC32 is not set | ||
| @@ -112,4 +112,3 @@ CONFIG_NLS_UTF8=y · 111 unmodified lines | |||
| 112 | # CONFIG_ENABLE_MUST_CHECK is not set | 112 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 113 | CONFIG_DEBUG_FS=y | 113 | CONFIG_DEBUG_FS=y |
| 114 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 114 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 115 | CONFIG_CRC_T10DIF=y | ||
| @@ -41,4 +41,3 @@ CONFIG_UIO_PDRV_GENIRQ=y · 40 unmodified lines | |||
| 41 | # CONFIG_SYSFS is not set | 41 | # CONFIG_SYSFS is not set |
| 42 | # CONFIG_MISC_FILESYSTEMS is not set | 42 | # CONFIG_MISC_FILESYSTEMS is not set |
| 43 | # CONFIG_ENABLE_MUST_CHECK is not set | 43 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 44 | # CONFIG_CRC32 is not set | ||
| @@ -264,4 +264,3 @@ CONFIG_CRYPTO_SERPENT=m · 263 unmodified lines | |||
| 264 | CONFIG_CRYPTO_TEA=m | 264 | CONFIG_CRYPTO_TEA=m |
| 265 | CONFIG_CRYPTO_TWOFISH=m | 265 | CONFIG_CRYPTO_TWOFISH=m |
| 266 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 266 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 267 | CONFIG_CRC16=m | ||
| @@ -229,7 +229,6 @@ CONFIG_CRYPTO_SERPENT=m · 228 unmodified lines | |||
| 229 | CONFIG_CRYPTO_TEA=m | 229 | CONFIG_CRYPTO_TEA=m |
| 230 | CONFIG_CRYPTO_TWOFISH=m | 230 | CONFIG_CRYPTO_TWOFISH=m |
| 231 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 231 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 232 | CONFIG_CRC16=m | ||
| 233 | CONFIG_VCC=m | 232 | CONFIG_VCC=m |
| 234 | CONFIG_PATA_CMD64X=y | 233 | CONFIG_PATA_CMD64X=y |
| 235 | CONFIG_IP_PNP=y | 234 | CONFIG_IP_PNP=y |
| @@ -154,5 +154,6 @@ MRPROPER_FILES += $(HOST_DIR)/include/generated · 153 unmodified lines | |||
| 154 | archclean: | 154 | archclean: |
| 155 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ | 155 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ |
| 156 | -o -name '*.gcov' \) -type f -print | xargs rm -f | 156 | -o -name '*.gcov' \) -type f -print | xargs rm -f |
| 157 | $(Q)$(MAKE) -f $(srctree)/Makefile ARCH=$(HEADER_ARCH) clean | ||
| 157 | 158 | ||
| 158 | export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING DEV_NULL_PATH | 159 | export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING DEV_NULL_PATH |
| @@ -55,6 +55,7 @@ do { \ · 54 unmodified lines | |||
| 55 | goto err_label; \ | 55 | goto err_label; \ |
| 56 | } \ | 56 | } \ |
| 57 | *((type *)dst) = get_unaligned((type *)(src)); \ | 57 | *((type *)dst) = get_unaligned((type *)(src)); \ |
| 58 | barrier(); \ | ||
| 58 | current->thread.segv_continue = NULL; \ | 59 | current->thread.segv_continue = NULL; \ |
| 59 | } while (0) | 60 | } while (0) |
| 60 | 61 | ||
| @@ -66,6 +67,7 @@ do { \ · 5 unmodified lines | |||
| 66 | if (__faulted) \ | 67 | if (__faulted) \ |
| 67 | goto err_label; \ | 68 | goto err_label; \ |
| 68 | put_unaligned(*((type *)src), (type *)(dst)); \ | 69 | put_unaligned(*((type *)src), (type *)(dst)); \ |
| 70 | barrier(); \ | ||
| 69 | current->thread.segv_continue = NULL; \ | 71 | current->thread.segv_continue = NULL; \ |
| 70 | } while (0) | 72 | } while (0) |
| 71 | 73 | ||
| @@ -225,20 +225,20 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, · 224 unmodified lines | |||
| 225 | panic("Failed to sync kernel TLBs: %d", err); | 225 | panic("Failed to sync kernel TLBs: %d", err); |
| 226 | goto out; | 226 | goto out; |
| 227 | } | 227 | } |
| 228 | else if (current->mm == NULL) { | 228 | else if (current->pagefault_disabled) { |
| 229 | if (current->pagefault_disabled) { | 229 | if (!mc) { |
| 230 | if (!mc) { | 230 | show_regs(container_of(regs, struct pt_regs, regs)); |
| 231 | show_regs(container_of(regs, struct pt_regs, regs)); | 231 | panic("Segfault with pagefaults disabled but no mcontext"); |
| 232 | panic("Segfault with pagefaults disabled but no mcontext"); | ||
| 233 | } | ||
| 234 | if (!current->thread.segv_continue) { | ||
| 235 | show_regs(container_of(regs, struct pt_regs, regs)); | ||
| 236 | panic("Segfault without recovery target"); | ||
| 237 | } | ||
| 238 | mc_set_rip(mc, current->thread.segv_continue); | ||
| 239 | current->thread.segv_continue = NULL; | ||
| 240 | goto out; | ||
| 241 | } | 232 | } |
| 233 | if (!current->thread.segv_continue) { | ||
| 234 | show_regs(container_of(regs, struct pt_regs, regs)); | ||
| 235 | panic("Segfault without recovery target"); | ||
| 236 | } | ||
| 237 | mc_set_rip(mc, current->thread.segv_continue); | ||
| 238 | current->thread.segv_continue = NULL; | ||
| 239 | goto out; | ||
| 240 | } | ||
| 241 | else if (current->mm == NULL) { | ||
| 242 | show_regs(container_of(regs, struct pt_regs, regs)); | 242 | show_regs(container_of(regs, struct pt_regs, regs)); |
| 243 | panic("Segfault with no mm"); | 243 | panic("Segfault with no mm"); |
| 244 | } | 244 | } |
| @@ -2368,6 +2368,7 @@ config STRICT_SIGALTSTACK_SIZE · 2367 unmodified lines | |||
| 2368 | config CFI_AUTO_DEFAULT | 2368 | config CFI_AUTO_DEFAULT |
| 2369 | bool "Attempt to use FineIBT by default at boot time" | 2369 | bool "Attempt to use FineIBT by default at boot time" |
| 2370 | depends on FINEIBT | 2370 | depends on FINEIBT |
| 2371 | depends on !RUST || RUSTC_VERSION >= 108800 | ||
| 2371 | default y | 2372 | default y |
| 2372 | help | 2373 | help |
| 2373 | Attempt to use FineIBT by default at boot time. If enabled, | 2374 | Attempt to use FineIBT by default at boot time. If enabled, |
| @@ -2710,6 +2711,18 @@ config MITIGATION_SSB · 336 unmodified lines | |||
| 2710 | of speculative execution in a similar way to the Meltdown and Spectre | 2711 | of speculative execution in a similar way to the Meltdown and Spectre |
| 2711 | security vulnerabilities. | 2712 | security vulnerabilities. |
| 2712 | 2713 | ||
| 2714 | config MITIGATION_ITS | ||
| 2715 | bool "Enable Indirect Target Selection mitigation" | ||
| 2716 | depends on CPU_SUP_INTEL && X86_64 | ||
| 2717 | depends on MITIGATION_RETPOLINE && MITIGATION_RETHUNK | ||
| 2718 | select EXECMEM | ||
| 2719 | default y | ||
| 2720 | help | ||
| 2721 | Enable Indirect Target Selection (ITS) mitigation. ITS is a bug in | ||
| 2722 | BPU on some Intel CPUs that may allow Spectre V2 style attacks. If | ||
| 2723 | disabled, mitigation cannot be enabled via cmdline. | ||
| 2724 | See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst> | ||
| 2725 | |||
| 2713 | endif | 2726 | endif |
| 2714 | 2727 | ||
| 2715 | config ARCH_HAS_ADD_PAGES | 2728 | config ARCH_HAS_ADD_PAGES |
| @@ -59,7 +59,7 @@ KBUILD_CFLAGS += $(CONFIG_CC_IMPLICIT_FALLTHROUGH) · 58 unmodified lines | |||
| 59 | $(obj)/bzImage: asflags-y := $(SVGA_MODE) | 59 | $(obj)/bzImage: asflags-y := $(SVGA_MODE) |
| 60 | 60 | ||
| 61 | quiet_cmd_image = BUILD $@ | 61 | quiet_cmd_image = BUILD $@ |
| 62 | cmd_image = cp $< $@; truncate -s %4K $@; cat $(obj)/vmlinux.bin >>$@ | 62 | cmd_image = (dd if=$< bs=4k conv=sync status=none; cat $(filter-out $<,$(real-prereqs))) >$@ |
| 63 | 63 | ||
| 64 | $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin FORCE | 64 | $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin FORCE |
| 65 | $(call if_changed,image) | 65 | $(call if_changed,image) |
| @@ -38,7 +38,7 @@ void arch_accept_memory(phys_addr_t start, phys_addr_t end) · 37 unmodified lines | |||
| 38 | if (early_is_tdx_guest()) { | 38 | if (early_is_tdx_guest()) { |
| 39 | if (!tdx_accept_memory(start, end)) | 39 | if (!tdx_accept_memory(start, end)) |
| 40 | panic("TDX: Failed to accept memory\n"); | 40 | panic("TDX: Failed to accept memory\n"); |
| 41 | } else if (sev_snp_enabled()) { | 41 | } else if (early_is_sevsnp_guest()) { |
| 42 | snp_accept_memory(start, end); | 42 | snp_accept_memory(start, end); |
| 43 | } else { | 43 | } else { |
| 44 | error("Cannot accept memory: unknown platform\n"); | 44 | error("Cannot accept memory: unknown platform\n"); |
| @@ -164,10 +164,7 @@ bool sev_snp_enabled(void) · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | static void __page_state_change(unsigned long paddr, enum psc_op op) | 165 | static void __page_state_change(unsigned long paddr, enum psc_op op) |
| 166 | { | 166 | { |
| 167 | u64 val; | 167 | u64 val, msr; |
| 168 | |||
| 169 | if (!sev_snp_enabled()) | ||
| 170 | return; | ||
| 171 | 168 | ||
| 172 | /* | 169 | /* |
| 173 | * If private -> shared then invalidate the page before requesting the | 170 | * 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) · 2 unmodified lines | |||
| 176 | if (op == SNP_PAGE_STATE_SHARED) | 173 | if (op == SNP_PAGE_STATE_SHARED) |
| 177 | pvalidate_4k_page(paddr, paddr, false); | 174 | pvalidate_4k_page(paddr, paddr, false); |
| 178 | 175 | ||
| 176 | /* Save the current GHCB MSR value */ | ||
| 177 | msr = sev_es_rd_ghcb_msr(); | ||
| 178 | |||
| 179 | /* Issue VMGEXIT to change the page state in RMP table. */ | 179 | /* Issue VMGEXIT to change the page state in RMP table. */ |
| 180 | sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op)); | 180 | sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op)); |
| 181 | VMGEXIT(); | 181 | VMGEXIT(); |
| @@ -185,6 +185,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op) · 3 unmodified lines | |||
| 185 | if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val)) | 185 | if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val)) |
| 186 | sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); | 186 | sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); |
| 187 | 187 | ||
| 188 | /* Restore the GHCB MSR value */ | ||
| 189 | sev_es_wr_ghcb_msr(msr); | ||
| 190 | |||
| 188 | /* | 191 | /* |
| 189 | * Now that page state is changed in the RMP table, validate it so that it is | 192 | * Now that page state is changed in the RMP table, validate it so that it is |
| 190 | * consistent with the RMP entry. | 193 | * consistent with the RMP entry. |
| @@ -195,11 +198,17 @@ static void __page_state_change(unsigned long paddr, enum psc_op op) · 4 unmodified lines | |||
| 195 | 198 | ||
| 196 | void snp_set_page_private(unsigned long paddr) | 199 | void snp_set_page_private(unsigned long paddr) |
| 197 | { | 200 | { |
| 201 | if (!sev_snp_enabled()) | ||
| 202 | return; | ||
| 203 | |||
| 198 | __page_state_change(paddr, SNP_PAGE_STATE_PRIVATE); | 204 | __page_state_change(paddr, SNP_PAGE_STATE_PRIVATE); |
| 199 | } | 205 | } |
| 200 | 206 | ||
| 201 | void snp_set_page_shared(unsigned long paddr) | 207 | void snp_set_page_shared(unsigned long paddr) |
| 202 | { | 208 | { |
| 209 | if (!sev_snp_enabled()) | ||
| 210 | return; | ||
| 211 | |||
| 203 | __page_state_change(paddr, SNP_PAGE_STATE_SHARED); | 212 | __page_state_change(paddr, SNP_PAGE_STATE_SHARED); |
| 204 | } | 213 | } |
| 205 | 214 | ||
| @@ -223,56 +232,10 @@ static bool early_setup_ghcb(void) · 17 unmodified lines | |||
| 223 | return true; | 232 | return true; |
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | static phys_addr_t __snp_accept_memory(struct snp_psc_desc *desc, | ||
| 227 | phys_addr_t pa, phys_addr_t pa_end) | ||
| 228 | { | ||
| 229 | struct psc_hdr *hdr; | ||
| 230 | struct psc_entry *e; | ||
| 231 | unsigned int i; | ||
| 232 | |||
| 233 | hdr = &desc->hdr; | ||
| 234 | memset(hdr, 0, sizeof(*hdr)); | ||
| 235 | |||
| 236 | e = desc->entries; | ||
| 237 | |||
| 238 | i = 0; | ||
| 239 | while (pa < pa_end && i < VMGEXIT_PSC_MAX_ENTRY) { | ||
| 240 | hdr->end_entry = i; | ||
| 241 | |||
| 242 | e->gfn = pa >> PAGE_SHIFT; | ||
| 243 | e->operation = SNP_PAGE_STATE_PRIVATE; | ||
| 244 | if (IS_ALIGNED(pa, PMD_SIZE) && (pa_end - pa) >= PMD_SIZE) { | ||
| 245 | e->pagesize = RMP_PG_SIZE_2M; | ||
| 246 | pa += PMD_SIZE; | ||
| 247 | } else { | ||
| 248 | e->pagesize = RMP_PG_SIZE_4K; | ||
| 249 | pa += PAGE_SIZE; | ||
| 250 | } | ||
| 251 | |||
| 252 | e++; | ||
| 253 | i++; | ||
| 254 | } | ||
| 255 | |||
| 256 | if (vmgexit_psc(boot_ghcb, desc)) | ||
| 257 | sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); | ||
| 258 | |||
| 259 | pvalidate_pages(desc); | ||
| 260 | |||
| 261 | return pa; | ||
| 262 | } | ||
| 263 | |||
| 264 | void snp_accept_memory(phys_addr_t start, phys_addr_t end) | 235 | void snp_accept_memory(phys_addr_t start, phys_addr_t end) |
| 265 | { | 236 | { |
| 266 | struct snp_psc_desc desc = {}; | 237 | for (phys_addr_t pa = start; pa < end; pa += PAGE_SIZE) |
| 267 | unsigned int i; | 238 | __page_state_change(pa, SNP_PAGE_STATE_PRIVATE); |
| 268 | phys_addr_t pa; | ||
| 269 | |||
| 270 | if (!boot_ghcb && !early_setup_ghcb()) | ||
| 271 | sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); | ||
| 272 | |||
| 273 | pa = start; | ||
| 274 | while (pa < end) | ||
| 275 | pa = __snp_accept_memory(&desc, pa, end); | ||
| 276 | } | 239 | } |
| 277 | 240 | ||
| 278 | void sev_es_shutdown_ghcb(void) | 241 | void sev_es_shutdown_ghcb(void) |
| @@ -682,3 +645,43 @@ void sev_prep_identity_maps(unsigned long top_level_pgt) · 403 unmodified lines | |||
| 682 | 645 | ||
| 683 | sev_verify_cbit(top_level_pgt); | 646 | sev_verify_cbit(top_level_pgt); |
| 684 | } | 647 | } |
| 648 | |||
| 649 | bool early_is_sevsnp_guest(void) | ||
| 650 | { | ||
| 651 | static bool sevsnp; | ||
| 652 | |||
| 653 | if (sevsnp) | ||
| 654 | return true; | ||
| 655 | |||
| 656 | if (!(sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) | ||
| 657 | return false; | ||
| 658 | |||
| 659 | sevsnp = true; | ||
| 660 | |||
| 661 | if (!snp_vmpl) { | ||
| 662 | unsigned int eax, ebx, ecx, edx; | ||
| 663 | |||
| 664 | /* | ||
| 665 | * CPUID Fn8000_001F_EAX[28] - SVSM support | ||
| 666 | */ | ||
| 667 | eax = 0x8000001f; | ||
| 668 | ecx = 0; | ||
| 669 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
| 670 | if (eax & BIT(28)) { | ||
| 671 | struct msr m; | ||
| 672 | |||
| 673 | /* Obtain the address of the calling area to use */ | ||
| 674 | boot_rdmsr(MSR_SVSM_CAA, &m); | ||
| 675 | boot_svsm_caa = (void *)m.q; | ||
| 676 | boot_svsm_caa_pa = m.q; | ||
| 677 | |||
| 678 | /* | ||
| 679 | * The real VMPL level cannot be discovered, but the | ||
| 680 | * memory acceptance routines make no use of that so | ||
| 681 | * any non-zero value suffices here. | ||
| 682 | */ | ||
| 683 | snp_vmpl = U8_MAX; | ||
| 684 | } | ||
| 685 | } | ||
| 686 | return true; | ||
| 687 | } | ||
| @@ -12,11 +12,15 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | bool sev_snp_enabled(void); | 13 | bool sev_snp_enabled(void); |
| 14 | void snp_accept_memory(phys_addr_t start, phys_addr_t end); | 14 | void snp_accept_memory(phys_addr_t start, phys_addr_t end); |
| 15 | u64 sev_get_status(void); | ||
| 16 | bool early_is_sevsnp_guest(void); | ||
| 15 | 17 | ||
| 16 | #else | 18 | #else |
| 17 | 19 | ||
| 18 | static inline bool sev_snp_enabled(void) { return false; } | 20 | static inline bool sev_snp_enabled(void) { return false; } |
| 19 | static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { } | 21 | static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { } |
| 22 | static inline u64 sev_get_status(void) { return 0; } | ||
| 23 | static inline bool early_is_sevsnp_guest(void) { return false; } | ||
| 20 | 24 | ||
| 21 | #endif | 25 | #endif |
| 22 | 26 | ||
| @@ -959,6 +959,102 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end) · 958 unmodified lines | |||
| 959 | set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE); | 959 | set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE); |
| 960 | } | 960 | } |
| 961 | 961 | ||
| 962 | static int vmgexit_ap_control(u64 event, struct sev_es_save_area *vmsa, u32 apic_id) | ||
| 963 | { | ||
| 964 | bool create = event != SVM_VMGEXIT_AP_DESTROY; | ||
| 965 | struct ghcb_state state; | ||
| 966 | unsigned long flags; | ||
| 967 | struct ghcb *ghcb; | ||
| 968 | int ret = 0; | ||
| 969 | |||
| 970 | local_irq_save(flags); | ||
| 971 | |||
| 972 | ghcb = __sev_get_ghcb(&state); | ||
| 973 | |||
| 974 | vc_ghcb_invalidate(ghcb); | ||
| 975 | |||
| 976 | if (create) | ||
| 977 | ghcb_set_rax(ghcb, vmsa->sev_features); | ||
| 978 | |||
| 979 | ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION); | ||
| 980 | ghcb_set_sw_exit_info_1(ghcb, | ||
| 981 | ((u64)apic_id << 32) | | ||
| 982 | ((u64)snp_vmpl << 16) | | ||
| 983 | event); | ||
| 984 | ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa)); | ||
| 985 | |||
| 986 | sev_es_wr_ghcb_msr(__pa(ghcb)); | ||
| 987 | VMGEXIT(); | ||
| 988 | |||
| 989 | if (!ghcb_sw_exit_info_1_is_valid(ghcb) || | ||
| 990 | lower_32_bits(ghcb->save.sw_exit_info_1)) { | ||
| 991 | pr_err("SNP AP %s error\n", (create ? "CREATE" : "DESTROY")); | ||
| 992 | ret = -EINVAL; | ||
| 993 | } | ||
| 994 | |||
| 995 | __sev_put_ghcb(&state); | ||
| 996 | |||
| 997 | local_irq_restore(flags); | ||
| 998 | |||
| 999 | return ret; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa) | ||
| 1003 | { | ||
| 1004 | int ret; | ||
| 1005 | |||
| 1006 | if (snp_vmpl) { | ||
| 1007 | struct svsm_call call = {}; | ||
| 1008 | unsigned long flags; | ||
| 1009 | |||
| 1010 | local_irq_save(flags); | ||
| 1011 | |||
| 1012 | call.caa = this_cpu_read(svsm_caa); | ||
| 1013 | call.rcx = __pa(va); | ||
| 1014 | |||
| 1015 | if (make_vmsa) { | ||
| 1016 | /* Protocol 0, Call ID 2 */ | ||
| 1017 | call.rax = SVSM_CORE_CALL(SVSM_CORE_CREATE_VCPU); | ||
| 1018 | call.rdx = __pa(caa); | ||
| 1019 | call.r8 = apic_id; | ||
| 1020 | } else { | ||
| 1021 | /* Protocol 0, Call ID 3 */ | ||
| 1022 | call.rax = SVSM_CORE_CALL(SVSM_CORE_DELETE_VCPU); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | ret = svsm_perform_call_protocol(&call); | ||
| 1026 | |||
| 1027 | local_irq_restore(flags); | ||
| 1028 | } else { | ||
| 1029 | /* | ||
| 1030 | * If the kernel runs at VMPL0, it can change the VMSA | ||
| 1031 | * bit for a page using the RMPADJUST instruction. | ||
| 1032 | * However, for the instruction to succeed it must | ||
| 1033 | * target the permissions of a lesser privileged (higher | ||
| 1034 | * numbered) VMPL level, so use VMPL1. | ||
| 1035 | */ | ||
| 1036 | u64 attrs = 1; | ||
| 1037 | |||
| 1038 | if (make_vmsa) | ||
| 1039 | attrs |= RMPADJUST_VMSA_PAGE_BIT; | ||
| 1040 | |||
| 1041 | ret = rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs); | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | return ret; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id) | ||
| 1048 | { | ||
| 1049 | int err; | ||
| 1050 | |||
| 1051 | err = snp_set_vmsa(vmsa, NULL, apic_id, false); | ||
| 1052 | if (err) | ||
| 1053 | pr_err("clear VMSA page failed (%u), leaking page\n", err); | ||
| 1054 | else | ||
| 1055 | free_page((unsigned long)vmsa); | ||
| 1056 | } | ||
| 1057 | |||
| 962 | static void set_pte_enc(pte_t *kpte, int level, void *va) | 1058 | static void set_pte_enc(pte_t *kpte, int level, void *va) |
| 963 | { | 1059 | { |
| 964 | struct pte_enc_desc d = { | 1060 | struct pte_enc_desc d = { |
| @@ -1005,7 +1101,8 @@ static void unshare_all_memory(void) · 40 unmodified lines | |||
| 1005 | data = per_cpu(runtime_data, cpu); | 1101 | data = per_cpu(runtime_data, cpu); |
| 1006 | ghcb = (unsigned long)&data->ghcb_page; | 1102 | ghcb = (unsigned long)&data->ghcb_page; |
| 1007 | 1103 | ||
| 1008 | if (addr <= ghcb && ghcb <= addr + size) { | 1104 | /* Handle the case of a huge page containing the GHCB page */ |
| 1105 | if (addr <= ghcb && ghcb < addr + size) { | ||
| 1009 | skipped_addr = true; | 1106 | skipped_addr = true; |
| 1010 | break; | 1107 | break; |
| 1011 | } | 1108 | } |
| @@ -1055,11 +1152,70 @@ void snp_kexec_begin(void) · 43 unmodified lines | |||
| 1055 | pr_warn("Failed to stop shared<->private conversions\n"); | 1152 | pr_warn("Failed to stop shared<->private conversions\n"); |
| 1056 | } | 1153 | } |
| 1057 | 1154 | ||
| 1155 | /* | ||
| 1156 | * Shutdown all APs except the one handling kexec/kdump and clearing | ||
| 1157 | * the VMSA tag on AP's VMSA pages as they are not being used as | ||
| 1158 | * VMSA page anymore. | ||
| 1159 | */ | ||
| 1160 | static void shutdown_all_aps(void) | ||
| 1161 | { | ||
| 1162 | struct sev_es_save_area *vmsa; | ||
| 1163 | int apic_id, this_cpu, cpu; | ||
| 1164 | |||
| 1165 | this_cpu = get_cpu(); | ||
| 1166 | |||
| 1167 | /* | ||
| 1168 | * APs are already in HLT loop when enc_kexec_finish() callback | ||
| 1169 | * is invoked. | ||
| 1170 | */ | ||
| 1171 | for_each_present_cpu(cpu) { | ||
| 1172 | vmsa = per_cpu(sev_vmsa, cpu); | ||
| 1173 | |||
| 1174 | /* | ||
| 1175 | * The BSP or offlined APs do not have guest allocated VMSA | ||
| 1176 | * and there is no need to clear the VMSA tag for this page. | ||
| 1177 | */ | ||
| 1178 | if (!vmsa) | ||
| 1179 | continue; | ||
| 1180 | |||
| 1181 | /* | ||
| 1182 | * Cannot clear the VMSA tag for the currently running vCPU. | ||
| 1183 | */ | ||
| 1184 | if (this_cpu == cpu) { | ||
| 1185 | unsigned long pa; | ||
| 1186 | struct page *p; | ||
| 1187 | |||
| 1188 | pa = __pa(vmsa); | ||
| 1189 | /* | ||
| 1190 | * Mark the VMSA page of the running vCPU as offline | ||
| 1191 | * so that is excluded and not touched by makedumpfile | ||
| 1192 | * while generating vmcore during kdump. | ||
| 1193 | */ | ||
| 1194 | p = pfn_to_online_page(pa >> PAGE_SHIFT); | ||
| 1195 | if (p) | ||
| 1196 | __SetPageOffline(p); | ||
| 1197 | continue; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | apic_id = cpuid_to_apicid[cpu]; | ||
| 1201 | |||
| 1202 | /* | ||
| 1203 | * Issue AP destroy to ensure AP gets kicked out of guest mode | ||
| 1204 | * to allow using RMPADJUST to remove the VMSA tag on it's | ||
| 1205 | * VMSA page. | ||
| 1206 | */ | ||
| 1207 | vmgexit_ap_control(SVM_VMGEXIT_AP_DESTROY, vmsa, apic_id); | ||
| 1208 | snp_cleanup_vmsa(vmsa, apic_id); | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | put_cpu(); | ||
| 1212 | } | ||
| 1213 | |||
| 1058 | void snp_kexec_finish(void) | 1214 | void snp_kexec_finish(void) |
| 1059 | { | 1215 | { |
| 1060 | struct sev_es_runtime_data *data; | 1216 | struct sev_es_runtime_data *data; |
| 1217 | unsigned long size, addr; | ||
| 1061 | unsigned int level, cpu; | 1218 | unsigned int level, cpu; |
| 1062 | unsigned long size; | ||
| 1063 | struct ghcb *ghcb; | 1219 | struct ghcb *ghcb; |
| 1064 | pte_t *pte; | 1220 | pte_t *pte; |
| 1065 | 1221 | ||
| @@ -1069,6 +1225,8 @@ void snp_kexec_finish(void) · 3 unmodified lines | |||
| 1069 | if (!IS_ENABLED(CONFIG_KEXEC_CORE)) | 1225 | if (!IS_ENABLED(CONFIG_KEXEC_CORE)) |
| 1070 | return; | 1226 | return; |
| 1071 | 1227 | ||
| 1228 | shutdown_all_aps(); | ||
| 1229 | |||
| 1072 | unshare_all_memory(); | 1230 | unshare_all_memory(); |
| 1073 | 1231 | ||
| 1074 | /* | 1232 | /* |
| @@ -1085,54 +1243,11 @@ void snp_kexec_finish(void) · 10 unmodified lines | |||
| 1085 | ghcb = &data->ghcb_page; | 1243 | ghcb = &data->ghcb_page; |
| 1086 | pte = lookup_address((unsigned long)ghcb, &level); | 1244 | pte = lookup_address((unsigned long)ghcb, &level); |
| 1087 | size = page_level_size(level); | 1245 | size = page_level_size(level); |
| 1088 | set_pte_enc(pte, level, (void *)ghcb); | 1246 | /* Handle the case of a huge page containing the GHCB page */ |
| 1089 | snp_set_memory_private((unsigned long)ghcb, (size / PAGE_SIZE)); | 1247 | addr = (unsigned long)ghcb & page_level_mask(level); |
| 1090 | } | 1248 | set_pte_enc(pte, level, (void *)addr); |
| 1091 | } | 1249 | snp_set_memory_private(addr, (size / PAGE_SIZE)); |
| 1092 | |||
| 1093 | static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa) | ||
| 1094 | { | ||
| 1095 | int ret; | ||
| 1096 | |||
| 1097 | if (snp_vmpl) { | ||
| 1098 | struct svsm_call call = {}; | ||
| 1099 | unsigned long flags; | ||
| 1100 | |||
| 1101 | local_irq_save(flags); | ||
| 1102 | |||
| 1103 | call.caa = this_cpu_read(svsm_caa); | ||
| 1104 | call.rcx = __pa(va); | ||
| 1105 | |||
| 1106 | if (make_vmsa) { | ||
| 1107 | /* Protocol 0, Call ID 2 */ | ||
| 1108 | call.rax = SVSM_CORE_CALL(SVSM_CORE_CREATE_VCPU); | ||
| 1109 | call.rdx = __pa(caa); | ||
| 1110 | call.r8 = apic_id; | ||
| 1111 | } else { | ||
| 1112 | /* Protocol 0, Call ID 3 */ | ||
| 1113 | call.rax = SVSM_CORE_CALL(SVSM_CORE_DELETE_VCPU); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | ret = svsm_perform_call_protocol(&call); | ||
| 1117 | |||
| 1118 | local_irq_restore(flags); | ||
| 1119 | } else { | ||
| 1120 | /* | ||
| 1121 | * If the kernel runs at VMPL0, it can change the VMSA | ||
| 1122 | * bit for a page using the RMPADJUST instruction. | ||
| 1123 | * However, for the instruction to succeed it must | ||
| 1124 | * target the permissions of a lesser privileged (higher | ||
| 1125 | * numbered) VMPL level, so use VMPL1. | ||
| 1126 | */ | ||
| 1127 | u64 attrs = 1; | ||
| 1128 | |||
| 1129 | if (make_vmsa) | ||
| 1130 | attrs |= RMPADJUST_VMSA_PAGE_BIT; | ||
| 1131 | |||
| 1132 | ret = rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs); | ||
| 1133 | } | 1250 | } |
| 1134 | |||
| 1135 | return ret; | ||
| 1136 | } | 1251 | } |
| 1137 | 1252 | ||
| 1138 | #define __ATTR_BASE (SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK) | 1253 | #define __ATTR_BASE (SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK) |
| @@ -1166,24 +1281,10 @@ static void *snp_alloc_vmsa_page(int cpu) · 27 unmodified lines | |||
| 1166 | return page_address(p + 1); | 1281 | return page_address(p + 1); |
| 1167 | } | 1282 | } |
| 1168 | 1283 | ||
| 1169 | static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id) | ||
| 1170 | { | ||
| 1171 | int err; | ||
| 1172 | |||
| 1173 | err = snp_set_vmsa(vmsa, NULL, apic_id, false); | ||
| 1174 | if (err) | ||
| 1175 | pr_err("clear VMSA page failed (%u), leaking page\n", err); | ||
| 1176 | else | ||
| 1177 | free_page((unsigned long)vmsa); | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip) | 1284 | static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip) |
| 1181 | { | 1285 | { |
| 1182 | struct sev_es_save_area *cur_vmsa, *vmsa; | 1286 | struct sev_es_save_area *cur_vmsa, *vmsa; |
| 1183 | struct ghcb_state state; | ||
| 1184 | struct svsm_ca *caa; | 1287 | struct svsm_ca *caa; |
| 1185 | unsigned long flags; | ||
| 1186 | struct ghcb *ghcb; | ||
| 1187 | u8 sipi_vector; | 1288 | u8 sipi_vector; |
| 1188 | int cpu, ret; | 1289 | int cpu, ret; |
| 1189 | u64 cr4; | 1290 | u64 cr4; |
| @@ -1297,33 +1398,7 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip) · 107 unmodified lines | |||
| 1297 | } | 1398 | } |
| 1298 | 1399 | ||
| 1299 | /* Issue VMGEXIT AP Creation NAE event */ | 1400 | /* Issue VMGEXIT AP Creation NAE event */ |
| 1300 | local_irq_save(flags); | 1401 | ret = vmgexit_ap_control(SVM_VMGEXIT_AP_CREATE, vmsa, apic_id); |
| 1301 | |||
| 1302 | ghcb = __sev_get_ghcb(&state); | ||
| 1303 | |||
| 1304 | vc_ghcb_invalidate(ghcb); | ||
| 1305 | ghcb_set_rax(ghcb, vmsa->sev_features); | ||
| 1306 | ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION); | ||
| 1307 | ghcb_set_sw_exit_info_1(ghcb, | ||
| 1308 | ((u64)apic_id << 32) | | ||
| 1309 | ((u64)snp_vmpl << 16) | | ||
| 1310 | SVM_VMGEXIT_AP_CREATE); | ||
| 1311 | ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa)); | ||
| 1312 | |||
| 1313 | sev_es_wr_ghcb_msr(__pa(ghcb)); | ||
| 1314 | VMGEXIT(); | ||
| 1315 | |||
| 1316 | if (!ghcb_sw_exit_info_1_is_valid(ghcb) || | ||
| 1317 | lower_32_bits(ghcb->save.sw_exit_info_1)) { | ||
| 1318 | pr_err("SNP AP Creation error\n"); | ||
| 1319 | ret = -EINVAL; | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | __sev_put_ghcb(&state); | ||
| 1323 | |||
| 1324 | local_irq_restore(flags); | ||
| 1325 | |||
| 1326 | /* Perform cleanup if there was an error */ | ||
| 1327 | if (ret) { | 1402 | if (ret) { |
| 1328 | snp_cleanup_vmsa(vmsa, apic_id); | 1403 | snp_cleanup_vmsa(vmsa, apic_id); |
| 1329 | vmsa = NULL; | 1404 | vmsa = NULL; |
| @@ -17,19 +17,20 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | .pushsection .noinstr.text, "ax" | 18 | .pushsection .noinstr.text, "ax" |
| 19 | 19 | ||
| 20 | SYM_FUNC_START(entry_ibpb) | 20 | /* Clobbers AX, CX, DX */ |
| 21 | SYM_FUNC_START(write_ibpb) | ||
| 21 | ANNOTATE_NOENDBR | 22 | ANNOTATE_NOENDBR |
| 22 | movl $MSR_IA32_PRED_CMD, %ecx | 23 | movl $MSR_IA32_PRED_CMD, %ecx |
| 23 | movl $PRED_CMD_IBPB, %eax | 24 | movl _ASM_RIP(x86_pred_cmd), %eax |
| 24 | xorl %edx, %edx | 25 | xorl %edx, %edx |
| 25 | wrmsr | 26 | wrmsr |
| 26 | 27 | ||
| 27 | /* Make sure IBPB clears return stack preductions too. */ | 28 | /* Make sure IBPB clears return stack preductions too. */ |
| 28 | FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET | 29 | FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET |
| 29 | RET | 30 | RET |
| 30 | SYM_FUNC_END(entry_ibpb) | 31 | SYM_FUNC_END(write_ibpb) |
| 31 | /* For KVM */ | 32 | /* For KVM */ |
| 32 | EXPORT_SYMBOL_GPL(entry_ibpb); | 33 | EXPORT_SYMBOL_GPL(write_ibpb); |
| 33 | 34 | ||
| 34 | .popsection | 35 | .popsection |
| 35 | 36 | ||
| @@ -1525,7 +1525,9 @@ SYM_CODE_END(rewind_stack_and_make_dead) · 1524 unmodified lines | |||
| 1525 | * ORC to unwind properly. | 1525 | * ORC to unwind properly. |
| 1526 | * | 1526 | * |
| 1527 | * The alignment is for performance and not for safety, and may be safely | 1527 | * The alignment is for performance and not for safety, and may be safely |
| 1528 | * refactored in the future if needed. | 1528 | * refactored in the future if needed. The .skips are for safety, to ensure |
| 1529 | * that all RETs are in the second half of a cacheline to mitigate Indirect | ||
| 1530 | * Target Selection, rather than taking the slowpath via its_return_thunk. | ||
| 1529 | */ | 1531 | */ |
| 1530 | SYM_FUNC_START(clear_bhb_loop) | 1532 | SYM_FUNC_START(clear_bhb_loop) |
| 1531 | ANNOTATE_NOENDBR | 1533 | ANNOTATE_NOENDBR |
| @@ -1536,10 +1538,22 @@ SYM_FUNC_START(clear_bhb_loop) · 4 unmodified lines | |||
| 1536 | call 1f | 1538 | call 1f |
| 1537 | jmp 5f | 1539 | jmp 5f |
| 1538 | .align 64, 0xcc | 1540 | .align 64, 0xcc |
| 1541 | /* | ||
| 1542 | * Shift instructions so that the RET is in the upper half of the | ||
| 1543 | * cacheline and don't take the slowpath to its_return_thunk. | ||
| 1544 | */ | ||
| 1545 | .skip 32 - (.Lret1 - 1f), 0xcc | ||
| 1539 | ANNOTATE_INTRA_FUNCTION_CALL | 1546 | ANNOTATE_INTRA_FUNCTION_CALL |
| 1540 | 1: call 2f | 1547 | 1: call 2f |
| 1541 | RET | 1548 | .Lret1: RET |
| 1542 | .align 64, 0xcc | 1549 | .align 64, 0xcc |
| 1550 | /* | ||
| 1551 | * As above shift instructions for RET at .Lret2 as well. | ||
| 1552 | * | ||
| 1553 | * This should be ideally be: .skip 32 - (.Lret2 - 2f), 0xcc | ||
| 1554 | * but some Clang versions (e.g. 18) don't like this. | ||
| 1555 | */ | ||
| 1556 | .skip 32 - 18, 0xcc | ||
| 1543 | 2: movl $5, %eax | 1557 | 2: movl $5, %eax |
| 1544 | 3: jmp 4f | 1558 | 3: jmp 4f |
| 1545 | nop | 1559 | nop |
| @@ -1547,7 +1561,7 @@ SYM_FUNC_START(clear_bhb_loop) · 1 unmodified line | |||
| 1547 | jnz 3b | 1561 | jnz 3b |
| 1548 | sub $1, %ecx | 1562 | sub $1, %ecx |
| 1549 | jnz 1b | 1563 | jnz 1b |
| 1550 | RET | 1564 | .Lret2: RET |
| 1551 | 5: lfence | 1565 | 5: lfence |
| 1552 | pop %rbp | 1566 | pop %rbp |
| 1553 | RET | 1567 | RET |
| @@ -629,7 +629,7 @@ int x86_pmu_hw_config(struct perf_event *event) · 628 unmodified lines | |||
| 629 | if (event->attr.type == event->pmu->type) | 629 | if (event->attr.type == event->pmu->type) |
| 630 | event->hw.config |= x86_pmu_get_event_config(event); | 630 | event->hw.config |= x86_pmu_get_event_config(event); |
| 631 | 631 | ||
| 632 | if (!event->attr.freq && x86_pmu.limit_period) { | 632 | if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) { |
| 633 | s64 left = event->attr.sample_period; | 633 | s64 left = event->attr.sample_period; |
| 634 | x86_pmu.limit_period(event, &left); | 634 | x86_pmu.limit_period(event, &left); |
| 635 | if (left > event->attr.sample_period) | 635 | if (left > event->attr.sample_period) |
| @@ -754,7 +754,7 @@ void x86_pmu_enable_all(int added) · 118 unmodified lines | |||
| 754 | } | 754 | } |
| 755 | } | 755 | } |
| 756 | 756 | ||
| 757 | static inline int is_x86_event(struct perf_event *event) | 757 | int is_x86_event(struct perf_event *event) |
| 758 | { | 758 | { |
| 759 | int i; | 759 | int i; |
| 760 | 760 | ||
| @@ -3049,7 +3049,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) · 3048 unmodified lines | |||
| 3049 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 3049 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 3050 | int bit; | 3050 | int bit; |
| 3051 | int handled = 0; | 3051 | int handled = 0; |
| 3052 | u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl); | ||
| 3053 | 3052 | ||
| 3054 | inc_irq_stat(apic_perf_irqs); | 3053 | inc_irq_stat(apic_perf_irqs); |
| 3055 | 3054 | ||
| @@ -3093,7 +3092,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) · 37 unmodified lines | |||
| 3093 | handled++; | 3092 | handled++; |
| 3094 | x86_pmu_handle_guest_pebs(regs, &data); | 3093 | x86_pmu_handle_guest_pebs(regs, &data); |
| 3095 | static_call(x86_pmu_drain_pebs)(regs, &data); | 3094 | static_call(x86_pmu_drain_pebs)(regs, &data); |
| 3096 | status &= intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI; | ||
| 3097 | 3095 | ||
| 3098 | /* | 3096 | /* |
| 3099 | * PMI throttle may be triggered, which stops the PEBS event. | 3097 | * PMI throttle may be triggered, which stops the PEBS event. |
| @@ -3104,6 +3102,15 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) · 4 unmodified lines | |||
| 3104 | */ | 3102 | */ |
| 3105 | if (pebs_enabled != cpuc->pebs_enabled) | 3103 | if (pebs_enabled != cpuc->pebs_enabled) |
| 3106 | wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); | 3104 | wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); |
| 3105 | |||
| 3106 | /* | ||
| 3107 | * Above PEBS handler (PEBS counters snapshotting) has updated fixed | ||
| 3108 | * counter 3 and perf metrics counts if they are in counter group, | ||
| 3109 | * unnecessary to update again. | ||
| 3110 | */ | ||
| 3111 | if (cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS] && | ||
| 3112 | is_pebs_counter_event_group(cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS])) | ||
| 3113 | status &= ~GLOBAL_STATUS_PERF_METRICS_OVF_BIT; | ||
| 3107 | } | 3114 | } |
| 3108 | 3115 | ||
| 3109 | /* | 3116 | /* |
| @@ -3123,6 +3130,8 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) · 13 unmodified lines | |||
| 3123 | static_call(intel_pmu_update_topdown_event)(NULL, NULL); | 3130 | static_call(intel_pmu_update_topdown_event)(NULL, NULL); |
| 3124 | } | 3131 | } |
| 3125 | 3132 | ||
| 3133 | status &= hybrid(cpuc->pmu, intel_ctrl); | ||
| 3134 | |||
| 3126 | /* | 3135 | /* |
| 3127 | * Checkpointed counters can lead to 'spurious' PMIs because the | 3136 | * Checkpointed counters can lead to 'spurious' PMIs because the |
| 3128 | * rollback caused by the PMI will have cleared the overflow status | 3137 | * rollback caused by the PMI will have cleared the overflow status |
| @@ -4386,7 +4395,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data) · 1257 unmodified lines | |||
| 4386 | arr[pebs_enable] = (struct perf_guest_switch_msr){ | 4395 | arr[pebs_enable] = (struct perf_guest_switch_msr){ |
| 4387 | .msr = MSR_IA32_PEBS_ENABLE, | 4396 | .msr = MSR_IA32_PEBS_ENABLE, |
| 4388 | .host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask, | 4397 | .host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask, |
| 4389 | .guest = pebs_mask & ~cpuc->intel_ctrl_host_mask, | 4398 | .guest = pebs_mask & ~cpuc->intel_ctrl_host_mask & kvm_pmu->pebs_enable, |
| 4390 | }; | 4399 | }; |
| 4391 | 4400 | ||
| 4392 | if (arr[pebs_enable].host) { | 4401 | if (arr[pebs_enable].host) { |
| @@ -7305,8 +7314,17 @@ __init int intel_pmu_init(void) · 2912 unmodified lines | |||
| 7305 | name = "meteorlake_hybrid"; | 7314 | name = "meteorlake_hybrid"; |
| 7306 | break; | 7315 | break; |
| 7307 | 7316 | ||
| 7317 | case INTEL_PANTHERLAKE_L: | ||
| 7318 | pr_cont("Pantherlake Hybrid events, "); | ||
| 7319 | name = "pantherlake_hybrid"; | ||
| 7320 | goto lnl_common; | ||
| 7321 | |||
| 7308 | case INTEL_LUNARLAKE_M: | 7322 | case INTEL_LUNARLAKE_M: |
| 7309 | case INTEL_ARROWLAKE: | 7323 | case INTEL_ARROWLAKE: |
| 7324 | pr_cont("Lunarlake Hybrid events, "); | ||
| 7325 | name = "lunarlake_hybrid"; | ||
| 7326 | |||
| 7327 | lnl_common: | ||
| 7310 | intel_pmu_init_hybrid(hybrid_big_small); | 7328 | intel_pmu_init_hybrid(hybrid_big_small); |
| 7311 | 7329 | ||
| 7312 | x86_pmu.pebs_latency_data = lnl_latency_data; | 7330 | x86_pmu.pebs_latency_data = lnl_latency_data; |
| @@ -7328,8 +7346,6 @@ __init int intel_pmu_init(void) · 15 unmodified lines | |||
| 7328 | intel_pmu_init_skt(&pmu->pmu); | 7346 | intel_pmu_init_skt(&pmu->pmu); |
| 7329 | 7347 | ||
| 7330 | intel_pmu_pebs_data_source_lnl(); | 7348 | intel_pmu_pebs_data_source_lnl(); |
| 7331 | pr_cont("Lunarlake Hybrid events, "); | ||
| 7332 | name = "lunarlake_hybrid"; | ||
| 7333 | break; | 7349 | break; |
| 7334 | 7350 | ||
| 7335 | case INTEL_ARROWLAKE_H: | 7351 | case INTEL_ARROWLAKE_H: |
| @@ -1399,8 +1399,10 @@ static u64 pebs_update_adaptive_cfg(struct perf_event *event) · 1398 unmodified lines | |||
| 1399 | * + precise_ip < 2 for the non event IP | 1399 | * + precise_ip < 2 for the non event IP |
| 1400 | * + For RTM TSX weight we need GPRs for the abort code. | 1400 | * + For RTM TSX weight we need GPRs for the abort code. |
| 1401 | */ | 1401 | */ |
| 1402 | gprs = (sample_type & PERF_SAMPLE_REGS_INTR) && | 1402 | gprs = ((sample_type & PERF_SAMPLE_REGS_INTR) && |
| 1403 | (attr->sample_regs_intr & PEBS_GP_REGS); | 1403 | (attr->sample_regs_intr & PEBS_GP_REGS)) || |
| 1404 | ((sample_type & PERF_SAMPLE_REGS_USER) && | ||
| 1405 | (attr->sample_regs_user & PEBS_GP_REGS)); | ||
| 1404 | 1406 | ||
| 1405 | tsx_weight = (sample_type & PERF_SAMPLE_WEIGHT_TYPE) && | 1407 | tsx_weight = (sample_type & PERF_SAMPLE_WEIGHT_TYPE) && |
| 1406 | ((attr->config & INTEL_ARCH_EVENT_MASK) == | 1408 | ((attr->config & INTEL_ARCH_EVENT_MASK) == |
| @@ -2123,7 +2125,7 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event, · 716 unmodified lines | |||
| 2123 | regs->flags &= ~PERF_EFLAGS_EXACT; | 2125 | regs->flags &= ~PERF_EFLAGS_EXACT; |
| 2124 | } | 2126 | } |
| 2125 | 2127 | ||
| 2126 | if (sample_type & PERF_SAMPLE_REGS_INTR) | 2128 | if (sample_type & (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)) |
| 2127 | adaptive_pebs_save_regs(regs, gprs); | 2129 | adaptive_pebs_save_regs(regs, gprs); |
| 2128 | } | 2130 | } |
| 2129 | 2131 | ||
| @@ -2377,8 +2379,25 @@ __intel_pmu_pebs_last_event(struct perf_event *event, · 247 unmodified lines | |||
| 2377 | */ | 2379 | */ |
| 2378 | intel_pmu_save_and_restart_reload(event, count); | 2380 | intel_pmu_save_and_restart_reload(event, count); |
| 2379 | } | 2381 | } |
| 2380 | } else | 2382 | } else { |
| 2381 | intel_pmu_save_and_restart(event); | 2383 | /* |
| 2384 | * For a non-precise event, it's possible the | ||
| 2385 | * counters-snapshotting records a positive value for the | ||
| 2386 | * overflowed event. Then the HW auto-reload mechanism | ||
| 2387 | * reset the counter to 0 immediately, because the | ||
| 2388 | * pebs_event_reset is cleared if the PERF_X86_EVENT_AUTO_RELOAD | ||
| 2389 | * is not set. The counter backwards may be observed in a | ||
| 2390 | * PMI handler. | ||
| 2391 | * | ||
| 2392 | * Since the event value has been updated when processing the | ||
| 2393 | * counters-snapshotting record, only needs to set the new | ||
| 2394 | * period for the counter. | ||
| 2395 | */ | ||
| 2396 | if (is_pebs_counter_event_group(event)) | ||
| 2397 | static_call(x86_pmu_set_period)(event); | ||
| 2398 | else | ||
| 2399 | intel_pmu_save_and_restart(event); | ||
| 2400 | } | ||
| 2382 | } | 2401 | } |
| 2383 | 2402 | ||
| 2384 | static __always_inline void | 2403 | static __always_inline void |
| @@ -2446,8 +2465,9 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs, struct perf_sample_ · 61 unmodified lines | |||
| 2446 | setup_pebs_fixed_sample_data); | 2465 | setup_pebs_fixed_sample_data); |
| 2447 | } | 2466 | } |
| 2448 | 2467 | ||
| 2449 | static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int size) | 2468 | static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, u64 mask) |
| 2450 | { | 2469 | { |
| 2470 | u64 pebs_enabled = cpuc->pebs_enabled & mask; | ||
| 2451 | struct perf_event *event; | 2471 | struct perf_event *event; |
| 2452 | int bit; | 2472 | int bit; |
| 2453 | 2473 | ||
| @@ -2458,7 +2478,7 @@ static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int · 4 unmodified lines | |||
| 2458 | * It needs to call intel_pmu_save_and_restart_reload() to | 2478 | * It needs to call intel_pmu_save_and_restart_reload() to |
| 2459 | * update the event->count for this case. | 2479 | * update the event->count for this case. |
| 2460 | */ | 2480 | */ |
| 2461 | for_each_set_bit(bit, (unsigned long *)&cpuc->pebs_enabled, size) { | 2481 | for_each_set_bit(bit, (unsigned long *)&pebs_enabled, X86_PMC_IDX_MAX) { |
| 2462 | event = cpuc->events[bit]; | 2482 | event = cpuc->events[bit]; |
| 2463 | if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD) | 2483 | if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD) |
| 2464 | intel_pmu_save_and_restart_reload(event, 0); | 2484 | intel_pmu_save_and_restart_reload(event, 0); |
| @@ -2493,7 +2513,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d · 28 unmodified lines | |||
| 2493 | } | 2513 | } |
| 2494 | 2514 | ||
| 2495 | if (unlikely(base >= top)) { | 2515 | if (unlikely(base >= top)) { |
| 2496 | intel_pmu_pebs_event_update_no_drain(cpuc, size); | 2516 | intel_pmu_pebs_event_update_no_drain(cpuc, mask); |
| 2497 | return; | 2517 | return; |
| 2498 | } | 2518 | } |
| 2499 | 2519 | ||
| @@ -2607,7 +2627,7 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d · 107 unmodified lines | |||
| 2607 | (hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED); | 2627 | (hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED); |
| 2608 | 2628 | ||
| 2609 | if (unlikely(base >= top)) { | 2629 | if (unlikely(base >= top)) { |
| 2610 | intel_pmu_pebs_event_update_no_drain(cpuc, X86_PMC_IDX_MAX); | 2630 | intel_pmu_pebs_event_update_no_drain(cpuc, mask); |
| 2611 | return; | 2631 | return; |
| 2612 | } | 2632 | } |
| 2613 | 2633 | ||
| @@ -4891,28 +4891,28 @@ static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = { · 4890 unmodified lines | |||
| 4891 | INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), | 4891 | INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), |
| 4892 | /* Free-Running IIO BANDWIDTH IN Counters */ | 4892 | /* Free-Running IIO BANDWIDTH IN Counters */ |
| 4893 | INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), | 4893 | INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), |
| 4894 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"), | 4894 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.0517578125e-5"), |
| 4895 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), | 4895 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), |
| 4896 | INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), | 4896 | INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), |
| 4897 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"), | 4897 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.0517578125e-5"), |
| 4898 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), | 4898 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), |
| 4899 | INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), | 4899 | INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), |
| 4900 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"), | 4900 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.0517578125e-5"), |
| 4901 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), | 4901 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), |
| 4902 | INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), | 4902 | INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), |
| 4903 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"), | 4903 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.0517578125e-5"), |
| 4904 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), | 4904 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), |
| 4905 | INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"), | 4905 | INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"), |
| 4906 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.814697266e-6"), | 4906 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.0517578125e-5"), |
| 4907 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), | 4907 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), |
| 4908 | INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"), | 4908 | INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"), |
| 4909 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.814697266e-6"), | 4909 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.0517578125e-5"), |
| 4910 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), | 4910 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), |
| 4911 | INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"), | 4911 | INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"), |
| 4912 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.814697266e-6"), | 4912 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.0517578125e-5"), |
| 4913 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), | 4913 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), |
| 4914 | INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"), | 4914 | INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"), |
| 4915 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.814697266e-6"), | 4915 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.0517578125e-5"), |
| 4916 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), | 4916 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), |
| 4917 | { /* end: all zeroes */ }, | 4917 | { /* end: all zeroes */ }, |
| 4918 | }; | 4918 | }; |
| @@ -5485,37 +5485,6 @@ static struct freerunning_counters icx_iio_freerunning[] = { · 566 unmodified lines | |||
| 5485 | [ICX_IIO_MSR_BW_IN] = { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets }, | 5485 | [ICX_IIO_MSR_BW_IN] = { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets }, |
| 5486 | }; | 5486 | }; |
| 5487 | 5487 | ||
| 5488 | static struct uncore_event_desc icx_uncore_iio_freerunning_events[] = { | ||
| 5489 | /* Free-Running IIO CLOCKS Counter */ | ||
| 5490 | INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), | ||
| 5491 | /* Free-Running IIO BANDWIDTH IN Counters */ | ||
| 5492 | INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), | ||
| 5493 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"), | ||
| 5494 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), | ||
| 5495 | INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), | ||
| 5496 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"), | ||
| 5497 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), | ||
| 5498 | INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), | ||
| 5499 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"), | ||
| 5500 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), | ||
| 5501 | INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), | ||
| 5502 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"), | ||
| 5503 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), | ||
| 5504 | INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"), | ||
| 5505 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.814697266e-6"), | ||
| 5506 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), | ||
| 5507 | INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"), | ||
| 5508 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.814697266e-6"), | ||
| 5509 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), | ||
| 5510 | INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"), | ||
| 5511 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.814697266e-6"), | ||
| 5512 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), | ||
| 5513 | INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"), | ||
| 5514 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.814697266e-6"), | ||
| 5515 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), | ||
| 5516 | { /* end: all zeroes */ }, | ||
| 5517 | }; | ||
| 5518 | |||
| 5519 | static struct intel_uncore_type icx_uncore_iio_free_running = { | 5488 | static struct intel_uncore_type icx_uncore_iio_free_running = { |
| 5520 | .name = "iio_free_running", | 5489 | .name = "iio_free_running", |
| 5521 | .num_counters = 9, | 5490 | .num_counters = 9, |
| @@ -5523,7 +5492,7 @@ static struct intel_uncore_type icx_uncore_iio_free_running = { · 1 unmodified line | |||
| 5523 | .num_freerunning_types = ICX_IIO_FREERUNNING_TYPE_MAX, | 5492 | .num_freerunning_types = ICX_IIO_FREERUNNING_TYPE_MAX, |
| 5524 | .freerunning = icx_iio_freerunning, | 5493 | .freerunning = icx_iio_freerunning, |
| 5525 | .ops = &skx_uncore_iio_freerunning_ops, | 5494 | .ops = &skx_uncore_iio_freerunning_ops, |
| 5526 | .event_descs = icx_uncore_iio_freerunning_events, | 5495 | .event_descs = snr_uncore_iio_freerunning_events, |
| 5527 | .format_group = &skx_uncore_iio_freerunning_format_group, | 5496 | .format_group = &skx_uncore_iio_freerunning_format_group, |
| 5528 | }; | 5497 | }; |
| 5529 | 5498 | ||
| @@ -6320,69 +6289,13 @@ static struct freerunning_counters spr_iio_freerunning[] = { · 790 unmodified lines | |||
| 6320 | [SPR_IIO_MSR_BW_OUT] = { 0x3808, 0x1, 0x10, 8, 48 }, | 6289 | [SPR_IIO_MSR_BW_OUT] = { 0x3808, 0x1, 0x10, 8, 48 }, |
| 6321 | }; | 6290 | }; |
| 6322 | 6291 | ||
| 6323 | static struct uncore_event_desc spr_uncore_iio_freerunning_events[] = { | ||
| 6324 | /* Free-Running IIO CLOCKS Counter */ | ||
| 6325 | INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), | ||
| 6326 | /* Free-Running IIO BANDWIDTH IN Counters */ | ||
| 6327 | INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), | ||
| 6328 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"), | ||
| 6329 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), | ||
| 6330 | INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), | ||
| 6331 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"), | ||
| 6332 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), | ||
| 6333 | INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), | ||
| 6334 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"), | ||
| 6335 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), | ||
| 6336 | INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), | ||
| 6337 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"), | ||
| 6338 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), | ||
| 6339 | INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"), | ||
| 6340 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.814697266e-6"), | ||
| 6341 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), | ||
| 6342 | INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"), | ||
| 6343 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.814697266e-6"), | ||
| 6344 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), | ||
| 6345 | INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"), | ||
| 6346 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.814697266e-6"), | ||
| 6347 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), | ||
| 6348 | INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"), | ||
| 6349 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.814697266e-6"), | ||
| 6350 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), | ||
| 6351 | /* Free-Running IIO BANDWIDTH OUT Counters */ | ||
| 6352 | INTEL_UNCORE_EVENT_DESC(bw_out_port0, "event=0xff,umask=0x30"), | ||
| 6353 | INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale, "3.814697266e-6"), | ||
| 6354 | INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit, "MiB"), | ||
| 6355 | INTEL_UNCORE_EVENT_DESC(bw_out_port1, "event=0xff,umask=0x31"), | ||
| 6356 | INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale, "3.814697266e-6"), | ||
| 6357 | INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit, "MiB"), | ||
| 6358 | INTEL_UNCORE_EVENT_DESC(bw_out_port2, "event=0xff,umask=0x32"), | ||
| 6359 | INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale, "3.814697266e-6"), | ||
| 6360 | INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit, "MiB"), | ||
| 6361 | INTEL_UNCORE_EVENT_DESC(bw_out_port3, "event=0xff,umask=0x33"), | ||
| 6362 | INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale, "3.814697266e-6"), | ||
| 6363 | INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit, "MiB"), | ||
| 6364 | INTEL_UNCORE_EVENT_DESC(bw_out_port4, "event=0xff,umask=0x34"), | ||
| 6365 | INTEL_UNCORE_EVENT_DESC(bw_out_port4.scale, "3.814697266e-6"), | ||
| 6366 | INTEL_UNCORE_EVENT_DESC(bw_out_port4.unit, "MiB"), | ||
| 6367 | INTEL_UNCORE_EVENT_DESC(bw_out_port5, "event=0xff,umask=0x35"), | ||
| 6368 | INTEL_UNCORE_EVENT_DESC(bw_out_port5.scale, "3.814697266e-6"), | ||
| 6369 | INTEL_UNCORE_EVENT_DESC(bw_out_port5.unit, "MiB"), | ||
| 6370 | INTEL_UNCORE_EVENT_DESC(bw_out_port6, "event=0xff,umask=0x36"), | ||
| 6371 | INTEL_UNCORE_EVENT_DESC(bw_out_port6.scale, "3.814697266e-6"), | ||
| 6372 | INTEL_UNCORE_EVENT_DESC(bw_out_port6.unit, "MiB"), | ||
| 6373 | INTEL_UNCORE_EVENT_DESC(bw_out_port7, "event=0xff,umask=0x37"), | ||
| 6374 | INTEL_UNCORE_EVENT_DESC(bw_out_port7.scale, "3.814697266e-6"), | ||
| 6375 | INTEL_UNCORE_EVENT_DESC(bw_out_port7.unit, "MiB"), | ||
| 6376 | { /* end: all zeroes */ }, | ||
| 6377 | }; | ||
| 6378 | |||
| 6379 | static struct intel_uncore_type spr_uncore_iio_free_running = { | 6292 | static struct intel_uncore_type spr_uncore_iio_free_running = { |
| 6380 | .name = "iio_free_running", | 6293 | .name = "iio_free_running", |
| 6381 | .num_counters = 17, | 6294 | .num_counters = 17, |
| 6382 | .num_freerunning_types = SPR_IIO_FREERUNNING_TYPE_MAX, | 6295 | .num_freerunning_types = SPR_IIO_FREERUNNING_TYPE_MAX, |
| 6383 | .freerunning = spr_iio_freerunning, | 6296 | .freerunning = spr_iio_freerunning, |
| 6384 | .ops = &skx_uncore_iio_freerunning_ops, | 6297 | .ops = &skx_uncore_iio_freerunning_ops, |
| 6385 | .event_descs = spr_uncore_iio_freerunning_events, | 6298 | .event_descs = snr_uncore_iio_freerunning_events, |
| 6386 | .format_group = &skx_uncore_iio_freerunning_format_group, | 6299 | .format_group = &skx_uncore_iio_freerunning_format_group, |
| 6387 | }; | 6300 | }; |
| 6388 | 6301 | ||
| @@ -110,14 +110,21 @@ static inline bool is_topdown_event(struct perf_event *event) · 109 unmodified lines | |||
| 110 | return is_metric_event(event) || is_slots_event(event); | 110 | return is_metric_event(event) || is_slots_event(event); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | int is_x86_event(struct perf_event *event); | ||
| 114 | |||
| 115 | static inline bool check_leader_group(struct perf_event *leader, int flags) | ||
| 116 | { | ||
| 117 | return is_x86_event(leader) ? !!(leader->hw.flags & flags) : false; | ||
| 118 | } | ||
| 119 | |||
| 113 | static inline bool is_branch_counters_group(struct perf_event *event) | 120 | static inline bool is_branch_counters_group(struct perf_event *event) |
| 114 | { | 121 | { |
| 115 | return event->group_leader->hw.flags & PERF_X86_EVENT_BRANCH_COUNTERS; | 122 | return check_leader_group(event->group_leader, PERF_X86_EVENT_BRANCH_COUNTERS); |
| 116 | } | 123 | } |
| 117 | 124 | ||
| 118 | static inline bool is_pebs_counter_event_group(struct perf_event *event) | 125 | static inline bool is_pebs_counter_event_group(struct perf_event *event) |
| 119 | { | 126 | { |
| 120 | return event->group_leader->hw.flags & PERF_X86_EVENT_PEBS_CNTR; | 127 | return check_leader_group(event->group_leader, PERF_X86_EVENT_PEBS_CNTR); |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 123 | struct amd_nb { | 130 | struct amd_nb { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/stringify.h> | 6 | #include <linux/stringify.h> |
| 7 | #include <linux/objtool.h> | 7 | #include <linux/objtool.h> |
| 8 | #include <asm/asm.h> | 8 | #include <asm/asm.h> |
| 9 | #include <asm/bug.h> | ||
| 9 | 10 | ||
| 10 | #define ALT_FLAGS_SHIFT 16 | 11 | #define ALT_FLAGS_SHIFT 16 |
| 11 | 12 | ||
| @@ -124,6 +125,37 @@ static __always_inline int x86_call_depth_emit_accounting(u8 **pprog, · 112 unmodified lines | |||
| 124 | } | 125 | } |
| 125 | #endif | 126 | #endif |
| 126 | 127 | ||
| 128 | #ifdef CONFIG_MITIGATION_ITS | ||
| 129 | extern void its_init_mod(struct module *mod); | ||
| 130 | extern void its_fini_mod(struct module *mod); | ||
| 131 | extern void its_free_mod(struct module *mod); | ||
| 132 | extern u8 *its_static_thunk(int reg); | ||
| 133 | #else /* CONFIG_MITIGATION_ITS */ | ||
| 134 | static inline void its_init_mod(struct module *mod) { } | ||
| 135 | static inline void its_fini_mod(struct module *mod) { } | ||
| 136 | static inline void its_free_mod(struct module *mod) { } | ||
| 137 | static inline u8 *its_static_thunk(int reg) | ||
| 138 | { | ||
| 139 | WARN_ONCE(1, "ITS not compiled in"); | ||
| 140 | |||
| 141 | return NULL; | ||
| 142 | } | ||
| 143 | #endif | ||
| 144 | |||
| 145 | #if defined(CONFIG_MITIGATION_RETHUNK) && defined(CONFIG_OBJTOOL) | ||
| 146 | extern bool cpu_wants_rethunk(void); | ||
| 147 | extern bool cpu_wants_rethunk_at(void *addr); | ||
| 148 | #else | ||
| 149 | static __always_inline bool cpu_wants_rethunk(void) | ||
| 150 | { | ||
| 151 | return false; | ||
| 152 | } | ||
| 153 | static __always_inline bool cpu_wants_rethunk_at(void *addr) | ||
| 154 | { | ||
| 155 | return false; | ||
| 156 | } | ||
| 157 | #endif | ||
| 158 | |||
| 127 | #ifdef CONFIG_SMP | 159 | #ifdef CONFIG_SMP |
| 128 | extern void alternatives_smp_module_add(struct module *mod, char *name, | 160 | extern void alternatives_smp_module_add(struct module *mod, char *name, |
| 129 | void *locks, void *locks_end, | 161 | void *locks, void *locks_end, |
| @@ -75,7 +75,7 @@ · 74 unmodified lines | |||
| 75 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */ | 75 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */ |
| 76 | #define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */ | 76 | #define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */ |
| 77 | #define X86_FEATURE_ZEN5 ( 3*32+ 5) /* CPU based on Zen5 microarchitecture */ | 77 | #define X86_FEATURE_ZEN5 ( 3*32+ 5) /* CPU based on Zen5 microarchitecture */ |
| 78 | /* Free ( 3*32+ 6) */ | 78 | #define X86_FEATURE_ZEN6 ( 3*32+ 6) /* CPU based on Zen6 microarchitecture */ |
| 79 | /* Free ( 3*32+ 7) */ | 79 | /* Free ( 3*32+ 7) */ |
| 80 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */ | 80 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */ |
| 81 | #define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */ | 81 | #define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */ |
| @@ -481,6 +481,7 @@ · 399 unmodified lines | |||
| 481 | #define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */ | 481 | #define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */ |
| 482 | #define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */ | 482 | #define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */ |
| 483 | #define X86_FEATURE_PREFER_YMM (21*32 + 8) /* Avoid ZMM registers due to downclocking */ | 483 | #define X86_FEATURE_PREFER_YMM (21*32 + 8) /* Avoid ZMM registers due to downclocking */ |
| 484 | #define X86_FEATURE_INDIRECT_THUNK_ITS (21*32 + 9) /* Use thunk for indirect branches in lower half of cacheline */ | ||
| 484 | 485 | ||
| 485 | /* | 486 | /* |
| 486 | * BUG word(s) | 487 | * BUG word(s) |
| @@ -533,4 +534,6 @@ · 46 unmodified lines | |||
| 533 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ | 534 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ |
| 534 | #define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ | 535 | #define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ |
| 535 | #define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */ | 536 | #define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */ |
| 537 | #define X86_BUG_ITS X86_BUG(1*32 + 6) /* "its" CPU is affected by Indirect Target Selection */ | ||
| 538 | #define X86_BUG_ITS_NATIVE_ONLY X86_BUG(1*32 + 7) /* "its_native_only" CPU is affected by ITS, VMX is not affected */ | ||
| 536 | #endif /* _ASM_X86_CPUFEATURES_H */ | 539 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -126,6 +126,8 @@ · 125 unmodified lines | |||
| 126 | #define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */ | 126 | #define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */ |
| 127 | #define INTEL_GRANITERAPIDS_D IFM(6, 0xAE) | 127 | #define INTEL_GRANITERAPIDS_D IFM(6, 0xAE) |
| 128 | 128 | ||
| 129 | #define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */ | ||
| 130 | |||
| 129 | /* "Hybrid" Processors (P-Core/E-Core) */ | 131 | /* "Hybrid" Processors (P-Core/E-Core) */ |
| 130 | 132 | ||
| 131 | #define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */ | 133 | #define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */ |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <asm/mtrr.h> | 35 | #include <asm/mtrr.h> |
| 36 | #include <asm/msr-index.h> | 36 | #include <asm/msr-index.h> |
| 37 | #include <asm/asm.h> | 37 | #include <asm/asm.h> |
| 38 | #include <asm/irq_remapping.h> | ||
| 38 | #include <asm/kvm_page_track.h> | 39 | #include <asm/kvm_page_track.h> |
| 39 | #include <asm/kvm_vcpu_regs.h> | 40 | #include <asm/kvm_vcpu_regs.h> |
| 40 | #include <asm/reboot.h> | 41 | #include <asm/reboot.h> |
| @@ -1472,8 +1473,13 @@ struct kvm_arch { · 1431 unmodified lines | |||
| 1472 | struct once nx_once; | 1473 | struct once nx_once; |
| 1473 | 1474 | ||
| 1474 | #ifdef CONFIG_X86_64 | 1475 | #ifdef CONFIG_X86_64 |
| 1475 | /* The number of TDP MMU pages across all roots. */ | 1476 | #ifdef CONFIG_KVM_PROVE_MMU |
| 1477 | /* | ||
| 1478 | * The number of TDP MMU pages across all roots. Used only to sanity | ||
| 1479 | * check that KVM isn't leaking TDP MMU pages. | ||
| 1480 | */ | ||
| 1476 | atomic64_t tdp_mmu_pages; | 1481 | atomic64_t tdp_mmu_pages; |
| 1482 | #endif | ||
| 1477 | 1483 | ||
| 1478 | /* | 1484 | /* |
| 1479 | * List of struct kvm_mmu_pages being used as roots. | 1485 | * List of struct kvm_mmu_pages being used as roots. |
| @@ -2418,4 +2424,9 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); · 938 unmodified lines | |||
| 2418 | */ | 2424 | */ |
| 2419 | #define KVM_EXIT_HYPERCALL_MBZ GENMASK_ULL(31, 1) | 2425 | #define KVM_EXIT_HYPERCALL_MBZ GENMASK_ULL(31, 1) |
| 2420 | 2426 | ||
| 2427 | static inline bool kvm_arch_has_irq_bypass(void) | ||
| 2428 | { | ||
| 2429 | return enable_apicv && irq_remapping_cap(IRQ_POSTING_CAP); | ||
| 2430 | } | ||
| 2431 | |||
| 2421 | #endif /* _ASM_X86_KVM_HOST_H */ | 2432 | #endif /* _ASM_X86_KVM_HOST_H */ |
| @@ -17,10 +17,12 @@ struct ucode_cpu_info { · 16 unmodified lines | |||
| 17 | void load_ucode_bsp(void); | 17 | void load_ucode_bsp(void); |
| 18 | void load_ucode_ap(void); | 18 | void load_ucode_ap(void); |
| 19 | void microcode_bsp_resume(void); | 19 | void microcode_bsp_resume(void); |
| 20 | bool __init microcode_loader_disabled(void); | ||
| 20 | #else | 21 | #else |
| 21 | static inline void load_ucode_bsp(void) { } | 22 | static inline void load_ucode_bsp(void) { } |
| 22 | static inline void load_ucode_ap(void) { } | 23 | static inline void load_ucode_ap(void) { } |
| 23 | static inline void microcode_bsp_resume(void) { } | 24 | static inline void microcode_bsp_resume(void) { } |
| 25 | static inline bool __init microcode_loader_disabled(void) { return false; } | ||
| 24 | #endif | 26 | #endif |
| 25 | 27 | ||
| 26 | extern unsigned long initrd_start_early; | 28 | extern unsigned long initrd_start_early; |
| @@ -211,6 +211,14 @@ · 210 unmodified lines | |||
| 211 | * VERW clears CPU Register | 211 | * VERW clears CPU Register |
| 212 | * File. | 212 | * File. |
| 213 | */ | 213 | */ |
| 214 | #define ARCH_CAP_ITS_NO BIT_ULL(62) /* | ||
| 215 | * Not susceptible to | ||
| 216 | * Indirect Target Selection. | ||
| 217 | * This bit is not set by | ||
| 218 | * HW, but is synthesized by | ||
| 219 | * VMMs for guests to know | ||
| 220 | * their affected status. | ||
| 221 | */ | ||
| 214 | 222 | ||
| 215 | #define MSR_IA32_FLUSH_CMD 0x0000010b | 223 | #define MSR_IA32_FLUSH_CMD 0x0000010b |
| 216 | #define L1D_FLUSH BIT(0) /* | 224 | #define L1D_FLUSH BIT(0) /* |
| @@ -269,7 +269,7 @@ · 268 unmodified lines | |||
| 269 | * typically has NO_MELTDOWN). | 269 | * typically has NO_MELTDOWN). |
| 270 | * | 270 | * |
| 271 | * While retbleed_untrain_ret() doesn't clobber anything but requires stack, | 271 | * While retbleed_untrain_ret() doesn't clobber anything but requires stack, |
| 272 | * entry_ibpb() will clobber AX, CX, DX. | 272 | * write_ibpb() will clobber AX, CX, DX. |
| 273 | * | 273 | * |
| 274 | * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point | 274 | * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point |
| 275 | * where we have a stack but before any RET instruction. | 275 | * where we have a stack but before any RET instruction. |
| @@ -279,7 +279,7 @@ · 3 unmodified lines | |||
| 279 | VALIDATE_UNRET_END | 279 | VALIDATE_UNRET_END |
| 280 | CALL_UNTRAIN_RET | 280 | CALL_UNTRAIN_RET |
| 281 | ALTERNATIVE_2 "", \ | 281 | ALTERNATIVE_2 "", \ |
| 282 | "call entry_ibpb", \ibpb_feature, \ | 282 | "call write_ibpb", \ibpb_feature, \ |
| 283 | __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH | 283 | __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH |
| 284 | #endif | 284 | #endif |
| 285 | .endm | 285 | .endm |
| @@ -336,10 +336,14 @@ · 50 unmodified lines | |||
| 336 | 336 | ||
| 337 | #else /* __ASSEMBLER__ */ | 337 | #else /* __ASSEMBLER__ */ |
| 338 | 338 | ||
| 339 | #define ITS_THUNK_SIZE 64 | ||
| 340 | |||
| 339 | typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE]; | 341 | typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE]; |
| 342 | typedef u8 its_thunk_t[ITS_THUNK_SIZE]; | ||
| 340 | extern retpoline_thunk_t __x86_indirect_thunk_array[]; | 343 | extern retpoline_thunk_t __x86_indirect_thunk_array[]; |
| 341 | extern retpoline_thunk_t __x86_indirect_call_thunk_array[]; | 344 | extern retpoline_thunk_t __x86_indirect_call_thunk_array[]; |
| 342 | extern retpoline_thunk_t __x86_indirect_jump_thunk_array[]; | 345 | extern retpoline_thunk_t __x86_indirect_jump_thunk_array[]; |
| 346 | extern its_thunk_t __x86_indirect_its_thunk_array[]; | ||
| 343 | 347 | ||
| 344 | #ifdef CONFIG_MITIGATION_RETHUNK | 348 | #ifdef CONFIG_MITIGATION_RETHUNK |
| 345 | extern void __x86_return_thunk(void); | 349 | extern void __x86_return_thunk(void); |
| @@ -363,12 +367,18 @@ static inline void srso_return_thunk(void) {} · 17 unmodified lines | |||
| 363 | static inline void srso_alias_return_thunk(void) {} | 367 | static inline void srso_alias_return_thunk(void) {} |
| 364 | #endif | 368 | #endif |
| 365 | 369 | ||
| 370 | #ifdef CONFIG_MITIGATION_ITS | ||
| 371 | extern void its_return_thunk(void); | ||
| 372 | #else | ||
| 373 | static inline void its_return_thunk(void) {} | ||
| 374 | #endif | ||
| 375 | |||
| 366 | extern void retbleed_return_thunk(void); | 376 | extern void retbleed_return_thunk(void); |
| 367 | extern void srso_return_thunk(void); | 377 | extern void srso_return_thunk(void); |
| 368 | extern void srso_alias_return_thunk(void); | 378 | extern void srso_alias_return_thunk(void); |
| 369 | 379 | ||
| 370 | extern void entry_untrain_ret(void); | 380 | extern void entry_untrain_ret(void); |
| 371 | extern void entry_ibpb(void); | 381 | extern void write_ibpb(void); |
| 372 | 382 | ||
| 373 | #ifdef CONFIG_X86_64 | 383 | #ifdef CONFIG_X86_64 |
| 374 | extern void clear_bhb_loop(void); | 384 | extern void clear_bhb_loop(void); |
| @@ -514,11 +524,11 @@ void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) · 139 unmodified lines | |||
| 514 | : "memory"); | 524 | : "memory"); |
| 515 | } | 525 | } |
| 516 | 526 | ||
| 517 | extern u64 x86_pred_cmd; | ||
| 518 | |||
| 519 | static inline void indirect_branch_prediction_barrier(void) | 527 | static inline void indirect_branch_prediction_barrier(void) |
| 520 | { | 528 | { |
| 521 | alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_IBPB); | 529 | asm_inline volatile(ALTERNATIVE("", "call write_ibpb", X86_FEATURE_IBPB) |
| 530 | : ASM_CALL_CONSTRAINT | ||
| 531 | :: "rax", "rcx", "rdx", "memory"); | ||
| 522 | } | 532 | } |
| 523 | 533 | ||
| 524 | /* The Intel SPEC CTRL MSR base value cache */ | 534 | /* The Intel SPEC CTRL MSR base value cache */ |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | #include <linux/mm.h> /* for struct page */ | 6 | #include <linux/mm.h> /* for struct page */ |
| 7 | #include <linux/pagemap.h> | 7 | #include <linux/pagemap.h> |
| 8 | 8 | ||
| 9 | #include <asm/cpufeature.h> | ||
| 10 | |||
| 9 | #define __HAVE_ARCH_PTE_ALLOC_ONE | 11 | #define __HAVE_ARCH_PTE_ALLOC_ONE |
| 10 | #define __HAVE_ARCH_PGD_FREE | 12 | #define __HAVE_ARCH_PGD_FREE |
| 11 | #include <asm-generic/pgalloc.h> | 13 | #include <asm-generic/pgalloc.h> |
| @@ -29,16 +31,17 @@ static inline void paravirt_release_pud(unsigned long pfn) {} · 17 unmodified lines | |||
| 29 | static inline void paravirt_release_p4d(unsigned long pfn) {} | 31 | static inline void paravirt_release_p4d(unsigned long pfn) {} |
| 30 | #endif | 32 | #endif |
| 31 | 33 | ||
| 32 | #ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION | ||
| 33 | /* | 34 | /* |
| 34 | * Instead of one PGD, we acquire two PGDs. Being order-1, it is | 35 | * In case of Page Table Isolation active, we acquire two PGDs instead of one. |
| 35 | * both 8k in size and 8k-aligned. That lets us just flip bit 12 | 36 | * Being order-1, it is both 8k in size and 8k-aligned. That lets us just |
| 36 | * in a pointer to swap between the two 4k halves. | 37 | * flip bit 12 in a pointer to swap between the two 4k halves. |
| 37 | */ | 38 | */ |
| 38 | #define PGD_ALLOCATION_ORDER 1 | 39 | static inline unsigned int pgd_allocation_order(void) |
| 39 | #else | 40 | { |
| 40 | #define PGD_ALLOCATION_ORDER 0 | 41 | if (cpu_feature_enabled(X86_FEATURE_PTI)) |
| 41 | #endif | 42 | return 1; |
| 43 | return 0; | ||
| 44 | } | ||
| 42 | 45 | ||
| 43 | /* | 46 | /* |
| 44 | * Allocate and free page tables. | 47 | * Allocate and free page tables. |
| @@ -116,7 +116,7 @@ enum psc_op { · 115 unmodified lines | |||
| 116 | #define GHCB_MSR_VMPL_REQ 0x016 | 116 | #define GHCB_MSR_VMPL_REQ 0x016 |
| 117 | #define GHCB_MSR_VMPL_REQ_LEVEL(v) \ | 117 | #define GHCB_MSR_VMPL_REQ_LEVEL(v) \ |
| 118 | /* GHCBData[39:32] */ \ | 118 | /* GHCBData[39:32] */ \ |
| 119 | (((u64)(v) & GENMASK_ULL(7, 0) << 32) | \ | 119 | ((((u64)(v) & GENMASK_ULL(7, 0)) << 32) | \ |
| 120 | /* GHCBDdata[11:0] */ \ | 120 | /* GHCBDdata[11:0] */ \ |
| 121 | GHCB_MSR_VMPL_REQ) | 121 | GHCB_MSR_VMPL_REQ) |
| 122 | 122 | ||
| @@ -16,23 +16,23 @@ · 15 unmodified lines | |||
| 16 | #ifdef __ASSEMBLER__ | 16 | #ifdef __ASSEMBLER__ |
| 17 | 17 | ||
| 18 | #define ASM_CLAC \ | 18 | #define ASM_CLAC \ |
| 19 | ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP | 19 | ALTERNATIVE "", "clac", X86_FEATURE_SMAP |
| 20 | 20 | ||
| 21 | #define ASM_STAC \ | 21 | #define ASM_STAC \ |
| 22 | ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP | 22 | ALTERNATIVE "", "stac", X86_FEATURE_SMAP |
| 23 | 23 | ||
| 24 | #else /* __ASSEMBLER__ */ | 24 | #else /* __ASSEMBLER__ */ |
| 25 | 25 | ||
| 26 | static __always_inline void clac(void) | 26 | static __always_inline void clac(void) |
| 27 | { | 27 | { |
| 28 | /* Note: a barrier is implicit in alternative() */ | 28 | /* Note: a barrier is implicit in alternative() */ |
| 29 | alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP); | 29 | alternative("", "clac", X86_FEATURE_SMAP); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static __always_inline void stac(void) | 32 | static __always_inline void stac(void) |
| 33 | { | 33 | { |
| 34 | /* Note: a barrier is implicit in alternative() */ | 34 | /* Note: a barrier is implicit in alternative() */ |
| 35 | alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP); | 35 | alternative("", "stac", X86_FEATURE_SMAP); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | static __always_inline unsigned long smap_save(void) | 38 | static __always_inline unsigned long smap_save(void) |
| @@ -59,9 +59,9 @@ static __always_inline void smap_restore(unsigned long flags) · 20 unmodified lines | |||
| 59 | 59 | ||
| 60 | /* These macros can be used in asm() statements */ | 60 | /* These macros can be used in asm() statements */ |
| 61 | #define ASM_CLAC \ | 61 | #define ASM_CLAC \ |
| 62 | ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP) | 62 | ALTERNATIVE("", "clac", X86_FEATURE_SMAP) |
| 63 | #define ASM_STAC \ | 63 | #define ASM_STAC \ |
| 64 | ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP) | 64 | ALTERNATIVE("", "stac", X86_FEATURE_SMAP) |
| 65 | 65 | ||
| 66 | #define ASM_CLAC_UNSAFE \ | 66 | #define ASM_CLAC_UNSAFE \ |
| 67 | ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP) | 67 | ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP) |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | |||
| 23 | #include <linux/serial_core.h> | 23 | #include <linux/serial_core.h> |
| 24 | #include <linux/pgtable.h> | 24 | #include <linux/pgtable.h> |
| 25 | 25 | ||
| 26 | #include <xen/xen.h> | ||
| 27 | |||
| 26 | #include <asm/e820/api.h> | 28 | #include <asm/e820/api.h> |
| 27 | #include <asm/irqdomain.h> | 29 | #include <asm/irqdomain.h> |
| 28 | #include <asm/pci_x86.h> | 30 | #include <asm/pci_x86.h> |
| @@ -1729,6 +1731,15 @@ int __init acpi_mps_check(void) · 1700 unmodified lines | |||
| 1729 | { | 1731 | { |
| 1730 | #if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE) | 1732 | #if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE) |
| 1731 | /* mptable code is not built-in*/ | 1733 | /* mptable code is not built-in*/ |
| 1734 | |||
| 1735 | /* | ||
| 1736 | * Xen disables ACPI in PV DomU guests but it still emulates APIC and | ||
| 1737 | * supports SMP. Returning early here ensures that APIC is not disabled | ||
| 1738 | * unnecessarily and the guest is not limited to a single vCPU. | ||
| 1739 | */ | ||
| 1740 | if (xen_pv_domain() && !xen_initial_domain()) | ||
| 1741 | return 0; | ||
| 1742 | |||
| 1732 | if (acpi_disabled || acpi_noirq) { | 1743 | if (acpi_disabled || acpi_noirq) { |
| 1733 | pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n"); | 1744 | pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n"); |
| 1734 | return 1; | 1745 | return 1; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/mmu_context.h> | 18 | #include <linux/mmu_context.h> |
| 19 | #include <linux/bsearch.h> | 19 | #include <linux/bsearch.h> |
| 20 | #include <linux/sync_core.h> | 20 | #include <linux/sync_core.h> |
| 21 | #include <linux/execmem.h> | ||
| 21 | #include <asm/text-patching.h> | 22 | #include <asm/text-patching.h> |
| 22 | #include <asm/alternative.h> | 23 | #include <asm/alternative.h> |
| 23 | #include <asm/sections.h> | 24 | #include <asm/sections.h> |
| @@ -31,6 +32,8 @@ · 7 unmodified lines | |||
| 31 | #include <asm/paravirt.h> | 32 | #include <asm/paravirt.h> |
| 32 | #include <asm/asm-prototypes.h> | 33 | #include <asm/asm-prototypes.h> |
| 33 | #include <asm/cfi.h> | 34 | #include <asm/cfi.h> |
| 35 | #include <asm/ibt.h> | ||
| 36 | #include <asm/set_memory.h> | ||
| 34 | 37 | ||
| 35 | int __read_mostly alternatives_patched; | 38 | int __read_mostly alternatives_patched; |
| 36 | 39 | ||
| @@ -124,6 +127,171 @@ const unsigned char * const x86_nops[ASM_NOP_MAX+1] = · 87 unmodified lines | |||
| 124 | #endif | 127 | #endif |
| 125 | }; | 128 | }; |
| 126 | 129 | ||
| 130 | #ifdef CONFIG_FINEIBT | ||
| 131 | static bool cfi_paranoid __ro_after_init; | ||
| 132 | #endif | ||
| 133 | |||
| 134 | #ifdef CONFIG_MITIGATION_ITS | ||
| 135 | |||
| 136 | #ifdef CONFIG_MODULES | ||
| 137 | static struct module *its_mod; | ||
| 138 | #endif | ||
| 139 | static void *its_page; | ||
| 140 | static unsigned int its_offset; | ||
| 141 | |||
| 142 | /* Initialize a thunk with the "jmp *reg; int3" instructions. */ | ||
| 143 | static void *its_init_thunk(void *thunk, int reg) | ||
| 144 | { | ||
| 145 | u8 *bytes = thunk; | ||
| 146 | int offset = 0; | ||
| 147 | int i = 0; | ||
| 148 | |||
| 149 | #ifdef CONFIG_FINEIBT | ||
| 150 | if (cfi_paranoid) { | ||
| 151 | /* | ||
| 152 | * When ITS uses indirect branch thunk the fineibt_paranoid | ||
| 153 | * caller sequence doesn't fit in the caller site. So put the | ||
| 154 | * remaining part of the sequence (<ea> + JNE) into the ITS | ||
| 155 | * thunk. | ||
| 156 | */ | ||
| 157 | bytes[i++] = 0xea; /* invalid instruction */ | ||
| 158 | bytes[i++] = 0x75; /* JNE */ | ||
| 159 | bytes[i++] = 0xfd; | ||
| 160 | |||
| 161 | offset = 1; | ||
| 162 | } | ||
| 163 | #endif | ||
| 164 | |||
| 165 | if (reg >= 8) { | ||
| 166 | bytes[i++] = 0x41; /* REX.B prefix */ | ||
| 167 | reg -= 8; | ||
| 168 | } | ||
| 169 | bytes[i++] = 0xff; | ||
| 170 | bytes[i++] = 0xe0 + reg; /* jmp *reg */ | ||
| 171 | bytes[i++] = 0xcc; | ||
| 172 | |||
| 173 | return thunk + offset; | ||
| 174 | } | ||
| 175 | |||
| 176 | #ifdef CONFIG_MODULES | ||
| 177 | void its_init_mod(struct module *mod) | ||
| 178 | { | ||
| 179 | if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) | ||
| 180 | return; | ||
| 181 | |||
| 182 | mutex_lock(&text_mutex); | ||
| 183 | its_mod = mod; | ||
| 184 | its_page = NULL; | ||
| 185 | } | ||
| 186 | |||
| 187 | void its_fini_mod(struct module *mod) | ||
| 188 | { | ||
| 189 | if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) | ||
| 190 | return; | ||
| 191 | |||
| 192 | WARN_ON_ONCE(its_mod != mod); | ||
| 193 | |||
| 194 | its_mod = NULL; | ||
| 195 | its_page = NULL; | ||
| 196 | mutex_unlock(&text_mutex); | ||
| 197 | |||
| 198 | for (int i = 0; i < mod->its_num_pages; i++) { | ||
| 199 | void *page = mod->its_page_array[i]; | ||
| 200 | execmem_restore_rox(page, PAGE_SIZE); | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | void its_free_mod(struct module *mod) | ||
| 205 | { | ||
| 206 | if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) | ||
| 207 | return; | ||
| 208 | |||
| 209 | for (int i = 0; i < mod->its_num_pages; i++) { | ||
| 210 | void *page = mod->its_page_array[i]; | ||
| 211 | execmem_free(page); | ||
| 212 | } | ||
| 213 | kfree(mod->its_page_array); | ||
| 214 | } | ||
| 215 | #endif /* CONFIG_MODULES */ | ||
| 216 | |||
| 217 | static void *its_alloc(void) | ||
| 218 | { | ||
| 219 | void *page __free(execmem) = execmem_alloc(EXECMEM_MODULE_TEXT, PAGE_SIZE); | ||
| 220 | |||
| 221 | if (!page) | ||
| 222 | return NULL; | ||
| 223 | |||
| 224 | #ifdef CONFIG_MODULES | ||
| 225 | if (its_mod) { | ||
| 226 | void *tmp = krealloc(its_mod->its_page_array, | ||
| 227 | (its_mod->its_num_pages+1) * sizeof(void *), | ||
| 228 | GFP_KERNEL); | ||
| 229 | if (!tmp) | ||
| 230 | return NULL; | ||
| 231 | |||
| 232 | its_mod->its_page_array = tmp; | ||
| 233 | its_mod->its_page_array[its_mod->its_num_pages++] = page; | ||
| 234 | |||
| 235 | execmem_make_temp_rw(page, PAGE_SIZE); | ||
| 236 | } | ||
| 237 | #endif /* CONFIG_MODULES */ | ||
| 238 | |||
| 239 | return no_free_ptr(page); | ||
| 240 | } | ||
| 241 | |||
| 242 | static void *its_allocate_thunk(int reg) | ||
| 243 | { | ||
| 244 | int size = 3 + (reg / 8); | ||
| 245 | void *thunk; | ||
| 246 | |||
| 247 | #ifdef CONFIG_FINEIBT | ||
| 248 | /* | ||
| 249 | * The ITS thunk contains an indirect jump and an int3 instruction so | ||
| 250 | * its size is 3 or 4 bytes depending on the register used. If CFI | ||
| 251 | * paranoid is used then 3 extra bytes are added in the ITS thunk to | ||
| 252 | * complete the fineibt_paranoid caller sequence. | ||
| 253 | */ | ||
| 254 | if (cfi_paranoid) | ||
| 255 | size += 3; | ||
| 256 | #endif | ||
| 257 | |||
| 258 | if (!its_page || (its_offset + size - 1) >= PAGE_SIZE) { | ||
| 259 | its_page = its_alloc(); | ||
| 260 | if (!its_page) { | ||
| 261 | pr_err("ITS page allocation failed\n"); | ||
| 262 | return NULL; | ||
| 263 | } | ||
| 264 | memset(its_page, INT3_INSN_OPCODE, PAGE_SIZE); | ||
| 265 | its_offset = 32; | ||
| 266 | } | ||
| 267 | |||
| 268 | /* | ||
| 269 | * If the indirect branch instruction will be in the lower half | ||
| 270 | * of a cacheline, then update the offset to reach the upper half. | ||
| 271 | */ | ||
| 272 | if ((its_offset + size - 1) % 64 < 32) | ||
| 273 | its_offset = ((its_offset - 1) | 0x3F) + 33; | ||
| 274 | |||
| 275 | thunk = its_page + its_offset; | ||
| 276 | its_offset += size; | ||
| 277 | |||
| 278 | return its_init_thunk(thunk, reg); | ||
| 279 | } | ||
| 280 | |||
| 281 | u8 *its_static_thunk(int reg) | ||
| 282 | { | ||
| 283 | u8 *thunk = __x86_indirect_its_thunk_array[reg]; | ||
| 284 | |||
| 285 | #ifdef CONFIG_FINEIBT | ||
| 286 | /* Paranoid thunk starts 2 bytes before */ | ||
| 287 | if (cfi_paranoid) | ||
| 288 | return thunk - 2; | ||
| 289 | #endif | ||
| 290 | return thunk; | ||
| 291 | } | ||
| 292 | |||
| 293 | #endif | ||
| 294 | |||
| 127 | /* | 295 | /* |
| 128 | * Nomenclature for variable names to simplify and clarify this code and ease | 296 | * Nomenclature for variable names to simplify and clarify this code and ease |
| 129 | * any potential staring at it: | 297 | * any potential staring at it: |
| @@ -581,7 +749,8 @@ static int emit_indirect(int op, int reg, u8 *bytes) · 451 unmodified lines | |||
| 581 | return i; | 749 | return i; |
| 582 | } | 750 | } |
| 583 | 751 | ||
| 584 | static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 *bytes) | 752 | static int __emit_trampoline(void *addr, struct insn *insn, u8 *bytes, |
| 753 | void *call_dest, void *jmp_dest) | ||
| 585 | { | 754 | { |
| 586 | u8 op = insn->opcode.bytes[0]; | 755 | u8 op = insn->opcode.bytes[0]; |
| 587 | int i = 0; | 756 | int i = 0; |
| @@ -602,7 +771,7 @@ static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 · 14 unmodified lines | |||
| 602 | switch (op) { | 771 | switch (op) { |
| 603 | case CALL_INSN_OPCODE: | 772 | case CALL_INSN_OPCODE: |
| 604 | __text_gen_insn(bytes+i, op, addr+i, | 773 | __text_gen_insn(bytes+i, op, addr+i, |
| 605 | __x86_indirect_call_thunk_array[reg], | 774 | call_dest, |
| 606 | CALL_INSN_SIZE); | 775 | CALL_INSN_SIZE); |
| 607 | i += CALL_INSN_SIZE; | 776 | i += CALL_INSN_SIZE; |
| 608 | break; | 777 | break; |
| @@ -610,7 +779,7 @@ static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 · 1 unmodified line | |||
| 610 | case JMP32_INSN_OPCODE: | 779 | case JMP32_INSN_OPCODE: |
| 611 | clang_jcc: | 780 | clang_jcc: |
| 612 | __text_gen_insn(bytes+i, op, addr+i, | 781 | __text_gen_insn(bytes+i, op, addr+i, |
| 613 | __x86_indirect_jump_thunk_array[reg], | 782 | jmp_dest, |
| 614 | JMP32_INSN_SIZE); | 783 | JMP32_INSN_SIZE); |
| 615 | i += JMP32_INSN_SIZE; | 784 | i += JMP32_INSN_SIZE; |
| 616 | break; | 785 | break; |
| @@ -625,6 +794,48 @@ clang_jcc: · 8 unmodified lines | |||
| 625 | return i; | 794 | return i; |
| 626 | } | 795 | } |
| 627 | 796 | ||
| 797 | static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 *bytes) | ||
| 798 | { | ||
| 799 | return __emit_trampoline(addr, insn, bytes, | ||
| 800 | __x86_indirect_call_thunk_array[reg], | ||
| 801 | __x86_indirect_jump_thunk_array[reg]); | ||
| 802 | } | ||
| 803 | |||
| 804 | #ifdef CONFIG_MITIGATION_ITS | ||
| 805 | static int emit_its_trampoline(void *addr, struct insn *insn, int reg, u8 *bytes) | ||
| 806 | { | ||
| 807 | u8 *thunk = __x86_indirect_its_thunk_array[reg]; | ||
| 808 | u8 *tmp = its_allocate_thunk(reg); | ||
| 809 | |||
| 810 | if (tmp) | ||
| 811 | thunk = tmp; | ||
| 812 | |||
| 813 | return __emit_trampoline(addr, insn, bytes, thunk, thunk); | ||
| 814 | } | ||
| 815 | |||
| 816 | /* Check if an indirect branch is at ITS-unsafe address */ | ||
| 817 | static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg) | ||
| 818 | { | ||
| 819 | if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) | ||
| 820 | return false; | ||
| 821 | |||
| 822 | /* Indirect branch opcode is 2 or 3 bytes depending on reg */ | ||
| 823 | addr += 1 + reg / 8; | ||
| 824 | |||
| 825 | /* Lower-half of the cacheline? */ | ||
| 826 | return !(addr & 0x20); | ||
| 827 | } | ||
| 828 | #else /* CONFIG_MITIGATION_ITS */ | ||
| 829 | |||
| 830 | #ifdef CONFIG_FINEIBT | ||
| 831 | static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg) | ||
| 832 | { | ||
| 833 | return false; | ||
| 834 | } | ||
| 835 | #endif | ||
| 836 | |||
| 837 | #endif /* CONFIG_MITIGATION_ITS */ | ||
| 838 | |||
| 628 | /* | 839 | /* |
| 629 | * Rewrite the compiler generated retpoline thunk calls. | 840 | * Rewrite the compiler generated retpoline thunk calls. |
| 630 | * | 841 | * |
| @@ -699,6 +910,15 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes) · 68 unmodified lines | |||
| 699 | bytes[i++] = 0xe8; /* LFENCE */ | 910 | bytes[i++] = 0xe8; /* LFENCE */ |
| 700 | } | 911 | } |
| 701 | 912 | ||
| 913 | #ifdef CONFIG_MITIGATION_ITS | ||
| 914 | /* | ||
| 915 | * Check if the address of last byte of emitted-indirect is in | ||
| 916 | * lower-half of the cacheline. Such branches need ITS mitigation. | ||
| 917 | */ | ||
| 918 | if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + i, reg)) | ||
| 919 | return emit_its_trampoline(addr, insn, reg, bytes); | ||
| 920 | #endif | ||
| 921 | |||
| 702 | ret = emit_indirect(op, reg, bytes + i); | 922 | ret = emit_indirect(op, reg, bytes + i); |
| 703 | if (ret < 0) | 923 | if (ret < 0) |
| 704 | return ret; | 924 | return ret; |
| @@ -732,6 +952,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) · 27 unmodified lines | |||
| 732 | int len, ret; | 952 | int len, ret; |
| 733 | u8 bytes[16]; | 953 | u8 bytes[16]; |
| 734 | u8 op1, op2; | 954 | u8 op1, op2; |
| 955 | u8 *dest; | ||
| 735 | 956 | ||
| 736 | ret = insn_decode_kernel(&insn, addr); | 957 | ret = insn_decode_kernel(&insn, addr); |
| 737 | if (WARN_ON_ONCE(ret < 0)) | 958 | if (WARN_ON_ONCE(ret < 0)) |
| @@ -748,6 +969,12 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) · 10 unmodified lines | |||
| 748 | 969 | ||
| 749 | case CALL_INSN_OPCODE: | 970 | case CALL_INSN_OPCODE: |
| 750 | case JMP32_INSN_OPCODE: | 971 | case JMP32_INSN_OPCODE: |
| 972 | /* Check for cfi_paranoid + ITS */ | ||
| 973 | dest = addr + insn.length + insn.immediate.value; | ||
| 974 | if (dest[-1] == 0xea && (dest[0] & 0xf0) == 0x70) { | ||
| 975 | WARN_ON_ONCE(cfi_mode != CFI_FINEIBT); | ||
| 976 | continue; | ||
| 977 | } | ||
| 751 | break; | 978 | break; |
| 752 | 979 | ||
| 753 | case 0x0f: /* escape */ | 980 | case 0x0f: /* escape */ |
| @@ -775,6 +1002,21 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) · 21 unmodified lines | |||
| 775 | 1002 | ||
| 776 | #ifdef CONFIG_MITIGATION_RETHUNK | 1003 | #ifdef CONFIG_MITIGATION_RETHUNK |
| 777 | 1004 | ||
| 1005 | bool cpu_wants_rethunk(void) | ||
| 1006 | { | ||
| 1007 | return cpu_feature_enabled(X86_FEATURE_RETHUNK); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | bool cpu_wants_rethunk_at(void *addr) | ||
| 1011 | { | ||
| 1012 | if (!cpu_feature_enabled(X86_FEATURE_RETHUNK)) | ||
| 1013 | return false; | ||
| 1014 | if (x86_return_thunk != its_return_thunk) | ||
| 1015 | return true; | ||
| 1016 | |||
| 1017 | return !((unsigned long)addr & 0x20); | ||
| 1018 | } | ||
| 1019 | |||
| 778 | /* | 1020 | /* |
| 779 | * Rewrite the compiler generated return thunk tail-calls. | 1021 | * Rewrite the compiler generated return thunk tail-calls. |
| 780 | * | 1022 | * |
| @@ -791,7 +1033,7 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes) · 10 unmodified lines | |||
| 791 | int i = 0; | 1033 | int i = 0; |
| 792 | 1034 | ||
| 793 | /* Patch the custom return thunks... */ | 1035 | /* Patch the custom return thunks... */ |
| 794 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { | 1036 | if (cpu_wants_rethunk_at(addr)) { |
| 795 | i = JMP32_INSN_SIZE; | 1037 | i = JMP32_INSN_SIZE; |
| 796 | __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i); | 1038 | __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i); |
| 797 | } else { | 1039 | } else { |
| @@ -808,7 +1050,7 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end) · 10 unmodified lines | |||
| 808 | { | 1050 | { |
| 809 | s32 *s; | 1051 | s32 *s; |
| 810 | 1052 | ||
| 811 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | 1053 | if (cpu_wants_rethunk()) |
| 812 | static_call_force_reinit(); | 1054 | static_call_force_reinit(); |
| 813 | 1055 | ||
| 814 | for (s = start; s < end; s++) { | 1056 | for (s = start; s < end; s++) { |
| @@ -1022,8 +1264,6 @@ int cfi_get_func_arity(void *func) · 207 unmodified lines | |||
| 1022 | static bool cfi_rand __ro_after_init = true; | 1264 | static bool cfi_rand __ro_after_init = true; |
| 1023 | static u32 cfi_seed __ro_after_init; | 1265 | static u32 cfi_seed __ro_after_init; |
| 1024 | 1266 | ||
| 1025 | static bool cfi_paranoid __ro_after_init = false; | ||
| 1026 | |||
| 1027 | /* | 1267 | /* |
| 1028 | * Re-hash the CFI hash with a boot-time seed while making sure the result is | 1268 | * Re-hash the CFI hash with a boot-time seed while making sure the result is |
| 1029 | * not a valid ENDBR instruction. | 1269 | * not a valid ENDBR instruction. |
| @@ -1436,6 +1676,19 @@ static int cfi_rand_callers(s32 *start, s32 *end) · 406 unmodified lines | |||
| 1436 | return 0; | 1676 | return 0; |
| 1437 | } | 1677 | } |
| 1438 | 1678 | ||
| 1679 | static int emit_paranoid_trampoline(void *addr, struct insn *insn, int reg, u8 *bytes) | ||
| 1680 | { | ||
| 1681 | u8 *thunk = (void *)__x86_indirect_its_thunk_array[reg] - 2; | ||
| 1682 | |||
| 1683 | #ifdef CONFIG_MITIGATION_ITS | ||
| 1684 | u8 *tmp = its_allocate_thunk(reg); | ||
| 1685 | if (tmp) | ||
| 1686 | thunk = tmp; | ||
| 1687 | #endif | ||
| 1688 | |||
| 1689 | return __emit_trampoline(addr, insn, bytes, thunk, thunk); | ||
| 1690 | } | ||
| 1691 | |||
| 1439 | static int cfi_rewrite_callers(s32 *start, s32 *end) | 1692 | static int cfi_rewrite_callers(s32 *start, s32 *end) |
| 1440 | { | 1693 | { |
| 1441 | s32 *s; | 1694 | s32 *s; |
| @@ -1477,9 +1730,14 @@ static int cfi_rewrite_callers(s32 *start, s32 *end) · 35 unmodified lines | |||
| 1477 | memcpy(bytes, fineibt_paranoid_start, fineibt_paranoid_size); | 1730 | memcpy(bytes, fineibt_paranoid_start, fineibt_paranoid_size); |
| 1478 | memcpy(bytes + fineibt_caller_hash, &hash, 4); | 1731 | memcpy(bytes + fineibt_caller_hash, &hash, 4); |
| 1479 | 1732 | ||
| 1480 | ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind); | 1733 | if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + fineibt_paranoid_ind, 11)) { |
| 1481 | if (WARN_ON_ONCE(ret != 3)) | 1734 | emit_paranoid_trampoline(addr + fineibt_caller_size, |
| 1482 | continue; | 1735 | &insn, 11, bytes + fineibt_caller_size); |
| 1736 | } else { | ||
| 1737 | ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind); | ||
| 1738 | if (WARN_ON_ONCE(ret != 3)) | ||
| 1739 | continue; | ||
| 1740 | } | ||
| 1483 | 1741 | ||
| 1484 | text_poke_early(addr, bytes, fineibt_paranoid_size); | 1742 | text_poke_early(addr, bytes, fineibt_paranoid_size); |
| 1485 | } | 1743 | } |
| @@ -1706,29 +1964,66 @@ Efault: · 220 unmodified lines | |||
| 1706 | return false; | 1964 | return false; |
| 1707 | } | 1965 | } |
| 1708 | 1966 | ||
| 1967 | static bool is_paranoid_thunk(unsigned long addr) | ||
| 1968 | { | ||
| 1969 | u32 thunk; | ||
| 1970 | |||
| 1971 | __get_kernel_nofault(&thunk, (u32 *)addr, u32, Efault); | ||
| 1972 | return (thunk & 0x00FFFFFF) == 0xfd75ea; | ||
| 1973 | |||
| 1974 | Efault: | ||
| 1975 | return false; | ||
| 1976 | } | ||
| 1977 | |||
| 1709 | /* | 1978 | /* |
| 1710 | * regs->ip points to a LOCK Jcc.d8 instruction from the fineibt_paranoid_start[] | 1979 | * regs->ip points to a LOCK Jcc.d8 instruction from the fineibt_paranoid_start[] |
| 1711 | * sequence. | 1980 | * sequence, or to an invalid instruction (0xea) + Jcc.d8 for cfi_paranoid + ITS |
| 1981 | * thunk. | ||
| 1712 | */ | 1982 | */ |
| 1713 | static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, u32 *type) | 1983 | static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, u32 *type) |
| 1714 | { | 1984 | { |
| 1715 | unsigned long addr = regs->ip - fineibt_paranoid_ud; | 1985 | unsigned long addr = regs->ip - fineibt_paranoid_ud; |
| 1716 | u32 hash; | ||
| 1717 | 1986 | ||
| 1718 | if (!cfi_paranoid || !is_cfi_trap(addr + fineibt_caller_size - LEN_UD2)) | 1987 | if (!cfi_paranoid) |
| 1719 | return false; | 1988 | return false; |
| 1720 | 1989 | ||
| 1721 | __get_kernel_nofault(&hash, addr + fineibt_caller_hash, u32, Efault); | 1990 | if (is_cfi_trap(addr + fineibt_caller_size - LEN_UD2)) { |
| 1722 | *target = regs->r11 + fineibt_preamble_size; | 1991 | *target = regs->r11 + fineibt_preamble_size; |
| 1723 | *type = regs->r10; | 1992 | *type = regs->r10; |
| 1993 | |||
| 1994 | /* | ||
| 1995 | * Since the trapping instruction is the exact, but LOCK prefixed, | ||
| 1996 | * Jcc.d8 that got us here, the normal fixup will work. | ||
| 1997 | */ | ||
| 1998 | return true; | ||
| 1999 | } | ||
| 1724 | 2000 | ||
| 1725 | /* | 2001 | /* |
| 1726 | * Since the trapping instruction is the exact, but LOCK prefixed, | 2002 | * The cfi_paranoid + ITS thunk combination results in: |
| 1727 | * Jcc.d8 that got us here, the normal fixup will work. | 2003 | * |
| 2004 | * 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d | ||
| 2005 | * 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d | ||
| 2006 | * a: 4d 8d 5b f0 lea -0x10(%r11), %r11 | ||
| 2007 | * e: 2e e8 XX XX XX XX cs call __x86_indirect_paranoid_thunk_r11 | ||
| 2008 | * | ||
| 2009 | * Where the paranoid_thunk looks like: | ||
| 2010 | * | ||
| 2011 | * 1d: <ea> (bad) | ||
| 2012 | * __x86_indirect_paranoid_thunk_r11: | ||
| 2013 | * 1e: 75 fd jne 1d | ||
| 2014 | * __x86_indirect_its_thunk_r11: | ||
| 2015 | * 20: 41 ff eb jmp *%r11 | ||
| 2016 | * 23: cc int3 | ||
| 2017 | * | ||
| 1728 | */ | 2018 | */ |
| 1729 | return true; | 2019 | if (is_paranoid_thunk(regs->ip)) { |
| 2020 | *target = regs->r11 + fineibt_preamble_size; | ||
| 2021 | *type = regs->r10; | ||
| 2022 | |||
| 2023 | regs->ip = *target; | ||
| 2024 | return true; | ||
| 2025 | } | ||
| 1730 | 2026 | ||
| 1731 | Efault: | ||
| 1732 | return false; | 2027 | return false; |
| 1733 | } | 2028 | } |
| 1734 | 2029 | ||
| @@ -2031,6 +2326,8 @@ static noinline void __init alt_reloc_selftest(void) · 296 unmodified lines | |||
| 2031 | 2326 | ||
| 2032 | void __init alternative_instructions(void) | 2327 | void __init alternative_instructions(void) |
| 2033 | { | 2328 | { |
| 2329 | u64 ibt; | ||
| 2330 | |||
| 2034 | int3_selftest(); | 2331 | int3_selftest(); |
| 2035 | 2332 | ||
| 2036 | /* | 2333 | /* |
| @@ -2057,6 +2354,9 @@ void __init alternative_instructions(void) · 20 unmodified lines | |||
| 2057 | */ | 2354 | */ |
| 2058 | paravirt_set_cap(); | 2355 | paravirt_set_cap(); |
| 2059 | 2356 | ||
| 2357 | /* Keep CET-IBT disabled until caller/callee are patched */ | ||
| 2358 | ibt = ibt_save(/*disable*/ true); | ||
| 2359 | |||
| 2060 | __apply_fineibt(__retpoline_sites, __retpoline_sites_end, | 2360 | __apply_fineibt(__retpoline_sites, __retpoline_sites_end, |
| 2061 | __cfi_sites, __cfi_sites_end, true); | 2361 | __cfi_sites, __cfi_sites_end, true); |
| 2062 | 2362 | ||
| @@ -2080,6 +2380,8 @@ void __init alternative_instructions(void) · 17 unmodified lines | |||
| 2080 | */ | 2380 | */ |
| 2081 | apply_seal_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end); | 2381 | apply_seal_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end); |
| 2082 | 2382 | ||
| 2383 | ibt_restore(ibt); | ||
| 2384 | |||
| 2083 | #ifdef CONFIG_SMP | 2385 | #ifdef CONFIG_SMP |
| 2084 | /* Patch to UP if other cpus not imminent. */ | 2386 | /* Patch to UP if other cpus not imminent. */ |
| 2085 | if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) { | 2387 | if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) { |
| @@ -472,6 +472,11 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) · 471 unmodified lines | |||
| 472 | case 0x60 ... 0x7f: | 472 | case 0x60 ... 0x7f: |
| 473 | setup_force_cpu_cap(X86_FEATURE_ZEN5); | 473 | setup_force_cpu_cap(X86_FEATURE_ZEN5); |
| 474 | break; | 474 | break; |
| 475 | case 0x50 ... 0x5f: | ||
| 476 | case 0x90 ... 0xaf: | ||
| 477 | case 0xc0 ... 0xcf: | ||
| 478 | setup_force_cpu_cap(X86_FEATURE_ZEN6); | ||
| 479 | break; | ||
| 475 | default: | 480 | default: |
| 476 | goto warn; | 481 | goto warn; |
| 477 | } | 482 | } |
| @@ -805,6 +810,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) · 327 unmodified lines | |||
| 805 | static const struct x86_cpu_id erratum_1386_microcode[] = { | 810 | static const struct x86_cpu_id erratum_1386_microcode[] = { |
| 806 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x01), 0x2, 0x2, 0x0800126e), | 811 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x01), 0x2, 0x2, 0x0800126e), |
| 807 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x31), 0x0, 0x0, 0x08301052), | 812 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x31), 0x0, 0x0, 0x08301052), |
| 813 | {} | ||
| 808 | }; | 814 | }; |
| 809 | 815 | ||
| 810 | static void fix_erratum_1386(struct cpuinfo_x86 *c) | 816 | static void fix_erratum_1386(struct cpuinfo_x86 *c) |
| @@ -868,6 +874,16 @@ static void init_amd_zen1(struct cpuinfo_x86 *c) · 57 unmodified lines | |||
| 868 | 874 | ||
| 869 | pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); | 875 | pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); |
| 870 | setup_force_cpu_bug(X86_BUG_DIV0); | 876 | setup_force_cpu_bug(X86_BUG_DIV0); |
| 877 | |||
| 878 | /* | ||
| 879 | * Turn off the Instructions Retired free counter on machines that are | ||
| 880 | * susceptible to erratum #1054 "Instructions Retired Performance | ||
| 881 | * Counter May Be Inaccurate". | ||
| 882 | */ | ||
| 883 | if (c->x86_model < 0x30) { | ||
| 884 | msr_clear_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); | ||
| 885 | clear_cpu_cap(c, X86_FEATURE_IRPERF); | ||
| 886 | } | ||
| 871 | } | 887 | } |
| 872 | 888 | ||
| 873 | static bool cpu_has_zenbleed_microcode(void) | 889 | static bool cpu_has_zenbleed_microcode(void) |
| @@ -1051,13 +1067,8 @@ static void init_amd(struct cpuinfo_x86 *c) · 177 unmodified lines | |||
| 1051 | if (!cpu_feature_enabled(X86_FEATURE_XENPV)) | 1067 | if (!cpu_feature_enabled(X86_FEATURE_XENPV)) |
| 1052 | set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); | 1068 | set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); |
| 1053 | 1069 | ||
| 1054 | /* | 1070 | /* Enable the Instructions Retired free counter */ |
| 1055 | * Turn on the Instructions Retired free counter on machines not | 1071 | if (cpu_has(c, X86_FEATURE_IRPERF)) |
| 1056 | * susceptible to erratum #1054 "Instructions Retired Performance | ||
| 1057 | * Counter May Be Inaccurate". | ||
| 1058 | */ | ||
| 1059 | if (cpu_has(c, X86_FEATURE_IRPERF) && | ||
| 1060 | (boot_cpu_has(X86_FEATURE_ZEN1) && c->x86_model > 0x2f)) | ||
| 1061 | msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); | 1072 | msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); |
| 1062 | 1073 | ||
| 1063 | check_null_seg_clears_base(c); | 1074 | check_null_seg_clears_base(c); |
| @@ -49,6 +49,7 @@ static void __init srbds_select_mitigation(void); · 48 unmodified lines | |||
| 49 | static void __init l1d_flush_select_mitigation(void); | 49 | static void __init l1d_flush_select_mitigation(void); |
| 50 | static void __init srso_select_mitigation(void); | 50 | static void __init srso_select_mitigation(void); |
| 51 | static void __init gds_select_mitigation(void); | 51 | static void __init gds_select_mitigation(void); |
| 52 | static void __init its_select_mitigation(void); | ||
| 52 | 53 | ||
| 53 | /* The base value of the SPEC_CTRL MSR without task-specific bits set */ | 54 | /* The base value of the SPEC_CTRL MSR without task-specific bits set */ |
| 54 | u64 x86_spec_ctrl_base; | 55 | u64 x86_spec_ctrl_base; |
| @@ -59,7 +60,6 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current); · 4 unmodified lines | |||
| 59 | EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current); | 60 | EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current); |
| 60 | 61 | ||
| 61 | u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; | 62 | u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; |
| 62 | EXPORT_SYMBOL_GPL(x86_pred_cmd); | ||
| 63 | 63 | ||
| 64 | static u64 __ro_after_init x86_arch_cap_msr; | 64 | static u64 __ro_after_init x86_arch_cap_msr; |
| 65 | 65 | ||
| @@ -67,6 +67,14 @@ static DEFINE_MUTEX(spec_ctrl_mutex); · 1 unmodified line | |||
| 67 | 67 | ||
| 68 | void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk; | 68 | void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk; |
| 69 | 69 | ||
| 70 | static void __init set_return_thunk(void *thunk) | ||
| 71 | { | ||
| 72 | if (x86_return_thunk != __x86_return_thunk) | ||
| 73 | pr_warn("x86/bugs: return thunk changed\n"); | ||
| 74 | |||
| 75 | x86_return_thunk = thunk; | ||
| 76 | } | ||
| 77 | |||
| 70 | /* Update SPEC_CTRL MSR and its cached copy unconditionally */ | 78 | /* Update SPEC_CTRL MSR and its cached copy unconditionally */ |
| 71 | static void update_spec_ctrl(u64 val) | 79 | static void update_spec_ctrl(u64 val) |
| 72 | { | 80 | { |
| @@ -179,6 +187,7 @@ void __init cpu_select_mitigations(void) · 106 unmodified lines | |||
| 179 | */ | 187 | */ |
| 180 | srso_select_mitigation(); | 188 | srso_select_mitigation(); |
| 181 | gds_select_mitigation(); | 189 | gds_select_mitigation(); |
| 190 | its_select_mitigation(); | ||
| 182 | } | 191 | } |
| 183 | 192 | ||
| 184 | /* | 193 | /* |
| @@ -1119,7 +1128,7 @@ do_cmd_auto: · 934 unmodified lines | |||
| 1119 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); | 1128 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); |
| 1120 | setup_force_cpu_cap(X86_FEATURE_UNRET); | 1129 | setup_force_cpu_cap(X86_FEATURE_UNRET); |
| 1121 | 1130 | ||
| 1122 | x86_return_thunk = retbleed_return_thunk; | 1131 | set_return_thunk(retbleed_return_thunk); |
| 1123 | 1132 | ||
| 1124 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && | 1133 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && |
| 1125 | boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) | 1134 | boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) |
| @@ -1142,7 +1151,7 @@ do_cmd_auto: · 16 unmodified lines | |||
| 1142 | setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | 1151 | setup_clear_cpu_cap(X86_FEATURE_RETHUNK); |
| 1143 | 1152 | ||
| 1144 | /* | 1153 | /* |
| 1145 | * There is no need for RSB filling: entry_ibpb() ensures | 1154 | * There is no need for RSB filling: write_ibpb() ensures |
| 1146 | * all predictions, including the RSB, are invalidated, | 1155 | * all predictions, including the RSB, are invalidated, |
| 1147 | * regardless of IBPB implementation. | 1156 | * regardless of IBPB implementation. |
| 1148 | */ | 1157 | */ |
| @@ -1154,7 +1163,7 @@ do_cmd_auto: · 5 unmodified lines | |||
| 1154 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); | 1163 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); |
| 1155 | setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH); | 1164 | setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH); |
| 1156 | 1165 | ||
| 1157 | x86_return_thunk = call_depth_return_thunk; | 1166 | set_return_thunk(call_depth_return_thunk); |
| 1158 | break; | 1167 | break; |
| 1159 | 1168 | ||
| 1160 | default: | 1169 | default: |
| @@ -1188,6 +1197,145 @@ do_cmd_auto: · 27 unmodified lines | |||
| 1188 | pr_info("%s\n", retbleed_strings[retbleed_mitigation]); | 1197 | pr_info("%s\n", retbleed_strings[retbleed_mitigation]); |
| 1189 | } | 1198 | } |
| 1190 | 1199 | ||
| 1200 | #undef pr_fmt | ||
| 1201 | #define pr_fmt(fmt) "ITS: " fmt | ||
| 1202 | |||
| 1203 | enum its_mitigation_cmd { | ||
| 1204 | ITS_CMD_OFF, | ||
| 1205 | ITS_CMD_ON, | ||
| 1206 | ITS_CMD_VMEXIT, | ||
| 1207 | ITS_CMD_RSB_STUFF, | ||
| 1208 | }; | ||
| 1209 | |||
| 1210 | enum its_mitigation { | ||
| 1211 | ITS_MITIGATION_OFF, | ||
| 1212 | ITS_MITIGATION_VMEXIT_ONLY, | ||
| 1213 | ITS_MITIGATION_ALIGNED_THUNKS, | ||
| 1214 | ITS_MITIGATION_RETPOLINE_STUFF, | ||
| 1215 | }; | ||
| 1216 | |||
| 1217 | static const char * const its_strings[] = { | ||
| 1218 | [ITS_MITIGATION_OFF] = "Vulnerable", | ||
| 1219 | [ITS_MITIGATION_VMEXIT_ONLY] = "Mitigation: Vulnerable, KVM: Not affected", | ||
| 1220 | [ITS_MITIGATION_ALIGNED_THUNKS] = "Mitigation: Aligned branch/return thunks", | ||
| 1221 | [ITS_MITIGATION_RETPOLINE_STUFF] = "Mitigation: Retpolines, Stuffing RSB", | ||
| 1222 | }; | ||
| 1223 | |||
| 1224 | static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS; | ||
| 1225 | |||
| 1226 | static enum its_mitigation_cmd its_cmd __ro_after_init = | ||
| 1227 | IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF; | ||
| 1228 | |||
| 1229 | static int __init its_parse_cmdline(char *str) | ||
| 1230 | { | ||
| 1231 | if (!str) | ||
| 1232 | return -EINVAL; | ||
| 1233 | |||
| 1234 | if (!IS_ENABLED(CONFIG_MITIGATION_ITS)) { | ||
| 1235 | pr_err("Mitigation disabled at compile time, ignoring option (%s)", str); | ||
| 1236 | return 0; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | if (!strcmp(str, "off")) { | ||
| 1240 | its_cmd = ITS_CMD_OFF; | ||
| 1241 | } else if (!strcmp(str, "on")) { | ||
| 1242 | its_cmd = ITS_CMD_ON; | ||
| 1243 | } else if (!strcmp(str, "force")) { | ||
| 1244 | its_cmd = ITS_CMD_ON; | ||
| 1245 | setup_force_cpu_bug(X86_BUG_ITS); | ||
| 1246 | } else if (!strcmp(str, "vmexit")) { | ||
| 1247 | its_cmd = ITS_CMD_VMEXIT; | ||
| 1248 | } else if (!strcmp(str, "stuff")) { | ||
| 1249 | its_cmd = ITS_CMD_RSB_STUFF; | ||
| 1250 | } else { | ||
| 1251 | pr_err("Ignoring unknown indirect_target_selection option (%s).", str); | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | return 0; | ||
| 1255 | } | ||
| 1256 | early_param("indirect_target_selection", its_parse_cmdline); | ||
| 1257 | |||
| 1258 | static void __init its_select_mitigation(void) | ||
| 1259 | { | ||
| 1260 | enum its_mitigation_cmd cmd = its_cmd; | ||
| 1261 | |||
| 1262 | if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) { | ||
| 1263 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1264 | return; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | /* Retpoline+CDT mitigates ITS, bail out */ | ||
| 1268 | if (boot_cpu_has(X86_FEATURE_RETPOLINE) && | ||
| 1269 | boot_cpu_has(X86_FEATURE_CALL_DEPTH)) { | ||
| 1270 | its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF; | ||
| 1271 | goto out; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | /* Exit early to avoid irrelevant warnings */ | ||
| 1275 | if (cmd == ITS_CMD_OFF) { | ||
| 1276 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1277 | goto out; | ||
| 1278 | } | ||
| 1279 | if (spectre_v2_enabled == SPECTRE_V2_NONE) { | ||
| 1280 | pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n"); | ||
| 1281 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1282 | goto out; | ||
| 1283 | } | ||
| 1284 | if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) || | ||
| 1285 | !IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) { | ||
| 1286 | pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n"); | ||
| 1287 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1288 | goto out; | ||
| 1289 | } | ||
| 1290 | if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) { | ||
| 1291 | pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n"); | ||
| 1292 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1293 | goto out; | ||
| 1294 | } | ||
| 1295 | if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) { | ||
| 1296 | pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n"); | ||
| 1297 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1298 | goto out; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | if (cmd == ITS_CMD_RSB_STUFF && | ||
| 1302 | (!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) { | ||
| 1303 | pr_err("RSB stuff mitigation not supported, using default\n"); | ||
| 1304 | cmd = ITS_CMD_ON; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | switch (cmd) { | ||
| 1308 | case ITS_CMD_OFF: | ||
| 1309 | its_mitigation = ITS_MITIGATION_OFF; | ||
| 1310 | break; | ||
| 1311 | case ITS_CMD_VMEXIT: | ||
| 1312 | if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) { | ||
| 1313 | its_mitigation = ITS_MITIGATION_VMEXIT_ONLY; | ||
| 1314 | goto out; | ||
| 1315 | } | ||
| 1316 | fallthrough; | ||
| 1317 | case ITS_CMD_ON: | ||
| 1318 | its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS; | ||
| 1319 | if (!boot_cpu_has(X86_FEATURE_RETPOLINE)) | ||
| 1320 | setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS); | ||
| 1321 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); | ||
| 1322 | set_return_thunk(its_return_thunk); | ||
| 1323 | break; | ||
| 1324 | case ITS_CMD_RSB_STUFF: | ||
| 1325 | its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF; | ||
| 1326 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); | ||
| 1327 | setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH); | ||
| 1328 | set_return_thunk(call_depth_return_thunk); | ||
| 1329 | if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) { | ||
| 1330 | retbleed_mitigation = RETBLEED_MITIGATION_STUFF; | ||
| 1331 | pr_info("Retbleed mitigation updated to stuffing\n"); | ||
| 1332 | } | ||
| 1333 | break; | ||
| 1334 | } | ||
| 1335 | out: | ||
| 1336 | pr_info("%s\n", its_strings[its_mitigation]); | ||
| 1337 | } | ||
| 1338 | |||
| 1191 | #undef pr_fmt | 1339 | #undef pr_fmt |
| 1192 | #define pr_fmt(fmt) "Spectre V2 : " fmt | 1340 | #define pr_fmt(fmt) "Spectre V2 : " fmt |
| 1193 | 1341 | ||
| @@ -1592,51 +1740,54 @@ static void __init spec_ctrl_disable_kernel_rrsba(void) · 398 unmodified lines | |||
| 1592 | rrsba_disabled = true; | 1740 | rrsba_disabled = true; |
| 1593 | } | 1741 | } |
| 1594 | 1742 | ||
| 1595 | static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode) | 1743 | static void __init spectre_v2_select_rsb_mitigation(enum spectre_v2_mitigation mode) |
| 1596 | { | 1744 | { |
| 1597 | /* | 1745 | /* |
| 1598 | * Similar to context switches, there are two types of RSB attacks | 1746 | * WARNING! There are many subtleties to consider when changing *any* |
| 1599 | * after VM exit: | 1747 | * code related to RSB-related mitigations. Before doing so, carefully |
| 1748 | * read the following document, and update if necessary: | ||
| 1600 | * | 1749 | * |
| 1601 | * 1) RSB underflow | 1750 | * Documentation/admin-guide/hw-vuln/rsb.rst |
| 1602 | * | 1751 | * |
| 1603 | * 2) Poisoned RSB entry | 1752 | * In an overly simplified nutshell: |
| 1604 | * | 1753 | * |
| 1605 | * When retpoline is enabled, both are mitigated by filling/clearing | 1754 | * - User->user RSB attacks are conditionally mitigated during |
| 1606 | * the RSB. | 1755 | * context switches by cond_mitigation -> write_ibpb(). |
| 1607 | * | 1756 | * |
| 1608 | * When IBRS is enabled, while #1 would be mitigated by the IBRS branch | 1757 | * - User->kernel and guest->host attacks are mitigated by eIBRS or |
| 1609 | * prediction isolation protections, RSB still needs to be cleared | 1758 | * RSB filling. |
| 1610 | * because of #2. Note that SMEP provides no protection here, unlike | ||
| 1611 | * user-space-poisoned RSB entries. | ||
| 1612 | * | 1759 | * |
| 1613 | * eIBRS should protect against RSB poisoning, but if the EIBRS_PBRSB | 1760 | * Though, depending on config, note that other alternative |
| 1614 | * bug is present then a LITE version of RSB protection is required, | 1761 | * mitigations may end up getting used instead, e.g., IBPB on |
| 1615 | * just a single call needs to retire before a RET is executed. | 1762 | * entry/vmexit, call depth tracking, or return thunks. |
| 1616 | */ | 1763 | */ |
| 1764 | |||
| 1617 | switch (mode) { | 1765 | switch (mode) { |
| 1618 | case SPECTRE_V2_NONE: | 1766 | case SPECTRE_V2_NONE: |
| 1619 | return; | 1767 | break; |
| 1620 | 1768 | ||
| 1621 | case SPECTRE_V2_EIBRS_LFENCE: | ||
| 1622 | case SPECTRE_V2_EIBRS: | 1769 | case SPECTRE_V2_EIBRS: |
| 1770 | case SPECTRE_V2_EIBRS_LFENCE: | ||
| 1771 | case SPECTRE_V2_EIBRS_RETPOLINE: | ||
| 1623 | if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { | 1772 | if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { |
| 1624 | setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); | ||
| 1625 | pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n"); | 1773 | pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n"); |
| 1774 | setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); | ||
| 1626 | } | 1775 | } |
| 1627 | return; | 1776 | break; |
| 1628 | 1777 | ||
| 1629 | case SPECTRE_V2_EIBRS_RETPOLINE: | ||
| 1630 | case SPECTRE_V2_RETPOLINE: | 1778 | case SPECTRE_V2_RETPOLINE: |
| 1631 | case SPECTRE_V2_LFENCE: | 1779 | case SPECTRE_V2_LFENCE: |
| 1632 | case SPECTRE_V2_IBRS: | 1780 | case SPECTRE_V2_IBRS: |
| 1781 | pr_info("Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT\n"); | ||
| 1782 | setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); | ||
| 1633 | setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); | 1783 | setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); |
| 1634 | pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n"); | 1784 | break; |
| 1635 | return; | ||
| 1636 | } | ||
| 1637 | 1785 | ||
| 1638 | pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit"); | 1786 | default: |
| 1639 | dump_stack(); | 1787 | pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation\n"); |
| 1788 | dump_stack(); | ||
| 1789 | break; | ||
| 1790 | } | ||
| 1640 | } | 1791 | } |
| 1641 | 1792 | ||
| 1642 | /* | 1793 | /* |
| @@ -1695,11 +1846,11 @@ static void __init bhi_select_mitigation(void) · 52 unmodified lines | |||
| 1695 | return; | 1846 | return; |
| 1696 | } | 1847 | } |
| 1697 | 1848 | ||
| 1698 | /* Mitigate in hardware if supported */ | 1849 | if (!IS_ENABLED(CONFIG_X86_64)) |
| 1699 | if (spec_ctrl_bhi_dis()) | ||
| 1700 | return; | 1850 | return; |
| 1701 | 1851 | ||
| 1702 | if (!IS_ENABLED(CONFIG_X86_64)) | 1852 | /* Mitigate in hardware if supported */ |
| 1853 | if (spec_ctrl_bhi_dis()) | ||
| 1703 | return; | 1854 | return; |
| 1704 | 1855 | ||
| 1705 | if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) { | 1856 | if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) { |
| @@ -1830,48 +1981,7 @@ static void __init spectre_v2_select_mitigation(void) · 124 unmodified lines | |||
| 1830 | spectre_v2_enabled = mode; | 1981 | spectre_v2_enabled = mode; |
| 1831 | pr_info("%s\n", spectre_v2_strings[mode]); | 1982 | pr_info("%s\n", spectre_v2_strings[mode]); |
| 1832 | 1983 | ||
| 1833 | /* | 1984 | spectre_v2_select_rsb_mitigation(mode); |
| 1834 | * If Spectre v2 protection has been enabled, fill the RSB during a | ||
| 1835 | * context switch. In general there are two types of RSB attacks | ||
| 1836 | * across context switches, for which the CALLs/RETs may be unbalanced. | ||
| 1837 | * | ||
| 1838 | * 1) RSB underflow | ||
| 1839 | * | ||
| 1840 | * Some Intel parts have "bottomless RSB". When the RSB is empty, | ||
| 1841 | * speculated return targets may come from the branch predictor, | ||
| 1842 | * which could have a user-poisoned BTB or BHB entry. | ||
| 1843 | * | ||
| 1844 | * AMD has it even worse: *all* returns are speculated from the BTB, | ||
| 1845 | * regardless of the state of the RSB. | ||
| 1846 | * | ||
| 1847 | * When IBRS or eIBRS is enabled, the "user -> kernel" attack | ||
| 1848 | * scenario is mitigated by the IBRS branch prediction isolation | ||
| 1849 | * properties, so the RSB buffer filling wouldn't be necessary to | ||
| 1850 | * protect against this type of attack. | ||
| 1851 | * | ||
| 1852 | * The "user -> user" attack scenario is mitigated by RSB filling. | ||
| 1853 | * | ||
| 1854 | * 2) Poisoned RSB entry | ||
| 1855 | * | ||
| 1856 | * If the 'next' in-kernel return stack is shorter than 'prev', | ||
| 1857 | * 'next' could be tricked into speculating with a user-poisoned RSB | ||
| 1858 | * entry. | ||
| 1859 | * | ||
| 1860 | * The "user -> kernel" attack scenario is mitigated by SMEP and | ||
| 1861 | * eIBRS. | ||
| 1862 | * | ||
| 1863 | * The "user -> user" scenario, also known as SpectreBHB, requires | ||
| 1864 | * RSB clearing. | ||
| 1865 | * | ||
| 1866 | * So to mitigate all cases, unconditionally fill RSB on context | ||
| 1867 | * switches. | ||
| 1868 | * | ||
| 1869 | * FIXME: Is this pointless for retbleed-affected AMD? | ||
| 1870 | */ | ||
| 1871 | setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); | ||
| 1872 | pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); | ||
| 1873 | |||
| 1874 | spectre_v2_determine_rsb_fill_type_at_vmexit(mode); | ||
| 1875 | 1985 | ||
| 1876 | /* | 1986 | /* |
| 1877 | * Retpoline protects the kernel, but doesn't protect firmware. IBRS | 1987 | * Retpoline protects the kernel, but doesn't protect firmware. IBRS |
| @@ -2646,10 +2756,10 @@ static void __init srso_select_mitigation(void) · 768 unmodified lines | |||
| 2646 | 2756 | ||
| 2647 | if (boot_cpu_data.x86 == 0x19) { | 2757 | if (boot_cpu_data.x86 == 0x19) { |
| 2648 | setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS); | 2758 | setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS); |
| 2649 | x86_return_thunk = srso_alias_return_thunk; | 2759 | set_return_thunk(srso_alias_return_thunk); |
| 2650 | } else { | 2760 | } else { |
| 2651 | setup_force_cpu_cap(X86_FEATURE_SRSO); | 2761 | setup_force_cpu_cap(X86_FEATURE_SRSO); |
| 2652 | x86_return_thunk = srso_return_thunk; | 2762 | set_return_thunk(srso_return_thunk); |
| 2653 | } | 2763 | } |
| 2654 | if (has_microcode) | 2764 | if (has_microcode) |
| 2655 | srso_mitigation = SRSO_MITIGATION_SAFE_RET; | 2765 | srso_mitigation = SRSO_MITIGATION_SAFE_RET; |
| @@ -2676,7 +2786,7 @@ static void __init srso_select_mitigation(void) · 20 unmodified lines | |||
| 2676 | setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | 2786 | setup_clear_cpu_cap(X86_FEATURE_RETHUNK); |
| 2677 | 2787 | ||
| 2678 | /* | 2788 | /* |
| 2679 | * There is no need for RSB filling: entry_ibpb() ensures | 2789 | * There is no need for RSB filling: write_ibpb() ensures |
| 2680 | * all predictions, including the RSB, are invalidated, | 2790 | * all predictions, including the RSB, are invalidated, |
| 2681 | * regardless of IBPB implementation. | 2791 | * regardless of IBPB implementation. |
| 2682 | */ | 2792 | */ |
| @@ -2701,7 +2811,7 @@ ibpb_on_vmexit: · 18 unmodified lines | |||
| 2701 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; | 2811 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; |
| 2702 | 2812 | ||
| 2703 | /* | 2813 | /* |
| 2704 | * There is no need for RSB filling: entry_ibpb() ensures | 2814 | * There is no need for RSB filling: write_ibpb() ensures |
| 2705 | * all predictions, including the RSB, are invalidated, | 2815 | * all predictions, including the RSB, are invalidated, |
| 2706 | * regardless of IBPB implementation. | 2816 | * regardless of IBPB implementation. |
| 2707 | */ | 2817 | */ |
| @@ -2839,6 +2949,11 @@ static ssize_t rfds_show_state(char *buf) · 131 unmodified lines | |||
| 2839 | return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]); | 2949 | return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]); |
| 2840 | } | 2950 | } |
| 2841 | 2951 | ||
| 2952 | static ssize_t its_show_state(char *buf) | ||
| 2953 | { | ||
| 2954 | return sysfs_emit(buf, "%s\n", its_strings[its_mitigation]); | ||
| 2955 | } | ||
| 2956 | |||
| 2842 | static char *stibp_state(void) | 2957 | static char *stibp_state(void) |
| 2843 | { | 2958 | { |
| 2844 | if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && | 2959 | if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && |
| @@ -3021,6 +3136,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr · 176 unmodified lines | |||
| 3021 | case X86_BUG_RFDS: | 3136 | case X86_BUG_RFDS: |
| 3022 | return rfds_show_state(buf); | 3137 | return rfds_show_state(buf); |
| 3023 | 3138 | ||
| 3139 | case X86_BUG_ITS: | ||
| 3140 | return its_show_state(buf); | ||
| 3141 | |||
| 3024 | default: | 3142 | default: |
| 3025 | break; | 3143 | break; |
| 3026 | } | 3144 | } |
| @@ -3100,6 +3218,11 @@ ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attrib · 73 unmodified lines | |||
| 3100 | { | 3218 | { |
| 3101 | return cpu_show_common(dev, attr, buf, X86_BUG_RFDS); | 3219 | return cpu_show_common(dev, attr, buf, X86_BUG_RFDS); |
| 3102 | } | 3220 | } |
| 3221 | |||
| 3222 | ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 3223 | { | ||
| 3224 | return cpu_show_common(dev, attr, buf, X86_BUG_ITS); | ||
| 3225 | } | ||
| 3103 | #endif | 3226 | #endif |
| 3104 | 3227 | ||
| 3105 | void __warn_thunk(void) | 3228 | void __warn_thunk(void) |
| @@ -1227,6 +1227,10 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 1226 unmodified lines | |||
| 1227 | #define GDS BIT(6) | 1227 | #define GDS BIT(6) |
| 1228 | /* CPU is affected by Register File Data Sampling */ | 1228 | /* CPU is affected by Register File Data Sampling */ |
| 1229 | #define RFDS BIT(7) | 1229 | #define RFDS BIT(7) |
| 1230 | /* CPU is affected by Indirect Target Selection */ | ||
| 1231 | #define ITS BIT(8) | ||
| 1232 | /* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */ | ||
| 1233 | #define ITS_NATIVE_ONLY BIT(9) | ||
| 1230 | 1234 | ||
| 1231 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { | 1235 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| 1232 | VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS), | 1236 | VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS), |
| @@ -1238,22 +1242,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { · 5 unmodified lines | |||
| 1238 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_G, X86_STEP_MAX, SRBDS), | 1242 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_G, X86_STEP_MAX, SRBDS), |
| 1239 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_X, X86_STEP_MAX, MMIO), | 1243 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_X, X86_STEP_MAX, MMIO), |
| 1240 | VULNBL_INTEL_STEPS(INTEL_BROADWELL, X86_STEP_MAX, SRBDS), | 1244 | VULNBL_INTEL_STEPS(INTEL_BROADWELL, X86_STEP_MAX, SRBDS), |
| 1241 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS), | 1245 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, 0x5, MMIO | RETBLEED | GDS), |
| 1246 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS), | ||
| 1242 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), | 1247 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), |
| 1243 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), | 1248 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), |
| 1244 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), | 1249 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, 0xb, MMIO | RETBLEED | GDS | SRBDS), |
| 1245 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), | 1250 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS), |
| 1251 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE, 0xc, MMIO | RETBLEED | GDS | SRBDS), | ||
| 1252 | VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS), | ||
| 1246 | VULNBL_INTEL_STEPS(INTEL_CANNONLAKE_L, X86_STEP_MAX, RETBLEED), | 1253 | VULNBL_INTEL_STEPS(INTEL_CANNONLAKE_L, X86_STEP_MAX, RETBLEED), |
| 1247 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS), | 1254 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY), |
| 1248 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS), | 1255 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY), |
| 1249 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS), | 1256 | VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY), |
| 1250 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS), | 1257 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS), |
| 1251 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED), | 1258 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED | ITS), |
| 1252 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS), | 1259 | VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS), |
| 1253 | VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS), | 1260 | VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY), |
| 1254 | VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS), | 1261 | VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY), |
| 1255 | VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED), | 1262 | VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED), |
| 1256 | VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS), | 1263 | VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY), |
| 1257 | VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS), | 1264 | VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS), |
| 1258 | VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS), | 1265 | VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS), |
| 1259 | VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS), | 1266 | VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS), |
| @@ -1318,6 +1325,32 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr) · 58 unmodified lines | |||
| 1318 | return cpu_matches(cpu_vuln_blacklist, RFDS); | 1325 | return cpu_matches(cpu_vuln_blacklist, RFDS); |
| 1319 | } | 1326 | } |
| 1320 | 1327 | ||
| 1328 | static bool __init vulnerable_to_its(u64 x86_arch_cap_msr) | ||
| 1329 | { | ||
| 1330 | /* The "immunity" bit trumps everything else: */ | ||
| 1331 | if (x86_arch_cap_msr & ARCH_CAP_ITS_NO) | ||
| 1332 | return false; | ||
| 1333 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | ||
| 1334 | return false; | ||
| 1335 | |||
| 1336 | /* None of the affected CPUs have BHI_CTRL */ | ||
| 1337 | if (boot_cpu_has(X86_FEATURE_BHI_CTRL)) | ||
| 1338 | return false; | ||
| 1339 | |||
| 1340 | /* | ||
| 1341 | * If a VMM did not expose ITS_NO, assume that a guest could | ||
| 1342 | * be running on a vulnerable hardware or may migrate to such | ||
| 1343 | * hardware. | ||
| 1344 | */ | ||
| 1345 | if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) | ||
| 1346 | return true; | ||
| 1347 | |||
| 1348 | if (cpu_matches(cpu_vuln_blacklist, ITS)) | ||
| 1349 | return true; | ||
| 1350 | |||
| 1351 | return false; | ||
| 1352 | } | ||
| 1353 | |||
| 1321 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | 1354 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| 1322 | { | 1355 | { |
| 1323 | u64 x86_arch_cap_msr = x86_read_arch_cap_msr(); | 1356 | u64 x86_arch_cap_msr = x86_read_arch_cap_msr(); |
| @@ -1439,9 +1472,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 115 unmodified lines | |||
| 1439 | if (vulnerable_to_rfds(x86_arch_cap_msr)) | 1472 | if (vulnerable_to_rfds(x86_arch_cap_msr)) |
| 1440 | setup_force_cpu_bug(X86_BUG_RFDS); | 1473 | setup_force_cpu_bug(X86_BUG_RFDS); |
| 1441 | 1474 | ||
| 1442 | /* When virtualized, eIBRS could be hidden, assume vulnerable */ | 1475 | /* |
| 1443 | if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) && | 1476 | * Intel parts with eIBRS are vulnerable to BHI attacks. Parts with |
| 1444 | !cpu_matches(cpu_vuln_whitelist, NO_BHI) && | 1477 | * BHI_NO still need to use the BHI mitigation to prevent Intra-mode |
| 1478 | * attacks. When virtualized, eIBRS could be hidden, assume vulnerable. | ||
| 1479 | */ | ||
| 1480 | if (!cpu_matches(cpu_vuln_whitelist, NO_BHI) && | ||
| 1445 | (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || | 1481 | (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || |
| 1446 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) | 1482 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1447 | setup_force_cpu_bug(X86_BUG_BHI); | 1483 | setup_force_cpu_bug(X86_BUG_BHI); |
| @@ -1449,6 +1485,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 1 unmodified line | |||
| 1449 | if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET)) | 1485 | if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET)) |
| 1450 | setup_force_cpu_bug(X86_BUG_IBPB_NO_RET); | 1486 | setup_force_cpu_bug(X86_BUG_IBPB_NO_RET); |
| 1451 | 1487 | ||
| 1488 | if (vulnerable_to_its(x86_arch_cap_msr)) { | ||
| 1489 | setup_force_cpu_bug(X86_BUG_ITS); | ||
| 1490 | if (cpu_matches(cpu_vuln_blacklist, ITS_NATIVE_ONLY)) | ||
| 1491 | setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY); | ||
| 1492 | } | ||
| 1493 | |||
| 1452 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) | 1494 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1453 | return; | 1495 | return; |
| 1454 | 1496 | ||
| @@ -199,6 +199,12 @@ static bool need_sha_check(u32 cur_rev) · 198 unmodified lines | |||
| 199 | case 0xa70c0: return cur_rev <= 0xa70C009; break; | 199 | case 0xa70c0: return cur_rev <= 0xa70C009; break; |
| 200 | case 0xaa001: return cur_rev <= 0xaa00116; break; | 200 | case 0xaa001: return cur_rev <= 0xaa00116; break; |
| 201 | case 0xaa002: return cur_rev <= 0xaa00218; break; | 201 | case 0xaa002: return cur_rev <= 0xaa00218; break; |
| 202 | case 0xb0021: return cur_rev <= 0xb002146; break; | ||
| 203 | case 0xb1010: return cur_rev <= 0xb101046; break; | ||
| 204 | case 0xb2040: return cur_rev <= 0xb204031; break; | ||
| 205 | case 0xb4040: return cur_rev <= 0xb404031; break; | ||
| 206 | case 0xb6000: return cur_rev <= 0xb600031; break; | ||
| 207 | case 0xb7000: return cur_rev <= 0xb700031; break; | ||
| 202 | default: break; | 208 | default: break; |
| 203 | } | 209 | } |
| 204 | 210 | ||
| @@ -214,8 +220,7 @@ static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsi · 9 unmodified lines | |||
| 214 | struct sha256_state s; | 220 | struct sha256_state s; |
| 215 | int i; | 221 | int i; |
| 216 | 222 | ||
| 217 | if (x86_family(bsp_cpuid_1_eax) < 0x17 || | 223 | if (x86_family(bsp_cpuid_1_eax) < 0x17) |
| 218 | x86_family(bsp_cpuid_1_eax) > 0x19) | ||
| 219 | return true; | 224 | return true; |
| 220 | 225 | ||
| 221 | if (!need_sha_check(cur_rev)) | 226 | if (!need_sha_check(cur_rev)) |
| @@ -1093,15 +1098,17 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz · 871 unmodified lines | |||
| 1093 | 1098 | ||
| 1094 | static int __init save_microcode_in_initrd(void) | 1099 | static int __init save_microcode_in_initrd(void) |
| 1095 | { | 1100 | { |
| 1096 | unsigned int cpuid_1_eax = native_cpuid_eax(1); | ||
| 1097 | struct cpuinfo_x86 *c = &boot_cpu_data; | 1101 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| 1098 | struct cont_desc desc = { 0 }; | 1102 | struct cont_desc desc = { 0 }; |
| 1103 | unsigned int cpuid_1_eax; | ||
| 1099 | enum ucode_state ret; | 1104 | enum ucode_state ret; |
| 1100 | struct cpio_data cp; | 1105 | struct cpio_data cp; |
| 1101 | 1106 | ||
| 1102 | if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) | 1107 | if (microcode_loader_disabled() || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) |
| 1103 | return 0; | 1108 | return 0; |
| 1104 | 1109 | ||
| 1110 | cpuid_1_eax = native_cpuid_eax(1); | ||
| 1111 | |||
| 1105 | if (!find_blobs_in_containers(&cp)) | 1112 | if (!find_blobs_in_containers(&cp)) |
| 1106 | return -EINVAL; | 1113 | return -EINVAL; |
| 1107 | 1114 | ||
| @@ -41,8 +41,8 @@ · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | #include "internal.h" | 42 | #include "internal.h" |
| 43 | 43 | ||
| 44 | static struct microcode_ops *microcode_ops; | 44 | static struct microcode_ops *microcode_ops; |
| 45 | bool dis_ucode_ldr = true; | 45 | static bool dis_ucode_ldr = false; |
| 46 | 46 | ||
| 47 | bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); | 47 | bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); |
| 48 | module_param(force_minrev, bool, S_IRUSR | S_IWUSR); | 48 | module_param(force_minrev, bool, S_IRUSR | S_IWUSR); |
| @@ -84,6 +84,9 @@ static bool amd_check_current_patch_level(void) · 35 unmodified lines | |||
| 84 | u32 lvl, dummy, i; | 84 | u32 lvl, dummy, i; |
| 85 | u32 *levels; | 85 | u32 *levels; |
| 86 | 86 | ||
| 87 | if (x86_cpuid_vendor() != X86_VENDOR_AMD) | ||
| 88 | return false; | ||
| 89 | |||
| 87 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy); | 90 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy); |
| 88 | 91 | ||
| 89 | levels = final_levels; | 92 | levels = final_levels; |
| @@ -95,27 +98,29 @@ static bool amd_check_current_patch_level(void) · 5 unmodified lines | |||
| 95 | return false; | 98 | return false; |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | static bool __init check_loader_disabled_bsp(void) | 101 | bool __init microcode_loader_disabled(void) |
| 99 | { | 102 | { |
| 100 | static const char *__dis_opt_str = "dis_ucode_ldr"; | 103 | if (dis_ucode_ldr) |
| 101 | const char *cmdline = boot_command_line; | 104 | return true; |
| 102 | const char *option = __dis_opt_str; | ||
| 103 | 105 | ||
| 104 | /* | 106 | /* |
| 105 | * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not | 107 | * Disable when: |
| 106 | * completely accurate as xen pv guests don't see that CPUID bit set but | 108 | * |
| 107 | * that's good enough as they don't land on the BSP path anyway. | 109 | * 1) The CPU does not support CPUID. |
| 110 | * | ||
| 111 | * 2) Bit 31 in CPUID[1]:ECX is clear | ||
| 112 | * The bit is reserved for hypervisor use. This is still not | ||
| 113 | * completely accurate as XEN PV guests don't see that CPUID bit | ||
| 114 | * set, but that's good enough as they don't land on the BSP | ||
| 115 | * path anyway. | ||
| 116 | * | ||
| 117 | * 3) Certain AMD patch levels are not allowed to be | ||
| 118 | * overwritten. | ||
| 108 | */ | 119 | */ |
| 109 | if (native_cpuid_ecx(1) & BIT(31)) | 120 | if (!have_cpuid_p() || |
| 110 | return true; | 121 | native_cpuid_ecx(1) & BIT(31) || |
| 111 | 122 | amd_check_current_patch_level()) | |
| 112 | if (x86_cpuid_vendor() == X86_VENDOR_AMD) { | 123 | dis_ucode_ldr = true; |
| 113 | if (amd_check_current_patch_level()) | ||
| 114 | return true; | ||
| 115 | } | ||
| 116 | |||
| 117 | if (cmdline_find_option_bool(cmdline, option) <= 0) | ||
| 118 | dis_ucode_ldr = false; | ||
| 119 | 124 | ||
| 120 | return dis_ucode_ldr; | 125 | return dis_ucode_ldr; |
| 121 | } | 126 | } |
| @@ -125,7 +130,10 @@ void __init load_ucode_bsp(void) · 3 unmodified lines | |||
| 125 | unsigned int cpuid_1_eax; | 130 | unsigned int cpuid_1_eax; |
| 126 | bool intel = true; | 131 | bool intel = true; |
| 127 | 132 | ||
| 128 | if (!have_cpuid_p()) | 133 | if (cmdline_find_option_bool(boot_command_line, "dis_ucode_ldr") > 0) |
| 134 | dis_ucode_ldr = true; | ||
| 135 | |||
| 136 | if (microcode_loader_disabled()) | ||
| 129 | return; | 137 | return; |
| 130 | 138 | ||
| 131 | cpuid_1_eax = native_cpuid_eax(1); | 139 | cpuid_1_eax = native_cpuid_eax(1); |
| @@ -146,9 +154,6 @@ void __init load_ucode_bsp(void) · 14 unmodified lines | |||
| 146 | return; | 154 | return; |
| 147 | } | 155 | } |
| 148 | 156 | ||
| 149 | if (check_loader_disabled_bsp()) | ||
| 150 | return; | ||
| 151 | |||
| 152 | if (intel) | 157 | if (intel) |
| 153 | load_ucode_intel_bsp(&early_data); | 158 | load_ucode_intel_bsp(&early_data); |
| 154 | else | 159 | else |
| @@ -159,6 +164,11 @@ void load_ucode_ap(void) · 4 unmodified lines | |||
| 159 | { | 164 | { |
| 160 | unsigned int cpuid_1_eax; | 165 | unsigned int cpuid_1_eax; |
| 161 | 166 | ||
| 167 | /* | ||
| 168 | * Can't use microcode_loader_disabled() here - .init section | ||
| 169 | * hell. It doesn't have to either - the BSP variant must've | ||
| 170 | * parsed cmdline already anyway. | ||
| 171 | */ | ||
| 162 | if (dis_ucode_ldr) | 172 | if (dis_ucode_ldr) |
| 163 | return; | 173 | return; |
| 164 | 174 | ||
| @@ -810,7 +820,7 @@ static int __init microcode_init(void) · 645 unmodified lines | |||
| 810 | struct cpuinfo_x86 *c = &boot_cpu_data; | 820 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| 811 | int error; | 821 | int error; |
| 812 | 822 | ||
| 813 | if (dis_ucode_ldr) | 823 | if (microcode_loader_disabled()) |
| 814 | return -EINVAL; | 824 | return -EINVAL; |
| 815 | 825 | ||
| 816 | if (c->x86_vendor == X86_VENDOR_INTEL) | 826 | if (c->x86_vendor == X86_VENDOR_INTEL) |
| @@ -389,7 +389,7 @@ static int __init save_builtin_microcode(void) · 388 unmodified lines | |||
| 389 | if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) | 389 | if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) |
| 390 | return 0; | 390 | return 0; |
| 391 | 391 | ||
| 392 | if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | 392 | if (microcode_loader_disabled() || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
| 393 | return 0; | 393 | return 0; |
| 394 | 394 | ||
| 395 | uci.mc = get_microcode_blob(&uci, true); | 395 | uci.mc = get_microcode_blob(&uci, true); |
| @@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_family(void) · 93 unmodified lines | |||
| 94 | return x86_family(eax); | 94 | return x86_family(eax); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | extern bool dis_ucode_ldr; | ||
| 98 | extern bool force_minrev; | 97 | extern bool force_minrev; |
| 99 | 98 | ||
| 100 | #ifdef CONFIG_CPU_SUP_AMD | 99 | #ifdef CONFIG_CPU_SUP_AMD |
| @@ -3553,6 +3553,22 @@ static void mkdir_rdt_prepare_rmid_free(struct rdtgroup *rgrp) · 3552 unmodified lines | |||
| 3553 | free_rmid(rgrp->closid, rgrp->mon.rmid); | 3553 | free_rmid(rgrp->closid, rgrp->mon.rmid); |
| 3554 | } | 3554 | } |
| 3555 | 3555 | ||
| 3556 | /* | ||
| 3557 | * We allow creating mon groups only with in a directory called "mon_groups" | ||
| 3558 | * which is present in every ctrl_mon group. Check if this is a valid | ||
| 3559 | * "mon_groups" directory. | ||
| 3560 | * | ||
| 3561 | * 1. The directory should be named "mon_groups". | ||
| 3562 | * 2. The mon group itself should "not" be named "mon_groups". | ||
| 3563 | * This makes sure "mon_groups" directory always has a ctrl_mon group | ||
| 3564 | * as parent. | ||
| 3565 | */ | ||
| 3566 | static bool is_mon_groups(struct kernfs_node *kn, const char *name) | ||
| 3567 | { | ||
| 3568 | return (!strcmp(rdt_kn_name(kn), "mon_groups") && | ||
| 3569 | strcmp(name, "mon_groups")); | ||
| 3570 | } | ||
| 3571 | |||
| 3556 | static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, | 3572 | static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, |
| 3557 | const char *name, umode_t mode, | 3573 | const char *name, umode_t mode, |
| 3558 | enum rdt_group_type rtype, struct rdtgroup **r) | 3574 | enum rdt_group_type rtype, struct rdtgroup **r) |
| @@ -3568,6 +3584,15 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, · 9 unmodified lines | |||
| 3568 | goto out_unlock; | 3584 | goto out_unlock; |
| 3569 | } | 3585 | } |
| 3570 | 3586 | ||
| 3587 | /* | ||
| 3588 | * Check that the parent directory for a monitor group is a "mon_groups" | ||
| 3589 | * directory. | ||
| 3590 | */ | ||
| 3591 | if (rtype == RDTMON_GROUP && !is_mon_groups(parent_kn, name)) { | ||
| 3592 | ret = -EPERM; | ||
| 3593 | goto out_unlock; | ||
| 3594 | } | ||
| 3595 | |||
| 3571 | if (rtype == RDTMON_GROUP && | 3596 | if (rtype == RDTMON_GROUP && |
| 3572 | (prdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP || | 3597 | (prdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP || |
| 3573 | prdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)) { | 3598 | prdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)) { |
| @@ -3751,22 +3776,6 @@ out_unlock: · 177 unmodified lines | |||
| 3751 | return ret; | 3776 | return ret; |
| 3752 | } | 3777 | } |
| 3753 | 3778 | ||
| 3754 | /* | ||
| 3755 | * We allow creating mon groups only with in a directory called "mon_groups" | ||
| 3756 | * which is present in every ctrl_mon group. Check if this is a valid | ||
| 3757 | * "mon_groups" directory. | ||
| 3758 | * | ||
| 3759 | * 1. The directory should be named "mon_groups". | ||
| 3760 | * 2. The mon group itself should "not" be named "mon_groups". | ||
| 3761 | * This makes sure "mon_groups" directory always has a ctrl_mon group | ||
| 3762 | * as parent. | ||
| 3763 | */ | ||
| 3764 | static bool is_mon_groups(struct kernfs_node *kn, const char *name) | ||
| 3765 | { | ||
| 3766 | return (!strcmp(rdt_kn_name(kn), "mon_groups") && | ||
| 3767 | strcmp(name, "mon_groups")); | ||
| 3768 | } | ||
| 3769 | |||
| 3770 | static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | 3779 | static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, |
| 3771 | umode_t mode) | 3780 | umode_t mode) |
| 3772 | { | 3781 | { |
| @@ -3782,11 +3791,8 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, · 9 unmodified lines | |||
| 3782 | if (resctrl_arch_alloc_capable() && parent_kn == rdtgroup_default.kn) | 3791 | if (resctrl_arch_alloc_capable() && parent_kn == rdtgroup_default.kn) |
| 3783 | return rdtgroup_mkdir_ctrl_mon(parent_kn, name, mode); | 3792 | return rdtgroup_mkdir_ctrl_mon(parent_kn, name, mode); |
| 3784 | 3793 | ||
| 3785 | /* | 3794 | /* Else, attempt to add a monitoring subdirectory. */ |
| 3786 | * If RDT monitoring is supported and the parent directory is a valid | 3795 | if (resctrl_arch_mon_capable()) |
| 3787 | * "mon_groups" directory, add a monitoring subdirectory. | ||
| 3788 | */ | ||
| 3789 | if (resctrl_arch_mon_capable() && is_mon_groups(parent_kn, name)) | ||
| 3790 | return rdtgroup_mkdir_mon(parent_kn, name, mode); | 3796 | return rdtgroup_mkdir_mon(parent_kn, name, mode); |
| 3791 | 3797 | ||
| 3792 | return -EPERM; | 3798 | return -EPERM; |
| @@ -753,22 +753,21 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len) · 752 unmodified lines | |||
| 753 | void __init e820__register_nosave_regions(unsigned long limit_pfn) | 753 | void __init e820__register_nosave_regions(unsigned long limit_pfn) |
| 754 | { | 754 | { |
| 755 | int i; | 755 | int i; |
| 756 | unsigned long pfn = 0; | 756 | u64 last_addr = 0; |
| 757 | 757 | ||
| 758 | for (i = 0; i < e820_table->nr_entries; i++) { | 758 | for (i = 0; i < e820_table->nr_entries; i++) { |
| 759 | struct e820_entry *entry = &e820_table->entries[i]; | 759 | struct e820_entry *entry = &e820_table->entries[i]; |
| 760 | 760 | ||
| 761 | if (pfn < PFN_UP(entry->addr)) | ||
| 762 | register_nosave_region(pfn, PFN_UP(entry->addr)); | ||
| 763 | |||
| 764 | pfn = PFN_DOWN(entry->addr + entry->size); | ||
| 765 | |||
| 766 | if (entry->type != E820_TYPE_RAM) | 761 | if (entry->type != E820_TYPE_RAM) |
| 767 | register_nosave_region(PFN_UP(entry->addr), pfn); | 762 | continue; |
| 768 | 763 | ||
| 769 | if (pfn >= limit_pfn) | 764 | if (last_addr < entry->addr) |
| 770 | break; | 765 | register_nosave_region(PFN_DOWN(last_addr), PFN_UP(entry->addr)); |
| 766 | |||
| 767 | last_addr = entry->addr + entry->size; | ||
| 771 | } | 768 | } |
| 769 | |||
| 770 | register_nosave_region(PFN_DOWN(last_addr), limit_pfn); | ||
| 772 | } | 771 | } |
| 773 | 772 | ||
| 774 | #ifdef CONFIG_ACPI | 773 | #ifdef CONFIG_ACPI |
| @@ -1300,6 +1299,14 @@ void __init e820__memblock_setup(void) · 525 unmodified lines | |||
| 1300 | memblock_add(entry->addr, entry->size); | 1299 | memblock_add(entry->addr, entry->size); |
| 1301 | } | 1300 | } |
| 1302 | 1301 | ||
| 1302 | /* | ||
| 1303 | * 32-bit systems are limited to 4BG of memory even with HIGHMEM and | ||
| 1304 | * to even less without it. | ||
| 1305 | * Discard memory after max_pfn - the actual limit detected at runtime. | ||
| 1306 | */ | ||
| 1307 | if (IS_ENABLED(CONFIG_X86_32)) | ||
| 1308 | memblock_remove(PFN_PHYS(max_pfn), -1); | ||
| 1309 | |||
| 1303 | /* Throw away partial pages: */ | 1310 | /* Throw away partial pages: */ |
| 1304 | memblock_trim_memory(PAGE_SIZE); | 1311 | memblock_trim_memory(PAGE_SIZE); |
| 1305 | 1312 | ||
| @@ -389,10 +389,10 @@ static int __init setup_early_printk(char *buf) · 388 unmodified lines | |||
| 389 | keep = (strstr(buf, "keep") != NULL); | 389 | keep = (strstr(buf, "keep") != NULL); |
| 390 | 390 | ||
| 391 | while (*buf != '\0') { | 391 | while (*buf != '\0') { |
| 392 | if (!strncmp(buf, "mmio", 4)) { | 392 | if (!strncmp(buf, "mmio32", 6)) { |
| 393 | early_mmio_serial_init(buf + 4); | 393 | buf += 6; |
| 394 | early_mmio_serial_init(buf); | ||
| 394 | early_console_register(&early_serial_console, keep); | 395 | early_console_register(&early_serial_console, keep); |
| 395 | buf += 4; | ||
| 396 | } | 396 | } |
| 397 | if (!strncmp(buf, "serial", 6)) { | 397 | if (!strncmp(buf, "serial", 6)) { |
| 398 | buf += 6; | 398 | buf += 6; |
| @@ -407,9 +407,9 @@ static int __init setup_early_printk(char *buf) · 8 unmodified lines | |||
| 407 | } | 407 | } |
| 408 | #ifdef CONFIG_PCI | 408 | #ifdef CONFIG_PCI |
| 409 | if (!strncmp(buf, "pciserial", 9)) { | 409 | if (!strncmp(buf, "pciserial", 9)) { |
| 410 | early_pci_serial_init(buf + 9); | 410 | buf += 9; /* Keep from match the above "pciserial" */ |
| 411 | early_pci_serial_init(buf); | ||
| 411 | early_console_register(&early_serial_console, keep); | 412 | early_console_register(&early_serial_console, keep); |
| 412 | buf += 9; /* Keep from match the above "serial" */ | ||
| 413 | } | 413 | } |
| 414 | #endif | 414 | #endif |
| 415 | if (!strncmp(buf, "vga", 3) && | 415 | if (!strncmp(buf, "vga", 3) && |
| @@ -354,7 +354,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 353 unmodified lines | |||
| 354 | goto fail; | 354 | goto fail; |
| 355 | 355 | ||
| 356 | ip = trampoline + size; | 356 | ip = trampoline + size; |
| 357 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | 357 | if (cpu_wants_rethunk_at(ip)) |
| 358 | __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE); | 358 | __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE); |
| 359 | else | 359 | else |
| 360 | memcpy(ip, retq, sizeof(retq)); | 360 | memcpy(ip, retq, sizeof(retq)); |
| @@ -145,10 +145,6 @@ void __init __no_stack_protector mk_early_pgtbl_32(void) · 144 unmodified lines | |||
| 145 | *ptr = (unsigned long)ptep + PAGE_OFFSET; | 145 | *ptr = (unsigned long)ptep + PAGE_OFFSET; |
| 146 | 146 | ||
| 147 | #ifdef CONFIG_MICROCODE_INITRD32 | 147 | #ifdef CONFIG_MICROCODE_INITRD32 |
| 148 | /* Running on a hypervisor? */ | ||
| 149 | if (native_cpuid_ecx(1) & BIT(31)) | ||
| 150 | return; | ||
| 151 | |||
| 152 | params = (struct boot_params *)__pa_nodebug(&boot_params); | 148 | params = (struct boot_params *)__pa_nodebug(&boot_params); |
| 153 | if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image) | 149 | if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image) |
| 154 | return; | 150 | return; |
| @@ -46,7 +46,8 @@ bool __init pit_timer_init(void) · 45 unmodified lines | |||
| 46 | * VMMs otherwise steal CPU time just to pointlessly waggle | 46 | * VMMs otherwise steal CPU time just to pointlessly waggle |
| 47 | * the (masked) IRQ. | 47 | * the (masked) IRQ. |
| 48 | */ | 48 | */ |
| 49 | clockevent_i8253_disable(); | 49 | scoped_guard(irq) |
| 50 | clockevent_i8253_disable(); | ||
| 50 | return false; | 51 | return false; |
| 51 | } | 52 | } |
| 52 | clockevent_i8253_init(true); | 53 | clockevent_i8253_init(true); |
| @@ -42,7 +42,7 @@ static void load_segments(void) · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | static void machine_kexec_free_page_tables(struct kimage *image) | 43 | static void machine_kexec_free_page_tables(struct kimage *image) |
| 44 | { | 44 | { |
| 45 | free_pages((unsigned long)image->arch.pgd, PGD_ALLOCATION_ORDER); | 45 | free_pages((unsigned long)image->arch.pgd, pgd_allocation_order()); |
| 46 | image->arch.pgd = NULL; | 46 | image->arch.pgd = NULL; |
| 47 | #ifdef CONFIG_X86_PAE | 47 | #ifdef CONFIG_X86_PAE |
| 48 | free_page((unsigned long)image->arch.pmd0); | 48 | free_page((unsigned long)image->arch.pmd0); |
| @@ -59,7 +59,7 @@ static void machine_kexec_free_page_tables(struct kimage *image) · 10 unmodified lines | |||
| 59 | static int machine_kexec_alloc_page_tables(struct kimage *image) | 59 | static int machine_kexec_alloc_page_tables(struct kimage *image) |
| 60 | { | 60 | { |
| 61 | image->arch.pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | 61 | image->arch.pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, |
| 62 | PGD_ALLOCATION_ORDER); | 62 | pgd_allocation_order()); |
| 63 | #ifdef CONFIG_X86_PAE | 63 | #ifdef CONFIG_X86_PAE |
| 64 | image->arch.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); | 64 | image->arch.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); |
| 65 | image->arch.pmd1 = (pmd_t *)get_zeroed_page(GFP_KERNEL); | 65 | image->arch.pmd1 = (pmd_t *)get_zeroed_page(GFP_KERNEL); |
| @@ -266,6 +266,8 @@ int module_finalize(const Elf_Ehdr *hdr, · 265 unmodified lines | |||
| 266 | ibt_endbr = s; | 266 | ibt_endbr = s; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | its_init_mod(me); | ||
| 270 | |||
| 269 | if (retpolines || cfi) { | 271 | if (retpolines || cfi) { |
| 270 | void *rseg = NULL, *cseg = NULL; | 272 | void *rseg = NULL, *cseg = NULL; |
| 271 | unsigned int rsize = 0, csize = 0; | 273 | unsigned int rsize = 0, csize = 0; |
| @@ -286,6 +288,9 @@ int module_finalize(const Elf_Ehdr *hdr, · 14 unmodified lines | |||
| 286 | void *rseg = (void *)retpolines->sh_addr; | 288 | void *rseg = (void *)retpolines->sh_addr; |
| 287 | apply_retpolines(rseg, rseg + retpolines->sh_size); | 289 | apply_retpolines(rseg, rseg + retpolines->sh_size); |
| 288 | } | 290 | } |
| 291 | |||
| 292 | its_fini_mod(me); | ||
| 293 | |||
| 289 | if (returns) { | 294 | if (returns) { |
| 290 | void *rseg = (void *)returns->sh_addr; | 295 | void *rseg = (void *)returns->sh_addr; |
| 291 | apply_returns(rseg, rseg + returns->sh_size); | 296 | apply_returns(rseg, rseg + returns->sh_size); |
| @@ -326,4 +331,5 @@ int module_finalize(const Elf_Ehdr *hdr, · 34 unmodified lines | |||
| 326 | void module_arch_cleanup(struct module *mod) | 331 | void module_arch_cleanup(struct module *mod) |
| 327 | { | 332 | { |
| 328 | alternatives_smp_module_del(mod); | 333 | alternatives_smp_module_del(mod); |
| 334 | its_free_mod(mod); | ||
| 329 | } | 335 | } |
| @@ -81,7 +81,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, · 80 unmodified lines | |||
| 81 | break; | 81 | break; |
| 82 | 82 | ||
| 83 | case RET: | 83 | case RET: |
| 84 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | 84 | if (cpu_wants_rethunk_at(insn)) |
| 85 | code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk); | 85 | code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk); |
| 86 | else | 86 | else |
| 87 | code = &retinsn; | 87 | code = &retinsn; |
| @@ -90,7 +90,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, · 2 unmodified lines | |||
| 90 | case JCC: | 90 | case JCC: |
| 91 | if (!func) { | 91 | if (!func) { |
| 92 | func = __static_call_return; | 92 | func = __static_call_return; |
| 93 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | 93 | if (cpu_wants_rethunk()) |
| 94 | func = x86_return_thunk; | 94 | func = x86_return_thunk; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| @@ -466,10 +466,18 @@ SECTIONS · 465 unmodified lines | |||
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | /* | 468 | /* |
| 469 | * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility: | 469 | * COMPILE_TEST kernels can be large - CONFIG_KASAN, for example, can cause |
| 470 | * this. Let's assume that nobody will be running a COMPILE_TEST kernel and | ||
| 471 | * let's assert that fuller build coverage is more valuable than being able to | ||
| 472 | * run a COMPILE_TEST kernel. | ||
| 473 | */ | ||
| 474 | #ifndef CONFIG_COMPILE_TEST | ||
| 475 | /* | ||
| 476 | * The ASSERT() sync to . is intentional, for binutils 2.14 compatibility: | ||
| 470 | */ | 477 | */ |
| 471 | . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), | 478 | . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), |
| 472 | "kernel image bigger than KERNEL_IMAGE_SIZE"); | 479 | "kernel image bigger than KERNEL_IMAGE_SIZE"); |
| 480 | #endif | ||
| 473 | 481 | ||
| 474 | /* needed for Clang - see arch/x86/entry/entry.S */ | 482 | /* needed for Clang - see arch/x86/entry/entry.S */ |
| 475 | PROVIDE(__ref_stack_chk_guard = __stack_chk_guard); | 483 | PROVIDE(__ref_stack_chk_guard = __stack_chk_guard); |
| @@ -497,6 +505,16 @@ PROVIDE(__ref_stack_chk_guard = __stack_chk_guard); · 21 unmodified lines | |||
| 497 | "SRSO function pair won't alias"); | 505 | "SRSO function pair won't alias"); |
| 498 | #endif | 506 | #endif |
| 499 | 507 | ||
| 508 | #if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B) | ||
| 509 | . = ASSERT(__x86_indirect_its_thunk_rax & 0x20, "__x86_indirect_thunk_rax not in second half of cacheline"); | ||
| 510 | . = ASSERT(((__x86_indirect_its_thunk_rcx - __x86_indirect_its_thunk_rax) % 64) == 0, "Indirect thunks are not cacheline apart"); | ||
| 511 | . = ASSERT(__x86_indirect_its_thunk_array == __x86_indirect_its_thunk_rax, "Gap in ITS thunk array"); | ||
| 512 | #endif | ||
| 513 | |||
| 514 | #if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B) | ||
| 515 | . = ASSERT(its_return_thunk & 0x20, "its_return_thunk not in second half of cacheline"); | ||
| 516 | #endif | ||
| 517 | |||
| 500 | #endif /* CONFIG_X86_64 */ | 518 | #endif /* CONFIG_X86_64 */ |
| 501 | 519 | ||
| 502 | /* | 520 | /* |
| @@ -1427,8 +1427,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 1426 unmodified lines | |||
| 1427 | } | 1427 | } |
| 1428 | break; | 1428 | break; |
| 1429 | case 0xa: { /* Architectural Performance Monitoring */ | 1429 | case 0xa: { /* Architectural Performance Monitoring */ |
| 1430 | union cpuid10_eax eax; | 1430 | union cpuid10_eax eax = { }; |
| 1431 | union cpuid10_edx edx; | 1431 | union cpuid10_edx edx = { }; |
| 1432 | 1432 | ||
| 1433 | if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) { | 1433 | if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) { |
| 1434 | entry->eax = entry->ebx = entry->ecx = entry->edx = 0; | 1434 | entry->eax = entry->ebx = entry->ecx = entry->edx = 0; |
| @@ -1444,8 +1444,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 9 unmodified lines | |||
| 1444 | 1444 | ||
| 1445 | if (kvm_pmu_cap.version) | 1445 | if (kvm_pmu_cap.version) |
| 1446 | edx.split.anythread_deprecated = 1; | 1446 | edx.split.anythread_deprecated = 1; |
| 1447 | edx.split.reserved1 = 0; | ||
| 1448 | edx.split.reserved2 = 0; | ||
| 1449 | 1447 | ||
| 1450 | entry->eax = eax.full; | 1448 | entry->eax = eax.full; |
| 1451 | entry->ebx = kvm_pmu_cap.events_mask; | 1449 | entry->ebx = kvm_pmu_cap.events_mask; |
| @@ -1763,7 +1761,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 311 unmodified lines | |||
| 1763 | break; | 1761 | break; |
| 1764 | /* AMD Extended Performance Monitoring and Debug */ | 1762 | /* AMD Extended Performance Monitoring and Debug */ |
| 1765 | case 0x80000022: { | 1763 | case 0x80000022: { |
| 1766 | union cpuid_0x80000022_ebx ebx; | 1764 | union cpuid_0x80000022_ebx ebx = { }; |
| 1767 | 1765 | ||
| 1768 | entry->ecx = entry->edx = 0; | 1766 | entry->ecx = entry->edx = 0; |
| 1769 | if (!enable_pmu || !kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) { | 1767 | if (!enable_pmu || !kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) { |
| @@ -104,6 +104,9 @@ void kvm_mmu_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, · 103 unmodified lines | |||
| 104 | 104 | ||
| 105 | static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu) | 105 | static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu) |
| 106 | { | 106 | { |
| 107 | if (kvm_check_request(KVM_REQ_MMU_FREE_OBSOLETE_ROOTS, vcpu)) | ||
| 108 | kvm_mmu_free_obsolete_roots(vcpu); | ||
| 109 | |||
| 107 | /* | 110 | /* |
| 108 | * Checking root.hpa is sufficient even when KVM has mirror root. | 111 | * Checking root.hpa is sufficient even when KVM has mirror root. |
| 109 | * We can have either: | 112 | * We can have either: |
| @@ -5974,6 +5974,7 @@ void kvm_mmu_free_obsolete_roots(struct kvm_vcpu *vcpu) · 5973 unmodified lines | |||
| 5974 | __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.root_mmu); | 5974 | __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.root_mmu); |
| 5975 | __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.guest_mmu); | 5975 | __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.guest_mmu); |
| 5976 | } | 5976 | } |
| 5977 | EXPORT_SYMBOL_GPL(kvm_mmu_free_obsolete_roots); | ||
| 5977 | 5978 | ||
| 5978 | static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, | 5979 | static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, |
| 5979 | int *bytes) | 5980 | int *bytes) |
| @@ -7669,9 +7670,30 @@ void kvm_mmu_pre_destroy_vm(struct kvm *kvm) · 1689 unmodified lines | |||
| 7669 | } | 7670 | } |
| 7670 | 7671 | ||
| 7671 | #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES | 7672 | #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES |
| 7673 | static bool hugepage_test_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7674 | int level) | ||
| 7675 | { | ||
| 7676 | return lpage_info_slot(gfn, slot, level)->disallow_lpage & KVM_LPAGE_MIXED_FLAG; | ||
| 7677 | } | ||
| 7678 | |||
| 7679 | static void hugepage_clear_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7680 | int level) | ||
| 7681 | { | ||
| 7682 | lpage_info_slot(gfn, slot, level)->disallow_lpage &= ~KVM_LPAGE_MIXED_FLAG; | ||
| 7683 | } | ||
| 7684 | |||
| 7685 | static void hugepage_set_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7686 | int level) | ||
| 7687 | { | ||
| 7688 | lpage_info_slot(gfn, slot, level)->disallow_lpage |= KVM_LPAGE_MIXED_FLAG; | ||
| 7689 | } | ||
| 7690 | |||
| 7672 | bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, | 7691 | bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, |
| 7673 | struct kvm_gfn_range *range) | 7692 | struct kvm_gfn_range *range) |
| 7674 | { | 7693 | { |
| 7694 | struct kvm_memory_slot *slot = range->slot; | ||
| 7695 | int level; | ||
| 7696 | |||
| 7675 | /* | 7697 | /* |
| 7676 | * Zap SPTEs even if the slot can't be mapped PRIVATE. KVM x86 only | 7698 | * Zap SPTEs even if the slot can't be mapped PRIVATE. KVM x86 only |
| 7677 | * supports KVM_MEMORY_ATTRIBUTE_PRIVATE, and so it *seems* like KVM | 7699 | * supports KVM_MEMORY_ATTRIBUTE_PRIVATE, and so it *seems* like KVM |
| @@ -7686,6 +7708,38 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, · 8 unmodified lines | |||
| 7686 | if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) | 7708 | if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) |
| 7687 | return false; | 7709 | return false; |
| 7688 | 7710 | ||
| 7711 | if (WARN_ON_ONCE(range->end <= range->start)) | ||
| 7712 | return false; | ||
| 7713 | |||
| 7714 | /* | ||
| 7715 | * If the head and tail pages of the range currently allow a hugepage, | ||
| 7716 | * i.e. reside fully in the slot and don't have mixed attributes, then | ||
| 7717 | * add each corresponding hugepage range to the ongoing invalidation, | ||
| 7718 | * e.g. to prevent KVM from creating a hugepage in response to a fault | ||
| 7719 | * for a gfn whose attributes aren't changing. Note, only the range | ||
| 7720 | * of gfns whose attributes are being modified needs to be explicitly | ||
| 7721 | * unmapped, as that will unmap any existing hugepages. | ||
| 7722 | */ | ||
| 7723 | for (level = PG_LEVEL_2M; level <= KVM_MAX_HUGEPAGE_LEVEL; level++) { | ||
| 7724 | gfn_t start = gfn_round_for_level(range->start, level); | ||
| 7725 | gfn_t end = gfn_round_for_level(range->end - 1, level); | ||
| 7726 | gfn_t nr_pages = KVM_PAGES_PER_HPAGE(level); | ||
| 7727 | |||
| 7728 | if ((start != range->start || start + nr_pages > range->end) && | ||
| 7729 | start >= slot->base_gfn && | ||
| 7730 | start + nr_pages <= slot->base_gfn + slot->npages && | ||
| 7731 | !hugepage_test_mixed(slot, start, level)) | ||
| 7732 | kvm_mmu_invalidate_range_add(kvm, start, start + nr_pages); | ||
| 7733 | |||
| 7734 | if (end == start) | ||
| 7735 | continue; | ||
| 7736 | |||
| 7737 | if ((end + nr_pages) > range->end && | ||
| 7738 | (end + nr_pages) <= (slot->base_gfn + slot->npages) && | ||
| 7739 | !hugepage_test_mixed(slot, end, level)) | ||
| 7740 | kvm_mmu_invalidate_range_add(kvm, end, end + nr_pages); | ||
| 7741 | } | ||
| 7742 | |||
| 7689 | /* Unmap the old attribute page. */ | 7743 | /* Unmap the old attribute page. */ |
| 7690 | if (range->arg.attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE) | 7744 | if (range->arg.attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE) |
| 7691 | range->attr_filter = KVM_FILTER_SHARED; | 7745 | range->attr_filter = KVM_FILTER_SHARED; |
| @@ -7695,23 +7749,7 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, · 3 unmodified lines | |||
| 7695 | return kvm_unmap_gfn_range(kvm, range); | 7749 | return kvm_unmap_gfn_range(kvm, range); |
| 7696 | } | 7750 | } |
| 7697 | 7751 | ||
| 7698 | static bool hugepage_test_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7699 | int level) | ||
| 7700 | { | ||
| 7701 | return lpage_info_slot(gfn, slot, level)->disallow_lpage & KVM_LPAGE_MIXED_FLAG; | ||
| 7702 | } | ||
| 7703 | |||
| 7704 | static void hugepage_clear_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7705 | int level) | ||
| 7706 | { | ||
| 7707 | lpage_info_slot(gfn, slot, level)->disallow_lpage &= ~KVM_LPAGE_MIXED_FLAG; | ||
| 7708 | } | ||
| 7709 | 7752 | ||
| 7710 | static void hugepage_set_mixed(struct kvm_memory_slot *slot, gfn_t gfn, | ||
| 7711 | int level) | ||
| 7712 | { | ||
| 7713 | lpage_info_slot(gfn, slot, level)->disallow_lpage |= KVM_LPAGE_MIXED_FLAG; | ||
| 7714 | } | ||
| 7715 | 7753 | ||
| 7716 | static bool hugepage_has_attrs(struct kvm *kvm, struct kvm_memory_slot *slot, | 7754 | static bool hugepage_has_attrs(struct kvm *kvm, struct kvm_memory_slot *slot, |
| 7717 | gfn_t gfn, int level, unsigned long attrs) | 7755 | gfn_t gfn, int level, unsigned long attrs) |
| @@ -40,7 +40,9 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 39 unmodified lines | |||
| 40 | kvm_tdp_mmu_invalidate_roots(kvm, KVM_VALID_ROOTS); | 40 | kvm_tdp_mmu_invalidate_roots(kvm, KVM_VALID_ROOTS); |
| 41 | kvm_tdp_mmu_zap_invalidated_roots(kvm, false); | 41 | kvm_tdp_mmu_zap_invalidated_roots(kvm, false); |
| 42 | 42 | ||
| 43 | WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); | 43 | #ifdef CONFIG_KVM_PROVE_MMU |
| 44 | KVM_MMU_WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); | ||
| 45 | #endif | ||
| 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); | 46 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); |
| 45 | 47 | ||
| 46 | /* | 48 | /* |
| @@ -325,13 +327,17 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, · 278 unmodified lines | |||
| 325 | static void tdp_account_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) | 327 | static void tdp_account_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 326 | { | 328 | { |
| 327 | kvm_account_pgtable_pages((void *)sp->spt, +1); | 329 | kvm_account_pgtable_pages((void *)sp->spt, +1); |
| 330 | #ifdef CONFIG_KVM_PROVE_MMU | ||
| 328 | atomic64_inc(&kvm->arch.tdp_mmu_pages); | 331 | atomic64_inc(&kvm->arch.tdp_mmu_pages); |
| 332 | #endif | ||
| 329 | } | 333 | } |
| 330 | 334 | ||
| 331 | static void tdp_unaccount_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) | 335 | static void tdp_unaccount_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 332 | { | 336 | { |
| 333 | kvm_account_pgtable_pages((void *)sp->spt, -1); | 337 | kvm_account_pgtable_pages((void *)sp->spt, -1); |
| 338 | #ifdef CONFIG_KVM_PROVE_MMU | ||
| 334 | atomic64_dec(&kvm->arch.tdp_mmu_pages); | 339 | atomic64_dec(&kvm->arch.tdp_mmu_pages); |
| 340 | #endif | ||
| 335 | } | 341 | } |
| 336 | 342 | ||
| 337 | /** | 343 | /** |
| @@ -131,6 +131,7 @@ void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm) · 130 unmodified lines | |||
| 131 | 131 | ||
| 132 | kvm_mmu_reset_context(vcpu); | 132 | kvm_mmu_reset_context(vcpu); |
| 133 | } | 133 | } |
| 134 | EXPORT_SYMBOL_GPL(kvm_smm_changed); | ||
| 134 | 135 | ||
| 135 | void process_smi(struct kvm_vcpu *vcpu) | 136 | void process_smi(struct kvm_vcpu *vcpu) |
| 136 | { | 137 | { |
| @@ -796,12 +796,15 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi) · 795 unmodified lines | |||
| 796 | struct amd_svm_iommu_ir *ir; | 796 | struct amd_svm_iommu_ir *ir; |
| 797 | u64 entry; | 797 | u64 entry; |
| 798 | 798 | ||
| 799 | if (WARN_ON_ONCE(!pi->ir_data)) | ||
| 800 | return -EINVAL; | ||
| 801 | |||
| 799 | /** | 802 | /** |
| 800 | * In some cases, the existing irte is updated and re-set, | 803 | * In some cases, the existing irte is updated and re-set, |
| 801 | * so we need to check here if it's already been * added | 804 | * so we need to check here if it's already been * added |
| 802 | * to the ir_list. | 805 | * to the ir_list. |
| 803 | */ | 806 | */ |
| 804 | if (pi->ir_data && (pi->prev_ga_tag != 0)) { | 807 | if (pi->prev_ga_tag) { |
| 805 | struct kvm *kvm = svm->vcpu.kvm; | 808 | struct kvm *kvm = svm->vcpu.kvm; |
| 806 | u32 vcpu_id = AVIC_GATAG_TO_VCPUID(pi->prev_ga_tag); | 809 | u32 vcpu_id = AVIC_GATAG_TO_VCPUID(pi->prev_ga_tag); |
| 807 | struct kvm_vcpu *prev_vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id); | 810 | struct kvm_vcpu *prev_vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id); |
| @@ -820,7 +823,7 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi) · 12 unmodified lines | |||
| 820 | * Allocating new amd_iommu_pi_data, which will get | 823 | * Allocating new amd_iommu_pi_data, which will get |
| 821 | * add to the per-vcpu ir_list. | 824 | * add to the per-vcpu ir_list. |
| 822 | */ | 825 | */ |
| 823 | ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_KERNEL_ACCOUNT); | 826 | ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_ATOMIC | __GFP_ACCOUNT); |
| 824 | if (!ir) { | 827 | if (!ir) { |
| 825 | ret = -ENOMEM; | 828 | ret = -ENOMEM; |
| 826 | goto out; | 829 | goto out; |
| @@ -896,10 +899,10 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 69 unmodified lines | |||
| 896 | { | 899 | { |
| 897 | struct kvm_kernel_irq_routing_entry *e; | 900 | struct kvm_kernel_irq_routing_entry *e; |
| 898 | struct kvm_irq_routing_table *irq_rt; | 901 | struct kvm_irq_routing_table *irq_rt; |
| 902 | bool enable_remapped_mode = true; | ||
| 899 | int idx, ret = 0; | 903 | int idx, ret = 0; |
| 900 | 904 | ||
| 901 | if (!kvm_arch_has_assigned_device(kvm) || | 905 | if (!kvm_arch_has_assigned_device(kvm) || !kvm_arch_has_irq_bypass()) |
| 902 | !irq_remapping_cap(IRQ_POSTING_CAP)) | ||
| 903 | return 0; | 906 | return 0; |
| 904 | 907 | ||
| 905 | pr_debug("SVM: %s: host_irq=%#x, guest_irq=%#x, set=%#x\n", | 908 | pr_debug("SVM: %s: host_irq=%#x, guest_irq=%#x, set=%#x\n", |
| @@ -933,6 +936,8 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 27 unmodified lines | |||
| 933 | kvm_vcpu_apicv_active(&svm->vcpu)) { | 936 | kvm_vcpu_apicv_active(&svm->vcpu)) { |
| 934 | struct amd_iommu_pi_data pi; | 937 | struct amd_iommu_pi_data pi; |
| 935 | 938 | ||
| 939 | enable_remapped_mode = false; | ||
| 940 | |||
| 936 | /* Try to enable guest_mode in IRTE */ | 941 | /* Try to enable guest_mode in IRTE */ |
| 937 | pi.base = __sme_set(page_to_phys(svm->avic_backing_page) & | 942 | pi.base = __sme_set(page_to_phys(svm->avic_backing_page) & |
| 938 | AVIC_HPA_MASK); | 943 | AVIC_HPA_MASK); |
| @@ -951,33 +956,6 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 12 unmodified lines | |||
| 951 | */ | 956 | */ |
| 952 | if (!ret && pi.is_guest_mode) | 957 | if (!ret && pi.is_guest_mode) |
| 953 | svm_ir_list_add(svm, &pi); | 958 | svm_ir_list_add(svm, &pi); |
| 954 | } else { | ||
| 955 | /* Use legacy mode in IRTE */ | ||
| 956 | struct amd_iommu_pi_data pi; | ||
| 957 | |||
| 958 | /** | ||
| 959 | * Here, pi is used to: | ||
| 960 | * - Tell IOMMU to use legacy mode for this interrupt. | ||
| 961 | * - Retrieve ga_tag of prior interrupt remapping data. | ||
| 962 | */ | ||
| 963 | pi.prev_ga_tag = 0; | ||
| 964 | pi.is_guest_mode = false; | ||
| 965 | ret = irq_set_vcpu_affinity(host_irq, &pi); | ||
| 966 | |||
| 967 | /** | ||
| 968 | * Check if the posted interrupt was previously | ||
| 969 | * setup with the guest_mode by checking if the ga_tag | ||
| 970 | * was cached. If so, we need to clean up the per-vcpu | ||
| 971 | * ir_list. | ||
| 972 | */ | ||
| 973 | if (!ret && pi.prev_ga_tag) { | ||
| 974 | int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag); | ||
| 975 | struct kvm_vcpu *vcpu; | ||
| 976 | |||
| 977 | vcpu = kvm_get_vcpu_by_id(kvm, id); | ||
| 978 | if (vcpu) | ||
| 979 | svm_ir_list_del(to_svm(vcpu), &pi); | ||
| 980 | } | ||
| 981 | } | 959 | } |
| 982 | 960 | ||
| 983 | if (!ret && svm) { | 961 | if (!ret && svm) { |
| @@ -993,6 +971,34 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 9 unmodified lines | |||
| 993 | } | 971 | } |
| 994 | 972 | ||
| 995 | ret = 0; | 973 | ret = 0; |
| 974 | if (enable_remapped_mode) { | ||
| 975 | /* Use legacy mode in IRTE */ | ||
| 976 | struct amd_iommu_pi_data pi; | ||
| 977 | |||
| 978 | /** | ||
| 979 | * Here, pi is used to: | ||
| 980 | * - Tell IOMMU to use legacy mode for this interrupt. | ||
| 981 | * - Retrieve ga_tag of prior interrupt remapping data. | ||
| 982 | */ | ||
| 983 | pi.prev_ga_tag = 0; | ||
| 984 | pi.is_guest_mode = false; | ||
| 985 | ret = irq_set_vcpu_affinity(host_irq, &pi); | ||
| 986 | |||
| 987 | /** | ||
| 988 | * Check if the posted interrupt was previously | ||
| 989 | * setup with the guest_mode by checking if the ga_tag | ||
| 990 | * was cached. If so, we need to clean up the per-vcpu | ||
| 991 | * ir_list. | ||
| 992 | */ | ||
| 993 | if (!ret && pi.prev_ga_tag) { | ||
| 994 | int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag); | ||
| 995 | struct kvm_vcpu *vcpu; | ||
| 996 | |||
| 997 | vcpu = kvm_get_vcpu_by_id(kvm, id); | ||
| 998 | if (vcpu) | ||
| 999 | svm_ir_list_del(to_svm(vcpu), &pi); | ||
| 1000 | } | ||
| 1001 | } | ||
| 996 | out: | 1002 | out: |
| 997 | srcu_read_unlock(&kvm->irq_srcu, idx); | 1003 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 998 | return ret; | 1004 | return ret; |
| @@ -3173,9 +3173,14 @@ skip_vmsa_free: · 3172 unmodified lines | |||
| 3173 | kvfree(svm->sev_es.ghcb_sa); | 3173 | kvfree(svm->sev_es.ghcb_sa); |
| 3174 | } | 3174 | } |
| 3175 | 3175 | ||
| 3176 | static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control) | ||
| 3177 | { | ||
| 3178 | return (((u64)control->exit_code_hi) << 32) | control->exit_code; | ||
| 3179 | } | ||
| 3180 | |||
| 3176 | static void dump_ghcb(struct vcpu_svm *svm) | 3181 | static void dump_ghcb(struct vcpu_svm *svm) |
| 3177 | { | 3182 | { |
| 3178 | struct ghcb *ghcb = svm->sev_es.ghcb; | 3183 | struct vmcb_control_area *control = &svm->vmcb->control; |
| 3179 | unsigned int nbits; | 3184 | unsigned int nbits; |
| 3180 | 3185 | ||
| 3181 | /* Re-use the dump_invalid_vmcb module parameter */ | 3186 | /* Re-use the dump_invalid_vmcb module parameter */ |
| @@ -3184,18 +3189,24 @@ static void dump_ghcb(struct vcpu_svm *svm) · 2 unmodified lines | |||
| 3184 | return; | 3189 | return; |
| 3185 | } | 3190 | } |
| 3186 | 3191 | ||
| 3187 | nbits = sizeof(ghcb->save.valid_bitmap) * 8; | 3192 | nbits = sizeof(svm->sev_es.valid_bitmap) * 8; |
| 3188 | 3193 | ||
| 3189 | pr_err("GHCB (GPA=%016llx):\n", svm->vmcb->control.ghcb_gpa); | 3194 | /* |
| 3195 | * Print KVM's snapshot of the GHCB values that were (unsuccessfully) | ||
| 3196 | * used to handle the exit. If the guest has since modified the GHCB | ||
| 3197 | * itself, dumping the raw GHCB won't help debug why KVM was unable to | ||
| 3198 | * handle the VMGEXIT that KVM observed. | ||
| 3199 | */ | ||
| 3200 | pr_err("GHCB (GPA=%016llx) snapshot:\n", svm->vmcb->control.ghcb_gpa); | ||
| 3190 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_code", | 3201 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_code", |
| 3191 | ghcb->save.sw_exit_code, ghcb_sw_exit_code_is_valid(ghcb)); | 3202 | kvm_ghcb_get_sw_exit_code(control), kvm_ghcb_sw_exit_code_is_valid(svm)); |
| 3192 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_1", | 3203 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_1", |
| 3193 | ghcb->save.sw_exit_info_1, ghcb_sw_exit_info_1_is_valid(ghcb)); | 3204 | control->exit_info_1, kvm_ghcb_sw_exit_info_1_is_valid(svm)); |
| 3194 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_2", | 3205 | pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_2", |
| 3195 | ghcb->save.sw_exit_info_2, ghcb_sw_exit_info_2_is_valid(ghcb)); | 3206 | control->exit_info_2, kvm_ghcb_sw_exit_info_2_is_valid(svm)); |
| 3196 | pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch", | 3207 | pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch", |
| 3197 | ghcb->save.sw_scratch, ghcb_sw_scratch_is_valid(ghcb)); | 3208 | svm->sev_es.sw_scratch, kvm_ghcb_sw_scratch_is_valid(svm)); |
| 3198 | pr_err("%-20s%*pb\n", "valid_bitmap", nbits, ghcb->save.valid_bitmap); | 3209 | pr_err("%-20s%*pb\n", "valid_bitmap", nbits, svm->sev_es.valid_bitmap); |
| 3199 | } | 3210 | } |
| 3200 | 3211 | ||
| 3201 | static void sev_es_sync_to_ghcb(struct vcpu_svm *svm) | 3212 | static void sev_es_sync_to_ghcb(struct vcpu_svm *svm) |
| @@ -3266,11 +3277,6 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) · 64 unmodified lines | |||
| 3266 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); | 3277 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); |
| 3267 | } | 3278 | } |
| 3268 | 3279 | ||
| 3269 | static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control) | ||
| 3270 | { | ||
| 3271 | return (((u64)control->exit_code_hi) << 32) | control->exit_code; | ||
| 3272 | } | ||
| 3273 | |||
| 3274 | static int sev_es_validate_vmgexit(struct vcpu_svm *svm) | 3280 | static int sev_es_validate_vmgexit(struct vcpu_svm *svm) |
| 3275 | { | 3281 | { |
| 3276 | struct vmcb_control_area *control = &svm->vmcb->control; | 3282 | struct vmcb_control_area *control = &svm->vmcb->control; |
| @@ -607,9 +607,6 @@ static void svm_disable_virtualization_cpu(void) · 606 unmodified lines | |||
| 607 | kvm_cpu_svm_disable(); | 607 | kvm_cpu_svm_disable(); |
| 608 | 608 | ||
| 609 | amd_pmu_disable_virt(); | 609 | amd_pmu_disable_virt(); |
| 610 | |||
| 611 | if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) | ||
| 612 | msr_clear_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT); | ||
| 613 | } | 610 | } |
| 614 | 611 | ||
| 615 | static int svm_enable_virtualization_cpu(void) | 612 | static int svm_enable_virtualization_cpu(void) |
| @@ -687,9 +684,6 @@ static int svm_enable_virtualization_cpu(void) · 71 unmodified lines | |||
| 687 | rdmsr(MSR_TSC_AUX, sev_es_host_save_area(sd)->tsc_aux, msr_hi); | 684 | rdmsr(MSR_TSC_AUX, sev_es_host_save_area(sd)->tsc_aux, msr_hi); |
| 688 | } | 685 | } |
| 689 | 686 | ||
| 690 | if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) | ||
| 691 | msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT); | ||
| 692 | |||
| 693 | return 0; | 687 | return 0; |
| 694 | } | 688 | } |
| 695 | 689 | ||
| @@ -1518,6 +1512,63 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 822 unmodified lines | |||
| 1518 | __free_pages(virt_to_page(svm->msrpm), get_order(MSRPM_SIZE)); | 1512 | __free_pages(virt_to_page(svm->msrpm), get_order(MSRPM_SIZE)); |
| 1519 | } | 1513 | } |
| 1520 | 1514 | ||
| 1515 | #ifdef CONFIG_CPU_MITIGATIONS | ||
| 1516 | static DEFINE_SPINLOCK(srso_lock); | ||
| 1517 | static atomic_t srso_nr_vms; | ||
| 1518 | |||
| 1519 | static void svm_srso_clear_bp_spec_reduce(void *ign) | ||
| 1520 | { | ||
| 1521 | struct svm_cpu_data *sd = this_cpu_ptr(&svm_data); | ||
| 1522 | |||
| 1523 | if (!sd->bp_spec_reduce_set) | ||
| 1524 | return; | ||
| 1525 | |||
| 1526 | msr_clear_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT); | ||
| 1527 | sd->bp_spec_reduce_set = false; | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | static void svm_srso_vm_destroy(void) | ||
| 1531 | { | ||
| 1532 | if (!cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) | ||
| 1533 | return; | ||
| 1534 | |||
| 1535 | if (atomic_dec_return(&srso_nr_vms)) | ||
| 1536 | return; | ||
| 1537 | |||
| 1538 | guard(spinlock)(&srso_lock); | ||
| 1539 | |||
| 1540 | /* | ||
| 1541 | * Verify a new VM didn't come along, acquire the lock, and increment | ||
| 1542 | * the count before this task acquired the lock. | ||
| 1543 | */ | ||
| 1544 | if (atomic_read(&srso_nr_vms)) | ||
| 1545 | return; | ||
| 1546 | |||
| 1547 | on_each_cpu(svm_srso_clear_bp_spec_reduce, NULL, 1); | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | static void svm_srso_vm_init(void) | ||
| 1551 | { | ||
| 1552 | if (!cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) | ||
| 1553 | return; | ||
| 1554 | |||
| 1555 | /* | ||
| 1556 | * Acquire the lock on 0 => 1 transitions to ensure a potential 1 => 0 | ||
| 1557 | * transition, i.e. destroying the last VM, is fully complete, e.g. so | ||
| 1558 | * that a delayed IPI doesn't clear BP_SPEC_REDUCE after a vCPU runs. | ||
| 1559 | */ | ||
| 1560 | if (atomic_inc_not_zero(&srso_nr_vms)) | ||
| 1561 | return; | ||
| 1562 | |||
| 1563 | guard(spinlock)(&srso_lock); | ||
| 1564 | |||
| 1565 | atomic_inc(&srso_nr_vms); | ||
| 1566 | } | ||
| 1567 | #else | ||
| 1568 | static void svm_srso_vm_init(void) { } | ||
| 1569 | static void svm_srso_vm_destroy(void) { } | ||
| 1570 | #endif | ||
| 1571 | |||
| 1521 | static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) | 1572 | static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) |
| 1522 | { | 1573 | { |
| 1523 | struct vcpu_svm *svm = to_svm(vcpu); | 1574 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -1550,6 +1601,11 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) · 26 unmodified lines | |||
| 1550 | (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm))) | 1601 | (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm))) |
| 1551 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); | 1602 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); |
| 1552 | 1603 | ||
| 1604 | if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE) && | ||
| 1605 | !sd->bp_spec_reduce_set) { | ||
| 1606 | sd->bp_spec_reduce_set = true; | ||
| 1607 | msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT); | ||
| 1608 | } | ||
| 1553 | svm->guest_state_loaded = true; | 1609 | svm->guest_state_loaded = true; |
| 1554 | } | 1610 | } |
| 1555 | 1611 | ||
| @@ -2231,6 +2287,10 @@ static int shutdown_interception(struct kvm_vcpu *vcpu) · 675 unmodified lines | |||
| 2231 | */ | 2287 | */ |
| 2232 | if (!sev_es_guest(vcpu->kvm)) { | 2288 | if (!sev_es_guest(vcpu->kvm)) { |
| 2233 | clear_page(svm->vmcb); | 2289 | clear_page(svm->vmcb); |
| 2290 | #ifdef CONFIG_KVM_SMM | ||
| 2291 | if (is_smm(vcpu)) | ||
| 2292 | kvm_smm_changed(vcpu, false); | ||
| 2293 | #endif | ||
| 2234 | kvm_vcpu_reset(vcpu, true); | 2294 | kvm_vcpu_reset(vcpu, true); |
| 2235 | } | 2295 | } |
| 2236 | 2296 | ||
| @@ -5036,6 +5096,8 @@ static void svm_vm_destroy(struct kvm *kvm) · 2799 unmodified lines | |||
| 5036 | { | 5096 | { |
| 5037 | avic_vm_destroy(kvm); | 5097 | avic_vm_destroy(kvm); |
| 5038 | sev_vm_destroy(kvm); | 5098 | sev_vm_destroy(kvm); |
| 5099 | |||
| 5100 | svm_srso_vm_destroy(); | ||
| 5039 | } | 5101 | } |
| 5040 | 5102 | ||
| 5041 | static int svm_vm_init(struct kvm *kvm) | 5103 | static int svm_vm_init(struct kvm *kvm) |
| @@ -5061,6 +5123,7 @@ static int svm_vm_init(struct kvm *kvm) · 19 unmodified lines | |||
| 5061 | return ret; | 5123 | return ret; |
| 5062 | } | 5124 | } |
| 5063 | 5125 | ||
| 5126 | svm_srso_vm_init(); | ||
| 5064 | return 0; | 5127 | return 0; |
| 5065 | } | 5128 | } |
| 5066 | 5129 | ||
| @@ -335,6 +335,8 @@ struct svm_cpu_data { · 334 unmodified lines | |||
| 335 | u32 next_asid; | 335 | u32 next_asid; |
| 336 | u32 min_asid; | 336 | u32 min_asid; |
| 337 | 337 | ||
| 338 | bool bp_spec_reduce_set; | ||
| 339 | |||
| 338 | struct vmcb *save_area; | 340 | struct vmcb *save_area; |
| 339 | unsigned long save_area_pa; | 341 | unsigned long save_area_pa; |
| 340 | 342 | ||
| @@ -11,6 +11,13 @@ · 10 unmodified lines | |||
| 11 | #undef TRACE_SYSTEM | 11 | #undef TRACE_SYSTEM |
| 12 | #define TRACE_SYSTEM kvm | 12 | #define TRACE_SYSTEM kvm |
| 13 | 13 | ||
| 14 | #ifdef CREATE_TRACE_POINTS | ||
| 15 | #define tracing_kvm_rip_read(vcpu) ({ \ | ||
| 16 | typeof(vcpu) __vcpu = vcpu; \ | ||
| 17 | __vcpu->arch.guest_state_protected ? 0 : kvm_rip_read(__vcpu); \ | ||
| 18 | }) | ||
| 19 | #endif | ||
| 20 | |||
| 14 | /* | 21 | /* |
| 15 | * Tracepoint for guest mode entry. | 22 | * Tracepoint for guest mode entry. |
| 16 | */ | 23 | */ |
| @@ -28,7 +35,7 @@ TRACE_EVENT(kvm_entry, · 11 unmodified lines | |||
| 28 | 35 | ||
| 29 | TP_fast_assign( | 36 | TP_fast_assign( |
| 30 | __entry->vcpu_id = vcpu->vcpu_id; | 37 | __entry->vcpu_id = vcpu->vcpu_id; |
| 31 | __entry->rip = kvm_rip_read(vcpu); | 38 | __entry->rip = tracing_kvm_rip_read(vcpu); |
| 32 | __entry->immediate_exit = force_immediate_exit; | 39 | __entry->immediate_exit = force_immediate_exit; |
| 33 | 40 | ||
| 34 | kvm_x86_call(get_entry_info)(vcpu, &__entry->intr_info, | 41 | kvm_x86_call(get_entry_info)(vcpu, &__entry->intr_info, |
| @@ -319,7 +326,7 @@ TRACE_EVENT(name, \ · 284 unmodified lines | |||
| 319 | ), \ | 326 | ), \ |
| 320 | \ | 327 | \ |
| 321 | TP_fast_assign( \ | 328 | TP_fast_assign( \ |
| 322 | __entry->guest_rip = kvm_rip_read(vcpu); \ | 329 | __entry->guest_rip = tracing_kvm_rip_read(vcpu); \ |
| 323 | __entry->isa = isa; \ | 330 | __entry->isa = isa; \ |
| 324 | __entry->vcpu_id = vcpu->vcpu_id; \ | 331 | __entry->vcpu_id = vcpu->vcpu_id; \ |
| 325 | __entry->requests = READ_ONCE(vcpu->requests); \ | 332 | __entry->requests = READ_ONCE(vcpu->requests); \ |
| @@ -423,7 +430,7 @@ TRACE_EVENT(kvm_page_fault, · 97 unmodified lines | |||
| 423 | 430 | ||
| 424 | TP_fast_assign( | 431 | TP_fast_assign( |
| 425 | __entry->vcpu_id = vcpu->vcpu_id; | 432 | __entry->vcpu_id = vcpu->vcpu_id; |
| 426 | __entry->guest_rip = kvm_rip_read(vcpu); | 433 | __entry->guest_rip = tracing_kvm_rip_read(vcpu); |
| 427 | __entry->fault_address = fault_address; | 434 | __entry->fault_address = fault_address; |
| 428 | __entry->error_code = error_code; | 435 | __entry->error_code = error_code; |
| 429 | ), | 436 | ), |
| @@ -31,6 +31,8 @@ static DEFINE_PER_CPU(struct list_head, wakeup_vcpus_on_cpu); · 30 unmodified lines | |||
| 31 | */ | 31 | */ |
| 32 | static DEFINE_PER_CPU(raw_spinlock_t, wakeup_vcpus_on_cpu_lock); | 32 | static DEFINE_PER_CPU(raw_spinlock_t, wakeup_vcpus_on_cpu_lock); |
| 33 | 33 | ||
| 34 | #define PI_LOCK_SCHED_OUT SINGLE_DEPTH_NESTING | ||
| 35 | |||
| 34 | static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) | 36 | static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) |
| 35 | { | 37 | { |
| 36 | return &(to_vmx(vcpu)->pi_desc); | 38 | return &(to_vmx(vcpu)->pi_desc); |
| @@ -89,9 +91,20 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) · 52 unmodified lines | |||
| 89 | * current pCPU if the task was migrated. | 91 | * current pCPU if the task was migrated. |
| 90 | */ | 92 | */ |
| 91 | if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR) { | 93 | if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR) { |
| 92 | raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); | 94 | raw_spinlock_t *spinlock = &per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu); |
| 95 | |||
| 96 | /* | ||
| 97 | * In addition to taking the wakeup lock for the regular/IRQ | ||
| 98 | * context, tell lockdep it is being taken for the "sched out" | ||
| 99 | * context as well. vCPU loads happens in task context, and | ||
| 100 | * this is taking the lock of the *previous* CPU, i.e. can race | ||
| 101 | * with both the scheduler and the wakeup handler. | ||
| 102 | */ | ||
| 103 | raw_spin_lock(spinlock); | ||
| 104 | spin_acquire(&spinlock->dep_map, PI_LOCK_SCHED_OUT, 0, _RET_IP_); | ||
| 93 | list_del(&vmx->pi_wakeup_list); | 105 | list_del(&vmx->pi_wakeup_list); |
| 94 | raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); | 106 | spin_release(&spinlock->dep_map, _RET_IP_); |
| 107 | raw_spin_unlock(spinlock); | ||
| 95 | } | 108 | } |
| 96 | 109 | ||
| 97 | dest = cpu_physical_id(cpu); | 110 | dest = cpu_physical_id(cpu); |
| @@ -148,11 +161,23 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) · 50 unmodified lines | |||
| 148 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); | 161 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 149 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 162 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 150 | struct pi_desc old, new; | 163 | struct pi_desc old, new; |
| 151 | unsigned long flags; | ||
| 152 | 164 | ||
| 153 | local_irq_save(flags); | 165 | lockdep_assert_irqs_disabled(); |
| 154 | 166 | ||
| 155 | raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); | 167 | /* |
| 168 | * Acquire the wakeup lock using the "sched out" context to workaround | ||
| 169 | * a lockdep false positive. When this is called, schedule() holds | ||
| 170 | * various per-CPU scheduler locks. When the wakeup handler runs, it | ||
| 171 | * holds this CPU's wakeup lock while calling try_to_wake_up(), which | ||
| 172 | * can eventually take the aforementioned scheduler locks, which causes | ||
| 173 | * lockdep to assume there is deadlock. | ||
| 174 | * | ||
| 175 | * Deadlock can't actually occur because IRQs are disabled for the | ||
| 176 | * entirety of the sched_out critical section, i.e. the wakeup handler | ||
| 177 | * can't run while the scheduler locks are held. | ||
| 178 | */ | ||
| 179 | raw_spin_lock_nested(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu), | ||
| 180 | PI_LOCK_SCHED_OUT); | ||
| 156 | list_add_tail(&vmx->pi_wakeup_list, | 181 | list_add_tail(&vmx->pi_wakeup_list, |
| 157 | &per_cpu(wakeup_vcpus_on_cpu, vcpu->cpu)); | 182 | &per_cpu(wakeup_vcpus_on_cpu, vcpu->cpu)); |
| 158 | raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); | 183 | raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); |
| @@ -176,8 +201,6 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) · 17 unmodified lines | |||
| 176 | */ | 201 | */ |
| 177 | if (pi_test_on(&new)) | 202 | if (pi_test_on(&new)) |
| 178 | __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR); | 203 | __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR); |
| 179 | |||
| 180 | local_irq_restore(flags); | ||
| 181 | } | 204 | } |
| 182 | 205 | ||
| 183 | static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu) | 206 | static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu) |
| @@ -274,6 +297,7 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 90 unmodified lines | |||
| 274 | { | 297 | { |
| 275 | struct kvm_kernel_irq_routing_entry *e; | 298 | struct kvm_kernel_irq_routing_entry *e; |
| 276 | struct kvm_irq_routing_table *irq_rt; | 299 | struct kvm_irq_routing_table *irq_rt; |
| 300 | bool enable_remapped_mode = true; | ||
| 277 | struct kvm_lapic_irq irq; | 301 | struct kvm_lapic_irq irq; |
| 278 | struct kvm_vcpu *vcpu; | 302 | struct kvm_vcpu *vcpu; |
| 279 | struct vcpu_data vcpu_info; | 303 | struct vcpu_data vcpu_info; |
| @@ -312,21 +336,8 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 32 unmodified lines | |||
| 312 | 336 | ||
| 313 | kvm_set_msi_irq(kvm, e, &irq); | 337 | kvm_set_msi_irq(kvm, e, &irq); |
| 314 | if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || | 338 | if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || |
| 315 | !kvm_irq_is_postable(&irq)) { | 339 | !kvm_irq_is_postable(&irq)) |
| 316 | /* | ||
| 317 | * Make sure the IRTE is in remapped mode if | ||
| 318 | * we don't handle it in posted mode. | ||
| 319 | */ | ||
| 320 | ret = irq_set_vcpu_affinity(host_irq, NULL); | ||
| 321 | if (ret < 0) { | ||
| 322 | printk(KERN_INFO | ||
| 323 | "failed to back to remapped mode, irq: %u\n", | ||
| 324 | host_irq); | ||
| 325 | goto out; | ||
| 326 | } | ||
| 327 | |||
| 328 | continue; | 340 | continue; |
| 329 | } | ||
| 330 | 341 | ||
| 331 | vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); | 342 | vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); |
| 332 | vcpu_info.vector = irq.vector; | 343 | vcpu_info.vector = irq.vector; |
| @@ -334,11 +345,12 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 1 unmodified line | |||
| 334 | trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, | 345 | trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, |
| 335 | vcpu_info.vector, vcpu_info.pi_desc_addr, set); | 346 | vcpu_info.vector, vcpu_info.pi_desc_addr, set); |
| 336 | 347 | ||
| 337 | if (set) | 348 | if (!set) |
| 338 | ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); | 349 | continue; |
| 339 | else | 350 | |
| 340 | ret = irq_set_vcpu_affinity(host_irq, NULL); | 351 | enable_remapped_mode = false; |
| 341 | 352 | ||
| 353 | ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); | ||
| 342 | if (ret < 0) { | 354 | if (ret < 0) { |
| 343 | printk(KERN_INFO "%s: failed to update PI IRTE\n", | 355 | printk(KERN_INFO "%s: failed to update PI IRTE\n", |
| 344 | __func__); | 356 | __func__); |
| @@ -346,6 +358,9 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, · 1 unmodified line | |||
| 346 | } | 358 | } |
| 347 | } | 359 | } |
| 348 | 360 | ||
| 361 | if (enable_remapped_mode) | ||
| 362 | ret = irq_set_vcpu_affinity(host_irq, NULL); | ||
| 363 | |||
| 349 | ret = 0; | 364 | ret = 0; |
| 350 | out: | 365 | out: |
| 351 | srcu_read_unlock(&kvm->irq_srcu, idx); | 366 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| @@ -1584,7 +1584,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc); · 1583 unmodified lines | |||
| 1584 | ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ | 1584 | ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ |
| 1585 | ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ | 1585 | ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ |
| 1586 | ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \ | 1586 | ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \ |
| 1587 | ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO) | 1587 | ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO) |
| 1588 | 1588 | ||
| 1589 | static u64 kvm_get_arch_capabilities(void) | 1589 | static u64 kvm_get_arch_capabilities(void) |
| 1590 | { | 1590 | { |
| @@ -1618,6 +1618,8 @@ static u64 kvm_get_arch_capabilities(void) · 27 unmodified lines | |||
| 1618 | data |= ARCH_CAP_MDS_NO; | 1618 | data |= ARCH_CAP_MDS_NO; |
| 1619 | if (!boot_cpu_has_bug(X86_BUG_RFDS)) | 1619 | if (!boot_cpu_has_bug(X86_BUG_RFDS)) |
| 1620 | data |= ARCH_CAP_RFDS_NO; | 1620 | data |= ARCH_CAP_RFDS_NO; |
| 1621 | if (!boot_cpu_has_bug(X86_BUG_ITS)) | ||
| 1622 | data |= ARCH_CAP_ITS_NO; | ||
| 1621 | 1623 | ||
| 1622 | if (!boot_cpu_has(X86_FEATURE_RTM)) { | 1624 | if (!boot_cpu_has(X86_FEATURE_RTM)) { |
| 1623 | /* | 1625 | /* |
| @@ -4597,7 +4599,7 @@ static bool kvm_is_vm_type_supported(unsigned long type) · 2973 unmodified lines | |||
| 4597 | return type < 32 && (kvm_caps.supported_vm_types & BIT(type)); | 4599 | return type < 32 && (kvm_caps.supported_vm_types & BIT(type)); |
| 4598 | } | 4600 | } |
| 4599 | 4601 | ||
| 4600 | static inline u32 kvm_sync_valid_fields(struct kvm *kvm) | 4602 | static inline u64 kvm_sync_valid_fields(struct kvm *kvm) |
| 4601 | { | 4603 | { |
| 4602 | return kvm && kvm->arch.has_protected_state ? 0 : KVM_SYNC_X86_VALID_FIELDS; | 4604 | return kvm && kvm->arch.has_protected_state ? 0 : KVM_SYNC_X86_VALID_FIELDS; |
| 4603 | } | 4605 | } |
| @@ -11098,7 +11100,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 6494 unmodified lines | |||
| 11098 | /* | 11100 | /* |
| 11099 | * Profile KVM exit RIPs: | 11101 | * Profile KVM exit RIPs: |
| 11100 | */ | 11102 | */ |
| 11101 | if (unlikely(prof_on == KVM_PROFILING)) { | 11103 | if (unlikely(prof_on == KVM_PROFILING && |
| 11104 | !vcpu->arch.guest_state_protected)) { | ||
| 11102 | unsigned long rip = kvm_rip_read(vcpu); | 11105 | unsigned long rip = kvm_rip_read(vcpu); |
| 11103 | profile_hit(KVM_PROFILING, (void *)rip); | 11106 | profile_hit(KVM_PROFILING, (void *)rip); |
| 11104 | } | 11107 | } |
| @@ -11492,7 +11495,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 387 unmodified lines | |||
| 11492 | { | 11495 | { |
| 11493 | struct kvm_queued_exception *ex = &vcpu->arch.exception; | 11496 | struct kvm_queued_exception *ex = &vcpu->arch.exception; |
| 11494 | struct kvm_run *kvm_run = vcpu->run; | 11497 | struct kvm_run *kvm_run = vcpu->run; |
| 11495 | u32 sync_valid_fields; | 11498 | u64 sync_valid_fields; |
| 11496 | int r; | 11499 | int r; |
| 11497 | 11500 | ||
| 11498 | r = kvm_mmu_post_init_vm(vcpu->kvm); | 11501 | r = kvm_mmu_post_init_vm(vcpu->kvm); |
| @@ -11786,6 +11789,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 287 unmodified lines | |||
| 11786 | if (kvm_mpx_supported()) | 11789 | if (kvm_mpx_supported()) |
| 11787 | kvm_load_guest_fpu(vcpu); | 11790 | kvm_load_guest_fpu(vcpu); |
| 11788 | 11791 | ||
| 11792 | kvm_vcpu_srcu_read_lock(vcpu); | ||
| 11793 | |||
| 11789 | r = kvm_apic_accept_events(vcpu); | 11794 | r = kvm_apic_accept_events(vcpu); |
| 11790 | if (r < 0) | 11795 | if (r < 0) |
| 11791 | goto out; | 11796 | goto out; |
| @@ -11799,6 +11804,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 7 unmodified lines | |||
| 11799 | mp_state->mp_state = vcpu->arch.mp_state; | 11804 | mp_state->mp_state = vcpu->arch.mp_state; |
| 11800 | 11805 | ||
| 11801 | out: | 11806 | out: |
| 11807 | kvm_vcpu_srcu_read_unlock(vcpu); | ||
| 11808 | |||
| 11802 | if (kvm_mpx_supported()) | 11809 | if (kvm_mpx_supported()) |
| 11803 | kvm_put_guest_fpu(vcpu); | 11810 | kvm_put_guest_fpu(vcpu); |
| 11804 | vcpu_put(vcpu); | 11811 | vcpu_put(vcpu); |
| @@ -13552,25 +13559,27 @@ bool kvm_arch_has_noncoherent_dma(struct kvm *kvm) · 1747 unmodified lines | |||
| 13552 | } | 13559 | } |
| 13553 | EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma); | 13560 | EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma); |
| 13554 | 13561 | ||
| 13555 | bool kvm_arch_has_irq_bypass(void) | ||
| 13556 | { | ||
| 13557 | return enable_apicv && irq_remapping_cap(IRQ_POSTING_CAP); | ||
| 13558 | } | ||
| 13559 | |||
| 13560 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, | 13562 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, |
| 13561 | struct irq_bypass_producer *prod) | 13563 | struct irq_bypass_producer *prod) |
| 13562 | { | 13564 | { |
| 13563 | struct kvm_kernel_irqfd *irqfd = | 13565 | struct kvm_kernel_irqfd *irqfd = |
| 13564 | container_of(cons, struct kvm_kernel_irqfd, consumer); | 13566 | container_of(cons, struct kvm_kernel_irqfd, consumer); |
| 13567 | struct kvm *kvm = irqfd->kvm; | ||
| 13565 | int ret; | 13568 | int ret; |
| 13566 | 13569 | ||
| 13567 | irqfd->producer = prod; | ||
| 13568 | kvm_arch_start_assignment(irqfd->kvm); | 13570 | kvm_arch_start_assignment(irqfd->kvm); |
| 13571 | |||
| 13572 | spin_lock_irq(&kvm->irqfds.lock); | ||
| 13573 | irqfd->producer = prod; | ||
| 13574 | |||
| 13569 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, | 13575 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, |
| 13570 | prod->irq, irqfd->gsi, 1); | 13576 | prod->irq, irqfd->gsi, 1); |
| 13571 | if (ret) | 13577 | if (ret) |
| 13572 | kvm_arch_end_assignment(irqfd->kvm); | 13578 | kvm_arch_end_assignment(irqfd->kvm); |
| 13573 | 13579 | ||
| 13580 | spin_unlock_irq(&kvm->irqfds.lock); | ||
| 13581 | |||
| 13582 | |||
| 13574 | return ret; | 13583 | return ret; |
| 13575 | } | 13584 | } |
| 13576 | 13585 | ||
| @@ -13580,9 +13589,9 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons, · 3 unmodified lines | |||
| 13580 | int ret; | 13589 | int ret; |
| 13581 | struct kvm_kernel_irqfd *irqfd = | 13590 | struct kvm_kernel_irqfd *irqfd = |
| 13582 | container_of(cons, struct kvm_kernel_irqfd, consumer); | 13591 | container_of(cons, struct kvm_kernel_irqfd, consumer); |
| 13592 | struct kvm *kvm = irqfd->kvm; | ||
| 13583 | 13593 | ||
| 13584 | WARN_ON(irqfd->producer != prod); | 13594 | WARN_ON(irqfd->producer != prod); |
| 13585 | irqfd->producer = NULL; | ||
| 13586 | 13595 | ||
| 13587 | /* | 13596 | /* |
| 13588 | * When producer of consumer is unregistered, we change back to | 13597 | * When producer of consumer is unregistered, we change back to |
| @@ -13590,12 +13599,18 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons, · 1 unmodified line | |||
| 13590 | * when the irq is masked/disabled or the consumer side (KVM | 13599 | * when the irq is masked/disabled or the consumer side (KVM |
| 13591 | * int this case doesn't want to receive the interrupts. | 13600 | * int this case doesn't want to receive the interrupts. |
| 13592 | */ | 13601 | */ |
| 13602 | spin_lock_irq(&kvm->irqfds.lock); | ||
| 13603 | irqfd->producer = NULL; | ||
| 13604 | |||
| 13593 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, | 13605 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, |
| 13594 | prod->irq, irqfd->gsi, 0); | 13606 | prod->irq, irqfd->gsi, 0); |
| 13595 | if (ret) | 13607 | if (ret) |
| 13596 | printk(KERN_INFO "irq bypass consumer (token %p) unregistration" | 13608 | printk(KERN_INFO "irq bypass consumer (token %p) unregistration" |
| 13597 | " fails: %d\n", irqfd->consumer.token, ret); | 13609 | " fails: %d\n", irqfd->consumer.token, ret); |
| 13598 | 13610 | ||
| 13611 | spin_unlock_irq(&kvm->irqfds.lock); | ||
| 13612 | |||
| 13613 | |||
| 13599 | kvm_arch_end_assignment(irqfd->kvm); | 13614 | kvm_arch_end_assignment(irqfd->kvm); |
| 13600 | } | 13615 | } |
| 13601 | 13616 | ||
| @@ -13608,7 +13623,8 @@ int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq, · 6 unmodified lines | |||
| 13608 | bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old, | 13623 | bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old, |
| 13609 | struct kvm_kernel_irq_routing_entry *new) | 13624 | struct kvm_kernel_irq_routing_entry *new) |
| 13610 | { | 13625 | { |
| 13611 | if (new->type != KVM_IRQ_ROUTING_MSI) | 13626 | if (old->type != KVM_IRQ_ROUTING_MSI || |
| 13627 | new->type != KVM_IRQ_ROUTING_MSI) | ||
| 13612 | return true; | 13628 | return true; |
| 13613 | 13629 | ||
| 13614 | return !!memcmp(&old->msi, &new->msi, sizeof(new->msi)); | 13630 | return !!memcmp(&old->msi, &new->msi, sizeof(new->msi)); |
| @@ -367,6 +367,54 @@ SYM_FUNC_END(call_depth_return_thunk) · 366 unmodified lines | |||
| 367 | 367 | ||
| 368 | #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ | 368 | #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ |
| 369 | 369 | ||
| 370 | #ifdef CONFIG_MITIGATION_ITS | ||
| 371 | |||
| 372 | .macro ITS_THUNK reg | ||
| 373 | |||
| 374 | /* | ||
| 375 | * If CFI paranoid is used then the ITS thunk starts with opcodes (0xea; jne 1b) | ||
| 376 | * that complete the fineibt_paranoid caller sequence. | ||
| 377 | */ | ||
| 378 | 1: .byte 0xea | ||
| 379 | SYM_INNER_LABEL(__x86_indirect_paranoid_thunk_\reg, SYM_L_GLOBAL) | ||
| 380 | UNWIND_HINT_UNDEFINED | ||
| 381 | ANNOTATE_NOENDBR | ||
| 382 | jne 1b | ||
| 383 | SYM_INNER_LABEL(__x86_indirect_its_thunk_\reg, SYM_L_GLOBAL) | ||
| 384 | UNWIND_HINT_UNDEFINED | ||
| 385 | ANNOTATE_NOENDBR | ||
| 386 | ANNOTATE_RETPOLINE_SAFE | ||
| 387 | jmp *%\reg | ||
| 388 | int3 | ||
| 389 | .align 32, 0xcc /* fill to the end of the line */ | ||
| 390 | .skip 32 - (__x86_indirect_its_thunk_\reg - 1b), 0xcc /* skip to the next upper half */ | ||
| 391 | .endm | ||
| 392 | |||
| 393 | /* ITS mitigation requires thunks be aligned to upper half of cacheline */ | ||
| 394 | .align 64, 0xcc | ||
| 395 | .skip 29, 0xcc | ||
| 396 | |||
| 397 | #define GEN(reg) ITS_THUNK reg | ||
| 398 | #include <asm/GEN-for-each-reg.h> | ||
| 399 | #undef GEN | ||
| 400 | |||
| 401 | .align 64, 0xcc | ||
| 402 | SYM_FUNC_ALIAS(__x86_indirect_its_thunk_array, __x86_indirect_its_thunk_rax) | ||
| 403 | SYM_CODE_END(__x86_indirect_its_thunk_array) | ||
| 404 | |||
| 405 | .align 64, 0xcc | ||
| 406 | .skip 32, 0xcc | ||
| 407 | SYM_CODE_START(its_return_thunk) | ||
| 408 | UNWIND_HINT_FUNC | ||
| 409 | ANNOTATE_NOENDBR | ||
| 410 | ANNOTATE_UNRET_SAFE | ||
| 411 | ret | ||
| 412 | int3 | ||
| 413 | SYM_CODE_END(its_return_thunk) | ||
| 414 | EXPORT_SYMBOL(its_return_thunk) | ||
| 415 | |||
| 416 | #endif /* CONFIG_MITIGATION_ITS */ | ||
| 417 | |||
| 370 | /* | 418 | /* |
| 371 | * This function name is magical and is used by -mfunction-return=thunk-extern | 419 | * This function name is magical and is used by -mfunction-return=thunk-extern |
| 372 | * for the compiler to generate JMPs to it. | 420 | * for the compiler to generate JMPs to it. |
| @@ -996,8 +996,8 @@ AVXcode: 4 · 995 unmodified lines | |||
| 996 | 83: Grp1 Ev,Ib (1A),(es) | 996 | 83: Grp1 Ev,Ib (1A),(es) |
| 997 | # CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, | 997 | # CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, |
| 998 | # CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ | 998 | # CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ |
| 999 | 84: CTESTSCC (ev) | 999 | 84: CTESTSCC Eb,Gb (ev) |
| 1000 | 85: CTESTSCC (es) | CTESTSCC (66),(es) | 1000 | 85: CTESTSCC Ev,Gv (es) | CTESTSCC Ev,Gv (66),(es) |
| 1001 | 88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) | 1001 | 88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) |
| 1002 | 8f: POP2 Bq,Rq (000),(11B),(ev) | 1002 | 8f: POP2 Bq,Rq (000),(11B),(ev) |
| 1003 | a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) | 1003 | a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | #include <linux/initrd.h> | 30 | #include <linux/initrd.h> |
| 31 | #include <linux/cpumask.h> | 31 | #include <linux/cpumask.h> |
| 32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
| 33 | #include <linux/execmem.h> | ||
| 33 | 34 | ||
| 34 | #include <asm/asm.h> | 35 | #include <asm/asm.h> |
| 35 | #include <asm/bios_ebda.h> | 36 | #include <asm/bios_ebda.h> |
| @@ -565,7 +566,7 @@ static void __init lowmem_pfn_init(void) · 529 unmodified lines | |||
| 565 | "only %luMB highmem pages available, ignoring highmem size of %luMB!\n" | 566 | "only %luMB highmem pages available, ignoring highmem size of %luMB!\n" |
| 566 | 567 | ||
| 567 | #define MSG_HIGHMEM_TRIMMED \ | 568 | #define MSG_HIGHMEM_TRIMMED \ |
| 568 | "Warning: only 4GB will be used. Support for for CONFIG_HIGHMEM64G was removed!\n" | 569 | "Warning: only 4GB will be used. Support for CONFIG_HIGHMEM64G was removed!\n" |
| 569 | /* | 570 | /* |
| 570 | * We have more RAM than fits into lowmem - we try to put it into | 571 | * We have more RAM than fits into lowmem - we try to put it into |
| 571 | * highmem, also taking the highmem=x boot parameter into account: | 572 | * highmem, also taking the highmem=x boot parameter into account: |
| @@ -755,6 +756,8 @@ void mark_rodata_ro(void) · 183 unmodified lines | |||
| 755 | pr_info("Write protecting kernel text and read-only data: %luk\n", | 756 | pr_info("Write protecting kernel text and read-only data: %luk\n", |
| 756 | size >> 10); | 757 | size >> 10); |
| 757 | 758 | ||
| 759 | execmem_cache_make_ro(); | ||
| 760 | |||
| 758 | kernel_set_to_readonly = 1; | 761 | kernel_set_to_readonly = 1; |
| 759 | 762 | ||
| 760 | #ifdef CONFIG_CPA_DEBUG | 763 | #ifdef CONFIG_CPA_DEBUG |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include <linux/gfp.h> | 34 | #include <linux/gfp.h> |
| 35 | #include <linux/kcore.h> | 35 | #include <linux/kcore.h> |
| 36 | #include <linux/bootmem_info.h> | 36 | #include <linux/bootmem_info.h> |
| 37 | #include <linux/execmem.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
| 39 | #include <asm/bios_ebda.h> | 40 | #include <asm/bios_ebda.h> |
| @@ -1391,6 +1392,8 @@ void mark_rodata_ro(void) · 1351 unmodified lines | |||
| 1391 | (end - start) >> 10); | 1392 | (end - start) >> 10); |
| 1392 | set_memory_ro(start, (end - start) >> PAGE_SHIFT); | 1393 | set_memory_ro(start, (end - start) >> PAGE_SHIFT); |
| 1393 | 1394 | ||
| 1395 | execmem_cache_make_ro(); | ||
| 1396 | |||
| 1394 | kernel_set_to_readonly = 1; | 1397 | kernel_set_to_readonly = 1; |
| 1395 | 1398 | ||
| 1396 | /* | 1399 | /* |
| @@ -360,7 +360,7 @@ static inline pgd_t *_pgd_alloc(struct mm_struct *mm) · 359 unmodified lines | |||
| 360 | * We allocate one page for pgd. | 360 | * We allocate one page for pgd. |
| 361 | */ | 361 | */ |
| 362 | if (!SHARED_KERNEL_PMD) | 362 | if (!SHARED_KERNEL_PMD) |
| 363 | return __pgd_alloc(mm, PGD_ALLOCATION_ORDER); | 363 | return __pgd_alloc(mm, pgd_allocation_order()); |
| 364 | 364 | ||
| 365 | /* | 365 | /* |
| 366 | * Now PAE kernel is not running as a Xen domain. We can allocate | 366 | * Now PAE kernel is not running as a Xen domain. We can allocate |
| @@ -380,7 +380,7 @@ static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd) · 13 unmodified lines | |||
| 380 | 380 | ||
| 381 | static inline pgd_t *_pgd_alloc(struct mm_struct *mm) | 381 | static inline pgd_t *_pgd_alloc(struct mm_struct *mm) |
| 382 | { | 382 | { |
| 383 | return __pgd_alloc(mm, PGD_ALLOCATION_ORDER); | 383 | return __pgd_alloc(mm, pgd_allocation_order()); |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd) | 386 | static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd) |
| @@ -667,9 +667,9 @@ static void cond_mitigation(struct task_struct *next) · 666 unmodified lines | |||
| 667 | prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec); | 667 | prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec); |
| 668 | 668 | ||
| 669 | /* | 669 | /* |
| 670 | * Avoid user/user BTB poisoning by flushing the branch predictor | 670 | * Avoid user->user BTB/RSB poisoning by flushing them when switching |
| 671 | * when switching between processes. This stops one process from | 671 | * between processes. This stops one process from doing Spectre-v2 |
| 672 | * doing Spectre-v2 attacks on another. | 672 | * attacks on another. |
| 673 | * | 673 | * |
| 674 | * Both, the conditional and the always IBPB mode use the mm | 674 | * Both, the conditional and the always IBPB mode use the mm |
| 675 | * pointer to avoid the IBPB when switching between tasks of the | 675 | * pointer to avoid the IBPB when switching between tasks of the |
| @@ -899,8 +899,9 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next, · 223 unmodified lines | |||
| 899 | cond_mitigation(tsk); | 899 | cond_mitigation(tsk); |
| 900 | 900 | ||
| 901 | /* | 901 | /* |
| 902 | * Let nmi_uaccess_okay() and finish_asid_transition() | 902 | * Indicate that CR3 is about to change. nmi_uaccess_okay() |
| 903 | * know that CR3 is changing. | 903 | * and others are sensitive to the window where mm_cpumask(), |
| 904 | * CR3 and cpu_tlbstate.loaded_mm are not all in sync. | ||
| 904 | */ | 905 | */ |
| 905 | this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING); | 906 | this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING); |
| 906 | barrier(); | 907 | barrier(); |
| @@ -1204,8 +1205,16 @@ done: · 297 unmodified lines | |||
| 1204 | 1205 | ||
| 1205 | static bool should_flush_tlb(int cpu, void *data) | 1206 | static bool should_flush_tlb(int cpu, void *data) |
| 1206 | { | 1207 | { |
| 1208 | struct mm_struct *loaded_mm = per_cpu(cpu_tlbstate.loaded_mm, cpu); | ||
| 1207 | struct flush_tlb_info *info = data; | 1209 | struct flush_tlb_info *info = data; |
| 1208 | 1210 | ||
| 1211 | /* | ||
| 1212 | * Order the 'loaded_mm' and 'is_lazy' against their | ||
| 1213 | * write ordering in switch_mm_irqs_off(). Ensure | ||
| 1214 | * 'is_lazy' is at least as new as 'loaded_mm'. | ||
| 1215 | */ | ||
| 1216 | smp_rmb(); | ||
| 1217 | |||
| 1209 | /* Lazy TLB will get flushed at the next context switch. */ | 1218 | /* Lazy TLB will get flushed at the next context switch. */ |
| 1210 | if (per_cpu(cpu_tlbstate_shared.is_lazy, cpu)) | 1219 | if (per_cpu(cpu_tlbstate_shared.is_lazy, cpu)) |
| 1211 | return false; | 1220 | return false; |
| @@ -1214,8 +1223,15 @@ static bool should_flush_tlb(int cpu, void *data) · 2 unmodified lines | |||
| 1214 | if (!info->mm) | 1223 | if (!info->mm) |
| 1215 | return true; | 1224 | return true; |
| 1216 | 1225 | ||
| 1226 | /* | ||
| 1227 | * While switching, the remote CPU could have state from | ||
| 1228 | * either the prev or next mm. Assume the worst and flush. | ||
| 1229 | */ | ||
| 1230 | if (loaded_mm == LOADED_MM_SWITCHING) | ||
| 1231 | return true; | ||
| 1232 | |||
| 1217 | /* The target mm is loaded, and the CPU is not lazy. */ | 1233 | /* The target mm is loaded, and the CPU is not lazy. */ |
| 1218 | if (per_cpu(cpu_tlbstate.loaded_mm, cpu) == info->mm) | 1234 | if (loaded_mm == info->mm) |
| 1219 | return true; | 1235 | return true; |
| 1220 | 1236 | ||
| 1221 | /* In cpumask, but not the loaded mm? Periodically remove by flushing. */ | 1237 | /* In cpumask, but not the loaded mm? Periodically remove by flushing. */ |
| @@ -41,6 +41,8 @@ static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) · 40 unmodified lines | |||
| 41 | #define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2) | 41 | #define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2) |
| 42 | #define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3) | 42 | #define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3) |
| 43 | #define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4) | 43 | #define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4) |
| 44 | #define EMIT5(b1, b2, b3, b4, b5) \ | ||
| 45 | do { EMIT1(b1); EMIT4(b2, b3, b4, b5); } while (0) | ||
| 44 | 46 | ||
| 45 | #define EMIT1_off32(b1, off) \ | 47 | #define EMIT1_off32(b1, off) \ |
| 46 | do { EMIT1(b1); EMIT(off, 4); } while (0) | 48 | do { EMIT1(b1); EMIT(off, 4); } while (0) |
| @@ -661,7 +663,10 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip) · 614 unmodified lines | |||
| 661 | { | 663 | { |
| 662 | u8 *prog = *pprog; | 664 | u8 *prog = *pprog; |
| 663 | 665 | ||
| 664 | if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) { | 666 | if (cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) { |
| 667 | OPTIMIZER_HIDE_VAR(reg); | ||
| 668 | emit_jump(&prog, its_static_thunk(reg), ip); | ||
| 669 | } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) { | ||
| 665 | EMIT_LFENCE(); | 670 | EMIT_LFENCE(); |
| 666 | EMIT2(0xFF, 0xE0 + reg); | 671 | EMIT2(0xFF, 0xE0 + reg); |
| 667 | } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) { | 672 | } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) { |
| @@ -683,7 +688,7 @@ static void emit_return(u8 **pprog, u8 *ip) · 15 unmodified lines | |||
| 683 | { | 688 | { |
| 684 | u8 *prog = *pprog; | 689 | u8 *prog = *pprog; |
| 685 | 690 | ||
| 686 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { | 691 | if (cpu_wants_rethunk()) { |
| 687 | emit_jump(&prog, x86_return_thunk, ip); | 692 | emit_jump(&prog, x86_return_thunk, ip); |
| 688 | } else { | 693 | } else { |
| 689 | EMIT1(0xC3); /* ret */ | 694 | EMIT1(0xC3); /* ret */ |
| @@ -1502,6 +1507,48 @@ static void emit_priv_frame_ptr(u8 **pprog, void __percpu *priv_frame_ptr) · 812 unmodified lines | |||
| 1502 | #define PRIV_STACK_GUARD_SZ 8 | 1507 | #define PRIV_STACK_GUARD_SZ 8 |
| 1503 | #define PRIV_STACK_GUARD_VAL 0xEB9F12345678eb9fULL | 1508 | #define PRIV_STACK_GUARD_VAL 0xEB9F12345678eb9fULL |
| 1504 | 1509 | ||
| 1510 | static int emit_spectre_bhb_barrier(u8 **pprog, u8 *ip, | ||
| 1511 | struct bpf_prog *bpf_prog) | ||
| 1512 | { | ||
| 1513 | u8 *prog = *pprog; | ||
| 1514 | u8 *func; | ||
| 1515 | |||
| 1516 | if (cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_LOOP)) { | ||
| 1517 | /* The clearing sequence clobbers eax and ecx. */ | ||
| 1518 | EMIT1(0x50); /* push rax */ | ||
| 1519 | EMIT1(0x51); /* push rcx */ | ||
| 1520 | ip += 2; | ||
| 1521 | |||
| 1522 | func = (u8 *)clear_bhb_loop; | ||
| 1523 | ip += x86_call_depth_emit_accounting(&prog, func, ip); | ||
| 1524 | |||
| 1525 | if (emit_call(&prog, func, ip)) | ||
| 1526 | return -EINVAL; | ||
| 1527 | EMIT1(0x59); /* pop rcx */ | ||
| 1528 | EMIT1(0x58); /* pop rax */ | ||
| 1529 | } | ||
| 1530 | /* Insert IBHF instruction */ | ||
| 1531 | if ((cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_LOOP) && | ||
| 1532 | cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) || | ||
| 1533 | cpu_feature_enabled(X86_FEATURE_CLEAR_BHB_HW)) { | ||
| 1534 | /* | ||
| 1535 | * Add an Indirect Branch History Fence (IBHF). IBHF acts as a | ||
| 1536 | * fence preventing branch history from before the fence from | ||
| 1537 | * affecting indirect branches after the fence. This is | ||
| 1538 | * specifically used in cBPF jitted code to prevent Intra-mode | ||
| 1539 | * BHI attacks. The IBHF instruction is designed to be a NOP on | ||
| 1540 | * hardware that doesn't need or support it. The REP and REX.W | ||
| 1541 | * prefixes are required by the microcode, and they also ensure | ||
| 1542 | * that the NOP is unlikely to be used in existing code. | ||
| 1543 | * | ||
| 1544 | * IBHF is not a valid instruction in 32-bit mode. | ||
| 1545 | */ | ||
| 1546 | EMIT5(0xF3, 0x48, 0x0F, 0x1E, 0xF8); /* ibhf */ | ||
| 1547 | } | ||
| 1548 | *pprog = prog; | ||
| 1549 | return 0; | ||
| 1550 | } | ||
| 1551 | |||
| 1505 | static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, | 1552 | static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, |
| 1506 | int oldproglen, struct jit_context *ctx, bool jmp_padding) | 1553 | int oldproglen, struct jit_context *ctx, bool jmp_padding) |
| 1507 | { | 1554 | { |
| @@ -2544,6 +2591,13 @@ emit_jmp: · 1036 unmodified lines | |||
| 2544 | seen_exit = true; | 2591 | seen_exit = true; |
| 2545 | /* Update cleanup_addr */ | 2592 | /* Update cleanup_addr */ |
| 2546 | ctx->cleanup_addr = proglen; | 2593 | ctx->cleanup_addr = proglen; |
| 2594 | if (bpf_prog_was_classic(bpf_prog) && | ||
| 2595 | !capable(CAP_SYS_ADMIN)) { | ||
| 2596 | u8 *ip = image + addrs[i - 1]; | ||
| 2597 | |||
| 2598 | if (emit_spectre_bhb_barrier(&prog, ip, bpf_prog)) | ||
| 2599 | return -EINVAL; | ||
| 2600 | } | ||
| 2547 | if (bpf_prog->aux->exception_boundary) { | 2601 | if (bpf_prog->aux->exception_boundary) { |
| 2548 | pop_callee_regs(&prog, all_callee_regs_used); | 2602 | pop_callee_regs(&prog, all_callee_regs_used); |
| 2549 | pop_r12(&prog); | 2603 | pop_r12(&prog); |
| @@ -73,7 +73,7 @@ int __init efi_alloc_page_tables(void) · 72 unmodified lines | |||
| 73 | gfp_t gfp_mask; | 73 | gfp_t gfp_mask; |
| 74 | 74 | ||
| 75 | gfp_mask = GFP_KERNEL | __GFP_ZERO; | 75 | gfp_mask = GFP_KERNEL | __GFP_ZERO; |
| 76 | efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); | 76 | efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, pgd_allocation_order()); |
| 77 | if (!efi_pgd) | 77 | if (!efi_pgd) |
| 78 | goto fail; | 78 | goto fail; |
| 79 | 79 | ||
| @@ -96,7 +96,7 @@ free_p4d: · 16 unmodified lines | |||
| 96 | if (pgtable_l5_enabled()) | 96 | if (pgtable_l5_enabled()) |
| 97 | free_page((unsigned long)pgd_page_vaddr(*pgd)); | 97 | free_page((unsigned long)pgd_page_vaddr(*pgd)); |
| 98 | free_pgd: | 98 | free_pgd: |
| 99 | free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); | 99 | free_pages((unsigned long)efi_pgd, pgd_allocation_order()); |
| 100 | fail: | 100 | fail: |
| 101 | return -ENOMEM; | 101 | return -ENOMEM; |
| 102 | } | 102 | } |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | /* code below belongs to the image kernel */ | 26 | /* code below belongs to the image kernel */ |
| 27 | .align PAGE_SIZE | 27 | .align PAGE_SIZE |
| 28 | SYM_FUNC_START(restore_registers) | 28 | SYM_FUNC_START(restore_registers) |
| 29 | ANNOTATE_NOENDBR | 29 | ENDBR |
| 30 | /* go back to the original page tables */ | 30 | /* go back to the original page tables */ |
| 31 | movq %r9, %cr3 | 31 | movq %r9, %cr3 |
| 32 | 32 | ||
| @@ -120,7 +120,7 @@ SYM_FUNC_END(restore_image) · 87 unmodified lines | |||
| 120 | 120 | ||
| 121 | /* code below has been relocated to a safe page */ | 121 | /* code below has been relocated to a safe page */ |
| 122 | SYM_FUNC_START(core_restore_code) | 122 | SYM_FUNC_START(core_restore_code) |
| 123 | ANNOTATE_NOENDBR | 123 | ENDBR |
| 124 | /* switch to temporary page tables */ | 124 | /* switch to temporary page tables */ |
| 125 | movq %rax, %cr3 | 125 | movq %rax, %cr3 |
| 126 | /* flush TLB */ | 126 | /* flush TLB */ |
| @@ -31,8 +31,8 @@ struct faultinfo { · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | #define ___backtrack_faulted(_faulted) \ | 32 | #define ___backtrack_faulted(_faulted) \ |
| 33 | asm volatile ( \ | 33 | asm volatile ( \ |
| 34 | "mov $0, %0\n" \ | ||
| 35 | "movl $__get_kernel_nofault_faulted_%=,%1\n" \ | 34 | "movl $__get_kernel_nofault_faulted_%=,%1\n" \ |
| 35 | "mov $0, %0\n" \ | ||
| 36 | "jmp _end_%=\n" \ | 36 | "jmp _end_%=\n" \ |
| 37 | "__get_kernel_nofault_faulted_%=:\n" \ | 37 | "__get_kernel_nofault_faulted_%=:\n" \ |
| 38 | "mov $1, %0;" \ | 38 | "mov $1, %0;" \ |
| @@ -31,8 +31,8 @@ struct faultinfo { · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | #define ___backtrack_faulted(_faulted) \ | 32 | #define ___backtrack_faulted(_faulted) \ |
| 33 | asm volatile ( \ | 33 | asm volatile ( \ |
| 34 | "mov $0, %0\n" \ | ||
| 35 | "movq $__get_kernel_nofault_faulted_%=,%1\n" \ | 34 | "movq $__get_kernel_nofault_faulted_%=,%1\n" \ |
| 35 | "mov $0, %0\n" \ | ||
| 36 | "jmp _end_%=\n" \ | 36 | "jmp _end_%=\n" \ |
| 37 | "__get_kernel_nofault_faulted_%=:\n" \ | 37 | "__get_kernel_nofault_faulted_%=:\n" \ |
| 38 | "mov $1, %0;" \ | 38 | "mov $1, %0;" \ |
| @@ -70,6 +70,9 @@ EXPORT_SYMBOL(xen_start_flags); · 69 unmodified lines | |||
| 70 | */ | 70 | */ |
| 71 | struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info; | 71 | struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info; |
| 72 | 72 | ||
| 73 | /* Number of pages released from the initial allocation. */ | ||
| 74 | unsigned long xen_released_pages; | ||
| 75 | |||
| 73 | static __ref void xen_get_vendor(void) | 76 | static __ref void xen_get_vendor(void) |
| 74 | { | 77 | { |
| 75 | init_cpu_devs(); | 78 | init_cpu_devs(); |
| @@ -100,10 +103,6 @@ noinstr void *__xen_hypercall_setfunc(void) · 24 unmodified lines | |||
| 100 | void (*func)(void); | 103 | void (*func)(void); |
| 101 | 104 | ||
| 102 | /* | 105 | /* |
| 103 | * Xen is supported only on CPUs with CPUID, so testing for | ||
| 104 | * X86_FEATURE_CPUID is a test for early_cpu_init() having been | ||
| 105 | * run. | ||
| 106 | * | ||
| 107 | * Note that __xen_hypercall_setfunc() is noinstr only due to a nasty | 106 | * Note that __xen_hypercall_setfunc() is noinstr only due to a nasty |
| 108 | * dependency chain: it is being called via the xen_hypercall static | 107 | * dependency chain: it is being called via the xen_hypercall static |
| 109 | * call when running as a PVH or HVM guest. Hypercalls need to be | 108 | * call when running as a PVH or HVM guest. Hypercalls need to be |
| @@ -115,8 +114,7 @@ noinstr void *__xen_hypercall_setfunc(void) · 5 unmodified lines | |||
| 115 | */ | 114 | */ |
| 116 | instrumentation_begin(); | 115 | instrumentation_begin(); |
| 117 | 116 | ||
| 118 | if (!boot_cpu_has(X86_FEATURE_CPUID)) | 117 | xen_get_vendor(); |
| 119 | xen_get_vendor(); | ||
| 120 | 118 | ||
| 121 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD || | 119 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD || |
| 122 | boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) | 120 | boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) |
| @@ -466,6 +464,13 @@ int __init arch_xen_unpopulated_init(struct resource **res) · 343 unmodified lines | |||
| 466 | xen_free_unpopulated_pages(1, &pg); | 464 | xen_free_unpopulated_pages(1, &pg); |
| 467 | } | 465 | } |
| 468 | 466 | ||
| 467 | /* | ||
| 468 | * Account for the region being in the physmap but unpopulated. | ||
| 469 | * The value in xen_released_pages is used by the balloon | ||
| 470 | * driver to know how much of the physmap is unpopulated and | ||
| 471 | * set an accurate initial memory target. | ||
| 472 | */ | ||
| 473 | xen_released_pages += xen_extra_mem[i].n_pfns; | ||
| 469 | /* Zero so region is not also added to the balloon driver. */ | 474 | /* Zero so region is not also added to the balloon driver. */ |
| 470 | xen_extra_mem[i].n_pfns = 0; | 475 | xen_extra_mem[i].n_pfns = 0; |
| 471 | } | 476 | } |
| @@ -1,5 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/acpi.h> | 2 | #include <linux/acpi.h> |
| 3 | #include <linux/cpufreq.h> | ||
| 4 | #include <linux/cpuidle.h> | ||
| 3 | #include <linux/export.h> | 5 | #include <linux/export.h> |
| 4 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
| 5 | 7 | ||
| @@ -123,8 +125,23 @@ static void __init pvh_arch_setup(void) · 117 unmodified lines | |||
| 123 | { | 125 | { |
| 124 | pvh_reserve_extra_memory(); | 126 | pvh_reserve_extra_memory(); |
| 125 | 127 | ||
| 126 | if (xen_initial_domain()) | 128 | if (xen_initial_domain()) { |
| 127 | xen_add_preferred_consoles(); | 129 | xen_add_preferred_consoles(); |
| 130 | |||
| 131 | /* | ||
| 132 | * Disable usage of CPU idle and frequency drivers: when | ||
| 133 | * running as hardware domain the exposed native ACPI tables | ||
| 134 | * causes idle and/or frequency drivers to attach and | ||
| 135 | * malfunction. It's Xen the entity that controls the idle and | ||
| 136 | * frequency states. | ||
| 137 | * | ||
| 138 | * For unprivileged domains the exposed ACPI tables are | ||
| 139 | * fabricated and don't contain such data. | ||
| 140 | */ | ||
| 141 | disable_cpuidle(); | ||
| 142 | disable_cpufreq(); | ||
| 143 | WARN_ON(xen_set_default_idle()); | ||
| 144 | } | ||
| 128 | } | 145 | } |
| 129 | 146 | ||
| 130 | void __init xen_pvh_init(struct boot_params *boot_params) | 147 | void __init xen_pvh_init(struct boot_params *boot_params) |
| @@ -54,14 +54,20 @@ struct mc_debug_data { · 53 unmodified lines | |||
| 54 | 54 | ||
| 55 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); | 55 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); |
| 56 | static struct mc_debug_data mc_debug_data_early __initdata; | 56 | static struct mc_debug_data mc_debug_data_early __initdata; |
| 57 | static DEFINE_PER_CPU(struct mc_debug_data *, mc_debug_data) = | ||
| 58 | &mc_debug_data_early; | ||
| 59 | static struct mc_debug_data __percpu *mc_debug_data_ptr; | 57 | static struct mc_debug_data __percpu *mc_debug_data_ptr; |
| 60 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); | 58 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); |
| 61 | 59 | ||
| 62 | static struct static_key mc_debug __ro_after_init; | 60 | static struct static_key mc_debug __ro_after_init; |
| 63 | static bool mc_debug_enabled __initdata; | 61 | static bool mc_debug_enabled __initdata; |
| 64 | 62 | ||
| 63 | static struct mc_debug_data * __ref get_mc_debug(void) | ||
| 64 | { | ||
| 65 | if (!mc_debug_data_ptr) | ||
| 66 | return &mc_debug_data_early; | ||
| 67 | |||
| 68 | return this_cpu_ptr(mc_debug_data_ptr); | ||
| 69 | } | ||
| 70 | |||
| 65 | static int __init xen_parse_mc_debug(char *arg) | 71 | static int __init xen_parse_mc_debug(char *arg) |
| 66 | { | 72 | { |
| 67 | mc_debug_enabled = true; | 73 | mc_debug_enabled = true; |
| @@ -71,20 +77,16 @@ static int __init xen_parse_mc_debug(char *arg) · 3 unmodified lines | |||
| 71 | } | 77 | } |
| 72 | early_param("xen_mc_debug", xen_parse_mc_debug); | 78 | early_param("xen_mc_debug", xen_parse_mc_debug); |
| 73 | 79 | ||
| 74 | void mc_percpu_init(unsigned int cpu) | ||
| 75 | { | ||
| 76 | per_cpu(mc_debug_data, cpu) = per_cpu_ptr(mc_debug_data_ptr, cpu); | ||
| 77 | } | ||
| 78 | |||
| 79 | static int __init mc_debug_enable(void) | 80 | static int __init mc_debug_enable(void) |
| 80 | { | 81 | { |
| 81 | unsigned long flags; | 82 | unsigned long flags; |
| 83 | struct mc_debug_data __percpu *mcdb; | ||
| 82 | 84 | ||
| 83 | if (!mc_debug_enabled) | 85 | if (!mc_debug_enabled) |
| 84 | return 0; | 86 | return 0; |
| 85 | 87 | ||
| 86 | mc_debug_data_ptr = alloc_percpu(struct mc_debug_data); | 88 | mcdb = alloc_percpu(struct mc_debug_data); |
| 87 | if (!mc_debug_data_ptr) { | 89 | if (!mcdb) { |
| 88 | pr_err("xen_mc_debug inactive\n"); | 90 | pr_err("xen_mc_debug inactive\n"); |
| 89 | static_key_slow_dec(&mc_debug); | 91 | static_key_slow_dec(&mc_debug); |
| 90 | return -ENOMEM; | 92 | return -ENOMEM; |
| @@ -93,7 +95,7 @@ static int __init mc_debug_enable(void) · 2 unmodified lines | |||
| 93 | /* Be careful when switching to percpu debug data. */ | 95 | /* Be careful when switching to percpu debug data. */ |
| 94 | local_irq_save(flags); | 96 | local_irq_save(flags); |
| 95 | xen_mc_flush(); | 97 | xen_mc_flush(); |
| 96 | mc_percpu_init(0); | 98 | mc_debug_data_ptr = mcdb; |
| 97 | local_irq_restore(flags); | 99 | local_irq_restore(flags); |
| 98 | 100 | ||
| 99 | pr_info("xen_mc_debug active\n"); | 101 | pr_info("xen_mc_debug active\n"); |
| @@ -155,7 +157,7 @@ void xen_mc_flush(void) · 55 unmodified lines | |||
| 155 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); | 157 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); |
| 156 | 158 | ||
| 157 | if (static_key_false(&mc_debug)) { | 159 | if (static_key_false(&mc_debug)) { |
| 158 | mcdb = __this_cpu_read(mc_debug_data); | 160 | mcdb = get_mc_debug(); |
| 159 | memcpy(mcdb->entries, b->entries, | 161 | memcpy(mcdb->entries, b->entries, |
| 160 | b->mcidx * sizeof(struct multicall_entry)); | 162 | b->mcidx * sizeof(struct multicall_entry)); |
| 161 | } | 163 | } |
| @@ -235,7 +237,7 @@ struct multicall_space __xen_mc_entry(size_t args) · 73 unmodified lines | |||
| 235 | 237 | ||
| 236 | ret.mc = &b->entries[b->mcidx]; | 238 | ret.mc = &b->entries[b->mcidx]; |
| 237 | if (static_key_false(&mc_debug)) { | 239 | if (static_key_false(&mc_debug)) { |
| 238 | struct mc_debug_data *mcdb = __this_cpu_read(mc_debug_data); | 240 | struct mc_debug_data *mcdb = get_mc_debug(); |
| 239 | 241 | ||
| 240 | mcdb->caller[b->mcidx] = __builtin_return_address(0); | 242 | mcdb->caller[b->mcidx] = __builtin_return_address(0); |
| 241 | mcdb->argsz[b->mcidx] = args; | 243 | mcdb->argsz[b->mcidx] = args; |
| @@ -37,9 +37,6 @@ · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) | 38 | #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) |
| 39 | 39 | ||
| 40 | /* Number of pages released from the initial allocation. */ | ||
| 41 | unsigned long xen_released_pages; | ||
| 42 | |||
| 43 | /* Memory map would allow PCI passthrough. */ | 40 | /* Memory map would allow PCI passthrough. */ |
| 44 | bool xen_pv_pci_possible; | 41 | bool xen_pv_pci_possible; |
| 45 | 42 | ||
| @@ -305,7 +305,6 @@ static int xen_pv_kick_ap(unsigned int cpu, struct task_struct *idle) · 304 unmodified lines | |||
| 305 | return rc; | 305 | return rc; |
| 306 | 306 | ||
| 307 | xen_pmu_init(cpu); | 307 | xen_pmu_init(cpu); |
| 308 | mc_percpu_init(cpu); | ||
| 309 | 308 | ||
| 310 | /* | 309 | /* |
| 311 | * Why is this a BUG? If the hypercall fails then everything can be | 310 | * Why is this a BUG? If the hypercall fails then everything can be |
| @@ -226,9 +226,7 @@ SYM_CODE_END(xen_early_idt_handler_array) · 225 unmodified lines | |||
| 226 | push %rax | 226 | push %rax |
| 227 | mov $__HYPERVISOR_iret, %eax | 227 | mov $__HYPERVISOR_iret, %eax |
| 228 | syscall /* Do the IRET. */ | 228 | syscall /* Do the IRET. */ |
| 229 | #ifdef CONFIG_MITIGATION_SLS | 229 | ud2 /* The SYSCALL should never return. */ |
| 230 | int3 | ||
| 231 | #endif | ||
| 232 | .endm | 230 | .endm |
| 233 | 231 | ||
| 234 | SYM_CODE_START(xen_iret) | 232 | SYM_CODE_START(xen_iret) |
| @@ -261,9 +261,6 @@ void xen_mc_callback(void (*fn)(void *), void *data); · 260 unmodified lines | |||
| 261 | */ | 261 | */ |
| 262 | struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size); | 262 | struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size); |
| 263 | 263 | ||
| 264 | /* Do percpu data initialization for multicalls. */ | ||
| 265 | void mc_percpu_init(unsigned int cpu); | ||
| 266 | |||
| 267 | extern bool is_xen_pmu; | 264 | extern bool is_xen_pmu; |
| 268 | 265 | ||
| 269 | irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id); | 266 | irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id); |
| @@ -152,27 +152,65 @@ static void set_init_blocksize(struct block_device *bdev) · 151 unmodified lines | |||
| 152 | get_order(bsize)); | 152 | get_order(bsize)); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int set_blocksize(struct file *file, int size) | 155 | /** |
| 156 | * bdev_validate_blocksize - check that this block size is acceptable | ||
| 157 | * @bdev: blockdevice to check | ||
| 158 | * @block_size: block size to check | ||
| 159 | * | ||
| 160 | * For block device users that do not use buffer heads or the block device | ||
| 161 | * page cache, make sure that this block size can be used with the device. | ||
| 162 | * | ||
| 163 | * Return: On success zero is returned, negative error code on failure. | ||
| 164 | */ | ||
| 165 | int bdev_validate_blocksize(struct block_device *bdev, int block_size) | ||
| 156 | { | 166 | { |
| 157 | struct inode *inode = file->f_mapping->host; | 167 | if (blk_validate_block_size(block_size)) |
| 158 | struct block_device *bdev = I_BDEV(inode); | ||
| 159 | |||
| 160 | if (blk_validate_block_size(size)) | ||
| 161 | return -EINVAL; | 168 | return -EINVAL; |
| 162 | 169 | ||
| 163 | /* Size cannot be smaller than the size supported by the device */ | 170 | /* Size cannot be smaller than the size supported by the device */ |
| 164 | if (size < bdev_logical_block_size(bdev)) | 171 | if (block_size < bdev_logical_block_size(bdev)) |
| 165 | return -EINVAL; | 172 | return -EINVAL; |
| 166 | 173 | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | EXPORT_SYMBOL_GPL(bdev_validate_blocksize); | ||
| 177 | |||
| 178 | int set_blocksize(struct file *file, int size) | ||
| 179 | { | ||
| 180 | struct inode *inode = file->f_mapping->host; | ||
| 181 | struct block_device *bdev = I_BDEV(inode); | ||
| 182 | int ret; | ||
| 183 | |||
| 184 | ret = bdev_validate_blocksize(bdev, size); | ||
| 185 | if (ret) | ||
| 186 | return ret; | ||
| 187 | |||
| 167 | if (!file->private_data) | 188 | if (!file->private_data) |
| 168 | return -EINVAL; | 189 | return -EINVAL; |
| 169 | 190 | ||
| 170 | /* Don't change the size if it is same as current */ | 191 | /* Don't change the size if it is same as current */ |
| 171 | if (inode->i_blkbits != blksize_bits(size)) { | 192 | if (inode->i_blkbits != blksize_bits(size)) { |
| 193 | /* | ||
| 194 | * Flush and truncate the pagecache before we reconfigure the | ||
| 195 | * mapping geometry because folio sizes are variable now. If a | ||
| 196 | * reader has already allocated a folio whose size is smaller | ||
| 197 | * than the new min_order but invokes readahead after the new | ||
| 198 | * min_order becomes visible, readahead will think there are | ||
| 199 | * "zero" blocks per folio and crash. Take the inode and | ||
| 200 | * invalidation locks to avoid racing with | ||
| 201 | * read/write/fallocate. | ||
| 202 | */ | ||
| 203 | inode_lock(inode); | ||
| 204 | filemap_invalidate_lock(inode->i_mapping); | ||
| 205 | |||
| 172 | sync_blockdev(bdev); | 206 | sync_blockdev(bdev); |
| 207 | kill_bdev(bdev); | ||
| 208 | |||
| 173 | inode->i_blkbits = blksize_bits(size); | 209 | inode->i_blkbits = blksize_bits(size); |
| 174 | mapping_set_folio_min_order(inode->i_mapping, get_order(size)); | 210 | mapping_set_folio_min_order(inode->i_mapping, get_order(size)); |
| 175 | kill_bdev(bdev); | 211 | kill_bdev(bdev); |
| 212 | filemap_invalidate_unlock(inode->i_mapping); | ||
| 213 | inode_unlock(inode); | ||
| 176 | } | 214 | } |
| 177 | return 0; | 215 | return 0; |
| 178 | } | 216 | } |
| @@ -777,13 +815,13 @@ static void blkdev_put_part(struct block_device *part) · 598 unmodified lines | |||
| 777 | blkdev_put_whole(whole); | 815 | blkdev_put_whole(whole); |
| 778 | } | 816 | } |
| 779 | 817 | ||
| 780 | struct block_device *blkdev_get_no_open(dev_t dev) | 818 | struct block_device *blkdev_get_no_open(dev_t dev, bool autoload) |
| 781 | { | 819 | { |
| 782 | struct block_device *bdev; | 820 | struct block_device *bdev; |
| 783 | struct inode *inode; | 821 | struct inode *inode; |
| 784 | 822 | ||
| 785 | inode = ilookup(blockdev_superblock, dev); | 823 | inode = ilookup(blockdev_superblock, dev); |
| 786 | if (!inode && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) { | 824 | if (!inode && autoload && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) { |
| 787 | blk_request_module(dev); | 825 | blk_request_module(dev); |
| 788 | inode = ilookup(blockdev_superblock, dev); | 826 | inode = ilookup(blockdev_superblock, dev); |
| 789 | if (inode) | 827 | if (inode) |
| @@ -1005,7 +1043,7 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder, · 215 unmodified lines | |||
| 1005 | if (ret) | 1043 | if (ret) |
| 1006 | return ERR_PTR(ret); | 1044 | return ERR_PTR(ret); |
| 1007 | 1045 | ||
| 1008 | bdev = blkdev_get_no_open(dev); | 1046 | bdev = blkdev_get_no_open(dev, true); |
| 1009 | if (!bdev) | 1047 | if (!bdev) |
| 1010 | return ERR_PTR(-ENXIO); | 1048 | return ERR_PTR(-ENXIO); |
| 1011 | 1049 | ||
| @@ -1272,21 +1310,17 @@ void sync_bdevs(bool wait) · 260 unmodified lines | |||
| 1272 | /* | 1310 | /* |
| 1273 | * Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices. | 1311 | * Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices. |
| 1274 | */ | 1312 | */ |
| 1275 | void bdev_statx(struct path *path, struct kstat *stat, | 1313 | void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask) |
| 1276 | u32 request_mask) | ||
| 1277 | { | 1314 | { |
| 1278 | struct inode *backing_inode; | ||
| 1279 | struct block_device *bdev; | 1315 | struct block_device *bdev; |
| 1280 | 1316 | ||
| 1281 | backing_inode = d_backing_inode(path->dentry); | ||
| 1282 | |||
| 1283 | /* | 1317 | /* |
| 1284 | * Note that backing_inode is the inode of a block device node file, | 1318 | * Note that d_backing_inode() returns the block device node inode, not |
| 1285 | * not the block device's internal inode. Therefore it is *not* valid | 1319 | * the block device's internal inode. Therefore it is *not* valid to |
| 1286 | * to use I_BDEV() here; the block device has to be looked up by i_rdev | 1320 | * use I_BDEV() here; the block device has to be looked up by i_rdev |
| 1287 | * instead. | 1321 | * instead. |
| 1288 | */ | 1322 | */ |
| 1289 | bdev = blkdev_get_no_open(backing_inode->i_rdev); | 1323 | bdev = blkdev_get_no_open(d_backing_inode(path->dentry)->i_rdev, false); |
| 1290 | if (!bdev) | 1324 | if (!bdev) |
| 1291 | return; | 1325 | return; |
| 1292 | 1326 | ||
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | * not aware of PI. | 9 | * not aware of PI. |
| 10 | */ | 10 | */ |
| 11 | #include <linux/blk-integrity.h> | 11 | #include <linux/blk-integrity.h> |
| 12 | #include <linux/t10-pi.h> | ||
| 12 | #include <linux/workqueue.h> | 13 | #include <linux/workqueue.h> |
| 13 | #include "blk.h" | 14 | #include "blk.h" |
| 14 | 15 | ||
| @@ -43,6 +44,29 @@ static void bio_integrity_verify_fn(struct work_struct *work) · 28 unmodified lines | |||
| 43 | bio_endio(bio); | 44 | bio_endio(bio); |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 47 | #define BIP_CHECK_FLAGS (BIP_CHECK_GUARD | BIP_CHECK_REFTAG | BIP_CHECK_APPTAG) | ||
| 48 | static bool bip_should_check(struct bio_integrity_payload *bip) | ||
| 49 | { | ||
| 50 | return bip->bip_flags & BIP_CHECK_FLAGS; | ||
| 51 | } | ||
| 52 | |||
| 53 | static bool bi_offload_capable(struct blk_integrity *bi) | ||
| 54 | { | ||
| 55 | switch (bi->csum_type) { | ||
| 56 | case BLK_INTEGRITY_CSUM_CRC64: | ||
| 57 | return bi->tuple_size == sizeof(struct crc64_pi_tuple); | ||
| 58 | case BLK_INTEGRITY_CSUM_CRC: | ||
| 59 | case BLK_INTEGRITY_CSUM_IP: | ||
| 60 | return bi->tuple_size == sizeof(struct t10_pi_tuple); | ||
| 61 | default: | ||
| 62 | pr_warn_once("%s: unknown integrity checksum type:%d\n", | ||
| 63 | __func__, bi->csum_type); | ||
| 64 | fallthrough; | ||
| 65 | case BLK_INTEGRITY_CSUM_NONE: | ||
| 66 | return false; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 46 | /** | 70 | /** |
| 47 | * __bio_integrity_endio - Integrity I/O completion function | 71 | * __bio_integrity_endio - Integrity I/O completion function |
| 48 | * @bio: Protected bio | 72 | * @bio: Protected bio |
| @@ -54,12 +78,12 @@ static void bio_integrity_verify_fn(struct work_struct *work) · 5 unmodified lines | |||
| 54 | */ | 78 | */ |
| 55 | bool __bio_integrity_endio(struct bio *bio) | 79 | bool __bio_integrity_endio(struct bio *bio) |
| 56 | { | 80 | { |
| 57 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); | ||
| 58 | struct bio_integrity_payload *bip = bio_integrity(bio); | 81 | struct bio_integrity_payload *bip = bio_integrity(bio); |
| 59 | struct bio_integrity_data *bid = | 82 | struct bio_integrity_data *bid = |
| 60 | container_of(bip, struct bio_integrity_data, bip); | 83 | container_of(bip, struct bio_integrity_data, bip); |
| 61 | 84 | ||
| 62 | if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && bi->csum_type) { | 85 | if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && |
| 86 | bip_should_check(bip)) { | ||
| 63 | INIT_WORK(&bid->work, bio_integrity_verify_fn); | 87 | INIT_WORK(&bid->work, bio_integrity_verify_fn); |
| 64 | queue_work(kintegrityd_wq, &bid->work); | 88 | queue_work(kintegrityd_wq, &bid->work); |
| 65 | return false; | 89 | return false; |
| @@ -84,6 +108,7 @@ bool bio_integrity_prep(struct bio *bio) · 18 unmodified lines | |||
| 84 | { | 108 | { |
| 85 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); | 109 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); |
| 86 | struct bio_integrity_data *bid; | 110 | struct bio_integrity_data *bid; |
| 111 | bool set_flags = true; | ||
| 87 | gfp_t gfp = GFP_NOIO; | 112 | gfp_t gfp = GFP_NOIO; |
| 88 | unsigned int len; | 113 | unsigned int len; |
| 89 | void *buf; | 114 | void *buf; |
| @@ -100,19 +125,24 @@ bool bio_integrity_prep(struct bio *bio) · 10 unmodified lines | |||
| 100 | 125 | ||
| 101 | switch (bio_op(bio)) { | 126 | switch (bio_op(bio)) { |
| 102 | case REQ_OP_READ: | 127 | case REQ_OP_READ: |
| 103 | if (bi->flags & BLK_INTEGRITY_NOVERIFY) | 128 | if (bi->flags & BLK_INTEGRITY_NOVERIFY) { |
| 104 | return true; | 129 | if (bi_offload_capable(bi)) |
| 130 | return true; | ||
| 131 | set_flags = false; | ||
| 132 | } | ||
| 105 | break; | 133 | break; |
| 106 | case REQ_OP_WRITE: | 134 | case REQ_OP_WRITE: |
| 107 | if (bi->flags & BLK_INTEGRITY_NOGENERATE) | ||
| 108 | return true; | ||
| 109 | |||
| 110 | /* | 135 | /* |
| 111 | * Zero the memory allocated to not leak uninitialized kernel | 136 | * Zero the memory allocated to not leak uninitialized kernel |
| 112 | * memory to disk for non-integrity metadata where nothing else | 137 | * memory to disk for non-integrity metadata where nothing else |
| 113 | * initializes the memory. | 138 | * initializes the memory. |
| 114 | */ | 139 | */ |
| 115 | if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE) | 140 | if (bi->flags & BLK_INTEGRITY_NOGENERATE) { |
| 141 | if (bi_offload_capable(bi)) | ||
| 142 | return true; | ||
| 143 | set_flags = false; | ||
| 144 | gfp |= __GFP_ZERO; | ||
| 145 | } else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE) | ||
| 116 | gfp |= __GFP_ZERO; | 146 | gfp |= __GFP_ZERO; |
| 117 | break; | 147 | break; |
| 118 | default: | 148 | default: |
| @@ -137,19 +167,21 @@ bool bio_integrity_prep(struct bio *bio) · 18 unmodified lines | |||
| 137 | bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY; | 167 | bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY; |
| 138 | bip_set_seed(&bid->bip, bio->bi_iter.bi_sector); | 168 | bip_set_seed(&bid->bip, bio->bi_iter.bi_sector); |
| 139 | 169 | ||
| 140 | if (bi->csum_type == BLK_INTEGRITY_CSUM_IP) | 170 | if (set_flags) { |
| 141 | bid->bip.bip_flags |= BIP_IP_CHECKSUM; | 171 | if (bi->csum_type == BLK_INTEGRITY_CSUM_IP) |
| 142 | if (bi->csum_type) | 172 | bid->bip.bip_flags |= BIP_IP_CHECKSUM; |
| 143 | bid->bip.bip_flags |= BIP_CHECK_GUARD; | 173 | if (bi->csum_type) |
| 144 | if (bi->flags & BLK_INTEGRITY_REF_TAG) | 174 | bid->bip.bip_flags |= BIP_CHECK_GUARD; |
| 145 | bid->bip.bip_flags |= BIP_CHECK_REFTAG; | 175 | if (bi->flags & BLK_INTEGRITY_REF_TAG) |
| 176 | bid->bip.bip_flags |= BIP_CHECK_REFTAG; | ||
| 177 | } | ||
| 146 | 178 | ||
| 147 | if (bio_integrity_add_page(bio, virt_to_page(buf), len, | 179 | if (bio_integrity_add_page(bio, virt_to_page(buf), len, |
| 148 | offset_in_page(buf)) < len) | 180 | offset_in_page(buf)) < len) |
| 149 | goto err_end_io; | 181 | goto err_end_io; |
| 150 | 182 | ||
| 151 | /* Auto-generate integrity metadata if this is a write */ | 183 | /* Auto-generate integrity metadata if this is a write */ |
| 152 | if (bio_data_dir(bio) == WRITE) | 184 | if (bio_data_dir(bio) == WRITE && bip_should_check(&bid->bip)) |
| 153 | blk_integrity_generate(bio); | 185 | blk_integrity_generate(bio); |
| 154 | else | 186 | else |
| 155 | bid->saved_bio_iter = bio->bi_iter; | 187 | bid->saved_bio_iter = bio->bi_iter; |
| @@ -66,16 +66,12 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, · 65 unmodified lines | |||
| 66 | } | 66 | } |
| 67 | EXPORT_SYMBOL(bio_integrity_alloc); | 67 | EXPORT_SYMBOL(bio_integrity_alloc); |
| 68 | 68 | ||
| 69 | static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs, | 69 | static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs) |
| 70 | bool dirty) | ||
| 71 | { | 70 | { |
| 72 | int i; | 71 | int i; |
| 73 | 72 | ||
| 74 | for (i = 0; i < nr_vecs; i++) { | 73 | for (i = 0; i < nr_vecs; i++) |
| 75 | if (dirty && !PageCompound(bv[i].bv_page)) | ||
| 76 | set_page_dirty_lock(bv[i].bv_page); | ||
| 77 | unpin_user_page(bv[i].bv_page); | 74 | unpin_user_page(bv[i].bv_page); |
| 78 | } | ||
| 79 | } | 75 | } |
| 80 | 76 | ||
| 81 | static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip) | 77 | 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) · 9 unmodified lines | |||
| 91 | ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter); | 87 | ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter); |
| 92 | WARN_ON_ONCE(ret != bytes); | 88 | WARN_ON_ONCE(ret != bytes); |
| 93 | 89 | ||
| 94 | bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs, true); | 90 | bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs); |
| 95 | } | 91 | } |
| 96 | 92 | ||
| 97 | /** | 93 | /** |
| @@ -111,8 +107,7 @@ void bio_integrity_unmap_user(struct bio *bio) · 13 unmodified lines | |||
| 111 | return; | 107 | return; |
| 112 | } | 108 | } |
| 113 | 109 | ||
| 114 | bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt, | 110 | bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt); |
| 115 | bio_data_dir(bio) == READ); | ||
| 116 | } | 111 | } |
| 117 | 112 | ||
| 118 | /** | 113 | /** |
| @@ -198,7 +193,7 @@ static int bio_integrity_copy_user(struct bio *bio, struct bio_vec *bvec, · 79 unmodified lines | |||
| 198 | } | 193 | } |
| 199 | 194 | ||
| 200 | if (write) | 195 | if (write) |
| 201 | bio_integrity_unpin_bvec(bvec, nr_vecs, false); | 196 | bio_integrity_unpin_bvec(bvec, nr_vecs); |
| 202 | else | 197 | else |
| 203 | memcpy(&bip->bip_vec[1], bvec, nr_vecs * sizeof(*bvec)); | 198 | memcpy(&bip->bip_vec[1], bvec, nr_vecs * sizeof(*bvec)); |
| 204 | 199 | ||
| @@ -319,7 +314,7 @@ int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter) · 114 unmodified lines | |||
| 319 | return 0; | 314 | return 0; |
| 320 | 315 | ||
| 321 | release_pages: | 316 | release_pages: |
| 322 | bio_integrity_unpin_bvec(bvec, nr_bvecs, false); | 317 | bio_integrity_unpin_bvec(bvec, nr_bvecs); |
| 323 | free_bvec: | 318 | free_bvec: |
| 324 | if (bvec != stack_vec) | 319 | if (bvec != stack_vec) |
| 325 | kfree(bvec); | 320 | kfree(bvec); |
| @@ -611,7 +611,7 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask) · 610 unmodified lines | |||
| 611 | { | 611 | { |
| 612 | struct bio *bio; | 612 | struct bio *bio; |
| 613 | 613 | ||
| 614 | if (nr_vecs > UIO_MAXIOV) | 614 | if (nr_vecs > BIO_MAX_INLINE_VECS) |
| 615 | return NULL; | 615 | return NULL; |
| 616 | return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask); | 616 | return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask); |
| 617 | } | 617 | } |
| @@ -797,7 +797,7 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) · 796 unmodified lines | |||
| 797 | return -EINVAL; | 797 | return -EINVAL; |
| 798 | input = skip_spaces(input); | 798 | input = skip_spaces(input); |
| 799 | 799 | ||
| 800 | bdev = blkdev_get_no_open(MKDEV(major, minor)); | 800 | bdev = blkdev_get_no_open(MKDEV(major, minor), false); |
| 801 | if (!bdev) | 801 | if (!bdev) |
| 802 | return -ENODEV; | 802 | return -ENODEV; |
| 803 | if (bdev_is_partition(bdev)) { | 803 | if (bdev_is_partition(bdev)) { |
| @@ -61,8 +61,14 @@ void blk_apply_bdi_limits(struct backing_dev_info *bdi, · 60 unmodified lines | |||
| 61 | /* | 61 | /* |
| 62 | * For read-ahead of large files to be effective, we need to read ahead | 62 | * For read-ahead of large files to be effective, we need to read ahead |
| 63 | * at least twice the optimal I/O size. | 63 | * at least twice the optimal I/O size. |
| 64 | * | ||
| 65 | * There is no hardware limitation for the read-ahead size and the user | ||
| 66 | * might have increased the read-ahead size through sysfs, so don't ever | ||
| 67 | * decrease it. | ||
| 64 | */ | 68 | */ |
| 65 | bdi->ra_pages = max(lim->io_opt * 2 / PAGE_SIZE, VM_READAHEAD_PAGES); | 69 | bdi->ra_pages = max3(bdi->ra_pages, |
| 70 | lim->io_opt * 2 / PAGE_SIZE, | ||
| 71 | VM_READAHEAD_PAGES); | ||
| 66 | bdi->io_pages = lim->max_sectors >> PAGE_SECTORS_SHIFT; | 72 | bdi->io_pages = lim->max_sectors >> PAGE_SECTORS_SHIFT; |
| 67 | } | 73 | } |
| 68 | 74 | ||
| @@ -909,6 +909,8 @@ out_unregister_ia_ranges: · 908 unmodified lines | |||
| 909 | out_debugfs_remove: | 909 | out_debugfs_remove: |
| 910 | blk_debugfs_remove(disk); | 910 | blk_debugfs_remove(disk); |
| 911 | mutex_unlock(&q->sysfs_lock); | 911 | mutex_unlock(&q->sysfs_lock); |
| 912 | if (queue_is_mq(q)) | ||
| 913 | blk_mq_sysfs_unregister(disk); | ||
| 912 | out_put_queue_kobj: | 914 | out_put_queue_kobj: |
| 913 | kobject_put(&disk->queue_kobj); | 915 | kobject_put(&disk->queue_kobj); |
| 914 | return ret; | 916 | return ret; |
| @@ -1,3 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 1 | #ifndef BLK_THROTTLE_H | 2 | #ifndef BLK_THROTTLE_H |
| 2 | #define BLK_THROTTLE_H | 3 | #define BLK_THROTTLE_H |
| 3 | 4 | ||
| @@ -343,6 +343,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode, · 342 unmodified lines | |||
| 343 | op = REQ_OP_ZONE_RESET; | 343 | op = REQ_OP_ZONE_RESET; |
| 344 | 344 | ||
| 345 | /* Invalidate the page cache, including dirty pages. */ | 345 | /* Invalidate the page cache, including dirty pages. */ |
| 346 | inode_lock(bdev->bd_mapping->host); | ||
| 346 | filemap_invalidate_lock(bdev->bd_mapping); | 347 | filemap_invalidate_lock(bdev->bd_mapping); |
| 347 | ret = blkdev_truncate_zone_range(bdev, mode, &zrange); | 348 | ret = blkdev_truncate_zone_range(bdev, mode, &zrange); |
| 348 | if (ret) | 349 | if (ret) |
| @@ -364,8 +365,10 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode, · 15 unmodified lines | |||
| 364 | ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors); | 365 | ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors); |
| 365 | 366 | ||
| 366 | fail: | 367 | fail: |
| 367 | if (cmd == BLKRESETZONE) | 368 | if (cmd == BLKRESETZONE) { |
| 368 | filemap_invalidate_unlock(bdev->bd_mapping); | 369 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 370 | inode_unlock(bdev->bd_mapping->host); | ||
| 371 | } | ||
| 369 | 372 | ||
| 370 | return ret; | 373 | return ret; |
| 371 | } | 374 | } |
| @@ -94,6 +94,9 @@ static inline void blk_wait_io(struct completion *done) · 93 unmodified lines | |||
| 94 | wait_for_completion_io(done); | 94 | wait_for_completion_io(done); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | struct block_device *blkdev_get_no_open(dev_t dev, bool autoload); | ||
| 98 | void blkdev_put_no_open(struct block_device *bdev); | ||
| 99 | |||
| 97 | #define BIO_INLINE_VECS 4 | 100 | #define BIO_INLINE_VECS 4 |
| 98 | struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs, | 101 | struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs, |
| 99 | gfp_t gfp_mask); | 102 | gfp_t gfp_mask); |
| @@ -477,7 +480,8 @@ static inline void blk_zone_update_request_bio(struct request *rq, · 377 unmodified lines | |||
| 477 | * the original BIO sector so that blk_zone_write_plug_bio_endio() can | 480 | * the original BIO sector so that blk_zone_write_plug_bio_endio() can |
| 478 | * lookup the zone write plug. | 481 | * lookup the zone write plug. |
| 479 | */ | 482 | */ |
| 480 | if (req_op(rq) == REQ_OP_ZONE_APPEND || bio_zone_write_plugging(bio)) | 483 | if (req_op(rq) == REQ_OP_ZONE_APPEND || |
| 484 | bio_flagged(bio, BIO_EMULATES_ZONE_APPEND)) | ||
| 481 | bio->bi_iter.bi_sector = rq->__sector; | 485 | bio->bi_iter.bi_sector = rq->__sector; |
| 482 | } | 486 | } |
| 483 | void blk_zone_write_plug_bio_endio(struct bio *bio); | 487 | void blk_zone_write_plug_bio_endio(struct bio *bio); |
| @@ -642,7 +642,7 @@ static int blkdev_open(struct inode *inode, struct file *filp) · 641 unmodified lines | |||
| 642 | if (ret) | 642 | if (ret) |
| 643 | return ret; | 643 | return ret; |
| 644 | 644 | ||
| 645 | bdev = blkdev_get_no_open(inode->i_rdev); | 645 | bdev = blkdev_get_no_open(inode->i_rdev, true); |
| 646 | if (!bdev) | 646 | if (!bdev) |
| 647 | return -ENXIO; | 647 | return -ENXIO; |
| 648 | 648 | ||
| @@ -746,7 +746,14 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) · 97 unmodified lines | |||
| 746 | ret = direct_write_fallback(iocb, from, ret, | 746 | ret = direct_write_fallback(iocb, from, ret, |
| 747 | blkdev_buffered_write(iocb, from)); | 747 | blkdev_buffered_write(iocb, from)); |
| 748 | } else { | 748 | } else { |
| 749 | /* | ||
| 750 | * Take i_rwsem and invalidate_lock to avoid racing with | ||
| 751 | * set_blocksize changing i_blkbits/folio order and punching | ||
| 752 | * out the pagecache. | ||
| 753 | */ | ||
| 754 | inode_lock_shared(bd_inode); | ||
| 749 | ret = blkdev_buffered_write(iocb, from); | 755 | ret = blkdev_buffered_write(iocb, from); |
| 756 | inode_unlock_shared(bd_inode); | ||
| 750 | } | 757 | } |
| 751 | 758 | ||
| 752 | if (ret > 0) | 759 | if (ret > 0) |
| @@ -757,6 +764,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) · 4 unmodified lines | |||
| 757 | 764 | ||
| 758 | static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) | 765 | static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) |
| 759 | { | 766 | { |
| 767 | struct inode *bd_inode = bdev_file_inode(iocb->ki_filp); | ||
| 760 | struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); | 768 | struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); |
| 761 | loff_t size = bdev_nr_bytes(bdev); | 769 | loff_t size = bdev_nr_bytes(bdev); |
| 762 | loff_t pos = iocb->ki_pos; | 770 | loff_t pos = iocb->ki_pos; |
| @@ -793,7 +801,13 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) · 30 unmodified lines | |||
| 793 | goto reexpand; | 801 | goto reexpand; |
| 794 | } | 802 | } |
| 795 | 803 | ||
| 804 | /* | ||
| 805 | * Take i_rwsem and invalidate_lock to avoid racing with set_blocksize | ||
| 806 | * changing i_blkbits/folio order and punching out the pagecache. | ||
| 807 | */ | ||
| 808 | inode_lock_shared(bd_inode); | ||
| 796 | ret = filemap_read(iocb, to, ret); | 809 | ret = filemap_read(iocb, to, ret); |
| 810 | inode_unlock_shared(bd_inode); | ||
| 797 | 811 | ||
| 798 | reexpand: | 812 | reexpand: |
| 799 | if (unlikely(shorted)) | 813 | if (unlikely(shorted)) |
| @@ -836,6 +850,7 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start, · 36 unmodified lines | |||
| 836 | if ((start | len) & (bdev_logical_block_size(bdev) - 1)) | 850 | if ((start | len) & (bdev_logical_block_size(bdev) - 1)) |
| 837 | return -EINVAL; | 851 | return -EINVAL; |
| 838 | 852 | ||
| 853 | inode_lock(inode); | ||
| 839 | filemap_invalidate_lock(inode->i_mapping); | 854 | filemap_invalidate_lock(inode->i_mapping); |
| 840 | 855 | ||
| 841 | /* | 856 | /* |
| @@ -868,6 +883,7 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start, · 26 unmodified lines | |||
| 868 | 883 | ||
| 869 | fail: | 884 | fail: |
| 870 | filemap_invalidate_unlock(inode->i_mapping); | 885 | filemap_invalidate_unlock(inode->i_mapping); |
| 886 | inode_unlock(inode); | ||
| 871 | return error; | 887 | return error; |
| 872 | } | 888 | } |
| 873 | 889 | ||
| @@ -142,6 +142,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, · 141 unmodified lines | |||
| 142 | if (err) | 142 | if (err) |
| 143 | return err; | 143 | return err; |
| 144 | 144 | ||
| 145 | inode_lock(bdev->bd_mapping->host); | ||
| 145 | filemap_invalidate_lock(bdev->bd_mapping); | 146 | filemap_invalidate_lock(bdev->bd_mapping); |
| 146 | err = truncate_bdev_range(bdev, mode, start, start + len - 1); | 147 | err = truncate_bdev_range(bdev, mode, start, start + len - 1); |
| 147 | if (err) | 148 | if (err) |
| @@ -174,6 +175,7 @@ out_unplug: · 26 unmodified lines | |||
| 174 | blk_finish_plug(&plug); | 175 | blk_finish_plug(&plug); |
| 175 | fail: | 176 | fail: |
| 176 | filemap_invalidate_unlock(bdev->bd_mapping); | 177 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 178 | inode_unlock(bdev->bd_mapping->host); | ||
| 177 | return err; | 179 | return err; |
| 178 | } | 180 | } |
| 179 | 181 | ||
| @@ -199,12 +201,14 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode, · 19 unmodified lines | |||
| 199 | end > bdev_nr_bytes(bdev)) | 201 | end > bdev_nr_bytes(bdev)) |
| 200 | return -EINVAL; | 202 | return -EINVAL; |
| 201 | 203 | ||
| 204 | inode_lock(bdev->bd_mapping->host); | ||
| 202 | filemap_invalidate_lock(bdev->bd_mapping); | 205 | filemap_invalidate_lock(bdev->bd_mapping); |
| 203 | err = truncate_bdev_range(bdev, mode, start, end - 1); | 206 | err = truncate_bdev_range(bdev, mode, start, end - 1); |
| 204 | if (!err) | 207 | if (!err) |
| 205 | err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9, | 208 | err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9, |
| 206 | GFP_KERNEL); | 209 | GFP_KERNEL); |
| 207 | filemap_invalidate_unlock(bdev->bd_mapping); | 210 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 211 | inode_unlock(bdev->bd_mapping->host); | ||
| 208 | return err; | 212 | return err; |
| 209 | } | 213 | } |
| 210 | 214 | ||
| @@ -236,6 +240,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode, · 25 unmodified lines | |||
| 236 | return -EINVAL; | 240 | return -EINVAL; |
| 237 | 241 | ||
| 238 | /* Invalidate the page cache, including dirty pages */ | 242 | /* Invalidate the page cache, including dirty pages */ |
| 243 | inode_lock(bdev->bd_mapping->host); | ||
| 239 | filemap_invalidate_lock(bdev->bd_mapping); | 244 | filemap_invalidate_lock(bdev->bd_mapping); |
| 240 | err = truncate_bdev_range(bdev, mode, start, end); | 245 | err = truncate_bdev_range(bdev, mode, start, end); |
| 241 | if (err) | 246 | if (err) |
| @@ -246,6 +251,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode, · 4 unmodified lines | |||
| 246 | 251 | ||
| 247 | fail: | 252 | fail: |
| 248 | filemap_invalidate_unlock(bdev->bd_mapping); | 253 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 254 | inode_unlock(bdev->bd_mapping->host); | ||
| 249 | return err; | 255 | return err; |
| 250 | } | 256 | } |
| 251 | 257 | ||
| @@ -46,12 +46,8 @@ int ioprio_check_cap(int ioprio) · 45 unmodified lines | |||
| 46 | */ | 46 | */ |
| 47 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) | 47 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) |
| 48 | return -EPERM; | 48 | return -EPERM; |
| 49 | fallthrough; | ||
| 50 | /* rt has prio field too */ | ||
| 51 | case IOPRIO_CLASS_BE: | ||
| 52 | if (level >= IOPRIO_NR_LEVELS) | ||
| 53 | return -EINVAL; | ||
| 54 | break; | 49 | break; |
| 50 | case IOPRIO_CLASS_BE: | ||
| 55 | case IOPRIO_CLASS_IDLE: | 51 | case IOPRIO_CLASS_IDLE: |
| 56 | break; | 52 | break; |
| 57 | case IOPRIO_CLASS_NONE: | 53 | case IOPRIO_CLASS_NONE: |
| @@ -315,16 +315,7 @@ EXPORT_SYMBOL_GPL(crypto_ahash_setkey); · 314 unmodified lines | |||
| 315 | 315 | ||
| 316 | static bool ahash_request_hasvirt(struct ahash_request *req) | 316 | static bool ahash_request_hasvirt(struct ahash_request *req) |
| 317 | { | 317 | { |
| 318 | struct ahash_request *r2; | 318 | return ahash_request_isvirt(req); |
| 319 | |||
| 320 | if (ahash_request_isvirt(req)) | ||
| 321 | return true; | ||
| 322 | |||
| 323 | list_for_each_entry(r2, &req->base.list, base.list) | ||
| 324 | if (ahash_request_isvirt(r2)) | ||
| 325 | return true; | ||
| 326 | |||
| 327 | return false; | ||
| 328 | } | 319 | } |
| 329 | 320 | ||
| 330 | static int ahash_reqchain_virt(struct ahash_save_req_state *state, | 321 | 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, · 141 unmodified lines | |||
| 472 | bool update = op == crypto_ahash_alg(tfm)->update; | 463 | bool update = op == crypto_ahash_alg(tfm)->update; |
| 473 | struct ahash_save_req_state *state; | 464 | struct ahash_save_req_state *state; |
| 474 | struct ahash_save_req_state state0; | 465 | struct ahash_save_req_state state0; |
| 475 | struct ahash_request *r2; | ||
| 476 | u8 *page = NULL; | 466 | u8 *page = NULL; |
| 477 | int err; | 467 | int err; |
| 478 | 468 | ||
| @@ -509,7 +499,6 @@ static int ahash_do_req_chain(struct ahash_request *req, · 30 unmodified lines | |||
| 509 | state->offset = 0; | 499 | state->offset = 0; |
| 510 | state->nbytes = 0; | 500 | state->nbytes = 0; |
| 511 | INIT_LIST_HEAD(&state->head); | 501 | INIT_LIST_HEAD(&state->head); |
| 512 | list_splice_init(&req->base.list, &state->head); | ||
| 513 | 502 | ||
| 514 | if (page) | 503 | if (page) |
| 515 | sg_init_one(&state->sg, page, PAGE_SIZE); | 504 | sg_init_one(&state->sg, page, PAGE_SIZE); |
| @@ -540,9 +529,6 @@ out_free_page: · 24 unmodified lines | |||
| 540 | 529 | ||
| 541 | out_set_chain: | 530 | out_set_chain: |
| 542 | req->base.err = err; | 531 | req->base.err = err; |
| 543 | list_for_each_entry(r2, &req->base.list, base.list) | ||
| 544 | r2->base.err = err; | ||
| 545 | |||
| 546 | return err; | 532 | return err; |
| 547 | } | 533 | } |
| 548 | 534 | ||
| @@ -551,19 +537,10 @@ int crypto_ahash_init(struct ahash_request *req) · 2 unmodified lines | |||
| 551 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 537 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 552 | 538 | ||
| 553 | if (likely(tfm->using_shash)) { | 539 | if (likely(tfm->using_shash)) { |
| 554 | struct ahash_request *r2; | ||
| 555 | int err; | 540 | int err; |
| 556 | 541 | ||
| 557 | err = crypto_shash_init(prepare_shash_desc(req, tfm)); | 542 | err = crypto_shash_init(prepare_shash_desc(req, tfm)); |
| 558 | req->base.err = err; | 543 | req->base.err = err; |
| 559 | |||
| 560 | list_for_each_entry(r2, &req->base.list, base.list) { | ||
| 561 | struct shash_desc *desc; | ||
| 562 | |||
| 563 | desc = prepare_shash_desc(r2, tfm); | ||
| 564 | r2->base.err = crypto_shash_init(desc); | ||
| 565 | } | ||
| 566 | |||
| 567 | return err; | 544 | return err; |
| 568 | } | 545 | } |
| 569 | 546 | ||
| @@ -620,19 +597,10 @@ int crypto_ahash_update(struct ahash_request *req) · 50 unmodified lines | |||
| 620 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 597 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 621 | 598 | ||
| 622 | if (likely(tfm->using_shash)) { | 599 | if (likely(tfm->using_shash)) { |
| 623 | struct ahash_request *r2; | ||
| 624 | int err; | 600 | int err; |
| 625 | 601 | ||
| 626 | err = shash_ahash_update(req, ahash_request_ctx(req)); | 602 | err = shash_ahash_update(req, ahash_request_ctx(req)); |
| 627 | req->base.err = err; | 603 | req->base.err = err; |
| 628 | |||
| 629 | list_for_each_entry(r2, &req->base.list, base.list) { | ||
| 630 | struct shash_desc *desc; | ||
| 631 | |||
| 632 | desc = ahash_request_ctx(r2); | ||
| 633 | r2->base.err = shash_ahash_update(r2, desc); | ||
| 634 | } | ||
| 635 | |||
| 636 | return err; | 604 | return err; |
| 637 | } | 605 | } |
| 638 | 606 | ||
| @@ -645,19 +613,10 @@ int crypto_ahash_final(struct ahash_request *req) · 6 unmodified lines | |||
| 645 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 613 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 646 | 614 | ||
| 647 | if (likely(tfm->using_shash)) { | 615 | if (likely(tfm->using_shash)) { |
| 648 | struct ahash_request *r2; | ||
| 649 | int err; | 616 | int err; |
| 650 | 617 | ||
| 651 | err = crypto_shash_final(ahash_request_ctx(req), req->result); | 618 | err = crypto_shash_final(ahash_request_ctx(req), req->result); |
| 652 | req->base.err = err; | 619 | req->base.err = err; |
| 653 | |||
| 654 | list_for_each_entry(r2, &req->base.list, base.list) { | ||
| 655 | struct shash_desc *desc; | ||
| 656 | |||
| 657 | desc = ahash_request_ctx(r2); | ||
| 658 | r2->base.err = crypto_shash_final(desc, r2->result); | ||
| 659 | } | ||
| 660 | |||
| 661 | return err; | 620 | return err; |
| 662 | } | 621 | } |
| 663 | 622 | ||
| @@ -670,19 +629,10 @@ int crypto_ahash_finup(struct ahash_request *req) · 6 unmodified lines | |||
| 670 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 629 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 671 | 630 | ||
| 672 | if (likely(tfm->using_shash)) { | 631 | if (likely(tfm->using_shash)) { |
| 673 | struct ahash_request *r2; | ||
| 674 | int err; | 632 | int err; |
| 675 | 633 | ||
| 676 | err = shash_ahash_finup(req, ahash_request_ctx(req)); | 634 | err = shash_ahash_finup(req, ahash_request_ctx(req)); |
| 677 | req->base.err = err; | 635 | req->base.err = err; |
| 678 | |||
| 679 | list_for_each_entry(r2, &req->base.list, base.list) { | ||
| 680 | struct shash_desc *desc; | ||
| 681 | |||
| 682 | desc = ahash_request_ctx(r2); | ||
| 683 | r2->base.err = shash_ahash_finup(r2, desc); | ||
| 684 | } | ||
| 685 | |||
| 686 | return err; | 636 | return err; |
| 687 | } | 637 | } |
| 688 | 638 | ||
| @@ -757,19 +707,10 @@ int crypto_ahash_digest(struct ahash_request *req) · 68 unmodified lines | |||
| 757 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 707 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 758 | 708 | ||
| 759 | if (likely(tfm->using_shash)) { | 709 | if (likely(tfm->using_shash)) { |
| 760 | struct ahash_request *r2; | ||
| 761 | int err; | 710 | int err; |
| 762 | 711 | ||
| 763 | err = shash_ahash_digest(req, prepare_shash_desc(req, tfm)); | 712 | err = shash_ahash_digest(req, prepare_shash_desc(req, tfm)); |
| 764 | req->base.err = err; | 713 | req->base.err = err; |
| 765 | |||
| 766 | list_for_each_entry(r2, &req->base.list, base.list) { | ||
| 767 | struct shash_desc *desc; | ||
| 768 | |||
| 769 | desc = prepare_shash_desc(r2, tfm); | ||
| 770 | r2->base.err = shash_ahash_digest(r2, desc); | ||
| 771 | } | ||
| 772 | |||
| 773 | return err; | 714 | return err; |
| 774 | } | 715 | } |
| 775 | 716 | ||
| @@ -1133,20 +1074,5 @@ int ahash_register_instance(struct crypto_template *tmpl, · 357 unmodified lines | |||
| 1133 | } | 1074 | } |
| 1134 | EXPORT_SYMBOL_GPL(ahash_register_instance); | 1075 | EXPORT_SYMBOL_GPL(ahash_register_instance); |
| 1135 | 1076 | ||
| 1136 | void ahash_request_free(struct ahash_request *req) | ||
| 1137 | { | ||
| 1138 | struct ahash_request *tmp; | ||
| 1139 | struct ahash_request *r2; | ||
| 1140 | |||
| 1141 | if (unlikely(!req)) | ||
| 1142 | return; | ||
| 1143 | |||
| 1144 | list_for_each_entry_safe(r2, tmp, &req->base.list, base.list) | ||
| 1145 | kfree_sensitive(r2); | ||
| 1146 | |||
| 1147 | kfree_sensitive(req); | ||
| 1148 | } | ||
| 1149 | EXPORT_SYMBOL_GPL(ahash_request_free); | ||
| 1150 | |||
| 1151 | MODULE_LICENSE("GPL"); | 1077 | MODULE_LICENSE("GPL"); |
| 1152 | MODULE_DESCRIPTION("Asynchronous cryptographic hash type"); | 1078 | MODULE_DESCRIPTION("Asynchronous cryptographic hash type"); |
| @@ -265,10 +265,6 @@ static int hash_accept(struct socket *sock, struct socket *newsock, · 264 unmodified lines | |||
| 265 | goto out_free_state; | 265 | goto out_free_state; |
| 266 | 266 | ||
| 267 | err = crypto_ahash_import(&ctx2->req, state); | 267 | err = crypto_ahash_import(&ctx2->req, state); |
| 268 | if (err) { | ||
| 269 | sock_orphan(sk2); | ||
| 270 | sock_put(sk2); | ||
| 271 | } | ||
| 272 | 268 | ||
| 273 | out_free_state: | 269 | out_free_state: |
| 274 | kfree_sensitive(state); | 270 | kfree_sensitive(state); |
| @@ -111,10 +111,14 @@ static void scomp_free_streams(struct scomp_alg *alg) · 110 unmodified lines | |||
| 111 | struct crypto_acomp_stream __percpu *stream = alg->stream; | 111 | struct crypto_acomp_stream __percpu *stream = alg->stream; |
| 112 | int i; | 112 | int i; |
| 113 | 113 | ||
| 114 | alg->stream = NULL; | ||
| 115 | if (!stream) | ||
| 116 | return; | ||
| 117 | |||
| 114 | for_each_possible_cpu(i) { | 118 | for_each_possible_cpu(i) { |
| 115 | struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i); | 119 | struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i); |
| 116 | 120 | ||
| 117 | if (!ps->ctx) | 121 | if (IS_ERR_OR_NULL(ps->ctx)) |
| 118 | break; | 122 | break; |
| 119 | 123 | ||
| 120 | alg->free_ctx(ps->ctx); | 124 | alg->free_ctx(ps->ctx); |
| @@ -132,6 +136,8 @@ static int scomp_alloc_streams(struct scomp_alg *alg) · 11 unmodified lines | |||
| 132 | if (!stream) | 136 | if (!stream) |
| 133 | return -ENOMEM; | 137 | return -ENOMEM; |
| 134 | 138 | ||
| 139 | alg->stream = stream; | ||
| 140 | |||
| 135 | for_each_possible_cpu(i) { | 141 | for_each_possible_cpu(i) { |
| 136 | struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i); | 142 | struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i); |
| 137 | 143 | ||
| @@ -143,8 +149,6 @@ static int scomp_alloc_streams(struct scomp_alg *alg) · 5 unmodified lines | |||
| 143 | 149 | ||
| 144 | spin_lock_init(&ps->lock); | 150 | spin_lock_init(&ps->lock); |
| 145 | } | 151 | } |
| 146 | |||
| 147 | alg->stream = stream; | ||
| 148 | return 0; | 152 | return 0; |
| 149 | } | 153 | } |
| 150 | 154 | ||
| @@ -159,11 +163,10 @@ static int crypto_scomp_init_tfm(struct crypto_tfm *tfm) · 8 unmodified lines | |||
| 159 | if (ret) | 163 | if (ret) |
| 160 | goto unlock; | 164 | goto unlock; |
| 161 | } | 165 | } |
| 162 | if (!scomp_scratch_users) { | 166 | if (!scomp_scratch_users++) { |
| 163 | ret = crypto_scomp_alloc_scratches(); | 167 | ret = crypto_scomp_alloc_scratches(); |
| 164 | if (ret) | 168 | if (ret) |
| 165 | goto unlock; | 169 | scomp_scratch_users--; |
| 166 | scomp_scratch_users++; | ||
| 167 | } | 170 | } |
| 168 | unlock: | 171 | unlock: |
| 169 | mutex_unlock(&scomp_lock); | 172 | mutex_unlock(&scomp_lock); |
| @@ -211,8 +214,8 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) · 41 unmodified lines | |||
| 211 | spage = nth_page(spage, soff / PAGE_SIZE); | 214 | spage = nth_page(spage, soff / PAGE_SIZE); |
| 212 | soff = offset_in_page(soff); | 215 | soff = offset_in_page(soff); |
| 213 | 216 | ||
| 214 | n = slen / PAGE_SIZE; | 217 | n = (slen - 1) / PAGE_SIZE; |
| 215 | n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE; | 218 | n += (offset_in_page(slen - 1) + soff) / PAGE_SIZE; |
| 216 | if (PageHighMem(nth_page(spage, n)) && | 219 | if (PageHighMem(nth_page(spage, n)) && |
| 217 | size_add(soff, slen) > PAGE_SIZE) | 220 | size_add(soff, slen) > PAGE_SIZE) |
| 218 | break; | 221 | break; |
| @@ -239,9 +242,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) · 20 unmodified lines | |||
| 239 | dpage = nth_page(dpage, doff / PAGE_SIZE); | 242 | dpage = nth_page(dpage, doff / PAGE_SIZE); |
| 240 | doff = offset_in_page(doff); | 243 | doff = offset_in_page(doff); |
| 241 | 244 | ||
| 242 | n = dlen / PAGE_SIZE; | 245 | n = (dlen - 1) / PAGE_SIZE; |
| 243 | n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE; | 246 | n += (offset_in_page(dlen - 1) + doff) / PAGE_SIZE; |
| 244 | if (PageHighMem(dpage + n) && | 247 | if (PageHighMem(nth_page(dpage, n)) && |
| 245 | size_add(doff, dlen) > PAGE_SIZE) | 248 | size_add(doff, dlen) > PAGE_SIZE) |
| 246 | break; | 249 | break; |
| 247 | dst = kmap_local_page(dpage) + doff; | 250 | dst = kmap_local_page(dpage) + doff; |
| @@ -58,9 +58,6 @@ module_param(fuzz_iterations, uint, 0644); · 57 unmodified lines | |||
| 58 | MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); | 58 | MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); |
| 59 | #endif | 59 | #endif |
| 60 | 60 | ||
| 61 | /* Multibuffer is unlimited. Set arbitrary limit for testing. */ | ||
| 62 | #define MAX_MB_MSGS 16 | ||
| 63 | |||
| 64 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS | 61 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS |
| 65 | 62 | ||
| 66 | /* a perfect nop */ | 63 | /* a perfect nop */ |
| @@ -3329,48 +3326,27 @@ static int test_acomp(struct crypto_acomp *tfm, · 3262 unmodified lines | |||
| 3329 | int ctcount, int dtcount) | 3326 | int ctcount, int dtcount) |
| 3330 | { | 3327 | { |
| 3331 | const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); | 3328 | const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); |
| 3332 | struct scatterlist *src = NULL, *dst = NULL; | ||
| 3333 | struct acomp_req *reqs[MAX_MB_MSGS] = {}; | ||
| 3334 | char *decomp_out[MAX_MB_MSGS] = {}; | ||
| 3335 | char *output[MAX_MB_MSGS] = {}; | ||
| 3336 | struct crypto_wait wait; | ||
| 3337 | struct acomp_req *req; | ||
| 3338 | int ret = -ENOMEM; | ||
| 3339 | unsigned int i; | 3329 | unsigned int i; |
| 3330 | char *output, *decomp_out; | ||
| 3331 | int ret; | ||
| 3332 | struct scatterlist src, dst; | ||
| 3333 | struct acomp_req *req; | ||
| 3334 | struct crypto_wait wait; | ||
| 3340 | 3335 | ||
| 3341 | src = kmalloc_array(MAX_MB_MSGS, sizeof(*src), GFP_KERNEL); | 3336 | output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); |
| 3342 | if (!src) | 3337 | if (!output) |
| 3343 | goto out; | 3338 | return -ENOMEM; |
| 3344 | dst = kmalloc_array(MAX_MB_MSGS, sizeof(*dst), GFP_KERNEL); | ||
| 3345 | if (!dst) | ||
| 3346 | goto out; | ||
| 3347 | |||
| 3348 | for (i = 0; i < MAX_MB_MSGS; i++) { | ||
| 3349 | reqs[i] = acomp_request_alloc(tfm); | ||
| 3350 | if (!reqs[i]) | ||
| 3351 | goto out; | ||
| 3352 | |||
| 3353 | acomp_request_set_callback(reqs[i], | ||
| 3354 | CRYPTO_TFM_REQ_MAY_SLEEP | | ||
| 3355 | CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
| 3356 | crypto_req_done, &wait); | ||
| 3357 | if (i) | ||
| 3358 | acomp_request_chain(reqs[i], reqs[0]); | ||
| 3359 | |||
| 3360 | output[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | ||
| 3361 | if (!output[i]) | ||
| 3362 | goto out; | ||
| 3363 | 3339 | ||
| 3364 | decomp_out[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | 3340 | decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); |
| 3365 | if (!decomp_out[i]) | 3341 | if (!decomp_out) { |
| 3366 | goto out; | 3342 | kfree(output); |
| 3343 | return -ENOMEM; | ||
| 3367 | } | 3344 | } |
| 3368 | 3345 | ||
| 3369 | for (i = 0; i < ctcount; i++) { | 3346 | for (i = 0; i < ctcount; i++) { |
| 3370 | unsigned int dlen = COMP_BUF_SIZE; | 3347 | unsigned int dlen = COMP_BUF_SIZE; |
| 3371 | int ilen = ctemplate[i].inlen; | 3348 | int ilen = ctemplate[i].inlen; |
| 3372 | void *input_vec; | 3349 | void *input_vec; |
| 3373 | int j; | ||
| 3374 | 3350 | ||
| 3375 | input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); | 3351 | input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); |
| 3376 | if (!input_vec) { | 3352 | if (!input_vec) { |
| @@ -3378,61 +3354,70 @@ static int test_acomp(struct crypto_acomp *tfm, · 1 unmodified line | |||
| 3378 | goto out; | 3354 | goto out; |
| 3379 | } | 3355 | } |
| 3380 | 3356 | ||
| 3357 | memset(output, 0, dlen); | ||
| 3381 | crypto_init_wait(&wait); | 3358 | crypto_init_wait(&wait); |
| 3382 | sg_init_one(src, input_vec, ilen); | 3359 | sg_init_one(&src, input_vec, ilen); |
| 3360 | sg_init_one(&dst, output, dlen); | ||
| 3383 | 3361 | ||
| 3384 | for (j = 0; j < MAX_MB_MSGS; j++) { | 3362 | req = acomp_request_alloc(tfm); |
| 3385 | sg_init_one(dst + j, output[j], dlen); | 3363 | if (!req) { |
| 3386 | acomp_request_set_params(reqs[j], src, dst + j, ilen, dlen); | 3364 | pr_err("alg: acomp: request alloc failed for %s\n", |
| 3365 | algo); | ||
| 3366 | kfree(input_vec); | ||
| 3367 | ret = -ENOMEM; | ||
| 3368 | goto out; | ||
| 3387 | } | 3369 | } |
| 3388 | 3370 | ||
| 3389 | req = reqs[0]; | 3371 | acomp_request_set_params(req, &src, &dst, ilen, dlen); |
| 3372 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
| 3373 | crypto_req_done, &wait); | ||
| 3374 | |||
| 3390 | ret = crypto_wait_req(crypto_acomp_compress(req), &wait); | 3375 | ret = crypto_wait_req(crypto_acomp_compress(req), &wait); |
| 3391 | if (ret) { | 3376 | if (ret) { |
| 3392 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", | 3377 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", |
| 3393 | i + 1, algo, -ret); | 3378 | i + 1, algo, -ret); |
| 3394 | kfree(input_vec); | 3379 | kfree(input_vec); |
| 3380 | acomp_request_free(req); | ||
| 3395 | goto out; | 3381 | goto out; |
| 3396 | } | 3382 | } |
| 3397 | 3383 | ||
| 3398 | ilen = req->dlen; | 3384 | ilen = req->dlen; |
| 3399 | dlen = COMP_BUF_SIZE; | 3385 | dlen = COMP_BUF_SIZE; |
| 3386 | sg_init_one(&src, output, ilen); | ||
| 3387 | sg_init_one(&dst, decomp_out, dlen); | ||
| 3400 | crypto_init_wait(&wait); | 3388 | crypto_init_wait(&wait); |
| 3401 | for (j = 0; j < MAX_MB_MSGS; j++) { | 3389 | acomp_request_set_params(req, &src, &dst, ilen, dlen); |
| 3402 | sg_init_one(src + j, output[j], ilen); | ||
| 3403 | sg_init_one(dst + j, decomp_out[j], dlen); | ||
| 3404 | acomp_request_set_params(reqs[j], src + j, dst + j, ilen, dlen); | ||
| 3405 | } | ||
| 3406 | |||
| 3407 | crypto_wait_req(crypto_acomp_decompress(req), &wait); | ||
| 3408 | for (j = 0; j < MAX_MB_MSGS; j++) { | ||
| 3409 | ret = reqs[j]->base.err; | ||
| 3410 | if (ret) { | ||
| 3411 | pr_err("alg: acomp: compression failed on test %d (%d) for %s: ret=%d\n", | ||
| 3412 | i + 1, j, algo, -ret); | ||
| 3413 | kfree(input_vec); | ||
| 3414 | goto out; | ||
| 3415 | } | ||
| 3416 | 3390 | ||
| 3417 | if (reqs[j]->dlen != ctemplate[i].inlen) { | 3391 | ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); |
| 3418 | pr_err("alg: acomp: Compression test %d (%d) failed for %s: output len = %d\n", | 3392 | if (ret) { |
| 3419 | i + 1, j, algo, reqs[j]->dlen); | 3393 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", |
| 3420 | ret = -EINVAL; | 3394 | i + 1, algo, -ret); |
| 3421 | kfree(input_vec); | 3395 | kfree(input_vec); |
| 3422 | goto out; | 3396 | acomp_request_free(req); |
| 3423 | } | 3397 | goto out; |
| 3398 | } | ||
| 3424 | 3399 | ||
| 3425 | if (memcmp(input_vec, decomp_out[j], reqs[j]->dlen)) { | 3400 | if (req->dlen != ctemplate[i].inlen) { |
| 3426 | pr_err("alg: acomp: Compression test %d (%d) failed for %s\n", | 3401 | pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", |
| 3427 | i + 1, j, algo); | 3402 | i + 1, algo, req->dlen); |
| 3428 | hexdump(output[j], reqs[j]->dlen); | 3403 | ret = -EINVAL; |
| 3429 | ret = -EINVAL; | 3404 | kfree(input_vec); |
| 3430 | kfree(input_vec); | 3405 | acomp_request_free(req); |
| 3431 | goto out; | 3406 | goto out; |
| 3432 | } | 3407 | } |
| 3408 | |||
| 3409 | if (memcmp(input_vec, decomp_out, req->dlen)) { | ||
| 3410 | pr_err("alg: acomp: Compression test %d failed for %s\n", | ||
| 3411 | i + 1, algo); | ||
| 3412 | hexdump(output, req->dlen); | ||
| 3413 | ret = -EINVAL; | ||
| 3414 | kfree(input_vec); | ||
| 3415 | acomp_request_free(req); | ||
| 3416 | goto out; | ||
| 3433 | } | 3417 | } |
| 3434 | 3418 | ||
| 3435 | kfree(input_vec); | 3419 | kfree(input_vec); |
| 3420 | acomp_request_free(req); | ||
| 3436 | } | 3421 | } |
| 3437 | 3422 | ||
| 3438 | for (i = 0; i < dtcount; i++) { | 3423 | for (i = 0; i < dtcount; i++) { |
| @@ -3446,9 +3431,10 @@ static int test_acomp(struct crypto_acomp *tfm, · 7 unmodified lines | |||
| 3446 | goto out; | 3431 | goto out; |
| 3447 | } | 3432 | } |
| 3448 | 3433 | ||
| 3434 | memset(output, 0, dlen); | ||
| 3449 | crypto_init_wait(&wait); | 3435 | crypto_init_wait(&wait); |
| 3450 | sg_init_one(src, input_vec, ilen); | 3436 | sg_init_one(&src, input_vec, ilen); |
| 3451 | sg_init_one(dst, output[0], dlen); | 3437 | sg_init_one(&dst, output, dlen); |
| 3452 | 3438 | ||
| 3453 | req = acomp_request_alloc(tfm); | 3439 | req = acomp_request_alloc(tfm); |
| 3454 | if (!req) { | 3440 | if (!req) { |
| @@ -3459,7 +3445,7 @@ static int test_acomp(struct crypto_acomp *tfm, · 4 unmodified lines | |||
| 3459 | goto out; | 3445 | goto out; |
| 3460 | } | 3446 | } |
| 3461 | 3447 | ||
| 3462 | acomp_request_set_params(req, src, dst, ilen, dlen); | 3448 | acomp_request_set_params(req, &src, &dst, ilen, dlen); |
| 3463 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 3449 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 3464 | crypto_req_done, &wait); | 3450 | crypto_req_done, &wait); |
| 3465 | 3451 | ||
| @@ -3481,10 +3467,10 @@ static int test_acomp(struct crypto_acomp *tfm, · 15 unmodified lines | |||
| 3481 | goto out; | 3467 | goto out; |
| 3482 | } | 3468 | } |
| 3483 | 3469 | ||
| 3484 | if (memcmp(output[0], dtemplate[i].output, req->dlen)) { | 3470 | if (memcmp(output, dtemplate[i].output, req->dlen)) { |
| 3485 | pr_err("alg: acomp: Decompression test %d failed for %s\n", | 3471 | pr_err("alg: acomp: Decompression test %d failed for %s\n", |
| 3486 | i + 1, algo); | 3472 | i + 1, algo); |
| 3487 | hexdump(output[0], req->dlen); | 3473 | hexdump(output, req->dlen); |
| 3488 | ret = -EINVAL; | 3474 | ret = -EINVAL; |
| 3489 | kfree(input_vec); | 3475 | kfree(input_vec); |
| 3490 | acomp_request_free(req); | 3476 | acomp_request_free(req); |
| @@ -3498,13 +3484,8 @@ static int test_acomp(struct crypto_acomp *tfm, · 7 unmodified lines | |||
| 3498 | ret = 0; | 3484 | ret = 0; |
| 3499 | 3485 | ||
| 3500 | out: | 3486 | out: |
| 3501 | acomp_request_free(reqs[0]); | 3487 | kfree(decomp_out); |
| 3502 | for (i = 0; i < MAX_MB_MSGS; i++) { | 3488 | kfree(output); |
| 3503 | kfree(output[i]); | ||
| 3504 | kfree(decomp_out[i]); | ||
| 3505 | } | ||
| 3506 | kfree(dst); | ||
| 3507 | kfree(src); | ||
| 3508 | return ret; | 3489 | return ret; |
| 3509 | } | 3490 | } |
| 3510 | 3491 | ||
| @@ -332,7 +332,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si · 331 unmodified lines | |||
| 332 | return -EINVAL; | 332 | return -EINVAL; |
| 333 | 333 | ||
| 334 | ret = ivpu_rpm_get(vdev); | 334 | ret = ivpu_rpm_get(vdev); |
| 335 | if (ret) | 335 | if (ret < 0) |
| 336 | return ret; | 336 | return ret; |
| 337 | 337 | ||
| 338 | ivpu_pm_trigger_recovery(vdev, "debugfs"); | 338 | ivpu_pm_trigger_recovery(vdev, "debugfs"); |
| @@ -383,7 +383,7 @@ static int dct_active_set(void *data, u64 active_percent) · 44 unmodified lines | |||
| 383 | return -EINVAL; | 383 | return -EINVAL; |
| 384 | 384 | ||
| 385 | ret = ivpu_rpm_get(vdev); | 385 | ret = ivpu_rpm_get(vdev); |
| 386 | if (ret) | 386 | if (ret < 0) |
| 387 | return ret; | 387 | return ret; |
| 388 | 388 | ||
| 389 | if (active_percent) | 389 | if (active_percent) |
| @@ -455,7 +455,7 @@ priority_bands_fops_write(struct file *file, const char __user *user_buf, size_t · 65 unmodified lines | |||
| 455 | if (ret < 0) | 455 | if (ret < 0) |
| 456 | return ret; | 456 | return ret; |
| 457 | 457 | ||
| 458 | buf[size] = '\0'; | 458 | buf[ret] = '\0'; |
| 459 | ret = sscanf(buf, "%u %u %u %u", &band, &grace_period, &process_grace_period, | 459 | ret = sscanf(buf, "%u %u %u %u", &band, &grace_period, &process_grace_period, |
| 460 | &process_quantum); | 460 | &process_quantum); |
| 461 | if (ret != 4) | 461 | if (ret != 4) |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2020-2024 Intel Corporation | 3 | * Copyright (C) 2020-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
| @@ -164,7 +164,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f · 157 unmodified lines | |||
| 164 | args->value = vdev->platform; | 164 | args->value = vdev->platform; |
| 165 | break; | 165 | break; |
| 166 | case DRM_IVPU_PARAM_CORE_CLOCK_RATE: | 166 | case DRM_IVPU_PARAM_CORE_CLOCK_RATE: |
| 167 | args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio); | 167 | args->value = ivpu_hw_dpu_max_freq_get(vdev); |
| 168 | break; | 168 | break; |
| 169 | case DRM_IVPU_PARAM_NUM_CONTEXTS: | 169 | case DRM_IVPU_PARAM_NUM_CONTEXTS: |
| 170 | args->value = ivpu_get_context_count(vdev); | 170 | args->value = ivpu_get_context_count(vdev); |
| @@ -421,9 +421,9 @@ void ivpu_prepare_for_reset(struct ivpu_device *vdev) · 250 unmodified lines | |||
| 421 | { | 421 | { |
| 422 | ivpu_hw_irq_disable(vdev); | 422 | ivpu_hw_irq_disable(vdev); |
| 423 | disable_irq(vdev->irq); | 423 | disable_irq(vdev->irq); |
| 424 | cancel_work_sync(&vdev->irq_ipc_work); | 424 | flush_work(&vdev->irq_ipc_work); |
| 425 | cancel_work_sync(&vdev->irq_dct_work); | 425 | flush_work(&vdev->irq_dct_work); |
| 426 | cancel_work_sync(&vdev->context_abort_work); | 426 | flush_work(&vdev->context_abort_work); |
| 427 | ivpu_ipc_disable(vdev); | 427 | ivpu_ipc_disable(vdev); |
| 428 | ivpu_mmu_disable(vdev); | 428 | ivpu_mmu_disable(vdev); |
| 429 | } | 429 | } |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2020-2024 Intel Corporation | 3 | * Copyright (C) 2020-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
| @@ -233,10 +233,20 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) · 226 unmodified lines | |||
| 233 | fw->dvfs_mode = 0; | 233 | fw->dvfs_mode = 0; |
| 234 | 234 | ||
| 235 | fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); | 235 | fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); |
| 236 | fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; | ||
| 237 | fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; | ||
| 238 | ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); | 236 | ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); |
| 239 | 237 | ||
| 238 | if (fw_hdr->preemption_buffer_1_max_size) | ||
| 239 | fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size; | ||
| 240 | else | ||
| 241 | fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; | ||
| 242 | |||
| 243 | if (fw_hdr->preemption_buffer_2_max_size) | ||
| 244 | fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size; | ||
| 245 | else | ||
| 246 | fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; | ||
| 247 | ivpu_dbg(vdev, FW_BOOT, "Preemption buffer sizes: primary %u, secondary %u\n", | ||
| 248 | fw->primary_preempt_buf_size, fw->secondary_preempt_buf_size); | ||
| 249 | |||
| 240 | if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, | 250 | if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, |
| 241 | fw_hdr->ro_section_size, | 251 | fw_hdr->ro_section_size, |
| 242 | fw_hdr->image_load_address, | 252 | fw_hdr->image_load_address, |
| @@ -534,7 +544,7 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_ · 291 unmodified lines | |||
| 534 | boot_params->d0i3_entry_vpu_ts); | 544 | boot_params->d0i3_entry_vpu_ts); |
| 535 | ivpu_dbg(vdev, FW_BOOT, "boot_params.system_time_us = %llu\n", | 545 | ivpu_dbg(vdev, FW_BOOT, "boot_params.system_time_us = %llu\n", |
| 536 | boot_params->system_time_us); | 546 | boot_params->system_time_us); |
| 537 | ivpu_dbg(vdev, FW_BOOT, "boot_params.power_profile = %u\n", | 547 | ivpu_dbg(vdev, FW_BOOT, "boot_params.power_profile = 0x%x\n", |
| 538 | boot_params->power_profile); | 548 | boot_params->power_profile); |
| 539 | } | 549 | } |
| 540 | 550 | ||
| @@ -566,7 +576,6 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 25 unmodified lines | |||
| 566 | 576 | ||
| 567 | boot_params->magic = VPU_BOOT_PARAMS_MAGIC; | 577 | boot_params->magic = VPU_BOOT_PARAMS_MAGIC; |
| 568 | boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number; | 578 | boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number; |
| 569 | boot_params->frequency = ivpu_hw_pll_freq_get(vdev); | ||
| 570 | 579 | ||
| 571 | /* | 580 | /* |
| 572 | * This param is a debug firmware feature. It switches default clock | 581 | * This param is a debug firmware feature. It switches default clock |
| @@ -637,7 +646,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 64 unmodified lines | |||
| 637 | boot_params->d0i3_residency_time_us = 0; | 646 | boot_params->d0i3_residency_time_us = 0; |
| 638 | boot_params->d0i3_entry_vpu_ts = 0; | 647 | boot_params->d0i3_entry_vpu_ts = 0; |
| 639 | if (IVPU_WA(disable_d0i2)) | 648 | if (IVPU_WA(disable_d0i2)) |
| 640 | boot_params->power_profile = 1; | 649 | boot_params->power_profile |= BIT(1); |
| 641 | 650 | ||
| 642 | boot_params->system_time_us = ktime_to_us(ktime_get_real()); | 651 | boot_params->system_time_us = ktime_to_us(ktime_get_real()); |
| 643 | wmb(); /* Flush WC buffers after writing bootparams */ | 652 | wmb(); /* Flush WC buffers after writing bootparams */ |
| @@ -119,7 +119,7 @@ static void timeouts_init(struct ivpu_device *vdev) · 118 unmodified lines | |||
| 119 | else | 119 | else |
| 120 | vdev->timeout.autosuspend = 100; | 120 | vdev->timeout.autosuspend = 100; |
| 121 | vdev->timeout.d0i3_entry_msg = 5; | 121 | vdev->timeout.d0i3_entry_msg = 5; |
| 122 | vdev->timeout.state_dump_msg = 10; | 122 | vdev->timeout.state_dump_msg = 100; |
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | 125 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2020-2024 Intel Corporation | 3 | * Copyright (C) 2020-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifndef __IVPU_HW_H__ | 6 | #ifndef __IVPU_HW_H__ |
| @@ -82,19 +82,19 @@ static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range) · 75 unmodified lines | |||
| 82 | return range->end - range->start; | 82 | return range->end - range->start; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) | 85 | static inline u32 ivpu_hw_dpu_max_freq_get(struct ivpu_device *vdev) |
| 86 | { | 86 | { |
| 87 | return ivpu_hw_btrs_ratio_to_freq(vdev, ratio); | 87 | return ivpu_hw_btrs_dpu_max_freq_get(vdev); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev) | 90 | static inline u32 ivpu_hw_dpu_freq_get(struct ivpu_device *vdev) |
| 91 | { | 91 | { |
| 92 | ivpu_hw_ip_irq_clear(vdev); | 92 | return ivpu_hw_btrs_dpu_freq_get(vdev); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev) | 95 | static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev) |
| 96 | { | 96 | { |
| 97 | return ivpu_hw_btrs_pll_freq_get(vdev); | 97 | ivpu_hw_ip_irq_clear(vdev); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev) | 100 | static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev) |
| @@ -1,8 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2020-2024 Intel Corporation | 3 | * Copyright (C) 2020-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/units.h> | ||
| 7 | |||
| 6 | #include "ivpu_drv.h" | 8 | #include "ivpu_drv.h" |
| 7 | #include "ivpu_hw.h" | 9 | #include "ivpu_hw.h" |
| 8 | #include "ivpu_hw_btrs.h" | 10 | #include "ivpu_hw_btrs.h" |
| @@ -28,17 +30,13 @@ · 19 unmodified lines | |||
| 28 | 30 | ||
| 29 | #define BTRS_LNL_ALL_IRQ_MASK ((u32)-1) | 31 | #define BTRS_LNL_ALL_IRQ_MASK ((u32)-1) |
| 30 | 32 | ||
| 31 | #define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3) | ||
| 32 | #define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3) | ||
| 33 | #define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3) | ||
| 34 | #define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3) | ||
| 35 | #define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0) | ||
| 36 | 33 | ||
| 37 | #define PLL_CDYN_DEFAULT 0x80 | 34 | #define PLL_CDYN_DEFAULT 0x80 |
| 38 | #define PLL_EPP_DEFAULT 0x80 | 35 | #define PLL_EPP_DEFAULT 0x80 |
| 39 | #define PLL_CONFIG_DEFAULT 0x0 | 36 | #define PLL_CONFIG_DEFAULT 0x0 |
| 40 | #define PLL_SIMULATION_FREQ 10000000 | 37 | #define PLL_REF_CLK_FREQ 50000000ull |
| 41 | #define PLL_REF_CLK_FREQ 50000000 | 38 | #define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ) |
| 39 | |||
| 42 | #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC) | 40 | #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC) |
| 43 | #define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC) | 41 | #define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC) |
| 44 | #define TIMEOUT_US (150 * USEC_PER_MSEC) | 42 | #define TIMEOUT_US (150 * USEC_PER_MSEC) |
| @@ -62,6 +60,8 @@ · 17 unmodified lines | |||
| 62 | #define DCT_ENABLE 0x1 | 60 | #define DCT_ENABLE 0x1 |
| 63 | #define DCT_DISABLE 0x0 | 61 | #define DCT_DISABLE 0x0 |
| 64 | 62 | ||
| 63 | static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio); | ||
| 64 | |||
| 65 | int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev) | 65 | int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev) |
| 66 | { | 66 | { |
| 67 | REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, BTRS_MTL_ALL_IRQ_MASK); | 67 | 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) · 88 unmodified lines | |||
| 156 | 156 | ||
| 157 | hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; | 157 | hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; |
| 158 | hw->sku = BTRS_MTL_TILE_SKU_BOTH; | 158 | hw->sku = BTRS_MTL_TILE_SKU_BOTH; |
| 159 | hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO; | 159 | hw->config = WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3); |
| 160 | 160 | ||
| 161 | return 0; | 161 | return 0; |
| 162 | } | 162 | } |
| @@ -334,8 +334,8 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable) · 171 unmodified lines | |||
| 334 | 334 | ||
| 335 | prepare_wp_request(vdev, &wp, enable); | 335 | prepare_wp_request(vdev, &wp, enable); |
| 336 | 336 | ||
| 337 | ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n", | 337 | ivpu_dbg(vdev, PM, "PLL workpoint request: %lu MHz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n", |
| 338 | PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn); | 338 | pll_ratio_to_dpu_freq(vdev, wp.target) / HZ_PER_MHZ, wp.cfg, wp.epp, wp.cdyn); |
| 339 | 339 | ||
| 340 | ret = wp_request_send(vdev, &wp); | 340 | ret = wp_request_send(vdev, &wp); |
| 341 | if (ret) { | 341 | if (ret) { |
| @@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev) · 231 unmodified lines | |||
| 573 | return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US); | 573 | return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US); |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | static u32 pll_config_get_mtl(struct ivpu_device *vdev) | ||
| 577 | { | ||
| 578 | return REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL); | ||
| 579 | } | ||
| 580 | |||
| 581 | static u32 pll_config_get_lnl(struct ivpu_device *vdev) | ||
| 582 | { | ||
| 583 | return REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ); | ||
| 584 | } | ||
| 585 | |||
| 586 | static u32 pll_ratio_to_dpu_freq_mtl(u16 ratio) | ||
| 587 | { | ||
| 588 | return (PLL_RATIO_TO_FREQ(ratio) * 2) / 3; | ||
| 589 | } | ||
| 590 | |||
| 591 | static u32 pll_ratio_to_dpu_freq_lnl(u16 ratio) | ||
| 592 | { | ||
| 593 | return PLL_RATIO_TO_FREQ(ratio) / 2; | ||
| 594 | } | ||
| 595 | |||
| 596 | static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio) | ||
| 597 | { | ||
| 598 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) | ||
| 599 | return pll_ratio_to_dpu_freq_mtl(ratio); | ||
| 600 | else | ||
| 601 | return pll_ratio_to_dpu_freq_lnl(ratio); | ||
| 602 | } | ||
| 603 | |||
| 604 | u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev) | ||
| 605 | { | ||
| 606 | return pll_ratio_to_dpu_freq(vdev, vdev->hw->pll.max_ratio); | ||
| 607 | } | ||
| 608 | |||
| 609 | u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev) | ||
| 610 | { | ||
| 611 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) | ||
| 612 | return pll_ratio_to_dpu_freq_mtl(pll_config_get_mtl(vdev)); | ||
| 613 | else | ||
| 614 | return pll_ratio_to_dpu_freq_lnl(pll_config_get_lnl(vdev)); | ||
| 615 | } | ||
| 616 | |||
| 576 | /* Handler for IRQs from Buttress core (irqB) */ | 617 | /* Handler for IRQs from Buttress core (irqB) */ |
| 577 | bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq) | 618 | bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq) |
| 578 | { | 619 | { |
| @@ -582,9 +623,12 @@ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq) · 3 unmodified lines | |||
| 582 | if (!status) | 623 | if (!status) |
| 583 | return false; | 624 | return false; |
| 584 | 625 | ||
| 585 | if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) | 626 | if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) { |
| 586 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", | 627 | u32 pll = pll_config_get_mtl(vdev); |
| 587 | REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL)); | 628 | |
| 629 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz", | ||
| 630 | pll, pll_ratio_to_dpu_freq_mtl(pll) / HZ_PER_MHZ); | ||
| 631 | } | ||
| 588 | 632 | ||
| 589 | if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) { | 633 | if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) { |
| 590 | ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0)); | 634 | 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) · 42 unmodified lines | |||
| 633 | queue_work(system_wq, &vdev->irq_dct_work); | 677 | queue_work(system_wq, &vdev->irq_dct_work); |
| 634 | } | 678 | } |
| 635 | 679 | ||
| 636 | if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) | 680 | if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) { |
| 637 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ)); | 681 | u32 pll = pll_config_get_lnl(vdev); |
| 682 | |||
| 683 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz", | ||
| 684 | pll, pll_ratio_to_dpu_freq_lnl(pll) / HZ_PER_MHZ); | ||
| 685 | } | ||
| 638 | 686 | ||
| 639 | if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) { | 687 | if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) { |
| 640 | ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n", | 688 | 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 · 76 unmodified lines | |||
| 717 | REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val); | 765 | REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val); |
| 718 | } | 766 | } |
| 719 | 767 | ||
| 720 | static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config) | ||
| 721 | { | ||
| 722 | u32 pll_clock = PLL_REF_CLK_FREQ * ratio; | ||
| 723 | u32 cpu_clock; | ||
| 724 | |||
| 725 | if ((config & 0xff) == MTL_PLL_RATIO_4_3) | ||
| 726 | cpu_clock = pll_clock * 2 / 4; | ||
| 727 | else | ||
| 728 | cpu_clock = pll_clock * 2 / 5; | ||
| 729 | |||
| 730 | return cpu_clock; | ||
| 731 | } | ||
| 732 | |||
| 733 | u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) | ||
| 734 | { | ||
| 735 | struct ivpu_hw_info *hw = vdev->hw; | ||
| 736 | |||
| 737 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) | ||
| 738 | return pll_ratio_to_freq_mtl(ratio, hw->config); | ||
| 739 | else | ||
| 740 | return PLL_RATIO_TO_FREQ(ratio); | ||
| 741 | } | ||
| 742 | |||
| 743 | static u32 pll_freq_get_mtl(struct ivpu_device *vdev) | ||
| 744 | { | ||
| 745 | u32 pll_curr_ratio; | ||
| 746 | |||
| 747 | pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL); | ||
| 748 | pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK; | ||
| 749 | |||
| 750 | if (!ivpu_is_silicon(vdev)) | ||
| 751 | return PLL_SIMULATION_FREQ; | ||
| 752 | |||
| 753 | return pll_ratio_to_freq_mtl(pll_curr_ratio, vdev->hw->config); | ||
| 754 | } | ||
| 755 | |||
| 756 | static u32 pll_freq_get_lnl(struct ivpu_device *vdev) | ||
| 757 | { | ||
| 758 | u32 pll_curr_ratio; | ||
| 759 | |||
| 760 | pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ); | ||
| 761 | pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK; | ||
| 762 | |||
| 763 | return PLL_RATIO_TO_FREQ(pll_curr_ratio); | ||
| 764 | } | ||
| 765 | |||
| 766 | u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev) | ||
| 767 | { | ||
| 768 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) | ||
| 769 | return pll_freq_get_mtl(vdev); | ||
| 770 | else | ||
| 771 | return pll_freq_get_lnl(vdev); | ||
| 772 | } | ||
| 773 | |||
| 774 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev) | 768 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev) |
| 775 | { | 769 | { |
| 776 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) | 770 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2020-2024 Intel Corporation | 3 | * Copyright (C) 2020-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifndef __IVPU_HW_BTRS_H__ | 6 | #ifndef __IVPU_HW_BTRS_H__ |
| @@ -13,9 +13,8 @@ · 6 unmodified lines | |||
| 13 | 13 | ||
| 14 | #define PLL_PROFILING_FREQ_DEFAULT 38400000 | 14 | #define PLL_PROFILING_FREQ_DEFAULT 38400000 |
| 15 | #define PLL_PROFILING_FREQ_HIGH 400000000 | 15 | #define PLL_PROFILING_FREQ_HIGH 400000000 |
| 16 | #define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ) | ||
| 17 | 16 | ||
| 18 | #define DCT_DEFAULT_ACTIVE_PERCENT 15u | 17 | #define DCT_DEFAULT_ACTIVE_PERCENT 30u |
| 19 | #define DCT_PERIOD_US 35300u | 18 | #define DCT_PERIOD_US 35300u |
| 20 | 19 | ||
| 21 | int ivpu_hw_btrs_info_init(struct ivpu_device *vdev); | 20 | int ivpu_hw_btrs_info_init(struct ivpu_device *vdev); |
| @@ -32,12 +31,12 @@ int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev); · 10 unmodified lines | |||
| 32 | void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev); | 31 | void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev); |
| 33 | void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev); | 32 | void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev); |
| 34 | void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev); | 33 | void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev); |
| 34 | u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev); | ||
| 35 | u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); | ||
| 35 | bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); | 36 | bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); |
| 36 | bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); | 37 | bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); |
| 37 | int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); | 38 | int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); |
| 38 | void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent); | 39 | void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent); |
| 39 | u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev); | ||
| 40 | u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio); | ||
| 41 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); | 40 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); |
| 42 | u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); | 41 | u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); |
| 43 | u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); | 42 | u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); |
| @@ -302,7 +302,8 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req · 301 unmodified lines | |||
| 302 | struct ivpu_ipc_consumer cons; | 302 | struct ivpu_ipc_consumer cons; |
| 303 | int ret; | 303 | int ret; |
| 304 | 304 | ||
| 305 | drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); | 305 | drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev) && |
| 306 | pm_runtime_enabled(vdev->drm.dev)); | ||
| 306 | 307 | ||
| 307 | ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); | 308 | ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); |
| 308 | 309 | ||
| @@ -470,8 +470,8 @@ static void ivpu_job_destroy(struct ivpu_job *job) · 469 unmodified lines | |||
| 470 | struct ivpu_device *vdev = job->vdev; | 470 | struct ivpu_device *vdev = job->vdev; |
| 471 | u32 i; | 471 | u32 i; |
| 472 | 472 | ||
| 473 | ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d", | 473 | ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d cmdq_id %u engine %d", |
| 474 | job->job_id, job->file_priv->ctx.id, job->engine_idx); | 474 | job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx); |
| 475 | 475 | ||
| 476 | for (i = 0; i < job->bo_count; i++) | 476 | for (i = 0; i < job->bo_count; i++) |
| 477 | if (job->bos[i]) | 477 | if (job->bos[i]) |
| @@ -564,8 +564,8 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 · 86 unmodified lines | |||
| 564 | dma_fence_signal(job->done_fence); | 564 | dma_fence_signal(job->done_fence); |
| 565 | 565 | ||
| 566 | trace_job("done", job); | 566 | trace_job("done", job); |
| 567 | ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", | 567 | ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d cmdq_id %u engine %d status 0x%x\n", |
| 568 | job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); | 568 | job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, job_status); |
| 569 | 569 | ||
| 570 | ivpu_job_destroy(job); | 570 | ivpu_job_destroy(job); |
| 571 | ivpu_stop_job_timeout_detection(vdev); | 571 | ivpu_stop_job_timeout_detection(vdev); |
| @@ -664,8 +664,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) · 92 unmodified lines | |||
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | trace_job("submit", job); | 666 | trace_job("submit", job); |
| 667 | ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n", | 667 | ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d cmdq_id %u engine %d prio %d addr 0x%llx next %d\n", |
| 668 | job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->priority, | 668 | job->job_id, file_priv->ctx.id, cmdq->id, job->engine_idx, cmdq->priority, |
| 669 | job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); | 669 | job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); |
| 670 | 670 | ||
| 671 | mutex_unlock(&file_priv->lock); | 671 | mutex_unlock(&file_priv->lock); |
| @@ -681,8 +681,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) · 9 unmodified lines | |||
| 681 | err_erase_xa: | 681 | err_erase_xa: |
| 682 | xa_erase(&vdev->submitted_jobs_xa, job->job_id); | 682 | xa_erase(&vdev->submitted_jobs_xa, job->job_id); |
| 683 | err_unlock: | 683 | err_unlock: |
| 684 | mutex_unlock(&vdev->submitted_jobs_lock); | ||
| 685 | mutex_unlock(&file_priv->lock); | 684 | mutex_unlock(&file_priv->lock); |
| 685 | mutex_unlock(&vdev->submitted_jobs_lock); | ||
| 686 | ivpu_rpm_put(vdev); | 686 | ivpu_rpm_put(vdev); |
| 687 | return ret; | 687 | return ret; |
| 688 | } | 688 | } |
| @@ -777,7 +777,8 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv, · 88 unmodified lines | |||
| 777 | goto err_free_handles; | 777 | goto err_free_handles; |
| 778 | } | 778 | } |
| 779 | 779 | ||
| 780 | ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", file_priv->ctx.id, buffer_count); | 780 | ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u cmdq_id %u buf_count %u\n", |
| 781 | file_priv->ctx.id, cmdq_id, buffer_count); | ||
| 781 | 782 | ||
| 782 | job = ivpu_job_create(file_priv, engine, buffer_count); | 783 | job = ivpu_job_create(file_priv, engine, buffer_count); |
| 783 | if (!job) { | 784 | if (!job) { |
| @@ -873,15 +874,21 @@ int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file * · 89 unmodified lines | |||
| 873 | int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | 874 | int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) |
| 874 | { | 875 | { |
| 875 | struct ivpu_file_priv *file_priv = file->driver_priv; | 876 | struct ivpu_file_priv *file_priv = file->driver_priv; |
| 877 | struct ivpu_device *vdev = file_priv->vdev; | ||
| 876 | struct drm_ivpu_cmdq_create *args = data; | 878 | struct drm_ivpu_cmdq_create *args = data; |
| 877 | struct ivpu_cmdq *cmdq; | 879 | struct ivpu_cmdq *cmdq; |
| 880 | int ret; | ||
| 878 | 881 | ||
| 879 | if (!ivpu_is_capable(file_priv->vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) | 882 | if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) |
| 880 | return -ENODEV; | 883 | return -ENODEV; |
| 881 | 884 | ||
| 882 | if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) | 885 | if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) |
| 883 | return -EINVAL; | 886 | return -EINVAL; |
| 884 | 887 | ||
| 888 | ret = ivpu_rpm_get(vdev); | ||
| 889 | if (ret < 0) | ||
| 890 | return ret; | ||
| 891 | |||
| 885 | mutex_lock(&file_priv->lock); | 892 | mutex_lock(&file_priv->lock); |
| 886 | 893 | ||
| 887 | cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false); | 894 | cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false); |
| @@ -890,6 +897,8 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file * · 2 unmodified lines | |||
| 890 | 897 | ||
| 891 | mutex_unlock(&file_priv->lock); | 898 | mutex_unlock(&file_priv->lock); |
| 892 | 899 | ||
| 900 | ivpu_rpm_put(vdev); | ||
| 901 | |||
| 893 | return cmdq ? 0 : -ENOMEM; | 902 | return cmdq ? 0 : -ENOMEM; |
| 894 | } | 903 | } |
| 895 | 904 | ||
| @@ -899,28 +908,35 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file · 3 unmodified lines | |||
| 899 | struct ivpu_device *vdev = file_priv->vdev; | 908 | struct ivpu_device *vdev = file_priv->vdev; |
| 900 | struct drm_ivpu_cmdq_destroy *args = data; | 909 | struct drm_ivpu_cmdq_destroy *args = data; |
| 901 | struct ivpu_cmdq *cmdq; | 910 | struct ivpu_cmdq *cmdq; |
| 902 | u32 cmdq_id; | 911 | u32 cmdq_id = 0; |
| 903 | int ret; | 912 | int ret; |
| 904 | 913 | ||
| 905 | if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) | 914 | if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) |
| 906 | return -ENODEV; | 915 | return -ENODEV; |
| 907 | 916 | ||
| 917 | ret = ivpu_rpm_get(vdev); | ||
| 918 | if (ret < 0) | ||
| 919 | return ret; | ||
| 920 | |||
| 908 | mutex_lock(&file_priv->lock); | 921 | mutex_lock(&file_priv->lock); |
| 909 | 922 | ||
| 910 | cmdq = xa_load(&file_priv->cmdq_xa, args->cmdq_id); | 923 | cmdq = xa_load(&file_priv->cmdq_xa, args->cmdq_id); |
| 911 | if (!cmdq || cmdq->is_legacy) { | 924 | if (!cmdq || cmdq->is_legacy) { |
| 912 | ret = -ENOENT; | 925 | ret = -ENOENT; |
| 913 | goto err_unlock; | 926 | } else { |
| 927 | cmdq_id = cmdq->id; | ||
| 928 | ivpu_cmdq_destroy(file_priv, cmdq); | ||
| 929 | ret = 0; | ||
| 914 | } | 930 | } |
| 915 | 931 | ||
| 916 | cmdq_id = cmdq->id; | ||
| 917 | ivpu_cmdq_destroy(file_priv, cmdq); | ||
| 918 | mutex_unlock(&file_priv->lock); | 932 | mutex_unlock(&file_priv->lock); |
| 919 | ivpu_cmdq_abort_all_jobs(vdev, file_priv->ctx.id, cmdq_id); | ||
| 920 | return 0; | ||
| 921 | 933 | ||
| 922 | err_unlock: | 934 | /* Abort any pending jobs only if cmdq was destroyed */ |
| 923 | mutex_unlock(&file_priv->lock); | 935 | if (!ret) |
| 936 | ivpu_cmdq_abort_all_jobs(vdev, file_priv->ctx.id, cmdq_id); | ||
| 937 | |||
| 938 | ivpu_rpm_put(vdev); | ||
| 939 | |||
| 924 | return ret; | 940 | return ret; |
| 925 | } | 941 | } |
| 926 | 942 | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <drm/drm_file.h> | 6 | #include <drm/drm_file.h> |
| 7 | #include <linux/pm_runtime.h> | ||
| 7 | 8 | ||
| 8 | #include "ivpu_drv.h" | 9 | #include "ivpu_drv.h" |
| 9 | #include "ivpu_gem.h" | 10 | #include "ivpu_gem.h" |
| @@ -44,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil · 34 unmodified lines | |||
| 44 | args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) | 45 | args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) |
| 45 | return -EINVAL; | 46 | return -EINVAL; |
| 46 | 47 | ||
| 48 | ret = ivpu_rpm_get(vdev); | ||
| 49 | if (ret < 0) | ||
| 50 | return ret; | ||
| 51 | |||
| 47 | mutex_lock(&file_priv->ms_lock); | 52 | mutex_lock(&file_priv->ms_lock); |
| 48 | 53 | ||
| 49 | if (get_instance_by_mask(file_priv, args->metric_group_mask)) { | 54 | if (get_instance_by_mask(file_priv, args->metric_group_mask)) { |
| @@ -96,6 +101,8 @@ err_free_ms: · 46 unmodified lines | |||
| 96 | kfree(ms); | 101 | kfree(ms); |
| 97 | unlock: | 102 | unlock: |
| 98 | mutex_unlock(&file_priv->ms_lock); | 103 | mutex_unlock(&file_priv->ms_lock); |
| 104 | |||
| 105 | ivpu_rpm_put(vdev); | ||
| 99 | return ret; | 106 | return ret; |
| 100 | } | 107 | } |
| 101 | 108 | ||
| @@ -160,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file * · 58 unmodified lines | |||
| 160 | if (!args->metric_group_mask) | 167 | if (!args->metric_group_mask) |
| 161 | return -EINVAL; | 168 | return -EINVAL; |
| 162 | 169 | ||
| 170 | ret = ivpu_rpm_get(vdev); | ||
| 171 | if (ret < 0) | ||
| 172 | return ret; | ||
| 173 | |||
| 163 | mutex_lock(&file_priv->ms_lock); | 174 | mutex_lock(&file_priv->ms_lock); |
| 164 | 175 | ||
| 165 | ms = get_instance_by_mask(file_priv, args->metric_group_mask); | 176 | ms = get_instance_by_mask(file_priv, args->metric_group_mask); |
| @@ -187,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file * · 21 unmodified lines | |||
| 187 | unlock: | 198 | unlock: |
| 188 | mutex_unlock(&file_priv->ms_lock); | 199 | mutex_unlock(&file_priv->ms_lock); |
| 189 | 200 | ||
| 201 | ivpu_rpm_put(vdev); | ||
| 190 | return ret; | 202 | return ret; |
| 191 | } | 203 | } |
| 192 | 204 | ||
| @@ -204,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 11 unmodified lines | |||
| 204 | { | 216 | { |
| 205 | struct ivpu_file_priv *file_priv = file->driver_priv; | 217 | struct ivpu_file_priv *file_priv = file->driver_priv; |
| 206 | struct drm_ivpu_metric_streamer_stop *args = data; | 218 | struct drm_ivpu_metric_streamer_stop *args = data; |
| 219 | struct ivpu_device *vdev = file_priv->vdev; | ||
| 207 | struct ivpu_ms_instance *ms; | 220 | struct ivpu_ms_instance *ms; |
| 221 | int ret; | ||
| 208 | 222 | ||
| 209 | if (!args->metric_group_mask) | 223 | if (!args->metric_group_mask) |
| 210 | return -EINVAL; | 224 | return -EINVAL; |
| 211 | 225 | ||
| 226 | ret = ivpu_rpm_get(vdev); | ||
| 227 | if (ret < 0) | ||
| 228 | return ret; | ||
| 229 | |||
| 212 | mutex_lock(&file_priv->ms_lock); | 230 | mutex_lock(&file_priv->ms_lock); |
| 213 | 231 | ||
| 214 | ms = get_instance_by_mask(file_priv, args->metric_group_mask); | 232 | ms = get_instance_by_mask(file_priv, args->metric_group_mask); |
| @@ -217,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 2 unmodified lines | |||
| 217 | 235 | ||
| 218 | mutex_unlock(&file_priv->ms_lock); | 236 | mutex_unlock(&file_priv->ms_lock); |
| 219 | 237 | ||
| 238 | ivpu_rpm_put(vdev); | ||
| 220 | return ms ? 0 : -EINVAL; | 239 | return ms ? 0 : -EINVAL; |
| 221 | } | 240 | } |
| 222 | 241 | ||
| @@ -281,6 +300,9 @@ unlock: · 58 unmodified lines | |||
| 281 | void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) | 300 | void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) |
| 282 | { | 301 | { |
| 283 | struct ivpu_ms_instance *ms, *tmp; | 302 | struct ivpu_ms_instance *ms, *tmp; |
| 303 | struct ivpu_device *vdev = file_priv->vdev; | ||
| 304 | |||
| 305 | pm_runtime_get_sync(vdev->drm.dev); | ||
| 284 | 306 | ||
| 285 | mutex_lock(&file_priv->ms_lock); | 307 | mutex_lock(&file_priv->ms_lock); |
| 286 | 308 | ||
| @@ -293,6 +315,8 @@ void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) · 6 unmodified lines | |||
| 293 | free_instance(file_priv, ms); | 315 | free_instance(file_priv, ms); |
| 294 | 316 | ||
| 295 | mutex_unlock(&file_priv->ms_lock); | 317 | mutex_unlock(&file_priv->ms_lock); |
| 318 | |||
| 319 | pm_runtime_put_autosuspend(vdev->drm.dev); | ||
| 296 | } | 320 | } |
| 297 | 321 | ||
| 298 | void ivpu_ms_cleanup_all(struct ivpu_device *vdev) | 322 | void ivpu_ms_cleanup_all(struct ivpu_device *vdev) |
| @@ -428,16 +428,17 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) · 427 unmodified lines | |||
| 428 | active_us = (DCT_PERIOD_US * active_percent) / 100; | 428 | active_us = (DCT_PERIOD_US * active_percent) / 100; |
| 429 | inactive_us = DCT_PERIOD_US - active_us; | 429 | inactive_us = DCT_PERIOD_US - active_us; |
| 430 | 430 | ||
| 431 | vdev->pm->dct_active_percent = active_percent; | ||
| 432 | |||
| 433 | ivpu_dbg(vdev, PM, "DCT requested %u%% (D0: %uus, D0i2: %uus)\n", | ||
| 434 | active_percent, active_us, inactive_us); | ||
| 435 | |||
| 431 | ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); | 436 | ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); |
| 432 | if (ret) { | 437 | if (ret) { |
| 433 | ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); | 438 | ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); |
| 434 | return ret; | 439 | return ret; |
| 435 | } | 440 | } |
| 436 | 441 | ||
| 437 | vdev->pm->dct_active_percent = active_percent; | ||
| 438 | |||
| 439 | ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n", | ||
| 440 | active_percent, active_us, inactive_us); | ||
| 441 | return 0; | 442 | return 0; |
| 442 | } | 443 | } |
| 443 | 444 | ||
| @@ -445,15 +446,16 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) · 1 unmodified line | |||
| 445 | { | 446 | { |
| 446 | int ret; | 447 | int ret; |
| 447 | 448 | ||
| 449 | vdev->pm->dct_active_percent = 0; | ||
| 450 | |||
| 451 | ivpu_dbg(vdev, PM, "DCT requested to be disabled\n"); | ||
| 452 | |||
| 448 | ret = ivpu_jsm_dct_disable(vdev); | 453 | ret = ivpu_jsm_dct_disable(vdev); |
| 449 | if (ret) { | 454 | if (ret) { |
| 450 | ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); | 455 | ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); |
| 451 | return ret; | 456 | return ret; |
| 452 | } | 457 | } |
| 453 | 458 | ||
| 454 | vdev->pm->dct_active_percent = 0; | ||
| 455 | |||
| 456 | ivpu_dbg(vdev, PM, "DCT disabled\n"); | ||
| 457 | return 0; | 459 | return 0; |
| 458 | } | 460 | } |
| 459 | 461 | ||
| @@ -466,7 +468,7 @@ void ivpu_pm_irq_dct_work_fn(struct work_struct *work) · 6 unmodified lines | |||
| 466 | if (ivpu_hw_btrs_dct_get_request(vdev, &enable)) | 468 | if (ivpu_hw_btrs_dct_get_request(vdev, &enable)) |
| 467 | return; | 469 | return; |
| 468 | 470 | ||
| 469 | if (vdev->pm->dct_active_percent) | 471 | if (enable) |
| 470 | ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT); | 472 | ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT); |
| 471 | else | 473 | else |
| 472 | ret = ivpu_pm_dct_disable(vdev); | 474 | ret = ivpu_pm_dct_disable(vdev); |
| @@ -1,10 +1,12 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2024 Intel Corporation | 3 | * Copyright (C) 2024-2025 Intel Corporation |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/device.h> | 6 | #include <linux/device.h> |
| 7 | #include <linux/err.h> | 7 | #include <linux/err.h> |
| 8 | #include <linux/pm_runtime.h> | ||
| 9 | #include <linux/units.h> | ||
| 8 | 10 | ||
| 9 | #include "ivpu_drv.h" | 11 | #include "ivpu_drv.h" |
| 10 | #include "ivpu_gem.h" | 12 | #include "ivpu_gem.h" |
| @@ -90,10 +92,55 @@ sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf) · 79 unmodified lines | |||
| 90 | 92 | ||
| 91 | static DEVICE_ATTR_RO(sched_mode); | 93 | static DEVICE_ATTR_RO(sched_mode); |
| 92 | 94 | ||
| 95 | /** | ||
| 96 | * DOC: npu_max_frequency | ||
| 97 | * | ||
| 98 | * The npu_max_frequency shows maximum frequency in MHz of the NPU's data | ||
| 99 | * processing unit | ||
| 100 | */ | ||
| 101 | static ssize_t | ||
| 102 | npu_max_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 103 | { | ||
| 104 | struct drm_device *drm = dev_get_drvdata(dev); | ||
| 105 | struct ivpu_device *vdev = to_ivpu_device(drm); | ||
| 106 | u32 freq = ivpu_hw_dpu_max_freq_get(vdev); | ||
| 107 | |||
| 108 | return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ); | ||
| 109 | } | ||
| 110 | |||
| 111 | static DEVICE_ATTR_RO(npu_max_frequency_mhz); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * DOC: npu_current_frequency_mhz | ||
| 115 | * | ||
| 116 | * The npu_current_frequency_mhz shows current frequency in MHz of the NPU's | ||
| 117 | * data processing unit | ||
| 118 | */ | ||
| 119 | static ssize_t | ||
| 120 | npu_current_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 121 | { | ||
| 122 | struct drm_device *drm = dev_get_drvdata(dev); | ||
| 123 | struct ivpu_device *vdev = to_ivpu_device(drm); | ||
| 124 | u32 freq = 0; | ||
| 125 | |||
| 126 | /* Read frequency only if device is active, otherwise frequency is 0 */ | ||
| 127 | if (pm_runtime_get_if_active(vdev->drm.dev) > 0) { | ||
| 128 | freq = ivpu_hw_dpu_freq_get(vdev); | ||
| 129 | |||
| 130 | pm_runtime_put_autosuspend(vdev->drm.dev); | ||
| 131 | } | ||
| 132 | |||
| 133 | return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ); | ||
| 134 | } | ||
| 135 | |||
| 136 | static DEVICE_ATTR_RO(npu_current_frequency_mhz); | ||
| 137 | |||
| 93 | static struct attribute *ivpu_dev_attrs[] = { | 138 | static struct attribute *ivpu_dev_attrs[] = { |
| 94 | &dev_attr_npu_busy_time_us.attr, | 139 | &dev_attr_npu_busy_time_us.attr, |
| 95 | &dev_attr_npu_memory_utilization.attr, | 140 | &dev_attr_npu_memory_utilization.attr, |
| 96 | &dev_attr_sched_mode.attr, | 141 | &dev_attr_sched_mode.attr, |
| 142 | &dev_attr_npu_max_frequency_mhz.attr, | ||
| 143 | &dev_attr_npu_current_frequency_mhz.attr, | ||
| 97 | NULL, | 144 | NULL, |
| 98 | }; | 145 | }; |
| 99 | 146 | ||
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | * Minor version changes when API backward compatibility is preserved. | 26 | * Minor version changes when API backward compatibility is preserved. |
| 27 | * Resets to 0 if Major version is incremented. | 27 | * Resets to 0 if Major version is incremented. |
| 28 | */ | 28 | */ |
| 29 | #define VPU_BOOT_API_VER_MINOR 26 | 29 | #define VPU_BOOT_API_VER_MINOR 28 |
| 30 | 30 | ||
| 31 | /* | 31 | /* |
| 32 | * API header changed (field names, documentation, formatting) but API itself has not been changed | 32 | * API header changed (field names, documentation, formatting) but API itself has not been changed |
| @@ -76,8 +76,15 @@ struct vpu_firmware_header { · 43 unmodified lines | |||
| 76 | * submission queue size and device capabilities. | 76 | * submission queue size and device capabilities. |
| 77 | */ | 77 | */ |
| 78 | u32 preemption_buffer_2_size; | 78 | u32 preemption_buffer_2_size; |
| 79 | /* | ||
| 80 | * Maximum preemption buffer size that the FW can use: no need for the host | ||
| 81 | * driver to allocate more space than that specified by these fields. | ||
| 82 | * A value of 0 means no declared limit. | ||
| 83 | */ | ||
| 84 | u32 preemption_buffer_1_max_size; | ||
| 85 | u32 preemption_buffer_2_max_size; | ||
| 79 | /* Space reserved for future preemption-related fields. */ | 86 | /* Space reserved for future preemption-related fields. */ |
| 80 | u32 preemption_reserved[6]; | 87 | u32 preemption_reserved[4]; |
| 81 | /* FW image read only section start address, 4KB aligned */ | 88 | /* FW image read only section start address, 4KB aligned */ |
| 82 | u64 ro_section_start_address; | 89 | u64 ro_section_start_address; |
| 83 | /* FW image read only section size, 4KB aligned */ | 90 | /* FW image read only section size, 4KB aligned */ |
| @@ -134,7 +141,7 @@ enum vpu_trace_destination { · 50 unmodified lines | |||
| 134 | /* | 141 | /* |
| 135 | * Processor bit shifts (for loggable HW components). | 142 | * Processor bit shifts (for loggable HW components). |
| 136 | */ | 143 | */ |
| 137 | #define VPU_TRACE_PROC_BIT_ARM 0 | 144 | #define VPU_TRACE_PROC_BIT_RESERVED 0 |
| 138 | #define VPU_TRACE_PROC_BIT_LRT 1 | 145 | #define VPU_TRACE_PROC_BIT_LRT 1 |
| 139 | #define VPU_TRACE_PROC_BIT_LNN 2 | 146 | #define VPU_TRACE_PROC_BIT_LNN 2 |
| 140 | #define VPU_TRACE_PROC_BIT_SHV_0 3 | 147 | #define VPU_TRACE_PROC_BIT_SHV_0 3 |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | |||
| 22 | /* | 22 | /* |
| 23 | * Minor version changes when API backward compatibility is preserved. | 23 | * Minor version changes when API backward compatibility is preserved. |
| 24 | */ | 24 | */ |
| 25 | #define VPU_JSM_API_VER_MINOR 25 | 25 | #define VPU_JSM_API_VER_MINOR 29 |
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | * API header changed (field names, documentation, formatting) but API itself has not been changed | 28 | * API header changed (field names, documentation, formatting) but API itself has not been changed |
| @@ -53,8 +53,7 @@ · 24 unmodified lines | |||
| 53 | * Engine indexes. | 53 | * Engine indexes. |
| 54 | */ | 54 | */ |
| 55 | #define VPU_ENGINE_COMPUTE 0 | 55 | #define VPU_ENGINE_COMPUTE 0 |
| 56 | #define VPU_ENGINE_COPY 1 | 56 | #define VPU_ENGINE_NB 1 |
| 57 | #define VPU_ENGINE_NB 2 | ||
| 58 | 57 | ||
| 59 | /* | 58 | /* |
| 60 | * VPU status values. | 59 | * VPU status values. |
| @@ -126,11 +125,13 @@ enum { · 65 unmodified lines | |||
| 126 | * When set, indicates that job queue uses native fences (as inline commands | 125 | * When set, indicates that job queue uses native fences (as inline commands |
| 127 | * in job queue). Such queues may also use legacy fences (as commands in batch buffers). | 126 | * in job queue). Such queues may also use legacy fences (as commands in batch buffers). |
| 128 | * When cleared, indicates the job queue only uses legacy fences. | 127 | * When cleared, indicates the job queue only uses legacy fences. |
| 129 | * NOTE: For queues using native fences, VPU expects that all jobs in the queue | 128 | * NOTES: |
| 130 | * are immediately followed by an inline command object. This object is expected | 129 | * 1. For queues using native fences, VPU expects that all jobs in the queue |
| 131 | * to be a fence signal command in most cases, but can also be a NOP in case the host | 130 | * are immediately followed by an inline command object. This object is expected |
| 132 | * does not need per-job fence signalling. Other inline commands objects can be | 131 | * to be a fence signal command in most cases, but can also be a NOP in case the host |
| 133 | * inserted between "job and inline command" pairs. | 132 | * does not need per-job fence signalling. Other inline commands objects can be |
| 133 | * inserted between "job and inline command" pairs. | ||
| 134 | * 2. Native fence queues are only supported on VPU 40xx onwards. | ||
| 134 | */ | 135 | */ |
| 135 | VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), | 136 | VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), |
| 136 | 137 | ||
| @@ -275,6 +276,8 @@ struct vpu_inline_cmd { · 138 unmodified lines | |||
| 275 | u64 value; | 276 | u64 value; |
| 276 | /* User VA of the log buffer in which to add log entry on completion. */ | 277 | /* User VA of the log buffer in which to add log entry on completion. */ |
| 277 | u64 log_buffer_va; | 278 | u64 log_buffer_va; |
| 279 | /* NPU private data. */ | ||
| 280 | u64 npu_private_data; | ||
| 278 | } fence; | 281 | } fence; |
| 279 | /* Other commands do not have a payload. */ | 282 | /* Other commands do not have a payload. */ |
| 280 | /* Payload definition for future inline commands can be inserted here. */ | 283 | /* Payload definition for future inline commands can be inserted here. */ |
| @@ -791,12 +794,22 @@ struct vpu_jsm_metric_streamer_update { · 510 unmodified lines | |||
| 791 | /** Metric group mask that identifies metric streamer instance. */ | 794 | /** Metric group mask that identifies metric streamer instance. */ |
| 792 | u64 metric_group_mask; | 795 | u64 metric_group_mask; |
| 793 | /** | 796 | /** |
| 794 | * Address and size of the buffer where the VPU will write metric data. If | 797 | * Address and size of the buffer where the VPU will write metric data. |
| 795 | * the buffer address is 0 or same as the currently used buffer the VPU will | 798 | * This member dictates how the update operation should perform: |
| 796 | * continue writing metric data to the current buffer. In this case the | 799 | * 1. client needs information about the number of collected samples and the |
| 797 | * buffer size is ignored and the size of the current buffer is unchanged. | 800 | * amount of data written to the current buffer |
| 798 | * If the address is non-zero and differs from the current buffer address the | 801 | * 2. client wants to switch to a new buffer |
| 799 | * VPU will immediately switch data collection to the new buffer. | 802 | * |
| 803 | * Case 1. is identified by the buffer address being 0 or the same as the | ||
| 804 | * currently used buffer address. In this case the buffer size is ignored and | ||
| 805 | * the size of the current buffer is unchanged. The VPU will return an update | ||
| 806 | * in the vpu_jsm_metric_streamer_done structure. The internal writing position | ||
| 807 | * into the buffer is not changed. | ||
| 808 | * | ||
| 809 | * Case 2. is identified by the address being non-zero and differs from the | ||
| 810 | * current buffer address. The VPU will immediately switch data collection to | ||
| 811 | * the new buffer. Then the VPU will return an update in the | ||
| 812 | * vpu_jsm_metric_streamer_done structure. | ||
| 800 | */ | 813 | */ |
| 801 | u64 buffer_addr; | 814 | u64 buffer_addr; |
| 802 | u64 buffer_size; | 815 | u64 buffer_size; |
| @@ -934,6 +947,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { · 131 unmodified lines | |||
| 934 | /* | 947 | /* |
| 935 | * Default quantum in 100ns units for scheduling across processes | 948 | * Default quantum in 100ns units for scheduling across processes |
| 936 | * within a priority band | 949 | * within a priority band |
| 950 | * Minimum value supported by NPU is 1ms (10000 in 100ns units). | ||
| 937 | */ | 951 | */ |
| 938 | u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS]; | 952 | u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS]; |
| 939 | /* | 953 | /* |
| @@ -946,8 +960,10 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { · 6 unmodified lines | |||
| 946 | * in situations when it's starved by the focus band. | 960 | * in situations when it's starved by the focus band. |
| 947 | */ | 961 | */ |
| 948 | u32 normal_band_percentage; | 962 | u32 normal_band_percentage; |
| 949 | /* Reserved */ | 963 | /* |
| 950 | u32 reserved_0; | 964 | * TDR timeout value in milliseconds. Default value of 0 meaning no timeout. |
| 965 | */ | ||
| 966 | u32 tdr_timeout; | ||
| 951 | }; | 967 | }; |
| 952 | 968 | ||
| 953 | /* | 969 | /* |
| @@ -1024,7 +1040,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { · 70 unmodified lines | |||
| 1024 | s32 in_process_priority; | 1040 | s32 in_process_priority; |
| 1025 | /* Zero padding / Reserved */ | 1041 | /* Zero padding / Reserved */ |
| 1026 | u32 reserved_1; | 1042 | u32 reserved_1; |
| 1027 | /* Context quantum relative to other contexts of same priority in the same process */ | 1043 | /* |
| 1044 | * Context quantum relative to other contexts of same priority in the same process | ||
| 1045 | * Minimum value supported by NPU is 1ms (10000 in 100ns units). | ||
| 1046 | */ | ||
| 1028 | u64 context_quantum; | 1047 | u64 context_quantum; |
| 1029 | /* Grace period when preempting context of the same priority within the same process */ | 1048 | /* Grace period when preempting context of the same priority within the same process */ |
| 1030 | u64 grace_period_same_priority; | 1049 | u64 grace_period_same_priority; |
| @@ -293,7 +293,7 @@ acpi_status (*acpi_internal_method) (struct acpi_walk_state * walk_state); · 292 unmodified lines | |||
| 293 | * expected_return_btypes - Allowed type(s) for the return value | 293 | * expected_return_btypes - Allowed type(s) for the return value |
| 294 | */ | 294 | */ |
| 295 | struct acpi_name_info { | 295 | struct acpi_name_info { |
| 296 | char name[ACPI_NAMESEG_SIZE]; | 296 | char name[ACPI_NAMESEG_SIZE] __nonstring; |
| 297 | u16 argument_list; | 297 | u16 argument_list; |
| 298 | u8 expected_btypes; | 298 | u8 expected_btypes; |
| 299 | }; | 299 | }; |
| @@ -370,7 +370,7 @@ typedef acpi_status (*acpi_object_converter) (struct acpi_namespace_node * · 70 unmodified lines | |||
| 370 | converted_object); | 370 | converted_object); |
| 371 | 371 | ||
| 372 | struct acpi_simple_repair_info { | 372 | struct acpi_simple_repair_info { |
| 373 | char name[ACPI_NAMESEG_SIZE]; | 373 | char name[ACPI_NAMESEG_SIZE] __nonstring; |
| 374 | u32 unexpected_btypes; | 374 | u32 unexpected_btypes; |
| 375 | u32 package_index; | 375 | u32 package_index; |
| 376 | acpi_object_converter object_converter; | 376 | acpi_object_converter object_converter; |
| @@ -25,7 +25,7 @@ acpi_status (*acpi_repair_function) (struct acpi_evaluate_info * info, · 24 unmodified lines | |||
| 25 | return_object_ptr); | 25 | return_object_ptr); |
| 26 | 26 | ||
| 27 | typedef struct acpi_repair_info { | 27 | typedef struct acpi_repair_info { |
| 28 | char name[ACPI_NAMESEG_SIZE]; | 28 | char name[ACPI_NAMESEG_SIZE] __nonstring; |
| 29 | acpi_repair_function repair_function; | 29 | acpi_repair_function repair_function; |
| 30 | 30 | ||
| 31 | } acpi_repair_info; | 31 | } acpi_repair_info; |
| @@ -458,7 +458,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) · 457 unmodified lines | |||
| 458 | acpi_pm_wakeup_event(&device->dev); | 458 | acpi_pm_wakeup_event(&device->dev); |
| 459 | 459 | ||
| 460 | button = acpi_driver_data(device); | 460 | button = acpi_driver_data(device); |
| 461 | if (button->suspended) | 461 | if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) |
| 462 | return; | 462 | return; |
| 463 | 463 | ||
| 464 | input = button->input; | 464 | input = button->input; |
| @@ -2301,6 +2301,34 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { · 2300 unmodified lines | |||
| 2301 | DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), | 2301 | DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), |
| 2302 | }, | 2302 | }, |
| 2303 | }, | 2303 | }, |
| 2304 | /* | ||
| 2305 | * Lenovo Legion Go S; touchscreen blocks HW sleep when woken up from EC | ||
| 2306 | * https://gitlab.freedesktop.org/drm/amd/-/issues/3929 | ||
| 2307 | */ | ||
| 2308 | { | ||
| 2309 | .matches = { | ||
| 2310 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 2311 | DMI_MATCH(DMI_PRODUCT_NAME, "83L3"), | ||
| 2312 | } | ||
| 2313 | }, | ||
| 2314 | { | ||
| 2315 | .matches = { | ||
| 2316 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 2317 | DMI_MATCH(DMI_PRODUCT_NAME, "83N6"), | ||
| 2318 | } | ||
| 2319 | }, | ||
| 2320 | { | ||
| 2321 | .matches = { | ||
| 2322 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 2323 | DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"), | ||
| 2324 | } | ||
| 2325 | }, | ||
| 2326 | { | ||
| 2327 | .matches = { | ||
| 2328 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 2329 | DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), | ||
| 2330 | } | ||
| 2331 | }, | ||
| 2304 | { }, | 2332 | { }, |
| 2305 | }; | 2333 | }; |
| 2306 | 2334 | ||
| @@ -229,18 +229,20 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr, · 228 unmodified lines | |||
| 229 | node_entry = ACPI_PTR_DIFF(node, table_hdr); | 229 | node_entry = ACPI_PTR_DIFF(node, table_hdr); |
| 230 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, | 230 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
| 231 | sizeof(struct acpi_table_pptt)); | 231 | sizeof(struct acpi_table_pptt)); |
| 232 | proc_sz = sizeof(struct acpi_pptt_processor *); | 232 | proc_sz = sizeof(struct acpi_pptt_processor); |
| 233 | 233 | ||
| 234 | while ((unsigned long)entry + proc_sz < table_end) { | 234 | /* ignore subtable types that are smaller than a processor node */ |
| 235 | while ((unsigned long)entry + proc_sz <= table_end) { | ||
| 235 | cpu_node = (struct acpi_pptt_processor *)entry; | 236 | cpu_node = (struct acpi_pptt_processor *)entry; |
| 237 | |||
| 236 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && | 238 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && |
| 237 | cpu_node->parent == node_entry) | 239 | cpu_node->parent == node_entry) |
| 238 | return 0; | 240 | return 0; |
| 239 | if (entry->length == 0) | 241 | if (entry->length == 0) |
| 240 | return 0; | 242 | return 0; |
| 243 | |||
| 241 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, | 244 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, |
| 242 | entry->length); | 245 | entry->length); |
| 243 | |||
| 244 | } | 246 | } |
| 245 | return 1; | 247 | return 1; |
| 246 | } | 248 | } |
| @@ -270,18 +272,21 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he · 23 unmodified lines | |||
| 270 | table_end = (unsigned long)table_hdr + table_hdr->length; | 272 | table_end = (unsigned long)table_hdr + table_hdr->length; |
| 271 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, | 273 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
| 272 | sizeof(struct acpi_table_pptt)); | 274 | sizeof(struct acpi_table_pptt)); |
| 273 | proc_sz = sizeof(struct acpi_pptt_processor *); | 275 | proc_sz = sizeof(struct acpi_pptt_processor); |
| 274 | 276 | ||
| 275 | /* find the processor structure associated with this cpuid */ | 277 | /* find the processor structure associated with this cpuid */ |
| 276 | while ((unsigned long)entry + proc_sz < table_end) { | 278 | while ((unsigned long)entry + proc_sz <= table_end) { |
| 277 | cpu_node = (struct acpi_pptt_processor *)entry; | 279 | cpu_node = (struct acpi_pptt_processor *)entry; |
| 278 | 280 | ||
| 279 | if (entry->length == 0) { | 281 | if (entry->length == 0) { |
| 280 | pr_warn("Invalid zero length subtable\n"); | 282 | pr_warn("Invalid zero length subtable\n"); |
| 281 | break; | 283 | break; |
| 282 | } | 284 | } |
| 285 | /* entry->length may not equal proc_sz, revalidate the processor structure length */ | ||
| 283 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && | 286 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && |
| 284 | acpi_cpu_id == cpu_node->acpi_processor_id && | 287 | acpi_cpu_id == cpu_node->acpi_processor_id && |
| 288 | (unsigned long)entry + entry->length <= table_end && | ||
| 289 | entry->length == proc_sz + cpu_node->number_of_priv_resources * sizeof(u32) && | ||
| 285 | acpi_pptt_leaf_node(table_hdr, cpu_node)) { | 290 | acpi_pptt_leaf_node(table_hdr, cpu_node)) { |
| 286 | return (struct acpi_pptt_processor *)entry; | 291 | return (struct acpi_pptt_processor *)entry; |
| 287 | } | 292 | } |
| @@ -6373,7 +6373,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, · 6372 unmodified lines | |||
| 6373 | seq_printf(m, " node %d", buffer->target_node->debug_id); | 6373 | seq_printf(m, " node %d", buffer->target_node->debug_id); |
| 6374 | seq_printf(m, " size %zd:%zd offset %lx\n", | 6374 | seq_printf(m, " size %zd:%zd offset %lx\n", |
| 6375 | buffer->data_size, buffer->offsets_size, | 6375 | buffer->data_size, buffer->offsets_size, |
| 6376 | proc->alloc.vm_start - buffer->user_data); | 6376 | buffer->user_data - proc->alloc.vm_start); |
| 6377 | } | 6377 | } |
| 6378 | 6378 | ||
| 6379 | static void print_binder_work_ilocked(struct seq_file *m, | 6379 | static void print_binder_work_ilocked(struct seq_file *m, |
| @@ -1510,6 +1510,8 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link) · 1509 unmodified lines | |||
| 1510 | unsigned int err_mask, tag; | 1510 | unsigned int err_mask, tag; |
| 1511 | u8 *sense, sk = 0, asc = 0, ascq = 0; | 1511 | u8 *sense, sk = 0, asc = 0, ascq = 0; |
| 1512 | u64 sense_valid, val; | 1512 | u64 sense_valid, val; |
| 1513 | u16 extended_sense; | ||
| 1514 | bool aux_icc_valid; | ||
| 1513 | int ret = 0; | 1515 | int ret = 0; |
| 1514 | 1516 | ||
| 1515 | err_mask = ata_read_log_page(dev, ATA_LOG_SENSE_NCQ, 0, buf, 2); | 1517 | 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) · 13 unmodified lines | |||
| 1529 | 1531 | ||
| 1530 | sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) | | 1532 | sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) | |
| 1531 | ((u64)buf[10] << 16) | ((u64)buf[11] << 24); | 1533 | ((u64)buf[10] << 16) | ((u64)buf[11] << 24); |
| 1534 | extended_sense = get_unaligned_le16(&buf[14]); | ||
| 1535 | aux_icc_valid = extended_sense & BIT(15); | ||
| 1532 | 1536 | ||
| 1533 | ata_qc_for_each_raw(ap, qc, tag) { | 1537 | ata_qc_for_each_raw(ap, qc, tag) { |
| 1534 | if (!(qc->flags & ATA_QCFLAG_EH) || | 1538 | if (!(qc->flags & ATA_QCFLAG_EH) || |
| @@ -1556,6 +1560,17 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link) · 21 unmodified lines | |||
| 1556 | continue; | 1560 | continue; |
| 1557 | } | 1561 | } |
| 1558 | 1562 | ||
| 1563 | qc->result_tf.nsect = sense[6]; | ||
| 1564 | qc->result_tf.hob_nsect = sense[7]; | ||
| 1565 | qc->result_tf.lbal = sense[8]; | ||
| 1566 | qc->result_tf.lbam = sense[9]; | ||
| 1567 | qc->result_tf.lbah = sense[10]; | ||
| 1568 | qc->result_tf.hob_lbal = sense[11]; | ||
| 1569 | qc->result_tf.hob_lbam = sense[12]; | ||
| 1570 | qc->result_tf.hob_lbah = sense[13]; | ||
| 1571 | if (aux_icc_valid) | ||
| 1572 | qc->result_tf.auxiliary = get_unaligned_le32(&sense[16]); | ||
| 1573 | |||
| 1559 | /* Set sense without also setting scsicmd->result */ | 1574 | /* Set sense without also setting scsicmd->result */ |
| 1560 | scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, | 1575 | scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, |
| 1561 | qc->scsicmd->sense_buffer, sk, | 1576 | qc->scsicmd->sense_buffer, sk, |
| @@ -2453,8 +2453,8 @@ static unsigned int ata_msense_control_ata_feature(struct ata_device *dev, · 2452 unmodified lines | |||
| 2453 | */ | 2453 | */ |
| 2454 | put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]); | 2454 | put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]); |
| 2455 | 2455 | ||
| 2456 | if (dev->flags & ATA_DFLAG_CDL) | 2456 | if (dev->flags & ATA_DFLAG_CDL_ENABLED) |
| 2457 | buf[4] = 0x02; /* Support T2A and T2B pages */ | 2457 | buf[4] = 0x02; /* T2A and T2B pages enabled */ |
| 2458 | else | 2458 | else |
| 2459 | buf[4] = 0; | 2459 | buf[4] = 0; |
| 2460 | 2460 | ||
| @@ -3886,12 +3886,11 @@ static int ata_mselect_control_spg0(struct ata_queued_cmd *qc, · 1425 unmodified lines | |||
| 3886 | } | 3886 | } |
| 3887 | 3887 | ||
| 3888 | /* | 3888 | /* |
| 3889 | * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode | 3889 | * Translate MODE SELECT control mode page, sub-page f2h (ATA feature mode |
| 3890 | * page) into a SET FEATURES command. | 3890 | * page) into a SET FEATURES command. |
| 3891 | */ | 3891 | */ |
| 3892 | static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, | 3892 | static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, |
| 3893 | const u8 *buf, int len, | 3893 | const u8 *buf, int len, u16 *fp) |
| 3894 | u16 *fp) | ||
| 3895 | { | 3894 | { |
| 3896 | struct ata_device *dev = qc->dev; | 3895 | struct ata_device *dev = qc->dev; |
| 3897 | struct ata_taskfile *tf = &qc->tf; | 3896 | struct ata_taskfile *tf = &qc->tf; |
| @@ -3909,17 +3908,27 @@ static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, · 11 unmodified lines | |||
| 3909 | /* Check cdl_ctrl */ | 3908 | /* Check cdl_ctrl */ |
| 3910 | switch (buf[0] & 0x03) { | 3909 | switch (buf[0] & 0x03) { |
| 3911 | case 0: | 3910 | case 0: |
| 3912 | /* Disable CDL */ | 3911 | /* Disable CDL if it is enabled */ |
| 3912 | if (!(dev->flags & ATA_DFLAG_CDL_ENABLED)) | ||
| 3913 | return 0; | ||
| 3914 | ata_dev_dbg(dev, "Disabling CDL\n"); | ||
| 3913 | cdl_action = 0; | 3915 | cdl_action = 0; |
| 3914 | dev->flags &= ~ATA_DFLAG_CDL_ENABLED; | 3916 | dev->flags &= ~ATA_DFLAG_CDL_ENABLED; |
| 3915 | break; | 3917 | break; |
| 3916 | case 0x02: | 3918 | case 0x02: |
| 3917 | /* Enable CDL T2A/T2B: NCQ priority must be disabled */ | 3919 | /* |
| 3920 | * Enable CDL if not already enabled. Since this is mutually | ||
| 3921 | * exclusive with NCQ priority, allow this only if NCQ priority | ||
| 3922 | * is disabled. | ||
| 3923 | */ | ||
| 3924 | if (dev->flags & ATA_DFLAG_CDL_ENABLED) | ||
| 3925 | return 0; | ||
| 3918 | if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { | 3926 | if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { |
| 3919 | ata_dev_err(dev, | 3927 | ata_dev_err(dev, |
| 3920 | "NCQ priority must be disabled to enable CDL\n"); | 3928 | "NCQ priority must be disabled to enable CDL\n"); |
| 3921 | return -EINVAL; | 3929 | return -EINVAL; |
| 3922 | } | 3930 | } |
| 3931 | ata_dev_dbg(dev, "Enabling CDL\n"); | ||
| 3923 | cdl_action = 1; | 3932 | cdl_action = 1; |
| 3924 | dev->flags |= ATA_DFLAG_CDL_ENABLED; | 3933 | dev->flags |= ATA_DFLAG_CDL_ENABLED; |
| 3925 | break; | 3934 | break; |
| @@ -223,10 +223,16 @@ static int pxa_ata_probe(struct platform_device *pdev) · 222 unmodified lines | |||
| 223 | 223 | ||
| 224 | ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start, | 224 | ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start, |
| 225 | resource_size(cmd_res)); | 225 | resource_size(cmd_res)); |
| 226 | if (!ap->ioaddr.cmd_addr) | ||
| 227 | return -ENOMEM; | ||
| 226 | ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, | 228 | ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, |
| 227 | resource_size(ctl_res)); | 229 | resource_size(ctl_res)); |
| 230 | if (!ap->ioaddr.ctl_addr) | ||
| 231 | return -ENOMEM; | ||
| 228 | ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start, | 232 | ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start, |
| 229 | resource_size(dma_res)); | 233 | resource_size(dma_res)); |
| 234 | if (!ap->ioaddr.bmdma_addr) | ||
| 235 | return -ENOMEM; | ||
| 230 | 236 | ||
| 231 | /* | 237 | /* |
| 232 | * Adjust register offsets | 238 | * Adjust register offsets |
| @@ -1117,9 +1117,14 @@ static int pdc20621_prog_dimm0(struct ata_host *host) · 1116 unmodified lines | |||
| 1117 | mmio += PDC_CHIP0_OFS; | 1117 | mmio += PDC_CHIP0_OFS; |
| 1118 | 1118 | ||
| 1119 | for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++) | 1119 | for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++) |
| 1120 | pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, | 1120 | if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, |
| 1121 | pdc_i2c_read_data[i].reg, | 1121 | pdc_i2c_read_data[i].reg, |
| 1122 | &spd0[pdc_i2c_read_data[i].ofs]); | 1122 | &spd0[pdc_i2c_read_data[i].ofs])) { |
| 1123 | dev_err(host->dev, | ||
| 1124 | "Failed in i2c read at index %d: device=%#x, reg=%#x\n", | ||
| 1125 | i, PDC_DIMM0_SPD_DEV_ADDRESS, pdc_i2c_read_data[i].reg); | ||
| 1126 | return -EIO; | ||
| 1127 | } | ||
| 1123 | 1128 | ||
| 1124 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); | 1129 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); |
| 1125 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | | 1130 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | |
| @@ -1284,6 +1289,8 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) · 158 unmodified lines | |||
| 1284 | 1289 | ||
| 1285 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ | 1290 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ |
| 1286 | size = pdc20621_prog_dimm0(host); | 1291 | size = pdc20621_prog_dimm0(host); |
| 1292 | if (size < 0) | ||
| 1293 | return size; | ||
| 1287 | dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size); | 1294 | dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size); |
| 1288 | 1295 | ||
| 1289 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ | 1296 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ |
| @@ -156,6 +156,16 @@ · 155 unmodified lines | |||
| 156 | * }, | 156 | * }, |
| 157 | * .ops = my_custom_ops, | 157 | * .ops = my_custom_ops, |
| 158 | * }; | 158 | * }; |
| 159 | * | ||
| 160 | * Please note that such custom ops approach is valid, but it is hard to implement | ||
| 161 | * it right without global locks per-device to protect from auxiliary_drv removal | ||
| 162 | * during call to that ops. In addition, this implementation lacks proper module | ||
| 163 | * dependency, which causes to load/unload races between auxiliary parent and devices | ||
| 164 | * modules. | ||
| 165 | * | ||
| 166 | * The most easiest way to provide these ops reliably without needing to | ||
| 167 | * have a lock is to EXPORT_SYMBOL*() them and rely on already existing | ||
| 168 | * modules infrastructure for validity and correct dependencies chains. | ||
| 159 | */ | 169 | */ |
| 160 | 170 | ||
| 161 | static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, | 171 | static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, |
| @@ -73,6 +73,7 @@ static inline void subsys_put(struct subsys_private *sp) · 72 unmodified lines | |||
| 73 | kset_put(&sp->subsys); | 73 | kset_put(&sp->subsys); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | struct subsys_private *bus_to_subsys(const struct bus_type *bus); | ||
| 76 | struct subsys_private *class_to_subsys(const struct class *class); | 77 | struct subsys_private *class_to_subsys(const struct class *class); |
| 77 | 78 | ||
| 78 | struct driver_private { | 79 | struct driver_private { |
| @@ -180,6 +181,22 @@ int driver_add_groups(const struct device_driver *drv, const struct attribute_gr · 101 unmodified lines | |||
| 180 | void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); | 181 | void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); |
| 181 | void device_driver_detach(struct device *dev); | 182 | void device_driver_detach(struct device *dev); |
| 182 | 183 | ||
| 184 | static inline void device_set_driver(struct device *dev, const struct device_driver *drv) | ||
| 185 | { | ||
| 186 | /* | ||
| 187 | * Majority (all?) read accesses to dev->driver happens either | ||
| 188 | * while holding device lock or in bus/driver code that is only | ||
| 189 | * invoked when the device is bound to a driver and there is no | ||
| 190 | * concern of the pointer being changed while it is being read. | ||
| 191 | * However when reading device's uevent file we read driver pointer | ||
| 192 | * without taking device lock (so we do not block there for | ||
| 193 | * arbitrary amount of time). We use WRITE_ONCE() here to prevent | ||
| 194 | * tearing so that READ_ONCE() can safely be used in uevent code. | ||
| 195 | */ | ||
| 196 | // FIXME - this cast should not be needed "soon" | ||
| 197 | WRITE_ONCE(dev->driver, (struct device_driver *)drv); | ||
| 198 | } | ||
| 199 | |||
| 183 | int devres_release_all(struct device *dev); | 200 | int devres_release_all(struct device *dev); |
| 184 | void device_block_probing(void); | 201 | void device_block_probing(void); |
| 185 | void device_unblock_probing(void); | 202 | void device_unblock_probing(void); |
| @@ -57,7 +57,7 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, · 56 unmodified lines | |||
| 57 | * NULL. A call to subsys_put() must be done when finished with the pointer in | 57 | * NULL. A call to subsys_put() must be done when finished with the pointer in |
| 58 | * order for it to be properly freed. | 58 | * order for it to be properly freed. |
| 59 | */ | 59 | */ |
| 60 | static struct subsys_private *bus_to_subsys(const struct bus_type *bus) | 60 | struct subsys_private *bus_to_subsys(const struct bus_type *bus) |
| 61 | { | 61 | { |
| 62 | struct subsys_private *sp = NULL; | 62 | struct subsys_private *sp = NULL; |
| 63 | struct kobject *kobj; | 63 | struct kobject *kobj; |
| @@ -2624,6 +2624,35 @@ static const char *dev_uevent_name(const struct kobject *kobj) · 2623 unmodified lines | |||
| 2624 | return NULL; | 2624 | return NULL; |
| 2625 | } | 2625 | } |
| 2626 | 2626 | ||
| 2627 | /* | ||
| 2628 | * Try filling "DRIVER=<name>" uevent variable for a device. Because this | ||
| 2629 | * function may race with binding and unbinding the device from a driver, | ||
| 2630 | * we need to be careful. Binding is generally safe, at worst we miss the | ||
| 2631 | * fact that the device is already bound to a driver (but the driver | ||
| 2632 | * information that is delivered through uevents is best-effort, it may | ||
| 2633 | * become obsolete as soon as it is generated anyways). Unbinding is more | ||
| 2634 | * risky as driver pointer is transitioning to NULL, so READ_ONCE() should | ||
| 2635 | * be used to make sure we are dealing with the same pointer, and to | ||
| 2636 | * ensure that driver structure is not going to disappear from under us | ||
| 2637 | * we take bus' drivers klist lock. The assumption that only registered | ||
| 2638 | * driver can be bound to a device, and to unregister a driver bus code | ||
| 2639 | * will take the same lock. | ||
| 2640 | */ | ||
| 2641 | static void dev_driver_uevent(const struct device *dev, struct kobj_uevent_env *env) | ||
| 2642 | { | ||
| 2643 | struct subsys_private *sp = bus_to_subsys(dev->bus); | ||
| 2644 | |||
| 2645 | if (sp) { | ||
| 2646 | scoped_guard(spinlock, &sp->klist_drivers.k_lock) { | ||
| 2647 | struct device_driver *drv = READ_ONCE(dev->driver); | ||
| 2648 | if (drv) | ||
| 2649 | add_uevent_var(env, "DRIVER=%s", drv->name); | ||
| 2650 | } | ||
| 2651 | |||
| 2652 | subsys_put(sp); | ||
| 2653 | } | ||
| 2654 | } | ||
| 2655 | |||
| 2627 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) | 2656 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
| 2628 | { | 2657 | { |
| 2629 | const struct device *dev = kobj_to_dev(kobj); | 2658 | const struct device *dev = kobj_to_dev(kobj); |
| @@ -2655,8 +2684,8 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) · 25 unmodified lines | |||
| 2655 | if (dev->type && dev->type->name) | 2684 | if (dev->type && dev->type->name) |
| 2656 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); | 2685 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
| 2657 | 2686 | ||
| 2658 | if (dev->driver) | 2687 | /* Add "DRIVER=%s" variable if the device is bound to a driver */ |
| 2659 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); | 2688 | dev_driver_uevent(dev, env); |
| 2660 | 2689 | ||
| 2661 | /* Add common DT information about the device */ | 2690 | /* Add common DT information about the device */ |
| 2662 | of_device_uevent(dev, env); | 2691 | of_device_uevent(dev, env); |
| @@ -2726,11 +2755,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, · 63 unmodified lines | |||
| 2726 | if (!env) | 2755 | if (!env) |
| 2727 | return -ENOMEM; | 2756 | return -ENOMEM; |
| 2728 | 2757 | ||
| 2729 | /* Synchronize with really_probe() */ | ||
| 2730 | device_lock(dev); | ||
| 2731 | /* let the kset specific function add its keys */ | 2758 | /* let the kset specific function add its keys */ |
| 2732 | retval = kset->uevent_ops->uevent(&dev->kobj, env); | 2759 | retval = kset->uevent_ops->uevent(&dev->kobj, env); |
| 2733 | device_unlock(dev); | ||
| 2734 | if (retval) | 2760 | if (retval) |
| 2735 | goto out; | 2761 | goto out; |
| 2736 | 2762 | ||
| @@ -3700,7 +3726,7 @@ done: · 963 unmodified lines | |||
| 3700 | device_pm_remove(dev); | 3726 | device_pm_remove(dev); |
| 3701 | dpm_sysfs_remove(dev); | 3727 | dpm_sysfs_remove(dev); |
| 3702 | DPMError: | 3728 | DPMError: |
| 3703 | dev->driver = NULL; | 3729 | device_set_driver(dev, NULL); |
| 3704 | bus_remove_device(dev); | 3730 | bus_remove_device(dev); |
| 3705 | BusError: | 3731 | BusError: |
| 3706 | device_remove_attrs(dev); | 3732 | device_remove_attrs(dev); |
| @@ -600,6 +600,7 @@ CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); · 599 unmodified lines | |||
| 600 | CPU_SHOW_VULN_FALLBACK(gds); | 600 | CPU_SHOW_VULN_FALLBACK(gds); |
| 601 | CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); | 601 | CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); |
| 602 | CPU_SHOW_VULN_FALLBACK(ghostwrite); | 602 | CPU_SHOW_VULN_FALLBACK(ghostwrite); |
| 603 | CPU_SHOW_VULN_FALLBACK(indirect_target_selection); | ||
| 603 | 604 | ||
| 604 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); | 605 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 605 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); | 606 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
| @@ -616,6 +617,7 @@ static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NU · 10 unmodified lines | |||
| 616 | static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); | 617 | static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); |
| 617 | static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); | 618 | static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); |
| 618 | static DEVICE_ATTR(ghostwrite, 0444, cpu_show_ghostwrite, NULL); | 619 | static DEVICE_ATTR(ghostwrite, 0444, cpu_show_ghostwrite, NULL); |
| 620 | static DEVICE_ATTR(indirect_target_selection, 0444, cpu_show_indirect_target_selection, NULL); | ||
| 619 | 621 | ||
| 620 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { | 622 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 621 | &dev_attr_meltdown.attr, | 623 | &dev_attr_meltdown.attr, |
| @@ -633,6 +635,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { · 11 unmodified lines | |||
| 633 | &dev_attr_gather_data_sampling.attr, | 635 | &dev_attr_gather_data_sampling.attr, |
| 634 | &dev_attr_reg_file_data_sampling.attr, | 636 | &dev_attr_reg_file_data_sampling.attr, |
| 635 | &dev_attr_ghostwrite.attr, | 637 | &dev_attr_ghostwrite.attr, |
| 638 | &dev_attr_indirect_target_selection.attr, | ||
| 636 | NULL | 639 | NULL |
| 637 | }; | 640 | }; |
| 638 | 641 | ||
| @@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct device *dev) · 549 unmodified lines | |||
| 550 | arch_teardown_dma_ops(dev); | 550 | arch_teardown_dma_ops(dev); |
| 551 | kfree(dev->dma_range_map); | 551 | kfree(dev->dma_range_map); |
| 552 | dev->dma_range_map = NULL; | 552 | dev->dma_range_map = NULL; |
| 553 | dev->driver = NULL; | 553 | device_set_driver(dev, NULL); |
| 554 | dev_set_drvdata(dev, NULL); | 554 | dev_set_drvdata(dev, NULL); |
| 555 | if (dev->pm_domain && dev->pm_domain->dismiss) | 555 | if (dev->pm_domain && dev->pm_domain->dismiss) |
| 556 | dev->pm_domain->dismiss(dev); | 556 | dev->pm_domain->dismiss(dev); |
| @@ -629,8 +629,7 @@ static int really_probe(struct device *dev, const struct device_driver *drv) · 72 unmodified lines | |||
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | re_probe: | 631 | re_probe: |
| 632 | // FIXME - this cast should not be needed "soon" | 632 | device_set_driver(dev, drv); |
| 633 | dev->driver = (struct device_driver *)drv; | ||
| 634 | 633 | ||
| 635 | /* If using pinctrl, bind pins now before probing */ | 634 | /* If using pinctrl, bind pins now before probing */ |
| 636 | ret = pinctrl_bind_pins(dev); | 635 | ret = pinctrl_bind_pins(dev); |
| @@ -1014,7 +1013,7 @@ static int __device_attach(struct device *dev, bool allow_async) · 377 unmodified lines | |||
| 1014 | if (ret == 0) | 1013 | if (ret == 0) |
| 1015 | ret = 1; | 1014 | ret = 1; |
| 1016 | else { | 1015 | else { |
| 1017 | dev->driver = NULL; | 1016 | device_set_driver(dev, NULL); |
| 1018 | ret = 0; | 1017 | ret = 0; |
| 1019 | } | 1018 | } |
| 1020 | } else { | 1019 | } else { |
| @@ -296,7 +296,7 @@ static int delete_path(const char *nodepath) · 295 unmodified lines | |||
| 296 | return err; | 296 | return err; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat) | 299 | static int dev_mynode(struct device *dev, struct inode *inode) |
| 300 | { | 300 | { |
| 301 | /* did we create it */ | 301 | /* did we create it */ |
| 302 | if (inode->i_private != &thread) | 302 | if (inode->i_private != &thread) |
| @@ -304,13 +304,13 @@ static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *sta · 1 unmodified line | |||
| 304 | 304 | ||
| 305 | /* does the dev_t match */ | 305 | /* does the dev_t match */ |
| 306 | if (is_blockdev(dev)) { | 306 | if (is_blockdev(dev)) { |
| 307 | if (!S_ISBLK(stat->mode)) | 307 | if (!S_ISBLK(inode->i_mode)) |
| 308 | return 0; | 308 | return 0; |
| 309 | } else { | 309 | } else { |
| 310 | if (!S_ISCHR(stat->mode)) | 310 | if (!S_ISCHR(inode->i_mode)) |
| 311 | return 0; | 311 | return 0; |
| 312 | } | 312 | } |
| 313 | if (stat->rdev != dev->devt) | 313 | if (inode->i_rdev != dev->devt) |
| 314 | return 0; | 314 | return 0; |
| 315 | 315 | ||
| 316 | /* ours */ | 316 | /* ours */ |
| @@ -321,20 +321,16 @@ static int handle_remove(const char *nodename, struct device *dev) · 4 unmodified lines | |||
| 321 | { | 321 | { |
| 322 | struct path parent; | 322 | struct path parent; |
| 323 | struct dentry *dentry; | 323 | struct dentry *dentry; |
| 324 | struct kstat stat; | 324 | struct inode *inode; |
| 325 | struct path p; | ||
| 326 | int deleted = 0; | 325 | int deleted = 0; |
| 327 | int err; | 326 | int err = 0; |
| 328 | 327 | ||
| 329 | dentry = kern_path_locked(nodename, &parent); | 328 | dentry = kern_path_locked(nodename, &parent); |
| 330 | if (IS_ERR(dentry)) | 329 | if (IS_ERR(dentry)) |
| 331 | return PTR_ERR(dentry); | 330 | return PTR_ERR(dentry); |
| 332 | 331 | ||
| 333 | p.mnt = parent.mnt; | 332 | inode = d_inode(dentry); |
| 334 | p.dentry = dentry; | 333 | if (dev_mynode(dev, inode)) { |
| 335 | err = vfs_getattr(&p, &stat, STATX_TYPE | STATX_MODE, | ||
| 336 | AT_STATX_SYNC_AS_STAT); | ||
| 337 | if (!err && dev_mynode(dev, d_inode(dentry), &stat)) { | ||
| 338 | struct iattr newattrs; | 334 | struct iattr newattrs; |
| 339 | /* | 335 | /* |
| 340 | * before unlinking this node, reset permissions | 336 | * before unlinking this node, reset permissions |
| @@ -342,7 +338,7 @@ static int handle_remove(const char *nodename, struct device *dev) · 1 unmodified line | |||
| 342 | */ | 338 | */ |
| 343 | newattrs.ia_uid = GLOBAL_ROOT_UID; | 339 | newattrs.ia_uid = GLOBAL_ROOT_UID; |
| 344 | newattrs.ia_gid = GLOBAL_ROOT_GID; | 340 | newattrs.ia_gid = GLOBAL_ROOT_GID; |
| 345 | newattrs.ia_mode = stat.mode & ~0777; | 341 | newattrs.ia_mode = inode->i_mode & ~0777; |
| 346 | newattrs.ia_valid = | 342 | newattrs.ia_valid = |
| 347 | ATTR_UID|ATTR_GID|ATTR_MODE; | 343 | ATTR_UID|ATTR_GID|ATTR_MODE; |
| 348 | inode_lock(d_inode(dentry)); | 344 | inode_lock(d_inode(dentry)); |
| @@ -816,21 +816,6 @@ static int add_memory_block(unsigned long block_id, unsigned long state, · 815 unmodified lines | |||
| 816 | return 0; | 816 | return 0; |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | static int __init add_boot_memory_block(unsigned long base_section_nr) | ||
| 820 | { | ||
| 821 | unsigned long nr; | ||
| 822 | |||
| 823 | for_each_present_section_nr(base_section_nr, nr) { | ||
| 824 | if (nr >= (base_section_nr + sections_per_block)) | ||
| 825 | break; | ||
| 826 | |||
| 827 | return add_memory_block(memory_block_id(base_section_nr), | ||
| 828 | MEM_ONLINE, NULL, NULL); | ||
| 829 | } | ||
| 830 | |||
| 831 | return 0; | ||
| 832 | } | ||
| 833 | |||
| 834 | static int add_hotplug_memory_block(unsigned long block_id, | 819 | static int add_hotplug_memory_block(unsigned long block_id, |
| 835 | struct vmem_altmap *altmap, | 820 | struct vmem_altmap *altmap, |
| 836 | struct memory_group *group) | 821 | struct memory_group *group) |
| @@ -957,7 +942,7 @@ static const struct attribute_group *memory_root_attr_groups[] = { · 120 unmodified lines | |||
| 957 | void __init memory_dev_init(void) | 942 | void __init memory_dev_init(void) |
| 958 | { | 943 | { |
| 959 | int ret; | 944 | int ret; |
| 960 | unsigned long block_sz, nr; | 945 | unsigned long block_sz, block_id, nr; |
| 961 | 946 | ||
| 962 | /* Validate the configured memory block size */ | 947 | /* Validate the configured memory block size */ |
| 963 | block_sz = memory_block_size_bytes(); | 948 | block_sz = memory_block_size_bytes(); |
| @@ -970,15 +955,23 @@ void __init memory_dev_init(void) · 6 unmodified lines | |||
| 970 | panic("%s() failed to register subsystem: %d\n", __func__, ret); | 955 | panic("%s() failed to register subsystem: %d\n", __func__, ret); |
| 971 | 956 | ||
| 972 | /* | 957 | /* |
| 973 | * Create entries for memory sections that were found | 958 | * Create entries for memory sections that were found during boot |
| 974 | * during boot and have been initialized | 959 | * and have been initialized. Use @block_id to track the last |
| 960 | * handled block and initialize it to an invalid value (ULONG_MAX) | ||
| 961 | * to bypass the block ID matching check for the first present | ||
| 962 | * block so that it can be covered. | ||
| 975 | */ | 963 | */ |
| 976 | for (nr = 0; nr <= __highest_present_section_nr; | 964 | block_id = ULONG_MAX; |
| 977 | nr += sections_per_block) { | 965 | for_each_present_section_nr(0, nr) { |
| 978 | ret = add_boot_memory_block(nr); | 966 | if (block_id != ULONG_MAX && memory_block_id(nr) == block_id) |
| 979 | if (ret) | 967 | continue; |
| 980 | panic("%s() failed to add memory block: %d\n", __func__, | 968 | |
| 981 | ret); | 969 | block_id = memory_block_id(nr); |
| 970 | ret = add_memory_block(block_id, MEM_ONLINE, NULL, NULL); | ||
| 971 | if (ret) { | ||
| 972 | panic("%s() failed to add memory block: %d\n", | ||
| 973 | __func__, ret); | ||
| 974 | } | ||
| 982 | } | 975 | } |
| 983 | } | 976 | } |
| 984 | 977 | ||
| @@ -42,16 +42,13 @@ int module_add_driver(struct module *mod, const struct device_driver *drv) · 41 unmodified lines | |||
| 42 | if (mod) | 42 | if (mod) |
| 43 | mk = &mod->mkobj; | 43 | mk = &mod->mkobj; |
| 44 | else if (drv->mod_name) { | 44 | else if (drv->mod_name) { |
| 45 | struct kobject *mkobj; | 45 | /* Lookup or create built-in module entry in /sys/modules */ |
| 46 | 46 | mk = lookup_or_create_module_kobject(drv->mod_name); | |
| 47 | /* Lookup built-in module entry in /sys/modules */ | 47 | if (mk) { |
| 48 | mkobj = kset_find_obj(module_kset, drv->mod_name); | ||
| 49 | if (mkobj) { | ||
| 50 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
| 51 | /* remember our module structure */ | 48 | /* remember our module structure */ |
| 52 | drv->p->mkobj = mk; | 49 | drv->p->mkobj = mk; |
| 53 | /* kset_find_obj took a reference */ | 50 | /* lookup_or_create_module_kobject took a reference */ |
| 54 | kobject_put(mkobj); | 51 | kobject_put(&mk->kobj); |
| 55 | } | 52 | } |
| 56 | } | 53 | } |
| 57 | 54 | ||
| @@ -1440,7 +1440,7 @@ static void platform_shutdown(struct device *_dev) · 1439 unmodified lines | |||
| 1440 | 1440 | ||
| 1441 | static int platform_dma_configure(struct device *dev) | 1441 | static int platform_dma_configure(struct device *dev) |
| 1442 | { | 1442 | { |
| 1443 | struct platform_driver *drv = to_platform_driver(dev->driver); | 1443 | struct device_driver *drv = READ_ONCE(dev->driver); |
| 1444 | struct fwnode_handle *fwnode = dev_fwnode(dev); | 1444 | struct fwnode_handle *fwnode = dev_fwnode(dev); |
| 1445 | enum dev_dma_attr attr; | 1445 | enum dev_dma_attr attr; |
| 1446 | int ret = 0; | 1446 | int ret = 0; |
| @@ -1451,8 +1451,8 @@ static int platform_dma_configure(struct device *dev) · 4 unmodified lines | |||
| 1451 | attr = acpi_get_dma_attr(to_acpi_device_node(fwnode)); | 1451 | attr = acpi_get_dma_attr(to_acpi_device_node(fwnode)); |
| 1452 | ret = acpi_dma_configure(dev, attr); | 1452 | ret = acpi_dma_configure(dev, attr); |
| 1453 | } | 1453 | } |
| 1454 | /* @drv may not be valid when we're called from the IOMMU layer */ | 1454 | /* @dev->driver may not be valid when we're called from the IOMMU layer */ |
| 1455 | if (ret || !dev->driver || drv->driver_managed_dma) | 1455 | if (ret || !drv || to_platform_driver(drv)->driver_managed_dma) |
| 1456 | return ret; | 1456 | return ret; |
| 1457 | 1457 | ||
| 1458 | ret = iommu_device_use_default_domain(dev); | 1458 | ret = iommu_device_use_default_domain(dev); |
| @@ -1080,6 +1080,7 @@ void software_node_notify(struct device *dev) · 1079 unmodified lines | |||
| 1080 | if (!swnode) | 1080 | if (!swnode) |
| 1081 | return; | 1081 | return; |
| 1082 | 1082 | ||
| 1083 | kobject_get(&swnode->kobj); | ||
| 1083 | ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node"); | 1084 | ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node"); |
| 1084 | if (ret) | 1085 | if (ret) |
| 1085 | return; | 1086 | return; |
| @@ -1089,8 +1090,6 @@ void software_node_notify(struct device *dev) · 3 unmodified lines | |||
| 1089 | sysfs_remove_link(&dev->kobj, "software_node"); | 1090 | sysfs_remove_link(&dev->kobj, "software_node"); |
| 1090 | return; | 1091 | return; |
| 1091 | } | 1092 | } |
| 1092 | |||
| 1093 | kobject_get(&swnode->kobj); | ||
| 1094 | } | 1093 | } |
| 1095 | 1094 | ||
| 1096 | void software_node_notify_remove(struct device *dev) | 1095 | void software_node_notify_remove(struct device *dev) |
| @@ -367,7 +367,7 @@ config BLK_DEV_RBD · 366 unmodified lines | |||
| 367 | tristate "Rados block device (RBD)" | 367 | tristate "Rados block device (RBD)" |
| 368 | depends on INET && BLOCK | 368 | depends on INET && BLOCK |
| 369 | select CEPH_LIB | 369 | select CEPH_LIB |
| 370 | select LIBCRC32C | 370 | select CRC32 |
| 371 | select CRYPTO_AES | 371 | select CRYPTO_AES |
| 372 | select CRYPTO | 372 | select CRYPTO |
| 373 | help | 373 | help |
| @@ -388,12 +388,6 @@ config BLK_DEV_UBLK · 14 unmodified lines | |||
| 388 | definition isn't finalized yet, and might change according to future | 388 | definition isn't finalized yet, and might change according to future |
| 389 | requirement, so mark is as experimental now. | 389 | requirement, so mark is as experimental now. |
| 390 | 390 | ||
| 391 | Say Y if you want to get better performance because task_work_add() | ||
| 392 | can be used in IO path for replacing io_uring cmd, which will become | ||
| 393 | shared between IO tasks and ubq daemon, meantime task_work_add() can | ||
| 394 | can handle batch more effectively, but task_work_add() isn't exported | ||
| 395 | for module, so ublk has to be built to kernel. | ||
| 396 | |||
| 397 | config BLKDEV_UBLK_LEGACY_OPCODES | 391 | config BLKDEV_UBLK_LEGACY_OPCODES |
| 398 | bool "Support legacy command opcode" | 392 | bool "Support legacy command opcode" |
| 399 | depends on BLK_DEV_UBLK | 393 | depends on BLK_DEV_UBLK |
| @@ -10,7 +10,7 @@ config BLK_DEV_DRBD · 9 unmodified lines | |||
| 10 | tristate "DRBD Distributed Replicated Block Device support" | 10 | tristate "DRBD Distributed Replicated Block Device support" |
| 11 | depends on PROC_FS && INET | 11 | depends on PROC_FS && INET |
| 12 | select LRU_CACHE | 12 | select LRU_CACHE |
| 13 | select LIBCRC32C | 13 | select CRC32 |
| 14 | help | 14 | help |
| 15 | 15 | ||
| 16 | NOTE: In order to authenticate connections you have to select | 16 | NOTE: In order to authenticate connections you have to select |
| @@ -211,72 +211,6 @@ static void loop_set_size(struct loop_device *lo, loff_t size) · 210 unmodified lines | |||
| 211 | kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); | 211 | kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) | ||
| 215 | { | ||
| 216 | struct iov_iter i; | ||
| 217 | ssize_t bw; | ||
| 218 | |||
| 219 | iov_iter_bvec(&i, ITER_SOURCE, bvec, 1, bvec->bv_len); | ||
| 220 | |||
| 221 | bw = vfs_iter_write(file, &i, ppos, 0); | ||
| 222 | |||
| 223 | if (likely(bw == bvec->bv_len)) | ||
| 224 | return 0; | ||
| 225 | |||
| 226 | printk_ratelimited(KERN_ERR | ||
| 227 | "loop: Write error at byte offset %llu, length %i.\n", | ||
| 228 | (unsigned long long)*ppos, bvec->bv_len); | ||
| 229 | if (bw >= 0) | ||
| 230 | bw = -EIO; | ||
| 231 | return bw; | ||
| 232 | } | ||
| 233 | |||
| 234 | static int lo_write_simple(struct loop_device *lo, struct request *rq, | ||
| 235 | loff_t pos) | ||
| 236 | { | ||
| 237 | struct bio_vec bvec; | ||
| 238 | struct req_iterator iter; | ||
| 239 | int ret = 0; | ||
| 240 | |||
| 241 | rq_for_each_segment(bvec, rq, iter) { | ||
| 242 | ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos); | ||
| 243 | if (ret < 0) | ||
| 244 | break; | ||
| 245 | cond_resched(); | ||
| 246 | } | ||
| 247 | |||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | |||
| 251 | static int lo_read_simple(struct loop_device *lo, struct request *rq, | ||
| 252 | loff_t pos) | ||
| 253 | { | ||
| 254 | struct bio_vec bvec; | ||
| 255 | struct req_iterator iter; | ||
| 256 | struct iov_iter i; | ||
| 257 | ssize_t len; | ||
| 258 | |||
| 259 | rq_for_each_segment(bvec, rq, iter) { | ||
| 260 | iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len); | ||
| 261 | len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0); | ||
| 262 | if (len < 0) | ||
| 263 | return len; | ||
| 264 | |||
| 265 | flush_dcache_page(bvec.bv_page); | ||
| 266 | |||
| 267 | if (len != bvec.bv_len) { | ||
| 268 | struct bio *bio; | ||
| 269 | |||
| 270 | __rq_for_each_bio(bio, rq) | ||
| 271 | zero_fill_bio(bio); | ||
| 272 | break; | ||
| 273 | } | ||
| 274 | cond_resched(); | ||
| 275 | } | ||
| 276 | |||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | |||
| 280 | static void loop_clear_limits(struct loop_device *lo, int mode) | 214 | static void loop_clear_limits(struct loop_device *lo, int mode) |
| 281 | { | 215 | { |
| 282 | struct queue_limits lim = queue_limits_start_update(lo->lo_queue); | 216 | struct queue_limits lim = queue_limits_start_update(lo->lo_queue); |
| @@ -342,7 +276,7 @@ static void lo_complete_rq(struct request *rq) · 59 unmodified lines | |||
| 342 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); | 276 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 343 | blk_status_t ret = BLK_STS_OK; | 277 | blk_status_t ret = BLK_STS_OK; |
| 344 | 278 | ||
| 345 | if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) || | 279 | if (cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) || |
| 346 | req_op(rq) != REQ_OP_READ) { | 280 | req_op(rq) != REQ_OP_READ) { |
| 347 | if (cmd->ret < 0) | 281 | if (cmd->ret < 0) |
| 348 | ret = errno_to_blk_status(cmd->ret); | 282 | ret = errno_to_blk_status(cmd->ret); |
| @@ -358,14 +292,13 @@ static void lo_complete_rq(struct request *rq) · 9 unmodified lines | |||
| 358 | cmd->ret = 0; | 292 | cmd->ret = 0; |
| 359 | blk_mq_requeue_request(rq, true); | 293 | blk_mq_requeue_request(rq, true); |
| 360 | } else { | 294 | } else { |
| 361 | if (cmd->use_aio) { | 295 | struct bio *bio = rq->bio; |
| 362 | struct bio *bio = rq->bio; | ||
| 363 | 296 | ||
| 364 | while (bio) { | 297 | while (bio) { |
| 365 | zero_fill_bio(bio); | 298 | zero_fill_bio(bio); |
| 366 | bio = bio->bi_next; | 299 | bio = bio->bi_next; |
| 367 | } | ||
| 368 | } | 300 | } |
| 301 | |||
| 369 | ret = BLK_STS_IOERR; | 302 | ret = BLK_STS_IOERR; |
| 370 | end_io: | 303 | end_io: |
| 371 | blk_mq_end_request(rq, ret); | 304 | blk_mq_end_request(rq, ret); |
| @@ -445,9 +378,14 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, · 73 unmodified lines | |||
| 445 | 378 | ||
| 446 | cmd->iocb.ki_pos = pos; | 379 | cmd->iocb.ki_pos = pos; |
| 447 | cmd->iocb.ki_filp = file; | 380 | cmd->iocb.ki_filp = file; |
| 448 | cmd->iocb.ki_complete = lo_rw_aio_complete; | 381 | cmd->iocb.ki_ioprio = req_get_ioprio(rq); |
| 449 | cmd->iocb.ki_flags = IOCB_DIRECT; | 382 | if (cmd->use_aio) { |
| 450 | cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0); | 383 | cmd->iocb.ki_complete = lo_rw_aio_complete; |
| 384 | cmd->iocb.ki_flags = IOCB_DIRECT; | ||
| 385 | } else { | ||
| 386 | cmd->iocb.ki_complete = NULL; | ||
| 387 | cmd->iocb.ki_flags = 0; | ||
| 388 | } | ||
| 451 | 389 | ||
| 452 | if (rw == ITER_SOURCE) | 390 | if (rw == ITER_SOURCE) |
| 453 | ret = file->f_op->write_iter(&cmd->iocb, &iter); | 391 | 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, · 4 unmodified lines | |||
| 458 | 396 | ||
| 459 | if (ret != -EIOCBQUEUED) | 397 | if (ret != -EIOCBQUEUED) |
| 460 | lo_rw_aio_complete(&cmd->iocb, ret); | 398 | lo_rw_aio_complete(&cmd->iocb, ret); |
| 461 | return 0; | 399 | return -EIOCBQUEUED; |
| 462 | } | 400 | } |
| 463 | 401 | ||
| 464 | static int do_req_filebacked(struct loop_device *lo, struct request *rq) | 402 | 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) · 1 unmodified line | |||
| 466 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); | 404 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 467 | loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; | 405 | loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; |
| 468 | 406 | ||
| 469 | /* | ||
| 470 | * lo_write_simple and lo_read_simple should have been covered | ||
| 471 | * by io submit style function like lo_rw_aio(), one blocker | ||
| 472 | * is that lo_read_simple() need to call flush_dcache_page after | ||
| 473 | * the page is written from kernel, and it isn't easy to handle | ||
| 474 | * this in io submit style function which submits all segments | ||
| 475 | * of the req at one time. And direct read IO doesn't need to | ||
| 476 | * run flush_dcache_page(). | ||
| 477 | */ | ||
| 478 | switch (req_op(rq)) { | 407 | switch (req_op(rq)) { |
| 479 | case REQ_OP_FLUSH: | 408 | case REQ_OP_FLUSH: |
| 480 | return lo_req_flush(lo, rq); | 409 | return lo_req_flush(lo, rq); |
| @@ -490,15 +419,9 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) · 9 unmodified lines | |||
| 490 | case REQ_OP_DISCARD: | 419 | case REQ_OP_DISCARD: |
| 491 | return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); | 420 | return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); |
| 492 | case REQ_OP_WRITE: | 421 | case REQ_OP_WRITE: |
| 493 | if (cmd->use_aio) | 422 | return lo_rw_aio(lo, cmd, pos, ITER_SOURCE); |
| 494 | return lo_rw_aio(lo, cmd, pos, ITER_SOURCE); | ||
| 495 | else | ||
| 496 | return lo_write_simple(lo, rq, pos); | ||
| 497 | case REQ_OP_READ: | 423 | case REQ_OP_READ: |
| 498 | if (cmd->use_aio) | 424 | return lo_rw_aio(lo, cmd, pos, ITER_DEST); |
| 499 | return lo_rw_aio(lo, cmd, pos, ITER_DEST); | ||
| 500 | else | ||
| 501 | return lo_read_simple(lo, rq, pos); | ||
| 502 | default: | 425 | default: |
| 503 | WARN_ON_ONCE(1); | 426 | WARN_ON_ONCE(1); |
| 504 | return -EIO; | 427 | return -EIO; |
| @@ -582,6 +505,17 @@ static void loop_assign_backing_file(struct loop_device *lo, struct file *file) · 77 unmodified lines | |||
| 582 | lo->lo_min_dio_size = loop_query_min_dio_size(lo); | 505 | lo->lo_min_dio_size = loop_query_min_dio_size(lo); |
| 583 | } | 506 | } |
| 584 | 507 | ||
| 508 | static int loop_check_backing_file(struct file *file) | ||
| 509 | { | ||
| 510 | if (!file->f_op->read_iter) | ||
| 511 | return -EINVAL; | ||
| 512 | |||
| 513 | if ((file->f_mode & FMODE_WRITE) && !file->f_op->write_iter) | ||
| 514 | return -EINVAL; | ||
| 515 | |||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 585 | /* | 519 | /* |
| 586 | * loop_change_fd switched the backing store of a loopback device to | 520 | * loop_change_fd switched the backing store of a loopback device to |
| 587 | * a new file. This is useful for operating system installers to free up | 521 | * a new file. This is useful for operating system installers to free up |
| @@ -603,6 +537,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 15 unmodified lines | |||
| 603 | if (!file) | 537 | if (!file) |
| 604 | return -EBADF; | 538 | return -EBADF; |
| 605 | 539 | ||
| 540 | error = loop_check_backing_file(file); | ||
| 541 | if (error) | ||
| 542 | return error; | ||
| 543 | |||
| 606 | /* suppress uevents while reconfiguring the device */ | 544 | /* suppress uevents while reconfiguring the device */ |
| 607 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1); | 545 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1); |
| 608 | 546 | ||
| @@ -662,19 +600,20 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 53 unmodified lines | |||
| 662 | * dependency. | 600 | * dependency. |
| 663 | */ | 601 | */ |
| 664 | fput(old_file); | 602 | fput(old_file); |
| 603 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | ||
| 665 | if (partscan) | 604 | if (partscan) |
| 666 | loop_reread_partitions(lo); | 605 | loop_reread_partitions(lo); |
| 667 | 606 | ||
| 668 | error = 0; | 607 | error = 0; |
| 669 | done: | 608 | done: |
| 670 | /* enable and uncork uevent now that we are done */ | 609 | kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); |
| 671 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | ||
| 672 | return error; | 610 | return error; |
| 673 | 611 | ||
| 674 | out_err: | 612 | out_err: |
| 675 | loop_global_unlock(lo, is_loop); | 613 | loop_global_unlock(lo, is_loop); |
| 676 | out_putf: | 614 | out_putf: |
| 677 | fput(file); | 615 | fput(file); |
| 616 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | ||
| 678 | goto done; | 617 | goto done; |
| 679 | } | 618 | } |
| 680 | 619 | ||
| @@ -1039,6 +978,11 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, · 358 unmodified lines | |||
| 1039 | 978 | ||
| 1040 | if (!file) | 979 | if (!file) |
| 1041 | return -EBADF; | 980 | return -EBADF; |
| 981 | |||
| 982 | error = loop_check_backing_file(file); | ||
| 983 | if (error) | ||
| 984 | return error; | ||
| 985 | |||
| 1042 | is_loop = is_loop_device(file); | 986 | is_loop = is_loop_device(file); |
| 1043 | 987 | ||
| 1044 | /* This is safe, since we have a reference from open(). */ | 988 | /* This is safe, since we have a reference from open(). */ |
| @@ -1129,8 +1073,8 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, · 84 unmodified lines | |||
| 1129 | if (partscan) | 1073 | if (partscan) |
| 1130 | clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); | 1074 | clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); |
| 1131 | 1075 | ||
| 1132 | /* enable and uncork uevent now that we are done */ | ||
| 1133 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | 1076 | dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); |
| 1077 | kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); | ||
| 1134 | 1078 | ||
| 1135 | loop_global_unlock(lo, is_loop); | 1079 | loop_global_unlock(lo, is_loop); |
| 1136 | if (partscan) | 1080 | if (partscan) |
| @@ -1921,7 +1865,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 784 unmodified lines | |||
| 1921 | struct loop_device *lo = rq->q->queuedata; | 1865 | struct loop_device *lo = rq->q->queuedata; |
| 1922 | int ret = 0; | 1866 | int ret = 0; |
| 1923 | struct mem_cgroup *old_memcg = NULL; | 1867 | struct mem_cgroup *old_memcg = NULL; |
| 1924 | const bool use_aio = cmd->use_aio; | ||
| 1925 | 1868 | ||
| 1926 | if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) { | 1869 | if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) { |
| 1927 | ret = -EIO; | 1870 | ret = -EIO; |
| @@ -1951,7 +1894,7 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 23 unmodified lines | |||
| 1951 | } | 1894 | } |
| 1952 | failed: | 1895 | failed: |
| 1953 | /* complete non-aio request */ | 1896 | /* complete non-aio request */ |
| 1954 | if (!use_aio || ret) { | 1897 | if (ret != -EIOCBQUEUED) { |
| 1955 | if (ret == -EOPNOTSUPP) | 1898 | if (ret == -EOPNOTSUPP) |
| 1956 | cmd->ret = ret; | 1899 | cmd->ret = ret; |
| 1957 | else | 1900 | else |
| @@ -2031,7 +2031,7 @@ static int null_add_dev(struct nullb_device *dev) · 2030 unmodified lines | |||
| 2031 | nullb->disk->minors = 1; | 2031 | nullb->disk->minors = 1; |
| 2032 | nullb->disk->fops = &null_ops; | 2032 | nullb->disk->fops = &null_ops; |
| 2033 | nullb->disk->private_data = nullb; | 2033 | nullb->disk->private_data = nullb; |
| 2034 | strscpy_pad(nullb->disk->disk_name, nullb->disk_name, DISK_NAME_LEN); | 2034 | strscpy(nullb->disk->disk_name, nullb->disk_name); |
| 2035 | 2035 | ||
| 2036 | if (nullb->dev->zoned) { | 2036 | if (nullb->dev->zoned) { |
| 2037 | rv = null_register_zoned_dev(nullb); | 2037 | rv = null_register_zoned_dev(nullb); |
| @@ -122,15 +122,6 @@ struct ublk_uring_cmd_pdu { · 121 unmodified lines | |||
| 122 | */ | 122 | */ |
| 123 | #define UBLK_IO_FLAG_OWNED_BY_SRV 0x02 | 123 | #define UBLK_IO_FLAG_OWNED_BY_SRV 0x02 |
| 124 | 124 | ||
| 125 | /* | ||
| 126 | * IO command is aborted, so this flag is set in case of | ||
| 127 | * !UBLK_IO_FLAG_ACTIVE. | ||
| 128 | * | ||
| 129 | * After this flag is observed, any pending or new incoming request | ||
| 130 | * associated with this io command will be failed immediately | ||
| 131 | */ | ||
| 132 | #define UBLK_IO_FLAG_ABORTED 0x04 | ||
| 133 | |||
| 134 | /* | 125 | /* |
| 135 | * UBLK_IO_FLAG_NEED_GET_DATA is set because IO command requires | 126 | * UBLK_IO_FLAG_NEED_GET_DATA is set because IO command requires |
| 136 | * get data buffer address from ublksrv. | 127 | * get data buffer address from ublksrv. |
| @@ -199,8 +190,6 @@ struct ublk_device { · 62 unmodified lines | |||
| 199 | struct completion completion; | 190 | struct completion completion; |
| 200 | unsigned int nr_queues_ready; | 191 | unsigned int nr_queues_ready; |
| 201 | unsigned int nr_privileged_daemon; | 192 | unsigned int nr_privileged_daemon; |
| 202 | |||
| 203 | struct work_struct nosrv_work; | ||
| 204 | }; | 193 | }; |
| 205 | 194 | ||
| 206 | /* header of ublk_params */ | 195 | /* header of ublk_params */ |
| @@ -209,18 +198,13 @@ struct ublk_params_header { · 2 unmodified lines | |||
| 209 | __u32 types; | 198 | __u32 types; |
| 210 | }; | 199 | }; |
| 211 | 200 | ||
| 212 | static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq); | 201 | static void ublk_stop_dev_unlocked(struct ublk_device *ub); |
| 213 | 202 | static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq); | |
| 214 | static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, | 203 | static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, |
| 215 | struct ublk_queue *ubq, int tag, size_t offset); | 204 | const struct ublk_queue *ubq, int tag, size_t offset); |
| 216 | static inline unsigned int ublk_req_build_flags(struct request *req); | 205 | static inline unsigned int ublk_req_build_flags(struct request *req); |
| 217 | static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq, | 206 | static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq, |
| 218 | int tag); | 207 | int tag); |
| 219 | static inline bool ublk_dev_is_user_copy(const struct ublk_device *ub) | ||
| 220 | { | ||
| 221 | return ub->dev_info.flags & (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY); | ||
| 222 | } | ||
| 223 | |||
| 224 | static inline bool ublk_dev_is_zoned(const struct ublk_device *ub) | 208 | static inline bool ublk_dev_is_zoned(const struct ublk_device *ub) |
| 225 | { | 209 | { |
| 226 | return ub->dev_info.flags & UBLK_F_ZONED; | 210 | return ub->dev_info.flags & UBLK_F_ZONED; |
| @@ -620,14 +604,19 @@ static void ublk_apply_params(struct ublk_device *ub) · 393 unmodified lines | |||
| 620 | ublk_dev_param_zoned_apply(ub); | 604 | ublk_dev_param_zoned_apply(ub); |
| 621 | } | 605 | } |
| 622 | 606 | ||
| 607 | static inline bool ublk_support_zero_copy(const struct ublk_queue *ubq) | ||
| 608 | { | ||
| 609 | return ubq->flags & UBLK_F_SUPPORT_ZERO_COPY; | ||
| 610 | } | ||
| 611 | |||
| 623 | static inline bool ublk_support_user_copy(const struct ublk_queue *ubq) | 612 | static inline bool ublk_support_user_copy(const struct ublk_queue *ubq) |
| 624 | { | 613 | { |
| 625 | return ubq->flags & (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY); | 614 | return ubq->flags & UBLK_F_USER_COPY; |
| 626 | } | 615 | } |
| 627 | 616 | ||
| 628 | static inline bool ublk_need_map_io(const struct ublk_queue *ubq) | 617 | static inline bool ublk_need_map_io(const struct ublk_queue *ubq) |
| 629 | { | 618 | { |
| 630 | return !ublk_support_user_copy(ubq); | 619 | return !ublk_support_user_copy(ubq) && !ublk_support_zero_copy(ubq); |
| 631 | } | 620 | } |
| 632 | 621 | ||
| 633 | static inline bool ublk_need_req_ref(const struct ublk_queue *ubq) | 622 | static inline bool ublk_need_req_ref(const struct ublk_queue *ubq) |
| @@ -635,8 +624,11 @@ static inline bool ublk_need_req_ref(const struct ublk_queue *ubq) · 1 unmodified line | |||
| 635 | /* | 624 | /* |
| 636 | * read()/write() is involved in user copy, so request reference | 625 | * read()/write() is involved in user copy, so request reference |
| 637 | * has to be grabbed | 626 | * has to be grabbed |
| 627 | * | ||
| 628 | * for zero copy, request buffer need to be registered to io_uring | ||
| 629 | * buffer table, so reference is needed | ||
| 638 | */ | 630 | */ |
| 639 | return ublk_support_user_copy(ubq); | 631 | return ublk_support_user_copy(ubq) || ublk_support_zero_copy(ubq); |
| 640 | } | 632 | } |
| 641 | 633 | ||
| 642 | static inline void ublk_init_req_ref(const struct ublk_queue *ubq, | 634 | static inline void ublk_init_req_ref(const struct ublk_queue *ubq, |
| @@ -1074,7 +1066,7 @@ static inline struct ublk_uring_cmd_pdu *ublk_get_uring_cmd_pdu( · 431 unmodified lines | |||
| 1074 | 1066 | ||
| 1075 | static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq) | 1067 | static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq) |
| 1076 | { | 1068 | { |
| 1077 | return ubq->ubq_daemon->flags & PF_EXITING; | 1069 | return !ubq->ubq_daemon || ubq->ubq_daemon->flags & PF_EXITING; |
| 1078 | } | 1070 | } |
| 1079 | 1071 | ||
| 1080 | /* todo: handle partial completion */ | 1072 | /* todo: handle partial completion */ |
| @@ -1085,12 +1077,6 @@ static inline void __ublk_complete_rq(struct request *req) · 4 unmodified lines | |||
| 1085 | unsigned int unmapped_bytes; | 1077 | unsigned int unmapped_bytes; |
| 1086 | blk_status_t res = BLK_STS_OK; | 1078 | blk_status_t res = BLK_STS_OK; |
| 1087 | 1079 | ||
| 1088 | /* called from ublk_abort_queue() code path */ | ||
| 1089 | if (io->flags & UBLK_IO_FLAG_ABORTED) { | ||
| 1090 | res = BLK_STS_IOERR; | ||
| 1091 | goto exit; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* failed read IO if nothing is read */ | 1080 | /* failed read IO if nothing is read */ |
| 1095 | if (!io->res && req_op(req) == REQ_OP_READ) | 1081 | if (!io->res && req_op(req) == REQ_OP_READ) |
| 1096 | io->res = -EIO; | 1082 | io->res = -EIO; |
| @@ -1140,25 +1126,6 @@ static void ublk_complete_rq(struct kref *ref) · 43 unmodified lines | |||
| 1140 | __ublk_complete_rq(req); | 1126 | __ublk_complete_rq(req); |
| 1141 | } | 1127 | } |
| 1142 | 1128 | ||
| 1143 | /* | ||
| 1144 | * Since ublk_rq_task_work_cb always fails requests immediately during | ||
| 1145 | * exiting, __ublk_fail_req() is only called from abort context during | ||
| 1146 | * exiting. So lock is unnecessary. | ||
| 1147 | * | ||
| 1148 | * Also aborting may not be started yet, keep in mind that one failed | ||
| 1149 | * request may be issued by block layer again. | ||
| 1150 | */ | ||
| 1151 | static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io, | ||
| 1152 | struct request *req) | ||
| 1153 | { | ||
| 1154 | WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE); | ||
| 1155 | |||
| 1156 | if (ublk_nosrv_should_reissue_outstanding(ubq->dev)) | ||
| 1157 | blk_mq_requeue_request(req, false); | ||
| 1158 | else | ||
| 1159 | ublk_put_req_ref(ubq, req); | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | static void ubq_complete_io_cmd(struct ublk_io *io, int res, | 1129 | static void ubq_complete_io_cmd(struct ublk_io *io, int res, |
| 1163 | unsigned issue_flags) | 1130 | unsigned issue_flags) |
| 1164 | { | 1131 | { |
| @@ -1314,8 +1281,6 @@ static void ublk_queue_cmd_list(struct ublk_queue *ubq, struct rq_list *l) · 149 unmodified lines | |||
| 1314 | static enum blk_eh_timer_return ublk_timeout(struct request *rq) | 1281 | static enum blk_eh_timer_return ublk_timeout(struct request *rq) |
| 1315 | { | 1282 | { |
| 1316 | struct ublk_queue *ubq = rq->mq_hctx->driver_data; | 1283 | struct ublk_queue *ubq = rq->mq_hctx->driver_data; |
| 1317 | unsigned int nr_inflight = 0; | ||
| 1318 | int i; | ||
| 1319 | 1284 | ||
| 1320 | if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) { | 1285 | if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) { |
| 1321 | if (!ubq->timeout) { | 1286 | if (!ubq->timeout) { |
| @@ -1326,30 +1291,11 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq) · 4 unmodified lines | |||
| 1326 | return BLK_EH_DONE; | 1291 | return BLK_EH_DONE; |
| 1327 | } | 1292 | } |
| 1328 | 1293 | ||
| 1329 | if (!ubq_daemon_is_dying(ubq)) | ||
| 1330 | return BLK_EH_RESET_TIMER; | ||
| 1331 | |||
| 1332 | for (i = 0; i < ubq->q_depth; i++) { | ||
| 1333 | struct ublk_io *io = &ubq->ios[i]; | ||
| 1334 | |||
| 1335 | if (!(io->flags & UBLK_IO_FLAG_ACTIVE)) | ||
| 1336 | nr_inflight++; | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | /* cancelable uring_cmd can't help us if all commands are in-flight */ | ||
| 1340 | if (nr_inflight == ubq->q_depth) { | ||
| 1341 | struct ublk_device *ub = ubq->dev; | ||
| 1342 | |||
| 1343 | if (ublk_abort_requests(ub, ubq)) { | ||
| 1344 | schedule_work(&ub->nosrv_work); | ||
| 1345 | } | ||
| 1346 | return BLK_EH_DONE; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | return BLK_EH_RESET_TIMER; | 1294 | return BLK_EH_RESET_TIMER; |
| 1350 | } | 1295 | } |
| 1351 | 1296 | ||
| 1352 | static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq) | 1297 | static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq, |
| 1298 | bool check_cancel) | ||
| 1353 | { | 1299 | { |
| 1354 | blk_status_t res; | 1300 | blk_status_t res; |
| 1355 | 1301 | ||
| @@ -1368,7 +1314,7 @@ static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq) · 12 unmodified lines | |||
| 1368 | if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) | 1314 | if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) |
| 1369 | return BLK_STS_IOERR; | 1315 | return BLK_STS_IOERR; |
| 1370 | 1316 | ||
| 1371 | if (unlikely(ubq->canceling)) | 1317 | if (check_cancel && unlikely(ubq->canceling)) |
| 1372 | return BLK_STS_IOERR; | 1318 | return BLK_STS_IOERR; |
| 1373 | 1319 | ||
| 1374 | /* fill iod to slot in io cmd buffer */ | 1320 | /* fill iod to slot in io cmd buffer */ |
| @@ -1387,7 +1333,7 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, · 12 unmodified lines | |||
| 1387 | struct request *rq = bd->rq; | 1333 | struct request *rq = bd->rq; |
| 1388 | blk_status_t res; | 1334 | blk_status_t res; |
| 1389 | 1335 | ||
| 1390 | res = ublk_prep_req(ubq, rq); | 1336 | res = ublk_prep_req(ubq, rq, false); |
| 1391 | if (res != BLK_STS_OK) | 1337 | if (res != BLK_STS_OK) |
| 1392 | return res; | 1338 | return res; |
| 1393 | 1339 | ||
| @@ -1419,7 +1365,7 @@ static void ublk_queue_rqs(struct rq_list *rqlist) · 25 unmodified lines | |||
| 1419 | ublk_queue_cmd_list(ubq, &submit_list); | 1365 | ublk_queue_cmd_list(ubq, &submit_list); |
| 1420 | ubq = this_q; | 1366 | ubq = this_q; |
| 1421 | 1367 | ||
| 1422 | if (ublk_prep_req(ubq, req) == BLK_STS_OK) | 1368 | if (ublk_prep_req(ubq, req, true) == BLK_STS_OK) |
| 1423 | rq_list_add_tail(&submit_list, req); | 1369 | rq_list_add_tail(&submit_list, req); |
| 1424 | else | 1370 | else |
| 1425 | rq_list_add_tail(&requeue_list, req); | 1371 | rq_list_add_tail(&requeue_list, req); |
| @@ -1447,6 +1393,37 @@ static const struct blk_mq_ops ublk_mq_ops = { · 21 unmodified lines | |||
| 1447 | .timeout = ublk_timeout, | 1393 | .timeout = ublk_timeout, |
| 1448 | }; | 1394 | }; |
| 1449 | 1395 | ||
| 1396 | static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) | ||
| 1397 | { | ||
| 1398 | int i; | ||
| 1399 | |||
| 1400 | /* All old ioucmds have to be completed */ | ||
| 1401 | ubq->nr_io_ready = 0; | ||
| 1402 | |||
| 1403 | /* | ||
| 1404 | * old daemon is PF_EXITING, put it now | ||
| 1405 | * | ||
| 1406 | * It could be NULL in case of closing one quisced device. | ||
| 1407 | */ | ||
| 1408 | if (ubq->ubq_daemon) | ||
| 1409 | put_task_struct(ubq->ubq_daemon); | ||
| 1410 | /* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */ | ||
| 1411 | ubq->ubq_daemon = NULL; | ||
| 1412 | ubq->timeout = false; | ||
| 1413 | |||
| 1414 | for (i = 0; i < ubq->q_depth; i++) { | ||
| 1415 | struct ublk_io *io = &ubq->ios[i]; | ||
| 1416 | |||
| 1417 | /* | ||
| 1418 | * UBLK_IO_FLAG_CANCELED is kept for avoiding to touch | ||
| 1419 | * io->cmd | ||
| 1420 | */ | ||
| 1421 | io->flags &= UBLK_IO_FLAG_CANCELED; | ||
| 1422 | io->cmd = NULL; | ||
| 1423 | io->addr = 0; | ||
| 1424 | } | ||
| 1425 | } | ||
| 1426 | |||
| 1450 | static int ublk_ch_open(struct inode *inode, struct file *filp) | 1427 | static int ublk_ch_open(struct inode *inode, struct file *filp) |
| 1451 | { | 1428 | { |
| 1452 | struct ublk_device *ub = container_of(inode->i_cdev, | 1429 | struct ublk_device *ub = container_of(inode->i_cdev, |
| @@ -1458,10 +1435,119 @@ static int ublk_ch_open(struct inode *inode, struct file *filp) · 5 unmodified lines | |||
| 1458 | return 0; | 1435 | return 0; |
| 1459 | } | 1436 | } |
| 1460 | 1437 | ||
| 1438 | static void ublk_reset_ch_dev(struct ublk_device *ub) | ||
| 1439 | { | ||
| 1440 | int i; | ||
| 1441 | |||
| 1442 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) | ||
| 1443 | ublk_queue_reinit(ub, ublk_get_queue(ub, i)); | ||
| 1444 | |||
| 1445 | /* set to NULL, otherwise new ubq_daemon cannot mmap the io_cmd_buf */ | ||
| 1446 | ub->mm = NULL; | ||
| 1447 | ub->nr_queues_ready = 0; | ||
| 1448 | ub->nr_privileged_daemon = 0; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | static struct gendisk *ublk_get_disk(struct ublk_device *ub) | ||
| 1452 | { | ||
| 1453 | struct gendisk *disk; | ||
| 1454 | |||
| 1455 | spin_lock(&ub->lock); | ||
| 1456 | disk = ub->ub_disk; | ||
| 1457 | if (disk) | ||
| 1458 | get_device(disk_to_dev(disk)); | ||
| 1459 | spin_unlock(&ub->lock); | ||
| 1460 | |||
| 1461 | return disk; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | static void ublk_put_disk(struct gendisk *disk) | ||
| 1465 | { | ||
| 1466 | if (disk) | ||
| 1467 | put_device(disk_to_dev(disk)); | ||
| 1468 | } | ||
| 1469 | |||
| 1461 | static int ublk_ch_release(struct inode *inode, struct file *filp) | 1470 | static int ublk_ch_release(struct inode *inode, struct file *filp) |
| 1462 | { | 1471 | { |
| 1463 | struct ublk_device *ub = filp->private_data; | 1472 | struct ublk_device *ub = filp->private_data; |
| 1473 | struct gendisk *disk; | ||
| 1474 | int i; | ||
| 1475 | |||
| 1476 | /* | ||
| 1477 | * disk isn't attached yet, either device isn't live, or it has | ||
| 1478 | * been removed already, so we needn't to do anything | ||
| 1479 | */ | ||
| 1480 | disk = ublk_get_disk(ub); | ||
| 1481 | if (!disk) | ||
| 1482 | goto out; | ||
| 1483 | |||
| 1484 | /* | ||
| 1485 | * All uring_cmd are done now, so abort any request outstanding to | ||
| 1486 | * the ublk server | ||
| 1487 | * | ||
| 1488 | * This can be done in lockless way because ublk server has been | ||
| 1489 | * gone | ||
| 1490 | * | ||
| 1491 | * More importantly, we have to provide forward progress guarantee | ||
| 1492 | * without holding ub->mutex, otherwise control task grabbing | ||
| 1493 | * ub->mutex triggers deadlock | ||
| 1494 | * | ||
| 1495 | * All requests may be inflight, so ->canceling may not be set, set | ||
| 1496 | * it now. | ||
| 1497 | */ | ||
| 1498 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { | ||
| 1499 | struct ublk_queue *ubq = ublk_get_queue(ub, i); | ||
| 1500 | |||
| 1501 | ubq->canceling = true; | ||
| 1502 | ublk_abort_queue(ub, ubq); | ||
| 1503 | } | ||
| 1504 | blk_mq_kick_requeue_list(disk->queue); | ||
| 1505 | |||
| 1506 | /* | ||
| 1507 | * All infligh requests have been completed or requeued and any new | ||
| 1508 | * request will be failed or requeued via `->canceling` now, so it is | ||
| 1509 | * fine to grab ub->mutex now. | ||
| 1510 | */ | ||
| 1511 | mutex_lock(&ub->mutex); | ||
| 1512 | |||
| 1513 | /* double check after grabbing lock */ | ||
| 1514 | if (!ub->ub_disk) | ||
| 1515 | goto unlock; | ||
| 1516 | |||
| 1517 | /* | ||
| 1518 | * Transition the device to the nosrv state. What exactly this | ||
| 1519 | * means depends on the recovery flags | ||
| 1520 | */ | ||
| 1521 | blk_mq_quiesce_queue(disk->queue); | ||
| 1522 | if (ublk_nosrv_should_stop_dev(ub)) { | ||
| 1523 | /* | ||
| 1524 | * Allow any pending/future I/O to pass through quickly | ||
| 1525 | * with an error. This is needed because del_gendisk | ||
| 1526 | * waits for all pending I/O to complete | ||
| 1527 | */ | ||
| 1528 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) | ||
| 1529 | ublk_get_queue(ub, i)->force_abort = true; | ||
| 1530 | blk_mq_unquiesce_queue(disk->queue); | ||
| 1464 | 1531 | ||
| 1532 | ublk_stop_dev_unlocked(ub); | ||
| 1533 | } else { | ||
| 1534 | if (ublk_nosrv_dev_should_queue_io(ub)) { | ||
| 1535 | /* ->canceling is set and all requests are aborted */ | ||
| 1536 | ub->dev_info.state = UBLK_S_DEV_QUIESCED; | ||
| 1537 | } else { | ||
| 1538 | ub->dev_info.state = UBLK_S_DEV_FAIL_IO; | ||
| 1539 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) | ||
| 1540 | ublk_get_queue(ub, i)->fail_io = true; | ||
| 1541 | } | ||
| 1542 | blk_mq_unquiesce_queue(disk->queue); | ||
| 1543 | } | ||
| 1544 | unlock: | ||
| 1545 | mutex_unlock(&ub->mutex); | ||
| 1546 | ublk_put_disk(disk); | ||
| 1547 | |||
| 1548 | /* all uring_cmd has been done now, reset device & ubq */ | ||
| 1549 | ublk_reset_ch_dev(ub); | ||
| 1550 | out: | ||
| 1465 | clear_bit(UB_STATE_OPEN, &ub->state); | 1551 | clear_bit(UB_STATE_OPEN, &ub->state); |
| 1466 | return 0; | 1552 | return 0; |
| 1467 | } | 1553 | } |
| @@ -1528,10 +1614,26 @@ static void ublk_commit_completion(struct ublk_device *ub, · 60 unmodified lines | |||
| 1528 | ublk_put_req_ref(ubq, req); | 1614 | ublk_put_req_ref(ubq, req); |
| 1529 | } | 1615 | } |
| 1530 | 1616 | ||
| 1617 | static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io, | ||
| 1618 | struct request *req) | ||
| 1619 | { | ||
| 1620 | WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE); | ||
| 1621 | |||
| 1622 | if (ublk_nosrv_should_reissue_outstanding(ubq->dev)) | ||
| 1623 | blk_mq_requeue_request(req, false); | ||
| 1624 | else { | ||
| 1625 | io->res = -EIO; | ||
| 1626 | __ublk_complete_rq(req); | ||
| 1627 | } | ||
| 1628 | } | ||
| 1629 | |||
| 1531 | /* | 1630 | /* |
| 1532 | * Called from ubq_daemon context via cancel fn, meantime quiesce ublk | 1631 | * Called from ublk char device release handler, when any uring_cmd is |
| 1533 | * blk-mq queue, so we are called exclusively with blk-mq and ubq_daemon | 1632 | * done, meantime request queue is "quiesced" since all inflight requests |
| 1534 | * context, so everything is serialized. | 1633 | * can't be completed because ublk server is dead. |
| 1634 | * | ||
| 1635 | * So no one can hold our request IO reference any more, simply ignore the | ||
| 1636 | * reference, and complete the request immediately | ||
| 1535 | */ | 1637 | */ |
| 1536 | static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq) | 1638 | static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq) |
| 1537 | { | 1639 | { |
| @@ -1548,46 +1650,29 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq) · 10 unmodified lines | |||
| 1548 | * will do it | 1650 | * will do it |
| 1549 | */ | 1651 | */ |
| 1550 | rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i); | 1652 | rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i); |
| 1551 | if (rq && blk_mq_request_started(rq)) { | 1653 | if (rq && blk_mq_request_started(rq)) |
| 1552 | io->flags |= UBLK_IO_FLAG_ABORTED; | ||
| 1553 | __ublk_fail_req(ubq, io, rq); | 1654 | __ublk_fail_req(ubq, io, rq); |
| 1554 | } | ||
| 1555 | } | 1655 | } |
| 1556 | } | 1656 | } |
| 1557 | } | 1657 | } |
| 1558 | 1658 | ||
| 1559 | /* Must be called when queue is frozen */ | 1659 | /* Must be called when queue is frozen */ |
| 1560 | static bool ublk_mark_queue_canceling(struct ublk_queue *ubq) | 1660 | static void ublk_mark_queue_canceling(struct ublk_queue *ubq) |
| 1561 | { | 1661 | { |
| 1562 | bool canceled; | ||
| 1563 | |||
| 1564 | spin_lock(&ubq->cancel_lock); | 1662 | spin_lock(&ubq->cancel_lock); |
| 1565 | canceled = ubq->canceling; | 1663 | if (!ubq->canceling) |
| 1566 | if (!canceled) | ||
| 1567 | ubq->canceling = true; | 1664 | ubq->canceling = true; |
| 1568 | spin_unlock(&ubq->cancel_lock); | 1665 | spin_unlock(&ubq->cancel_lock); |
| 1569 | |||
| 1570 | return canceled; | ||
| 1571 | } | 1666 | } |
| 1572 | 1667 | ||
| 1573 | static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq) | 1668 | static void ublk_start_cancel(struct ublk_queue *ubq) |
| 1574 | { | 1669 | { |
| 1575 | bool was_canceled = ubq->canceling; | 1670 | struct ublk_device *ub = ubq->dev; |
| 1576 | struct gendisk *disk; | 1671 | struct gendisk *disk = ublk_get_disk(ub); |
| 1577 | |||
| 1578 | if (was_canceled) | ||
| 1579 | return false; | ||
| 1580 | |||
| 1581 | spin_lock(&ub->lock); | ||
| 1582 | disk = ub->ub_disk; | ||
| 1583 | if (disk) | ||
| 1584 | get_device(disk_to_dev(disk)); | ||
| 1585 | spin_unlock(&ub->lock); | ||
| 1586 | 1672 | ||
| 1587 | /* Our disk has been dead */ | 1673 | /* Our disk has been dead */ |
| 1588 | if (!disk) | 1674 | if (!disk) |
| 1589 | return false; | 1675 | return; |
| 1590 | |||
| 1591 | /* | 1676 | /* |
| 1592 | * Now we are serialized with ublk_queue_rq() | 1677 | * Now we are serialized with ublk_queue_rq() |
| 1593 | * | 1678 | * |
| @@ -1596,25 +1681,36 @@ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq) · 2 unmodified lines | |||
| 1596 | * touch completed uring_cmd | 1681 | * touch completed uring_cmd |
| 1597 | */ | 1682 | */ |
| 1598 | blk_mq_quiesce_queue(disk->queue); | 1683 | blk_mq_quiesce_queue(disk->queue); |
| 1599 | was_canceled = ublk_mark_queue_canceling(ubq); | 1684 | ublk_mark_queue_canceling(ubq); |
| 1600 | if (!was_canceled) { | ||
| 1601 | /* abort queue is for making forward progress */ | ||
| 1602 | ublk_abort_queue(ub, ubq); | ||
| 1603 | } | ||
| 1604 | blk_mq_unquiesce_queue(disk->queue); | 1685 | blk_mq_unquiesce_queue(disk->queue); |
| 1605 | put_device(disk_to_dev(disk)); | 1686 | ublk_put_disk(disk); |
| 1606 | |||
| 1607 | return !was_canceled; | ||
| 1608 | } | 1687 | } |
| 1609 | 1688 | ||
| 1610 | static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io, | 1689 | static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag, |
| 1611 | unsigned int issue_flags) | 1690 | unsigned int issue_flags) |
| 1612 | { | 1691 | { |
| 1692 | struct ublk_io *io = &ubq->ios[tag]; | ||
| 1693 | struct ublk_device *ub = ubq->dev; | ||
| 1694 | struct request *req; | ||
| 1613 | bool done; | 1695 | bool done; |
| 1614 | 1696 | ||
| 1615 | if (!(io->flags & UBLK_IO_FLAG_ACTIVE)) | 1697 | if (!(io->flags & UBLK_IO_FLAG_ACTIVE)) |
| 1616 | return; | 1698 | return; |
| 1617 | 1699 | ||
| 1700 | /* | ||
| 1701 | * Don't try to cancel this command if the request is started for | ||
| 1702 | * avoiding race between io_uring_cmd_done() and | ||
| 1703 | * io_uring_cmd_complete_in_task(). | ||
| 1704 | * | ||
| 1705 | * Either the started request will be aborted via __ublk_abort_rq(), | ||
| 1706 | * then this uring_cmd is canceled next time, or it will be done in | ||
| 1707 | * task work function ublk_dispatch_req() because io_uring guarantees | ||
| 1708 | * that ublk_dispatch_req() is always called | ||
| 1709 | */ | ||
| 1710 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], tag); | ||
| 1711 | if (req && blk_mq_request_started(req) && req->tag == tag) | ||
| 1712 | return; | ||
| 1713 | |||
| 1618 | spin_lock(&ubq->cancel_lock); | 1714 | spin_lock(&ubq->cancel_lock); |
| 1619 | done = !!(io->flags & UBLK_IO_FLAG_CANCELED); | 1715 | done = !!(io->flags & UBLK_IO_FLAG_CANCELED); |
| 1620 | if (!done) | 1716 | if (!done) |
| @@ -1628,6 +1724,17 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io, · 7 unmodified lines | |||
| 1628 | /* | 1724 | /* |
| 1629 | * The ublk char device won't be closed when calling cancel fn, so both | 1725 | * The ublk char device won't be closed when calling cancel fn, so both |
| 1630 | * ublk device and queue are guaranteed to be live | 1726 | * ublk device and queue are guaranteed to be live |
| 1727 | * | ||
| 1728 | * Two-stage cancel: | ||
| 1729 | * | ||
| 1730 | * - make every active uring_cmd done in ->cancel_fn() | ||
| 1731 | * | ||
| 1732 | * - aborting inflight ublk IO requests in ublk char device release handler, | ||
| 1733 | * which depends on 1st stage because device can only be closed iff all | ||
| 1734 | * uring_cmd are done | ||
| 1735 | * | ||
| 1736 | * Do _not_ try to acquire ub->mutex before all inflight requests are | ||
| 1737 | * aborted, otherwise deadlock may be caused. | ||
| 1631 | */ | 1738 | */ |
| 1632 | static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, | 1739 | static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, |
| 1633 | unsigned int issue_flags) | 1740 | unsigned int issue_flags) |
| @@ -1635,9 +1742,6 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, · 1 unmodified line | |||
| 1635 | struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); | 1742 | struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); |
| 1636 | struct ublk_queue *ubq = pdu->ubq; | 1743 | struct ublk_queue *ubq = pdu->ubq; |
| 1637 | struct task_struct *task; | 1744 | struct task_struct *task; |
| 1638 | struct ublk_device *ub; | ||
| 1639 | bool need_schedule; | ||
| 1640 | struct ublk_io *io; | ||
| 1641 | 1745 | ||
| 1642 | if (WARN_ON_ONCE(!ubq)) | 1746 | if (WARN_ON_ONCE(!ubq)) |
| 1643 | return; | 1747 | return; |
| @@ -1649,16 +1753,11 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, · 5 unmodified lines | |||
| 1649 | if (WARN_ON_ONCE(task && task != ubq->ubq_daemon)) | 1753 | if (WARN_ON_ONCE(task && task != ubq->ubq_daemon)) |
| 1650 | return; | 1754 | return; |
| 1651 | 1755 | ||
| 1652 | ub = ubq->dev; | 1756 | if (!ubq->canceling) |
| 1653 | need_schedule = ublk_abort_requests(ub, ubq); | 1757 | ublk_start_cancel(ubq); |
| 1654 | 1758 | ||
| 1655 | io = &ubq->ios[pdu->tag]; | 1759 | WARN_ON_ONCE(ubq->ios[pdu->tag].cmd != cmd); |
| 1656 | WARN_ON_ONCE(io->cmd != cmd); | 1760 | ublk_cancel_cmd(ubq, pdu->tag, issue_flags); |
| 1657 | ublk_cancel_cmd(ubq, io, issue_flags); | ||
| 1658 | |||
| 1659 | if (need_schedule) { | ||
| 1660 | schedule_work(&ub->nosrv_work); | ||
| 1661 | } | ||
| 1662 | } | 1761 | } |
| 1663 | 1762 | ||
| 1664 | static inline bool ublk_queue_ready(struct ublk_queue *ubq) | 1763 | static inline bool ublk_queue_ready(struct ublk_queue *ubq) |
| @@ -1671,7 +1770,7 @@ static void ublk_cancel_queue(struct ublk_queue *ubq) · 6 unmodified lines | |||
| 1671 | int i; | 1770 | int i; |
| 1672 | 1771 | ||
| 1673 | for (i = 0; i < ubq->q_depth; i++) | 1772 | for (i = 0; i < ubq->q_depth; i++) |
| 1674 | ublk_cancel_cmd(ubq, &ubq->ios[i], IO_URING_F_UNLOCKED); | 1773 | ublk_cancel_cmd(ubq, i, IO_URING_F_UNLOCKED); |
| 1675 | } | 1774 | } |
| 1676 | 1775 | ||
| 1677 | /* Cancel all pending commands, must be called after del_gendisk() returns */ | 1776 | /* Cancel all pending commands, must be called after del_gendisk() returns */ |
| @@ -1709,33 +1808,20 @@ static void ublk_wait_tagset_rqs_idle(struct ublk_device *ub) · 31 unmodified lines | |||
| 1709 | } | 1808 | } |
| 1710 | } | 1809 | } |
| 1711 | 1810 | ||
| 1712 | static void __ublk_quiesce_dev(struct ublk_device *ub) | 1811 | static void ublk_force_abort_dev(struct ublk_device *ub) |
| 1713 | { | ||
| 1714 | pr_devel("%s: quiesce ub: dev_id %d state %s\n", | ||
| 1715 | __func__, ub->dev_info.dev_id, | ||
| 1716 | ub->dev_info.state == UBLK_S_DEV_LIVE ? | ||
| 1717 | "LIVE" : "QUIESCED"); | ||
| 1718 | blk_mq_quiesce_queue(ub->ub_disk->queue); | ||
| 1719 | ublk_wait_tagset_rqs_idle(ub); | ||
| 1720 | ub->dev_info.state = UBLK_S_DEV_QUIESCED; | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | static void ublk_unquiesce_dev(struct ublk_device *ub) | ||
| 1724 | { | 1812 | { |
| 1725 | int i; | 1813 | int i; |
| 1726 | 1814 | ||
| 1727 | pr_devel("%s: unquiesce ub: dev_id %d state %s\n", | 1815 | pr_devel("%s: force abort ub: dev_id %d state %s\n", |
| 1728 | __func__, ub->dev_info.dev_id, | 1816 | __func__, ub->dev_info.dev_id, |
| 1729 | ub->dev_info.state == UBLK_S_DEV_LIVE ? | 1817 | ub->dev_info.state == UBLK_S_DEV_LIVE ? |
| 1730 | "LIVE" : "QUIESCED"); | 1818 | "LIVE" : "QUIESCED"); |
| 1731 | /* quiesce_work has run. We let requeued rqs be aborted | 1819 | blk_mq_quiesce_queue(ub->ub_disk->queue); |
| 1732 | * before running fallback_wq. "force_abort" must be seen | 1820 | if (ub->dev_info.state == UBLK_S_DEV_LIVE) |
| 1733 | * after request queue is unqiuesced. Then del_gendisk() | 1821 | ublk_wait_tagset_rqs_idle(ub); |
| 1734 | * can move on. | 1822 | |
| 1735 | */ | ||
| 1736 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) | 1823 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) |
| 1737 | ublk_get_queue(ub, i)->force_abort = true; | 1824 | ublk_get_queue(ub, i)->force_abort = true; |
| 1738 | |||
| 1739 | blk_mq_unquiesce_queue(ub->ub_disk->queue); | 1825 | blk_mq_unquiesce_queue(ub->ub_disk->queue); |
| 1740 | /* We may have requeued some rqs in ublk_quiesce_queue() */ | 1826 | /* We may have requeued some rqs in ublk_quiesce_queue() */ |
| 1741 | blk_mq_kick_requeue_list(ub->ub_disk->queue); | 1827 | blk_mq_kick_requeue_list(ub->ub_disk->queue); |
| @@ -1756,61 +1842,51 @@ static struct gendisk *ublk_detach_disk(struct ublk_device *ub) · 14 unmodified lines | |||
| 1756 | return disk; | 1842 | return disk; |
| 1757 | } | 1843 | } |
| 1758 | 1844 | ||
| 1759 | static void ublk_stop_dev(struct ublk_device *ub) | 1845 | static void ublk_stop_dev_unlocked(struct ublk_device *ub) |
| 1846 | __must_hold(&ub->mutex) | ||
| 1760 | { | 1847 | { |
| 1761 | struct gendisk *disk; | 1848 | struct gendisk *disk; |
| 1762 | 1849 | ||
| 1763 | mutex_lock(&ub->mutex); | ||
| 1764 | if (ub->dev_info.state == UBLK_S_DEV_DEAD) | 1850 | if (ub->dev_info.state == UBLK_S_DEV_DEAD) |
| 1765 | goto unlock; | 1851 | return; |
| 1766 | if (ublk_nosrv_dev_should_queue_io(ub)) { | 1852 | |
| 1767 | if (ub->dev_info.state == UBLK_S_DEV_LIVE) | 1853 | if (ublk_nosrv_dev_should_queue_io(ub)) |
| 1768 | __ublk_quiesce_dev(ub); | 1854 | ublk_force_abort_dev(ub); |
| 1769 | ublk_unquiesce_dev(ub); | ||
| 1770 | } | ||
| 1771 | del_gendisk(ub->ub_disk); | 1855 | del_gendisk(ub->ub_disk); |
| 1772 | disk = ublk_detach_disk(ub); | 1856 | disk = ublk_detach_disk(ub); |
| 1773 | put_disk(disk); | 1857 | put_disk(disk); |
| 1774 | unlock: | 1858 | } |
| 1859 | |||
| 1860 | static void ublk_stop_dev(struct ublk_device *ub) | ||
| 1861 | { | ||
| 1862 | mutex_lock(&ub->mutex); | ||
| 1863 | ublk_stop_dev_unlocked(ub); | ||
| 1775 | mutex_unlock(&ub->mutex); | 1864 | mutex_unlock(&ub->mutex); |
| 1776 | ublk_cancel_dev(ub); | 1865 | ublk_cancel_dev(ub); |
| 1777 | } | 1866 | } |
| 1778 | 1867 | ||
| 1779 | static void ublk_nosrv_work(struct work_struct *work) | 1868 | /* reset ublk io_uring queue & io flags */ |
| 1869 | static void ublk_reset_io_flags(struct ublk_device *ub) | ||
| 1780 | { | 1870 | { |
| 1781 | struct ublk_device *ub = | 1871 | int i, j; |
| 1782 | container_of(work, struct ublk_device, nosrv_work); | ||
| 1783 | int i; | ||
| 1784 | |||
| 1785 | if (ublk_nosrv_should_stop_dev(ub)) { | ||
| 1786 | ublk_stop_dev(ub); | ||
| 1787 | return; | ||
| 1788 | } | ||
| 1789 | 1872 | ||
| 1790 | mutex_lock(&ub->mutex); | 1873 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { |
| 1791 | if (ub->dev_info.state != UBLK_S_DEV_LIVE) | 1874 | struct ublk_queue *ubq = ublk_get_queue(ub, i); |
| 1792 | goto unlock; | ||
| 1793 | 1875 | ||
| 1794 | if (ublk_nosrv_dev_should_queue_io(ub)) { | 1876 | /* UBLK_IO_FLAG_CANCELED can be cleared now */ |
| 1795 | __ublk_quiesce_dev(ub); | 1877 | spin_lock(&ubq->cancel_lock); |
| 1796 | } else { | 1878 | for (j = 0; j < ubq->q_depth; j++) |
| 1797 | blk_mq_quiesce_queue(ub->ub_disk->queue); | 1879 | ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED; |
| 1798 | ub->dev_info.state = UBLK_S_DEV_FAIL_IO; | 1880 | spin_unlock(&ubq->cancel_lock); |
| 1799 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { | 1881 | ubq->canceling = false; |
| 1800 | ublk_get_queue(ub, i)->fail_io = true; | 1882 | ubq->fail_io = false; |
| 1801 | } | ||
| 1802 | blk_mq_unquiesce_queue(ub->ub_disk->queue); | ||
| 1803 | } | 1883 | } |
| 1804 | |||
| 1805 | unlock: | ||
| 1806 | mutex_unlock(&ub->mutex); | ||
| 1807 | ublk_cancel_dev(ub); | ||
| 1808 | } | 1884 | } |
| 1809 | 1885 | ||
| 1810 | /* device can only be started after all IOs are ready */ | 1886 | /* device can only be started after all IOs are ready */ |
| 1811 | static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq) | 1887 | static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq) |
| 1888 | __must_hold(&ub->mutex) | ||
| 1812 | { | 1889 | { |
| 1813 | mutex_lock(&ub->mutex); | ||
| 1814 | ubq->nr_io_ready++; | 1890 | ubq->nr_io_ready++; |
| 1815 | if (ublk_queue_ready(ubq)) { | 1891 | if (ublk_queue_ready(ubq)) { |
| 1816 | ubq->ubq_daemon = current; | 1892 | ubq->ubq_daemon = current; |
| @@ -1820,18 +1896,12 @@ static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq) · 3 unmodified lines | |||
| 1820 | if (capable(CAP_SYS_ADMIN)) | 1896 | if (capable(CAP_SYS_ADMIN)) |
| 1821 | ub->nr_privileged_daemon++; | 1897 | ub->nr_privileged_daemon++; |
| 1822 | } | 1898 | } |
| 1823 | if (ub->nr_queues_ready == ub->dev_info.nr_hw_queues) | ||
| 1824 | complete_all(&ub->completion); | ||
| 1825 | mutex_unlock(&ub->mutex); | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id, | ||
| 1829 | int tag) | ||
| 1830 | { | ||
| 1831 | struct ublk_queue *ubq = ublk_get_queue(ub, q_id); | ||
| 1832 | struct request *req = blk_mq_tag_to_rq(ub->tag_set.tags[q_id], tag); | ||
| 1833 | 1899 | ||
| 1834 | ublk_queue_cmd(ubq, req); | 1900 | if (ub->nr_queues_ready == ub->dev_info.nr_hw_queues) { |
| 1901 | /* now we are ready for handling ublk io request */ | ||
| 1902 | ublk_reset_io_flags(ub); | ||
| 1903 | complete_all(&ub->completion); | ||
| 1904 | } | ||
| 1835 | } | 1905 | } |
| 1836 | 1906 | ||
| 1837 | static inline int ublk_check_cmd_op(u32 cmd_op) | 1907 | static inline int ublk_check_cmd_op(u32 cmd_op) |
| @@ -1879,13 +1949,20 @@ static void ublk_io_release(void *priv) · 41 unmodified lines | |||
| 1879 | } | 1949 | } |
| 1880 | 1950 | ||
| 1881 | static int ublk_register_io_buf(struct io_uring_cmd *cmd, | 1951 | static int ublk_register_io_buf(struct io_uring_cmd *cmd, |
| 1882 | struct ublk_queue *ubq, unsigned int tag, | 1952 | const struct ublk_queue *ubq, unsigned int tag, |
| 1883 | unsigned int index, unsigned int issue_flags) | 1953 | unsigned int index, unsigned int issue_flags) |
| 1884 | { | 1954 | { |
| 1885 | struct ublk_device *ub = cmd->file->private_data; | 1955 | struct ublk_device *ub = cmd->file->private_data; |
| 1956 | const struct ublk_io *io = &ubq->ios[tag]; | ||
| 1886 | struct request *req; | 1957 | struct request *req; |
| 1887 | int ret; | 1958 | int ret; |
| 1888 | 1959 | ||
| 1960 | if (!ublk_support_zero_copy(ubq)) | ||
| 1961 | return -EINVAL; | ||
| 1962 | |||
| 1963 | if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) | ||
| 1964 | return -EINVAL; | ||
| 1965 | |||
| 1889 | req = __ublk_check_and_get_req(ub, ubq, tag, 0); | 1966 | req = __ublk_check_and_get_req(ub, ubq, tag, 0); |
| 1890 | if (!req) | 1967 | if (!req) |
| 1891 | return -EINVAL; | 1968 | return -EINVAL; |
| @@ -1901,11 +1978,66 @@ static int ublk_register_io_buf(struct io_uring_cmd *cmd, · 9 unmodified lines | |||
| 1901 | } | 1978 | } |
| 1902 | 1979 | ||
| 1903 | static int ublk_unregister_io_buf(struct io_uring_cmd *cmd, | 1980 | static int ublk_unregister_io_buf(struct io_uring_cmd *cmd, |
| 1981 | const struct ublk_queue *ubq, unsigned int tag, | ||
| 1904 | unsigned int index, unsigned int issue_flags) | 1982 | unsigned int index, unsigned int issue_flags) |
| 1905 | { | 1983 | { |
| 1984 | const struct ublk_io *io = &ubq->ios[tag]; | ||
| 1985 | |||
| 1986 | if (!ublk_support_zero_copy(ubq)) | ||
| 1987 | return -EINVAL; | ||
| 1988 | |||
| 1989 | if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) | ||
| 1990 | return -EINVAL; | ||
| 1991 | |||
| 1906 | return io_buffer_unregister_bvec(cmd, index, issue_flags); | 1992 | return io_buffer_unregister_bvec(cmd, index, issue_flags); |
| 1907 | } | 1993 | } |
| 1908 | 1994 | ||
| 1995 | static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_queue *ubq, | ||
| 1996 | struct ublk_io *io, __u64 buf_addr) | ||
| 1997 | { | ||
| 1998 | struct ublk_device *ub = ubq->dev; | ||
| 1999 | int ret = 0; | ||
| 2000 | |||
| 2001 | /* | ||
| 2002 | * When handling FETCH command for setting up ublk uring queue, | ||
| 2003 | * ub->mutex is the innermost lock, and we won't block for handling | ||
| 2004 | * FETCH, so it is fine even for IO_URING_F_NONBLOCK. | ||
| 2005 | */ | ||
| 2006 | mutex_lock(&ub->mutex); | ||
| 2007 | /* UBLK_IO_FETCH_REQ is only allowed before queue is setup */ | ||
| 2008 | if (ublk_queue_ready(ubq)) { | ||
| 2009 | ret = -EBUSY; | ||
| 2010 | goto out; | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | /* allow each command to be FETCHed at most once */ | ||
| 2014 | if (io->flags & UBLK_IO_FLAG_ACTIVE) { | ||
| 2015 | ret = -EINVAL; | ||
| 2016 | goto out; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV); | ||
| 2020 | |||
| 2021 | if (ublk_need_map_io(ubq)) { | ||
| 2022 | /* | ||
| 2023 | * FETCH_RQ has to provide IO buffer if NEED GET | ||
| 2024 | * DATA is not enabled | ||
| 2025 | */ | ||
| 2026 | if (!buf_addr && !ublk_need_get_data(ubq)) | ||
| 2027 | goto out; | ||
| 2028 | } else if (buf_addr) { | ||
| 2029 | /* User copy requires addr to be unset */ | ||
| 2030 | ret = -EINVAL; | ||
| 2031 | goto out; | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | ublk_fill_io_cmd(io, cmd, buf_addr); | ||
| 2035 | ublk_mark_io_ready(ub, ubq); | ||
| 2036 | out: | ||
| 2037 | mutex_unlock(&ub->mutex); | ||
| 2038 | return ret; | ||
| 2039 | } | ||
| 2040 | |||
| 1909 | static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, | 2041 | static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, |
| 1910 | unsigned int issue_flags, | 2042 | unsigned int issue_flags, |
| 1911 | const struct ublksrv_io_cmd *ub_cmd) | 2043 | const struct ublksrv_io_cmd *ub_cmd) |
| @@ -1960,35 +2092,11 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, · 48 unmodified lines | |||
| 1960 | case UBLK_IO_REGISTER_IO_BUF: | 2092 | case UBLK_IO_REGISTER_IO_BUF: |
| 1961 | return ublk_register_io_buf(cmd, ubq, tag, ub_cmd->addr, issue_flags); | 2093 | return ublk_register_io_buf(cmd, ubq, tag, ub_cmd->addr, issue_flags); |
| 1962 | case UBLK_IO_UNREGISTER_IO_BUF: | 2094 | case UBLK_IO_UNREGISTER_IO_BUF: |
| 1963 | return ublk_unregister_io_buf(cmd, ub_cmd->addr, issue_flags); | 2095 | return ublk_unregister_io_buf(cmd, ubq, tag, ub_cmd->addr, issue_flags); |
| 1964 | case UBLK_IO_FETCH_REQ: | 2096 | case UBLK_IO_FETCH_REQ: |
| 1965 | /* UBLK_IO_FETCH_REQ is only allowed before queue is setup */ | 2097 | ret = ublk_fetch(cmd, ubq, io, ub_cmd->addr); |
| 1966 | if (ublk_queue_ready(ubq)) { | 2098 | if (ret) |
| 1967 | ret = -EBUSY; | ||
| 1968 | goto out; | ||
| 1969 | } | ||
| 1970 | /* | ||
| 1971 | * The io is being handled by server, so COMMIT_RQ is expected | ||
| 1972 | * instead of FETCH_REQ | ||
| 1973 | */ | ||
| 1974 | if (io->flags & UBLK_IO_FLAG_OWNED_BY_SRV) | ||
| 1975 | goto out; | ||
| 1976 | |||
| 1977 | if (ublk_need_map_io(ubq)) { | ||
| 1978 | /* | ||
| 1979 | * FETCH_RQ has to provide IO buffer if NEED GET | ||
| 1980 | * DATA is not enabled | ||
| 1981 | */ | ||
| 1982 | if (!ub_cmd->addr && !ublk_need_get_data(ubq)) | ||
| 1983 | goto out; | ||
| 1984 | } else if (ub_cmd->addr) { | ||
| 1985 | /* User copy requires addr to be unset */ | ||
| 1986 | ret = -EINVAL; | ||
| 1987 | goto out; | 2099 | goto out; |
| 1988 | } | ||
| 1989 | |||
| 1990 | ublk_fill_io_cmd(io, cmd, ub_cmd->addr); | ||
| 1991 | ublk_mark_io_ready(ub, ubq); | ||
| 1992 | break; | 2100 | break; |
| 1993 | case UBLK_IO_COMMIT_AND_FETCH_REQ: | 2101 | case UBLK_IO_COMMIT_AND_FETCH_REQ: |
| 1994 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag); | 2102 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag); |
| @@ -2020,8 +2128,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, · 25 unmodified lines | |||
| 2020 | if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) | 2128 | if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) |
| 2021 | goto out; | 2129 | goto out; |
| 2022 | ublk_fill_io_cmd(io, cmd, ub_cmd->addr); | 2130 | ublk_fill_io_cmd(io, cmd, ub_cmd->addr); |
| 2023 | ublk_handle_need_get_data(ub, ub_cmd->q_id, ub_cmd->tag); | 2131 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag); |
| 2024 | break; | 2132 | ublk_dispatch_req(ubq, req, issue_flags); |
| 2133 | return -EIOCBQUEUED; | ||
| 2025 | default: | 2134 | default: |
| 2026 | goto out; | 2135 | goto out; |
| 2027 | } | 2136 | } |
| @@ -2035,13 +2144,10 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, · 7 unmodified lines | |||
| 2035 | } | 2144 | } |
| 2036 | 2145 | ||
| 2037 | static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, | 2146 | static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, |
| 2038 | struct ublk_queue *ubq, int tag, size_t offset) | 2147 | const struct ublk_queue *ubq, int tag, size_t offset) |
| 2039 | { | 2148 | { |
| 2040 | struct request *req; | 2149 | struct request *req; |
| 2041 | 2150 | ||
| 2042 | if (!ublk_need_req_ref(ubq)) | ||
| 2043 | return NULL; | ||
| 2044 | |||
| 2045 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], tag); | 2151 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], tag); |
| 2046 | if (!req) | 2152 | if (!req) |
| 2047 | return NULL; | 2153 | return NULL; |
| @@ -2155,6 +2261,9 @@ static struct request *ublk_check_and_get_req(struct kiocb *iocb, · 107 unmodified lines | |||
| 2155 | if (!ubq) | 2261 | if (!ubq) |
| 2156 | return ERR_PTR(-EINVAL); | 2262 | return ERR_PTR(-EINVAL); |
| 2157 | 2263 | ||
| 2264 | if (!ublk_support_user_copy(ubq)) | ||
| 2265 | return ERR_PTR(-EACCES); | ||
| 2266 | |||
| 2158 | if (tag >= ubq->q_depth) | 2267 | if (tag >= ubq->q_depth) |
| 2159 | return ERR_PTR(-EINVAL); | 2268 | return ERR_PTR(-EINVAL); |
| 2160 | 2269 | ||
| @@ -2388,7 +2497,6 @@ static void ublk_remove(struct ublk_device *ub) · 227 unmodified lines | |||
| 2388 | bool unprivileged; | 2497 | bool unprivileged; |
| 2389 | 2498 | ||
| 2390 | ublk_stop_dev(ub); | 2499 | ublk_stop_dev(ub); |
| 2391 | cancel_work_sync(&ub->nosrv_work); | ||
| 2392 | cdev_device_del(&ub->cdev, &ub->cdev_dev); | 2500 | cdev_device_del(&ub->cdev, &ub->cdev_dev); |
| 2393 | unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV; | 2501 | unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV; |
| 2394 | ublk_put_device(ub); | 2502 | ublk_put_device(ub); |
| @@ -2413,9 +2521,9 @@ static struct ublk_device *ublk_get_device_from_id(int idx) · 18 unmodified lines | |||
| 2413 | return ub; | 2521 | return ub; |
| 2414 | } | 2522 | } |
| 2415 | 2523 | ||
| 2416 | static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd) | 2524 | static int ublk_ctrl_start_dev(struct ublk_device *ub, |
| 2525 | const struct ublksrv_ctrl_cmd *header) | ||
| 2417 | { | 2526 | { |
| 2418 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2419 | const struct ublk_param_basic *p = &ub->params.basic; | 2527 | const struct ublk_param_basic *p = &ub->params.basic; |
| 2420 | int ublksrv_pid = (int)header->data[0]; | 2528 | int ublksrv_pid = (int)header->data[0]; |
| 2421 | struct queue_limits lim = { | 2529 | struct queue_limits lim = { |
| @@ -2534,9 +2642,8 @@ out_unlock: · 112 unmodified lines | |||
| 2534 | } | 2642 | } |
| 2535 | 2643 | ||
| 2536 | static int ublk_ctrl_get_queue_affinity(struct ublk_device *ub, | 2644 | static int ublk_ctrl_get_queue_affinity(struct ublk_device *ub, |
| 2537 | struct io_uring_cmd *cmd) | 2645 | const struct ublksrv_ctrl_cmd *header) |
| 2538 | { | 2646 | { |
| 2539 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2540 | void __user *argp = (void __user *)(unsigned long)header->addr; | 2647 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2541 | cpumask_var_t cpumask; | 2648 | cpumask_var_t cpumask; |
| 2542 | unsigned long queue; | 2649 | unsigned long queue; |
| @@ -2585,9 +2692,8 @@ static inline void ublk_dump_dev_info(struct ublksrv_ctrl_dev_info *info) · 42 unmodified lines | |||
| 2585 | info->nr_hw_queues, info->queue_depth); | 2692 | info->nr_hw_queues, info->queue_depth); |
| 2586 | } | 2693 | } |
| 2587 | 2694 | ||
| 2588 | static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) | 2695 | static int ublk_ctrl_add_dev(const struct ublksrv_ctrl_cmd *header) |
| 2589 | { | 2696 | { |
| 2590 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2591 | void __user *argp = (void __user *)(unsigned long)header->addr; | 2697 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2592 | struct ublksrv_ctrl_dev_info info; | 2698 | struct ublksrv_ctrl_dev_info info; |
| 2593 | struct ublk_device *ub; | 2699 | struct ublk_device *ub; |
| @@ -2675,7 +2781,6 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 81 unmodified lines | |||
| 2675 | goto out_unlock; | 2781 | goto out_unlock; |
| 2676 | mutex_init(&ub->mutex); | 2782 | mutex_init(&ub->mutex); |
| 2677 | spin_lock_init(&ub->lock); | 2783 | spin_lock_init(&ub->lock); |
| 2678 | INIT_WORK(&ub->nosrv_work, ublk_nosrv_work); | ||
| 2679 | 2784 | ||
| 2680 | ret = ublk_alloc_dev_number(ub, header->dev_id); | 2785 | ret = ublk_alloc_dev_number(ub, header->dev_id); |
| 2681 | if (ret < 0) | 2786 | if (ret < 0) |
| @@ -2697,13 +2802,18 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 15 unmodified lines | |||
| 2697 | ub->dev_info.flags |= UBLK_F_CMD_IOCTL_ENCODE | | 2802 | ub->dev_info.flags |= UBLK_F_CMD_IOCTL_ENCODE | |
| 2698 | UBLK_F_URING_CMD_COMP_IN_TASK; | 2803 | UBLK_F_URING_CMD_COMP_IN_TASK; |
| 2699 | 2804 | ||
| 2700 | /* GET_DATA isn't needed any more with USER_COPY */ | 2805 | /* GET_DATA isn't needed any more with USER_COPY or ZERO COPY */ |
| 2701 | if (ublk_dev_is_user_copy(ub)) | 2806 | if (ub->dev_info.flags & (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY)) |
| 2702 | ub->dev_info.flags &= ~UBLK_F_NEED_GET_DATA; | 2807 | ub->dev_info.flags &= ~UBLK_F_NEED_GET_DATA; |
| 2703 | 2808 | ||
| 2704 | /* Zoned storage support requires user copy feature */ | 2809 | /* |
| 2810 | * Zoned storage support requires reuse `ublksrv_io_cmd->addr` for | ||
| 2811 | * returning write_append_lba, which is only allowed in case of | ||
| 2812 | * user copy or zero copy | ||
| 2813 | */ | ||
| 2705 | if (ublk_dev_is_zoned(ub) && | 2814 | if (ublk_dev_is_zoned(ub) && |
| 2706 | (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) || !ublk_dev_is_user_copy(ub))) { | 2815 | (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) || !(ub->dev_info.flags & |
| 2816 | (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY)))) { | ||
| 2707 | ret = -EINVAL; | 2817 | ret = -EINVAL; |
| 2708 | goto out_free_dev_number; | 2818 | goto out_free_dev_number; |
| 2709 | } | 2819 | } |
| @@ -2807,14 +2917,12 @@ static inline void ublk_ctrl_cmd_dump(struct io_uring_cmd *cmd) · 97 unmodified lines | |||
| 2807 | static int ublk_ctrl_stop_dev(struct ublk_device *ub) | 2917 | static int ublk_ctrl_stop_dev(struct ublk_device *ub) |
| 2808 | { | 2918 | { |
| 2809 | ublk_stop_dev(ub); | 2919 | ublk_stop_dev(ub); |
| 2810 | cancel_work_sync(&ub->nosrv_work); | ||
| 2811 | return 0; | 2920 | return 0; |
| 2812 | } | 2921 | } |
| 2813 | 2922 | ||
| 2814 | static int ublk_ctrl_get_dev_info(struct ublk_device *ub, | 2923 | static int ublk_ctrl_get_dev_info(struct ublk_device *ub, |
| 2815 | struct io_uring_cmd *cmd) | 2924 | const struct ublksrv_ctrl_cmd *header) |
| 2816 | { | 2925 | { |
| 2817 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2818 | void __user *argp = (void __user *)(unsigned long)header->addr; | 2926 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2819 | 2927 | ||
| 2820 | if (header->len < sizeof(struct ublksrv_ctrl_dev_info) || !header->addr) | 2928 | if (header->len < sizeof(struct ublksrv_ctrl_dev_info) || !header->addr) |
| @@ -2843,9 +2951,8 @@ static void ublk_ctrl_fill_params_devt(struct ublk_device *ub) · 22 unmodified lines | |||
| 2843 | } | 2951 | } |
| 2844 | 2952 | ||
| 2845 | static int ublk_ctrl_get_params(struct ublk_device *ub, | 2953 | static int ublk_ctrl_get_params(struct ublk_device *ub, |
| 2846 | struct io_uring_cmd *cmd) | 2954 | const struct ublksrv_ctrl_cmd *header) |
| 2847 | { | 2955 | { |
| 2848 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2849 | void __user *argp = (void __user *)(unsigned long)header->addr; | 2956 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2850 | struct ublk_params_header ph; | 2957 | struct ublk_params_header ph; |
| 2851 | int ret; | 2958 | int ret; |
| @@ -2874,9 +2981,8 @@ static int ublk_ctrl_get_params(struct ublk_device *ub, · 22 unmodified lines | |||
| 2874 | } | 2981 | } |
| 2875 | 2982 | ||
| 2876 | static int ublk_ctrl_set_params(struct ublk_device *ub, | 2983 | static int ublk_ctrl_set_params(struct ublk_device *ub, |
| 2877 | struct io_uring_cmd *cmd) | 2984 | const struct ublksrv_ctrl_cmd *header) |
| 2878 | { | 2985 | { |
| 2879 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2880 | void __user *argp = (void __user *)(unsigned long)header->addr; | 2986 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2881 | struct ublk_params_header ph; | 2987 | struct ublk_params_header ph; |
| 2882 | int ret = -EFAULT; | 2988 | int ret = -EFAULT; |
| @@ -2914,43 +3020,14 @@ static int ublk_ctrl_set_params(struct ublk_device *ub, · 31 unmodified lines | |||
| 2914 | return ret; | 3020 | return ret; |
| 2915 | } | 3021 | } |
| 2916 | 3022 | ||
| 2917 | static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) | ||
| 2918 | { | ||
| 2919 | int i; | ||
| 2920 | |||
| 2921 | WARN_ON_ONCE(!(ubq->ubq_daemon && ubq_daemon_is_dying(ubq))); | ||
| 2922 | |||
| 2923 | /* All old ioucmds have to be completed */ | ||
| 2924 | ubq->nr_io_ready = 0; | ||
| 2925 | /* old daemon is PF_EXITING, put it now */ | ||
| 2926 | put_task_struct(ubq->ubq_daemon); | ||
| 2927 | /* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */ | ||
| 2928 | ubq->ubq_daemon = NULL; | ||
| 2929 | ubq->timeout = false; | ||
| 2930 | ubq->canceling = false; | ||
| 2931 | |||
| 2932 | for (i = 0; i < ubq->q_depth; i++) { | ||
| 2933 | struct ublk_io *io = &ubq->ios[i]; | ||
| 2934 | |||
| 2935 | /* forget everything now and be ready for new FETCH_REQ */ | ||
| 2936 | io->flags = 0; | ||
| 2937 | io->cmd = NULL; | ||
| 2938 | io->addr = 0; | ||
| 2939 | } | ||
| 2940 | } | ||
| 2941 | |||
| 2942 | static int ublk_ctrl_start_recovery(struct ublk_device *ub, | 3023 | static int ublk_ctrl_start_recovery(struct ublk_device *ub, |
| 2943 | struct io_uring_cmd *cmd) | 3024 | const struct ublksrv_ctrl_cmd *header) |
| 2944 | { | 3025 | { |
| 2945 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2946 | int ret = -EINVAL; | 3026 | int ret = -EINVAL; |
| 2947 | int i; | ||
| 2948 | 3027 | ||
| 2949 | mutex_lock(&ub->mutex); | 3028 | mutex_lock(&ub->mutex); |
| 2950 | if (ublk_nosrv_should_stop_dev(ub)) | 3029 | if (ublk_nosrv_should_stop_dev(ub)) |
| 2951 | goto out_unlock; | 3030 | goto out_unlock; |
| 2952 | if (!ub->nr_queues_ready) | ||
| 2953 | goto out_unlock; | ||
| 2954 | /* | 3031 | /* |
| 2955 | * START_RECOVERY is only allowd after: | 3032 | * START_RECOVERY is only allowd after: |
| 2956 | * | 3033 | * |
| @@ -2974,12 +3051,6 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub, · 17 unmodified lines | |||
| 2974 | goto out_unlock; | 3051 | goto out_unlock; |
| 2975 | } | 3052 | } |
| 2976 | pr_devel("%s: start recovery for dev id %d.\n", __func__, header->dev_id); | 3053 | pr_devel("%s: start recovery for dev id %d.\n", __func__, header->dev_id); |
| 2977 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) | ||
| 2978 | ublk_queue_reinit(ub, ublk_get_queue(ub, i)); | ||
| 2979 | /* set to NULL, otherwise new ubq_daemon cannot mmap the io_cmd_buf */ | ||
| 2980 | ub->mm = NULL; | ||
| 2981 | ub->nr_queues_ready = 0; | ||
| 2982 | ub->nr_privileged_daemon = 0; | ||
| 2983 | init_completion(&ub->completion); | 3054 | init_completion(&ub->completion); |
| 2984 | ret = 0; | 3055 | ret = 0; |
| 2985 | out_unlock: | 3056 | out_unlock: |
| @@ -2988,12 +3059,10 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub, · 2 unmodified lines | |||
| 2988 | } | 3059 | } |
| 2989 | 3060 | ||
| 2990 | static int ublk_ctrl_end_recovery(struct ublk_device *ub, | 3061 | static int ublk_ctrl_end_recovery(struct ublk_device *ub, |
| 2991 | struct io_uring_cmd *cmd) | 3062 | const struct ublksrv_ctrl_cmd *header) |
| 2992 | { | 3063 | { |
| 2993 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 2994 | int ublksrv_pid = (int)header->data[0]; | 3064 | int ublksrv_pid = (int)header->data[0]; |
| 2995 | int ret = -EINVAL; | 3065 | int ret = -EINVAL; |
| 2996 | int i; | ||
| 2997 | 3066 | ||
| 2998 | pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n", | 3067 | pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n", |
| 2999 | __func__, ub->dev_info.nr_hw_queues, header->dev_id); | 3068 | __func__, ub->dev_info.nr_hw_queues, header->dev_id); |
| @@ -3013,33 +3082,18 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub, · 13 unmodified lines | |||
| 3013 | goto out_unlock; | 3082 | goto out_unlock; |
| 3014 | } | 3083 | } |
| 3015 | ub->dev_info.ublksrv_pid = ublksrv_pid; | 3084 | ub->dev_info.ublksrv_pid = ublksrv_pid; |
| 3085 | ub->dev_info.state = UBLK_S_DEV_LIVE; | ||
| 3016 | pr_devel("%s: new ublksrv_pid %d, dev id %d\n", | 3086 | pr_devel("%s: new ublksrv_pid %d, dev id %d\n", |
| 3017 | __func__, ublksrv_pid, header->dev_id); | 3087 | __func__, ublksrv_pid, header->dev_id); |
| 3018 | 3088 | blk_mq_kick_requeue_list(ub->ub_disk->queue); | |
| 3019 | if (ublk_nosrv_dev_should_queue_io(ub)) { | ||
| 3020 | ub->dev_info.state = UBLK_S_DEV_LIVE; | ||
| 3021 | blk_mq_unquiesce_queue(ub->ub_disk->queue); | ||
| 3022 | pr_devel("%s: queue unquiesced, dev id %d.\n", | ||
| 3023 | __func__, header->dev_id); | ||
| 3024 | blk_mq_kick_requeue_list(ub->ub_disk->queue); | ||
| 3025 | } else { | ||
| 3026 | blk_mq_quiesce_queue(ub->ub_disk->queue); | ||
| 3027 | ub->dev_info.state = UBLK_S_DEV_LIVE; | ||
| 3028 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { | ||
| 3029 | ublk_get_queue(ub, i)->fail_io = false; | ||
| 3030 | } | ||
| 3031 | blk_mq_unquiesce_queue(ub->ub_disk->queue); | ||
| 3032 | } | ||
| 3033 | |||
| 3034 | ret = 0; | 3089 | ret = 0; |
| 3035 | out_unlock: | 3090 | out_unlock: |
| 3036 | mutex_unlock(&ub->mutex); | 3091 | mutex_unlock(&ub->mutex); |
| 3037 | return ret; | 3092 | return ret; |
| 3038 | } | 3093 | } |
| 3039 | 3094 | ||
| 3040 | static int ublk_ctrl_get_features(struct io_uring_cmd *cmd) | 3095 | static int ublk_ctrl_get_features(const struct ublksrv_ctrl_cmd *header) |
| 3041 | { | 3096 | { |
| 3042 | const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); | ||
| 3043 | void __user *argp = (void __user *)(unsigned long)header->addr; | 3097 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 3044 | u64 features = UBLK_F_ALL; | 3098 | u64 features = UBLK_F_ALL; |
| 3045 | 3099 | ||
| @@ -3178,7 +3232,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, · 132 unmodified lines | |||
| 3178 | goto out; | 3232 | goto out; |
| 3179 | 3233 | ||
| 3180 | if (cmd_op == UBLK_U_CMD_GET_FEATURES) { | 3234 | if (cmd_op == UBLK_U_CMD_GET_FEATURES) { |
| 3181 | ret = ublk_ctrl_get_features(cmd); | 3235 | ret = ublk_ctrl_get_features(header); |
| 3182 | goto out; | 3236 | goto out; |
| 3183 | } | 3237 | } |
| 3184 | 3238 | ||
| @@ -3195,17 +3249,17 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, · 10 unmodified lines | |||
| 3195 | 3249 | ||
| 3196 | switch (_IOC_NR(cmd_op)) { | 3250 | switch (_IOC_NR(cmd_op)) { |
| 3197 | case UBLK_CMD_START_DEV: | 3251 | case UBLK_CMD_START_DEV: |
| 3198 | ret = ublk_ctrl_start_dev(ub, cmd); | 3252 | ret = ublk_ctrl_start_dev(ub, header); |
| 3199 | break; | 3253 | break; |
| 3200 | case UBLK_CMD_STOP_DEV: | 3254 | case UBLK_CMD_STOP_DEV: |
| 3201 | ret = ublk_ctrl_stop_dev(ub); | 3255 | ret = ublk_ctrl_stop_dev(ub); |
| 3202 | break; | 3256 | break; |
| 3203 | case UBLK_CMD_GET_DEV_INFO: | 3257 | case UBLK_CMD_GET_DEV_INFO: |
| 3204 | case UBLK_CMD_GET_DEV_INFO2: | 3258 | case UBLK_CMD_GET_DEV_INFO2: |
| 3205 | ret = ublk_ctrl_get_dev_info(ub, cmd); | 3259 | ret = ublk_ctrl_get_dev_info(ub, header); |
| 3206 | break; | 3260 | break; |
| 3207 | case UBLK_CMD_ADD_DEV: | 3261 | case UBLK_CMD_ADD_DEV: |
| 3208 | ret = ublk_ctrl_add_dev(cmd); | 3262 | ret = ublk_ctrl_add_dev(header); |
| 3209 | break; | 3263 | break; |
| 3210 | case UBLK_CMD_DEL_DEV: | 3264 | case UBLK_CMD_DEL_DEV: |
| 3211 | ret = ublk_ctrl_del_dev(&ub, true); | 3265 | ret = ublk_ctrl_del_dev(&ub, true); |
| @@ -3214,19 +3268,19 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, · 2 unmodified lines | |||
| 3214 | ret = ublk_ctrl_del_dev(&ub, false); | 3268 | ret = ublk_ctrl_del_dev(&ub, false); |
| 3215 | break; | 3269 | break; |
| 3216 | case UBLK_CMD_GET_QUEUE_AFFINITY: | 3270 | case UBLK_CMD_GET_QUEUE_AFFINITY: |
| 3217 | ret = ublk_ctrl_get_queue_affinity(ub, cmd); | 3271 | ret = ublk_ctrl_get_queue_affinity(ub, header); |
| 3218 | break; | 3272 | break; |
| 3219 | case UBLK_CMD_GET_PARAMS: | 3273 | case UBLK_CMD_GET_PARAMS: |
| 3220 | ret = ublk_ctrl_get_params(ub, cmd); | 3274 | ret = ublk_ctrl_get_params(ub, header); |
| 3221 | break; | 3275 | break; |
| 3222 | case UBLK_CMD_SET_PARAMS: | 3276 | case UBLK_CMD_SET_PARAMS: |
| 3223 | ret = ublk_ctrl_set_params(ub, cmd); | 3277 | ret = ublk_ctrl_set_params(ub, header); |
| 3224 | break; | 3278 | break; |
| 3225 | case UBLK_CMD_START_USER_RECOVERY: | 3279 | case UBLK_CMD_START_USER_RECOVERY: |
| 3226 | ret = ublk_ctrl_start_recovery(ub, cmd); | 3280 | ret = ublk_ctrl_start_recovery(ub, header); |
| 3227 | break; | 3281 | break; |
| 3228 | case UBLK_CMD_END_USER_RECOVERY: | 3282 | case UBLK_CMD_END_USER_RECOVERY: |
| 3229 | ret = ublk_ctrl_end_recovery(ub, cmd); | 3283 | ret = ublk_ctrl_end_recovery(ub, header); |
| 3230 | break; | 3284 | break; |
| 3231 | default: | 3285 | default: |
| 3232 | ret = -EOPNOTSUPP; | 3286 | ret = -EOPNOTSUPP; |
| @@ -957,8 +957,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb) · 956 unmodified lines | |||
| 957 | /* This is a debug event that comes from IML and OP image when it | 957 | /* This is a debug event that comes from IML and OP image when it |
| 958 | * starts execution. There is no need pass this event to stack. | 958 | * starts execution. There is no need pass this event to stack. |
| 959 | */ | 959 | */ |
| 960 | if (skb->data[2] == 0x97) | 960 | if (skb->data[2] == 0x97) { |
| 961 | hci_recv_diag(hdev, skb); | ||
| 961 | return 0; | 962 | return 0; |
| 963 | } | ||
| 962 | } | 964 | } |
| 963 | 965 | ||
| 964 | return hci_recv_frame(hdev, skb); | 966 | return hci_recv_frame(hdev, skb); |
| @@ -974,7 +976,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, · 9 unmodified lines | |||
| 974 | u8 pkt_type; | 976 | u8 pkt_type; |
| 975 | u16 plen; | 977 | u16 plen; |
| 976 | u32 pcie_pkt_type; | 978 | u32 pcie_pkt_type; |
| 977 | struct sk_buff *new_skb; | ||
| 978 | void *pdata; | 979 | void *pdata; |
| 979 | struct hci_dev *hdev = data->hdev; | 980 | struct hci_dev *hdev = data->hdev; |
| 980 | 981 | ||
| @@ -1051,24 +1052,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, · 70 unmodified lines | |||
| 1051 | 1052 | ||
| 1052 | bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen); | 1053 | bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen); |
| 1053 | 1054 | ||
| 1054 | new_skb = bt_skb_alloc(plen, GFP_ATOMIC); | 1055 | hci_skb_pkt_type(skb) = pkt_type; |
| 1055 | if (!new_skb) { | ||
| 1056 | bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u", | ||
| 1057 | skb->len); | ||
| 1058 | ret = -ENOMEM; | ||
| 1059 | goto exit_error; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | hci_skb_pkt_type(new_skb) = pkt_type; | ||
| 1063 | skb_put_data(new_skb, skb->data, plen); | ||
| 1064 | hdev->stat.byte_rx += plen; | 1056 | hdev->stat.byte_rx += plen; |
| 1057 | skb_trim(skb, plen); | ||
| 1065 | 1058 | ||
| 1066 | if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT) | 1059 | if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT) |
| 1067 | ret = btintel_pcie_recv_event(hdev, new_skb); | 1060 | ret = btintel_pcie_recv_event(hdev, skb); |
| 1068 | else | 1061 | else |
| 1069 | ret = hci_recv_frame(hdev, new_skb); | 1062 | ret = hci_recv_frame(hdev, skb); |
| 1063 | skb = NULL; /* skb is freed in the callee */ | ||
| 1070 | 1064 | ||
| 1071 | exit_error: | 1065 | exit_error: |
| 1066 | if (skb) | ||
| 1067 | kfree_skb(skb); | ||
| 1068 | |||
| 1072 | if (ret) | 1069 | if (ret) |
| 1073 | hdev->stat.err_rx++; | 1070 | hdev->stat.err_rx++; |
| 1074 | 1071 | ||
| @@ -1202,8 +1199,6 @@ static void btintel_pcie_rx_work(struct work_struct *work) · 127 unmodified lines | |||
| 1202 | struct btintel_pcie_data *data = container_of(work, | 1199 | struct btintel_pcie_data *data = container_of(work, |
| 1203 | struct btintel_pcie_data, rx_work); | 1200 | struct btintel_pcie_data, rx_work); |
| 1204 | struct sk_buff *skb; | 1201 | struct sk_buff *skb; |
| 1205 | int err; | ||
| 1206 | struct hci_dev *hdev = data->hdev; | ||
| 1207 | 1202 | ||
| 1208 | if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) { | 1203 | if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) { |
| 1209 | /* Unlike usb products, controller will not send hardware | 1204 | /* Unlike usb products, controller will not send hardware |
| @@ -1224,11 +1219,7 @@ static void btintel_pcie_rx_work(struct work_struct *work) · 14 unmodified lines | |||
| 1224 | 1219 | ||
| 1225 | /* Process the sk_buf in queue and send to the HCI layer */ | 1220 | /* Process the sk_buf in queue and send to the HCI layer */ |
| 1226 | while ((skb = skb_dequeue(&data->rx_skb_q))) { | 1221 | while ((skb = skb_dequeue(&data->rx_skb_q))) { |
| 1227 | err = btintel_pcie_recv_frame(data, skb); | 1222 | btintel_pcie_recv_frame(data, skb); |
| 1228 | if (err) | ||
| 1229 | bt_dev_err(hdev, "Failed to send received frame: %d", | ||
| 1230 | err); | ||
| 1231 | kfree_skb(skb); | ||
| 1232 | } | 1223 | } |
| 1233 | } | 1224 | } |
| 1234 | 1225 | ||
| @@ -1281,10 +1272,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data) · 46 unmodified lines | |||
| 1281 | bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia); | 1272 | bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia); |
| 1282 | 1273 | ||
| 1283 | /* Check CR_TIA and CR_HIA for change */ | 1274 | /* Check CR_TIA and CR_HIA for change */ |
| 1284 | if (cr_tia == cr_hia) { | 1275 | if (cr_tia == cr_hia) |
| 1285 | bt_dev_warn(hdev, "RXQ: no new CD found"); | ||
| 1286 | return; | 1276 | return; |
| 1287 | } | ||
| 1288 | 1277 | ||
| 1289 | rxq = &data->rxq; | 1278 | rxq = &data->rxq; |
| 1290 | 1279 | ||
| @@ -1320,6 +1309,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data) · 29 unmodified lines | |||
| 1320 | return IRQ_WAKE_THREAD; | 1309 | return IRQ_WAKE_THREAD; |
| 1321 | } | 1310 | } |
| 1322 | 1311 | ||
| 1312 | static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data) | ||
| 1313 | { | ||
| 1314 | return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM]; | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data) | ||
| 1318 | { | ||
| 1319 | return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM]; | ||
| 1320 | } | ||
| 1321 | |||
| 1323 | static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) | 1322 | static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) |
| 1324 | { | 1323 | { |
| 1325 | struct msix_entry *entry = dev_id; | 1324 | struct msix_entry *entry = dev_id; |
| @@ -1351,12 +1350,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) · 25 unmodified lines | |||
| 1351 | btintel_pcie_msix_gp0_handler(data); | 1350 | btintel_pcie_msix_gp0_handler(data); |
| 1352 | 1351 | ||
| 1353 | /* For TX */ | 1352 | /* For TX */ |
| 1354 | if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) | 1353 | if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) { |
| 1355 | btintel_pcie_msix_tx_handle(data); | 1354 | btintel_pcie_msix_tx_handle(data); |
| 1355 | if (!btintel_pcie_is_rxq_empty(data)) | ||
| 1356 | btintel_pcie_msix_rx_handle(data); | ||
| 1357 | } | ||
| 1356 | 1358 | ||
| 1357 | /* For RX */ | 1359 | /* For RX */ |
| 1358 | if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) | 1360 | if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) { |
| 1359 | btintel_pcie_msix_rx_handle(data); | 1361 | btintel_pcie_msix_rx_handle(data); |
| 1362 | if (!btintel_pcie_is_txackq_empty(data)) | ||
| 1363 | btintel_pcie_msix_tx_handle(data); | ||
| 1364 | } | ||
| 1360 | 1365 | ||
| 1361 | /* | 1366 | /* |
| 1362 | * Before sending the interrupt the HW disables it to prevent a nested | 1367 | * Before sending the interrupt the HW disables it to prevent a nested |
| @@ -723,6 +723,10 @@ static int btmtksdio_close(struct hci_dev *hdev) · 722 unmodified lines | |||
| 723 | { | 723 | { |
| 724 | struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); | 724 | struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); |
| 725 | 725 | ||
| 726 | /* Skip btmtksdio_close if BTMTKSDIO_FUNC_ENABLED isn't set */ | ||
| 727 | if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) | ||
| 728 | return 0; | ||
| 729 | |||
| 726 | sdio_claim_host(bdev->func); | 730 | sdio_claim_host(bdev->func); |
| 727 | 731 | ||
| 728 | /* Disable interrupt */ | 732 | /* Disable interrupt */ |
| @@ -1443,11 +1447,15 @@ static void btmtksdio_remove(struct sdio_func *func) · 714 unmodified lines | |||
| 1443 | if (!bdev) | 1447 | if (!bdev) |
| 1444 | return; | 1448 | return; |
| 1445 | 1449 | ||
| 1450 | hdev = bdev->hdev; | ||
| 1451 | |||
| 1452 | /* Make sure to call btmtksdio_close before removing sdio card */ | ||
| 1453 | if (test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) | ||
| 1454 | btmtksdio_close(hdev); | ||
| 1455 | |||
| 1446 | /* Be consistent the state in btmtksdio_probe */ | 1456 | /* Be consistent the state in btmtksdio_probe */ |
| 1447 | pm_runtime_get_noresume(bdev->dev); | 1457 | pm_runtime_get_noresume(bdev->dev); |
| 1448 | 1458 | ||
| 1449 | hdev = bdev->hdev; | ||
| 1450 | |||
| 1451 | sdio_set_drvdata(func, NULL); | 1459 | sdio_set_drvdata(func, NULL); |
| 1452 | hci_unregister_dev(hdev); | 1460 | hci_unregister_dev(hdev); |
| 1453 | hci_free_dev(hdev); | 1461 | hci_free_dev(hdev); |
| @@ -1286,7 +1286,9 @@ static void nxp_coredump(struct hci_dev *hdev) · 1285 unmodified lines | |||
| 1286 | u8 pcmd = 2; | 1286 | u8 pcmd = 2; |
| 1287 | 1287 | ||
| 1288 | skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd); | 1288 | skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd); |
| 1289 | if (!IS_ERR(skb)) | 1289 | if (IS_ERR(skb)) |
| 1290 | bt_dev_err(hdev, "Failed to trigger FW Dump. (%ld)", PTR_ERR(skb)); | ||
| 1291 | else | ||
| 1290 | kfree_skb(skb); | 1292 | kfree_skb(skb); |
| 1291 | } | 1293 | } |
| 1292 | 1294 | ||
| @@ -1445,9 +1447,6 @@ static int nxp_shutdown(struct hci_dev *hdev) · 152 unmodified lines | |||
| 1445 | /* HCI_NXP_IND_RESET command may not returns any response */ | 1447 | /* HCI_NXP_IND_RESET command may not returns any response */ |
| 1446 | if (!IS_ERR(skb)) | 1448 | if (!IS_ERR(skb)) |
| 1447 | kfree_skb(skb); | 1449 | kfree_skb(skb); |
| 1448 | } else if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) { | ||
| 1449 | nxpdev->new_baudrate = nxpdev->fw_init_baudrate; | ||
| 1450 | nxp_set_baudrate_cmd(hdev, NULL); | ||
| 1451 | } | 1450 | } |
| 1452 | 1451 | ||
| 1453 | return 0; | 1452 | return 0; |
| @@ -1799,13 +1798,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev) · 345 unmodified lines | |||
| 1799 | clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); | 1798 | clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); |
| 1800 | wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); | 1799 | wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); |
| 1801 | wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); | 1800 | wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); |
| 1802 | } | 1801 | } else { |
| 1803 | 1802 | /* Restore FW baudrate to fw_init_baudrate if changed. | |
| 1804 | if (test_bit(HCI_RUNNING, &hdev->flags)) { | 1803 | * This will ensure FW baudrate is in sync with |
| 1805 | /* Ensure shutdown callback is executed before unregistering, so | 1804 | * driver baudrate in case this driver is re-inserted. |
| 1806 | * that baudrate is reset to initial value. | ||
| 1807 | */ | 1805 | */ |
| 1808 | nxp_shutdown(hdev); | 1806 | if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) { |
| 1807 | nxpdev->new_baudrate = nxpdev->fw_init_baudrate; | ||
| 1808 | nxp_set_baudrate_cmd(hdev, NULL); | ||
| 1809 | } | ||
| 1809 | } | 1810 | } |
| 1810 | 1811 | ||
| 1811 | ps_cleanup(nxpdev); | 1812 | ps_cleanup(nxpdev); |
| @@ -889,7 +889,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, · 888 unmodified lines | |||
| 889 | if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T) | 889 | if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T) |
| 890 | variant = "t"; | 890 | variant = "t"; |
| 891 | else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S) | 891 | else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S) |
| 892 | variant = "u"; | 892 | variant = "s"; |
| 893 | 893 | ||
| 894 | snprintf(config.fwname, sizeof(config.fwname), | 894 | snprintf(config.fwname, sizeof(config.fwname), |
| 895 | "qca/cmnv%02x%s.bin", rom_ver, variant); | 895 | "qca/cmnv%02x%s.bin", rom_ver, variant); |
| @@ -1215,6 +1215,8 @@ next: · 1214 unmodified lines | |||
| 1215 | rtl_dev_err(hdev, "mandatory config file %s not found", | 1215 | rtl_dev_err(hdev, "mandatory config file %s not found", |
| 1216 | btrtl_dev->ic_info->cfg_name); | 1216 | btrtl_dev->ic_info->cfg_name); |
| 1217 | ret = btrtl_dev->cfg_len; | 1217 | ret = btrtl_dev->cfg_len; |
| 1218 | if (!ret) | ||
| 1219 | ret = -EINVAL; | ||
| 1218 | goto err_free; | 1220 | goto err_free; |
| 1219 | } | 1221 | } |
| 1220 | } | 1222 | } |
| @@ -3010,55 +3010,27 @@ static void btusb_coredump_qca(struct hci_dev *hdev) · 3009 unmodified lines | |||
| 3010 | bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); | 3010 | bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); |
| 3011 | } | 3011 | } |
| 3012 | 3012 | ||
| 3013 | /* | 3013 | /* Return: 0 on success, negative errno on failure. */ |
| 3014 | * ==0: not a dump pkt. | ||
| 3015 | * < 0: fails to handle a dump pkt | ||
| 3016 | * > 0: otherwise. | ||
| 3017 | */ | ||
| 3018 | static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) | 3014 | static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) |
| 3019 | { | 3015 | { |
| 3020 | int ret = 1; | 3016 | int ret = 0; |
| 3017 | unsigned int skip = 0; | ||
| 3021 | u8 pkt_type; | 3018 | u8 pkt_type; |
| 3022 | u8 *sk_ptr; | ||
| 3023 | unsigned int sk_len; | ||
| 3024 | u16 seqno; | 3019 | u16 seqno; |
| 3025 | u32 dump_size; | 3020 | u32 dump_size; |
| 3026 | 3021 | ||
| 3027 | struct hci_event_hdr *event_hdr; | ||
| 3028 | struct hci_acl_hdr *acl_hdr; | ||
| 3029 | struct qca_dump_hdr *dump_hdr; | 3022 | struct qca_dump_hdr *dump_hdr; |
| 3030 | struct btusb_data *btdata = hci_get_drvdata(hdev); | 3023 | struct btusb_data *btdata = hci_get_drvdata(hdev); |
| 3031 | struct usb_device *udev = btdata->udev; | 3024 | struct usb_device *udev = btdata->udev; |
| 3032 | 3025 | ||
| 3033 | pkt_type = hci_skb_pkt_type(skb); | 3026 | pkt_type = hci_skb_pkt_type(skb); |
| 3034 | sk_ptr = skb->data; | 3027 | skip = sizeof(struct hci_event_hdr); |
| 3035 | sk_len = skb->len; | 3028 | if (pkt_type == HCI_ACLDATA_PKT) |
| 3036 | 3029 | skip += sizeof(struct hci_acl_hdr); | |
| 3037 | if (pkt_type == HCI_ACLDATA_PKT) { | ||
| 3038 | acl_hdr = hci_acl_hdr(skb); | ||
| 3039 | if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE) | ||
| 3040 | return 0; | ||
| 3041 | sk_ptr += HCI_ACL_HDR_SIZE; | ||
| 3042 | sk_len -= HCI_ACL_HDR_SIZE; | ||
| 3043 | event_hdr = (struct hci_event_hdr *)sk_ptr; | ||
| 3044 | } else { | ||
| 3045 | event_hdr = hci_event_hdr(skb); | ||
| 3046 | } | ||
| 3047 | |||
| 3048 | if ((event_hdr->evt != HCI_VENDOR_PKT) | ||
| 3049 | || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) | ||
| 3050 | return 0; | ||
| 3051 | |||
| 3052 | sk_ptr += HCI_EVENT_HDR_SIZE; | ||
| 3053 | sk_len -= HCI_EVENT_HDR_SIZE; | ||
| 3054 | 3030 | ||
| 3055 | dump_hdr = (struct qca_dump_hdr *)sk_ptr; | 3031 | skb_pull(skb, skip); |
| 3056 | if ((sk_len < offsetof(struct qca_dump_hdr, data)) | 3032 | dump_hdr = (struct qca_dump_hdr *)skb->data; |
| 3057 | || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) | ||
| 3058 | || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) | ||
| 3059 | return 0; | ||
| 3060 | 3033 | ||
| 3061 | /*it is dump pkt now*/ | ||
| 3062 | seqno = le16_to_cpu(dump_hdr->seqno); | 3034 | seqno = le16_to_cpu(dump_hdr->seqno); |
| 3063 | if (seqno == 0) { | 3035 | if (seqno == 0) { |
| 3064 | set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags); | 3036 | set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags); |
| @@ -3078,16 +3050,15 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) · 13 unmodified lines | |||
| 3078 | 3050 | ||
| 3079 | btdata->qca_dump.ram_dump_size = dump_size; | 3051 | btdata->qca_dump.ram_dump_size = dump_size; |
| 3080 | btdata->qca_dump.ram_dump_seqno = 0; | 3052 | btdata->qca_dump.ram_dump_seqno = 0; |
| 3081 | sk_ptr += offsetof(struct qca_dump_hdr, data0); | 3053 | |
| 3082 | sk_len -= offsetof(struct qca_dump_hdr, data0); | 3054 | skb_pull(skb, offsetof(struct qca_dump_hdr, data0)); |
| 3083 | 3055 | ||
| 3084 | usb_disable_autosuspend(udev); | 3056 | usb_disable_autosuspend(udev); |
| 3085 | bt_dev_info(hdev, "%s memdump size(%u)\n", | 3057 | bt_dev_info(hdev, "%s memdump size(%u)\n", |
| 3086 | (pkt_type == HCI_ACLDATA_PKT) ? "ACL" : "event", | 3058 | (pkt_type == HCI_ACLDATA_PKT) ? "ACL" : "event", |
| 3087 | dump_size); | 3059 | dump_size); |
| 3088 | } else { | 3060 | } else { |
| 3089 | sk_ptr += offsetof(struct qca_dump_hdr, data); | 3061 | skb_pull(skb, offsetof(struct qca_dump_hdr, data)); |
| 3090 | sk_len -= offsetof(struct qca_dump_hdr, data); | ||
| 3091 | } | 3062 | } |
| 3092 | 3063 | ||
| 3093 | if (!btdata->qca_dump.ram_dump_size) { | 3064 | if (!btdata->qca_dump.ram_dump_size) { |
| @@ -3107,7 +3078,6 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) · 13 unmodified lines | |||
| 3107 | return ret; | 3078 | return ret; |
| 3108 | } | 3079 | } |
| 3109 | 3080 | ||
| 3110 | skb_pull(skb, skb->len - sk_len); | ||
| 3111 | hci_devcd_append(hdev, skb); | 3081 | hci_devcd_append(hdev, skb); |
| 3112 | btdata->qca_dump.ram_dump_seqno++; | 3082 | btdata->qca_dump.ram_dump_seqno++; |
| 3113 | if (seqno == QCA_LAST_SEQUENCE_NUM) { | 3083 | if (seqno == QCA_LAST_SEQUENCE_NUM) { |
| @@ -3132,17 +3102,74 @@ out: · 18 unmodified lines | |||
| 3132 | return ret; | 3102 | return ret; |
| 3133 | } | 3103 | } |
| 3134 | 3104 | ||
| 3105 | /* Return: true if the ACL packet is a dump packet, false otherwise. */ | ||
| 3106 | static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 3107 | { | ||
| 3108 | struct hci_event_hdr *event_hdr; | ||
| 3109 | struct hci_acl_hdr *acl_hdr; | ||
| 3110 | struct qca_dump_hdr *dump_hdr; | ||
| 3111 | struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); | ||
| 3112 | bool is_dump = false; | ||
| 3113 | |||
| 3114 | if (!clone) | ||
| 3115 | return false; | ||
| 3116 | |||
| 3117 | acl_hdr = skb_pull_data(clone, sizeof(*acl_hdr)); | ||
| 3118 | if (!acl_hdr || (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)) | ||
| 3119 | goto out; | ||
| 3120 | |||
| 3121 | event_hdr = skb_pull_data(clone, sizeof(*event_hdr)); | ||
| 3122 | if (!event_hdr || (event_hdr->evt != HCI_VENDOR_PKT)) | ||
| 3123 | goto out; | ||
| 3124 | |||
| 3125 | dump_hdr = skb_pull_data(clone, sizeof(*dump_hdr)); | ||
| 3126 | if (!dump_hdr || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || | ||
| 3127 | (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) | ||
| 3128 | goto out; | ||
| 3129 | |||
| 3130 | is_dump = true; | ||
| 3131 | out: | ||
| 3132 | consume_skb(clone); | ||
| 3133 | return is_dump; | ||
| 3134 | } | ||
| 3135 | |||
| 3136 | /* Return: true if the event packet is a dump packet, false otherwise. */ | ||
| 3137 | static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 3138 | { | ||
| 3139 | struct hci_event_hdr *event_hdr; | ||
| 3140 | struct qca_dump_hdr *dump_hdr; | ||
| 3141 | struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); | ||
| 3142 | bool is_dump = false; | ||
| 3143 | |||
| 3144 | if (!clone) | ||
| 3145 | return false; | ||
| 3146 | |||
| 3147 | event_hdr = skb_pull_data(clone, sizeof(*event_hdr)); | ||
| 3148 | if (!event_hdr || (event_hdr->evt != HCI_VENDOR_PKT)) | ||
| 3149 | goto out; | ||
| 3150 | |||
| 3151 | dump_hdr = skb_pull_data(clone, sizeof(*dump_hdr)); | ||
| 3152 | if (!dump_hdr || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || | ||
| 3153 | (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) | ||
| 3154 | goto out; | ||
| 3155 | |||
| 3156 | is_dump = true; | ||
| 3157 | out: | ||
| 3158 | consume_skb(clone); | ||
| 3159 | return is_dump; | ||
| 3160 | } | ||
| 3161 | |||
| 3135 | static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb) | 3162 | static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb) |
| 3136 | { | 3163 | { |
| 3137 | if (handle_dump_pkt_qca(hdev, skb)) | 3164 | if (acl_pkt_is_dump_qca(hdev, skb)) |
| 3138 | return 0; | 3165 | return handle_dump_pkt_qca(hdev, skb); |
| 3139 | return hci_recv_frame(hdev, skb); | 3166 | return hci_recv_frame(hdev, skb); |
| 3140 | } | 3167 | } |
| 3141 | 3168 | ||
| 3142 | static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb) | 3169 | static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb) |
| 3143 | { | 3170 | { |
| 3144 | if (handle_dump_pkt_qca(hdev, skb)) | 3171 | if (evt_pkt_is_dump_qca(hdev, skb)) |
| 3145 | return 0; | 3172 | return handle_dump_pkt_qca(hdev, skb); |
| 3146 | return hci_recv_frame(hdev, skb); | 3173 | return hci_recv_frame(hdev, skb); |
| 3147 | } | 3174 | } |
| 3148 | 3175 | ||
| @@ -289,18 +289,18 @@ static void vhci_coredump(struct hci_dev *hdev) · 288 unmodified lines | |||
| 289 | 289 | ||
| 290 | static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb) | 290 | static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb) |
| 291 | { | 291 | { |
| 292 | char buf[80]; | 292 | const char *buf; |
| 293 | 293 | ||
| 294 | snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n"); | 294 | buf = "Controller Name: vhci_ctrl\n"; |
| 295 | skb_put_data(skb, buf, strlen(buf)); | 295 | skb_put_data(skb, buf, strlen(buf)); |
| 296 | 296 | ||
| 297 | snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n"); | 297 | buf = "Firmware Version: vhci_fw\n"; |
| 298 | skb_put_data(skb, buf, strlen(buf)); | 298 | skb_put_data(skb, buf, strlen(buf)); |
| 299 | 299 | ||
| 300 | snprintf(buf, sizeof(buf), "Driver: vhci_drv\n"); | 300 | buf = "Driver: vhci_drv\n"; |
| 301 | skb_put_data(skb, buf, strlen(buf)); | 301 | skb_put_data(skb, buf, strlen(buf)); |
| 302 | 302 | ||
| 303 | snprintf(buf, sizeof(buf), "Vendor: vhci\n"); | 303 | buf = "Vendor: vhci\n"; |
| 304 | skb_put_data(skb, buf, strlen(buf)); | 304 | skb_put_data(skb, buf, strlen(buf)); |
| 305 | } | 305 | } |
| 306 | 306 | ||
| @@ -315,7 +315,7 @@ static int __init misc_init(void) · 314 unmodified lines | |||
| 315 | goto fail_remove; | 315 | goto fail_remove; |
| 316 | 316 | ||
| 317 | err = -EIO; | 317 | err = -EIO; |
| 318 | if (register_chrdev(MISC_MAJOR, "misc", &misc_fops)) | 318 | if (__register_chrdev(MISC_MAJOR, 0, MINORMASK + 1, "misc", &misc_fops)) |
| 319 | goto fail_printk; | 319 | goto fail_printk; |
| 320 | return 0; | 320 | return 0; |
| 321 | 321 | ||
| @@ -201,7 +201,7 @@ static void tpm_buf_read(struct tpm_buf *buf, off_t *offset, size_t count, void · 200 unmodified lines | |||
| 201 | */ | 201 | */ |
| 202 | u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset) | 202 | u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset) |
| 203 | { | 203 | { |
| 204 | u8 value; | 204 | u8 value = 0; |
| 205 | 205 | ||
| 206 | tpm_buf_read(buf, offset, sizeof(value), &value); | 206 | tpm_buf_read(buf, offset, sizeof(value), &value); |
| 207 | 207 | ||
| @@ -218,7 +218,7 @@ EXPORT_SYMBOL_GPL(tpm_buf_read_u8); · 10 unmodified lines | |||
| 218 | */ | 218 | */ |
| 219 | u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset) | 219 | u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset) |
| 220 | { | 220 | { |
| 221 | u16 value; | 221 | u16 value = 0; |
| 222 | 222 | ||
| 223 | tpm_buf_read(buf, offset, sizeof(value), &value); | 223 | tpm_buf_read(buf, offset, sizeof(value), &value); |
| 224 | 224 | ||
| @@ -235,7 +235,7 @@ EXPORT_SYMBOL_GPL(tpm_buf_read_u16); · 10 unmodified lines | |||
| 235 | */ | 235 | */ |
| 236 | u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset) | 236 | u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset) |
| 237 | { | 237 | { |
| 238 | u32 value; | 238 | u32 value = 0; |
| 239 | 239 | ||
| 240 | tpm_buf_read(buf, offset, sizeof(value), &value); | 240 | tpm_buf_read(buf, offset, sizeof(value), &value); |
| 241 | 241 | ||
| @@ -40,11 +40,6 @@ · 39 unmodified lines | |||
| 40 | * | 40 | * |
| 41 | * These are the usage functions: | 41 | * These are the usage functions: |
| 42 | * | 42 | * |
| 43 | * tpm2_start_auth_session() which allocates the opaque auth structure | ||
| 44 | * and gets a session from the TPM. This must be called before | ||
| 45 | * any of the following functions. The session is protected by a | ||
| 46 | * session_key which is derived from a random salt value | ||
| 47 | * encrypted to the NULL seed. | ||
| 48 | * tpm2_end_auth_session() kills the session and frees the resources. | 43 | * tpm2_end_auth_session() kills the session and frees the resources. |
| 49 | * Under normal operation this function is done by | 44 | * Under normal operation this function is done by |
| 50 | * tpm_buf_check_hmac_response(), so this is only to be used on | 45 | * tpm_buf_check_hmac_response(), so this is only to be used on |
| @@ -963,16 +958,13 @@ err: · 912 unmodified lines | |||
| 963 | } | 958 | } |
| 964 | 959 | ||
| 965 | /** | 960 | /** |
| 966 | * tpm2_start_auth_session() - create a HMAC authentication session with the TPM | 961 | * tpm2_start_auth_session() - Create an a HMAC authentication session |
| 967 | * @chip: the TPM chip structure to create the session with | 962 | * @chip: A TPM chip |
| 968 | * | 963 | * |
| 969 | * This function loads the NULL seed from its saved context and starts | 964 | * Loads the ephemeral key (null seed), and starts an HMAC authenticated |
| 970 | * an authentication session on the null seed, fills in the | 965 | * session. The null seed is flushed before the return. |
| 971 | * @chip->auth structure to contain all the session details necessary | ||
| 972 | * for performing the HMAC, encrypt and decrypt operations and | ||
| 973 | * returns. The NULL seed is flushed before this function returns. | ||
| 974 | * | 966 | * |
| 975 | * Return: zero on success or actual error encountered. | 967 | * Returns zero on success, or a POSIX error code. |
| 976 | */ | 968 | */ |
| 977 | int tpm2_start_auth_session(struct tpm_chip *chip) | 969 | int tpm2_start_auth_session(struct tpm_chip *chip) |
| 978 | { | 970 | { |
| @@ -1024,7 +1016,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip) · 45 unmodified lines | |||
| 1024 | /* hash algorithm for session */ | 1016 | /* hash algorithm for session */ |
| 1025 | tpm_buf_append_u16(&buf, TPM_ALG_SHA256); | 1017 | tpm_buf_append_u16(&buf, TPM_ALG_SHA256); |
| 1026 | 1018 | ||
| 1027 | rc = tpm_transmit_cmd(chip, &buf, 0, "start auth session"); | 1019 | rc = tpm_ret_to_err(tpm_transmit_cmd(chip, &buf, 0, "StartAuthSession")); |
| 1028 | tpm2_flush_context(chip, null_key); | 1020 | tpm2_flush_context(chip, null_key); |
| 1029 | 1021 | ||
| 1030 | if (rc == TPM2_RC_SUCCESS) | 1022 | if (rc == TPM2_RC_SUCCESS) |
| @@ -54,7 +54,7 @@ enum tis_int_flags { · 53 unmodified lines | |||
| 54 | enum tis_defaults { | 54 | enum tis_defaults { |
| 55 | TIS_MEM_LEN = 0x5000, | 55 | TIS_MEM_LEN = 0x5000, |
| 56 | TIS_SHORT_TIMEOUT = 750, /* ms */ | 56 | TIS_SHORT_TIMEOUT = 750, /* ms */ |
| 57 | TIS_LONG_TIMEOUT = 2000, /* 2 sec */ | 57 | TIS_LONG_TIMEOUT = 4000, /* 4 secs */ |
| 58 | TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ | 58 | TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ |
| 59 | TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ | 59 | TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ |
| 60 | }; | 60 | }; |
| @@ -1576,8 +1576,8 @@ static void handle_control_message(struct virtio_device *vdev, · 1575 unmodified lines | |||
| 1576 | break; | 1576 | break; |
| 1577 | case VIRTIO_CONSOLE_RESIZE: { | 1577 | case VIRTIO_CONSOLE_RESIZE: { |
| 1578 | struct { | 1578 | struct { |
| 1579 | __u16 rows; | 1579 | __virtio16 cols; |
| 1580 | __u16 cols; | 1580 | __virtio16 rows; |
| 1581 | } size; | 1581 | } size; |
| 1582 | 1582 | ||
| 1583 | if (!is_console_port(port)) | 1583 | if (!is_console_port(port)) |
| @@ -1585,7 +1585,8 @@ static void handle_control_message(struct virtio_device *vdev, · 1 unmodified line | |||
| 1585 | 1585 | ||
| 1586 | memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), | 1586 | memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), |
| 1587 | sizeof(size)); | 1587 | sizeof(size)); |
| 1588 | set_console_size(port, size.rows, size.cols); | 1588 | set_console_size(port, virtio16_to_cpu(vdev, size.rows), |
| 1589 | virtio16_to_cpu(vdev, size.cols)); | ||
| 1589 | 1590 | ||
| 1590 | port->cons.hvc->irq_requested = 1; | 1591 | port->cons.hvc->irq_requested = 1; |
| 1591 | resize_console(port); | 1592 | resize_console(port); |
| @@ -137,6 +137,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev) · 136 unmodified lines | |||
| 137 | if (!clk_data) | 137 | if (!clk_data) |
| 138 | return -ENOMEM; | 138 | return -ENOMEM; |
| 139 | 139 | ||
| 140 | clk_data->num = S2MPS11_CLKS_NUM; | ||
| 141 | |||
| 140 | switch (hwid) { | 142 | switch (hwid) { |
| 141 | case S2MPS11X: | 143 | case S2MPS11X: |
| 142 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; | 144 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; |
| @@ -186,7 +188,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev) · 43 unmodified lines | |||
| 186 | clk_data->hws[i] = &s2mps11_clks[i].hw; | 188 | clk_data->hws[i] = &s2mps11_clks[i].hw; |
| 187 | } | 189 | } |
| 188 | 190 | ||
| 189 | clk_data->num = S2MPS11_CLKS_NUM; | ||
| 190 | of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get, | 191 | of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get, |
| 191 | clk_data); | 192 | clk_data); |
| 192 | 193 | ||
| @@ -541,6 +541,8 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = { · 540 unmodified lines | |||
| 541 | RK3576_CLKGATE_CON(5), 14, GFLAGS), | 541 | RK3576_CLKGATE_CON(5), 14, GFLAGS), |
| 542 | GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, | 542 | GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, |
| 543 | RK3576_CLKGATE_CON(5), 15, GFLAGS), | 543 | RK3576_CLKGATE_CON(5), 15, GFLAGS), |
| 544 | GATE(CLK_OTP_PHY_G, "clk_otp_phy_g", "xin24m", 0, | ||
| 545 | RK3576_CLKGATE_CON(6), 0, GFLAGS), | ||
| 544 | COMPOSITE(CLK_MIPI_CAMERAOUT_M0, "clk_mipi_cameraout_m0", mux_24m_spll_gpll_cpll_p, 0, | 546 | COMPOSITE(CLK_MIPI_CAMERAOUT_M0, "clk_mipi_cameraout_m0", mux_24m_spll_gpll_cpll_p, 0, |
| 545 | RK3576_CLKSEL_CON(38), 8, 2, MFLAGS, 0, 8, DFLAGS, | 547 | RK3576_CLKSEL_CON(38), 8, 2, MFLAGS, 0, 8, DFLAGS, |
| 546 | RK3576_CLKGATE_CON(6), 3, GFLAGS), | 548 | RK3576_CLKGATE_CON(6), 3, GFLAGS), |
| @@ -412,19 +412,23 @@ static const struct clk_parent_data mmc0_mmc1_parents[] = { · 411 unmodified lines | |||
| 412 | { .hw = &pll_periph0_2x_clk.common.hw }, | 412 | { .hw = &pll_periph0_2x_clk.common.hw }, |
| 413 | { .hw = &pll_audio1_div2_clk.common.hw }, | 413 | { .hw = &pll_audio1_div2_clk.common.hw }, |
| 414 | }; | 414 | }; |
| 415 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc0_mmc1_parents, 0x830, | 415 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", |
| 416 | 0, 4, /* M */ | 416 | mmc0_mmc1_parents, 0x830, |
| 417 | 8, 2, /* P */ | 417 | 0, 4, /* M */ |
| 418 | 24, 3, /* mux */ | 418 | 8, 2, /* P */ |
| 419 | BIT(31), /* gate */ | 419 | 24, 3, /* mux */ |
| 420 | 0); | 420 | BIT(31), /* gate */ |
| 421 | 421 | 2, /* post-div */ | |
| 422 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834, | 422 | 0); |
| 423 | 0, 4, /* M */ | 423 | |
| 424 | 8, 2, /* P */ | 424 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", |
| 425 | 24, 3, /* mux */ | 425 | mmc0_mmc1_parents, 0x834, |
| 426 | BIT(31), /* gate */ | 426 | 0, 4, /* M */ |
| 427 | 0); | 427 | 8, 2, /* P */ |
| 428 | 24, 3, /* mux */ | ||
| 429 | BIT(31), /* gate */ | ||
| 430 | 2, /* post-div */ | ||
| 431 | 0); | ||
| 428 | 432 | ||
| 429 | static const struct clk_parent_data mmc2_parents[] = { | 433 | static const struct clk_parent_data mmc2_parents[] = { |
| 430 | { .fw_name = "hosc" }, | 434 | { .fw_name = "hosc" }, |
| @@ -433,12 +437,14 @@ static const struct clk_parent_data mmc2_parents[] = { · 2 unmodified lines | |||
| 433 | { .hw = &pll_periph0_800M_clk.common.hw }, | 437 | { .hw = &pll_periph0_800M_clk.common.hw }, |
| 434 | { .hw = &pll_audio1_div2_clk.common.hw }, | 438 | { .hw = &pll_audio1_div2_clk.common.hw }, |
| 435 | }; | 439 | }; |
| 436 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc2_parents, 0x838, | 440 | static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc2_parents, |
| 437 | 0, 4, /* M */ | 441 | 0x838, |
| 438 | 8, 2, /* P */ | 442 | 0, 4, /* M */ |
| 439 | 24, 3, /* mux */ | 443 | 8, 2, /* P */ |
| 440 | BIT(31), /* gate */ | 444 | 24, 3, /* mux */ |
| 441 | 0); | 445 | BIT(31), /* gate */ |
| 446 | 2, /* post-div */ | ||
| 447 | 0); | ||
| 442 | 448 | ||
| 443 | static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws, | 449 | static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws, |
| 444 | 0x84c, BIT(0), 0); | 450 | 0x84c, BIT(0), 0); |
| @@ -52,6 +52,28 @@ struct ccu_mp { · 51 unmodified lines | |||
| 52 | } \ | 52 | } \ |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | #define SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, \ | ||
| 56 | _reg, \ | ||
| 57 | _mshift, _mwidth, \ | ||
| 58 | _pshift, _pwidth, \ | ||
| 59 | _muxshift, _muxwidth, \ | ||
| 60 | _gate, _postdiv, _flags)\ | ||
| 61 | struct ccu_mp _struct = { \ | ||
| 62 | .enable = _gate, \ | ||
| 63 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | ||
| 64 | .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ | ||
| 65 | .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ | ||
| 66 | .fixed_post_div = _postdiv, \ | ||
| 67 | .common = { \ | ||
| 68 | .reg = _reg, \ | ||
| 69 | .features = CCU_FEATURE_FIXED_POSTDIV, \ | ||
| 70 | .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ | ||
| 71 | _parents, \ | ||
| 72 | &ccu_mp_ops, \ | ||
| 73 | _flags), \ | ||
| 74 | } \ | ||
| 75 | } | ||
| 76 | |||
| 55 | #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ | 77 | #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ |
| 56 | _mshift, _mwidth, \ | 78 | _mshift, _mwidth, \ |
| 57 | _pshift, _pwidth, \ | 79 | _pshift, _pwidth, \ |
| @@ -109,8 +131,7 @@ struct ccu_mp { · 51 unmodified lines | |||
| 109 | _mshift, _mwidth, \ | 131 | _mshift, _mwidth, \ |
| 110 | _pshift, _pwidth, \ | 132 | _pshift, _pwidth, \ |
| 111 | _muxshift, _muxwidth, \ | 133 | _muxshift, _muxwidth, \ |
| 112 | _gate, _features, \ | 134 | _gate, _flags, _features) \ |
| 113 | _flags) \ | ||
| 114 | struct ccu_mp _struct = { \ | 135 | struct ccu_mp _struct = { \ |
| 115 | .enable = _gate, \ | 136 | .enable = _gate, \ |
| 116 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | 137 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
| @@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void) · 102 unmodified lines | |||
| 103 | #ifdef CONFIG_CLKEVT_I8253 | 103 | #ifdef CONFIG_CLKEVT_I8253 |
| 104 | void clockevent_i8253_disable(void) | 104 | void clockevent_i8253_disable(void) |
| 105 | { | 105 | { |
| 106 | raw_spin_lock(&i8253_lock); | 106 | guard(raw_spinlock_irqsave)(&i8253_lock); |
| 107 | 107 | ||
| 108 | /* | 108 | /* |
| 109 | * Writing the MODE register should stop the counter, according to | 109 | * Writing the MODE register should stop the counter, according to |
| @@ -132,8 +132,6 @@ void clockevent_i8253_disable(void) · 22 unmodified lines | |||
| 132 | outb_p(0, PIT_CH0); | 132 | outb_p(0, PIT_CH0); |
| 133 | 133 | ||
| 134 | outb_p(0x30, PIT_MODE); | 134 | outb_p(0x30, PIT_MODE); |
| 135 | |||
| 136 | raw_spin_unlock(&i8253_lock); | ||
| 137 | } | 135 | } |
| 138 | 136 | ||
| 139 | static int pit_shutdown(struct clock_event_device *evt) | 137 | static int pit_shutdown(struct clock_event_device *evt) |
| @@ -758,7 +758,7 @@ static void jr3_pci_detach(struct comedi_device *dev) · 757 unmodified lines | |||
| 758 | struct jr3_pci_dev_private *devpriv = dev->private; | 758 | struct jr3_pci_dev_private *devpriv = dev->private; |
| 759 | 759 | ||
| 760 | if (devpriv) | 760 | if (devpriv) |
| 761 | timer_delete_sync(&devpriv->timer); | 761 | timer_shutdown_sync(&devpriv->timer); |
| 762 | 762 | ||
| 763 | comedi_pci_detach(dev); | 763 | comedi_pci_detach(dev); |
| 764 | } | 764 | } |
| @@ -76,7 +76,7 @@ config ARM_VEXPRESS_SPC_CPUFREQ · 75 unmodified lines | |||
| 76 | config ARM_BRCMSTB_AVS_CPUFREQ | 76 | config ARM_BRCMSTB_AVS_CPUFREQ |
| 77 | tristate "Broadcom STB AVS CPUfreq driver" | 77 | tristate "Broadcom STB AVS CPUfreq driver" |
| 78 | depends on (ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ) || COMPILE_TEST | 78 | depends on (ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ) || COMPILE_TEST |
| 79 | default y | 79 | default y if ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ |
| 80 | help | 80 | help |
| 81 | Some Broadcom STB SoCs use a co-processor running proprietary firmware | 81 | Some Broadcom STB SoCs use a co-processor running proprietary firmware |
| 82 | ("AVS") to handle voltage and frequency scaling. This driver provides | 82 | ("AVS") to handle voltage and frequency scaling. This driver provides |
| @@ -88,7 +88,7 @@ config ARM_HIGHBANK_CPUFREQ · 5 unmodified lines | |||
| 88 | tristate "Calxeda Highbank-based" | 88 | tristate "Calxeda Highbank-based" |
| 89 | depends on ARCH_HIGHBANK || COMPILE_TEST | 89 | depends on ARCH_HIGHBANK || COMPILE_TEST |
| 90 | depends on CPUFREQ_DT && REGULATOR && PL320_MBOX | 90 | depends on CPUFREQ_DT && REGULATOR && PL320_MBOX |
| 91 | default m | 91 | default m if ARCH_HIGHBANK |
| 92 | help | 92 | help |
| 93 | This adds the CPUFreq driver for Calxeda Highbank SoC | 93 | This adds the CPUFreq driver for Calxeda Highbank SoC |
| 94 | based boards. | 94 | based boards. |
| @@ -133,7 +133,7 @@ config ARM_MEDIATEK_CPUFREQ · 38 unmodified lines | |||
| 133 | config ARM_MEDIATEK_CPUFREQ_HW | 133 | config ARM_MEDIATEK_CPUFREQ_HW |
| 134 | tristate "MediaTek CPUFreq HW driver" | 134 | tristate "MediaTek CPUFreq HW driver" |
| 135 | depends on ARCH_MEDIATEK || COMPILE_TEST | 135 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 136 | default m | 136 | default m if ARCH_MEDIATEK |
| 137 | help | 137 | help |
| 138 | Support for the CPUFreq HW driver. | 138 | Support for the CPUFreq HW driver. |
| 139 | Some MediaTek chipsets have a HW engine to offload the steps | 139 | Some MediaTek chipsets have a HW engine to offload the steps |
| @@ -181,7 +181,7 @@ config ARM_RASPBERRYPI_CPUFREQ · 41 unmodified lines | |||
| 181 | config ARM_S3C64XX_CPUFREQ | 181 | config ARM_S3C64XX_CPUFREQ |
| 182 | bool "Samsung S3C64XX" | 182 | bool "Samsung S3C64XX" |
| 183 | depends on CPU_S3C6410 || COMPILE_TEST | 183 | depends on CPU_S3C6410 || COMPILE_TEST |
| 184 | default y | 184 | default CPU_S3C6410 |
| 185 | help | 185 | help |
| 186 | This adds the CPUFreq driver for Samsung S3C6410 SoC. | 186 | This adds the CPUFreq driver for Samsung S3C6410 SoC. |
| 187 | 187 | ||
| @@ -190,7 +190,7 @@ config ARM_S3C64XX_CPUFREQ · 2 unmodified lines | |||
| 190 | config ARM_S5PV210_CPUFREQ | 190 | config ARM_S5PV210_CPUFREQ |
| 191 | bool "Samsung S5PV210 and S5PC110" | 191 | bool "Samsung S5PV210 and S5PC110" |
| 192 | depends on CPU_S5PV210 || COMPILE_TEST | 192 | depends on CPU_S5PV210 || COMPILE_TEST |
| 193 | default y | 193 | default CPU_S5PV210 |
| 194 | help | 194 | help |
| 195 | This adds the CPUFreq driver for Samsung S5PV210 and | 195 | This adds the CPUFreq driver for Samsung S5PV210 and |
| 196 | S5PC110 SoCs. | 196 | S5PC110 SoCs. |
| @@ -214,7 +214,7 @@ config ARM_SCMI_CPUFREQ · 17 unmodified lines | |||
| 214 | config ARM_SPEAR_CPUFREQ | 214 | config ARM_SPEAR_CPUFREQ |
| 215 | bool "SPEAr CPUFreq support" | 215 | bool "SPEAr CPUFreq support" |
| 216 | depends on PLAT_SPEAR || COMPILE_TEST | 216 | depends on PLAT_SPEAR || COMPILE_TEST |
| 217 | default y | 217 | default PLAT_SPEAR |
| 218 | help | 218 | help |
| 219 | This adds the CPUFreq driver support for SPEAr SOCs. | 219 | This adds the CPUFreq driver support for SPEAr SOCs. |
| 220 | 220 | ||
| @@ -233,7 +233,7 @@ config ARM_TEGRA20_CPUFREQ · 12 unmodified lines | |||
| 233 | tristate "Tegra20/30 CPUFreq support" | 233 | tristate "Tegra20/30 CPUFreq support" |
| 234 | depends on ARCH_TEGRA || COMPILE_TEST | 234 | depends on ARCH_TEGRA || COMPILE_TEST |
| 235 | depends on CPUFREQ_DT | 235 | depends on CPUFREQ_DT |
| 236 | default y | 236 | default ARCH_TEGRA |
| 237 | help | 237 | help |
| 238 | This adds the CPUFreq driver support for Tegra20/30 SOCs. | 238 | This adds the CPUFreq driver support for Tegra20/30 SOCs. |
| 239 | 239 | ||
| @@ -241,7 +241,7 @@ config ARM_TEGRA124_CPUFREQ · 1 unmodified line | |||
| 241 | bool "Tegra124 CPUFreq support" | 241 | bool "Tegra124 CPUFreq support" |
| 242 | depends on ARCH_TEGRA || COMPILE_TEST | 242 | depends on ARCH_TEGRA || COMPILE_TEST |
| 243 | depends on CPUFREQ_DT | 243 | depends on CPUFREQ_DT |
| 244 | default y | 244 | default ARCH_TEGRA |
| 245 | help | 245 | help |
| 246 | This adds the CPUFreq driver support for Tegra124 SOCs. | 246 | This adds the CPUFreq driver support for Tegra124 SOCs. |
| 247 | 247 | ||
| @@ -256,14 +256,14 @@ config ARM_TEGRA194_CPUFREQ · 8 unmodified lines | |||
| 256 | tristate "Tegra194 CPUFreq support" | 256 | tristate "Tegra194 CPUFreq support" |
| 257 | depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST) | 257 | depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST) |
| 258 | depends on TEGRA_BPMP | 258 | depends on TEGRA_BPMP |
| 259 | default y | 259 | default ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC |
| 260 | help | 260 | help |
| 261 | This adds CPU frequency driver support for Tegra194 SOCs. | 261 | This adds CPU frequency driver support for Tegra194 SOCs. |
| 262 | 262 | ||
| 263 | config ARM_TI_CPUFREQ | 263 | config ARM_TI_CPUFREQ |
| 264 | bool "Texas Instruments CPUFreq support" | 264 | bool "Texas Instruments CPUFreq support" |
| 265 | depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST | 265 | depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST |
| 266 | default y | 266 | default ARCH_OMAP2PLUS || ARCH_K3 |
| 267 | help | 267 | help |
| 268 | This driver enables valid OPPs on the running platform based on | 268 | This driver enables valid OPPs on the running platform based on |
| 269 | values contained within the SoC in use. Enable this in order to | 269 | values contained within the SoC in use. Enable this in order to |
| @@ -909,8 +909,19 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) · 908 unmodified lines | |||
| 909 | if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) | 909 | if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) |
| 910 | pr_warn(FW_WARN "P-state 0 is not max freq\n"); | 910 | pr_warn(FW_WARN "P-state 0 is not max freq\n"); |
| 911 | 911 | ||
| 912 | if (acpi_cpufreq_driver.set_boost) | 912 | if (acpi_cpufreq_driver.set_boost) { |
| 913 | policy->boost_supported = true; | 913 | if (policy->boost_supported) { |
| 914 | /* | ||
| 915 | * The firmware may have altered boost state while the | ||
| 916 | * CPU was offline (for example during a suspend-resume | ||
| 917 | * cycle). | ||
| 918 | */ | ||
| 919 | if (policy->boost_enabled != boost_state(cpu)) | ||
| 920 | set_boost(policy, policy->boost_enabled); | ||
| 921 | } else { | ||
| 922 | policy->boost_supported = true; | ||
| 923 | } | ||
| 924 | } | ||
| 914 | 925 | ||
| 915 | return result; | 926 | return result; |
| 916 | 927 | ||
| @@ -607,13 +607,16 @@ static void amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) · 606 unmodified lines | |||
| 607 | union perf_cached perf = READ_ONCE(cpudata->perf); | 607 | union perf_cached perf = READ_ONCE(cpudata->perf); |
| 608 | 608 | ||
| 609 | perf.max_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->max); | 609 | perf.max_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->max); |
| 610 | perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min); | 610 | WRITE_ONCE(cpudata->max_limit_freq, policy->max); |
| 611 | 611 | ||
| 612 | if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) | 612 | if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) { |
| 613 | perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf); | 613 | perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf); |
| 614 | WRITE_ONCE(cpudata->min_limit_freq, min(cpudata->nominal_freq, cpudata->max_limit_freq)); | ||
| 615 | } else { | ||
| 616 | perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min); | ||
| 617 | WRITE_ONCE(cpudata->min_limit_freq, policy->min); | ||
| 618 | } | ||
| 614 | 619 | ||
| 615 | WRITE_ONCE(cpudata->max_limit_freq, policy->max); | ||
| 616 | WRITE_ONCE(cpudata->min_limit_freq, policy->min); | ||
| 617 | WRITE_ONCE(cpudata->perf, perf); | 620 | WRITE_ONCE(cpudata->perf, perf); |
| 618 | } | 621 | } |
| 619 | 622 | ||
| @@ -791,16 +794,6 @@ static void amd_perf_ctl_reset(unsigned int cpu) · 171 unmodified lines | |||
| 791 | wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); | 794 | wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); |
| 792 | } | 795 | } |
| 793 | 796 | ||
| 794 | /* | ||
| 795 | * Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks | ||
| 796 | * due to locking, so queue the work for later. | ||
| 797 | */ | ||
| 798 | static void amd_pstste_sched_prefcore_workfn(struct work_struct *work) | ||
| 799 | { | ||
| 800 | sched_set_itmt_support(); | ||
| 801 | } | ||
| 802 | static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn); | ||
| 803 | |||
| 804 | #define CPPC_MAX_PERF U8_MAX | 797 | #define CPPC_MAX_PERF U8_MAX |
| 805 | 798 | ||
| 806 | static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata) | 799 | static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata) |
| @@ -811,14 +804,8 @@ static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata) · 4 unmodified lines | |||
| 811 | 804 | ||
| 812 | cpudata->hw_prefcore = true; | 805 | cpudata->hw_prefcore = true; |
| 813 | 806 | ||
| 814 | /* | 807 | /* Priorities must be initialized before ITMT support can be toggled on. */ |
| 815 | * The priorities can be set regardless of whether or not | ||
| 816 | * sched_set_itmt_support(true) has been called and it is valid to | ||
| 817 | * update them at any time after it has been called. | ||
| 818 | */ | ||
| 819 | sched_set_itmt_core_prio((int)READ_ONCE(cpudata->prefcore_ranking), cpudata->cpu); | 808 | sched_set_itmt_core_prio((int)READ_ONCE(cpudata->prefcore_ranking), cpudata->cpu); |
| 820 | |||
| 821 | schedule_work(&sched_prefcore_work); | ||
| 822 | } | 809 | } |
| 823 | 810 | ||
| 824 | static void amd_pstate_update_limits(unsigned int cpu) | 811 | static void amd_pstate_update_limits(unsigned int cpu) |
| @@ -1193,6 +1180,9 @@ static ssize_t show_energy_performance_preference( · 368 unmodified lines | |||
| 1193 | 1180 | ||
| 1194 | static void amd_pstate_driver_cleanup(void) | 1181 | static void amd_pstate_driver_cleanup(void) |
| 1195 | { | 1182 | { |
| 1183 | if (amd_pstate_prefcore) | ||
| 1184 | sched_clear_itmt_support(); | ||
| 1185 | |||
| 1196 | cppc_state = AMD_PSTATE_DISABLE; | 1186 | cppc_state = AMD_PSTATE_DISABLE; |
| 1197 | current_pstate_driver = NULL; | 1187 | current_pstate_driver = NULL; |
| 1198 | } | 1188 | } |
| @@ -1235,6 +1225,10 @@ static int amd_pstate_register_driver(int mode) · 36 unmodified lines | |||
| 1235 | return ret; | 1225 | return ret; |
| 1236 | } | 1226 | } |
| 1237 | 1227 | ||
| 1228 | /* Enable ITMT support once all CPUs have initialized their asym priorities. */ | ||
| 1229 | if (amd_pstate_prefcore) | ||
| 1230 | sched_set_itmt_support(); | ||
| 1231 | |||
| 1238 | return 0; | 1232 | return 0; |
| 1239 | } | 1233 | } |
| 1240 | 1234 | ||
| @@ -134,11 +134,17 @@ static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = { · 133 unmodified lines | |||
| 134 | 134 | ||
| 135 | static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu) | 135 | static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu) |
| 136 | { | 136 | { |
| 137 | struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | 137 | struct cpufreq_policy *policy; |
| 138 | struct apple_cpu_priv *priv = policy->driver_data; | 138 | struct apple_cpu_priv *priv; |
| 139 | struct cpufreq_frequency_table *p; | 139 | struct cpufreq_frequency_table *p; |
| 140 | unsigned int pstate; | 140 | unsigned int pstate; |
| 141 | 141 | ||
| 142 | policy = cpufreq_cpu_get_raw(cpu); | ||
| 143 | if (unlikely(!policy)) | ||
| 144 | return 0; | ||
| 145 | |||
| 146 | priv = policy->driver_data; | ||
| 147 | |||
| 142 | if (priv->info->cur_pstate_mask) { | 148 | if (priv->info->cur_pstate_mask) { |
| 143 | u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS); | 149 | u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS); |
| 144 | 150 | ||
| @@ -747,7 +747,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) · 746 unmodified lines | |||
| 747 | int ret; | 747 | int ret; |
| 748 | 748 | ||
| 749 | if (!policy) | 749 | if (!policy) |
| 750 | return -ENODEV; | 750 | return 0; |
| 751 | 751 | ||
| 752 | cpu_data = policy->driver_data; | 752 | cpu_data = policy->driver_data; |
| 753 | 753 | ||
| @@ -175,6 +175,7 @@ static const struct of_device_id blocklist[] __initconst = { · 174 unmodified lines | |||
| 175 | { .compatible = "qcom,sm8350", }, | 175 | { .compatible = "qcom,sm8350", }, |
| 176 | { .compatible = "qcom,sm8450", }, | 176 | { .compatible = "qcom,sm8450", }, |
| 177 | { .compatible = "qcom,sm8550", }, | 177 | { .compatible = "qcom,sm8550", }, |
| 178 | { .compatible = "qcom,sm8650", }, | ||
| 178 | 179 | ||
| 179 | { .compatible = "st,stih407", }, | 180 | { .compatible = "st,stih407", }, |
| 180 | { .compatible = "st,stih410", }, | 181 | { .compatible = "st,stih410", }, |
| @@ -536,16 +536,18 @@ void cpufreq_disable_fast_switch(struct cpufreq_policy *policy) · 535 unmodified lines | |||
| 536 | EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch); | 536 | EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch); |
| 537 | 537 | ||
| 538 | static unsigned int __resolve_freq(struct cpufreq_policy *policy, | 538 | static unsigned int __resolve_freq(struct cpufreq_policy *policy, |
| 539 | unsigned int target_freq, unsigned int relation) | 539 | unsigned int target_freq, |
| 540 | unsigned int min, unsigned int max, | ||
| 541 | unsigned int relation) | ||
| 540 | { | 542 | { |
| 541 | unsigned int idx; | 543 | unsigned int idx; |
| 542 | 544 | ||
| 543 | target_freq = clamp_val(target_freq, policy->min, policy->max); | 545 | target_freq = clamp_val(target_freq, min, max); |
| 544 | 546 | ||
| 545 | if (!policy->freq_table) | 547 | if (!policy->freq_table) |
| 546 | return target_freq; | 548 | return target_freq; |
| 547 | 549 | ||
| 548 | idx = cpufreq_frequency_table_target(policy, target_freq, relation); | 550 | idx = cpufreq_frequency_table_target(policy, target_freq, min, max, relation); |
| 549 | policy->cached_resolved_idx = idx; | 551 | policy->cached_resolved_idx = idx; |
| 550 | policy->cached_target_freq = target_freq; | 552 | policy->cached_target_freq = target_freq; |
| 551 | return policy->freq_table[idx].frequency; | 553 | return policy->freq_table[idx].frequency; |
| @@ -565,7 +567,21 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy, · 13 unmodified lines | |||
| 565 | unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, | 567 | unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, |
| 566 | unsigned int target_freq) | 568 | unsigned int target_freq) |
| 567 | { | 569 | { |
| 568 | return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE); | 570 | unsigned int min = READ_ONCE(policy->min); |
| 571 | unsigned int max = READ_ONCE(policy->max); | ||
| 572 | |||
| 573 | /* | ||
| 574 | * If this function runs in parallel with cpufreq_set_policy(), it may | ||
| 575 | * read policy->min before the update and policy->max after the update | ||
| 576 | * or the other way around, so there is no ordering guarantee. | ||
| 577 | * | ||
| 578 | * Resolve this by always honoring the max (in case it comes from | ||
| 579 | * thermal throttling or similar). | ||
| 580 | */ | ||
| 581 | if (unlikely(min > max)) | ||
| 582 | min = max; | ||
| 583 | |||
| 584 | return __resolve_freq(policy, target_freq, min, max, CPUFREQ_RELATION_LE); | ||
| 569 | } | 585 | } |
| 570 | EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); | 586 | EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); |
| 571 | 587 | ||
| @@ -2384,7 +2400,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, · 1812 unmodified lines | |||
| 2384 | if (cpufreq_disabled()) | 2400 | if (cpufreq_disabled()) |
| 2385 | return -ENODEV; | 2401 | return -ENODEV; |
| 2386 | 2402 | ||
| 2387 | target_freq = __resolve_freq(policy, target_freq, relation); | 2403 | target_freq = __resolve_freq(policy, target_freq, policy->min, |
| 2404 | policy->max, relation); | ||
| 2388 | 2405 | ||
| 2389 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", | 2406 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", |
| 2390 | policy->cpu, target_freq, relation, old_target_freq); | 2407 | policy->cpu, target_freq, relation, old_target_freq); |
| @@ -2708,11 +2725,18 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, · 317 unmodified lines | |||
| 2708 | * Resolve policy min/max to available frequencies. It ensures | 2725 | * Resolve policy min/max to available frequencies. It ensures |
| 2709 | * no frequency resolution will neither overshoot the requested maximum | 2726 | * no frequency resolution will neither overshoot the requested maximum |
| 2710 | * nor undershoot the requested minimum. | 2727 | * nor undershoot the requested minimum. |
| 2728 | * | ||
| 2729 | * Avoid storing intermediate values in policy->max or policy->min and | ||
| 2730 | * compiler optimizations around them because they may be accessed | ||
| 2731 | * concurrently by cpufreq_driver_resolve_freq() during the update. | ||
| 2711 | */ | 2732 | */ |
| 2712 | policy->min = new_data.min; | 2733 | WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, |
| 2713 | policy->max = new_data.max; | 2734 | new_data.min, new_data.max, |
| 2714 | policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L); | 2735 | CPUFREQ_RELATION_H)); |
| 2715 | policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H); | 2736 | new_data.min = __resolve_freq(policy, new_data.min, new_data.min, |
| 2737 | new_data.max, CPUFREQ_RELATION_L); | ||
| 2738 | WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min); | ||
| 2739 | |||
| 2716 | trace_cpu_frequency_limits(policy); | 2740 | trace_cpu_frequency_limits(policy); |
| 2717 | 2741 | ||
| 2718 | cpufreq_update_pressure(policy); | 2742 | cpufreq_update_pressure(policy); |
| @@ -76,7 +76,8 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, · 75 unmodified lines | |||
| 76 | return freq_next; | 76 | return freq_next; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | index = cpufreq_frequency_table_target(policy, freq_next, relation); | 79 | index = cpufreq_frequency_table_target(policy, freq_next, policy->min, |
| 80 | policy->max, relation); | ||
| 80 | freq_req = freq_table[index].frequency; | 81 | freq_req = freq_table[index].frequency; |
| 81 | freq_reduc = freq_req * od_tuners->powersave_bias / 1000; | 82 | freq_reduc = freq_req * od_tuners->powersave_bias / 1000; |
| 82 | freq_avg = freq_req - freq_reduc; | 83 | freq_avg = freq_req - freq_reduc; |
| @@ -115,8 +115,8 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy) · 114 unmodified lines | |||
| 115 | EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); | 115 | EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); |
| 116 | 116 | ||
| 117 | int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, | 117 | int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, |
| 118 | unsigned int target_freq, | 118 | unsigned int target_freq, unsigned int min, |
| 119 | unsigned int relation) | 119 | unsigned int max, unsigned int relation) |
| 120 | { | 120 | { |
| 121 | struct cpufreq_frequency_table optimal = { | 121 | struct cpufreq_frequency_table optimal = { |
| 122 | .driver_data = ~0, | 122 | .driver_data = ~0, |
| @@ -147,7 +147,7 @@ int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, · 24 unmodified lines | |||
| 147 | cpufreq_for_each_valid_entry_idx(pos, table, i) { | 147 | cpufreq_for_each_valid_entry_idx(pos, table, i) { |
| 148 | freq = pos->frequency; | 148 | freq = pos->frequency; |
| 149 | 149 | ||
| 150 | if ((freq < policy->min) || (freq > policy->max)) | 150 | if (freq < min || freq > max) |
| 151 | continue; | 151 | continue; |
| 152 | if (freq == target_freq) { | 152 | if (freq == target_freq) { |
| 153 | optimal.driver_data = i; | 153 | optimal.driver_data = i; |
| @@ -598,6 +598,9 @@ static bool turbo_is_disabled(void) · 597 unmodified lines | |||
| 598 | { | 598 | { |
| 599 | u64 misc_en; | 599 | u64 misc_en; |
| 600 | 600 | ||
| 601 | if (!cpu_feature_enabled(X86_FEATURE_IDA)) | ||
| 602 | return true; | ||
| 603 | |||
| 601 | rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); | 604 | rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); |
| 602 | 605 | ||
| 603 | return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); | 606 | return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); |
| @@ -2209,7 +2212,7 @@ static int knl_get_turbo_pstate(int cpu) · 1605 unmodified lines | |||
| 2209 | static int hwp_get_cpu_scaling(int cpu) | 2212 | static int hwp_get_cpu_scaling(int cpu) |
| 2210 | { | 2213 | { |
| 2211 | if (hybrid_scaling_factor) { | 2214 | if (hybrid_scaling_factor) { |
| 2212 | struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | 2215 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 2213 | u8 cpu_type = c->topo.intel_type; | 2216 | u8 cpu_type = c->topo.intel_type; |
| 2214 | 2217 | ||
| 2215 | /* | 2218 | /* |
| @@ -37,11 +37,17 @@ static struct cpufreq_driver scmi_cpufreq_driver; · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | static unsigned int scmi_cpufreq_get_rate(unsigned int cpu) | 38 | static unsigned int scmi_cpufreq_get_rate(unsigned int cpu) |
| 39 | { | 39 | { |
| 40 | struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | 40 | struct cpufreq_policy *policy; |
| 41 | struct scmi_data *priv = policy->driver_data; | 41 | struct scmi_data *priv; |
| 42 | unsigned long rate; | 42 | unsigned long rate; |
| 43 | int ret; | 43 | int ret; |
| 44 | 44 | ||
| 45 | policy = cpufreq_cpu_get_raw(cpu); | ||
| 46 | if (unlikely(!policy)) | ||
| 47 | return 0; | ||
| 48 | |||
| 49 | priv = policy->driver_data; | ||
| 50 | |||
| 45 | ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false); | 51 | ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false); |
| 46 | if (ret) | 52 | if (ret) |
| 47 | return 0; | 53 | return 0; |
| @@ -29,9 +29,16 @@ static struct scpi_ops *scpi_ops; · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | static unsigned int scpi_cpufreq_get_rate(unsigned int cpu) | 30 | static unsigned int scpi_cpufreq_get_rate(unsigned int cpu) |
| 31 | { | 31 | { |
| 32 | struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | 32 | struct cpufreq_policy *policy; |
| 33 | struct scpi_data *priv = policy->driver_data; | 33 | struct scpi_data *priv; |
| 34 | unsigned long rate = clk_get_rate(priv->clk); | 34 | unsigned long rate; |
| 35 | |||
| 36 | policy = cpufreq_cpu_get_raw(cpu); | ||
| 37 | if (unlikely(!policy)) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | priv = policy->driver_data; | ||
| 41 | rate = clk_get_rate(priv->clk); | ||
| 35 | 42 | ||
| 36 | return rate / 1000; | 43 | return rate / 1000; |
| 37 | } | 44 | } |
| @@ -194,7 +194,9 @@ static int sun50i_cpufreq_get_efuse(void) · 193 unmodified lines | |||
| 194 | struct nvmem_cell *speedbin_nvmem; | 194 | struct nvmem_cell *speedbin_nvmem; |
| 195 | const struct of_device_id *match; | 195 | const struct of_device_id *match; |
| 196 | struct device *cpu_dev; | 196 | struct device *cpu_dev; |
| 197 | u32 *speedbin; | 197 | void *speedbin_ptr; |
| 198 | u32 speedbin = 0; | ||
| 199 | size_t len; | ||
| 198 | int ret; | 200 | int ret; |
| 199 | 201 | ||
| 200 | cpu_dev = get_cpu_device(0); | 202 | cpu_dev = get_cpu_device(0); |
| @@ -217,14 +219,18 @@ static int sun50i_cpufreq_get_efuse(void) · 16 unmodified lines | |||
| 217 | return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), | 219 | return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), |
| 218 | "Could not get nvmem cell\n"); | 220 | "Could not get nvmem cell\n"); |
| 219 | 221 | ||
| 220 | speedbin = nvmem_cell_read(speedbin_nvmem, NULL); | 222 | speedbin_ptr = nvmem_cell_read(speedbin_nvmem, &len); |
| 221 | nvmem_cell_put(speedbin_nvmem); | 223 | nvmem_cell_put(speedbin_nvmem); |
| 222 | if (IS_ERR(speedbin)) | 224 | if (IS_ERR(speedbin_ptr)) |
| 223 | return PTR_ERR(speedbin); | 225 | return PTR_ERR(speedbin_ptr); |
| 224 | 226 | ||
| 225 | ret = opp_data->efuse_xlate(*speedbin); | 227 | if (len <= 4) |
| 228 | memcpy(&speedbin, speedbin_ptr, len); | ||
| 229 | speedbin = le32_to_cpu(speedbin); | ||
| 226 | 230 | ||
| 227 | kfree(speedbin); | 231 | ret = opp_data->efuse_xlate(speedbin); |
| 232 | |||
| 233 | kfree(speedbin_ptr); | ||
| 228 | 234 | ||
| 229 | return ret; | 235 | return ret; |
| 230 | }; | 236 | }; |
| @@ -163,6 +163,12 @@ static int atmel_sha204a_probe(struct i2c_client *client) · 162 unmodified lines | |||
| 163 | i2c_priv->hwrng.name = dev_name(&client->dev); | 163 | i2c_priv->hwrng.name = dev_name(&client->dev); |
| 164 | i2c_priv->hwrng.read = atmel_sha204a_rng_read; | 164 | i2c_priv->hwrng.read = atmel_sha204a_rng_read; |
| 165 | 165 | ||
| 166 | /* | ||
| 167 | * According to review by Bill Cox [1], this HWRNG has very low entropy. | ||
| 168 | * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html | ||
| 169 | */ | ||
| 170 | i2c_priv->hwrng.quality = 1; | ||
| 171 | |||
| 166 | ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng); | 172 | ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng); |
| 167 | if (ret) | 173 | if (ret) |
| 168 | dev_warn(&client->dev, "failed to register RNG (%d)\n", ret); | 174 | dev_warn(&client->dev, "failed to register RNG (%d)\n", ret); |
| @@ -122,12 +122,12 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req) · 121 unmodified lines | |||
| 122 | qm_fd_addr_set64(&fd, addr); | 122 | qm_fd_addr_set64(&fd, addr); |
| 123 | 123 | ||
| 124 | do { | 124 | do { |
| 125 | refcount_inc(&req->drv_ctx->refcnt); | ||
| 125 | ret = qman_enqueue(req->drv_ctx->req_fq, &fd); | 126 | ret = qman_enqueue(req->drv_ctx->req_fq, &fd); |
| 126 | if (likely(!ret)) { | 127 | if (likely(!ret)) |
| 127 | refcount_inc(&req->drv_ctx->refcnt); | ||
| 128 | return 0; | 128 | return 0; |
| 129 | } | ||
| 130 | 129 | ||
| 130 | refcount_dec(&req->drv_ctx->refcnt); | ||
| 131 | if (ret != -EBUSY) | 131 | if (ret != -EBUSY) |
| 132 | break; | 132 | break; |
| 133 | num_retries++; | 133 | num_retries++; |
| @@ -269,7 +269,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq) · 268 unmodified lines | |||
| 269 | unsigned int cmdlen, key1_id, key2_id; | 269 | unsigned int cmdlen, key1_id, key2_id; |
| 270 | int ret; | 270 | int ret; |
| 271 | 271 | ||
| 272 | rctx->iv = (u32 *)req->iv; | 272 | rctx->iv = (ctx->alg == SE_ALG_ECB) ? NULL : (u32 *)req->iv; |
| 273 | rctx->len = req->cryptlen; | 273 | rctx->len = req->cryptlen; |
| 274 | key1_id = ctx->key1_id; | 274 | key1_id = ctx->key1_id; |
| 275 | key2_id = ctx->key2_id; | 275 | key2_id = ctx->key2_id; |
| @@ -498,9 +498,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt) · 222 unmodified lines | |||
| 498 | if (!req->cryptlen) | 498 | if (!req->cryptlen) |
| 499 | return 0; | 499 | return 0; |
| 500 | 500 | ||
| 501 | if (ctx->alg == SE_ALG_ECB) | ||
| 502 | req->iv = NULL; | ||
| 503 | |||
| 504 | rctx->encrypt = encrypt; | 501 | rctx->encrypt = encrypt; |
| 505 | 502 | ||
| 506 | return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req); | 503 | return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req); |
| @@ -119,7 +119,7 @@ int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port, · 118 unmodified lines | |||
| 119 | 119 | ||
| 120 | int cxl_ras_init(void); | 120 | int cxl_ras_init(void); |
| 121 | void cxl_ras_exit(void); | 121 | void cxl_ras_exit(void); |
| 122 | int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port); | 122 | int cxl_gpf_port_setup(struct cxl_dport *dport); |
| 123 | int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res, | 123 | int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res, |
| 124 | int nid, resource_size_t *size); | 124 | int nid, resource_size_t *size); |
| 125 | 125 | ||
| @@ -528,13 +528,13 @@ static void *cxlctl_set_feature(struct cxl_features_state *cxlfs, · 527 unmodified lines | |||
| 528 | rc = cxl_set_feature(cxl_mbox, &feat_in->uuid, | 528 | rc = cxl_set_feature(cxl_mbox, &feat_in->uuid, |
| 529 | feat_in->version, feat_in->feat_data, | 529 | feat_in->version, feat_in->feat_data, |
| 530 | data_size, flags, offset, &return_code); | 530 | data_size, flags, offset, &return_code); |
| 531 | *out_len = sizeof(*rpc_out); | ||
| 531 | if (rc) { | 532 | if (rc) { |
| 532 | rpc_out->retval = return_code; | 533 | rpc_out->retval = return_code; |
| 533 | return no_free_ptr(rpc_out); | 534 | return no_free_ptr(rpc_out); |
| 534 | } | 535 | } |
| 535 | 536 | ||
| 536 | rpc_out->retval = CXL_MBOX_CMD_RC_SUCCESS; | 537 | rpc_out->retval = CXL_MBOX_CMD_RC_SUCCESS; |
| 537 | *out_len = sizeof(*rpc_out); | ||
| 538 | 538 | ||
| 539 | return no_free_ptr(rpc_out); | 539 | return no_free_ptr(rpc_out); |
| 540 | } | 540 | } |
| @@ -677,7 +677,7 @@ static void free_memdev_fwctl(void *_fwctl_dev) · 136 unmodified lines | |||
| 677 | fwctl_put(fwctl_dev); | 677 | fwctl_put(fwctl_dev); |
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd) | 680 | int devm_cxl_setup_fwctl(struct device *host, struct cxl_memdev *cxlmd) |
| 681 | { | 681 | { |
| 682 | struct cxl_dev_state *cxlds = cxlmd->cxlds; | 682 | struct cxl_dev_state *cxlds = cxlmd->cxlds; |
| 683 | struct cxl_features_state *cxlfs; | 683 | struct cxl_features_state *cxlfs; |
| @@ -700,7 +700,7 @@ int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd) · 16 unmodified lines | |||
| 700 | if (rc) | 700 | if (rc) |
| 701 | return rc; | 701 | return rc; |
| 702 | 702 | ||
| 703 | return devm_add_action_or_reset(&cxlmd->dev, free_memdev_fwctl, | 703 | return devm_add_action_or_reset(host, free_memdev_fwctl, |
| 704 | no_free_ptr(fwctl_dev)); | 704 | no_free_ptr(fwctl_dev)); |
| 705 | } | 705 | } |
| 706 | EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fwctl, "CXL"); | 706 | EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fwctl, "CXL"); |
| @@ -1072,14 +1072,20 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c) · 1071 unmodified lines | |||
| 1072 | #define GPF_TIMEOUT_BASE_MAX 2 | 1072 | #define GPF_TIMEOUT_BASE_MAX 2 |
| 1073 | #define GPF_TIMEOUT_SCALE_MAX 7 /* 10 seconds */ | 1073 | #define GPF_TIMEOUT_SCALE_MAX 7 /* 10 seconds */ |
| 1074 | 1074 | ||
| 1075 | u16 cxl_gpf_get_dvsec(struct device *dev, bool is_port) | 1075 | u16 cxl_gpf_get_dvsec(struct device *dev) |
| 1076 | { | 1076 | { |
| 1077 | struct pci_dev *pdev; | ||
| 1078 | bool is_port = true; | ||
| 1077 | u16 dvsec; | 1079 | u16 dvsec; |
| 1078 | 1080 | ||
| 1079 | if (!dev_is_pci(dev)) | 1081 | if (!dev_is_pci(dev)) |
| 1080 | return 0; | 1082 | return 0; |
| 1081 | 1083 | ||
| 1082 | dvsec = pci_find_dvsec_capability(to_pci_dev(dev), PCI_VENDOR_ID_CXL, | 1084 | pdev = to_pci_dev(dev); |
| 1085 | if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) | ||
| 1086 | is_port = false; | ||
| 1087 | |||
| 1088 | dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL, | ||
| 1083 | is_port ? CXL_DVSEC_PORT_GPF : CXL_DVSEC_DEVICE_GPF); | 1089 | is_port ? CXL_DVSEC_PORT_GPF : CXL_DVSEC_DEVICE_GPF); |
| 1084 | if (!dvsec) | 1090 | if (!dvsec) |
| 1085 | dev_warn(dev, "%s GPF DVSEC not present\n", | 1091 | dev_warn(dev, "%s GPF DVSEC not present\n", |
| @@ -1128,26 +1134,24 @@ static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase) · 42 unmodified lines | |||
| 1128 | return rc; | 1134 | return rc; |
| 1129 | } | 1135 | } |
| 1130 | 1136 | ||
| 1131 | int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port) | 1137 | int cxl_gpf_port_setup(struct cxl_dport *dport) |
| 1132 | { | 1138 | { |
| 1133 | struct pci_dev *pdev; | 1139 | if (!dport) |
| 1134 | |||
| 1135 | if (!port) | ||
| 1136 | return -EINVAL; | 1140 | return -EINVAL; |
| 1137 | 1141 | ||
| 1138 | if (!port->gpf_dvsec) { | 1142 | if (!dport->gpf_dvsec) { |
| 1143 | struct pci_dev *pdev; | ||
| 1139 | int dvsec; | 1144 | int dvsec; |
| 1140 | 1145 | ||
| 1141 | dvsec = cxl_gpf_get_dvsec(dport_dev, true); | 1146 | dvsec = cxl_gpf_get_dvsec(dport->dport_dev); |
| 1142 | if (!dvsec) | 1147 | if (!dvsec) |
| 1143 | return -EINVAL; | 1148 | return -EINVAL; |
| 1144 | 1149 | ||
| 1145 | port->gpf_dvsec = dvsec; | 1150 | dport->gpf_dvsec = dvsec; |
| 1151 | pdev = to_pci_dev(dport->dport_dev); | ||
| 1152 | update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 1); | ||
| 1153 | update_gpf_port_dvsec(pdev, dport->gpf_dvsec, 2); | ||
| 1146 | } | 1154 | } |
| 1147 | 1155 | ||
| 1148 | pdev = to_pci_dev(dport_dev); | ||
| 1149 | update_gpf_port_dvsec(pdev, port->gpf_dvsec, 1); | ||
| 1150 | update_gpf_port_dvsec(pdev, port->gpf_dvsec, 2); | ||
| 1151 | |||
| 1152 | return 0; | 1156 | return 0; |
| 1153 | } | 1157 | } |
| @@ -1678,7 +1678,7 @@ retry: · 1677 unmodified lines | |||
| 1678 | if (rc && rc != -EBUSY) | 1678 | if (rc && rc != -EBUSY) |
| 1679 | return rc; | 1679 | return rc; |
| 1680 | 1680 | ||
| 1681 | cxl_gpf_port_setup(dport_dev, port); | 1681 | cxl_gpf_port_setup(dport); |
| 1682 | 1682 | ||
| 1683 | /* Any more ports to add between this one and the root? */ | 1683 | /* Any more ports to add between this one and the root? */ |
| 1684 | if (!dev_is_cxl_root_child(&port->dev)) | 1684 | if (!dev_is_cxl_root_child(&port->dev)) |
| @@ -581,7 +581,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri · 580 unmodified lines | |||
| 581 | resource_size_t rcrb = ri->base; | 581 | resource_size_t rcrb = ri->base; |
| 582 | void __iomem *addr; | 582 | void __iomem *addr; |
| 583 | u32 bar0, bar1; | 583 | u32 bar0, bar1; |
| 584 | u16 cmd; | ||
| 585 | u32 id; | 584 | u32 id; |
| 586 | 585 | ||
| 587 | if (which == CXL_RCRB_UPSTREAM) | 586 | if (which == CXL_RCRB_UPSTREAM) |
| @@ -603,7 +602,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri · 15 unmodified lines | |||
| 603 | } | 602 | } |
| 604 | 603 | ||
| 605 | id = readl(addr + PCI_VENDOR_ID); | 604 | id = readl(addr + PCI_VENDOR_ID); |
| 606 | cmd = readw(addr + PCI_COMMAND); | ||
| 607 | bar0 = readl(addr + PCI_BASE_ADDRESS_0); | 605 | bar0 = readl(addr + PCI_BASE_ADDRESS_0); |
| 608 | bar1 = readl(addr + PCI_BASE_ADDRESS_1); | 606 | bar1 = readl(addr + PCI_BASE_ADDRESS_1); |
| 609 | iounmap(addr); | 607 | iounmap(addr); |
| @@ -618,8 +616,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri · 8 unmodified lines | |||
| 618 | dev_err(dev, "Failed to access Downstream Port RCRB\n"); | 616 | dev_err(dev, "Failed to access Downstream Port RCRB\n"); |
| 619 | return CXL_RESOURCE_NONE; | 617 | return CXL_RESOURCE_NONE; |
| 620 | } | 618 | } |
| 621 | if (!(cmd & PCI_COMMAND_MEMORY)) | ||
| 622 | return CXL_RESOURCE_NONE; | ||
| 623 | /* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */ | 619 | /* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */ |
| 624 | if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO)) | 620 | if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO)) |
| 625 | return CXL_RESOURCE_NONE; | 621 | return CXL_RESOURCE_NONE; |
| @@ -592,7 +592,6 @@ struct cxl_dax_region { · 591 unmodified lines | |||
| 592 | * @cdat: Cached CDAT data | 592 | * @cdat: Cached CDAT data |
| 593 | * @cdat_available: Should a CDAT attribute be available in sysfs | 593 | * @cdat_available: Should a CDAT attribute be available in sysfs |
| 594 | * @pci_latency: Upstream latency in picoseconds | 594 | * @pci_latency: Upstream latency in picoseconds |
| 595 | * @gpf_dvsec: Cached GPF port DVSEC | ||
| 596 | */ | 595 | */ |
| 597 | struct cxl_port { | 596 | struct cxl_port { |
| 598 | struct device dev; | 597 | struct device dev; |
| @@ -616,7 +615,6 @@ struct cxl_port { · 17 unmodified lines | |||
| 616 | } cdat; | 615 | } cdat; |
| 617 | bool cdat_available; | 616 | bool cdat_available; |
| 618 | long pci_latency; | 617 | long pci_latency; |
| 619 | int gpf_dvsec; | ||
| 620 | }; | 618 | }; |
| 621 | 619 | ||
| 622 | /** | 620 | /** |
| @@ -664,6 +662,7 @@ struct cxl_rcrb_info { · 41 unmodified lines | |||
| 664 | * @regs: Dport parsed register blocks | 662 | * @regs: Dport parsed register blocks |
| 665 | * @coord: access coordinates (bandwidth and latency performance attributes) | 663 | * @coord: access coordinates (bandwidth and latency performance attributes) |
| 666 | * @link_latency: calculated PCIe downstream latency | 664 | * @link_latency: calculated PCIe downstream latency |
| 665 | * @gpf_dvsec: Cached GPF port DVSEC | ||
| 667 | */ | 666 | */ |
| 668 | struct cxl_dport { | 667 | struct cxl_dport { |
| 669 | struct device *dport_dev; | 668 | struct device *dport_dev; |
| @@ -675,6 +674,7 @@ struct cxl_dport { · 5 unmodified lines | |||
| 675 | struct cxl_regs regs; | 674 | struct cxl_regs regs; |
| 676 | struct access_coordinate coord[ACCESS_COORDINATE_MAX]; | 675 | struct access_coordinate coord[ACCESS_COORDINATE_MAX]; |
| 677 | long link_latency; | 676 | long link_latency; |
| 677 | int gpf_dvsec; | ||
| 678 | }; | 678 | }; |
| 679 | 679 | ||
| 680 | /** | 680 | /** |
| @@ -910,6 +910,6 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port); · 229 unmodified lines | |||
| 910 | #define __mock static | 910 | #define __mock static |
| 911 | #endif | 911 | #endif |
| 912 | 912 | ||
| 913 | u16 cxl_gpf_get_dvsec(struct device *dev, bool is_port); | 913 | u16 cxl_gpf_get_dvsec(struct device *dev); |
| 914 | 914 | ||
| 915 | #endif /* __CXL_H__ */ | 915 | #endif /* __CXL_H__ */ |
| @@ -1018,7 +1018,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 1017 unmodified lines | |||
| 1018 | if (rc) | 1018 | if (rc) |
| 1019 | return rc; | 1019 | return rc; |
| 1020 | 1020 | ||
| 1021 | rc = devm_cxl_setup_fwctl(cxlmd); | 1021 | rc = devm_cxl_setup_fwctl(&pdev->dev, cxlmd); |
| 1022 | if (rc) | 1022 | if (rc) |
| 1023 | dev_dbg(&pdev->dev, "No CXL FWCTL setup\n"); | 1023 | dev_dbg(&pdev->dev, "No CXL FWCTL setup\n"); |
| 1024 | 1024 | ||
| @@ -108,7 +108,7 @@ static void cxl_nvdimm_arm_dirty_shutdown_tracking(struct cxl_nvdimm *cxl_nvd) · 107 unmodified lines | |||
| 108 | return; | 108 | return; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | if (!cxl_gpf_get_dvsec(cxlds->dev, false)) | 111 | if (!cxl_gpf_get_dvsec(cxlds->dev)) |
| 112 | return; | 112 | return; |
| 113 | 113 | ||
| 114 | if (cxl_get_dirty_count(mds, &count)) { | 114 | if (cxl_get_dirty_count(mds, &count)) { |
| @@ -320,8 +320,9 @@ void dma_resv_add_fence(struct dma_resv *obj, struct dma_fence *fence, · 319 unmodified lines | |||
| 320 | count++; | 320 | count++; |
| 321 | 321 | ||
| 322 | dma_resv_list_set(fobj, i, fence, usage); | 322 | dma_resv_list_set(fobj, i, fence, usage); |
| 323 | /* pointer update must be visible before we extend the num_fences */ | 323 | /* fence update must be visible before we extend the num_fences */ |
| 324 | smp_store_mb(fobj->num_fences, count); | 324 | smp_wmb(); |
| 325 | fobj->num_fences = count; | ||
| 325 | } | 326 | } |
| 326 | EXPORT_SYMBOL(dma_resv_add_fence); | 327 | EXPORT_SYMBOL(dma_resv_add_fence); |
| 327 | 328 | ||
| @@ -438,15 +438,17 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a · 437 unmodified lines | |||
| 438 | return -EINVAL; | 438 | return -EINVAL; |
| 439 | 439 | ||
| 440 | pt = dma_fence_to_sync_pt(fence); | 440 | pt = dma_fence_to_sync_pt(fence); |
| 441 | if (!pt) | 441 | if (!pt) { |
| 442 | return -EINVAL; | 442 | ret = -EINVAL; |
| 443 | goto put_fence; | ||
| 444 | } | ||
| 443 | 445 | ||
| 444 | spin_lock_irqsave(fence->lock, flags); | 446 | spin_lock_irqsave(fence->lock, flags); |
| 445 | if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { | 447 | if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { |
| 446 | data.deadline_ns = ktime_to_ns(pt->deadline); | ||
| 447 | } else { | ||
| 448 | ret = -ENOENT; | 448 | ret = -ENOENT; |
| 449 | goto unlock; | ||
| 449 | } | 450 | } |
| 451 | data.deadline_ns = ktime_to_ns(pt->deadline); | ||
| 450 | spin_unlock_irqrestore(fence->lock, flags); | 452 | spin_unlock_irqrestore(fence->lock, flags); |
| 451 | 453 | ||
| 452 | dma_fence_put(fence); | 454 | dma_fence_put(fence); |
| @@ -458,6 +460,13 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a · 5 unmodified lines | |||
| 458 | return -EFAULT; | 460 | return -EFAULT; |
| 459 | 461 | ||
| 460 | return 0; | 462 | return 0; |
| 463 | |||
| 464 | unlock: | ||
| 465 | spin_unlock_irqrestore(fence->lock, flags); | ||
| 466 | put_fence: | ||
| 467 | dma_fence_put(fence); | ||
| 468 | |||
| 469 | return ret; | ||
| 461 | } | 470 | } |
| 462 | 471 | ||
| 463 | static long sw_sync_ioctl(struct file *file, unsigned int cmd, | 472 | static long sw_sync_ioctl(struct file *file, unsigned int cmd, |
| @@ -393,7 +393,7 @@ static long udmabuf_create(struct miscdevice *device, · 392 unmodified lines | |||
| 393 | if (!ubuf) | 393 | if (!ubuf) |
| 394 | return -ENOMEM; | 394 | return -ENOMEM; |
| 395 | 395 | ||
| 396 | pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; | 396 | pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; |
| 397 | for (i = 0; i < head->count; i++) { | 397 | for (i = 0; i < head->count; i++) { |
| 398 | pgoff_t subpgcnt; | 398 | pgoff_t subpgcnt; |
| 399 | 399 | ||
| @@ -342,6 +342,9 @@ static void pt_cmd_callback_work(void *data, int err) · 341 unmodified lines | |||
| 342 | struct pt_dma_chan *chan; | 342 | struct pt_dma_chan *chan; |
| 343 | unsigned long flags; | 343 | unsigned long flags; |
| 344 | 344 | ||
| 345 | if (!desc) | ||
| 346 | return; | ||
| 347 | |||
| 345 | dma_chan = desc->vd.tx.chan; | 348 | dma_chan = desc->vd.tx.chan; |
| 346 | chan = to_pt_chan(dma_chan); | 349 | chan = to_pt_chan(dma_chan); |
| 347 | 350 | ||
| @@ -355,16 +358,14 @@ static void pt_cmd_callback_work(void *data, int err) · 7 unmodified lines | |||
| 355 | desc->status = DMA_ERROR; | 358 | desc->status = DMA_ERROR; |
| 356 | 359 | ||
| 357 | spin_lock_irqsave(&chan->vc.lock, flags); | 360 | spin_lock_irqsave(&chan->vc.lock, flags); |
| 358 | if (desc) { | 361 | if (desc->status != DMA_COMPLETE) { |
| 359 | if (desc->status != DMA_COMPLETE) { | 362 | if (desc->status != DMA_ERROR) |
| 360 | if (desc->status != DMA_ERROR) | 363 | desc->status = DMA_COMPLETE; |
| 361 | desc->status = DMA_COMPLETE; | ||
| 362 | 364 | ||
| 363 | dma_cookie_complete(tx_desc); | 365 | dma_cookie_complete(tx_desc); |
| 364 | dma_descriptor_unmap(tx_desc); | 366 | dma_descriptor_unmap(tx_desc); |
| 365 | } else { | 367 | } else { |
| 366 | tx_desc = NULL; | 368 | tx_desc = NULL; |
| 367 | } | ||
| 368 | } | 369 | } |
| 369 | spin_unlock_irqrestore(&chan->vc.lock, flags); | 370 | spin_unlock_irqrestore(&chan->vc.lock, flags); |
| 370 | 371 | ||
| @@ -841,9 +841,9 @@ static int dmatest_func(void *data) · 840 unmodified lines | |||
| 841 | } else { | 841 | } else { |
| 842 | dma_async_issue_pending(chan); | 842 | dma_async_issue_pending(chan); |
| 843 | 843 | ||
| 844 | wait_event_timeout(thread->done_wait, | 844 | wait_event_freezable_timeout(thread->done_wait, |
| 845 | done->done, | 845 | done->done, |
| 846 | msecs_to_jiffies(params->timeout)); | 846 | msecs_to_jiffies(params->timeout)); |
| 847 | 847 | ||
| 848 | status = dma_async_is_tx_complete(chan, cookie, NULL, | 848 | status = dma_async_is_tx_complete(chan, cookie, NULL, |
| 849 | NULL); | 849 | NULL); |
| @@ -57,7 +57,7 @@ static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id) · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | intr = edma_readl_chreg(fsl_chan, ch_int); | 58 | intr = edma_readl_chreg(fsl_chan, ch_int); |
| 59 | if (!intr) | 59 | if (!intr) |
| 60 | return IRQ_HANDLED; | 60 | return IRQ_NONE; |
| 61 | 61 | ||
| 62 | edma_writel_chreg(fsl_chan, 1, ch_int); | 62 | edma_writel_chreg(fsl_chan, 1, ch_int); |
| 63 | 63 | ||
| @@ -222,7 +222,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) · 221 unmodified lines | |||
| 222 | struct idxd_wq *wq; | 222 | struct idxd_wq *wq; |
| 223 | struct device *dev, *fdev; | 223 | struct device *dev, *fdev; |
| 224 | int rc = 0; | 224 | int rc = 0; |
| 225 | struct iommu_sva *sva; | 225 | struct iommu_sva *sva = NULL; |
| 226 | unsigned int pasid; | 226 | unsigned int pasid; |
| 227 | struct idxd_cdev *idxd_cdev; | 227 | struct idxd_cdev *idxd_cdev; |
| 228 | 228 | ||
| @@ -317,7 +317,7 @@ failed_set_pasid: · 88 unmodified lines | |||
| 317 | if (device_user_pasid_enabled(idxd)) | 317 | if (device_user_pasid_enabled(idxd)) |
| 318 | idxd_xa_pasid_remove(ctx); | 318 | idxd_xa_pasid_remove(ctx); |
| 319 | failed_get_pasid: | 319 | failed_get_pasid: |
| 320 | if (device_user_pasid_enabled(idxd)) | 320 | if (device_user_pasid_enabled(idxd) && !IS_ERR_OR_NULL(sva)) |
| 321 | iommu_sva_unbind_device(sva); | 321 | iommu_sva_unbind_device(sva); |
| 322 | failed: | 322 | failed: |
| 323 | mutex_unlock(&wq->wq_lock); | 323 | mutex_unlock(&wq->wq_lock); |
| @@ -407,6 +407,9 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma) · 83 unmodified lines | |||
| 407 | if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO)) | 407 | if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO)) |
| 408 | return -EPERM; | 408 | return -EPERM; |
| 409 | 409 | ||
| 410 | if (current->mm != ctx->mm) | ||
| 411 | return -EPERM; | ||
| 412 | |||
| 410 | rc = check_vma(wq, vma, __func__); | 413 | rc = check_vma(wq, vma, __func__); |
| 411 | if (rc < 0) | 414 | if (rc < 0) |
| 412 | return rc; | 415 | return rc; |
| @@ -473,6 +476,9 @@ static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t · 60 unmodified lines | |||
| 473 | ssize_t written = 0; | 476 | ssize_t written = 0; |
| 474 | int i; | 477 | int i; |
| 475 | 478 | ||
| 479 | if (current->mm != ctx->mm) | ||
| 480 | return -EPERM; | ||
| 481 | |||
| 476 | for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) { | 482 | for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) { |
| 477 | int rc = idxd_submit_user_descriptor(ctx, udesc + i); | 483 | int rc = idxd_submit_user_descriptor(ctx, udesc + i); |
| 478 | 484 | ||
| @@ -493,6 +499,9 @@ static __poll_t idxd_cdev_poll(struct file *filp, · 14 unmodified lines | |||
| 493 | struct idxd_device *idxd = wq->idxd; | 499 | struct idxd_device *idxd = wq->idxd; |
| 494 | __poll_t out = 0; | 500 | __poll_t out = 0; |
| 495 | 501 | ||
| 502 | if (current->mm != ctx->mm) | ||
| 503 | return POLLNVAL; | ||
| 504 | |||
| 496 | poll_wait(filp, &wq->err_queue, wait); | 505 | poll_wait(filp, &wq->err_queue, wait); |
| 497 | spin_lock(&idxd->dev_lock); | 506 | spin_lock(&idxd->dev_lock); |
| 498 | if (idxd->sw_err.valid) | 507 | if (idxd->sw_err.valid) |
| @@ -155,6 +155,25 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd) · 154 unmodified lines | |||
| 155 | pci_free_irq_vectors(pdev); | 155 | pci_free_irq_vectors(pdev); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void idxd_clean_wqs(struct idxd_device *idxd) | ||
| 159 | { | ||
| 160 | struct idxd_wq *wq; | ||
| 161 | struct device *conf_dev; | ||
| 162 | int i; | ||
| 163 | |||
| 164 | for (i = 0; i < idxd->max_wqs; i++) { | ||
| 165 | wq = idxd->wqs[i]; | ||
| 166 | if (idxd->hw.wq_cap.op_config) | ||
| 167 | bitmap_free(wq->opcap_bmap); | ||
| 168 | kfree(wq->wqcfg); | ||
| 169 | conf_dev = wq_confdev(wq); | ||
| 170 | put_device(conf_dev); | ||
| 171 | kfree(wq); | ||
| 172 | } | ||
| 173 | bitmap_free(idxd->wq_enable_map); | ||
| 174 | kfree(idxd->wqs); | ||
| 175 | } | ||
| 176 | |||
| 158 | static int idxd_setup_wqs(struct idxd_device *idxd) | 177 | static int idxd_setup_wqs(struct idxd_device *idxd) |
| 159 | { | 178 | { |
| 160 | struct device *dev = &idxd->pdev->dev; | 179 | struct device *dev = &idxd->pdev->dev; |
| @@ -169,8 +188,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 8 unmodified lines | |||
| 169 | 188 | ||
| 170 | idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev)); | 189 | idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev)); |
| 171 | if (!idxd->wq_enable_map) { | 190 | if (!idxd->wq_enable_map) { |
| 172 | kfree(idxd->wqs); | 191 | rc = -ENOMEM; |
| 173 | return -ENOMEM; | 192 | goto err_bitmap; |
| 174 | } | 193 | } |
| 175 | 194 | ||
| 176 | for (i = 0; i < idxd->max_wqs; i++) { | 195 | for (i = 0; i < idxd->max_wqs; i++) { |
| @@ -189,10 +208,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 12 unmodified lines | |||
| 189 | conf_dev->bus = &dsa_bus_type; | 208 | conf_dev->bus = &dsa_bus_type; |
| 190 | conf_dev->type = &idxd_wq_device_type; | 209 | conf_dev->type = &idxd_wq_device_type; |
| 191 | rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id); | 210 | rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id); |
| 192 | if (rc < 0) { | 211 | if (rc < 0) |
| 193 | put_device(conf_dev); | ||
| 194 | goto err; | 212 | goto err; |
| 195 | } | ||
| 196 | 213 | ||
| 197 | mutex_init(&wq->wq_lock); | 214 | mutex_init(&wq->wq_lock); |
| 198 | init_waitqueue_head(&wq->err_queue); | 215 | init_waitqueue_head(&wq->err_queue); |
| @@ -203,7 +220,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 4 unmodified lines | |||
| 203 | wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; | 220 | wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; |
| 204 | wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); | 221 | wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); |
| 205 | if (!wq->wqcfg) { | 222 | if (!wq->wqcfg) { |
| 206 | put_device(conf_dev); | ||
| 207 | rc = -ENOMEM; | 223 | rc = -ENOMEM; |
| 208 | goto err; | 224 | goto err; |
| 209 | } | 225 | } |
| @@ -211,9 +227,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 1 unmodified line | |||
| 211 | if (idxd->hw.wq_cap.op_config) { | 227 | if (idxd->hw.wq_cap.op_config) { |
| 212 | wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL); | 228 | wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL); |
| 213 | if (!wq->opcap_bmap) { | 229 | if (!wq->opcap_bmap) { |
| 214 | put_device(conf_dev); | ||
| 215 | rc = -ENOMEM; | 230 | rc = -ENOMEM; |
| 216 | goto err; | 231 | goto err_opcap_bmap; |
| 217 | } | 232 | } |
| 218 | bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS); | 233 | bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS); |
| 219 | } | 234 | } |
| @@ -224,15 +239,46 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 4 unmodified lines | |||
| 224 | 239 | ||
| 225 | return 0; | 240 | return 0; |
| 226 | 241 | ||
| 227 | err: | 242 | err_opcap_bmap: |
| 243 | kfree(wq->wqcfg); | ||
| 244 | |||
| 245 | err: | ||
| 246 | put_device(conf_dev); | ||
| 247 | kfree(wq); | ||
| 248 | |||
| 228 | while (--i >= 0) { | 249 | while (--i >= 0) { |
| 229 | wq = idxd->wqs[i]; | 250 | wq = idxd->wqs[i]; |
| 251 | if (idxd->hw.wq_cap.op_config) | ||
| 252 | bitmap_free(wq->opcap_bmap); | ||
| 253 | kfree(wq->wqcfg); | ||
| 230 | conf_dev = wq_confdev(wq); | 254 | conf_dev = wq_confdev(wq); |
| 231 | put_device(conf_dev); | 255 | put_device(conf_dev); |
| 256 | kfree(wq); | ||
| 257 | |||
| 232 | } | 258 | } |
| 259 | bitmap_free(idxd->wq_enable_map); | ||
| 260 | |||
| 261 | err_bitmap: | ||
| 262 | kfree(idxd->wqs); | ||
| 263 | |||
| 233 | return rc; | 264 | return rc; |
| 234 | } | 265 | } |
| 235 | 266 | ||
| 267 | static void idxd_clean_engines(struct idxd_device *idxd) | ||
| 268 | { | ||
| 269 | struct idxd_engine *engine; | ||
| 270 | struct device *conf_dev; | ||
| 271 | int i; | ||
| 272 | |||
| 273 | for (i = 0; i < idxd->max_engines; i++) { | ||
| 274 | engine = idxd->engines[i]; | ||
| 275 | conf_dev = engine_confdev(engine); | ||
| 276 | put_device(conf_dev); | ||
| 277 | kfree(engine); | ||
| 278 | } | ||
| 279 | kfree(idxd->engines); | ||
| 280 | } | ||
| 281 | |||
| 236 | static int idxd_setup_engines(struct idxd_device *idxd) | 282 | static int idxd_setup_engines(struct idxd_device *idxd) |
| 237 | { | 283 | { |
| 238 | struct idxd_engine *engine; | 284 | struct idxd_engine *engine; |
| @@ -263,6 +309,7 @@ static int idxd_setup_engines(struct idxd_device *idxd) · 24 unmodified lines | |||
| 263 | rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id); | 309 | rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id); |
| 264 | if (rc < 0) { | 310 | if (rc < 0) { |
| 265 | put_device(conf_dev); | 311 | put_device(conf_dev); |
| 312 | kfree(engine); | ||
| 266 | goto err; | 313 | goto err; |
| 267 | } | 314 | } |
| 268 | 315 | ||
| @@ -276,10 +323,26 @@ static int idxd_setup_engines(struct idxd_device *idxd) · 7 unmodified lines | |||
| 276 | engine = idxd->engines[i]; | 323 | engine = idxd->engines[i]; |
| 277 | conf_dev = engine_confdev(engine); | 324 | conf_dev = engine_confdev(engine); |
| 278 | put_device(conf_dev); | 325 | put_device(conf_dev); |
| 326 | kfree(engine); | ||
| 279 | } | 327 | } |
| 328 | kfree(idxd->engines); | ||
| 329 | |||
| 280 | return rc; | 330 | return rc; |
| 281 | } | 331 | } |
| 282 | 332 | ||
| 333 | static void idxd_clean_groups(struct idxd_device *idxd) | ||
| 334 | { | ||
| 335 | struct idxd_group *group; | ||
| 336 | int i; | ||
| 337 | |||
| 338 | for (i = 0; i < idxd->max_groups; i++) { | ||
| 339 | group = idxd->groups[i]; | ||
| 340 | put_device(group_confdev(group)); | ||
| 341 | kfree(group); | ||
| 342 | } | ||
| 343 | kfree(idxd->groups); | ||
| 344 | } | ||
| 345 | |||
| 283 | static int idxd_setup_groups(struct idxd_device *idxd) | 346 | static int idxd_setup_groups(struct idxd_device *idxd) |
| 284 | { | 347 | { |
| 285 | struct device *dev = &idxd->pdev->dev; | 348 | struct device *dev = &idxd->pdev->dev; |
| @@ -310,6 +373,7 @@ static int idxd_setup_groups(struct idxd_device *idxd) · 24 unmodified lines | |||
| 310 | rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id); | 373 | rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id); |
| 311 | if (rc < 0) { | 374 | if (rc < 0) { |
| 312 | put_device(conf_dev); | 375 | put_device(conf_dev); |
| 376 | kfree(group); | ||
| 313 | goto err; | 377 | goto err; |
| 314 | } | 378 | } |
| 315 | 379 | ||
| @@ -334,20 +398,18 @@ static int idxd_setup_groups(struct idxd_device *idxd) · 18 unmodified lines | |||
| 334 | while (--i >= 0) { | 398 | while (--i >= 0) { |
| 335 | group = idxd->groups[i]; | 399 | group = idxd->groups[i]; |
| 336 | put_device(group_confdev(group)); | 400 | put_device(group_confdev(group)); |
| 401 | kfree(group); | ||
| 337 | } | 402 | } |
| 403 | kfree(idxd->groups); | ||
| 404 | |||
| 338 | return rc; | 405 | return rc; |
| 339 | } | 406 | } |
| 340 | 407 | ||
| 341 | static void idxd_cleanup_internals(struct idxd_device *idxd) | 408 | static void idxd_cleanup_internals(struct idxd_device *idxd) |
| 342 | { | 409 | { |
| 343 | int i; | 410 | idxd_clean_groups(idxd); |
| 344 | 411 | idxd_clean_engines(idxd); | |
| 345 | for (i = 0; i < idxd->max_groups; i++) | 412 | idxd_clean_wqs(idxd); |
| 346 | put_device(group_confdev(idxd->groups[i])); | ||
| 347 | for (i = 0; i < idxd->max_engines; i++) | ||
| 348 | put_device(engine_confdev(idxd->engines[i])); | ||
| 349 | for (i = 0; i < idxd->max_wqs; i++) | ||
| 350 | put_device(wq_confdev(idxd->wqs[i])); | ||
| 351 | destroy_workqueue(idxd->wq); | 413 | destroy_workqueue(idxd->wq); |
| 352 | } | 414 | } |
| 353 | 415 | ||
| @@ -390,7 +452,7 @@ static int idxd_init_evl(struct idxd_device *idxd) · 36 unmodified lines | |||
| 390 | static int idxd_setup_internals(struct idxd_device *idxd) | 452 | static int idxd_setup_internals(struct idxd_device *idxd) |
| 391 | { | 453 | { |
| 392 | struct device *dev = &idxd->pdev->dev; | 454 | struct device *dev = &idxd->pdev->dev; |
| 393 | int rc, i; | 455 | int rc; |
| 394 | 456 | ||
| 395 | init_waitqueue_head(&idxd->cmd_waitq); | 457 | init_waitqueue_head(&idxd->cmd_waitq); |
| 396 | 458 | ||
| @@ -421,14 +483,11 @@ static int idxd_setup_internals(struct idxd_device *idxd) · 24 unmodified lines | |||
| 421 | err_evl: | 483 | err_evl: |
| 422 | destroy_workqueue(idxd->wq); | 484 | destroy_workqueue(idxd->wq); |
| 423 | err_wkq_create: | 485 | err_wkq_create: |
| 424 | for (i = 0; i < idxd->max_groups; i++) | 486 | idxd_clean_groups(idxd); |
| 425 | put_device(group_confdev(idxd->groups[i])); | ||
| 426 | err_group: | 487 | err_group: |
| 427 | for (i = 0; i < idxd->max_engines; i++) | 488 | idxd_clean_engines(idxd); |
| 428 | put_device(engine_confdev(idxd->engines[i])); | ||
| 429 | err_engine: | 489 | err_engine: |
| 430 | for (i = 0; i < idxd->max_wqs; i++) | 490 | idxd_clean_wqs(idxd); |
| 431 | put_device(wq_confdev(idxd->wqs[i])); | ||
| 432 | err_wqs: | 491 | err_wqs: |
| 433 | return rc; | 492 | return rc; |
| 434 | } | 493 | } |
| @@ -528,6 +587,17 @@ static void idxd_read_caps(struct idxd_device *idxd) · 93 unmodified lines | |||
| 528 | idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET); | 587 | idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET); |
| 529 | } | 588 | } |
| 530 | 589 | ||
| 590 | static void idxd_free(struct idxd_device *idxd) | ||
| 591 | { | ||
| 592 | if (!idxd) | ||
| 593 | return; | ||
| 594 | |||
| 595 | put_device(idxd_confdev(idxd)); | ||
| 596 | bitmap_free(idxd->opcap_bmap); | ||
| 597 | ida_free(&idxd_ida, idxd->id); | ||
| 598 | kfree(idxd); | ||
| 599 | } | ||
| 600 | |||
| 531 | static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) | 601 | static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) |
| 532 | { | 602 | { |
| 533 | struct device *dev = &pdev->dev; | 603 | struct device *dev = &pdev->dev; |
| @@ -545,28 +615,34 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d · 11 unmodified lines | |||
| 545 | idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type); | 615 | idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type); |
| 546 | idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL); | 616 | idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL); |
| 547 | if (idxd->id < 0) | 617 | if (idxd->id < 0) |
| 548 | return NULL; | 618 | goto err_ida; |
| 549 | 619 | ||
| 550 | idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev)); | 620 | idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev)); |
| 551 | if (!idxd->opcap_bmap) { | 621 | if (!idxd->opcap_bmap) |
| 552 | ida_free(&idxd_ida, idxd->id); | 622 | goto err_opcap; |
| 553 | return NULL; | ||
| 554 | } | ||
| 555 | 623 | ||
| 556 | device_initialize(conf_dev); | 624 | device_initialize(conf_dev); |
| 557 | conf_dev->parent = dev; | 625 | conf_dev->parent = dev; |
| 558 | conf_dev->bus = &dsa_bus_type; | 626 | conf_dev->bus = &dsa_bus_type; |
| 559 | conf_dev->type = idxd->data->dev_type; | 627 | conf_dev->type = idxd->data->dev_type; |
| 560 | rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id); | 628 | rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id); |
| 561 | if (rc < 0) { | 629 | if (rc < 0) |
| 562 | put_device(conf_dev); | 630 | goto err_name; |
| 563 | return NULL; | ||
| 564 | } | ||
| 565 | 631 | ||
| 566 | spin_lock_init(&idxd->dev_lock); | 632 | spin_lock_init(&idxd->dev_lock); |
| 567 | spin_lock_init(&idxd->cmd_lock); | 633 | spin_lock_init(&idxd->cmd_lock); |
| 568 | 634 | ||
| 569 | return idxd; | 635 | return idxd; |
| 636 | |||
| 637 | err_name: | ||
| 638 | put_device(conf_dev); | ||
| 639 | bitmap_free(idxd->opcap_bmap); | ||
| 640 | err_opcap: | ||
| 641 | ida_free(&idxd_ida, idxd->id); | ||
| 642 | err_ida: | ||
| 643 | kfree(idxd); | ||
| 644 | |||
| 645 | return NULL; | ||
| 570 | } | 646 | } |
| 571 | 647 | ||
| 572 | static int idxd_enable_system_pasid(struct idxd_device *idxd) | 648 | static int idxd_enable_system_pasid(struct idxd_device *idxd) |
| @@ -1190,7 +1266,7 @@ int idxd_pci_probe_alloc(struct idxd_device *idxd, struct pci_dev *pdev, · 617 unmodified lines | |||
| 1190 | err: | 1266 | err: |
| 1191 | pci_iounmap(pdev, idxd->reg_base); | 1267 | pci_iounmap(pdev, idxd->reg_base); |
| 1192 | err_iomap: | 1268 | err_iomap: |
| 1193 | put_device(idxd_confdev(idxd)); | 1269 | idxd_free(idxd); |
| 1194 | err_idxd_alloc: | 1270 | err_idxd_alloc: |
| 1195 | pci_disable_device(pdev); | 1271 | pci_disable_device(pdev); |
| 1196 | return rc; | 1272 | return rc; |
| @@ -1232,7 +1308,6 @@ static void idxd_shutdown(struct pci_dev *pdev) · 35 unmodified lines | |||
| 1232 | static void idxd_remove(struct pci_dev *pdev) | 1308 | static void idxd_remove(struct pci_dev *pdev) |
| 1233 | { | 1309 | { |
| 1234 | struct idxd_device *idxd = pci_get_drvdata(pdev); | 1310 | struct idxd_device *idxd = pci_get_drvdata(pdev); |
| 1235 | struct idxd_irq_entry *irq_entry; | ||
| 1236 | 1311 | ||
| 1237 | idxd_unregister_devices(idxd); | 1312 | idxd_unregister_devices(idxd); |
| 1238 | /* | 1313 | /* |
| @@ -1245,20 +1320,12 @@ static void idxd_remove(struct pci_dev *pdev) · 6 unmodified lines | |||
| 1245 | get_device(idxd_confdev(idxd)); | 1320 | get_device(idxd_confdev(idxd)); |
| 1246 | device_unregister(idxd_confdev(idxd)); | 1321 | device_unregister(idxd_confdev(idxd)); |
| 1247 | idxd_shutdown(pdev); | 1322 | idxd_shutdown(pdev); |
| 1248 | if (device_pasid_enabled(idxd)) | ||
| 1249 | idxd_disable_system_pasid(idxd); | ||
| 1250 | idxd_device_remove_debugfs(idxd); | 1323 | idxd_device_remove_debugfs(idxd); |
| 1251 | 1324 | idxd_cleanup(idxd); | |
| 1252 | irq_entry = idxd_get_ie(idxd, 0); | ||
| 1253 | free_irq(irq_entry->vector, irq_entry); | ||
| 1254 | pci_free_irq_vectors(pdev); | ||
| 1255 | pci_iounmap(pdev, idxd->reg_base); | 1325 | pci_iounmap(pdev, idxd->reg_base); |
| 1256 | if (device_user_pasid_enabled(idxd)) | ||
| 1257 | idxd_disable_sva(pdev); | ||
| 1258 | pci_disable_device(pdev); | ||
| 1259 | destroy_workqueue(idxd->wq); | ||
| 1260 | perfmon_pmu_remove(idxd); | ||
| 1261 | put_device(idxd_confdev(idxd)); | 1326 | put_device(idxd_confdev(idxd)); |
| 1327 | idxd_free(idxd); | ||
| 1328 | pci_disable_device(pdev); | ||
| 1262 | } | 1329 | } |
| 1263 | 1330 | ||
| 1264 | static struct pci_driver idxd_pci_driver = { | 1331 | static struct pci_driver idxd_pci_driver = { |
| @@ -420,15 +420,11 @@ static struct virt_dma_desc *mtk_cqdma_find_active_desc(struct dma_chan *c, · 419 unmodified lines | |||
| 420 | { | 420 | { |
| 421 | struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c); | 421 | struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c); |
| 422 | struct virt_dma_desc *vd; | 422 | struct virt_dma_desc *vd; |
| 423 | unsigned long flags; | ||
| 424 | 423 | ||
| 425 | spin_lock_irqsave(&cvc->pc->lock, flags); | ||
| 426 | list_for_each_entry(vd, &cvc->pc->queue, node) | 424 | list_for_each_entry(vd, &cvc->pc->queue, node) |
| 427 | if (vd->tx.cookie == cookie) { | 425 | if (vd->tx.cookie == cookie) { |
| 428 | spin_unlock_irqrestore(&cvc->pc->lock, flags); | ||
| 429 | return vd; | 426 | return vd; |
| 430 | } | 427 | } |
| 431 | spin_unlock_irqrestore(&cvc->pc->lock, flags); | ||
| 432 | 428 | ||
| 433 | list_for_each_entry(vd, &cvc->vc.desc_issued, node) | 429 | list_for_each_entry(vd, &cvc->vc.desc_issued, node) |
| 434 | if (vd->tx.cookie == cookie) | 430 | if (vd->tx.cookie == cookie) |
| @@ -452,9 +448,11 @@ static enum dma_status mtk_cqdma_tx_status(struct dma_chan *c, · 17 unmodified lines | |||
| 452 | if (ret == DMA_COMPLETE || !txstate) | 448 | if (ret == DMA_COMPLETE || !txstate) |
| 453 | return ret; | 449 | return ret; |
| 454 | 450 | ||
| 451 | spin_lock_irqsave(&cvc->pc->lock, flags); | ||
| 455 | spin_lock_irqsave(&cvc->vc.lock, flags); | 452 | spin_lock_irqsave(&cvc->vc.lock, flags); |
| 456 | vd = mtk_cqdma_find_active_desc(c, cookie); | 453 | vd = mtk_cqdma_find_active_desc(c, cookie); |
| 457 | spin_unlock_irqrestore(&cvc->vc.lock, flags); | 454 | spin_unlock_irqrestore(&cvc->vc.lock, flags); |
| 455 | spin_unlock_irqrestore(&cvc->pc->lock, flags); | ||
| 458 | 456 | ||
| 459 | if (vd) { | 457 | if (vd) { |
| 460 | cvd = to_cqdma_vdesc(vd); | 458 | cvd = to_cqdma_vdesc(vd); |
| @@ -1091,8 +1091,11 @@ static void udma_check_tx_completion(struct work_struct *work) · 1090 unmodified lines | |||
| 1091 | u32 residue_diff; | 1091 | u32 residue_diff; |
| 1092 | ktime_t time_diff; | 1092 | ktime_t time_diff; |
| 1093 | unsigned long delay; | 1093 | unsigned long delay; |
| 1094 | unsigned long flags; | ||
| 1094 | 1095 | ||
| 1095 | while (1) { | 1096 | while (1) { |
| 1097 | spin_lock_irqsave(&uc->vc.lock, flags); | ||
| 1098 | |||
| 1096 | if (uc->desc) { | 1099 | if (uc->desc) { |
| 1097 | /* Get previous residue and time stamp */ | 1100 | /* Get previous residue and time stamp */ |
| 1098 | residue_diff = uc->tx_drain.residue; | 1101 | residue_diff = uc->tx_drain.residue; |
| @@ -1127,6 +1130,8 @@ static void udma_check_tx_completion(struct work_struct *work) · 28 unmodified lines | |||
| 1127 | break; | 1130 | break; |
| 1128 | } | 1131 | } |
| 1129 | 1132 | ||
| 1133 | spin_unlock_irqrestore(&uc->vc.lock, flags); | ||
| 1134 | |||
| 1130 | usleep_range(ktime_to_us(delay), | 1135 | usleep_range(ktime_to_us(delay), |
| 1131 | ktime_to_us(delay) + 10); | 1136 | ktime_to_us(delay) + 10); |
| 1132 | continue; | 1137 | continue; |
| @@ -1143,6 +1148,8 @@ static void udma_check_tx_completion(struct work_struct *work) · 10 unmodified lines | |||
| 1143 | 1148 | ||
| 1144 | break; | 1149 | break; |
| 1145 | } | 1150 | } |
| 1151 | |||
| 1152 | spin_unlock_irqrestore(&uc->vc.lock, flags); | ||
| 1146 | } | 1153 | } |
| 1147 | 1154 | ||
| 1148 | static irqreturn_t udma_ring_irq_handler(int irq, void *data) | 1155 | static irqreturn_t udma_ring_irq_handler(int irq, void *data) |
| @@ -4246,7 +4253,6 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec, · 3097 unmodified lines | |||
| 4246 | struct of_dma *ofdma) | 4253 | struct of_dma *ofdma) |
| 4247 | { | 4254 | { |
| 4248 | struct udma_dev *ud = ofdma->of_dma_data; | 4255 | struct udma_dev *ud = ofdma->of_dma_data; |
| 4249 | dma_cap_mask_t mask = ud->ddev.cap_mask; | ||
| 4250 | struct udma_filter_param filter_param; | 4256 | struct udma_filter_param filter_param; |
| 4251 | struct dma_chan *chan; | 4257 | struct dma_chan *chan; |
| 4252 | 4258 | ||
| @@ -4278,7 +4284,7 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec, · 25 unmodified lines | |||
| 4278 | } | 4284 | } |
| 4279 | } | 4285 | } |
| 4280 | 4286 | ||
| 4281 | chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param, | 4287 | chan = __dma_request_channel(&ud->ddev.cap_mask, udma_dma_filter_fn, &filter_param, |
| 4282 | ofdma->of_node); | 4288 | ofdma->of_node); |
| 4283 | if (!chan) { | 4289 | if (!chan) { |
| 4284 | dev_err(ud->dev, "get channel fail in %s.\n", __func__); | 4290 | dev_err(ud->dev, "get channel fail in %s.\n", __func__); |
| @@ -99,7 +99,7 @@ static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id) · 98 unmodified lines | |||
| 99 | if (status & priv->ecc_stat_ce_mask) { | 99 | if (status & priv->ecc_stat_ce_mask) { |
| 100 | regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, | 100 | regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, |
| 101 | &err_addr); | 101 | &err_addr); |
| 102 | if (priv->ecc_uecnt_offset) | 102 | if (priv->ecc_cecnt_offset) |
| 103 | regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, | 103 | regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, |
| 104 | &err_count); | 104 | &err_count); |
| 105 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count, | 105 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count, |
| @@ -1005,9 +1005,6 @@ altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask, · 899 unmodified lines | |||
| 1005 | } | 1005 | } |
| 1006 | } | 1006 | } |
| 1007 | 1007 | ||
| 1008 | /* Interrupt mode set to every SBERR */ | ||
| 1009 | regmap_write(ecc_mgr_map, ALTR_A10_ECC_INTMODE_OFST, | ||
| 1010 | ALTR_A10_ECC_INTMODE); | ||
| 1011 | /* Enable ECC */ | 1008 | /* Enable ECC */ |
| 1012 | ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base + | 1009 | ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base + |
| 1013 | ALTR_A10_ECC_CTRL_OFST)); | 1010 | ALTR_A10_ECC_CTRL_OFST)); |
| @@ -2127,6 +2124,10 @@ static int altr_edac_a10_probe(struct platform_device *pdev) · 1113 unmodified lines | |||
| 2127 | return PTR_ERR(edac->ecc_mgr_map); | 2124 | return PTR_ERR(edac->ecc_mgr_map); |
| 2128 | } | 2125 | } |
| 2129 | 2126 | ||
| 2127 | /* Set irq mask for DDR SBE to avoid any pending irq before registration */ | ||
| 2128 | regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST, | ||
| 2129 | (A10_SYSMGR_ECC_INTMASK_SDMMCB | A10_SYSMGR_ECC_INTMASK_DDR0)); | ||
| 2130 | |||
| 2130 | edac->irq_chip.name = pdev->dev.of_node->name; | 2131 | edac->irq_chip.name = pdev->dev.of_node->name; |
| 2131 | edac->irq_chip.irq_mask = a10_eccmgr_irq_mask; | 2132 | edac->irq_chip.irq_mask = a10_eccmgr_irq_mask; |
| 2132 | edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask; | 2133 | edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask; |
| @@ -249,6 +249,8 @@ struct altr_sdram_mc_data { · 248 unmodified lines | |||
| 249 | #define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94 | 249 | #define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94 |
| 250 | #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 | 250 | #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 |
| 251 | #define A10_SYSMGR_ECC_INTMASK_OCRAM BIT(1) | 251 | #define A10_SYSMGR_ECC_INTMASK_OCRAM BIT(1) |
| 252 | #define A10_SYSMGR_ECC_INTMASK_SDMMCB BIT(16) | ||
| 253 | #define A10_SYSMGR_ECC_INTMASK_DDR0 BIT(17) | ||
| 252 | 254 | ||
| 253 | #define A10_SYSMGR_ECC_INTSTAT_SERR_OFST 0x9C | 255 | #define A10_SYSMGR_ECC_INTSTAT_SERR_OFST 0x9C |
| 254 | #define A10_SYSMGR_ECC_INTSTAT_DERR_OFST 0xA0 | 256 | #define A10_SYSMGR_ECC_INTSTAT_DERR_OFST 0xA0 |
| @@ -299,7 +299,8 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, · 298 unmodified lines | |||
| 299 | import_uuid(&buf->uuid, (u8 *)&rx_buf->uuid); | 299 | import_uuid(&buf->uuid, (u8 *)&rx_buf->uuid); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | ffa_rx_release(); | 302 | if (!(flags & PARTITION_INFO_GET_RETURN_COUNT_ONLY)) |
| 303 | ffa_rx_release(); | ||
| 303 | 304 | ||
| 304 | mutex_unlock(&drv_info->rx_lock); | 305 | mutex_unlock(&drv_info->rx_lock); |
| 305 | 306 | ||
| @@ -255,6 +255,9 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent, · 254 unmodified lines | |||
| 255 | if (!dev) | 255 | if (!dev) |
| 256 | return NULL; | 256 | return NULL; |
| 257 | 257 | ||
| 258 | /* Drop the refcnt bumped implicitly by device_find_child */ | ||
| 259 | put_device(dev); | ||
| 260 | |||
| 258 | return to_scmi_dev(dev); | 261 | return to_scmi_dev(dev); |
| 259 | } | 262 | } |
| 260 | 263 | ||
| @@ -1248,7 +1248,8 @@ static void xfer_put(const struct scmi_protocol_handle *ph, · 1247 unmodified lines | |||
| 1248 | } | 1248 | } |
| 1249 | 1249 | ||
| 1250 | static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, | 1250 | static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, |
| 1251 | struct scmi_xfer *xfer, ktime_t stop) | 1251 | struct scmi_xfer *xfer, ktime_t stop, |
| 1252 | bool *ooo) | ||
| 1252 | { | 1253 | { |
| 1253 | struct scmi_info *info = handle_to_scmi_info(cinfo->handle); | 1254 | struct scmi_info *info = handle_to_scmi_info(cinfo->handle); |
| 1254 | 1255 | ||
| @@ -1257,7 +1258,7 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, · 2 unmodified lines | |||
| 1257 | * in case of out-of-order receptions of delayed responses | 1258 | * in case of out-of-order receptions of delayed responses |
| 1258 | */ | 1259 | */ |
| 1259 | return info->desc->ops->poll_done(cinfo, xfer) || | 1260 | return info->desc->ops->poll_done(cinfo, xfer) || |
| 1260 | try_wait_for_completion(&xfer->done) || | 1261 | (*ooo = try_wait_for_completion(&xfer->done)) || |
| 1261 | ktime_after(ktime_get(), stop); | 1262 | ktime_after(ktime_get(), stop); |
| 1262 | } | 1263 | } |
| 1263 | 1264 | ||
| @@ -1274,15 +1275,17 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, · 10 unmodified lines | |||
| 1274 | * itself to support synchronous commands replies. | 1275 | * itself to support synchronous commands replies. |
| 1275 | */ | 1276 | */ |
| 1276 | if (!desc->sync_cmds_completed_on_ret) { | 1277 | if (!desc->sync_cmds_completed_on_ret) { |
| 1278 | bool ooo = false; | ||
| 1279 | |||
| 1277 | /* | 1280 | /* |
| 1278 | * Poll on xfer using transport provided .poll_done(); | 1281 | * Poll on xfer using transport provided .poll_done(); |
| 1279 | * assumes no completion interrupt was available. | 1282 | * assumes no completion interrupt was available. |
| 1280 | */ | 1283 | */ |
| 1281 | ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); | 1284 | ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); |
| 1282 | 1285 | ||
| 1283 | spin_until_cond(scmi_xfer_done_no_timeout(cinfo, | 1286 | spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, |
| 1284 | xfer, stop)); | 1287 | stop, &ooo)); |
| 1285 | if (ktime_after(ktime_get(), stop)) { | 1288 | if (!ooo && !info->desc->ops->poll_done(cinfo, xfer)) { |
| 1286 | dev_err(dev, | 1289 | dev_err(dev, |
| 1287 | "timed out in resp(caller: %pS) - polling\n", | 1290 | "timed out in resp(caller: %pS) - polling\n", |
| 1288 | (void *)_RET_IP_); | 1291 | (void *)_RET_IP_); |
| @@ -6,14 +6,11 @@ config FW_CS_DSP · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | config FW_CS_DSP_KUNIT_TEST_UTILS | 7 | config FW_CS_DSP_KUNIT_TEST_UTILS |
| 8 | tristate | 8 | tristate |
| 9 | depends on KUNIT && REGMAP | ||
| 10 | select FW_CS_DSP | ||
| 11 | 9 | ||
| 12 | config FW_CS_DSP_KUNIT_TEST | 10 | config FW_CS_DSP_KUNIT_TEST |
| 13 | tristate "KUnit tests for Cirrus Logic cs_dsp" if !KUNIT_ALL_TESTS | 11 | tristate "KUnit tests for Cirrus Logic cs_dsp" if !KUNIT_ALL_TESTS |
| 14 | depends on KUNIT && REGMAP | 12 | depends on KUNIT && REGMAP && FW_CS_DSP |
| 15 | default KUNIT_ALL_TESTS | 13 | default KUNIT_ALL_TESTS |
| 16 | select FW_CS_DSP | ||
| 17 | select FW_CS_DSP_KUNIT_TEST_UTILS | 14 | select FW_CS_DSP_KUNIT_TEST_UTILS |
| 18 | help | 15 | help |
| 19 | This builds KUnit tests for cs_dsp. | 16 | This builds KUnit tests for cs_dsp. |
| @@ -461,36 +461,6 @@ unsigned int cs_dsp_mock_xm_header_get_alg_base_in_words(struct cs_dsp_test *pri · 460 unmodified lines | |||
| 461 | } | 461 | } |
| 462 | EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_alg_base_in_words, "FW_CS_DSP_KUNIT_TEST_UTILS"); | 462 | EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_alg_base_in_words, "FW_CS_DSP_KUNIT_TEST_UTILS"); |
| 463 | 463 | ||
| 464 | /** | ||
| 465 | * cs_dsp_mock_xm_header_get_fw_version_from_regmap() - Firmware version. | ||
| 466 | * | ||
| 467 | * @priv: Pointer to struct cs_dsp_test. | ||
| 468 | * | ||
| 469 | * Return: Firmware version word value. | ||
| 470 | */ | ||
| 471 | unsigned int cs_dsp_mock_xm_header_get_fw_version_from_regmap(struct cs_dsp_test *priv) | ||
| 472 | { | ||
| 473 | unsigned int xm = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM); | ||
| 474 | union { | ||
| 475 | struct wmfw_id_hdr adsp2; | ||
| 476 | struct wmfw_v3_id_hdr halo; | ||
| 477 | } hdr; | ||
| 478 | |||
| 479 | switch (priv->dsp->type) { | ||
| 480 | case WMFW_ADSP2: | ||
| 481 | regmap_raw_read(priv->dsp->regmap, xm, &hdr.adsp2, sizeof(hdr.adsp2)); | ||
| 482 | return be32_to_cpu(hdr.adsp2.ver); | ||
| 483 | case WMFW_HALO: | ||
| 484 | regmap_raw_read(priv->dsp->regmap, xm, &hdr.halo, sizeof(hdr.halo)); | ||
| 485 | return be32_to_cpu(hdr.halo.ver); | ||
| 486 | default: | ||
| 487 | KUNIT_FAIL(priv->test, NULL); | ||
| 488 | return 0; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_fw_version_from_regmap, | ||
| 492 | "FW_CS_DSP_KUNIT_TEST_UTILS"); | ||
| 493 | |||
| 494 | /** | 464 | /** |
| 495 | * cs_dsp_mock_xm_header_get_fw_version() - Firmware version. | 465 | * cs_dsp_mock_xm_header_get_fw_version() - Firmware version. |
| 496 | * | 466 | * |
| @@ -2198,7 +2198,7 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp) · 2197 unmodified lines | |||
| 2198 | 2198 | ||
| 2199 | priv->local->bin_builder = | 2199 | priv->local->bin_builder = |
| 2200 | cs_dsp_mock_bin_init(priv, 1, | 2200 | cs_dsp_mock_bin_init(priv, 1, |
| 2201 | cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv)); | 2201 | cs_dsp_mock_xm_header_get_fw_version(xm_hdr)); |
| 2202 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder); | 2202 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder); |
| 2203 | 2203 | ||
| 2204 | /* We must provide a dummy wmfw to load */ | 2204 | /* 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 · 450 unmodified lines | |||
| 451 | 451 | ||
| 452 | local->bin_builder = | 452 | local->bin_builder = |
| 453 | cs_dsp_mock_bin_init(priv, 1, | 453 | cs_dsp_mock_bin_init(priv, 1, |
| 454 | cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv)); | 454 | cs_dsp_mock_xm_header_get_fw_version(local->xm_header)); |
| 455 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->bin_builder); | 455 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->bin_builder); |
| 456 | 456 | ||
| 457 | /* Init cs_dsp */ | 457 | /* Init cs_dsp */ |
| @@ -184,6 +184,29 @@ struct acpm_match_data { · 183 unmodified lines | |||
| 184 | #define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl) | 184 | #define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl) |
| 185 | #define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle) | 185 | #define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle) |
| 186 | 186 | ||
| 187 | /** | ||
| 188 | * acpm_get_saved_rx() - get the response if it was already saved. | ||
| 189 | * @achan: ACPM channel info. | ||
| 190 | * @xfer: reference to the transfer to get response for. | ||
| 191 | * @tx_seqnum: xfer TX sequence number. | ||
| 192 | */ | ||
| 193 | static void acpm_get_saved_rx(struct acpm_chan *achan, | ||
| 194 | const struct acpm_xfer *xfer, u32 tx_seqnum) | ||
| 195 | { | ||
| 196 | const struct acpm_rx_data *rx_data = &achan->rx_data[tx_seqnum - 1]; | ||
| 197 | u32 rx_seqnum; | ||
| 198 | |||
| 199 | if (!rx_data->response) | ||
| 200 | return; | ||
| 201 | |||
| 202 | rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]); | ||
| 203 | |||
| 204 | if (rx_seqnum == tx_seqnum) { | ||
| 205 | memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen); | ||
| 206 | clear_bit(rx_seqnum - 1, achan->bitmap_seqnum); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 187 | /** | 210 | /** |
| 188 | * acpm_get_rx() - get response from RX queue. | 211 | * acpm_get_rx() - get response from RX queue. |
| 189 | * @achan: ACPM channel info. | 212 | * @achan: ACPM channel info. |
| @@ -204,15 +227,16 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) · 14 unmodified lines | |||
| 204 | rx_front = readl(achan->rx.front); | 227 | rx_front = readl(achan->rx.front); |
| 205 | i = readl(achan->rx.rear); | 228 | i = readl(achan->rx.rear); |
| 206 | 229 | ||
| 207 | /* Bail out if RX is empty. */ | 230 | tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]); |
| 208 | if (i == rx_front) | 231 | |
| 232 | if (i == rx_front) { | ||
| 233 | acpm_get_saved_rx(achan, xfer, tx_seqnum); | ||
| 209 | return 0; | 234 | return 0; |
| 235 | } | ||
| 210 | 236 | ||
| 211 | base = achan->rx.base; | 237 | base = achan->rx.base; |
| 212 | mlen = achan->mlen; | 238 | mlen = achan->mlen; |
| 213 | 239 | ||
| 214 | tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]); | ||
| 215 | |||
| 216 | /* Drain RX queue. */ | 240 | /* Drain RX queue. */ |
| 217 | do { | 241 | do { |
| 218 | /* Read RX seqnum. */ | 242 | /* Read RX seqnum. */ |
| @@ -259,16 +283,8 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) · 40 unmodified lines | |||
| 259 | * If the response was not in this iteration of the queue, check if the | 283 | * If the response was not in this iteration of the queue, check if the |
| 260 | * RX data was previously saved. | 284 | * RX data was previously saved. |
| 261 | */ | 285 | */ |
| 262 | rx_data = &achan->rx_data[tx_seqnum - 1]; | 286 | if (!rx_set) |
| 263 | if (!rx_set && rx_data->response) { | 287 | acpm_get_saved_rx(achan, xfer, tx_seqnum); |
| 264 | rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, | ||
| 265 | rx_data->cmd[0]); | ||
| 266 | |||
| 267 | if (rx_seqnum == tx_seqnum) { | ||
| 268 | memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen); | ||
| 269 | clear_bit(rx_seqnum - 1, achan->bitmap_seqnum); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | 288 | ||
| 273 | return 0; | 289 | return 0; |
| 274 | } | 290 | } |
| @@ -95,7 +95,7 @@ void __init kvm_arm_target_impl_cpu_init(void) · 94 unmodified lines | |||
| 95 | 95 | ||
| 96 | for (i = 0; i < max_cpus; i++) { | 96 | for (i = 0; i < max_cpus; i++) { |
| 97 | arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID, | 97 | arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID, |
| 98 | i, &res); | 98 | i, 0, 0, &res); |
| 99 | if (res.a0 != SMCCC_RET_SUCCESS) { | 99 | if (res.a0 != SMCCC_RET_SUCCESS) { |
| 100 | pr_warn("Discovering target implementation CPUs failed\n"); | 100 | pr_warn("Discovering target implementation CPUs failed\n"); |
| 101 | goto mem_free; | 101 | goto mem_free; |
| @@ -103,7 +103,7 @@ void __init kvm_arm_target_impl_cpu_init(void) · 1 unmodified line | |||
| 103 | target[i].midr = res.a1; | 103 | target[i].midr = res.a1; |
| 104 | target[i].revidr = res.a2; | 104 | target[i].revidr = res.a2; |
| 105 | target[i].aidr = res.a3; | 105 | target[i].aidr = res.a3; |
| 106 | }; | 106 | } |
| 107 | 107 | ||
| 108 | if (!cpu_errata_set_target_impl(max_cpus, target)) { | 108 | if (!cpu_errata_set_target_impl(max_cpus, target)) { |
| 109 | pr_warn("Failed to set target implementation CPUs\n"); | 109 | pr_warn("Failed to set target implementation CPUs\n"); |
| @@ -1224,22 +1224,28 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) · 1223 unmodified lines | |||
| 1224 | if (!svc->intel_svc_fcs) { | 1224 | if (!svc->intel_svc_fcs) { |
| 1225 | dev_err(dev, "failed to allocate %s device\n", INTEL_FCS); | 1225 | dev_err(dev, "failed to allocate %s device\n", INTEL_FCS); |
| 1226 | ret = -ENOMEM; | 1226 | ret = -ENOMEM; |
| 1227 | goto err_unregister_dev; | 1227 | goto err_unregister_rsu_dev; |
| 1228 | } | 1228 | } |
| 1229 | 1229 | ||
| 1230 | ret = platform_device_add(svc->intel_svc_fcs); | 1230 | ret = platform_device_add(svc->intel_svc_fcs); |
| 1231 | if (ret) { | 1231 | if (ret) { |
| 1232 | platform_device_put(svc->intel_svc_fcs); | 1232 | platform_device_put(svc->intel_svc_fcs); |
| 1233 | goto err_unregister_dev; | 1233 | goto err_unregister_rsu_dev; |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | ret = of_platform_default_populate(dev_of_node(dev), NULL, dev); | ||
| 1237 | if (ret) | ||
| 1238 | goto err_unregister_fcs_dev; | ||
| 1239 | |||
| 1236 | dev_set_drvdata(dev, svc); | 1240 | dev_set_drvdata(dev, svc); |
| 1237 | 1241 | ||
| 1238 | pr_info("Intel Service Layer Driver Initialized\n"); | 1242 | pr_info("Intel Service Layer Driver Initialized\n"); |
| 1239 | 1243 | ||
| 1240 | return 0; | 1244 | return 0; |
| 1241 | 1245 | ||
| 1242 | err_unregister_dev: | 1246 | err_unregister_fcs_dev: |
| 1247 | platform_device_unregister(svc->intel_svc_fcs); | ||
| 1248 | err_unregister_rsu_dev: | ||
| 1243 | platform_device_unregister(svc->stratix10_svc_rsu); | 1249 | platform_device_unregister(svc->stratix10_svc_rsu); |
| 1244 | err_free_kfifo: | 1250 | err_free_kfifo: |
| 1245 | kfifo_free(&controller->svc_fifo); | 1251 | kfifo_free(&controller->svc_fifo); |
| @@ -1253,6 +1259,8 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev) · 7 unmodified lines | |||
| 1253 | struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); | 1259 | struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); |
| 1254 | struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev); | 1260 | struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev); |
| 1255 | 1261 | ||
| 1262 | of_platform_depopulate(ctrl->dev); | ||
| 1263 | |||
| 1256 | platform_device_unregister(svc->intel_svc_fcs); | 1264 | platform_device_unregister(svc->intel_svc_fcs); |
| 1257 | platform_device_unregister(svc->stratix10_svc_rsu); | 1265 | platform_device_unregister(svc->stratix10_svc_rsu); |
| 1258 | 1266 | ||
| @@ -170,4 +170,5 @@ static struct kunit_suite fpga_bridge_suite = { · 169 unmodified lines | |||
| 170 | 170 | ||
| 171 | kunit_test_suite(fpga_bridge_suite); | 171 | kunit_test_suite(fpga_bridge_suite); |
| 172 | 172 | ||
| 173 | MODULE_DESCRIPTION("KUnit test for the FPGA Bridge"); | ||
| 173 | MODULE_LICENSE("GPL"); | 174 | MODULE_LICENSE("GPL"); |
| @@ -330,4 +330,5 @@ static struct kunit_suite fpga_mgr_suite = { · 329 unmodified lines | |||
| 330 | 330 | ||
| 331 | kunit_test_suite(fpga_mgr_suite); | 331 | kunit_test_suite(fpga_mgr_suite); |
| 332 | 332 | ||
| 333 | MODULE_DESCRIPTION("KUnit test for the FPGA Manager"); | ||
| 333 | MODULE_LICENSE("GPL"); | 334 | MODULE_LICENSE("GPL"); |
| @@ -214,4 +214,5 @@ static struct kunit_suite fpga_region_suite = { · 213 unmodified lines | |||
| 214 | 214 | ||
| 215 | kunit_test_suite(fpga_region_suite); | 215 | kunit_test_suite(fpga_region_suite); |
| 216 | 216 | ||
| 217 | MODULE_DESCRIPTION("KUnit test for the FPGA Region"); | ||
| 217 | MODULE_LICENSE("GPL"); | 218 | MODULE_LICENSE("GPL"); |
| @@ -105,7 +105,7 @@ static int fwctl_cmd_rpc(struct fwctl_ucmd *ucmd) · 104 unmodified lines | |||
| 105 | if (!test_and_set_bit(0, &fwctl_tainted)) { | 105 | if (!test_and_set_bit(0, &fwctl_tainted)) { |
| 106 | dev_warn( | 106 | dev_warn( |
| 107 | &fwctl->dev, | 107 | &fwctl->dev, |
| 108 | "%s(%d): has requested full access to the physical device device", | 108 | "%s(%d): has requested full access to the physical device", |
| 109 | current->comm, task_pid_nr(current)); | 109 | current->comm, task_pid_nr(current)); |
| 110 | add_taint(TAINT_FWCTL, LOCKDEP_STILL_OK); | 110 | add_taint(TAINT_FWCTL, LOCKDEP_STILL_OK); |
| 111 | } | 111 | } |
| @@ -105,12 +105,14 @@ static int pdsfc_identify(struct pdsfc_dev *pdsfc) · 104 unmodified lines | |||
| 105 | static void pdsfc_free_endpoints(struct pdsfc_dev *pdsfc) | 105 | static void pdsfc_free_endpoints(struct pdsfc_dev *pdsfc) |
| 106 | { | 106 | { |
| 107 | struct device *dev = &pdsfc->fwctl.dev; | 107 | struct device *dev = &pdsfc->fwctl.dev; |
| 108 | u32 num_endpoints; | ||
| 108 | int i; | 109 | int i; |
| 109 | 110 | ||
| 110 | if (!pdsfc->endpoints) | 111 | if (!pdsfc->endpoints) |
| 111 | return; | 112 | return; |
| 112 | 113 | ||
| 113 | for (i = 0; pdsfc->endpoint_info && i < pdsfc->endpoints->num_entries; i++) | 114 | num_endpoints = le32_to_cpu(pdsfc->endpoints->num_entries); |
| 115 | for (i = 0; pdsfc->endpoint_info && i < num_endpoints; i++) | ||
| 114 | mutex_destroy(&pdsfc->endpoint_info[i].lock); | 116 | mutex_destroy(&pdsfc->endpoint_info[i].lock); |
| 115 | vfree(pdsfc->endpoint_info); | 117 | vfree(pdsfc->endpoint_info); |
| 116 | pdsfc->endpoint_info = NULL; | 118 | pdsfc->endpoint_info = NULL; |
| @@ -199,7 +201,7 @@ static int pdsfc_init_endpoints(struct pdsfc_dev *pdsfc) · 82 unmodified lines | |||
| 199 | ep_entry = (struct pds_fwctl_query_data_endpoint *)pdsfc->endpoints->entries; | 201 | ep_entry = (struct pds_fwctl_query_data_endpoint *)pdsfc->endpoints->entries; |
| 200 | for (i = 0; i < num_endpoints; i++) { | 202 | for (i = 0; i < num_endpoints; i++) { |
| 201 | mutex_init(&pdsfc->endpoint_info[i].lock); | 203 | mutex_init(&pdsfc->endpoint_info[i].lock); |
| 202 | pdsfc->endpoint_info[i].endpoint = ep_entry[i].id; | 204 | pdsfc->endpoint_info[i].endpoint = le32_to_cpu(ep_entry[i].id); |
| 203 | } | 205 | } |
| 204 | 206 | ||
| 205 | return 0; | 207 | return 0; |
| @@ -214,6 +216,7 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc · 8 unmodified lines | |||
| 214 | struct pds_fwctl_query_data *data; | 216 | struct pds_fwctl_query_data *data; |
| 215 | union pds_core_adminq_cmd cmd; | 217 | union pds_core_adminq_cmd cmd; |
| 216 | dma_addr_t data_pa; | 218 | dma_addr_t data_pa; |
| 219 | u32 num_entries; | ||
| 217 | int err; | 220 | int err; |
| 218 | int i; | 221 | int i; |
| 219 | 222 | ||
| @@ -246,8 +249,9 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc · 26 unmodified lines | |||
| 246 | *pa = data_pa; | 249 | *pa = data_pa; |
| 247 | 250 | ||
| 248 | entries = (struct pds_fwctl_query_data_operation *)data->entries; | 251 | entries = (struct pds_fwctl_query_data_operation *)data->entries; |
| 249 | dev_dbg(dev, "num_entries %d\n", data->num_entries); | 252 | num_entries = le32_to_cpu(data->num_entries); |
| 250 | for (i = 0; i < data->num_entries; i++) { | 253 | dev_dbg(dev, "num_entries %d\n", num_entries); |
| 254 | for (i = 0; i < num_entries; i++) { | ||
| 251 | 255 | ||
| 252 | /* Translate FW command attribute to fwctl scope */ | 256 | /* Translate FW command attribute to fwctl scope */ |
| 253 | switch (entries[i].scope) { | 257 | switch (entries[i].scope) { |
| @@ -267,7 +271,7 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc · 13 unmodified lines | |||
| 267 | break; | 271 | break; |
| 268 | } | 272 | } |
| 269 | dev_dbg(dev, "endpoint %d operation: id %x scope %d\n", | 273 | dev_dbg(dev, "endpoint %d operation: id %x scope %d\n", |
| 270 | ep, entries[i].id, entries[i].scope); | 274 | ep, le32_to_cpu(entries[i].id), entries[i].scope); |
| 271 | } | 275 | } |
| 272 | 276 | ||
| 273 | return data; | 277 | return data; |
| @@ -280,24 +284,26 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc, · 6 unmodified lines | |||
| 280 | struct pds_fwctl_query_data_operation *op_entry; | 284 | struct pds_fwctl_query_data_operation *op_entry; |
| 281 | struct pdsfc_rpc_endpoint_info *ep_info = NULL; | 285 | struct pdsfc_rpc_endpoint_info *ep_info = NULL; |
| 282 | struct device *dev = &pdsfc->fwctl.dev; | 286 | struct device *dev = &pdsfc->fwctl.dev; |
| 287 | u32 num_entries; | ||
| 283 | int i; | 288 | int i; |
| 284 | 289 | ||
| 285 | /* validate rpc in_len & out_len based | 290 | /* validate rpc in_len & out_len based |
| 286 | * on ident.max_req_sz & max_resp_sz | 291 | * on ident.max_req_sz & max_resp_sz |
| 287 | */ | 292 | */ |
| 288 | if (rpc->in.len > pdsfc->ident.max_req_sz) { | 293 | if (rpc->in.len > le32_to_cpu(pdsfc->ident.max_req_sz)) { |
| 289 | dev_dbg(dev, "Invalid request size %u, max %u\n", | 294 | dev_dbg(dev, "Invalid request size %u, max %u\n", |
| 290 | rpc->in.len, pdsfc->ident.max_req_sz); | 295 | rpc->in.len, le32_to_cpu(pdsfc->ident.max_req_sz)); |
| 291 | return -EINVAL; | 296 | return -EINVAL; |
| 292 | } | 297 | } |
| 293 | 298 | ||
| 294 | if (rpc->out.len > pdsfc->ident.max_resp_sz) { | 299 | if (rpc->out.len > le32_to_cpu(pdsfc->ident.max_resp_sz)) { |
| 295 | dev_dbg(dev, "Invalid response size %u, max %u\n", | 300 | dev_dbg(dev, "Invalid response size %u, max %u\n", |
| 296 | rpc->out.len, pdsfc->ident.max_resp_sz); | 301 | rpc->out.len, le32_to_cpu(pdsfc->ident.max_resp_sz)); |
| 297 | return -EINVAL; | 302 | return -EINVAL; |
| 298 | } | 303 | } |
| 299 | 304 | ||
| 300 | for (i = 0; i < pdsfc->endpoints->num_entries; i++) { | 305 | num_entries = le32_to_cpu(pdsfc->endpoints->num_entries); |
| 306 | for (i = 0; i < num_entries; i++) { | ||
| 301 | if (pdsfc->endpoint_info[i].endpoint == rpc->in.ep) { | 307 | if (pdsfc->endpoint_info[i].endpoint == rpc->in.ep) { |
| 302 | ep_info = &pdsfc->endpoint_info[i]; | 308 | ep_info = &pdsfc->endpoint_info[i]; |
| 303 | break; | 309 | break; |
| @@ -326,8 +332,9 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc, · 22 unmodified lines | |||
| 326 | 332 | ||
| 327 | /* reject unsupported and/or out of scope commands */ | 333 | /* reject unsupported and/or out of scope commands */ |
| 328 | op_entry = (struct pds_fwctl_query_data_operation *)ep_info->operations->entries; | 334 | op_entry = (struct pds_fwctl_query_data_operation *)ep_info->operations->entries; |
| 329 | for (i = 0; i < ep_info->operations->num_entries; i++) { | 335 | num_entries = le32_to_cpu(ep_info->operations->num_entries); |
| 330 | if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, op_entry[i].id)) { | 336 | for (i = 0; i < num_entries; i++) { |
| 337 | if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, le32_to_cpu(op_entry[i].id))) { | ||
| 331 | if (scope < op_entry[i].scope) | 338 | if (scope < op_entry[i].scope) |
| 332 | return -EPERM; | 339 | return -EPERM; |
| 333 | return 0; | 340 | return 0; |
| @@ -402,7 +409,7 @@ static void *pdsfc_fw_rpc(struct fwctl_uctx *uctx, enum fwctl_rpc_scope scope, · 68 unmodified lines | |||
| 402 | cmd = (union pds_core_adminq_cmd) { | 409 | cmd = (union pds_core_adminq_cmd) { |
| 403 | .fwctl_rpc = { | 410 | .fwctl_rpc = { |
| 404 | .opcode = PDS_FWCTL_CMD_RPC, | 411 | .opcode = PDS_FWCTL_CMD_RPC, |
| 405 | .flags = PDS_FWCTL_RPC_IND_REQ | PDS_FWCTL_RPC_IND_RESP, | 412 | .flags = cpu_to_le16(PDS_FWCTL_RPC_IND_REQ | PDS_FWCTL_RPC_IND_RESP), |
| 406 | .ep = cpu_to_le32(rpc->in.ep), | 413 | .ep = cpu_to_le32(rpc->in.ep), |
| 407 | .op = cpu_to_le32(rpc->in.op), | 414 | .op = cpu_to_le32(rpc->in.op), |
| 408 | .req_pa = cpu_to_le64(in_payload_dma_addr), | 415 | .req_pa = cpu_to_le64(in_payload_dma_addr), |
| @@ -186,3 +186,37 @@ their hardware offsets within the chip. · 185 unmodified lines | |||
| 186 | 186 | ||
| 187 | Encourage users to switch to using them and eventually remove the existing | 187 | Encourage users to switch to using them and eventually remove the existing |
| 188 | global export/unexport attribues. | 188 | global export/unexport attribues. |
| 189 | |||
| 190 | ------------------------------------------------------------------------------- | ||
| 191 | |||
| 192 | Remove GPIOD_FLAGS_BIT_NONEXCLUSIVE | ||
| 193 | |||
| 194 | GPIOs in the linux kernel are meant to be an exclusive resource. This means | ||
| 195 | that the GPIO descriptors (the software representation of the hardware concept) | ||
| 196 | are not reference counted and - in general - only one user at a time can | ||
| 197 | request a GPIO line and control its settings. The consumer API is designed | ||
| 198 | around full control of the line's state as evidenced by the fact that, for | ||
| 199 | instance, gpiod_set_value() does indeed drive the line as requested, instead | ||
| 200 | of bumping an enable counter of some sort. | ||
| 201 | |||
| 202 | A problematic use-case for GPIOs is when two consumers want to use the same | ||
| 203 | descriptor independently. An example of such a user is the regulator subsystem | ||
| 204 | which may instantiate several struct regulator_dev instances containing | ||
| 205 | a struct device but using the same enable GPIO line. | ||
| 206 | |||
| 207 | A workaround was introduced in the form of the GPIOD_FLAGS_BIT_NONEXCLUSIVE | ||
| 208 | flag but its implementation is problematic: it does not provide any | ||
| 209 | synchronization of usage nor did it introduce any enable count meaning the | ||
| 210 | non-exclusive users of the same descriptor will in fact "fight" for the | ||
| 211 | control over it. This flag should be removed and replaced with a better | ||
| 212 | solution, possibly based on the new power sequencing subsystem. | ||
| 213 | |||
| 214 | ------------------------------------------------------------------------------- | ||
| 215 | |||
| 216 | Remove devm_gpiod_unhinge() | ||
| 217 | |||
| 218 | devm_gpiod_unhinge() is provided as a way to transfer the ownership of managed | ||
| 219 | enable GPIOs to the regulator core. Rather than doing that however, we should | ||
| 220 | make it possible for the regulator subsystem to deal with GPIO resources the | ||
| 221 | lifetime of which it doesn't control as logically, a GPIO obtained by a caller | ||
| 222 | should also be freed by it. | ||
| @@ -410,7 +410,9 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 409 unmodified lines | |||
| 410 | goto err; | 410 | goto err; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | device_init_wakeup(dev, true); | 413 | ret = devm_device_init_wakeup(dev); |
| 414 | if (ret) | ||
| 415 | return dev_err_probe(dev, ret, "Failed to init wakeup\n"); | ||
| 414 | 416 | ||
| 415 | return 0; | 417 | return 0; |
| 416 | err: | 418 | err: |
| @@ -1204,6 +1204,8 @@ static int pca953x_restore_context(struct pca953x_chip *chip) · 1203 unmodified lines | |||
| 1204 | 1204 | ||
| 1205 | guard(mutex)(&chip->i2c_lock); | 1205 | guard(mutex)(&chip->i2c_lock); |
| 1206 | 1206 | ||
| 1207 | if (chip->client->irq > 0) | ||
| 1208 | enable_irq(chip->client->irq); | ||
| 1207 | regcache_cache_only(chip->regmap, false); | 1209 | regcache_cache_only(chip->regmap, false); |
| 1208 | regcache_mark_dirty(chip->regmap); | 1210 | regcache_mark_dirty(chip->regmap); |
| 1209 | ret = pca953x_regcache_sync(chip); | 1211 | ret = pca953x_regcache_sync(chip); |
| @@ -1216,6 +1218,10 @@ static int pca953x_restore_context(struct pca953x_chip *chip) · 6 unmodified lines | |||
| 1216 | static void pca953x_save_context(struct pca953x_chip *chip) | 1218 | static void pca953x_save_context(struct pca953x_chip *chip) |
| 1217 | { | 1219 | { |
| 1218 | guard(mutex)(&chip->i2c_lock); | 1220 | guard(mutex)(&chip->i2c_lock); |
| 1221 | |||
| 1222 | /* Disable IRQ to prevent early triggering while regmap "cache only" is on */ | ||
| 1223 | if (chip->client->irq > 0) | ||
| 1224 | disable_irq(chip->client->irq); | ||
| 1219 | regcache_cache_only(chip->regmap, true); | 1225 | regcache_cache_only(chip->regmap, true); |
| 1220 | } | 1226 | } |
| 1221 | 1227 | ||
| @@ -823,6 +823,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) · 822 unmodified lines | |||
| 823 | struct gpio_irq_chip *irq; | 823 | struct gpio_irq_chip *irq; |
| 824 | struct tegra_gpio *gpio; | 824 | struct tegra_gpio *gpio; |
| 825 | struct device_node *np; | 825 | struct device_node *np; |
| 826 | struct resource *res; | ||
| 826 | char **names; | 827 | char **names; |
| 827 | int err; | 828 | int err; |
| 828 | 829 | ||
| @@ -842,19 +843,19 @@ static int tegra186_gpio_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 842 | gpio->num_banks++; | 843 | gpio->num_banks++; |
| 843 | 844 | ||
| 844 | /* get register apertures */ | 845 | /* get register apertures */ |
| 845 | gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); | 846 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "security"); |
| 846 | if (IS_ERR(gpio->secure)) { | 847 | if (!res) |
| 847 | gpio->secure = devm_platform_ioremap_resource(pdev, 0); | 848 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 848 | if (IS_ERR(gpio->secure)) | 849 | gpio->secure = devm_ioremap_resource(&pdev->dev, res); |
| 849 | return PTR_ERR(gpio->secure); | 850 | if (IS_ERR(gpio->secure)) |
| 850 | } | 851 | return PTR_ERR(gpio->secure); |
| 851 | 852 | ||
| 852 | gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); | 853 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio"); |
| 853 | if (IS_ERR(gpio->base)) { | 854 | if (!res) |
| 854 | gpio->base = devm_platform_ioremap_resource(pdev, 1); | 855 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 855 | if (IS_ERR(gpio->base)) | 856 | gpio->base = devm_ioremap_resource(&pdev->dev, res); |
| 856 | return PTR_ERR(gpio->base); | 857 | if (IS_ERR(gpio->base)) |
| 857 | } | 858 | return PTR_ERR(gpio->base); |
| 858 | 859 | ||
| 859 | err = platform_irq_count(pdev); | 860 | err = platform_irq_count(pdev); |
| 860 | if (err < 0) | 861 | if (err < 0) |
| @@ -401,10 +401,15 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file, · 400 unmodified lines | |||
| 401 | char buf[32], *trimmed; | 401 | char buf[32], *trimmed; |
| 402 | int ret, dir, val = 0; | 402 | int ret, dir, val = 0; |
| 403 | 403 | ||
| 404 | ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count); | 404 | if (count >= sizeof(buf)) |
| 405 | return -EINVAL; | ||
| 406 | |||
| 407 | ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); | ||
| 405 | if (ret < 0) | 408 | if (ret < 0) |
| 406 | return ret; | 409 | return ret; |
| 407 | 410 | ||
| 411 | buf[ret] = '\0'; | ||
| 412 | |||
| 408 | trimmed = strim(buf); | 413 | trimmed = strim(buf); |
| 409 | 414 | ||
| 410 | if (strcmp(trimmed, "input") == 0) { | 415 | if (strcmp(trimmed, "input") == 0) { |
| @@ -623,12 +628,15 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file, · 212 unmodified lines | |||
| 623 | char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2]; | 628 | char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2]; |
| 624 | int ret; | 629 | int ret; |
| 625 | 630 | ||
| 631 | if (count >= sizeof(buf)) | ||
| 632 | return -EINVAL; | ||
| 633 | |||
| 626 | ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos, | 634 | ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos, |
| 627 | user_buf, count); | 635 | user_buf, count); |
| 628 | if (ret < 0) | 636 | if (ret < 0) |
| 629 | return ret; | 637 | return ret; |
| 630 | 638 | ||
| 631 | buf[strlen(buf) - 1] = '\0'; | 639 | buf[ret] = '\0'; |
| 632 | 640 | ||
| 633 | ret = gpiod_set_consumer_name(data->ad.desc, buf); | 641 | ret = gpiod_set_consumer_name(data->ad.desc, buf); |
| 634 | if (ret) | 642 | if (ret) |
| @@ -1011,6 +1011,7 @@ static void zynq_gpio_remove(struct platform_device *pdev) · 1010 unmodified lines | |||
| 1011 | ret = pm_runtime_get_sync(&pdev->dev); | 1011 | ret = pm_runtime_get_sync(&pdev->dev); |
| 1012 | if (ret < 0) | 1012 | if (ret < 0) |
| 1013 | dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); | 1013 | dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); |
| 1014 | device_init_wakeup(&pdev->dev, 0); | ||
| 1014 | gpiochip_remove(&gpio->chip); | 1015 | gpiochip_remove(&gpio->chip); |
| 1015 | device_set_wakeup_capable(&pdev->dev, 0); | 1016 | device_set_wakeup_capable(&pdev->dev, 0); |
| 1016 | pm_runtime_disable(&pdev->dev); | 1017 | pm_runtime_disable(&pdev->dev); |
| @@ -317,11 +317,15 @@ EXPORT_SYMBOL_GPL(devm_gpiod_put); · 316 unmodified lines | |||
| 317 | * @dev: GPIO consumer | 317 | * @dev: GPIO consumer |
| 318 | * @desc: GPIO descriptor to remove resource management from | 318 | * @desc: GPIO descriptor to remove resource management from |
| 319 | * | 319 | * |
| 320 | * *DEPRECATED* | ||
| 321 | * This function should not be used. It's been provided as a workaround for | ||
| 322 | * resource ownership issues in the regulator framework and should be replaced | ||
| 323 | * with a better solution. | ||
| 324 | * | ||
| 320 | * Remove resource management from a GPIO descriptor. This is needed when | 325 | * Remove resource management from a GPIO descriptor. This is needed when |
| 321 | * you want to hand over lifecycle management of a descriptor to another | 326 | * you want to hand over lifecycle management of a descriptor to another |
| 322 | * mechanism. | 327 | * mechanism. |
| 323 | */ | 328 | */ |
| 324 | |||
| 325 | void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc) | 329 | void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc) |
| 326 | { | 330 | { |
| 327 | int ret; | 331 | int ret; |
| @@ -193,6 +193,8 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np, · 192 unmodified lines | |||
| 193 | */ | 193 | */ |
| 194 | { "himax,hx8357", "gpios-reset", false }, | 194 | { "himax,hx8357", "gpios-reset", false }, |
| 195 | { "himax,hx8369", "gpios-reset", false }, | 195 | { "himax,hx8369", "gpios-reset", false }, |
| 196 | #endif | ||
| 197 | #if IS_ENABLED(CONFIG_MTD_NAND_JZ4780) | ||
| 196 | /* | 198 | /* |
| 197 | * The rb-gpios semantics was undocumented and qi,lb60 (along with | 199 | * The rb-gpios semantics was undocumented and qi,lb60 (along with |
| 198 | * the ingenic driver) got it wrong. The active state encodes the | 200 | * the ingenic driver) got it wrong. The active state encodes the |
| @@ -266,6 +268,9 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np, · 67 unmodified lines | |||
| 266 | { "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" }, | 268 | { "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" }, |
| 267 | { "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" }, | 269 | { "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" }, |
| 268 | #endif | 270 | #endif |
| 271 | #if IS_ENABLED(CONFIG_MMC_ATMELMCI) | ||
| 272 | { "atmel,hsmci", "cd-gpios", "cd-inverted" }, | ||
| 273 | #endif | ||
| 269 | #if IS_ENABLED(CONFIG_PCI_IMX6) | 274 | #if IS_ENABLED(CONFIG_PCI_IMX6) |
| 270 | { "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" }, | 275 | { "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" }, |
| 271 | { "fsl,imx6sx-pcie", "reset-gpio", "reset-gpio-active-high" }, | 276 | { "fsl,imx6sx-pcie", "reset-gpio", "reset-gpio-active-high" }, |
| @@ -291,9 +296,6 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np, · 19 unmodified lines | |||
| 291 | #if IS_ENABLED(CONFIG_REGULATOR_GPIO) | 296 | #if IS_ENABLED(CONFIG_REGULATOR_GPIO) |
| 292 | { "regulator-gpio", "enable-gpio", "enable-active-high" }, | 297 | { "regulator-gpio", "enable-gpio", "enable-active-high" }, |
| 293 | { "regulator-gpio", "enable-gpios", "enable-active-high" }, | 298 | { "regulator-gpio", "enable-gpios", "enable-active-high" }, |
| 294 | #endif | ||
| 295 | #if IS_ENABLED(CONFIG_MMC_ATMELMCI) | ||
| 296 | { "atmel,hsmci", "cd-gpios", "cd-inverted" }, | ||
| 297 | #endif | 299 | #endif |
| 298 | }; | 300 | }; |
| 299 | unsigned int i; | 301 | unsigned int i; |
| @@ -742,6 +742,12 @@ EXPORT_SYMBOL_GPL(gpiochip_query_valid_mask); · 741 unmodified lines | |||
| 742 | bool gpiochip_line_is_valid(const struct gpio_chip *gc, | 742 | bool gpiochip_line_is_valid(const struct gpio_chip *gc, |
| 743 | unsigned int offset) | 743 | unsigned int offset) |
| 744 | { | 744 | { |
| 745 | /* | ||
| 746 | * hog pins are requested before registering GPIO chip | ||
| 747 | */ | ||
| 748 | if (!gc->gpiodev) | ||
| 749 | return true; | ||
| 750 | |||
| 745 | /* No mask means all valid */ | 751 | /* No mask means all valid */ |
| 746 | if (likely(!gc->gpiodev->valid_mask)) | 752 | if (likely(!gc->gpiodev->valid_mask)) |
| 747 | return true; | 753 | return true; |
| @@ -2879,7 +2885,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value) · 2131 unmodified lines | |||
| 2879 | * output-only, but if there is then not even a .set() operation it | 2885 | * output-only, but if there is then not even a .set() operation it |
| 2880 | * is pretty tricky to drive the output line. | 2886 | * is pretty tricky to drive the output line. |
| 2881 | */ | 2887 | */ |
| 2882 | if (!guard.gc->set && !guard.gc->direction_output) { | 2888 | if (!guard.gc->set && !guard.gc->set_rv && !guard.gc->direction_output) { |
| 2883 | gpiod_warn(desc, | 2889 | gpiod_warn(desc, |
| 2884 | "%s: missing set() and direction_output() operations\n", | 2890 | "%s: missing set() and direction_output() operations\n", |
| 2885 | __func__); | 2891 | __func__); |
| @@ -188,7 +188,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS · 187 unmodified lines | |||
| 188 | bool "Enable refcount backtrace history in the DP MST helpers" | 188 | bool "Enable refcount backtrace history in the DP MST helpers" |
| 189 | depends on STACKTRACE_SUPPORT | 189 | depends on STACKTRACE_SUPPORT |
| 190 | select STACKDEPOT | 190 | select STACKDEPOT |
| 191 | depends on DRM_KMS_HELPER | 191 | select DRM_KMS_HELPER |
| 192 | depends on DEBUG_KERNEL | 192 | depends on DEBUG_KERNEL |
| 193 | depends on EXPERT | 193 | depends on EXPERT |
| 194 | help | 194 | help |
| @@ -121,7 +121,6 @@ struct adp_drv_private { · 120 unmodified lines | |||
| 121 | dma_addr_t mask_iova; | 121 | dma_addr_t mask_iova; |
| 122 | int be_irq; | 122 | int be_irq; |
| 123 | int fe_irq; | 123 | int fe_irq; |
| 124 | spinlock_t irq_lock; | ||
| 125 | struct drm_pending_vblank_event *event; | 124 | struct drm_pending_vblank_event *event; |
| 126 | }; | 125 | }; |
| 127 | 126 | ||
| @@ -288,6 +287,7 @@ static void adp_crtc_atomic_enable(struct drm_crtc *crtc, · 160 unmodified lines | |||
| 288 | writel(BIT(0), adp->be + ADBE_BLEND_EN3); | 287 | writel(BIT(0), adp->be + ADBE_BLEND_EN3); |
| 289 | writel(BIT(0), adp->be + ADBE_BLEND_BYPASS); | 288 | writel(BIT(0), adp->be + ADBE_BLEND_BYPASS); |
| 290 | writel(BIT(0), adp->be + ADBE_BLEND_EN4); | 289 | writel(BIT(0), adp->be + ADBE_BLEND_EN4); |
| 290 | drm_crtc_vblank_on(crtc); | ||
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | static void adp_crtc_atomic_disable(struct drm_crtc *crtc, | 293 | static void adp_crtc_atomic_disable(struct drm_crtc *crtc, |
| @@ -310,6 +310,7 @@ static void adp_crtc_atomic_flush(struct drm_crtc *crtc, · 16 unmodified lines | |||
| 310 | struct drm_atomic_state *state) | 310 | struct drm_atomic_state *state) |
| 311 | { | 311 | { |
| 312 | u32 frame_num = 1; | 312 | u32 frame_num = 1; |
| 313 | unsigned long flags; | ||
| 313 | struct adp_drv_private *adp = crtc_to_adp(crtc); | 314 | struct adp_drv_private *adp = crtc_to_adp(crtc); |
| 314 | struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); | 315 | struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); |
| 315 | u64 new_size = ALIGN(new_state->mode.hdisplay * | 316 | u64 new_size = ALIGN(new_state->mode.hdisplay * |
| @@ -330,13 +331,19 @@ static void adp_crtc_atomic_flush(struct drm_crtc *crtc, · 14 unmodified lines | |||
| 330 | } | 331 | } |
| 331 | writel(ADBE_FIFO_SYNC | frame_num, adp->be + ADBE_FIFO); | 332 | writel(ADBE_FIFO_SYNC | frame_num, adp->be + ADBE_FIFO); |
| 332 | //FIXME: use adbe flush interrupt | 333 | //FIXME: use adbe flush interrupt |
| 333 | spin_lock_irq(&crtc->dev->event_lock); | ||
| 334 | if (crtc->state->event) { | 334 | if (crtc->state->event) { |
| 335 | drm_crtc_vblank_get(crtc); | 335 | struct drm_pending_vblank_event *event = crtc->state->event; |
| 336 | adp->event = crtc->state->event; | 336 | |
| 337 | crtc->state->event = NULL; | ||
| 338 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
| 339 | |||
| 340 | if (drm_crtc_vblank_get(crtc) != 0) | ||
| 341 | drm_crtc_send_vblank_event(crtc, event); | ||
| 342 | else | ||
| 343 | adp->event = event; | ||
| 344 | |||
| 345 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
| 337 | } | 346 | } |
| 338 | crtc->state->event = NULL; | ||
| 339 | spin_unlock_irq(&crtc->dev->event_lock); | ||
| 340 | } | 347 | } |
| 341 | 348 | ||
| 342 | static const struct drm_crtc_funcs adp_crtc_funcs = { | 349 | static const struct drm_crtc_funcs adp_crtc_funcs = { |
| @@ -482,8 +489,6 @@ static irqreturn_t adp_fe_irq(int irq, void *arg) · 139 unmodified lines | |||
| 482 | u32 int_status; | 489 | u32 int_status; |
| 483 | u32 int_ctl; | 490 | u32 int_ctl; |
| 484 | 491 | ||
| 485 | spin_lock(&adp->irq_lock); | ||
| 486 | |||
| 487 | int_status = readl(adp->fe + ADP_INT_STATUS); | 492 | int_status = readl(adp->fe + ADP_INT_STATUS); |
| 488 | if (int_status & ADP_INT_STATUS_VBLANK) { | 493 | if (int_status & ADP_INT_STATUS_VBLANK) { |
| 489 | drm_crtc_handle_vblank(&adp->crtc); | 494 | drm_crtc_handle_vblank(&adp->crtc); |
| @@ -501,7 +506,6 @@ static irqreturn_t adp_fe_irq(int irq, void *arg) · 11 unmodified lines | |||
| 501 | 506 | ||
| 502 | writel(int_status, adp->fe + ADP_INT_STATUS); | 507 | writel(int_status, adp->fe + ADP_INT_STATUS); |
| 503 | 508 | ||
| 504 | spin_unlock(&adp->irq_lock); | ||
| 505 | 509 | ||
| 506 | return IRQ_HANDLED; | 510 | return IRQ_HANDLED; |
| 507 | } | 511 | } |
| @@ -512,8 +516,7 @@ static int adp_drm_bind(struct device *dev) · 4 unmodified lines | |||
| 512 | struct adp_drv_private *adp = to_adp(drm); | 516 | struct adp_drv_private *adp = to_adp(drm); |
| 513 | int err; | 517 | int err; |
| 514 | 518 | ||
| 515 | adp_disable_vblank(adp); | 519 | writel(ADP_CTRL_FIFO_ON, adp->fe + ADP_CTRL); |
| 516 | writel(ADP_CTRL_FIFO_ON | ADP_CTRL_VBLANK_ON, adp->fe + ADP_CTRL); | ||
| 517 | 520 | ||
| 518 | adp->next_bridge = drmm_of_get_bridge(&adp->drm, dev->of_node, 0, 0); | 521 | adp->next_bridge = drmm_of_get_bridge(&adp->drm, dev->of_node, 0, 0); |
| 519 | if (IS_ERR(adp->next_bridge)) { | 522 | if (IS_ERR(adp->next_bridge)) { |
| @@ -567,8 +570,6 @@ static int adp_probe(struct platform_device *pdev) · 47 unmodified lines | |||
| 567 | if (IS_ERR(adp)) | 570 | if (IS_ERR(adp)) |
| 568 | return PTR_ERR(adp); | 571 | return PTR_ERR(adp); |
| 569 | 572 | ||
| 570 | spin_lock_init(&adp->irq_lock); | ||
| 571 | |||
| 572 | dev_set_drvdata(&pdev->dev, &adp->drm); | 573 | dev_set_drvdata(&pdev->dev, &adp->drm); |
| 573 | 574 | ||
| 574 | err = adp_parse_of(pdev, adp); | 575 | err = adp_parse_of(pdev, adp); |
| @@ -353,7 +353,6 @@ enum amdgpu_kiq_irq { · 352 unmodified lines | |||
| 353 | AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0, | 353 | AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0, |
| 354 | AMDGPU_CP_KIQ_IRQ_LAST | 354 | AMDGPU_CP_KIQ_IRQ_LAST |
| 355 | }; | 355 | }; |
| 356 | #define SRIOV_USEC_TIMEOUT 1200000 /* wait 12 * 100ms for SRIOV */ | ||
| 357 | #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ | 356 | #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ |
| 358 | #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ | 357 | #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ |
| 359 | #define MAX_KIQ_REG_TRY 1000 | 358 | #define MAX_KIQ_REG_TRY 1000 |
| @@ -1124,6 +1123,7 @@ struct amdgpu_device { · 764 unmodified lines | |||
| 1124 | bool in_s3; | 1123 | bool in_s3; |
| 1125 | bool in_s4; | 1124 | bool in_s4; |
| 1126 | bool in_s0ix; | 1125 | bool in_s0ix; |
| 1126 | suspend_state_t last_suspend_state; | ||
| 1127 | 1127 | ||
| 1128 | enum pp_mp1_state mp1_state; | 1128 | enum pp_mp1_state mp1_state; |
| 1129 | struct amdgpu_doorbell_index doorbell_index; | 1129 | struct amdgpu_doorbell_index doorbell_index; |
| @@ -1614,11 +1614,9 @@ static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_cap · 484 unmodified lines | |||
| 1614 | #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) | 1614 | #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) |
| 1615 | bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); | 1615 | bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); |
| 1616 | bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); | 1616 | bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); |
| 1617 | void amdgpu_choose_low_power_state(struct amdgpu_device *adev); | ||
| 1618 | #else | 1617 | #else |
| 1619 | static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } | 1618 | static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } |
| 1620 | static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } | 1619 | static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } |
| 1621 | static inline void amdgpu_choose_low_power_state(struct amdgpu_device *adev) { } | ||
| 1622 | #endif | 1620 | #endif |
| 1623 | 1621 | ||
| 1624 | void amdgpu_register_gpu_instance(struct amdgpu_device *adev); | 1622 | void amdgpu_register_gpu_instance(struct amdgpu_device *adev); |
| @@ -1533,22 +1533,4 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) · 1532 unmodified lines | |||
| 1533 | #endif /* CONFIG_AMD_PMC */ | 1533 | #endif /* CONFIG_AMD_PMC */ |
| 1534 | } | 1534 | } |
| 1535 | 1535 | ||
| 1536 | /** | ||
| 1537 | * amdgpu_choose_low_power_state | ||
| 1538 | * | ||
| 1539 | * @adev: amdgpu_device_pointer | ||
| 1540 | * | ||
| 1541 | * Choose the target low power state for the GPU | ||
| 1542 | */ | ||
| 1543 | void amdgpu_choose_low_power_state(struct amdgpu_device *adev) | ||
| 1544 | { | ||
| 1545 | if (adev->in_runpm) | ||
| 1546 | return; | ||
| 1547 | |||
| 1548 | if (amdgpu_acpi_is_s0ix_active(adev)) | ||
| 1549 | adev->in_s0ix = true; | ||
| 1550 | else if (amdgpu_acpi_is_s3_active(adev)) | ||
| 1551 | adev->in_s3 = true; | ||
| 1552 | } | ||
| 1553 | |||
| 1554 | #endif /* CONFIG_SUSPEND */ | 1536 | #endif /* CONFIG_SUSPEND */ |
| @@ -109,7 +109,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 108 unmodified lines | |||
| 109 | struct drm_exec exec; | 109 | struct drm_exec exec; |
| 110 | int r; | 110 | int r; |
| 111 | 111 | ||
| 112 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | 112 | drm_exec_init(&exec, 0, 0); |
| 113 | drm_exec_until_all_locked(&exec) { | 113 | drm_exec_until_all_locked(&exec) { |
| 114 | r = amdgpu_vm_lock_pd(vm, &exec, 0); | 114 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 115 | if (likely(!r)) | 115 | if (likely(!r)) |
| @@ -3510,6 +3510,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 3509 unmodified lines | |||
| 3510 | amdgpu_device_mem_scratch_fini(adev); | 3510 | amdgpu_device_mem_scratch_fini(adev); |
| 3511 | amdgpu_ib_pool_fini(adev); | 3511 | amdgpu_ib_pool_fini(adev); |
| 3512 | amdgpu_seq64_fini(adev); | 3512 | amdgpu_seq64_fini(adev); |
| 3513 | amdgpu_doorbell_fini(adev); | ||
| 3513 | } | 3514 | } |
| 3514 | if (adev->ip_blocks[i].version->funcs->sw_fini) { | 3515 | if (adev->ip_blocks[i].version->funcs->sw_fini) { |
| 3515 | r = adev->ip_blocks[i].version->funcs->sw_fini(&adev->ip_blocks[i]); | 3516 | r = adev->ip_blocks[i].version->funcs->sw_fini(&adev->ip_blocks[i]); |
| @@ -3643,6 +3644,13 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) · 127 unmodified lines | |||
| 3643 | adev, adev->ip_blocks[i].version->type)) | 3644 | adev, adev->ip_blocks[i].version->type)) |
| 3644 | continue; | 3645 | continue; |
| 3645 | 3646 | ||
| 3647 | /* Since we skip suspend for S0i3, we need to cancel the delayed | ||
| 3648 | * idle work here as the suspend callback never gets called. | ||
| 3649 | */ | ||
| 3650 | if (adev->in_s0ix && | ||
| 3651 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX && | ||
| 3652 | amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0)) | ||
| 3653 | cancel_delayed_work_sync(&adev->gfx.idle_work); | ||
| 3646 | /* skip suspend of gfx/mes and psp for S0ix | 3654 | /* skip suspend of gfx/mes and psp for S0ix |
| 3647 | * gfx is in gfxoff state, so on resume it will exit gfxoff just | 3655 | * gfx is in gfxoff state, so on resume it will exit gfxoff just |
| 3648 | * like at runtime. PSP is also part of the always on hardware | 3656 | * like at runtime. PSP is also part of the always on hardware |
| @@ -4851,7 +4859,6 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) · 1202 unmodified lines | |||
| 4851 | 4859 | ||
| 4852 | iounmap(adev->rmmio); | 4860 | iounmap(adev->rmmio); |
| 4853 | adev->rmmio = NULL; | 4861 | adev->rmmio = NULL; |
| 4854 | amdgpu_doorbell_fini(adev); | ||
| 4855 | drm_dev_exit(idx); | 4862 | drm_dev_exit(idx); |
| 4856 | } | 4863 | } |
| 4857 | 4864 | ||
| @@ -4900,28 +4907,20 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev) · 42 unmodified lines | |||
| 4900 | * @data: data | 4907 | * @data: data |
| 4901 | * | 4908 | * |
| 4902 | * This function is called when the system is about to suspend or hibernate. | 4909 | * This function is called when the system is about to suspend or hibernate. |
| 4903 | * It is used to evict resources from the device before the system goes to | 4910 | * It is used to set the appropriate flags so that eviction can be optimized |
| 4904 | * sleep while there is still access to swap. | 4911 | * in the pm prepare callback. |
| 4905 | */ | 4912 | */ |
| 4906 | static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, | 4913 | static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, |
| 4907 | void *data) | 4914 | void *data) |
| 4908 | { | 4915 | { |
| 4909 | struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb); | 4916 | struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb); |
| 4910 | int r; | ||
| 4911 | 4917 | ||
| 4912 | switch (mode) { | 4918 | switch (mode) { |
| 4913 | case PM_HIBERNATION_PREPARE: | 4919 | case PM_HIBERNATION_PREPARE: |
| 4914 | adev->in_s4 = true; | 4920 | adev->in_s4 = true; |
| 4915 | fallthrough; | 4921 | break; |
| 4916 | case PM_SUSPEND_PREPARE: | 4922 | case PM_POST_HIBERNATION: |
| 4917 | r = amdgpu_device_evict_resources(adev); | 4923 | adev->in_s4 = false; |
| 4918 | /* | ||
| 4919 | * This is considered non-fatal at this time because | ||
| 4920 | * amdgpu_device_prepare() will also fatally evict resources. | ||
| 4921 | * See https://gitlab.freedesktop.org/drm/amd/-/issues/3781 | ||
| 4922 | */ | ||
| 4923 | if (r) | ||
| 4924 | drm_warn(adev_to_drm(adev), "Failed to evict resources, freeze active processes if problems occur: %d\n", r); | ||
| 4925 | break; | 4924 | break; |
| 4926 | } | 4925 | } |
| 4927 | 4926 | ||
| @@ -4942,15 +4941,13 @@ int amdgpu_device_prepare(struct drm_device *dev) · 14 unmodified lines | |||
| 4942 | struct amdgpu_device *adev = drm_to_adev(dev); | 4941 | struct amdgpu_device *adev = drm_to_adev(dev); |
| 4943 | int i, r; | 4942 | int i, r; |
| 4944 | 4943 | ||
| 4945 | amdgpu_choose_low_power_state(adev); | ||
| 4946 | |||
| 4947 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 4944 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 4948 | return 0; | 4945 | return 0; |
| 4949 | 4946 | ||
| 4950 | /* Evict the majority of BOs before starting suspend sequence */ | 4947 | /* Evict the majority of BOs before starting suspend sequence */ |
| 4951 | r = amdgpu_device_evict_resources(adev); | 4948 | r = amdgpu_device_evict_resources(adev); |
| 4952 | if (r) | 4949 | if (r) |
| 4953 | goto unprepare; | 4950 | return r; |
| 4954 | 4951 | ||
| 4955 | flush_delayed_work(&adev->gfx.gfx_off_delay_work); | 4952 | flush_delayed_work(&adev->gfx.gfx_off_delay_work); |
| 4956 | 4953 | ||
| @@ -4961,15 +4958,10 @@ int amdgpu_device_prepare(struct drm_device *dev) · 4 unmodified lines | |||
| 4961 | continue; | 4958 | continue; |
| 4962 | r = adev->ip_blocks[i].version->funcs->prepare_suspend(&adev->ip_blocks[i]); | 4959 | r = adev->ip_blocks[i].version->funcs->prepare_suspend(&adev->ip_blocks[i]); |
| 4963 | if (r) | 4960 | if (r) |
| 4964 | goto unprepare; | 4961 | return r; |
| 4965 | } | 4962 | } |
| 4966 | 4963 | ||
| 4967 | return 0; | 4964 | return 0; |
| 4968 | |||
| 4969 | unprepare: | ||
| 4970 | adev->in_s0ix = adev->in_s3 = adev->in_s4 = false; | ||
| 4971 | |||
| 4972 | return r; | ||
| 4973 | } | 4965 | } |
| 4974 | 4966 | ||
| 4975 | /** | 4967 | /** |
| @@ -120,6 +120,8 @@ MODULE_FIRMWARE("amdgpu/vega20_ip_discovery.bin"); · 119 unmodified lines | |||
| 120 | MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin"); | 120 | MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin"); |
| 121 | MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin"); | 121 | MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin"); |
| 122 | MODULE_FIRMWARE("amdgpu/picasso_ip_discovery.bin"); | 122 | MODULE_FIRMWARE("amdgpu/picasso_ip_discovery.bin"); |
| 123 | MODULE_FIRMWARE("amdgpu/arcturus_ip_discovery.bin"); | ||
| 124 | MODULE_FIRMWARE("amdgpu/aldebaran_ip_discovery.bin"); | ||
| 123 | 125 | ||
| 124 | #define mmIP_DISCOVERY_VERSION 0x16A00 | 126 | #define mmIP_DISCOVERY_VERSION 0x16A00 |
| 125 | #define mmRCC_CONFIG_MEMSIZE 0xde3 | 127 | #define mmRCC_CONFIG_MEMSIZE 0xde3 |
| @@ -43,6 +43,29 @@ · 42 unmodified lines | |||
| 43 | #include <linux/dma-fence-array.h> | 43 | #include <linux/dma-fence-array.h> |
| 44 | #include <linux/pci-p2pdma.h> | 44 | #include <linux/pci-p2pdma.h> |
| 45 | 45 | ||
| 46 | static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * dma_buf_attach_adev - Helper to get adev of an attachment | ||
| 50 | * | ||
| 51 | * @attach: attachment | ||
| 52 | * | ||
| 53 | * Returns: | ||
| 54 | * A struct amdgpu_device * if the attaching device is an amdgpu device or | ||
| 55 | * partition, NULL otherwise. | ||
| 56 | */ | ||
| 57 | static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *attach) | ||
| 58 | { | ||
| 59 | if (attach->importer_ops == &amdgpu_dma_buf_attach_ops) { | ||
| 60 | struct drm_gem_object *obj = attach->importer_priv; | ||
| 61 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | ||
| 62 | |||
| 63 | return amdgpu_ttm_adev(bo->tbo.bdev); | ||
| 64 | } | ||
| 65 | |||
| 66 | return NULL; | ||
| 67 | } | ||
| 68 | |||
| 46 | /** | 69 | /** |
| 47 | * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation | 70 | * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation |
| 48 | * | 71 | * |
| @@ -54,11 +77,13 @@ · 5 unmodified lines | |||
| 54 | static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, | 77 | static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, |
| 55 | struct dma_buf_attachment *attach) | 78 | struct dma_buf_attachment *attach) |
| 56 | { | 79 | { |
| 80 | struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach); | ||
| 57 | struct drm_gem_object *obj = dmabuf->priv; | 81 | struct drm_gem_object *obj = dmabuf->priv; |
| 58 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | 82 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); |
| 59 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | 83 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); |
| 60 | 84 | ||
| 61 | if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) | 85 | if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) && |
| 86 | pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) | ||
| 62 | attach->peer2peer = false; | 87 | attach->peer2peer = false; |
| 63 | 88 | ||
| 64 | amdgpu_vm_bo_update_shared(bo); | 89 | amdgpu_vm_bo_update_shared(bo); |
| @@ -75,11 +100,35 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, · 10 unmodified lines | |||
| 75 | */ | 100 | */ |
| 76 | static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) | 101 | static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) |
| 77 | { | 102 | { |
| 78 | struct drm_gem_object *obj = attach->dmabuf->priv; | 103 | struct dma_buf *dmabuf = attach->dmabuf; |
| 79 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | 104 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(dmabuf->priv); |
| 105 | u32 domains = bo->allowed_domains; | ||
| 106 | |||
| 107 | dma_resv_assert_held(dmabuf->resv); | ||
| 108 | |||
| 109 | /* Try pinning into VRAM to allow P2P with RDMA NICs without ODP | ||
| 110 | * support if all attachments can do P2P. If any attachment can't do | ||
| 111 | * P2P just pin into GTT instead. | ||
| 112 | * | ||
| 113 | * To avoid with conflicting pinnings between GPUs and RDMA when move | ||
| 114 | * notifiers are disabled, only allow pinning in VRAM when move | ||
| 115 | * notiers are enabled. | ||
| 116 | */ | ||
| 117 | if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) { | ||
| 118 | domains &= ~AMDGPU_GEM_DOMAIN_VRAM; | ||
| 119 | } else { | ||
| 120 | list_for_each_entry(attach, &dmabuf->attachments, node) | ||
| 121 | if (!attach->peer2peer) | ||
| 122 | domains &= ~AMDGPU_GEM_DOMAIN_VRAM; | ||
| 123 | } | ||
| 80 | 124 | ||
| 81 | /* pin buffer into GTT */ | 125 | if (domains & AMDGPU_GEM_DOMAIN_VRAM) |
| 82 | return amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); | 126 | bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; |
| 127 | |||
| 128 | if (WARN_ON(!domains)) | ||
| 129 | return -EINVAL; | ||
| 130 | |||
| 131 | return amdgpu_bo_pin(bo, domains); | ||
| 83 | } | 132 | } |
| 84 | 133 | ||
| 85 | /** | 134 | /** |
| @@ -134,9 +183,6 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, · 48 unmodified lines | |||
| 134 | r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); | 183 | r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); |
| 135 | if (r) | 184 | if (r) |
| 136 | return ERR_PTR(r); | 185 | return ERR_PTR(r); |
| 137 | |||
| 138 | } else if (bo->tbo.resource->mem_type != TTM_PL_TT) { | ||
| 139 | return ERR_PTR(-EBUSY); | ||
| 140 | } | 186 | } |
| 141 | 187 | ||
| 142 | switch (bo->tbo.resource->mem_type) { | 188 | switch (bo->tbo.resource->mem_type) { |
| @@ -153,6 +199,11 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, · 10 unmodified lines | |||
| 153 | break; | 199 | break; |
| 154 | 200 | ||
| 155 | case TTM_PL_VRAM: | 201 | case TTM_PL_VRAM: |
| 202 | /* XGMI-accessible memory should never be DMA-mapped */ | ||
| 203 | if (WARN_ON(amdgpu_dmabuf_is_xgmi_accessible( | ||
| 204 | dma_buf_attach_adev(attach), bo))) | ||
| 205 | return ERR_PTR(-EINVAL); | ||
| 206 | |||
| 156 | r = amdgpu_vram_mgr_alloc_sgt(adev, bo->tbo.resource, 0, | 207 | r = amdgpu_vram_mgr_alloc_sgt(adev, bo->tbo.resource, 0, |
| 157 | bo->tbo.base.size, attach->dev, | 208 | bo->tbo.base.size, attach->dev, |
| 158 | dir, &sgt); | 209 | dir, &sgt); |
| @@ -184,7 +235,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, · 25 unmodified lines | |||
| 184 | struct sg_table *sgt, | 235 | struct sg_table *sgt, |
| 185 | enum dma_data_direction dir) | 236 | enum dma_data_direction dir) |
| 186 | { | 237 | { |
| 187 | if (sgt->sgl->page_link) { | 238 | if (sg_page(sgt->sgl)) { |
| 188 | dma_unmap_sgtable(attach->dev, sgt, dir, 0); | 239 | dma_unmap_sgtable(attach->dev, sgt, dir, 0); |
| 189 | sg_free_table(sgt); | 240 | sg_free_table(sgt); |
| 190 | kfree(sgt); | 241 | kfree(sgt); |
| @@ -459,6 +510,9 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, · 268 unmodified lines | |||
| 459 | struct drm_gem_object *obj = &bo->tbo.base; | 510 | struct drm_gem_object *obj = &bo->tbo.base; |
| 460 | struct drm_gem_object *gobj; | 511 | struct drm_gem_object *gobj; |
| 461 | 512 | ||
| 513 | if (!adev) | ||
| 514 | return false; | ||
| 515 | |||
| 462 | if (obj->import_attach) { | 516 | if (obj->import_attach) { |
| 463 | struct dma_buf *dma_buf = obj->import_attach->dmabuf; | 517 | struct dma_buf *dma_buf = obj->import_attach->dmabuf; |
| 464 | 518 | ||
| @@ -2548,8 +2548,20 @@ static int amdgpu_pmops_suspend(struct device *dev) · 2547 unmodified lines | |||
| 2548 | adev->in_s0ix = true; | 2548 | adev->in_s0ix = true; |
| 2549 | else if (amdgpu_acpi_is_s3_active(adev)) | 2549 | else if (amdgpu_acpi_is_s3_active(adev)) |
| 2550 | adev->in_s3 = true; | 2550 | adev->in_s3 = true; |
| 2551 | if (!adev->in_s0ix && !adev->in_s3) | 2551 | if (!adev->in_s0ix && !adev->in_s3) { |
| 2552 | /* don't allow going deep first time followed by s2idle the next time */ | ||
| 2553 | if (adev->last_suspend_state != PM_SUSPEND_ON && | ||
| 2554 | adev->last_suspend_state != pm_suspend_target_state) { | ||
| 2555 | drm_err_once(drm_dev, "Unsupported suspend state %d\n", | ||
| 2556 | pm_suspend_target_state); | ||
| 2557 | return -EINVAL; | ||
| 2558 | } | ||
| 2552 | return 0; | 2559 | return 0; |
| 2560 | } | ||
| 2561 | |||
| 2562 | /* cache the state last used for suspend */ | ||
| 2563 | adev->last_suspend_state = pm_suspend_target_state; | ||
| 2564 | |||
| 2553 | return amdgpu_device_suspend(drm_dev, true); | 2565 | return amdgpu_device_suspend(drm_dev, true); |
| 2554 | } | 2566 | } |
| 2555 | 2567 | ||
| @@ -2603,13 +2615,8 @@ static int amdgpu_pmops_freeze(struct device *dev) · 47 unmodified lines | |||
| 2603 | static int amdgpu_pmops_thaw(struct device *dev) | 2615 | static int amdgpu_pmops_thaw(struct device *dev) |
| 2604 | { | 2616 | { |
| 2605 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 2617 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 2606 | struct amdgpu_device *adev = drm_to_adev(drm_dev); | ||
| 2607 | int r; | ||
| 2608 | |||
| 2609 | r = amdgpu_device_resume(drm_dev, true); | ||
| 2610 | adev->in_s4 = false; | ||
| 2611 | 2618 | ||
| 2612 | return r; | 2619 | return amdgpu_device_resume(drm_dev, true); |
| 2613 | } | 2620 | } |
| 2614 | 2621 | ||
| 2615 | static int amdgpu_pmops_poweroff(struct device *dev) | 2622 | static int amdgpu_pmops_poweroff(struct device *dev) |
| @@ -2622,9 +2629,6 @@ static int amdgpu_pmops_poweroff(struct device *dev) · 6 unmodified lines | |||
| 2622 | static int amdgpu_pmops_restore(struct device *dev) | 2629 | static int amdgpu_pmops_restore(struct device *dev) |
| 2623 | { | 2630 | { |
| 2624 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 2631 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 2625 | struct amdgpu_device *adev = drm_to_adev(drm_dev); | ||
| 2626 | |||
| 2627 | adev->in_s4 = false; | ||
| 2628 | 2632 | ||
| 2629 | return amdgpu_device_resume(drm_dev, true); | 2633 | return amdgpu_device_resume(drm_dev, true); |
| 2630 | } | 2634 | } |
| @@ -1438,9 +1438,11 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring) · 1437 unmodified lines | |||
| 1438 | struct amdgpu_device *adev = ring->adev; | 1438 | struct amdgpu_device *adev = ring->adev; |
| 1439 | struct drm_gpu_scheduler *sched = &ring->sched; | 1439 | struct drm_gpu_scheduler *sched = &ring->sched; |
| 1440 | struct drm_sched_entity entity; | 1440 | struct drm_sched_entity entity; |
| 1441 | static atomic_t counter; | ||
| 1441 | struct dma_fence *f; | 1442 | struct dma_fence *f; |
| 1442 | struct amdgpu_job *job; | 1443 | struct amdgpu_job *job; |
| 1443 | struct amdgpu_ib *ib; | 1444 | struct amdgpu_ib *ib; |
| 1445 | void *owner; | ||
| 1444 | int i, r; | 1446 | int i, r; |
| 1445 | 1447 | ||
| 1446 | /* Initialize the scheduler entity */ | 1448 | /* Initialize the scheduler entity */ |
| @@ -1451,9 +1453,15 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring) · 4 unmodified lines | |||
| 1451 | goto err; | 1453 | goto err; |
| 1452 | } | 1454 | } |
| 1453 | 1455 | ||
| 1454 | r = amdgpu_job_alloc_with_ib(ring->adev, &entity, NULL, | 1456 | /* |
| 1455 | 64, 0, | 1457 | * Use some unique dummy value as the owner to make sure we execute |
| 1456 | &job); | 1458 | * the cleaner shader on each submission. The value just need to change |
| 1459 | * for each submission and is otherwise meaningless. | ||
| 1460 | */ | ||
| 1461 | owner = (void *)(unsigned long)atomic_inc_return(&counter); | ||
| 1462 | |||
| 1463 | r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner, | ||
| 1464 | 64, 0, &job); | ||
| 1457 | if (r) | 1465 | if (r) |
| 1458 | goto err; | 1466 | goto err; |
| 1459 | 1467 | ||
| @@ -699,12 +699,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, · 698 unmodified lines | |||
| 699 | uint32_t flush_type, bool all_hub, | 699 | uint32_t flush_type, bool all_hub, |
| 700 | uint32_t inst) | 700 | uint32_t inst) |
| 701 | { | 701 | { |
| 702 | u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : | ||
| 703 | adev->usec_timeout; | ||
| 704 | struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; | 702 | struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; |
| 705 | struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; | 703 | struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; |
| 706 | unsigned int ndw; | 704 | unsigned int ndw; |
| 707 | int r; | 705 | int r, cnt = 0; |
| 708 | uint32_t seq; | 706 | uint32_t seq; |
| 709 | 707 | ||
| 710 | /* | 708 | /* |
| @@ -761,10 +759,21 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, · 50 unmodified lines | |||
| 761 | 759 | ||
| 762 | amdgpu_ring_commit(ring); | 760 | amdgpu_ring_commit(ring); |
| 763 | spin_unlock(&adev->gfx.kiq[inst].ring_lock); | 761 | spin_unlock(&adev->gfx.kiq[inst].ring_lock); |
| 764 | if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { | 762 | |
| 763 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
| 764 | |||
| 765 | might_sleep(); | ||
| 766 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY && | ||
| 767 | !amdgpu_reset_pending(adev->reset_domain)) { | ||
| 768 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); | ||
| 769 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
| 770 | } | ||
| 771 | |||
| 772 | if (cnt > MAX_KIQ_REG_TRY) { | ||
| 765 | dev_err(adev->dev, "timeout waiting for kiq fence\n"); | 773 | dev_err(adev->dev, "timeout waiting for kiq fence\n"); |
| 766 | r = -ETIME; | 774 | r = -ETIME; |
| 767 | } | 775 | } else |
| 776 | r = 0; | ||
| 768 | } | 777 | } |
| 769 | 778 | ||
| 770 | error_unlock_reset: | 779 | error_unlock_reset: |
| @@ -163,8 +163,8 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain) · 162 unmodified lines | |||
| 163 | * When GTT is just an alternative to VRAM make sure that we | 163 | * When GTT is just an alternative to VRAM make sure that we |
| 164 | * only use it as fallback and still try to fill up VRAM first. | 164 | * only use it as fallback and still try to fill up VRAM first. |
| 165 | */ | 165 | */ |
| 166 | if (domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM && | 166 | if (abo->tbo.resource && !(adev->flags & AMD_IS_APU) && |
| 167 | !(adev->flags & AMD_IS_APU)) | 167 | domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) |
| 168 | places[c].flags |= TTM_PL_FLAG_FALLBACK; | 168 | places[c].flags |= TTM_PL_FLAG_FALLBACK; |
| 169 | c++; | 169 | c++; |
| 170 | } | 170 | } |
| @@ -66,7 +66,6 @@ · 65 unmodified lines | |||
| 66 | #define VCN_ENC_CMD_REG_WAIT 0x0000000c | 66 | #define VCN_ENC_CMD_REG_WAIT 0x0000000c |
| 67 | 67 | ||
| 68 | #define VCN_AON_SOC_ADDRESS_2_0 0x1f800 | 68 | #define VCN_AON_SOC_ADDRESS_2_0 0x1f800 |
| 69 | #define VCN1_AON_SOC_ADDRESS_3_0 0x48000 | ||
| 70 | #define VCN_VID_IP_ADDRESS_2_0 0x0 | 69 | #define VCN_VID_IP_ADDRESS_2_0 0x0 |
| 71 | #define VCN_AON_IP_ADDRESS_2_0 0x30000 | 70 | #define VCN_AON_IP_ADDRESS_2_0 0x30000 |
| 72 | 71 | ||
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
| 26 | #include <drm/ttm/ttm_range_manager.h> | 26 | #include <drm/ttm/ttm_range_manager.h> |
| 27 | #include <drm/drm_drv.h> | ||
| 27 | 28 | ||
| 28 | #include "amdgpu.h" | 29 | #include "amdgpu.h" |
| 29 | #include "amdgpu_vm.h" | 30 | #include "amdgpu_vm.h" |
| @@ -907,6 +908,9 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) · 877 unmodified lines | |||
| 907 | struct ttm_resource_manager *man = &mgr->manager; | 908 | struct ttm_resource_manager *man = &mgr->manager; |
| 908 | int err; | 909 | int err; |
| 909 | 910 | ||
| 911 | man->cg = drmm_cgroup_register_region(adev_to_drm(adev), "vram", adev->gmc.real_vram_size); | ||
| 912 | if (IS_ERR(man->cg)) | ||
| 913 | return PTR_ERR(man->cg); | ||
| 910 | ttm_resource_manager_init(man, &adev->mman.bdev, | 914 | ttm_resource_manager_init(man, &adev->mman.bdev, |
| 911 | adev->gmc.real_vram_size); | 915 | adev->gmc.real_vram_size); |
| 912 | 916 | ||
| @@ -6114,7 +6114,7 @@ static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev) · 6113 unmodified lines | |||
| 6114 | } | 6114 | } |
| 6115 | 6115 | ||
| 6116 | if (amdgpu_emu_mode == 1) | 6116 | if (amdgpu_emu_mode == 1) |
| 6117 | adev->hdp.funcs->flush_hdp(adev, NULL); | 6117 | amdgpu_device_flush_hdp(adev, NULL); |
| 6118 | 6118 | ||
| 6119 | tmp = RREG32_SOC15(GC, 0, mmCP_PFP_IC_BASE_CNTL); | 6119 | tmp = RREG32_SOC15(GC, 0, mmCP_PFP_IC_BASE_CNTL); |
| 6120 | tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0); | 6120 | 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) · 71 unmodified lines | |||
| 6192 | } | 6192 | } |
| 6193 | 6193 | ||
| 6194 | if (amdgpu_emu_mode == 1) | 6194 | if (amdgpu_emu_mode == 1) |
| 6195 | adev->hdp.funcs->flush_hdp(adev, NULL); | 6195 | amdgpu_device_flush_hdp(adev, NULL); |
| 6196 | 6196 | ||
| 6197 | tmp = RREG32_SOC15(GC, 0, mmCP_CE_IC_BASE_CNTL); | 6197 | tmp = RREG32_SOC15(GC, 0, mmCP_CE_IC_BASE_CNTL); |
| 6198 | tmp = REG_SET_FIELD(tmp, CP_CE_IC_BASE_CNTL, VMID, 0); | 6198 | 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) · 70 unmodified lines | |||
| 6269 | } | 6269 | } |
| 6270 | 6270 | ||
| 6271 | if (amdgpu_emu_mode == 1) | 6271 | if (amdgpu_emu_mode == 1) |
| 6272 | adev->hdp.funcs->flush_hdp(adev, NULL); | 6272 | amdgpu_device_flush_hdp(adev, NULL); |
| 6273 | 6273 | ||
| 6274 | tmp = RREG32_SOC15(GC, 0, mmCP_ME_IC_BASE_CNTL); | 6274 | tmp = RREG32_SOC15(GC, 0, mmCP_ME_IC_BASE_CNTL); |
| 6275 | tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0); | 6275 | 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) · 368 unmodified lines | |||
| 6644 | } | 6644 | } |
| 6645 | 6645 | ||
| 6646 | if (amdgpu_emu_mode == 1) | 6646 | if (amdgpu_emu_mode == 1) |
| 6647 | adev->hdp.funcs->flush_hdp(adev, NULL); | 6647 | amdgpu_device_flush_hdp(adev, NULL); |
| 6648 | 6648 | ||
| 6649 | tmp = RREG32_SOC15(GC, 0, mmCP_CPC_IC_BASE_CNTL); | 6649 | tmp = RREG32_SOC15(GC, 0, mmCP_CPC_IC_BASE_CNTL); |
| 6650 | tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0); | 6650 | 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) · 2427 unmodified lines | |||
| 2428 | } | 2428 | } |
| 2429 | 2429 | ||
| 2430 | if (amdgpu_emu_mode == 1) | 2430 | if (amdgpu_emu_mode == 1) |
| 2431 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2431 | amdgpu_device_flush_hdp(adev, NULL); |
| 2432 | 2432 | ||
| 2433 | tmp = RREG32_SOC15(GC, 0, regCP_ME_IC_BASE_CNTL); | 2433 | tmp = RREG32_SOC15(GC, 0, regCP_ME_IC_BASE_CNTL); |
| 2434 | tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0); | 2434 | 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) · 37 unmodified lines | |||
| 2472 | } | 2472 | } |
| 2473 | 2473 | ||
| 2474 | if (amdgpu_emu_mode == 1) | 2474 | if (amdgpu_emu_mode == 1) |
| 2475 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2475 | amdgpu_device_flush_hdp(adev, NULL); |
| 2476 | 2476 | ||
| 2477 | tmp = RREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_CNTL); | 2477 | tmp = RREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_CNTL); |
| 2478 | tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0); | 2478 | 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) · 38 unmodified lines | |||
| 2517 | } | 2517 | } |
| 2518 | 2518 | ||
| 2519 | if (amdgpu_emu_mode == 1) | 2519 | if (amdgpu_emu_mode == 1) |
| 2520 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2520 | amdgpu_device_flush_hdp(adev, NULL); |
| 2521 | 2521 | ||
| 2522 | tmp = RREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_CNTL); | 2522 | tmp = RREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_CNTL); |
| 2523 | tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0); | 2523 | 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) · 629 unmodified lines | |||
| 3153 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); | 3153 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); |
| 3154 | 3154 | ||
| 3155 | if (amdgpu_emu_mode == 1) | 3155 | if (amdgpu_emu_mode == 1) |
| 3156 | adev->hdp.funcs->flush_hdp(adev, NULL); | 3156 | amdgpu_device_flush_hdp(adev, NULL); |
| 3157 | 3157 | ||
| 3158 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, | 3158 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, |
| 3159 | lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr)); | 3159 | 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) · 211 unmodified lines | |||
| 3371 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); | 3371 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); |
| 3372 | 3372 | ||
| 3373 | if (amdgpu_emu_mode == 1) | 3373 | if (amdgpu_emu_mode == 1) |
| 3374 | adev->hdp.funcs->flush_hdp(adev, NULL); | 3374 | amdgpu_device_flush_hdp(adev, NULL); |
| 3375 | 3375 | ||
| 3376 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, | 3376 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, |
| 3377 | lower_32_bits(adev->gfx.me.me_fw_gpu_addr)); | 3377 | 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) · 1163 unmodified lines | |||
| 4541 | if (r) | 4541 | if (r) |
| 4542 | return r; | 4542 | return r; |
| 4543 | 4543 | ||
| 4544 | adev->hdp.funcs->flush_hdp(adev, NULL); | 4544 | amdgpu_device_flush_hdp(adev, NULL); |
| 4545 | 4545 | ||
| 4546 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? | 4546 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 4547 | false : true; | 4547 | false : true; |
| @@ -2324,7 +2324,7 @@ static int gfx_v12_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev) · 2323 unmodified lines | |||
| 2324 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); | 2324 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); |
| 2325 | 2325 | ||
| 2326 | if (amdgpu_emu_mode == 1) | 2326 | if (amdgpu_emu_mode == 1) |
| 2327 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2327 | amdgpu_device_flush_hdp(adev, NULL); |
| 2328 | 2328 | ||
| 2329 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, | 2329 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, |
| 2330 | lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr)); | 2330 | 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) · 137 unmodified lines | |||
| 2468 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); | 2468 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); |
| 2469 | 2469 | ||
| 2470 | if (amdgpu_emu_mode == 1) | 2470 | if (amdgpu_emu_mode == 1) |
| 2471 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2471 | amdgpu_device_flush_hdp(adev, NULL); |
| 2472 | 2472 | ||
| 2473 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, | 2473 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, |
| 2474 | lower_32_bits(adev->gfx.me.me_fw_gpu_addr)); | 2474 | 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) · 951 unmodified lines | |||
| 3426 | if (r) | 3426 | if (r) |
| 3427 | return r; | 3427 | return r; |
| 3428 | 3428 | ||
| 3429 | adev->hdp.funcs->flush_hdp(adev, NULL); | 3429 | amdgpu_device_flush_hdp(adev, NULL); |
| 3430 | 3430 | ||
| 3431 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? | 3431 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 3432 | false : true; | 3432 | false : true; |
| @@ -268,7 +268,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 267 unmodified lines | |||
| 268 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; | 268 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; |
| 269 | 269 | ||
| 270 | /* flush hdp cache */ | 270 | /* flush hdp cache */ |
| 271 | adev->hdp.funcs->flush_hdp(adev, NULL); | 271 | amdgpu_device_flush_hdp(adev, NULL); |
| 272 | 272 | ||
| 273 | /* This is necessary for SRIOV as well as for GFXOFF to function | 273 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 274 | * properly under bare metal | 274 | * properly under bare metal |
| @@ -969,7 +969,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) · 694 unmodified lines | |||
| 969 | adev->hdp.funcs->init_registers(adev); | 969 | adev->hdp.funcs->init_registers(adev); |
| 970 | 970 | ||
| 971 | /* Flush HDP after it is initialized */ | 971 | /* Flush HDP after it is initialized */ |
| 972 | adev->hdp.funcs->flush_hdp(adev, NULL); | 972 | amdgpu_device_flush_hdp(adev, NULL); |
| 973 | 973 | ||
| 974 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? | 974 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 975 | false : true; | 975 | false : true; |
| @@ -229,7 +229,7 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 228 unmodified lines | |||
| 229 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; | 229 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; |
| 230 | 230 | ||
| 231 | /* flush hdp cache */ | 231 | /* flush hdp cache */ |
| 232 | adev->hdp.funcs->flush_hdp(adev, NULL); | 232 | amdgpu_device_flush_hdp(adev, NULL); |
| 233 | 233 | ||
| 234 | /* This is necessary for SRIOV as well as for GFXOFF to function | 234 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 235 | * properly under bare metal | 235 | * properly under bare metal |
| @@ -752,6 +752,18 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block) · 516 unmodified lines | |||
| 752 | adev->gmc.vram_type = vram_type; | 752 | adev->gmc.vram_type = vram_type; |
| 753 | adev->gmc.vram_vendor = vram_vendor; | 753 | adev->gmc.vram_vendor = vram_vendor; |
| 754 | 754 | ||
| 755 | /* The mall_size is already calculated as mall_size_per_umc * num_umc. | ||
| 756 | * However, for gfx1151, which features a 2-to-1 UMC mapping, | ||
| 757 | * the result must be multiplied by 2 to determine the actual mall size. | ||
| 758 | */ | ||
| 759 | switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { | ||
| 760 | case IP_VERSION(11, 5, 1): | ||
| 761 | adev->gmc.mall_size *= 2; | ||
| 762 | break; | ||
| 763 | default: | ||
| 764 | break; | ||
| 765 | } | ||
| 766 | |||
| 755 | switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { | 767 | switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { |
| 756 | case IP_VERSION(11, 0, 0): | 768 | case IP_VERSION(11, 0, 0): |
| 757 | case IP_VERSION(11, 0, 1): | 769 | case IP_VERSION(11, 0, 1): |
| @@ -899,7 +911,7 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device *adev) · 141 unmodified lines | |||
| 899 | return r; | 911 | return r; |
| 900 | 912 | ||
| 901 | /* Flush HDP after it is initialized */ | 913 | /* Flush HDP after it is initialized */ |
| 902 | adev->hdp.funcs->flush_hdp(adev, NULL); | 914 | amdgpu_device_flush_hdp(adev, NULL); |
| 903 | 915 | ||
| 904 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? | 916 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 905 | false : true; | 917 | false : true; |
| @@ -297,7 +297,7 @@ static void gmc_v12_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, · 296 unmodified lines | |||
| 297 | return; | 297 | return; |
| 298 | 298 | ||
| 299 | /* flush hdp cache */ | 299 | /* flush hdp cache */ |
| 300 | adev->hdp.funcs->flush_hdp(adev, NULL); | 300 | amdgpu_device_flush_hdp(adev, NULL); |
| 301 | 301 | ||
| 302 | /* This is necessary for SRIOV as well as for GFXOFF to function | 302 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 303 | * properly under bare metal | 303 | * properly under bare metal |
| @@ -881,7 +881,7 @@ static int gmc_v12_0_gart_enable(struct amdgpu_device *adev) · 577 unmodified lines | |||
| 881 | return r; | 881 | return r; |
| 882 | 882 | ||
| 883 | /* Flush HDP after it is initialized */ | 883 | /* Flush HDP after it is initialized */ |
| 884 | adev->hdp.funcs->flush_hdp(adev, NULL); | 884 | amdgpu_device_flush_hdp(adev, NULL); |
| 885 | 885 | ||
| 886 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? | 886 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 887 | false : true; | 887 | false : true; |
| @@ -2435,7 +2435,7 @@ static int gmc_v9_0_hw_init(struct amdgpu_ip_block *ip_block) · 2434 unmodified lines | |||
| 2435 | adev->hdp.funcs->init_registers(adev); | 2435 | adev->hdp.funcs->init_registers(adev); |
| 2436 | 2436 | ||
| 2437 | /* After HDP is initialized, flush HDP.*/ | 2437 | /* After HDP is initialized, flush HDP.*/ |
| 2438 | adev->hdp.funcs->flush_hdp(adev, NULL); | 2438 | amdgpu_device_flush_hdp(adev, NULL); |
| 2439 | 2439 | ||
| 2440 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) | 2440 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) |
| 2441 | value = false; | 2441 | value = false; |
| @@ -41,7 +41,12 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev, · 40 unmodified lines | |||
| 41 | { | 41 | { |
| 42 | if (!ring || !ring->funcs->emit_wreg) { | 42 | if (!ring || !ring->funcs->emit_wreg) { |
| 43 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 43 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 44 | RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | 44 | /* We just need to read back a register to post the write. |
| 45 | * Reading back the remapped register causes problems on | ||
| 46 | * some platforms so just read back the memory size register. | ||
| 47 | */ | ||
| 48 | if (adev->nbio.funcs->get_memsize) | ||
| 49 | adev->nbio.funcs->get_memsize(adev); | ||
| 45 | } else { | 50 | } else { |
| 46 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 51 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 47 | } | 52 | } |
| @@ -32,7 +32,12 @@ static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev, · 31 unmodified lines | |||
| 32 | { | 32 | { |
| 33 | if (!ring || !ring->funcs->emit_wreg) { | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 34 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 35 | RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | 35 | /* We just need to read back a register to post the write. |
| 36 | * Reading back the remapped register causes problems on | ||
| 37 | * some platforms so just read back the memory size register. | ||
| 38 | */ | ||
| 39 | if (adev->nbio.funcs->get_memsize) | ||
| 40 | adev->nbio.funcs->get_memsize(adev); | ||
| 36 | } else { | 41 | } else { |
| 37 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 42 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 38 | } | 43 | } |
| @@ -33,7 +33,17 @@ static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev, · 32 unmodified lines | |||
| 33 | if (!ring || !ring->funcs->emit_wreg) { | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, | 34 | WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, |
| 35 | 0); | 35 | 0); |
| 36 | RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | 36 | if (amdgpu_sriov_vf(adev)) { |
| 37 | /* this is fine because SR_IOV doesn't remap the register */ | ||
| 38 | RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | ||
| 39 | } else { | ||
| 40 | /* We just need to read back a register to post the write. | ||
| 41 | * Reading back the remapped register causes problems on | ||
| 42 | * some platforms so just read back the memory size register. | ||
| 43 | */ | ||
| 44 | if (adev->nbio.funcs->get_memsize) | ||
| 45 | adev->nbio.funcs->get_memsize(adev); | ||
| 46 | } | ||
| 37 | } else { | 47 | } else { |
| 38 | amdgpu_ring_emit_wreg(ring, | 48 | amdgpu_ring_emit_wreg(ring, |
| 39 | (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, | 49 | (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, |
| @@ -35,7 +35,12 @@ static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev, · 34 unmodified lines | |||
| 35 | { | 35 | { |
| 36 | if (!ring || !ring->funcs->emit_wreg) { | 36 | if (!ring || !ring->funcs->emit_wreg) { |
| 37 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 37 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 38 | RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | 38 | /* We just need to read back a register to post the write. |
| 39 | * Reading back the remapped register causes problems on | ||
| 40 | * some platforms so just read back the memory size register. | ||
| 41 | */ | ||
| 42 | if (adev->nbio.funcs->get_memsize) | ||
| 43 | adev->nbio.funcs->get_memsize(adev); | ||
| 39 | } else { | 44 | } else { |
| 40 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 45 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 41 | } | 46 | } |
| @@ -32,7 +32,12 @@ static void hdp_v7_0_flush_hdp(struct amdgpu_device *adev, · 31 unmodified lines | |||
| 32 | { | 32 | { |
| 33 | if (!ring || !ring->funcs->emit_wreg) { | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 34 | WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 35 | RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); | 35 | /* We just need to read back a register to post the write. |
| 36 | * Reading back the remapped register causes problems on | ||
| 37 | * some platforms so just read back the memory size register. | ||
| 38 | */ | ||
| 39 | if (adev->nbio.funcs->get_memsize) | ||
| 40 | adev->nbio.funcs->get_memsize(adev); | ||
| 36 | } else { | 41 | } else { |
| 37 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | 42 | amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); |
| 38 | } | 43 | } |
| @@ -894,6 +894,10 @@ static void mes_v11_0_get_fw_version(struct amdgpu_device *adev) · 893 unmodified lines | |||
| 894 | { | 894 | { |
| 895 | int pipe; | 895 | int pipe; |
| 896 | 896 | ||
| 897 | /* return early if we have already fetched these */ | ||
| 898 | if (adev->mes.sched_version && adev->mes.kiq_version) | ||
| 899 | return; | ||
| 900 | |||
| 897 | /* get MES scheduler/KIQ versions */ | 901 | /* get MES scheduler/KIQ versions */ |
| 898 | mutex_lock(&adev->srbm_mutex); | 902 | mutex_lock(&adev->srbm_mutex); |
| 899 | 903 | ||
| @@ -1392,17 +1392,20 @@ static int mes_v12_0_queue_init(struct amdgpu_device *adev, · 1391 unmodified lines | |||
| 1392 | mes_v12_0_queue_init_register(ring); | 1392 | mes_v12_0_queue_init_register(ring); |
| 1393 | } | 1393 | } |
| 1394 | 1394 | ||
| 1395 | /* get MES scheduler/KIQ versions */ | 1395 | if (((pipe == AMDGPU_MES_SCHED_PIPE) && !adev->mes.sched_version) || |
| 1396 | mutex_lock(&adev->srbm_mutex); | 1396 | ((pipe == AMDGPU_MES_KIQ_PIPE) && !adev->mes.kiq_version)) { |
| 1397 | soc21_grbm_select(adev, 3, pipe, 0, 0); | 1397 | /* get MES scheduler/KIQ versions */ |
| 1398 | mutex_lock(&adev->srbm_mutex); | ||
| 1399 | soc21_grbm_select(adev, 3, pipe, 0, 0); | ||
| 1398 | 1400 | ||
| 1399 | if (pipe == AMDGPU_MES_SCHED_PIPE) | 1401 | if (pipe == AMDGPU_MES_SCHED_PIPE) |
| 1400 | adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); | 1402 | adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); |
| 1401 | else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) | 1403 | else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) |
| 1402 | adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); | 1404 | adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); |
| 1403 | 1405 | ||
8 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 453 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 349 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 170 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 389 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 474 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 250 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 314 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 170 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 727 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 308 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 405 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 369 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 599 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 370 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 242 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 386 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 324 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 828 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 667 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 453 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 449 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 266 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 318 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 236 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 916 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 422 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 448 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 597 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 233 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.