[<prev] [next>] [day] [month] [year] [list]
Message-ID: <202207090603.yuv3ek6F-lkp@intel.com>
Date: Sat, 9 Jul 2022 06:41:56 +0800
From: kernel test robot <lkp@...el.com>
To: Isaku Yamahata <isaku.yamahata@...el.com>
Cc: kbuild-all@...ts.01.org, linux-kernel@...r.kernel.org,
Kai Huang <kai.huang@...el.com>
Subject: [intel-tdx:kvm-upstream-workaround 177/411]
arch/x86/kvm/mmu/tdp_mmu.c:651:17: sparse: sparse: incorrect type in
argument 1 (different address spaces)
tree: https://github.com/intel/tdx.git kvm-upstream-workaround
head: 36253a6ed7e922a2e6888cde465578b98145404e
commit: c602b2f7cd6637d6149fd47022a75349ac414a59 [177/411] KVM: x86/tdp_mmu: Support TDX private mapping for TDP MMU
config: x86_64-rhel-8.3-kselftests (https://download.01.org/0day-ci/archive/20220709/202207090603.yuv3ek6F-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel/tdx/commit/c602b2f7cd6637d6149fd47022a75349ac414a59
git remote add intel-tdx https://github.com/intel/tdx.git
git fetch --no-tags intel-tdx kvm-upstream-workaround
git checkout c602b2f7cd6637d6149fd47022a75349ac414a59
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=x86_64 SHELL=/bin/bash arch/x86/kvm/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@...el.com>
sparse warnings: (new ones prefixed by >>)
>> arch/x86/kvm/mmu/tdp_mmu.c:651:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:651:17: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:651:17: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:1344:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:1344:25: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:1344:25: sparse: got unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
>> arch/x86/kvm/mmu/tdp_mmu.c:1611:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:1611:9: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:1611:9: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:416:9: sparse: sparse: context imbalance in 'tdp_mmu_unlink_sp' - different lock contexts for basic block
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c: note: in included file (through include/linux/rculist.h, include/linux/pid.h, include/linux/sched.h, ...):
include/linux/rcupdate.h:726:9: sparse: sparse: context imbalance in '__tdp_mmu_zap_root' - unexpected unlock
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
include/linux/rcupdate.h:726:9: sparse: sparse: context imbalance in 'tdp_mmu_alloc_sp_for_split' - unexpected unlock
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
>> arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep @@ got unsigned long long [usertype] *sptep @@
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: expected unsigned long long [noderef] [usertype] __rcu *[addressable] [usertype] sptep
arch/x86/kvm/mmu/tdp_mmu.c:754:42: sparse: got unsigned long long [usertype] *sptep
vim +651 arch/x86/kvm/mmu/tdp_mmu.c
533
534 /**
535 * __handle_changed_spte - handle bookkeeping associated with an SPTE change
536 * @kvm: kvm instance
537 * @as_id: the address space of the paging structure the SPTE was a part of
538 * @gfn: the base GFN that was mapped by the SPTE
539 * @private_spte: the SPTE is private or not
540 * @old_spte: The value of the SPTE before the change
541 * @new_spte: The value of the SPTE after the change
542 * @level: the level of the PT the SPTE is part of in the paging structure
543 * @shared: This operation may not be running under the exclusive use of
544 * the MMU lock and the operation must synchronize with other
545 * threads that might be modifying SPTEs.
546 *
547 * Handle bookkeeping that might result from the modification of a SPTE.
548 * This function must be called for all TDP SPTE modifications.
549 */
550 static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
551 bool private_spte, u64 old_spte,
552 u64 new_spte, int level, bool shared)
553 {
554 bool was_present = is_shadow_present_pte(old_spte);
555 bool is_present = is_shadow_present_pte(new_spte);
556 bool was_leaf = was_present && is_last_spte(old_spte, level);
557 bool is_leaf = is_present && is_last_spte(new_spte, level);
558 kvm_pfn_t old_pfn = spte_to_pfn(old_spte);
559 kvm_pfn_t new_pfn = spte_to_pfn(new_spte);
560 bool pfn_changed = old_pfn != new_pfn;
561 struct kvm_spte_change change = {
562 .gfn = gfn,
563 .level = level,
564 .old = {
565 .pfn = old_pfn,
566 .is_present = was_present,
567 .is_leaf = was_leaf,
568 },
569 .new = {
570 .pfn = new_pfn,
571 .is_present = is_present,
572 .is_leaf = is_leaf,
573 },
574 };
575
576 WARN_ON(level > PT64_ROOT_MAX_LEVEL);
577 WARN_ON(level < PG_LEVEL_4K);
578 WARN_ON(gfn & (KVM_PAGES_PER_HPAGE(level) - 1));
579
580 /*
581 * If this warning were to trigger it would indicate that there was a
582 * missing MMU notifier or a race with some notifier handler.
583 * A present, leaf SPTE should never be directly replaced with another
584 * present leaf SPTE pointing to a different PFN. A notifier handler
585 * should be zapping the SPTE before the main MM's page table is
586 * changed, or the SPTE should be zeroed, and the TLBs flushed by the
587 * thread before replacement.
588 */
589 if (was_leaf && is_leaf && pfn_changed) {
590 pr_err("Invalid SPTE change: cannot replace a present leaf\n"
591 "SPTE with another present leaf SPTE mapping a\n"
592 "different PFN!\n"
593 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
594 as_id, gfn, old_spte, new_spte, level);
595
596 /*
597 * Crash the host to prevent error propagation and guest data
598 * corruption.
599 */
600 BUG();
601 }
602
603 if (old_spte == new_spte)
604 return;
605
606 trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);
607
608 if (is_leaf)
609 check_spte_writable_invariants(new_spte);
610
611 /*
612 * The only times a SPTE should be changed from a non-present to
613 * non-present state is when an MMIO entry is installed/modified/
614 * removed. In that case, there is nothing to do here.
615 */
616 if (!was_present && !is_present) {
617 /*
618 * If this change does not involve a MMIO SPTE or removed SPTE,
619 * it is unexpected. Log the change, though it should not
620 * impact the guest since both the former and current SPTEs
621 * are nonpresent.
622 */
623 if (WARN_ON(!is_mmio_spte(kvm, old_spte) &&
624 !is_mmio_spte(kvm, new_spte) &&
625 !is_removed_spte(new_spte)))
626 pr_err("Unexpected SPTE change! Nonpresent SPTEs\n"
627 "should not be replaced with another,\n"
628 "different nonpresent SPTE, unless one or both\n"
629 "are MMIO SPTEs, or the new SPTE is\n"
630 "a temporary removed SPTE.\n"
631 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
632 as_id, gfn, old_spte, new_spte, level);
633 return;
634 }
635
636 if (is_leaf != was_leaf)
637 kvm_update_page_stats(kvm, level, is_leaf ? 1 : -1);
638
639 if (was_leaf && is_dirty_spte(old_spte) &&
640 (!is_present || !is_dirty_spte(new_spte) || pfn_changed))
641 kvm_set_pfn_dirty(old_pfn);
642
643 /*
644 * Recursively handle child PTs if the change removed a subtree from
645 * the paging structure. Note the WARN on the PFN changing without the
646 * SPTE being converted to a hugepage (leaf) or being zapped. Shadow
647 * pages are kernel allocations and should never be migrated.
648 */
649 if (was_present && !was_leaf &&
650 (is_leaf || !is_present || WARN_ON_ONCE(pfn_changed))) {
> 651 WARN_ON(private_spte !=
652 is_private_sptep(spte_to_child_pt(old_spte, level)));
653 handle_removed_pt(kvm, spte_to_child_pt(old_spte, level),
654 private_spte, shared);
655 }
656
657 /*
658 * Special handling for the private mapping. We are either
659 * setting up new mapping at middle level page table, or leaf,
660 * or tearing down existing mapping.
661 *
662 * This is after handling lower page table by above
663 * handle_remove_tdp_mmu_page(). S-EPT requires to remove S-EPT tables
664 * after removing childrens.
665 */
666 if (private_spte &&
667 /* Ignore change of software only bits. e.g. host_writable */
668 (was_leaf != is_leaf || was_present != is_present || pfn_changed)) {
669 void *sept_page = NULL;
670
671 if (is_present && !is_leaf) {
672 struct kvm_mmu_page *sp = to_shadow_page(pfn_to_hpa(new_pfn));
673
674 sept_page = kvm_mmu_private_sp(sp);
675 WARN_ON(!sept_page);
676 WARN_ON(sp->role.level + 1 != level);
677 WARN_ON(sp->gfn != gfn);
678 }
679 change.sept_page = sept_page;
680
681 static_call(kvm_x86_handle_changed_private_spte)(kvm, &change);
682 }
683 }
684
685 static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
686 bool private_spte, u64 old_spte, u64 new_spte,
687 int level, bool shared)
688 {
689 __handle_changed_spte(kvm, as_id, gfn, private_spte,
690 old_spte, new_spte, level, shared);
691 handle_changed_spte_acc_track(old_spte, new_spte, level);
692 handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte,
693 new_spte, level);
694 }
695
696 /*
697 * tdp_mmu_set_spte_atomic - Set a TDP MMU SPTE atomically
698 * and handle the associated bookkeeping. Do not mark the page dirty
699 * in KVM's dirty bitmaps.
700 *
701 * If setting the SPTE fails because it has changed, iter->old_spte will be
702 * refreshed to the current value of the spte.
703 *
704 * @kvm: kvm instance
705 * @iter: a tdp_iter instance currently on the SPTE that should be set
706 * @new_spte: The value the SPTE should be set to
707 * Return:
708 * * 0 - If the SPTE was set.
709 * * -EBUSY - If the SPTE cannot be set. In this case this function will have
710 * no side-effects other than setting iter->old_spte to the last
711 * known value of the spte.
712 */
713 static inline int tdp_mmu_set_spte_atomic(struct kvm *kvm,
714 struct tdp_iter *iter,
715 u64 new_spte)
716 {
717 bool freeze_spte = iter->is_private && !is_removed_spte(new_spte);
718 u64 tmp_spte = freeze_spte ? REMOVED_SPTE : new_spte;
719 u64 *sptep = rcu_dereference(iter->sptep);
720 u64 old_spte;
721
722 /*
723 * The caller is responsible for ensuring the old SPTE is not a REMOVED
724 * SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE,
725 * and pre-checking before inserting a new SPTE is advantageous as it
726 * avoids unnecessary work.
727 */
728 WARN_ON_ONCE(iter->yielded || is_removed_spte(iter->old_spte));
729
730 lockdep_assert_held_read(&kvm->mmu_lock);
731
732 /*
733 * Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs and
734 * does not hold the mmu_lock.
735 */
736 old_spte = cmpxchg64(sptep, iter->old_spte, tmp_spte);
737 if (old_spte != iter->old_spte) {
738 /*
739 * The page table entry was modified by a different logical
740 * CPU. Refresh iter->old_spte with the current value so the
741 * caller operates on fresh data, e.g. if it retries
742 * tdp_mmu_set_spte_atomic().
743 */
744 iter->old_spte = old_spte;
745 return -EBUSY;
746 }
747
748 __handle_changed_spte(
749 kvm, iter->as_id, iter->gfn, iter->is_private,
750 iter->old_spte, new_spte, iter->level, true);
751 handle_changed_spte_acc_track(iter->old_spte, new_spte, iter->level);
752
753 if (freeze_spte)
> 754 __kvm_tdp_mmu_write_spte(sptep, new_spte);
755
756 return 0;
757 }
758
--
0-DAY CI Kernel Test Service
https://01.org/lkp
Powered by blists - more mailing lists