ANDROID: virtio_balloon: Replace generic mem_relinquish api with a driver-specific alternative

The old API was used only by virtio_balloon, and this way we end up
less scattered around the kernel tree.

Bug: 381400679
Bug: 357781595
Change-Id: Ic896d1da83565cc260567b5a1183e94a4d13daab
Signed-off-by: Keir Fraser <keirf@google.com>
This commit is contained in:
Keir Fraser
2025-03-11 16:19:34 +00:00
parent 364e0dad2f
commit 9d6f55bedc
10 changed files with 79 additions and 43 deletions
+1 -1
View File
@@ -1539,7 +1539,7 @@ config RELR
config ARCH_HAS_MEM_ENCRYPT
bool
config ARCH_HAS_MEM_RELINQUISH
config ARCH_HAS_VIRTIO_BALLOON_HYP_OPS
bool
config ARCH_HAS_CC_PLATFORM
+1 -1
View File
@@ -1,7 +1,7 @@
config ARM_PKVM_GUEST
bool "Arm pKVM protected guest driver"
depends on ARM64
select ARCH_HAS_MEM_RELINQUISH
select ARCH_HAS_VIRTIO_BALLOON_HYP_OPS
help
Protected guests running under the pKVM hypervisor on arm64
are isolated from the host and must issue hypercalls to enable
+12 -8
View File
@@ -11,10 +11,10 @@
#include <linux/array_size.h>
#include <linux/io.h>
#include <linux/mem_encrypt.h>
#include <linux/mem_relinquish.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/pgtable.h>
#include <linux/virtio_balloon.h>
#include <asm/hypervisor.h>
@@ -125,17 +125,16 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
return 0;
}
#ifdef CONFIG_MEMORY_RELINQUISH
#ifdef CONFIG_VIRTIO_BALLOON_HYP_OPS
static bool mem_relinquish_available;
bool page_relinquish_disallowed(void)
static bool pkvm_page_relinquish_disallowed(void)
{
return mem_relinquish_available && (pkvm_granule > PAGE_SIZE);
}
EXPORT_SYMBOL_GPL(page_relinquish_disallowed);
void page_relinquish(struct page *page)
static void pkvm_page_relinquish(struct page *page, unsigned int nr)
{
phys_addr_t phys, end;
u32 func_id = ARM_SMCCC_VENDOR_HYP_KVM_MEM_RELINQUISH_FUNC_ID;
@@ -144,7 +143,7 @@ void page_relinquish(struct page *page)
return;
phys = page_to_phys(page);
end = phys + PAGE_SIZE;
end = phys + PAGE_SIZE * nr;
while (phys < end) {
struct arm_smccc_res res;
@@ -155,7 +154,11 @@ void page_relinquish(struct page *page)
phys += pkvm_granule;
}
}
EXPORT_SYMBOL_GPL(page_relinquish);
static struct virtio_balloon_hyp_ops pkvm_virtio_balloon_hyp_ops = {
.page_relinquish_disallowed = pkvm_page_relinquish_disallowed,
.page_relinquish = pkvm_page_relinquish
};
#endif
@@ -208,7 +211,8 @@ void pkvm_init_hyp_services(void)
__dram_is_aligned(pkvm_granule))
arm64_ioremap_prot_hook_register(&mmio_guard_ioremap_hook);
#ifdef CONFIG_MEMORY_RELINQUISH
#ifdef CONFIG_VIRTIO_BALLOON_HYP_OPS
virtio_balloon_hyp_ops = &pkvm_virtio_balloon_hyp_ops;
if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_MEM_RELINQUISH))
mem_relinquish_available = true;
#endif
+5
View File
@@ -120,6 +120,11 @@ config VIRTIO_BALLOON
If unsure, say M.
config VIRTIO_BALLOON_HYP_OPS
def_bool y
depends on VIRTIO_BALLOON
depends on ARCH_HAS_VIRTIO_BALLOON_HYP_OPS
config VIRTIO_MEM
tristate "Virtio mem driver"
depends on X86_64 || ARM64 || RISCV
+1
View File
@@ -9,6 +9,7 @@ virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
virtio_pci-$(CONFIG_VIRTIO_PCI_ADMIN_LEGACY) += virtio_pci_admin_legacy_io.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
obj-$(CONFIG_VIRTIO_BALLOON_HYP_OPS) += virtio_balloon_hyp_ops.o
obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
+7 -2
View File
@@ -197,15 +197,19 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
}
static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
struct scatterlist *sg, unsigned int nents)
struct scatterlist *sgl, unsigned int nents)
{
struct virtio_balloon *vb =
container_of(pr_dev_info, struct virtio_balloon, pr_dev_info);
struct virtqueue *vq = vb->reporting_vq;
unsigned int unused, err;
struct scatterlist *sg;
for (sg = sgl; sg != NULL; sg = sg_next(sg))
page_relinquish(sg_page(sg), sg->length >> PAGE_SHIFT);
/* We should always be able to add these buffers to an empty queue. */
err = virtqueue_add_inbuf(vq, sg, nents, vb, GFP_NOWAIT | __GFP_NOWARN);
err = virtqueue_add_inbuf(vq, sgl, nents, vb, GFP_NOWAIT | __GFP_NOWARN);
/*
* In the extremely unlikely case that something has occurred and we
@@ -263,6 +267,7 @@ static unsigned int fill_balloon(struct virtio_balloon *vb, size_t num)
}
balloon_page_push(&pages, page);
page_relinquish(page, 1);
}
mutex_lock(&vb->balloon_lock);
+7
View File
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/virtio.h>
#include <linux/virtio_balloon.h>
struct virtio_balloon_hyp_ops *virtio_balloon_hyp_ops;
EXPORT_SYMBOL_GPL(virtio_balloon_hyp_ops);
-24
View File
@@ -1,24 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2022 Google LLC
* Author: Keir Fraser <keirf@google.com>
*/
#ifndef __MEM_RELINQUISH_H__
#define __MEM_RELINQUISH_H__
struct page;
#ifdef CONFIG_MEMORY_RELINQUISH
bool page_relinquish_disallowed(void);
void page_relinquish(struct page *page);
#else /* !CONFIG_MEMORY_RELINQUISH */
static inline bool page_relinquish_disallowed(void) { return false; }
static inline void page_relinquish(struct page *page) { }
#endif /* CONFIG_MEMORY_RELINQUISH */
#endif /* __MEM_RELINQUISH_H__ */
+45
View File
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2022 Google LLC
* Author: Keir Fraser <keirf@google.com>
*/
#ifndef _LINUX_VIRTIO_BALLOON_H
#define _LINUX_VIRTIO_BALLOON_H
#include <uapi/linux/virtio_balloon.h>
struct page;
#ifdef CONFIG_VIRTIO_BALLOON_HYP_OPS
struct virtio_balloon_hyp_ops {
bool (*page_relinquish_disallowed)(void);
void (*page_relinquish)(struct page *page, unsigned int nr);
};
extern struct virtio_balloon_hyp_ops *virtio_balloon_hyp_ops;
static inline bool page_relinquish_disallowed(void)
{
if (virtio_balloon_hyp_ops &&
virtio_balloon_hyp_ops->page_relinquish_disallowed)
return virtio_balloon_hyp_ops->page_relinquish_disallowed();
return false;
}
static inline void page_relinquish(struct page *page, unsigned int nr)
{
if (virtio_balloon_hyp_ops &&
virtio_balloon_hyp_ops->page_relinquish_disallowed)
return virtio_balloon_hyp_ops->page_relinquish(page, nr);
}
#else /* !CONFIG_VIRTIO_BALLOON_HYP_OPS */
static inline bool page_relinquish_disallowed(void) { return false; }
static inline void page_relinquish(struct page *page, unsigned int nr) { }
#endif /* CONFIG_VIRTIO_BALLOON_HYP_OPS */
#endif /* _LINUX_VIRTIO_BALLOON_H */
-7
View File
@@ -613,13 +613,6 @@ config SPLIT_PMD_PTLOCKS
config MEMORY_BALLOON
bool
#
# support for memory relinquish
config MEMORY_RELINQUISH
def_bool y
depends on ARCH_HAS_MEM_RELINQUISH
depends on MEMORY_BALLOON || PAGE_REPORTING
#
# support for memory balloon compaction
config BALLOON_COMPACTION