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 | 92 | - '__rq_for_each_bio' |
| 93 | 93 | - '__shost_for_each_device' |
| 94 | 94 | - '__sym_for_each' |
| 95 | + - '_for_each_counter' | |
| 95 | 96 | - 'apei_estatus_for_each_section' |
| 96 | 97 | - 'ata_for_each_dev' |
| 97 | 98 | - 'ata_for_each_link' |
| @@ -141,11 +142,14 @@ ForEachMacros: · 43 unmodified lines | ||
| 141 | 142 | - 'damon_for_each_target_safe' |
| 142 | 143 | - 'damos_for_each_filter' |
| 143 | 144 | - 'damos_for_each_filter_safe' |
| 145 | + - 'damos_for_each_ops_filter' | |
| 146 | + - 'damos_for_each_ops_filter_safe' | |
| 144 | 147 | - 'damos_for_each_quota_goal' |
| 145 | 148 | - 'damos_for_each_quota_goal_safe' |
| 146 | 149 | - 'data__for_each_file' |
| 147 | 150 | - 'data__for_each_file_new' |
| 148 | 151 | - 'data__for_each_file_start' |
| 152 | + - 'def_for_each_cpu' | |
| 149 | 153 | - 'device_for_each_child_node' |
| 150 | 154 | - 'device_for_each_child_node_scoped' |
| 151 | 155 | - 'dma_fence_array_for_each' |
| @@ -176,6 +180,7 @@ ForEachMacros: · 24 unmodified lines | ||
| 176 | 180 | - 'drm_for_each_privobj' |
| 177 | 181 | - 'drm_gem_for_each_gpuvm_bo' |
| 178 | 182 | - 'drm_gem_for_each_gpuvm_bo_safe' |
| 183 | + - 'drm_gpusvm_for_each_range' | |
| 179 | 184 | - 'drm_gpuva_for_each_op' |
| 180 | 185 | - 'drm_gpuva_for_each_op_from_reverse' |
| 181 | 186 | - 'drm_gpuva_for_each_op_reverse' |
| @@ -216,8 +221,10 @@ ForEachMacros: · 34 unmodified lines | ||
| 216 | 221 | - 'for_each_active_dev_scope' |
| 217 | 222 | - 'for_each_active_drhd_unit' |
| 218 | 223 | - 'for_each_active_iommu' |
| 224 | + - 'for_each_active_irq' | |
| 219 | 225 | - 'for_each_active_route' |
| 220 | 226 | - 'for_each_aggr_pgid' |
| 227 | + - 'for_each_alloc_capable_rdt_resource' | |
| 221 | 228 | - 'for_each_and_bit' |
| 222 | 229 | - 'for_each_andnot_bit' |
| 223 | 230 | - 'for_each_available_child_of_node' |
| @@ -228,6 +235,7 @@ ForEachMacros: · 4 unmodified lines | ||
| 228 | 235 | - 'for_each_btf_ext_rec' |
| 229 | 236 | - 'for_each_btf_ext_sec' |
| 230 | 237 | - 'for_each_bvec' |
| 238 | + - 'for_each_capable_rdt_resource' | |
| 231 | 239 | - 'for_each_card_auxs' |
| 232 | 240 | - 'for_each_card_auxs_safe' |
| 233 | 241 | - 'for_each_card_components' |
| @@ -241,6 +249,7 @@ ForEachMacros: · 7 unmodified lines | ||
| 241 | 249 | - 'for_each_cgroup_storage_type' |
| 242 | 250 | - 'for_each_child_of_node' |
| 243 | 251 | - 'for_each_child_of_node_scoped' |
| 252 | + - 'for_each_child_of_node_with_prefix' | |
| 244 | 253 | - 'for_each_clear_bit' |
| 245 | 254 | - 'for_each_clear_bit_from' |
| 246 | 255 | - 'for_each_clear_bitrange' |
| @@ -296,6 +305,7 @@ ForEachMacros: · 49 unmodified lines | ||
| 296 | 305 | - 'for_each_group_member_head' |
| 297 | 306 | - 'for_each_hstate' |
| 298 | 307 | - 'for_each_hwgpio' |
| 308 | + - 'for_each_hwgpio_in_range' | |
| 299 | 309 | - 'for_each_if' |
| 300 | 310 | - 'for_each_inject_fn' |
| 301 | 311 | - 'for_each_insn' |
| @@ -304,6 +314,7 @@ ForEachMacros: · 2 unmodified lines | ||
| 304 | 314 | - 'for_each_intid' |
| 305 | 315 | - 'for_each_iommu' |
| 306 | 316 | - 'for_each_ip_tunnel_rcu' |
| 317 | + - 'for_each_irq_desc' | |
| 307 | 318 | - 'for_each_irq_nr' |
| 308 | 319 | - 'for_each_lang' |
| 309 | 320 | - 'for_each_link_ch_maps' |
| @@ -324,6 +335,8 @@ ForEachMacros: · 14 unmodified lines | ||
| 324 | 335 | - 'for_each_missing_reg' |
| 325 | 336 | - 'for_each_mle_subelement' |
| 326 | 337 | - 'for_each_mod_mem_type' |
| 338 | + - 'for_each_mon_capable_rdt_resource' | |
| 339 | + - 'for_each_mp_bvec' | |
| 327 | 340 | - 'for_each_net' |
| 328 | 341 | - 'for_each_net_continue_reverse' |
| 329 | 342 | - 'for_each_net_rcu' |
| @@ -351,6 +364,7 @@ ForEachMacros: · 21 unmodified lines | ||
| 351 | 364 | - 'for_each_node_by_name' |
| 352 | 365 | - 'for_each_node_by_type' |
| 353 | 366 | - 'for_each_node_mask' |
| 367 | + - 'for_each_node_numadist' | |
| 354 | 368 | - 'for_each_node_state' |
| 355 | 369 | - 'for_each_node_with_cpus' |
| 356 | 370 | - 'for_each_node_with_property' |
| @@ -359,6 +373,8 @@ ForEachMacros: · 2 unmodified lines | ||
| 359 | 373 | - 'for_each_of_allnodes' |
| 360 | 374 | - 'for_each_of_allnodes_from' |
| 361 | 375 | - 'for_each_of_cpu_node' |
| 376 | + - 'for_each_of_graph_port' | |
| 377 | + - 'for_each_of_graph_port_endpoint' | |
| 362 | 378 | - 'for_each_of_pci_range' |
| 363 | 379 | - 'for_each_old_connector_in_state' |
| 364 | 380 | - 'for_each_old_crtc_in_state' |
| @@ -372,9 +388,11 @@ ForEachMacros: · 7 unmodified lines | ||
| 372 | 388 | - 'for_each_oldnew_plane_in_state_reverse' |
| 373 | 389 | - 'for_each_oldnew_private_obj_in_state' |
| 374 | 390 | - 'for_each_online_cpu' |
| 391 | + - 'for_each_online_cpu_wrap' | |
| 375 | 392 | - 'for_each_online_node' |
| 376 | 393 | - 'for_each_online_pgdat' |
| 377 | 394 | - 'for_each_or_bit' |
| 395 | + - 'for_each_page_ext' | |
| 378 | 396 | - 'for_each_path' |
| 379 | 397 | - 'for_each_pci_bridge' |
| 380 | 398 | - 'for_each_pci_dev' |
| @@ -382,8 +400,10 @@ ForEachMacros: · 1 unmodified line | ||
| 382 | 400 | - 'for_each_physmem_range' |
| 383 | 401 | - 'for_each_populated_zone' |
| 384 | 402 | - 'for_each_possible_cpu' |
| 403 | + - 'for_each_possible_cpu_wrap' | |
| 385 | 404 | - 'for_each_present_blessed_reg' |
| 386 | 405 | - 'for_each_present_cpu' |
| 406 | + - 'for_each_present_section_nr' | |
| 387 | 407 | - 'for_each_prime_number' |
| 388 | 408 | - 'for_each_prime_number_from' |
| 389 | 409 | - 'for_each_probe_cache_entry' |
| @@ -396,6 +416,7 @@ ForEachMacros: · 6 unmodified lines | ||
| 396 | 416 | - 'for_each_prop_dlc_cpus' |
| 397 | 417 | - 'for_each_prop_dlc_platforms' |
| 398 | 418 | - 'for_each_property_of_node' |
| 419 | + - 'for_each_rdt_resource' | |
| 399 | 420 | - 'for_each_reg' |
| 400 | 421 | - 'for_each_reg_filtered' |
| 401 | 422 | - 'for_each_reloc' |
| @@ -434,10 +455,10 @@ ForEachMacros: · 32 unmodified lines | ||
| 434 | 455 | - 'for_each_subelement_id' |
| 435 | 456 | - 'for_each_sublist' |
| 436 | 457 | - 'for_each_subsystem' |
| 458 | + - 'for_each_suite' | |
| 437 | 459 | - 'for_each_supported_activate_fn' |
| 438 | 460 | - 'for_each_supported_inject_fn' |
| 439 | 461 | - 'for_each_sym' |
| 440 | − - 'for_each_test' | |
| 441 | 462 | - 'for_each_thread' |
| 442 | 463 | - 'for_each_token' |
| 443 | 464 | - 'for_each_unicast_dest_pgid' |
| @@ -499,8 +520,10 @@ ForEachMacros: · 55 unmodified lines | ||
| 499 | 520 | - 'idr_for_each_entry_continue' |
| 500 | 521 | - 'idr_for_each_entry_continue_ul' |
| 501 | 522 | - 'idr_for_each_entry_ul' |
| 523 | + - 'iio_for_each_active_channel' | |
| 502 | 524 | - 'in_dev_for_each_ifa_rcu' |
| 503 | 525 | - 'in_dev_for_each_ifa_rtnl' |
| 526 | + - 'in_dev_for_each_ifa_rtnl_net' | |
| 504 | 527 | - 'inet_bind_bucket_for_each' |
| 505 | 528 | - 'interval_tree_for_each_span' |
| 506 | 529 | - 'intlist__for_each_entry' |
| @@ -542,7 +565,6 @@ ForEachMacros: · 35 unmodified lines | ||
| 542 | 565 | - 'list_for_each_prev' |
| 543 | 566 | - 'list_for_each_prev_safe' |
| 544 | 567 | - 'list_for_each_rcu' |
| 545 | − - 'list_for_each_reverse' | |
| 546 | 568 | - 'list_for_each_safe' |
| 547 | 569 | - 'llist_for_each' |
| 548 | 570 | - 'llist_for_each_entry' |
| @@ -552,6 +574,7 @@ ForEachMacros: · 3 unmodified lines | ||
| 552 | 574 | - 'map__for_each_symbol' |
| 553 | 575 | - 'map__for_each_symbol_by_name' |
| 554 | 576 | - 'mas_for_each' |
| 577 | + - 'mas_for_each_rev' | |
| 555 | 578 | - 'mci_for_each_dimm' |
| 556 | 579 | - 'media_device_for_each_entity' |
| 557 | 580 | - 'media_device_for_each_intf' |
| @@ -561,10 +584,15 @@ ForEachMacros: · 3 unmodified lines | ||
| 561 | 584 | - 'media_pipeline_for_each_entity' |
| 562 | 585 | - 'media_pipeline_for_each_pad' |
| 563 | 586 | - 'mlx5_lag_for_each_peer_mdev' |
| 587 | + - 'mptcp_for_each_subflow' | |
| 564 | 588 | - 'msi_domain_for_each_desc' |
| 565 | 589 | - 'msi_for_each_desc' |
| 566 | 590 | - 'mt_for_each' |
| 591 | + - 'nanddev_io_for_each_block' | |
| 567 | 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 | 596 | - 'netdev_for_each_lower_dev' |
| 569 | 597 | - 'netdev_for_each_lower_private' |
| 570 | 598 | - 'netdev_for_each_lower_private_rcu' |
| @@ -604,11 +632,11 @@ ForEachMacros: · 33 unmodified lines | ||
| 604 | 632 | - 'perf_evlist__for_each_entry_safe' |
| 605 | 633 | - 'perf_evlist__for_each_evsel' |
| 606 | 634 | - 'perf_evlist__for_each_mmap' |
| 635 | + - 'perf_evsel_for_each_per_thread_period_safe' | |
| 607 | 636 | - 'perf_hpp_list__for_each_format' |
| 608 | 637 | - 'perf_hpp_list__for_each_format_safe' |
| 609 | 638 | - 'perf_hpp_list__for_each_sort_list' |
| 610 | 639 | - 'perf_hpp_list__for_each_sort_list_safe' |
| 611 | − - 'perf_tool_event__for_each_event' | |
| 612 | 640 | - 'plist_for_each' |
| 613 | 641 | - 'plist_for_each_continue' |
| 614 | 642 | - 'plist_for_each_entry' |
| @@ -627,7 +655,6 @@ ForEachMacros: · 12 unmodified lines | ||
| 627 | 655 | - 'rdma_for_each_block' |
| 628 | 656 | - 'rdma_for_each_port' |
| 629 | 657 | - 'rdma_umem_for_each_dma_block' |
| 630 | − - 'resort_rb__for_each_entry' | |
| 631 | 658 | - 'resource_list_for_each_entry' |
| 632 | 659 | - 'resource_list_for_each_entry_safe' |
| 633 | 660 | - 'rhl_for_each_entry_rcu' |
| @@ -658,6 +685,7 @@ ForEachMacros: · 24 unmodified lines | ||
| 658 | 685 | - 'shost_for_each_device' |
| 659 | 686 | - 'sk_for_each' |
| 660 | 687 | - 'sk_for_each_bound' |
| 688 | + - 'sk_for_each_bound_safe' | |
| 661 | 689 | - 'sk_for_each_entry_offset_rcu' |
| 662 | 690 | - 'sk_for_each_from' |
| 663 | 691 | - 'sk_for_each_rcu' |
| @@ -680,7 +708,11 @@ ForEachMacros: · 16 unmodified lines | ||
| 680 | 708 | - 'tb_property_for_each' |
| 681 | 709 | - 'tcf_act_for_each_action' |
| 682 | 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 | 714 | - 'ttm_resource_manager_for_each_res' |
| 715 | + - 'udp_lrpa_for_each_entry_rcu' | |
| 684 | 716 | - 'udp_portaddr_for_each_entry' |
| 685 | 717 | - 'udp_portaddr_for_each_entry_rcu' |
| 686 | 718 | - 'usb_hub_for_each_child' |
| @@ -691,6 +723,7 @@ ForEachMacros: · 4 unmodified lines | ||
| 691 | 723 | - 'v4l2_m2m_for_each_src_buf_safe' |
| 692 | 724 | - 'virtio_device_for_each_vq' |
| 693 | 725 | - 'while_for_each_ftrace_op' |
| 726 | + - 'workloads__for_each' | |
| 694 | 727 | - 'xa_for_each' |
| 695 | 728 | - 'xa_for_each_marked' |
| 696 | 729 | - 'xa_for_each_range' |
| @@ -7,5 +7,5 @@ check-private-items = true · 6 unmodified lines | ||
| 7 | 7 | disallowed-macros = [ |
| 8 | 8 | # The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate |
| 9 | 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 | 102 | Arnaud Patard <arnaud.patard@rtp-net.org> |
| 103 | 103 | Arnd Bergmann <arnd@arndb.de> |
| 104 | 104 | Arun Kumar Neelakantam <quic_aneela@quicinc.com> <aneela@codeaurora.org> |
| 105 | +Asahi Lina <lina+kernel@asahilina.net> <lina@asahilina.net> | |
| 105 | 106 | Ashok Raj Nagarajan <quic_arnagara@quicinc.com> <arnagara@codeaurora.org> |
| 106 | 107 | Ashwin Chaugule <quic_ashwinc@quicinc.com> <ashwinc@codeaurora.org> |
| 107 | 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 | 313 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> |
| 313 | 314 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 314 | 315 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> |
| 316 | +Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@opinsys.com> | |
| 315 | 317 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 316 | 318 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 317 | 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 | 324 | Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com> |
| 323 | 325 | Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com> |
| 324 | 326 | <jean-philippe@linaro.org> <jean-philippe.brucker@arm.com> |
| 327 | +Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org> <jeanmichel.hautbois@ideasonboard.com> | |
| 325 | 328 | Jean Tourrilhes <jt@hpl.hp.com> |
| 326 | 329 | Jeevan Shriram <quic_jshriram@quicinc.com> <jshriram@codeaurora.org> |
| 327 | 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 | 441 | Li Yang <leoyang.li@nxp.com> <leoli@freescale.com> |
| 439 | 442 | Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org> |
| 440 | 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 | 446 | Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com> |
| 442 | 447 | Lorenzo Stoakes <lorenzo.stoakes@oracle.com> <lstoakes@gmail.com> |
| 443 | 448 | Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net> |
| 444 | 449 | Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz> |
| 445 | 450 | Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com> |
| 446 | 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 | 454 | Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com> |
| 448 | 455 | Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org> |
| 449 | 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 | 487 | Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net> |
| 481 | 488 | Matthieu CASTET <castet.matthieu@free.fr> |
| 482 | 489 | Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com> |
| 490 | +Mattijs Korpershoek <mkorpershoek@kernel.org> <mkorpershoek@baylibre.com> | |
| 483 | 491 | Matt Ranostay <matt@ranostay.sg> <matt.ranostay@konsulko.com> |
| 484 | 492 | Matt Ranostay <matt@ranostay.sg> <matt@ranostay.consulting> |
| 485 | 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 | 693 | Simon Wunderlich <sw@simonwunderlich.de> <simon@open-mesh.com> |
| 686 | 694 | Simon Wunderlich <sw@simonwunderlich.de> <siwu@hrz.tu-chemnitz.de> |
| 687 | 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 | 698 | Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org> |
| 689 | 699 | Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org> |
| 690 | 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 | 754 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> |
| 745 | 755 | Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> |
| 746 | 756 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> |
| 757 | +Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com> | |
| 747 | 758 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> |
| 748 | 759 | Uwe Kleine-König <ukleinek@strlen.de> |
| 749 | 760 | Uwe Kleine-König <ukl@pengutronix.de> |
| @@ -2071,6 +2071,10 @@ S: 660 Harvard Ave. #7 · 2070 unmodified lines | ||
| 2071 | 2071 | S: Santa Clara, CA 95051 |
| 2072 | 2072 | S: USA |
| 2073 | 2073 | |
| 2074 | +N: Joonsoo Kim | |
| 2075 | +E: iamjoonsoo.kim@lge.com | |
| 2076 | +D: Slab allocators | |
| 2077 | + | |
| 2074 | 2078 | N: Kukjin Kim |
| 2075 | 2079 | E: kgene@kernel.org |
| 2076 | 2080 | D: Samsung S3C, S5P and Exynos ARM architectures |
| @@ -77,7 +77,7 @@ Description: · 76 unmodified lines | ||
| 77 | 77 | |
| 78 | 78 | What: /sys/block/<disk>/diskseq |
| 79 | 79 | Date: February 2021 |
| 80 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 80 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 81 | 81 | Description: |
| 82 | 82 | The /sys/block/<disk>/diskseq files reports the disk |
| 83 | 83 | sequence number, which is a monotonically increasing |
| @@ -511,6 +511,7 @@ Description: information about CPUs heterogeneity. · 510 unmodified lines | ||
| 511 | 511 | |
| 512 | 512 | What: /sys/devices/system/cpu/vulnerabilities |
| 513 | 513 | /sys/devices/system/cpu/vulnerabilities/gather_data_sampling |
| 514 | + /sys/devices/system/cpu/vulnerabilities/indirect_target_selection | |
| 514 | 515 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit |
| 515 | 516 | /sys/devices/system/cpu/vulnerabilities/l1tf |
| 516 | 517 | /sys/devices/system/cpu/vulnerabilities/mds |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | What: /sys/bus/hid/drivers/hid-appletb-kbd/<dev>/mode |
| 2 | −Date: September, 2023 | |
| 3 | −KernelVersion: 6.5 | |
| 2 | +Date: March, 2025 | |
| 3 | +KernelVersion: 6.15 | |
| 4 | 4 | Contact: linux-input@vger.kernel.org |
| 5 | 5 | Description: |
| 6 | 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 | 112 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_input |
| 113 | 113 | Date: March 2025 |
| 114 | −KernelVersion: 6.14 | |
| 114 | +KernelVersion: 6.15 | |
| 115 | 115 | Contact: intel-xe@lists.freedesktop.org |
| 116 | 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 | 120 | What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_input |
| 121 | 121 | Date: March 2025 |
| 122 | −KernelVersion: 6.14 | |
| 122 | +KernelVersion: 6.15 | |
| 123 | 123 | Contact: intel-xe@lists.freedesktop.org |
| 124 | 124 | Description: RO. VRAM temperature in millidegree Celsius. |
| 125 | 125 | |
| @@ -1604,3 +1604,35 @@ Description: · 1603 unmodified lines | ||
| 1604 | 1604 | prevent the UFS from frequently performing clock gating/ungating. |
| 1605 | 1605 | |
| 1606 | 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 | 1 | What: /sys/kernel/reboot |
| 2 | 2 | Date: November 2020 |
| 3 | 3 | KernelVersion: 5.11 |
| 4 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 4 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 5 | 5 | Description: Interface to set the kernel reboot behavior, similarly to |
| 6 | 6 | what can be done via the reboot= cmdline option. |
| 7 | 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 | 9 | What: /sys/kernel/reboot/mode |
| 10 | 10 | Date: November 2020 |
| 11 | 11 | KernelVersion: 5.11 |
| 12 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 12 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 13 | 13 | Description: Reboot mode. Valid values are: cold warm hard soft gpio |
| 14 | 14 | |
| 15 | 15 | What: /sys/kernel/reboot/type |
| 16 | 16 | Date: November 2020 |
| 17 | 17 | KernelVersion: 5.11 |
| 18 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 18 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 19 | 19 | Description: Reboot type. Valid values are: bios acpi kbd triple efi pci |
| 20 | 20 | |
| 21 | 21 | What: /sys/kernel/reboot/cpu |
| 22 | 22 | Date: November 2020 |
| 23 | 23 | KernelVersion: 5.11 |
| 24 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 24 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 25 | 25 | Description: CPU number to use to reboot. |
| 26 | 26 | |
| 27 | 27 | What: /sys/kernel/reboot/force |
| 28 | 28 | Date: November 2020 |
| 29 | 29 | KernelVersion: 5.11 |
| 30 | −Contact: Matteo Croce <mcroce@microsoft.com> | |
| 30 | +Contact: Matteo Croce <teknoraver@meta.com> | |
| 31 | 31 | Description: Don't wait for any other CPUs on reboot and |
| 32 | 32 | avoid anything that could hang. |
| 33 | 33 | |
| @@ -22,3 +22,5 @@ are configurable at compile, boot or run time. · 21 unmodified lines | ||
| 22 | 22 | srso |
| 23 | 23 | gather_data_sampling |
| 24 | 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 | 1407 | earlyprintk=serial[,0x...[,baudrate]] |
| 1408 | 1408 | earlyprintk=ttySn[,baudrate] |
| 1409 | 1409 | earlyprintk=dbgp[debugController#] |
| 1410 | + earlyprintk=mmio32,membase[,{nocfg|baudrate}] | |
| 1410 | 1411 | earlyprintk=pciserial[,force],bus:device.function[,{nocfg|baudrate}] |
| 1411 | 1412 | earlyprintk=xdbc[xhciController#] |
| 1412 | 1413 | earlyprintk=bios |
| 1413 | − earlyprintk=mmio,membase[,{nocfg|baudrate}] | |
| 1414 | 1414 | |
| 1415 | 1415 | earlyprintk is useful when the kernel crashes before |
| 1416 | 1416 | the normal console is initialized. It is not enabled by |
| 1417 | 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 | 1419 | Use "nocfg" to skip UART configuration, assume |
| 1423 | 1420 | BIOS/firmware has configured UART correctly. |
| 1424 | 1421 | |
| @@ -2205,6 +2202,23 @@ · 780 unmodified lines | ||
| 2205 | 2202 | different crypto accelerators. This option can be used |
| 2206 | 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 | 2222 | init= [KNL] |
| 2209 | 2223 | Format: <full_path> |
| 2210 | 2224 | Run specified binary instead of /sbin/init as init |
| @@ -3696,6 +3710,7 @@ · 1485 unmodified lines | ||
| 3696 | 3710 | expose users to several CPU vulnerabilities. |
| 3697 | 3711 | Equivalent to: if nokaslr then kpti=0 [ARM64] |
| 3698 | 3712 | gather_data_sampling=off [X86] |
| 3713 | + indirect_target_selection=off [X86] | |
| 3699 | 3714 | kvm.nx_huge_pages=off [X86] |
| 3700 | 3715 | l1tf=off [X86] |
| 3701 | 3716 | mds=off [X86] |
| @@ -124,6 +124,14 @@ When mounting an XFS filesystem, the following options are accepted. · 123 unmodified lines | ||
| 124 | 124 | controls the size of each buffer and so is also relevant to |
| 125 | 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 | 135 | logbsize=value |
| 128 | 136 | Set the size of each in-memory log buffer. The size may be |
| 129 | 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 | 151 | optional, and the log section can be separate from the data |
| 144 | 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 | 162 | noalign |
| 147 | 163 | Data allocations will not be aligned at stripe unit |
| 148 | 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 | 558 | nice Relative priority of scheduling the threads. These are the |
| 543 | 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 | 8 | For information about OpenRISC processors and ongoing development: |
| 9 | 9 | |
| 10 | − ======= ============================= | |
| 10 | + ======= ============================== | |
| 11 | 11 | website https://openrisc.io |
| 12 | − email openrisc@lists.librecores.org | |
| 13 | − ======= ============================= | |
| 12 | + email linux-openrisc@vger.kernel.org | |
| 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 | 27 | Instructions for building the different toolchains can be found on openrisc.io |
| 28 | 28 | or Stafford's toolchain build and release scripts. |
| 29 | 29 | |
| 30 | − ========== ================================================= | |
| 31 | − binaries https://github.com/openrisc/or1k-gcc/releases | |
| 30 | + ========== ========================================================== | |
| 31 | + binaries https://github.com/stffrdhrn/or1k-toolchain-build/releases | |
| 32 | 32 | toolchains https://openrisc.io/software |
| 33 | 33 | building https://github.com/stffrdhrn/or1k-toolchain-build |
| 34 | − ========== ================================================= | |
| 34 | + ========== ========================================================== | |
| 35 | 35 | |
| 36 | 36 | 2) Building |
| 37 | 37 | |
| @@ -51,7 +51,7 @@ The following keys are defined: · 50 unmodified lines | ||
| 51 | 51 | * :c:macro:`RISCV_HWPROBE_KEY_MARCHID`: Contains the value of ``marchid``, as |
| 52 | 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 | 55 | defined by the RISC-V privileged architecture specification. |
| 56 | 56 | |
| 57 | 57 | * :c:macro:`RISCV_HWPROBE_KEY_BASE_BEHAVIOR`: A bitmask containing the base |
| @@ -79,8 +79,9 @@ feature flags. · 78 unmodified lines | ||
| 79 | 79 | How are feature flags created? |
| 80 | 80 | ============================== |
| 81 | 81 | |
| 82 | −a: Feature flags can be derived from the contents of CPUID leaves. | |
| 83 | −------------------------------------------------------------------ | |
| 82 | +Feature flags can be derived from the contents of CPUID leaves | |
| 83 | +-------------------------------------------------------------- | |
| 84 | + | |
| 84 | 85 | These feature definitions are organized mirroring the layout of CPUID |
| 85 | 86 | leaves and grouped in words with offsets as mapped in enum cpuid_leafs |
| 86 | 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 | 90 | displayed accordingly in /proc/cpuinfo. For example, the flag "avx2" |
| 90 | 91 | comes from X86_FEATURE_AVX2 in cpufeatures.h. |
| 91 | 92 | |
| 92 | −b: Flags can be from scattered CPUID-based features. | |
| 93 | −---------------------------------------------------- | |
| 93 | +Flags can be from scattered CPUID-based features | |
| 94 | +------------------------------------------------ | |
| 95 | + | |
| 94 | 96 | Hardware features enumerated in sparsely populated CPUID leaves get |
| 95 | 97 | software-defined values. Still, CPUID needs to be queried to determine |
| 96 | 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 | 106 | array. Since there is a struct cpuinfo_x86 for each possible CPU, the wasted |
| 105 | 107 | memory is not trivial. |
| 106 | 108 | |
| 107 | −c: Flags can be created synthetically under certain conditions for hardware features. | |
| 108 | −------------------------------------------------------------------------------------- | |
| 109 | +Flags can be created synthetically under certain conditions for hardware features | |
| 110 | +--------------------------------------------------------------------------------- | |
| 111 | + | |
| 109 | 112 | Examples of conditions include whether certain features are present in |
| 110 | 113 | MSR_IA32_CORE_CAPS or specific CPU models are identified. If the needed |
| 111 | 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 | 117 | "split_lock_detect" will be displayed. The flag "ring3mwait" will be |
| 115 | 118 | displayed only when running on INTEL_XEON_PHI_[KNL|KNM] processors. |
| 116 | 119 | |
| 117 | −d: Flags can represent purely software features. | |
| 118 | −------------------------------------------------ | |
| 120 | +Flags can represent purely software features | |
| 121 | +-------------------------------------------- | |
| 119 | 122 | These flags do not represent hardware features. Instead, they represent a |
| 120 | 123 | software feature implemented in the kernel. For example, Kernel Page Table |
| 121 | 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 | 133 | resulting x86_cap/bug_flags[] are used to populate /proc/cpuinfo. The naming |
| 131 | 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. | |
| 134 | −---------------------------------------------------------------------------- | |
| 135 | −By default, the flag <name> in /proc/cpuinfo is extracted from the respective | |
| 136 | −X86_FEATURE_<name> in cpufeatures.h. For example, the flag "avx2" is from | |
| 137 | −X86_FEATURE_AVX2. | |
| 136 | +Flags do not appear by default in /proc/cpuinfo | |
| 137 | +----------------------------------------------- | |
| 138 | + | |
| 139 | +Feature flags are omitted by default from /proc/cpuinfo as it does not make | |
| 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 | 148 | If the comment on the line for the #define X86_FEATURE_* starts with a |
| 142 | 149 | double-quote character (""), the string inside the double-quote characters |
| 143 | 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 | 155 | constant. If, for some reason, the naming of X86_FEATURE_<name> changes, one |
| 149 | 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 | 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. | |
| 163 | −-------------------------------------------------- | |
| 161 | +The hardware does not enumerate support for it | |
| 162 | +---------------------------------------------- | |
| 163 | + | |
| 164 | 164 | For example, when a new kernel is running on old hardware or the feature is |
| 165 | 165 | not enabled by boot firmware. Even if the hardware is new, there might be a |
| 166 | 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. | |
| 169 | −------------------------------------------- | |
| 168 | +The kernel does not know about the flag | |
| 169 | +--------------------------------------- | |
| 170 | + | |
| 170 | 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 | −------------------------------------------------------ | |
| 173 | +The kernel disabled support for it at compile-time | |
| 174 | +-------------------------------------------------- | |
| 175 | + | |
| 174 | 176 | For example, if 5-level-paging is not enabled when building (i.e., |
| 175 | 177 | CONFIG_X86_5LEVEL is not selected) the flag "la57" will not show up [#f1]_. |
| 176 | 178 | Even though the feature will still be detected via CPUID, the kernel disables |
| 177 | 179 | it by clearing via setup_clear_cpu_cap(X86_FEATURE_LA57). |
| 178 | 180 | |
| 179 | −d: The feature is disabled at boot-time. | |
| 180 | −---------------------------------------- | |
| 181 | +The feature is disabled at boot-time | |
| 182 | +------------------------------------ | |
| 181 | 183 | A feature can be disabled either using a command-line parameter or because |
| 182 | 184 | it failed to be enabled. The command-line parameter clearcpuid= can be used |
| 183 | 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 | 192 | to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using |
| 191 | 193 | "no5lvl". |
| 192 | 194 | |
| 193 | −e: The feature was known to be non-functional. | |
| 194 | −---------------------------------------------- | |
| 195 | +The feature was known to be non-functional | |
| 196 | +------------------------------------------ | |
| 197 | + | |
| 195 | 198 | The feature was known to be non-functional because a dependency was |
| 196 | 199 | missing at runtime. For example, AVX flags will not show up if XSAVE feature |
| 197 | 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 | 382 | into the Linux kernel, please implement support into LLVM's BPF back |
| 383 | 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 | 393 | Stable submission |
| 386 | 394 | ================= |
| 387 | 395 | |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Ceva AHCI SATA Controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 11 | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | |
| 13 | 12 | description: | |
| @@ -111,11 +111,27 @@ properties: · 110 unmodified lines | ||
| 111 | 111 | unevaluatedProperties: false |
| 112 | 112 | |
| 113 | 113 | port@1: |
| 114 | − $ref: /schemas/graph.yaml#/properties/port | |
| 114 | + $ref: /schemas/graph.yaml#/$defs/port-base | |
| 115 | + unevaluatedProperties: false | |
| 115 | 116 | description: |
| 116 | 117 | DSI output port node to the panel or the next bridge |
| 117 | 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 | 135 | required: |
| 120 | 136 | - port@0 |
| 121 | 137 | - port@1 |
| @@ -12,7 +12,6 @@ description: · 11 unmodified lines | ||
| 12 | 12 | PS_MODE). Every pin can be configured as input/output. |
| 13 | 13 | |
| 14 | 14 | maintainers: |
| 15 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 16 | 15 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 17 | 16 | |
| 18 | 17 | properties: |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Mediatek's Keypad Controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Mattijs Korpershoek <mkorpershoek@baylibre.com> | |
| 10 | + - Mattijs Korpershoek <mkorpershoek@kernel.org> | |
| 11 | 11 | |
| 12 | 12 | allOf: |
| 13 | 13 | - $ref: /schemas/input/matrix-keymap.yaml# |
| @@ -19,6 +19,7 @@ properties: · 18 unmodified lines | ||
| 19 | 19 | - fsl,imx8mp-irqsteer |
| 20 | 20 | - fsl,imx8qm-irqsteer |
| 21 | 21 | - fsl,imx8qxp-irqsteer |
| 22 | + - fsl,imx94-irqsteer | |
| 22 | 23 | - const: fsl,imx-irqsteer |
| 23 | 24 | |
| 24 | 25 | reg: |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 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 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | 7 | title: Microchip MCP251X stand-alone CAN controller |
| @@ -74,19 +74,17 @@ properties: · 73 unmodified lines | ||
| 74 | 74 | - rev-rmii |
| 75 | 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 | 78 | - rgmii |
| 79 | 79 | |
| 80 | − # RGMII with internal RX and TX delays provided by the PHY, | |
| 81 | − # the MAC should not add the RX or TX delays in this case | |
| 80 | + # RX and TX delays are not provided by the PCB. This is the most | |
| 81 | + # frequent case. See below | |
| 82 | 82 | - rgmii-id |
| 83 | 83 | |
| 84 | − # RGMII with internal RX delay provided by the PHY, the MAC | |
| 85 | − # should not add an RX delay in this case | |
| 84 | + # TX delay is provided by the PCB. See below | |
| 86 | 85 | - rgmii-rxid |
| 87 | 86 | |
| 88 | − # RGMII with internal TX delay provided by the PHY, the MAC | |
| 89 | − # should not add an TX delay in this case | |
| 87 | + # RX delay is provided by the PCB. See below | |
| 90 | 88 | - rgmii-txid |
| 91 | 89 | - rtbi |
| 92 | 90 | - smii |
| @@ -286,4 +284,89 @@ allOf: · 193 unmodified lines | ||
| 286 | 284 | |
| 287 | 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 | 27 | $ref: /schemas/types.yaml#/definitions/uint32-array |
| 28 | 28 | items: |
| 29 | 29 | - minimum: 0 |
| 30 | − maximum: 7 | |
| 30 | + maximum: 31 | |
| 31 | 31 | description: |
| 32 | 32 | Offset in bit within the address range specified by reg. |
| 33 | 33 | - minimum: 1 |
| @@ -19,6 +19,7 @@ properties: · 18 unmodified lines | ||
| 19 | 19 | - enum: |
| 20 | 20 | - qcom,apq8064-qfprom |
| 21 | 21 | - qcom,apq8084-qfprom |
| 22 | + - qcom,ipq5018-qfprom | |
| 22 | 23 | - qcom,ipq5332-qfprom |
| 23 | 24 | - qcom,ipq5424-qfprom |
| 24 | 25 | - qcom,ipq6018-qfprom |
| @@ -28,6 +29,8 @@ properties: · 3 unmodified lines | ||
| 28 | 29 | - qcom,msm8226-qfprom |
| 29 | 30 | - qcom,msm8916-qfprom |
| 30 | 31 | - qcom,msm8917-qfprom |
| 32 | + - qcom,msm8937-qfprom | |
| 33 | + - qcom,msm8960-qfprom | |
| 31 | 34 | - qcom,msm8974-qfprom |
| 32 | 35 | - qcom,msm8976-qfprom |
| 33 | 36 | - qcom,msm8996-qfprom |
| @@ -51,6 +54,7 @@ properties: · 17 unmodified lines | ||
| 51 | 54 | - qcom,sm8450-qfprom |
| 52 | 55 | - qcom,sm8550-qfprom |
| 53 | 56 | - qcom,sm8650-qfprom |
| 57 | + - qcom,x1e80100-qfprom | |
| 54 | 58 | - const: qcom,qfprom |
| 55 | 59 | |
| 56 | 60 | reg: |
| @@ -14,6 +14,7 @@ properties: · 13 unmodified lines | ||
| 14 | 14 | enum: |
| 15 | 15 | - rockchip,px30-otp |
| 16 | 16 | - rockchip,rk3308-otp |
| 17 | + - rockchip,rk3576-otp | |
| 17 | 18 | - rockchip,rk3588-otp |
| 18 | 19 | |
| 19 | 20 | reg: |
| @@ -62,12 +63,34 @@ allOf: · 42 unmodified lines | ||
| 62 | 63 | properties: |
| 63 | 64 | clocks: |
| 64 | 65 | maxItems: 3 |
| 66 | + clock-names: | |
| 67 | + maxItems: 3 | |
| 65 | 68 | resets: |
| 66 | 69 | maxItems: 1 |
| 67 | 70 | reset-names: |
| 68 | 71 | items: |
| 69 | 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 | 94 | - if: |
| 72 | 95 | properties: |
| 73 | 96 | compatible: |
| @@ -78,6 +101,8 @@ allOf: · 4 unmodified lines | ||
| 78 | 101 | properties: |
| 79 | 102 | clocks: |
| 80 | 103 | minItems: 4 |
| 104 | + clock-names: | |
| 105 | + minItems: 4 | |
| 81 | 106 | resets: |
| 82 | 107 | minItems: 3 |
| 83 | 108 | reset-names: |
| @@ -9,15 +9,6 @@ title: Renesas R-Car Timer Pulse Unit PWM Controller · 8 unmodified lines | ||
| 9 | 9 | maintainers: |
| 10 | 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 | 12 | properties: |
| 22 | 13 | compatible: |
| 23 | 14 | items: |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Zynq UltraScale+ MPSoC and Versal reset |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 11 | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | |
| 13 | 12 | description: | |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Freescale Layerscape Reset Registers Module |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Frank Li | |
| 10 | + - Frank Li <Frank.Li@nxp.com> | |
| 11 | 11 | |
| 12 | 12 | description: |
| 13 | 13 | Reset Module includes chip reset, service processor control and Reset Control |
| @@ -56,19 +56,18 @@ properties: · 55 unmodified lines | ||
| 56 | 56 | enum: |
| 57 | 57 | - snps,dw-apb-ssi |
| 58 | 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 | 59 | - description: Microchip Sparx5 SoC SPI Controller |
| 66 | 60 | const: microchip,sparx5-spi |
| 67 | 61 | - description: Amazon Alpine SPI Controller |
| 68 | 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 | 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 | 71 | - const: snps,dw-apb-ssi |
| 73 | 72 | - description: Intel Keem Bay SPI Controller |
| 74 | 73 | const: intel,keembay-ssi |
| @@ -88,10 +87,6 @@ properties: · 13 unmodified lines | ||
| 88 | 87 | - renesas,r9a06g032-spi # RZ/N1D |
| 89 | 88 | - renesas,r9a06g033-spi # RZ/N1S |
| 90 | 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 | 91 | reg: |
| 97 | 92 | minItems: 1 |
| @@ -18,9 +18,14 @@ description: | · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | properties: |
| 20 | 20 | compatible: |
| 21 | − enum: | |
| 22 | − - nxp,imx95-sysctr-timer | |
| 23 | − - nxp,sysctr-timer | |
| 21 | + oneOf: | |
| 22 | + - enum: | |
| 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 | 30 | reg: |
| 26 | 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 | 7 | title: Xilinx SuperSpeed DWC3 USB SoC controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 11 | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | |
| 13 | 12 | properties: |
| @@ -17,7 +17,6 @@ description: · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | maintainers: |
| 19 | 19 | - Michal Simek <michal.simek@amd.com> |
| 20 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 21 | 20 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 22 | 21 | |
| 23 | 22 | properties: |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Xilinx udc controller |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Mubin Sayyed <mubin.sayyed@amd.com> | |
| 11 | 10 | - Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> |
| 12 | 11 | |
| 13 | 12 | properties: |
| @@ -328,9 +328,13 @@ The ext4 superblock is laid out as follows in · 327 unmodified lines | ||
| 328 | 328 | - s_checksum_type |
| 329 | 329 | - Metadata checksum algorithm type. The only valid value is 1 (crc32c). |
| 330 | 330 | * - 0x176 |
| 331 | − - __le16 | |
| 332 | − - s_reserved_pad | |
| 333 | − - | |
| 331 | + - \_\_u8 | |
| 332 | + - s\_encryption\_level | |
| 333 | + - Versioning level for encryption. | |
| 334 | + * - 0x177 | |
| 335 | + - \_\_u8 | |
| 336 | + - s\_reserved\_pad | |
| 337 | + - Padding to next 32bits. | |
| 334 | 338 | * - 0x178 |
| 335 | 339 | - __le64 |
| 336 | 340 | - s_kbytes_written |
| @@ -466,9 +470,13 @@ The ext4 superblock is laid out as follows in · 129 unmodified lines | ||
| 466 | 470 | - s_last_error_time_hi |
| 467 | 471 | - Upper 8 bits of the s_last_error_time field. |
| 468 | 472 | * - 0x27A |
| 469 | − - __u8 | |
| 470 | − - s_pad[2] | |
| 471 | − - Zero padding. | |
| 473 | + - \_\_u8 | |
| 474 | + - s\_first\_error\_errcode | |
| 475 | + - | |
| 476 | + * - 0x27B | |
| 477 | + - \_\_u8 | |
| 478 | + - s\_last\_error\_errcode | |
| 479 | + - | |
| 472 | 480 | * - 0x27C |
| 473 | 481 | - __le16 |
| 474 | 482 | - s_encoding |
| @@ -46,6 +46,21 @@ The kernel embeds the building user and host names in · 45 unmodified lines | ||
| 46 | 46 | `KBUILD_BUILD_USER and KBUILD_BUILD_HOST`_ variables. If you are |
| 47 | 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 | 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 | 132 | .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp |
| 118 | 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 | 136 | .. _Reproducible Builds project: https://reproducible-builds.org/ |
| 120 | 137 | .. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/ |
| @@ -89,8 +89,10 @@ definitions: · 88 unmodified lines | ||
| 89 | 89 | doc: Group of short_detected states |
| 90 | 90 | - |
| 91 | 91 | name: phy-upstream-type |
| 92 | − enum-name: | |
| 92 | + enum-name: phy-upstream | |
| 93 | + header: linux/ethtool.h | |
| 93 | 94 | type: enum |
| 95 | + name-prefix: phy-upstream | |
| 94 | 96 | entries: [ mac, phy ] |
| 95 | 97 | - |
| 96 | 98 | name: tcp-data-split |
| @@ -123,12 +123,12 @@ attribute-sets: · 122 unmodified lines | ||
| 123 | 123 | |
| 124 | 124 | operations: |
| 125 | 125 | name-prefix: ovs-vport-cmd- |
| 126 | + fixed-header: ovs-header | |
| 126 | 127 | list: |
| 127 | 128 | - |
| 128 | 129 | name: new |
| 129 | 130 | doc: Create a new OVS vport |
| 130 | 131 | attribute-set: vport |
| 131 | − fixed-header: ovs-header | |
| 132 | 132 | do: |
| 133 | 133 | request: |
| 134 | 134 | attributes: |
| @@ -141,7 +141,6 @@ operations: · 6 unmodified lines | ||
| 141 | 141 | name: del |
| 142 | 142 | doc: Delete existing OVS vport from a data path |
| 143 | 143 | attribute-set: vport |
| 144 | − fixed-header: ovs-header | |
| 145 | 144 | do: |
| 146 | 145 | request: |
| 147 | 146 | attributes: |
| @@ -152,7 +151,6 @@ operations: · 4 unmodified lines | ||
| 152 | 151 | name: get |
| 153 | 152 | doc: Get / dump OVS vport configuration and state |
| 154 | 153 | attribute-set: vport |
| 155 | − fixed-header: ovs-header | |
| 156 | 154 | do: &vport-get-op |
| 157 | 155 | request: |
| 158 | 156 | attributes: |
| @@ -1113,11 +1113,10 @@ attribute-sets: · 1112 unmodified lines | ||
| 1113 | 1113 | - |
| 1114 | 1114 | name: prop-list |
| 1115 | 1115 | type: nest |
| 1116 | − nested-attributes: link-attrs | |
| 1116 | + nested-attributes: prop-list-link-attrs | |
| 1117 | 1117 | - |
| 1118 | 1118 | name: alt-ifname |
| 1119 | 1119 | type: string |
| 1120 | − multi-attr: true | |
| 1121 | 1120 | - |
| 1122 | 1121 | name: perm-address |
| 1123 | 1122 | type: binary |
| @@ -1163,6 +1162,13 @@ attribute-sets: · 39 unmodified lines | ||
| 1163 | 1162 | - |
| 1164 | 1163 | name: netns-immutable |
| 1165 | 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 | 1173 | name: af-spec-attrs |
| 1168 | 1174 | attributes: |
| @@ -1585,7 +1591,7 @@ attribute-sets: · 416 unmodified lines | ||
| 1585 | 1591 | name: nf-call-iptables |
| 1586 | 1592 | type: u8 |
| 1587 | 1593 | - |
| 1588 | − name: nf-call-ip6-tables | |
| 1594 | + name: nf-call-ip6tables | |
| 1589 | 1595 | type: u8 |
| 1590 | 1596 | - |
| 1591 | 1597 | name: nf-call-arptables |
| @@ -2077,7 +2083,7 @@ attribute-sets: · 485 unmodified lines | ||
| 2077 | 2083 | name: id |
| 2078 | 2084 | type: u16 |
| 2079 | 2085 | - |
| 2080 | − name: flag | |
| 2086 | + name: flags | |
| 2081 | 2087 | type: binary |
| 2082 | 2088 | struct: ifla-vlan-flags |
| 2083 | 2089 | - |
| @@ -2165,7 +2171,7 @@ attribute-sets: · 81 unmodified lines | ||
| 2165 | 2171 | type: binary |
| 2166 | 2172 | struct: ifla-cacheinfo |
| 2167 | 2173 | - |
| 2168 | − name: icmp6-stats | |
| 2174 | + name: icmp6stats | |
| 2169 | 2175 | type: binary |
| 2170 | 2176 | struct: ifla-icmp6-stats |
| 2171 | 2177 | - |
| @@ -2179,9 +2185,10 @@ attribute-sets: · 7 unmodified lines | ||
| 2179 | 2185 | type: u32 |
| 2180 | 2186 | - |
| 2181 | 2187 | name: mctp-attrs |
| 2188 | + name-prefix: ifla-mctp- | |
| 2182 | 2189 | attributes: |
| 2183 | 2190 | - |
| 2184 | − name: mctp-net | |
| 2191 | + name: net | |
| 2185 | 2192 | type: u32 |
| 2186 | 2193 | - |
| 2187 | 2194 | name: phys-binding |
| @@ -2453,7 +2460,6 @@ operations: · 265 unmodified lines | ||
| 2453 | 2460 | - min-mtu |
| 2454 | 2461 | - max-mtu |
| 2455 | 2462 | - prop-list |
| 2456 | − - alt-ifname | |
| 2457 | 2463 | - perm-address |
| 2458 | 2464 | - proto-down-reason |
| 2459 | 2465 | - parent-dev-name |
| @@ -13,25 +13,25 @@ definitions: · 12 unmodified lines | ||
| 13 | 13 | type: struct |
| 14 | 14 | members: |
| 15 | 15 | - |
| 16 | − name: family | |
| 16 | + name: ndm-family | |
| 17 | 17 | type: u8 |
| 18 | 18 | - |
| 19 | − name: pad | |
| 19 | + name: ndm-pad | |
| 20 | 20 | type: pad |
| 21 | 21 | len: 3 |
| 22 | 22 | - |
| 23 | − name: ifindex | |
| 23 | + name: ndm-ifindex | |
| 24 | 24 | type: s32 |
| 25 | 25 | - |
| 26 | − name: state | |
| 26 | + name: ndm-state | |
| 27 | 27 | type: u16 |
| 28 | 28 | enum: nud-state |
| 29 | 29 | - |
| 30 | − name: flags | |
| 30 | + name: ndm-flags | |
| 31 | 31 | type: u8 |
| 32 | 32 | enum: ntf-flags |
| 33 | 33 | - |
| 34 | − name: type | |
| 34 | + name: ndm-type | |
| 35 | 35 | type: u8 |
| 36 | 36 | enum: rtm-type |
| 37 | 37 | - |
| @@ -189,7 +189,7 @@ attribute-sets: · 151 unmodified lines | ||
| 189 | 189 | type: binary |
| 190 | 190 | display-hint: ipv4 |
| 191 | 191 | - |
| 192 | − name: lladr | |
| 192 | + name: lladdr | |
| 193 | 193 | type: binary |
| 194 | 194 | display-hint: mac |
| 195 | 195 | - |
| @@ -2017,7 +2017,8 @@ attribute-sets: · 2016 unmodified lines | ||
| 2017 | 2017 | attributes: |
| 2018 | 2018 | - |
| 2019 | 2019 | name: act |
| 2020 | − type: nest | |
| 2020 | + type: indexed-array | |
| 2021 | + sub-type: nest | |
| 2021 | 2022 | nested-attributes: tc-act-attrs |
| 2022 | 2023 | - |
| 2023 | 2024 | name: police |
| @@ -2250,7 +2251,8 @@ attribute-sets: · 226 unmodified lines | ||
| 2250 | 2251 | attributes: |
| 2251 | 2252 | - |
| 2252 | 2253 | name: act |
| 2253 | − type: nest | |
| 2254 | + type: indexed-array | |
| 2255 | + sub-type: nest | |
| 2254 | 2256 | nested-attributes: tc-act-attrs |
| 2255 | 2257 | - |
| 2256 | 2258 | name: police |
| @@ -2745,7 +2747,7 @@ attribute-sets: · 488 unmodified lines | ||
| 2745 | 2747 | type: u16 |
| 2746 | 2748 | byte-order: big-endian |
| 2747 | 2749 | - |
| 2748 | − name: key-l2-tpv3-sid | |
| 2750 | + name: key-l2tpv3-sid | |
| 2749 | 2751 | type: u32 |
| 2750 | 2752 | byte-order: big-endian |
| 2751 | 2753 | - |
| @@ -3504,7 +3506,7 @@ attribute-sets: · 752 unmodified lines | ||
| 3504 | 3506 | name: rate64 |
| 3505 | 3507 | type: u64 |
| 3506 | 3508 | - |
| 3507 | − name: prate4 | |
| 3509 | + name: prate64 | |
| 3508 | 3510 | type: u64 |
| 3509 | 3511 | - |
| 3510 | 3512 | name: burst |
| @@ -338,10 +338,11 @@ operations directly under the netdev instance lock. · 337 unmodified lines | ||
| 338 | 338 | Devices drivers are encouraged to rely on the instance lock where possible. |
| 339 | 339 | |
| 340 | 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., | |
| 342 | −``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx`` functions handle | |
| 343 | −acquiring the instance lock themselves, while the ``netif_xxx`` functions | |
| 344 | −assume that the driver has already acquired the instance lock. | |
| 341 | +there are two sets of interfaces: ``dev_xxx``/``netdev_xxx`` and ``netif_xxx`` | |
| 342 | +(e.g., ``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx``/``netdev_xxx`` | |
| 343 | +functions handle acquiring the instance lock themselves, while the | |
| 344 | +``netif_xxx`` functions assume that the driver has already acquired | |
| 345 | +the instance lock. | |
| 345 | 346 | |
| 346 | 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 | 355 | running under the lock: |
| 355 | 356 | * ``NETDEV_REGISTER`` |
| 356 | 357 | * ``NETDEV_UP`` |
| 358 | +* ``NETDEV_CHANGE`` | |
| 357 | 359 | |
| 358 | 360 | The following notifiers are running without the lock: |
| 359 | 361 | * ``NETDEV_UNREGISTER`` |
| @@ -811,11 +811,9 @@ Documentation/devicetree/bindings/ptp/timestamper.txt for more details. · 810 unmodified lines | ||
| 811 | 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 | |
| 815 | −modification to MAC drivers, so it is more difficult to ensure correctness of | |
| 816 | −all possible code paths - is that they uncover bugs which were impossible to | |
| 817 | −trigger before the existence of stacked PTP clocks. One example has to do with | |
| 818 | −this line of code, already presented earlier:: | |
| 814 | +The use of stacked PHCs may uncover MAC driver bugs which were impossible to | |
| 815 | +trigger without them. One example has to do with this line of code, already | |
| 816 | +presented earlier:: | |
| 819 | 817 | |
| 820 | 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 | 154 | device in that case. If there is no idle callback, or if the callback returns |
| 155 | 155 | 0, then the PM core will attempt to carry out a runtime suspend of the device, |
| 156 | 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 | 158 | device last busy mark, pm_runtime_mark_last_busy(), to control the delay under |
| 159 | 159 | this circumstance). To prevent this (for example, if the callback routine has |
| 160 | 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 | 18 | 关于OpenRISC处理器和正在进行中的开发的信息: |
| 19 | 19 | |
| 20 | − ======= ============================= | |
| 20 | + ======= ============================== | |
| 21 | 21 | 网站 https://openrisc.io |
| 22 | − 邮箱 openrisc@lists.librecores.org | |
| 23 | − ======= ============================= | |
| 22 | + 邮箱 linux-openrisc@vger.kernel.org | |
| 23 | + ======= ============================== | |
| 24 | 24 | |
| 25 | 25 | --------------------------------------------------------------------- |
| 26 | 26 | |
| @@ -36,11 +36,11 @@ OpenRISC工具链和Linux的构建指南 · 9 unmodified lines | ||
| 36 | 36 | 工具链的构建指南可以在openrisc.io或Stafford的工具链构建和发布脚本 |
| 37 | 37 | 中找到。 |
| 38 | 38 | |
| 39 | − ====== ================================================= | |
| 40 | − 二进制 https://github.com/openrisc/or1k-gcc/releases | |
| 39 | + ====== ========================================================== | |
| 40 | + 二进制 https://github.com/stffrdhrn/or1k-toolchain-build/releases | |
| 41 | 41 | 工具链 https://openrisc.io/software |
| 42 | 42 | 构建 https://github.com/stffrdhrn/or1k-toolchain-build |
| 43 | − ====== ================================================= | |
| 43 | + ====== ========================================================== | |
| 44 | 44 | |
| 45 | 45 | 2) 构建 |
| 46 | 46 | |
| @@ -17,10 +17,10 @@ OpenRISC 1000系列(或1k)。 · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | 關於OpenRISC處理器和正在進行中的開發的信息: |
| 19 | 19 | |
| 20 | − ======= ============================= | |
| 20 | + ======= ============================== | |
| 21 | 21 | 網站 https://openrisc.io |
| 22 | − 郵箱 openrisc@lists.librecores.org | |
| 23 | − ======= ============================= | |
| 22 | + 郵箱 linux-openrisc@vger.kernel.org | |
| 23 | + ======= ============================== | |
| 24 | 24 | |
| 25 | 25 | --------------------------------------------------------------------- |
| 26 | 26 | |
| @@ -36,11 +36,11 @@ OpenRISC工具鏈和Linux的構建指南 · 9 unmodified lines | ||
| 36 | 36 | 工具鏈的構建指南可以在openrisc.io或Stafford的工具鏈構建和發佈腳本 |
| 37 | 37 | 中找到。 |
| 38 | 38 | |
| 39 | − ====== ================================================= | |
| 40 | − 二進制 https://github.com/openrisc/or1k-gcc/releases | |
| 39 | + ====== ========================================================== | |
| 40 | + 二進制 https://github.com/stffrdhrn/or1k-toolchain-build/releases | |
| 41 | 41 | 工具鏈 https://openrisc.io/software |
| 42 | 42 | 構建 https://github.com/stffrdhrn/or1k-toolchain-build |
| 43 | − ====== ================================================= | |
| 43 | + ====== ========================================================== | |
| 44 | 44 | |
| 45 | 45 | 2) 構建 |
| 46 | 46 | |
| @@ -27,7 +27,7 @@ SYSCALL · 26 unmodified lines | ||
| 27 | 27 | ======= |
| 28 | 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 | 32 | **addr**/**len**: virtual memory address range. |
| 33 | 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 | 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 | 7519 | .. _cap_enable_vm: |
| 7451 | 7520 | |
| 7452 | 7521 | 7. Capabilities that can be enabled on VMs |
| @@ -7927,10 +7996,10 @@ by POWER10 processor. · 474 unmodified lines | ||
| 7927 | 7996 | 7.24 KVM_CAP_VM_COPY_ENC_CONTEXT_FROM |
| 7928 | 7997 | ------------------------------------- |
| 7929 | 7998 | |
| 7930 | −Architectures: x86 SEV enabled | |
| 7931 | −Type: vm | |
| 7932 | −Parameters: args[0] is the fd of the source vm | |
| 7933 | −Returns: 0 on success; ENOTTY on error | |
| 7999 | +:Architectures: x86 SEV enabled | |
| 8000 | +:Type: vm | |
| 8001 | +:Parameters: args[0] is the fd of the source vm | |
| 8002 | +:Returns: 0 on success; ENOTTY on error | |
| 7934 | 8003 | |
| 7935 | 8004 | This capability enables userspace to copy encryption context from the vm |
| 7936 | 8005 | indicated by the fd to the vm this is called on. |
| @@ -7963,24 +8032,6 @@ default. · 26 unmodified lines | ||
| 7963 | 8032 | |
| 7964 | 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 | 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 | 8089 | This is intended to support intra-host migration of VMs between userspace VMMs, |
| 8039 | 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 | 8092 | 7.31 KVM_CAP_DISABLE_QUIRKS2 |
| 8056 | 8093 | ---------------------------- |
| 8057 | 8094 | |
| 8058 | −:Capability: KVM_CAP_DISABLE_QUIRKS2 | |
| 8059 | 8095 | :Parameters: args[0] - set of KVM quirks to disable |
| 8060 | 8096 | :Architectures: x86 |
| 8061 | 8097 | :Type: vm |
| @@ -8210,27 +8246,6 @@ This capability is aimed to mitigate the threat that malicious VMs can · 148 unmodified lines | ||
| 8210 | 8246 | cause CPU stuck (due to event windows don't open up) and make the CPU |
| 8211 | 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 | 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 | 8263 | Note: Userspace is responsible for correctly configuring CPUID 0x15, a.k.a. the |
| 8249 | 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 | |
| 8252 | −------------------------------ | |
| 8253 | − | |
| 8254 | −:Architectures: x86 | |
| 8255 | −:Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP. | |
| 8266 | +7.36 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL | |
| 8267 | +---------------------------------------------------------- | |
| 8256 | 8268 | |
| 8257 | −The presence of this capability indicates that KVM_RUN will update the | |
| 8258 | −KVM_RUN_X86_GUEST_MODE bit in kvm_run.flags to indicate whether the | |
| 8259 | −vCPU was executing nested guest code when it exited. | |
| 8269 | +:Architectures: x86, arm64 | |
| 8270 | +:Type: vm | |
| 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 | |
| 8262 | −depending on which executed at the time of an exit. Userspace must | |
| 8263 | −take care to differentiate between these cases. | |
| 8273 | +KVM is capable of tracking dirty memory using ring buffers that are | |
| 8274 | +mmapped into userspace; there is one dirty ring per vcpu. | |
| 8264 | 8275 | |
| 8265 | −7.37 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS | |
| 8266 | −------------------------------------- | |
| 8276 | +The dirty ring is available to userspace as an array of | |
| 8277 | +``struct kvm_dirty_gfn``. Each dirty entry is defined as:: | |
| 8267 | 8278 | |
| 8268 | −:Architectures: arm64 | |
| 8269 | −:Target: VM | |
| 8270 | −:Parameters: None | |
| 8271 | −:Returns: 0 on success, -EINVAL if vCPUs have been created before enabling this | |
| 8272 | − capability. | |
| 8279 | + struct kvm_dirty_gfn { | |
| 8280 | + __u32 flags; | |
| 8281 | + __u32 slot; /* as_id | slot_id */ | |
| 8282 | + __u64 offset; | |
| 8283 | + }; | |
| 8273 | 8284 | |
| 8274 | −This capability changes the behavior of the registers that identify a PE | |
| 8275 | −implementation of the Arm architecture: MIDR_EL1, REVIDR_EL1, and AIDR_EL1. | |
| 8276 | −By default, these registers are visible to userspace but treated as invariant. | |
| 8285 | +The following values are defined for the flags field to define the | |
| 8286 | +current state of the entry:: | |
| 8277 | 8287 | |
| 8278 | −When this capability is enabled, KVM allows userspace to change the | |
| 8279 | −aforementioned registers before the first KVM_RUN. These registers are VM | |
| 8280 | −scoped, meaning that the same set of values are presented on all vCPUs in a | |
| 8281 | −given VM. | |
| 8288 | + #define KVM_DIRTY_GFN_F_DIRTY BIT(0) | |
| 8289 | + #define KVM_DIRTY_GFN_F_RESET BIT(1) | |
| 8290 | + #define KVM_DIRTY_GFN_F_MASK 0x3 | |
| 8282 | 8291 | |
| 8283 | −8. Other capabilities. | |
| 8284 | −====================== | |
| 8292 | +Userspace should call KVM_ENABLE_CAP ioctl right after KVM_CREATE_VM | |
| 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 | |
| 8287 | −features of the KVM implementation. | |
| 8300 | +Just like for dirty page bitmaps, the buffer tracks writes to | |
| 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 | |
| 8290 | −--------------------- | |
| 8306 | +An entry in the ring buffer can be unused (flag bits ``00``), | |
| 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 | |
| 8295 | −available, means that the kernel has an implementation of the | |
| 8296 | −H_RANDOM hypercall backed by a hardware random-number generator. | |
| 8297 | −If present, the kernel H_RANDOM handler can be enabled for guest use | |
| 8298 | −with the KVM_CAP_PPC_ENABLE_HCALL capability. | |
| 8316 | +To harvest the dirty pages, userspace accesses the mmapped ring buffer | |
| 8317 | +to read the dirty GFNs. If the flags has the DIRTY bit set (at this stage | |
| 8318 | +the RESET bit must be cleared), then it means this GFN is a dirty GFN. | |
| 8319 | +The userspace should harvest this GFN and mark the flags from state | |
| 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 | |
| 8301 | −------------------------ | |
| 8326 | +Note that on weakly ordered architectures, userspace accesses to the | |
| 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 | |
| 8306 | −available, means that the kernel has an implementation of the | |
| 8307 | −Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is | |
| 8308 | −used to support Windows Hyper-V based guest paravirt drivers(VMBus). | |
| 8335 | +After processing one or more entries in the ring buffer, userspace | |
| 8336 | +calls the VM ioctl KVM_RESET_DIRTY_RINGS to notify the kernel about | |
| 8337 | +it, so that the kernel will reprotect those collected GFNs. | |
| 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 | |
| 8311 | −capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this | |
| 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. | |
| 8341 | +The dirty ring can get full. When it happens, the KVM_RUN of the | |
| 8342 | +vcpu will return with exit reason KVM_EXIT_DIRTY_LOG_FULL. | |
| 8314 | 8343 | |
| 8315 | −8.3 KVM_CAP_PPC_MMU_RADIX | |
| 8316 | −------------------------- | |
| 8344 | +The dirty ring interface has a major difference comparing to the | |
| 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 | |
| 8321 | −available, means that the kernel can support guests using the | |
| 8322 | −radix MMU defined in Power ISA V3.00 (as implemented in the POWER9 | |
| 8323 | −processor). | |
| 8360 | +After enabling the dirty rings, the userspace needs to detect the | |
| 8361 | +capability of KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP to see whether the | |
| 8362 | +ring structures can be backed by per-slot bitmaps. With this capability | |
| 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 | |
| 8326 | −--------------------------- | |
| 8369 | +Note that the bitmap here is only a backup of the ring structure. The | |
| 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 | 8529 | :Architectures: ppc |
| 8329 | 8530 | |
| @@ -8362,20 +8563,6 @@ may be incompatible with the MIPS VZ ASE. · 32 unmodified lines | ||
| 8362 | 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 | 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 | 8644 | (counting from the right) is set, then a virtual SMT mode of 2^N is |
| 8458 | 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 | 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 | 8660 | :Architectures: s390 |
| 8484 | −:Parameters: none | |
| 8485 | 8661 | |
| 8486 | 8662 | This capability indicates if the flic device will be able to get/set the |
| 8487 | 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 | 8731 | hypercalls: |
| 8556 | 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 | 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 | 8808 | trap and emulate MSRs that are outside of the scope of KVM as well as |
| 8648 | 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 | 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 | 8872 | done when the KVM_CAP_XEN_HVM ioctl sets the |
| 8848 | 8873 | KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag. |
| 8849 | 8874 | |
| 8850 | −8.31 KVM_CAP_PPC_MULTITCE | |
| 8851 | −------------------------- | |
| 8875 | +8.31 KVM_CAP_SPAPR_MULTITCE | |
| 8876 | +--------------------------- | |
| 8852 | 8877 | |
| 8853 | −:Capability: KVM_CAP_PPC_MULTITCE | |
| 8854 | 8878 | :Architectures: ppc |
| 8855 | 8879 | :Type: vm |
| 8856 | 8880 | |
| @@ -8882,72 +8906,9 @@ This capability indicates that the KVM virtual PTP service is · 25 unmodified lines | ||
| 8882 | 8906 | supported in the host. A VMM can check whether the service is |
| 8883 | 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 | 8909 | 8.37 KVM_CAP_S390_PROTECTED_DUMP |
| 8948 | 8910 | -------------------------------- |
| 8949 | 8911 | |
| 8950 | −:Capability: KVM_CAP_S390_PROTECTED_DUMP | |
| 8951 | 8912 | :Architectures: s390 |
| 8952 | 8913 | :Type: vm |
| 8953 | 8914 | |
| @@ -8957,27 +8918,9 @@ PV guests. The `KVM_PV_DUMP` command is available for the · 3 unmodified lines | ||
| 8957 | 8918 | dump related UV data. Also the vcpu ioctl `KVM_S390_PV_CPU_COMMAND` is |
| 8958 | 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 | 8921 | 8.39 KVM_CAP_S390_CPU_TOPOLOGY |
| 8978 | 8922 | ------------------------------ |
| 8979 | 8923 | |
| 8980 | −:Capability: KVM_CAP_S390_CPU_TOPOLOGY | |
| 8981 | 8924 | :Architectures: s390 |
| 8982 | 8925 | :Type: vm |
| 8983 | 8926 | |
| @@ -8999,37 +8942,9 @@ structure. · 15 unmodified lines | ||
| 8999 | 8942 | When getting the Modified Change Topology Report value, the attr->addr |
| 9000 | 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 | 8945 | 8.41 KVM_CAP_VM_TYPES |
| 9030 | 8946 | --------------------- |
| 9031 | 8947 | |
| 9032 | −:Capability: KVM_CAP_MEMORY_ATTRIBUTES | |
| 9033 | 8948 | :Architectures: x86 |
| 9034 | 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 | 8961 | production. The behavior and effective ABI for software-protected VMs is |
| 9047 | 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 | 9025 | 9. Known KVM API problems |
| 9050 | 9026 | ========================= |
| 9051 | 9027 | |
| @@ -9076,9 +9052,10 @@ the local APIC. · 24 unmodified lines | ||
| 9076 | 9052 | |
| 9077 | 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``. | |
| 9080 | −It can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` is present and the kernel | |
| 9081 | −has enabled in-kernel emulation of the local APIC. | |
| 9055 | +On older versions of Linux, CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by | |
| 9056 | +``KVM_GET_SUPPORTED_CPUID``, but it can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` | |
| 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 | 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 | 138 | The output buffer contains a single byte which signals success or failure (``0x00`` on failure) |
| 139 | 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 | 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 | 2519 | F: arch/arm/boot/dts/nxp/imx/ |
| 2520 | 2520 | F: arch/arm/boot/dts/nxp/mxs/ |
| 2521 | 2521 | F: arch/arm64/boot/dts/freescale/ |
| 2522 | +X: Documentation/devicetree/bindings/media/i2c/ | |
| 2522 | 2523 | X: arch/arm64/boot/dts/freescale/fsl-* |
| 2523 | 2524 | X: arch/arm64/boot/dts/freescale/qoriq-* |
| 2524 | 2525 | X: drivers/media/i2c/ |
| @@ -3191,6 +3192,12 @@ M: Dinh Nguyen <dinguyen@kernel.org> · 666 unmodified lines | ||
| 3191 | 3192 | S: Maintained |
| 3192 | 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 | 3201 | ARM/SOCFPGA EDAC BINDINGS |
| 3195 | 3202 | M: Matthew Gerlach <matthew.gerlach@altera.com> |
| 3196 | 3203 | S: Maintained |
| @@ -3867,8 +3874,9 @@ AUXILIARY BUS DRIVER · 670 unmodified lines | ||
| 3867 | 3874 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 3868 | 3875 | R: Dave Ertman <david.m.ertman@intel.com> |
| 3869 | 3876 | R: Ira Weiny <ira.weiny@intel.com> |
| 3877 | +R: Leon Romanovsky <leon@kernel.org> | |
| 3870 | 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 | 3880 | F: Documentation/driver-api/auxiliary_bus.rst |
| 3873 | 3881 | F: drivers/base/auxiliary.c |
| 3874 | 3882 | F: include/linux/auxiliary_bus.h |
| @@ -6335,6 +6343,7 @@ F: Documentation/process/cve.rst · 2460 unmodified lines | ||
| 6335 | 6343 | |
| 6336 | 6344 | CW1200 WLAN driver |
| 6337 | 6345 | S: Orphan |
| 6346 | +L: linux-wireless@vger.kernel.org | |
| 6338 | 6347 | F: drivers/net/wireless/st/ |
| 6339 | 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 | 7029 | S: Supported |
| 7021 | 7030 | W: https://rust-for-linux.com |
| 7022 | 7031 | T: git https://github.com/Rust-for-Linux/linux.git alloc-next |
| 7032 | +F: rust/helpers/dma.c | |
| 7023 | 7033 | F: rust/kernel/dma.rs |
| 7024 | 7034 | F: samples/rust/rust_dma.rs |
| 7025 | 7035 | |
| @@ -7225,7 +7235,7 @@ M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> · 199 unmodified lines | ||
| 7225 | 7235 | M: "Rafael J. Wysocki" <rafael@kernel.org> |
| 7226 | 7236 | M: Danilo Krummrich <dakr@kernel.org> |
| 7227 | 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 | 7239 | F: Documentation/core-api/kobject.rst |
| 7230 | 7240 | F: drivers/base/ |
| 7231 | 7241 | F: fs/debugfs/ |
| @@ -8717,6 +8727,7 @@ M: Chao Yu <chao@kernel.org> · 1485 unmodified lines | ||
| 8717 | 8727 | R: Yue Hu <zbestahu@gmail.com> |
| 8718 | 8728 | R: Jeffle Xu <jefflexu@linux.alibaba.com> |
| 8719 | 8729 | R: Sandeep Dhavale <dhavale@google.com> |
| 8730 | +R: Hongbo Li <lihongbo22@huawei.com> | |
| 8720 | 8731 | L: linux-erofs@lists.ozlabs.org |
| 8721 | 8732 | S: Maintained |
| 8722 | 8733 | W: https://erofs.docs.kernel.org |
| @@ -10136,6 +10147,13 @@ F: drivers/gpio/gpio-regmap.c · 1413 unmodified lines | ||
| 10136 | 10147 | F: include/linux/gpio/regmap.h |
| 10137 | 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 | 10157 | GPIO SUBSYSTEM |
| 10140 | 10158 | M: Linus Walleij <linus.walleij@linaro.org> |
| 10141 | 10159 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -10151,6 +10169,8 @@ F: include/linux/gpio.h · 9 unmodified lines | ||
| 10151 | 10169 | F: include/linux/gpio/ |
| 10152 | 10170 | F: include/linux/of_gpio.h |
| 10153 | 10171 | K: (devm_)?gpio_(request|free|direction|get|set) |
| 10172 | +K: GPIOD_FLAGS_BIT_NONEXCLUSIVE | |
| 10173 | +K: devm_gpiod_unhinge | |
| 10154 | 10174 | |
| 10155 | 10175 | GPIO UAPI |
| 10156 | 10176 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -10453,14 +10473,20 @@ S: Supported · 296 unmodified lines | ||
| 10453 | 10473 | F: drivers/infiniband/hw/hfi1 |
| 10454 | 10474 | |
| 10455 | 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 | 10479 | L: linux-fsdevel@vger.kernel.org |
| 10457 | −S: Orphan | |
| 10480 | +S: Maintained | |
| 10458 | 10481 | F: Documentation/filesystems/hfs.rst |
| 10459 | 10482 | F: fs/hfs/ |
| 10460 | 10483 | |
| 10461 | 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 | 10488 | L: linux-fsdevel@vger.kernel.org |
| 10463 | −S: Orphan | |
| 10489 | +S: Maintained | |
| 10464 | 10490 | F: Documentation/filesystems/hfsplus.rst |
| 10465 | 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 | 10981 | HUGETLB SUBSYSTEM |
| 10956 | 10982 | M: Muchun Song <muchun.song@linux.dev> |
| 10983 | +R: Oscar Salvador <osalvador@suse.de> | |
| 10957 | 10984 | L: linux-mm@kvack.org |
| 10958 | 10985 | S: Maintained |
| 10959 | 10986 | F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages |
| @@ -11079,6 +11106,14 @@ L: linuxppc-dev@lists.ozlabs.org · 119 unmodified lines | ||
| 11079 | 11106 | S: Odd Fixes |
| 11080 | 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 | 11117 | I2C ACPI SUPPORT |
| 11083 | 11118 | M: Mika Westerberg <westeri@kernel.org> |
| 11084 | 11119 | L: linux-i2c@vger.kernel.org |
| @@ -11217,7 +11252,6 @@ S: Maintained · 132 unmodified lines | ||
| 11217 | 11252 | F: drivers/i2c/busses/i2c-cht-wc.c |
| 11218 | 11253 | |
| 11219 | 11254 | I2C/SMBUS ISMT DRIVER |
| 11220 | −M: Seth Heasley <seth.heasley@intel.com> | |
| 11221 | 11255 | M: Neil Horman <nhorman@tuxdriver.com> |
| 11222 | 11256 | L: linux-i2c@vger.kernel.org |
| 11223 | 11257 | F: Documentation/i2c/busses/i2c-ismt.rst |
| @@ -12810,6 +12844,7 @@ F: lib/Kconfig.kcsan · 1586 unmodified lines | ||
| 12810 | 12844 | F: scripts/Makefile.kcsan |
| 12811 | 12845 | |
| 12812 | 12846 | KDUMP |
| 12847 | +M: Andrew Morton <akpm@linux-foundation.org> | |
| 12813 | 12848 | M: Baoquan He <bhe@redhat.com> |
| 12814 | 12849 | R: Vivek Goyal <vgoyal@redhat.com> |
| 12815 | 12850 | R: Dave Young <dyoung@redhat.com> |
| @@ -13106,11 +13141,13 @@ KERNFS · 290 unmodified lines | ||
| 13106 | 13141 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 13107 | 13142 | M: Tejun Heo <tj@kernel.org> |
| 13108 | 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 | 13145 | F: fs/kernfs/ |
| 13111 | 13146 | F: include/linux/kernfs.h |
| 13112 | 13147 | |
| 13113 | 13148 | KEXEC |
| 13149 | +M: Andrew Morton <akpm@linux-foundation.org> | |
| 13150 | +M: Baoquan He <bhe@redhat.com> | |
| 13114 | 13151 | L: kexec@lists.infradead.org |
| 13115 | 13152 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ |
| 13116 | 13153 | F: include/linux/kexec.h |
| @@ -14283,6 +14320,7 @@ S: Odd fixes · 1166 unmodified lines | ||
| 14283 | 14320 | F: drivers/net/ethernet/marvell/sk* |
| 14284 | 14321 | |
| 14285 | 14322 | MARVELL LIBERTAS WIRELESS DRIVER |
| 14323 | +L: linux-wireless@vger.kernel.org | |
| 14286 | 14324 | L: libertas-dev@lists.infradead.org |
| 14287 | 14325 | S: Orphan |
| 14288 | 14326 | F: drivers/net/wireless/marvell/libertas/ |
| @@ -15049,7 +15087,7 @@ F: Documentation/devicetree/bindings/media/mediatek-jpeg-*.yaml · 760 unmodified lines | ||
| 15049 | 15087 | F: drivers/media/platform/mediatek/jpeg/ |
| 15050 | 15088 | |
| 15051 | 15089 | MEDIATEK KEYPAD DRIVER |
| 15052 | −M: Mattijs Korpershoek <mkorpershoek@baylibre.com> | |
| 15090 | +M: Mattijs Korpershoek <mkorpershoek@kernel.org> | |
| 15053 | 15091 | S: Supported |
| 15054 | 15092 | F: Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml |
| 15055 | 15093 | F: drivers/input/keyboard/mt6779-keypad.c |
| @@ -15472,24 +15510,45 @@ F: Documentation/mm/ · 416 unmodified lines | ||
| 15472 | 15510 | F: include/linux/gfp.h |
| 15473 | 15511 | F: include/linux/gfp_types.h |
| 15474 | 15512 | F: include/linux/memfd.h |
| 15475 | −F: include/linux/memory.h | |
| 15476 | 15513 | F: include/linux/memory_hotplug.h |
| 15477 | 15514 | F: include/linux/memory-tiers.h |
| 15478 | 15515 | F: include/linux/mempolicy.h |
| 15479 | 15516 | F: include/linux/mempool.h |
| 15480 | 15517 | F: include/linux/memremap.h |
| 15481 | −F: include/linux/mm.h | |
| 15482 | −F: include/linux/mm_*.h | |
| 15483 | 15518 | F: include/linux/mmzone.h |
| 15484 | 15519 | F: include/linux/mmu_notifier.h |
| 15485 | 15520 | F: include/linux/pagewalk.h |
| 15486 | −F: include/linux/rmap.h | |
| 15487 | 15521 | F: include/trace/events/ksm.h |
| 15488 | 15522 | F: mm/ |
| 15489 | 15523 | F: tools/mm/ |
| 15490 | 15524 | F: tools/testing/selftests/mm/ |
| 15491 | 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 | 15552 | MEMORY MANAGEMENT - EXECMEM |
| 15494 | 15553 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15495 | 15554 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15498,6 +15557,53 @@ S: Maintained · 2 unmodified lines | ||
| 15498 | 15557 | F: include/linux/execmem.h |
| 15499 | 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 | 15607 | MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION |
| 15502 | 15608 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15503 | 15609 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15508,6 +15614,49 @@ F: mm/numa.c · 4 unmodified lines | ||
| 15508 | 15614 | F: mm/numa_emulation.c |
| 15509 | 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 | 15660 | MEMORY MANAGEMENT - SECRETMEM |
| 15512 | 15661 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15513 | 15662 | M: Mike Rapoport <rppt@kernel.org> |
| @@ -15516,6 +15665,30 @@ S: Maintained · 2 unmodified lines | ||
| 15516 | 15665 | F: include/linux/secretmem.h |
| 15517 | 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 | 15692 | MEMORY MANAGEMENT - USERFAULTFD |
| 15520 | 15693 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15521 | 15694 | R: Peter Xu <peterx@redhat.com> |
| @@ -15535,10 +15708,12 @@ M: Liam R. Howlett <Liam.Howlett@oracle.com> · 13 unmodified lines | ||
| 15535 | 15708 | M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> |
| 15536 | 15709 | R: Vlastimil Babka <vbabka@suse.cz> |
| 15537 | 15710 | R: Jann Horn <jannh@google.com> |
| 15711 | +R: Pedro Falcato <pfalcato@suse.de> | |
| 15538 | 15712 | L: linux-mm@kvack.org |
| 15539 | 15713 | S: Maintained |
| 15540 | 15714 | W: http://www.linux-mm.org |
| 15541 | 15715 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm |
| 15716 | +F: include/trace/events/mmap.h | |
| 15542 | 15717 | F: mm/mlock.c |
| 15543 | 15718 | F: mm/mmap.c |
| 15544 | 15719 | F: mm/mprotect.c |
| @@ -15549,6 +15724,36 @@ F: mm/vma.h · 4 unmodified lines | ||
| 15549 | 15724 | F: mm/vma_internal.h |
| 15550 | 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 | 15757 | MEMORY TECHNOLOGY DEVICES (MTD) |
| 15553 | 15758 | M: Miquel Raynal <miquel.raynal@bootlin.com> |
| 15554 | 15759 | M: Richard Weinberger <richard@nod.at> |
| @@ -16756,6 +16961,7 @@ F: Documentation/networking/net_cachelines/net_device.rst · 1201 unmodified lines | ||
| 16756 | 16961 | F: drivers/connector/ |
| 16757 | 16962 | F: drivers/net/ |
| 16758 | 16963 | F: drivers/ptp/ |
| 16964 | +F: drivers/s390/net/ | |
| 16759 | 16965 | F: include/dt-bindings/net/ |
| 16760 | 16966 | F: include/linux/cn_proc.h |
| 16761 | 16967 | F: include/linux/etherdevice.h |
| @@ -16765,6 +16971,7 @@ F: include/linux/fddidevice.h · 3 unmodified lines | ||
| 16765 | 16971 | F: include/linux/hippidevice.h |
| 16766 | 16972 | F: include/linux/if_* |
| 16767 | 16973 | F: include/linux/inetdevice.h |
| 16974 | +F: include/linux/ism.h | |
| 16768 | 16975 | F: include/linux/netdev* |
| 16769 | 16976 | F: include/linux/platform_data/wiznet.h |
| 16770 | 16977 | F: include/uapi/linux/cn_proc.h |
| @@ -17368,7 +17575,7 @@ T: git git://git.infradead.org/nvme.git · 597 unmodified lines | ||
| 17368 | 17575 | F: drivers/nvme/target/ |
| 17369 | 17576 | |
| 17370 | 17577 | NVMEM FRAMEWORK |
| 17371 | −M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
| 17578 | +M: Srinivas Kandagatla <srini@kernel.org> | |
| 17372 | 17579 | S: Maintained |
| 17373 | 17580 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git |
| 17374 | 17581 | F: Documentation/ABI/stable/sysfs-bus-nvmem |
| @@ -18302,7 +18509,7 @@ F: include/uapi/linux/ppdev.h · 927 unmodified lines | ||
| 18302 | 18509 | PARAVIRT_OPS INTERFACE |
| 18303 | 18510 | M: Juergen Gross <jgross@suse.com> |
| 18304 | 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 | 18513 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 18307 | 18514 | L: virtualization@lists.linux.dev |
| 18308 | 18515 | L: x86@kernel.org |
| @@ -18633,7 +18840,7 @@ F: drivers/pci/controller/pci-xgene-msi.c · 324 unmodified lines | ||
| 18633 | 18840 | PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS |
| 18634 | 18841 | M: Lorenzo Pieralisi <lpieralisi@kernel.org> |
| 18635 | 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 | 18844 | R: Rob Herring <robh@kernel.org> |
| 18638 | 18845 | L: linux-pci@vger.kernel.org |
| 18639 | 18846 | S: Supported |
| @@ -18686,6 +18893,16 @@ F: include/asm-generic/pci* · 46 unmodified lines | ||
| 18686 | 18893 | F: include/linux/of_pci.h |
| 18687 | 18894 | F: include/linux/pci* |
| 18688 | 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 | 18906 | F: rust/kernel/pci.rs |
| 18690 | 18907 | F: samples/rust/rust_driver_pci.rs |
| 18691 | 18908 | |
| @@ -19573,7 +19790,7 @@ S: Supported · 881 unmodified lines | ||
| 19573 | 19790 | F: drivers/crypto/intel/qat/ |
| 19574 | 19791 | |
| 19575 | 19792 | QCOM AUDIO (ASoC) DRIVERS |
| 19576 | −M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
| 19793 | +M: Srinivas Kandagatla <srini@kernel.org> | |
| 19577 | 19794 | L: linux-sound@vger.kernel.org |
| 19578 | 19795 | L: linux-arm-msm@vger.kernel.org |
| 19579 | 19796 | S: Supported |
| @@ -19746,6 +19963,7 @@ F: drivers/media/tuners/qt1010* · 166 unmodified lines | ||
| 19746 | 19963 | |
| 19747 | 19964 | QUALCOMM ATH12K WIRELESS DRIVER |
| 19748 | 19965 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19966 | +L: linux-wireless@vger.kernel.org | |
| 19749 | 19967 | L: ath12k@lists.infradead.org |
| 19750 | 19968 | S: Supported |
| 19751 | 19969 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k |
| @@ -19755,6 +19973,7 @@ N: ath12k · 3 unmodified lines | ||
| 19755 | 19973 | |
| 19756 | 19974 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER |
| 19757 | 19975 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19976 | +L: linux-wireless@vger.kernel.org | |
| 19758 | 19977 | L: ath10k@lists.infradead.org |
| 19759 | 19978 | S: Supported |
| 19760 | 19979 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k |
| @@ -19764,6 +19983,7 @@ N: ath10k · 3 unmodified lines | ||
| 19764 | 19983 | |
| 19765 | 19984 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER |
| 19766 | 19985 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19986 | +L: linux-wireless@vger.kernel.org | |
| 19767 | 19987 | L: ath11k@lists.infradead.org |
| 19768 | 19988 | S: Supported |
| 19769 | 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 | 20093 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
| 19874 | 20094 | |
| 19875 | 20095 | QUALCOMM FASTRPC DRIVER |
| 19876 | −M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
| 20096 | +M: Srinivas Kandagatla <srini@kernel.org> | |
| 19877 | 20097 | M: Amol Maheshwari <amahesh@qti.qualcomm.com> |
| 19878 | 20098 | L: linux-arm-msm@vger.kernel.org |
| 19879 | 20099 | L: dri-devel@lists.freedesktop.org |
| @@ -20451,8 +20671,8 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml · 571 unmodified lines | ||
| 20451 | 20671 | F: drivers/i2c/busses/i2c-emev2.c |
| 20452 | 20672 | |
| 20453 | 20673 | RENESAS ETHERNET AVB DRIVER |
| 20454 | −M: Paul Barker <paul.barker.ct@bp.renesas.com> | |
| 20455 | 20674 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 20675 | +R: Paul Barker <paul@pbarker.dev> | |
| 20456 | 20676 | L: netdev@vger.kernel.org |
| 20457 | 20677 | L: linux-renesas-soc@vger.kernel.org |
| 20458 | 20678 | S: Maintained |
| @@ -21253,6 +21473,7 @@ L: linux-s390@vger.kernel.org · 794 unmodified lines | ||
| 21253 | 21473 | L: netdev@vger.kernel.org |
| 21254 | 21474 | S: Supported |
| 21255 | 21475 | F: drivers/s390/net/ |
| 21476 | +F: include/linux/ism.h | |
| 21256 | 21477 | |
| 21257 | 21478 | S390 PCI SUBSYSTEM |
| 21258 | 21479 | M: Niklas Schnelle <schnelle@linux.ibm.com> |
| @@ -21921,7 +22142,7 @@ S: Maintained · 662 unmodified lines | ||
| 21921 | 22142 | F: drivers/media/rc/serial_ir.c |
| 21922 | 22143 | |
| 21923 | 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 | 22146 | L: linux-sound@vger.kernel.org |
| 21926 | 22147 | S: Maintained |
| 21927 | 22148 | F: Documentation/devicetree/bindings/slimbus/ |
| @@ -22137,6 +22358,7 @@ F: drivers/platform/x86/touchscreen_dmi.c · 209 unmodified lines | ||
| 22137 | 22358 | |
| 22138 | 22359 | SILICON LABS WIRELESS DRIVERS (for WFxxx series) |
| 22139 | 22360 | M: Jérôme Pouiller <jerome.pouiller@silabs.com> |
| 22361 | +L: linux-wireless@vger.kernel.org | |
| 22140 | 22362 | S: Supported |
| 22141 | 22363 | F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml |
| 22142 | 22364 | F: drivers/net/wireless/silabs/ |
| @@ -22237,9 +22459,7 @@ F: drivers/nvmem/layouts/sl28vpd.c · 94 unmodified lines | ||
| 22237 | 22459 | |
| 22238 | 22460 | SLAB ALLOCATOR |
| 22239 | 22461 | M: Christoph Lameter <cl@linux.com> |
| 22240 | −M: Pekka Enberg <penberg@kernel.org> | |
| 22241 | 22462 | M: David Rientjes <rientjes@google.com> |
| 22242 | −M: Joonsoo Kim <iamjoonsoo.kim@lge.com> | |
| 22243 | 22463 | M: Andrew Morton <akpm@linux-foundation.org> |
| 22244 | 22464 | M: Vlastimil Babka <vbabka@suse.cz> |
| 22245 | 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 | 22874 | F: Documentation/devicetree/bindings/sound/ |
| 22655 | 22875 | F: Documentation/sound/soc/ |
| 22656 | 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 | 22882 | F: include/sound/soc* |
| 22658 | 22883 | F: include/sound/sof.h |
| 22659 | 22884 | F: include/sound/sof/ |
| 22885 | +F: include/sound/wm*.h | |
| 22660 | 22886 | F: include/trace/events/sof*.h |
| 22661 | 22887 | F: include/uapi/sound/asoc.h |
| 22662 | 22888 | F: sound/soc/ |
| @@ -22767,7 +22993,6 @@ F: drivers/accessibility/speakup/ · 104 unmodified lines | ||
| 22767 | 22993 | |
| 22768 | 22994 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 22769 | 22995 | M: Viresh Kumar <vireshk@kernel.org> |
| 22770 | −M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> | |
| 22771 | 22996 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 22772 | 22997 | L: soc@lists.linux.dev |
| 22773 | 22998 | S: Maintained |
| @@ -25126,9 +25351,13 @@ S: Maintained · 2352 unmodified lines | ||
| 25126 | 25351 | F: drivers/usb/typec/mux/pi3usb30532.c |
| 25127 | 25352 | |
| 25128 | 25353 | USB TYPEC PORT CONTROLLER DRIVERS |
| 25354 | +M: Badhri Jagan Sridharan <badhri@google.com> | |
| 25129 | 25355 | L: linux-usb@vger.kernel.org |
| 25130 | −S: Orphan | |
| 25131 | −F: drivers/usb/typec/tcpm/ | |
| 25356 | +S: Maintained | |
| 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 | 25362 | USB TYPEC TUSB1046 MUX DRIVER |
| 25134 | 25363 | M: Romain Gantois <romain.gantois@bootlin.com> |
| @@ -25741,7 +25970,7 @@ F: tools/testing/vsock/ · 606 unmodified lines | ||
| 25741 | 25970 | |
| 25742 | 25971 | VMALLOC |
| 25743 | 25972 | M: Andrew Morton <akpm@linux-foundation.org> |
| 25744 | −R: Uladzislau Rezki <urezki@gmail.com> | |
| 25973 | +M: Uladzislau Rezki <urezki@gmail.com> | |
| 25745 | 25974 | L: linux-mm@kvack.org |
| 25746 | 25975 | S: Maintained |
| 25747 | 25976 | W: http://www.linux-mm.org |
| @@ -25765,7 +25994,7 @@ F: drivers/misc/vmw_balloon.c · 17 unmodified lines | ||
| 25765 | 25994 | |
| 25766 | 25995 | VMWARE HYPERVISOR INTERFACE |
| 25767 | 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 | 25998 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 25770 | 25999 | L: virtualization@lists.linux.dev |
| 25771 | 26000 | L: x86@kernel.org |
| @@ -25793,7 +26022,7 @@ F: drivers/scsi/vmw_pvscsi.h · 21 unmodified lines | ||
| 25793 | 26022 | VMWARE VIRTUAL PTP CLOCK DRIVER |
| 25794 | 26023 | M: Nick Shi <nick.shi@broadcom.com> |
| 25795 | 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 | 26026 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 25798 | 26027 | L: netdev@vger.kernel.org |
| 25799 | 26028 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 15 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = | |
| 6 | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -477,7 +477,6 @@ export rust_common_flags := --edition=2021 \ · 468 unmodified lines | ||
| 477 | 477 | -Wclippy::ignored_unit_patterns \ |
| 478 | 478 | -Wclippy::mut_mut \ |
| 479 | 479 | -Wclippy::needless_bitwise_bool \ |
| 480 | − -Wclippy::needless_continue \ | |
| 481 | 480 | -Aclippy::needless_lifetimes \ |
| 482 | 481 | -Wclippy::no_mangle_with_rust_abi \ |
| 483 | 482 | -Wclippy::undocumented_unsafe_blocks \ |
| @@ -1053,10 +1052,6 @@ NOSTDINC_FLAGS += -nostdinc · 569 unmodified lines | ||
| 1053 | 1052 | # perform bounds checking. |
| 1054 | 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 | 1055 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 1061 | 1056 | KBUILD_CFLAGS += -fno-strict-overflow |
| 1062 | 1057 | |
| @@ -1068,10 +1063,12 @@ ifdef CONFIG_CC_IS_GCC · 5 unmodified lines | ||
| 1068 | 1063 | KBUILD_CFLAGS += -fconserve-stack |
| 1069 | 1064 | endif |
| 1070 | 1065 | |
| 1066 | +# Ensure compilers do not transform certain loops into calls to wcslen() | |
| 1067 | +KBUILD_CFLAGS += -fno-builtin-wcslen | |
| 1068 | + | |
| 1071 | 1069 | # change __FILE__ to the relative path to the source directory |
| 1072 | 1070 | ifdef building_out_of_srctree |
| 1073 | −KBUILD_CPPFLAGS += $(call cc-option,-ffile-prefix-map=$(srcroot)/=) | |
| 1074 | −KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= | |
| 1071 | +KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) | |
| 1075 | 1072 | endif |
| 1076 | 1073 | |
| 1077 | 1074 | # include additional Makefiles when needed |
| @@ -451,7 +451,7 @@ · 450 unmodified lines | ||
| 451 | 451 | pwm_ef: pwm@86c0 { |
| 452 | 452 | compatible = "amlogic,meson8-pwm-v2"; |
| 453 | 453 | clocks = <&xtal>, |
| 454 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 454 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 455 | 455 | <&clkc CLKID_FCLK_DIV4>, |
| 456 | 456 | <&clkc CLKID_FCLK_DIV3>; |
| 457 | 457 | reg = <0x86c0 0x10>; |
| @@ -705,7 +705,7 @@ · 247 unmodified lines | ||
| 705 | 705 | &pwm_ab { |
| 706 | 706 | compatible = "amlogic,meson8-pwm-v2"; |
| 707 | 707 | clocks = <&xtal>, |
| 708 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 708 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 709 | 709 | <&clkc CLKID_FCLK_DIV4>, |
| 710 | 710 | <&clkc CLKID_FCLK_DIV3>; |
| 711 | 711 | }; |
| @@ -713,7 +713,7 @@ · 1 unmodified line | ||
| 713 | 713 | &pwm_cd { |
| 714 | 714 | compatible = "amlogic,meson8-pwm-v2"; |
| 715 | 715 | clocks = <&xtal>, |
| 716 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 716 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 717 | 717 | <&clkc CLKID_FCLK_DIV4>, |
| 718 | 718 | <&clkc CLKID_FCLK_DIV3>; |
| 719 | 719 | }; |
| @@ -406,7 +406,7 @@ · 405 unmodified lines | ||
| 406 | 406 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 407 | 407 | reg = <0x86c0 0x10>; |
| 408 | 408 | clocks = <&xtal>, |
| 409 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 409 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 410 | 410 | <&clkc CLKID_FCLK_DIV4>, |
| 411 | 411 | <&clkc CLKID_FCLK_DIV3>; |
| 412 | 412 | #pwm-cells = <3>; |
| @@ -680,7 +680,7 @@ · 267 unmodified lines | ||
| 680 | 680 | &pwm_ab { |
| 681 | 681 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 682 | 682 | clocks = <&xtal>, |
| 683 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 683 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 684 | 684 | <&clkc CLKID_FCLK_DIV4>, |
| 685 | 685 | <&clkc CLKID_FCLK_DIV3>; |
| 686 | 686 | }; |
| @@ -688,7 +688,7 @@ · 1 unmodified line | ||
| 688 | 688 | &pwm_cd { |
| 689 | 689 | compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2"; |
| 690 | 690 | clocks = <&xtal>, |
| 691 | − <>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 691 | + <0>, /* unknown/untested, the datasheet calls it "Video PLL" */ | |
| 692 | 692 | <&clkc CLKID_FCLK_DIV4>, |
| 693 | 693 | <&clkc CLKID_FCLK_DIV3>; |
| 694 | 694 | }; |
| @@ -40,6 +40,9 @@ · 39 unmodified lines | ||
| 40 | 40 | reg = <1>; |
| 41 | 41 | interrupt-parent = <&gpio4>; |
| 42 | 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 | 46 | status = "okay"; |
| 44 | 47 | }; |
| 45 | 48 | }; |
| @@ -232,7 +232,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 231 unmodified lines | ||
| 232 | 232 | CONFIG_CRYPTO_DEV_ATMEL_AES=y |
| 233 | 233 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y |
| 234 | 234 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y |
| 235 | −CONFIG_CRC_CCITT=y | |
| 236 | 235 | CONFIG_FONTS=y |
| 237 | 236 | CONFIG_FONT_8x8=y |
| 238 | 237 | CONFIG_FONT_ACORN_8x8=y |
| @@ -78,7 +78,6 @@ CONFIG_ROMFS_FS=y · 77 unmodified lines | ||
| 78 | 78 | CONFIG_NLS_DEFAULT="cp437" |
| 79 | 79 | CONFIG_NLS_CODEPAGE_437=y |
| 80 | 80 | CONFIG_NLS_ISO8859_1=y |
| 81 | −CONFIG_CRC_CCITT=y | |
| 82 | 81 | CONFIG_FONTS=y |
| 83 | 82 | CONFIG_FONT_MINI_4x6=y |
| 84 | 83 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| @@ -249,7 +249,6 @@ CONFIG_NLS_ASCII=m · 248 unmodified lines | ||
| 249 | 249 | CONFIG_NLS_ISO8859_1=y |
| 250 | 250 | CONFIG_NLS_UTF8=m |
| 251 | 251 | # CONFIG_CRYPTO_HW is not set |
| 252 | −CONFIG_CRC_T10DIF=m | |
| 253 | 252 | CONFIG_DMA_CMA=y |
| 254 | 253 | CONFIG_DEBUG_FS=y |
| 255 | 254 | CONFIG_DEBUG_RT_MUTEXES=y |
| @@ -128,7 +128,6 @@ CONFIG_CRYPTO_DEFLATE=y · 127 unmodified lines | ||
| 128 | 128 | CONFIG_CRYPTO_LZO=y |
| 129 | 129 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 130 | 130 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 131 | −CONFIG_CRC_CCITT=y | |
| 132 | 131 | CONFIG_PRINTK_TIME=y |
| 133 | 132 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 134 | 133 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -370,7 +370,6 @@ CONFIG_CRYPTO_AES_ARM_BS=m · 369 unmodified lines | ||
| 370 | 370 | CONFIG_CRYPTO_CHACHA20_NEON=m |
| 371 | 371 | CONFIG_CRYPTO_DEV_EXYNOS_RNG=y |
| 372 | 372 | CONFIG_CRYPTO_DEV_S5P=y |
| 373 | −CONFIG_CRC_CCITT=y | |
| 374 | 373 | CONFIG_DMA_CMA=y |
| 375 | 374 | CONFIG_CMA_SIZE_MBYTES=96 |
| 376 | 375 | CONFIG_FONTS=y |
| @@ -481,8 +481,6 @@ CONFIG_SECURITYFS=y · 480 unmodified lines | ||
| 481 | 481 | CONFIG_CRYPTO_DEV_FSL_CAAM=y |
| 482 | 482 | CONFIG_CRYPTO_DEV_SAHARA=y |
| 483 | 483 | CONFIG_CRYPTO_DEV_MXS_DCP=y |
| 484 | −CONFIG_CRC_CCITT=m | |
| 485 | −CONFIG_CRC_T10DIF=y | |
| 486 | 484 | CONFIG_CMA_SIZE_MBYTES=64 |
| 487 | 485 | CONFIG_FONTS=y |
| 488 | 486 | CONFIG_FONT_8x8=y |
| @@ -147,7 +147,6 @@ CONFIG_EXT2_FS=y · 146 unmodified lines | ||
| 147 | 147 | # CONFIG_INOTIFY_USER is not set |
| 148 | 148 | CONFIG_JFFS2_FS=y |
| 149 | 149 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 150 | −CONFIG_CRC_ITU_T=y | |
| 151 | 150 | CONFIG_PRINTK_TIME=y |
| 152 | 151 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 153 | 152 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| @@ -179,7 +179,6 @@ CONFIG_NLS_ISO8859_1=y · 178 unmodified lines | ||
| 179 | 179 | CONFIG_NLS_UTF8=y |
| 180 | 180 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 181 | 181 | # CONFIG_CRYPTO_HW is not set |
| 182 | −CONFIG_CRC_CCITT=y | |
| 183 | 182 | CONFIG_PRINTK_TIME=y |
| 184 | 183 | CONFIG_DYNAMIC_DEBUG=y |
| 185 | 184 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -108,8 +108,6 @@ CONFIG_CRYPTO_AES_ARM_BS=m · 107 unmodified lines | ||
| 108 | 108 | CONFIG_CRYPTO_AES_ARM_CE=m |
| 109 | 109 | CONFIG_CRYPTO_CHACHA20_NEON=m |
| 110 | 110 | # CONFIG_CRYPTO_HW is not set |
| 111 | −CONFIG_CRC_CCITT=m | |
| 112 | −CONFIG_CRC_ITU_T=m | |
| 113 | 111 | CONFIG_DMA_CMA=y |
| 114 | 112 | CONFIG_CMA_SIZE_MBYTES=64 |
| 115 | 113 | CONFIG_PRINTK_TIME=y |
| @@ -67,7 +67,6 @@ CONFIG_NFS_V3=y · 66 unmodified lines | ||
| 67 | 67 | CONFIG_NFS_V3_ACL=y |
| 68 | 68 | CONFIG_NFS_V4=y |
| 69 | 69 | CONFIG_ROOT_NFS=y |
| 70 | −CONFIG_CRC_CCITT=y | |
| 71 | 70 | CONFIG_PRINTK_TIME=y |
| 72 | 71 | CONFIG_DEBUG_KERNEL=y |
| 73 | 72 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -91,6 +91,5 @@ CONFIG_MSDOS_FS=y · 90 unmodified lines | ||
| 91 | 91 | CONFIG_VFAT_FS=y |
| 92 | 92 | CONFIG_CRAMFS=y |
| 93 | 93 | CONFIG_MINIX_FS=y |
| 94 | −CONFIG_CRC_CCITT=y | |
| 95 | 94 | # CONFIG_FTRACE is not set |
| 96 | 95 | CONFIG_DEBUG_USER=y |
| @@ -289,7 +289,6 @@ CONFIG_NLS_UTF8=y · 288 unmodified lines | ||
| 289 | 289 | CONFIG_CRYPTO_CBC=m |
| 290 | 290 | CONFIG_CRYPTO_PCBC=m |
| 291 | 291 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 292 | −CONFIG_CRC_CCITT=y | |
| 293 | 292 | CONFIG_DEBUG_KERNEL=y |
| 294 | 293 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 295 | 294 | CONFIG_MAGIC_SYSRQ=y |
| @@ -187,7 +187,6 @@ CONFIG_NLS_UTF8=y · 186 unmodified lines | ||
| 187 | 187 | CONFIG_CRYPTO_CBC=m |
| 188 | 188 | CONFIG_CRYPTO_PCBC=m |
| 189 | 189 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 190 | −CONFIG_CRC_CCITT=y | |
| 191 | 190 | CONFIG_DEBUG_KERNEL=y |
| 192 | 191 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 193 | 192 | CONFIG_MAGIC_SYSRQ=y |
| @@ -160,7 +160,6 @@ CONFIG_NLS_CODEPAGE_850=y · 159 unmodified lines | ||
| 160 | 160 | CONFIG_NLS_ISO8859_1=y |
| 161 | 161 | CONFIG_NLS_ISO8859_15=y |
| 162 | 162 | CONFIG_CRYPTO_DEV_MXS_DCP=y |
| 163 | −CONFIG_CRC_ITU_T=m | |
| 164 | 163 | CONFIG_FONTS=y |
| 165 | 164 | CONFIG_PRINTK_TIME=y |
| 166 | 165 | CONFIG_DEBUG_KERNEL=y |
| @@ -706,9 +706,6 @@ CONFIG_CRYPTO_DEV_OMAP=m · 705 unmodified lines | ||
| 706 | 706 | CONFIG_CRYPTO_DEV_OMAP_SHAM=m |
| 707 | 707 | CONFIG_CRYPTO_DEV_OMAP_AES=m |
| 708 | 708 | CONFIG_CRYPTO_DEV_OMAP_DES=m |
| 709 | −CONFIG_CRC_CCITT=y | |
| 710 | −CONFIG_CRC_T10DIF=y | |
| 711 | −CONFIG_CRC_ITU_T=y | |
| 712 | 709 | CONFIG_DMA_CMA=y |
| 713 | 710 | CONFIG_FONTS=y |
| 714 | 711 | CONFIG_FONT_8x8=y |
| @@ -136,7 +136,6 @@ CONFIG_CRYPTO_CBC=m · 135 unmodified lines | ||
| 136 | 136 | CONFIG_CRYPTO_ECB=m |
| 137 | 137 | CONFIG_CRYPTO_PCBC=m |
| 138 | 138 | CONFIG_CRYPTO_DEV_MARVELL_CESA=y |
| 139 | −CONFIG_CRC_T10DIF=y | |
| 140 | 139 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 141 | 140 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 142 | 141 | CONFIG_MAGIC_SYSRQ=y |
| @@ -41,7 +41,6 @@ CONFIG_NFS_V3=y · 40 unmodified lines | ||
| 41 | 41 | CONFIG_NFS_V3_ACL=y |
| 42 | 42 | CONFIG_NFS_V4=y |
| 43 | 43 | CONFIG_ROOT_NFS=y |
| 44 | −CONFIG_CRC_CCITT=y | |
| 45 | 44 | CONFIG_PRINTK_TIME=y |
| 46 | 45 | CONFIG_DEBUG_KERNEL=y |
| 47 | 46 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -50,7 +50,6 @@ CONFIG_NFS_V3=y · 49 unmodified lines | ||
| 50 | 50 | CONFIG_NFS_V3_ACL=y |
| 51 | 51 | CONFIG_NFS_V4=y |
| 52 | 52 | CONFIG_ROOT_NFS=y |
| 53 | −CONFIG_CRC_CCITT=y | |
| 54 | 53 | CONFIG_PRINTK_TIME=y |
| 55 | 54 | CONFIG_DEBUG_KERNEL=y |
| 56 | 55 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -663,8 +663,6 @@ CONFIG_CRYPTO_SHA1_ARM=m · 662 unmodified lines | ||
| 663 | 663 | CONFIG_CRYPTO_SHA256_ARM=m |
| 664 | 664 | CONFIG_CRYPTO_SHA512_ARM=m |
| 665 | 665 | CONFIG_CRYPTO_AES_ARM=m |
| 666 | −CONFIG_CRC_CCITT=y | |
| 667 | −CONFIG_CRC_T10DIF=m | |
| 668 | 666 | CONFIG_FONTS=y |
| 669 | 667 | CONFIG_FONT_8x8=y |
| 670 | 668 | CONFIG_FONT_8x16=y |
| @@ -113,7 +113,6 @@ CONFIG_NLS_CODEPAGE_437=y · 112 unmodified lines | ||
| 113 | 113 | CONFIG_NLS_ASCII=y |
| 114 | 114 | CONFIG_NLS_ISO8859_1=y |
| 115 | 115 | CONFIG_NLS_UTF8=y |
| 116 | −CONFIG_CRC_CCITT=y | |
| 117 | 116 | CONFIG_DEBUG_KERNEL=y |
| 118 | 117 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 119 | 118 | CONFIG_MAGIC_SYSRQ=y |
| @@ -227,8 +227,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 226 unmodified lines | ||
| 227 | 227 | CONFIG_CRYPTO_DEV_ATMEL_AES=y |
| 228 | 228 | CONFIG_CRYPTO_DEV_ATMEL_TDES=y |
| 229 | 229 | CONFIG_CRYPTO_DEV_ATMEL_SHA=y |
| 230 | −CONFIG_CRC_CCITT=y | |
| 231 | −CONFIG_CRC_ITU_T=y | |
| 232 | 230 | CONFIG_DMA_CMA=y |
| 233 | 231 | CONFIG_CMA_SIZE_MBYTES=32 |
| 234 | 232 | CONFIG_CMA_ALIGNMENT=9 |
| @@ -234,7 +234,6 @@ CONFIG_CRYPTO_MD4=m · 233 unmodified lines | ||
| 234 | 234 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 235 | 235 | CONFIG_CRYPTO_SHA512=m |
| 236 | 236 | CONFIG_CRYPTO_WP512=m |
| 237 | −CONFIG_CRC_CCITT=y | |
| 238 | 237 | CONFIG_FONTS=y |
| 239 | 238 | CONFIG_FONT_8x8=y |
| 240 | 239 | CONFIG_FONT_8x16=y |
| @@ -74,7 +74,6 @@ CONFIG_EXT3_FS=y · 73 unmodified lines | ||
| 74 | 74 | # CONFIG_DNOTIFY is not set |
| 75 | 75 | # CONFIG_INOTIFY_USER is not set |
| 76 | 76 | CONFIG_NLS=y |
| 77 | −CONFIG_CRC_ITU_T=y | |
| 78 | 77 | CONFIG_PRINTK_TIME=y |
| 79 | 78 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 80 | 79 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -191,8 +191,6 @@ CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y · 190 unmodified lines | ||
| 191 | 191 | CONFIG_X509_CERTIFICATE_PARSER=y |
| 192 | 192 | CONFIG_PKCS7_MESSAGE_PARSER=y |
| 193 | 193 | CONFIG_SYSTEM_TRUSTED_KEYRING=y |
| 194 | −CONFIG_CRC_CCITT=y | |
| 195 | −CONFIG_CRC_ITU_T=m | |
| 196 | 194 | CONFIG_PRINTK_TIME=y |
| 197 | 195 | CONFIG_DEBUG_KERNEL=y |
| 198 | 196 | CONFIG_MAGIC_SYSRQ=y |
| @@ -152,28 +152,12 @@ · 151 unmodified lines | ||
| 152 | 152 | vcc-pg-supply = <®_aldo1>; |
| 153 | 153 | }; |
| 154 | 154 | |
| 155 | −&r_ir { | |
| 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 { | |
| 155 | +&r_i2c { | |
| 172 | 156 | status = "okay"; |
| 173 | 157 | |
| 174 | − axp805: pmic@745 { | |
| 158 | + axp805: pmic@36 { | |
| 175 | 159 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 176 | − reg = <0x745>; | |
| 160 | + reg = <0x36>; | |
| 177 | 161 | interrupt-parent = <&r_intc>; |
| 178 | 162 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 179 | 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 | 294 | &spdif { |
| 295 | 295 | pinctrl-names = "default"; |
| 296 | 296 | pinctrl-0 = <&spdif_tx_pin>; |
| @@ -176,16 +176,12 @@ · 175 unmodified lines | ||
| 176 | 176 | vcc-pg-supply = <®_vcc_wifi_io>; |
| 177 | 177 | }; |
| 178 | 178 | |
| 179 | −&r_ir { | |
| 180 | − status = "okay"; | |
| 181 | −}; | |
| 182 | − | |
| 183 | −&r_rsb { | |
| 179 | +&r_i2c { | |
| 184 | 180 | status = "okay"; |
| 185 | 181 | |
| 186 | − axp805: pmic@745 { | |
| 182 | + axp805: pmic@36 { | |
| 187 | 183 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 188 | − reg = <0x745>; | |
| 184 | + reg = <0x36>; | |
| 189 | 185 | interrupt-parent = <&r_intc>; |
| 190 | 186 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 191 | 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 | 299 | &rtc { |
| 300 | 300 | clocks = <&ext_osc32k>; |
| 301 | 301 | }; |
| @@ -113,20 +113,12 @@ · 112 unmodified lines | ||
| 113 | 113 | vcc-pg-supply = <®_aldo1>; |
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | −&r_ir { | |
| 117 | − status = "okay"; | |
| 118 | −}; | |
| 119 | − | |
| 120 | −&r_pio { | |
| 121 | − vcc-pm-supply = <®_bldo3>; | |
| 122 | −}; | |
| 123 | − | |
| 124 | −&r_rsb { | |
| 116 | +&r_i2c { | |
| 125 | 117 | status = "okay"; |
| 126 | 118 | |
| 127 | − axp805: pmic@745 { | |
| 119 | + axp805: pmic@36 { | |
| 128 | 120 | compatible = "x-powers,axp805", "x-powers,axp806"; |
| 129 | − reg = <0x745>; | |
| 121 | + reg = <0x36>; | |
| 130 | 122 | interrupt-parent = <&r_intc>; |
| 131 | 123 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; |
| 132 | 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 | 244 | &rtc { |
| 245 | 245 | clocks = <&ext_osc32k>; |
| 246 | 246 | }; |
| @@ -151,7 +151,7 @@ · 150 unmodified lines | ||
| 151 | 151 | al,msi-num-spis = <160>; |
| 152 | 152 | }; |
| 153 | 153 | |
| 154 | − io-fabric@fc000000 { | |
| 154 | + io-bus@fc000000 { | |
| 155 | 155 | compatible = "simple-bus"; |
| 156 | 156 | #address-cells = <1>; |
| 157 | 157 | #size-cells = <1>; |
| @@ -361,7 +361,7 @@ · 360 unmodified lines | ||
| 361 | 361 | interrupt-parent = <&gic>; |
| 362 | 362 | }; |
| 363 | 363 | |
| 364 | − io-fabric@fc000000 { | |
| 364 | + io-bus@fc000000 { | |
| 365 | 365 | compatible = "simple-bus"; |
| 366 | 366 | #address-cells = <1>; |
| 367 | 367 | #size-cells = <1>; |
| @@ -2313,7 +2313,7 @@ · 2312 unmodified lines | ||
| 2313 | 2313 | "amlogic,meson8-pwm-v2"; |
| 2314 | 2314 | reg = <0x0 0x19000 0x0 0x20>; |
| 2315 | 2315 | clocks = <&xtal>, |
| 2316 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2316 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2317 | 2317 | <&clkc CLKID_FCLK_DIV4>, |
| 2318 | 2318 | <&clkc CLKID_FCLK_DIV3>; |
| 2319 | 2319 | #pwm-cells = <3>; |
| @@ -2325,7 +2325,7 @@ · 5 unmodified lines | ||
| 2325 | 2325 | "amlogic,meson8-pwm-v2"; |
| 2326 | 2326 | reg = <0x0 0x1a000 0x0 0x20>; |
| 2327 | 2327 | clocks = <&xtal>, |
| 2328 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2328 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2329 | 2329 | <&clkc CLKID_FCLK_DIV4>, |
| 2330 | 2330 | <&clkc CLKID_FCLK_DIV3>; |
| 2331 | 2331 | #pwm-cells = <3>; |
| @@ -2337,7 +2337,7 @@ · 5 unmodified lines | ||
| 2337 | 2337 | "amlogic,meson8-pwm-v2"; |
| 2338 | 2338 | reg = <0x0 0x1b000 0x0 0x20>; |
| 2339 | 2339 | clocks = <&xtal>, |
| 2340 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2340 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 2341 | 2341 | <&clkc CLKID_FCLK_DIV4>, |
| 2342 | 2342 | <&clkc CLKID_FCLK_DIV3>; |
| 2343 | 2343 | #pwm-cells = <3>; |
| @@ -116,6 +116,10 @@ · 115 unmodified lines | ||
| 116 | 116 | status = "okay"; |
| 117 | 117 | }; |
| 118 | 118 | |
| 119 | +&clkc_audio { | |
| 120 | + status = "okay"; | |
| 121 | +}; | |
| 122 | + | |
| 119 | 123 | &frddr_a { |
| 120 | 124 | status = "okay"; |
| 121 | 125 | }; |
| @@ -741,7 +741,7 @@ · 740 unmodified lines | ||
| 741 | 741 | |
| 742 | 742 | &pwm_ab { |
| 743 | 743 | clocks = <&xtal>, |
| 744 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 744 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 745 | 745 | <&clkc CLKID_FCLK_DIV4>, |
| 746 | 746 | <&clkc CLKID_FCLK_DIV3>; |
| 747 | 747 | }; |
| @@ -752,14 +752,14 @@ · 4 unmodified lines | ||
| 752 | 752 | |
| 753 | 753 | &pwm_cd { |
| 754 | 754 | clocks = <&xtal>, |
| 755 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 755 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 756 | 756 | <&clkc CLKID_FCLK_DIV4>, |
| 757 | 757 | <&clkc CLKID_FCLK_DIV3>; |
| 758 | 758 | }; |
| 759 | 759 | |
| 760 | 760 | &pwm_ef { |
| 761 | 761 | clocks = <&xtal>, |
| 762 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 762 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 763 | 763 | <&clkc CLKID_FCLK_DIV4>, |
| 764 | 764 | <&clkc CLKID_FCLK_DIV3>; |
| 765 | 765 | }; |
| @@ -811,7 +811,7 @@ · 810 unmodified lines | ||
| 811 | 811 | |
| 812 | 812 | &pwm_ab { |
| 813 | 813 | clocks = <&xtal>, |
| 814 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 814 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 815 | 815 | <&clkc CLKID_FCLK_DIV4>, |
| 816 | 816 | <&clkc CLKID_FCLK_DIV3>; |
| 817 | 817 | }; |
| @@ -822,14 +822,14 @@ · 4 unmodified lines | ||
| 822 | 822 | |
| 823 | 823 | &pwm_cd { |
| 824 | 824 | clocks = <&xtal>, |
| 825 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 825 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 826 | 826 | <&clkc CLKID_FCLK_DIV4>, |
| 827 | 827 | <&clkc CLKID_FCLK_DIV3>; |
| 828 | 828 | }; |
| 829 | 829 | |
| 830 | 830 | &pwm_ef { |
| 831 | 831 | clocks = <&xtal>, |
| 832 | − <>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 832 | + <0>, /* unknown/untested, the datasheet calls it "vid_pll" */ | |
| 833 | 833 | <&clkc CLKID_FCLK_DIV4>, |
| 834 | 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 | 90 | &display_dfr { |
| 81 | 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 | 53 | &display_dfr { |
| 44 | 54 | status = "okay"; |
| 45 | 55 | }; |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | next-level-cache = <&l2_0>; |
| 45 | 45 | clocks = <&scmi_dvfs 0>; |
| 46 | 46 | |
| 47 | − l2_0: l2-cache-0 { | |
| 47 | + l2_0: l2-cache { | |
| 48 | 48 | compatible = "cache"; |
| 49 | 49 | cache-level = <2>; |
| 50 | 50 | /* 8 ways set associative */ |
| @@ -53,13 +53,6 @@ · 2 unmodified lines | ||
| 53 | 53 | cache-sets = <2048>; |
| 54 | 54 | cache-unified; |
| 55 | 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 | 71 | next-level-cache = <&l2_1>; |
| 79 | 72 | clocks = <&scmi_dvfs 0>; |
| 80 | 73 | |
| 81 | − l2_1: l2-cache-1 { | |
| 74 | + l2_1: l2-cache { | |
| 82 | 75 | compatible = "cache"; |
| 83 | 76 | cache-level = <2>; |
| 84 | 77 | /* 8 ways set associative */ |
| @@ -105,7 +98,7 @@ · 20 unmodified lines | ||
| 105 | 98 | next-level-cache = <&l2_2>; |
| 106 | 99 | clocks = <&scmi_dvfs 1>; |
| 107 | 100 | |
| 108 | − l2_2: l2-cache-2 { | |
| 101 | + l2_2: l2-cache { | |
| 109 | 102 | compatible = "cache"; |
| 110 | 103 | cache-level = <2>; |
| 111 | 104 | /* 8 ways set associative */ |
| @@ -132,7 +125,7 @@ · 20 unmodified lines | ||
| 132 | 125 | next-level-cache = <&l2_3>; |
| 133 | 126 | clocks = <&scmi_dvfs 1>; |
| 134 | 127 | |
| 135 | − l2_3: l2-cache-3 { | |
| 128 | + l2_3: l2-cache { | |
| 136 | 129 | compatible = "cache"; |
| 137 | 130 | cache-level = <2>; |
| 138 | 131 | /* 8 ways set associative */ |
| @@ -143,6 +136,13 @@ · 4 unmodified lines | ||
| 143 | 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 | 148 | firmware { |
| @@ -144,6 +144,19 @@ · 143 unmodified lines | ||
| 144 | 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 | 160 | reserved-memory { |
| 148 | 161 | #address-cells = <2>; |
| 149 | 162 | #size-cells = <2>; |
| @@ -269,7 +282,7 @@ · 119 unmodified lines | ||
| 269 | 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 | 798 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>; |
| 786 | 799 | pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>; |
| 787 | 800 | vmmc-supply = <®_usdhc2_vmmc>; |
| 801 | + vqmmc-supply = <®_usdhc2_vqmmc>; | |
| 788 | 802 | }; |
| 789 | 803 | |
| 790 | 804 | &wdog1 { |
| @@ -1206,13 +1220,17 @@ · 415 unmodified lines | ||
| 1206 | 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 | 1229 | * Note: Due to ERR050080 we use discrete external on-module resistors pulling-up to the |
| 1211 | 1230 | * on-module +V3.3_1.8_SD (LDO5) rail and explicitly disable the internal pull-ups here. |
| 1212 | 1231 | */ |
| 1213 | 1232 | pinctrl_usdhc2: usdhc2grp { |
| 1214 | 1233 | fsl,pins = |
| 1215 | − <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | |
| 1216 | 1234 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90>, /* SODIMM 78 */ |
| 1217 | 1235 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x90>, /* SODIMM 74 */ |
| 1218 | 1236 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x90>, /* SODIMM 80 */ |
| @@ -1223,7 +1241,6 @@ · 4 unmodified lines | ||
| 1223 | 1241 | |
| 1224 | 1242 | pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { |
| 1225 | 1243 | fsl,pins = |
| 1226 | − <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | |
| 1227 | 1244 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94>, |
| 1228 | 1245 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x94>, |
| 1229 | 1246 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x94>, |
| @@ -1234,7 +1251,6 @@ · 4 unmodified lines | ||
| 1234 | 1251 | |
| 1235 | 1252 | pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { |
| 1236 | 1253 | fsl,pins = |
| 1237 | − <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x10>, | |
| 1238 | 1254 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96>, |
| 1239 | 1255 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x96>, |
| 1240 | 1256 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x96>, |
| @@ -1246,7 +1262,6 @@ · 5 unmodified lines | ||
| 1246 | 1262 | /* Avoid backfeeding with removed card power */ |
| 1247 | 1263 | pinctrl_usdhc2_sleep: usdhc2slpgrp { |
| 1248 | 1264 | fsl,pins = |
| 1249 | − <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x0>, | |
| 1250 | 1265 | <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x0>, |
| 1251 | 1266 | <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x0>, |
| 1252 | 1267 | <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x0>, |
| @@ -24,6 +24,20 @@ · 23 unmodified lines | ||
| 24 | 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 | 41 | &pgc_hdmimix { |
| 28 | 42 | assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>, |
| 29 | 43 | <&clk IMX8MP_CLK_HDMI_APB>; |
| @@ -46,6 +60,18 @@ · 16 unmodified lines | ||
| 46 | 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 | 75 | &media_blk_ctrl { |
| 50 | 76 | assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI>, |
| 51 | 77 | <&clk IMX8MP_CLK_MEDIA_APB>, |
| @@ -62,3 +88,5 @@ · 10 unmodified lines | ||
| 62 | 88 | <0>, <0>, <400000000>, |
| 63 | 89 | <1039500000>; |
| 64 | 90 | }; |
| 91 | + | |
| 92 | +/delete-node/ &{noc_opp_table/opp-1000000000}; | |
| @@ -35,7 +35,6 @@ · 34 unmodified lines | ||
| 35 | 35 | <0x1 0x00000000 0 0xc0000000>; |
| 36 | 36 | }; |
| 37 | 37 | |
| 38 | − | |
| 39 | 38 | reg_usdhc2_vmmc: regulator-usdhc2-vmmc { |
| 40 | 39 | compatible = "regulator-fixed"; |
| 41 | 40 | regulator-name = "VSD_3V3"; |
| @@ -46,6 +45,16 @@ · 4 unmodified lines | ||
| 46 | 45 | startup-delay-us = <100>; |
| 47 | 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 | 60 | &A53_0 { |
| @@ -205,6 +214,7 @@ · 153 unmodified lines | ||
| 205 | 214 | pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; |
| 206 | 215 | cd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; |
| 207 | 216 | vmmc-supply = <®_usdhc2_vmmc>; |
| 217 | + vqmmc-supply = <®_usdhc2_vqmmc>; | |
| 208 | 218 | bus-width = <4>; |
| 209 | 219 | status = "okay"; |
| 210 | 220 | }; |
| @@ -1645,6 +1645,12 @@ · 1644 unmodified lines | ||
| 1645 | 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 | 1654 | opp-1000000000 { |
| 1649 | 1655 | opp-hz = /bits/ 64 <1000000000>; |
| 1650 | 1656 | }; |
| @@ -1626,7 +1626,7 @@ · 1625 unmodified lines | ||
| 1626 | 1626 | reg = <0 0x4c300000 0 0x10000>, |
| 1627 | 1627 | <0 0x60100000 0 0xfe00000>, |
| 1628 | 1628 | <0 0x4c360000 0 0x10000>, |
| 1629 | − <0 0x4c340000 0 0x2000>; | |
| 1629 | + <0 0x4c340000 0 0x4000>; | |
| 1630 | 1630 | reg-names = "dbi", "config", "atu", "app"; |
| 1631 | 1631 | ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>, |
| 1632 | 1632 | <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>; |
| @@ -1673,7 +1673,7 @@ · 40 unmodified lines | ||
| 1673 | 1673 | reg = <0 0x4c300000 0 0x10000>, |
| 1674 | 1674 | <0 0x4c360000 0 0x1000>, |
| 1675 | 1675 | <0 0x4c320000 0 0x1000>, |
| 1676 | − <0 0x4c340000 0 0x2000>, | |
| 1676 | + <0 0x4c340000 0 0x4000>, | |
| 1677 | 1677 | <0 0x4c370000 0 0x10000>, |
| 1678 | 1678 | <0x9 0 1 0>; |
| 1679 | 1679 | reg-names = "dbi","atu", "dbi2", "app", "dma", "addr_space"; |
| @@ -1700,7 +1700,7 @@ · 20 unmodified lines | ||
| 1700 | 1700 | reg = <0 0x4c380000 0 0x10000>, |
| 1701 | 1701 | <8 0x80100000 0 0xfe00000>, |
| 1702 | 1702 | <0 0x4c3e0000 0 0x10000>, |
| 1703 | − <0 0x4c3c0000 0 0x2000>; | |
| 1703 | + <0 0x4c3c0000 0 0x4000>; | |
| 1704 | 1704 | reg-names = "dbi", "config", "atu", "app"; |
| 1705 | 1705 | ranges = <0x81000000 0 0x00000000 0x8 0x8ff00000 0 0x00100000>, |
| 1706 | 1706 | <0x82000000 0 0x10000000 0xa 0x10000000 0 0x10000000>; |
| @@ -1749,7 +1749,7 @@ · 42 unmodified lines | ||
| 1749 | 1749 | reg = <0 0x4c380000 0 0x10000>, |
| 1750 | 1750 | <0 0x4c3e0000 0 0x1000>, |
| 1751 | 1751 | <0 0x4c3a0000 0 0x1000>, |
| 1752 | − <0 0x4c3c0000 0 0x2000>, | |
| 1752 | + <0 0x4c3c0000 0 0x4000>, | |
| 1753 | 1753 | <0 0x4c3f0000 0 0x10000>, |
| 1754 | 1754 | <0xa 0 1 0>; |
| 1755 | 1755 | reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space"; |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | leds { |
| 28 | 28 | compatible = "gpio-leds"; |
| 29 | + pinctrl-names = "default"; | |
| 30 | + pinctrl-0 = <&spi_quad_pins>; | |
| 29 | 31 | |
| 30 | 32 | led-power1 { |
| 31 | 33 | label = "udpu:green:power"; |
| @@ -82,8 +84,6 @@ · 50 unmodified lines | ||
| 82 | 84 | |
| 83 | 85 | &spi0 { |
| 84 | 86 | status = "okay"; |
| 85 | − pinctrl-names = "default"; | |
| 86 | − pinctrl-0 = <&spi_quad_pins>; | |
| 87 | 87 | |
| 88 | 88 | flash@0 { |
| 89 | 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 | 115 | &pinctrl_nb { |
| 112 | 116 | i2c2_recovery_pins: i2c2-recovery-pins { |
| 113 | 117 | groups = "i2c2"; |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | 33 | vcc3v3_btreg: vcc3v3-btreg { |
| 34 | − compatible = "regulator-gpio"; | |
| 34 | + compatible = "regulator-fixed"; | |
| 35 | 35 | enable-active-high; |
| 36 | 36 | pinctrl-names = "default"; |
| 37 | 37 | pinctrl-0 = <&bt_enable_h>; |
| @@ -39,7 +39,6 @@ · 1 unmodified line | ||
| 39 | 39 | regulator-min-microvolt = <3300000>; |
| 40 | 40 | regulator-max-microvolt = <3300000>; |
| 41 | 41 | regulator-always-on; |
| 42 | − states = <3300000 0x0>; | |
| 43 | 42 | }; |
| 44 | 43 | |
| 45 | 44 | vcc3v3_rf_aux_mod: regulator-vcc3v3-rf-aux-mod { |
| @@ -26,5 +26,5 @@ · 25 unmodified lines | ||
| 26 | 26 | }; |
| 27 | 27 | |
| 28 | 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 | 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 | 43 | sdio_pwrseq: sdio-pwrseq { |
| 44 | 44 | compatible = "mmc-pwrseq-simple"; |
| 45 | 45 | clocks = <&rk808 1>; |
| 46 | − clock-names = "lpo"; | |
| 46 | + clock-names = "ext_clock"; | |
| 47 | 47 | pinctrl-names = "default"; |
| 48 | 48 | pinctrl-0 = <&wifi_enable_h>; |
| 49 | 49 | reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; |
| @@ -775,7 +775,7 @@ · 774 unmodified lines | ||
| 775 | 775 | rockchip,default-sample-phase = <90>; |
| 776 | 776 | status = "okay"; |
| 777 | 777 | |
| 778 | − sdio-wifi@1 { | |
| 778 | + wifi@1 { | |
| 779 | 779 | compatible = "brcm,bcm4329-fmac"; |
| 780 | 780 | reg = <1>; |
| 781 | 781 | interrupt-parent = <&gpio2>; |
| @@ -619,6 +619,8 @@ · 618 unmodified lines | ||
| 619 | 619 | bus-width = <8>; |
| 620 | 620 | max-frequency = <200000000>; |
| 621 | 621 | non-removable; |
| 622 | + pinctrl-names = "default"; | |
| 623 | + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; | |
| 622 | 624 | status = "okay"; |
| 623 | 625 | }; |
| 624 | 626 | |
| @@ -610,7 +610,7 @@ · 609 unmodified lines | ||
| 610 | 610 | reg = <0x51>; |
| 611 | 611 | clock-output-names = "hym8563"; |
| 612 | 612 | interrupt-parent = <&gpio0>; |
| 613 | − interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; | |
| 613 | + interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>; | |
| 614 | 614 | pinctrl-names = "default"; |
| 615 | 615 | pinctrl-0 = <&hym8563_int>; |
| 616 | 616 | wakeup-source; |
| @@ -222,6 +222,10 @@ · 221 unmodified lines | ||
| 222 | 222 | compatible = "realtek,rt5616"; |
| 223 | 223 | reg = <0x1b>; |
| 224 | 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 | 216 | &package_thermal { |
| 217 | + polling-delay = <1000>; | |
| 218 | + | |
| 217 | 219 | trips { |
| 218 | 220 | package_active1: trip-active1 { |
| 219 | 221 | temperature = <45000>; |
| @@ -11,20 +11,15 @@ · 10 unmodified lines | ||
| 11 | 11 | compatible = "operating-points-v2"; |
| 12 | 12 | opp-shared; |
| 13 | 13 | |
| 14 | − opp-1416000000 { | |
| 15 | − opp-hz = /bits/ 64 <1416000000>; | |
| 14 | + opp-1200000000 { | |
| 15 | + opp-hz = /bits/ 64 <1200000000>; | |
| 16 | 16 | opp-microvolt = <750000 750000 950000>; |
| 17 | 17 | clock-latency-ns = <40000>; |
| 18 | 18 | opp-suspend; |
| 19 | 19 | }; |
| 20 | − opp-1608000000 { | |
| 21 | − opp-hz = /bits/ 64 <1608000000>; | |
| 22 | − opp-microvolt = <887500 887500 950000>; | |
| 23 | − clock-latency-ns = <40000>; | |
| 24 | − }; | |
| 25 | − opp-1704000000 { | |
| 26 | − opp-hz = /bits/ 64 <1704000000>; | |
| 27 | − opp-microvolt = <937500 937500 950000>; | |
| 20 | + opp-1296000000 { | |
| 21 | + opp-hz = /bits/ 64 <1296000000>; | |
| 22 | + opp-microvolt = <775000 775000 950000>; | |
| 28 | 23 | clock-latency-ns = <40000>; |
| 29 | 24 | }; |
| 30 | 25 | }; |
| @@ -33,9 +28,14 @@ · 2 unmodified lines | ||
| 33 | 28 | compatible = "operating-points-v2"; |
| 34 | 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 | 36 | opp-1416000000 { |
| 37 | 37 | opp-hz = /bits/ 64 <1416000000>; |
| 38 | − opp-microvolt = <750000 750000 950000>; | |
| 38 | + opp-microvolt = <762500 762500 950000>; | |
| 39 | 39 | clock-latency-ns = <40000>; |
| 40 | 40 | }; |
| 41 | 41 | opp-1608000000 { |
| @@ -43,25 +43,20 @@ · 1 unmodified line | ||
| 43 | 43 | opp-microvolt = <787500 787500 950000>; |
| 44 | 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 | 48 | cluster2_opp_table: opp-table-cluster2 { |
| 59 | 49 | compatible = "operating-points-v2"; |
| 60 | 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 | 57 | opp-1416000000 { |
| 63 | 58 | opp-hz = /bits/ 64 <1416000000>; |
| 64 | − opp-microvolt = <750000 750000 950000>; | |
| 59 | + opp-microvolt = <762500 762500 950000>; | |
| 65 | 60 | clock-latency-ns = <40000>; |
| 66 | 61 | }; |
| 67 | 62 | opp-1608000000 { |
| @@ -69,16 +64,6 @@ · 1 unmodified line | ||
| 69 | 64 | opp-microvolt = <787500 787500 950000>; |
| 70 | 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 | 69 | gpu_opp_table: opp-table { |
| @@ -104,10 +89,6 @@ · 19 unmodified lines | ||
| 104 | 89 | opp-hz = /bits/ 64 <700000000>; |
| 105 | 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 | 118 | intc: interrupt-controller@4ac10000 { |
| 119 | − compatible = "arm,cortex-a7-gic"; | |
| 119 | + compatible = "arm,gic-400"; | |
| 120 | 120 | reg = <0x4ac10000 0x0 0x1000>, |
| 121 | − <0x4ac20000 0x0 0x2000>, | |
| 122 | − <0x4ac40000 0x0 0x2000>, | |
| 123 | − <0x4ac60000 0x0 0x2000>; | |
| 121 | + <0x4ac20000 0x0 0x20000>, | |
| 122 | + <0x4ac40000 0x0 0x20000>, | |
| 123 | + <0x4ac60000 0x0 0x20000>; | |
| 124 | 124 | #interrupt-cells = <3>; |
| 125 | 125 | interrupt-controller; |
| 126 | 126 | }; |
| @@ -1201,13 +1201,12 @@ · 1200 unmodified lines | ||
| 1201 | 1201 | }; |
| 1202 | 1202 | |
| 1203 | 1203 | intc: interrupt-controller@4ac10000 { |
| 1204 | − compatible = "arm,cortex-a7-gic"; | |
| 1204 | + compatible = "arm,gic-400"; | |
| 1205 | 1205 | reg = <0x4ac10000 0x1000>, |
| 1206 | − <0x4ac20000 0x2000>, | |
| 1207 | − <0x4ac40000 0x2000>, | |
| 1208 | − <0x4ac60000 0x2000>; | |
| 1206 | + <0x4ac20000 0x20000>, | |
| 1207 | + <0x4ac40000 0x20000>, | |
| 1208 | + <0x4ac60000 0x20000>; | |
| 1209 | 1209 | #interrupt-cells = <3>; |
| 1210 | − #address-cells = <1>; | |
| 1211 | 1210 | interrupt-controller; |
| 1212 | 1211 | }; |
| 1213 | 1212 | }; |
| @@ -115,14 +115,13 @@ · 114 unmodified lines | ||
| 115 | 115 | }; |
| 116 | 116 | |
| 117 | 117 | intc: interrupt-controller@4ac00000 { |
| 118 | − compatible = "arm,cortex-a7-gic"; | |
| 118 | + compatible = "arm,gic-400"; | |
| 119 | 119 | #interrupt-cells = <3>; |
| 120 | − #address-cells = <1>; | |
| 121 | 120 | interrupt-controller; |
| 122 | 121 | reg = <0x0 0x4ac10000 0x0 0x1000>, |
| 123 | − <0x0 0x4ac20000 0x0 0x2000>, | |
| 124 | − <0x0 0x4ac40000 0x0 0x2000>, | |
| 125 | − <0x0 0x4ac60000 0x0 0x2000>; | |
| 122 | + <0x0 0x4ac20000 0x0 0x20000>, | |
| 123 | + <0x0 0x4ac40000 0x0 0x20000>, | |
| 124 | + <0x0 0x4ac60000 0x0 0x20000>; | |
| 126 | 125 | }; |
| 127 | 126 | |
| 128 | 127 | psci { |
| @@ -1729,12 +1729,12 @@ CONFIG_NLS_CODEPAGE_437=y · 1728 unmodified lines | ||
| 1729 | 1729 | CONFIG_NLS_ISO8859_1=y |
| 1730 | 1730 | CONFIG_SECURITY=y |
| 1731 | 1731 | CONFIG_CRYPTO_USER=y |
| 1732 | +CONFIG_CRYPTO_CHACHA20=m | |
| 1732 | 1733 | CONFIG_CRYPTO_TEST=m |
| 1733 | 1734 | CONFIG_CRYPTO_ECHAINIV=y |
| 1734 | 1735 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 1735 | 1736 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 1736 | 1737 | CONFIG_CRYPTO_USER_API_RNG=m |
| 1737 | −CONFIG_CRYPTO_CHACHA20_NEON=m | |
| 1738 | 1738 | CONFIG_CRYPTO_GHASH_ARM64_CE=y |
| 1739 | 1739 | CONFIG_CRYPTO_SHA1_ARM64_CE=y |
| 1740 | 1740 | CONFIG_CRYPTO_SHA2_ARM64_CE=y |
| @@ -81,6 +81,7 @@ · 80 unmodified lines | ||
| 81 | 81 | #define ARM_CPU_PART_CORTEX_A78AE 0xD42 |
| 82 | 82 | #define ARM_CPU_PART_CORTEX_X1 0xD44 |
| 83 | 83 | #define ARM_CPU_PART_CORTEX_A510 0xD46 |
| 84 | +#define ARM_CPU_PART_CORTEX_X1C 0xD4C | |
| 84 | 85 | #define ARM_CPU_PART_CORTEX_A520 0xD80 |
| 85 | 86 | #define ARM_CPU_PART_CORTEX_A710 0xD47 |
| 86 | 87 | #define ARM_CPU_PART_CORTEX_A715 0xD4D |
| @@ -168,6 +169,7 @@ · 81 unmodified lines | ||
| 168 | 169 | #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) |
| 169 | 170 | #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) |
| 170 | 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 | 173 | #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) |
| 172 | 174 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) |
| 173 | 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 | 52 | mrs x0, id_aa64mmfr1_el1 |
| 53 | 53 | ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 |
| 54 | 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 | 57 | /* Enable GCS if supported */ |
| 58 | 58 | mrs_s x1, SYS_ID_AA64PFR1_EL1 |
| @@ -121,6 +121,15 @@ · 120 unmodified lines | ||
| 121 | 121 | #define ESR_ELx_FSC_SEA_TTW(n) (0x14 + (n)) |
| 122 | 122 | #define ESR_ELx_FSC_SECC (0x18) |
| 123 | 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 | 134 | /* Status codes for individual page table levels */ |
| 126 | 135 | #define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + (n)) |
| @@ -161,8 +170,6 @@ · 34 unmodified lines | ||
| 161 | 170 | #define ESR_ELx_Xs_MASK (GENMASK_ULL(4, 0)) |
| 162 | 171 | |
| 163 | 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 | 173 | #define ESR_ELx_CV (UL(1) << 24) |
| 167 | 174 | #define ESR_ELx_COND_SHIFT (20) |
| 168 | 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 | 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 | 507 | /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */ |
| 468 | 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 | 707 | #endif |
| 708 | 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 | 710 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, |
| 710 | 711 | enum aarch64_insn_system_register sysreg); |
| 711 | 712 | |
| @@ -100,9 +100,8 @@ · 99 unmodified lines | ||
| 100 | 100 | HCR_FMO | HCR_IMO | HCR_PTW | HCR_TID3 | HCR_TID1) |
| 101 | 101 | #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA) |
| 102 | 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 | 105 | #define MPAMHCR_HOST_FLAGS 0 |
| 107 | 106 | |
| 108 | 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 | 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 | 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 | 1588 | #define kvm_has_s1poe(k) \ |
| 1589 | 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 | 1596 | #endif /* __ARM64_KVM_HOST_H__ */ |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | * Was this synchronous external abort a RAS notification? |
| 15 | 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 | 19 | /* apei_claim_sea(NULL) expects to mask interrupts itself */ |
| 20 | 20 | lockdep_assert_irqs_enabled(); |
| @@ -94,17 +94,6 @@ static inline bool kaslr_requires_kpti(void) · 93 unmodified lines | ||
| 94 | 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 | 97 | return true; |
| 109 | 98 | } |
| 110 | 99 | |
| @@ -86,7 +86,7 @@ · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 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 | 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 | 98 | enum mitigation_state arm64_get_spectre_bhb_state(void); |
| 99 | 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 | 103 | void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused); |
| 101 | 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 | 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 | 115 | #endif /* !__ASSEMBLY__ */ |
| 103 | 116 | |
| 104 | 117 | #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ |
| @@ -335,7 +335,7 @@ static const struct midr_range cavium_erratum_23154_cpus[] = { · 334 unmodified lines | ||
| 335 | 335 | #endif |
| 336 | 336 | |
| 337 | 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 | 339 | /* Cavium ThunderX, T88 pass 1.x - 2.1 */ |
| 340 | 340 | MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), |
| 341 | 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 | 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 | 125 | EXPORT_SYMBOL(arm64_use_ng_mappings); |
| 119 | 126 | |
| 120 | 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 | 47 | PROVIDE(__pi_id_aa64zfr0_override = id_aa64zfr0_override); |
| 48 | 48 | PROVIDE(__pi_arm64_sw_feature_override = arm64_sw_feature_override); |
| 49 | 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 | 50 | PROVIDE(__pi__ctype = _ctype); |
| 55 | 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 | 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 | 233 | asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt) |
| 211 | 234 | { |
| 212 | 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 | 269 | u64 kaslr_seed = kaslr_early_init(fdt, chosen); |
| 247 | 270 | |
| 248 | 271 | if (kaslr_seed && kaslr_requires_kpti()) |
| 249 | − arm64_use_ng_mappings = true; | |
| 272 | + arm64_use_ng_mappings = ng_mappings_allowed(); | |
| 250 | 273 | |
| 251 | 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 | 879 | static const struct midr_range spectre_bhb_k132_list[] = { |
| 880 | 880 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), |
| 881 | 881 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), |
| 882 | + {}, | |
| 882 | 883 | }; |
| 883 | 884 | static const struct midr_range spectre_bhb_k38_list[] = { |
| 884 | 885 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), |
| 885 | 886 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), |
| 887 | + {}, | |
| 886 | 888 | }; |
| 887 | 889 | static const struct midr_range spectre_bhb_k32_list[] = { |
| 888 | 890 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), |
| 889 | 891 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE), |
| 890 | 892 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), |
| 891 | 893 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), |
| 894 | + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), | |
| 892 | 895 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 893 | 896 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), |
| 894 | 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 | 1000 | return true; |
| 998 | 1001 | } |
| 999 | 1002 | |
| 1003 | +u8 get_spectre_bhb_loop_value(void) | |
| 1004 | +{ | |
| 1005 | + return max_bhb_k; | |
| 1006 | +} | |
| 1007 | + | |
| 1000 | 1008 | static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) |
| 1001 | 1009 | { |
| 1002 | 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 | 1022 | isb(); |
| 1015 | 1023 | } |
| 1016 | 1024 | |
| 1017 | −static bool __read_mostly __nospectre_bhb; | |
| 1025 | +bool __read_mostly __nospectre_bhb; | |
| 1018 | 1026 | static int __init parse_spectre_bhb_param(char *str) |
| 1019 | 1027 | { |
| 1020 | 1028 | __nospectre_bhb = true; |
| @@ -1092,6 +1100,11 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry) · 71 unmodified lines | ||
| 1092 | 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 | 1108 | /* Patched to NOP when enabled */ |
| 1096 | 1109 | void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt, |
| 1097 | 1110 | __le32 *origptr, |
| @@ -2743,11 +2743,6 @@ bool kvm_arch_irqchip_in_kernel(struct kvm *kvm) · 2742 unmodified lines | ||
| 2743 | 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 | 2746 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, |
| 2752 | 2747 | struct irq_bypass_producer *prod) |
| 2753 | 2748 | { |
| @@ -12,6 +12,16 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/kvm_hyp.h> |
| 13 | 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 | 25 | static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) |
| 16 | 26 | { |
| 17 | 27 | int ret; |
| @@ -44,34 +54,50 @@ static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) · 26 unmodified lines | ||
| 44 | 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 | |
| 55 | − * happen during a stage 1 page table walk (the ESR_EL2.S1PTW | |
| 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 | |
| 63 | + * CPUs affected by ARM erratum #834220 may incorrectly report a | |
| 64 | + * stage-2 translation fault when a stage-1 permission fault occurs. | |
| 59 | 65 | * |
| 60 | − * Therefore, for all non S1PTW faults where we either have a | |
| 61 | − * permission fault or the errata workaround is enabled, we | |
| 62 | − * resolve the IPA using the AT instruction. | |
| 66 | + * Re-walk the page tables to determine if a stage-1 fault actually | |
| 67 | + * occurred. | |
| 63 | 68 | */ |
| 64 | − if (!(esr & ESR_ELx_S1PTW) && | |
| 65 | − (cpus_have_final_cap(ARM64_WORKAROUND_834220) || | |
| 66 | − esr_fsc_is_permission_fault(esr))) { | |
| 67 | − if (!__translate_far_to_hpfar(far, &hpfar)) | |
| 68 | − return false; | |
| 69 | − } else { | |
| 69 | + if (cpus_have_final_cap(ARM64_WORKAROUND_834220) && | |
| 70 | + esr_fsc_is_translation_fault(esr)) | |
| 71 | + return false; | |
| 72 | + | |
| 73 | + if (esr_fsc_is_translation_fault(esr) || esr_fsc_is_access_flag_fault(esr)) | |
| 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 | 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; | |
| 74 | − fault->hpfar_el2 = hpfar; | |
| 96 | + /* | |
| 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 | 101 | return true; |
| 76 | 102 | } |
| 77 | 103 | |
| @@ -235,6 +235,8 @@ static inline void __deactivate_traps_mpam(void) · 234 unmodified lines | ||
| 235 | 235 | |
| 236 | 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 | 240 | /* Trap on AArch32 cp15 c15 (impdef sysregs) accesses (EL1 or EL0) */ |
| 239 | 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 | 247 | * EL1 instead of being trapped to EL2. |
| 246 | 248 | */ |
| 247 | 249 | if (system_supports_pmuv3()) { |
| 248 | − struct kvm_cpu_context *hctxt; | |
| 249 | − | |
| 250 | 250 | write_sysreg(0, pmselr_el0); |
| 251 | 251 | |
| 252 | − hctxt = host_data_ptr(host_ctxt); | |
| 253 | 252 | ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0); |
| 254 | 253 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); |
| 255 | 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 | 268 | hcrx &= ~clr; |
| 270 | 269 | } |
| 271 | 270 | |
| 271 | + ctxt_sys_reg(hctxt, HCRX_EL2) = read_sysreg_s(SYS_HCRX_EL2); | |
| 272 | 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 | 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 | 283 | write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2); |
| 282 | 284 | |
| 283 | 285 | write_sysreg(0, hstr_el2); |
| 284 | 286 | if (system_supports_pmuv3()) { |
| 285 | − struct kvm_cpu_context *hctxt; | |
| 286 | − | |
| 287 | − hctxt = host_data_ptr(host_ctxt); | |
| 288 | 287 | write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0); |
| 289 | 288 | vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU); |
| 290 | 289 | } |
| 291 | 290 | |
| 292 | 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 | 294 | __deactivate_traps_hfgxtr(vcpu); |
| 296 | 295 | __deactivate_traps_mpam(); |
| @@ -730,10 +730,10 @@ static void do_ffa_version(struct arm_smccc_res *res, · 729 unmodified lines | ||
| 730 | 730 | hyp_ffa_version = ffa_req_version; |
| 731 | 731 | } |
| 732 | 732 | |
| 733 | − if (hyp_ffa_post_init()) | |
| 733 | + if (hyp_ffa_post_init()) { | |
| 734 | 734 | res->a0 = FFA_RET_NOT_SUPPORTED; |
| 735 | − else { | |
| 736 | − has_version_negotiated = true; | |
| 735 | + } else { | |
| 736 | + smp_store_release(&has_version_negotiated, true); | |
| 737 | 737 | res->a0 = hyp_ffa_version; |
| 738 | 738 | } |
| 739 | 739 | unlock: |
| @@ -809,7 +809,8 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) · 69 unmodified lines | ||
| 809 | 809 | if (!is_ffa_call(func_id)) |
| 810 | 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 | 814 | ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS); |
| 814 | 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 | 504 | int ret; |
| 505 | 505 | |
| 506 | − if (!addr_is_memory(addr)) | |
| 506 | + if (!range_is_memory(addr, addr + size)) | |
| 507 | 507 | return -EPERM; |
| 508 | 508 | |
| 509 | 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 | 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 | 589 | ret = host_stage2_idmap(addr); |
| 583 | 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 | 430 | * To check whether we have a MMIO-based (GICv2 compatible) |
| 431 | 431 | * CPU interface, we need to disable the system register |
| 432 | − * view. To do that safely, we have to prevent any interrupt | |
| 433 | − * from firing (which would be deadly). | |
| 432 | + * view. | |
| 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 | 434 | * Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates |
| 444 | 435 | * that to be able to set ICC_SRE_EL1.SRE to 0, all the |
| 445 | 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); | |
| 448 | − isb(); | |
| 446 | + if (has_vhe()) { | |
| 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 | 453 | write_gicreg(0, ICC_SRE_EL1); |
| 450 | 454 | isb(); |
| 451 | 455 | |
| @@ -453,11 +457,13 @@ u64 __vgic_v3_get_gic_config(void) · 1 unmodified line | ||
| 453 | 457 | |
| 454 | 458 | write_gicreg(sre, ICC_SRE_EL1); |
| 455 | 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 | 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 | 468 | val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63); |
| 463 | 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 | 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 | 1510 | * Permission faults just need to update the existing leaf entry, |
| 1506 | 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 | 1515 | if (!fault_is_perm || (logging_active && write_fault)) { |
| 1511 | 1516 | int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu); |
| 1512 | 1517 | |
| 1513 | − if (!is_protected_kvm_enabled()) { | |
| 1514 | − memcache = &vcpu->arch.mmu_page_cache; | |
| 1518 | + if (!is_protected_kvm_enabled()) | |
| 1515 | 1519 | ret = kvm_mmu_topup_memory_cache(memcache, min_pages); |
| 1516 | − } else { | |
| 1517 | − memcache = &vcpu->arch.pkvm_memcache; | |
| 1520 | + else | |
| 1518 | 1521 | ret = topup_hyp_memcache(memcache, min_pages); |
| 1519 | − } | |
| 1522 | + | |
| 1520 | 1523 | if (ret) |
| 1521 | 1524 | return ret; |
| 1522 | 1525 | } |
| @@ -1794,9 +1797,28 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) · 271 unmodified lines | ||
| 1794 | 1797 | gfn_t gfn; |
| 1795 | 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 | 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 | 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 | 1822 | is_iabt = kvm_vcpu_trap_is_iabt(vcpu); |
| 1801 | 1823 | |
| 1802 | 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 | 1843 | trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu), |
| 1834 | 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 | 1945 | if ((hw_val & mpam_mask) == (user_val & mpam_mask)) |
| 1946 | 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 | 1954 | return set_id_reg(vcpu, rd, user_val); |
| 1949 | 1955 | } |
| 1950 | 1956 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> |
| 7 | 7 | */ |
| 8 | +#include <linux/bitfield.h> | |
| 8 | 9 | #include <linux/bitops.h> |
| 9 | 10 | #include <linux/bug.h> |
| 10 | 11 | #include <linux/printk.h> |
| @@ -1500,43 +1501,41 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant, · 1489 unmodified lines | ||
| 1500 | 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 | 1506 | switch (type) { |
| 1509 | 1507 | case AARCH64_INSN_MB_SY: |
| 1510 | − opt = 0xf; | |
| 1511 | − break; | |
| 1508 | + return 0xf; | |
| 1512 | 1509 | case AARCH64_INSN_MB_ST: |
| 1513 | − opt = 0xe; | |
| 1514 | − break; | |
| 1510 | + return 0xe; | |
| 1515 | 1511 | case AARCH64_INSN_MB_LD: |
| 1516 | − opt = 0xd; | |
| 1517 | − break; | |
| 1512 | + return 0xd; | |
| 1518 | 1513 | case AARCH64_INSN_MB_ISH: |
| 1519 | − opt = 0xb; | |
| 1520 | − break; | |
| 1514 | + return 0xb; | |
| 1521 | 1515 | case AARCH64_INSN_MB_ISHST: |
| 1522 | − opt = 0xa; | |
| 1523 | − break; | |
| 1516 | + return 0xa; | |
| 1524 | 1517 | case AARCH64_INSN_MB_ISHLD: |
| 1525 | − opt = 0x9; | |
| 1526 | − break; | |
| 1518 | + return 0x9; | |
| 1527 | 1519 | case AARCH64_INSN_MB_NSH: |
| 1528 | − opt = 0x7; | |
| 1529 | − break; | |
| 1520 | + return 0x7; | |
| 1530 | 1521 | case AARCH64_INSN_MB_NSHST: |
| 1531 | − opt = 0x6; | |
| 1532 | − break; | |
| 1522 | + return 0x6; | |
| 1533 | 1523 | case AARCH64_INSN_MB_NSHLD: |
| 1534 | − opt = 0x5; | |
| 1535 | − break; | |
| 1524 | + return 0x5; | |
| 1536 | 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 | 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 | 1540 | insn = aarch64_insn_get_dmb_value(); |
| 1542 | 1541 | insn &= ~GENMASK(11, 8); |
| @@ -1545,6 +1544,21 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type) · 2 unmodified lines | ||
| 1545 | 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 | 1562 | u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, |
| 1549 | 1563 | enum aarch64_insn_system_register sysreg) |
| 1550 | 1564 | { |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #define pr_fmt(fmt) "bpf_jit: " fmt |
| 9 | 9 | |
| 10 | +#include <linux/arm-smccc.h> | |
| 10 | 11 | #include <linux/bitfield.h> |
| 11 | 12 | #include <linux/bpf.h> |
| 12 | 13 | #include <linux/filter.h> |
| @@ -17,6 +18,7 @@ · 4 unmodified lines | ||
| 17 | 18 | #include <asm/asm-extable.h> |
| 18 | 19 | #include <asm/byteorder.h> |
| 19 | 20 | #include <asm/cacheflush.h> |
| 21 | +#include <asm/cpufeature.h> | |
| 20 | 22 | #include <asm/debug-monitors.h> |
| 21 | 23 | #include <asm/insn.h> |
| 22 | 24 | #include <asm/text-patching.h> |
| @@ -939,7 +941,51 @@ static void build_plt(struct jit_ctx *ctx) · 916 unmodified lines | ||
| 939 | 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 | 990 | const u8 r0 = bpf2a64[BPF_REG_0]; |
| 945 | 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 | 999 | emit(A64_POP(A64_ZR, ptr, A64_SP), ctx); |
| 954 | 1000 | |
| 1001 | + if (was_classic) | |
| 1002 | + build_bhb_mitigation(ctx); | |
| 1003 | + | |
| 955 | 1004 | /* Restore FP/LR registers */ |
| 956 | 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 | 1008 | emit(A64_MOV(1, A64_R(0), r0), ctx); |
| 960 | 1009 | |
| 961 | 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 | 1949 | ctx.epilogue_offset = ctx.idx; |
| 1901 | − build_epilogue(&ctx); | |
| 1950 | + build_epilogue(&ctx, was_classic); | |
| 1902 | 1951 | build_plt(&ctx); |
| 1903 | 1952 | |
| 1904 | 1953 | extable_align = __alignof__(struct exception_table_entry); |
| @@ -1961,7 +2010,7 @@ skip_init_ctx: · 56 unmodified lines | ||
| 1961 | 2010 | goto out_free_hdr; |
| 1962 | 2011 | } |
| 1963 | 2012 | |
| 1964 | − build_epilogue(&ctx); | |
| 2013 | + build_epilogue(&ctx, was_classic); | |
| 1965 | 2014 | build_plt(&ctx); |
| 1966 | 2015 | |
| 1967 | 2016 | /* Extra pass to validate JITed code. */ |
| @@ -3536,3 +3536,10 @@ Field 5 F · 3535 unmodified lines | ||
| 3536 | 3536 | Field 4 P |
| 3537 | 3537 | Field 3:0 Align |
| 3538 | 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 | 72 | CONFIG_CRYPTO_MD5=y |
| 73 | 73 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 74 | 74 | # CONFIG_CRYPTO_HW is not set |
| 75 | −CONFIG_CRC_CCITT=y | |
| 76 | −CONFIG_CRC16=y | |
| 77 | −CONFIG_CRC_T10DIF=y | |
| 78 | 75 | CONFIG_FRAME_WARN=0 |
| 79 | 76 | CONFIG_MAGIC_SYSRQ=y |
| 80 | 77 | CONFIG_DEBUG_FS=y |
| @@ -73,6 +73,7 @@ config LOONGARCH · 72 unmodified lines | ||
| 73 | 73 | select ARCH_SUPPORTS_RT |
| 74 | 74 | select ARCH_USE_BUILTIN_BSWAP |
| 75 | 75 | select ARCH_USE_CMPXCHG_LOCKREF |
| 76 | + select ARCH_USE_MEMTEST | |
| 76 | 77 | select ARCH_USE_QUEUED_RWLOCKS |
| 77 | 78 | select ARCH_USE_QUEUED_SPINLOCKS |
| 78 | 79 | select ARCH_WANT_DEFAULT_BPF_JIT |
| @@ -22,22 +22,29 @@ · 21 unmodified lines | ||
| 22 | 22 | struct sigcontext; |
| 23 | 23 | |
| 24 | 24 | #define kernel_fpu_available() cpu_has_fpu |
| 25 | −extern void kernel_fpu_begin(void); | |
| 26 | −extern void kernel_fpu_end(void); | |
| 27 | − | |
| 28 | −extern void _init_fpu(unsigned int); | |
| 29 | −extern void _save_fp(struct loongarch_fpu *); | |
| 30 | −extern void _restore_fp(struct loongarch_fpu *); | |
| 31 | − | |
| 32 | −extern void _save_lsx(struct loongarch_fpu *fpu); | |
| 33 | −extern void _restore_lsx(struct loongarch_fpu *fpu); | |
| 34 | −extern void _init_lsx_upper(void); | |
| 35 | −extern void _restore_lsx_upper(struct loongarch_fpu *fpu); | |
| 36 | − | |
| 37 | −extern void _save_lasx(struct loongarch_fpu *fpu); | |
| 38 | −extern void _restore_lasx(struct loongarch_fpu *fpu); | |
| 39 | −extern void _init_lasx_upper(void); | |
| 40 | −extern void _restore_lasx_upper(struct loongarch_fpu *fpu); | |
| 25 | + | |
| 26 | +void kernel_fpu_begin(void); | |
| 27 | +void kernel_fpu_end(void); | |
| 28 | + | |
| 29 | +asmlinkage void _init_fpu(unsigned int); | |
| 30 | +asmlinkage void _save_fp(struct loongarch_fpu *); | |
| 31 | +asmlinkage void _restore_fp(struct loongarch_fpu *); | |
| 32 | +asmlinkage int _save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); | |
| 33 | +asmlinkage int _restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); | |
| 34 | + | |
| 35 | +asmlinkage void _save_lsx(struct loongarch_fpu *fpu); | |
| 36 | +asmlinkage void _restore_lsx(struct loongarch_fpu *fpu); | |
| 37 | +asmlinkage void _init_lsx_upper(void); | |
| 38 | +asmlinkage void _restore_lsx_upper(struct loongarch_fpu *fpu); | |
| 39 | +asmlinkage int _save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); | |
| 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 | 49 | static inline void enable_lsx(void); |
| 43 | 50 | static inline void disable_lsx(void); |
| @@ -12,9 +12,13 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/loongarch.h> |
| 13 | 13 | #include <asm/processor.h> |
| 14 | 14 | |
| 15 | −extern void _init_lbt(void); | |
| 16 | −extern void _save_lbt(struct loongarch_lbt *); | |
| 17 | −extern void _restore_lbt(struct loongarch_lbt *); | |
| 15 | +asmlinkage void _init_lbt(void); | |
| 16 | +asmlinkage void _save_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 | 23 | static inline int is_lbt_enabled(void) |
| 20 | 24 | { |
| @@ -33,9 +33,9 @@ struct pt_regs { · 32 unmodified lines | ||
| 33 | 33 | unsigned long __last[]; |
| 34 | 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 | 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 | 56 | /* Query offset/name of register from its name/offset */ |
| 57 | 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 | 61 | * regs_get_register() - get register value from its offset |
| @@ -15,7 +15,6 @@ typedef u32 uprobe_opcode_t; · 14 unmodified lines | ||
| 15 | 15 | #define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP) |
| 16 | 16 | |
| 17 | 17 | struct arch_uprobe { |
| 18 | − unsigned long resume_era; | |
| 19 | 18 | u32 insn[2]; |
| 20 | 19 | u32 ixol[2]; |
| 21 | 20 | bool simulate; |
| @@ -21,10 +21,10 @@ obj-$(CONFIG_CPU_HAS_LBT) += lbt.o · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o |
| 23 | 23 | |
| 24 | −CFLAGS_module.o += $(call cc-option,-Wno-override-init,) | |
| 25 | −CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,) | |
| 26 | −CFLAGS_traps.o += $(call cc-option,-Wno-override-init,) | |
| 27 | −CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,) | |
| 24 | +CFLAGS_module.o += $(call cc-disable-warning, override-init) | |
| 25 | +CFLAGS_syscall.o += $(call cc-disable-warning, override-init) | |
| 26 | +CFLAGS_traps.o += $(call cc-disable-warning, override-init) | |
| 27 | +CFLAGS_perf_event.o += $(call cc-disable-warning, override-init) | |
| 28 | 28 | |
| 29 | 29 | ifdef CONFIG_FUNCTION_TRACER |
| 30 | 30 | ifndef CONFIG_DYNAMIC_FTRACE |
| @@ -458,6 +458,7 @@ SYM_FUNC_START(_save_fp_context) · 457 unmodified lines | ||
| 458 | 458 | li.w a0, 0 # success |
| 459 | 459 | jr ra |
| 460 | 460 | SYM_FUNC_END(_save_fp_context) |
| 461 | +EXPORT_SYMBOL_GPL(_save_fp_context) | |
| 461 | 462 | |
| 462 | 463 | /* |
| 463 | 464 | * a0: fpregs |
| @@ -471,6 +472,7 @@ SYM_FUNC_START(_restore_fp_context) · 7 unmodified lines | ||
| 471 | 472 | li.w a0, 0 # success |
| 472 | 473 | jr ra |
| 473 | 474 | SYM_FUNC_END(_restore_fp_context) |
| 475 | +EXPORT_SYMBOL_GPL(_restore_fp_context) | |
| 474 | 476 | |
| 475 | 477 | /* |
| 476 | 478 | * a0: fpregs |
| @@ -484,6 +486,7 @@ SYM_FUNC_START(_save_lsx_context) · 7 unmodified lines | ||
| 484 | 486 | li.w a0, 0 # success |
| 485 | 487 | jr ra |
| 486 | 488 | SYM_FUNC_END(_save_lsx_context) |
| 489 | +EXPORT_SYMBOL_GPL(_save_lsx_context) | |
| 487 | 490 | |
| 488 | 491 | /* |
| 489 | 492 | * a0: fpregs |
| @@ -497,6 +500,7 @@ SYM_FUNC_START(_restore_lsx_context) · 7 unmodified lines | ||
| 497 | 500 | li.w a0, 0 # success |
| 498 | 501 | jr ra |
| 499 | 502 | SYM_FUNC_END(_restore_lsx_context) |
| 503 | +EXPORT_SYMBOL_GPL(_restore_lsx_context) | |
| 500 | 504 | |
| 501 | 505 | /* |
| 502 | 506 | * a0: fpregs |
| @@ -510,6 +514,7 @@ SYM_FUNC_START(_save_lasx_context) · 7 unmodified lines | ||
| 510 | 514 | li.w a0, 0 # success |
| 511 | 515 | jr ra |
| 512 | 516 | SYM_FUNC_END(_save_lasx_context) |
| 517 | +EXPORT_SYMBOL_GPL(_save_lasx_context) | |
| 513 | 518 | |
| 514 | 519 | /* |
| 515 | 520 | * a0: fpregs |
| @@ -523,6 +528,7 @@ SYM_FUNC_START(_restore_lasx_context) · 7 unmodified lines | ||
| 523 | 528 | li.w a0, 0 # success |
| 524 | 529 | jr ra |
| 525 | 530 | SYM_FUNC_END(_restore_lasx_context) |
| 531 | +EXPORT_SYMBOL_GPL(_restore_lasx_context) | |
| 526 | 532 | |
| 527 | 533 | .L_fpu_fault: |
| 528 | 534 | li.w a0, -EFAULT # failure |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/stackframe.h> |
| 17 | 17 | #include <asm/thread_info.h> |
| 18 | 18 | |
| 19 | + .section .cpuidle.text, "ax" | |
| 19 | 20 | .align 5 |
| 20 | 21 | SYM_FUNC_START(__arch_cpu_idle) |
| 21 | 22 | /* start of idle interrupt region */ |
| @@ -31,14 +32,16 @@ SYM_FUNC_START(__arch_cpu_idle) · 9 unmodified lines | ||
| 31 | 32 | */ |
| 32 | 33 | idle 0 |
| 33 | 34 | /* end of idle interrupt region */ |
| 34 | −1: jr ra | |
| 35 | +idle_exit: | |
| 36 | + jr ra | |
| 35 | 37 | SYM_FUNC_END(__arch_cpu_idle) |
| 38 | + .previous | |
| 36 | 39 | |
| 37 | 40 | SYM_CODE_START(handle_vint) |
| 38 | 41 | UNWIND_HINT_UNDEFINED |
| 39 | 42 | BACKUP_T0T1 |
| 40 | 43 | SAVE_ALL |
| 41 | − la_abs t1, 1b | |
| 44 | + la_abs t1, idle_exit | |
| 42 | 45 | LONG_L t0, sp, PT_ERA |
| 43 | 46 | /* 3 instructions idle interrupt region */ |
| 44 | 47 | ori t0, t0, 0b1100 |
| @@ -18,11 +18,28 @@ static unsigned int euen_mask = CSR_EUEN_FPEN; · 17 unmodified lines | ||
| 18 | 18 | static DEFINE_PER_CPU(bool, in_kernel_fpu); |
| 19 | 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 | 37 | void kernel_fpu_begin(void) |
| 22 | 38 | { |
| 23 | 39 | unsigned int *euen_curr; |
| 24 | 40 | |
| 25 | − preempt_disable(); | |
| 41 | + if (!irqs_disabled()) | |
| 42 | + fpregs_lock(); | |
| 26 | 43 | |
| 27 | 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 | 91 | this_cpu_write(in_kernel_fpu, false); |
| 75 | 92 | |
| 76 | − preempt_enable(); | |
| 93 | + if (!irqs_disabled()) | |
| 94 | + fpregs_unlock(); | |
| 77 | 95 | } |
| 78 | 96 | EXPORT_SYMBOL_GPL(kernel_fpu_end); |
| 79 | 97 | |
| @@ -90,6 +90,7 @@ SYM_FUNC_START(_save_lbt_context) · 89 unmodified lines | ||
| 90 | 90 | li.w a0, 0 # success |
| 91 | 91 | jr ra |
| 92 | 92 | SYM_FUNC_END(_save_lbt_context) |
| 93 | +EXPORT_SYMBOL_GPL(_save_lbt_context) | |
| 93 | 94 | |
| 94 | 95 | /* |
| 95 | 96 | * a0: scr |
| @@ -110,6 +111,7 @@ SYM_FUNC_START(_restore_lbt_context) · 14 unmodified lines | ||
| 110 | 111 | li.w a0, 0 # success |
| 111 | 112 | jr ra |
| 112 | 113 | SYM_FUNC_END(_restore_lbt_context) |
| 114 | +EXPORT_SYMBOL_GPL(_restore_lbt_context) | |
| 113 | 115 | |
| 114 | 116 | /* |
| 115 | 117 | * a0: ftop |
| @@ -120,6 +122,7 @@ SYM_FUNC_START(_save_ftop_context) · 4 unmodified lines | ||
| 120 | 122 | li.w a0, 0 # success |
| 121 | 123 | jr ra |
| 122 | 124 | SYM_FUNC_END(_save_ftop_context) |
| 125 | +EXPORT_SYMBOL_GPL(_save_ftop_context) | |
| 123 | 126 | |
| 124 | 127 | /* |
| 125 | 128 | * a0: ftop |
| @@ -150,6 +153,7 @@ SYM_FUNC_START(_restore_ftop_context) · 24 unmodified lines | ||
| 150 | 153 | li.w a0, 0 # success |
| 151 | 154 | jr ra |
| 152 | 155 | SYM_FUNC_END(_restore_ftop_context) |
| 156 | +EXPORT_SYMBOL_GPL(_restore_ftop_context) | |
| 153 | 157 | |
| 154 | 158 | .L_lbt_fault: |
| 155 | 159 | li.w a0, -EFAULT # failure |
| @@ -51,27 +51,6 @@ · 50 unmodified lines | ||
| 51 | 51 | #define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); }) |
| 52 | 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 | 54 | struct rt_sigframe { |
| 76 | 55 | struct siginfo rs_info; |
| 77 | 56 | struct ucontext rs_uctx; |
| @@ -111,7 +111,7 @@ static unsigned long __init get_loops_per_jiffy(void) · 110 unmodified lines | ||
| 111 | 111 | return lpj; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | −static long init_offset __nosavedata; | |
| 114 | +static long init_offset; | |
| 115 | 115 | |
| 116 | 116 | void save_counter(void) |
| 117 | 117 | { |
| @@ -553,9 +553,10 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) · 552 unmodified lines | ||
| 553 | 553 | die_if_kernel("Kernel ale access", regs); |
| 554 | 554 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 555 | 555 | #else |
| 556 | + bool pie = regs_irqs_disabled(regs); | |
| 556 | 557 | unsigned int *pc; |
| 557 | 558 | |
| 558 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 559 | + if (!pie) | |
| 559 | 560 | local_irq_enable(); |
| 560 | 561 | |
| 561 | 562 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); |
| @@ -582,7 +583,7 @@ sigbus: · 20 unmodified lines | ||
| 582 | 583 | die_if_kernel("Kernel ale access", regs); |
| 583 | 584 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 584 | 585 | out: |
| 585 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 586 | + if (!pie) | |
| 586 | 587 | local_irq_disable(); |
| 587 | 588 | #endif |
| 588 | 589 | irqentry_exit(regs, state); |
| @@ -621,12 +622,13 @@ static void bug_handler(struct pt_regs *regs) · 32 unmodified lines | ||
| 621 | 622 | asmlinkage void noinstr do_bce(struct pt_regs *regs) |
| 622 | 623 | { |
| 623 | 624 | bool user = user_mode(regs); |
| 625 | + bool pie = regs_irqs_disabled(regs); | |
| 624 | 626 | unsigned long era = exception_era(regs); |
| 625 | 627 | u64 badv = 0, lower = 0, upper = ULONG_MAX; |
| 626 | 628 | union loongarch_instruction insn; |
| 627 | 629 | irqentry_state_t state = irqentry_enter(regs); |
| 628 | 630 | |
| 629 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 631 | + if (!pie) | |
| 630 | 632 | local_irq_enable(); |
| 631 | 633 | |
| 632 | 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 | 694 | force_sig_bnderr((void __user *)badv, (void __user *)lower, (void __user *)upper); |
| 693 | 695 | |
| 694 | 696 | out: |
| 695 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 697 | + if (!pie) | |
| 696 | 698 | local_irq_disable(); |
| 697 | 699 | |
| 698 | 700 | irqentry_exit(regs, state); |
| @@ -710,11 +712,12 @@ bad_era: · 11 unmodified lines | ||
| 710 | 712 | asmlinkage void noinstr do_bp(struct pt_regs *regs) |
| 711 | 713 | { |
| 712 | 714 | bool user = user_mode(regs); |
| 715 | + bool pie = regs_irqs_disabled(regs); | |
| 713 | 716 | unsigned int opcode, bcode; |
| 714 | 717 | unsigned long era = exception_era(regs); |
| 715 | 718 | irqentry_state_t state = irqentry_enter(regs); |
| 716 | 719 | |
| 717 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 720 | + if (!pie) | |
| 718 | 721 | local_irq_enable(); |
| 719 | 722 | |
| 720 | 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 | 785 | out: |
| 783 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 786 | + if (!pie) | |
| 784 | 787 | local_irq_disable(); |
| 785 | 788 | |
| 786 | 789 | irqentry_exit(regs, state); |
| @@ -1015,6 +1018,7 @@ static void init_restore_lbt(void) · 228 unmodified lines | ||
| 1015 | 1018 | |
| 1016 | 1019 | asmlinkage void noinstr do_lbt(struct pt_regs *regs) |
| 1017 | 1020 | { |
| 1021 | + bool pie = regs_irqs_disabled(regs); | |
| 1018 | 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 | 1028 | * (including the user using 'MOVGR2GCSR' to turn on TM, which |
| 1025 | 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 | 1032 | local_irq_enable(); |
| 1029 | 1033 | |
| 1030 | 1034 | if (!cpu_has_lbt) { |
| @@ -1038,7 +1042,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs) · 7 unmodified lines | ||
| 1038 | 1042 | preempt_enable(); |
| 1039 | 1043 | |
| 1040 | 1044 | out: |
| 1041 | − if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 1045 | + if (!pie) | |
| 1042 | 1046 | local_irq_disable(); |
| 1043 | 1047 | |
| 1044 | 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 | 42 | utask->autask.saved_trap_nr = current->thread.trap_nr; |
| 43 | 43 | current->thread.trap_nr = UPROBE_TRAP_NR; |
| 44 | 44 | instruction_pointer_set(regs, utask->xol_vaddr); |
| 45 | − user_enable_single_step(current); | |
| 46 | 45 | |
| 47 | 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 | 53 | WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR); |
| 55 | 54 | current->thread.trap_nr = utask->autask.saved_trap_nr; |
| 56 | − | |
| 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); | |
| 55 | + instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE); | |
| 63 | 56 | |
| 64 | 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 | 64 | current->thread.trap_nr = utask->autask.saved_trap_nr; |
| 72 | 65 | instruction_pointer_set(regs, utask->vaddr); |
| 73 | − user_disable_single_step(current); | |
| 74 | 66 | } |
| 75 | 67 | |
| 76 | 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 | 83 | insn.word = auprobe->insn[0]; |
| 92 | 84 | arch_simulate_insn(insn, regs); |
| 93 | − auprobe->resume_era = regs->csr_era; | |
| 94 | 85 | |
| 95 | 86 | return true; |
| 96 | 87 | } |
| @@ -21,4 +21,4 @@ kvm-y += intc/eiointc.o · 20 unmodified lines | ||
| 21 | 21 | kvm-y += intc/pch_pic.o |
| 22 | 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 | 111 | ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); |
| 112 | 112 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
| 113 | 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 | 115 | return ret; |
| 116 | 116 | } |
| 117 | 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 | 127 | ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); |
| 128 | 128 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
| 129 | 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 | 132 | return ret; |
| 133 | 133 | } |
| @@ -296,10 +296,10 @@ int kvm_arch_enable_virtualization_cpu(void) · 295 unmodified lines | ||
| 296 | 296 | /* |
| 297 | 297 | * Enable virtualization features granting guest direct control of |
| 298 | 298 | * certain features: |
| 299 | − * GCI=2: Trap on init or unimplement cache instruction. | |
| 299 | + * GCI=2: Trap on init or unimplemented cache instruction. | |
| 300 | 300 | * TORU=0: Trap on Root Unimplement. |
| 301 | 301 | * CACTRL=1: Root control cache. |
| 302 | − * TOP=0: Trap on Previlege. | |
| 302 | + * TOP=0: Trap on Privilege. | |
| 303 | 303 | * TOE=0: Trap on Exception. |
| 304 | 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 | 294 | vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST; |
| 295 | 295 | |
| 296 | 296 | if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) { |
| 297 | + kvm_lose_pmu(vcpu); | |
| 297 | 298 | /* make sure the vcpu mode has been written */ |
| 298 | 299 | smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE); |
| 299 | 300 | local_irq_enable(); |
| @@ -902,6 +903,13 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu, · 602 unmodified lines | ||
| 902 | 903 | vcpu->arch.st.guest_addr = 0; |
| 903 | 904 | memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending)); |
| 904 | 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 | 913 | break; |
| 906 | 914 | default: |
| 907 | 915 | ret = -EINVAL; |
| @@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, · 46 unmodified lines | ||
| 47 | 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 | 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 | 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 | 68 | #ifdef CONFIG_ZONE_DMA32 |
| 72 | 69 | max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; |
| 73 | 70 | #endif |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #include <asm/fpu.h> |
| 3 | 3 | #include <asm/loongson.h> |
| 4 | 4 | #include <asm/sections.h> |
| 5 | +#include <asm/time.h> | |
| 5 | 6 | #include <asm/tlbflush.h> |
| 6 | 7 | #include <linux/suspend.h> |
| 7 | 8 | |
| @@ -14,6 +15,7 @@ struct pt_regs saved_regs; · 6 unmodified lines | ||
| 14 | 15 | |
| 15 | 16 | void save_processor_state(void) |
| 16 | 17 | { |
| 18 | + save_counter(); | |
| 17 | 19 | saved_crmd = csr_read32(LOONGARCH_CSR_CRMD); |
| 18 | 20 | saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); |
| 19 | 21 | saved_euen = csr_read32(LOONGARCH_CSR_EUEN); |
| @@ -26,6 +28,7 @@ void save_processor_state(void) · 6 unmodified lines | ||
| 26 | 28 | |
| 27 | 29 | void restore_processor_state(void) |
| 28 | 30 | { |
| 31 | + sync_counter(); | |
| 29 | 32 | csr_write32(saved_crmd, LOONGARCH_CSR_CRMD); |
| 30 | 33 | csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); |
| 31 | 34 | csr_write32(saved_euen, LOONGARCH_CSR_EUEN); |
| @@ -89,4 +89,3 @@ CONFIG_PANIC_ON_OOPS=y · 88 unmodified lines | ||
| 89 | 89 | # CONFIG_CRYPTO_ECHAINIV is not set |
| 90 | 90 | CONFIG_CRYPTO_ANSI_CPRNG=y |
| 91 | 91 | # CONFIG_CRYPTO_HW is not set |
| 92 | −CONFIG_CRC16=y | |
| @@ -82,7 +82,6 @@ CONFIG_LEDS_GPIO=y · 81 unmodified lines | ||
| 82 | 82 | # CONFIG_IOMMU_SUPPORT is not set |
| 83 | 83 | # CONFIG_DNOTIFY is not set |
| 84 | 84 | # CONFIG_PROC_PAGE_MONITOR is not set |
| 85 | −CONFIG_CRC_ITU_T=m | |
| 86 | 85 | CONFIG_STRIP_ASM_SYMS=y |
| 87 | 86 | CONFIG_DEBUG_FS=y |
| 88 | 87 | # CONFIG_SCHED_DEBUG is not set |
| @@ -238,7 +238,6 @@ CONFIG_CRYPTO_SERPENT=m · 237 unmodified lines | ||
| 238 | 238 | CONFIG_CRYPTO_TEA=m |
| 239 | 239 | CONFIG_CRYPTO_TWOFISH=m |
| 240 | 240 | CONFIG_CRYPTO_LZO=m |
| 241 | −CONFIG_CRC_T10DIF=m | |
| 242 | 241 | CONFIG_MAGIC_SYSRQ=y |
| 243 | 242 | CONFIG_DEBUG_MEMORY_INIT=y |
| 244 | 243 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -218,4 +218,3 @@ CONFIG_CRYPTO_SEED=m · 217 unmodified lines | ||
| 218 | 218 | CONFIG_CRYPTO_DEFLATE=m |
| 219 | 219 | CONFIG_CRYPTO_LZO=m |
| 220 | 220 | # CONFIG_CRYPTO_HW is not set |
| 221 | −CONFIG_CRC_CCITT=y | |
| @@ -326,5 +326,4 @@ CONFIG_CRYPTO_TEA=m · 325 unmodified lines | ||
| 326 | 326 | CONFIG_CRYPTO_TWOFISH=m |
| 327 | 327 | CONFIG_CRYPTO_LZO=m |
| 328 | 328 | # CONFIG_CRYPTO_HW is not set |
| 329 | −CONFIG_CRC_T10DIF=m | |
| 330 | 329 | CONFIG_DEBUG_MEMORY_INIT=y |
| @@ -317,4 +317,3 @@ CONFIG_CRYPTO_SERPENT=m · 316 unmodified lines | ||
| 317 | 317 | CONFIG_CRYPTO_TEA=m |
| 318 | 318 | CONFIG_CRYPTO_TWOFISH=m |
| 319 | 319 | CONFIG_CRYPTO_LZO=m |
| 320 | −CONFIG_CRC_T10DIF=m | |
| @@ -179,4 +179,3 @@ CONFIG_CRYPTO_RMD160=m · 178 unmodified lines | ||
| 179 | 179 | CONFIG_CRYPTO_WP512=m |
| 180 | 180 | CONFIG_CRYPTO_XCBC=m |
| 181 | 181 | CONFIG_CRYPTO_LZO=m |
| 182 | −CONFIG_CRC_T10DIF=m | |
| @@ -177,7 +177,6 @@ CONFIG_CRYPTO_SERPENT=y · 176 unmodified lines | ||
| 177 | 177 | CONFIG_CRYPTO_TEA=y |
| 178 | 178 | CONFIG_CRYPTO_TWOFISH=y |
| 179 | 179 | CONFIG_CRYPTO_DEFLATE=y |
| 180 | −CONFIG_CRC_T10DIF=y | |
| 181 | 180 | CONFIG_FONTS=y |
| 182 | 181 | CONFIG_FONT_8x8=y |
| 183 | 182 | CONFIG_FONT_8x16=y |
| @@ -111,7 +111,6 @@ CONFIG_NLS_KOI8_U=y · 110 unmodified lines | ||
| 111 | 111 | CONFIG_NLS_UTF8=y |
| 112 | 112 | CONFIG_CRYPTO_DEFLATE=y |
| 113 | 113 | CONFIG_CRYPTO_LZO=y |
| 114 | −CONFIG_CRC16=y | |
| 115 | 114 | CONFIG_XZ_DEC=y |
| 116 | 115 | CONFIG_PRINTK_TIME=y |
| 117 | 116 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -155,5 +155,4 @@ CONFIG_JFFS2_COMPRESSION_OPTIONS=y · 154 unmodified lines | ||
| 155 | 155 | CONFIG_SQUASHFS=y |
| 156 | 156 | CONFIG_CRYPTO_TEST=m |
| 157 | 157 | # CONFIG_CRYPTO_HW is not set |
| 158 | −CONFIG_CRC16=m | |
| 159 | 158 | CONFIG_STRIP_ASM_SYMS=y |
| @@ -128,7 +128,6 @@ CONFIG_SQUASHFS=y · 127 unmodified lines | ||
| 128 | 128 | # CONFIG_SQUASHFS_ZLIB is not set |
| 129 | 129 | CONFIG_SQUASHFS_XZ=y |
| 130 | 130 | CONFIG_CRYPTO_ARC4=m |
| 131 | −CONFIG_CRC_ITU_T=m | |
| 132 | 131 | # CONFIG_XZ_DEC_X86 is not set |
| 133 | 132 | # CONFIG_XZ_DEC_POWERPC is not set |
| 134 | 133 | # CONFIG_XZ_DEC_IA64 is not set |
| @@ -99,4 +99,3 @@ CONFIG_CRYPTO_TWOFISH=m · 98 unmodified lines | ||
| 99 | 99 | CONFIG_CRYPTO_DEFLATE=m |
| 100 | 100 | CONFIG_CRYPTO_LZO=m |
| 101 | 101 | # CONFIG_CRYPTO_HW is not set |
| 102 | −CONFIG_CRC16=m | |
| @@ -111,7 +111,6 @@ CONFIG_NLS_KOI8_U=y · 110 unmodified lines | ||
| 111 | 111 | CONFIG_NLS_UTF8=y |
| 112 | 112 | CONFIG_CRYPTO_DEFLATE=y |
| 113 | 113 | CONFIG_CRYPTO_LZO=y |
| 114 | −CONFIG_CRC16=y | |
| 115 | 114 | CONFIG_XZ_DEC=y |
| 116 | 115 | CONFIG_PRINTK_TIME=y |
| 117 | 116 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| @@ -140,7 +140,6 @@ CONFIG_SQUASHFS=y · 139 unmodified lines | ||
| 140 | 140 | # CONFIG_SQUASHFS_ZLIB is not set |
| 141 | 141 | CONFIG_SQUASHFS_XZ=y |
| 142 | 142 | CONFIG_CRYPTO_ARC4=m |
| 143 | −CONFIG_CRC_ITU_T=m | |
| 144 | 143 | CONFIG_PRINTK_TIME=y |
| 145 | 144 | CONFIG_STRIP_ASM_SYMS=y |
| 146 | 145 | CONFIG_DEBUG_FS=y |
| @@ -6,11 +6,10 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/linkage.h> |
| 7 | 7 | |
| 8 | 8 | extern void (*cpu_wait)(void); |
| 9 | −extern void r4k_wait(void); | |
| 10 | −extern asmlinkage void __r4k_wait(void); | |
| 9 | +extern asmlinkage void r4k_wait(void); | |
| 11 | 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 | 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 | 66 | /* Query offset/name of register from its name/offset */ |
| 67 | 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 | 72 | * regs_get_register() - get register value from its offset |
| @@ -104,48 +104,59 @@ handle_vcei: · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | __FINIT |
| 106 | 106 | |
| 107 | − .align 5 /* 32 byte rollback region */ | |
| 108 | −LEAF(__r4k_wait) | |
| 109 | − .set push | |
| 110 | − .set noreorder | |
| 111 | − /* start of rollback region */ | |
| 112 | − LONG_L t0, TI_FLAGS($28) | |
| 113 | − nop | |
| 114 | − andi t0, _TIF_NEED_RESCHED | |
| 115 | − bnez t0, 1f | |
| 116 | − nop | |
| 117 | − nop | |
| 118 | − nop | |
| 119 | −#ifdef CONFIG_CPU_MICROMIPS | |
| 120 | − nop | |
| 121 | − nop | |
| 122 | − nop | |
| 123 | − nop | |
| 124 | −#endif | |
| 107 | + .section .cpuidle.text,"ax" | |
| 108 | + /* Align to 32 bytes for the maximum idle interrupt region size. */ | |
| 109 | + .align 5 | |
| 110 | +LEAF(r4k_wait) | |
| 111 | + /* Keep the ISA bit clear for calculations on local labels here. */ | |
| 112 | +0: .fill 0 | |
| 113 | + /* Start of idle interrupt region. */ | |
| 114 | + local_irq_enable | |
| 115 | + /* | |
| 116 | + * If an interrupt lands here, before going idle on the next | |
| 117 | + * instruction, we must *NOT* go idle since the interrupt could | |
| 118 | + * have set TIF_NEED_RESCHED or caused a timer to need resched. | |
| 119 | + * Fall through -- see skipover_handler below -- and have the | |
| 120 | + * idle loop take care of things. | |
| 121 | + */ | |
| 122 | +1: .fill 0 | |
| 123 | + /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */ | |
| 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 | 132 | .set MIPS_ISA_ARCH_LEVEL_RAW |
| 133 | +r4k_wait_insn: | |
| 126 | 134 | wait |
| 127 | − /* end of rollback region (the region size must be power of two) */ | |
| 128 | −1: | |
| 135 | +r4k_wait_exit: | |
| 136 | + .set mips0 | |
| 137 | + local_irq_disable | |
| 129 | 138 | jr ra |
| 130 | − nop | |
| 131 | − .set pop | |
| 132 | − END(__r4k_wait) | |
| 139 | + END(r4k_wait) | |
| 140 | + .previous | |
| 133 | 141 | |
| 134 | − .macro BUILD_ROLLBACK_PROLOGUE handler | |
| 135 | − FEXPORT(rollback_\handler) | |
| 142 | + .macro BUILD_SKIPOVER_PROLOGUE handler | |
| 143 | + FEXPORT(skipover_\handler) | |
| 136 | 144 | .set push |
| 137 | 145 | .set noat |
| 138 | 146 | MFC0 k0, CP0_EPC |
| 139 | − PTR_LA k1, __r4k_wait | |
| 140 | − ori k0, 0x1f /* 32 byte rollback region */ | |
| 141 | − xori k0, 0x1f | |
| 147 | + /* Subtract/add 2 to let the ISA bit propagate through the mask. */ | |
| 148 | + PTR_LA k1, r4k_wait_insn - 2 | |
| 149 | + ori k0, r4k_wait_idle_size - 2 | |
| 150 | + .set noreorder | |
| 142 | 151 | bne k0, k1, \handler |
| 152 | + PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 | |
| 153 | + .set reorder | |
| 143 | 154 | MTC0 k0, CP0_EPC |
| 144 | 155 | .set pop |
| 145 | 156 | .endm |
| 146 | 157 | |
| 147 | 158 | .align 5 |
| 148 | −BUILD_ROLLBACK_PROLOGUE handle_int | |
| 159 | +BUILD_SKIPOVER_PROLOGUE handle_int | |
| 149 | 160 | NESTED(handle_int, PT_SIZE, sp) |
| 150 | 161 | .cfi_signal_frame |
| 151 | 162 | #ifdef CONFIG_TRACE_IRQFLAGS |
| @@ -265,7 +276,7 @@ NESTED(except_vec_ejtag_debug, 0, sp) · 113 unmodified lines | ||
| 265 | 276 | * This prototype is copied to ebase + n*IntCtl.VS and patched |
| 266 | 277 | * to invoke the handler |
| 267 | 278 | */ |
| 268 | −BUILD_ROLLBACK_PROLOGUE except_vec_vi | |
| 279 | +BUILD_SKIPOVER_PROLOGUE except_vec_vi | |
| 269 | 280 | NESTED(except_vec_vi, 0, sp) |
| 270 | 281 | SAVE_SOME docfi=1 |
| 271 | 282 | SAVE_AT docfi=1 |
| @@ -35,13 +35,6 @@ static void __cpuidle r3081_wait(void) · 34 unmodified lines | ||
| 35 | 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 | 39 | * This variant is preferable as it allows testing need_resched and going to |
| 47 | 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 | 332 | mips_cps_cluster_bootcfg = kcalloc(nclusters, |
| 333 | 333 | sizeof(*mips_cps_cluster_bootcfg), |
| 334 | 334 | GFP_KERNEL); |
| 335 | + if (!mips_cps_cluster_bootcfg) | |
| 336 | + goto err_out; | |
| 335 | 337 | |
| 336 | 338 | if (nclusters > 1) |
| 337 | 339 | mips_cm_update_property(); |
| @@ -348,6 +350,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) · 10 unmodified lines | ||
| 348 | 350 | mips_cps_cluster_bootcfg[cl].core_power = |
| 349 | 351 | kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long), |
| 350 | 352 | GFP_KERNEL); |
| 353 | + if (!mips_cps_cluster_bootcfg[cl].core_power) | |
| 354 | + goto err_out; | |
| 351 | 355 | |
| 352 | 356 | /* Allocate VPE boot configuration structs */ |
| 353 | 357 | for (c = 0; c < ncores; c++) { |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | ||
| 77 | 77 | #include "access-helper.h" |
| 78 | 78 | |
| 79 | 79 | extern void check_wait(void); |
| 80 | −extern asmlinkage void rollback_handle_int(void); | |
| 80 | +extern asmlinkage void skipover_handle_int(void); | |
| 81 | 81 | extern asmlinkage void handle_int(void); |
| 82 | 82 | extern asmlinkage void handle_adel(void); |
| 83 | 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 | 2067 | extern const u8 except_vec_vi[]; |
| 2068 | 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 | 2070 | unsigned long handler; |
| 2071 | 2071 | unsigned long old_handler = vi_handlers[n]; |
| 2072 | 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 | 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 | 2099 | except_vec_vi; |
| 2100 | 2100 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) |
| 2101 | 2101 | ori_offset = except_vec_vi_ori - vec_start + 2; |
| @@ -2426,8 +2426,8 @@ void __init trap_init(void) · 324 unmodified lines | ||
| 2426 | 2426 | if (board_be_init) |
| 2427 | 2427 | board_be_init(); |
| 2428 | 2428 | |
| 2429 | − set_except_vector(EXCCODE_INT, using_rollback_handler() ? | |
| 2430 | − rollback_handle_int : handle_int); | |
| 2429 | + set_except_vector(EXCCODE_INT, using_skipover_handler() ? | |
| 2430 | + skipover_handle_int : handle_int); | |
| 2431 | 2431 | set_except_vector(EXCCODE_MOD, handle_tlbm); |
| 2432 | 2432 | set_except_vector(EXCCODE_TLBL, handle_tlbl); |
| 2433 | 2433 | set_except_vector(EXCCODE_TLBS, handle_tlbs); |
| @@ -23,6 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | */ |
| 24 | 24 | extern void local_dcache_page_flush(struct page *page); |
| 25 | 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 | 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 | 41 | extern void smp_icache_page_inv(struct page *page); |
| 39 | 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 | 59 | * Synchronizes caches. Whenever a cpu writes executable code to memory, this |
| 43 | 60 | * should be called to make sure the processor sees the newly written code. |
| @@ -15,16 +15,21 @@ · 14 unmodified lines | ||
| 15 | 15 | #ifndef __ASM_OPENRISC_CPUINFO_H |
| 16 | 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 | 28 | struct cpuinfo_or1k { |
| 19 | 29 | u32 clock_frequency; |
| 20 | 30 | |
| 21 | − u32 icache_size; | |
| 22 | − u32 icache_block_size; | |
| 23 | − u32 icache_ways; | |
| 24 | − | |
| 25 | − u32 dcache_size; | |
| 26 | − u32 dcache_block_size; | |
| 27 | − u32 dcache_ways; | |
| 31 | + struct cache_desc icache; | |
| 32 | + struct cache_desc dcache; | |
| 28 | 33 | |
| 29 | 34 | u16 coreid; |
| 30 | 35 | }; |
| @@ -32,4 +37,9 @@ struct cpuinfo_or1k { · 1 unmodified line | ||
| 32 | 37 | extern struct cpuinfo_or1k cpuinfo_or1k[NR_CPUS]; |
| 33 | 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 | 45 | #endif /* __ASM_OPENRISC_CPUINFO_H */ |
| @@ -7,7 +7,7 @@ extra-y := vmlinux.lds · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | obj-y := head.o setup.o or32_ksyms.o process.o dma.o \ |
| 9 | 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 | 12 | obj-$(CONFIG_SMP) += smp.o sync-timer.o |
| 13 | 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 | 17 | #include <linux/pagewalk.h> |
| 18 | 18 | |
| 19 | 19 | #include <asm/cpuinfo.h> |
| 20 | +#include <asm/cacheflush.h> | |
| 20 | 21 | #include <asm/spr_defs.h> |
| 21 | 22 | #include <asm/tlbflush.h> |
| 22 | 23 | |
| @@ -24,9 +25,6 @@ static int · 1 unmodified line | ||
| 24 | 25 | page_set_nocache(pte_t *pte, unsigned long addr, |
| 25 | 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 | 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 | 34 | flush_tlb_kernel_range(addr, addr + PAGE_SIZE); |
| 37 | 35 | |
| 38 | 36 | /* Flush page out of dcache */ |
| 39 | − for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo->dcache_block_size) | |
| 40 | − mtspr(SPR_DCBFR, cl); | |
| 37 | + local_dcache_range_flush(__pa(addr), __pa(next)); | |
| 41 | 38 | |
| 42 | 39 | return 0; |
| 43 | 40 | } |
| @@ -98,21 +95,14 @@ void arch_dma_clear_uncached(void *cpu_addr, size_t size) · 54 unmodified lines | ||
| 98 | 95 | void arch_sync_dma_for_device(phys_addr_t addr, size_t size, |
| 99 | 96 | enum dma_data_direction dir) |
| 100 | 97 | { |
| 101 | − unsigned long cl; | |
| 102 | − struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; | |
| 103 | − | |
| 104 | 98 | switch (dir) { |
| 105 | 99 | case DMA_TO_DEVICE: |
| 106 | 100 | /* Flush the dcache for the requested range */ |
| 107 | − for (cl = addr; cl < addr + size; | |
| 108 | − cl += cpuinfo->dcache_block_size) | |
| 109 | − mtspr(SPR_DCBFR, cl); | |
| 101 | + local_dcache_range_flush(addr, addr + size); | |
| 110 | 102 | break; |
| 111 | 103 | case DMA_FROM_DEVICE: |
| 112 | 104 | /* Invalidate the dcache for the requested range */ |
| 113 | − for (cl = addr; cl < addr + size; | |
| 114 | − cl += cpuinfo->dcache_block_size) | |
| 115 | − mtspr(SPR_DCBIR, cl); | |
| 105 | + local_dcache_range_inv(addr, addr + size); | |
| 116 | 106 | break; |
| 117 | 107 | default: |
| 118 | 108 | /* |
| @@ -113,21 +113,6 @@ static void print_cpuinfo(void) · 112 unmodified lines | ||
| 113 | 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 | 116 | if (upr & SPR_UPR_DMP) |
| 132 | 117 | printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n", |
| 133 | 118 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), |
| @@ -155,8 +140,6 @@ static void print_cpuinfo(void) · 21 unmodified lines | ||
| 155 | 140 | void __init setup_cpuinfo(void) |
| 156 | 141 | { |
| 157 | 142 | struct device_node *cpu; |
| 158 | − unsigned long iccfgr, dccfgr; | |
| 159 | − unsigned long cache_set_size; | |
| 160 | 143 | int cpu_id = smp_processor_id(); |
| 161 | 144 | struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[cpu_id]; |
| 162 | 145 | |
| @@ -164,20 +147,6 @@ void __init setup_cpuinfo(void) · 1 unmodified line | ||
| 164 | 147 | if (!cpu) |
| 165 | 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 | 150 | if (of_property_read_u32(cpu, "clock-frequency", |
| 182 | 151 | &cpuinfo->clock_frequency)) { |
| 183 | 152 | printk(KERN_WARNING |
| @@ -294,14 +263,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 110 unmodified lines | ||
| 294 | 263 | unsigned int vr, cpucfgr; |
| 295 | 264 | unsigned int avr; |
| 296 | 265 | unsigned int version; |
| 266 | +#ifdef CONFIG_SMP | |
| 297 | 267 | struct cpuinfo_or1k *cpuinfo = v; |
| 268 | + seq_printf(m, "processor\t\t: %d\n", cpuinfo->coreid); | |
| 269 | +#endif | |
| 298 | 270 | |
| 299 | 271 | vr = mfspr(SPR_VR); |
| 300 | 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 | 274 | if (vr & SPR_VR_UVRP) { |
| 306 | 275 | vr = mfspr(SPR_VR2); |
| 307 | 276 | version = vr & SPR_VR2_VER; |
| @@ -320,14 +289,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 12 unmodified lines | ||
| 320 | 289 | seq_printf(m, "revision\t\t: %d\n", vr & SPR_VR_REV); |
| 321 | 290 | } |
| 322 | 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 | 292 | seq_printf(m, "immu\t\t\t: %d entries, %lu ways\n", |
| 332 | 293 | 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), |
| 333 | 294 | 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW)); |
| @@ -14,31 +14,70 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <asm/spr_defs.h> |
| 15 | 15 | #include <asm/cache.h> |
| 16 | 16 | #include <asm/cacheflush.h> |
| 17 | +#include <asm/cpuinfo.h> | |
| 17 | 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; | |
| 22 | − unsigned long line = paddr & ~(L1_CACHE_BYTES - 1); | |
| 25 | + unsigned long upr = mfspr(SPR_UPR); | |
| 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) { | |
| 25 | − mtspr(reg, line); | |
| 26 | − line += L1_CACHE_BYTES; | |
| 37 | + while (paddr < end) { | |
| 38 | + mtspr(reg, paddr); | |
| 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 | 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 | 58 | EXPORT_SYMBOL(local_dcache_page_flush); |
| 35 | 59 | |
| 36 | 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 | 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 | 81 | void update_cache(struct vm_area_struct *vma, unsigned long address, |
| 43 | 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 | 97 | sync_icache_dcache(folio_page(folio, nr)); |
| 59 | 98 | } |
| 60 | 99 | } |
| 61 | − | |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <asm/fixmap.h> |
| 36 | 36 | #include <asm/tlbflush.h> |
| 37 | 37 | #include <asm/sections.h> |
| 38 | +#include <asm/cacheflush.h> | |
| 38 | 39 | |
| 39 | 40 | int mem_init_done; |
| 40 | 41 | |
| @@ -176,8 +177,8 @@ void __init paging_init(void) · 135 unmodified lines | ||
| 176 | 177 | barrier(); |
| 177 | 178 | |
| 178 | 179 | /* Invalidate instruction caches after code modification */ |
| 179 | − mtspr(SPR_ICBIR, 0x900); | |
| 180 | − mtspr(SPR_ICBIR, 0xa00); | |
| 180 | + local_icache_block_inv(0x900); | |
| 181 | + local_icache_block_inv(0xa00); | |
| 181 | 182 | |
| 182 | 183 | /* New TLB miss handlers and kernel page tables are in now place. |
| 183 | 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 | 264 | CONFIG_CRYPTO_SHA1=y |
| 265 | 265 | CONFIG_CRYPTO_WP512=m |
| 266 | 266 | CONFIG_CRYPTO_DEFLATE=y |
| 267 | −CONFIG_CRC_CCITT=m | |
| 268 | −CONFIG_CRC_T10DIF=y | |
| 269 | 267 | CONFIG_FONTS=y |
| 270 | 268 | CONFIG_PRINTK_TIME=y |
| 271 | 269 | CONFIG_MAGIC_SYSRQ=y |
| @@ -292,7 +292,6 @@ CONFIG_CRYPTO_MD5=y · 291 unmodified lines | ||
| 292 | 292 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 293 | 293 | CONFIG_CRYPTO_DEFLATE=m |
| 294 | 294 | # CONFIG_CRYPTO_HW is not set |
| 295 | −CONFIG_CRC_CCITT=m | |
| 296 | 295 | CONFIG_PRINTK_TIME=y |
| 297 | 296 | CONFIG_DEBUG_KERNEL=y |
| 298 | 297 | CONFIG_STRIP_ASM_SYMS=y |
| @@ -97,9 +97,19 @@ handle_fpe(struct pt_regs *regs) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | memcpy(regs->fr, frcopy, sizeof regs->fr); |
| 99 | 99 | if (signalcode != 0) { |
| 100 | − force_sig_fault(signalcode >> 24, signalcode & 0xffffff, | |
| 101 | − (void __user *) regs->iaoq[0]); | |
| 102 | − return -1; | |
| 100 | + int sig = signalcode >> 24; | |
| 101 | + | |
| 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 | 115 | return signalcode ? -1 : 0; |
| @@ -234,10 +234,8 @@ fi · 233 unmodified lines | ||
| 234 | 234 | |
| 235 | 235 | # suppress some warnings in recent ld versions |
| 236 | 236 | nowarn="-z noexecstack" |
| 237 | −if ! ld_is_lld; then | |
| 238 | − if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then | |
| 239 | − nowarn="$nowarn --no-warn-rwx-segments" | |
| 240 | − fi | |
| 237 | +if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then | |
| 238 | + nowarn="$nowarn --no-warn-rwx-segments" | |
| 241 | 239 | fi |
| 242 | 240 | |
| 243 | 241 | platformo=$object/"$platform".o |
| @@ -91,5 +91,4 @@ CONFIG_AFFS_FS=m · 90 unmodified lines | ||
| 91 | 91 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 92 | 92 | CONFIG_NLS_CODEPAGE_437=y |
| 93 | 93 | CONFIG_NLS_ISO8859_1=y |
| 94 | −CONFIG_CRC_T10DIF=y | |
| 95 | 94 | CONFIG_MAGIC_SYSRQ=y |
| @@ -85,8 +85,6 @@ CONFIG_NLS_ASCII=y · 84 unmodified lines | ||
| 85 | 85 | CONFIG_NLS_ISO8859_1=y |
| 86 | 86 | CONFIG_NLS_ISO8859_15=y |
| 87 | 87 | CONFIG_NLS_UTF8=y |
| 88 | −CONFIG_CRC_CCITT=y | |
| 89 | −CONFIG_CRC_T10DIF=y | |
| 90 | 88 | CONFIG_PRINTK_TIME=y |
| 91 | 89 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 92 | 90 | CONFIG_DEBUG_FS=y |
| @@ -73,6 +73,5 @@ CONFIG_NLS_CODEPAGE_437=y · 72 unmodified lines | ||
| 73 | 73 | CONFIG_NLS_CODEPAGE_932=y |
| 74 | 74 | CONFIG_NLS_ISO8859_8=y |
| 75 | 75 | CONFIG_NLS_ISO8859_1=y |
| 76 | −CONFIG_CRC_T10DIF=y | |
| 77 | 76 | CONFIG_CRYPTO_ECB=m |
| 78 | 77 | CONFIG_CRYPTO_PCBC=m |
| @@ -80,5 +80,4 @@ CONFIG_TMPFS=y · 79 unmodified lines | ||
| 80 | 80 | CONFIG_NFS_FS=y |
| 81 | 81 | CONFIG_NFS_V4=y |
| 82 | 82 | CONFIG_ROOT_NFS=y |
| 83 | −CONFIG_CRC_T10DIF=y | |
| 84 | 83 | CONFIG_CRYPTO_PCBC=m |
| @@ -72,5 +72,4 @@ CONFIG_TMPFS=y · 71 unmodified lines | ||
| 72 | 72 | CONFIG_NFS_FS=y |
| 73 | 73 | CONFIG_NFS_V4=y |
| 74 | 74 | CONFIG_ROOT_NFS=y |
| 75 | −CONFIG_CRC_T10DIF=y | |
| 76 | 75 | CONFIG_CRYPTO_PCBC=m |
| @@ -75,6 +75,5 @@ CONFIG_TMPFS=y · 74 unmodified lines | ||
| 75 | 75 | CONFIG_NFS_FS=y |
| 76 | 76 | CONFIG_NFS_V4=y |
| 77 | 77 | CONFIG_ROOT_NFS=y |
| 78 | −CONFIG_CRC_T10DIF=y | |
| 79 | 78 | CONFIG_CRYPTO_ECB=m |
| 80 | 79 | CONFIG_CRYPTO_PCBC=m |
| @@ -221,8 +221,6 @@ CONFIG_NLS_ISO8859_15=y · 220 unmodified lines | ||
| 221 | 221 | CONFIG_NLS_KOI8_R=m |
| 222 | 222 | CONFIG_NLS_KOI8_U=m |
| 223 | 223 | CONFIG_NLS_UTF8=y |
| 224 | −CONFIG_CRC_CCITT=y | |
| 225 | −CONFIG_CRC_T10DIF=y | |
| 226 | 224 | CONFIG_MAGIC_SYSRQ=y |
| 227 | 225 | CONFIG_CRYPTO_CBC=y |
| 228 | 226 | CONFIG_CRYPTO_MD5=y |
| @@ -60,8 +60,6 @@ CONFIG_CRAMFS=m · 59 unmodified lines | ||
| 60 | 60 | CONFIG_NFS_FS=y |
| 61 | 61 | CONFIG_ROOT_NFS=y |
| 62 | 62 | CONFIG_NLS=y |
| 63 | −CONFIG_CRC_CCITT=y | |
| 64 | −CONFIG_CRC_T10DIF=m | |
| 65 | 63 | CONFIG_DETECT_HUNG_TASK=y |
| 66 | 64 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 67 | 65 | CONFIG_BDI_SWITCH=y |
| @@ -132,7 +132,6 @@ CONFIG_ROOT_NFS=y · 131 unmodified lines | ||
| 132 | 132 | CONFIG_NFSD=y |
| 133 | 133 | CONFIG_NLS_CODEPAGE_437=y |
| 134 | 134 | CONFIG_NLS_ISO8859_1=y |
| 135 | −CONFIG_CRC_T10DIF=y | |
| 136 | 135 | CONFIG_DETECT_HUNG_TASK=y |
| 137 | 136 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 138 | 137 | CONFIG_CRYPTO_HMAC=y |
| @@ -5,7 +5,6 @@ CONFIG_BROADCOM_PHY=y · 4 unmodified lines | ||
| 5 | 5 | # CONFIG_CARDBUS is not set |
| 6 | 6 | CONFIG_CHR_DEV_SG=y |
| 7 | 7 | CONFIG_CHR_DEV_ST=y |
| 8 | −CONFIG_CRC_T10DIF=y | |
| 9 | 8 | CONFIG_CRYPTO_HMAC=y |
| 10 | 9 | CONFIG_DS1682=y |
| 11 | 10 | CONFIG_EEPROM_LEGACY=y |
| @@ -106,7 +106,6 @@ CONFIG_TMPFS=y · 105 unmodified lines | ||
| 106 | 106 | CONFIG_AFFS_FS=m |
| 107 | 107 | CONFIG_NLS_ASCII=y |
| 108 | 108 | CONFIG_NLS_ISO8859_1=m |
| 109 | −CONFIG_CRC_T10DIF=y | |
| 110 | 109 | CONFIG_MAGIC_SYSRQ=y |
| 111 | 110 | CONFIG_DEBUG_KERNEL=y |
| 112 | 111 | CONFIG_DEBUG_MUTEXES=y |
| @@ -110,7 +110,6 @@ CONFIG_PROC_KCORE=y · 109 unmodified lines | ||
| 110 | 110 | CONFIG_TMPFS=y |
| 111 | 111 | CONFIG_NLS_ASCII=y |
| 112 | 112 | CONFIG_NLS_ISO8859_1=m |
| 113 | −CONFIG_CRC_T10DIF=y | |
| 114 | 113 | CONFIG_MAGIC_SYSRQ=y |
| 115 | 114 | CONFIG_DEBUG_KERNEL=y |
| 116 | 115 | CONFIG_DEBUG_MUTEXES=y |
| @@ -15,7 +15,6 @@ CONFIG_CGROUP_CPUACCT=y · 14 unmodified lines | ||
| 15 | 15 | CONFIG_CGROUP_SCHED=y |
| 16 | 16 | CONFIG_CGROUPS=y |
| 17 | 17 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 18 | −CONFIG_CRC_T10DIF=y | |
| 19 | 18 | CONFIG_CPUSETS=y |
| 20 | 19 | CONFIG_CRAMFS=y |
| 21 | 20 | CONFIG_CRYPTO_MD4=y |
| @@ -231,7 +231,6 @@ CONFIG_NLS_ASCII=y · 230 unmodified lines | ||
| 231 | 231 | CONFIG_NLS_ISO8859_1=y |
| 232 | 232 | CONFIG_NLS_ISO8859_15=y |
| 233 | 233 | CONFIG_NLS_UTF8=y |
| 234 | −CONFIG_CRC_T10DIF=y | |
| 235 | 234 | CONFIG_MAGIC_SYSRQ=y |
| 236 | 235 | CONFIG_DEBUG_KERNEL=y |
| 237 | 236 | CONFIG_DEBUG_MUTEXES=y |
| @@ -82,7 +82,6 @@ CONFIG_ROOT_NFS=y · 81 unmodified lines | ||
| 82 | 82 | CONFIG_CIFS=y |
| 83 | 83 | CONFIG_NLS_CODEPAGE_437=y |
| 84 | 84 | CONFIG_NLS_ISO8859_1=y |
| 85 | −CONFIG_CRC_CCITT=y | |
| 86 | 85 | CONFIG_PRINTK_TIME=y |
| 87 | 86 | CONFIG_DEBUG_SPINLOCK=y |
| 88 | 87 | CONFIG_DEBUG_MUTEXES=y |
| @@ -125,8 +125,6 @@ CONFIG_NLS_CODEPAGE_437=m · 124 unmodified lines | ||
| 125 | 125 | CONFIG_NLS_CODEPAGE_932=m |
| 126 | 126 | CONFIG_NLS_ISO8859_1=m |
| 127 | 127 | CONFIG_NLS_UTF8=m |
| 128 | −CONFIG_CRC_CCITT=m | |
| 129 | −CONFIG_CRC_T10DIF=y | |
| 130 | 128 | CONFIG_MAGIC_SYSRQ=y |
| 131 | 129 | CONFIG_DEBUG_KERNEL=y |
| 132 | 130 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -97,7 +97,6 @@ CONFIG_TMPFS=y · 96 unmodified lines | ||
| 97 | 97 | CONFIG_NFS_FS=y |
| 98 | 98 | CONFIG_NFS_V4=y |
| 99 | 99 | CONFIG_ROOT_NFS=y |
| 100 | −CONFIG_CRC_T10DIF=y | |
| 101 | 100 | CONFIG_CRYPTO_ECB=m |
| 102 | 101 | CONFIG_CRYPTO_PCBC=m |
| 103 | 102 | CONFIG_CRYPTO_SHA512=y |
| @@ -38,4 +38,3 @@ CONFIG_TMPFS=y · 37 unmodified lines | ||
| 38 | 38 | CONFIG_CRAMFS=y |
| 39 | 39 | CONFIG_NFS_FS=y |
| 40 | 40 | CONFIG_ROOT_NFS=y |
| 41 | −CONFIG_CRC_CCITT=y | |
| @@ -107,8 +107,6 @@ CONFIG_NLS_CODEPAGE_437=m · 106 unmodified lines | ||
| 107 | 107 | CONFIG_NLS_CODEPAGE_932=m |
| 108 | 108 | CONFIG_NLS_ISO8859_1=m |
| 109 | 109 | CONFIG_NLS_UTF8=m |
| 110 | −CONFIG_CRC_CCITT=m | |
| 111 | −CONFIG_CRC_T10DIF=y | |
| 112 | 110 | CONFIG_XZ_DEC=y |
| 113 | 111 | CONFIG_MAGIC_SYSRQ=y |
| 114 | 112 | CONFIG_DEBUG_KERNEL=y |
| @@ -159,7 +159,6 @@ CONFIG_NFSD=y · 158 unmodified lines | ||
| 159 | 159 | CONFIG_NFSD_V4=y |
| 160 | 160 | CONFIG_NLS_CODEPAGE_437=y |
| 161 | 161 | CONFIG_NLS_ISO8859_1=y |
| 162 | −CONFIG_CRC_CCITT=y | |
| 163 | 162 | CONFIG_PRINTK_TIME=y |
| 164 | 163 | CONFIG_MAGIC_SYSRQ=y |
| 165 | 164 | CONFIG_DEBUG_KERNEL=y |
| @@ -276,7 +276,6 @@ CONFIG_NFSD_V3_ACL=y · 275 unmodified lines | ||
| 276 | 276 | CONFIG_NFSD_V4=y |
| 277 | 277 | CONFIG_NLS_CODEPAGE_437=m |
| 278 | 278 | CONFIG_NLS_ISO8859_1=m |
| 279 | −CONFIG_CRC_T10DIF=y | |
| 280 | 279 | CONFIG_MAGIC_SYSRQ=y |
| 281 | 280 | CONFIG_DEBUG_KERNEL=y |
| 282 | 281 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -90,7 +90,6 @@ CONFIG_NFS_FS=y · 89 unmodified lines | ||
| 90 | 90 | CONFIG_ROOT_NFS=y |
| 91 | 91 | CONFIG_NLS_CODEPAGE_437=m |
| 92 | 92 | CONFIG_NLS_ISO8859_1=m |
| 93 | −CONFIG_CRC_T10DIF=m | |
| 94 | 93 | CONFIG_MAGIC_SYSRQ=y |
| 95 | 94 | CONFIG_DETECT_HUNG_TASK=y |
| 96 | 95 | CONFIG_CRYPTO_ECB=y |
| @@ -207,7 +207,6 @@ CONFIG_NLS_CODEPAGE_437=y · 206 unmodified lines | ||
| 207 | 207 | CONFIG_NLS_ASCII=y |
| 208 | 208 | CONFIG_NLS_ISO8859_1=y |
| 209 | 209 | CONFIG_NLS_UTF8=y |
| 210 | −CONFIG_CRC_T10DIF=y | |
| 211 | 210 | CONFIG_MAGIC_SYSRQ=y |
| 212 | 211 | CONFIG_DEBUG_KERNEL=y |
| 213 | 212 | CONFIG_DEBUG_STACK_USAGE=y |
| @@ -148,8 +148,6 @@ CONFIG_NLS_ISO8859_1=y · 147 unmodified lines | ||
| 148 | 148 | CONFIG_CRYPTO_PCBC=m |
| 149 | 149 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 150 | 150 | CONFIG_CRYPTO_LZO=m |
| 151 | −CONFIG_CRC_CCITT=m | |
| 152 | −CONFIG_CRC_T10DIF=y | |
| 153 | 151 | CONFIG_PRINTK_TIME=y |
| 154 | 152 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 155 | 153 | CONFIG_MAGIC_SYSRQ=y |
| @@ -278,8 +278,6 @@ CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY=y · 277 unmodified lines | ||
| 278 | 278 | # CONFIG_INTEGRITY is not set |
| 279 | 279 | CONFIG_LSM="yama,loadpin,safesetid,integrity" |
| 280 | 280 | # CONFIG_CRYPTO_HW is not set |
| 281 | −CONFIG_CRC16=y | |
| 282 | −CONFIG_CRC_ITU_T=y | |
| 283 | 281 | # CONFIG_XZ_DEC_X86 is not set |
| 284 | 282 | # CONFIG_XZ_DEC_IA64 is not set |
| 285 | 283 | # CONFIG_XZ_DEC_ARM is not set |
| @@ -75,4 +75,3 @@ CONFIG_NLS_DEFAULT="utf8" · 74 unmodified lines | ||
| 75 | 75 | CONFIG_NLS_CODEPAGE_437=y |
| 76 | 76 | CONFIG_NLS_ISO8859_1=y |
| 77 | 77 | CONFIG_NLS_UTF8=y |
| 78 | −CONFIG_CRC_T10DIF=y | |
| @@ -114,7 +114,6 @@ CONFIG_ROOT_NFS=y · 113 unmodified lines | ||
| 114 | 114 | CONFIG_CIFS=m |
| 115 | 115 | CONFIG_NLS_CODEPAGE_437=y |
| 116 | 116 | CONFIG_NLS_ISO8859_1=y |
| 117 | −CONFIG_CRC_CCITT=y | |
| 118 | 117 | CONFIG_PRINTK_TIME=y |
| 119 | 118 | CONFIG_MAGIC_SYSRQ=y |
| 120 | 119 | CONFIG_DEBUG_SPINLOCK=y |
| @@ -258,10 +258,6 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, · 257 unmodified lines | ||
| 258 | 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 | 261 | #endif |
| 266 | 262 | |
| 267 | 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 | 976 | return 0; |
| 977 | 977 | } |
| 978 | 978 | |
| 979 | − | |
| 979 | +#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP | |
| 980 | 980 | bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) |
| 981 | 981 | { |
| 982 | 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 | 985 | return false; |
| 986 | 986 | } |
| 987 | +#endif | |
| 987 | 988 | |
| 988 | 989 | int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, |
| 989 | 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 | 1121 | pmd_t *pmd; |
| 1121 | 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 | 1137 | for (addr = start; addr < end; addr = next) { |
| 1124 | 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 | 1159 | * in altmap block allocation failures, in which case |
| 1146 | 1160 | * we fallback to RAM for vmemmap allocation. |
| 1147 | 1161 | */ |
| 1148 | − if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) || | |
| 1149 | − altmap_cross_boundary(altmap, addr, PMD_SIZE))) { | |
| 1162 | + if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap && | |
| 1163 | + altmap_cross_boundary(altmap, addr, PMD_SIZE))) { | |
| 1150 | 1164 | /* |
| 1151 | 1165 | * make sure we don't create altmap mappings |
| 1152 | 1166 | * covering things outside the device. |
| @@ -17,7 +17,7 @@ config PPC_POWERNV · 16 unmodified lines | ||
| 17 | 17 | select MMU_NOTIFIER |
| 18 | 18 | select FORCE_SMP |
| 19 | 19 | select ARCH_SUPPORTS_PER_VMA_LOCK |
| 20 | − select PPC_RADIX_BROADCAST_TLBIE | |
| 20 | + select PPC_RADIX_BROADCAST_TLBIE if PPC_RADIX_MMU | |
| 21 | 21 | default y |
| 22 | 22 | |
| 23 | 23 | config OPAL_PRD |
| @@ -23,7 +23,7 @@ config PPC_PSERIES · 22 unmodified lines | ||
| 23 | 23 | select FORCE_SMP |
| 24 | 24 | select SWIOTLB |
| 25 | 25 | select ARCH_SUPPORTS_PER_VMA_LOCK |
| 26 | − select PPC_RADIX_BROADCAST_TLBIE | |
| 26 | + select PPC_RADIX_BROADCAST_TLBIE if PPC_RADIX_MMU | |
| 27 | 27 | default y |
| 28 | 28 | |
| 29 | 29 | config PARAVIRT |
| @@ -341,7 +341,7 @@ · 340 unmodified lines | ||
| 341 | 341 | 1024 1024 1024 1024>; |
| 342 | 342 | snps,priority = <0 1 2 3 4 5 6 7>; |
| 343 | 343 | snps,dma-masters = <2>; |
| 344 | − snps,data-width = <4>; | |
| 344 | + snps,data-width = <2>; | |
| 345 | 345 | status = "disabled"; |
| 346 | 346 | }; |
| 347 | 347 | |
| @@ -115,24 +115,19 @@ · 114 unmodified lines | ||
| 115 | 115 | \old_c |
| 116 | 116 | .endm |
| 117 | 117 | |
| 118 | −#define _ALTERNATIVE_CFG(old_c, ...) \ | |
| 119 | − ALTERNATIVE_CFG old_c | |
| 120 | − | |
| 121 | −#define _ALTERNATIVE_CFG_2(old_c, ...) \ | |
| 122 | − ALTERNATIVE_CFG old_c | |
| 118 | +#define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c | |
| 119 | +#define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c | |
| 123 | 120 | |
| 124 | 121 | #else /* !__ASSEMBLY__ */ |
| 125 | 122 | |
| 126 | −#define __ALTERNATIVE_CFG(old_c) \ | |
| 127 | − old_c "\n" | |
| 123 | +#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n" | |
| 124 | +#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n" | |
| 128 | 125 | |
| 129 | −#define _ALTERNATIVE_CFG(old_c, ...) \ | |
| 130 | − __ALTERNATIVE_CFG(old_c) | |
| 126 | +#endif /* __ASSEMBLY__ */ | |
| 131 | 127 | |
| 132 | −#define _ALTERNATIVE_CFG_2(old_c, ...) \ | |
| 133 | − __ALTERNATIVE_CFG(old_c) | |
| 128 | +#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c) | |
| 129 | +#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c) | |
| 134 | 130 | |
| 135 | −#endif /* __ASSEMBLY__ */ | |
| 136 | 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 | 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 | 37 | #define flush_icache_user_page(vma, pg, addr, len) \ |
| 43 | 38 | do { \ |
| 44 | 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 | 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 | 86 | extern unsigned int riscv_cbom_block_size; |
| 82 | 87 | extern unsigned int riscv_cboz_block_size; |
| 83 | 88 | void riscv_init_cbo_blocksizes(void); |
| @@ -19,16 +19,9 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #ifndef __ASSEMBLY__ |
| 21 | 21 | |
| 22 | +void arch_kgdb_breakpoint(void); | |
| 22 | 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 | 25 | #endif /* !__ASSEMBLY__ */ |
| 33 | 26 | |
| 34 | 27 | #define DBG_REG_ZERO "zero" |
| @@ -62,8 +62,11 @@ static inline void syscall_get_arguments(struct task_struct *task, · 61 unmodified lines | ||
| 62 | 62 | unsigned long *args) |
| 63 | 63 | { |
| 64 | 64 | args[0] = regs->orig_a0; |
| 65 | − args++; | |
| 66 | − memcpy(args, ®s->a1, 5 * sizeof(args[0])); | |
| 65 | + args[1] = regs->a1; | |
| 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 | 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 | 9 | CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) |
| 10 | 10 | CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) |
| 11 | 11 | endif |
| 12 | −CFLAGS_syscall_table.o += $(call cc-option,-Wno-override-init,) | |
| 13 | −CFLAGS_compat_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-disable-warning, override-init) | |
| 14 | 14 | |
| 15 | 15 | ifdef CONFIG_KEXEC_CORE |
| 16 | 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 | 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 | 263 | void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer, |
| 258 | 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 | 73 | static void count_max_entries(Elf_Rela *relas, int num, |
| 74 | 74 | unsigned int *plts, unsigned int *gots) |
| 75 | 75 | { |
| 76 | − unsigned int type, i; | |
| 77 | − | |
| 78 | − for (i = 0; i < num; i++) { | |
| 79 | − type = ELF_RISCV_R_TYPE(relas[i].r_info); | |
| 80 | − if (type == R_RISCV_CALL_PLT) { | |
| 76 | + for (int i = 0; i < num; i++) { | |
| 77 | + switch (ELF_R_TYPE(relas[i].r_info)) { | |
| 78 | + case R_RISCV_CALL_PLT: | |
| 79 | + case R_RISCV_PLT32: | |
| 81 | 80 | if (!duplicate_rela(relas, i)) |
| 82 | 81 | (*plts)++; |
| 83 | − } else if (type == R_RISCV_GOT_HI20) { | |
| 82 | + break; | |
| 83 | + case R_RISCV_GOT_HI20: | |
| 84 | 84 | if (!duplicate_rela(relas, i)) |
| 85 | 85 | (*gots)++; |
| 86 | + break; | |
| 86 | 87 | } |
| 87 | 88 | } |
| 88 | 89 | } |
| @@ -648,7 +648,7 @@ process_accumulated_relocations(struct module *me, · 647 unmodified lines | ||
| 648 | 648 | kfree(bucket_iter); |
| 649 | 649 | } |
| 650 | 650 | |
| 651 | − kfree(*relocation_hashtable); | |
| 651 | + kvfree(*relocation_hashtable); | |
| 652 | 652 | } |
| 653 | 653 | |
| 654 | 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 | 753 | hashtable_size <<= should_double_size; |
| 754 | 754 | |
| 755 | − *relocation_hashtable = kmalloc_array(hashtable_size, | |
| 756 | − sizeof(**relocation_hashtable), | |
| 757 | − GFP_KERNEL); | |
| 755 | + /* Number of relocations may be large, so kvmalloc it */ | |
| 756 | + *relocation_hashtable = kvmalloc_array(hashtable_size, | |
| 757 | + sizeof(**relocation_hashtable), | |
| 758 | + GFP_KERNEL); | |
| 758 | 759 | if (!*relocation_hashtable) |
| 759 | 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 | 862 | j++; |
| 862 | − if (j > sechdrs[relsec].sh_size / sizeof(*rel)) | |
| 863 | + if (j == num_relocations) | |
| 863 | 864 | j = 0; |
| 864 | 865 | |
| 865 | 866 | } while (j_idx != j); |
| @@ -167,6 +167,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, · 166 unmodified lines | ||
| 167 | 167 | /* Initialize the slot */ |
| 168 | 168 | void *kaddr = kmap_atomic(page); |
| 169 | 169 | void *dst = kaddr + (vaddr & ~PAGE_MASK); |
| 170 | + unsigned long start = (unsigned long)dst; | |
| 170 | 171 | |
| 171 | 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 | 177 | *(uprobe_opcode_t *)dst = __BUG_INSN_32; |
| 177 | 178 | } |
| 178 | 179 | |
| 180 | + flush_icache_range(start, start + len); | |
| 179 | 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 | 275 | unsigned long pmm; |
| 276 | 276 | u8 pmlen; |
| 277 | 277 | |
| 278 | + if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) | |
| 279 | + return -EINVAL; | |
| 280 | + | |
| 278 | 281 | if (is_compat_thread(ti)) |
| 279 | 282 | return -EINVAL; |
| 280 | 283 | |
| @@ -330,6 +333,9 @@ long get_tagged_addr_ctrl(struct task_struct *task) · 49 unmodified lines | ||
| 330 | 333 | struct thread_info *ti = task_thread_info(task); |
| 331 | 334 | long ret = 0; |
| 332 | 335 | |
| 336 | + if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) | |
| 337 | + return -EINVAL; | |
| 338 | + | |
| 333 | 339 | if (is_compat_thread(ti)) |
| 334 | 340 | return -EINVAL; |
| 335 | 341 | |
| @@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", }; · 65 unmodified lines | ||
| 66 | 66 | static struct resource elfcorehdr_res = { .name = "ELF Core hdr", }; |
| 67 | 67 | #endif |
| 68 | 68 | |
| 69 | +static int num_standard_resources; | |
| 70 | +static struct resource *standard_resources; | |
| 71 | + | |
| 69 | 72 | static int __init add_resource(struct resource *parent, |
| 70 | 73 | struct resource *res) |
| 71 | 74 | { |
| @@ -139,7 +142,7 @@ static void __init init_resources(void) · 67 unmodified lines | ||
| 139 | 142 | struct resource *res = NULL; |
| 140 | 143 | struct resource *mem_res = NULL; |
| 141 | 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 | 146 | int ret = 0; |
| 144 | 147 | |
| 145 | 148 | /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */ |
| @@ -193,6 +196,7 @@ static void __init init_resources(void) · 47 unmodified lines | ||
| 193 | 196 | /* Add /memory regions to the resource tree */ |
| 194 | 197 | for_each_mem_region(region) { |
| 195 | 198 | res = &mem_res[res_idx--]; |
| 199 | + non_resv_res++; | |
| 196 | 200 | |
| 197 | 201 | if (unlikely(memblock_is_nomap(region))) { |
| 198 | 202 | res->name = "Reserved"; |
| @@ -210,6 +214,9 @@ static void __init init_resources(void) · 11 unmodified lines | ||
| 210 | 214 | goto error; |
| 211 | 215 | } |
| 212 | 216 | |
| 217 | + num_standard_resources = non_resv_res; | |
| 218 | + standard_resources = &mem_res[res_idx + 1]; | |
| 219 | + | |
| 213 | 220 | /* Clean-up any unused pre-allocated resources */ |
| 214 | 221 | if (res_idx >= 0) |
| 215 | 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 | 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 | 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 | 198 | DO_ERROR_INFO(do_trap_load_fault, |
| 199 | 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 | 223 | if (user_mode(regs)) { |
| 204 | 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)) | |
| 207 | − do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | |
| 208 | − "Oops - load address misaligned"); | |
| 230 | + if (misaligned_handler[type].handler(regs)) | |
| 231 | + do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, | |
| 232 | + misaligned_handler[type].type_str); | |
| 209 | 233 | |
| 234 | + if (user_mode(regs)) { | |
| 235 | + local_irq_disable(); | |
| 210 | 236 | irqentry_exit_to_user_mode(regs); |
| 211 | 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 | 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)) { | |
| 225 | − irqentry_enter_from_user_mode(regs); | |
| 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"); | |
| 244 | + do_trap_misaligned(regs, MISALIGNED_LOAD); | |
| 245 | +} | |
| 238 | 246 | |
| 239 | − irqentry_nmi_exit(regs, state); | |
| 240 | − } | |
| 247 | +asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs) | |
| 248 | +{ | |
| 249 | + do_trap_misaligned(regs, MISALIGNED_STORE); | |
| 241 | 250 | } |
| 251 | + | |
| 242 | 252 | DO_ERROR_INFO(do_trap_store_fault, |
| 243 | 253 | SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); |
| 244 | 254 | DO_ERROR_INFO(do_trap_ecall_s, |
| @@ -88,6 +88,13 @@ · 87 unmodified lines | ||
| 88 | 88 | #define INSN_MATCH_C_FSWSP 0xe002 |
| 89 | 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 | 98 | #define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4) |
| 92 | 99 | |
| 93 | 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 | 275 | int __ret; \ |
| 269 | 276 | \ |
| 270 | 277 | if (user_mode(regs)) { \ |
| 271 | − __ret = __get_user(insn, (type __user *) insn_addr); \ | |
| 278 | + __ret = get_user(insn, (type __user *) insn_addr); \ | |
| 272 | 279 | } else { \ |
| 273 | 280 | insn = *(type *)insn_addr; \ |
| 274 | 281 | __ret = 0; \ |
| @@ -431,6 +438,13 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs) · 156 unmodified lines | ||
| 431 | 438 | fp = 1; |
| 432 | 439 | len = 4; |
| 433 | 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 | 448 | } else { |
| 435 | 449 | regs->epc = epc; |
| 436 | 450 | return -1; |
| @@ -530,6 +544,9 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs) · 93 unmodified lines | ||
| 530 | 544 | len = 4; |
| 531 | 545 | val.data_ulong = GET_F32_RS2C(insn, regs); |
| 532 | 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 | 550 | } else { |
| 534 | 551 | regs->epc = epc; |
| 535 | 552 | return -1; |
| @@ -439,29 +439,36 @@ static int __init check_unaligned_access_all_cpus(void) · 438 unmodified lines | ||
| 439 | 439 | { |
| 440 | 440 | int cpu; |
| 441 | 441 | |
| 442 | − if (unaligned_scalar_speed_param == RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN && | |
| 443 | − !check_unaligned_access_emulated_all_cpus()) { | |
| 444 | − check_unaligned_access_speed_all_cpus(); | |
| 445 | − } else { | |
| 446 | − pr_info("scalar unaligned access speed set to '%s' by command line\n", | |
| 447 | − speed_str[unaligned_scalar_speed_param]); | |
| 442 | + if (unaligned_scalar_speed_param != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN) { | |
| 443 | + pr_info("scalar unaligned access speed set to '%s' (%lu) by command line\n", | |
| 444 | + speed_str[unaligned_scalar_speed_param], unaligned_scalar_speed_param); | |
| 448 | 445 | for_each_online_cpu(cpu) |
| 449 | 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 | 462 | if (!has_vector()) |
| 453 | 463 | unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED; |
| 454 | 464 | |
| 455 | − 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]); | |
| 465 | + if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) { | |
| 463 | 466 | for_each_online_cpu(cpu) |
| 464 | 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 | 77 | memcpy(cntx, reset_cntx, sizeof(*cntx)); |
| 78 | 78 | spin_unlock(&vcpu->arch.reset_cntx_lock); |
| 79 | 79 | |
| 80 | + memset(&vcpu->arch.smstateen_csr, 0, sizeof(vcpu->arch.smstateen_csr)); | |
| 81 | + | |
| 80 | 82 | kvm_riscv_vcpu_fp_reset(vcpu); |
| 81 | 83 | |
| 82 | 84 | kvm_riscv_vcpu_vector_reset(vcpu); |
| @@ -332,6 +332,10 @@ config HAVE_MARCH_Z16_FEATURES · 331 unmodified lines | ||
| 332 | 332 | def_bool n |
| 333 | 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 | 339 | choice |
| 336 | 340 | prompt "Processor type" |
| 337 | 341 | default MARCH_Z196 |
| @@ -397,6 +401,14 @@ config MARCH_Z16 · 59 unmodified lines | ||
| 397 | 401 | Select this to enable optimizations for IBM z16 (3931 and |
| 398 | 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 | 412 | endchoice |
| 401 | 413 | |
| 402 | 414 | config MARCH_Z10_TUNE |
| @@ -420,6 +432,9 @@ config MARCH_Z15_TUNE · 17 unmodified lines | ||
| 420 | 432 | config MARCH_Z16_TUNE |
| 421 | 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 | 438 | choice |
| 424 | 439 | prompt "Tune code generation" |
| 425 | 440 | default TUNE_DEFAULT |
| @@ -464,6 +479,10 @@ config TUNE_Z16 · 38 unmodified lines | ||
| 464 | 479 | bool "IBM z16" |
| 465 | 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 | 486 | endchoice |
| 468 | 487 | |
| 469 | 488 | config 64BIT |
| @@ -48,6 +48,7 @@ mflags-$(CONFIG_MARCH_Z13) := -march=z13 · 47 unmodified lines | ||
| 48 | 48 | mflags-$(CONFIG_MARCH_Z14) := -march=z14 |
| 49 | 49 | mflags-$(CONFIG_MARCH_Z15) := -march=z15 |
| 50 | 50 | mflags-$(CONFIG_MARCH_Z16) := -march=z16 |
| 51 | +mflags-$(CONFIG_MARCH_Z17) := -march=z17 | |
| 51 | 52 | |
| 52 | 53 | export CC_FLAGS_MARCH := $(mflags-y) |
| 53 | 54 | |
| @@ -61,6 +62,7 @@ cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 · 7 unmodified lines | ||
| 61 | 62 | cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 |
| 62 | 63 | cflags-$(CONFIG_MARCH_Z15_TUNE) += -mtune=z15 |
| 63 | 64 | cflags-$(CONFIG_MARCH_Z16_TUNE) += -mtune=z16 |
| 65 | +cflags-$(CONFIG_MARCH_Z17_TUNE) += -mtune=z17 | |
| 64 | 66 | |
| 65 | 67 | cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include |
| 66 | 68 | |
| @@ -38,7 +38,6 @@ CONFIG_USER_NS=y · 37 unmodified lines | ||
| 38 | 38 | CONFIG_CHECKPOINT_RESTORE=y |
| 39 | 39 | CONFIG_SCHED_AUTOGROUP=y |
| 40 | 40 | CONFIG_EXPERT=y |
| 41 | −# CONFIG_SYSFS_SYSCALL is not set | |
| 42 | 41 | CONFIG_PROFILING=y |
| 43 | 42 | CONFIG_KEXEC=y |
| 44 | 43 | CONFIG_KEXEC_FILE=y |
| @@ -92,7 +91,6 @@ CONFIG_UNIXWARE_DISKLABEL=y · 47 unmodified lines | ||
| 92 | 91 | CONFIG_IOSCHED_BFQ=y |
| 93 | 92 | CONFIG_BINFMT_MISC=m |
| 94 | 93 | CONFIG_ZSWAP=y |
| 95 | −CONFIG_ZSMALLOC=y | |
| 96 | 94 | CONFIG_ZSMALLOC_STAT=y |
| 97 | 95 | CONFIG_SLAB_BUCKETS=y |
| 98 | 96 | CONFIG_SLUB_STATS=y |
| @@ -395,6 +393,9 @@ CONFIG_CLS_U32_MARK=y · 296 unmodified lines | ||
| 395 | 393 | CONFIG_NET_CLS_FLOW=m |
| 396 | 394 | CONFIG_NET_CLS_CGROUP=y |
| 397 | 395 | CONFIG_NET_CLS_BPF=m |
| 396 | +CONFIG_NET_CLS_FLOWER=m | |
| 397 | +CONFIG_NET_CLS_MATCHALL=m | |
| 398 | +CONFIG_NET_EMATCH=y | |
| 398 | 399 | CONFIG_NET_CLS_ACT=y |
| 399 | 400 | CONFIG_NET_ACT_POLICE=m |
| 400 | 401 | CONFIG_NET_ACT_GACT=m |
| @@ -405,6 +406,9 @@ CONFIG_NET_ACT_PEDIT=m · 4 unmodified lines | ||
| 405 | 406 | CONFIG_NET_ACT_SIMP=m |
| 406 | 407 | CONFIG_NET_ACT_SKBEDIT=m |
| 407 | 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 | 412 | CONFIG_NET_ACT_GATE=m |
| 409 | 413 | CONFIG_NET_TC_SKB_EXT=y |
| 410 | 414 | CONFIG_DNS_RESOLVER=y |
| @@ -628,8 +632,16 @@ CONFIG_VIRTIO_PCI=m · 217 unmodified lines | ||
| 628 | 632 | CONFIG_VIRTIO_BALLOON=m |
| 629 | 633 | CONFIG_VIRTIO_MEM=m |
| 630 | 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 | 642 | CONFIG_VHOST_NET=m |
| 632 | 643 | CONFIG_VHOST_VSOCK=m |
| 644 | +CONFIG_VHOST_VDPA=m | |
| 633 | 645 | CONFIG_EXT4_FS=y |
| 634 | 646 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 635 | 647 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -654,7 +666,6 @@ CONFIG_NILFS2_FS=m · 18 unmodified lines | ||
| 654 | 666 | CONFIG_BCACHEFS_FS=y |
| 655 | 667 | CONFIG_BCACHEFS_QUOTA=y |
| 656 | 668 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 657 | −CONFIG_FS_DAX=y | |
| 658 | 669 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 659 | 670 | CONFIG_FS_ENCRYPTION=y |
| 660 | 671 | CONFIG_FS_VERITY=y |
| @@ -724,11 +735,10 @@ CONFIG_NLS_UTF8=m · 63 unmodified lines | ||
| 724 | 735 | CONFIG_DLM=m |
| 725 | 736 | CONFIG_UNICODE=y |
| 726 | 737 | CONFIG_PERSISTENT_KEYRINGS=y |
| 738 | +CONFIG_BIG_KEYS=y | |
| 727 | 739 | CONFIG_ENCRYPTED_KEYS=m |
| 728 | 740 | CONFIG_KEY_NOTIFICATIONS=y |
| 729 | 741 | CONFIG_SECURITY=y |
| 730 | −CONFIG_HARDENED_USERCOPY=y | |
| 731 | −CONFIG_FORTIFY_SOURCE=y | |
| 732 | 742 | CONFIG_SECURITY_SELINUX=y |
| 733 | 743 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y |
| 734 | 744 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| @@ -741,6 +751,8 @@ CONFIG_IMA=y · 6 unmodified lines | ||
| 741 | 751 | CONFIG_IMA_DEFAULT_HASH_SHA256=y |
| 742 | 752 | CONFIG_IMA_WRITE_POLICY=y |
| 743 | 753 | CONFIG_IMA_APPRAISE=y |
| 754 | +CONFIG_FORTIFY_SOURCE=y | |
| 755 | +CONFIG_HARDENED_USERCOPY=y | |
| 744 | 756 | CONFIG_BUG_ON_DATA_CORRUPTION=y |
| 745 | 757 | CONFIG_CRYPTO_USER=m |
| 746 | 758 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| @@ -756,7 +768,6 @@ CONFIG_CRYPTO_AES_TI=m · 9 unmodified lines | ||
| 756 | 768 | CONFIG_CRYPTO_ANUBIS=m |
| 757 | 769 | CONFIG_CRYPTO_ARIA=m |
| 758 | 770 | CONFIG_CRYPTO_BLOWFISH=m |
| 759 | −CONFIG_CRYPTO_CAMELLIA=m | |
| 760 | 771 | CONFIG_CRYPTO_CAST5=m |
| 761 | 772 | CONFIG_CRYPTO_CAST6=m |
| 762 | 773 | CONFIG_CRYPTO_DES=m |
| @@ -801,7 +812,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m · 38 unmodified lines | ||
| 801 | 812 | CONFIG_CRYPTO_GHASH_S390=m |
| 802 | 813 | CONFIG_CRYPTO_AES_S390=m |
| 803 | 814 | CONFIG_CRYPTO_DES_S390=m |
| 804 | −CONFIG_CRYPTO_CHACHA_S390=m | |
| 805 | 815 | CONFIG_CRYPTO_HMAC_S390=m |
| 806 | 816 | CONFIG_ZCRYPT=m |
| 807 | 817 | CONFIG_PKEY=m |
| @@ -812,9 +822,9 @@ CONFIG_PKEY_UV=m · 4 unmodified lines | ||
| 812 | 822 | CONFIG_CRYPTO_PAES_S390=m |
| 813 | 823 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 814 | 824 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
| 825 | +CONFIG_CRYPTO_KRB5=m | |
| 826 | +CONFIG_CRYPTO_KRB5_SELFTESTS=y | |
| 815 | 827 | CONFIG_CORDIC=m |
| 816 | −CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 817 | −CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 818 | 828 | CONFIG_RANDOM32_SELFTEST=y |
| 819 | 829 | CONFIG_XZ_DEC_MICROLZMA=y |
| 820 | 830 | CONFIG_DMA_CMA=y |
| @@ -36,7 +36,6 @@ CONFIG_USER_NS=y · 35 unmodified lines | ||
| 36 | 36 | CONFIG_CHECKPOINT_RESTORE=y |
| 37 | 37 | CONFIG_SCHED_AUTOGROUP=y |
| 38 | 38 | CONFIG_EXPERT=y |
| 39 | −# CONFIG_SYSFS_SYSCALL is not set | |
| 40 | 39 | CONFIG_PROFILING=y |
| 41 | 40 | CONFIG_KEXEC=y |
| 42 | 41 | CONFIG_KEXEC_FILE=y |
| @@ -86,7 +85,6 @@ CONFIG_UNIXWARE_DISKLABEL=y · 43 unmodified lines | ||
| 86 | 85 | CONFIG_IOSCHED_BFQ=y |
| 87 | 86 | CONFIG_BINFMT_MISC=m |
| 88 | 87 | CONFIG_ZSWAP=y |
| 89 | −CONFIG_ZSMALLOC=y | |
| 90 | 88 | CONFIG_ZSMALLOC_STAT=y |
| 91 | 89 | CONFIG_SLAB_BUCKETS=y |
| 92 | 90 | # CONFIG_COMPAT_BRK is not set |
| @@ -385,6 +383,9 @@ CONFIG_CLS_U32_MARK=y · 292 unmodified lines | ||
| 385 | 383 | CONFIG_NET_CLS_FLOW=m |
| 386 | 384 | CONFIG_NET_CLS_CGROUP=y |
| 387 | 385 | CONFIG_NET_CLS_BPF=m |
| 386 | +CONFIG_NET_CLS_FLOWER=m | |
| 387 | +CONFIG_NET_CLS_MATCHALL=m | |
| 388 | +CONFIG_NET_EMATCH=y | |
| 388 | 389 | CONFIG_NET_CLS_ACT=y |
| 389 | 390 | CONFIG_NET_ACT_POLICE=m |
| 390 | 391 | CONFIG_NET_ACT_GACT=m |
| @@ -395,6 +396,9 @@ CONFIG_NET_ACT_PEDIT=m · 4 unmodified lines | ||
| 395 | 396 | CONFIG_NET_ACT_SIMP=m |
| 396 | 397 | CONFIG_NET_ACT_SKBEDIT=m |
| 397 | 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 | 402 | CONFIG_NET_ACT_GATE=m |
| 399 | 403 | CONFIG_NET_TC_SKB_EXT=y |
| 400 | 404 | CONFIG_DNS_RESOLVER=y |
| @@ -618,8 +622,16 @@ CONFIG_VIRTIO_PCI=m · 217 unmodified lines | ||
| 618 | 622 | CONFIG_VIRTIO_BALLOON=m |
| 619 | 623 | CONFIG_VIRTIO_MEM=m |
| 620 | 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 | 632 | CONFIG_VHOST_NET=m |
| 622 | 633 | CONFIG_VHOST_VSOCK=m |
| 634 | +CONFIG_VHOST_VDPA=m | |
| 623 | 635 | CONFIG_EXT4_FS=y |
| 624 | 636 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 625 | 637 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -641,7 +653,6 @@ CONFIG_NILFS2_FS=m · 15 unmodified lines | ||
| 641 | 653 | CONFIG_BCACHEFS_FS=m |
| 642 | 654 | CONFIG_BCACHEFS_QUOTA=y |
| 643 | 655 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 644 | −CONFIG_FS_DAX=y | |
| 645 | 656 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 646 | 657 | CONFIG_FS_ENCRYPTION=y |
| 647 | 658 | CONFIG_FS_VERITY=y |
| @@ -711,6 +722,7 @@ CONFIG_NLS_UTF8=m · 63 unmodified lines | ||
| 711 | 722 | CONFIG_DLM=m |
| 712 | 723 | CONFIG_UNICODE=y |
| 713 | 724 | CONFIG_PERSISTENT_KEYRINGS=y |
| 725 | +CONFIG_BIG_KEYS=y | |
| 714 | 726 | CONFIG_ENCRYPTED_KEYS=m |
| 715 | 727 | CONFIG_KEY_NOTIFICATIONS=y |
| 716 | 728 | CONFIG_SECURITY=y |
| @@ -742,7 +754,6 @@ CONFIG_CRYPTO_AES_TI=m · 25 unmodified lines | ||
| 742 | 754 | CONFIG_CRYPTO_ANUBIS=m |
| 743 | 755 | CONFIG_CRYPTO_ARIA=m |
| 744 | 756 | CONFIG_CRYPTO_BLOWFISH=m |
| 745 | −CONFIG_CRYPTO_CAMELLIA=m | |
| 746 | 757 | CONFIG_CRYPTO_CAST5=m |
| 747 | 758 | CONFIG_CRYPTO_CAST6=m |
| 748 | 759 | CONFIG_CRYPTO_DES=m |
| @@ -788,7 +799,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m · 39 unmodified lines | ||
| 788 | 799 | CONFIG_CRYPTO_GHASH_S390=m |
| 789 | 800 | CONFIG_CRYPTO_AES_S390=m |
| 790 | 801 | CONFIG_CRYPTO_DES_S390=m |
| 791 | −CONFIG_CRYPTO_CHACHA_S390=m | |
| 792 | 802 | CONFIG_CRYPTO_HMAC_S390=m |
| 793 | 803 | CONFIG_ZCRYPT=m |
| 794 | 804 | CONFIG_PKEY=m |
| @@ -799,10 +809,10 @@ CONFIG_PKEY_UV=m · 4 unmodified lines | ||
| 799 | 809 | CONFIG_CRYPTO_PAES_S390=m |
| 800 | 810 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 801 | 811 | CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
| 812 | +CONFIG_CRYPTO_KRB5=m | |
| 813 | +CONFIG_CRYPTO_KRB5_SELFTESTS=y | |
| 802 | 814 | CONFIG_CORDIC=m |
| 803 | 815 | CONFIG_PRIME_NUMBERS=m |
| 804 | −CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 805 | −CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 806 | 816 | CONFIG_XZ_DEC_MICROLZMA=y |
| 807 | 817 | CONFIG_DMA_CMA=y |
| 808 | 818 | CONFIG_CMA_SIZE_MBYTES=0 |
| @@ -70,7 +70,6 @@ CONFIG_DEBUG_KERNEL=y · 69 unmodified lines | ||
| 70 | 70 | CONFIG_DEBUG_INFO_DWARF4=y |
| 71 | 71 | CONFIG_DEBUG_FS=y |
| 72 | 72 | CONFIG_PANIC_ON_OOPS=y |
| 73 | −# CONFIG_SCHED_DEBUG is not set | |
| 74 | 73 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
| 75 | 74 | # CONFIG_RCU_TRACE is not set |
| 76 | 75 | # CONFIG_FTRACE is not set |
| @@ -33,6 +33,10 @@ · 32 unmodified lines | ||
| 33 | 33 | #define MARCH_HAS_Z16_FEATURES 1 |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | +#ifdef CONFIG_HAVE_MARCH_Z17_FEATURES | |
| 37 | +#define MARCH_HAS_Z17_FEATURES 1 | |
| 38 | +#endif | |
| 39 | + | |
| 36 | 40 | #endif /* __DECOMPRESSOR */ |
| 37 | 41 | |
| 38 | 42 | #endif /* __ASM_S390_MARCH_H */ |
| @@ -602,7 +602,8 @@ SYM_CODE_START(stack_invalid) · 601 unmodified lines | ||
| 602 | 602 | stmg %r0,%r7,__PT_R0(%r11) |
| 603 | 603 | stmg %r8,%r9,__PT_PSW(%r11) |
| 604 | 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 | 607 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
| 607 | 608 | lgr %r2,%r11 # pass pointer to pt_regs |
| 608 | 609 | jg kernel_stack_invalid |
| @@ -442,7 +442,7 @@ static void cpum_cf_make_setsize(enum cpumf_ctr_set ctrset) · 441 unmodified lines | ||
| 442 | 442 | ctrset_size = 48; |
| 443 | 443 | else if (cpumf_ctr_info.csvn >= 3 && cpumf_ctr_info.csvn <= 5) |
| 444 | 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 | 446 | ctrset_size = 160; |
| 447 | 447 | break; |
| 448 | 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 | 858 | static int cpumf_pmu_event_init(struct perf_event *event) |
| 859 | 859 | { |
| 860 | 860 | unsigned int type = event->attr.type; |
| 861 | − int err; | |
| 861 | + int err = -ENOENT; | |
| 862 | 862 | |
| 863 | 863 | if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) |
| 864 | 864 | err = __hw_perf_event_init(event, type); |
| 865 | 865 | else if (event->pmu->type == type) |
| 866 | 866 | /* Registered as unknown PMU */ |
| 867 | 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 | 869 | return err; |
| 875 | 870 | } |
| @@ -1819,8 +1814,6 @@ static int cfdiag_event_init(struct perf_event *event) · 943 unmodified lines | ||
| 1819 | 1814 | event->destroy = hw_perf_event_destroy; |
| 1820 | 1815 | |
| 1821 | 1816 | err = cfdiag_event_init2(event); |
| 1822 | − if (unlikely(err)) | |
| 1823 | − event->destroy(event); | |
| 1824 | 1817 | out: |
| 1825 | 1818 | return err; |
| 1826 | 1819 | } |
| @@ -237,7 +237,6 @@ CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_NO_SPECIAL, 0x00f4); · 236 unmodified lines | ||
| 237 | 237 | CPUMF_EVENT_ATTR(cf_z14, TX_C_TABORT_SPECIAL, 0x00f5); |
| 238 | 238 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 239 | 239 | CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); |
| 240 | − | |
| 241 | 240 | CPUMF_EVENT_ATTR(cf_z15, L1D_RO_EXCL_WRITES, 0x0080); |
| 242 | 241 | CPUMF_EVENT_ATTR(cf_z15, DTLB2_WRITES, 0x0081); |
| 243 | 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 | 364 | CPUMF_EVENT_ATTR(cf_z16, NNPA_HOLD_LOCK, 0x010e); |
| 366 | 365 | CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 367 | 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 | 445 | static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = { |
| 370 | 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 | 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 | 494 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS), |
| 419 | 495 | CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES), |
| 420 | 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 | 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 | 939 | /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ |
| 783 | 940 | |
| 784 | 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 | 1016 | if (ci.csvn >= 1 && ci.csvn <= 5) |
| 860 | 1017 | csvn = cpumcf_svn_12345_pmu_event_attr; |
| 861 | 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 | 1021 | /* Determine model-specific counter set(s) */ |
| 865 | 1022 | get_cpu_id(&cpu_id); |
| @@ -892,6 +1049,10 @@ __init const struct attribute_group **cpumf_cf_event_group(void) · 26 unmodified lines | ||
| 892 | 1049 | case 0x3932: |
| 893 | 1050 | model = cpumcf_z16_pmu_event_attr; |
| 894 | 1051 | break; |
| 1052 | + case 0x9175: | |
| 1053 | + case 0x9176: | |
| 1054 | + model = cpumcf_z17_pmu_event_attr; | |
| 1055 | + break; | |
| 895 | 1056 | default: |
| 896 | 1057 | model = none; |
| 897 | 1058 | break; |
| @@ -885,9 +885,6 @@ static int cpumsf_pmu_event_init(struct perf_event *event) · 884 unmodified lines | ||
| 885 | 885 | event->attr.exclude_idle = 0; |
| 886 | 886 | |
| 887 | 887 | err = __hw_perf_event_init(event); |
| 888 | − if (unlikely(err)) | |
| 889 | − if (event->destroy) | |
| 890 | − event->destroy(event); | |
| 891 | 888 | return err; |
| 892 | 889 | } |
| 893 | 890 | |
| @@ -294,6 +294,10 @@ static int __init setup_elf_platform(void) · 293 unmodified lines | ||
| 294 | 294 | case 0x3932: |
| 295 | 295 | strcpy(elf_platform, "z16"); |
| 296 | 296 | break; |
| 297 | + case 0x9175: | |
| 298 | + case 0x9176: | |
| 299 | + strcpy(elf_platform, "z17"); | |
| 300 | + break; | |
| 297 | 301 | } |
| 298 | 302 | return 0; |
| 299 | 303 | } |
| @@ -95,7 +95,7 @@ static int handle_validity(struct kvm_vcpu *vcpu) · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | vcpu->stat.exit_validity++; |
| 97 | 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 | 99 | current->pid, vcpu->kvm); |
| 100 | 100 | |
| 101 | 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 | 3161 | if (!gi->origin) |
| 3162 | 3162 | return; |
| 3163 | 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 | 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 | 3177 | hrtimer_setup(&gi->timer, gisa_vcpu_kicker, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 3178 | 3178 | memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); |
| 3179 | 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 | 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 | 3218 | process_gib_alert_list(); |
| 3219 | 3219 | hrtimer_cancel(&gi->timer); |
| 3220 | 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 | 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 | 3471 | goto out; |
| 3472 | 3472 | |
| 3473 | 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 | 1023 | mutex_unlock(&kvm->lock); |
| 1024 | 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 | 1026 | (void *) kvm->arch.gmap->asce); |
| 1027 | 1027 | break; |
| 1028 | 1028 | } |
| @@ -3466,7 +3466,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 2437 unmodified lines | ||
| 3466 | 3466 | kvm_s390_gisa_init(kvm); |
| 3467 | 3467 | INIT_LIST_HEAD(&kvm->arch.pv.need_cleanup); |
| 3468 | 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 | 3471 | return 0; |
| 3472 | 3472 | out_err: |
| @@ -3529,7 +3529,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) · 56 unmodified lines | ||
| 3529 | 3529 | kvm_s390_destroy_adapters(kvm); |
| 3530 | 3530 | kvm_s390_clear_float_irqs(kvm); |
| 3531 | 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 | 3535 | /* Section: vcpu related */ |
| @@ -3650,7 +3650,7 @@ static int sca_switch_to_extended(struct kvm *kvm) · 114 unmodified lines | ||
| 3650 | 3650 | |
| 3651 | 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 | 3654 | old_sca, kvm->arch.sca); |
| 3655 | 3655 | return 0; |
| 3656 | 3656 | } |
| @@ -4027,7 +4027,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 370 unmodified lines | ||
| 4027 | 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 | 4031 | vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); |
| 4032 | 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 | 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 | 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 | 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 | 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 | 428 | return; |
| 429 | 429 | } |
| 430 | 430 | zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state); |
| 431 | + if (IS_ERR(zdev)) | |
| 432 | + return; | |
| 431 | 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 | 53 | #endif |
| 54 | 54 | #ifdef CONFIG_HAVE_MARCH_Z15_FEATURES |
| 55 | 55 | 61, /* miscellaneous-instruction-extension 3 */ |
| 56 | +#endif | |
| 57 | +#ifdef CONFIG_HAVE_MARCH_Z17_FEATURES | |
| 58 | + 84, /* miscellaneous-instruction-extension 4 */ | |
| 56 | 59 | #endif |
| 57 | 60 | -1 /* END */ |
| 58 | 61 | } |
| @@ -99,4 +99,3 @@ CONFIG_NLS_ISO8859_1=y · 98 unmodified lines | ||
| 99 | 99 | CONFIG_CRYPTO=y |
| 100 | 100 | CONFIG_CRYPTO_CBC=y |
| 101 | 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 | 128 | CONFIG_CRYPTO=y |
| 129 | 129 | CONFIG_CRYPTO_CBC=y |
| 130 | 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 | 33 | # CONFIG_PROC_FS is not set |
| 34 | 34 | # CONFIG_SYSFS is not set |
| 35 | 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 | 110 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 111 | 111 | CONFIG_DEBUG_FS=y |
| 112 | 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 | 56 | CONFIG_CRYPTO_MD5=y |
| 57 | 57 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 58 | 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 | 49 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 50 | 50 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 51 | 51 | CONFIG_DEBUG_FS=y |
| 52 | −# CONFIG_CRC32 is not set | |
| @@ -111,4 +111,3 @@ CONFIG_NLS_CODEPAGE_437=y · 110 unmodified lines | ||
| 111 | 111 | CONFIG_NLS_CODEPAGE_932=y |
| 112 | 112 | CONFIG_SH_STANDARD_BIOS=y |
| 113 | 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 | 58 | CONFIG_NLS_CODEPAGE_437=y |
| 59 | 59 | CONFIG_SH_STANDARD_BIOS=y |
| 60 | 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 | 86 | CONFIG_DEBUG_KOBJECT=y |
| 87 | 87 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 88 | 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 | 90 | CONFIG_CRYPTO_MANAGER=y |
| 91 | 91 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 92 | 92 | # CONFIG_CRYPTO_HW is not set |
| 93 | −CONFIG_CRC_T10DIF=y | |
| @@ -105,4 +105,3 @@ CONFIG_CRYPTO_ECB=m · 104 unmodified lines | ||
| 105 | 105 | CONFIG_CRYPTO_PCBC=m |
| 106 | 106 | CONFIG_CRYPTO_HMAC=y |
| 107 | 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 | 103 | CONFIG_CRYPTO_PCBC=m |
| 104 | 104 | CONFIG_CRYPTO_HMAC=y |
| 105 | 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 | 87 | CONFIG_NLS_CODEPAGE_932=y |
| 88 | 88 | CONFIG_DEBUG_FS=y |
| 89 | 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 | 92 | CONFIG_NLS_CODEPAGE_932=y |
| 93 | 93 | CONFIG_DEBUG_FS=y |
| 94 | 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 | 136 | CONFIG_CRYPTO_MD5=y |
| 137 | 137 | CONFIG_CRYPTO_DES=y |
| 138 | 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 | 101 | CONFIG_CRYPTO_LZO=y |
| 102 | 102 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 103 | 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 | 96 | CONFIG_CRYPTO_ECB=m |
| 97 | 97 | CONFIG_CRYPTO_PCBC=m |
| 98 | 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 | 122 | CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y |
| 123 | 123 | CONFIG_FRAME_POINTER=y |
| 124 | 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 | 128 | CONFIG_CRYPTO=y |
| 129 | 129 | CONFIG_CRYPTO_CBC=y |
| 130 | 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 | 120 | CONFIG_CRYPTO_SHA1=y |
| 121 | 121 | CONFIG_CRYPTO_DEFLATE=y |
| 122 | 122 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 123 | −CONFIG_CRC_CCITT=y | |
| 124 | 123 | CONFIG_RTC_CLASS=y |
| 125 | 124 | CONFIG_RTC_DRV_GENERIC=y |
| @@ -193,5 +193,3 @@ CONFIG_CRYPTO_DEFLATE=y · 192 unmodified lines | ||
| 193 | 193 | CONFIG_CRYPTO_LZO=y |
| 194 | 194 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 195 | 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 | 39 | # CONFIG_SYSFS is not set |
| 40 | 40 | # CONFIG_MISC_FILESYSTEMS is not set |
| 41 | 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 | 112 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 113 | 113 | CONFIG_DEBUG_FS=y |
| 114 | 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 | 41 | # CONFIG_SYSFS is not set |
| 42 | 42 | # CONFIG_MISC_FILESYSTEMS is not set |
| 43 | 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 | 264 | CONFIG_CRYPTO_TEA=m |
| 265 | 265 | CONFIG_CRYPTO_TWOFISH=m |
| 266 | 266 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 267 | −CONFIG_CRC16=m | |
| @@ -229,7 +229,6 @@ CONFIG_CRYPTO_SERPENT=m · 228 unmodified lines | ||
| 229 | 229 | CONFIG_CRYPTO_TEA=m |
| 230 | 230 | CONFIG_CRYPTO_TWOFISH=m |
| 231 | 231 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 232 | −CONFIG_CRC16=m | |
| 233 | 232 | CONFIG_VCC=m |
| 234 | 233 | CONFIG_PATA_CMD64X=y |
| 235 | 234 | CONFIG_IP_PNP=y |
| @@ -154,5 +154,6 @@ MRPROPER_FILES += $(HOST_DIR)/include/generated · 153 unmodified lines | ||
| 154 | 154 | archclean: |
| 155 | 155 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ |
| 156 | 156 | -o -name '*.gcov' \) -type f -print | xargs rm -f |
| 157 | + $(Q)$(MAKE) -f $(srctree)/Makefile ARCH=$(HEADER_ARCH) clean | |
| 157 | 158 | |
| 158 | 159 | export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING DEV_NULL_PATH |
| @@ -55,6 +55,7 @@ do { \ · 54 unmodified lines | ||
| 55 | 55 | goto err_label; \ |
| 56 | 56 | } \ |
| 57 | 57 | *((type *)dst) = get_unaligned((type *)(src)); \ |
| 58 | + barrier(); \ | |
| 58 | 59 | current->thread.segv_continue = NULL; \ |
| 59 | 60 | } while (0) |
| 60 | 61 | |
| @@ -66,6 +67,7 @@ do { \ · 5 unmodified lines | ||
| 66 | 67 | if (__faulted) \ |
| 67 | 68 | goto err_label; \ |
| 68 | 69 | put_unaligned(*((type *)src), (type *)(dst)); \ |
| 70 | + barrier(); \ | |
| 69 | 71 | current->thread.segv_continue = NULL; \ |
| 70 | 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 | 225 | panic("Failed to sync kernel TLBs: %d", err); |
| 226 | 226 | goto out; |
| 227 | 227 | } |
| 228 | − else if (current->mm == NULL) { | |
| 229 | − if (current->pagefault_disabled) { | |
| 230 | − if (!mc) { | |
| 231 | − show_regs(container_of(regs, struct pt_regs, regs)); | |
| 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; | |
| 228 | + else if (current->pagefault_disabled) { | |
| 229 | + if (!mc) { | |
| 230 | + show_regs(container_of(regs, struct pt_regs, regs)); | |
| 231 | + panic("Segfault with pagefaults disabled but no mcontext"); | |
| 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 | 242 | show_regs(container_of(regs, struct pt_regs, regs)); |
| 243 | 243 | panic("Segfault with no mm"); |
| 244 | 244 | } |
| @@ -2368,6 +2368,7 @@ config STRICT_SIGALTSTACK_SIZE · 2367 unmodified lines | ||
| 2368 | 2368 | config CFI_AUTO_DEFAULT |
| 2369 | 2369 | bool "Attempt to use FineIBT by default at boot time" |
| 2370 | 2370 | depends on FINEIBT |
| 2371 | + depends on !RUST || RUSTC_VERSION >= 108800 | |
| 2371 | 2372 | default y |
| 2372 | 2373 | help |
| 2373 | 2374 | Attempt to use FineIBT by default at boot time. If enabled, |
| @@ -2710,6 +2711,18 @@ config MITIGATION_SSB · 336 unmodified lines | ||
| 2710 | 2711 | of speculative execution in a similar way to the Meltdown and Spectre |
| 2711 | 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 | 2726 | endif |
| 2714 | 2727 | |
| 2715 | 2728 | config ARCH_HAS_ADD_PAGES |
| @@ -59,7 +59,7 @@ KBUILD_CFLAGS += $(CONFIG_CC_IMPLICIT_FALLTHROUGH) · 58 unmodified lines | ||
| 59 | 59 | $(obj)/bzImage: asflags-y := $(SVGA_MODE) |
| 60 | 60 | |
| 61 | 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 | 64 | $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin FORCE |
| 65 | 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 | 38 | if (early_is_tdx_guest()) { |
| 39 | 39 | if (!tdx_accept_memory(start, end)) |
| 40 | 40 | panic("TDX: Failed to accept memory\n"); |
| 41 | − } else if (sev_snp_enabled()) { | |
| 41 | + } else if (early_is_sevsnp_guest()) { | |
| 42 | 42 | snp_accept_memory(start, end); |
| 43 | 43 | } else { |
| 44 | 44 | error("Cannot accept memory: unknown platform\n"); |
| @@ -164,10 +164,7 @@ bool sev_snp_enabled(void) · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | static void __page_state_change(unsigned long paddr, enum psc_op op) |
| 166 | 166 | { |
| 167 | − u64 val; | |
| 168 | − | |
| 169 | − if (!sev_snp_enabled()) | |
| 170 | − return; | |
| 167 | + u64 val, msr; | |
| 171 | 168 | |
| 172 | 169 | /* |
| 173 | 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 | 173 | if (op == SNP_PAGE_STATE_SHARED) |
| 177 | 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 | 179 | /* Issue VMGEXIT to change the page state in RMP table. */ |
| 180 | 180 | sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op)); |
| 181 | 181 | VMGEXIT(); |
| @@ -185,6 +185,9 @@ static void __page_state_change(unsigned long paddr, enum psc_op op) · 3 unmodified lines | ||
| 185 | 185 | if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val)) |
| 186 | 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 | 192 | * Now that page state is changed in the RMP table, validate it so that it is |
| 190 | 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 | 199 | void snp_set_page_private(unsigned long paddr) |
| 197 | 200 | { |
| 201 | + if (!sev_snp_enabled()) | |
| 202 | + return; | |
| 203 | + | |
| 198 | 204 | __page_state_change(paddr, SNP_PAGE_STATE_PRIVATE); |
| 199 | 205 | } |
| 200 | 206 | |
| 201 | 207 | void snp_set_page_shared(unsigned long paddr) |
| 202 | 208 | { |
| 209 | + if (!sev_snp_enabled()) | |
| 210 | + return; | |
| 211 | + | |
| 203 | 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 | 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 | 235 | void snp_accept_memory(phys_addr_t start, phys_addr_t end) |
| 265 | 236 | { |
| 266 | − struct snp_psc_desc desc = {}; | |
| 267 | − unsigned int i; | |
| 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); | |
| 237 | + for (phys_addr_t pa = start; pa < end; pa += PAGE_SIZE) | |
| 238 | + __page_state_change(pa, SNP_PAGE_STATE_PRIVATE); | |
| 276 | 239 | } |
| 277 | 240 | |
| 278 | 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 | 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 | 13 | bool sev_snp_enabled(void); |
| 14 | 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 | 18 | #else |
| 17 | 19 | |
| 18 | 20 | static inline bool sev_snp_enabled(void) { return false; } |
| 19 | 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 | 25 | #endif |
| 22 | 26 | |
| @@ -959,6 +959,102 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end) · 958 unmodified lines | ||
| 959 | 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 | 1058 | static void set_pte_enc(pte_t *kpte, int level, void *va) |
| 963 | 1059 | { |
| 964 | 1060 | struct pte_enc_desc d = { |
| @@ -1005,7 +1101,8 @@ static void unshare_all_memory(void) · 40 unmodified lines | ||
| 1005 | 1101 | data = per_cpu(runtime_data, cpu); |
| 1006 | 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 | 1106 | skipped_addr = true; |
| 1010 | 1107 | break; |
| 1011 | 1108 | } |
| @@ -1055,11 +1152,70 @@ void snp_kexec_begin(void) · 43 unmodified lines | ||
| 1055 | 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 | 1214 | void snp_kexec_finish(void) |
| 1059 | 1215 | { |
| 1060 | 1216 | struct sev_es_runtime_data *data; |
| 1217 | + unsigned long size, addr; | |
| 1061 | 1218 | unsigned int level, cpu; |
| 1062 | − unsigned long size; | |
| 1063 | 1219 | struct ghcb *ghcb; |
| 1064 | 1220 | pte_t *pte; |
| 1065 | 1221 | |
| @@ -1069,6 +1225,8 @@ void snp_kexec_finish(void) · 3 unmodified lines | ||
| 1069 | 1225 | if (!IS_ENABLED(CONFIG_KEXEC_CORE)) |
| 1070 | 1226 | return; |
| 1071 | 1227 | |
| 1228 | + shutdown_all_aps(); | |
| 1229 | + | |
| 1072 | 1230 | unshare_all_memory(); |
| 1073 | 1231 | |
| 1074 | 1232 | /* |
| @@ -1085,54 +1243,11 @@ void snp_kexec_finish(void) · 10 unmodified lines | ||
| 1085 | 1243 | ghcb = &data->ghcb_page; |
| 1086 | 1244 | pte = lookup_address((unsigned long)ghcb, &level); |
| 1087 | 1245 | size = page_level_size(level); |
| 1088 | − set_pte_enc(pte, level, (void *)ghcb); | |
| 1089 | − snp_set_memory_private((unsigned long)ghcb, (size / PAGE_SIZE)); | |
| 1090 | − } | |
| 1091 | −} | |
| 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); | |
| 1246 | + /* Handle the case of a huge page containing the GHCB page */ | |
| 1247 | + addr = (unsigned long)ghcb & page_level_mask(level); | |
| 1248 | + set_pte_enc(pte, level, (void *)addr); | |
| 1249 | + snp_set_memory_private(addr, (size / PAGE_SIZE)); | |
| 1133 | 1250 | } |
| 1134 | − | |
| 1135 | − return ret; | |
| 1136 | 1251 | } |
| 1137 | 1252 | |
| 1138 | 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 | 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 | 1284 | static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip) |
| 1181 | 1285 | { |
| 1182 | 1286 | struct sev_es_save_area *cur_vmsa, *vmsa; |
| 1183 | − struct ghcb_state state; | |
| 1184 | 1287 | struct svsm_ca *caa; |
| 1185 | − unsigned long flags; | |
| 1186 | − struct ghcb *ghcb; | |
| 1187 | 1288 | u8 sipi_vector; |
| 1188 | 1289 | int cpu, ret; |
| 1189 | 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 | 1400 | /* Issue VMGEXIT AP Creation NAE event */ |
| 1300 | − local_irq_save(flags); | |
| 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 */ | |
| 1401 | + ret = vmgexit_ap_control(SVM_VMGEXIT_AP_CREATE, vmsa, apic_id); | |
| 1327 | 1402 | if (ret) { |
| 1328 | 1403 | snp_cleanup_vmsa(vmsa, apic_id); |
| 1329 | 1404 | vmsa = NULL; |
| @@ -17,19 +17,20 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 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 | 22 | ANNOTATE_NOENDBR |
| 22 | 23 | movl $MSR_IA32_PRED_CMD, %ecx |
| 23 | − movl $PRED_CMD_IBPB, %eax | |
| 24 | + movl _ASM_RIP(x86_pred_cmd), %eax | |
| 24 | 25 | xorl %edx, %edx |
| 25 | 26 | wrmsr |
| 26 | 27 | |
| 27 | 28 | /* Make sure IBPB clears return stack preductions too. */ |
| 28 | 29 | FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET |
| 29 | 30 | RET |
| 30 | −SYM_FUNC_END(entry_ibpb) | |
| 31 | +SYM_FUNC_END(write_ibpb) | |
| 31 | 32 | /* For KVM */ |
| 32 | −EXPORT_SYMBOL_GPL(entry_ibpb); | |
| 33 | +EXPORT_SYMBOL_GPL(write_ibpb); | |
| 33 | 34 | |
| 34 | 35 | .popsection |
| 35 | 36 | |
| @@ -1525,7 +1525,9 @@ SYM_CODE_END(rewind_stack_and_make_dead) · 1524 unmodified lines | ||
| 1525 | 1525 | * ORC to unwind properly. |
| 1526 | 1526 | * |
| 1527 | 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 | 1532 | SYM_FUNC_START(clear_bhb_loop) |
| 1531 | 1533 | ANNOTATE_NOENDBR |
| @@ -1536,10 +1538,22 @@ SYM_FUNC_START(clear_bhb_loop) · 4 unmodified lines | ||
| 1536 | 1538 | call 1f |
| 1537 | 1539 | jmp 5f |
| 1538 | 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 | 1546 | ANNOTATE_INTRA_FUNCTION_CALL |
| 1540 | 1547 | 1: call 2f |
| 1541 | − RET | |
| 1548 | +.Lret1: RET | |
| 1542 | 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 | 1557 | 2: movl $5, %eax |
| 1544 | 1558 | 3: jmp 4f |
| 1545 | 1559 | nop |
| @@ -1547,7 +1561,7 @@ SYM_FUNC_START(clear_bhb_loop) · 1 unmodified line | ||
| 1547 | 1561 | jnz 3b |
| 1548 | 1562 | sub $1, %ecx |
| 1549 | 1563 | jnz 1b |
| 1550 | − RET | |
| 1564 | +.Lret2: RET | |
| 1551 | 1565 | 5: lfence |
| 1552 | 1566 | pop %rbp |
| 1553 | 1567 | RET |
| @@ -629,7 +629,7 @@ int x86_pmu_hw_config(struct perf_event *event) · 628 unmodified lines | ||
| 629 | 629 | if (event->attr.type == event->pmu->type) |
| 630 | 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 | 633 | s64 left = event->attr.sample_period; |
| 634 | 634 | x86_pmu.limit_period(event, &left); |
| 635 | 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 | 759 | int i; |
| 760 | 760 | |
| @@ -3049,7 +3049,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) · 3048 unmodified lines | ||
| 3049 | 3049 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 3050 | 3050 | int bit; |
| 3051 | 3051 | int handled = 0; |
| 3052 | − u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl); | |
| 3053 | 3052 | |
| 3054 | 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 | 3092 | handled++; |
| 3094 | 3093 | x86_pmu_handle_guest_pebs(regs, &data); |
| 3095 | 3094 | static_call(x86_pmu_drain_pebs)(regs, &data); |
| 3096 | − status &= intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI; | |
| 3097 | 3095 | |
| 3098 | 3096 | /* |
| 3099 | 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 | 3103 | if (pebs_enabled != cpuc->pebs_enabled) |
| 3106 | 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 | 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 | 3136 | * Checkpointed counters can lead to 'spurious' PMIs because the |
| 3128 | 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 | 4395 | arr[pebs_enable] = (struct perf_guest_switch_msr){ |
| 4387 | 4396 | .msr = MSR_IA32_PEBS_ENABLE, |
| 4388 | 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 | 4401 | if (arr[pebs_enable].host) { |
| @@ -7305,8 +7314,17 @@ __init int intel_pmu_init(void) · 2912 unmodified lines | ||
| 7305 | 7314 | name = "meteorlake_hybrid"; |
| 7306 | 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 | 7322 | case INTEL_LUNARLAKE_M: |
| 7309 | 7323 | case INTEL_ARROWLAKE: |
| 7324 | + pr_cont("Lunarlake Hybrid events, "); | |
| 7325 | + name = "lunarlake_hybrid"; | |
| 7326 | + | |
| 7327 | + lnl_common: | |
| 7310 | 7328 | intel_pmu_init_hybrid(hybrid_big_small); |
| 7311 | 7329 | |
| 7312 | 7330 | x86_pmu.pebs_latency_data = lnl_latency_data; |
| @@ -7328,8 +7346,6 @@ __init int intel_pmu_init(void) · 15 unmodified lines | ||
| 7328 | 7346 | intel_pmu_init_skt(&pmu->pmu); |
| 7329 | 7347 | |
| 7330 | 7348 | intel_pmu_pebs_data_source_lnl(); |
| 7331 | − pr_cont("Lunarlake Hybrid events, "); | |
| 7332 | − name = "lunarlake_hybrid"; | |
| 7333 | 7349 | break; |
| 7334 | 7350 | |
| 7335 | 7351 | case INTEL_ARROWLAKE_H: |
| @@ -1399,8 +1399,10 @@ static u64 pebs_update_adaptive_cfg(struct perf_event *event) · 1398 unmodified lines | ||
| 1399 | 1399 | * + precise_ip < 2 for the non event IP |
| 1400 | 1400 | * + For RTM TSX weight we need GPRs for the abort code. |
| 1401 | 1401 | */ |
| 1402 | − gprs = (sample_type & PERF_SAMPLE_REGS_INTR) && | |
| 1403 | − (attr->sample_regs_intr & PEBS_GP_REGS); | |
| 1402 | + gprs = ((sample_type & PERF_SAMPLE_REGS_INTR) && | |
| 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 | 1407 | tsx_weight = (sample_type & PERF_SAMPLE_WEIGHT_TYPE) && |
| 1406 | 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 | 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 | 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 | 2380 | intel_pmu_save_and_restart_reload(event, count); |
| 2379 | 2381 | } |
| 2380 | − } else | |
| 2381 | − intel_pmu_save_and_restart(event); | |
| 2382 | + } else { | |
| 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 | 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 | 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 | 2471 | struct perf_event *event; |
| 2452 | 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 | 2478 | * It needs to call intel_pmu_save_and_restart_reload() to |
| 2459 | 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 | 2482 | event = cpuc->events[bit]; |
| 2463 | 2483 | if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD) |
| 2464 | 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 | 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 | 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 | 2627 | (hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED); |
| 2608 | 2628 | |
| 2609 | 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 | 2631 | return; |
| 2612 | 2632 | } |
| 2613 | 2633 | |
| @@ -4891,28 +4891,28 @@ static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = { · 4890 unmodified lines | ||
| 4891 | 4891 | INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), |
| 4892 | 4892 | /* Free-Running IIO BANDWIDTH IN Counters */ |
| 4893 | 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 | 4895 | INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), |
| 4896 | 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 | 4898 | INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), |
| 4899 | 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 | 4901 | INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), |
| 4902 | 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 | 4904 | INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), |
| 4905 | 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 | 4907 | INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"), |
| 4908 | 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 | 4910 | INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"), |
| 4911 | 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 | 4913 | INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"), |
| 4914 | 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 | 4916 | INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"), |
| 4917 | 4917 | { /* end: all zeroes */ }, |
| 4918 | 4918 | }; |
| @@ -5485,37 +5485,6 @@ static struct freerunning_counters icx_iio_freerunning[] = { · 566 unmodified lines | ||
| 5485 | 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 | 5488 | static struct intel_uncore_type icx_uncore_iio_free_running = { |
| 5520 | 5489 | .name = "iio_free_running", |
| 5521 | 5490 | .num_counters = 9, |
| @@ -5523,7 +5492,7 @@ static struct intel_uncore_type icx_uncore_iio_free_running = { · 1 unmodified line | ||
| 5523 | 5492 | .num_freerunning_types = ICX_IIO_FREERUNNING_TYPE_MAX, |
| 5524 | 5493 | .freerunning = icx_iio_freerunning, |
| 5525 | 5494 | .ops = &skx_uncore_iio_freerunning_ops, |
| 5526 | − .event_descs = icx_uncore_iio_freerunning_events, | |
| 5495 | + .event_descs = snr_uncore_iio_freerunning_events, | |
| 5527 | 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 | 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 | 6292 | static struct intel_uncore_type spr_uncore_iio_free_running = { |
| 6380 | 6293 | .name = "iio_free_running", |
| 6381 | 6294 | .num_counters = 17, |
| 6382 | 6295 | .num_freerunning_types = SPR_IIO_FREERUNNING_TYPE_MAX, |
| 6383 | 6296 | .freerunning = spr_iio_freerunning, |
| 6384 | 6297 | .ops = &skx_uncore_iio_freerunning_ops, |
| 6385 | − .event_descs = spr_uncore_iio_freerunning_events, | |
| 6298 | + .event_descs = snr_uncore_iio_freerunning_events, | |
| 6386 | 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 | 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 | 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 | 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 | 130 | struct amd_nb { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/stringify.h> |
| 7 | 7 | #include <linux/objtool.h> |
| 8 | 8 | #include <asm/asm.h> |
| 9 | +#include <asm/bug.h> | |
| 9 | 10 | |
| 10 | 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 | 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 | 159 | #ifdef CONFIG_SMP |
| 128 | 160 | extern void alternatives_smp_module_add(struct module *mod, char *name, |
| 129 | 161 | void *locks, void *locks_end, |
| @@ -75,7 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */ |
| 76 | 76 | #define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */ |
| 77 | 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 | 79 | /* Free ( 3*32+ 7) */ |
| 80 | 80 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */ |
| 81 | 81 | #define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */ |
| @@ -481,6 +481,7 @@ · 399 unmodified lines | ||
| 481 | 481 | #define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */ |
| 482 | 482 | #define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */ |
| 483 | 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 | 487 | * BUG word(s) |
| @@ -533,4 +534,6 @@ · 46 unmodified lines | ||
| 533 | 534 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ |
| 534 | 535 | #define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ |
| 535 | 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 | 539 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -126,6 +126,8 @@ · 125 unmodified lines | ||
| 126 | 126 | #define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */ |
| 127 | 127 | #define INTEL_GRANITERAPIDS_D IFM(6, 0xAE) |
| 128 | 128 | |
| 129 | +#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */ | |
| 130 | + | |
| 129 | 131 | /* "Hybrid" Processors (P-Core/E-Core) */ |
| 130 | 132 | |
| 131 | 133 | #define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */ |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <asm/mtrr.h> |
| 36 | 36 | #include <asm/msr-index.h> |
| 37 | 37 | #include <asm/asm.h> |
| 38 | +#include <asm/irq_remapping.h> | |
| 38 | 39 | #include <asm/kvm_page_track.h> |
| 39 | 40 | #include <asm/kvm_vcpu_regs.h> |
| 40 | 41 | #include <asm/reboot.h> |
| @@ -1472,8 +1473,13 @@ struct kvm_arch { · 1431 unmodified lines | ||
| 1472 | 1473 | struct once nx_once; |
| 1473 | 1474 | |
| 1474 | 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 | 1481 | atomic64_t tdp_mmu_pages; |
| 1482 | +#endif | |
| 1477 | 1483 | |
| 1478 | 1484 | /* |
| 1479 | 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 | 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 | 2432 | #endif /* _ASM_X86_KVM_HOST_H */ |
| @@ -17,10 +17,12 @@ struct ucode_cpu_info { · 16 unmodified lines | ||
| 17 | 17 | void load_ucode_bsp(void); |
| 18 | 18 | void load_ucode_ap(void); |
| 19 | 19 | void microcode_bsp_resume(void); |
| 20 | +bool __init microcode_loader_disabled(void); | |
| 20 | 21 | #else |
| 21 | 22 | static inline void load_ucode_bsp(void) { } |
| 22 | 23 | static inline void load_ucode_ap(void) { } |
| 23 | 24 | static inline void microcode_bsp_resume(void) { } |
| 25 | +static inline bool __init microcode_loader_disabled(void) { return false; } | |
| 24 | 26 | #endif |
| 25 | 27 | |
| 26 | 28 | extern unsigned long initrd_start_early; |
| @@ -211,6 +211,14 @@ · 210 unmodified lines | ||
| 211 | 211 | * VERW clears CPU Register |
| 212 | 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 | 223 | #define MSR_IA32_FLUSH_CMD 0x0000010b |
| 216 | 224 | #define L1D_FLUSH BIT(0) /* |
| @@ -269,7 +269,7 @@ · 268 unmodified lines | ||
| 269 | 269 | * typically has NO_MELTDOWN). |
| 270 | 270 | * |
| 271 | 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 | 274 | * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point |
| 275 | 275 | * where we have a stack but before any RET instruction. |
| @@ -279,7 +279,7 @@ · 3 unmodified lines | ||
| 279 | 279 | VALIDATE_UNRET_END |
| 280 | 280 | CALL_UNTRAIN_RET |
| 281 | 281 | ALTERNATIVE_2 "", \ |
| 282 | − "call entry_ibpb", \ibpb_feature, \ | |
| 282 | + "call write_ibpb", \ibpb_feature, \ | |
| 283 | 283 | __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH |
| 284 | 284 | #endif |
| 285 | 285 | .endm |
| @@ -336,10 +336,14 @@ · 50 unmodified lines | ||
| 336 | 336 | |
| 337 | 337 | #else /* __ASSEMBLER__ */ |
| 338 | 338 | |
| 339 | +#define ITS_THUNK_SIZE 64 | |
| 340 | + | |
| 339 | 341 | typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE]; |
| 342 | +typedef u8 its_thunk_t[ITS_THUNK_SIZE]; | |
| 340 | 343 | extern retpoline_thunk_t __x86_indirect_thunk_array[]; |
| 341 | 344 | extern retpoline_thunk_t __x86_indirect_call_thunk_array[]; |
| 342 | 345 | extern retpoline_thunk_t __x86_indirect_jump_thunk_array[]; |
| 346 | +extern its_thunk_t __x86_indirect_its_thunk_array[]; | |
| 343 | 347 | |
| 344 | 348 | #ifdef CONFIG_MITIGATION_RETHUNK |
| 345 | 349 | extern void __x86_return_thunk(void); |
| @@ -363,12 +367,18 @@ static inline void srso_return_thunk(void) {} · 17 unmodified lines | ||
| 363 | 367 | static inline void srso_alias_return_thunk(void) {} |
| 364 | 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 | 376 | extern void retbleed_return_thunk(void); |
| 367 | 377 | extern void srso_return_thunk(void); |
| 368 | 378 | extern void srso_alias_return_thunk(void); |
| 369 | 379 | |
| 370 | 380 | extern void entry_untrain_ret(void); |
| 371 | −extern void entry_ibpb(void); | |
| 381 | +extern void write_ibpb(void); | |
| 372 | 382 | |
| 373 | 383 | #ifdef CONFIG_X86_64 |
| 374 | 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 | 524 | : "memory"); |
| 515 | 525 | } |
| 516 | 526 | |
| 517 | −extern u64 x86_pred_cmd; | |
| 518 | − | |
| 519 | 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 | 534 | /* The Intel SPEC CTRL MSR base value cache */ |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/mm.h> /* for struct page */ |
| 7 | 7 | #include <linux/pagemap.h> |
| 8 | 8 | |
| 9 | +#include <asm/cpufeature.h> | |
| 10 | + | |
| 9 | 11 | #define __HAVE_ARCH_PTE_ALLOC_ONE |
| 10 | 12 | #define __HAVE_ARCH_PGD_FREE |
| 11 | 13 | #include <asm-generic/pgalloc.h> |
| @@ -29,16 +31,17 @@ static inline void paravirt_release_pud(unsigned long pfn) {} · 17 unmodified lines | ||
| 29 | 31 | static inline void paravirt_release_p4d(unsigned long pfn) {} |
| 30 | 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 | − * both 8k in size and 8k-aligned. That lets us just flip bit 12 | |
| 36 | − * in a pointer to swap between the two 4k halves. | |
| 35 | + * In case of Page Table Isolation active, we acquire two PGDs instead of one. | |
| 36 | + * Being order-1, it is both 8k in size and 8k-aligned. That lets us just | |
| 37 | + * flip bit 12 in a pointer to swap between the two 4k halves. | |
| 37 | 38 | */ |
| 38 | −#define PGD_ALLOCATION_ORDER 1 | |
| 39 | −#else | |
| 40 | −#define PGD_ALLOCATION_ORDER 0 | |
| 41 | −#endif | |
| 39 | +static inline unsigned int pgd_allocation_order(void) | |
| 40 | +{ | |
| 41 | + if (cpu_feature_enabled(X86_FEATURE_PTI)) | |
| 42 | + return 1; | |
| 43 | + return 0; | |
| 44 | +} | |
| 42 | 45 | |
| 43 | 46 | /* |
| 44 | 47 | * Allocate and free page tables. |
| @@ -116,7 +116,7 @@ enum psc_op { · 115 unmodified lines | ||
| 116 | 116 | #define GHCB_MSR_VMPL_REQ 0x016 |
| 117 | 117 | #define GHCB_MSR_VMPL_REQ_LEVEL(v) \ |
| 118 | 118 | /* GHCBData[39:32] */ \ |
| 119 | − (((u64)(v) & GENMASK_ULL(7, 0) << 32) | \ | |
| 119 | + ((((u64)(v) & GENMASK_ULL(7, 0)) << 32) | \ | |
| 120 | 120 | /* GHCBDdata[11:0] */ \ |
| 121 | 121 | GHCB_MSR_VMPL_REQ) |
| 122 | 122 | |
| @@ -16,23 +16,23 @@ · 15 unmodified lines | ||
| 16 | 16 | #ifdef __ASSEMBLER__ |
| 17 | 17 | |
| 18 | 18 | #define ASM_CLAC \ |
| 19 | − ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP | |
| 19 | + ALTERNATIVE "", "clac", X86_FEATURE_SMAP | |
| 20 | 20 | |
| 21 | 21 | #define ASM_STAC \ |
| 22 | − ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP | |
| 22 | + ALTERNATIVE "", "stac", X86_FEATURE_SMAP | |
| 23 | 23 | |
| 24 | 24 | #else /* __ASSEMBLER__ */ |
| 25 | 25 | |
| 26 | 26 | static __always_inline void clac(void) |
| 27 | 27 | { |
| 28 | 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 | 32 | static __always_inline void stac(void) |
| 33 | 33 | { |
| 34 | 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 | 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 | 60 | /* These macros can be used in asm() statements */ |
| 61 | 61 | #define ASM_CLAC \ |
| 62 | − ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP) | |
| 62 | + ALTERNATIVE("", "clac", X86_FEATURE_SMAP) | |
| 63 | 63 | #define ASM_STAC \ |
| 64 | − ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP) | |
| 64 | + ALTERNATIVE("", "stac", X86_FEATURE_SMAP) | |
| 65 | 65 | |
| 66 | 66 | #define ASM_CLAC_UNSAFE \ |
| 67 | 67 | ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP) |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/serial_core.h> |
| 24 | 24 | #include <linux/pgtable.h> |
| 25 | 25 | |
| 26 | +#include <xen/xen.h> | |
| 27 | + | |
| 26 | 28 | #include <asm/e820/api.h> |
| 27 | 29 | #include <asm/irqdomain.h> |
| 28 | 30 | #include <asm/pci_x86.h> |
| @@ -1729,6 +1731,15 @@ int __init acpi_mps_check(void) · 1700 unmodified lines | ||
| 1729 | 1731 | { |
| 1730 | 1732 | #if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE) |
| 1731 | 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 | 1743 | if (acpi_disabled || acpi_noirq) { |
| 1733 | 1744 | pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n"); |
| 1734 | 1745 | return 1; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/mmu_context.h> |
| 19 | 19 | #include <linux/bsearch.h> |
| 20 | 20 | #include <linux/sync_core.h> |
| 21 | +#include <linux/execmem.h> | |
| 21 | 22 | #include <asm/text-patching.h> |
| 22 | 23 | #include <asm/alternative.h> |
| 23 | 24 | #include <asm/sections.h> |
| @@ -31,6 +32,8 @@ · 7 unmodified lines | ||
| 31 | 32 | #include <asm/paravirt.h> |
| 32 | 33 | #include <asm/asm-prototypes.h> |
| 33 | 34 | #include <asm/cfi.h> |
| 35 | +#include <asm/ibt.h> | |
| 36 | +#include <asm/set_memory.h> | |
| 34 | 37 | |
| 35 | 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 | 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 | 296 | * Nomenclature for variable names to simplify and clarify this code and ease |
| 129 | 297 | * any potential staring at it: |
| @@ -581,7 +749,8 @@ static int emit_indirect(int op, int reg, u8 *bytes) · 451 unmodified lines | ||
| 581 | 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 | 755 | u8 op = insn->opcode.bytes[0]; |
| 587 | 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 | 771 | switch (op) { |
| 603 | 772 | case CALL_INSN_OPCODE: |
| 604 | 773 | __text_gen_insn(bytes+i, op, addr+i, |
| 605 | − __x86_indirect_call_thunk_array[reg], | |
| 774 | + call_dest, | |
| 606 | 775 | CALL_INSN_SIZE); |
| 607 | 776 | i += CALL_INSN_SIZE; |
| 608 | 777 | break; |
| @@ -610,7 +779,7 @@ static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 · 1 unmodified line | ||
| 610 | 779 | case JMP32_INSN_OPCODE: |
| 611 | 780 | clang_jcc: |
| 612 | 781 | __text_gen_insn(bytes+i, op, addr+i, |
| 613 | − __x86_indirect_jump_thunk_array[reg], | |
| 782 | + jmp_dest, | |
| 614 | 783 | JMP32_INSN_SIZE); |
| 615 | 784 | i += JMP32_INSN_SIZE; |
| 616 | 785 | break; |
| @@ -625,6 +794,48 @@ clang_jcc: · 8 unmodified lines | ||
| 625 | 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 | 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 | 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 | 922 | ret = emit_indirect(op, reg, bytes + i); |
| 703 | 923 | if (ret < 0) |
| 704 | 924 | return ret; |
| @@ -732,6 +952,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) · 27 unmodified lines | ||
| 732 | 952 | int len, ret; |
| 733 | 953 | u8 bytes[16]; |
| 734 | 954 | u8 op1, op2; |
| 955 | + u8 *dest; | |
| 735 | 956 | |
| 736 | 957 | ret = insn_decode_kernel(&insn, addr); |
| 737 | 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 | 970 | case CALL_INSN_OPCODE: |
| 750 | 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 | 978 | break; |
| 752 | 979 | |
| 753 | 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 | 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 | 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 | 1033 | int i = 0; |
| 792 | 1034 | |
| 793 | 1035 | /* Patch the custom return thunks... */ |
| 794 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { | |
| 1036 | + if (cpu_wants_rethunk_at(addr)) { | |
| 795 | 1037 | i = JMP32_INSN_SIZE; |
| 796 | 1038 | __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i); |
| 797 | 1039 | } else { |
| @@ -808,7 +1050,7 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end) · 10 unmodified lines | ||
| 808 | 1050 | { |
| 809 | 1051 | s32 *s; |
| 810 | 1052 | |
| 811 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | |
| 1053 | + if (cpu_wants_rethunk()) | |
| 812 | 1054 | static_call_force_reinit(); |
| 813 | 1055 | |
| 814 | 1056 | for (s = start; s < end; s++) { |
| @@ -1022,8 +1264,6 @@ int cfi_get_func_arity(void *func) · 207 unmodified lines | ||
| 1022 | 1264 | static bool cfi_rand __ro_after_init = true; |
| 1023 | 1265 | static u32 cfi_seed __ro_after_init; |
| 1024 | 1266 | |
| 1025 | −static bool cfi_paranoid __ro_after_init = false; | |
| 1026 | − | |
| 1027 | 1267 | /* |
| 1028 | 1268 | * Re-hash the CFI hash with a boot-time seed while making sure the result is |
| 1029 | 1269 | * not a valid ENDBR instruction. |
| @@ -1436,6 +1676,19 @@ static int cfi_rand_callers(s32 *start, s32 *end) · 406 unmodified lines | ||
| 1436 | 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 | 1692 | static int cfi_rewrite_callers(s32 *start, s32 *end) |
| 1440 | 1693 | { |
| 1441 | 1694 | s32 *s; |
| @@ -1477,9 +1730,14 @@ static int cfi_rewrite_callers(s32 *start, s32 *end) · 35 unmodified lines | ||
| 1477 | 1730 | memcpy(bytes, fineibt_paranoid_start, fineibt_paranoid_size); |
| 1478 | 1731 | memcpy(bytes + fineibt_caller_hash, &hash, 4); |
| 1479 | 1732 | |
| 1480 | − ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind); | |
| 1481 | − if (WARN_ON_ONCE(ret != 3)) | |
| 1482 | − continue; | |
| 1733 | + if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + fineibt_paranoid_ind, 11)) { | |
| 1734 | + emit_paranoid_trampoline(addr + fineibt_caller_size, | |
| 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 | 1742 | text_poke_early(addr, bytes, fineibt_paranoid_size); |
| 1485 | 1743 | } |
| @@ -1706,29 +1964,66 @@ Efault: · 220 unmodified lines | ||
| 1706 | 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 | 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 | 1983 | static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, u32 *type) |
| 1714 | 1984 | { |
| 1715 | 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 | 1988 | return false; |
| 1720 | 1989 | |
| 1721 | − __get_kernel_nofault(&hash, addr + fineibt_caller_hash, u32, Efault); | |
| 1722 | − *target = regs->r11 + fineibt_preamble_size; | |
| 1723 | − *type = regs->r10; | |
| 1990 | + if (is_cfi_trap(addr + fineibt_caller_size - LEN_UD2)) { | |
| 1991 | + *target = regs->r11 + fineibt_preamble_size; | |
| 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, | |
| 1727 | − * Jcc.d8 that got us here, the normal fixup will work. | |
| 2002 | + * The cfi_paranoid + ITS thunk combination results in: | |
| 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 | 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 | 2327 | void __init alternative_instructions(void) |
| 2033 | 2328 | { |
| 2329 | + u64 ibt; | |
| 2330 | + | |
| 2034 | 2331 | int3_selftest(); |
| 2035 | 2332 | |
| 2036 | 2333 | /* |
| @@ -2057,6 +2354,9 @@ void __init alternative_instructions(void) · 20 unmodified lines | ||
| 2057 | 2354 | */ |
| 2058 | 2355 | paravirt_set_cap(); |
| 2059 | 2356 | |
| 2357 | + /* Keep CET-IBT disabled until caller/callee are patched */ | |
| 2358 | + ibt = ibt_save(/*disable*/ true); | |
| 2359 | + | |
| 2060 | 2360 | __apply_fineibt(__retpoline_sites, __retpoline_sites_end, |
| 2061 | 2361 | __cfi_sites, __cfi_sites_end, true); |
| 2062 | 2362 | |
| @@ -2080,6 +2380,8 @@ void __init alternative_instructions(void) · 17 unmodified lines | ||
| 2080 | 2380 | */ |
| 2081 | 2381 | apply_seal_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end); |
| 2082 | 2382 | |
| 2383 | + ibt_restore(ibt); | |
| 2384 | + | |
| 2083 | 2385 | #ifdef CONFIG_SMP |
| 2084 | 2386 | /* Patch to UP if other cpus not imminent. */ |
| 2085 | 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 | 472 | case 0x60 ... 0x7f: |
| 473 | 473 | setup_force_cpu_cap(X86_FEATURE_ZEN5); |
| 474 | 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 | 480 | default: |
| 476 | 481 | goto warn; |
| 477 | 482 | } |
| @@ -805,6 +810,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) · 327 unmodified lines | ||
| 805 | 810 | static const struct x86_cpu_id erratum_1386_microcode[] = { |
| 806 | 811 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x01), 0x2, 0x2, 0x0800126e), |
| 807 | 812 | X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x31), 0x0, 0x0, 0x08301052), |
| 813 | + {} | |
| 808 | 814 | }; |
| 809 | 815 | |
| 810 | 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 | 875 | pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); |
| 870 | 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 | 889 | static bool cpu_has_zenbleed_microcode(void) |
| @@ -1051,13 +1067,8 @@ static void init_amd(struct cpuinfo_x86 *c) · 177 unmodified lines | ||
| 1051 | 1067 | if (!cpu_feature_enabled(X86_FEATURE_XENPV)) |
| 1052 | 1068 | set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); |
| 1053 | 1069 | |
| 1054 | − /* | |
| 1055 | − * Turn on the Instructions Retired free counter on machines not | |
| 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)) | |
| 1070 | + /* Enable the Instructions Retired free counter */ | |
| 1071 | + if (cpu_has(c, X86_FEATURE_IRPERF)) | |
| 1061 | 1072 | msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); |
| 1062 | 1073 | |
| 1063 | 1074 | check_null_seg_clears_base(c); |
| @@ -49,6 +49,7 @@ static void __init srbds_select_mitigation(void); · 48 unmodified lines | ||
| 49 | 49 | static void __init l1d_flush_select_mitigation(void); |
| 50 | 50 | static void __init srso_select_mitigation(void); |
| 51 | 51 | static void __init gds_select_mitigation(void); |
| 52 | +static void __init its_select_mitigation(void); | |
| 52 | 53 | |
| 53 | 54 | /* The base value of the SPEC_CTRL MSR without task-specific bits set */ |
| 54 | 55 | u64 x86_spec_ctrl_base; |
| @@ -59,7 +60,6 @@ DEFINE_PER_CPU(u64, x86_spec_ctrl_current); · 4 unmodified lines | ||
| 59 | 60 | EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current); |
| 60 | 61 | |
| 61 | 62 | u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; |
| 62 | −EXPORT_SYMBOL_GPL(x86_pred_cmd); | |
| 63 | 63 | |
| 64 | 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 | 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 | 78 | /* Update SPEC_CTRL MSR and its cached copy unconditionally */ |
| 71 | 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 | 188 | srso_select_mitigation(); |
| 181 | 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 | 1128 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); |
| 1120 | 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 | 1133 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && |
| 1125 | 1134 | boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) |
| @@ -1142,7 +1151,7 @@ do_cmd_auto: · 16 unmodified lines | ||
| 1142 | 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 | 1155 | * all predictions, including the RSB, are invalidated, |
| 1147 | 1156 | * regardless of IBPB implementation. |
| 1148 | 1157 | */ |
| @@ -1154,7 +1163,7 @@ do_cmd_auto: · 5 unmodified lines | ||
| 1154 | 1163 | setup_force_cpu_cap(X86_FEATURE_RETHUNK); |
| 1155 | 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 | 1167 | break; |
| 1159 | 1168 | |
| 1160 | 1169 | default: |
| @@ -1188,6 +1197,145 @@ do_cmd_auto: · 27 unmodified lines | ||
| 1188 | 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 | 1339 | #undef pr_fmt |
| 1192 | 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 | 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 | |
| 1599 | − * after VM exit: | |
| 1746 | + * WARNING! There are many subtleties to consider when changing *any* | |
| 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 | |
| 1606 | − * the RSB. | |
| 1754 | + * - User->user RSB attacks are conditionally mitigated during | |
| 1755 | + * context switches by cond_mitigation -> write_ibpb(). | |
| 1607 | 1756 | * |
| 1608 | − * When IBRS is enabled, while #1 would be mitigated by the IBRS branch | |
| 1609 | − * prediction isolation protections, RSB still needs to be cleared | |
| 1610 | − * because of #2. Note that SMEP provides no protection here, unlike | |
| 1611 | − * user-space-poisoned RSB entries. | |
| 1757 | + * - User->kernel and guest->host attacks are mitigated by eIBRS or | |
| 1758 | + * RSB filling. | |
| 1612 | 1759 | * |
| 1613 | − * eIBRS should protect against RSB poisoning, but if the EIBRS_PBRSB | |
| 1614 | − * bug is present then a LITE version of RSB protection is required, | |
| 1615 | − * just a single call needs to retire before a RET is executed. | |
| 1760 | + * Though, depending on config, note that other alternative | |
| 1761 | + * mitigations may end up getting used instead, e.g., IBPB on | |
| 1762 | + * entry/vmexit, call depth tracking, or return thunks. | |
| 1616 | 1763 | */ |
| 1764 | + | |
| 1617 | 1765 | switch (mode) { |
| 1618 | 1766 | case SPECTRE_V2_NONE: |
| 1619 | − return; | |
| 1767 | + break; | |
| 1620 | 1768 | |
| 1621 | − case SPECTRE_V2_EIBRS_LFENCE: | |
| 1622 | 1769 | case SPECTRE_V2_EIBRS: |
| 1770 | + case SPECTRE_V2_EIBRS_LFENCE: | |
| 1771 | + case SPECTRE_V2_EIBRS_RETPOLINE: | |
| 1623 | 1772 | if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { |
| 1624 | − setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); | |
| 1625 | 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 | 1778 | case SPECTRE_V2_RETPOLINE: |
| 1631 | 1779 | case SPECTRE_V2_LFENCE: |
| 1632 | 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 | 1783 | setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); |
| 1634 | − pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n"); | |
| 1635 | − return; | |
| 1636 | − } | |
| 1784 | + break; | |
| 1637 | 1785 | |
| 1638 | − pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit"); | |
| 1639 | − dump_stack(); | |
| 1786 | + default: | |
| 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 | 1846 | return; |
| 1696 | 1847 | } |
| 1697 | 1848 | |
| 1698 | − /* Mitigate in hardware if supported */ | |
| 1699 | − if (spec_ctrl_bhi_dis()) | |
| 1849 | + if (!IS_ENABLED(CONFIG_X86_64)) | |
| 1700 | 1850 | return; |
| 1701 | 1851 | |
| 1702 | − if (!IS_ENABLED(CONFIG_X86_64)) | |
| 1852 | + /* Mitigate in hardware if supported */ | |
| 1853 | + if (spec_ctrl_bhi_dis()) | |
| 1703 | 1854 | return; |
| 1704 | 1855 | |
| 1705 | 1856 | if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) { |
| @@ -1830,48 +1981,7 @@ static void __init spectre_v2_select_mitigation(void) · 124 unmodified lines | ||
| 1830 | 1981 | spectre_v2_enabled = mode; |
| 1831 | 1982 | pr_info("%s\n", spectre_v2_strings[mode]); |
| 1832 | 1983 | |
| 1833 | − /* | |
| 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); | |
| 1984 | + spectre_v2_select_rsb_mitigation(mode); | |
| 1875 | 1985 | |
| 1876 | 1986 | /* |
| 1877 | 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 | 2757 | if (boot_cpu_data.x86 == 0x19) { |
| 2648 | 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 | 2760 | } else { |
| 2651 | 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 | 2764 | if (has_microcode) |
| 2655 | 2765 | srso_mitigation = SRSO_MITIGATION_SAFE_RET; |
| @@ -2676,7 +2786,7 @@ static void __init srso_select_mitigation(void) · 20 unmodified lines | ||
| 2676 | 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 | 2790 | * all predictions, including the RSB, are invalidated, |
| 2681 | 2791 | * regardless of IBPB implementation. |
| 2682 | 2792 | */ |
| @@ -2701,7 +2811,7 @@ ibpb_on_vmexit: · 18 unmodified lines | ||
| 2701 | 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 | 2815 | * all predictions, including the RSB, are invalidated, |
| 2706 | 2816 | * regardless of IBPB implementation. |
| 2707 | 2817 | */ |
| @@ -2839,6 +2949,11 @@ static ssize_t rfds_show_state(char *buf) · 131 unmodified lines | ||
| 2839 | 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 | 2957 | static char *stibp_state(void) |
| 2843 | 2958 | { |
| 2844 | 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 | 3136 | case X86_BUG_RFDS: |
| 3022 | 3137 | return rfds_show_state(buf); |
| 3023 | 3138 | |
| 3139 | + case X86_BUG_ITS: | |
| 3140 | + return its_show_state(buf); | |
| 3141 | + | |
| 3024 | 3142 | default: |
| 3025 | 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 | 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 | 3226 | #endif |
| 3104 | 3227 | |
| 3105 | 3228 | void __warn_thunk(void) |
| @@ -1227,6 +1227,10 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 1226 unmodified lines | ||
| 1227 | 1227 | #define GDS BIT(6) |
| 1228 | 1228 | /* CPU is affected by Register File Data Sampling */ |
| 1229 | 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 | 1235 | static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| 1232 | 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 | 1242 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_G, X86_STEP_MAX, SRBDS), |
| 1239 | 1243 | VULNBL_INTEL_STEPS(INTEL_BROADWELL_X, X86_STEP_MAX, MMIO), |
| 1240 | 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 | 1247 | VULNBL_INTEL_STEPS(INTEL_SKYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), |
| 1243 | 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), | |
| 1245 | − VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS), | |
| 1249 | + VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, 0xb, 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 | 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), | |
| 1248 | − VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS), | |
| 1249 | − VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS), | |
| 1250 | − VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS), | |
| 1251 | − VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED), | |
| 1252 | − VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS), | |
| 1253 | − VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS), | |
| 1254 | − VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS), | |
| 1254 | + VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY), | |
| 1255 | + VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY), | |
| 1256 | + VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY), | |
| 1257 | + VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS), | |
| 1258 | + VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED | ITS), | |
| 1259 | + VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS), | |
| 1260 | + VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY), | |
| 1261 | + VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY), | |
| 1255 | 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 | 1264 | VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS), |
| 1258 | 1265 | VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS), |
| 1259 | 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 | 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 | 1354 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| 1322 | 1355 | { |
| 1323 | 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 | 1472 | if (vulnerable_to_rfds(x86_arch_cap_msr)) |
| 1440 | 1473 | setup_force_cpu_bug(X86_BUG_RFDS); |
| 1441 | 1474 | |
| 1442 | − /* When virtualized, eIBRS could be hidden, assume vulnerable */ | |
| 1443 | − if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) && | |
| 1444 | − !cpu_matches(cpu_vuln_whitelist, NO_BHI) && | |
| 1475 | + /* | |
| 1476 | + * Intel parts with eIBRS are vulnerable to BHI attacks. Parts with | |
| 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 | 1481 | (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || |
| 1446 | 1482 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1447 | 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 | 1485 | if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET)) |
| 1450 | 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 | 1494 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1453 | 1495 | return; |
| 1454 | 1496 | |
| @@ -199,6 +199,12 @@ static bool need_sha_check(u32 cur_rev) · 198 unmodified lines | ||
| 199 | 199 | case 0xa70c0: return cur_rev <= 0xa70C009; break; |
| 200 | 200 | case 0xaa001: return cur_rev <= 0xaa00116; break; |
| 201 | 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 | 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 | 220 | struct sha256_state s; |
| 215 | 221 | int i; |
| 216 | 222 | |
| 217 | − if (x86_family(bsp_cpuid_1_eax) < 0x17 || | |
| 218 | − x86_family(bsp_cpuid_1_eax) > 0x19) | |
| 223 | + if (x86_family(bsp_cpuid_1_eax) < 0x17) | |
| 219 | 224 | return true; |
| 220 | 225 | |
| 221 | 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 | 1099 | static int __init save_microcode_in_initrd(void) |
| 1095 | 1100 | { |
| 1096 | − unsigned int cpuid_1_eax = native_cpuid_eax(1); | |
| 1097 | 1101 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| 1098 | 1102 | struct cont_desc desc = { 0 }; |
| 1103 | + unsigned int cpuid_1_eax; | |
| 1099 | 1104 | enum ucode_state ret; |
| 1100 | 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 | 1108 | return 0; |
| 1104 | 1109 | |
| 1110 | + cpuid_1_eax = native_cpuid_eax(1); | |
| 1111 | + | |
| 1105 | 1112 | if (!find_blobs_in_containers(&cp)) |
| 1106 | 1113 | return -EINVAL; |
| 1107 | 1114 | |
| @@ -41,8 +41,8 @@ · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | #include "internal.h" |
| 43 | 43 | |
| 44 | −static struct microcode_ops *microcode_ops; | |
| 45 | −bool dis_ucode_ldr = true; | |
| 44 | +static struct microcode_ops *microcode_ops; | |
| 45 | +static bool dis_ucode_ldr = false; | |
| 46 | 46 | |
| 47 | 47 | bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); |
| 48 | 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 | 84 | u32 lvl, dummy, i; |
| 85 | 85 | u32 *levels; |
| 86 | 86 | |
| 87 | + if (x86_cpuid_vendor() != X86_VENDOR_AMD) | |
| 88 | + return false; | |
| 89 | + | |
| 87 | 90 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy); |
| 88 | 91 | |
| 89 | 92 | levels = final_levels; |
| @@ -95,27 +98,29 @@ static bool amd_check_current_patch_level(void) · 5 unmodified lines | ||
| 95 | 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"; | |
| 101 | − const char *cmdline = boot_command_line; | |
| 102 | − const char *option = __dis_opt_str; | |
| 103 | + if (dis_ucode_ldr) | |
| 104 | + return true; | |
| 103 | 105 | |
| 104 | 106 | /* |
| 105 | − * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not | |
| 106 | − * completely accurate as xen pv guests don't see that CPUID bit set but | |
| 107 | − * that's good enough as they don't land on the BSP path anyway. | |
| 107 | + * Disable when: | |
| 108 | + * | |
| 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)) | |
| 110 | − return true; | |
| 111 | − | |
| 112 | − if (x86_cpuid_vendor() == X86_VENDOR_AMD) { | |
| 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; | |
| 120 | + if (!have_cpuid_p() || | |
| 121 | + native_cpuid_ecx(1) & BIT(31) || | |
| 122 | + amd_check_current_patch_level()) | |
| 123 | + dis_ucode_ldr = true; | |
| 119 | 124 | |
| 120 | 125 | return dis_ucode_ldr; |
| 121 | 126 | } |
| @@ -125,7 +130,10 @@ void __init load_ucode_bsp(void) · 3 unmodified lines | ||
| 125 | 130 | unsigned int cpuid_1_eax; |
| 126 | 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 | 137 | return; |
| 130 | 138 | |
| 131 | 139 | cpuid_1_eax = native_cpuid_eax(1); |
| @@ -146,9 +154,6 @@ void __init load_ucode_bsp(void) · 14 unmodified lines | ||
| 146 | 154 | return; |
| 147 | 155 | } |
| 148 | 156 | |
| 149 | − if (check_loader_disabled_bsp()) | |
| 150 | − return; | |
| 151 | − | |
| 152 | 157 | if (intel) |
| 153 | 158 | load_ucode_intel_bsp(&early_data); |
| 154 | 159 | else |
| @@ -159,6 +164,11 @@ void load_ucode_ap(void) · 4 unmodified lines | ||
| 159 | 164 | { |
| 160 | 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 | 172 | if (dis_ucode_ldr) |
| 163 | 173 | return; |
| 164 | 174 | |
| @@ -810,7 +820,7 @@ static int __init microcode_init(void) · 645 unmodified lines | ||
| 810 | 820 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| 811 | 821 | int error; |
| 812 | 822 | |
| 813 | − if (dis_ucode_ldr) | |
| 823 | + if (microcode_loader_disabled()) | |
| 814 | 824 | return -EINVAL; |
| 815 | 825 | |
| 816 | 826 | if (c->x86_vendor == X86_VENDOR_INTEL) |
| @@ -389,7 +389,7 @@ static int __init save_builtin_microcode(void) · 388 unmodified lines | ||
| 389 | 389 | if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) |
| 390 | 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 | 393 | return 0; |
| 394 | 394 | |
| 395 | 395 | uci.mc = get_microcode_blob(&uci, true); |
| @@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_family(void) · 93 unmodified lines | ||
| 94 | 94 | return x86_family(eax); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | −extern bool dis_ucode_ldr; | |
| 98 | 97 | extern bool force_minrev; |
| 99 | 98 | |
| 100 | 99 | #ifdef CONFIG_CPU_SUP_AMD |
| @@ -3553,6 +3553,22 @@ static void mkdir_rdt_prepare_rmid_free(struct rdtgroup *rgrp) · 3552 unmodified lines | ||
| 3553 | 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 | 3572 | static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, |
| 3557 | 3573 | const char *name, umode_t mode, |
| 3558 | 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 | 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 | 3596 | if (rtype == RDTMON_GROUP && |
| 3572 | 3597 | (prdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP || |
| 3573 | 3598 | prdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)) { |
| @@ -3751,22 +3776,6 @@ out_unlock: · 177 unmodified lines | ||
| 3751 | 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 | 3779 | static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, |
| 3771 | 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 | 3791 | if (resctrl_arch_alloc_capable() && parent_kn == rdtgroup_default.kn) |
| 3783 | 3792 | return rdtgroup_mkdir_ctrl_mon(parent_kn, name, mode); |
| 3784 | 3793 | |
| 3785 | − /* | |
| 3786 | − * If RDT monitoring is supported and the parent directory is a valid | |
| 3787 | − * "mon_groups" directory, add a monitoring subdirectory. | |
| 3788 | − */ | |
| 3789 | − if (resctrl_arch_mon_capable() && is_mon_groups(parent_kn, name)) | |
| 3794 | + /* Else, attempt to add a monitoring subdirectory. */ | |
| 3795 | + if (resctrl_arch_mon_capable()) | |
| 3790 | 3796 | return rdtgroup_mkdir_mon(parent_kn, name, mode); |
| 3791 | 3797 | |
| 3792 | 3798 | return -EPERM; |
| @@ -753,22 +753,21 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len) · 752 unmodified lines | ||
| 753 | 753 | void __init e820__register_nosave_regions(unsigned long limit_pfn) |
| 754 | 754 | { |
| 755 | 755 | int i; |
| 756 | − unsigned long pfn = 0; | |
| 756 | + u64 last_addr = 0; | |
| 757 | 757 | |
| 758 | 758 | for (i = 0; i < e820_table->nr_entries; i++) { |
| 759 | 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 | 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) | |
| 770 | − break; | |
| 764 | + if (last_addr < entry->addr) | |
| 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 | 773 | #ifdef CONFIG_ACPI |
| @@ -1300,6 +1299,14 @@ void __init e820__memblock_setup(void) · 525 unmodified lines | ||
| 1300 | 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 | 1310 | /* Throw away partial pages: */ |
| 1304 | 1311 | memblock_trim_memory(PAGE_SIZE); |
| 1305 | 1312 | |
| @@ -389,10 +389,10 @@ static int __init setup_early_printk(char *buf) · 388 unmodified lines | ||
| 389 | 389 | keep = (strstr(buf, "keep") != NULL); |
| 390 | 390 | |
| 391 | 391 | while (*buf != '\0') { |
| 392 | − if (!strncmp(buf, "mmio", 4)) { | |
| 393 | − early_mmio_serial_init(buf + 4); | |
| 392 | + if (!strncmp(buf, "mmio32", 6)) { | |
| 393 | + buf += 6; | |
| 394 | + early_mmio_serial_init(buf); | |
| 394 | 395 | early_console_register(&early_serial_console, keep); |
| 395 | − buf += 4; | |
| 396 | 396 | } |
| 397 | 397 | if (!strncmp(buf, "serial", 6)) { |
| 398 | 398 | buf += 6; |
| @@ -407,9 +407,9 @@ static int __init setup_early_printk(char *buf) · 8 unmodified lines | ||
| 407 | 407 | } |
| 408 | 408 | #ifdef CONFIG_PCI |
| 409 | 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 | 412 | early_console_register(&early_serial_console, keep); |
| 412 | − buf += 9; /* Keep from match the above "serial" */ | |
| 413 | 413 | } |
| 414 | 414 | #endif |
| 415 | 415 | if (!strncmp(buf, "vga", 3) && |
| @@ -354,7 +354,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 353 unmodified lines | ||
| 354 | 354 | goto fail; |
| 355 | 355 | |
| 356 | 356 | ip = trampoline + size; |
| 357 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | |
| 357 | + if (cpu_wants_rethunk_at(ip)) | |
| 358 | 358 | __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE); |
| 359 | 359 | else |
| 360 | 360 | memcpy(ip, retq, sizeof(retq)); |
| @@ -145,10 +145,6 @@ void __init __no_stack_protector mk_early_pgtbl_32(void) · 144 unmodified lines | ||
| 145 | 145 | *ptr = (unsigned long)ptep + PAGE_OFFSET; |
| 146 | 146 | |
| 147 | 147 | #ifdef CONFIG_MICROCODE_INITRD32 |
| 148 | − /* Running on a hypervisor? */ | |
| 149 | − if (native_cpuid_ecx(1) & BIT(31)) | |
| 150 | − return; | |
| 151 | − | |
| 152 | 148 | params = (struct boot_params *)__pa_nodebug(&boot_params); |
| 153 | 149 | if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image) |
| 154 | 150 | return; |
| @@ -46,7 +46,8 @@ bool __init pit_timer_init(void) · 45 unmodified lines | ||
| 46 | 46 | * VMMs otherwise steal CPU time just to pointlessly waggle |
| 47 | 47 | * the (masked) IRQ. |
| 48 | 48 | */ |
| 49 | − clockevent_i8253_disable(); | |
| 49 | + scoped_guard(irq) | |
| 50 | + clockevent_i8253_disable(); | |
| 50 | 51 | return false; |
| 51 | 52 | } |
| 52 | 53 | clockevent_i8253_init(true); |
| @@ -42,7 +42,7 @@ static void load_segments(void) · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 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 | 46 | image->arch.pgd = NULL; |
| 47 | 47 | #ifdef CONFIG_X86_PAE |
| 48 | 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 | 59 | static int machine_kexec_alloc_page_tables(struct kimage *image) |
| 60 | 60 | { |
| 61 | 61 | image->arch.pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, |
| 62 | − PGD_ALLOCATION_ORDER); | |
| 62 | + pgd_allocation_order()); | |
| 63 | 63 | #ifdef CONFIG_X86_PAE |
| 64 | 64 | image->arch.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); |
| 65 | 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 | 266 | ibt_endbr = s; |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | + its_init_mod(me); | |
| 270 | + | |
| 269 | 271 | if (retpolines || cfi) { |
| 270 | 272 | void *rseg = NULL, *cseg = NULL; |
| 271 | 273 | unsigned int rsize = 0, csize = 0; |
| @@ -286,6 +288,9 @@ int module_finalize(const Elf_Ehdr *hdr, · 14 unmodified lines | ||
| 286 | 288 | void *rseg = (void *)retpolines->sh_addr; |
| 287 | 289 | apply_retpolines(rseg, rseg + retpolines->sh_size); |
| 288 | 290 | } |
| 291 | + | |
| 292 | + its_fini_mod(me); | |
| 293 | + | |
| 289 | 294 | if (returns) { |
| 290 | 295 | void *rseg = (void *)returns->sh_addr; |
| 291 | 296 | apply_returns(rseg, rseg + returns->sh_size); |
| @@ -326,4 +331,5 @@ int module_finalize(const Elf_Ehdr *hdr, · 34 unmodified lines | ||
| 326 | 331 | void module_arch_cleanup(struct module *mod) |
| 327 | 332 | { |
| 328 | 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 | 81 | break; |
| 82 | 82 | |
| 83 | 83 | case RET: |
| 84 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | |
| 84 | + if (cpu_wants_rethunk_at(insn)) | |
| 85 | 85 | code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk); |
| 86 | 86 | else |
| 87 | 87 | code = &retinsn; |
| @@ -90,7 +90,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, · 2 unmodified lines | ||
| 90 | 90 | case JCC: |
| 91 | 91 | if (!func) { |
| 92 | 92 | func = __static_call_return; |
| 93 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) | |
| 93 | + if (cpu_wants_rethunk()) | |
| 94 | 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 | 478 | . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), |
| 472 | 479 | "kernel image bigger than KERNEL_IMAGE_SIZE"); |
| 480 | +#endif | |
| 473 | 481 | |
| 474 | 482 | /* needed for Clang - see arch/x86/entry/entry.S */ |
| 475 | 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 | 505 | "SRSO function pair won't alias"); |
| 498 | 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 | 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 | 1428 | break; |
| 1429 | 1429 | case 0xa: { /* Architectural Performance Monitoring */ |
| 1430 | − union cpuid10_eax eax; | |
| 1431 | − union cpuid10_edx edx; | |
| 1430 | + union cpuid10_eax eax = { }; | |
| 1431 | + union cpuid10_edx edx = { }; | |
| 1432 | 1432 | |
| 1433 | 1433 | if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) { |
| 1434 | 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 | 1445 | if (kvm_pmu_cap.version) |
| 1446 | 1446 | edx.split.anythread_deprecated = 1; |
| 1447 | − edx.split.reserved1 = 0; | |
| 1448 | − edx.split.reserved2 = 0; | |
| 1449 | 1447 | |
| 1450 | 1448 | entry->eax = eax.full; |
| 1451 | 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 | 1761 | break; |
| 1764 | 1762 | /* AMD Extended Performance Monitoring and Debug */ |
| 1765 | 1763 | case 0x80000022: { |
| 1766 | − union cpuid_0x80000022_ebx ebx; | |
| 1764 | + union cpuid_0x80000022_ebx ebx = { }; | |
| 1767 | 1765 | |
| 1768 | 1766 | entry->ecx = entry->edx = 0; |
| 1769 | 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 | 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 | 111 | * Checking root.hpa is sufficient even when KVM has mirror root. |
| 109 | 112 | * We can have either: |
| @@ -5974,6 +5974,7 @@ void kvm_mmu_free_obsolete_roots(struct kvm_vcpu *vcpu) · 5973 unmodified lines | ||
| 5974 | 5974 | __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.root_mmu); |
| 5975 | 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 | 5979 | static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, |
| 5979 | 5980 | int *bytes) |
| @@ -7669,9 +7670,30 @@ void kvm_mmu_pre_destroy_vm(struct kvm *kvm) · 1689 unmodified lines | ||
| 7669 | 7670 | } |
| 7670 | 7671 | |
| 7671 | 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 | 7691 | bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, |
| 7673 | 7692 | struct kvm_gfn_range *range) |
| 7674 | 7693 | { |
| 7694 | + struct kvm_memory_slot *slot = range->slot; | |
| 7695 | + int level; | |
| 7696 | + | |
| 7675 | 7697 | /* |
| 7676 | 7698 | * Zap SPTEs even if the slot can't be mapped PRIVATE. KVM x86 only |
| 7677 | 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 | 7708 | if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) |
| 7687 | 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 | 7743 | /* Unmap the old attribute page. */ |
| 7690 | 7744 | if (range->arg.attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE) |
| 7691 | 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 | 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 | 7754 | static bool hugepage_has_attrs(struct kvm *kvm, struct kvm_memory_slot *slot, |
| 7717 | 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 | 40 | kvm_tdp_mmu_invalidate_roots(kvm, KVM_VALID_ROOTS); |
| 41 | 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 | 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 | 327 | static void tdp_account_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 326 | 328 | { |
| 327 | 329 | kvm_account_pgtable_pages((void *)sp->spt, +1); |
| 330 | +#ifdef CONFIG_KVM_PROVE_MMU | |
| 328 | 331 | atomic64_inc(&kvm->arch.tdp_mmu_pages); |
| 332 | +#endif | |
| 329 | 333 | } |
| 330 | 334 | |
| 331 | 335 | static void tdp_unaccount_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 332 | 336 | { |
| 333 | 337 | kvm_account_pgtable_pages((void *)sp->spt, -1); |
| 338 | +#ifdef CONFIG_KVM_PROVE_MMU | |
| 334 | 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 | 132 | kvm_mmu_reset_context(vcpu); |
| 133 | 133 | } |
| 134 | +EXPORT_SYMBOL_GPL(kvm_smm_changed); | |
| 134 | 135 | |
| 135 | 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 | 796 | struct amd_svm_iommu_ir *ir; |
| 797 | 797 | u64 entry; |
| 798 | 798 | |
| 799 | + if (WARN_ON_ONCE(!pi->ir_data)) | |
| 800 | + return -EINVAL; | |
| 801 | + | |
| 799 | 802 | /** |
| 800 | 803 | * In some cases, the existing irte is updated and re-set, |
| 801 | 804 | * so we need to check here if it's already been * added |
| 802 | 805 | * to the ir_list. |
| 803 | 806 | */ |
| 804 | − if (pi->ir_data && (pi->prev_ga_tag != 0)) { | |
| 807 | + if (pi->prev_ga_tag) { | |
| 805 | 808 | struct kvm *kvm = svm->vcpu.kvm; |
| 806 | 809 | u32 vcpu_id = AVIC_GATAG_TO_VCPUID(pi->prev_ga_tag); |
| 807 | 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 | 823 | * Allocating new amd_iommu_pi_data, which will get |
| 821 | 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 | 827 | if (!ir) { |
| 825 | 828 | ret = -ENOMEM; |
| 826 | 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 | 900 | struct kvm_kernel_irq_routing_entry *e; |
| 898 | 901 | struct kvm_irq_routing_table *irq_rt; |
| 902 | + bool enable_remapped_mode = true; | |
| 899 | 903 | int idx, ret = 0; |
| 900 | 904 | |
| 901 | − if (!kvm_arch_has_assigned_device(kvm) || | |
| 902 | − !irq_remapping_cap(IRQ_POSTING_CAP)) | |
| 905 | + if (!kvm_arch_has_assigned_device(kvm) || !kvm_arch_has_irq_bypass()) | |
| 903 | 906 | return 0; |
| 904 | 907 | |
| 905 | 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 | 936 | kvm_vcpu_apicv_active(&svm->vcpu)) { |
| 934 | 937 | struct amd_iommu_pi_data pi; |
| 935 | 938 | |
| 939 | + enable_remapped_mode = false; | |
| 940 | + | |
| 936 | 941 | /* Try to enable guest_mode in IRTE */ |
| 937 | 942 | pi.base = __sme_set(page_to_phys(svm->avic_backing_page) & |
| 938 | 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 | 957 | if (!ret && pi.is_guest_mode) |
| 953 | 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 | 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 | 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 | 1002 | out: |
| 997 | 1003 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 998 | 1004 | return ret; |
| @@ -3173,9 +3173,14 @@ skip_vmsa_free: · 3172 unmodified lines | ||
| 3173 | 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 | 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 | 3184 | unsigned int nbits; |
| 3180 | 3185 | |
| 3181 | 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 | 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 | 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 | 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 | 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 | 3207 | pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch", |
| 3197 | − ghcb->save.sw_scratch, ghcb_sw_scratch_is_valid(ghcb)); | |
| 3198 | − pr_err("%-20s%*pb\n", "valid_bitmap", nbits, ghcb->save.valid_bitmap); | |
| 3208 | + svm->sev_es.sw_scratch, kvm_ghcb_sw_scratch_is_valid(svm)); | |
| 3209 | + pr_err("%-20s%*pb\n", "valid_bitmap", nbits, svm->sev_es.valid_bitmap); | |
| 3199 | 3210 | } |
| 3200 | 3211 | |
| 3201 | 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 | 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 | 3280 | static int sev_es_validate_vmgexit(struct vcpu_svm *svm) |
| 3275 | 3281 | { |
| 3276 | 3282 | struct vmcb_control_area *control = &svm->vmcb->control; |
| @@ -607,9 +607,6 @@ static void svm_disable_virtualization_cpu(void) · 606 unmodified lines | ||
| 607 | 607 | kvm_cpu_svm_disable(); |
| 608 | 608 | |
| 609 | 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 | 612 | static int svm_enable_virtualization_cpu(void) |
| @@ -687,9 +684,6 @@ static int svm_enable_virtualization_cpu(void) · 71 unmodified lines | ||
| 687 | 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 | 687 | return 0; |
| 694 | 688 | } |
| 695 | 689 | |
| @@ -1518,6 +1512,63 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 822 unmodified lines | ||
| 1518 | 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 | 1572 | static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) |
| 1522 | 1573 | { |
| 1523 | 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 | 1601 | (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm))) |
| 1551 | 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 | 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 | 2288 | if (!sev_es_guest(vcpu->kvm)) { |
| 2233 | 2289 | clear_page(svm->vmcb); |
| 2290 | +#ifdef CONFIG_KVM_SMM | |
| 2291 | + if (is_smm(vcpu)) | |
| 2292 | + kvm_smm_changed(vcpu, false); | |
| 2293 | +#endif | |
| 2234 | 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 | 5097 | avic_vm_destroy(kvm); |
| 5038 | 5098 | sev_vm_destroy(kvm); |
| 5099 | + | |
| 5100 | + svm_srso_vm_destroy(); | |
| 5039 | 5101 | } |
| 5040 | 5102 | |
| 5041 | 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 | 5123 | return ret; |
| 5062 | 5124 | } |
| 5063 | 5125 | |
| 5126 | + svm_srso_vm_init(); | |
| 5064 | 5127 | return 0; |
| 5065 | 5128 | } |
| 5066 | 5129 | |
| @@ -335,6 +335,8 @@ struct svm_cpu_data { · 334 unmodified lines | ||
| 335 | 335 | u32 next_asid; |
| 336 | 336 | u32 min_asid; |
| 337 | 337 | |
| 338 | + bool bp_spec_reduce_set; | |
| 339 | + | |
| 338 | 340 | struct vmcb *save_area; |
| 339 | 341 | unsigned long save_area_pa; |
| 340 | 342 | |
| @@ -11,6 +11,13 @@ · 10 unmodified lines | ||
| 11 | 11 | #undef TRACE_SYSTEM |
| 12 | 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 | 22 | * Tracepoint for guest mode entry. |
| 16 | 23 | */ |
| @@ -28,7 +35,7 @@ TRACE_EVENT(kvm_entry, · 11 unmodified lines | ||
| 28 | 35 | |
| 29 | 36 | TP_fast_assign( |
| 30 | 37 | __entry->vcpu_id = vcpu->vcpu_id; |
| 31 | − __entry->rip = kvm_rip_read(vcpu); | |
| 38 | + __entry->rip = tracing_kvm_rip_read(vcpu); | |
| 32 | 39 | __entry->immediate_exit = force_immediate_exit; |
| 33 | 40 | |
| 34 | 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 | 328 | TP_fast_assign( \ |
| 322 | − __entry->guest_rip = kvm_rip_read(vcpu); \ | |
| 329 | + __entry->guest_rip = tracing_kvm_rip_read(vcpu); \ | |
| 323 | 330 | __entry->isa = isa; \ |
| 324 | 331 | __entry->vcpu_id = vcpu->vcpu_id; \ |
| 325 | 332 | __entry->requests = READ_ONCE(vcpu->requests); \ |
| @@ -423,7 +430,7 @@ TRACE_EVENT(kvm_page_fault, · 97 unmodified lines | ||
| 423 | 430 | |
| 424 | 431 | TP_fast_assign( |
| 425 | 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 | 434 | __entry->fault_address = fault_address; |
| 428 | 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 | 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 | 36 | static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) |
| 35 | 37 | { |
| 36 | 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 | 91 | * current pCPU if the task was migrated. |
| 90 | 92 | */ |
| 91 | 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 | 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 | 110 | dest = cpu_physical_id(cpu); |
| @@ -148,11 +161,23 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) · 50 unmodified lines | ||
| 148 | 161 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 149 | 162 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 150 | 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 | 181 | list_add_tail(&vmx->pi_wakeup_list, |
| 157 | 182 | &per_cpu(wakeup_vcpus_on_cpu, vcpu->cpu)); |
| 158 | 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 | 202 | if (pi_test_on(&new)) |
| 178 | 203 | __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR); |
| 179 | − | |
| 180 | − local_irq_restore(flags); | |
| 181 | 204 | } |
| 182 | 205 | |
| 183 | 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 | 298 | struct kvm_kernel_irq_routing_entry *e; |
| 276 | 299 | struct kvm_irq_routing_table *irq_rt; |
| 300 | + bool enable_remapped_mode = true; | |
| 277 | 301 | struct kvm_lapic_irq irq; |
| 278 | 302 | struct kvm_vcpu *vcpu; |
| 279 | 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 | 337 | kvm_set_msi_irq(kvm, e, &irq); |
| 314 | 338 | if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || |
| 315 | − !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 | − | |
| 339 | + !kvm_irq_is_postable(&irq)) | |
| 328 | 340 | continue; |
| 329 | − } | |
| 330 | 341 | |
| 331 | 342 | vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); |
| 332 | 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 | 345 | trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, |
| 335 | 346 | vcpu_info.vector, vcpu_info.pi_desc_addr, set); |
| 336 | 347 | |
| 337 | − if (set) | |
| 338 | − ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); | |
| 339 | − else | |
| 340 | − ret = irq_set_vcpu_affinity(host_irq, NULL); | |
| 348 | + if (!set) | |
| 349 | + continue; | |
| 350 | + | |
| 351 | + enable_remapped_mode = false; | |
| 341 | 352 | |
| 353 | + ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); | |
| 342 | 354 | if (ret < 0) { |
| 343 | 355 | printk(KERN_INFO "%s: failed to update PI IRTE\n", |
| 344 | 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 | 364 | ret = 0; |
| 350 | 365 | out: |
| 351 | 366 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| @@ -1584,7 +1584,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc); · 1583 unmodified lines | ||
| 1584 | 1584 | ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ |
| 1585 | 1585 | ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ |
| 1586 | 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 | 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 | 1618 | data |= ARCH_CAP_MDS_NO; |
| 1619 | 1619 | if (!boot_cpu_has_bug(X86_BUG_RFDS)) |
| 1620 | 1620 | data |= ARCH_CAP_RFDS_NO; |
| 1621 | + if (!boot_cpu_has_bug(X86_BUG_ITS)) | |
| 1622 | + data |= ARCH_CAP_ITS_NO; | |
| 1621 | 1623 | |
| 1622 | 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 | 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 | 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 | 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 | 11105 | unsigned long rip = kvm_rip_read(vcpu); |
| 11103 | 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 | 11496 | struct kvm_queued_exception *ex = &vcpu->arch.exception; |
| 11494 | 11497 | struct kvm_run *kvm_run = vcpu->run; |
| 11495 | − u32 sync_valid_fields; | |
| 11498 | + u64 sync_valid_fields; | |
| 11496 | 11499 | int r; |
| 11497 | 11500 | |
| 11498 | 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 | 11789 | if (kvm_mpx_supported()) |
| 11787 | 11790 | kvm_load_guest_fpu(vcpu); |
| 11788 | 11791 | |
| 11792 | + kvm_vcpu_srcu_read_lock(vcpu); | |
| 11793 | + | |
| 11789 | 11794 | r = kvm_apic_accept_events(vcpu); |
| 11790 | 11795 | if (r < 0) |
| 11791 | 11796 | goto out; |
| @@ -11799,6 +11804,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 7 unmodified lines | ||
| 11799 | 11804 | mp_state->mp_state = vcpu->arch.mp_state; |
| 11800 | 11805 | |
| 11801 | 11806 | out: |
| 11807 | + kvm_vcpu_srcu_read_unlock(vcpu); | |
| 11808 | + | |
| 11802 | 11809 | if (kvm_mpx_supported()) |
| 11803 | 11810 | kvm_put_guest_fpu(vcpu); |
| 11804 | 11811 | vcpu_put(vcpu); |
| @@ -13552,25 +13559,27 @@ bool kvm_arch_has_noncoherent_dma(struct kvm *kvm) · 1747 unmodified lines | ||
| 13552 | 13559 | } |
| 13553 | 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 | 13562 | int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons, |
| 13561 | 13563 | struct irq_bypass_producer *prod) |
| 13562 | 13564 | { |
| 13563 | 13565 | struct kvm_kernel_irqfd *irqfd = |
| 13564 | 13566 | container_of(cons, struct kvm_kernel_irqfd, consumer); |
| 13567 | + struct kvm *kvm = irqfd->kvm; | |
| 13565 | 13568 | int ret; |
| 13566 | 13569 | |
| 13567 | − irqfd->producer = prod; | |
| 13568 | 13570 | kvm_arch_start_assignment(irqfd->kvm); |
| 13571 | + | |
| 13572 | + spin_lock_irq(&kvm->irqfds.lock); | |
| 13573 | + irqfd->producer = prod; | |
| 13574 | + | |
| 13569 | 13575 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, |
| 13570 | 13576 | prod->irq, irqfd->gsi, 1); |
| 13571 | 13577 | if (ret) |
| 13572 | 13578 | kvm_arch_end_assignment(irqfd->kvm); |
| 13573 | 13579 | |
| 13580 | + spin_unlock_irq(&kvm->irqfds.lock); | |
| 13581 | + | |
| 13582 | + | |
| 13574 | 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 | 13589 | int ret; |
| 13581 | 13590 | struct kvm_kernel_irqfd *irqfd = |
| 13582 | 13591 | container_of(cons, struct kvm_kernel_irqfd, consumer); |
| 13592 | + struct kvm *kvm = irqfd->kvm; | |
| 13583 | 13593 | |
| 13584 | 13594 | WARN_ON(irqfd->producer != prod); |
| 13585 | − irqfd->producer = NULL; | |
| 13586 | 13595 | |
| 13587 | 13596 | /* |
| 13588 | 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 | 13599 | * when the irq is masked/disabled or the consumer side (KVM |
| 13591 | 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 | 13605 | ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, |
| 13594 | 13606 | prod->irq, irqfd->gsi, 0); |
| 13595 | 13607 | if (ret) |
| 13596 | 13608 | printk(KERN_INFO "irq bypass consumer (token %p) unregistration" |
| 13597 | 13609 | " fails: %d\n", irqfd->consumer.token, ret); |
| 13598 | 13610 | |
| 13611 | + spin_unlock_irq(&kvm->irqfds.lock); | |
| 13612 | + | |
| 13613 | + | |
| 13599 | 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 | 13623 | bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old, |
| 13609 | 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 | 13628 | return true; |
| 13613 | 13629 | |
| 13614 | 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 | 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 | 419 | * This function name is magical and is used by -mfunction-return=thunk-extern |
| 372 | 420 | * for the compiler to generate JMPs to it. |
| @@ -996,8 +996,8 @@ AVXcode: 4 · 995 unmodified lines | ||
| 996 | 996 | 83: Grp1 Ev,Ib (1A),(es) |
| 997 | 997 | # CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, |
| 998 | 998 | # CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ |
| 999 | −84: CTESTSCC (ev) | |
| 1000 | −85: CTESTSCC (es) | CTESTSCC (66),(es) | |
| 999 | +84: CTESTSCC Eb,Gb (ev) | |
| 1000 | +85: CTESTSCC Ev,Gv (es) | CTESTSCC Ev,Gv (66),(es) | |
| 1001 | 1001 | 88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) |
| 1002 | 1002 | 8f: POP2 Bq,Rq (000),(11B),(ev) |
| 1003 | 1003 | a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <linux/initrd.h> |
| 31 | 31 | #include <linux/cpumask.h> |
| 32 | 32 | #include <linux/gfp.h> |
| 33 | +#include <linux/execmem.h> | |
| 33 | 34 | |
| 34 | 35 | #include <asm/asm.h> |
| 35 | 36 | #include <asm/bios_ebda.h> |
| @@ -565,7 +566,7 @@ static void __init lowmem_pfn_init(void) · 529 unmodified lines | ||
| 565 | 566 | "only %luMB highmem pages available, ignoring highmem size of %luMB!\n" |
| 566 | 567 | |
| 567 | 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 | 571 | * We have more RAM than fits into lowmem - we try to put it into |
| 571 | 572 | * highmem, also taking the highmem=x boot parameter into account: |
| @@ -755,6 +756,8 @@ void mark_rodata_ro(void) · 183 unmodified lines | ||
| 755 | 756 | pr_info("Write protecting kernel text and read-only data: %luk\n", |
| 756 | 757 | size >> 10); |
| 757 | 758 | |
| 759 | + execmem_cache_make_ro(); | |
| 760 | + | |
| 758 | 761 | kernel_set_to_readonly = 1; |
| 759 | 762 | |
| 760 | 763 | #ifdef CONFIG_CPA_DEBUG |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/gfp.h> |
| 35 | 35 | #include <linux/kcore.h> |
| 36 | 36 | #include <linux/bootmem_info.h> |
| 37 | +#include <linux/execmem.h> | |
| 37 | 38 | |
| 38 | 39 | #include <asm/processor.h> |
| 39 | 40 | #include <asm/bios_ebda.h> |
| @@ -1391,6 +1392,8 @@ void mark_rodata_ro(void) · 1351 unmodified lines | ||
| 1391 | 1392 | (end - start) >> 10); |
| 1392 | 1393 | set_memory_ro(start, (end - start) >> PAGE_SHIFT); |
| 1393 | 1394 | |
| 1395 | + execmem_cache_make_ro(); | |
| 1396 | + | |
| 1394 | 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 | 360 | * We allocate one page for pgd. |
| 361 | 361 | */ |
| 362 | 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 | 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 | 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 | 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 | 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 | |
| 671 | − * when switching between processes. This stops one process from | |
| 672 | − * doing Spectre-v2 attacks on another. | |
| 670 | + * Avoid user->user BTB/RSB poisoning by flushing them when switching | |
| 671 | + * between processes. This stops one process from doing Spectre-v2 | |
| 672 | + * attacks on another. | |
| 673 | 673 | * |
| 674 | 674 | * Both, the conditional and the always IBPB mode use the mm |
| 675 | 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 | 899 | cond_mitigation(tsk); |
| 900 | 900 | |
| 901 | 901 | /* |
| 902 | − * Let nmi_uaccess_okay() and finish_asid_transition() | |
| 903 | − * know that CR3 is changing. | |
| 902 | + * Indicate that CR3 is about to change. nmi_uaccess_okay() | |
| 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 | 906 | this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING); |
| 906 | 907 | barrier(); |
| @@ -1204,8 +1205,16 @@ done: · 297 unmodified lines | ||
| 1204 | 1205 | |
| 1205 | 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 | 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 | 1218 | /* Lazy TLB will get flushed at the next context switch. */ |
| 1210 | 1219 | if (per_cpu(cpu_tlbstate_shared.is_lazy, cpu)) |
| 1211 | 1220 | return false; |
| @@ -1214,8 +1223,15 @@ static bool should_flush_tlb(int cpu, void *data) · 2 unmodified lines | ||
| 1214 | 1223 | if (!info->mm) |
| 1215 | 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 | 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 | 1235 | return true; |
| 1220 | 1236 | |
| 1221 | 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 | 41 | #define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2) |
| 42 | 42 | #define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3) |
| 43 | 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 | 47 | #define EMIT1_off32(b1, off) \ |
| 46 | 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 | 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 | 670 | EMIT_LFENCE(); |
| 666 | 671 | EMIT2(0xFF, 0xE0 + reg); |
| 667 | 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 | 689 | u8 *prog = *pprog; |
| 685 | 690 | |
| 686 | − if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { | |
| 691 | + if (cpu_wants_rethunk()) { | |
| 687 | 692 | emit_jump(&prog, x86_return_thunk, ip); |
| 688 | 693 | } else { |
| 689 | 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 | 1507 | #define PRIV_STACK_GUARD_SZ 8 |
| 1503 | 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 | 1552 | static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, |
| 1506 | 1553 | int oldproglen, struct jit_context *ctx, bool jmp_padding) |
| 1507 | 1554 | { |
| @@ -2544,6 +2591,13 @@ emit_jmp: · 1036 unmodified lines | ||
| 2544 | 2591 | seen_exit = true; |
| 2545 | 2592 | /* Update cleanup_addr */ |
| 2546 | 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 | 2601 | if (bpf_prog->aux->exception_boundary) { |
| 2548 | 2602 | pop_callee_regs(&prog, all_callee_regs_used); |
| 2549 | 2603 | pop_r12(&prog); |
| @@ -73,7 +73,7 @@ int __init efi_alloc_page_tables(void) · 72 unmodified lines | ||
| 73 | 73 | gfp_t gfp_mask; |
| 74 | 74 | |
| 75 | 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 | 77 | if (!efi_pgd) |
| 78 | 78 | goto fail; |
| 79 | 79 | |
| @@ -96,7 +96,7 @@ free_p4d: · 16 unmodified lines | ||
| 96 | 96 | if (pgtable_l5_enabled()) |
| 97 | 97 | free_page((unsigned long)pgd_page_vaddr(*pgd)); |
| 98 | 98 | free_pgd: |
| 99 | − free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); | |
| 99 | + free_pages((unsigned long)efi_pgd, pgd_allocation_order()); | |
| 100 | 100 | fail: |
| 101 | 101 | return -ENOMEM; |
| 102 | 102 | } |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | /* code below belongs to the image kernel */ |
| 27 | 27 | .align PAGE_SIZE |
| 28 | 28 | SYM_FUNC_START(restore_registers) |
| 29 | − ANNOTATE_NOENDBR | |
| 29 | + ENDBR | |
| 30 | 30 | /* go back to the original page tables */ |
| 31 | 31 | movq %r9, %cr3 |
| 32 | 32 | |
| @@ -120,7 +120,7 @@ SYM_FUNC_END(restore_image) · 87 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | /* code below has been relocated to a safe page */ |
| 122 | 122 | SYM_FUNC_START(core_restore_code) |
| 123 | − ANNOTATE_NOENDBR | |
| 123 | + ENDBR | |
| 124 | 124 | /* switch to temporary page tables */ |
| 125 | 125 | movq %rax, %cr3 |
| 126 | 126 | /* flush TLB */ |
| @@ -31,8 +31,8 @@ struct faultinfo { · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #define ___backtrack_faulted(_faulted) \ |
| 33 | 33 | asm volatile ( \ |
| 34 | − "mov $0, %0\n" \ | |
| 35 | 34 | "movl $__get_kernel_nofault_faulted_%=,%1\n" \ |
| 35 | + "mov $0, %0\n" \ | |
| 36 | 36 | "jmp _end_%=\n" \ |
| 37 | 37 | "__get_kernel_nofault_faulted_%=:\n" \ |
| 38 | 38 | "mov $1, %0;" \ |
| @@ -31,8 +31,8 @@ struct faultinfo { · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #define ___backtrack_faulted(_faulted) \ |
| 33 | 33 | asm volatile ( \ |
| 34 | − "mov $0, %0\n" \ | |
| 35 | 34 | "movq $__get_kernel_nofault_faulted_%=,%1\n" \ |
| 35 | + "mov $0, %0\n" \ | |
| 36 | 36 | "jmp _end_%=\n" \ |
| 37 | 37 | "__get_kernel_nofault_faulted_%=:\n" \ |
| 38 | 38 | "mov $1, %0;" \ |
| @@ -70,6 +70,9 @@ EXPORT_SYMBOL(xen_start_flags); · 69 unmodified lines | ||
| 70 | 70 | */ |
| 71 | 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 | 76 | static __ref void xen_get_vendor(void) |
| 74 | 77 | { |
| 75 | 78 | init_cpu_devs(); |
| @@ -100,10 +103,6 @@ noinstr void *__xen_hypercall_setfunc(void) · 24 unmodified lines | ||
| 100 | 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 | 106 | * Note that __xen_hypercall_setfunc() is noinstr only due to a nasty |
| 108 | 107 | * dependency chain: it is being called via the xen_hypercall static |
| 109 | 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 | 115 | instrumentation_begin(); |
| 117 | 116 | |
| 118 | − if (!boot_cpu_has(X86_FEATURE_CPUID)) | |
| 119 | − xen_get_vendor(); | |
| 117 | + xen_get_vendor(); | |
| 120 | 118 | |
| 121 | 119 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD || |
| 122 | 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 | 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 | 474 | /* Zero so region is not also added to the balloon driver. */ |
| 470 | 475 | xen_extra_mem[i].n_pfns = 0; |
| 471 | 476 | } |
| @@ -1,5 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/acpi.h> |
| 3 | +#include <linux/cpufreq.h> | |
| 4 | +#include <linux/cpuidle.h> | |
| 3 | 5 | #include <linux/export.h> |
| 4 | 6 | #include <linux/mm.h> |
| 5 | 7 | |
| @@ -123,8 +125,23 @@ static void __init pvh_arch_setup(void) · 117 unmodified lines | ||
| 123 | 125 | { |
| 124 | 126 | pvh_reserve_extra_memory(); |
| 125 | 127 | |
| 126 | − if (xen_initial_domain()) | |
| 128 | + if (xen_initial_domain()) { | |
| 127 | 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 | 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 | 55 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); |
| 56 | 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 | 57 | static struct mc_debug_data __percpu *mc_debug_data_ptr; |
| 60 | 58 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); |
| 61 | 59 | |
| 62 | 60 | static struct static_key mc_debug __ro_after_init; |
| 63 | 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 | 71 | static int __init xen_parse_mc_debug(char *arg) |
| 66 | 72 | { |
| 67 | 73 | mc_debug_enabled = true; |
| @@ -71,20 +77,16 @@ static int __init xen_parse_mc_debug(char *arg) · 3 unmodified lines | ||
| 71 | 77 | } |
| 72 | 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 | 80 | static int __init mc_debug_enable(void) |
| 80 | 81 | { |
| 81 | 82 | unsigned long flags; |
| 83 | + struct mc_debug_data __percpu *mcdb; | |
| 82 | 84 | |
| 83 | 85 | if (!mc_debug_enabled) |
| 84 | 86 | return 0; |
| 85 | 87 | |
| 86 | − mc_debug_data_ptr = alloc_percpu(struct mc_debug_data); | |
| 87 | − if (!mc_debug_data_ptr) { | |
| 88 | + mcdb = alloc_percpu(struct mc_debug_data); | |
| 89 | + if (!mcdb) { | |
| 88 | 90 | pr_err("xen_mc_debug inactive\n"); |
| 89 | 91 | static_key_slow_dec(&mc_debug); |
| 90 | 92 | return -ENOMEM; |
| @@ -93,7 +95,7 @@ static int __init mc_debug_enable(void) · 2 unmodified lines | ||
| 93 | 95 | /* Be careful when switching to percpu debug data. */ |
| 94 | 96 | local_irq_save(flags); |
| 95 | 97 | xen_mc_flush(); |
| 96 | − mc_percpu_init(0); | |
| 98 | + mc_debug_data_ptr = mcdb; | |
| 97 | 99 | local_irq_restore(flags); |
| 98 | 100 | |
| 99 | 101 | pr_info("xen_mc_debug active\n"); |
| @@ -155,7 +157,7 @@ void xen_mc_flush(void) · 55 unmodified lines | ||
| 155 | 157 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); |
| 156 | 158 | |
| 157 | 159 | if (static_key_false(&mc_debug)) { |
| 158 | − mcdb = __this_cpu_read(mc_debug_data); | |
| 160 | + mcdb = get_mc_debug(); | |
| 159 | 161 | memcpy(mcdb->entries, b->entries, |
| 160 | 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 | 238 | ret.mc = &b->entries[b->mcidx]; |
| 237 | 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 | 242 | mcdb->caller[b->mcidx] = __builtin_return_address(0); |
| 241 | 243 | mcdb->argsz[b->mcidx] = args; |
| @@ -37,9 +37,6 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 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 | 40 | /* Memory map would allow PCI passthrough. */ |
| 44 | 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 | 305 | return rc; |
| 306 | 306 | |
| 307 | 307 | xen_pmu_init(cpu); |
| 308 | − mc_percpu_init(cpu); | |
| 309 | 308 | |
| 310 | 309 | /* |
| 311 | 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 | 226 | push %rax |
| 227 | 227 | mov $__HYPERVISOR_iret, %eax |
| 228 | 228 | syscall /* Do the IRET. */ |
| 229 | −#ifdef CONFIG_MITIGATION_SLS | |
| 230 | − int3 | |
| 231 | −#endif | |
| 229 | + ud2 /* The SYSCALL should never return. */ | |
| 232 | 230 | .endm |
| 233 | 231 | |
| 234 | 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 | 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 | 264 | extern bool is_xen_pmu; |
| 268 | 265 | |
| 269 | 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 | 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; | |
| 158 | − struct block_device *bdev = I_BDEV(inode); | |
| 159 | − | |
| 160 | − if (blk_validate_block_size(size)) | |
| 167 | + if (blk_validate_block_size(block_size)) | |
| 161 | 168 | return -EINVAL; |
| 162 | 169 | |
| 163 | 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 | 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 | 188 | if (!file->private_data) |
| 168 | 189 | return -EINVAL; |
| 169 | 190 | |
| 170 | 191 | /* Don't change the size if it is same as current */ |
| 171 | 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 | 206 | sync_blockdev(bdev); |
| 207 | + kill_bdev(bdev); | |
| 208 | + | |
| 173 | 209 | inode->i_blkbits = blksize_bits(size); |
| 174 | 210 | mapping_set_folio_min_order(inode->i_mapping, get_order(size)); |
| 175 | 211 | kill_bdev(bdev); |
| 212 | + filemap_invalidate_unlock(inode->i_mapping); | |
| 213 | + inode_unlock(inode); | |
| 176 | 214 | } |
| 177 | 215 | return 0; |
| 178 | 216 | } |
| @@ -777,13 +815,13 @@ static void blkdev_put_part(struct block_device *part) · 598 unmodified lines | ||
| 777 | 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 | 820 | struct block_device *bdev; |
| 783 | 821 | struct inode *inode; |
| 784 | 822 | |
| 785 | 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 | 825 | blk_request_module(dev); |
| 788 | 826 | inode = ilookup(blockdev_superblock, dev); |
| 789 | 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 | 1043 | if (ret) |
| 1006 | 1044 | return ERR_PTR(ret); |
| 1007 | 1045 | |
| 1008 | − bdev = blkdev_get_no_open(dev); | |
| 1046 | + bdev = blkdev_get_no_open(dev, true); | |
| 1009 | 1047 | if (!bdev) |
| 1010 | 1048 | return ERR_PTR(-ENXIO); |
| 1011 | 1049 | |
| @@ -1272,21 +1310,17 @@ void sync_bdevs(bool wait) · 260 unmodified lines | ||
| 1272 | 1310 | /* |
| 1273 | 1311 | * Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices. |
| 1274 | 1312 | */ |
| 1275 | −void bdev_statx(struct path *path, struct kstat *stat, | |
| 1276 | − u32 request_mask) | |
| 1313 | +void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask) | |
| 1277 | 1314 | { |
| 1278 | − struct inode *backing_inode; | |
| 1279 | 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, | |
| 1285 | − * not the block device's internal inode. Therefore it is *not* valid | |
| 1286 | − * to use I_BDEV() here; the block device has to be looked up by i_rdev | |
| 1318 | + * Note that d_backing_inode() returns the block device node inode, not | |
| 1319 | + * the block device's internal inode. Therefore it is *not* valid to | |
| 1320 | + * use I_BDEV() here; the block device has to be looked up by i_rdev | |
| 1287 | 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 | 1324 | if (!bdev) |
| 1291 | 1325 | return; |
| 1292 | 1326 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * not aware of PI. |
| 10 | 10 | */ |
| 11 | 11 | #include <linux/blk-integrity.h> |
| 12 | +#include <linux/t10-pi.h> | |
| 12 | 13 | #include <linux/workqueue.h> |
| 13 | 14 | #include "blk.h" |
| 14 | 15 | |
| @@ -43,6 +44,29 @@ static void bio_integrity_verify_fn(struct work_struct *work) · 28 unmodified lines | ||
| 43 | 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 | 71 | * __bio_integrity_endio - Integrity I/O completion function |
| 48 | 72 | * @bio: Protected bio |
| @@ -54,12 +78,12 @@ static void bio_integrity_verify_fn(struct work_struct *work) · 5 unmodified lines | ||
| 54 | 78 | */ |
| 55 | 79 | bool __bio_integrity_endio(struct bio *bio) |
| 56 | 80 | { |
| 57 | − struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); | |
| 58 | 81 | struct bio_integrity_payload *bip = bio_integrity(bio); |
| 59 | 82 | struct bio_integrity_data *bid = |
| 60 | 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 | 87 | INIT_WORK(&bid->work, bio_integrity_verify_fn); |
| 64 | 88 | queue_work(kintegrityd_wq, &bid->work); |
| 65 | 89 | return false; |
| @@ -84,6 +108,7 @@ bool bio_integrity_prep(struct bio *bio) · 18 unmodified lines | ||
| 84 | 108 | { |
| 85 | 109 | struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); |
| 86 | 110 | struct bio_integrity_data *bid; |
| 111 | + bool set_flags = true; | |
| 87 | 112 | gfp_t gfp = GFP_NOIO; |
| 88 | 113 | unsigned int len; |
| 89 | 114 | void *buf; |
| @@ -100,19 +125,24 @@ bool bio_integrity_prep(struct bio *bio) · 10 unmodified lines | ||
| 100 | 125 | |
| 101 | 126 | switch (bio_op(bio)) { |
| 102 | 127 | case REQ_OP_READ: |
| 103 | − if (bi->flags & BLK_INTEGRITY_NOVERIFY) | |
| 104 | − return true; | |
| 128 | + if (bi->flags & BLK_INTEGRITY_NOVERIFY) { | |
| 129 | + if (bi_offload_capable(bi)) | |
| 130 | + return true; | |
| 131 | + set_flags = false; | |
| 132 | + } | |
| 105 | 133 | break; |
| 106 | 134 | case REQ_OP_WRITE: |
| 107 | − if (bi->flags & BLK_INTEGRITY_NOGENERATE) | |
| 108 | − return true; | |
| 109 | − | |
| 110 | 135 | /* |
| 111 | 136 | * Zero the memory allocated to not leak uninitialized kernel |
| 112 | 137 | * memory to disk for non-integrity metadata where nothing else |
| 113 | 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 | 146 | gfp |= __GFP_ZERO; |
| 117 | 147 | break; |
| 118 | 148 | default: |
| @@ -137,19 +167,21 @@ bool bio_integrity_prep(struct bio *bio) · 18 unmodified lines | ||
| 137 | 167 | bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY; |
| 138 | 168 | bip_set_seed(&bid->bip, bio->bi_iter.bi_sector); |
| 139 | 169 | |
| 140 | − if (bi->csum_type == BLK_INTEGRITY_CSUM_IP) | |
| 141 | − bid->bip.bip_flags |= BIP_IP_CHECKSUM; | |
| 142 | − if (bi->csum_type) | |
| 143 | − bid->bip.bip_flags |= BIP_CHECK_GUARD; | |
| 144 | − if (bi->flags & BLK_INTEGRITY_REF_TAG) | |
| 145 | − bid->bip.bip_flags |= BIP_CHECK_REFTAG; | |
| 170 | + if (set_flags) { | |
| 171 | + if (bi->csum_type == BLK_INTEGRITY_CSUM_IP) | |
| 172 | + bid->bip.bip_flags |= BIP_IP_CHECKSUM; | |
| 173 | + if (bi->csum_type) | |
| 174 | + bid->bip.bip_flags |= BIP_CHECK_GUARD; | |
| 175 | + if (bi->flags & BLK_INTEGRITY_REF_TAG) | |
| 176 | + bid->bip.bip_flags |= BIP_CHECK_REFTAG; | |
| 177 | + } | |
| 146 | 178 | |
| 147 | 179 | if (bio_integrity_add_page(bio, virt_to_page(buf), len, |
| 148 | 180 | offset_in_page(buf)) < len) |
| 149 | 181 | goto err_end_io; |
| 150 | 182 | |
| 151 | 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 | 185 | blk_integrity_generate(bio); |
| 154 | 186 | else |
| 155 | 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 | 67 | EXPORT_SYMBOL(bio_integrity_alloc); |
| 68 | 68 | |
| 69 | −static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs, | |
| 70 | − bool dirty) | |
| 69 | +static void bio_integrity_unpin_bvec(struct bio_vec *bv, int nr_vecs) | |
| 71 | 70 | { |
| 72 | 71 | int i; |
| 73 | 72 | |
| 74 | − for (i = 0; i < nr_vecs; i++) { | |
| 75 | − if (dirty && !PageCompound(bv[i].bv_page)) | |
| 76 | − set_page_dirty_lock(bv[i].bv_page); | |
| 73 | + for (i = 0; i < nr_vecs; i++) | |
| 77 | 74 | unpin_user_page(bv[i].bv_page); |
| 78 | − } | |
| 79 | 75 | } |
| 80 | 76 | |
| 81 | 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 | 87 | ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter); |
| 92 | 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 | 107 | return; |
| 112 | 108 | } |
| 113 | 109 | |
| 114 | − bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt, | |
| 115 | − bio_data_dir(bio) == READ); | |
| 110 | + bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt); | |
| 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 | 195 | if (write) |
| 201 | − bio_integrity_unpin_bvec(bvec, nr_vecs, false); | |
| 196 | + bio_integrity_unpin_bvec(bvec, nr_vecs); | |
| 202 | 197 | else |
| 203 | 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 | 314 | return 0; |
| 320 | 315 | |
| 321 | 316 | release_pages: |
| 322 | − bio_integrity_unpin_bvec(bvec, nr_bvecs, false); | |
| 317 | + bio_integrity_unpin_bvec(bvec, nr_bvecs); | |
| 323 | 318 | free_bvec: |
| 324 | 319 | if (bvec != stack_vec) |
| 325 | 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 | 612 | struct bio *bio; |
| 613 | 613 | |
| 614 | − if (nr_vecs > UIO_MAXIOV) | |
| 614 | + if (nr_vecs > BIO_MAX_INLINE_VECS) | |
| 615 | 615 | return NULL; |
| 616 | 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 | 797 | return -EINVAL; |
| 798 | 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 | 801 | if (!bdev) |
| 802 | 802 | return -ENODEV; |
| 803 | 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 | 62 | * For read-ahead of large files to be effective, we need to read ahead |
| 63 | 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 | 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 | 909 | out_debugfs_remove: |
| 910 | 910 | blk_debugfs_remove(disk); |
| 911 | 911 | mutex_unlock(&q->sysfs_lock); |
| 912 | + if (queue_is_mq(q)) | |
| 913 | + blk_mq_sysfs_unregister(disk); | |
| 912 | 914 | out_put_queue_kobj: |
| 913 | 915 | kobject_put(&disk->queue_kobj); |
| 914 | 916 | return ret; |
| @@ -1,3 +1,4 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 1 | 2 | #ifndef BLK_THROTTLE_H |
| 2 | 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 | 343 | op = REQ_OP_ZONE_RESET; |
| 344 | 344 | |
| 345 | 345 | /* Invalidate the page cache, including dirty pages. */ |
| 346 | + inode_lock(bdev->bd_mapping->host); | |
| 346 | 347 | filemap_invalidate_lock(bdev->bd_mapping); |
| 347 | 348 | ret = blkdev_truncate_zone_range(bdev, mode, &zrange); |
| 348 | 349 | if (ret) |
| @@ -364,8 +365,10 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode, · 15 unmodified lines | ||
| 364 | 365 | ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors); |
| 365 | 366 | |
| 366 | 367 | fail: |
| 367 | − if (cmd == BLKRESETZONE) | |
| 368 | + if (cmd == BLKRESETZONE) { | |
| 368 | 369 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 370 | + inode_unlock(bdev->bd_mapping->host); | |
| 371 | + } | |
| 369 | 372 | |
| 370 | 373 | return ret; |
| 371 | 374 | } |
| @@ -94,6 +94,9 @@ static inline void blk_wait_io(struct completion *done) · 93 unmodified lines | ||
| 94 | 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 | 100 | #define BIO_INLINE_VECS 4 |
| 98 | 101 | struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs, |
| 99 | 102 | gfp_t gfp_mask); |
| @@ -477,7 +480,8 @@ static inline void blk_zone_update_request_bio(struct request *rq, · 377 unmodified lines | ||
| 477 | 480 | * the original BIO sector so that blk_zone_write_plug_bio_endio() can |
| 478 | 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 | 485 | bio->bi_iter.bi_sector = rq->__sector; |
| 482 | 486 | } |
| 483 | 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 | 642 | if (ret) |
| 643 | 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 | 646 | if (!bdev) |
| 647 | 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 | 746 | ret = direct_write_fallback(iocb, from, ret, |
| 747 | 747 | blkdev_buffered_write(iocb, from)); |
| 748 | 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 | 755 | ret = blkdev_buffered_write(iocb, from); |
| 756 | + inode_unlock_shared(bd_inode); | |
| 750 | 757 | } |
| 751 | 758 | |
| 752 | 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 | 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 | 768 | struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); |
| 761 | 769 | loff_t size = bdev_nr_bytes(bdev); |
| 762 | 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 | 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 | 809 | ret = filemap_read(iocb, to, ret); |
| 810 | + inode_unlock_shared(bd_inode); | |
| 797 | 811 | |
| 798 | 812 | reexpand: |
| 799 | 813 | if (unlikely(shorted)) |
| @@ -836,6 +850,7 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start, · 36 unmodified lines | ||
| 836 | 850 | if ((start | len) & (bdev_logical_block_size(bdev) - 1)) |
| 837 | 851 | return -EINVAL; |
| 838 | 852 | |
| 853 | + inode_lock(inode); | |
| 839 | 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 | 884 | fail: |
| 870 | 885 | filemap_invalidate_unlock(inode->i_mapping); |
| 886 | + inode_unlock(inode); | |
| 871 | 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 | 142 | if (err) |
| 143 | 143 | return err; |
| 144 | 144 | |
| 145 | + inode_lock(bdev->bd_mapping->host); | |
| 145 | 146 | filemap_invalidate_lock(bdev->bd_mapping); |
| 146 | 147 | err = truncate_bdev_range(bdev, mode, start, start + len - 1); |
| 147 | 148 | if (err) |
| @@ -174,6 +175,7 @@ out_unplug: · 26 unmodified lines | ||
| 174 | 175 | blk_finish_plug(&plug); |
| 175 | 176 | fail: |
| 176 | 177 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 178 | + inode_unlock(bdev->bd_mapping->host); | |
| 177 | 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 | 201 | end > bdev_nr_bytes(bdev)) |
| 200 | 202 | return -EINVAL; |
| 201 | 203 | |
| 204 | + inode_lock(bdev->bd_mapping->host); | |
| 202 | 205 | filemap_invalidate_lock(bdev->bd_mapping); |
| 203 | 206 | err = truncate_bdev_range(bdev, mode, start, end - 1); |
| 204 | 207 | if (!err) |
| 205 | 208 | err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9, |
| 206 | 209 | GFP_KERNEL); |
| 207 | 210 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 211 | + inode_unlock(bdev->bd_mapping->host); | |
| 208 | 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 | 240 | return -EINVAL; |
| 237 | 241 | |
| 238 | 242 | /* Invalidate the page cache, including dirty pages */ |
| 243 | + inode_lock(bdev->bd_mapping->host); | |
| 239 | 244 | filemap_invalidate_lock(bdev->bd_mapping); |
| 240 | 245 | err = truncate_bdev_range(bdev, mode, start, end); |
| 241 | 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 | 252 | fail: |
| 248 | 253 | filemap_invalidate_unlock(bdev->bd_mapping); |
| 254 | + inode_unlock(bdev->bd_mapping->host); | |
| 249 | 255 | return err; |
| 250 | 256 | } |
| 251 | 257 | |
| @@ -46,12 +46,8 @@ int ioprio_check_cap(int ioprio) · 45 unmodified lines | ||
| 46 | 46 | */ |
| 47 | 47 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) |
| 48 | 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 | 49 | break; |
| 50 | + case IOPRIO_CLASS_BE: | |
| 55 | 51 | case IOPRIO_CLASS_IDLE: |
| 56 | 52 | break; |
| 57 | 53 | case IOPRIO_CLASS_NONE: |
| @@ -315,16 +315,7 @@ EXPORT_SYMBOL_GPL(crypto_ahash_setkey); · 314 unmodified lines | ||
| 315 | 315 | |
| 316 | 316 | static bool ahash_request_hasvirt(struct ahash_request *req) |
| 317 | 317 | { |
| 318 | − struct ahash_request *r2; | |
| 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; | |
| 318 | + return ahash_request_isvirt(req); | |
| 328 | 319 | } |
| 329 | 320 | |
| 330 | 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 | 463 | bool update = op == crypto_ahash_alg(tfm)->update; |
| 473 | 464 | struct ahash_save_req_state *state; |
| 474 | 465 | struct ahash_save_req_state state0; |
| 475 | − struct ahash_request *r2; | |
| 476 | 466 | u8 *page = NULL; |
| 477 | 467 | int err; |
| 478 | 468 | |
| @@ -509,7 +499,6 @@ static int ahash_do_req_chain(struct ahash_request *req, · 30 unmodified lines | ||
| 509 | 499 | state->offset = 0; |
| 510 | 500 | state->nbytes = 0; |
| 511 | 501 | INIT_LIST_HEAD(&state->head); |
| 512 | − list_splice_init(&req->base.list, &state->head); | |
| 513 | 502 | |
| 514 | 503 | if (page) |
| 515 | 504 | sg_init_one(&state->sg, page, PAGE_SIZE); |
| @@ -540,9 +529,6 @@ out_free_page: · 24 unmodified lines | ||
| 540 | 529 | |
| 541 | 530 | out_set_chain: |
| 542 | 531 | req->base.err = err; |
| 543 | − list_for_each_entry(r2, &req->base.list, base.list) | |
| 544 | − r2->base.err = err; | |
| 545 | − | |
| 546 | 532 | return err; |
| 547 | 533 | } |
| 548 | 534 | |
| @@ -551,19 +537,10 @@ int crypto_ahash_init(struct ahash_request *req) · 2 unmodified lines | ||
| 551 | 537 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 552 | 538 | |
| 553 | 539 | if (likely(tfm->using_shash)) { |
| 554 | − struct ahash_request *r2; | |
| 555 | 540 | int err; |
| 556 | 541 | |
| 557 | 542 | err = crypto_shash_init(prepare_shash_desc(req, tfm)); |
| 558 | 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 | 544 | return err; |
| 568 | 545 | } |
| 569 | 546 | |
| @@ -620,19 +597,10 @@ int crypto_ahash_update(struct ahash_request *req) · 50 unmodified lines | ||
| 620 | 597 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 621 | 598 | |
| 622 | 599 | if (likely(tfm->using_shash)) { |
| 623 | − struct ahash_request *r2; | |
| 624 | 600 | int err; |
| 625 | 601 | |
| 626 | 602 | err = shash_ahash_update(req, ahash_request_ctx(req)); |
| 627 | 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 | 604 | return err; |
| 637 | 605 | } |
| 638 | 606 | |
| @@ -645,19 +613,10 @@ int crypto_ahash_final(struct ahash_request *req) · 6 unmodified lines | ||
| 645 | 613 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 646 | 614 | |
| 647 | 615 | if (likely(tfm->using_shash)) { |
| 648 | − struct ahash_request *r2; | |
| 649 | 616 | int err; |
| 650 | 617 | |
| 651 | 618 | err = crypto_shash_final(ahash_request_ctx(req), req->result); |
| 652 | 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 | 620 | return err; |
| 662 | 621 | } |
| 663 | 622 | |
| @@ -670,19 +629,10 @@ int crypto_ahash_finup(struct ahash_request *req) · 6 unmodified lines | ||
| 670 | 629 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 671 | 630 | |
| 672 | 631 | if (likely(tfm->using_shash)) { |
| 673 | − struct ahash_request *r2; | |
| 674 | 632 | int err; |
| 675 | 633 | |
| 676 | 634 | err = shash_ahash_finup(req, ahash_request_ctx(req)); |
| 677 | 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 | 636 | return err; |
| 687 | 637 | } |
| 688 | 638 | |
| @@ -757,19 +707,10 @@ int crypto_ahash_digest(struct ahash_request *req) · 68 unmodified lines | ||
| 757 | 707 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 758 | 708 | |
| 759 | 709 | if (likely(tfm->using_shash)) { |
| 760 | − struct ahash_request *r2; | |
| 761 | 710 | int err; |
| 762 | 711 | |
| 763 | 712 | err = shash_ahash_digest(req, prepare_shash_desc(req, tfm)); |
| 764 | 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 | 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 | 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 | 1077 | MODULE_LICENSE("GPL"); |
| 1152 | 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 | 265 | goto out_free_state; |
| 266 | 266 | |
| 267 | 267 | err = crypto_ahash_import(&ctx2->req, state); |
| 268 | − if (err) { | |
| 269 | − sock_orphan(sk2); | |
| 270 | − sock_put(sk2); | |
| 271 | − } | |
| 272 | 268 | |
| 273 | 269 | out_free_state: |
| 274 | 270 | kfree_sensitive(state); |
| @@ -111,10 +111,14 @@ static void scomp_free_streams(struct scomp_alg *alg) · 110 unmodified lines | ||
| 111 | 111 | struct crypto_acomp_stream __percpu *stream = alg->stream; |
| 112 | 112 | int i; |
| 113 | 113 | |
| 114 | + alg->stream = NULL; | |
| 115 | + if (!stream) | |
| 116 | + return; | |
| 117 | + | |
| 114 | 118 | for_each_possible_cpu(i) { |
| 115 | 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 | 122 | break; |
| 119 | 123 | |
| 120 | 124 | alg->free_ctx(ps->ctx); |
| @@ -132,6 +136,8 @@ static int scomp_alloc_streams(struct scomp_alg *alg) · 11 unmodified lines | ||
| 132 | 136 | if (!stream) |
| 133 | 137 | return -ENOMEM; |
| 134 | 138 | |
| 139 | + alg->stream = stream; | |
| 140 | + | |
| 135 | 141 | for_each_possible_cpu(i) { |
| 136 | 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 | 150 | spin_lock_init(&ps->lock); |
| 145 | 151 | } |
| 146 | − | |
| 147 | − alg->stream = stream; | |
| 148 | 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 | 163 | if (ret) |
| 160 | 164 | goto unlock; |
| 161 | 165 | } |
| 162 | − if (!scomp_scratch_users) { | |
| 166 | + if (!scomp_scratch_users++) { | |
| 163 | 167 | ret = crypto_scomp_alloc_scratches(); |
| 164 | 168 | if (ret) |
| 165 | − goto unlock; | |
| 166 | − scomp_scratch_users++; | |
| 169 | + scomp_scratch_users--; | |
| 167 | 170 | } |
| 168 | 171 | unlock: |
| 169 | 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 | 214 | spage = nth_page(spage, soff / PAGE_SIZE); |
| 212 | 215 | soff = offset_in_page(soff); |
| 213 | 216 | |
| 214 | − n = slen / PAGE_SIZE; | |
| 215 | − n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE; | |
| 217 | + n = (slen - 1) / PAGE_SIZE; | |
| 218 | + n += (offset_in_page(slen - 1) + soff) / PAGE_SIZE; | |
| 216 | 219 | if (PageHighMem(nth_page(spage, n)) && |
| 217 | 220 | size_add(soff, slen) > PAGE_SIZE) |
| 218 | 221 | break; |
| @@ -239,9 +242,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) · 20 unmodified lines | ||
| 239 | 242 | dpage = nth_page(dpage, doff / PAGE_SIZE); |
| 240 | 243 | doff = offset_in_page(doff); |
| 241 | 244 | |
| 242 | − n = dlen / PAGE_SIZE; | |
| 243 | − n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE; | |
| 244 | − if (PageHighMem(dpage + n) && | |
| 245 | + n = (dlen - 1) / PAGE_SIZE; | |
| 246 | + n += (offset_in_page(dlen - 1) + doff) / PAGE_SIZE; | |
| 247 | + if (PageHighMem(nth_page(dpage, n)) && | |
| 245 | 248 | size_add(doff, dlen) > PAGE_SIZE) |
| 246 | 249 | break; |
| 247 | 250 | dst = kmap_local_page(dpage) + doff; |
| @@ -58,9 +58,6 @@ module_param(fuzz_iterations, uint, 0644); · 57 unmodified lines | ||
| 58 | 58 | MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); |
| 59 | 59 | #endif |
| 60 | 60 | |
| 61 | −/* Multibuffer is unlimited. Set arbitrary limit for testing. */ | |
| 62 | −#define MAX_MB_MSGS 16 | |
| 63 | − | |
| 64 | 61 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS |
| 65 | 62 | |
| 66 | 63 | /* a perfect nop */ |
| @@ -3329,48 +3326,27 @@ static int test_acomp(struct crypto_acomp *tfm, · 3262 unmodified lines | ||
| 3329 | 3326 | int ctcount, int dtcount) |
| 3330 | 3327 | { |
| 3331 | 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 | 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); | |
| 3342 | − if (!src) | |
| 3343 | − goto out; | |
| 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; | |
| 3336 | + output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | |
| 3337 | + if (!output) | |
| 3338 | + return -ENOMEM; | |
| 3363 | 3339 | |
| 3364 | − decomp_out[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | |
| 3365 | − if (!decomp_out[i]) | |
| 3366 | − goto out; | |
| 3340 | + decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | |
| 3341 | + if (!decomp_out) { | |
| 3342 | + kfree(output); | |
| 3343 | + return -ENOMEM; | |
| 3367 | 3344 | } |
| 3368 | 3345 | |
| 3369 | 3346 | for (i = 0; i < ctcount; i++) { |
| 3370 | 3347 | unsigned int dlen = COMP_BUF_SIZE; |
| 3371 | 3348 | int ilen = ctemplate[i].inlen; |
| 3372 | 3349 | void *input_vec; |
| 3373 | − int j; | |
| 3374 | 3350 | |
| 3375 | 3351 | input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); |
| 3376 | 3352 | if (!input_vec) { |
| @@ -3378,61 +3354,70 @@ static int test_acomp(struct crypto_acomp *tfm, · 1 unmodified line | ||
| 3378 | 3354 | goto out; |
| 3379 | 3355 | } |
| 3380 | 3356 | |
| 3357 | + memset(output, 0, dlen); | |
| 3381 | 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++) { | |
| 3385 | − sg_init_one(dst + j, output[j], dlen); | |
| 3386 | − acomp_request_set_params(reqs[j], src, dst + j, ilen, dlen); | |
| 3362 | + req = acomp_request_alloc(tfm); | |
| 3363 | + if (!req) { | |
| 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 | 3375 | ret = crypto_wait_req(crypto_acomp_compress(req), &wait); |
| 3391 | 3376 | if (ret) { |
| 3392 | 3377 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", |
| 3393 | 3378 | i + 1, algo, -ret); |
| 3394 | 3379 | kfree(input_vec); |
| 3380 | + acomp_request_free(req); | |
| 3395 | 3381 | goto out; |
| 3396 | 3382 | } |
| 3397 | 3383 | |
| 3398 | 3384 | ilen = req->dlen; |
| 3399 | 3385 | dlen = COMP_BUF_SIZE; |
| 3386 | + sg_init_one(&src, output, ilen); | |
| 3387 | + sg_init_one(&dst, decomp_out, dlen); | |
| 3400 | 3388 | crypto_init_wait(&wait); |
| 3401 | − for (j = 0; j < MAX_MB_MSGS; j++) { | |
| 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 | − } | |
| 3389 | + acomp_request_set_params(req, &src, &dst, ilen, dlen); | |
| 3416 | 3390 | |
| 3417 | − if (reqs[j]->dlen != ctemplate[i].inlen) { | |
| 3418 | − pr_err("alg: acomp: Compression test %d (%d) failed for %s: output len = %d\n", | |
| 3419 | − i + 1, j, algo, reqs[j]->dlen); | |
| 3420 | − ret = -EINVAL; | |
| 3421 | − kfree(input_vec); | |
| 3422 | − goto out; | |
| 3423 | − } | |
| 3391 | + ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); | |
| 3392 | + if (ret) { | |
| 3393 | + pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", | |
| 3394 | + i + 1, algo, -ret); | |
| 3395 | + kfree(input_vec); | |
| 3396 | + acomp_request_free(req); | |
| 3397 | + goto out; | |
| 3398 | + } | |
| 3424 | 3399 | |
| 3425 | − if (memcmp(input_vec, decomp_out[j], reqs[j]->dlen)) { | |
| 3426 | − pr_err("alg: acomp: Compression test %d (%d) failed for %s\n", | |
| 3427 | − i + 1, j, algo); | |
| 3428 | − hexdump(output[j], reqs[j]->dlen); | |
| 3429 | − ret = -EINVAL; | |
| 3430 | − kfree(input_vec); | |
| 3431 | − goto out; | |
| 3432 | − } | |
| 3400 | + if (req->dlen != ctemplate[i].inlen) { | |
| 3401 | + pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", | |
| 3402 | + i + 1, algo, req->dlen); | |
| 3403 | + ret = -EINVAL; | |
| 3404 | + kfree(input_vec); | |
| 3405 | + acomp_request_free(req); | |
| 3406 | + goto out; | |
| 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 | 3419 | kfree(input_vec); |
| 3420 | + acomp_request_free(req); | |
| 3436 | 3421 | } |
| 3437 | 3422 | |
| 3438 | 3423 | for (i = 0; i < dtcount; i++) { |
| @@ -3446,9 +3431,10 @@ static int test_acomp(struct crypto_acomp *tfm, · 7 unmodified lines | ||
| 3446 | 3431 | goto out; |
| 3447 | 3432 | } |
| 3448 | 3433 | |
| 3434 | + memset(output, 0, dlen); | |
| 3449 | 3435 | crypto_init_wait(&wait); |
| 3450 | − sg_init_one(src, input_vec, ilen); | |
| 3451 | − sg_init_one(dst, output[0], dlen); | |
| 3436 | + sg_init_one(&src, input_vec, ilen); | |
| 3437 | + sg_init_one(&dst, output, dlen); | |
| 3452 | 3438 | |
| 3453 | 3439 | req = acomp_request_alloc(tfm); |
| 3454 | 3440 | if (!req) { |
| @@ -3459,7 +3445,7 @@ static int test_acomp(struct crypto_acomp *tfm, · 4 unmodified lines | ||
| 3459 | 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 | 3449 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 3464 | 3450 | crypto_req_done, &wait); |
| 3465 | 3451 | |
| @@ -3481,10 +3467,10 @@ static int test_acomp(struct crypto_acomp *tfm, · 15 unmodified lines | ||
| 3481 | 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 | 3471 | pr_err("alg: acomp: Decompression test %d failed for %s\n", |
| 3486 | 3472 | i + 1, algo); |
| 3487 | − hexdump(output[0], req->dlen); | |
| 3473 | + hexdump(output, req->dlen); | |
| 3488 | 3474 | ret = -EINVAL; |
| 3489 | 3475 | kfree(input_vec); |
| 3490 | 3476 | acomp_request_free(req); |
| @@ -3498,13 +3484,8 @@ static int test_acomp(struct crypto_acomp *tfm, · 7 unmodified lines | ||
| 3498 | 3484 | ret = 0; |
| 3499 | 3485 | |
| 3500 | 3486 | out: |
| 3501 | − acomp_request_free(reqs[0]); | |
| 3502 | − for (i = 0; i < MAX_MB_MSGS; i++) { | |
| 3503 | − kfree(output[i]); | |
| 3504 | − kfree(decomp_out[i]); | |
| 3505 | − } | |
| 3506 | − kfree(dst); | |
| 3507 | − kfree(src); | |
| 3487 | + kfree(decomp_out); | |
| 3488 | + kfree(output); | |
| 3508 | 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 | 332 | return -EINVAL; |
| 333 | 333 | |
| 334 | 334 | ret = ivpu_rpm_get(vdev); |
| 335 | − if (ret) | |
| 335 | + if (ret < 0) | |
| 336 | 336 | return ret; |
| 337 | 337 | |
| 338 | 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 | 383 | return -EINVAL; |
| 384 | 384 | |
| 385 | 385 | ret = ivpu_rpm_get(vdev); |
| 386 | − if (ret) | |
| 386 | + if (ret < 0) | |
| 387 | 387 | return ret; |
| 388 | 388 | |
| 389 | 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 | 455 | if (ret < 0) |
| 456 | 456 | return ret; |
| 457 | 457 | |
| 458 | − buf[size] = '\0'; | |
| 458 | + buf[ret] = '\0'; | |
| 459 | 459 | ret = sscanf(buf, "%u %u %u %u", &band, &grace_period, &process_grace_period, |
| 460 | 460 | &process_quantum); |
| 461 | 461 | if (ret != 4) |
| @@ -1,6 +1,6 @@ | ||
| 1 | 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 | 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 | 164 | args->value = vdev->platform; |
| 165 | 165 | break; |
| 166 | 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 | 168 | break; |
| 169 | 169 | case DRM_IVPU_PARAM_NUM_CONTEXTS: |
| 170 | 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 | 422 | ivpu_hw_irq_disable(vdev); |
| 423 | 423 | disable_irq(vdev->irq); |
| 424 | − cancel_work_sync(&vdev->irq_ipc_work); | |
| 425 | − cancel_work_sync(&vdev->irq_dct_work); | |
| 426 | − cancel_work_sync(&vdev->context_abort_work); | |
| 424 | + flush_work(&vdev->irq_ipc_work); | |
| 425 | + flush_work(&vdev->irq_dct_work); | |
| 426 | + flush_work(&vdev->context_abort_work); | |
| 427 | 427 | ivpu_ipc_disable(vdev); |
| 428 | 428 | ivpu_mmu_disable(vdev); |
| 429 | 429 | } |
| @@ -1,6 +1,6 @@ | ||
| 1 | 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 | 6 | #include <linux/firmware.h> |
| @@ -233,10 +233,20 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) · 226 unmodified lines | ||
| 233 | 233 | fw->dvfs_mode = 0; |
| 234 | 234 | |
| 235 | 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 | 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 | 250 | if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, |
| 241 | 251 | fw_hdr->ro_section_size, |
| 242 | 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 | 544 | boot_params->d0i3_entry_vpu_ts); |
| 535 | 545 | ivpu_dbg(vdev, FW_BOOT, "boot_params.system_time_us = %llu\n", |
| 536 | 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 | 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 | 577 | boot_params->magic = VPU_BOOT_PARAMS_MAGIC; |
| 568 | 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 | 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 | 646 | boot_params->d0i3_residency_time_us = 0; |
| 638 | 647 | boot_params->d0i3_entry_vpu_ts = 0; |
| 639 | 648 | if (IVPU_WA(disable_d0i2)) |
| 640 | − boot_params->power_profile = 1; | |
| 649 | + boot_params->power_profile |= BIT(1); | |
| 641 | 650 | |
| 642 | 651 | boot_params->system_time_us = ktime_to_us(ktime_get_real()); |
| 643 | 652 | wmb(); /* Flush WC buffers after writing bootparams */ |
| @@ -119,7 +119,7 @@ static void timeouts_init(struct ivpu_device *vdev) · 118 unmodified lines | ||
| 119 | 119 | else |
| 120 | 120 | vdev->timeout.autosuspend = 100; |
| 121 | 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 | 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 | 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 | 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 | 100 | static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev) |
| @@ -1,8 +1,10 @@ | ||
| 1 | 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 | 8 | #include "ivpu_drv.h" |
| 7 | 9 | #include "ivpu_hw.h" |
| 8 | 10 | #include "ivpu_hw_btrs.h" |
| @@ -28,17 +30,13 @@ · 19 unmodified lines | ||
| 28 | 30 | |
| 29 | 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 | 34 | #define PLL_CDYN_DEFAULT 0x80 |
| 38 | 35 | #define PLL_EPP_DEFAULT 0x80 |
| 39 | 36 | #define PLL_CONFIG_DEFAULT 0x0 |
| 40 | −#define PLL_SIMULATION_FREQ 10000000 | |
| 41 | −#define PLL_REF_CLK_FREQ 50000000 | |
| 37 | +#define PLL_REF_CLK_FREQ 50000000ull | |
| 38 | +#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ) | |
| 39 | + | |
| 42 | 40 | #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC) |
| 43 | 41 | #define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC) |
| 44 | 42 | #define TIMEOUT_US (150 * USEC_PER_MSEC) |
| @@ -62,6 +60,8 @@ · 17 unmodified lines | ||
| 62 | 60 | #define DCT_ENABLE 0x1 |
| 63 | 61 | #define DCT_DISABLE 0x0 |
| 64 | 62 | |
| 63 | +static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio); | |
| 64 | + | |
| 65 | 65 | int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev) |
| 66 | 66 | { |
| 67 | 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 | 157 | hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; |
| 158 | 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 | 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 | 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", | |
| 338 | − PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn); | |
| 337 | + ivpu_dbg(vdev, PM, "PLL workpoint request: %lu MHz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n", | |
| 338 | + pll_ratio_to_dpu_freq(vdev, wp.target) / HZ_PER_MHZ, wp.cfg, wp.epp, wp.cdyn); | |
| 339 | 339 | |
| 340 | 340 | ret = wp_request_send(vdev, &wp); |
| 341 | 341 | if (ret) { |
| @@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev) · 231 unmodified lines | ||
| 573 | 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 | 617 | /* Handler for IRQs from Buttress core (irqB) */ |
| 577 | 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 | 623 | if (!status) |
| 583 | 624 | return false; |
| 584 | 625 | |
| 585 | − if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) | |
| 586 | − ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", | |
| 587 | − REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL)); | |
| 626 | + if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) { | |
| 627 | + u32 pll = pll_config_get_mtl(vdev); | |
| 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 | 633 | if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) { |
| 590 | 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 | 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)) | |
| 637 | − ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ)); | |
| 680 | + if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) { | |
| 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 | 687 | if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) { |
| 640 | 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 | 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 | 768 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev) |
| 775 | 769 | { |
| 776 | 770 | if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) |
| @@ -1,6 +1,6 @@ | ||
| 1 | 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 | 6 | #ifndef __IVPU_HW_BTRS_H__ |
| @@ -13,9 +13,8 @@ · 6 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #define PLL_PROFILING_FREQ_DEFAULT 38400000 |
| 15 | 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 | 18 | #define DCT_PERIOD_US 35300u |
| 20 | 19 | |
| 21 | 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 | 31 | void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev); |
| 33 | 32 | void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev); |
| 34 | 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 | 36 | bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); |
| 36 | 37 | bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); |
| 37 | 38 | int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); |
| 38 | 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 | 40 | u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); |
| 42 | 41 | u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); |
| 43 | 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 | 302 | struct ivpu_ipc_consumer cons; |
| 303 | 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 | 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 | 470 | struct ivpu_device *vdev = job->vdev; |
| 471 | 471 | u32 i; |
| 472 | 472 | |
| 473 | − ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d", | |
| 474 | − job->job_id, job->file_priv->ctx.id, job->engine_idx); | |
| 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->cmdq_id, job->engine_idx); | |
| 475 | 475 | |
| 476 | 476 | for (i = 0; i < job->bo_count; i++) |
| 477 | 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 | 564 | dma_fence_signal(job->done_fence); |
| 565 | 565 | |
| 566 | 566 | trace_job("done", job); |
| 567 | − ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", | |
| 568 | − job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); | |
| 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->cmdq_id, job->engine_idx, job_status); | |
| 569 | 569 | |
| 570 | 570 | ivpu_job_destroy(job); |
| 571 | 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 | 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", | |
| 668 | − job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->priority, | |
| 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, cmdq->id, job->engine_idx, cmdq->priority, | |
| 669 | 669 | job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); |
| 670 | 670 | |
| 671 | 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 | 681 | err_erase_xa: |
| 682 | 682 | xa_erase(&vdev->submitted_jobs_xa, job->job_id); |
| 683 | 683 | err_unlock: |
| 684 | − mutex_unlock(&vdev->submitted_jobs_lock); | |
| 685 | 684 | mutex_unlock(&file_priv->lock); |
| 685 | + mutex_unlock(&vdev->submitted_jobs_lock); | |
| 686 | 686 | ivpu_rpm_put(vdev); |
| 687 | 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 | 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 | 783 | job = ivpu_job_create(file_priv, engine, buffer_count); |
| 783 | 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 | 874 | int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) |
| 874 | 875 | { |
| 875 | 876 | struct ivpu_file_priv *file_priv = file->driver_priv; |
| 877 | + struct ivpu_device *vdev = file_priv->vdev; | |
| 876 | 878 | struct drm_ivpu_cmdq_create *args = data; |
| 877 | 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 | 883 | return -ENODEV; |
| 881 | 884 | |
| 882 | 885 | if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) |
| 883 | 886 | return -EINVAL; |
| 884 | 887 | |
| 888 | + ret = ivpu_rpm_get(vdev); | |
| 889 | + if (ret < 0) | |
| 890 | + return ret; | |
| 891 | + | |
| 885 | 892 | mutex_lock(&file_priv->lock); |
| 886 | 893 | |
| 887 | 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 | 898 | mutex_unlock(&file_priv->lock); |
| 892 | 899 | |
| 900 | + ivpu_rpm_put(vdev); | |
| 901 | + | |
| 893 | 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 | 908 | struct ivpu_device *vdev = file_priv->vdev; |
| 900 | 909 | struct drm_ivpu_cmdq_destroy *args = data; |
| 901 | 910 | struct ivpu_cmdq *cmdq; |
| 902 | − u32 cmdq_id; | |
| 911 | + u32 cmdq_id = 0; | |
| 903 | 912 | int ret; |
| 904 | 913 | |
| 905 | 914 | if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) |
| 906 | 915 | return -ENODEV; |
| 907 | 916 | |
| 917 | + ret = ivpu_rpm_get(vdev); | |
| 918 | + if (ret < 0) | |
| 919 | + return ret; | |
| 920 | + | |
| 908 | 921 | mutex_lock(&file_priv->lock); |
| 909 | 922 | |
| 910 | 923 | cmdq = xa_load(&file_priv->cmdq_xa, args->cmdq_id); |
| 911 | 924 | if (!cmdq || cmdq->is_legacy) { |
| 912 | 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 | 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: | |
| 923 | − mutex_unlock(&file_priv->lock); | |
| 934 | + /* Abort any pending jobs only if cmdq was destroyed */ | |
| 935 | + if (!ret) | |
| 936 | + ivpu_cmdq_abort_all_jobs(vdev, file_priv->ctx.id, cmdq_id); | |
| 937 | + | |
| 938 | + ivpu_rpm_put(vdev); | |
| 939 | + | |
| 924 | 940 | return ret; |
| 925 | 941 | } |
| 926 | 942 | |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <drm/drm_file.h> |
| 7 | +#include <linux/pm_runtime.h> | |
| 7 | 8 | |
| 8 | 9 | #include "ivpu_drv.h" |
| 9 | 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 | 45 | args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) |
| 45 | 46 | return -EINVAL; |
| 46 | 47 | |
| 48 | + ret = ivpu_rpm_get(vdev); | |
| 49 | + if (ret < 0) | |
| 50 | + return ret; | |
| 51 | + | |
| 47 | 52 | mutex_lock(&file_priv->ms_lock); |
| 48 | 53 | |
| 49 | 54 | if (get_instance_by_mask(file_priv, args->metric_group_mask)) { |
| @@ -96,6 +101,8 @@ err_free_ms: · 46 unmodified lines | ||
| 96 | 101 | kfree(ms); |
| 97 | 102 | unlock: |
| 98 | 103 | mutex_unlock(&file_priv->ms_lock); |
| 104 | + | |
| 105 | + ivpu_rpm_put(vdev); | |
| 99 | 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 | 167 | if (!args->metric_group_mask) |
| 161 | 168 | return -EINVAL; |
| 162 | 169 | |
| 170 | + ret = ivpu_rpm_get(vdev); | |
| 171 | + if (ret < 0) | |
| 172 | + return ret; | |
| 173 | + | |
| 163 | 174 | mutex_lock(&file_priv->ms_lock); |
| 164 | 175 | |
| 165 | 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 | 198 | unlock: |
| 188 | 199 | mutex_unlock(&file_priv->ms_lock); |
| 189 | 200 | |
| 201 | + ivpu_rpm_put(vdev); | |
| 190 | 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 | 217 | struct ivpu_file_priv *file_priv = file->driver_priv; |
| 206 | 218 | struct drm_ivpu_metric_streamer_stop *args = data; |
| 219 | + struct ivpu_device *vdev = file_priv->vdev; | |
| 207 | 220 | struct ivpu_ms_instance *ms; |
| 221 | + int ret; | |
| 208 | 222 | |
| 209 | 223 | if (!args->metric_group_mask) |
| 210 | 224 | return -EINVAL; |
| 211 | 225 | |
| 226 | + ret = ivpu_rpm_get(vdev); | |
| 227 | + if (ret < 0) | |
| 228 | + return ret; | |
| 229 | + | |
| 212 | 230 | mutex_lock(&file_priv->ms_lock); |
| 213 | 231 | |
| 214 | 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 | 236 | mutex_unlock(&file_priv->ms_lock); |
| 219 | 237 | |
| 238 | + ivpu_rpm_put(vdev); | |
| 220 | 239 | return ms ? 0 : -EINVAL; |
| 221 | 240 | } |
| 222 | 241 | |
| @@ -281,6 +300,9 @@ unlock: · 58 unmodified lines | ||
| 281 | 300 | void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) |
| 282 | 301 | { |
| 283 | 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 | 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 | 315 | free_instance(file_priv, ms); |
| 294 | 316 | |
| 295 | 317 | mutex_unlock(&file_priv->ms_lock); |
| 318 | + | |
| 319 | + pm_runtime_put_autosuspend(vdev->drm.dev); | |
| 296 | 320 | } |
| 297 | 321 | |
| 298 | 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 | 428 | active_us = (DCT_PERIOD_US * active_percent) / 100; |
| 429 | 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 | 436 | ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); |
| 432 | 437 | if (ret) { |
| 433 | 438 | ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); |
| 434 | 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 | 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 | 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 | 453 | ret = ivpu_jsm_dct_disable(vdev); |
| 449 | 454 | if (ret) { |
| 450 | 455 | ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); |
| 451 | 456 | return ret; |
| 452 | 457 | } |
| 453 | 458 | |
| 454 | − vdev->pm->dct_active_percent = 0; | |
| 455 | − | |
| 456 | − ivpu_dbg(vdev, PM, "DCT disabled\n"); | |
| 457 | 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 | 468 | if (ivpu_hw_btrs_dct_get_request(vdev, &enable)) |
| 467 | 469 | return; |
| 468 | 470 | |
| 469 | − if (vdev->pm->dct_active_percent) | |
| 471 | + if (enable) | |
| 470 | 472 | ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT); |
| 471 | 473 | else |
| 472 | 474 | ret = ivpu_pm_dct_disable(vdev); |
| @@ -1,10 +1,12 @@ | ||
| 1 | 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 | 6 | #include <linux/device.h> |
| 7 | 7 | #include <linux/err.h> |
| 8 | +#include <linux/pm_runtime.h> | |
| 9 | +#include <linux/units.h> | |
| 8 | 10 | |
| 9 | 11 | #include "ivpu_drv.h" |
| 10 | 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 | 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 | 138 | static struct attribute *ivpu_dev_attrs[] = { |
| 94 | 139 | &dev_attr_npu_busy_time_us.attr, |
| 95 | 140 | &dev_attr_npu_memory_utilization.attr, |
| 96 | 141 | &dev_attr_sched_mode.attr, |
| 142 | + &dev_attr_npu_max_frequency_mhz.attr, | |
| 143 | + &dev_attr_npu_current_frequency_mhz.attr, | |
| 97 | 144 | NULL, |
| 98 | 145 | }; |
| 99 | 146 | |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | * Minor version changes when API backward compatibility is preserved. |
| 27 | 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 | 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 | 76 | * submission queue size and device capabilities. |
| 77 | 77 | */ |
| 78 | 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 | 86 | /* Space reserved for future preemption-related fields. */ |
| 80 | − u32 preemption_reserved[6]; | |
| 87 | + u32 preemption_reserved[4]; | |
| 81 | 88 | /* FW image read only section start address, 4KB aligned */ |
| 82 | 89 | u64 ro_section_start_address; |
| 83 | 90 | /* FW image read only section size, 4KB aligned */ |
| @@ -134,7 +141,7 @@ enum vpu_trace_destination { · 50 unmodified lines | ||
| 134 | 141 | /* |
| 135 | 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 | 145 | #define VPU_TRACE_PROC_BIT_LRT 1 |
| 139 | 146 | #define VPU_TRACE_PROC_BIT_LNN 2 |
| 140 | 147 | #define VPU_TRACE_PROC_BIT_SHV_0 3 |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | /* |
| 23 | 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 | 28 | * API header changed (field names, documentation, formatting) but API itself has not been changed |
| @@ -53,8 +53,7 @@ · 24 unmodified lines | ||
| 53 | 53 | * Engine indexes. |
| 54 | 54 | */ |
| 55 | 55 | #define VPU_ENGINE_COMPUTE 0 |
| 56 | −#define VPU_ENGINE_COPY 1 | |
| 57 | −#define VPU_ENGINE_NB 2 | |
| 56 | +#define VPU_ENGINE_NB 1 | |
| 58 | 57 | |
| 59 | 58 | /* |
| 60 | 59 | * VPU status values. |
| @@ -126,11 +125,13 @@ enum { · 65 unmodified lines | ||
| 126 | 125 | * When set, indicates that job queue uses native fences (as inline commands |
| 127 | 126 | * in job queue). Such queues may also use legacy fences (as commands in batch buffers). |
| 128 | 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 | |
| 130 | − * are immediately followed by an inline command object. This object is expected | |
| 131 | − * to be a fence signal command in most cases, but can also be a NOP in case the host | |
| 132 | − * does not need per-job fence signalling. Other inline commands objects can be | |
| 133 | − * inserted between "job and inline command" pairs. | |
| 128 | + * NOTES: | |
| 129 | + * 1. For queues using native fences, VPU expects that all jobs in the queue | |
| 130 | + * are immediately followed by an inline command object. This object is expected | |
| 131 | + * to be a fence signal command in most cases, but can also be a NOP in case the host | |
| 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 | 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 | 276 | u64 value; |
| 276 | 277 | /* User VA of the log buffer in which to add log entry on completion. */ |
| 277 | 278 | u64 log_buffer_va; |
| 279 | + /* NPU private data. */ | |
| 280 | + u64 npu_private_data; | |
| 278 | 281 | } fence; |
| 279 | 282 | /* Other commands do not have a payload. */ |
| 280 | 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 | 794 | /** Metric group mask that identifies metric streamer instance. */ |
| 792 | 795 | u64 metric_group_mask; |
| 793 | 796 | /** |
| 794 | − * Address and size of the buffer where the VPU will write metric data. If | |
| 795 | − * the buffer address is 0 or same as the currently used buffer the VPU will | |
| 796 | − * continue writing metric data to the current buffer. In this case the | |
| 797 | − * buffer size is ignored and the size of the current buffer is unchanged. | |
| 798 | − * If the address is non-zero and differs from the current buffer address the | |
| 799 | − * VPU will immediately switch data collection to the new buffer. | |
| 797 | + * Address and size of the buffer where the VPU will write metric data. | |
| 798 | + * This member dictates how the update operation should perform: | |
| 799 | + * 1. client needs information about the number of collected samples and the | |
| 800 | + * amount of data written to the current buffer | |
| 801 | + * 2. client wants to switch to a 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 | 814 | u64 buffer_addr; |
| 802 | 815 | u64 buffer_size; |
| @@ -934,6 +947,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { · 131 unmodified lines | ||
| 934 | 947 | /* |
| 935 | 948 | * Default quantum in 100ns units for scheduling across processes |
| 936 | 949 | * within a priority band |
| 950 | + * Minimum value supported by NPU is 1ms (10000 in 100ns units). | |
| 937 | 951 | */ |
| 938 | 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 | 960 | * in situations when it's starved by the focus band. |
| 947 | 961 | */ |
| 948 | 962 | u32 normal_band_percentage; |
| 949 | − /* Reserved */ | |
| 950 | − u32 reserved_0; | |
| 963 | + /* | |
| 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 | 1040 | s32 in_process_priority; |
| 1025 | 1041 | /* Zero padding / Reserved */ |
| 1026 | 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 | 1047 | u64 context_quantum; |
| 1029 | 1048 | /* Grace period when preempting context of the same priority within the same process */ |
| 1030 | 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 | 293 | * expected_return_btypes - Allowed type(s) for the return value |
| 294 | 294 | */ |
| 295 | 295 | struct acpi_name_info { |
| 296 | − char name[ACPI_NAMESEG_SIZE]; | |
| 296 | + char name[ACPI_NAMESEG_SIZE] __nonstring; | |
| 297 | 297 | u16 argument_list; |
| 298 | 298 | u8 expected_btypes; |
| 299 | 299 | }; |
| @@ -370,7 +370,7 @@ typedef acpi_status (*acpi_object_converter) (struct acpi_namespace_node * · 70 unmodified lines | ||
| 370 | 370 | converted_object); |
| 371 | 371 | |
| 372 | 372 | struct acpi_simple_repair_info { |
| 373 | − char name[ACPI_NAMESEG_SIZE]; | |
| 373 | + char name[ACPI_NAMESEG_SIZE] __nonstring; | |
| 374 | 374 | u32 unexpected_btypes; |
| 375 | 375 | u32 package_index; |
| 376 | 376 | acpi_object_converter object_converter; |
| @@ -25,7 +25,7 @@ acpi_status (*acpi_repair_function) (struct acpi_evaluate_info * info, · 24 unmodified lines | ||
| 25 | 25 | return_object_ptr); |
| 26 | 26 | |
| 27 | 27 | typedef struct acpi_repair_info { |
| 28 | − char name[ACPI_NAMESEG_SIZE]; | |
| 28 | + char name[ACPI_NAMESEG_SIZE] __nonstring; | |
| 29 | 29 | acpi_repair_function repair_function; |
| 30 | 30 | |
| 31 | 31 | } acpi_repair_info; |
| @@ -458,7 +458,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) · 457 unmodified lines | ||
| 458 | 458 | acpi_pm_wakeup_event(&device->dev); |
| 459 | 459 | |
| 460 | 460 | button = acpi_driver_data(device); |
| 461 | − if (button->suspended) | |
| 461 | + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) | |
| 462 | 462 | return; |
| 463 | 463 | |
| 464 | 464 | input = button->input; |
| @@ -2301,6 +2301,34 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { · 2300 unmodified lines | ||
| 2301 | 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 | 229 | node_entry = ACPI_PTR_DIFF(node, table_hdr); |
| 230 | 230 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
| 231 | 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 | 236 | cpu_node = (struct acpi_pptt_processor *)entry; |
| 237 | + | |
| 236 | 238 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && |
| 237 | 239 | cpu_node->parent == node_entry) |
| 238 | 240 | return 0; |
| 239 | 241 | if (entry->length == 0) |
| 240 | 242 | return 0; |
| 243 | + | |
| 241 | 244 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, |
| 242 | 245 | entry->length); |
| 243 | − | |
| 244 | 246 | } |
| 245 | 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 | 272 | table_end = (unsigned long)table_hdr + table_hdr->length; |
| 271 | 273 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
| 272 | 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 | 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 | 279 | cpu_node = (struct acpi_pptt_processor *)entry; |
| 278 | 280 | |
| 279 | 281 | if (entry->length == 0) { |
| 280 | 282 | pr_warn("Invalid zero length subtable\n"); |
| 281 | 283 | break; |
| 282 | 284 | } |
| 285 | + /* entry->length may not equal proc_sz, revalidate the processor structure length */ | |
| 283 | 286 | if (entry->type == ACPI_PPTT_TYPE_PROCESSOR && |
| 284 | 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 | 290 | acpi_pptt_leaf_node(table_hdr, cpu_node)) { |
| 286 | 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 | 6373 | seq_printf(m, " node %d", buffer->target_node->debug_id); |
| 6374 | 6374 | seq_printf(m, " size %zd:%zd offset %lx\n", |
| 6375 | 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 | 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 | 1510 | unsigned int err_mask, tag; |
| 1511 | 1511 | u8 *sense, sk = 0, asc = 0, ascq = 0; |
| 1512 | 1512 | u64 sense_valid, val; |
| 1513 | + u16 extended_sense; | |
| 1514 | + bool aux_icc_valid; | |
| 1513 | 1515 | int ret = 0; |
| 1514 | 1516 | |
| 1515 | 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 | 1532 | sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) | |
| 1531 | 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 | 1537 | ata_qc_for_each_raw(ap, qc, tag) { |
| 1534 | 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 | 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 | 1574 | /* Set sense without also setting scsicmd->result */ |
| 1560 | 1575 | scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, |
| 1561 | 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 | 2454 | put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]); |
| 2455 | 2455 | |
| 2456 | − if (dev->flags & ATA_DFLAG_CDL) | |
| 2457 | − buf[4] = 0x02; /* Support T2A and T2B pages */ | |
| 2456 | + if (dev->flags & ATA_DFLAG_CDL_ENABLED) | |
| 2457 | + buf[4] = 0x02; /* T2A and T2B pages enabled */ | |
| 2458 | 2458 | else |
| 2459 | 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 | 3890 | * page) into a SET FEATURES command. |
| 3891 | 3891 | */ |
| 3892 | −static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, | |
| 3893 | − const u8 *buf, int len, | |
| 3894 | − u16 *fp) | |
| 3892 | +static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, | |
| 3893 | + const u8 *buf, int len, u16 *fp) | |
| 3895 | 3894 | { |
| 3896 | 3895 | struct ata_device *dev = qc->dev; |
| 3897 | 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 | 3908 | /* Check cdl_ctrl */ |
| 3910 | 3909 | switch (buf[0] & 0x03) { |
| 3911 | 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 | 3915 | cdl_action = 0; |
| 3914 | 3916 | dev->flags &= ~ATA_DFLAG_CDL_ENABLED; |
| 3915 | 3917 | break; |
| 3916 | 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 | 3926 | if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { |
| 3919 | 3927 | ata_dev_err(dev, |
| 3920 | 3928 | "NCQ priority must be disabled to enable CDL\n"); |
| 3921 | 3929 | return -EINVAL; |
| 3922 | 3930 | } |
| 3931 | + ata_dev_dbg(dev, "Enabling CDL\n"); | |
| 3923 | 3932 | cdl_action = 1; |
| 3924 | 3933 | dev->flags |= ATA_DFLAG_CDL_ENABLED; |
| 3925 | 3934 | break; |
| @@ -223,10 +223,16 @@ static int pxa_ata_probe(struct platform_device *pdev) · 222 unmodified lines | ||
| 223 | 223 | |
| 224 | 224 | ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start, |
| 225 | 225 | resource_size(cmd_res)); |
| 226 | + if (!ap->ioaddr.cmd_addr) | |
| 227 | + return -ENOMEM; | |
| 226 | 228 | ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, |
| 227 | 229 | resource_size(ctl_res)); |
| 230 | + if (!ap->ioaddr.ctl_addr) | |
| 231 | + return -ENOMEM; | |
| 228 | 232 | ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start, |
| 229 | 233 | resource_size(dma_res)); |
| 234 | + if (!ap->ioaddr.bmdma_addr) | |
| 235 | + return -ENOMEM; | |
| 230 | 236 | |
| 231 | 237 | /* |
| 232 | 238 | * Adjust register offsets |
| @@ -1117,9 +1117,14 @@ static int pdc20621_prog_dimm0(struct ata_host *host) · 1116 unmodified lines | ||
| 1117 | 1117 | mmio += PDC_CHIP0_OFS; |
| 1118 | 1118 | |
| 1119 | 1119 | for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++) |
| 1120 | − pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, | |
| 1121 | − pdc_i2c_read_data[i].reg, | |
| 1122 | − &spd0[pdc_i2c_read_data[i].ofs]); | |
| 1120 | + if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, | |
| 1121 | + pdc_i2c_read_data[i].reg, | |
| 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 | 1129 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); |
| 1125 | 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 | 1290 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ |
| 1286 | 1291 | size = pdc20621_prog_dimm0(host); |
| 1292 | + if (size < 0) | |
| 1293 | + return size; | |
| 1287 | 1294 | dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size); |
| 1288 | 1295 | |
| 1289 | 1296 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ |
| @@ -156,6 +156,16 @@ · 155 unmodified lines | ||
| 156 | 156 | * }, |
| 157 | 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 | 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 | 73 | kset_put(&sp->subsys); |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | +struct subsys_private *bus_to_subsys(const struct bus_type *bus); | |
| 76 | 77 | struct subsys_private *class_to_subsys(const struct class *class); |
| 77 | 78 | |
| 78 | 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 | 181 | void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); |
| 181 | 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 | 200 | int devres_release_all(struct device *dev); |
| 184 | 201 | void device_block_probing(void); |
| 185 | 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 | 57 | * NULL. A call to subsys_put() must be done when finished with the pointer in |
| 58 | 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 | 62 | struct subsys_private *sp = NULL; |
| 63 | 63 | struct kobject *kobj; |
| @@ -2624,6 +2624,35 @@ static const char *dev_uevent_name(const struct kobject *kobj) · 2623 unmodified lines | ||
| 2624 | 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 | 2656 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
| 2628 | 2657 | { |
| 2629 | 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 | 2684 | if (dev->type && dev->type->name) |
| 2656 | 2685 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
| 2657 | 2686 | |
| 2658 | − if (dev->driver) | |
| 2659 | − add_uevent_var(env, "DRIVER=%s", dev->driver->name); | |
| 2687 | + /* Add "DRIVER=%s" variable if the device is bound to a driver */ | |
| 2688 | + dev_driver_uevent(dev, env); | |
| 2660 | 2689 | |
| 2661 | 2690 | /* Add common DT information about the device */ |
| 2662 | 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 | 2755 | if (!env) |
| 2727 | 2756 | return -ENOMEM; |
| 2728 | 2757 | |
| 2729 | − /* Synchronize with really_probe() */ | |
| 2730 | − device_lock(dev); | |
| 2731 | 2758 | /* let the kset specific function add its keys */ |
| 2732 | 2759 | retval = kset->uevent_ops->uevent(&dev->kobj, env); |
| 2733 | − device_unlock(dev); | |
| 2734 | 2760 | if (retval) |
| 2735 | 2761 | goto out; |
| 2736 | 2762 | |
| @@ -3700,7 +3726,7 @@ done: · 963 unmodified lines | ||
| 3700 | 3726 | device_pm_remove(dev); |
| 3701 | 3727 | dpm_sysfs_remove(dev); |
| 3702 | 3728 | DPMError: |
| 3703 | − dev->driver = NULL; | |
| 3729 | + device_set_driver(dev, NULL); | |
| 3704 | 3730 | bus_remove_device(dev); |
| 3705 | 3731 | BusError: |
| 3706 | 3732 | device_remove_attrs(dev); |
| @@ -600,6 +600,7 @@ CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); · 599 unmodified lines | ||
| 600 | 600 | CPU_SHOW_VULN_FALLBACK(gds); |
| 601 | 601 | CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); |
| 602 | 602 | CPU_SHOW_VULN_FALLBACK(ghostwrite); |
| 603 | +CPU_SHOW_VULN_FALLBACK(indirect_target_selection); | |
| 603 | 604 | |
| 604 | 605 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 605 | 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 | 617 | static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); |
| 617 | 618 | static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); |
| 618 | 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 | 622 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 621 | 623 | &dev_attr_meltdown.attr, |
| @@ -633,6 +635,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { · 11 unmodified lines | ||
| 633 | 635 | &dev_attr_gather_data_sampling.attr, |
| 634 | 636 | &dev_attr_reg_file_data_sampling.attr, |
| 635 | 637 | &dev_attr_ghostwrite.attr, |
| 638 | + &dev_attr_indirect_target_selection.attr, | |
| 636 | 639 | NULL |
| 637 | 640 | }; |
| 638 | 641 | |
| @@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct device *dev) · 549 unmodified lines | ||
| 550 | 550 | arch_teardown_dma_ops(dev); |
| 551 | 551 | kfree(dev->dma_range_map); |
| 552 | 552 | dev->dma_range_map = NULL; |
| 553 | − dev->driver = NULL; | |
| 553 | + device_set_driver(dev, NULL); | |
| 554 | 554 | dev_set_drvdata(dev, NULL); |
| 555 | 555 | if (dev->pm_domain && dev->pm_domain->dismiss) |
| 556 | 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 | 631 | re_probe: |
| 632 | − // FIXME - this cast should not be needed "soon" | |
| 633 | − dev->driver = (struct device_driver *)drv; | |
| 632 | + device_set_driver(dev, drv); | |
| 634 | 633 | |
| 635 | 634 | /* If using pinctrl, bind pins now before probing */ |
| 636 | 635 | ret = pinctrl_bind_pins(dev); |
| @@ -1014,7 +1013,7 @@ static int __device_attach(struct device *dev, bool allow_async) · 377 unmodified lines | ||
| 1014 | 1013 | if (ret == 0) |
| 1015 | 1014 | ret = 1; |
| 1016 | 1015 | else { |
| 1017 | − dev->driver = NULL; | |
| 1016 | + device_set_driver(dev, NULL); | |
| 1018 | 1017 | ret = 0; |
| 1019 | 1018 | } |
| 1020 | 1019 | } else { |
| @@ -296,7 +296,7 @@ static int delete_path(const char *nodepath) · 295 unmodified lines | ||
| 296 | 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 | 301 | /* did we create it */ |
| 302 | 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 | 305 | /* does the dev_t match */ |
| 306 | 306 | if (is_blockdev(dev)) { |
| 307 | − if (!S_ISBLK(stat->mode)) | |
| 307 | + if (!S_ISBLK(inode->i_mode)) | |
| 308 | 308 | return 0; |
| 309 | 309 | } else { |
| 310 | − if (!S_ISCHR(stat->mode)) | |
| 310 | + if (!S_ISCHR(inode->i_mode)) | |
| 311 | 311 | return 0; |
| 312 | 312 | } |
| 313 | − if (stat->rdev != dev->devt) | |
| 313 | + if (inode->i_rdev != dev->devt) | |
| 314 | 314 | return 0; |
| 315 | 315 | |
| 316 | 316 | /* ours */ |
| @@ -321,20 +321,16 @@ static int handle_remove(const char *nodename, struct device *dev) · 4 unmodified lines | ||
| 321 | 321 | { |
| 322 | 322 | struct path parent; |
| 323 | 323 | struct dentry *dentry; |
| 324 | − struct kstat stat; | |
| 325 | − struct path p; | |
| 324 | + struct inode *inode; | |
| 326 | 325 | int deleted = 0; |
| 327 | − int err; | |
| 326 | + int err = 0; | |
| 328 | 327 | |
| 329 | 328 | dentry = kern_path_locked(nodename, &parent); |
| 330 | 329 | if (IS_ERR(dentry)) |
| 331 | 330 | return PTR_ERR(dentry); |
| 332 | 331 | |
| 333 | − p.mnt = parent.mnt; | |
| 334 | − p.dentry = dentry; | |
| 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)) { | |
| 332 | + inode = d_inode(dentry); | |
| 333 | + if (dev_mynode(dev, inode)) { | |
| 338 | 334 | struct iattr newattrs; |
| 339 | 335 | /* |
| 340 | 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 | 339 | newattrs.ia_uid = GLOBAL_ROOT_UID; |
| 344 | 340 | newattrs.ia_gid = GLOBAL_ROOT_GID; |
| 345 | − newattrs.ia_mode = stat.mode & ~0777; | |
| 341 | + newattrs.ia_mode = inode->i_mode & ~0777; | |
| 346 | 342 | newattrs.ia_valid = |
| 347 | 343 | ATTR_UID|ATTR_GID|ATTR_MODE; |
| 348 | 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 | 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 | 819 | static int add_hotplug_memory_block(unsigned long block_id, |
| 835 | 820 | struct vmem_altmap *altmap, |
| 836 | 821 | struct memory_group *group) |
| @@ -957,7 +942,7 @@ static const struct attribute_group *memory_root_attr_groups[] = { · 120 unmodified lines | ||
| 957 | 942 | void __init memory_dev_init(void) |
| 958 | 943 | { |
| 959 | 944 | int ret; |
| 960 | − unsigned long block_sz, nr; | |
| 945 | + unsigned long block_sz, block_id, nr; | |
| 961 | 946 | |
| 962 | 947 | /* Validate the configured memory block size */ |
| 963 | 948 | block_sz = memory_block_size_bytes(); |
| @@ -970,15 +955,23 @@ void __init memory_dev_init(void) · 6 unmodified lines | ||
| 970 | 955 | panic("%s() failed to register subsystem: %d\n", __func__, ret); |
| 971 | 956 | |
| 972 | 957 | /* |
| 973 | − * Create entries for memory sections that were found | |
| 974 | − * during boot and have been initialized | |
| 958 | + * Create entries for memory sections that were found during boot | |
| 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; | |
| 977 | − nr += sections_per_block) { | |
| 978 | − ret = add_boot_memory_block(nr); | |
| 979 | − if (ret) | |
| 980 | − panic("%s() failed to add memory block: %d\n", __func__, | |
| 981 | − ret); | |
| 964 | + block_id = ULONG_MAX; | |
| 965 | + for_each_present_section_nr(0, nr) { | |
| 966 | + if (block_id != ULONG_MAX && memory_block_id(nr) == block_id) | |
| 967 | + continue; | |
| 968 | + | |
| 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 | 42 | if (mod) |
| 43 | 43 | mk = &mod->mkobj; |
| 44 | 44 | else if (drv->mod_name) { |
| 45 | − struct kobject *mkobj; | |
| 46 | − | |
| 47 | − /* Lookup built-in module entry in /sys/modules */ | |
| 48 | − mkobj = kset_find_obj(module_kset, drv->mod_name); | |
| 49 | − if (mkobj) { | |
| 50 | − mk = container_of(mkobj, struct module_kobject, kobj); | |
| 45 | + /* Lookup or create built-in module entry in /sys/modules */ | |
| 46 | + mk = lookup_or_create_module_kobject(drv->mod_name); | |
| 47 | + if (mk) { | |
| 51 | 48 | /* remember our module structure */ |
| 52 | 49 | drv->p->mkobj = mk; |
| 53 | − /* kset_find_obj took a reference */ | |
| 54 | − kobject_put(mkobj); | |
| 50 | + /* lookup_or_create_module_kobject took a reference */ | |
| 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 | 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 | 1444 | struct fwnode_handle *fwnode = dev_fwnode(dev); |
| 1445 | 1445 | enum dev_dma_attr attr; |
| 1446 | 1446 | int ret = 0; |
| @@ -1451,8 +1451,8 @@ static int platform_dma_configure(struct device *dev) · 4 unmodified lines | ||
| 1451 | 1451 | attr = acpi_get_dma_attr(to_acpi_device_node(fwnode)); |
| 1452 | 1452 | ret = acpi_dma_configure(dev, attr); |
| 1453 | 1453 | } |
| 1454 | − /* @drv may not be valid when we're called from the IOMMU layer */ | |
| 1455 | − if (ret || !dev->driver || drv->driver_managed_dma) | |
| 1454 | + /* @dev->driver may not be valid when we're called from the IOMMU layer */ | |
| 1455 | + if (ret || !drv || to_platform_driver(drv)->driver_managed_dma) | |
| 1456 | 1456 | return ret; |
| 1457 | 1457 | |
| 1458 | 1458 | ret = iommu_device_use_default_domain(dev); |
| @@ -1080,6 +1080,7 @@ void software_node_notify(struct device *dev) · 1079 unmodified lines | ||
| 1080 | 1080 | if (!swnode) |
| 1081 | 1081 | return; |
| 1082 | 1082 | |
| 1083 | + kobject_get(&swnode->kobj); | |
| 1083 | 1084 | ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node"); |
| 1084 | 1085 | if (ret) |
| 1085 | 1086 | return; |
| @@ -1089,8 +1090,6 @@ void software_node_notify(struct device *dev) · 3 unmodified lines | ||
| 1089 | 1090 | sysfs_remove_link(&dev->kobj, "software_node"); |
| 1090 | 1091 | return; |
| 1091 | 1092 | } |
| 1092 | − | |
| 1093 | − kobject_get(&swnode->kobj); | |
| 1094 | 1093 | } |
| 1095 | 1094 | |
| 1096 | 1095 | void software_node_notify_remove(struct device *dev) |
| @@ -367,7 +367,7 @@ config BLK_DEV_RBD · 366 unmodified lines | ||
| 367 | 367 | tristate "Rados block device (RBD)" |
| 368 | 368 | depends on INET && BLOCK |
| 369 | 369 | select CEPH_LIB |
| 370 | − select LIBCRC32C | |
| 370 | + select CRC32 | |
| 371 | 371 | select CRYPTO_AES |
| 372 | 372 | select CRYPTO |
| 373 | 373 | help |
| @@ -388,12 +388,6 @@ config BLK_DEV_UBLK · 14 unmodified lines | ||
| 388 | 388 | definition isn't finalized yet, and might change according to future |
| 389 | 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 | 391 | config BLKDEV_UBLK_LEGACY_OPCODES |
| 398 | 392 | bool "Support legacy command opcode" |
| 399 | 393 | depends on BLK_DEV_UBLK |
| @@ -10,7 +10,7 @@ config BLK_DEV_DRBD · 9 unmodified lines | ||
| 10 | 10 | tristate "DRBD Distributed Replicated Block Device support" |
| 11 | 11 | depends on PROC_FS && INET |
| 12 | 12 | select LRU_CACHE |
| 13 | − select LIBCRC32C | |
| 13 | + select CRC32 | |
| 14 | 14 | help |
| 15 | 15 | |
| 16 | 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 | 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 | 214 | static void loop_clear_limits(struct loop_device *lo, int mode) |
| 281 | 215 | { |
| 282 | 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 | 276 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 343 | 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 | 280 | req_op(rq) != REQ_OP_READ) { |
| 347 | 281 | if (cmd->ret < 0) |
| 348 | 282 | ret = errno_to_blk_status(cmd->ret); |
| @@ -358,14 +292,13 @@ static void lo_complete_rq(struct request *rq) · 9 unmodified lines | ||
| 358 | 292 | cmd->ret = 0; |
| 359 | 293 | blk_mq_requeue_request(rq, true); |
| 360 | 294 | } else { |
| 361 | − if (cmd->use_aio) { | |
| 362 | − struct bio *bio = rq->bio; | |
| 295 | + struct bio *bio = rq->bio; | |
| 363 | 296 | |
| 364 | − while (bio) { | |
| 365 | − zero_fill_bio(bio); | |
| 366 | − bio = bio->bi_next; | |
| 367 | − } | |
| 297 | + while (bio) { | |
| 298 | + zero_fill_bio(bio); | |
| 299 | + bio = bio->bi_next; | |
| 368 | 300 | } |
| 301 | + | |
| 369 | 302 | ret = BLK_STS_IOERR; |
| 370 | 303 | end_io: |
| 371 | 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 | 379 | cmd->iocb.ki_pos = pos; |
| 447 | 380 | cmd->iocb.ki_filp = file; |
| 448 | − cmd->iocb.ki_complete = lo_rw_aio_complete; | |
| 449 | − cmd->iocb.ki_flags = IOCB_DIRECT; | |
| 450 | − cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0); | |
| 381 | + cmd->iocb.ki_ioprio = req_get_ioprio(rq); | |
| 382 | + if (cmd->use_aio) { | |
| 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 | 390 | if (rw == ITER_SOURCE) |
| 453 | 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 | 397 | if (ret != -EIOCBQUEUED) |
| 460 | 398 | lo_rw_aio_complete(&cmd->iocb, ret); |
| 461 | − return 0; | |
| 399 | + return -EIOCBQUEUED; | |
| 462 | 400 | } |
| 463 | 401 | |
| 464 | 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 | 404 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 467 | 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 | 407 | switch (req_op(rq)) { |
| 479 | 408 | case REQ_OP_FLUSH: |
| 480 | 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 | 419 | case REQ_OP_DISCARD: |
| 491 | 420 | return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); |
| 492 | 421 | case REQ_OP_WRITE: |
| 493 | − if (cmd->use_aio) | |
| 494 | − return lo_rw_aio(lo, cmd, pos, ITER_SOURCE); | |
| 495 | − else | |
| 496 | − return lo_write_simple(lo, rq, pos); | |
| 422 | + return lo_rw_aio(lo, cmd, pos, ITER_SOURCE); | |
| 497 | 423 | case REQ_OP_READ: |
| 498 | − if (cmd->use_aio) | |
| 499 | − return lo_rw_aio(lo, cmd, pos, ITER_DEST); | |
| 500 | − else | |
| 501 | − return lo_read_simple(lo, rq, pos); | |
| 424 | + return lo_rw_aio(lo, cmd, pos, ITER_DEST); | |
| 502 | 425 | default: |
| 503 | 426 | WARN_ON_ONCE(1); |
| 504 | 427 | return -EIO; |
| @@ -582,6 +505,17 @@ static void loop_assign_backing_file(struct loop_device *lo, struct file *file) · 77 unmodified lines | ||
| 582 | 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 | 520 | * loop_change_fd switched the backing store of a loopback device to |
| 587 | 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 | 537 | if (!file) |
| 604 | 538 | return -EBADF; |
| 605 | 539 | |
| 540 | + error = loop_check_backing_file(file); | |
| 541 | + if (error) | |
| 542 | + return error; | |
| 543 | + | |
| 606 | 544 | /* suppress uevents while reconfiguring the device */ |
| 607 | 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 | 600 | * dependency. |
| 663 | 601 | */ |
| 664 | 602 | fput(old_file); |
| 603 | + dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | |
| 665 | 604 | if (partscan) |
| 666 | 605 | loop_reread_partitions(lo); |
| 667 | 606 | |
| 668 | 607 | error = 0; |
| 669 | 608 | done: |
| 670 | − /* enable and uncork uevent now that we are done */ | |
| 671 | − dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | |
| 609 | + kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); | |
| 672 | 610 | return error; |
| 673 | 611 | |
| 674 | 612 | out_err: |
| 675 | 613 | loop_global_unlock(lo, is_loop); |
| 676 | 614 | out_putf: |
| 677 | 615 | fput(file); |
| 616 | + dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0); | |
| 678 | 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 | 979 | if (!file) |
| 1041 | 980 | return -EBADF; |
| 981 | + | |
| 982 | + error = loop_check_backing_file(file); | |
| 983 | + if (error) | |
| 984 | + return error; | |
| 985 | + | |
| 1042 | 986 | is_loop = is_loop_device(file); |
| 1043 | 987 | |
| 1044 | 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 | 1073 | if (partscan) |
| 1130 | 1074 | clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); |
| 1131 | 1075 | |
| 1132 | − /* enable and uncork uevent now that we are done */ | |
| 1133 | 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 | 1079 | loop_global_unlock(lo, is_loop); |
| 1136 | 1080 | if (partscan) |
| @@ -1921,7 +1865,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 784 unmodified lines | ||
| 1921 | 1865 | struct loop_device *lo = rq->q->queuedata; |
| 1922 | 1866 | int ret = 0; |
| 1923 | 1867 | struct mem_cgroup *old_memcg = NULL; |
| 1924 | − const bool use_aio = cmd->use_aio; | |
| 1925 | 1868 | |
| 1926 | 1869 | if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) { |
| 1927 | 1870 | ret = -EIO; |
| @@ -1951,7 +1894,7 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 23 unmodified lines | ||
| 1951 | 1894 | } |
| 1952 | 1895 | failed: |
| 1953 | 1896 | /* complete non-aio request */ |
| 1954 | − if (!use_aio || ret) { | |
| 1897 | + if (ret != -EIOCBQUEUED) { | |
| 1955 | 1898 | if (ret == -EOPNOTSUPP) |
| 1956 | 1899 | cmd->ret = ret; |
| 1957 | 1900 | else |
| @@ -2031,7 +2031,7 @@ static int null_add_dev(struct nullb_device *dev) · 2030 unmodified lines | ||
| 2031 | 2031 | nullb->disk->minors = 1; |
| 2032 | 2032 | nullb->disk->fops = &null_ops; |
| 2033 | 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 | 2036 | if (nullb->dev->zoned) { |
| 2037 | 2037 | rv = null_register_zoned_dev(nullb); |
| @@ -122,15 +122,6 @@ struct ublk_uring_cmd_pdu { · 121 unmodified lines | ||
| 122 | 122 | */ |
| 123 | 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 | 126 | * UBLK_IO_FLAG_NEED_GET_DATA is set because IO command requires |
| 136 | 127 | * get data buffer address from ublksrv. |
| @@ -199,8 +190,6 @@ struct ublk_device { · 62 unmodified lines | ||
| 199 | 190 | struct completion completion; |
| 200 | 191 | unsigned int nr_queues_ready; |
| 201 | 192 | unsigned int nr_privileged_daemon; |
| 202 | − | |
| 203 | − struct work_struct nosrv_work; | |
| 204 | 193 | }; |
| 205 | 194 | |
| 206 | 195 | /* header of ublk_params */ |
| @@ -209,18 +198,13 @@ struct ublk_params_header { · 2 unmodified lines | ||
| 209 | 198 | __u32 types; |
| 210 | 199 | }; |
| 211 | 200 | |
| 212 | −static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq); | |
| 213 | − | |
| 201 | +static void ublk_stop_dev_unlocked(struct ublk_device *ub); | |
| 202 | +static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq); | |
| 214 | 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 | 205 | static inline unsigned int ublk_req_build_flags(struct request *req); |
| 217 | 206 | static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq, |
| 218 | 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 | 208 | static inline bool ublk_dev_is_zoned(const struct ublk_device *ub) |
| 225 | 209 | { |
| 226 | 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 | 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 | 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 | 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 | 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 | 625 | * read()/write() is involved in user copy, so request reference |
| 637 | 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 | 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 | 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 | 1072 | /* todo: handle partial completion */ |
| @@ -1085,12 +1077,6 @@ static inline void __ublk_complete_rq(struct request *req) · 4 unmodified lines | ||
| 1085 | 1077 | unsigned int unmapped_bytes; |
| 1086 | 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 | 1080 | /* failed read IO if nothing is read */ |
| 1095 | 1081 | if (!io->res && req_op(req) == REQ_OP_READ) |
| 1096 | 1082 | io->res = -EIO; |
| @@ -1140,25 +1126,6 @@ static void ublk_complete_rq(struct kref *ref) · 43 unmodified lines | ||
| 1140 | 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 | 1129 | static void ubq_complete_io_cmd(struct ublk_io *io, int res, |
| 1163 | 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 | 1281 | static enum blk_eh_timer_return ublk_timeout(struct request *rq) |
| 1315 | 1282 | { |
| 1316 | 1283 | struct ublk_queue *ubq = rq->mq_hctx->driver_data; |
| 1317 | − unsigned int nr_inflight = 0; | |
| 1318 | − int i; | |
| 1319 | 1284 | |
| 1320 | 1285 | if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) { |
| 1321 | 1286 | if (!ubq->timeout) { |
| @@ -1326,30 +1291,11 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq) · 4 unmodified lines | ||
| 1326 | 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 | 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 | 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 | 1314 | if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) |
| 1369 | 1315 | return BLK_STS_IOERR; |
| 1370 | 1316 | |
| 1371 | − if (unlikely(ubq->canceling)) | |
| 1317 | + if (check_cancel && unlikely(ubq->canceling)) | |
| 1372 | 1318 | return BLK_STS_IOERR; |
| 1373 | 1319 | |
| 1374 | 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 | 1333 | struct request *rq = bd->rq; |
| 1388 | 1334 | blk_status_t res; |
| 1389 | 1335 | |
| 1390 | − res = ublk_prep_req(ubq, rq); | |
| 1336 | + res = ublk_prep_req(ubq, rq, false); | |
| 1391 | 1337 | if (res != BLK_STS_OK) |
| 1392 | 1338 | return res; |
| 1393 | 1339 | |
| @@ -1419,7 +1365,7 @@ static void ublk_queue_rqs(struct rq_list *rqlist) · 25 unmodified lines | ||
| 1419 | 1365 | ublk_queue_cmd_list(ubq, &submit_list); |
| 1420 | 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 | 1369 | rq_list_add_tail(&submit_list, req); |
| 1424 | 1370 | else |
| 1425 | 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 | 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 | 1427 | static int ublk_ch_open(struct inode *inode, struct file *filp) |
| 1451 | 1428 | { |
| 1452 | 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 | 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 | 1470 | static int ublk_ch_release(struct inode *inode, struct file *filp) |
| 1462 | 1471 | { |
| 1463 | 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 | 1551 | clear_bit(UB_STATE_OPEN, &ub->state); |
| 1466 | 1552 | return 0; |
| 1467 | 1553 | } |
| @@ -1528,10 +1614,26 @@ static void ublk_commit_completion(struct ublk_device *ub, · 60 unmodified lines | ||
| 1528 | 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 | |
| 1533 | − * blk-mq queue, so we are called exclusively with blk-mq and ubq_daemon | |
| 1534 | − * context, so everything is serialized. | |
| 1631 | + * Called from ublk char device release handler, when any uring_cmd is | |
| 1632 | + * done, meantime request queue is "quiesced" since all inflight requests | |
| 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 | 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 | 1650 | * will do it |
| 1549 | 1651 | */ |
| 1550 | 1652 | rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i); |
| 1551 | − if (rq && blk_mq_request_started(rq)) { | |
| 1552 | − io->flags |= UBLK_IO_FLAG_ABORTED; | |
| 1653 | + if (rq && blk_mq_request_started(rq)) | |
| 1553 | 1654 | __ublk_fail_req(ubq, io, rq); |
| 1554 | − } | |
| 1555 | 1655 | } |
| 1556 | 1656 | } |
| 1557 | 1657 | } |
| 1558 | 1658 | |
| 1559 | 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 | 1662 | spin_lock(&ubq->cancel_lock); |
| 1565 | − canceled = ubq->canceling; | |
| 1566 | − if (!canceled) | |
| 1663 | + if (!ubq->canceling) | |
| 1567 | 1664 | ubq->canceling = true; |
| 1568 | 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; | |
| 1576 | − struct gendisk *disk; | |
| 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); | |
| 1670 | + struct ublk_device *ub = ubq->dev; | |
| 1671 | + struct gendisk *disk = ublk_get_disk(ub); | |
| 1586 | 1672 | |
| 1587 | 1673 | /* Our disk has been dead */ |
| 1588 | 1674 | if (!disk) |
| 1589 | − return false; | |
| 1590 | − | |
| 1675 | + return; | |
| 1591 | 1676 | /* |
| 1592 | 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 | 1681 | * touch completed uring_cmd |
| 1597 | 1682 | */ |
| 1598 | 1683 | blk_mq_quiesce_queue(disk->queue); |
| 1599 | − was_canceled = ublk_mark_queue_canceling(ubq); | |
| 1600 | − if (!was_canceled) { | |
| 1601 | − /* abort queue is for making forward progress */ | |
| 1602 | − ublk_abort_queue(ub, ubq); | |
| 1603 | − } | |
| 1684 | + ublk_mark_queue_canceling(ubq); | |
| 1604 | 1685 | blk_mq_unquiesce_queue(disk->queue); |
| 1605 | − put_device(disk_to_dev(disk)); | |
| 1606 | − | |
| 1607 | − return !was_canceled; | |
| 1686 | + ublk_put_disk(disk); | |
| 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 | 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 | 1695 | bool done; |
| 1614 | 1696 | |
| 1615 | 1697 | if (!(io->flags & UBLK_IO_FLAG_ACTIVE)) |
| 1616 | 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 | 1714 | spin_lock(&ubq->cancel_lock); |
| 1619 | 1715 | done = !!(io->flags & UBLK_IO_FLAG_CANCELED); |
| 1620 | 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 | 1725 | * The ublk char device won't be closed when calling cancel fn, so both |
| 1630 | 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 | 1739 | static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, |
| 1633 | 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 | 1742 | struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); |
| 1636 | 1743 | struct ublk_queue *ubq = pdu->ubq; |
| 1637 | 1744 | struct task_struct *task; |
| 1638 | − struct ublk_device *ub; | |
| 1639 | − bool need_schedule; | |
| 1640 | − struct ublk_io *io; | |
| 1641 | 1745 | |
| 1642 | 1746 | if (WARN_ON_ONCE(!ubq)) |
| 1643 | 1747 | return; |
| @@ -1649,16 +1753,11 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd, · 5 unmodified lines | ||
| 1649 | 1753 | if (WARN_ON_ONCE(task && task != ubq->ubq_daemon)) |
| 1650 | 1754 | return; |
| 1651 | 1755 | |
| 1652 | − ub = ubq->dev; | |
| 1653 | − need_schedule = ublk_abort_requests(ub, ubq); | |
| 1756 | + if (!ubq->canceling) | |
| 1757 | + ublk_start_cancel(ubq); | |
| 1654 | 1758 | |
| 1655 | − io = &ubq->ios[pdu->tag]; | |
| 1656 | − WARN_ON_ONCE(io->cmd != cmd); | |
| 1657 | − ublk_cancel_cmd(ubq, io, issue_flags); | |
| 1658 | − | |
| 1659 | − if (need_schedule) { | |
| 1660 | − schedule_work(&ub->nosrv_work); | |
| 1661 | − } | |
| 1759 | + WARN_ON_ONCE(ubq->ios[pdu->tag].cmd != cmd); | |
| 1760 | + ublk_cancel_cmd(ubq, pdu->tag, issue_flags); | |
| 1662 | 1761 | } |
| 1663 | 1762 | |
| 1664 | 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 | 1770 | int i; |
| 1672 | 1771 | |
| 1673 | 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 | 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) | |
| 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) | |
| 1811 | +static void ublk_force_abort_dev(struct ublk_device *ub) | |
| 1724 | 1812 | { |
| 1725 | 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 | 1816 | __func__, ub->dev_info.dev_id, |
| 1729 | 1817 | ub->dev_info.state == UBLK_S_DEV_LIVE ? |
| 1730 | 1818 | "LIVE" : "QUIESCED"); |
| 1731 | − /* quiesce_work has run. We let requeued rqs be aborted | |
| 1732 | − * before running fallback_wq. "force_abort" must be seen | |
| 1733 | − * after request queue is unqiuesced. Then del_gendisk() | |
| 1734 | − * can move on. | |
| 1735 | − */ | |
| 1819 | + blk_mq_quiesce_queue(ub->ub_disk->queue); | |
| 1820 | + if (ub->dev_info.state == UBLK_S_DEV_LIVE) | |
| 1821 | + ublk_wait_tagset_rqs_idle(ub); | |
| 1822 | + | |
| 1736 | 1823 | for (i = 0; i < ub->dev_info.nr_hw_queues; i++) |
| 1737 | 1824 | ublk_get_queue(ub, i)->force_abort = true; |
| 1738 | − | |
| 1739 | 1825 | blk_mq_unquiesce_queue(ub->ub_disk->queue); |
| 1740 | 1826 | /* We may have requeued some rqs in ublk_quiesce_queue() */ |
| 1741 | 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 | 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 | 1848 | struct gendisk *disk; |
| 1762 | 1849 | |
| 1763 | − mutex_lock(&ub->mutex); | |
| 1764 | 1850 | if (ub->dev_info.state == UBLK_S_DEV_DEAD) |
| 1765 | − goto unlock; | |
| 1766 | − if (ublk_nosrv_dev_should_queue_io(ub)) { | |
| 1767 | − if (ub->dev_info.state == UBLK_S_DEV_LIVE) | |
| 1768 | − __ublk_quiesce_dev(ub); | |
| 1769 | − ublk_unquiesce_dev(ub); | |
| 1770 | − } | |
| 1851 | + return; | |
| 1852 | + | |
| 1853 | + if (ublk_nosrv_dev_should_queue_io(ub)) | |
| 1854 | + ublk_force_abort_dev(ub); | |
| 1771 | 1855 | del_gendisk(ub->ub_disk); |
| 1772 | 1856 | disk = ublk_detach_disk(ub); |
| 1773 | 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 | 1864 | mutex_unlock(&ub->mutex); |
| 1776 | 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 = | |
| 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 | − } | |
| 1871 | + int i, j; | |
| 1789 | 1872 | |
| 1790 | − mutex_lock(&ub->mutex); | |
| 1791 | − if (ub->dev_info.state != UBLK_S_DEV_LIVE) | |
| 1792 | − goto unlock; | |
| 1873 | + for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { | |
| 1874 | + struct ublk_queue *ubq = ublk_get_queue(ub, i); | |
| 1793 | 1875 | |
| 1794 | − if (ublk_nosrv_dev_should_queue_io(ub)) { | |
| 1795 | − __ublk_quiesce_dev(ub); | |
| 1796 | − } else { | |
| 1797 | − blk_mq_quiesce_queue(ub->ub_disk->queue); | |
| 1798 | − ub->dev_info.state = UBLK_S_DEV_FAIL_IO; | |
| 1799 | − for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { | |
| 1800 | − ublk_get_queue(ub, i)->fail_io = true; | |
| 1801 | − } | |
| 1802 | − blk_mq_unquiesce_queue(ub->ub_disk->queue); | |
| 1876 | + /* UBLK_IO_FLAG_CANCELED can be cleared now */ | |
| 1877 | + spin_lock(&ubq->cancel_lock); | |
| 1878 | + for (j = 0; j < ubq->q_depth; j++) | |
| 1879 | + ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED; | |
| 1880 | + spin_unlock(&ubq->cancel_lock); | |
| 1881 | + ubq->canceling = false; | |
| 1882 | + ubq->fail_io = false; | |
| 1803 | 1883 | } |
| 1804 | − | |
| 1805 | − unlock: | |
| 1806 | − mutex_unlock(&ub->mutex); | |
| 1807 | − ublk_cancel_dev(ub); | |
| 1808 | 1884 | } |
| 1809 | 1885 | |
| 1810 | 1886 | /* device can only be started after all IOs are ready */ |
| 1811 | 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 | 1890 | ubq->nr_io_ready++; |
| 1815 | 1891 | if (ublk_queue_ready(ubq)) { |
| 1816 | 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 | 1896 | if (capable(CAP_SYS_ADMIN)) |
| 1821 | 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 | 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 | 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 | 1953 | unsigned int index, unsigned int issue_flags) |
| 1884 | 1954 | { |
| 1885 | 1955 | struct ublk_device *ub = cmd->file->private_data; |
| 1956 | + const struct ublk_io *io = &ubq->ios[tag]; | |
| 1886 | 1957 | struct request *req; |
| 1887 | 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 | 1966 | req = __ublk_check_and_get_req(ub, ubq, tag, 0); |
| 1890 | 1967 | if (!req) |
| 1891 | 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 | 1980 | static int ublk_unregister_io_buf(struct io_uring_cmd *cmd, |
| 1981 | + const struct ublk_queue *ubq, unsigned int tag, | |
| 1904 | 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 | 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 | 2041 | static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, |
| 1910 | 2042 | unsigned int issue_flags, |
| 1911 | 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 | 2092 | case UBLK_IO_REGISTER_IO_BUF: |
| 1961 | 2093 | return ublk_register_io_buf(cmd, ubq, tag, ub_cmd->addr, issue_flags); |
| 1962 | 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 | 2096 | case UBLK_IO_FETCH_REQ: |
| 1965 | − /* UBLK_IO_FETCH_REQ is only allowed before queue is setup */ | |
| 1966 | − if (ublk_queue_ready(ubq)) { | |
| 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; | |
| 2097 | + ret = ublk_fetch(cmd, ubq, io, ub_cmd->addr); | |
| 2098 | + if (ret) | |
| 1987 | 2099 | goto out; |
| 1988 | − } | |
| 1989 | − | |
| 1990 | − ublk_fill_io_cmd(io, cmd, ub_cmd->addr); | |
| 1991 | − ublk_mark_io_ready(ub, ubq); | |
| 1992 | 2100 | break; |
| 1993 | 2101 | case UBLK_IO_COMMIT_AND_FETCH_REQ: |
| 1994 | 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 | 2128 | if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) |
| 2021 | 2129 | goto out; |
| 2022 | 2130 | ublk_fill_io_cmd(io, cmd, ub_cmd->addr); |
| 2023 | − ublk_handle_need_get_data(ub, ub_cmd->q_id, ub_cmd->tag); | |
| 2024 | − break; | |
| 2131 | + req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag); | |
| 2132 | + ublk_dispatch_req(ubq, req, issue_flags); | |
| 2133 | + return -EIOCBQUEUED; | |
| 2025 | 2134 | default: |
| 2026 | 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 | 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 | 2149 | struct request *req; |
| 2041 | 2150 | |
| 2042 | − if (!ublk_need_req_ref(ubq)) | |
| 2043 | − return NULL; | |
| 2044 | − | |
| 2045 | 2151 | req = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], tag); |
| 2046 | 2152 | if (!req) |
| 2047 | 2153 | return NULL; |
| @@ -2155,6 +2261,9 @@ static struct request *ublk_check_and_get_req(struct kiocb *iocb, · 107 unmodified lines | ||
| 2155 | 2261 | if (!ubq) |
| 2156 | 2262 | return ERR_PTR(-EINVAL); |
| 2157 | 2263 | |
| 2264 | + if (!ublk_support_user_copy(ubq)) | |
| 2265 | + return ERR_PTR(-EACCES); | |
| 2266 | + | |
| 2158 | 2267 | if (tag >= ubq->q_depth) |
| 2159 | 2268 | return ERR_PTR(-EINVAL); |
| 2160 | 2269 | |
| @@ -2388,7 +2497,6 @@ static void ublk_remove(struct ublk_device *ub) · 227 unmodified lines | ||
| 2388 | 2497 | bool unprivileged; |
| 2389 | 2498 | |
| 2390 | 2499 | ublk_stop_dev(ub); |
| 2391 | − cancel_work_sync(&ub->nosrv_work); | |
| 2392 | 2500 | cdev_device_del(&ub->cdev, &ub->cdev_dev); |
| 2393 | 2501 | unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV; |
| 2394 | 2502 | ublk_put_device(ub); |
| @@ -2413,9 +2521,9 @@ static struct ublk_device *ublk_get_device_from_id(int idx) · 18 unmodified lines | ||
| 2413 | 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 | 2527 | const struct ublk_param_basic *p = &ub->params.basic; |
| 2420 | 2528 | int ublksrv_pid = (int)header->data[0]; |
| 2421 | 2529 | struct queue_limits lim = { |
| @@ -2534,9 +2642,8 @@ out_unlock: · 112 unmodified lines | ||
| 2534 | 2642 | } |
| 2535 | 2643 | |
| 2536 | 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 | 2647 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2541 | 2648 | cpumask_var_t cpumask; |
| 2542 | 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 | 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 | 2697 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2592 | 2698 | struct ublksrv_ctrl_dev_info info; |
| 2593 | 2699 | struct ublk_device *ub; |
| @@ -2675,7 +2781,6 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 81 unmodified lines | ||
| 2675 | 2781 | goto out_unlock; |
| 2676 | 2782 | mutex_init(&ub->mutex); |
| 2677 | 2783 | spin_lock_init(&ub->lock); |
| 2678 | − INIT_WORK(&ub->nosrv_work, ublk_nosrv_work); | |
| 2679 | 2784 | |
| 2680 | 2785 | ret = ublk_alloc_dev_number(ub, header->dev_id); |
| 2681 | 2786 | if (ret < 0) |
| @@ -2697,13 +2802,18 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 15 unmodified lines | ||
| 2697 | 2802 | ub->dev_info.flags |= UBLK_F_CMD_IOCTL_ENCODE | |
| 2698 | 2803 | UBLK_F_URING_CMD_COMP_IN_TASK; |
| 2699 | 2804 | |
| 2700 | − /* GET_DATA isn't needed any more with USER_COPY */ | |
| 2701 | − if (ublk_dev_is_user_copy(ub)) | |
| 2805 | + /* GET_DATA isn't needed any more with USER_COPY or ZERO COPY */ | |
| 2806 | + if (ub->dev_info.flags & (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY)) | |
| 2702 | 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 | 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 | 2817 | ret = -EINVAL; |
| 2708 | 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 | 2917 | static int ublk_ctrl_stop_dev(struct ublk_device *ub) |
| 2808 | 2918 | { |
| 2809 | 2919 | ublk_stop_dev(ub); |
| 2810 | − cancel_work_sync(&ub->nosrv_work); | |
| 2811 | 2920 | return 0; |
| 2812 | 2921 | } |
| 2813 | 2922 | |
| 2814 | 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 | 2926 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2819 | 2927 | |
| 2820 | 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 | 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 | 2956 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2850 | 2957 | struct ublk_params_header ph; |
| 2851 | 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 | 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 | 2986 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 2881 | 2987 | struct ublk_params_header ph; |
| 2882 | 2988 | int ret = -EFAULT; |
| @@ -2914,43 +3020,14 @@ static int ublk_ctrl_set_params(struct ublk_device *ub, · 31 unmodified lines | ||
| 2914 | 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 | 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 | 3026 | int ret = -EINVAL; |
| 2947 | − int i; | |
| 2948 | 3027 | |
| 2949 | 3028 | mutex_lock(&ub->mutex); |
| 2950 | 3029 | if (ublk_nosrv_should_stop_dev(ub)) |
| 2951 | 3030 | goto out_unlock; |
| 2952 | − if (!ub->nr_queues_ready) | |
| 2953 | − goto out_unlock; | |
| 2954 | 3031 | /* |
| 2955 | 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 | 3051 | goto out_unlock; |
| 2975 | 3052 | } |
| 2976 | 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 | 3054 | init_completion(&ub->completion); |
| 2984 | 3055 | ret = 0; |
| 2985 | 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 | 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 | 3064 | int ublksrv_pid = (int)header->data[0]; |
| 2995 | 3065 | int ret = -EINVAL; |
| 2996 | − int i; | |
| 2997 | 3066 | |
| 2998 | 3067 | pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n", |
| 2999 | 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 | 3082 | goto out_unlock; |
| 3014 | 3083 | } |
| 3015 | 3084 | ub->dev_info.ublksrv_pid = ublksrv_pid; |
| 3085 | + ub->dev_info.state = UBLK_S_DEV_LIVE; | |
| 3016 | 3086 | pr_devel("%s: new ublksrv_pid %d, dev id %d\n", |
| 3017 | 3087 | __func__, ublksrv_pid, header->dev_id); |
| 3018 | − | |
| 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 | − | |
| 3088 | + blk_mq_kick_requeue_list(ub->ub_disk->queue); | |
| 3034 | 3089 | ret = 0; |
| 3035 | 3090 | out_unlock: |
| 3036 | 3091 | mutex_unlock(&ub->mutex); |
| 3037 | 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 | 3097 | void __user *argp = (void __user *)(unsigned long)header->addr; |
| 3044 | 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 | 3232 | goto out; |
| 3179 | 3233 | |
| 3180 | 3234 | if (cmd_op == UBLK_U_CMD_GET_FEATURES) { |
| 3181 | − ret = ublk_ctrl_get_features(cmd); | |
| 3235 | + ret = ublk_ctrl_get_features(header); | |
| 3182 | 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 | 3250 | switch (_IOC_NR(cmd_op)) { |
| 3197 | 3251 | case UBLK_CMD_START_DEV: |
| 3198 | − ret = ublk_ctrl_start_dev(ub, cmd); | |
| 3252 | + ret = ublk_ctrl_start_dev(ub, header); | |
| 3199 | 3253 | break; |
| 3200 | 3254 | case UBLK_CMD_STOP_DEV: |
| 3201 | 3255 | ret = ublk_ctrl_stop_dev(ub); |
| 3202 | 3256 | break; |
| 3203 | 3257 | case UBLK_CMD_GET_DEV_INFO: |
| 3204 | 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 | 3260 | break; |
| 3207 | 3261 | case UBLK_CMD_ADD_DEV: |
| 3208 | − ret = ublk_ctrl_add_dev(cmd); | |
| 3262 | + ret = ublk_ctrl_add_dev(header); | |
| 3209 | 3263 | break; |
| 3210 | 3264 | case UBLK_CMD_DEL_DEV: |
| 3211 | 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 | 3268 | ret = ublk_ctrl_del_dev(&ub, false); |
| 3215 | 3269 | break; |
| 3216 | 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 | 3272 | break; |
| 3219 | 3273 | case UBLK_CMD_GET_PARAMS: |
| 3220 | − ret = ublk_ctrl_get_params(ub, cmd); | |
| 3274 | + ret = ublk_ctrl_get_params(ub, header); | |
| 3221 | 3275 | break; |
| 3222 | 3276 | case UBLK_CMD_SET_PARAMS: |
| 3223 | − ret = ublk_ctrl_set_params(ub, cmd); | |
| 3277 | + ret = ublk_ctrl_set_params(ub, header); | |
| 3224 | 3278 | break; |
| 3225 | 3279 | case UBLK_CMD_START_USER_RECOVERY: |
| 3226 | − ret = ublk_ctrl_start_recovery(ub, cmd); | |
| 3280 | + ret = ublk_ctrl_start_recovery(ub, header); | |
| 3227 | 3281 | break; |
| 3228 | 3282 | case UBLK_CMD_END_USER_RECOVERY: |
| 3229 | − ret = ublk_ctrl_end_recovery(ub, cmd); | |
| 3283 | + ret = ublk_ctrl_end_recovery(ub, header); | |
| 3230 | 3284 | break; |
| 3231 | 3285 | default: |
| 3232 | 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 | 957 | /* This is a debug event that comes from IML and OP image when it |
| 958 | 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 | 962 | return 0; |
| 963 | + } | |
| 962 | 964 | } |
| 963 | 965 | |
| 964 | 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 | 976 | u8 pkt_type; |
| 975 | 977 | u16 plen; |
| 976 | 978 | u32 pcie_pkt_type; |
| 977 | − struct sk_buff *new_skb; | |
| 978 | 979 | void *pdata; |
| 979 | 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 | 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 | − 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); | |
| 1055 | + hci_skb_pkt_type(skb) = pkt_type; | |
| 1064 | 1056 | hdev->stat.byte_rx += plen; |
| 1057 | + skb_trim(skb, plen); | |
| 1065 | 1058 | |
| 1066 | 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 | 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 | 1065 | exit_error: |
| 1066 | + if (skb) | |
| 1067 | + kfree_skb(skb); | |
| 1068 | + | |
| 1072 | 1069 | if (ret) |
| 1073 | 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 | 1199 | struct btintel_pcie_data *data = container_of(work, |
| 1203 | 1200 | struct btintel_pcie_data, rx_work); |
| 1204 | 1201 | struct sk_buff *skb; |
| 1205 | − int err; | |
| 1206 | − struct hci_dev *hdev = data->hdev; | |
| 1207 | 1202 | |
| 1208 | 1203 | if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) { |
| 1209 | 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 | 1220 | /* Process the sk_buf in queue and send to the HCI layer */ |
| 1226 | 1221 | while ((skb = skb_dequeue(&data->rx_skb_q))) { |
| 1227 | − err = 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); | |
| 1222 | + btintel_pcie_recv_frame(data, 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 | 1272 | bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia); |
| 1282 | 1273 | |
| 1283 | 1274 | /* Check CR_TIA and CR_HIA for change */ |
| 1284 | − if (cr_tia == cr_hia) { | |
| 1285 | − bt_dev_warn(hdev, "RXQ: no new CD found"); | |
| 1275 | + if (cr_tia == cr_hia) | |
| 1286 | 1276 | return; |
| 1287 | − } | |
| 1288 | 1277 | |
| 1289 | 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 | 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 | 1322 | static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) |
| 1324 | 1323 | { |
| 1325 | 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 | 1350 | btintel_pcie_msix_gp0_handler(data); |
| 1352 | 1351 | |
| 1353 | 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 | 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 | 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 | 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 | 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 | 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 | 730 | sdio_claim_host(bdev->func); |
| 727 | 731 | |
| 728 | 732 | /* Disable interrupt */ |
| @@ -1443,11 +1447,15 @@ static void btmtksdio_remove(struct sdio_func *func) · 714 unmodified lines | ||
| 1443 | 1447 | if (!bdev) |
| 1444 | 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 | 1456 | /* Be consistent the state in btmtksdio_probe */ |
| 1447 | 1457 | pm_runtime_get_noresume(bdev->dev); |
| 1448 | 1458 | |
| 1449 | − hdev = bdev->hdev; | |
| 1450 | − | |
| 1451 | 1459 | sdio_set_drvdata(func, NULL); |
| 1452 | 1460 | hci_unregister_dev(hdev); |
| 1453 | 1461 | hci_free_dev(hdev); |
| @@ -1286,7 +1286,9 @@ static void nxp_coredump(struct hci_dev *hdev) · 1285 unmodified lines | ||
| 1286 | 1286 | u8 pcmd = 2; |
| 1287 | 1287 | |
| 1288 | 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 | 1292 | kfree_skb(skb); |
| 1291 | 1293 | } |
| 1292 | 1294 | |
| @@ -1445,9 +1447,6 @@ static int nxp_shutdown(struct hci_dev *hdev) · 152 unmodified lines | ||
| 1445 | 1447 | /* HCI_NXP_IND_RESET command may not returns any response */ |
| 1446 | 1448 | if (!IS_ERR(skb)) |
| 1447 | 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 | 1452 | return 0; |
| @@ -1799,13 +1798,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev) · 345 unmodified lines | ||
| 1799 | 1798 | clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); |
| 1800 | 1799 | wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); |
| 1801 | 1800 | wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); |
| 1802 | − } | |
| 1803 | − | |
| 1804 | − if (test_bit(HCI_RUNNING, &hdev->flags)) { | |
| 1805 | − /* Ensure shutdown callback is executed before unregistering, so | |
| 1806 | − * that baudrate is reset to initial value. | |
| 1801 | + } else { | |
| 1802 | + /* Restore FW baudrate to fw_init_baudrate if changed. | |
| 1803 | + * This will ensure FW baudrate is in sync with | |
| 1804 | + * driver baudrate in case this driver is re-inserted. | |
| 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 | 1812 | ps_cleanup(nxpdev); |
| @@ -889,7 +889,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, · 888 unmodified lines | ||
| 889 | 889 | if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T) |
| 890 | 890 | variant = "t"; |
| 891 | 891 | else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S) |
| 892 | − variant = "u"; | |
| 892 | + variant = "s"; | |
| 893 | 893 | |
| 894 | 894 | snprintf(config.fwname, sizeof(config.fwname), |
| 895 | 895 | "qca/cmnv%02x%s.bin", rom_ver, variant); |
| @@ -1215,6 +1215,8 @@ next: · 1214 unmodified lines | ||
| 1215 | 1215 | rtl_dev_err(hdev, "mandatory config file %s not found", |
| 1216 | 1216 | btrtl_dev->ic_info->cfg_name); |
| 1217 | 1217 | ret = btrtl_dev->cfg_len; |
| 1218 | + if (!ret) | |
| 1219 | + ret = -EINVAL; | |
| 1218 | 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 | 3010 | bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); |
| 3011 | 3011 | } |
| 3012 | 3012 | |
| 3013 | −/* | |
| 3014 | − * ==0: not a dump pkt. | |
| 3015 | − * < 0: fails to handle a dump pkt | |
| 3016 | − * > 0: otherwise. | |
| 3017 | − */ | |
| 3013 | +/* Return: 0 on success, negative errno on failure. */ | |
| 3018 | 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 | 3018 | u8 pkt_type; |
| 3022 | − u8 *sk_ptr; | |
| 3023 | − unsigned int sk_len; | |
| 3024 | 3019 | u16 seqno; |
| 3025 | 3020 | u32 dump_size; |
| 3026 | 3021 | |
| 3027 | − struct hci_event_hdr *event_hdr; | |
| 3028 | − struct hci_acl_hdr *acl_hdr; | |
| 3029 | 3022 | struct qca_dump_hdr *dump_hdr; |
| 3030 | 3023 | struct btusb_data *btdata = hci_get_drvdata(hdev); |
| 3031 | 3024 | struct usb_device *udev = btdata->udev; |
| 3032 | 3025 | |
| 3033 | 3026 | pkt_type = hci_skb_pkt_type(skb); |
| 3034 | − sk_ptr = skb->data; | |
| 3035 | − sk_len = skb->len; | |
| 3036 | − | |
| 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; | |
| 3027 | + skip = sizeof(struct hci_event_hdr); | |
| 3028 | + if (pkt_type == HCI_ACLDATA_PKT) | |
| 3029 | + skip += sizeof(struct hci_acl_hdr); | |
| 3054 | 3030 | |
| 3055 | − dump_hdr = (struct qca_dump_hdr *)sk_ptr; | |
| 3056 | − if ((sk_len < offsetof(struct qca_dump_hdr, data)) | |
| 3057 | − || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) | |
| 3058 | − || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) | |
| 3059 | − return 0; | |
| 3031 | + skb_pull(skb, skip); | |
| 3032 | + dump_hdr = (struct qca_dump_hdr *)skb->data; | |
| 3060 | 3033 | |
| 3061 | − /*it is dump pkt now*/ | |
| 3062 | 3034 | seqno = le16_to_cpu(dump_hdr->seqno); |
| 3063 | 3035 | if (seqno == 0) { |
| 3064 | 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 | 3051 | btdata->qca_dump.ram_dump_size = dump_size; |
| 3080 | 3052 | btdata->qca_dump.ram_dump_seqno = 0; |
| 3081 | − sk_ptr += offsetof(struct qca_dump_hdr, data0); | |
| 3082 | − sk_len -= offsetof(struct qca_dump_hdr, data0); | |
| 3053 | + | |
| 3054 | + skb_pull(skb, offsetof(struct qca_dump_hdr, data0)); | |
| 3083 | 3055 | |
| 3084 | 3056 | usb_disable_autosuspend(udev); |
| 3085 | 3057 | bt_dev_info(hdev, "%s memdump size(%u)\n", |
| 3086 | 3058 | (pkt_type == HCI_ACLDATA_PKT) ? "ACL" : "event", |
| 3087 | 3059 | dump_size); |
| 3088 | 3060 | } else { |
| 3089 | − sk_ptr += offsetof(struct qca_dump_hdr, data); | |
| 3090 | − sk_len -= offsetof(struct qca_dump_hdr, data); | |
| 3061 | + skb_pull(skb, offsetof(struct qca_dump_hdr, data)); | |
| 3091 | 3062 | } |
| 3092 | 3063 | |
| 3093 | 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 | 3078 | return ret; |
| 3108 | 3079 | } |
| 3109 | 3080 | |
| 3110 | − skb_pull(skb, skb->len - sk_len); | |
| 3111 | 3081 | hci_devcd_append(hdev, skb); |
| 3112 | 3082 | btdata->qca_dump.ram_dump_seqno++; |
| 3113 | 3083 | if (seqno == QCA_LAST_SEQUENCE_NUM) { |
| @@ -3132,17 +3102,74 @@ out: · 18 unmodified lines | ||
| 3132 | 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 | 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)) | |
| 3138 | − return 0; | |
| 3164 | + if (acl_pkt_is_dump_qca(hdev, skb)) | |
| 3165 | + return handle_dump_pkt_qca(hdev, skb); | |
| 3139 | 3166 | return hci_recv_frame(hdev, skb); |
| 3140 | 3167 | } |
| 3141 | 3168 | |
| 3142 | 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)) | |
| 3145 | − return 0; | |
| 3171 | + if (evt_pkt_is_dump_qca(hdev, skb)) | |
| 3172 | + return handle_dump_pkt_qca(hdev, skb); | |
| 3146 | 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 | 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 | 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 | 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 | 301 | skb_put_data(skb, buf, strlen(buf)); |
| 302 | 302 | |
| 303 | − snprintf(buf, sizeof(buf), "Vendor: vhci\n"); | |
| 303 | + buf = "Vendor: vhci\n"; | |
| 304 | 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 | 315 | goto fail_remove; |
| 316 | 316 | |
| 317 | 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 | 319 | goto fail_printk; |
| 320 | 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 | 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 | 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 | 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 | 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 | 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 | 240 | tpm_buf_read(buf, offset, sizeof(value), &value); |
| 241 | 241 | |
| @@ -40,11 +40,6 @@ · 39 unmodified lines | ||
| 40 | 40 | * |
| 41 | 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 | 43 | * tpm2_end_auth_session() kills the session and frees the resources. |
| 49 | 44 | * Under normal operation this function is done by |
| 50 | 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 | |
| 967 | − * @chip: the TPM chip structure to create the session with | |
| 961 | + * tpm2_start_auth_session() - Create an a HMAC authentication session | |
| 962 | + * @chip: A TPM chip | |
| 968 | 963 | * |
| 969 | − * This function loads the NULL seed from its saved context and starts | |
| 970 | − * an authentication session on the null seed, fills in the | |
| 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. | |
| 964 | + * Loads the ephemeral key (null seed), and starts an HMAC authenticated | |
| 965 | + * session. The null seed is flushed before the return. | |
| 974 | 966 | * |
| 975 | − * Return: zero on success or actual error encountered. | |
| 967 | + * Returns zero on success, or a POSIX error code. | |
| 976 | 968 | */ |
| 977 | 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 | 1016 | /* hash algorithm for session */ |
| 1025 | 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 | 1020 | tpm2_flush_context(chip, null_key); |
| 1029 | 1021 | |
| 1030 | 1022 | if (rc == TPM2_RC_SUCCESS) |
| @@ -54,7 +54,7 @@ enum tis_int_flags { · 53 unmodified lines | ||
| 54 | 54 | enum tis_defaults { |
| 55 | 55 | TIS_MEM_LEN = 0x5000, |
| 56 | 56 | TIS_SHORT_TIMEOUT = 750, /* ms */ |
| 57 | − TIS_LONG_TIMEOUT = 2000, /* 2 sec */ | |
| 57 | + TIS_LONG_TIMEOUT = 4000, /* 4 secs */ | |
| 58 | 58 | TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ |
| 59 | 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 | 1576 | break; |
| 1577 | 1577 | case VIRTIO_CONSOLE_RESIZE: { |
| 1578 | 1578 | struct { |
| 1579 | − __u16 rows; | |
| 1580 | − __u16 cols; | |
| 1579 | + __virtio16 cols; | |
| 1580 | + __virtio16 rows; | |
| 1581 | 1581 | } size; |
| 1582 | 1582 | |
| 1583 | 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 | 1586 | memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), |
| 1587 | 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 | 1591 | port->cons.hvc->irq_requested = 1; |
| 1591 | 1592 | resize_console(port); |
| @@ -137,6 +137,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev) · 136 unmodified lines | ||
| 137 | 137 | if (!clk_data) |
| 138 | 138 | return -ENOMEM; |
| 139 | 139 | |
| 140 | + clk_data->num = S2MPS11_CLKS_NUM; | |
| 141 | + | |
| 140 | 142 | switch (hwid) { |
| 141 | 143 | case S2MPS11X: |
| 142 | 144 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; |
| @@ -186,7 +188,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev) · 43 unmodified lines | ||
| 186 | 188 | clk_data->hws[i] = &s2mps11_clks[i].hw; |
| 187 | 189 | } |
| 188 | 190 | |
| 189 | − clk_data->num = S2MPS11_CLKS_NUM; | |
| 190 | 191 | of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get, |
| 191 | 192 | clk_data); |
| 192 | 193 | |
| @@ -541,6 +541,8 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = { · 540 unmodified lines | ||
| 541 | 541 | RK3576_CLKGATE_CON(5), 14, GFLAGS), |
| 542 | 542 | GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, |
| 543 | 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 | 546 | COMPOSITE(CLK_MIPI_CAMERAOUT_M0, "clk_mipi_cameraout_m0", mux_24m_spll_gpll_cpll_p, 0, |
| 545 | 547 | RK3576_CLKSEL_CON(38), 8, 2, MFLAGS, 0, 8, DFLAGS, |
| 546 | 548 | RK3576_CLKGATE_CON(6), 3, GFLAGS), |
| @@ -412,19 +412,23 @@ static const struct clk_parent_data mmc0_mmc1_parents[] = { · 411 unmodified lines | ||
| 412 | 412 | { .hw = &pll_periph0_2x_clk.common.hw }, |
| 413 | 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, | |
| 416 | − 0, 4, /* M */ | |
| 417 | − 8, 2, /* P */ | |
| 418 | − 24, 3, /* mux */ | |
| 419 | − BIT(31), /* gate */ | |
| 420 | − 0); | |
| 421 | − | |
| 422 | −static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834, | |
| 423 | − 0, 4, /* M */ | |
| 424 | − 8, 2, /* P */ | |
| 425 | − 24, 3, /* mux */ | |
| 426 | − BIT(31), /* gate */ | |
| 427 | − 0); | |
| 415 | +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", | |
| 416 | + mmc0_mmc1_parents, 0x830, | |
| 417 | + 0, 4, /* M */ | |
| 418 | + 8, 2, /* P */ | |
| 419 | + 24, 3, /* mux */ | |
| 420 | + BIT(31), /* gate */ | |
| 421 | + 2, /* post-div */ | |
| 422 | + 0); | |
| 423 | + | |
| 424 | +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", | |
| 425 | + mmc0_mmc1_parents, 0x834, | |
| 426 | + 0, 4, /* M */ | |
| 427 | + 8, 2, /* P */ | |
| 428 | + 24, 3, /* mux */ | |
| 429 | + BIT(31), /* gate */ | |
| 430 | + 2, /* post-div */ | |
| 431 | + 0); | |
| 428 | 432 | |
| 429 | 433 | static const struct clk_parent_data mmc2_parents[] = { |
| 430 | 434 | { .fw_name = "hosc" }, |
| @@ -433,12 +437,14 @@ static const struct clk_parent_data mmc2_parents[] = { · 2 unmodified lines | ||
| 433 | 437 | { .hw = &pll_periph0_800M_clk.common.hw }, |
| 434 | 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, | |
| 437 | − 0, 4, /* M */ | |
| 438 | − 8, 2, /* P */ | |
| 439 | − 24, 3, /* mux */ | |
| 440 | − BIT(31), /* gate */ | |
| 441 | − 0); | |
| 440 | +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc2_parents, | |
| 441 | + 0x838, | |
| 442 | + 0, 4, /* M */ | |
| 443 | + 8, 2, /* P */ | |
| 444 | + 24, 3, /* mux */ | |
| 445 | + BIT(31), /* gate */ | |
| 446 | + 2, /* post-div */ | |
| 447 | + 0); | |
| 442 | 448 | |
| 443 | 449 | static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws, |
| 444 | 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 | 77 | #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ |
| 56 | 78 | _mshift, _mwidth, \ |
| 57 | 79 | _pshift, _pwidth, \ |
| @@ -109,8 +131,7 @@ struct ccu_mp { · 51 unmodified lines | ||
| 109 | 131 | _mshift, _mwidth, \ |
| 110 | 132 | _pshift, _pwidth, \ |
| 111 | 133 | _muxshift, _muxwidth, \ |
| 112 | − _gate, _features, \ | |
| 113 | − _flags) \ | |
| 134 | + _gate, _flags, _features) \ | |
| 114 | 135 | struct ccu_mp _struct = { \ |
| 115 | 136 | .enable = _gate, \ |
| 116 | 137 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
| @@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void) · 102 unmodified lines | ||
| 103 | 103 | #ifdef CONFIG_CLKEVT_I8253 |
| 104 | 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 | 109 | * Writing the MODE register should stop the counter, according to |
| @@ -132,8 +132,6 @@ void clockevent_i8253_disable(void) · 22 unmodified lines | ||
| 132 | 132 | outb_p(0, PIT_CH0); |
| 133 | 133 | |
| 134 | 134 | outb_p(0x30, PIT_MODE); |
| 135 | − | |
| 136 | − raw_spin_unlock(&i8253_lock); | |
| 137 | 135 | } |
| 138 | 136 | |
| 139 | 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 | 758 | struct jr3_pci_dev_private *devpriv = dev->private; |
| 759 | 759 | |
| 760 | 760 | if (devpriv) |
| 761 | − timer_delete_sync(&devpriv->timer); | |
| 761 | + timer_shutdown_sync(&devpriv->timer); | |
| 762 | 762 | |
| 763 | 763 | comedi_pci_detach(dev); |
| 764 | 764 | } |
| @@ -76,7 +76,7 @@ config ARM_VEXPRESS_SPC_CPUFREQ · 75 unmodified lines | ||
| 76 | 76 | config ARM_BRCMSTB_AVS_CPUFREQ |
| 77 | 77 | tristate "Broadcom STB AVS CPUfreq driver" |
| 78 | 78 | depends on (ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ) || COMPILE_TEST |
| 79 | − default y | |
| 79 | + default y if ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ | |
| 80 | 80 | help |
| 81 | 81 | Some Broadcom STB SoCs use a co-processor running proprietary firmware |
| 82 | 82 | ("AVS") to handle voltage and frequency scaling. This driver provides |
| @@ -88,7 +88,7 @@ config ARM_HIGHBANK_CPUFREQ · 5 unmodified lines | ||
| 88 | 88 | tristate "Calxeda Highbank-based" |
| 89 | 89 | depends on ARCH_HIGHBANK || COMPILE_TEST |
| 90 | 90 | depends on CPUFREQ_DT && REGULATOR && PL320_MBOX |
| 91 | − default m | |
| 91 | + default m if ARCH_HIGHBANK | |
| 92 | 92 | help |
| 93 | 93 | This adds the CPUFreq driver for Calxeda Highbank SoC |
| 94 | 94 | based boards. |
| @@ -133,7 +133,7 @@ config ARM_MEDIATEK_CPUFREQ · 38 unmodified lines | ||
| 133 | 133 | config ARM_MEDIATEK_CPUFREQ_HW |
| 134 | 134 | tristate "MediaTek CPUFreq HW driver" |
| 135 | 135 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 136 | − default m | |
| 136 | + default m if ARCH_MEDIATEK | |
| 137 | 137 | help |
| 138 | 138 | Support for the CPUFreq HW driver. |
| 139 | 139 | Some MediaTek chipsets have a HW engine to offload the steps |
| @@ -181,7 +181,7 @@ config ARM_RASPBERRYPI_CPUFREQ · 41 unmodified lines | ||
| 181 | 181 | config ARM_S3C64XX_CPUFREQ |
| 182 | 182 | bool "Samsung S3C64XX" |
| 183 | 183 | depends on CPU_S3C6410 || COMPILE_TEST |
| 184 | − default y | |
| 184 | + default CPU_S3C6410 | |
| 185 | 185 | help |
| 186 | 186 | This adds the CPUFreq driver for Samsung S3C6410 SoC. |
| 187 | 187 | |
| @@ -190,7 +190,7 @@ config ARM_S3C64XX_CPUFREQ · 2 unmodified lines | ||
| 190 | 190 | config ARM_S5PV210_CPUFREQ |
| 191 | 191 | bool "Samsung S5PV210 and S5PC110" |
| 192 | 192 | depends on CPU_S5PV210 || COMPILE_TEST |
| 193 | − default y | |
| 193 | + default CPU_S5PV210 | |
| 194 | 194 | help |
| 195 | 195 | This adds the CPUFreq driver for Samsung S5PV210 and |
| 196 | 196 | S5PC110 SoCs. |
| @@ -214,7 +214,7 @@ config ARM_SCMI_CPUFREQ · 17 unmodified lines | ||
| 214 | 214 | config ARM_SPEAR_CPUFREQ |
| 215 | 215 | bool "SPEAr CPUFreq support" |
| 216 | 216 | depends on PLAT_SPEAR || COMPILE_TEST |
| 217 | − default y | |
| 217 | + default PLAT_SPEAR | |
| 218 | 218 | help |
| 219 | 219 | This adds the CPUFreq driver support for SPEAr SOCs. |
| 220 | 220 | |
| @@ -233,7 +233,7 @@ config ARM_TEGRA20_CPUFREQ · 12 unmodified lines | ||
| 233 | 233 | tristate "Tegra20/30 CPUFreq support" |
| 234 | 234 | depends on ARCH_TEGRA || COMPILE_TEST |
| 235 | 235 | depends on CPUFREQ_DT |
| 236 | − default y | |
| 236 | + default ARCH_TEGRA | |
| 237 | 237 | help |
| 238 | 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 | 241 | bool "Tegra124 CPUFreq support" |
| 242 | 242 | depends on ARCH_TEGRA || COMPILE_TEST |
| 243 | 243 | depends on CPUFREQ_DT |
| 244 | − default y | |
| 244 | + default ARCH_TEGRA | |
| 245 | 245 | help |
| 246 | 246 | This adds the CPUFreq driver support for Tegra124 SOCs. |
| 247 | 247 | |
| @@ -256,14 +256,14 @@ config ARM_TEGRA194_CPUFREQ · 8 unmodified lines | ||
| 256 | 256 | tristate "Tegra194 CPUFreq support" |
| 257 | 257 | depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST) |
| 258 | 258 | depends on TEGRA_BPMP |
| 259 | − default y | |
| 259 | + default ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC | |
| 260 | 260 | help |
| 261 | 261 | This adds CPU frequency driver support for Tegra194 SOCs. |
| 262 | 262 | |
| 263 | 263 | config ARM_TI_CPUFREQ |
| 264 | 264 | bool "Texas Instruments CPUFreq support" |
| 265 | 265 | depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST |
| 266 | − default y | |
| 266 | + default ARCH_OMAP2PLUS || ARCH_K3 | |
| 267 | 267 | help |
| 268 | 268 | This driver enables valid OPPs on the running platform based on |
| 269 | 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 | 909 | if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) |
| 910 | 910 | pr_warn(FW_WARN "P-state 0 is not max freq\n"); |
| 911 | 911 | |
| 912 | − if (acpi_cpufreq_driver.set_boost) | |
| 913 | − policy->boost_supported = true; | |
| 912 | + if (acpi_cpufreq_driver.set_boost) { | |
| 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 | 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 | 607 | union perf_cached perf = READ_ONCE(cpudata->perf); |
| 608 | 608 | |
| 609 | 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 | 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 | 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 | 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 | 797 | #define CPPC_MAX_PERF U8_MAX |
| 805 | 798 | |
| 806 | 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 | 805 | cpudata->hw_prefcore = true; |
| 813 | 806 | |
| 814 | − /* | |
| 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 | − */ | |
| 807 | + /* Priorities must be initialized before ITMT support can be toggled on. */ | |
| 819 | 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 | 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 | 1181 | static void amd_pstate_driver_cleanup(void) |
| 1195 | 1182 | { |
| 1183 | + if (amd_pstate_prefcore) | |
| 1184 | + sched_clear_itmt_support(); | |
| 1185 | + | |
| 1196 | 1186 | cppc_state = AMD_PSTATE_DISABLE; |
| 1197 | 1187 | current_pstate_driver = NULL; |
| 1198 | 1188 | } |
| @@ -1235,6 +1225,10 @@ static int amd_pstate_register_driver(int mode) · 36 unmodified lines | ||
| 1235 | 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 | 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 | 135 | static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu) |
| 136 | 136 | { |
| 137 | − struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | |
| 138 | − struct apple_cpu_priv *priv = policy->driver_data; | |
| 137 | + struct cpufreq_policy *policy; | |
| 138 | + struct apple_cpu_priv *priv; | |
| 139 | 139 | struct cpufreq_frequency_table *p; |
| 140 | 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 | 148 | if (priv->info->cur_pstate_mask) { |
| 143 | 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 | 747 | int ret; |
| 748 | 748 | |
| 749 | 749 | if (!policy) |
| 750 | − return -ENODEV; | |
| 750 | + return 0; | |
| 751 | 751 | |
| 752 | 752 | cpu_data = policy->driver_data; |
| 753 | 753 | |
| @@ -175,6 +175,7 @@ static const struct of_device_id blocklist[] __initconst = { · 174 unmodified lines | ||
| 175 | 175 | { .compatible = "qcom,sm8350", }, |
| 176 | 176 | { .compatible = "qcom,sm8450", }, |
| 177 | 177 | { .compatible = "qcom,sm8550", }, |
| 178 | + { .compatible = "qcom,sm8650", }, | |
| 178 | 179 | |
| 179 | 180 | { .compatible = "st,stih407", }, |
| 180 | 181 | { .compatible = "st,stih410", }, |
| @@ -536,16 +536,18 @@ void cpufreq_disable_fast_switch(struct cpufreq_policy *policy) · 535 unmodified lines | ||
| 536 | 536 | EXPORT_SYMBOL_GPL(cpufreq_disable_fast_switch); |
| 537 | 537 | |
| 538 | 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 | 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 | 547 | if (!policy->freq_table) |
| 546 | 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 | 551 | policy->cached_resolved_idx = idx; |
| 550 | 552 | policy->cached_target_freq = target_freq; |
| 551 | 553 | return policy->freq_table[idx].frequency; |
| @@ -565,7 +567,21 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy, · 13 unmodified lines | ||
| 565 | 567 | unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, |
| 566 | 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 | 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 | 2400 | if (cpufreq_disabled()) |
| 2385 | 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 | 2406 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", |
| 2390 | 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 | 2725 | * Resolve policy min/max to available frequencies. It ensures |
| 2709 | 2726 | * no frequency resolution will neither overshoot the requested maximum |
| 2710 | 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; | |
| 2713 | − policy->max = new_data.max; | |
| 2714 | − policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L); | |
| 2715 | − policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H); | |
| 2733 | + WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, | |
| 2734 | + new_data.min, new_data.max, | |
| 2735 | + 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 | 2740 | trace_cpu_frequency_limits(policy); |
| 2717 | 2741 | |
| 2718 | 2742 | cpufreq_update_pressure(policy); |
| @@ -76,7 +76,8 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, · 75 unmodified lines | ||
| 76 | 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 | 81 | freq_req = freq_table[index].frequency; |
| 81 | 82 | freq_reduc = freq_req * od_tuners->powersave_bias / 1000; |
| 82 | 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 | 115 | EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); |
| 116 | 116 | |
| 117 | 117 | int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, |
| 118 | − unsigned int target_freq, | |
| 119 | − unsigned int relation) | |
| 118 | + unsigned int target_freq, unsigned int min, | |
| 119 | + unsigned int max, unsigned int relation) | |
| 120 | 120 | { |
| 121 | 121 | struct cpufreq_frequency_table optimal = { |
| 122 | 122 | .driver_data = ~0, |
| @@ -147,7 +147,7 @@ int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, · 24 unmodified lines | ||
| 147 | 147 | cpufreq_for_each_valid_entry_idx(pos, table, i) { |
| 148 | 148 | freq = pos->frequency; |
| 149 | 149 | |
| 150 | − if ((freq < policy->min) || (freq > policy->max)) | |
| 150 | + if (freq < min || freq > max) | |
| 151 | 151 | continue; |
| 152 | 152 | if (freq == target_freq) { |
| 153 | 153 | optimal.driver_data = i; |
| @@ -598,6 +598,9 @@ static bool turbo_is_disabled(void) · 597 unmodified lines | ||
| 598 | 598 | { |
| 599 | 599 | u64 misc_en; |
| 600 | 600 | |
| 601 | + if (!cpu_feature_enabled(X86_FEATURE_IDA)) | |
| 602 | + return true; | |
| 603 | + | |
| 601 | 604 | rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); |
| 602 | 605 | |
| 603 | 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 | 2212 | static int hwp_get_cpu_scaling(int cpu) |
| 2210 | 2213 | { |
| 2211 | 2214 | if (hybrid_scaling_factor) { |
| 2212 | − struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | |
| 2215 | + struct cpuinfo_x86 *c = &cpu_data(cpu); | |
| 2213 | 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 | 38 | static unsigned int scmi_cpufreq_get_rate(unsigned int cpu) |
| 39 | 39 | { |
| 40 | − struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | |
| 41 | − struct scmi_data *priv = policy->driver_data; | |
| 40 | + struct cpufreq_policy *policy; | |
| 41 | + struct scmi_data *priv; | |
| 42 | 42 | unsigned long rate; |
| 43 | 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 | 51 | ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false); |
| 46 | 52 | if (ret) |
| 47 | 53 | return 0; |
| @@ -29,9 +29,16 @@ static struct scpi_ops *scpi_ops; · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | static unsigned int scpi_cpufreq_get_rate(unsigned int cpu) |
| 31 | 31 | { |
| 32 | − struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); | |
| 33 | − struct scpi_data *priv = policy->driver_data; | |
| 34 | − unsigned long rate = clk_get_rate(priv->clk); | |
| 32 | + struct cpufreq_policy *policy; | |
| 33 | + struct scpi_data *priv; | |
| 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 | 43 | return rate / 1000; |
| 37 | 44 | } |
| @@ -194,7 +194,9 @@ static int sun50i_cpufreq_get_efuse(void) · 193 unmodified lines | ||
| 194 | 194 | struct nvmem_cell *speedbin_nvmem; |
| 195 | 195 | const struct of_device_id *match; |
| 196 | 196 | struct device *cpu_dev; |
| 197 | − u32 *speedbin; | |
| 197 | + void *speedbin_ptr; | |
| 198 | + u32 speedbin = 0; | |
| 199 | + size_t len; | |
| 198 | 200 | int ret; |
| 199 | 201 | |
| 200 | 202 | cpu_dev = get_cpu_device(0); |
| @@ -217,14 +219,18 @@ static int sun50i_cpufreq_get_efuse(void) · 16 unmodified lines | ||
| 217 | 219 | return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), |
| 218 | 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 | 223 | nvmem_cell_put(speedbin_nvmem); |
| 222 | − if (IS_ERR(speedbin)) | |
| 223 | − return PTR_ERR(speedbin); | |
| 224 | + if (IS_ERR(speedbin_ptr)) | |
| 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 | 235 | return ret; |
| 230 | 236 | }; |
| @@ -163,6 +163,12 @@ static int atmel_sha204a_probe(struct i2c_client *client) · 162 unmodified lines | ||
| 163 | 163 | i2c_priv->hwrng.name = dev_name(&client->dev); |
| 164 | 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 | 172 | ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng); |
| 167 | 173 | if (ret) |
| 168 | 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 | 122 | qm_fd_addr_set64(&fd, addr); |
| 123 | 123 | |
| 124 | 124 | do { |
| 125 | + refcount_inc(&req->drv_ctx->refcnt); | |
| 125 | 126 | ret = qman_enqueue(req->drv_ctx->req_fq, &fd); |
| 126 | − if (likely(!ret)) { | |
| 127 | − refcount_inc(&req->drv_ctx->refcnt); | |
| 127 | + if (likely(!ret)) | |
| 128 | 128 | return 0; |
| 129 | − } | |
| 130 | 129 | |
| 130 | + refcount_dec(&req->drv_ctx->refcnt); | |
| 131 | 131 | if (ret != -EBUSY) |
| 132 | 132 | break; |
| 133 | 133 | num_retries++; |
| @@ -269,7 +269,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq) · 268 unmodified lines | ||
| 269 | 269 | unsigned int cmdlen, key1_id, key2_id; |
| 270 | 270 | int ret; |
| 271 | 271 | |
| 272 | − rctx->iv = (u32 *)req->iv; | |
| 272 | + rctx->iv = (ctx->alg == SE_ALG_ECB) ? NULL : (u32 *)req->iv; | |
| 273 | 273 | rctx->len = req->cryptlen; |
| 274 | 274 | key1_id = ctx->key1_id; |
| 275 | 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 | 498 | if (!req->cryptlen) |
| 499 | 499 | return 0; |
| 500 | 500 | |
| 501 | − if (ctx->alg == SE_ALG_ECB) | |
| 502 | − req->iv = NULL; | |
| 503 | − | |
| 504 | 501 | rctx->encrypt = encrypt; |
| 505 | 502 | |
| 506 | 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 | 120 | int cxl_ras_init(void); |
| 121 | 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 | 123 | int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res, |
| 124 | 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 | 528 | rc = cxl_set_feature(cxl_mbox, &feat_in->uuid, |
| 529 | 529 | feat_in->version, feat_in->feat_data, |
| 530 | 530 | data_size, flags, offset, &return_code); |
| 531 | + *out_len = sizeof(*rpc_out); | |
| 531 | 532 | if (rc) { |
| 532 | 533 | rpc_out->retval = return_code; |
| 533 | 534 | return no_free_ptr(rpc_out); |
| 534 | 535 | } |
| 535 | 536 | |
| 536 | 537 | rpc_out->retval = CXL_MBOX_CMD_RC_SUCCESS; |
| 537 | − *out_len = sizeof(*rpc_out); | |
| 538 | 538 | |
| 539 | 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 | 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 | 682 | struct cxl_dev_state *cxlds = cxlmd->cxlds; |
| 683 | 683 | struct cxl_features_state *cxlfs; |
| @@ -700,7 +700,7 @@ int devm_cxl_setup_fwctl(struct cxl_memdev *cxlmd) · 16 unmodified lines | ||
| 700 | 700 | if (rc) |
| 701 | 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 | 704 | no_free_ptr(fwctl_dev)); |
| 705 | 705 | } |
| 706 | 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 | 1072 | #define GPF_TIMEOUT_BASE_MAX 2 |
| 1073 | 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 | 1079 | u16 dvsec; |
| 1078 | 1080 | |
| 1079 | 1081 | if (!dev_is_pci(dev)) |
| 1080 | 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 | 1089 | is_port ? CXL_DVSEC_PORT_GPF : CXL_DVSEC_DEVICE_GPF); |
| 1084 | 1090 | if (!dvsec) |
| 1085 | 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 | 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; | |
| 1134 | − | |
| 1135 | − if (!port) | |
| 1139 | + if (!dport) | |
| 1136 | 1140 | return -EINVAL; |
| 1137 | 1141 | |
| 1138 | − if (!port->gpf_dvsec) { | |
| 1142 | + if (!dport->gpf_dvsec) { | |
| 1143 | + struct pci_dev *pdev; | |
| 1139 | 1144 | int dvsec; |
| 1140 | 1145 | |
| 1141 | − dvsec = cxl_gpf_get_dvsec(dport_dev, true); | |
| 1146 | + dvsec = cxl_gpf_get_dvsec(dport->dport_dev); | |
| 1142 | 1147 | if (!dvsec) |
| 1143 | 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 | 1156 | return 0; |
| 1153 | 1157 | } |
| @@ -1678,7 +1678,7 @@ retry: · 1677 unmodified lines | ||
| 1678 | 1678 | if (rc && rc != -EBUSY) |
| 1679 | 1679 | return rc; |
| 1680 | 1680 | |
| 1681 | − cxl_gpf_port_setup(dport_dev, port); | |
| 1681 | + cxl_gpf_port_setup(dport); | |
| 1682 | 1682 | |
| 1683 | 1683 | /* Any more ports to add between this one and the root? */ |
| 1684 | 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 | 581 | resource_size_t rcrb = ri->base; |
| 582 | 582 | void __iomem *addr; |
| 583 | 583 | u32 bar0, bar1; |
| 584 | − u16 cmd; | |
| 585 | 584 | u32 id; |
| 586 | 585 | |
| 587 | 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 | 604 | id = readl(addr + PCI_VENDOR_ID); |
| 606 | − cmd = readw(addr + PCI_COMMAND); | |
| 607 | 605 | bar0 = readl(addr + PCI_BASE_ADDRESS_0); |
| 608 | 606 | bar1 = readl(addr + PCI_BASE_ADDRESS_1); |
| 609 | 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 | 616 | dev_err(dev, "Failed to access Downstream Port RCRB\n"); |
| 619 | 617 | return CXL_RESOURCE_NONE; |
| 620 | 618 | } |
| 621 | − if (!(cmd & PCI_COMMAND_MEMORY)) | |
| 622 | − return CXL_RESOURCE_NONE; | |
| 623 | 619 | /* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */ |
| 624 | 620 | if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO)) |
| 625 | 621 | return CXL_RESOURCE_NONE; |
| @@ -592,7 +592,6 @@ struct cxl_dax_region { · 591 unmodified lines | ||
| 592 | 592 | * @cdat: Cached CDAT data |
| 593 | 593 | * @cdat_available: Should a CDAT attribute be available in sysfs |
| 594 | 594 | * @pci_latency: Upstream latency in picoseconds |
| 595 | − * @gpf_dvsec: Cached GPF port DVSEC | |
| 596 | 595 | */ |
| 597 | 596 | struct cxl_port { |
| 598 | 597 | struct device dev; |
| @@ -616,7 +615,6 @@ struct cxl_port { · 17 unmodified lines | ||
| 616 | 615 | } cdat; |
| 617 | 616 | bool cdat_available; |
| 618 | 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 | 662 | * @regs: Dport parsed register blocks |
| 665 | 663 | * @coord: access coordinates (bandwidth and latency performance attributes) |
| 666 | 664 | * @link_latency: calculated PCIe downstream latency |
| 665 | + * @gpf_dvsec: Cached GPF port DVSEC | |
| 667 | 666 | */ |
| 668 | 667 | struct cxl_dport { |
| 669 | 668 | struct device *dport_dev; |
| @@ -675,6 +674,7 @@ struct cxl_dport { · 5 unmodified lines | ||
| 675 | 674 | struct cxl_regs regs; |
| 676 | 675 | struct access_coordinate coord[ACCESS_COORDINATE_MAX]; |
| 677 | 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 | 910 | #define __mock static |
| 911 | 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 | 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 | 1018 | if (rc) |
| 1019 | 1019 | return rc; |
| 1020 | 1020 | |
| 1021 | − rc = devm_cxl_setup_fwctl(cxlmd); | |
| 1021 | + rc = devm_cxl_setup_fwctl(&pdev->dev, cxlmd); | |
| 1022 | 1022 | if (rc) |
| 1023 | 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 | 108 | return; |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | − if (!cxl_gpf_get_dvsec(cxlds->dev, false)) | |
| 111 | + if (!cxl_gpf_get_dvsec(cxlds->dev)) | |
| 112 | 112 | return; |
| 113 | 113 | |
| 114 | 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 | 320 | count++; |
| 321 | 321 | |
| 322 | 322 | dma_resv_list_set(fobj, i, fence, usage); |
| 323 | − /* pointer update must be visible before we extend the num_fences */ | |
| 324 | − smp_store_mb(fobj->num_fences, count); | |
| 323 | + /* fence update must be visible before we extend the num_fences */ | |
| 324 | + smp_wmb(); | |
| 325 | + fobj->num_fences = count; | |
| 325 | 326 | } |
| 326 | 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 | 438 | return -EINVAL; |
| 439 | 439 | |
| 440 | 440 | pt = dma_fence_to_sync_pt(fence); |
| 441 | − if (!pt) | |
| 442 | − return -EINVAL; | |
| 441 | + if (!pt) { | |
| 442 | + ret = -EINVAL; | |
| 443 | + goto put_fence; | |
| 444 | + } | |
| 443 | 445 | |
| 444 | 446 | spin_lock_irqsave(fence->lock, flags); |
| 445 | − if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { | |
| 446 | − data.deadline_ns = ktime_to_ns(pt->deadline); | |
| 447 | − } else { | |
| 447 | + if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) { | |
| 448 | 448 | ret = -ENOENT; |
| 449 | + goto unlock; | |
| 449 | 450 | } |
| 451 | + data.deadline_ns = ktime_to_ns(pt->deadline); | |
| 450 | 452 | spin_unlock_irqrestore(fence->lock, flags); |
| 451 | 453 | |
| 452 | 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 | 460 | return -EFAULT; |
| 459 | 461 | |
| 460 | 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 | 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 | 393 | if (!ubuf) |
| 394 | 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 | 397 | for (i = 0; i < head->count; i++) { |
| 398 | 398 | pgoff_t subpgcnt; |
| 399 | 399 | |
| @@ -342,6 +342,9 @@ static void pt_cmd_callback_work(void *data, int err) · 341 unmodified lines | ||
| 342 | 342 | struct pt_dma_chan *chan; |
| 343 | 343 | unsigned long flags; |
| 344 | 344 | |
| 345 | + if (!desc) | |
| 346 | + return; | |
| 347 | + | |
| 345 | 348 | dma_chan = desc->vd.tx.chan; |
| 346 | 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 | 358 | desc->status = DMA_ERROR; |
| 356 | 359 | |
| 357 | 360 | spin_lock_irqsave(&chan->vc.lock, flags); |
| 358 | − if (desc) { | |
| 359 | − if (desc->status != DMA_COMPLETE) { | |
| 360 | − if (desc->status != DMA_ERROR) | |
| 361 | − desc->status = DMA_COMPLETE; | |
| 361 | + if (desc->status != DMA_COMPLETE) { | |
| 362 | + if (desc->status != DMA_ERROR) | |
| 363 | + desc->status = DMA_COMPLETE; | |
| 362 | 364 | |
| 363 | − dma_cookie_complete(tx_desc); | |
| 364 | − dma_descriptor_unmap(tx_desc); | |
| 365 | − } else { | |
| 366 | − tx_desc = NULL; | |
| 367 | − } | |
| 365 | + dma_cookie_complete(tx_desc); | |
| 366 | + dma_descriptor_unmap(tx_desc); | |
| 367 | + } else { | |
| 368 | + tx_desc = NULL; | |
| 368 | 369 | } |
| 369 | 370 | spin_unlock_irqrestore(&chan->vc.lock, flags); |
| 370 | 371 | |
| @@ -841,9 +841,9 @@ static int dmatest_func(void *data) · 840 unmodified lines | ||
| 841 | 841 | } else { |
| 842 | 842 | dma_async_issue_pending(chan); |
| 843 | 843 | |
| 844 | − wait_event_timeout(thread->done_wait, | |
| 845 | − done->done, | |
| 846 | − msecs_to_jiffies(params->timeout)); | |
| 844 | + wait_event_freezable_timeout(thread->done_wait, | |
| 845 | + done->done, | |
| 846 | + msecs_to_jiffies(params->timeout)); | |
| 847 | 847 | |
| 848 | 848 | status = dma_async_is_tx_complete(chan, cookie, NULL, |
| 849 | 849 | NULL); |
| @@ -57,7 +57,7 @@ static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | intr = edma_readl_chreg(fsl_chan, ch_int); |
| 59 | 59 | if (!intr) |
| 60 | − return IRQ_HANDLED; | |
| 60 | + return IRQ_NONE; | |
| 61 | 61 | |
| 62 | 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 | 222 | struct idxd_wq *wq; |
| 223 | 223 | struct device *dev, *fdev; |
| 224 | 224 | int rc = 0; |
| 225 | − struct iommu_sva *sva; | |
| 225 | + struct iommu_sva *sva = NULL; | |
| 226 | 226 | unsigned int pasid; |
| 227 | 227 | struct idxd_cdev *idxd_cdev; |
| 228 | 228 | |
| @@ -317,7 +317,7 @@ failed_set_pasid: · 88 unmodified lines | ||
| 317 | 317 | if (device_user_pasid_enabled(idxd)) |
| 318 | 318 | idxd_xa_pasid_remove(ctx); |
| 319 | 319 | failed_get_pasid: |
| 320 | − if (device_user_pasid_enabled(idxd)) | |
| 320 | + if (device_user_pasid_enabled(idxd) && !IS_ERR_OR_NULL(sva)) | |
| 321 | 321 | iommu_sva_unbind_device(sva); |
| 322 | 322 | failed: |
| 323 | 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 | 407 | if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO)) |
| 408 | 408 | return -EPERM; |
| 409 | 409 | |
| 410 | + if (current->mm != ctx->mm) | |
| 411 | + return -EPERM; | |
| 412 | + | |
| 410 | 413 | rc = check_vma(wq, vma, __func__); |
| 411 | 414 | if (rc < 0) |
| 412 | 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 | 476 | ssize_t written = 0; |
| 474 | 477 | int i; |
| 475 | 478 | |
| 479 | + if (current->mm != ctx->mm) | |
| 480 | + return -EPERM; | |
| 481 | + | |
| 476 | 482 | for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) { |
| 477 | 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 | 499 | struct idxd_device *idxd = wq->idxd; |
| 494 | 500 | __poll_t out = 0; |
| 495 | 501 | |
| 502 | + if (current->mm != ctx->mm) | |
| 503 | + return POLLNVAL; | |
| 504 | + | |
| 496 | 505 | poll_wait(filp, &wq->err_queue, wait); |
| 497 | 506 | spin_lock(&idxd->dev_lock); |
| 498 | 507 | if (idxd->sw_err.valid) |
| @@ -155,6 +155,25 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd) · 154 unmodified lines | ||
| 155 | 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 | 177 | static int idxd_setup_wqs(struct idxd_device *idxd) |
| 159 | 178 | { |
| 160 | 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 | 189 | idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev)); |
| 171 | 190 | if (!idxd->wq_enable_map) { |
| 172 | − kfree(idxd->wqs); | |
| 173 | − return -ENOMEM; | |
| 191 | + rc = -ENOMEM; | |
| 192 | + goto err_bitmap; | |
| 174 | 193 | } |
| 175 | 194 | |
| 176 | 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 | 208 | conf_dev->bus = &dsa_bus_type; |
| 190 | 209 | conf_dev->type = &idxd_wq_device_type; |
| 191 | 210 | rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id); |
| 192 | − if (rc < 0) { | |
| 193 | − put_device(conf_dev); | |
| 211 | + if (rc < 0) | |
| 194 | 212 | goto err; |
| 195 | − } | |
| 196 | 213 | |
| 197 | 214 | mutex_init(&wq->wq_lock); |
| 198 | 215 | init_waitqueue_head(&wq->err_queue); |
| @@ -203,7 +220,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 4 unmodified lines | ||
| 203 | 220 | wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; |
| 204 | 221 | wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); |
| 205 | 222 | if (!wq->wqcfg) { |
| 206 | − put_device(conf_dev); | |
| 207 | 223 | rc = -ENOMEM; |
| 208 | 224 | goto err; |
| 209 | 225 | } |
| @@ -211,9 +227,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 1 unmodified line | ||
| 211 | 227 | if (idxd->hw.wq_cap.op_config) { |
| 212 | 228 | wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL); |
| 213 | 229 | if (!wq->opcap_bmap) { |
| 214 | − put_device(conf_dev); | |
| 215 | 230 | rc = -ENOMEM; |
| 216 | − goto err; | |
| 231 | + goto err_opcap_bmap; | |
| 217 | 232 | } |
| 218 | 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 | 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 | 249 | while (--i >= 0) { |
| 229 | 250 | wq = idxd->wqs[i]; |
| 251 | + if (idxd->hw.wq_cap.op_config) | |
| 252 | + bitmap_free(wq->opcap_bmap); | |
| 253 | + kfree(wq->wqcfg); | |
| 230 | 254 | conf_dev = wq_confdev(wq); |
| 231 | 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 | 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 | 282 | static int idxd_setup_engines(struct idxd_device *idxd) |
| 237 | 283 | { |
| 238 | 284 | struct idxd_engine *engine; |
| @@ -263,6 +309,7 @@ static int idxd_setup_engines(struct idxd_device *idxd) · 24 unmodified lines | ||
| 263 | 309 | rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id); |
| 264 | 310 | if (rc < 0) { |
| 265 | 311 | put_device(conf_dev); |
| 312 | + kfree(engine); | |
| 266 | 313 | goto err; |
| 267 | 314 | } |
| 268 | 315 | |
| @@ -276,10 +323,26 @@ static int idxd_setup_engines(struct idxd_device *idxd) · 7 unmodified lines | ||
| 276 | 323 | engine = idxd->engines[i]; |
| 277 | 324 | conf_dev = engine_confdev(engine); |
| 278 | 325 | put_device(conf_dev); |
| 326 | + kfree(engine); | |
| 279 | 327 | } |
| 328 | + kfree(idxd->engines); | |
| 329 | + | |
| 280 | 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 | 346 | static int idxd_setup_groups(struct idxd_device *idxd) |
| 284 | 347 | { |
| 285 | 348 | struct device *dev = &idxd->pdev->dev; |
| @@ -310,6 +373,7 @@ static int idxd_setup_groups(struct idxd_device *idxd) · 24 unmodified lines | ||
| 310 | 373 | rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id); |
| 311 | 374 | if (rc < 0) { |
| 312 | 375 | put_device(conf_dev); |
| 376 | + kfree(group); | |
| 313 | 377 | goto err; |
| 314 | 378 | } |
| 315 | 379 | |
| @@ -334,20 +398,18 @@ static int idxd_setup_groups(struct idxd_device *idxd) · 18 unmodified lines | ||
| 334 | 398 | while (--i >= 0) { |
| 335 | 399 | group = idxd->groups[i]; |
| 336 | 400 | put_device(group_confdev(group)); |
| 401 | + kfree(group); | |
| 337 | 402 | } |
| 403 | + kfree(idxd->groups); | |
| 404 | + | |
| 338 | 405 | return rc; |
| 339 | 406 | } |
| 340 | 407 | |
| 341 | 408 | static void idxd_cleanup_internals(struct idxd_device *idxd) |
| 342 | 409 | { |
| 343 | − int i; | |
| 344 | − | |
| 345 | − for (i = 0; i < idxd->max_groups; i++) | |
| 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])); | |
| 410 | + idxd_clean_groups(idxd); | |
| 411 | + idxd_clean_engines(idxd); | |
| 412 | + idxd_clean_wqs(idxd); | |
| 351 | 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 | 452 | static int idxd_setup_internals(struct idxd_device *idxd) |
| 391 | 453 | { |
| 392 | 454 | struct device *dev = &idxd->pdev->dev; |
| 393 | − int rc, i; | |
| 455 | + int rc; | |
| 394 | 456 | |
| 395 | 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 | 483 | err_evl: |
| 422 | 484 | destroy_workqueue(idxd->wq); |
| 423 | 485 | err_wkq_create: |
| 424 | − for (i = 0; i < idxd->max_groups; i++) | |
| 425 | − put_device(group_confdev(idxd->groups[i])); | |
| 486 | + idxd_clean_groups(idxd); | |
| 426 | 487 | err_group: |
| 427 | − for (i = 0; i < idxd->max_engines; i++) | |
| 428 | − put_device(engine_confdev(idxd->engines[i])); | |
| 488 | + idxd_clean_engines(idxd); | |
| 429 | 489 | err_engine: |
| 430 | − for (i = 0; i < idxd->max_wqs; i++) | |
| 431 | − put_device(wq_confdev(idxd->wqs[i])); | |
| 490 | + idxd_clean_wqs(idxd); | |
| 432 | 491 | err_wqs: |
| 433 | 492 | return rc; |
| 434 | 493 | } |
| @@ -528,6 +587,17 @@ static void idxd_read_caps(struct idxd_device *idxd) · 93 unmodified lines | ||
| 528 | 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 | 601 | static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) |
| 532 | 602 | { |
| 533 | 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 | 615 | idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type); |
| 546 | 616 | idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL); |
| 547 | 617 | if (idxd->id < 0) |
| 548 | − return NULL; | |
| 618 | + goto err_ida; | |
| 549 | 619 | |
| 550 | 620 | idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev)); |
| 551 | − if (!idxd->opcap_bmap) { | |
| 552 | − ida_free(&idxd_ida, idxd->id); | |
| 553 | − return NULL; | |
| 554 | − } | |
| 621 | + if (!idxd->opcap_bmap) | |
| 622 | + goto err_opcap; | |
| 555 | 623 | |
| 556 | 624 | device_initialize(conf_dev); |
| 557 | 625 | conf_dev->parent = dev; |
| 558 | 626 | conf_dev->bus = &dsa_bus_type; |
| 559 | 627 | conf_dev->type = idxd->data->dev_type; |
| 560 | 628 | rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id); |
| 561 | − if (rc < 0) { | |
| 562 | − put_device(conf_dev); | |
| 563 | − return NULL; | |
| 564 | − } | |
| 629 | + if (rc < 0) | |
| 630 | + goto err_name; | |
| 565 | 631 | |
| 566 | 632 | spin_lock_init(&idxd->dev_lock); |
| 567 | 633 | spin_lock_init(&idxd->cmd_lock); |
| 568 | 634 | |
| 569 | 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 | 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 | 1266 | err: |
| 1191 | 1267 | pci_iounmap(pdev, idxd->reg_base); |
| 1192 | 1268 | err_iomap: |
| 1193 | − put_device(idxd_confdev(idxd)); | |
| 1269 | + idxd_free(idxd); | |
| 1194 | 1270 | err_idxd_alloc: |
| 1195 | 1271 | pci_disable_device(pdev); |
| 1196 | 1272 | return rc; |
| @@ -1232,7 +1308,6 @@ static void idxd_shutdown(struct pci_dev *pdev) · 35 unmodified lines | ||
| 1232 | 1308 | static void idxd_remove(struct pci_dev *pdev) |
| 1233 | 1309 | { |
| 1234 | 1310 | struct idxd_device *idxd = pci_get_drvdata(pdev); |
| 1235 | − struct idxd_irq_entry *irq_entry; | |
| 1236 | 1311 | |
| 1237 | 1312 | idxd_unregister_devices(idxd); |
| 1238 | 1313 | /* |
| @@ -1245,20 +1320,12 @@ static void idxd_remove(struct pci_dev *pdev) · 6 unmodified lines | ||
| 1245 | 1320 | get_device(idxd_confdev(idxd)); |
| 1246 | 1321 | device_unregister(idxd_confdev(idxd)); |
| 1247 | 1322 | idxd_shutdown(pdev); |
| 1248 | − if (device_pasid_enabled(idxd)) | |
| 1249 | − idxd_disable_system_pasid(idxd); | |
| 1250 | 1323 | idxd_device_remove_debugfs(idxd); |
| 1251 | − | |
| 1252 | − irq_entry = idxd_get_ie(idxd, 0); | |
| 1253 | − free_irq(irq_entry->vector, irq_entry); | |
| 1254 | − pci_free_irq_vectors(pdev); | |
| 1324 | + idxd_cleanup(idxd); | |
| 1255 | 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 | 1326 | put_device(idxd_confdev(idxd)); |
| 1327 | + idxd_free(idxd); | |
| 1328 | + pci_disable_device(pdev); | |
| 1262 | 1329 | } |
| 1263 | 1330 | |
| 1264 | 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 | 421 | struct mtk_cqdma_vchan *cvc = to_cqdma_vchan(c); |
| 422 | 422 | struct virt_dma_desc *vd; |
| 423 | − unsigned long flags; | |
| 424 | 423 | |
| 425 | − spin_lock_irqsave(&cvc->pc->lock, flags); | |
| 426 | 424 | list_for_each_entry(vd, &cvc->pc->queue, node) |
| 427 | 425 | if (vd->tx.cookie == cookie) { |
| 428 | − spin_unlock_irqrestore(&cvc->pc->lock, flags); | |
| 429 | 426 | return vd; |
| 430 | 427 | } |
| 431 | − spin_unlock_irqrestore(&cvc->pc->lock, flags); | |
| 432 | 428 | |
| 433 | 429 | list_for_each_entry(vd, &cvc->vc.desc_issued, node) |
| 434 | 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 | 448 | if (ret == DMA_COMPLETE || !txstate) |
| 453 | 449 | return ret; |
| 454 | 450 | |
| 451 | + spin_lock_irqsave(&cvc->pc->lock, flags); | |
| 455 | 452 | spin_lock_irqsave(&cvc->vc.lock, flags); |
| 456 | 453 | vd = mtk_cqdma_find_active_desc(c, cookie); |
| 457 | 454 | spin_unlock_irqrestore(&cvc->vc.lock, flags); |
| 455 | + spin_unlock_irqrestore(&cvc->pc->lock, flags); | |
| 458 | 456 | |
| 459 | 457 | if (vd) { |
| 460 | 458 | cvd = to_cqdma_vdesc(vd); |
| @@ -1091,8 +1091,11 @@ static void udma_check_tx_completion(struct work_struct *work) · 1090 unmodified lines | ||
| 1091 | 1091 | u32 residue_diff; |
| 1092 | 1092 | ktime_t time_diff; |
| 1093 | 1093 | unsigned long delay; |
| 1094 | + unsigned long flags; | |
| 1094 | 1095 | |
| 1095 | 1096 | while (1) { |
| 1097 | + spin_lock_irqsave(&uc->vc.lock, flags); | |
| 1098 | + | |
| 1096 | 1099 | if (uc->desc) { |
| 1097 | 1100 | /* Get previous residue and time stamp */ |
| 1098 | 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 | 1130 | break; |
| 1128 | 1131 | } |
| 1129 | 1132 | |
| 1133 | + spin_unlock_irqrestore(&uc->vc.lock, flags); | |
| 1134 | + | |
| 1130 | 1135 | usleep_range(ktime_to_us(delay), |
| 1131 | 1136 | ktime_to_us(delay) + 10); |
| 1132 | 1137 | continue; |
| @@ -1143,6 +1148,8 @@ static void udma_check_tx_completion(struct work_struct *work) · 10 unmodified lines | ||
| 1143 | 1148 | |
| 1144 | 1149 | break; |
| 1145 | 1150 | } |
| 1151 | + | |
| 1152 | + spin_unlock_irqrestore(&uc->vc.lock, flags); | |
| 1146 | 1153 | } |
| 1147 | 1154 | |
| 1148 | 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 | 4253 | struct of_dma *ofdma) |
| 4247 | 4254 | { |
| 4248 | 4255 | struct udma_dev *ud = ofdma->of_dma_data; |
| 4249 | − dma_cap_mask_t mask = ud->ddev.cap_mask; | |
| 4250 | 4256 | struct udma_filter_param filter_param; |
| 4251 | 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 | 4288 | ofdma->of_node); |
| 4283 | 4289 | if (!chan) { |
| 4284 | 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 | 99 | if (status & priv->ecc_stat_ce_mask) { |
| 100 | 100 | regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, |
| 101 | 101 | &err_addr); |
| 102 | − if (priv->ecc_uecnt_offset) | |
| 102 | + if (priv->ecc_cecnt_offset) | |
| 103 | 103 | regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, |
| 104 | 104 | &err_count); |
| 105 | 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 | 1008 | /* Enable ECC */ |
| 1012 | 1009 | ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base + |
| 1013 | 1010 | ALTR_A10_ECC_CTRL_OFST)); |
| @@ -2127,6 +2124,10 @@ static int altr_edac_a10_probe(struct platform_device *pdev) · 1113 unmodified lines | ||
| 2127 | 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 | 2131 | edac->irq_chip.name = pdev->dev.of_node->name; |
| 2131 | 2132 | edac->irq_chip.irq_mask = a10_eccmgr_irq_mask; |
| 2132 | 2133 | edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask; |
| @@ -249,6 +249,8 @@ struct altr_sdram_mc_data { · 248 unmodified lines | ||
| 249 | 249 | #define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94 |
| 250 | 250 | #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 |
| 251 | 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 | 255 | #define A10_SYSMGR_ECC_INTSTAT_SERR_OFST 0x9C |
| 254 | 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 | 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 | 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 | 255 | if (!dev) |
| 256 | 256 | return NULL; |
| 257 | 257 | |
| 258 | + /* Drop the refcnt bumped implicitly by device_find_child */ | |
| 259 | + put_device(dev); | |
| 260 | + | |
| 258 | 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 | 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 | 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 | 1258 | * in case of out-of-order receptions of delayed responses |
| 1258 | 1259 | */ |
| 1259 | 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 | 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 | 1275 | * itself to support synchronous commands replies. |
| 1275 | 1276 | */ |
| 1276 | 1277 | if (!desc->sync_cmds_completed_on_ret) { |
| 1278 | + bool ooo = false; | |
| 1279 | + | |
| 1277 | 1280 | /* |
| 1278 | 1281 | * Poll on xfer using transport provided .poll_done(); |
| 1279 | 1282 | * assumes no completion interrupt was available. |
| 1280 | 1283 | */ |
| 1281 | 1284 | ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); |
| 1282 | 1285 | |
| 1283 | − spin_until_cond(scmi_xfer_done_no_timeout(cinfo, | |
| 1284 | − xfer, stop)); | |
| 1285 | − if (ktime_after(ktime_get(), stop)) { | |
| 1286 | + spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, | |
| 1287 | + stop, &ooo)); | |
| 1288 | + if (!ooo && !info->desc->ops->poll_done(cinfo, xfer)) { | |
| 1286 | 1289 | dev_err(dev, |
| 1287 | 1290 | "timed out in resp(caller: %pS) - polling\n", |
| 1288 | 1291 | (void *)_RET_IP_); |
| @@ -6,14 +6,11 @@ config FW_CS_DSP · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | config FW_CS_DSP_KUNIT_TEST_UTILS |
| 8 | 8 | tristate |
| 9 | − depends on KUNIT && REGMAP | |
| 10 | − select FW_CS_DSP | |
| 11 | 9 | |
| 12 | 10 | config FW_CS_DSP_KUNIT_TEST |
| 13 | 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 | 13 | default KUNIT_ALL_TESTS |
| 16 | − select FW_CS_DSP | |
| 17 | 14 | select FW_CS_DSP_KUNIT_TEST_UTILS |
| 18 | 15 | help |
| 19 | 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 | 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 | 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 | 2199 | priv->local->bin_builder = |
| 2200 | 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 | 2202 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder); |
| 2203 | 2203 | |
| 2204 | 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 | 452 | local->bin_builder = |
| 453 | 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 | 455 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->bin_builder); |
| 456 | 456 | |
| 457 | 457 | /* Init cs_dsp */ |
| @@ -184,6 +184,29 @@ struct acpm_match_data { · 183 unmodified lines | ||
| 184 | 184 | #define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl) |
| 185 | 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 | 211 | * acpm_get_rx() - get response from RX queue. |
| 189 | 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 | 227 | rx_front = readl(achan->rx.front); |
| 205 | 228 | i = readl(achan->rx.rear); |
| 206 | 229 | |
| 207 | − /* Bail out if RX is empty. */ | |
| 208 | − if (i == rx_front) | |
| 230 | + tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]); | |
| 231 | + | |
| 232 | + if (i == rx_front) { | |
| 233 | + acpm_get_saved_rx(achan, xfer, tx_seqnum); | |
| 209 | 234 | return 0; |
| 235 | + } | |
| 210 | 236 | |
| 211 | 237 | base = achan->rx.base; |
| 212 | 238 | mlen = achan->mlen; |
| 213 | 239 | |
| 214 | − tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]); | |
| 215 | − | |
| 216 | 240 | /* Drain RX queue. */ |
| 217 | 241 | do { |
| 218 | 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 | 283 | * If the response was not in this iteration of the queue, check if the |
| 260 | 284 | * RX data was previously saved. |
| 261 | 285 | */ |
| 262 | − rx_data = &achan->rx_data[tx_seqnum - 1]; | |
| 263 | − if (!rx_set && rx_data->response) { | |
| 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 | − } | |
| 286 | + if (!rx_set) | |
| 287 | + acpm_get_saved_rx(achan, xfer, tx_seqnum); | |
| 272 | 288 | |
| 273 | 289 | return 0; |
| 274 | 290 | } |
| @@ -95,7 +95,7 @@ void __init kvm_arm_target_impl_cpu_init(void) · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | for (i = 0; i < max_cpus; i++) { |
| 97 | 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 | 99 | if (res.a0 != SMCCC_RET_SUCCESS) { |
| 100 | 100 | pr_warn("Discovering target implementation CPUs failed\n"); |
| 101 | 101 | goto mem_free; |
| @@ -103,7 +103,7 @@ void __init kvm_arm_target_impl_cpu_init(void) · 1 unmodified line | ||
| 103 | 103 | target[i].midr = res.a1; |
| 104 | 104 | target[i].revidr = res.a2; |
| 105 | 105 | target[i].aidr = res.a3; |
| 106 | − }; | |
| 106 | + } | |
| 107 | 107 | |
| 108 | 108 | if (!cpu_errata_set_target_impl(max_cpus, target)) { |
| 109 | 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 | 1224 | if (!svc->intel_svc_fcs) { |
| 1225 | 1225 | dev_err(dev, "failed to allocate %s device\n", INTEL_FCS); |
| 1226 | 1226 | ret = -ENOMEM; |
| 1227 | − goto err_unregister_dev; | |
| 1227 | + goto err_unregister_rsu_dev; | |
| 1228 | 1228 | } |
| 1229 | 1229 | |
| 1230 | 1230 | ret = platform_device_add(svc->intel_svc_fcs); |
| 1231 | 1231 | if (ret) { |
| 1232 | 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 | 1240 | dev_set_drvdata(dev, svc); |
| 1237 | 1241 | |
| 1238 | 1242 | pr_info("Intel Service Layer Driver Initialized\n"); |
| 1239 | 1243 | |
| 1240 | 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 | 1249 | platform_device_unregister(svc->stratix10_svc_rsu); |
| 1244 | 1250 | err_free_kfifo: |
| 1245 | 1251 | kfifo_free(&controller->svc_fifo); |
| @@ -1253,6 +1259,8 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev) · 7 unmodified lines | ||
| 1253 | 1259 | struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); |
| 1254 | 1260 | struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev); |
| 1255 | 1261 | |
| 1262 | + of_platform_depopulate(ctrl->dev); | |
| 1263 | + | |
| 1256 | 1264 | platform_device_unregister(svc->intel_svc_fcs); |
| 1257 | 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 | 171 | kunit_test_suite(fpga_bridge_suite); |
| 172 | 172 | |
| 173 | +MODULE_DESCRIPTION("KUnit test for the FPGA Bridge"); | |
| 173 | 174 | MODULE_LICENSE("GPL"); |
| @@ -330,4 +330,5 @@ static struct kunit_suite fpga_mgr_suite = { · 329 unmodified lines | ||
| 330 | 330 | |
| 331 | 331 | kunit_test_suite(fpga_mgr_suite); |
| 332 | 332 | |
| 333 | +MODULE_DESCRIPTION("KUnit test for the FPGA Manager"); | |
| 333 | 334 | MODULE_LICENSE("GPL"); |
| @@ -214,4 +214,5 @@ static struct kunit_suite fpga_region_suite = { · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | kunit_test_suite(fpga_region_suite); |
| 216 | 216 | |
| 217 | +MODULE_DESCRIPTION("KUnit test for the FPGA Region"); | |
| 217 | 218 | MODULE_LICENSE("GPL"); |
| @@ -105,7 +105,7 @@ static int fwctl_cmd_rpc(struct fwctl_ucmd *ucmd) · 104 unmodified lines | ||
| 105 | 105 | if (!test_and_set_bit(0, &fwctl_tainted)) { |
| 106 | 106 | dev_warn( |
| 107 | 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 | 109 | current->comm, task_pid_nr(current)); |
| 110 | 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 | 105 | static void pdsfc_free_endpoints(struct pdsfc_dev *pdsfc) |
| 106 | 106 | { |
| 107 | 107 | struct device *dev = &pdsfc->fwctl.dev; |
| 108 | + u32 num_endpoints; | |
| 108 | 109 | int i; |
| 109 | 110 | |
| 110 | 111 | if (!pdsfc->endpoints) |
| 111 | 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 | 116 | mutex_destroy(&pdsfc->endpoint_info[i].lock); |
| 115 | 117 | vfree(pdsfc->endpoint_info); |
| 116 | 118 | pdsfc->endpoint_info = NULL; |
| @@ -199,7 +201,7 @@ static int pdsfc_init_endpoints(struct pdsfc_dev *pdsfc) · 82 unmodified lines | ||
| 199 | 201 | ep_entry = (struct pds_fwctl_query_data_endpoint *)pdsfc->endpoints->entries; |
| 200 | 202 | for (i = 0; i < num_endpoints; i++) { |
| 201 | 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 | 207 | return 0; |
| @@ -214,6 +216,7 @@ static struct pds_fwctl_query_data *pdsfc_get_operations(struct pdsfc_dev *pdsfc · 8 unmodified lines | ||
| 214 | 216 | struct pds_fwctl_query_data *data; |
| 215 | 217 | union pds_core_adminq_cmd cmd; |
| 216 | 218 | dma_addr_t data_pa; |
| 219 | + u32 num_entries; | |
| 217 | 220 | int err; |
| 218 | 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 | 249 | *pa = data_pa; |
| 247 | 250 | |
| 248 | 251 | entries = (struct pds_fwctl_query_data_operation *)data->entries; |
| 249 | − dev_dbg(dev, "num_entries %d\n", data->num_entries); | |
| 250 | − for (i = 0; i < data->num_entries; i++) { | |
| 252 | + num_entries = le32_to_cpu(data->num_entries); | |
| 253 | + dev_dbg(dev, "num_entries %d\n", num_entries); | |
| 254 | + for (i = 0; i < num_entries; i++) { | |
| 251 | 255 | |
| 252 | 256 | /* Translate FW command attribute to fwctl scope */ |
| 253 | 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 | 271 | break; |
| 268 | 272 | } |
| 269 | 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 | 277 | return data; |
| @@ -280,24 +284,26 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc, · 6 unmodified lines | ||
| 280 | 284 | struct pds_fwctl_query_data_operation *op_entry; |
| 281 | 285 | struct pdsfc_rpc_endpoint_info *ep_info = NULL; |
| 282 | 286 | struct device *dev = &pdsfc->fwctl.dev; |
| 287 | + u32 num_entries; | |
| 283 | 288 | int i; |
| 284 | 289 | |
| 285 | 290 | /* validate rpc in_len & out_len based |
| 286 | 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 | 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 | 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 | 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 | 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 | 307 | if (pdsfc->endpoint_info[i].endpoint == rpc->in.ep) { |
| 302 | 308 | ep_info = &pdsfc->endpoint_info[i]; |
| 303 | 309 | break; |
| @@ -326,8 +332,9 @@ static int pdsfc_validate_rpc(struct pdsfc_dev *pdsfc, · 22 unmodified lines | ||
| 326 | 332 | |
| 327 | 333 | /* reject unsupported and/or out of scope commands */ |
| 328 | 334 | op_entry = (struct pds_fwctl_query_data_operation *)ep_info->operations->entries; |
| 329 | − for (i = 0; i < ep_info->operations->num_entries; i++) { | |
| 330 | − if (PDS_FWCTL_RPC_OPCODE_CMP(rpc->in.op, op_entry[i].id)) { | |
| 335 | + num_entries = le32_to_cpu(ep_info->operations->num_entries); | |
| 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 | 338 | if (scope < op_entry[i].scope) |
| 332 | 339 | return -EPERM; |
| 333 | 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 | 409 | cmd = (union pds_core_adminq_cmd) { |
| 403 | 410 | .fwctl_rpc = { |
| 404 | 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 | 413 | .ep = cpu_to_le32(rpc->in.ep), |
| 407 | 414 | .op = cpu_to_le32(rpc->in.op), |
| 408 | 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 | 187 | Encourage users to switch to using them and eventually remove the existing |
| 188 | 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 | 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 | 417 | return 0; |
| 416 | 418 | err: |
| @@ -1204,6 +1204,8 @@ static int pca953x_restore_context(struct pca953x_chip *chip) · 1203 unmodified lines | ||
| 1204 | 1204 | |
| 1205 | 1205 | guard(mutex)(&chip->i2c_lock); |
| 1206 | 1206 | |
| 1207 | + if (chip->client->irq > 0) | |
| 1208 | + enable_irq(chip->client->irq); | |
| 1207 | 1209 | regcache_cache_only(chip->regmap, false); |
| 1208 | 1210 | regcache_mark_dirty(chip->regmap); |
| 1209 | 1211 | ret = pca953x_regcache_sync(chip); |
| @@ -1216,6 +1218,10 @@ static int pca953x_restore_context(struct pca953x_chip *chip) · 6 unmodified lines | ||
| 1216 | 1218 | static void pca953x_save_context(struct pca953x_chip *chip) |
| 1217 | 1219 | { |
| 1218 | 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 | 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 | 823 | struct gpio_irq_chip *irq; |
| 824 | 824 | struct tegra_gpio *gpio; |
| 825 | 825 | struct device_node *np; |
| 826 | + struct resource *res; | |
| 826 | 827 | char **names; |
| 827 | 828 | int err; |
| 828 | 829 | |
| @@ -842,19 +843,19 @@ static int tegra186_gpio_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 842 | 843 | gpio->num_banks++; |
| 843 | 844 | |
| 844 | 845 | /* get register apertures */ |
| 845 | − gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); | |
| 846 | − if (IS_ERR(gpio->secure)) { | |
| 847 | − gpio->secure = devm_platform_ioremap_resource(pdev, 0); | |
| 848 | − if (IS_ERR(gpio->secure)) | |
| 849 | − return PTR_ERR(gpio->secure); | |
| 850 | − } | |
| 851 | − | |
| 852 | − gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); | |
| 853 | − if (IS_ERR(gpio->base)) { | |
| 854 | − gpio->base = devm_platform_ioremap_resource(pdev, 1); | |
| 855 | − if (IS_ERR(gpio->base)) | |
| 856 | − return PTR_ERR(gpio->base); | |
| 857 | − } | |
| 846 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "security"); | |
| 847 | + if (!res) | |
| 848 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 849 | + gpio->secure = devm_ioremap_resource(&pdev->dev, res); | |
| 850 | + if (IS_ERR(gpio->secure)) | |
| 851 | + return PTR_ERR(gpio->secure); | |
| 852 | + | |
| 853 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio"); | |
| 854 | + if (!res) | |
| 855 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | |
| 856 | + gpio->base = devm_ioremap_resource(&pdev->dev, res); | |
| 857 | + if (IS_ERR(gpio->base)) | |
| 858 | + return PTR_ERR(gpio->base); | |
| 858 | 859 | |
| 859 | 860 | err = platform_irq_count(pdev); |
| 860 | 861 | if (err < 0) |
| @@ -401,10 +401,15 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file, · 400 unmodified lines | ||
| 401 | 401 | char buf[32], *trimmed; |
| 402 | 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 | 408 | if (ret < 0) |
| 406 | 409 | return ret; |
| 407 | 410 | |
| 411 | + buf[ret] = '\0'; | |
| 412 | + | |
| 408 | 413 | trimmed = strim(buf); |
| 409 | 414 | |
| 410 | 415 | if (strcmp(trimmed, "input") == 0) { |
| @@ -623,12 +628,15 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file, · 212 unmodified lines | ||
| 623 | 628 | char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2]; |
| 624 | 629 | int ret; |
| 625 | 630 | |
| 631 | + if (count >= sizeof(buf)) | |
| 632 | + return -EINVAL; | |
| 633 | + | |
| 626 | 634 | ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos, |
| 627 | 635 | user_buf, count); |
| 628 | 636 | if (ret < 0) |
| 629 | 637 | return ret; |
| 630 | 638 | |
| 631 | − buf[strlen(buf) - 1] = '\0'; | |
| 639 | + buf[ret] = '\0'; | |
| 632 | 640 | |
| 633 | 641 | ret = gpiod_set_consumer_name(data->ad.desc, buf); |
| 634 | 642 | if (ret) |
| @@ -1011,6 +1011,7 @@ static void zynq_gpio_remove(struct platform_device *pdev) · 1010 unmodified lines | ||
| 1011 | 1011 | ret = pm_runtime_get_sync(&pdev->dev); |
| 1012 | 1012 | if (ret < 0) |
| 1013 | 1013 | dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); |
| 1014 | + device_init_wakeup(&pdev->dev, 0); | |
| 1014 | 1015 | gpiochip_remove(&gpio->chip); |
| 1015 | 1016 | device_set_wakeup_capable(&pdev->dev, 0); |
| 1016 | 1017 | pm_runtime_disable(&pdev->dev); |
| @@ -317,11 +317,15 @@ EXPORT_SYMBOL_GPL(devm_gpiod_put); · 316 unmodified lines | ||
| 317 | 317 | * @dev: GPIO consumer |
| 318 | 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 | 325 | * Remove resource management from a GPIO descriptor. This is needed when |
| 321 | 326 | * you want to hand over lifecycle management of a descriptor to another |
| 322 | 327 | * mechanism. |
| 323 | 328 | */ |
| 324 | − | |
| 325 | 329 | void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc) |
| 326 | 330 | { |
| 327 | 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 | 194 | { "himax,hx8357", "gpios-reset", false }, |
| 195 | 195 | { "himax,hx8369", "gpios-reset", false }, |
| 196 | +#endif | |
| 197 | +#if IS_ENABLED(CONFIG_MTD_NAND_JZ4780) | |
| 196 | 198 | /* |
| 197 | 199 | * The rb-gpios semantics was undocumented and qi,lb60 (along with |
| 198 | 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 | 268 | { "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" }, |
| 267 | 269 | { "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" }, |
| 268 | 270 | #endif |
| 271 | +#if IS_ENABLED(CONFIG_MMC_ATMELMCI) | |
| 272 | + { "atmel,hsmci", "cd-gpios", "cd-inverted" }, | |
| 273 | +#endif | |
| 269 | 274 | #if IS_ENABLED(CONFIG_PCI_IMX6) |
| 270 | 275 | { "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" }, |
| 271 | 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 | 296 | #if IS_ENABLED(CONFIG_REGULATOR_GPIO) |
| 292 | 297 | { "regulator-gpio", "enable-gpio", "enable-active-high" }, |
| 293 | 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 | 299 | #endif |
| 298 | 300 | }; |
| 299 | 301 | unsigned int i; |
| @@ -742,6 +742,12 @@ EXPORT_SYMBOL_GPL(gpiochip_query_valid_mask); · 741 unmodified lines | ||
| 742 | 742 | bool gpiochip_line_is_valid(const struct gpio_chip *gc, |
| 743 | 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 | 751 | /* No mask means all valid */ |
| 746 | 752 | if (likely(!gc->gpiodev->valid_mask)) |
| 747 | 753 | return true; |
| @@ -2879,7 +2885,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value) · 2131 unmodified lines | ||
| 2879 | 2885 | * output-only, but if there is then not even a .set() operation it |
| 2880 | 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 | 2889 | gpiod_warn(desc, |
| 2884 | 2890 | "%s: missing set() and direction_output() operations\n", |
| 2885 | 2891 | __func__); |
| @@ -188,7 +188,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS · 187 unmodified lines | ||
| 188 | 188 | bool "Enable refcount backtrace history in the DP MST helpers" |
| 189 | 189 | depends on STACKTRACE_SUPPORT |
| 190 | 190 | select STACKDEPOT |
| 191 | − depends on DRM_KMS_HELPER | |
| 191 | + select DRM_KMS_HELPER | |
| 192 | 192 | depends on DEBUG_KERNEL |
| 193 | 193 | depends on EXPERT |
| 194 | 194 | help |
| @@ -121,7 +121,6 @@ struct adp_drv_private { · 120 unmodified lines | ||
| 121 | 121 | dma_addr_t mask_iova; |
| 122 | 122 | int be_irq; |
| 123 | 123 | int fe_irq; |
| 124 | − spinlock_t irq_lock; | |
| 125 | 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 | 287 | writel(BIT(0), adp->be + ADBE_BLEND_EN3); |
| 289 | 288 | writel(BIT(0), adp->be + ADBE_BLEND_BYPASS); |
| 290 | 289 | writel(BIT(0), adp->be + ADBE_BLEND_EN4); |
| 290 | + drm_crtc_vblank_on(crtc); | |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | 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 | 310 | struct drm_atomic_state *state) |
| 311 | 311 | { |
| 312 | 312 | u32 frame_num = 1; |
| 313 | + unsigned long flags; | |
| 313 | 314 | struct adp_drv_private *adp = crtc_to_adp(crtc); |
| 314 | 315 | struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); |
| 315 | 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 | 332 | writel(ADBE_FIFO_SYNC | frame_num, adp->be + ADBE_FIFO); |
| 332 | 333 | //FIXME: use adbe flush interrupt |
| 333 | − spin_lock_irq(&crtc->dev->event_lock); | |
| 334 | 334 | if (crtc->state->event) { |
| 335 | − drm_crtc_vblank_get(crtc); | |
| 336 | − adp->event = crtc->state->event; | |
| 335 | + struct drm_pending_vblank_event *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 | 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 | 489 | u32 int_status; |
| 483 | 490 | u32 int_ctl; |
| 484 | 491 | |
| 485 | − spin_lock(&adp->irq_lock); | |
| 486 | − | |
| 487 | 492 | int_status = readl(adp->fe + ADP_INT_STATUS); |
| 488 | 493 | if (int_status & ADP_INT_STATUS_VBLANK) { |
| 489 | 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 | 507 | writel(int_status, adp->fe + ADP_INT_STATUS); |
| 503 | 508 | |
| 504 | − spin_unlock(&adp->irq_lock); | |
| 505 | 509 | |
| 506 | 510 | return IRQ_HANDLED; |
| 507 | 511 | } |
| @@ -512,8 +516,7 @@ static int adp_drm_bind(struct device *dev) · 4 unmodified lines | ||
| 512 | 516 | struct adp_drv_private *adp = to_adp(drm); |
| 513 | 517 | int err; |
| 514 | 518 | |
| 515 | − adp_disable_vblank(adp); | |
| 516 | − writel(ADP_CTRL_FIFO_ON | ADP_CTRL_VBLANK_ON, adp->fe + ADP_CTRL); | |
| 519 | + writel(ADP_CTRL_FIFO_ON, adp->fe + ADP_CTRL); | |
| 517 | 520 | |
| 518 | 521 | adp->next_bridge = drmm_of_get_bridge(&adp->drm, dev->of_node, 0, 0); |
| 519 | 522 | if (IS_ERR(adp->next_bridge)) { |
| @@ -567,8 +570,6 @@ static int adp_probe(struct platform_device *pdev) · 47 unmodified lines | ||
| 567 | 570 | if (IS_ERR(adp)) |
| 568 | 571 | return PTR_ERR(adp); |
| 569 | 572 | |
| 570 | − spin_lock_init(&adp->irq_lock); | |
| 571 | − | |
| 572 | 573 | dev_set_drvdata(&pdev->dev, &adp->drm); |
| 573 | 574 | |
| 574 | 575 | err = adp_parse_of(pdev, adp); |
| @@ -353,7 +353,6 @@ enum amdgpu_kiq_irq { · 352 unmodified lines | ||
| 353 | 353 | AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0, |
| 354 | 354 | AMDGPU_CP_KIQ_IRQ_LAST |
| 355 | 355 | }; |
| 356 | −#define SRIOV_USEC_TIMEOUT 1200000 /* wait 12 * 100ms for SRIOV */ | |
| 357 | 356 | #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ |
| 358 | 357 | #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ |
| 359 | 358 | #define MAX_KIQ_REG_TRY 1000 |
| @@ -1124,6 +1123,7 @@ struct amdgpu_device { · 764 unmodified lines | ||
| 1124 | 1123 | bool in_s3; |
| 1125 | 1124 | bool in_s4; |
| 1126 | 1125 | bool in_s0ix; |
| 1126 | + suspend_state_t last_suspend_state; | |
| 1127 | 1127 | |
| 1128 | 1128 | enum pp_mp1_state mp1_state; |
| 1129 | 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 | 1614 | #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) |
| 1615 | 1615 | bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); |
| 1616 | 1616 | bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); |
| 1617 | −void amdgpu_choose_low_power_state(struct amdgpu_device *adev); | |
| 1618 | 1617 | #else |
| 1619 | 1618 | static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } |
| 1620 | 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 | 1620 | #endif |
| 1623 | 1621 | |
| 1624 | 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 | 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 | 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 | 109 | struct drm_exec exec; |
| 110 | 110 | int r; |
| 111 | 111 | |
| 112 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 112 | + drm_exec_init(&exec, 0, 0); | |
| 113 | 113 | drm_exec_until_all_locked(&exec) { |
| 114 | 114 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 115 | 115 | if (likely(!r)) |
| @@ -3510,6 +3510,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 3509 unmodified lines | ||
| 3510 | 3510 | amdgpu_device_mem_scratch_fini(adev); |
| 3511 | 3511 | amdgpu_ib_pool_fini(adev); |
| 3512 | 3512 | amdgpu_seq64_fini(adev); |
| 3513 | + amdgpu_doorbell_fini(adev); | |
| 3513 | 3514 | } |
| 3514 | 3515 | if (adev->ip_blocks[i].version->funcs->sw_fini) { |
| 3515 | 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 | 3644 | adev, adev->ip_blocks[i].version->type)) |
| 3644 | 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 | 3654 | /* skip suspend of gfx/mes and psp for S0ix |
| 3647 | 3655 | * gfx is in gfxoff state, so on resume it will exit gfxoff just |
| 3648 | 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 | 4860 | iounmap(adev->rmmio); |
| 4853 | 4861 | adev->rmmio = NULL; |
| 4854 | − amdgpu_doorbell_fini(adev); | |
| 4855 | 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 | 4907 | * @data: data |
| 4901 | 4908 | * |
| 4902 | 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 | |
| 4904 | − * sleep while there is still access to swap. | |
| 4910 | + * It is used to set the appropriate flags so that eviction can be optimized | |
| 4911 | + * in the pm prepare callback. | |
| 4905 | 4912 | */ |
| 4906 | 4913 | static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, |
| 4907 | 4914 | void *data) |
| 4908 | 4915 | { |
| 4909 | 4916 | struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb); |
| 4910 | − int r; | |
| 4911 | 4917 | |
| 4912 | 4918 | switch (mode) { |
| 4913 | 4919 | case PM_HIBERNATION_PREPARE: |
| 4914 | 4920 | adev->in_s4 = true; |
| 4915 | − fallthrough; | |
| 4916 | − case PM_SUSPEND_PREPARE: | |
| 4917 | − r = amdgpu_device_evict_resources(adev); | |
| 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); | |
| 4921 | + break; | |
| 4922 | + case PM_POST_HIBERNATION: | |
| 4923 | + adev->in_s4 = false; | |
| 4925 | 4924 | break; |
| 4926 | 4925 | } |
| 4927 | 4926 | |
| @@ -4942,15 +4941,13 @@ int amdgpu_device_prepare(struct drm_device *dev) · 14 unmodified lines | ||
| 4942 | 4941 | struct amdgpu_device *adev = drm_to_adev(dev); |
| 4943 | 4942 | int i, r; |
| 4944 | 4943 | |
| 4945 | − amdgpu_choose_low_power_state(adev); | |
| 4946 | − | |
| 4947 | 4944 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 4948 | 4945 | return 0; |
| 4949 | 4946 | |
| 4950 | 4947 | /* Evict the majority of BOs before starting suspend sequence */ |
| 4951 | 4948 | r = amdgpu_device_evict_resources(adev); |
| 4952 | 4949 | if (r) |
| 4953 | − goto unprepare; | |
| 4950 | + return r; | |
| 4954 | 4951 | |
| 4955 | 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 | 4958 | continue; |
| 4962 | 4959 | r = adev->ip_blocks[i].version->funcs->prepare_suspend(&adev->ip_blocks[i]); |
| 4963 | 4960 | if (r) |
| 4964 | − goto unprepare; | |
| 4961 | + return r; | |
| 4965 | 4962 | } |
| 4966 | 4963 | |
| 4967 | 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 | 120 | MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin"); |
| 121 | 121 | MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin"); |
| 122 | 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 | 126 | #define mmIP_DISCOVERY_VERSION 0x16A00 |
| 125 | 127 | #define mmRCC_CONFIG_MEMSIZE 0xde3 |
| @@ -43,6 +43,29 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <linux/dma-fence-array.h> |
| 44 | 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 | 70 | * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation |
| 48 | 71 | * |
| @@ -54,11 +77,13 @@ · 5 unmodified lines | ||
| 54 | 77 | static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, |
| 55 | 78 | struct dma_buf_attachment *attach) |
| 56 | 79 | { |
| 80 | + struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach); | |
| 57 | 81 | struct drm_gem_object *obj = dmabuf->priv; |
| 58 | 82 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); |
| 59 | 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 | 87 | attach->peer2peer = false; |
| 63 | 88 | |
| 64 | 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 | 101 | static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) |
| 77 | 102 | { |
| 78 | − struct drm_gem_object *obj = attach->dmabuf->priv; | |
| 79 | − struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | |
| 103 | + struct dma_buf *dmabuf = attach->dmabuf; | |
| 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 */ | |
| 82 | − return amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); | |
| 125 | + if (domains & AMDGPU_GEM_DOMAIN_VRAM) | |
| 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 | 183 | r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); |
| 135 | 184 | if (r) |
| 136 | 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 | 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 | 199 | break; |
| 154 | 200 | |
| 155 | 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 | 207 | r = amdgpu_vram_mgr_alloc_sgt(adev, bo->tbo.resource, 0, |
| 157 | 208 | bo->tbo.base.size, attach->dev, |
| 158 | 209 | dir, &sgt); |
| @@ -184,7 +235,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, · 25 unmodified lines | ||
| 184 | 235 | struct sg_table *sgt, |
| 185 | 236 | enum dma_data_direction dir) |
| 186 | 237 | { |
| 187 | − if (sgt->sgl->page_link) { | |
| 238 | + if (sg_page(sgt->sgl)) { | |
| 188 | 239 | dma_unmap_sgtable(attach->dev, sgt, dir, 0); |
| 189 | 240 | sg_free_table(sgt); |
| 190 | 241 | kfree(sgt); |
| @@ -459,6 +510,9 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, · 268 unmodified lines | ||
| 459 | 510 | struct drm_gem_object *obj = &bo->tbo.base; |
| 460 | 511 | struct drm_gem_object *gobj; |
| 461 | 512 | |
| 513 | + if (!adev) | |
| 514 | + return false; | |
| 515 | + | |
| 462 | 516 | if (obj->import_attach) { |
| 463 | 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 | 2548 | adev->in_s0ix = true; |
| 2549 | 2549 | else if (amdgpu_acpi_is_s3_active(adev)) |
| 2550 | 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 | 2559 | return 0; |
| 2560 | + } | |
| 2561 | + | |
| 2562 | + /* cache the state last used for suspend */ | |
| 2563 | + adev->last_suspend_state = pm_suspend_target_state; | |
| 2564 | + | |
| 2553 | 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 | 2615 | static int amdgpu_pmops_thaw(struct device *dev) |
| 2604 | 2616 | { |
| 2605 | 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 | 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 | 2629 | static int amdgpu_pmops_restore(struct device *dev) |
| 2623 | 2630 | { |
| 2624 | 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 | 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 | 1438 | struct amdgpu_device *adev = ring->adev; |
| 1439 | 1439 | struct drm_gpu_scheduler *sched = &ring->sched; |
| 1440 | 1440 | struct drm_sched_entity entity; |
| 1441 | + static atomic_t counter; | |
| 1441 | 1442 | struct dma_fence *f; |
| 1442 | 1443 | struct amdgpu_job *job; |
| 1443 | 1444 | struct amdgpu_ib *ib; |
| 1445 | + void *owner; | |
| 1444 | 1446 | int i, r; |
| 1445 | 1447 | |
| 1446 | 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 | 1453 | goto err; |
| 1452 | 1454 | } |
| 1453 | 1455 | |
| 1454 | − r = amdgpu_job_alloc_with_ib(ring->adev, &entity, NULL, | |
| 1455 | − 64, 0, | |
| 1456 | − &job); | |
| 1456 | + /* | |
| 1457 | + * Use some unique dummy value as the owner to make sure we execute | |
| 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 | 1465 | if (r) |
| 1458 | 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 | 699 | uint32_t flush_type, bool all_hub, |
| 700 | 700 | uint32_t inst) |
| 701 | 701 | { |
| 702 | − u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : | |
| 703 | − adev->usec_timeout; | |
| 704 | 702 | struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; |
| 705 | 703 | struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; |
| 706 | 704 | unsigned int ndw; |
| 707 | − int r; | |
| 705 | + int r, cnt = 0; | |
| 708 | 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 | 760 | amdgpu_ring_commit(ring); |
| 763 | 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 | 773 | dev_err(adev->dev, "timeout waiting for kiq fence\n"); |
| 766 | 774 | r = -ETIME; |
| 767 | − } | |
| 775 | + } else | |
| 776 | + r = 0; | |
| 768 | 777 | } |
| 769 | 778 | |
| 770 | 779 | error_unlock_reset: |
| @@ -163,8 +163,8 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain) · 162 unmodified lines | ||
| 163 | 163 | * When GTT is just an alternative to VRAM make sure that we |
| 164 | 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 && | |
| 167 | − !(adev->flags & AMD_IS_APU)) | |
| 166 | + if (abo->tbo.resource && !(adev->flags & AMD_IS_APU) && | |
| 167 | + domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) | |
| 168 | 168 | places[c].flags |= TTM_PL_FLAG_FALLBACK; |
| 169 | 169 | c++; |
| 170 | 170 | } |
| @@ -66,7 +66,6 @@ · 65 unmodified lines | ||
| 66 | 66 | #define VCN_ENC_CMD_REG_WAIT 0x0000000c |
| 67 | 67 | |
| 68 | 68 | #define VCN_AON_SOC_ADDRESS_2_0 0x1f800 |
| 69 | −#define VCN1_AON_SOC_ADDRESS_3_0 0x48000 | |
| 70 | 69 | #define VCN_VID_IP_ADDRESS_2_0 0x0 |
| 71 | 70 | #define VCN_AON_IP_ADDRESS_2_0 0x30000 |
| 72 | 71 | |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include <linux/dma-mapping.h> |
| 26 | 26 | #include <drm/ttm/ttm_range_manager.h> |
| 27 | +#include <drm/drm_drv.h> | |
| 27 | 28 | |
| 28 | 29 | #include "amdgpu.h" |
| 29 | 30 | #include "amdgpu_vm.h" |
| @@ -907,6 +908,9 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) · 877 unmodified lines | ||
| 907 | 908 | struct ttm_resource_manager *man = &mgr->manager; |
| 908 | 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 | 914 | ttm_resource_manager_init(man, &adev->mman.bdev, |
| 911 | 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 | 6116 | if (amdgpu_emu_mode == 1) |
| 6117 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 6117 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 6118 | 6118 | |
| 6119 | 6119 | tmp = RREG32_SOC15(GC, 0, mmCP_PFP_IC_BASE_CNTL); |
| 6120 | 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 | 6194 | if (amdgpu_emu_mode == 1) |
| 6195 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 6195 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 6196 | 6196 | |
| 6197 | 6197 | tmp = RREG32_SOC15(GC, 0, mmCP_CE_IC_BASE_CNTL); |
| 6198 | 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 | 6271 | if (amdgpu_emu_mode == 1) |
| 6272 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 6272 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 6273 | 6273 | |
| 6274 | 6274 | tmp = RREG32_SOC15(GC, 0, mmCP_ME_IC_BASE_CNTL); |
| 6275 | 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 | 6646 | if (amdgpu_emu_mode == 1) |
| 6647 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 6647 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 6648 | 6648 | |
| 6649 | 6649 | tmp = RREG32_SOC15(GC, 0, mmCP_CPC_IC_BASE_CNTL); |
| 6650 | 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 | 2430 | if (amdgpu_emu_mode == 1) |
| 2431 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 2431 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 2432 | 2432 | |
| 2433 | 2433 | tmp = RREG32_SOC15(GC, 0, regCP_ME_IC_BASE_CNTL); |
| 2434 | 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 | 2474 | if (amdgpu_emu_mode == 1) |
| 2475 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 2475 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 2476 | 2476 | |
| 2477 | 2477 | tmp = RREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_CNTL); |
| 2478 | 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 | 2519 | if (amdgpu_emu_mode == 1) |
| 2520 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 2520 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 2521 | 2521 | |
| 2522 | 2522 | tmp = RREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_CNTL); |
| 2523 | 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 | 3153 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); |
| 3154 | 3154 | |
| 3155 | 3155 | if (amdgpu_emu_mode == 1) |
| 3156 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 3156 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 3157 | 3157 | |
| 3158 | 3158 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, |
| 3159 | 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 | 3371 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); |
| 3372 | 3372 | |
| 3373 | 3373 | if (amdgpu_emu_mode == 1) |
| 3374 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 3374 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 3375 | 3375 | |
| 3376 | 3376 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, |
| 3377 | 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 | 4541 | if (r) |
| 4542 | 4542 | return r; |
| 4543 | 4543 | |
| 4544 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 4544 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 4545 | 4545 | |
| 4546 | 4546 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 4547 | 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 | 2324 | amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj); |
| 2325 | 2325 | |
| 2326 | 2326 | if (amdgpu_emu_mode == 1) |
| 2327 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 2327 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 2328 | 2328 | |
| 2329 | 2329 | WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, |
| 2330 | 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 | 2468 | amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj); |
| 2469 | 2469 | |
| 2470 | 2470 | if (amdgpu_emu_mode == 1) |
| 2471 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 2471 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 2472 | 2472 | |
| 2473 | 2473 | WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, |
| 2474 | 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 | 3426 | if (r) |
| 3427 | 3427 | return r; |
| 3428 | 3428 | |
| 3429 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 3429 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 3430 | 3430 | |
| 3431 | 3431 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 3432 | 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 | 268 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; |
| 269 | 269 | |
| 270 | 270 | /* flush hdp cache */ |
| 271 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 271 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 272 | 272 | |
| 273 | 273 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 274 | 274 | * properly under bare metal |
| @@ -969,7 +969,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) · 694 unmodified lines | ||
| 969 | 969 | adev->hdp.funcs->init_registers(adev); |
| 970 | 970 | |
| 971 | 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 | 974 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 975 | 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 | 229 | ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; |
| 230 | 230 | |
| 231 | 231 | /* flush hdp cache */ |
| 232 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 232 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 233 | 233 | |
| 234 | 234 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 235 | 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 | 752 | adev->gmc.vram_type = vram_type; |
| 753 | 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 | 767 | switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { |
| 756 | 768 | case IP_VERSION(11, 0, 0): |
| 757 | 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 | 911 | return r; |
| 900 | 912 | |
| 901 | 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 | 916 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 905 | 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 | 297 | return; |
| 298 | 298 | |
| 299 | 299 | /* flush hdp cache */ |
| 300 | − adev->hdp.funcs->flush_hdp(adev, NULL); | |
| 300 | + amdgpu_device_flush_hdp(adev, NULL); | |
| 301 | 301 | |
| 302 | 302 | /* This is necessary for SRIOV as well as for GFXOFF to function |
| 303 | 303 | * properly under bare metal |
| @@ -881,7 +881,7 @@ static int gmc_v12_0_gart_enable(struct amdgpu_device *adev) · 577 unmodified lines | ||
| 881 | 881 | return r; |
| 882 | 882 | |
| 883 | 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 | 886 | value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? |
| 887 | 887 | false : true; |
| @@ -2435,7 +2435,7 @@ static int gmc_v9_0_hw_init(struct amdgpu_ip_block *ip_block) · 2434 unmodified lines | ||
| 2435 | 2435 | adev->hdp.funcs->init_registers(adev); |
| 2436 | 2436 | |
| 2437 | 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 | 2440 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) |
| 2441 | 2441 | value = false; |
| @@ -41,7 +41,12 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev, · 40 unmodified lines | ||
| 41 | 41 | { |
| 42 | 42 | if (!ring || !ring->funcs->emit_wreg) { |
| 43 | 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 | 50 | } else { |
| 46 | 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 | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | 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 | 41 | } else { |
| 37 | 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 | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | 34 | WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, |
| 35 | 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 | 47 | } else { |
| 38 | 48 | amdgpu_ring_emit_wreg(ring, |
| 39 | 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 | 36 | if (!ring || !ring->funcs->emit_wreg) { |
| 37 | 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 | 44 | } else { |
| 40 | 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 | 33 | if (!ring || !ring->funcs->emit_wreg) { |
| 34 | 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 | 41 | } else { |
| 37 | 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 | 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 | 901 | /* get MES scheduler/KIQ versions */ |
| 898 | 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 | 1392 | mes_v12_0_queue_init_register(ring); |
| 1393 | 1393 | } |
| 1394 | 1394 | |
| 1395 | − /* get MES scheduler/KIQ versions */ | |
| 1396 | − mutex_lock(&adev->srbm_mutex); | |
| 1397 | − soc21_grbm_select(adev, 3, pipe, 0, 0); | |
| 1395 | + if (((pipe == AMDGPU_MES_SCHED_PIPE) && !adev->mes.sched_version) || | |
| 1396 | + ((pipe == AMDGPU_MES_KIQ_PIPE) && !adev->mes.kiq_version)) { | |
| 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) | |
| 1400 | − adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); | |
| 1401 | − else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) | |
| 1402 | − adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); | |
| 1401 | + if (pipe == AMDGPU_MES_SCHED_PIPE) | |
| 1402 | + adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO); | |
| 1403 | + else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq) | |
| 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.