hv_wdt: Make HV WDT CPU configurable and WDT optional

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-09-15 22:08:35 +09:00
parent 6c186f8468
commit 368b48a365
7 changed files with 26 additions and 14 deletions

View file

@ -132,6 +132,7 @@ class HV(Reloadable):
self.shell_locals = {} self.shell_locals = {}
self.xnu_mode = False self.xnu_mode = False
self._update_shell_locals() self._update_shell_locals()
self.wdt_cpu = None
def _reloadme(self): def _reloadme(self):
super()._reloadme() super()._reloadme()
@ -1041,14 +1042,9 @@ class HV(Reloadable):
del self.adt[name] del self.adt[name]
except KeyError: except KeyError:
pass pass
for name in ("/cpus/cpu1",
"/cpus/cpu2", if self.wdt_cpu is not None:
"/cpus/cpu3", name = f"/cpus/cpu{self.wdt_cpu}"
"/cpus/cpu4",
"/cpus/cpu5",
"/cpus/cpu6",
"/cpus/cpu7",
):
print(f"Removing ADT node {name}") print(f"Removing ADT node {name}")
try: try:
del self.adt[name] del self.adt[name]
@ -1239,6 +1235,8 @@ class HV(Reloadable):
self.iface.dev.timeout = None self.iface.dev.timeout = None
self.default_sigint = signal.signal(signal.SIGINT, self._handle_sigint) self.default_sigint = signal.signal(signal.SIGINT, self._handle_sigint)
if self.wdt_cpu is not None:
self.p.hv_wdt_start(self.wdt_cpu)
# Does not return # Does not return
self.p.hv_start(self.entry, self.guest_base + self.bootargs_off) self.p.hv_start(self.entry, self.guest_base + self.bootargs_off)

View file

@ -561,6 +561,7 @@ class M1N1Proxy(Reloadable):
P_HV_PT_WALK = 0xc04 P_HV_PT_WALK = 0xc04
P_HV_MAP_VUART = 0xc05 P_HV_MAP_VUART = 0xc05
P_HV_TRACE_IRQ = 0xc06 P_HV_TRACE_IRQ = 0xc06
P_HV_WDT_START = 0xc07
P_FB_INIT = 0xd00 P_FB_INIT = 0xd00
P_FB_SHUTDOWN = 0xd01 P_FB_SHUTDOWN = 0xd01
@ -955,6 +956,8 @@ class M1N1Proxy(Reloadable):
return self.request(self.P_HV_MAP_VUART, base, irq, iodev) return self.request(self.P_HV_MAP_VUART, base, irq, iodev)
def hv_trace_irq(self, evt_type, num, count, flags): def hv_trace_irq(self, evt_type, num, count, flags):
return self.request(self.P_HV_TRACE_IRQ, evt_type, num, count, flags) return self.request(self.P_HV_TRACE_IRQ, evt_type, num, count, flags)
def hv_wdt_start(self, cpu):
return self.request(self.P_HV_WDT_START, cpu)
def fb_init(self): def fb_init(self):
return self.request(self.P_FB_INIT) return self.request(self.P_FB_INIT)

View file

@ -65,7 +65,6 @@ void hv_start(void *entry, u64 regs[4])
if (gxf_enabled()) if (gxf_enabled())
gl2_call(hv_set_gxf_vbar, 0, 0, 0, 0); gl2_call(hv_set_gxf_vbar, 0, 0, 0, 0);
hv_wdt_start();
hv_arm_tick(); hv_arm_tick();
hv_enter_guest(regs[0], regs[1], regs[2], regs[3], entry); hv_enter_guest(regs[0], regs[1], regs[2], regs[3], entry);
hv_wdt_stop(); hv_wdt_stop();

View file

@ -71,7 +71,7 @@ void hv_wdt_pet(void);
void hv_wdt_suspend(void); void hv_wdt_suspend(void);
void hv_wdt_resume(void); void hv_wdt_resume(void);
void hv_wdt_init(void); void hv_wdt_init(void);
void hv_wdt_start(void); void hv_wdt_start(int cpu);
void hv_wdt_stop(void); void hv_wdt_stop(void);
void hv_wdt_breadcrumb(char c); void hv_wdt_breadcrumb(char c);

View file

@ -6,7 +6,6 @@
#include "uart.h" #include "uart.h"
#include "utils.h" #include "utils.h"
#define WDT_CPU 1
#define WDT_TIMEOUT 1 #define WDT_TIMEOUT 1
static bool hv_wdt_active = false; static bool hv_wdt_active = false;
@ -15,6 +14,8 @@ static volatile u64 hv_wdt_timestamp = 0;
static u64 hv_wdt_timeout = 0; static u64 hv_wdt_timeout = 0;
static volatile u64 hv_wdt_breadcrumbs; static volatile u64 hv_wdt_breadcrumbs;
static int hv_wdt_cpu;
static u64 cpu_dbg_base = 0; static u64 cpu_dbg_base = 0;
void hv_wdt_bark(void) void hv_wdt_bark(void)
@ -105,18 +106,25 @@ void hv_wdt_init(void)
cpu_dbg_base = reg[0]; cpu_dbg_base = reg[0];
} }
void hv_wdt_start(void) void hv_wdt_start(int cpu)
{ {
if (hv_wdt_active)
return;
hv_wdt_cpu = cpu;
hv_wdt_breadcrumbs = 0; hv_wdt_breadcrumbs = 0;
hv_wdt_timeout = mrs(CNTFRQ_EL0) * WDT_TIMEOUT; hv_wdt_timeout = mrs(CNTFRQ_EL0) * WDT_TIMEOUT;
hv_wdt_pet(); hv_wdt_pet();
hv_wdt_active = true; hv_wdt_active = true;
hv_wdt_enabled = true; hv_wdt_enabled = true;
smp_call4(WDT_CPU, hv_wdt_main, 0, 0, 0, 0); smp_call4(hv_wdt_cpu, hv_wdt_main, 0, 0, 0, 0);
} }
void hv_wdt_stop(void) void hv_wdt_stop(void)
{ {
if (!hv_wdt_active)
return;
hv_wdt_active = false; hv_wdt_active = false;
smp_wait(WDT_CPU); smp_wait(hv_wdt_cpu);
} }

View file

@ -436,6 +436,9 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
reply->retval = hv_trace_irq(request->args[0], request->args[1], request->args[2], reply->retval = hv_trace_irq(request->args[0], request->args[1], request->args[2],
request->args[3]); request->args[3]);
break; break;
case P_HV_WDT_START:
hv_wdt_start(request->args[0]);
break;
case P_FB_INIT: case P_FB_INIT:
fb_init(); fb_init();

View file

@ -119,6 +119,7 @@ typedef enum {
P_HV_PT_WALK, P_HV_PT_WALK,
P_HV_MAP_VUART, P_HV_MAP_VUART,
P_HV_TRACE_IRQ, P_HV_TRACE_IRQ,
P_HV_WDT_START,
P_FB_INIT = 0xd00, P_FB_INIT = 0xd00,
P_FB_SHUTDOWN, P_FB_SHUTDOWN,