tools/ocaml: Fix crash in Xenctrl.domain_getinfo{,list}() on ARM

The Store_field(result, 16, arch_config) sits inside an #ifdef x86, meaning
that on other architectures the pointer is not filled in.  Ocaml code then
falls over a NULL(ish) pointer (really the Val_unit used to initialise
'result') when the layout in the heap doesn't match the type system.

Rearrange alloc_domaininfo() to avoid this.  Similarly to
physinfo_arch_caps(), raise an exception if the architecture code hasn't
filled in an appropriate tag.  Move the setup of arch_domainconfig to be
common logic.

In order to simplify the addition of other architectures, remove the
arch_config variable (reusing tmp as it's touched exactly once), and rename
x86_arch_config to be arch_config so each architecture can fill in a suitable
one without needing more local variables.

Fixes: 9d683b5e37 ("tools/ocaml: Expose arch_config in domaininfo")
Fixes: 81838c9067 ("ocaml: fix arm build")
Reported-by: Julian Vetter <julian.vetter@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
(cherry picked from commit 365d2a5be3)
This commit is contained in:
Andrew Cooper committed 2026-07-29 13:41:28 +01:00
1 parent eb4905ec4e
commit cd29f1c5dd
1 file changed
+14 -9
+14 -9
View File
@@ -414,7 +414,8 @@ CAMLprim value stub_xc_domain_shutdown(value xch_val, value domid, value reason)
static value alloc_domaininfo(xc_domaininfo_t * info)
{
CAMLparam0();
CAMLlocal5(result, tmp, arch_config, x86_arch_config, emul_list);
CAMLlocal4(result, tmp, arch_config, emul_list);
int tag = -1;
int i;
result = caml_alloc_tuple(17);
@@ -444,6 +445,9 @@ static value alloc_domaininfo(xc_domaininfo_t * info)
Store_field(result, 15, tmp);
#if defined(__i386__) || defined(__x86_64__)
tag = 1; /* tag x86 */
/*
* emulation_flags: x86_arch_emulation_flags list;
*/
@@ -452,16 +456,17 @@ static value alloc_domaininfo(xc_domaininfo_t * info)
(info->arch_config.emulation_flags);
/* xen_x86_arch_domainconfig */
x86_arch_config = caml_alloc_tuple(1);
Store_field(x86_arch_config, 0, emul_list);
arch_config = caml_alloc_tuple(1);
Field(arch_config, 0) = emul_list;
#endif
if (tag < 0)
caml_failwith("Unimplemented architecture in alloc_domaininfo()");
/* arch_config: arch_domainconfig */
arch_config = caml_alloc_small(1, 1);
Store_field(arch_config, 0, x86_arch_config);
Store_field(result, 16, arch_config);
#endif
tmp = caml_alloc_small(1, tag);
Field(tmp, 0) = arch_config;
Field(result, 16) = tmp;
CAMLreturn(result);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.