提交 c3a569db 编写于 作者: K Kemeng Shi 提交者: Zheng Zengkai

etmem_scan: x86: support scan 4 level ept under 5 level host page table

euleros inclusion
category: feature
feature: etmem
bugzilla: https://gitee.com/openeuler/kernel/issues/I4OODH?from=project-issue
CVE: NA

-------------------------------------------------

Before this patch, etmem_scan is failed if vm and host has different
page level. This patch supports scan 4 level ept while 5 level page
is enabled in host.
Signed-off-by: NKemeng Shi <shikemeng@huawei.com>
Reviewed-by: Nlouhongxiang <louhongxiang@huawei.com>
Reviewed-by: NChen Wandun <chenwandun@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f0f2e730
......@@ -454,14 +454,13 @@ static int ept_pud_range(struct page_idle_ctrl *pic,
}
static int ept_p4d_range(struct page_idle_ctrl *pic,
pgd_t *pgd, unsigned long addr, unsigned long end,
p4d_t *p4d, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
p4d_t *p4d;
unsigned long next;
int err = 0;
p4d = p4d_offset(pgd, addr);
p4d += p4d_index(addr);
do {
next = p4d_addr_end(addr, end);
if (!ept_p4d_present(*p4d)) {
......@@ -477,6 +476,33 @@ static int ept_p4d_range(struct page_idle_ctrl *pic,
return err;
}
static int ept_pgd_range(struct page_idle_ctrl *pic,
pgd_t *pgd,
unsigned long addr,
unsigned long end,
struct mm_walk *walk)
{
p4d_t *p4d;
unsigned long next;
int err = 0;
pgd = pgd_offset_pgd(pgd, addr);
do {
next = pgd_addr_end(addr, end);
if (!ept_pgd_present(*pgd)) {
set_restart_gpa(next, "PGD_HOLE");
continue;
}
p4d = (p4d_t *)pgd_page_vaddr(*pgd);
err = ept_p4d_range(pic, p4d, addr, next, walk);
if (err)
break;
} while (pgd++, addr = next, addr != end);
return err;
}
static int ept_page_range(struct page_idle_ctrl *pic,
unsigned long addr,
unsigned long end,
......@@ -484,9 +510,7 @@ static int ept_page_range(struct page_idle_ctrl *pic,
{
struct kvm_vcpu *vcpu;
struct kvm_mmu *mmu;
pgd_t *ept_root;
pgd_t *pgd;
unsigned long next;
uint64_t *ept_root;
int err = 0;
WARN_ON(addr >= end);
......@@ -509,18 +533,11 @@ static int ept_page_range(struct page_idle_ctrl *pic,
spin_unlock(&pic->kvm->mmu_lock);
local_irq_disable();
pgd = pgd_offset_pgd(ept_root, addr);
do {
next = pgd_addr_end(addr, end);
if (!ept_pgd_present(*pgd)) {
set_restart_gpa(next, "PGD_HOLE");
continue;
}
err = ept_p4d_range(pic, pgd, addr, next, walk);
if (err)
break;
} while (pgd++, addr = next, addr != end);
/* Walk start at p4d when vm has 4 level table pages */
if (mmu->shadow_root_level != 4)
err = ept_pgd_range(pic, (pgd_t *)ept_root, addr, end, walk);
else
err = ept_p4d_range(pic, (p4d_t *)ept_root, addr, end, walk);
local_irq_enable();
return err;
}
......@@ -540,7 +557,8 @@ static int ept_idle_supports_cpu(struct kvm *kvm)
if (kvm_mmu_ad_disabled(mmu)) {
printk(KERN_NOTICE "CPU does not support EPT A/D bits tracking\n");
ret = -EINVAL;
} else if (mmu->shadow_root_level != 4 + (!!pgtable_l5_enabled())) {
} else if (mmu->shadow_root_level < 4 ||
(mmu->shadow_root_level == 5 && !pgtable_l5_enabled())) {
printk(KERN_NOTICE "Unsupported EPT level %d\n", mmu->shadow_root_level);
ret = -EINVAL;
} else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册