vmm_x86: guest code page in separate asm file

Implement the guest code in dedicated assembler source file, assemble
and link the binary to vmm_x86. The resulting guest-code binary
populates one page that is mapped to host the reset vector of the guest.

This approach simplifies future guest code adaption resp. extension,
e.g., to test rdmsr/wrmsr exiting.

Fixes #4638
This commit is contained in:
Christian Helmuth 2022-10-12 15:45:57 +02:00
parent 2edf02dccb
commit c086eb088d
4 changed files with 64 additions and 24 deletions

View File

@ -208,7 +208,7 @@ compare_output_to {
[init -> vmm] vcpu 0 : created
vcpu 0 : XX. vm exit - reason 0xfe handled by 'ep'
vcpu 0 : XX. vm exit - reason 0x78 handled by 'ep'
vcpu 0 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 0 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
}
puts $output_1
@ -217,19 +217,19 @@ compare_output_to {
[init -> vmm] vcpu 1 : created
vcpu 1 : XX. vm exit - reason 0xfe handled by 'ep'
vcpu 1 : XX. vm exit - reason 0x78 handled by 'ep'
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
vcpu 1 : XX. vm exit - reason 0xff handled by 'ep'
vcpu 1 : XX. vm exit - due to pause() request - ip=0xfff3
vcpu 1 : XX. vm exit - due to pause() request - ip=0xff81
vcpu 1 : XX. vm exit - reason 0x78 handled by 'ep'
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
vcpu 1 : XX. vm exit - reason 0xff handled by 'ep'
vcpu 1 : XX. vm exit - due to pause() request - ip=0xfff3
vcpu 1 : XX. vm exit - due to pause() request - ip=0xff81
vcpu 1 : XX. vm exit - reason 0xff handled by 'ep'
vcpu 1 : XX. vm exit - due to pause() request - ip=0xfff5
vcpu 1 : XX. vm exit - due to pause() request - ip=0xff83
vcpu 1 : XX. vm exit - reason 0x78 handled by 'ep'
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff7
vcpu 1 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff85
vcpu 1 : XX. vm exit - reason 0xff handled by 'ep'
vcpu 1 : XX. vm exit - due to pause() request - ip=0xfff7
vcpu 1 : XX. vm exit - due to pause() request - ip=0xff85
}
puts $output_2
@ -238,17 +238,17 @@ compare_output_to {
[init -> vmm] vcpu 2 : created
vcpu 2 : XX. vm exit - reason 0xfe handled by 'second ep'
vcpu 2 : XX. vm exit - reason 0x78 handled by 'second ep'
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
vcpu 2 : XX. vm exit - reason 0xff handled by 'second ep'
vcpu 2 : XX. vm exit - due to pause() request - ip=0xfff3
vcpu 2 : XX. vm exit - due to pause() request - ip=0xff81
vcpu 2 : XX. vm exit - reason 0x78 handled by 'second ep'
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
vcpu 2 : XX. vm exit - reason 0xff handled by 'second ep'
vcpu 2 : XX. vm exit - due to pause() request - ip=0xfff3
vcpu 2 : XX. vm exit - due to pause() request - ip=0xff81
vcpu 2 : XX. vm exit - reason 0x78 handled by 'second ep'
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff4
vcpu 2 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff82
vcpu 2 : XX. vm exit - reason 0xff handled by 'second ep'
vcpu 2 : XX. vm exit - due to pause() request - ip=0xfff4
vcpu 2 : XX. vm exit - due to pause() request - ip=0xff82
}
puts $output_3
@ -257,7 +257,7 @@ compare_output_to {
[init -> vmm] vcpu 3 : created
vcpu 3 : XX. vm exit - reason 0xfe handled by 'second ep'
vcpu 3 : XX. vm exit - reason 0x78 handled by 'second ep'
vcpu 3 : XX. vm exit - halting vCPU - guest called HLT - ip=0xfff3
vcpu 3 : XX. vm exit - halting vCPU - guest called HLT - ip=0xff81
}
set output $output_saved

View File

@ -216,6 +216,9 @@ class Vmm::Vcpu
};
extern char _binary_guest_bin_start[];
extern char _binary_guest_bin_end[];
class Vmm::Vm
{
private:
@ -295,17 +298,9 @@ class Vmm::Vm
/* prepare guest memory with some instructions for testing */
uint8_t * guest = env.rm().attach(_memory);
unsigned byte = 0xff0;
guest[byte++] = 0x0f; /* rdtscp */
guest[byte++] = 0x01;
guest[byte++] = 0xf9;
memcpy(guest, &_binary_guest_bin_start, 4096);
guest[byte++] = 0xf4; /* HLT instruction */
guest[byte++] = 0xf4; /* HLT instruction */
guest[byte++] = 0xeb; /* JMP - endless loop to RIP */
guest[byte++] = 0xfe; /* JMP of -2 byte (size of JMP inst) */
guest[byte++] = 0xf4; /* HLT instruction */
env.rm().detach(guest);
log ("let vCPUs run - first EP");

View File

@ -0,0 +1,35 @@
/*
* \brief VM session interface test for x86: guest code
* \author Alexander Boettcher
* \author Christian Helmuth
* \date 2018-09-26
*
* The guest code is placed on the page hosting the reset vector 0xffff:fff0.
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
.code16
/* offset code start to keep the jmp distance in imm8 */
.org 0xf7e, 0x90
1:
rdtscp
hlt
hlt
jmp .
hlt
jmp .
/* reset vector entry - just jmp to code start above */
.org 0xff0, 0x90
jmp 1b
/* fill page with hlt */
.org 0x1000, 0xf4

View File

@ -4,3 +4,13 @@ SRC_CC = component.cc
LIBS = base
CC_CXX_WARN_STRICT_CONVERSION =
SRC_BIN = guest.bin
guest.o: guest.s
$(MSG_ASSEM)$@
$(VERBOSE)$(CC) -m16 -c $< -o $@
guest.bin: guest.o
$(MSG_CONVERT)$@
$(VERBOSE)$(OBJCOPY) -O binary $< $@