nvmm & kernel: Implement necessary functions/classes for AMD support.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user