|
@@ -726,6 +726,19 @@ static bool runs_at_el2(const struct arm64_cpu_capabilities *entry, int __unused
|
|
return is_kernel_in_hyp_mode();
|
|
return is_kernel_in_hyp_mode();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool hyp_offset_low(const struct arm64_cpu_capabilities *entry,
|
|
|
|
+ int __unused)
|
|
|
|
+{
|
|
|
|
+ phys_addr_t idmap_addr = virt_to_phys(__hyp_idmap_text_start);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Activate the lower HYP offset only if:
|
|
|
|
+ * - the idmap doesn't clash with it,
|
|
|
|
+ * - the kernel is not running at EL2.
|
|
|
|
+ */
|
|
|
|
+ return idmap_addr > GENMASK(VA_BITS - 2, 0) && !is_kernel_in_hyp_mode();
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct arm64_cpu_capabilities arm64_features[] = {
|
|
static const struct arm64_cpu_capabilities arm64_features[] = {
|
|
{
|
|
{
|
|
.desc = "GIC system register CPU interface",
|
|
.desc = "GIC system register CPU interface",
|
|
@@ -803,6 +816,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|
.field_pos = ID_AA64PFR0_EL0_SHIFT,
|
|
.field_pos = ID_AA64PFR0_EL0_SHIFT,
|
|
.min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
|
|
.min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
|
|
},
|
|
},
|
|
|
|
+ {
|
|
|
|
+ .desc = "Reduced HYP mapping offset",
|
|
|
|
+ .capability = ARM64_HYP_OFFSET_LOW,
|
|
|
|
+ .def_scope = SCOPE_SYSTEM,
|
|
|
|
+ .matches = hyp_offset_low,
|
|
|
|
+ },
|
|
{},
|
|
{},
|
|
};
|
|
};
|
|
|
|
|