提交 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, ...@@ -454,14 +454,13 @@ static int ept_pud_range(struct page_idle_ctrl *pic,
} }
static int ept_p4d_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) struct mm_walk *walk)
{ {
p4d_t *p4d;
unsigned long next; unsigned long next;
int err = 0; int err = 0;
p4d = p4d_offset(pgd, addr); p4d += p4d_index(addr);
do { do {
next = p4d_addr_end(addr, end); next = p4d_addr_end(addr, end);
if (!ept_p4d_present(*p4d)) { if (!ept_p4d_present(*p4d)) {
...@@ -477,6 +476,33 @@ static int ept_p4d_range(struct page_idle_ctrl *pic, ...@@ -477,6 +476,33 @@ static int ept_p4d_range(struct page_idle_ctrl *pic,
return err; 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, static int ept_page_range(struct page_idle_ctrl *pic,
unsigned long addr, unsigned long addr,
unsigned long end, unsigned long end,
...@@ -484,9 +510,7 @@ static int ept_page_range(struct page_idle_ctrl *pic, ...@@ -484,9 +510,7 @@ static int ept_page_range(struct page_idle_ctrl *pic,
{ {
struct kvm_vcpu *vcpu; struct kvm_vcpu *vcpu;
struct kvm_mmu *mmu; struct kvm_mmu *mmu;
pgd_t *ept_root; uint64_t *ept_root;
pgd_t *pgd;
unsigned long next;
int err = 0; int err = 0;
WARN_ON(addr >= end); WARN_ON(addr >= end);
...@@ -509,18 +533,11 @@ static int ept_page_range(struct page_idle_ctrl *pic, ...@@ -509,18 +533,11 @@ static int ept_page_range(struct page_idle_ctrl *pic,
spin_unlock(&pic->kvm->mmu_lock); spin_unlock(&pic->kvm->mmu_lock);
local_irq_disable(); local_irq_disable();
pgd = pgd_offset_pgd(ept_root, addr); /* Walk start at p4d when vm has 4 level table pages */
do { if (mmu->shadow_root_level != 4)
next = pgd_addr_end(addr, end); err = ept_pgd_range(pic, (pgd_t *)ept_root, addr, end, walk);
if (!ept_pgd_present(*pgd)) { else
set_restart_gpa(next, "PGD_HOLE"); err = ept_p4d_range(pic, (p4d_t *)ept_root, addr, end, walk);
continue;
}
err = ept_p4d_range(pic, pgd, addr, next, walk);
if (err)
break;
} while (pgd++, addr = next, addr != end);
local_irq_enable(); local_irq_enable();
return err; return err;
} }
...@@ -540,7 +557,8 @@ static int ept_idle_supports_cpu(struct kvm *kvm) ...@@ -540,7 +557,8 @@ static int ept_idle_supports_cpu(struct kvm *kvm)
if (kvm_mmu_ad_disabled(mmu)) { if (kvm_mmu_ad_disabled(mmu)) {
printk(KERN_NOTICE "CPU does not support EPT A/D bits tracking\n"); printk(KERN_NOTICE "CPU does not support EPT A/D bits tracking\n");
ret = -EINVAL; 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); printk(KERN_NOTICE "Unsupported EPT level %d\n", mmu->shadow_root_level);
ret = -EINVAL; ret = -EINVAL;
} else } else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册