On Wed, Mar 11, 2020 at 06:45:06PM +0100, Maxime Villard wrote: > Please CC me for issues related to NVMM, there is a number of lists where > I'm not subscribed. > > My understanding is that this commit is the cause (CC ad@): > > https://mail-index.netbsd.org/source-changes/2019/12/06/msg111617.html > > NVMM reschedules the thread when the SPCF_SHOULDYIELD flag is set. But > after this change the flag never gets set, so the rescheduling never > occurs, and NVMM is stuck with running the guest forever unless a signal > is caught in the emulator thread. > > The test program below shows the difference. On NetBSD-9 you have many > "resched", as expected. On NetBSD-current you have none. > > Andrew, can you have a look? There is a good dozen of places that use > SPCF_SHOULDYIELD for reschedulings, and they too may potentially be buggy > now.
Yes that was incorrect and I have fixed it. I will see about adding a wrapper function for this too. Andrew > > Thanks, > Maxime > > > > --------------------------------------------------------------------------- > > /* > * # gcc -o test test.c -lnvmm > * # ./test > */ > > #include <stdio.h> > #include <stdlib.h> > #include <unistd.h> > #include <sys/mman.h> > #include <fcntl.h> > #include <nvmm.h> > #include <stdint.h> > #include <string.h> > > int main() > { > uint8_t instr[] = { 0xEB, 0xFE }; > struct nvmm_machine mach; > struct nvmm_vcpu vcpu; > uintptr_t hva; > > nvmm_init(); > nvmm_machine_create(&mach); > nvmm_vcpu_create(&mach, 0, &vcpu); > > hva = (uintptr_t)mmap(NULL, 4096, PROT_READ|PROT_WRITE, > MAP_ANON|MAP_PRIVATE, -1, 0); > nvmm_hva_map(&mach, hva, 4096); > nvmm_gpa_map(&mach, hva, 0xFFFF0000, 4096, PROT_READ|PROT_EXEC); > > memcpy((void *)hva, instr, sizeof(instr)); > > nvmm_vcpu_getstate(&mach, &vcpu, NVMM_X64_STATE_GPRS); > vcpu.state->gprs[NVMM_X64_GPR_RIP] = 0; > nvmm_vcpu_setstate(&mach, &vcpu, NVMM_X64_STATE_GPRS); > > while (1) { > printf("looping\n"); > nvmm_vcpu_run(&mach, &vcpu); > > switch (vcpu.exit->reason) { > case NVMM_VCPU_EXIT_NONE: > printf("resched\n"); > break; > default: > printf("unknown: %d\n", vcpu.exit->reason); > break; > } > } > }