ANDROID: virt: gunyah: Support boot context register values up to ULONG_MAX

Values from (LONG_MAX, ULONG_MAX] aren't supported values by xarray.
Allocate a container to store the value instead and insert the container
to the xarray.

Change-Id: Iaf6a50cc4d56ab2108e3e21f2dfc493cd518cb22
Bug: 373872273
Fixes: ed8ebd8c80c5 ("FROMLIST: virt: gunyah: Allow userspace to initialize context of primary vCPU")
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
Signed-off-by: Elliot Berman <elliot.berman@oss.qualcomm.com>
This commit is contained in:
Elliot Berman
2024-10-16 10:53:06 -07:00
committed by Treehugger Robot
parent 86fff7cab3
commit 324fcc6bc0
+22 -3
View File
@@ -551,6 +551,7 @@ static long gunyah_vm_set_boot_context(struct gunyah_vm *ghvm,
struct gunyah_vm_boot_context *boot_ctx)
{
u8 reg_set, reg_index; /* to check values are reasonable */
u64 *value;
int ret;
if (boot_ctx->reg & ~BOOT_CONTEXT_REG_MASK)
@@ -585,8 +586,21 @@ static long gunyah_vm_set_boot_context(struct gunyah_vm *ghvm,
goto out;
}
/*
* allocate memory for the value because xarray supports [0, LONG_MAX]
* for values and we want [0, ULONG_MAX]
*/
value = kmalloc(sizeof(*value), GFP_KERNEL);
if (!value) {
ret = -ENOMEM;
goto out;
}
*value = boot_ctx->value;
ret = xa_err(xa_store(&ghvm->boot_context, boot_ctx->reg,
(void *)boot_ctx->value, GFP_KERNEL));
value, GFP_KERNEL));
if (ret)
kfree(value);
out:
up_read(&ghvm->status_lock);
return ret;
@@ -601,8 +615,9 @@ static inline int gunyah_vm_fill_boot_context(struct gunyah_vm *ghvm)
xa_for_each(&ghvm->boot_context, id, entry) {
reg_set = (id >> GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT) & 0xff;
reg_index = id & 0xff;
ret = gunyah_rm_vm_set_boot_context(
ghvm->rm, ghvm->vmid, reg_set, reg_index, (u64)entry);
ret = gunyah_rm_vm_set_boot_context(ghvm->rm, ghvm->vmid,
reg_set, reg_index,
*(u64 *)entry);
if (ret)
return ret;
}
@@ -976,6 +991,7 @@ static void _gunyah_vm_put(struct kref *kref)
struct gunyah_vm *ghvm = container_of(kref, struct gunyah_vm, kref);
struct gunyah_vm_gup_binding *b;
unsigned long index = 0;
void *entry;
int ret;
/**
@@ -1059,6 +1075,9 @@ static void _gunyah_vm_put(struct kref *kref)
"Failed to deallocate vmid: %d\n", ret);
}
xa_for_each(&ghvm->boot_context, index, entry)
kfree(entry);
xa_destroy(&ghvm->boot_context);
gunyah_rm_put(ghvm->rm);
mmdrop(ghvm->mm_s);