forked from M-Labs/artiq
1
0
Fork 0

runtime: avoid race condition when running kernel.

Also, don't bother passing kernel name: entry point is already
recorded in DT_INIT when the kernel is linked.
This commit is contained in:
whitequark 2015-08-07 08:49:57 +03:00
parent 1a969aa9e4
commit b5cf1e395d
6 changed files with 41 additions and 62 deletions

View File

@ -130,10 +130,9 @@ class CommGeneric:
if ty != _D2HMsgType.LOAD_COMPLETED: if ty != _D2HMsgType.LOAD_COMPLETED:
raise IOError("Incorrect reply from device: "+str(ty)) raise IOError("Incorrect reply from device: "+str(ty))
def run(self, kname): def run(self):
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL) self._write_header(9, _H2DMsgType.RUN_KERNEL)
self.write(bytes(kname, "ascii")) logger.debug("running kernel")
logger.debug("running kernel: %s", kname)
def flash_storage_read(self, key): def flash_storage_read(self, key):
self._write_header(9+len(key), _H2DMsgType.FLASH_READ_REQUEST) self._write_header(9+len(key), _H2DMsgType.FLASH_READ_REQUEST)

View File

@ -30,22 +30,29 @@ void kloader_start_bridge()
start_kernel_cpu(NULL); start_kernel_cpu(NULL);
} }
static int load_or_start_kernel(void *library, const char *kernel) static int load_or_start_kernel(void *library, int run_kernel)
{ {
static struct dyld_info library_info; static struct dyld_info library_info;
struct msg_load_request request = { struct msg_load_request request = {
.library = library, .library = library,
.library_info = &library_info, .library_info = &library_info,
.kernel = kernel, .run_kernel = run_kernel,
}; };
start_kernel_cpu(&request); start_kernel_cpu(&request);
struct msg_load_reply *reply = mailbox_wait_and_receive(); struct msg_load_reply *reply = mailbox_wait_and_receive();
if(reply != NULL && reply->type == MESSAGE_TYPE_LOAD_REPLY) { if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
log("cannot load/run kernel: %s", reply->error); log("BUG: unexpected reply to load/run request");
return 0; return 0;
} }
if(reply->error != NULL) {
log("cannot load kernel: %s", reply->error);
return 0;
}
mailbox_acknowledge();
return 1; return 1;
} }
@ -56,12 +63,12 @@ int kloader_load_library(void *library)
return 0; return 0;
} }
return load_or_start_kernel(library, NULL); return load_or_start_kernel(library, 0);
} }
int kloader_start_kernel(const char *name) void kloader_start_kernel()
{ {
return load_or_start_kernel(NULL, name); load_or_start_kernel(NULL, 1);
} }
int kloader_start_idle_kernel(void) int kloader_start_idle_kernel(void)
@ -74,7 +81,7 @@ int kloader_start_idle_kernel(void)
if(length <= 0) if(length <= 0)
return 0; return 0;
return load_or_start_kernel(buffer, "test.__modinit__"); return load_or_start_kernel(buffer, 1);
#else #else
return 0; return 0;
#endif #endif

View File

@ -12,7 +12,7 @@ int kloader_load_library(void *code);
void kloader_start_bridge(void); void kloader_start_bridge(void);
int kloader_start_idle_kernel(void); int kloader_start_idle_kernel(void);
int kloader_start_kernel(const char *name); void kloader_start_kernel(void);
void kloader_stop(void); void kloader_stop(void);
int kloader_validate_kpointer(void *p); int kloader_validate_kpointer(void *p);

View File

@ -184,51 +184,37 @@ void exception_handler(unsigned long vect, unsigned long *regs,
int main(void); int main(void);
int main(void) int main(void)
{ {
struct msg_load_request *msg = mailbox_receive(); struct msg_load_request *request = mailbox_receive();
struct msg_load_reply load_reply = {
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = NULL
};
if(msg == NULL) { if(request == NULL) {
bridge_main(); bridge_main();
while(1); while(1);
} }
if(msg->library != NULL) { if(request->library != NULL) {
const char *error; if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
if(!dyld_load(msg->library, KERNELCPU_PAYLOAD_ADDRESS, resolve_runtime_export, request->library_info,
resolve_runtime_export, msg->library_info, &error)) { &load_reply.error)) {
struct msg_load_reply msg = { mailbox_send(&load_reply);
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = error
};
mailbox_send(&msg);
while(1); while(1);
} }
} }
void (*kernel)(void) = NULL; if(request->run_kernel) {
if(msg->kernel != NULL) { void (*kernel_init)() = request->library_info->init;
kernel = dyld_lookup(msg->kernel, msg->library_info);
if(kernel == NULL) {
char error[256];
snprintf(error, sizeof(error),
"kernel '%s' not found in library", msg->kernel);
struct msg_load_reply msg = {
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = error
};
mailbox_send(&msg);
while(1);
}
}
mailbox_acknowledge(); mailbox_send_and_wait(&load_reply);
kernel_init();
if(kernel) { struct msg_base finished_reply;
void (*run_closure)(void *) = msg->library_info->init; finished_reply.type = MESSAGE_TYPE_FINISHED;
run_closure(kernel); mailbox_send_and_wait(&finished_reply);
} else {
struct msg_base msg; mailbox_send(&load_reply);
msg.type = MESSAGE_TYPE_FINISHED;
mailbox_send_and_wait(&msg);
} }
while(1); while(1);

View File

@ -39,7 +39,7 @@ struct msg_base {
struct msg_load_request { struct msg_load_request {
void *library; void *library;
struct dyld_info *library_info; struct dyld_info *library_info;
const char *kernel; int run_kernel;
}; };
struct msg_load_reply { struct msg_load_reply {

View File

@ -184,21 +184,8 @@ static int process_input(void)
break; break;
} }
if((buffer_in_index + 1) > BUFFER_OUT_SIZE) {
log("Kernel name too long");
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
submit_output(9);
break;
}
buffer_in[buffer_in_index] = 0;
watchdog_init(); watchdog_init();
if(!kloader_start_kernel((char *)&buffer_in[9])) { kloader_start_kernel();
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
submit_output(9);
break;
}
user_kernel_state = USER_KERNEL_RUNNING; user_kernel_state = USER_KERNEL_RUNNING;
break; break;