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.

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;
                }
        }
}

Reply via email to