@@ -200,6 +200,7 @@ ENDPROC(\label)
invalid_vector el2h_fiq_invalid
invalid_vector el1_fiq_invalid
+hyp_entry_literal_pool:
.ltorg
.align 11
@@ -86,7 +86,7 @@ static void __hyp_text __deactivate_traps_common(void)
write_sysreg(0, pmuserenr_el0);
}
-static void activate_traps_vhe(struct kvm_vcpu *vcpu)
+static noinline void activate_traps_vhe(struct kvm_vcpu *vcpu)
{
u64 val;
@@ -125,7 +125,7 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
__activate_traps_nvhe(vcpu);
}
-static void deactivate_traps_vhe(void)
+static noinline void deactivate_traps_vhe(void)
{
extern char vectors[]; /* kernel exception vectors */
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
@@ -529,8 +529,8 @@ static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par,
read_sysreg(hpfar_el2), par, vcpu);
}
-static void __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par,
- struct kvm_cpu_context *host_ctxt)
+static noinline void __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par,
+ struct kvm_cpu_context *host_ctxt)
{
struct kvm_vcpu *vcpu;
vcpu = host_ctxt->__hyp_running_vcpu;
@@ -964,6 +964,7 @@ enum mismatch {
ANY_EXIT_TO_ANY_INIT,
EXPORT_TO_INIT_EXIT,
EXTABLE_TO_NON_TEXT,
+ HYP_TEXT_TO_NON_HYP,
};
/**
@@ -1003,6 +1004,11 @@ static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
Elf_Rela *r, Elf_Sym *sym,
const char *fromsec);
+static void hyp_mismatch_handler(const char *modname, struct elf_info *elf,
+ const struct sectioncheck* const mismatch,
+ Elf_Rela *r, Elf_Sym *sym,
+ const char *fromsec);
+
static const struct sectioncheck sectioncheck[] = {
/* Do not reference init/exit code/data from
* normal code and data
@@ -1090,7 +1096,15 @@ static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
.good_tosec = {ALL_TEXT_SECTIONS , NULL},
.mismatch = EXTABLE_TO_NON_TEXT,
.handler = extable_mismatch_handler,
-}
+},
+{
+ .fromsec = { ".hyp.text", NULL },
+ .good_tosec = { ".hyp.text", ".hyp.idmap.text",
+ ".rodata", ".data..ro_after_init",
+ ".bss", NULL },
+ .mismatch = HYP_TEXT_TO_NON_HYP,
+ .handler = hyp_mismatch_handler,
+},
};
static const struct sectioncheck *section_mismatch(
@@ -1525,6 +1539,10 @@ static void report_sec_mismatch(const char *modname,
fatal("There's a special handler for this mismatch type, "
"we should never get here.");
break;
+ case HYP_TEXT_TO_NON_HYP:
+ fatal("There's a special handler for this mismatch type, "
+ "we should never get here.");
+ break;
}
fprintf(stderr, "\n");
}
@@ -1681,6 +1699,46 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
}
}
+static void hyp_mismatch_handler(const char *modname, struct elf_info *elf,
+ const struct sectioncheck* const mismatch,
+ Elf_Rela *r, Elf_Sym *sym,
+ const char *fromsec)
+{
+ Elf_Sym *from = find_elf_symbol2(elf, r->r_offset, fromsec);
+ Elf_Sym *to = find_elf_symbol(elf, r->r_addend, sym);
+ const char *fromsym = sym_name(elf, from);
+ const char *tosec = sec_name(elf, get_secindex(elf, sym));
+ const char *tosym = sym_name(elf, to);
+ char *s;
+
+ switch (mismatch->mismatch) {
+ case HYP_TEXT_TO_NON_HYP:
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+ if (!is_valid_name(elf, from) || !is_valid_name(elf, to)) {
+ /*
+ * Skip unknown symbols to reduce false alarms,
+ * of course at the risk of missing something...
+ */
+ return;
+ }
+ if (strcmp(tosym, "kvm_arm_hyp_stack_page") == 0 ||
+ strcmp(tosym, "kvm_host_cpu_state") == 0)
+ return;
+ if (strcmp(fromsym, "hyp_entry_literal_pool") == 0)
+ return;
+ if ((s = strstr(tosym, "_vhe")) &&
+ (strlen(s) == 4 || s[4] == '.'))
+ return;
+ fprintf(stderr,
+ ".hyp.text:%s references %s:%s\n\n",
+ fromsym, tosec, tosym);
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
static void check_section_mismatch(const char *modname, struct elf_info *elf,
Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
{