To make kaslr_offset detection code happy.
calc_kaslr_offset() requires valid CR3 and IDTR values in order
to find kernel start virtual and physical addresses.
One of CPUs might have zeroed ITDR register caused by triggering
triple fault. If CPU #0 has zeroed IDTR, walk through other CPUs
to get valid and not zeroed value.
In case of only one CPU, we should use another approach such as
page tree walking to get kasr offset.
Signed-off-by: Alexey Makhalov <amakhalov(a)vmware.com>
---
vmware_vmss.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/vmware_vmss.c b/vmware_vmss.c
index b168f29..8aa0de0 100644
--- a/vmware_vmss.c
+++ b/vmware_vmss.c
@@ -881,6 +881,27 @@ vmware_vmss_get_cr3_idtr(ulong *cr3, ulong *idtr)
*cr3 = vmss.regs64[0]->cr[3];
*idtr = vmss.regs64[0]->idtr;
+ /*
+ * debug.guest is generated on guest triple fault. One of the possible
+ * ways to triple fault is: zeroing IDTR and int3.
+ * This is used in linux to reboot machine using triple fault:
+ * "reboot=t" cmdline.
+ * In that case CPU which triggered triple fault will have zeroed
+ * IDTR. IDTR and CR3 are used to calculate kaslr offset and phys
+ * base.
+ * If IDTR on CPU0 is zeroed and we have several CPUs, return IDTR from
+ * another CPU.
+ */
+ if (vmss.num_vcpus > 1 && *idtr == 0) {
+ int i;
+ for (i = 0; i < vmss.num_vcpus; i++) {
+ if (vmss.vcpu_regs[i] == REGS_PRESENT_ALL) {
+ *idtr = vmss.regs64[i]->idtr;
+ break;
+ }
+ }
+ }
+
return TRUE;
}
--
2.11.0