* arch/x86/kvm/mmu/tdp_mmu.c:291:9: sparse: sparse: context imbalance in 'tdp_mmu_link_page' - different lock contexts for basic block
@ 2021-04-22 1:55 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2021-04-22 1:55 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 30142 bytes --]
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Ben Gardon <bgardon@google.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Peter Feiner <pfeiner@google.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 16fc44d6387e260f4932e9248b985837324705d8
commit: 9a77daacc87dee9fd63e31243f21894132ed8407 KVM: x86/mmu: Use atomic ops to set SPTEs in TDP MMU map
date: 3 months ago
:::::: branch date: 9 hours ago
:::::: commit date: 3 months ago
config: x86_64-randconfig-s021-20210422 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-341-g8af24329-dirty
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9a77daacc87dee9fd63e31243f21894132ed8407
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout 9a77daacc87dee9fd63e31243f21894132ed8407
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: expected unsigned long long [usertype] *pt
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:291:9: sparse: sparse: context imbalance in 'tdp_mmu_link_page' - different lock contexts for basic block
>> arch/x86/kvm/mmu/tdp_mmu.c:316:9: sparse: sparse: context imbalance in 'tdp_mmu_unlink_page' - different lock contexts for basic block
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
vim +/tdp_mmu_link_page +291 arch/x86/kvm/mmu/tdp_mmu.c
a6a0b05da9f37f Ben Gardon 2020-10-14 267
a9442f594147f9 Ben Gardon 2021-02-02 268 /**
a9442f594147f9 Ben Gardon 2021-02-02 269 * tdp_mmu_link_page - Add a new page to the list of pages used by the TDP MMU
a9442f594147f9 Ben Gardon 2021-02-02 270 *
a9442f594147f9 Ben Gardon 2021-02-02 271 * @kvm: kvm instance
a9442f594147f9 Ben Gardon 2021-02-02 272 * @sp: the new page
9a77daacc87dee Ben Gardon 2021-02-02 273 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 274 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 275 * threads that might be adding or removing pages.
a9442f594147f9 Ben Gardon 2021-02-02 276 * @account_nx: This page replaces a NX large page and should be marked for
a9442f594147f9 Ben Gardon 2021-02-02 277 * eventual reclaim.
a9442f594147f9 Ben Gardon 2021-02-02 278 */
a9442f594147f9 Ben Gardon 2021-02-02 279 static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp,
9a77daacc87dee Ben Gardon 2021-02-02 280 bool shared, bool account_nx)
a9442f594147f9 Ben Gardon 2021-02-02 281 {
9a77daacc87dee Ben Gardon 2021-02-02 282 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 283 spin_lock(&kvm->arch.tdp_mmu_pages_lock);
9a77daacc87dee Ben Gardon 2021-02-02 284 else
a9442f594147f9 Ben Gardon 2021-02-02 285 lockdep_assert_held_write(&kvm->mmu_lock);
a9442f594147f9 Ben Gardon 2021-02-02 286
a9442f594147f9 Ben Gardon 2021-02-02 287 list_add(&sp->link, &kvm->arch.tdp_mmu_pages);
a9442f594147f9 Ben Gardon 2021-02-02 288 if (account_nx)
a9442f594147f9 Ben Gardon 2021-02-02 289 account_huge_nx_page(kvm, sp);
9a77daacc87dee Ben Gardon 2021-02-02 290
9a77daacc87dee Ben Gardon 2021-02-02 @291 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 292 spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
a9442f594147f9 Ben Gardon 2021-02-02 293 }
a9442f594147f9 Ben Gardon 2021-02-02 294
a9442f594147f9 Ben Gardon 2021-02-02 295 /**
a9442f594147f9 Ben Gardon 2021-02-02 296 * tdp_mmu_unlink_page - Remove page from the list of pages used by the TDP MMU
a9442f594147f9 Ben Gardon 2021-02-02 297 *
a9442f594147f9 Ben Gardon 2021-02-02 298 * @kvm: kvm instance
a9442f594147f9 Ben Gardon 2021-02-02 299 * @sp: the page to be removed
9a77daacc87dee Ben Gardon 2021-02-02 300 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 301 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 302 * threads that might be adding or removing pages.
a9442f594147f9 Ben Gardon 2021-02-02 303 */
9a77daacc87dee Ben Gardon 2021-02-02 304 static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp,
9a77daacc87dee Ben Gardon 2021-02-02 305 bool shared)
a9442f594147f9 Ben Gardon 2021-02-02 306 {
9a77daacc87dee Ben Gardon 2021-02-02 307 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 308 spin_lock(&kvm->arch.tdp_mmu_pages_lock);
9a77daacc87dee Ben Gardon 2021-02-02 309 else
a9442f594147f9 Ben Gardon 2021-02-02 310 lockdep_assert_held_write(&kvm->mmu_lock);
a9442f594147f9 Ben Gardon 2021-02-02 311
a9442f594147f9 Ben Gardon 2021-02-02 312 list_del(&sp->link);
a9442f594147f9 Ben Gardon 2021-02-02 313 if (sp->lpage_disallowed)
a9442f594147f9 Ben Gardon 2021-02-02 314 unaccount_huge_nx_page(kvm, sp);
9a77daacc87dee Ben Gardon 2021-02-02 315
9a77daacc87dee Ben Gardon 2021-02-02 @316 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 317 spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
a9442f594147f9 Ben Gardon 2021-02-02 318 }
a9442f594147f9 Ben Gardon 2021-02-02 319
a066e61f13cf4b Ben Gardon 2021-02-02 320 /**
a066e61f13cf4b Ben Gardon 2021-02-02 321 * handle_removed_tdp_mmu_page - handle a pt removed from the TDP structure
a066e61f13cf4b Ben Gardon 2021-02-02 322 *
a066e61f13cf4b Ben Gardon 2021-02-02 323 * @kvm: kvm instance
a066e61f13cf4b Ben Gardon 2021-02-02 324 * @pt: the page removed from the paging structure
9a77daacc87dee Ben Gardon 2021-02-02 325 * @shared: This operation may not be running under the exclusive use
9a77daacc87dee Ben Gardon 2021-02-02 326 * of the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 327 * threads that might be modifying SPTEs.
a066e61f13cf4b Ben Gardon 2021-02-02 328 *
a066e61f13cf4b Ben Gardon 2021-02-02 329 * Given a page table that has been removed from the TDP paging structure,
a066e61f13cf4b Ben Gardon 2021-02-02 330 * iterates through the page table to clear SPTEs and free child page tables.
a066e61f13cf4b Ben Gardon 2021-02-02 331 */
9a77daacc87dee Ben Gardon 2021-02-02 332 static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt,
9a77daacc87dee Ben Gardon 2021-02-02 333 bool shared)
a066e61f13cf4b Ben Gardon 2021-02-02 334 {
a066e61f13cf4b Ben Gardon 2021-02-02 335 struct kvm_mmu_page *sp = sptep_to_sp(pt);
a066e61f13cf4b Ben Gardon 2021-02-02 336 int level = sp->role.level;
a066e61f13cf4b Ben Gardon 2021-02-02 337 gfn_t gfn = sp->gfn;
a066e61f13cf4b Ben Gardon 2021-02-02 338 u64 old_child_spte;
9a77daacc87dee Ben Gardon 2021-02-02 339 u64 *sptep;
a066e61f13cf4b Ben Gardon 2021-02-02 340 int i;
a066e61f13cf4b Ben Gardon 2021-02-02 341
a066e61f13cf4b Ben Gardon 2021-02-02 342 trace_kvm_mmu_prepare_zap_page(sp);
a066e61f13cf4b Ben Gardon 2021-02-02 343
9a77daacc87dee Ben Gardon 2021-02-02 344 tdp_mmu_unlink_page(kvm, sp, shared);
a066e61f13cf4b Ben Gardon 2021-02-02 345
a066e61f13cf4b Ben Gardon 2021-02-02 346 for (i = 0; i < PT64_ENT_PER_PAGE; i++) {
9a77daacc87dee Ben Gardon 2021-02-02 347 sptep = pt + i;
9a77daacc87dee Ben Gardon 2021-02-02 348
9a77daacc87dee Ben Gardon 2021-02-02 349 if (shared) {
9a77daacc87dee Ben Gardon 2021-02-02 350 old_child_spte = xchg(sptep, 0);
9a77daacc87dee Ben Gardon 2021-02-02 351 } else {
9a77daacc87dee Ben Gardon 2021-02-02 352 old_child_spte = READ_ONCE(*sptep);
9a77daacc87dee Ben Gardon 2021-02-02 353 WRITE_ONCE(*sptep, 0);
9a77daacc87dee Ben Gardon 2021-02-02 354 }
a066e61f13cf4b Ben Gardon 2021-02-02 355 handle_changed_spte(kvm, kvm_mmu_page_as_id(sp),
a066e61f13cf4b Ben Gardon 2021-02-02 356 gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)),
9a77daacc87dee Ben Gardon 2021-02-02 357 old_child_spte, 0, level - 1, shared);
a066e61f13cf4b Ben Gardon 2021-02-02 358 }
a066e61f13cf4b Ben Gardon 2021-02-02 359
a066e61f13cf4b Ben Gardon 2021-02-02 360 kvm_flush_remote_tlbs_with_address(kvm, gfn,
a066e61f13cf4b Ben Gardon 2021-02-02 361 KVM_PAGES_PER_HPAGE(level));
a066e61f13cf4b Ben Gardon 2021-02-02 362
7cca2d0b7e7d9f Ben Gardon 2021-02-02 363 call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback);
a066e61f13cf4b Ben Gardon 2021-02-02 364 }
a066e61f13cf4b Ben Gardon 2021-02-02 365
2f2fad0897cbfd Ben Gardon 2020-10-14 366 /**
2f2fad0897cbfd Ben Gardon 2020-10-14 367 * handle_changed_spte - handle bookkeeping associated with an SPTE change
2f2fad0897cbfd Ben Gardon 2020-10-14 368 * @kvm: kvm instance
2f2fad0897cbfd Ben Gardon 2020-10-14 369 * @as_id: the address space of the paging structure the SPTE was a part of
2f2fad0897cbfd Ben Gardon 2020-10-14 370 * @gfn: the base GFN that was mapped by the SPTE
2f2fad0897cbfd Ben Gardon 2020-10-14 371 * @old_spte: The value of the SPTE before the change
2f2fad0897cbfd Ben Gardon 2020-10-14 372 * @new_spte: The value of the SPTE after the change
2f2fad0897cbfd Ben Gardon 2020-10-14 373 * @level: the level of the PT the SPTE is part of in the paging structure
9a77daacc87dee Ben Gardon 2021-02-02 374 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 375 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 376 * threads that might be modifying SPTEs.
2f2fad0897cbfd Ben Gardon 2020-10-14 377 *
2f2fad0897cbfd Ben Gardon 2020-10-14 378 * Handle bookkeeping that might result from the modification of a SPTE.
2f2fad0897cbfd Ben Gardon 2020-10-14 379 * This function must be called for all TDP SPTE modifications.
2f2fad0897cbfd Ben Gardon 2020-10-14 380 */
2f2fad0897cbfd Ben Gardon 2020-10-14 381 static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
9a77daacc87dee Ben Gardon 2021-02-02 382 u64 old_spte, u64 new_spte, int level,
9a77daacc87dee Ben Gardon 2021-02-02 383 bool shared)
2f2fad0897cbfd Ben Gardon 2020-10-14 384 {
2f2fad0897cbfd Ben Gardon 2020-10-14 385 bool was_present = is_shadow_present_pte(old_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 386 bool is_present = is_shadow_present_pte(new_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 387 bool was_leaf = was_present && is_last_spte(old_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 388 bool is_leaf = is_present && is_last_spte(new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 389 bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 390
2f2fad0897cbfd Ben Gardon 2020-10-14 391 WARN_ON(level > PT64_ROOT_MAX_LEVEL);
2f2fad0897cbfd Ben Gardon 2020-10-14 392 WARN_ON(level < PG_LEVEL_4K);
764388ce598f0c Sean Christopherson 2020-10-23 393 WARN_ON(gfn & (KVM_PAGES_PER_HPAGE(level) - 1));
2f2fad0897cbfd Ben Gardon 2020-10-14 394
2f2fad0897cbfd Ben Gardon 2020-10-14 395 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 396 * If this warning were to trigger it would indicate that there was a
2f2fad0897cbfd Ben Gardon 2020-10-14 397 * missing MMU notifier or a race with some notifier handler.
2f2fad0897cbfd Ben Gardon 2020-10-14 398 * A present, leaf SPTE should never be directly replaced with another
2f2fad0897cbfd Ben Gardon 2020-10-14 399 * present leaf SPTE pointing to a differnt PFN. A notifier handler
2f2fad0897cbfd Ben Gardon 2020-10-14 400 * should be zapping the SPTE before the main MM's page table is
2f2fad0897cbfd Ben Gardon 2020-10-14 401 * changed, or the SPTE should be zeroed, and the TLBs flushed by the
2f2fad0897cbfd Ben Gardon 2020-10-14 402 * thread before replacement.
2f2fad0897cbfd Ben Gardon 2020-10-14 403 */
2f2fad0897cbfd Ben Gardon 2020-10-14 404 if (was_leaf && is_leaf && pfn_changed) {
2f2fad0897cbfd Ben Gardon 2020-10-14 405 pr_err("Invalid SPTE change: cannot replace a present leaf\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 406 "SPTE with another present leaf SPTE mapping a\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 407 "different PFN!\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 408 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
2f2fad0897cbfd Ben Gardon 2020-10-14 409 as_id, gfn, old_spte, new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 410
2f2fad0897cbfd Ben Gardon 2020-10-14 411 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 412 * Crash the host to prevent error propagation and guest data
2f2fad0897cbfd Ben Gardon 2020-10-14 413 * courruption.
2f2fad0897cbfd Ben Gardon 2020-10-14 414 */
2f2fad0897cbfd Ben Gardon 2020-10-14 415 BUG();
2f2fad0897cbfd Ben Gardon 2020-10-14 416 }
2f2fad0897cbfd Ben Gardon 2020-10-14 417
2f2fad0897cbfd Ben Gardon 2020-10-14 418 if (old_spte == new_spte)
2f2fad0897cbfd Ben Gardon 2020-10-14 419 return;
2f2fad0897cbfd Ben Gardon 2020-10-14 420
b9a98c3437e353 Ben Gardon 2020-10-27 421 trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);
b9a98c3437e353 Ben Gardon 2020-10-27 422
2f2fad0897cbfd Ben Gardon 2020-10-14 423 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 424 * The only times a SPTE should be changed from a non-present to
2f2fad0897cbfd Ben Gardon 2020-10-14 425 * non-present state is when an MMIO entry is installed/modified/
2f2fad0897cbfd Ben Gardon 2020-10-14 426 * removed. In that case, there is nothing to do here.
2f2fad0897cbfd Ben Gardon 2020-10-14 427 */
2f2fad0897cbfd Ben Gardon 2020-10-14 428 if (!was_present && !is_present) {
2f2fad0897cbfd Ben Gardon 2020-10-14 429 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 430 * If this change does not involve a MMIO SPTE, it is
2f2fad0897cbfd Ben Gardon 2020-10-14 431 * unexpected. Log the change, though it should not impact the
2f2fad0897cbfd Ben Gardon 2020-10-14 432 * guest since both the former and current SPTEs are nonpresent.
2f2fad0897cbfd Ben Gardon 2020-10-14 433 */
2f2fad0897cbfd Ben Gardon 2020-10-14 434 if (WARN_ON(!is_mmio_spte(old_spte) && !is_mmio_spte(new_spte)))
2f2fad0897cbfd Ben Gardon 2020-10-14 435 pr_err("Unexpected SPTE change! Nonpresent SPTEs\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 436 "should not be replaced with another,\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 437 "different nonpresent SPTE, unless one or both\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 438 "are MMIO SPTEs.\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 439 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
2f2fad0897cbfd Ben Gardon 2020-10-14 440 as_id, gfn, old_spte, new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 441 return;
2f2fad0897cbfd Ben Gardon 2020-10-14 442 }
2f2fad0897cbfd Ben Gardon 2020-10-14 443
2f2fad0897cbfd Ben Gardon 2020-10-14 444
2f2fad0897cbfd Ben Gardon 2020-10-14 445 if (was_leaf && is_dirty_spte(old_spte) &&
2f2fad0897cbfd Ben Gardon 2020-10-14 446 (!is_dirty_spte(new_spte) || pfn_changed))
2f2fad0897cbfd Ben Gardon 2020-10-14 447 kvm_set_pfn_dirty(spte_to_pfn(old_spte));
2f2fad0897cbfd Ben Gardon 2020-10-14 448
2f2fad0897cbfd Ben Gardon 2020-10-14 449 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 450 * Recursively handle child PTs if the change removed a subtree from
2f2fad0897cbfd Ben Gardon 2020-10-14 451 * the paging structure.
2f2fad0897cbfd Ben Gardon 2020-10-14 452 */
a066e61f13cf4b Ben Gardon 2021-02-02 453 if (was_present && !was_leaf && (pfn_changed || !is_present))
a066e61f13cf4b Ben Gardon 2021-02-02 454 handle_removed_tdp_mmu_page(kvm,
9a77daacc87dee Ben Gardon 2021-02-02 455 spte_to_child_pt(old_spte, level), shared);
2f2fad0897cbfd Ben Gardon 2020-10-14 456 }
2f2fad0897cbfd Ben Gardon 2020-10-14 457
2f2fad0897cbfd Ben Gardon 2020-10-14 458 static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
9a77daacc87dee Ben Gardon 2021-02-02 459 u64 old_spte, u64 new_spte, int level,
9a77daacc87dee Ben Gardon 2021-02-02 460 bool shared)
2f2fad0897cbfd Ben Gardon 2020-10-14 461 {
9a77daacc87dee Ben Gardon 2021-02-02 462 __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level,
9a77daacc87dee Ben Gardon 2021-02-02 463 shared);
f8e144971c6834 Ben Gardon 2020-10-14 464 handle_changed_spte_acc_track(old_spte, new_spte, level);
a6a0b05da9f37f Ben Gardon 2020-10-14 465 handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte,
a6a0b05da9f37f Ben Gardon 2020-10-14 466 new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 467 }
faaf05b00aecdb Ben Gardon 2020-10-14 468
9a77daacc87dee Ben Gardon 2021-02-02 469 /*
9a77daacc87dee Ben Gardon 2021-02-02 470 * tdp_mmu_set_spte_atomic - Set a TDP MMU SPTE atomically and handle the
9a77daacc87dee Ben Gardon 2021-02-02 471 * associated bookkeeping
9a77daacc87dee Ben Gardon 2021-02-02 472 *
9a77daacc87dee Ben Gardon 2021-02-02 473 * @kvm: kvm instance
9a77daacc87dee Ben Gardon 2021-02-02 474 * @iter: a tdp_iter instance currently on the SPTE that should be set
9a77daacc87dee Ben Gardon 2021-02-02 475 * @new_spte: The value the SPTE should be set to
9a77daacc87dee Ben Gardon 2021-02-02 476 * Returns: true if the SPTE was set, false if it was not. If false is returned,
9a77daacc87dee Ben Gardon 2021-02-02 477 * this function will have no side-effects.
9a77daacc87dee Ben Gardon 2021-02-02 478 */
9a77daacc87dee Ben Gardon 2021-02-02 479 static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm,
9a77daacc87dee Ben Gardon 2021-02-02 480 struct tdp_iter *iter,
9a77daacc87dee Ben Gardon 2021-02-02 481 u64 new_spte)
9a77daacc87dee Ben Gardon 2021-02-02 482 {
9a77daacc87dee Ben Gardon 2021-02-02 @483 u64 *root_pt = tdp_iter_root_pt(iter);
9a77daacc87dee Ben Gardon 2021-02-02 484 struct kvm_mmu_page *root = sptep_to_sp(root_pt);
9a77daacc87dee Ben Gardon 2021-02-02 485 int as_id = kvm_mmu_page_as_id(root);
9a77daacc87dee Ben Gardon 2021-02-02 486
9a77daacc87dee Ben Gardon 2021-02-02 487 lockdep_assert_held_read(&kvm->mmu_lock);
9a77daacc87dee Ben Gardon 2021-02-02 488
9a77daacc87dee Ben Gardon 2021-02-02 489 if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte,
9a77daacc87dee Ben Gardon 2021-02-02 490 new_spte) != iter->old_spte)
9a77daacc87dee Ben Gardon 2021-02-02 491 return false;
9a77daacc87dee Ben Gardon 2021-02-02 492
9a77daacc87dee Ben Gardon 2021-02-02 493 handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte,
9a77daacc87dee Ben Gardon 2021-02-02 494 iter->level, true);
9a77daacc87dee Ben Gardon 2021-02-02 495
9a77daacc87dee Ben Gardon 2021-02-02 496 return true;
9a77daacc87dee Ben Gardon 2021-02-02 497 }
9a77daacc87dee Ben Gardon 2021-02-02 498
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35651 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
* arch/x86/kvm/mmu/tdp_mmu.c:291:9: sparse: sparse: context imbalance in 'tdp_mmu_link_page' - different lock contexts for basic block
@ 2021-02-27 22:46 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2021-02-27 22:46 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 30138 bytes --]
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Ben Gardon <bgardon@google.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Peter Feiner <pfeiner@google.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 5695e51619745d4fe3ec2506a2f0cd982c5e27a4
commit: 9a77daacc87dee9fd63e31243f21894132ed8407 KVM: x86/mmu: Use atomic ops to set SPTEs in TDP MMU map
date: 3 weeks ago
:::::: branch date: 6 hours ago
:::::: commit date: 3 weeks ago
config: x86_64-randconfig-s022-20210228 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-241-geaceeafa-dirty
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9a77daacc87dee9fd63e31243f21894132ed8407
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout 9a77daacc87dee9fd63e31243f21894132ed8407
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
"sparse warnings: (new ones prefixed by >>)"
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: expected unsigned long long [usertype] *pt
arch/x86/kvm/mmu/tdp_mmu.c:455:49: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:291:9: sparse: sparse: context imbalance in 'tdp_mmu_link_page' - different lock contexts for basic block
>> arch/x86/kvm/mmu/tdp_mmu.c:316:9: sparse: sparse: context imbalance in 'tdp_mmu_unlink_page' - different lock contexts for basic block
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
>> arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:483:40: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected unsigned long long [usertype] *root_pt @@ got unsigned long long [noderef] [usertype] __rcu * @@
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: expected unsigned long long [usertype] *root_pt
arch/x86/kvm/mmu/tdp_mmu.c:606:51: sparse: got unsigned long long [noderef] [usertype] __rcu *
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long long [usertype] *sptep @@ got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt @@
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: expected unsigned long long [usertype] *sptep
arch/x86/kvm/mmu/tdp_mmu.c:521:49: sparse: got unsigned long long [noderef] [usertype] __rcu *[usertype] root_pt
vim +/tdp_mmu_link_page +291 arch/x86/kvm/mmu/tdp_mmu.c
a6a0b05da9f37f Ben Gardon 2020-10-14 267
a9442f594147f9 Ben Gardon 2021-02-02 268 /**
a9442f594147f9 Ben Gardon 2021-02-02 269 * tdp_mmu_link_page - Add a new page to the list of pages used by the TDP MMU
a9442f594147f9 Ben Gardon 2021-02-02 270 *
a9442f594147f9 Ben Gardon 2021-02-02 271 * @kvm: kvm instance
a9442f594147f9 Ben Gardon 2021-02-02 272 * @sp: the new page
9a77daacc87dee Ben Gardon 2021-02-02 273 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 274 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 275 * threads that might be adding or removing pages.
a9442f594147f9 Ben Gardon 2021-02-02 276 * @account_nx: This page replaces a NX large page and should be marked for
a9442f594147f9 Ben Gardon 2021-02-02 277 * eventual reclaim.
a9442f594147f9 Ben Gardon 2021-02-02 278 */
a9442f594147f9 Ben Gardon 2021-02-02 279 static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp,
9a77daacc87dee Ben Gardon 2021-02-02 280 bool shared, bool account_nx)
a9442f594147f9 Ben Gardon 2021-02-02 281 {
9a77daacc87dee Ben Gardon 2021-02-02 282 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 283 spin_lock(&kvm->arch.tdp_mmu_pages_lock);
9a77daacc87dee Ben Gardon 2021-02-02 284 else
a9442f594147f9 Ben Gardon 2021-02-02 285 lockdep_assert_held_write(&kvm->mmu_lock);
a9442f594147f9 Ben Gardon 2021-02-02 286
a9442f594147f9 Ben Gardon 2021-02-02 287 list_add(&sp->link, &kvm->arch.tdp_mmu_pages);
a9442f594147f9 Ben Gardon 2021-02-02 288 if (account_nx)
a9442f594147f9 Ben Gardon 2021-02-02 289 account_huge_nx_page(kvm, sp);
9a77daacc87dee Ben Gardon 2021-02-02 290
9a77daacc87dee Ben Gardon 2021-02-02 @291 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 292 spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
a9442f594147f9 Ben Gardon 2021-02-02 293 }
a9442f594147f9 Ben Gardon 2021-02-02 294
a9442f594147f9 Ben Gardon 2021-02-02 295 /**
a9442f594147f9 Ben Gardon 2021-02-02 296 * tdp_mmu_unlink_page - Remove page from the list of pages used by the TDP MMU
a9442f594147f9 Ben Gardon 2021-02-02 297 *
a9442f594147f9 Ben Gardon 2021-02-02 298 * @kvm: kvm instance
a9442f594147f9 Ben Gardon 2021-02-02 299 * @sp: the page to be removed
9a77daacc87dee Ben Gardon 2021-02-02 300 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 301 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 302 * threads that might be adding or removing pages.
a9442f594147f9 Ben Gardon 2021-02-02 303 */
9a77daacc87dee Ben Gardon 2021-02-02 304 static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp,
9a77daacc87dee Ben Gardon 2021-02-02 305 bool shared)
a9442f594147f9 Ben Gardon 2021-02-02 306 {
9a77daacc87dee Ben Gardon 2021-02-02 307 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 308 spin_lock(&kvm->arch.tdp_mmu_pages_lock);
9a77daacc87dee Ben Gardon 2021-02-02 309 else
a9442f594147f9 Ben Gardon 2021-02-02 310 lockdep_assert_held_write(&kvm->mmu_lock);
a9442f594147f9 Ben Gardon 2021-02-02 311
a9442f594147f9 Ben Gardon 2021-02-02 312 list_del(&sp->link);
a9442f594147f9 Ben Gardon 2021-02-02 313 if (sp->lpage_disallowed)
a9442f594147f9 Ben Gardon 2021-02-02 314 unaccount_huge_nx_page(kvm, sp);
9a77daacc87dee Ben Gardon 2021-02-02 315
9a77daacc87dee Ben Gardon 2021-02-02 @316 if (shared)
9a77daacc87dee Ben Gardon 2021-02-02 317 spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
a9442f594147f9 Ben Gardon 2021-02-02 318 }
a9442f594147f9 Ben Gardon 2021-02-02 319
a066e61f13cf4b Ben Gardon 2021-02-02 320 /**
a066e61f13cf4b Ben Gardon 2021-02-02 321 * handle_removed_tdp_mmu_page - handle a pt removed from the TDP structure
a066e61f13cf4b Ben Gardon 2021-02-02 322 *
a066e61f13cf4b Ben Gardon 2021-02-02 323 * @kvm: kvm instance
a066e61f13cf4b Ben Gardon 2021-02-02 324 * @pt: the page removed from the paging structure
9a77daacc87dee Ben Gardon 2021-02-02 325 * @shared: This operation may not be running under the exclusive use
9a77daacc87dee Ben Gardon 2021-02-02 326 * of the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 327 * threads that might be modifying SPTEs.
a066e61f13cf4b Ben Gardon 2021-02-02 328 *
a066e61f13cf4b Ben Gardon 2021-02-02 329 * Given a page table that has been removed from the TDP paging structure,
a066e61f13cf4b Ben Gardon 2021-02-02 330 * iterates through the page table to clear SPTEs and free child page tables.
a066e61f13cf4b Ben Gardon 2021-02-02 331 */
9a77daacc87dee Ben Gardon 2021-02-02 332 static void handle_removed_tdp_mmu_page(struct kvm *kvm, u64 *pt,
9a77daacc87dee Ben Gardon 2021-02-02 333 bool shared)
a066e61f13cf4b Ben Gardon 2021-02-02 334 {
a066e61f13cf4b Ben Gardon 2021-02-02 335 struct kvm_mmu_page *sp = sptep_to_sp(pt);
a066e61f13cf4b Ben Gardon 2021-02-02 336 int level = sp->role.level;
a066e61f13cf4b Ben Gardon 2021-02-02 337 gfn_t gfn = sp->gfn;
a066e61f13cf4b Ben Gardon 2021-02-02 338 u64 old_child_spte;
9a77daacc87dee Ben Gardon 2021-02-02 339 u64 *sptep;
a066e61f13cf4b Ben Gardon 2021-02-02 340 int i;
a066e61f13cf4b Ben Gardon 2021-02-02 341
a066e61f13cf4b Ben Gardon 2021-02-02 342 trace_kvm_mmu_prepare_zap_page(sp);
a066e61f13cf4b Ben Gardon 2021-02-02 343
9a77daacc87dee Ben Gardon 2021-02-02 344 tdp_mmu_unlink_page(kvm, sp, shared);
a066e61f13cf4b Ben Gardon 2021-02-02 345
a066e61f13cf4b Ben Gardon 2021-02-02 346 for (i = 0; i < PT64_ENT_PER_PAGE; i++) {
9a77daacc87dee Ben Gardon 2021-02-02 347 sptep = pt + i;
9a77daacc87dee Ben Gardon 2021-02-02 348
9a77daacc87dee Ben Gardon 2021-02-02 349 if (shared) {
9a77daacc87dee Ben Gardon 2021-02-02 350 old_child_spte = xchg(sptep, 0);
9a77daacc87dee Ben Gardon 2021-02-02 351 } else {
9a77daacc87dee Ben Gardon 2021-02-02 352 old_child_spte = READ_ONCE(*sptep);
9a77daacc87dee Ben Gardon 2021-02-02 353 WRITE_ONCE(*sptep, 0);
9a77daacc87dee Ben Gardon 2021-02-02 354 }
a066e61f13cf4b Ben Gardon 2021-02-02 355 handle_changed_spte(kvm, kvm_mmu_page_as_id(sp),
a066e61f13cf4b Ben Gardon 2021-02-02 356 gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)),
9a77daacc87dee Ben Gardon 2021-02-02 357 old_child_spte, 0, level - 1, shared);
a066e61f13cf4b Ben Gardon 2021-02-02 358 }
a066e61f13cf4b Ben Gardon 2021-02-02 359
a066e61f13cf4b Ben Gardon 2021-02-02 360 kvm_flush_remote_tlbs_with_address(kvm, gfn,
a066e61f13cf4b Ben Gardon 2021-02-02 361 KVM_PAGES_PER_HPAGE(level));
a066e61f13cf4b Ben Gardon 2021-02-02 362
7cca2d0b7e7d9f Ben Gardon 2021-02-02 363 call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback);
a066e61f13cf4b Ben Gardon 2021-02-02 364 }
a066e61f13cf4b Ben Gardon 2021-02-02 365
2f2fad0897cbfd Ben Gardon 2020-10-14 366 /**
2f2fad0897cbfd Ben Gardon 2020-10-14 367 * handle_changed_spte - handle bookkeeping associated with an SPTE change
2f2fad0897cbfd Ben Gardon 2020-10-14 368 * @kvm: kvm instance
2f2fad0897cbfd Ben Gardon 2020-10-14 369 * @as_id: the address space of the paging structure the SPTE was a part of
2f2fad0897cbfd Ben Gardon 2020-10-14 370 * @gfn: the base GFN that was mapped by the SPTE
2f2fad0897cbfd Ben Gardon 2020-10-14 371 * @old_spte: The value of the SPTE before the change
2f2fad0897cbfd Ben Gardon 2020-10-14 372 * @new_spte: The value of the SPTE after the change
2f2fad0897cbfd Ben Gardon 2020-10-14 373 * @level: the level of the PT the SPTE is part of in the paging structure
9a77daacc87dee Ben Gardon 2021-02-02 374 * @shared: This operation may not be running under the exclusive use of
9a77daacc87dee Ben Gardon 2021-02-02 375 * the MMU lock and the operation must synchronize with other
9a77daacc87dee Ben Gardon 2021-02-02 376 * threads that might be modifying SPTEs.
2f2fad0897cbfd Ben Gardon 2020-10-14 377 *
2f2fad0897cbfd Ben Gardon 2020-10-14 378 * Handle bookkeeping that might result from the modification of a SPTE.
2f2fad0897cbfd Ben Gardon 2020-10-14 379 * This function must be called for all TDP SPTE modifications.
2f2fad0897cbfd Ben Gardon 2020-10-14 380 */
2f2fad0897cbfd Ben Gardon 2020-10-14 381 static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
9a77daacc87dee Ben Gardon 2021-02-02 382 u64 old_spte, u64 new_spte, int level,
9a77daacc87dee Ben Gardon 2021-02-02 383 bool shared)
2f2fad0897cbfd Ben Gardon 2020-10-14 384 {
2f2fad0897cbfd Ben Gardon 2020-10-14 385 bool was_present = is_shadow_present_pte(old_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 386 bool is_present = is_shadow_present_pte(new_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 387 bool was_leaf = was_present && is_last_spte(old_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 388 bool is_leaf = is_present && is_last_spte(new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 389 bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte);
2f2fad0897cbfd Ben Gardon 2020-10-14 390
2f2fad0897cbfd Ben Gardon 2020-10-14 391 WARN_ON(level > PT64_ROOT_MAX_LEVEL);
2f2fad0897cbfd Ben Gardon 2020-10-14 392 WARN_ON(level < PG_LEVEL_4K);
764388ce598f0c Sean Christopherson 2020-10-23 393 WARN_ON(gfn & (KVM_PAGES_PER_HPAGE(level) - 1));
2f2fad0897cbfd Ben Gardon 2020-10-14 394
2f2fad0897cbfd Ben Gardon 2020-10-14 395 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 396 * If this warning were to trigger it would indicate that there was a
2f2fad0897cbfd Ben Gardon 2020-10-14 397 * missing MMU notifier or a race with some notifier handler.
2f2fad0897cbfd Ben Gardon 2020-10-14 398 * A present, leaf SPTE should never be directly replaced with another
2f2fad0897cbfd Ben Gardon 2020-10-14 399 * present leaf SPTE pointing to a differnt PFN. A notifier handler
2f2fad0897cbfd Ben Gardon 2020-10-14 400 * should be zapping the SPTE before the main MM's page table is
2f2fad0897cbfd Ben Gardon 2020-10-14 401 * changed, or the SPTE should be zeroed, and the TLBs flushed by the
2f2fad0897cbfd Ben Gardon 2020-10-14 402 * thread before replacement.
2f2fad0897cbfd Ben Gardon 2020-10-14 403 */
2f2fad0897cbfd Ben Gardon 2020-10-14 404 if (was_leaf && is_leaf && pfn_changed) {
2f2fad0897cbfd Ben Gardon 2020-10-14 405 pr_err("Invalid SPTE change: cannot replace a present leaf\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 406 "SPTE with another present leaf SPTE mapping a\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 407 "different PFN!\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 408 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
2f2fad0897cbfd Ben Gardon 2020-10-14 409 as_id, gfn, old_spte, new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 410
2f2fad0897cbfd Ben Gardon 2020-10-14 411 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 412 * Crash the host to prevent error propagation and guest data
2f2fad0897cbfd Ben Gardon 2020-10-14 413 * courruption.
2f2fad0897cbfd Ben Gardon 2020-10-14 414 */
2f2fad0897cbfd Ben Gardon 2020-10-14 415 BUG();
2f2fad0897cbfd Ben Gardon 2020-10-14 416 }
2f2fad0897cbfd Ben Gardon 2020-10-14 417
2f2fad0897cbfd Ben Gardon 2020-10-14 418 if (old_spte == new_spte)
2f2fad0897cbfd Ben Gardon 2020-10-14 419 return;
2f2fad0897cbfd Ben Gardon 2020-10-14 420
b9a98c3437e353 Ben Gardon 2020-10-27 421 trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);
b9a98c3437e353 Ben Gardon 2020-10-27 422
2f2fad0897cbfd Ben Gardon 2020-10-14 423 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 424 * The only times a SPTE should be changed from a non-present to
2f2fad0897cbfd Ben Gardon 2020-10-14 425 * non-present state is when an MMIO entry is installed/modified/
2f2fad0897cbfd Ben Gardon 2020-10-14 426 * removed. In that case, there is nothing to do here.
2f2fad0897cbfd Ben Gardon 2020-10-14 427 */
2f2fad0897cbfd Ben Gardon 2020-10-14 428 if (!was_present && !is_present) {
2f2fad0897cbfd Ben Gardon 2020-10-14 429 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 430 * If this change does not involve a MMIO SPTE, it is
2f2fad0897cbfd Ben Gardon 2020-10-14 431 * unexpected. Log the change, though it should not impact the
2f2fad0897cbfd Ben Gardon 2020-10-14 432 * guest since both the former and current SPTEs are nonpresent.
2f2fad0897cbfd Ben Gardon 2020-10-14 433 */
2f2fad0897cbfd Ben Gardon 2020-10-14 434 if (WARN_ON(!is_mmio_spte(old_spte) && !is_mmio_spte(new_spte)))
2f2fad0897cbfd Ben Gardon 2020-10-14 435 pr_err("Unexpected SPTE change! Nonpresent SPTEs\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 436 "should not be replaced with another,\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 437 "different nonpresent SPTE, unless one or both\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 438 "are MMIO SPTEs.\n"
2f2fad0897cbfd Ben Gardon 2020-10-14 439 "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d",
2f2fad0897cbfd Ben Gardon 2020-10-14 440 as_id, gfn, old_spte, new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 441 return;
2f2fad0897cbfd Ben Gardon 2020-10-14 442 }
2f2fad0897cbfd Ben Gardon 2020-10-14 443
2f2fad0897cbfd Ben Gardon 2020-10-14 444
2f2fad0897cbfd Ben Gardon 2020-10-14 445 if (was_leaf && is_dirty_spte(old_spte) &&
2f2fad0897cbfd Ben Gardon 2020-10-14 446 (!is_dirty_spte(new_spte) || pfn_changed))
2f2fad0897cbfd Ben Gardon 2020-10-14 447 kvm_set_pfn_dirty(spte_to_pfn(old_spte));
2f2fad0897cbfd Ben Gardon 2020-10-14 448
2f2fad0897cbfd Ben Gardon 2020-10-14 449 /*
2f2fad0897cbfd Ben Gardon 2020-10-14 450 * Recursively handle child PTs if the change removed a subtree from
2f2fad0897cbfd Ben Gardon 2020-10-14 451 * the paging structure.
2f2fad0897cbfd Ben Gardon 2020-10-14 452 */
a066e61f13cf4b Ben Gardon 2021-02-02 453 if (was_present && !was_leaf && (pfn_changed || !is_present))
a066e61f13cf4b Ben Gardon 2021-02-02 454 handle_removed_tdp_mmu_page(kvm,
9a77daacc87dee Ben Gardon 2021-02-02 455 spte_to_child_pt(old_spte, level), shared);
2f2fad0897cbfd Ben Gardon 2020-10-14 456 }
2f2fad0897cbfd Ben Gardon 2020-10-14 457
2f2fad0897cbfd Ben Gardon 2020-10-14 458 static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
9a77daacc87dee Ben Gardon 2021-02-02 459 u64 old_spte, u64 new_spte, int level,
9a77daacc87dee Ben Gardon 2021-02-02 460 bool shared)
2f2fad0897cbfd Ben Gardon 2020-10-14 461 {
9a77daacc87dee Ben Gardon 2021-02-02 462 __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level,
9a77daacc87dee Ben Gardon 2021-02-02 463 shared);
f8e144971c6834 Ben Gardon 2020-10-14 464 handle_changed_spte_acc_track(old_spte, new_spte, level);
a6a0b05da9f37f Ben Gardon 2020-10-14 465 handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte,
a6a0b05da9f37f Ben Gardon 2020-10-14 466 new_spte, level);
2f2fad0897cbfd Ben Gardon 2020-10-14 467 }
faaf05b00aecdb Ben Gardon 2020-10-14 468
9a77daacc87dee Ben Gardon 2021-02-02 469 /*
9a77daacc87dee Ben Gardon 2021-02-02 470 * tdp_mmu_set_spte_atomic - Set a TDP MMU SPTE atomically and handle the
9a77daacc87dee Ben Gardon 2021-02-02 471 * associated bookkeeping
9a77daacc87dee Ben Gardon 2021-02-02 472 *
9a77daacc87dee Ben Gardon 2021-02-02 473 * @kvm: kvm instance
9a77daacc87dee Ben Gardon 2021-02-02 474 * @iter: a tdp_iter instance currently on the SPTE that should be set
9a77daacc87dee Ben Gardon 2021-02-02 475 * @new_spte: The value the SPTE should be set to
9a77daacc87dee Ben Gardon 2021-02-02 476 * Returns: true if the SPTE was set, false if it was not. If false is returned,
9a77daacc87dee Ben Gardon 2021-02-02 477 * this function will have no side-effects.
9a77daacc87dee Ben Gardon 2021-02-02 478 */
9a77daacc87dee Ben Gardon 2021-02-02 479 static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm,
9a77daacc87dee Ben Gardon 2021-02-02 480 struct tdp_iter *iter,
9a77daacc87dee Ben Gardon 2021-02-02 481 u64 new_spte)
9a77daacc87dee Ben Gardon 2021-02-02 482 {
9a77daacc87dee Ben Gardon 2021-02-02 @483 u64 *root_pt = tdp_iter_root_pt(iter);
9a77daacc87dee Ben Gardon 2021-02-02 484 struct kvm_mmu_page *root = sptep_to_sp(root_pt);
9a77daacc87dee Ben Gardon 2021-02-02 485 int as_id = kvm_mmu_page_as_id(root);
9a77daacc87dee Ben Gardon 2021-02-02 486
9a77daacc87dee Ben Gardon 2021-02-02 487 lockdep_assert_held_read(&kvm->mmu_lock);
9a77daacc87dee Ben Gardon 2021-02-02 488
9a77daacc87dee Ben Gardon 2021-02-02 489 if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte,
9a77daacc87dee Ben Gardon 2021-02-02 490 new_spte) != iter->old_spte)
9a77daacc87dee Ben Gardon 2021-02-02 491 return false;
9a77daacc87dee Ben Gardon 2021-02-02 492
9a77daacc87dee Ben Gardon 2021-02-02 493 handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte,
9a77daacc87dee Ben Gardon 2021-02-02 494 iter->level, true);
9a77daacc87dee Ben Gardon 2021-02-02 495
9a77daacc87dee Ben Gardon 2021-02-02 496 return true;
9a77daacc87dee Ben Gardon 2021-02-02 497 }
9a77daacc87dee Ben Gardon 2021-02-02 498
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 36274 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-04-22 1:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-22 1:55 arch/x86/kvm/mmu/tdp_mmu.c:291:9: sparse: sparse: context imbalance in 'tdp_mmu_link_page' - different lock contexts for basic block kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2021-02-27 22:46 kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.