Skip to content

Commit fdd8e34

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
In order to be able to store different values for member of an encoding range, replace xa_store_range() calls with discrete xa_store() calls and an encoding iterator. We end-up using a bit more memory, but we gain some flexibility that we will make use of shortly. Take this opportunity to tidy up the error handling path. Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Joey Gouly <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 9958d58 commit fdd8e34

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

arch/arm64/kvm/emulate-nested.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,28 @@ static __init void print_nv_trap_error(const struct encoding_to_trap_config *tc,
17571757
err);
17581758
}
17591759

1760+
static u32 encoding_next(u32 encoding)
1761+
{
1762+
u8 op0, op1, crn, crm, op2;
1763+
1764+
op0 = sys_reg_Op0(encoding);
1765+
op1 = sys_reg_Op1(encoding);
1766+
crn = sys_reg_CRn(encoding);
1767+
crm = sys_reg_CRm(encoding);
1768+
op2 = sys_reg_Op2(encoding);
1769+
1770+
if (op2 < Op2_mask)
1771+
return sys_reg(op0, op1, crn, crm, op2 + 1);
1772+
if (crm < CRm_mask)
1773+
return sys_reg(op0, op1, crn, crm + 1, 0);
1774+
if (crn < CRn_mask)
1775+
return sys_reg(op0, op1, crn + 1, 0, 0);
1776+
if (op1 < Op1_mask)
1777+
return sys_reg(op0, op1 + 1, 0, 0, 0);
1778+
1779+
return sys_reg(op0 + 1, 0, 0, 0, 0);
1780+
}
1781+
17601782
int __init populate_nv_trap_config(void)
17611783
{
17621784
int ret = 0;
@@ -1775,23 +1797,18 @@ int __init populate_nv_trap_config(void)
17751797
ret = -EINVAL;
17761798
}
17771799

1778-
if (cgt->encoding != cgt->end) {
1779-
prev = xa_store_range(&sr_forward_xa,
1780-
cgt->encoding, cgt->end,
1781-
xa_mk_value(cgt->tc.val),
1782-
GFP_KERNEL);
1783-
} else {
1784-
prev = xa_store(&sr_forward_xa, cgt->encoding,
1800+
for (u32 enc = cgt->encoding; enc <= cgt->end; enc = encoding_next(enc)) {
1801+
prev = xa_store(&sr_forward_xa, enc,
17851802
xa_mk_value(cgt->tc.val), GFP_KERNEL);
17861803
if (prev && !xa_is_err(prev)) {
17871804
ret = -EINVAL;
17881805
print_nv_trap_error(cgt, "Duplicate CGT", ret);
17891806
}
1790-
}
17911807

1792-
if (xa_is_err(prev)) {
1793-
ret = xa_err(prev);
1794-
print_nv_trap_error(cgt, "Failed CGT insertion", ret);
1808+
if (xa_is_err(prev)) {
1809+
ret = xa_err(prev);
1810+
print_nv_trap_error(cgt, "Failed CGT insertion", ret);
1811+
}
17951812
}
17961813
}
17971814

@@ -1804,6 +1821,7 @@ int __init populate_nv_trap_config(void)
18041821
for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) {
18051822
const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i];
18061823
union trap_config tc;
1824+
void *prev;
18071825

18081826
if (fgt->tc.fgt >= __NR_FGT_GROUP_IDS__) {
18091827
ret = -EINVAL;
@@ -1818,8 +1836,13 @@ int __init populate_nv_trap_config(void)
18181836
}
18191837

18201838
tc.val |= fgt->tc.val;
1821-
xa_store(&sr_forward_xa, fgt->encoding,
1822-
xa_mk_value(tc.val), GFP_KERNEL);
1839+
prev = xa_store(&sr_forward_xa, fgt->encoding,
1840+
xa_mk_value(tc.val), GFP_KERNEL);
1841+
1842+
if (xa_is_err(prev)) {
1843+
ret = xa_err(prev);
1844+
print_nv_trap_error(fgt, "Failed FGT insertion", ret);
1845+
}
18231846
}
18241847

18251848
kvm_info("nv: %ld fine grained trap handlers\n",

0 commit comments

Comments
 (0)