On Mon, Dec 26, 2016 at 09:34:54PM +0100, Lluís Vilanova wrote: > +static void segv_handler(int signum, siginfo_t *siginfo, void *sigctxt) > +{ > + CPUState *vcpu = current_cpu; > + void *control_0 = vcpu->hypertrace_control; > + void *control_1 = vcpu->hypertrace_control + config.control_size / 2; > + void *control_2 = control_1 + config.control_size / 2; > + > + if (control_0 <= siginfo->si_addr && siginfo->si_addr < control_1) { > + > + /* 1st fault (guest will write cmd) */ > + assert(((unsigned long)siginfo->si_addr % sizeof(uint64_t)) == 0); > + swap_control(control_0, control_1); > + > + } else if (control_1 <= siginfo->si_addr && siginfo->si_addr < > control_2) { > + size_t client = (siginfo->si_addr - control_1) / sizeof(uint64_t); > + uint64_t vcontrol = ((uint64_t *)control_0)[client]; > + uint64_t *data_ptr = &qemu_data[client * config.client_data_size]; > + > + /* 2nd fault (invoke) */ > + assert(((unsigned long)siginfo->si_addr % sizeof(uint64_t)) == 0); > + hypertrace_emit(current_cpu, vcontrol, data_ptr); > + swap_control(control_1, control_0);
A simpler and faster approach is to permanently mprotect just one region and load all arguments from data[] (including the first argument). Then swapping isn't necessary.
signature.asc
Description: PGP signature