Skip to content

Commit

Permalink
hv: ept: apply MCE on page size change mitigation conditionally
Browse files Browse the repository at this point in the history
Only apply the software workaround on the models that might be
affected by MCE on page size change. For these models that are
known immune to the issue, the mitigation is turned off.

Atom processors are not afftected by the issue.
Also check the CPUID & MSR to check whether the model is immune to the issue:
CPU is not vulnerable when both CPUID.(EAX=07H,ECX=0H).EDX[29] and
IA32_ARCH_CAPABILITIES[IF_PSCHANGE_MC_NO] are 1.

Other cases not listed above, CPU may be vulnerable.

Tracked-On: #4121
Signed-off-by: Binbin Wu <[email protected]>
Acked-by: Eddie Dong <[email protected]>
  • Loading branch information
binbinwu1 authored and wenlingz committed Nov 18, 2019
1 parent 3834f6a commit 241a811
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
19 changes: 13 additions & 6 deletions hypervisor/arch/x86/page.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <trusty.h>
#include <vtd.h>
#include <vm_configurations.h>
#include <security.h>

static struct page ppt_pml4_pages[PML4_PAGE_NUM(CONFIG_PLATFORM_RAM_SIZE + PLATFORM_LO_MMIO_SIZE)];
static struct page ppt_pdpt_pages[PDPT_PAGE_NUM(CONFIG_PLATFORM_RAM_SIZE + PLATFORM_LO_MMIO_SIZE)];
Expand Down Expand Up @@ -60,8 +61,8 @@ static inline struct page *ppt_get_pd_page(const union pgtable_pages_info *info,
return pd_page;
}

static inline void ppt_tweak_exe_right(uint64_t *entry __attribute__((unused))) {}
static inline void ppt_recover_exe_right(uint64_t *entry __attribute__((unused))) {}
static inline void nop_tweak_exe_right(uint64_t *entry __attribute__((unused))) {}
static inline void nop_recover_exe_right(uint64_t *entry __attribute__((unused))) {}

const struct memory_ops ppt_mem_ops = {
.info = &ppt_pages_info,
Expand All @@ -71,8 +72,8 @@ const struct memory_ops ppt_mem_ops = {
.get_pdpt_page = ppt_get_pdpt_page,
.get_pd_page = ppt_get_pd_page,
.clflush_pagewalk = ppt_clflush_pagewalk,
.tweak_exe_right = ppt_tweak_exe_right,
.recover_exe_right = ppt_recover_exe_right,
.tweak_exe_right = nop_tweak_exe_right,
.recover_exe_right = nop_recover_exe_right,
};

static struct page sos_vm_pml4_pages[PML4_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE))];
Expand Down Expand Up @@ -204,7 +205,13 @@ void init_ept_mem_ops(struct memory_ops *mem_ops, uint16_t vm_id)
mem_ops->get_pd_page = ept_get_pd_page;
mem_ops->get_pt_page = ept_get_pt_page;
mem_ops->clflush_pagewalk = ept_clflush_pagewalk;

/* Mitigation for issue "Machine Check Error on Page Size Change" */
mem_ops->tweak_exe_right = ept_tweak_exe_right;
mem_ops->recover_exe_right = ept_recover_exe_right;
if (is_ept_force_4k_ipage()) {
mem_ops->tweak_exe_right = ept_tweak_exe_right;
mem_ops->recover_exe_right = ept_recover_exe_right;
} else {
mem_ops->tweak_exe_right = nop_tweak_exe_right;
mem_ops->recover_exe_right = nop_recover_exe_right;
}
}
45 changes: 45 additions & 0 deletions hypervisor/arch/x86/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,48 @@ void set_fs_base(void)
msr_write(MSR_IA32_FS_BASE, (uint64_t)psc);
}
#endif

bool is_ept_force_4k_ipage(void)
{
bool force_4k_ipage = true;
const struct cpuinfo_x86 *info = get_pcpu_info();
uint64_t x86_arch_capabilities;

if (info->family == 0x6U) {
switch (info->model) {
case 0x26U:
case 0x27U:
case 0x35U:
case 0x36U:
case 0x37U:
case 0x86U:
case 0x1CU:
case 0x4AU:
case 0x4CU:
case 0x4DU:
case 0x5AU:
case 0x5CU:
case 0x5DU:
case 0x5FU:
case 0x6EU:
case 0x7AU:
/* Atom processor is not affected by the issue
* "Machine Check Error on Page Size Change"
*/
force_4k_ipage = false;
break;
default:
force_4k_ipage = true;
break;
}
}

if (pcpu_has_cap(X86_FEATURE_ARCH_CAP)) {
x86_arch_capabilities = msr_read(MSR_IA32_ARCH_CAPABILITIES);
if ((x86_arch_capabilities & IA32_ARCH_CAP_IF_PSCHANGE_MC_NO) != 0UL) {
force_4k_ipage = false;
}
}

return force_4k_ipage;
}
1 change: 1 addition & 0 deletions hypervisor/include/arch/x86/msr.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
#define IA32_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3U)
#define IA32_ARCH_CAP_SSB_NO (1U << 4U)
#define IA32_ARCH_CAP_MDS_NO (1U << 5U)
#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO (1U << 6U)

/* Flush L1 D-cache */
#define IA32_L1D_FLUSH (1UL << 0U)
Expand Down
1 change: 1 addition & 0 deletions hypervisor/include/arch/x86/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int32_t get_ibrs_type(void);
void cpu_l1d_flush(void);
bool check_cpu_security_cap(void);
void cpu_internal_buffers_clear(void);
bool is_ept_force_4k_ipage(void);

#ifdef STACK_PROTECTOR
struct stack_canary {
Expand Down

0 comments on commit 241a811

Please sign in to comment.