ANDROID: KVM: arm64: devices: Register assignable devices as moveable
To prevent assignable devices MMIO from being unmapped under pressure, register them as moveable memory. Unfortunately, as moveable memory is registered very early at boot, while devices are registered later after pKVM init and IOMMU driver register, we would have some duplicate code parsing assignable devices from the device tree. Bug: 357781595 Bug: 348382247 Change-Id: I5957c5f7c10f435a970409195825259dc65072ad Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
@@ -268,6 +268,7 @@ static inline bool kvm_pvm_ext_allowed(long ext)
|
||||
enum pkvm_moveable_reg_type {
|
||||
PKVM_MREG_MEMORY,
|
||||
PKVM_MREG_PROTECTED_RANGE,
|
||||
PKVM_MREG_ASSIGN_MMIO,
|
||||
};
|
||||
|
||||
struct pkvm_moveable_reg {
|
||||
|
||||
+49
-22
@@ -110,11 +110,39 @@ static void __init sort_moveable_regs(void)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int __init register_moveable_fdt_resource(struct device_node *np,
|
||||
enum pkvm_moveable_reg_type type)
|
||||
{
|
||||
struct resource res;
|
||||
u64 start, size;
|
||||
unsigned int j = 0;
|
||||
unsigned int i = kvm_nvhe_sym(pkvm_moveable_regs_nr);
|
||||
|
||||
while(!of_address_to_resource(np, j, &res)) {
|
||||
if (i >= PKVM_NR_MOVEABLE_REGS)
|
||||
return -ENOMEM;
|
||||
|
||||
start = res.start;
|
||||
size = resource_size(&res);
|
||||
if (!PAGE_ALIGNED(start) || !PAGE_ALIGNED(size))
|
||||
return -EINVAL;
|
||||
|
||||
moveable_regs[i].start = start;
|
||||
moveable_regs[i].size = size;
|
||||
moveable_regs[i].type = type;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
kvm_nvhe_sym(pkvm_moveable_regs_nr) = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init register_moveable_regions(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
struct device_node *np;
|
||||
int i = 0;
|
||||
int i = 0, ret = 0, idx = 0;
|
||||
|
||||
for_each_mem_region(reg) {
|
||||
if (i >= PKVM_NR_MOVEABLE_REGS)
|
||||
@@ -124,34 +152,33 @@ static int __init register_moveable_regions(void)
|
||||
moveable_regs[i].type = PKVM_MREG_MEMORY;
|
||||
i++;
|
||||
}
|
||||
kvm_nvhe_sym(pkvm_moveable_regs_nr) = i;
|
||||
|
||||
for_each_compatible_node(np, NULL, "pkvm,protected-region") {
|
||||
struct resource res;
|
||||
u64 start, size;
|
||||
int ret;
|
||||
|
||||
if (i >= PKVM_NR_MOVEABLE_REGS)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_address_to_resource(np, 0, &res);
|
||||
ret = register_moveable_fdt_resource(np, PKVM_MREG_PROTECTED_RANGE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
start = res.start;
|
||||
size = resource_size(&res);
|
||||
if (!PAGE_ALIGNED(start) || !PAGE_ALIGNED(size))
|
||||
return -EINVAL;
|
||||
|
||||
moveable_regs[i].start = start;
|
||||
moveable_regs[i].size = size;
|
||||
moveable_regs[i].type = PKVM_MREG_PROTECTED_RANGE;
|
||||
i++;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
for_each_compatible_node(np, NULL, PKVM_DEVICE_ASSIGN_COMPAT) {
|
||||
struct of_phandle_args args;
|
||||
|
||||
while (!of_parse_phandle_with_fixed_args(np, "devices", 1, idx, &args)) {
|
||||
idx++;
|
||||
ret = register_moveable_fdt_resource(args.np, PKVM_MREG_ASSIGN_MMIO);
|
||||
of_node_put(args.np);
|
||||
if (ret)
|
||||
goto out_fail;
|
||||
}
|
||||
}
|
||||
|
||||
kvm_nvhe_sym(pkvm_moveable_regs_nr) = i;
|
||||
sort_moveable_regs();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
out_fail:
|
||||
of_node_put(np);
|
||||
kvm_nvhe_sym(pkvm_moveable_regs_nr) = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __init kvm_hyp_reserve(void)
|
||||
|
||||
Reference in New Issue
Block a user