From nobody Wed Dec 17 10:47:41 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7017F2951B1 for ; Fri, 9 May 2025 13:17:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746796638; cv=none; b=Eu50xEuqETchDB/1EHnS3Nag6P8/ijxNkU+/R1KRJUVQMISQqUHXBd9PhppPmm4ELtvgKWsmCvL3Q7PxIKAY/H20StYAdYvuz1V5VJN1GxqWmFp0DcPRnMyAIhR/Mf+JoKaE7aSZ77YdsCe5qC3zpCeGKGTT85/YeXOOXb+x4fg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746796638; c=relaxed/simple; bh=4qe2GlMyMtPmem+nY3Rk87tsumdIvPPjYYhaHo+Z3CI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=bLSCWBZlCxlNPBSv38D/HuLvKb/XJsJMTCwoAS0oyKsYy+305ZIGTXecMJQenTGfZMxwRmb/hhn8KXk4ykQRtLveMl56V9P8EP5grn2nzB3y4Rykobwip9Tj0BQK9sNW9H5Jz9Kb5634lkGYo2CbOE59+T9Y/xINns2rUyopSrg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=gsuMIYvb; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gsuMIYvb" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cf5196c25so10336025e9.0 for ; Fri, 09 May 2025 06:17:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746796635; x=1747401435; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=MuUUPGUNlLgL3YW2d98D/HjXl/LhdxFI7FznSu/zXVs=; b=gsuMIYvbdNH2VQnf0BUtY7/YgmMiYd5VbzvQ4qTL1RZh5RMiOTzMjdNraR0SPXdAiz HZ2Fz6PbfZbGBcNK2+Ni8XI/yHxn60u2RGnrGTnalJEjs44SVI/exT2vGeVk3JTCQ/c2 mBCUOTZ73lxJRWIB/VRZqwNZ8JEdmDHOqVC69GKF0krC10PbHpnaKGGdmJTzq/EYBTJH R191nsoKOY9i+opVblpx8vwl/MzC2VUWMhGjKivPzS/6eGErUjOzVBDdiyfwYmr4Z++F ryhD9OkNqxpWn5xUC92K5iKh+ST97RJMnxw1EC0mnPavhL8QUcSyXwZ/9W6EQTMDV4KO L1Ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746796635; x=1747401435; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=MuUUPGUNlLgL3YW2d98D/HjXl/LhdxFI7FznSu/zXVs=; b=U3mA4R2Sza9zRSW/IpaRQLZXaPTVcYf5U/4420+kSSGWgqlprTaZXj3UpqkfKrBpJE lpJC4MtMsWUci2eY4ZUvtwAYPHAQ1YAPMho4e3XGxIP3UmbWqUw+qpEN19nbQ4bm4Utq EXX+Sm1wGc0xL30mZwZ9Y5xQ41vsam7T/pppWWpXLSiRPM0x0XSeoaYJLBWc5erWK7Ch 5GIN2J5up9jqB+RMjYfHfDqXWMd3flonJludeXuSiQ2qDaPuYpSGcJhOdkjdUVxHln7z ZKp0UL8BOnJVjnXzONz/mQhqA+drmFdo3IM036ihIAQFPkCnAS8yg0h3gTTFSoI5bJNF M+Aw== X-Forwarded-Encrypted: i=1; AJvYcCUZWplwdqgq5drOlzjMdRBsxpZcwUH1VLVLUT0QmIo1010WbXsBBqekmk0qBShVdZatpAMuDYO6uFpaods=@vger.kernel.org X-Gm-Message-State: AOJu0YwyFkMbwKqYwvjsHQenWDuJx2aMuvxNKTYelXBIDQ5WNAM753aL ngvXMXTboBPi+wUBat17+gwHIECkMXj2+Z/logQlynL0620o8datAAVd60D3oQk7HAc7GYlgU3A NNLeWKNb4LQ6IjYotlg== X-Google-Smtp-Source: AGHT+IHr/LYMD6ZOv2XrHZsPTX950y7HhnTgMHB9cYGym0qmTnKEqfwNLxc6Z2FepzPjnmTq0Q2LQl1tmzVkxjk1 X-Received: from wmbfl14.prod.google.com ([2002:a05:600c:b8e:b0:440:58dd:3795]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:6488:b0:43c:fffc:786c with SMTP id 5b1f17b1804b1-442d6d6ace2mr32830755e9.19.1746796634979; Fri, 09 May 2025 06:17:14 -0700 (PDT) Date: Fri, 9 May 2025 14:16:58 +0100 In-Reply-To: <20250509131706.2336138-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250509131706.2336138-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.1015.ga840276032-goog Message-ID: <20250509131706.2336138-3-vdonnefort@google.com> Subject: [PATCH v4 02/10] KVM: arm64: Introduce for_each_hyp_page From: Vincent Donnefort To: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: qperret@google.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kernel-team@android.com, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a helper to iterate over the hypervisor vmemmap. This will be particularly handy with the introduction of huge mapping support for the np-guest stage-2. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/= include/nvhe/memory.h index eb0c2ebd1743..676a0a13c741 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h @@ -96,24 +96,24 @@ static inline struct hyp_page *hyp_phys_to_page(phys_ad= dr_t phys) #define hyp_page_to_virt(page) __hyp_va(hyp_page_to_phys(page)) #define hyp_page_to_pool(page) (((struct hyp_page *)page)->pool) =20 -static inline enum pkvm_page_state get_host_state(phys_addr_t phys) +static inline enum pkvm_page_state get_host_state(struct hyp_page *p) { - return (enum pkvm_page_state)hyp_phys_to_page(phys)->__host_state; + return (enum pkvm_page_state)p->__host_state; } =20 -static inline void set_host_state(phys_addr_t phys, enum pkvm_page_state s= tate) +static inline void set_host_state(struct hyp_page *p, enum pkvm_page_state= state) { - hyp_phys_to_page(phys)->__host_state =3D state; + p->__host_state =3D state; } =20 -static inline enum pkvm_page_state get_hyp_state(phys_addr_t phys) +static inline enum pkvm_page_state get_hyp_state(struct hyp_page *p) { - return hyp_phys_to_page(phys)->__hyp_state_comp ^ PKVM_PAGE_STATE_MASK; + return p->__hyp_state_comp ^ PKVM_PAGE_STATE_MASK; } =20 -static inline void set_hyp_state(phys_addr_t phys, enum pkvm_page_state st= ate) +static inline void set_hyp_state(struct hyp_page *p, enum pkvm_page_state = state) { - hyp_phys_to_page(phys)->__hyp_state_comp =3D state ^ PKVM_PAGE_STATE_MASK; + p->__hyp_state_comp =3D state ^ PKVM_PAGE_STATE_MASK; } =20 /* diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvh= e/mem_protect.c index 23544928a637..4d269210dae0 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -60,6 +60,9 @@ static void hyp_unlock_component(void) hyp_spin_unlock(&pkvm_pgd_lock); } =20 +#define for_each_hyp_page(start, size, page) \ + for (page =3D hyp_phys_to_page(start); page < hyp_phys_to_page((start) + = (size)); page++) + static void *host_s2_zalloc_pages_exact(size_t size) { void *addr =3D hyp_alloc_pages(&host_s2_pool, get_order(size)); @@ -481,7 +484,8 @@ static int host_stage2_adjust_range(u64 addr, struct kv= m_mem_range *range) return -EAGAIN; =20 if (pte) { - WARN_ON(addr_is_memory(addr) && get_host_state(addr) !=3D PKVM_NOPAGE); + WARN_ON(addr_is_memory(addr) && + get_host_state(hyp_phys_to_page(addr)) !=3D PKVM_NOPAGE); return -EPERM; } =20 @@ -507,10 +511,10 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 si= ze, =20 static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm= _page_state state) { - phys_addr_t end =3D addr + size; + struct hyp_page *page; =20 - for (; addr < end; addr +=3D PAGE_SIZE) - set_host_state(addr, state); + for_each_hyp_page(addr, size, page) + set_host_state(page, state); } =20 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) @@ -632,16 +636,17 @@ static int check_page_state_range(struct kvm_pgtable = *pgt, u64 addr, u64 size, static int __host_check_page_state_range(u64 addr, u64 size, enum pkvm_page_state state) { - u64 end =3D addr + size; + struct hyp_page *page; int ret; =20 - ret =3D check_range_allowed_memory(addr, end); + ret =3D check_range_allowed_memory(addr, addr + size); if (ret) return ret; =20 hyp_assert_lock_held(&host_mmu.lock); - for (; addr < end; addr +=3D PAGE_SIZE) { - if (get_host_state(addr) !=3D state) + + for_each_hyp_page(addr, size, page) { + if (get_host_state(page) !=3D state) return -EPERM; } =20 @@ -651,7 +656,7 @@ static int __host_check_page_state_range(u64 addr, u64 = size, static int __host_set_page_state_range(u64 addr, u64 size, enum pkvm_page_state state) { - if (get_host_state(addr) =3D=3D PKVM_NOPAGE) { + if (get_host_state(hyp_phys_to_page(addr)) =3D=3D PKVM_NOPAGE) { int ret =3D host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT); =20 if (ret) @@ -665,18 +670,18 @@ static int __host_set_page_state_range(u64 addr, u64 = size, =20 static void __hyp_set_page_state_range(phys_addr_t phys, u64 size, enum pk= vm_page_state state) { - phys_addr_t end =3D phys + size; + struct hyp_page *page; =20 - for (; phys < end; phys +=3D PAGE_SIZE) - set_hyp_state(phys, state); + for_each_hyp_page(phys, size, page) + set_hyp_state(page, state); } =20 static int __hyp_check_page_state_range(phys_addr_t phys, u64 size, enum p= kvm_page_state state) { - phys_addr_t end =3D phys + size; + struct hyp_page *page; =20 - for (; phys < end; phys +=3D PAGE_SIZE) { - if (get_hyp_state(phys) !=3D state) + for_each_hyp_page(phys, size, page) { + if (get_hyp_state(page) !=3D state) return -EPERM; } =20 @@ -927,7 +932,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pk= vm_hyp_vcpu *vcpu, goto unlock; =20 page =3D hyp_phys_to_page(phys); - switch (get_host_state(phys)) { + switch (get_host_state(page)) { case PKVM_PAGE_OWNED: WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OW= NED)); break; @@ -979,9 +984,9 @@ static int __check_host_shared_guest(struct pkvm_hyp_vm= *vm, u64 *__phys, u64 ip if (WARN_ON(ret)) return ret; =20 - if (get_host_state(phys) !=3D PKVM_PAGE_SHARED_OWNED) - return -EPERM; page =3D hyp_phys_to_page(phys); + if (get_host_state(page) !=3D PKVM_PAGE_SHARED_OWNED) + return -EPERM; if (WARN_ON(!page->host_share_guest_count)) return -EINVAL; =20 diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setu= p.c index 6d513a4b3763..c19860fc8183 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -190,6 +190,7 @@ static int fix_host_ownership_walker(const struct kvm_p= gtable_visit_ctx *ctx, enum kvm_pgtable_walk_flags visit) { enum pkvm_page_state state; + struct hyp_page *page; phys_addr_t phys; =20 if (!kvm_pte_valid(ctx->old)) @@ -202,6 +203,8 @@ static int fix_host_ownership_walker(const struct kvm_p= gtable_visit_ctx *ctx, if (!addr_is_memory(phys)) return -EINVAL; =20 + page =3D hyp_phys_to_page(phys); + /* * Adjust the host stage-2 mappings to match the ownership attributes * configured in the hypervisor stage-1, and make sure to propagate them @@ -210,15 +213,15 @@ static int fix_host_ownership_walker(const struct kvm= _pgtable_visit_ctx *ctx, state =3D pkvm_getstate(kvm_pgtable_hyp_pte_prot(ctx->old)); switch (state) { case PKVM_PAGE_OWNED: - set_hyp_state(phys, PKVM_PAGE_OWNED); + set_hyp_state(page, PKVM_PAGE_OWNED); return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP); case PKVM_PAGE_SHARED_OWNED: - set_hyp_state(phys, PKVM_PAGE_SHARED_OWNED); - set_host_state(phys, PKVM_PAGE_SHARED_BORROWED); + set_hyp_state(page, PKVM_PAGE_SHARED_OWNED); + set_host_state(page, PKVM_PAGE_SHARED_BORROWED); break; case PKVM_PAGE_SHARED_BORROWED: - set_hyp_state(phys, PKVM_PAGE_SHARED_BORROWED); - set_host_state(phys, PKVM_PAGE_SHARED_OWNED); + set_hyp_state(page, PKVM_PAGE_SHARED_BORROWED); + set_host_state(page, PKVM_PAGE_SHARED_OWNED); break; default: return -EINVAL; --=20 2.49.0.1015.ga840276032-goog