nvmm & kernel: Implement necessary functions/classes for AMD support.

This commit is contained in:
Augustin Cavalier
2026-06-03 23:04:56 -04:00
parent 099de13932
commit be817ba080
7 changed files with 141 additions and 28 deletions
+1
View File
@@ -21,6 +21,7 @@ KernelAddon nvmm :
nvmm_x86_vmx.c nvmm_x86_vmx.c
nvmm_x86_vmxfunc.S nvmm_x86_vmxfunc.S
nvmm_x86_svm.c nvmm_x86_svm.c
nvmm_x86_svmfunc.S
nvmm_haiku.cpp nvmm_haiku.cpp
VMVirtualAddressSpace.cpp VMVirtualAddressSpace.cpp
+14 -3
View File
@@ -32,6 +32,7 @@ extern "C" {
#include "VMVirtualAddressSpace.h" #include "VMVirtualAddressSpace.h"
#include <paging/nested/X86VMTranslationMapEPT.h> #include <paging/nested/X86VMTranslationMapEPT.h>
#include <paging/nested/X86VMTranslationMapRVI.h>
extern "C" void extern "C" void
@@ -281,9 +282,19 @@ os_vmspace_create(vaddr_t vmin, vaddr_t vmax)
os_vmspace_t *ret = (os_vmspace_t *)os_mem_alloc(sizeof(os_vmspace_t)); os_vmspace_t *ret = (os_vmspace_t *)os_mem_alloc(sizeof(os_vmspace_t));
if (ret == NULL) if (ret == NULL)
return NULL; return NULL;
X86VMTranslationMapEPT *translationMap = new(std::nothrow) X86VMTranslationMapEPT; X86VMTranslationMap *translationMap = NULL;
status_t status = translationMap->Init(); status_t status = B_ERROR;
if (nvmm_impl == &nvmm_x86_vmx) {
X86VMTranslationMapEPT *map = new(std::nothrow) X86VMTranslationMapEPT;
status = map->Init();
translationMap = map;
} else if (nvmm_impl == &nvmm_x86_svm) {
X86VMTranslationMapRVI *map = new(std::nothrow) X86VMTranslationMapRVI;
status = map->Init();
translationMap = map;
}
if (status != B_OK) { if (status != B_OK) {
delete translationMap; delete translationMap;
os_mem_free(ret, sizeof(os_vmspace_t)); os_mem_free(ret, sizeof(os_vmspace_t));
@@ -39,8 +39,11 @@
#include "../nvmm_internal.h" #include "../nvmm_internal.h"
#include "nvmm_x86.h" #include "nvmm_x86.h"
#if 0 #ifdef __HAIKU__
void svm_vmrun(paddr_t, uint64_t *, uint64_t *);
#else
void svm_vmrun(paddr_t, uint64_t *); void svm_vmrun(paddr_t, uint64_t *);
#endif
static inline void static inline void
svm_clgi(void) svm_clgi(void)
@@ -53,7 +56,6 @@ svm_stgi(void)
{ {
__asm volatile ("stgi" ::: "memory"); __asm volatile ("stgi" ::: "memory");
} }
#endif
#define MSR_VM_HSAVE_PA 0xC0010117 #define MSR_VM_HSAVE_PA 0xC0010117
@@ -343,6 +345,10 @@ struct vmcb_ctrl {
uint64_t exitcode; uint64_t exitcode;
uint64_t exitinfo1; uint64_t exitinfo1;
uint64_t exitinfo2; uint64_t exitinfo2;
#ifdef __HAIKU__
#define PGEX_W 0x02 /* during a Write cycle */
#define PGEX_I 0x10 /* during an instruction fetch */
#endif
uint64_t exitintinfo; uint64_t exitintinfo;
#define VMCB_CTRL_EXITINTINFO_VECTOR __BITS(7,0) #define VMCB_CTRL_EXITINTINFO_VECTOR __BITS(7,0)
@@ -542,7 +548,6 @@ static uint64_t svm_xcr0_mask __read_mostly;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
struct svm_machdata { struct svm_machdata {
volatile uint64_t mach_htlb_gen; volatile uint64_t mach_htlb_gen;
}; };
@@ -833,13 +838,11 @@ svm_inkernel_advance(struct vmcb *vmcb)
vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW; vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
} }
#endif
#define SVM_CPUID_MAX_BASIC 0xD #define SVM_CPUID_MAX_BASIC 0xD
#define SVM_CPUID_MAX_HYPERVISOR 0x40000000 #define SVM_CPUID_MAX_HYPERVISOR 0x40000000
#define SVM_CPUID_MAX_EXTENDED 0x8000001F #define SVM_CPUID_MAX_EXTENDED 0x8000001F
static uint32_t svm_cpuid_max_basic __read_mostly; static uint32_t svm_cpuid_max_basic __read_mostly;
static uint32_t svm_cpuid_max_extended __read_mostly; static uint32_t svm_cpuid_max_extended __read_mostly;
#if 0
static void static void
svm_inkernel_exec_cpuid(struct svm_cpudata *cpudata, uint32_t eax, uint32_t ecx) svm_inkernel_exec_cpuid(struct svm_cpudata *cpudata, uint32_t eax, uint32_t ecx)
@@ -1377,10 +1380,8 @@ svm_exit_invalid(struct nvmm_vcpu_exit *exit, uint64_t code)
exit->reason = NVMM_VCPU_EXIT_INVALID; exit->reason = NVMM_VCPU_EXIT_INVALID;
} }
#endif // 0
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
static void static void
svm_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu) svm_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
{ {
@@ -1472,11 +1473,9 @@ svm_vcpu_guest_misc_leave(struct nvmm_cpu *vcpu)
wrmsr(MSR_FSBASE, cpudata->hstate.fsbase); wrmsr(MSR_FSBASE, cpudata->hstate.fsbase);
wrmsr(MSR_KERNELGSBASE, cpudata->hstate.kernelgsbase); wrmsr(MSR_KERNELGSBASE, cpudata->hstate.kernelgsbase);
} }
#endif
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
static inline void static inline void
svm_gtlb_catchup(struct nvmm_cpu *vcpu, int hcpu) svm_gtlb_catchup(struct nvmm_cpu *vcpu, int hcpu)
{ {
@@ -1637,7 +1636,7 @@ svm_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
} }
#endif #endif
svm_vmrun(cpudata->vmcb_pa, cpudata->gprs); svm_vmrun(cpudata->vmcb_pa, cpudata->gprs, os_curcpu_gdt());
svm_htlb_flush_ack(cpudata, machgen); svm_htlb_flush_ack(cpudata, machgen);
svm_vcpu_guest_fpu_leave(vcpu); svm_vcpu_guest_fpu_leave(vcpu);
svm_stgi(); svm_stgi();
@@ -1741,11 +1740,9 @@ svm_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
return error; return error;
} }
#endif
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
#define SVM_MSRBM_READ __BIT(0) #define SVM_MSRBM_READ __BIT(0)
#define SVM_MSRBM_WRITE __BIT(1) #define SVM_MSRBM_WRITE __BIT(1)
@@ -2121,11 +2118,9 @@ svm_vcpu_state_commit(struct nvmm_cpu *vcpu)
vcpu->comm->state_commit = 0; vcpu->comm->state_commit = 0;
svm_vcpu_setstate(vcpu); svm_vcpu_setstate(vcpu);
} }
#endif // 0
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
static void static void
svm_asid_alloc(struct nvmm_cpu *vcpu) svm_asid_alloc(struct nvmm_cpu *vcpu)
{ {
@@ -2373,11 +2368,9 @@ svm_vcpu_destroy(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
os_pagemem_free(cpudata, sizeof(*cpudata)); os_pagemem_free(cpudata, sizeof(*cpudata));
} }
#endif
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
static int static int
svm_vcpu_configure_cpuid(struct svm_cpudata *cpudata, void *data) svm_vcpu_configure_cpuid(struct svm_cpudata *cpudata, void *data)
{ {
@@ -2445,11 +2438,9 @@ svm_vcpu_configure(struct nvmm_cpu *vcpu, uint64_t op, void *data)
return EINVAL; return EINVAL;
} }
} }
#endif
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#if 0
#ifdef __NetBSD__ #ifdef __NetBSD__
static void static void
svm_tlb_flush(struct pmap *pm) svm_tlb_flush(struct pmap *pm)
@@ -2500,7 +2491,6 @@ svm_machine_configure(struct nvmm_machine *mach, uint64_t op, void *data)
{ {
panic("%s: impossible", __func__); panic("%s: impossible", __func__);
} }
#endif // 0
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@@ -2728,7 +2718,7 @@ const struct nvmm_impl nvmm_x86_svm = {
.ident = svm_ident, .ident = svm_ident,
.init = svm_init, .init = svm_init,
.fini = svm_fini, .fini = svm_fini,
.capability = svm_capability/*, .capability = svm_capability,
.mach_conf_max = NVMM_X86_MACH_NCONF, .mach_conf_max = NVMM_X86_MACH_NCONF,
.mach_conf_sizes = NULL, .mach_conf_sizes = NULL,
.vcpu_conf_max = NVMM_X86_VCPU_NCONF, .vcpu_conf_max = NVMM_X86_VCPU_NCONF,
@@ -2743,5 +2733,5 @@ const struct nvmm_impl nvmm_x86_svm = {
.vcpu_setstate = svm_vcpu_setstate, .vcpu_setstate = svm_vcpu_setstate,
.vcpu_getstate = svm_vcpu_getstate, .vcpu_getstate = svm_vcpu_getstate,
.vcpu_inject = svm_vcpu_inject, .vcpu_inject = svm_vcpu_inject,
.vcpu_run = svm_vcpu_run*/ .vcpu_run = svm_vcpu_run
}; };
@@ -34,12 +34,15 @@
#define _LOCORE #define _LOCORE
#include "assym.h" #include "assym.h"
#include <machine/asm.h> #include <machine/asm.h>
#include <machine/segments.h>
#elif defined(__DragonFly__) #elif defined(__DragonFly__)
#include <machine/asmacros.h> #include <machine/asmacros.h>
#include "assym.s"
#endif
#include <machine/segments.h> #include <machine/segments.h>
#include "assym.s"
#elif defined(__HAIKU__)
#define _C_LABEL(x) x
#include <machine/asmacros.h>
#endif
#define ASM_NVMM #define ASM_NVMM
#include "nvmm_x86.h" #include "nvmm_x86.h"
@@ -76,7 +79,8 @@
#define HOST_SAVE_TR \ #define HOST_SAVE_TR \
strw %ax ;\ strw %ax ;\
pushq %rax pushq %rdx ;/*Haiku*/\
pushq %rax ;\
#if defined(__NetBSD__) #if defined(__NetBSD__)
#define HOST_RESTORE_TR \ #define HOST_RESTORE_TR \
@@ -97,6 +101,14 @@
/* Clear the busy bit for reloading. */ \ /* Clear the busy bit for reloading. */ \
andq $~0x0200,4(%rax) ;\ andq $~0x0200,4(%rax) ;\
ltrw %dx ltrw %dx
#elif defined(__HAIKU__)
#define HOST_RESTORE_TR \
popq %rax ;\
movzwq %ax,%rdx ;\
popq %rax ;\
/* Clear the busy bit for reloading. */ \
andq $~0x0200,4(%rax,%rdx, 1) ;\
ltrw %dx
#endif #endif
#define HOST_SAVE_LDT \ #define HOST_SAVE_LDT \
@@ -146,6 +158,7 @@
/* /*
* %rdi = PA of VMCB * %rdi = PA of VMCB
* %rsi = VA of guest GPR state * %rsi = VA of guest GPR state
* %rdx = VA of GDT entry
*/ */
ENTRY(svm_vmrun) ENTRY(svm_vmrun)
/* Save the Host GPRs. */ /* Save the Host GPRs. */
+1
View File
@@ -45,6 +45,7 @@ if $(TARGET_ARCH) = x86_64 {
# paging/nested # paging/nested
X86PagingMethodEPT.cpp X86PagingMethodEPT.cpp
X86VMTranslationMapEPT.cpp X86VMTranslationMapEPT.cpp
X86VMTranslationMapRVI.cpp
; ;
} else { } else {
SEARCH_SOURCE += [ FDirName $(SUBDIR) 32 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) 32 ] ;
@@ -0,0 +1,69 @@
/*
* Copyright 2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "paging/nested/X86VMTranslationMapRVI.h"
#include "paging/64bit/X86PagingStructures64Bit.h"
//#define TRACE_X86_VM_TRANSLATION_MAP_RVI
#ifdef TRACE_X86_VM_TRANSLATION_MAP_RVI
# define TRACE(x...) dprintf(x)
#else
# define TRACE(x...) ;
#endif
// #pragma mark - X86VMTranslationMapRVI
X86VMTranslationMapRVI::X86VMTranslationMapRVI()
:
X86VMTranslationMap64Bit(false)
{
}
X86VMTranslationMapRVI::~X86VMTranslationMapRVI()
{
}
status_t
X86VMTranslationMapRVI::Init()
{
TRACE("X86VMTranslationMapRVI::Init()\n");
status_t status = X86VMTranslationMap64Bit::Init(false);
if (status != B_OK)
return status;
// Clear the PMLTop, as we don't want the kernel mappings in there.
memset(PagingStructures64Bit()->VirtualPMLTop(), 0, B_PAGE_SIZE);
return B_OK;
}
status_t
X86VMTranslationMapRVI::Map(addr_t virtualAddress, phys_addr_t physicalAddress,
uint32 attributes, uint32 memoryType, vm_page_reservation* reservation)
{
// Always specify B_EXECUTE_AREA, so that the NX flag isn't set.
attributes |= B_EXECUTE_AREA;
return X86VMTranslationMap64Bit::Map(virtualAddress, physicalAddress,
attributes, memoryType, reservation);
}
status_t
X86VMTranslationMapRVI::Protect(addr_t start, addr_t end, uint32 attributes,
uint32 memoryType)
{
ASSERT_UNREACHABLE();
return B_ERROR;
}
@@ -0,0 +1,28 @@
/*
* Copyright 2026, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_ARCH_X86_PAGING_NESTED_X86_VM_TRANSLATION_MAP_RVI_H
#define KERNEL_ARCH_X86_PAGING_NESTED_X86_VM_TRANSLATION_MAP_RVI_H
#include "paging/64bit/X86VMTranslationMap64Bit.h"
struct X86VMTranslationMapRVI final : X86VMTranslationMap64Bit {
X86VMTranslationMapRVI();
virtual ~X86VMTranslationMapRVI();
status_t Init();
virtual status_t Map(addr_t virtualAddress,
phys_addr_t physicalAddress,
uint32 attributes, uint32 memoryType,
vm_page_reservation* reservation) override;
virtual status_t Protect(addr_t base, addr_t top,
uint32 attributes, uint32 memoryType) override;
};
#endif // KERNEL_ARCH_X86_PAGING_NESTED_X86_VM_TRANSLATION_MAP_RVI_H