* [PATCH v3 1/4] xen/arm: vcpu_vgic_free() updates
2025-12-22 16:40 [PATCH v3 0/4] Move alloc/free_vcpu_struct() to common code Oleksii Kurochko
@ 2025-12-22 16:40 ` Oleksii Kurochko
2025-12-23 12:36 ` Andrew Cooper
2025-12-22 16:40 ` [PATCH v3 2/4] xen/arm: optimize the size of struct vcpu Oleksii Kurochko
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Oleksii Kurochko @ 2025-12-22 16:40 UTC (permalink / raw)
To: xen-devel
Cc: Oleksii Kurochko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper
Use XFREE() instead of xfree() so that vcpu_vgic_free() can be idempotent.
With XFREE(), vgic_vcpu->private_irqs is set to NULL, so calling
vcpu_vgic_free() a second time is not an issue.
Update the prototype of vcpu_vgic_free() to return void to satisfy MISRA
Rule 17.7, since the return value of vcpu_vgic_free() is not used by any
callers.
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Change in v3:
- New patch.
---
xen/arch/arm/include/asm/vgic.h | 2 +-
xen/arch/arm/vgic.c | 5 ++---
xen/arch/arm/vgic/vgic-init.c | 4 +---
3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/include/asm/vgic.h b/xen/arch/arm/include/asm/vgic.h
index 31b3d3e5ec5d..6f9ab1c98c1c 100644
--- a/xen/arch/arm/include/asm/vgic.h
+++ b/xen/arch/arm/include/asm/vgic.h
@@ -418,7 +418,7 @@ int domain_vgic_register(struct domain *d, unsigned int *mmio_count);
int domain_vgic_init(struct domain *d, unsigned int nr_spis);
void domain_vgic_free(struct domain *d);
int vcpu_vgic_init(struct vcpu *v);
-int vcpu_vgic_free(struct vcpu *v);
+void vcpu_vgic_free(struct vcpu *v);
void vgic_inject_irq(struct domain *d, struct vcpu *v, unsigned int virq,
bool level);
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 3ebdf9953f07..6647071ad4d7 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -390,10 +390,9 @@ int vcpu_vgic_init(struct vcpu *v)
return 0;
}
-int vcpu_vgic_free(struct vcpu *v)
+void vcpu_vgic_free(struct vcpu *v)
{
- xfree(v->arch.vgic.private_irqs);
- return 0;
+ XFREE(v->arch.vgic.private_irqs);
}
struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int virq)
diff --git a/xen/arch/arm/vgic/vgic-init.c b/xen/arch/arm/vgic/vgic-init.c
index f8d7d3a226d0..aef526f2e717 100644
--- a/xen/arch/arm/vgic/vgic-init.c
+++ b/xen/arch/arm/vgic/vgic-init.c
@@ -239,13 +239,11 @@ void domain_vgic_free(struct domain *d)
dist->nr_spis = 0;
}
-int vcpu_vgic_free(struct vcpu *v)
+void vcpu_vgic_free(struct vcpu *v)
{
struct vgic_cpu *vgic_cpu = &v->arch.vgic;
INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
-
- return 0;
}
/*
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v3 1/4] xen/arm: vcpu_vgic_free() updates
2025-12-22 16:40 ` [PATCH v3 1/4] xen/arm: vcpu_vgic_free() updates Oleksii Kurochko
@ 2025-12-23 12:36 ` Andrew Cooper
0 siblings, 0 replies; 10+ messages in thread
From: Andrew Cooper @ 2025-12-23 12:36 UTC (permalink / raw)
To: Oleksii Kurochko, xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Michal Orzel, Volodymyr Babchuk
On 22/12/2025 4:40 pm, Oleksii Kurochko wrote:
> Use XFREE() instead of xfree() so that vcpu_vgic_free() can be idempotent.
> With XFREE(), vgic_vcpu->private_irqs is set to NULL, so calling
> vcpu_vgic_free() a second time is not an issue.
>
> Update the prototype of vcpu_vgic_free() to return void to satisfy MISRA
> Rule 17.7, since the return value of vcpu_vgic_free() is not used by any
> callers.
>
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/4] xen/arm: optimize the size of struct vcpu
2025-12-22 16:40 [PATCH v3 0/4] Move alloc/free_vcpu_struct() to common code Oleksii Kurochko
2025-12-22 16:40 ` [PATCH v3 1/4] xen/arm: vcpu_vgic_free() updates Oleksii Kurochko
@ 2025-12-22 16:40 ` Oleksii Kurochko
2025-12-23 12:37 ` Andrew Cooper
2025-12-22 16:40 ` [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code Oleksii Kurochko
2025-12-22 16:40 ` [PATCH v3 4/4] xen/common: make {alloc,free}_domain_struct() static Oleksii Kurochko
3 siblings, 1 reply; 10+ messages in thread
From: Oleksii Kurochko @ 2025-12-22 16:40 UTC (permalink / raw)
To: xen-devel
Cc: Oleksii Kurochko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper
When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
exceeds one page, which requires allocating two pages and led to the
introduction of MAX_PAGES_PER_VCPU.
To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
pointer to struct vgic_irq.
As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
CONFIG_NEW_VGIC=y).
Since the private_irqs member is now a pointer, vcpu_vgic_init() and
vcpu_vgic_free() are updated to allocate and free private_irqs instance.
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in v3:
- Make private_irqs member as pointer to vgic_irq in struct vgic_cpu
of new_vgic instead of vgic member of arch_vcpu.
---
Changes in v2:
- New patch.
---
xen/arch/arm/include/asm/new_vgic.h | 2 +-
xen/arch/arm/vgic/vgic-init.c | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/include/asm/new_vgic.h b/xen/arch/arm/include/asm/new_vgic.h
index 1e762138939f..6f7af0e02b2b 100644
--- a/xen/arch/arm/include/asm/new_vgic.h
+++ b/xen/arch/arm/include/asm/new_vgic.h
@@ -155,7 +155,7 @@ struct vgic_dist {
};
struct vgic_cpu {
- struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
+ struct vgic_irq *private_irqs;
struct list_head ap_list_head;
spinlock_t ap_list_lock; /* Protects the ap_list */
diff --git a/xen/arch/arm/vgic/vgic-init.c b/xen/arch/arm/vgic/vgic-init.c
index aef526f2e717..4eb49d922492 100644
--- a/xen/arch/arm/vgic/vgic-init.c
+++ b/xen/arch/arm/vgic/vgic-init.c
@@ -202,6 +202,11 @@ int vcpu_vgic_init(struct vcpu *v)
{
int ret = 0;
+ v->arch.vgic.private_irqs =
+ xzalloc_array(struct vgic_irq, VGIC_NR_PRIVATE_IRQS);
+ if ( !v->arch.vgic.private_irqs )
+ return -ENOMEM;
+
vgic_vcpu_early_init(v);
if ( gic_hw_version() == GIC_V2 )
@@ -244,6 +249,8 @@ void vcpu_vgic_free(struct vcpu *v)
struct vgic_cpu *vgic_cpu = &v->arch.vgic;
INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
+
+ XFREE(v->arch.vgic.private_irqs);
}
/*
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v3 2/4] xen/arm: optimize the size of struct vcpu
2025-12-22 16:40 ` [PATCH v3 2/4] xen/arm: optimize the size of struct vcpu Oleksii Kurochko
@ 2025-12-23 12:37 ` Andrew Cooper
0 siblings, 0 replies; 10+ messages in thread
From: Andrew Cooper @ 2025-12-23 12:37 UTC (permalink / raw)
To: Oleksii Kurochko, xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Michal Orzel, Volodymyr Babchuk
On 22/12/2025 4:40 pm, Oleksii Kurochko wrote:
> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
> exceeds one page, which requires allocating two pages and led to the
> introduction of MAX_PAGES_PER_VCPU.
>
> To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
> member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
> pointer to struct vgic_irq.
> As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
> compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
> and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
> CONFIG_NEW_VGIC=y).
>
> Since the private_irqs member is now a pointer, vcpu_vgic_init() and
> vcpu_vgic_free() are updated to allocate and free private_irqs instance.
>
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Oh - even smaller than I was expecting.
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code
2025-12-22 16:40 [PATCH v3 0/4] Move alloc/free_vcpu_struct() to common code Oleksii Kurochko
2025-12-22 16:40 ` [PATCH v3 1/4] xen/arm: vcpu_vgic_free() updates Oleksii Kurochko
2025-12-22 16:40 ` [PATCH v3 2/4] xen/arm: optimize the size of struct vcpu Oleksii Kurochko
@ 2025-12-22 16:40 ` Oleksii Kurochko
2025-12-23 11:33 ` Jan Beulich
2025-12-23 12:41 ` Andrew Cooper
2025-12-22 16:40 ` [PATCH v3 4/4] xen/common: make {alloc,free}_domain_struct() static Oleksii Kurochko
3 siblings, 2 replies; 10+ messages in thread
From: Oleksii Kurochko @ 2025-12-22 16:40 UTC (permalink / raw)
To: xen-devel
Cc: Oleksii Kurochko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
Anthony PERARD, Jan Beulich, Roger Pau Monné,
Timothy Pearson, Alistair Francis, Bob Eshleman, Connor Davis
alloc_vcpu_struct() and free_vcpu_struct() contain little
architecture-specific logic and are suitable for sharing across
architectures. Move both helpers to common code.
To support the remaining architectural differences, introduce
arch_vcpu_struct_memflags(), allowing architectures to override the
memory flags passed to alloc_xenheap_pages(). This is currently needed
by x86, which may require MEMF_bits(32) for HVM guests using shadow
paging.
The ARM implementation of alloc/free_vcpu_struct() is removed and
replaced by the common version. Stub implementations are also dropped
from PPC and RISC-V.
Now that the size of struct vcpu for Arm64 is smaller than PAGE_SIZE,
MAX_PAGES_PER_VCPU is no longer needed and is removed.
Finally, make alloc_vcpu_struct() and free_vcpu_struct() static to
common/domain.c, as they are no longer used outside common code.
No functional changes.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in v3:
- Make from function arch_vcpu_struct_memflags() a macros in asm/domain.h.
- Drop forward declaration of arch_vcpu_struct_memflags() in asm/domain.h.
- Update defintion of arch_vcpu_stuct_memflags() in alloc_vcpu_struct().
---
Changes in v2:
- Rework alloc/free_vcpu_struct() to work with only one page.
- Return back the comment about the restriction inside x86's
arch_vcpu_struct_memflags().
- Drop MAX_PAGES_PER_VCPU.
---
xen/arch/arm/domain.c | 32 -------------------------------
xen/arch/ppc/stubs.c | 10 ----------
xen/arch/riscv/stubs.c | 10 ----------
xen/arch/x86/domain.c | 24 -----------------------
xen/arch/x86/include/asm/domain.h | 12 ++++++++++++
xen/common/domain.c | 20 +++++++++++++++++++
xen/include/xen/domain.h | 4 ----
7 files changed, 32 insertions(+), 80 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 47973f99d935..507df807edb8 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -473,38 +473,6 @@ void dump_pageframe_info(struct domain *d)
}
-/*
- * The new VGIC has a bigger per-IRQ structure, so we need more than one
- * page on ARM64. Cowardly increase the limit in this case.
- */
-#if defined(CONFIG_NEW_VGIC) && defined(CONFIG_ARM_64)
-#define MAX_PAGES_PER_VCPU 2
-#else
-#define MAX_PAGES_PER_VCPU 1
-#endif
-
-struct vcpu *alloc_vcpu_struct(const struct domain *d)
-{
- struct vcpu *v;
-
- BUILD_BUG_ON(sizeof(*v) > MAX_PAGES_PER_VCPU * PAGE_SIZE);
- v = alloc_xenheap_pages(get_order_from_bytes(sizeof(*v)), 0);
- if ( v != NULL )
- {
- unsigned int i;
-
- for ( i = 0; i < DIV_ROUND_UP(sizeof(*v), PAGE_SIZE); i++ )
- clear_page((void *)v + i * PAGE_SIZE);
- }
-
- return v;
-}
-
-void free_vcpu_struct(struct vcpu *v)
-{
- free_xenheap_pages(v, get_order_from_bytes(sizeof(*v)));
-}
-
int arch_vcpu_create(struct vcpu *v)
{
int rc = 0;
diff --git a/xen/arch/ppc/stubs.c b/xen/arch/ppc/stubs.c
index 9953ea1c6c08..f7f6e7ed97af 100644
--- a/xen/arch/ppc/stubs.c
+++ b/xen/arch/ppc/stubs.c
@@ -152,11 +152,6 @@ void dump_pageframe_info(struct domain *d)
BUG_ON("unimplemented");
}
-void free_vcpu_struct(struct vcpu *v)
-{
- BUG_ON("unimplemented");
-}
-
int arch_vcpu_create(struct vcpu *v)
{
BUG_ON("unimplemented");
@@ -264,11 +259,6 @@ void vcpu_kick(struct vcpu *v)
BUG_ON("unimplemented");
}
-struct vcpu *alloc_vcpu_struct(const struct domain *d)
-{
- BUG_ON("unimplemented");
-}
-
unsigned long
hypercall_create_continuation(unsigned int op, const char *format, ...)
{
diff --git a/xen/arch/riscv/stubs.c b/xen/arch/riscv/stubs.c
index 164fc091b28a..29bdb65afbdf 100644
--- a/xen/arch/riscv/stubs.c
+++ b/xen/arch/riscv/stubs.c
@@ -121,11 +121,6 @@ void dump_pageframe_info(struct domain *d)
BUG_ON("unimplemented");
}
-void free_vcpu_struct(struct vcpu *v)
-{
- BUG_ON("unimplemented");
-}
-
int arch_vcpu_create(struct vcpu *v)
{
BUG_ON("unimplemented");
@@ -233,11 +228,6 @@ void vcpu_kick(struct vcpu *v)
BUG_ON("unimplemented");
}
-struct vcpu *alloc_vcpu_struct(const struct domain *d)
-{
- BUG_ON("unimplemented");
-}
-
unsigned long
hypercall_create_continuation(unsigned int op, const char *format, ...)
{
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 7632d5e2d62d..c29a6b0decee 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -493,30 +493,6 @@ unsigned int arch_domain_struct_memflags(void)
return MEMF_bits(bits);
}
-struct vcpu *alloc_vcpu_struct(const struct domain *d)
-{
- struct vcpu *v;
- /*
- * This structure contains embedded PAE PDPTEs, used when an HVM guest
- * runs on shadow pagetables outside of 64-bit mode. In this case the CPU
- * may require that the shadow CR3 points below 4GB, and hence the whole
- * structure must satisfy this restriction. Thus we specify MEMF_bits(32).
- */
- unsigned int memflags =
- (is_hvm_domain(d) && paging_mode_shadow(d)) ? MEMF_bits(32) : 0;
-
- BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
- v = alloc_xenheap_pages(0, memflags);
- if ( v != NULL )
- clear_page(v);
- return v;
-}
-
-void free_vcpu_struct(struct vcpu *v)
-{
- free_xenheap_page(v);
-}
-
/* Initialise various registers to their architectural INIT/RESET state. */
void arch_vcpu_regs_init(struct vcpu *v)
{
diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
index 16cd45cc32c0..effb23a23416 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -15,6 +15,18 @@
unsigned int arch_domain_struct_memflags(void);
#define arch_domain_struct_memflags arch_domain_struct_memflags
+/*
+ * This structure contains embedded PAE PDPTEs, used when an HVM guest
+ * runs on shadow pagetables outside of 64-bit mode. In this case the CPU
+ * may require that the shadow CR3 points below 4GB, and hence the whole
+ * structure must satisfy this restriction. Thus we specify MEMF_bits(32).
+ */
+#define arch_vcpu_struct_memflags(d) ({ \
+ const struct domain *d_ = (d); \
+ \
+ (is_hvm_domain(d_) && paging_mode_shadow(d_) ? MEMF_bits(32) : 0); \
+})
+
#define has_32bit_shinfo(d) ((d)->arch.has_32bit_shinfo)
/*
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 93c71bc766b0..568a63b7c6a2 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -392,6 +392,26 @@ static int vcpu_teardown(struct vcpu *v)
return 0;
}
+static struct vcpu *alloc_vcpu_struct(const struct domain *d)
+{
+#ifndef arch_vcpu_struct_memflags
+# define arch_vcpu_struct_memflags(d) ((void)(d), 0)
+#endif
+ struct vcpu *v;
+
+ BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
+ v = alloc_xenheap_pages(0, arch_vcpu_struct_memflags(d));
+ if ( v )
+ clear_page(v);
+
+ return v;
+}
+
+static void free_vcpu_struct(struct vcpu *v)
+{
+ free_xenheap_page(v);
+}
+
/*
* Destoy a vcpu once all references to it have been dropped. Used either
* from domain_destroy()'s RCU path, or from the vcpu_create() error path
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 8aab05ae93c8..644f5ac3f293 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -70,10 +70,6 @@ void domid_free(domid_t domid);
struct domain *alloc_domain_struct(void);
void free_domain_struct(struct domain *d);
-/* Allocate/free a VCPU structure. */
-struct vcpu *alloc_vcpu_struct(const struct domain *d);
-void free_vcpu_struct(struct vcpu *v);
-
/* Allocate/free a PIRQ structure. */
#ifndef alloc_pirq_struct
struct pirq *alloc_pirq_struct(struct domain *d);
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code
2025-12-22 16:40 ` [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code Oleksii Kurochko
@ 2025-12-23 11:33 ` Jan Beulich
2025-12-23 12:41 ` Andrew Cooper
1 sibling, 0 replies; 10+ messages in thread
From: Jan Beulich @ 2025-12-23 11:33 UTC (permalink / raw)
To: Oleksii Kurochko
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
Roger Pau Monné, Timothy Pearson, Alistair Francis,
Bob Eshleman, Connor Davis, xen-devel
On 22.12.2025 17:40, Oleksii Kurochko wrote:
> alloc_vcpu_struct() and free_vcpu_struct() contain little
> architecture-specific logic and are suitable for sharing across
> architectures. Move both helpers to common code.
>
> To support the remaining architectural differences, introduce
> arch_vcpu_struct_memflags(), allowing architectures to override the
> memory flags passed to alloc_xenheap_pages(). This is currently needed
> by x86, which may require MEMF_bits(32) for HVM guests using shadow
> paging.
>
> The ARM implementation of alloc/free_vcpu_struct() is removed and
> replaced by the common version. Stub implementations are also dropped
> from PPC and RISC-V.
>
> Now that the size of struct vcpu for Arm64 is smaller than PAGE_SIZE,
> MAX_PAGES_PER_VCPU is no longer needed and is removed.
>
> Finally, make alloc_vcpu_struct() and free_vcpu_struct() static to
> common/domain.c, as they are no longer used outside common code.
>
> No functional changes.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
With the functions moved a little further up as indicated in the reply
to patch 4:
Acked-by: Jan Beulich <jbeulich@suse.com>
Jan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code
2025-12-22 16:40 ` [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code Oleksii Kurochko
2025-12-23 11:33 ` Jan Beulich
@ 2025-12-23 12:41 ` Andrew Cooper
1 sibling, 0 replies; 10+ messages in thread
From: Andrew Cooper @ 2025-12-23 12:41 UTC (permalink / raw)
To: Oleksii Kurochko, xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall, Bertrand Marquis,
Michal Orzel, Volodymyr Babchuk, Anthony PERARD, Jan Beulich,
Roger Pau Monné, Timothy Pearson, Alistair Francis,
Bob Eshleman, Connor Davis
On 22/12/2025 4:40 pm, Oleksii Kurochko wrote:
> alloc_vcpu_struct() and free_vcpu_struct() contain little
> architecture-specific logic and are suitable for sharing across
> architectures. Move both helpers to common code.
>
> To support the remaining architectural differences, introduce
> arch_vcpu_struct_memflags(), allowing architectures to override the
> memory flags passed to alloc_xenheap_pages(). This is currently needed
> by x86, which may require MEMF_bits(32) for HVM guests using shadow
> paging.
>
> The ARM implementation of alloc/free_vcpu_struct() is removed and
> replaced by the common version. Stub implementations are also dropped
> from PPC and RISC-V.
>
> Now that the size of struct vcpu for Arm64 is smaller than PAGE_SIZE,
> MAX_PAGES_PER_VCPU is no longer needed and is removed.
>
> Finally, make alloc_vcpu_struct() and free_vcpu_struct() static to
> common/domain.c, as they are no longer used outside common code.
>
> No functional changes.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> with the
repositioning as per Jan's request.
I've found one error in the comment block, but I'll submit a fix for
that separately (so as not to mix it with code movement).
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 4/4] xen/common: make {alloc,free}_domain_struct() static
2025-12-22 16:40 [PATCH v3 0/4] Move alloc/free_vcpu_struct() to common code Oleksii Kurochko
` (2 preceding siblings ...)
2025-12-22 16:40 ` [PATCH v3 3/4] xen: move alloc/free_vcpu_struct() to common code Oleksii Kurochko
@ 2025-12-22 16:40 ` Oleksii Kurochko
2025-12-23 11:31 ` Jan Beulich
3 siblings, 1 reply; 10+ messages in thread
From: Oleksii Kurochko @ 2025-12-22 16:40 UTC (permalink / raw)
To: xen-devel
Cc: Oleksii Kurochko, Andrew Cooper, Anthony PERARD, Michal Orzel,
Jan Beulich, Julien Grall, Roger Pau Monné,
Stefano Stabellini
As {alloc,free}_domain_struct() are used only within domain.c,
they can be declared static and their declarations removed
from xen/domain.h.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes in v3:
- Move alloc_domain_struct() and free_domain_struct() to not have
forward declaration.
- Add Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>.
---
Changes in v2:
- New patch.
---
xen/common/domain.c | 42 ++++++++++++++++++++--------------------
xen/include/xen/domain.h | 4 ----
2 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 568a63b7c6a2..7a3e5ce6593f 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -690,6 +690,27 @@ static int domain_teardown(struct domain *d)
return 0;
}
+static struct domain *alloc_domain_struct(void)
+{
+#ifndef arch_domain_struct_memflags
+# define arch_domain_struct_memflags() 0
+#endif
+
+ struct domain *d = alloc_xenheap_pages(0, arch_domain_struct_memflags());
+
+ BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE);
+
+ if ( d )
+ clear_page(d);
+
+ return d;
+}
+
+static void free_domain_struct(struct domain *d)
+{
+ free_xenheap_page(d);
+}
+
/*
* Destroy a domain once all references to it have been dropped. Used either
* from the RCU path, or from the domain_create() error path before the domain
@@ -819,27 +840,6 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
return arch_sanitise_domain_config(config);
}
-struct domain *alloc_domain_struct(void)
-{
-#ifndef arch_domain_struct_memflags
-# define arch_domain_struct_memflags() 0
-#endif
-
- struct domain *d = alloc_xenheap_pages(0, arch_domain_struct_memflags());
-
- BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE);
-
- if ( d )
- clear_page(d);
-
- return d;
-}
-
-void free_domain_struct(struct domain *d)
-{
- free_xenheap_page(d);
-}
-
struct domain *domain_create(domid_t domid,
struct xen_domctl_createdomain *config,
unsigned int flags)
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 644f5ac3f293..273717c31b3f 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -66,10 +66,6 @@ void domid_free(domid_t domid);
* Arch-specifics.
*/
-/* Allocate/free a domain structure. */
-struct domain *alloc_domain_struct(void);
-void free_domain_struct(struct domain *d);
-
/* Allocate/free a PIRQ structure. */
#ifndef alloc_pirq_struct
struct pirq *alloc_pirq_struct(struct domain *d);
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v3 4/4] xen/common: make {alloc,free}_domain_struct() static
2025-12-22 16:40 ` [PATCH v3 4/4] xen/common: make {alloc,free}_domain_struct() static Oleksii Kurochko
@ 2025-12-23 11:31 ` Jan Beulich
0 siblings, 0 replies; 10+ messages in thread
From: Jan Beulich @ 2025-12-23 11:31 UTC (permalink / raw)
To: Oleksii Kurochko
Cc: Andrew Cooper, Anthony PERARD, Michal Orzel, Julien Grall,
Roger Pau Monné, Stefano Stabellini, xen-devel
On 22.12.2025 17:40, Oleksii Kurochko wrote:
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -690,6 +690,27 @@ static int domain_teardown(struct domain *d)
> return 0;
> }
>
> +static struct domain *alloc_domain_struct(void)
> +{
> +#ifndef arch_domain_struct_memflags
> +# define arch_domain_struct_memflags() 0
> +#endif
> +
> + struct domain *d = alloc_xenheap_pages(0, arch_domain_struct_memflags());
> +
> + BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE);
> +
> + if ( d )
> + clear_page(d);
> +
> + return d;
> +}
> +
> +static void free_domain_struct(struct domain *d)
> +{
> + free_xenheap_page(d);
> +}
> +
> /*
> * Destroy a domain once all references to it have been dropped. Used either
> * from the RCU path, or from the domain_create() error path before the domain
I think this is unfortunate placement: You put the two functions between two
other related ones, which imo would better stay together. I would suggest to
put them (and the ones moved by patch 3) ahead of vcpu_teardown(), or ahead
of vmtrace_free_buffer().
Jan
^ permalink raw reply [flat|nested] 10+ messages in thread