blob: 06272b3d5e20c109a566b820a0a66b0b659bbcab [file] [log] [blame] [edit]
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "constants_priv.h"
#define IA32_GS_BASE 0xc0000101
#define INTERRUPT_ADDR(base, x) (x - base + GUEST_IP)
#define CODE_64_SELECTOR 0x8
.text
.macro init_interrupt_handling start
lgdt INTERRUPT_ADDR(\start, gdtr_for_\start)
lidt INTERRUPT_ADDR(\start, idtr_for_\start)
mov $GUEST_IP + 0x1000, %rsp
jmp end_of_\start
int0_for_\start:
movq $0, (EXIT_TEST_ADDR)
.align 8
gdt_for_\start:
// Null entry.
.8byte 0
// CODE_64_SELECTOR
.2byte 0xffff // Limit 15:00
.2byte 0x0000 // Base 15:00
.byte 0x00 // Base 23:16
.byte 0b10011010 // P(1) DPL(00) S(1) 1 C(0) R(1) A(0)
.byte 0b10101111 // G(1) D(0) L(1) AVL(0) Limit 19:16
.byte 0x0 // Base 31:24
gdtr_for_\start:
.2byte gdtr_for_\start - gdt_for_\start - 1
.8byte INTERRUPT_ADDR(\start, gdt_for_\start)
.align 8
idt_for_\start:
.2byte INTERRUPT_ADDR(\start, int0_for_\start) // Offset 15:00
.2byte CODE_64_SELECTOR // Segment selector
.byte 0 // IST(000)
.byte 0b10001110 // P(1) DPL(00) 0 Type(1110)
.2byte 0 // Offset 31:16
.4byte 0 // Offset 63:32
.4byte 0 // Reserved
idtr_for_\start:
.2byte idtr_for_\start - idt_for_\start - 1 // Limit
.8byte INTERRUPT_ADDR(\start, idt_for_\start) // Address
end_of_\start:
.endm
// Test vcpu_resume.
FUNCTION(vcpu_resume_start)
// Test that we do not exit on load/store of CR3.
mov %cr3, %rax
mov %rax, %cr3
// Test that we do not exit on store of GS_BASE.
xor %eax, %eax
xor %edx, %edx
mov $IA32_GS_BASE, %ecx
wrmsr
// Test that we handle CPUID instruction correctly.
xor %eax, %eax
cpuid
movq $0, (EXIT_TEST_ADDR)
FUNCTION(vcpu_resume_end)
// Test vcpu_interrupt.
FUNCTION(vcpu_interrupt_start)
init_interrupt_handling vcpu_interrupt_start
sti
jmp .
FUNCTION(vcpu_interrupt_end)
// Test guest HLT instruction handling.
FUNCTION(vcpu_hlt_start)
init_interrupt_handling vcpu_hlt_start
sti
hlt
FUNCTION(vcpu_hlt_end)
// Test vcpu_read_state and vcpu_write_state.
FUNCTION(vcpu_read_write_state_start)
add $1, %rax
add $2, %rcx
add $3, %rdx
add $4, %rbx
add $5, %rsp
add $6, %rbp
add $7, %rsi
add $8, %rdi
add $9, %r8
add $10, %r9
add $11, %r10
add $12, %r11
add $13, %r12
add $14, %r13
add $15, %r14
add $16, %r15
stc // Set carry flag (bit 0)
stac // Set AC flag (bit 18)
movq $0, (EXIT_TEST_ADDR)
FUNCTION(vcpu_read_write_state_end)
// Test guest_set_trap using a memory-based trap.
FUNCTION(guest_set_trap_start)
movq $0, (TRAP_ADDR)
movq $0, (EXIT_TEST_ADDR)
FUNCTION(guest_set_trap_end)
// Test guest_set_trap using an IO-based trap.
FUNCTION(guest_set_trap_with_io_start)
out %al, $TRAP_PORT
movq $0, (EXIT_TEST_ADDR)
FUNCTION(guest_set_trap_with_io_end)