Skip to content

Commit

Permalink
Cleanly hide DMAR from ACPI so that Linux does not I/O error when ls …
Browse files Browse the repository at this point in the history
…/sys/firmware/acpi/tables/
  • Loading branch information
lxylxy123456 committed Dec 21, 2022
1 parent 6b2c4d4 commit 93cbd69
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ u32 xmhf_baseplatform_arch_flat_readu32(u32 addr);
//read 64-bits from absolute physical address
u64 xmhf_baseplatform_arch_flat_readu64(u32 addr);

//write 8-bits to absolute physical address
void xmhf_baseplatform_arch_flat_writeu8(u32 addr, u8 val);

//write 32-bits to absolute physical address
void xmhf_baseplatform_arch_flat_writeu32(u32 addr, u32 val);

Expand Down
2 changes: 2 additions & 0 deletions xmhf/src/xmhf-core/include/xmhf-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ extern volatile u32 g_lock_appmain_success_counter __attribute__(( section(".dat
//exported FUNCTIONS
//----------------------------------------------------------------------

void vmx_dmar_zap(spa_t dmaraddrphys);

//entry point of EMHF runtime; this is where we get control from the SL
void xmhf_runtime_entry(void);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ u64 xmhf_baseplatform_arch_flat_readu64(u32 addr){
#endif /* !defined(__I386__) && !defined(__AMD64__) */
}

//write 32-bits to absolute physical address
void xmhf_baseplatform_arch_flat_writeu8(u32 addr, u8 val) {
#ifdef __AMD64__
*(u8*)(xmhf_baseplatform_arch_flat_pa2va(addr)) = val;
#elif defined(__I386__)
__asm__ __volatile__("movb %%al, %%fs:(%%ebx)\r\n"
:
: "b"(addr), "a"((u32)val)
);
#else /* !defined(__I386__) && !defined(__AMD64__) */
#error "Unsupported Arch"
#endif /* !defined(__I386__) && !defined(__AMD64__) */
}

//write 32-bits to absolute physical address
void xmhf_baseplatform_arch_flat_writeu32(u32 addr, u32 val) {
#ifdef __AMD64__
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ static u32 vmx_eap_initialize(
// zap VT-d presence in ACPI table...
// DRHD pages are protected from guest memory access in
// xmhf_dmaprot_arch_x86_vmx_protect_drhd().
xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys, 0UL);
vmx_dmar_zap(dmaraddrphys);

// Flush CPU cache
wbinvd();
Expand Down
38 changes: 35 additions & 3 deletions xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,40 @@
//---includes-------------------------------------------------------------------
#include <xmhf.h>

#if defined(__DRT__) || defined(__DMAP__)

/* Size of ACPI DESCRIPTION_HEADER Fields */
#define ACPI_DESC_HEADER_SIZE 36

/* Offset of interesting DESCRIPTION_HEADER fields */
#define ACPI_DESC_SIGNATURE_OFF 0
#define ACPI_DESC_LENGTH_OFF 4
#define ACPI_DESC_CHECKSUM_OFF 9

/*
* Given the address of ACPI DMAR table, change it to something else so that
* the red OS thinks there is no DMAR table present. Currently changing to a
* table with signature "XMHF".
*/
void vmx_dmar_zap(spa_t dmaraddrphys)
{
u8 buffer[ACPI_DESC_HEADER_SIZE];
u8 checksum = 0;
/* Signature: "XMHF" */
xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys + ACPI_DESC_SIGNATURE_OFF, 0x46484d58UL);
/* Length: 36 */
xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys + ACPI_DESC_LENGTH_OFF, 36UL);
/* Compute checksum */
xmhf_baseplatform_arch_flat_copy(buffer, (u8 *)dmaraddrphys, ACPI_DESC_HEADER_SIZE);
buffer[ACPI_DESC_CHECKSUM_OFF] = 0;
for (size_t i = 0; i < ACPI_DESC_HEADER_SIZE; i++) {
checksum -= buffer[i];
}
xmhf_baseplatform_arch_flat_writeu8(dmaraddrphys + ACPI_DESC_CHECKSUM_OFF, checksum);
}

#endif /* defined(__DRT__) || defined(__DMAP__) */

#if defined(__DRT__) && !defined(__DMAP__)

// This macro is defined in xmhf-dmaprot.h. However when !__DMAP__ this header
Expand All @@ -74,7 +108,6 @@ static void vmx_eap_zap(void)
memset(&rsdt, 0, sizeof(ACPI_RSDT));

// get ACPI RSDP
// [TODO] Unify the name of <xmhf_baseplatform_arch_x86_acpi_getRSDP> and <xmhf_baseplatform_arch_x86_acpi_getRSDP>, and then remove the following #ifdef
status = xmhf_baseplatform_arch_x86_acpi_getRSDP(&rsdp);
HALT_ON_ERRORCOND(status != 0); // we need a valid RSDP to proceed
printf("%s: RSDP at %08x\n", __FUNCTION__, status);
Expand Down Expand Up @@ -137,7 +170,7 @@ static void vmx_eap_zap(void)
// zap VT-d presence in ACPI table...
// TODO: we need to be a little elegant here. eventually need to setup
// EPT/NPTs such that the DMAR pages are unmapped for the guest
xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys, 0UL);
vmx_dmar_zap(dmaraddrphys);

// success
printf("%s: success, leaving...\n", __FUNCTION__);
Expand Down Expand Up @@ -193,7 +226,6 @@ void xmhf_runtime_entry(void){
#endif

#if defined (__DMAP__)
// TODO: DMAP code not ported to amd64 yet
{
#define ADDR_512GB (PAGE_SIZE_512G)
u64 protectedbuffer_paddr;
Expand Down

0 comments on commit 93cbd69

Please sign in to comment.