mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
KVM: arm64: Allow sysreg ranges for FGT descriptors
Just like we allow sysreg ranges for Coarse Grained Trap descriptors, allow them for Fine Grain Traps as well. This comes with a warning that not all ranges are suitable for this particular definition of ranges. Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
@@ -622,6 +622,11 @@ struct encoding_to_trap_config {
|
||||
const unsigned int line;
|
||||
};
|
||||
|
||||
/*
|
||||
* WARNING: using ranges is a treacherous endeavour, as sysregs that
|
||||
* are part of an architectural range are not necessarily contiguous
|
||||
* in the [Op0,Op1,CRn,CRm,Ops] space. Tread carefully.
|
||||
*/
|
||||
#define SR_RANGE_TRAP(sr_start, sr_end, trap_id) \
|
||||
{ \
|
||||
.encoding = sr_start, \
|
||||
@@ -1289,15 +1294,22 @@ enum fg_filter_id {
|
||||
|
||||
#define FGT(g, b, p) __FGT(g, b, p, __NO_FGF__)
|
||||
|
||||
#define SR_FGF(sr, g, b, p, f) \
|
||||
/*
|
||||
* See the warning next to SR_RANGE_TRAP(), and apply the same
|
||||
* level of caution.
|
||||
*/
|
||||
#define SR_FGF_RANGE(sr, e, g, b, p, f) \
|
||||
{ \
|
||||
.encoding = sr, \
|
||||
.end = sr, \
|
||||
.end = e, \
|
||||
.tc = __FGT(g, b, p, f), \
|
||||
.line = __LINE__, \
|
||||
}
|
||||
|
||||
#define SR_FGT(sr, g, b, p) SR_FGF(sr, g, b, p, __NO_FGF__)
|
||||
#define SR_FGF(sr, g, b, p, f) SR_FGF_RANGE(sr, sr, g, b, p, f)
|
||||
#define SR_FGT(sr, g, b, p) SR_FGF_RANGE(sr, sr, g, b, p, __NO_FGF__)
|
||||
#define SR_FGT_RANGE(sr, end, g, b, p) \
|
||||
SR_FGF_RANGE(sr, end, g, b, p, __NO_FGF__)
|
||||
|
||||
static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
|
||||
/* HFGRTR_EL2, HFGWTR_EL2 */
|
||||
@@ -1794,68 +1806,12 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
|
||||
SR_FGT(SYS_PMCNTENSET_EL0, HDFGRTR, PMCNTEN, 1),
|
||||
SR_FGT(SYS_PMCCNTR_EL0, HDFGRTR, PMCCNTR_EL0, 1),
|
||||
SR_FGT(SYS_PMCCFILTR_EL0, HDFGRTR, PMCCFILTR_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(0), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(1), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(2), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(3), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(4), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(5), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(6), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(7), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(8), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(9), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(10), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(11), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(12), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(13), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(14), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(15), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(16), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(17), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(18), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(19), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(20), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(21), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(22), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(23), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(24), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(25), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(26), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(27), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(28), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(29), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVTYPERn_EL0(30), HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(0), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(1), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(2), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(3), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(4), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(5), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(6), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(7), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(8), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(9), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(10), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(11), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(12), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(13), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(14), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(15), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(16), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(17), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(18), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(19), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(20), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(21), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(22), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(23), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(24), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(25), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(26), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(27), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(28), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(29), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_PMEVCNTRn_EL0(30), HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT_RANGE(SYS_PMEVTYPERn_EL0(0),
|
||||
SYS_PMEVTYPERn_EL0(30),
|
||||
HDFGRTR, PMEVTYPERn_EL0, 1),
|
||||
SR_FGT_RANGE(SYS_PMEVCNTRn_EL0(0),
|
||||
SYS_PMEVCNTRn_EL0(30),
|
||||
HDFGRTR, PMEVCNTRn_EL0, 1),
|
||||
SR_FGT(SYS_OSDLR_EL1, HDFGRTR, OSDLR_EL1, 1),
|
||||
SR_FGT(SYS_OSECCR_EL1, HDFGRTR, OSECCR_EL1, 1),
|
||||
SR_FGT(SYS_OSLSR_EL1, HDFGRTR, OSLSR_EL1, 1),
|
||||
@@ -2172,6 +2128,9 @@ static __init int check_all_fgt_masks(int ret)
|
||||
return ret ?: err;
|
||||
}
|
||||
|
||||
#define for_each_encoding_in(__x, __s, __e) \
|
||||
for (u32 __x = __s; __x <= __e; __x = encoding_next(__x))
|
||||
|
||||
int __init populate_nv_trap_config(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -2191,7 +2150,7 @@ int __init populate_nv_trap_config(void)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
for (u32 enc = cgt->encoding; enc <= cgt->end; enc = encoding_next(enc)) {
|
||||
for_each_encoding_in(enc, cgt->encoding, cgt->end) {
|
||||
prev = xa_store(&sr_forward_xa, enc,
|
||||
xa_mk_value(cgt->tc.val), GFP_KERNEL);
|
||||
if (prev && !xa_is_err(prev)) {
|
||||
@@ -2226,25 +2185,27 @@ int __init populate_nv_trap_config(void)
|
||||
print_nv_trap_error(fgt, "Invalid FGT", ret);
|
||||
}
|
||||
|
||||
tc = get_trap_config(fgt->encoding);
|
||||
for_each_encoding_in(enc, fgt->encoding, fgt->end) {
|
||||
tc = get_trap_config(enc);
|
||||
|
||||
if (tc.fgt) {
|
||||
ret = -EINVAL;
|
||||
print_nv_trap_error(fgt, "Duplicate FGT", ret);
|
||||
}
|
||||
if (tc.fgt) {
|
||||
ret = -EINVAL;
|
||||
print_nv_trap_error(fgt, "Duplicate FGT", ret);
|
||||
}
|
||||
|
||||
tc.val |= fgt->tc.val;
|
||||
prev = xa_store(&sr_forward_xa, fgt->encoding,
|
||||
xa_mk_value(tc.val), GFP_KERNEL);
|
||||
tc.val |= fgt->tc.val;
|
||||
prev = xa_store(&sr_forward_xa, enc,
|
||||
xa_mk_value(tc.val), GFP_KERNEL);
|
||||
|
||||
if (xa_is_err(prev)) {
|
||||
ret = xa_err(prev);
|
||||
print_nv_trap_error(fgt, "Failed FGT insertion", ret);
|
||||
}
|
||||
if (xa_is_err(prev)) {
|
||||
ret = xa_err(prev);
|
||||
print_nv_trap_error(fgt, "Failed FGT insertion", ret);
|
||||
}
|
||||
|
||||
if (!aggregate_fgt(tc)) {
|
||||
ret = -EINVAL;
|
||||
print_nv_trap_error(fgt, "FGT bit is reserved", ret);
|
||||
if (!aggregate_fgt(tc)) {
|
||||
ret = -EINVAL;
|
||||
print_nv_trap_error(fgt, "FGT bit is reserved", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user