Project

General

Profile

Actions

Bug #14952

closed

bhyve should expose PAGING exits to userspace

Added by Patrick Mooney 3 months ago. Updated 2 months ago.

Status:
Closed
Priority:
Normal
Category:
bhyve
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:
External Bug:

Description

When bhyve encounters a nested paging fault against an address backed by host physical memory (instead of an unbacked GPA, which would be handled as instruction-emulated MMIO), it exits guest context with VM_EXITCODE_PAGING. The kernel vmm attempts to process that exit in vm_handle_paging(), in case the nested-paging mechanism is required to fault in an entry for the page(s) in question. If that is not the case, it returns all the way to userspace with a rather opaque EFAULT. Until this logic can be improved to cover more cases (such as attempted writes to read-only memory, for example), we should at least pass the VM_EXITCODE_PAGING and its contextual information all the way out to userspace as a "normal" exit. This way it could at least report the condition and reboot the machine instead of aborting (as is the expectation in the face of an IO error).

Actions #1

Updated by Electric Monk 3 months ago

  • Gerrit CR set to 2346
Actions #2

Updated by Patrick Mooney 3 months ago

Ideally, our instruction emulation would be robust enough to handle this itself (eat the errant writes, or attempt full-on execution for accesses to NX GPAs), but in the mean time, this is better than tossing EFAULT.

Actions #3

Updated by Patrick Mooney 2 months ago

As this is a very minor change to behavior - the VM_EXITCODE_PAGING exit would previously be an EFAULT emitted to the consumer, resulting in a prompt instance halt - testing was somewhat limited.

Emission of the new exit was confirmed via a newly added unit test, with it (inst_emul/exit_paging) and all existing tests passing:

Test: /opt/bhyve-tests/tests/mevent/vnode_zvol (run as root)      [00:02] [PASS]
Test: /opt/bhyve-tests/tests/inst_emul/cpuid (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/inst_emul/rdmsr (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/inst_emul/wrmsr (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/inst_emul/triple_fault (run as root) [00:00] [PASS]
Test: /opt/bhyve-tests/tests/inst_emul/exit_paging (run as root)  [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vatpit_freq (run as root)       [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vhpet_freq (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vlapic_freq (run as root)       [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vlapic_freq_periodic (run as root) [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vlapic_mmio_access (run as root) [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vlapic_msr_access (run as root) [00:00] [PASS]
Test: /opt/bhyve-tests/tests/kdev/vpmtmr_freq (run as root)       [00:00] [PASS]
Test: /opt/bhyve-tests/tests/mevent/lists_delete (run as root)    [00:00] [PASS]
Test: /opt/bhyve-tests/tests/mevent/read_disable (run as root)    [00:00] [PASS]
Test: /opt/bhyve-tests/tests/mevent/read_pause (run as root)      [00:00] [PASS]
Test: /opt/bhyve-tests/tests/mevent/read_requeue (run as root)    [00:00] [PASS]
Test: /opt/bhyve-tests/tests/mevent/vnode_file (run as root)      [00:08] [PASS]
Test: /opt/bhyve-tests/tests/viona/interface_version (run as root) [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/auto_destruct (run as root)      [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/cpuid_ioctl (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/drv_hold (run as root)           [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/fpu_getset (run as root)         [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/interface_version (run as root)  [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/legacy_destruct (run as root)    [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/mem_devmem (run as root)         [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/mem_partial (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/mem_seg_map (run as root)        [00:00] [PASS]
Test: /opt/bhyve-tests/tests/vmm/self_destruct (run as root)      [00:00] [PASS]

Results Summary
PASS      29

Running Time:   00:00:14
Percent passed: 100.0%
Log directory:  /var/tmp/test_results/20220929T025633

As an extra smoke-test, a typical guest was booted up and observed to run with no issues.

Actions #4

Updated by Electric Monk 2 months ago

  • Status changed from In Progress to Closed
  • % Done changed from 0 to 100

git commit 3f6fd99d844f7d4b62e4e1ddb0c29a4c2f7eca15

commit  3f6fd99d844f7d4b62e4e1ddb0c29a4c2f7eca15
Author: Patrick Mooney <pmooney@pfmooney.com>
Date:   2022-10-02T01:02:06.000Z

    14952 bhyve should expose PAGING exits to userspace
    Reviewed by: Andy Fiddaman <illumos@fiddaman.net>
    Approved by: Gordon Ross <gordon.w.ross@gmail.com>

Actions

Also available in: Atom PDF