From patchwork Fri Aug 25 11:57:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu Zhang X-Patchwork-Id: 9921921 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BED026022E for ; Fri, 25 Aug 2017 12:20:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF3442810E for ; Fri, 25 Aug 2017 12:20:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A450B28113; Fri, 25 Aug 2017 12:20:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 007D02810E for ; Fri, 25 Aug 2017 12:20:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754687AbdHYMUJ (ORCPT ); Fri, 25 Aug 2017 08:20:09 -0400 Received: from mga07.intel.com ([134.134.136.100]:60409 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754446AbdHYMUI (ORCPT ); Fri, 25 Aug 2017 08:20:08 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 25 Aug 2017 05:20:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,425,1498546800"; d="scan'208";a="1166075179" Received: from zhangyu-optiplex-9020.bj.intel.com ([10.238.135.159]) by orsmga001.jf.intel.com with ESMTP; 25 Aug 2017 05:20:06 -0700 From: Yu Zhang To: kvm@vger.kernel.org Cc: pbonzini@redhat.com Subject: [kvm-unit-tests] x86: access: Add test for 5 level paging mode Date: Fri, 25 Aug 2017 19:57:31 +0800 Message-Id: <1503662251-13895-1-git-send-email-yu.c.zhang@linux.intel.com> X-Mailer: git-send-email 1.9.1 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Provide paging mode switching logic to run access test in 5 level paging mode if LA57 is detected. Qemu parameter +la57 should be used to expose this feature, for example: ./x86-run ./x86/access.flat -cpu qemu64,+la57 Signed-off-by: Yu Zhang --- x86/access.c | 17 +++++++++++++++-- x86/cstart64.S | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/x86/access.c b/x86/access.c index 0546dbb..56d17a1 100644 --- a/x86/access.c +++ b/x86/access.c @@ -15,6 +15,7 @@ typedef unsigned long pt_element_t; static int cpuid_7_ebx; static int cpuid_7_ecx; static int invalid_mask; +static int page_table_levels; #define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK)) #define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) @@ -107,6 +108,8 @@ enum { #define AC_CPU_CR4_SMEP_MASK (1 << AC_CPU_CR4_SMEP_BIT) #define AC_CPU_CR4_PKE_MASK (1 << AC_CPU_CR4_PKE_BIT) +extern void setup_5level_page_table(); + const char *ac_names[] = { [AC_PTE_PRESENT_BIT] = "pte.p", [AC_PTE_ACCESSED_BIT] = "pte.a", @@ -467,11 +470,12 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, ac_test_reset_pt_pool(pool); at->ptep = 0; - for (int i = 4; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) { + for (int i = page_table_levels; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) { pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK); unsigned index = PT_INDEX((unsigned long)at->virt, i); pt_element_t pte = 0; switch (i) { + case 5: case 4: case 3: pte = pd_page ? pd_page : ac_test_alloc_pt(pool); @@ -552,7 +556,7 @@ static void dump_mapping(ac_test_t *at) int i; printf("Dump mapping: address: %p\n", at->virt); - for (i = 4; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) { + for (i = page_table_levels ; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) { pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK); unsigned index = PT_INDEX((unsigned long)at->virt, i); pt_element_t pte = vroot[index]; @@ -986,6 +990,15 @@ int main() cpuid_7_ecx = cpuid(7).c; printf("starting test\n\n"); + page_table_levels = 4; r = ac_test_run(); + + if (cpuid_7_ecx & (1 << 16)) { + page_table_levels = 5; + setup_5level_page_table(); + printf("starting 5-level paging test.\n\n"); + r = ac_test_run(); + } + return r ? 0 : 1; } diff --git a/x86/cstart64.S b/x86/cstart64.S index 4c26fb2..8e4a1f3 100644 --- a/x86/cstart64.S +++ b/x86/cstart64.S @@ -45,6 +45,10 @@ ptl4: .quad ptl3 + 7 .align 4096 +ptl5: + .quad ptl4 + 7 + +.align 4096 gdt64_desc: .word gdt64_end - gdt64 - 1 @@ -91,6 +95,8 @@ tss_end: mb_boot_info: .quad 0 +pt_root: .quad ptl4 + .section .init .code32 @@ -119,14 +125,36 @@ start: call prepare_64 jmpl $8, $start64 +switch_to_5level: + /* Disable CR4.PCIDE */ + mov %cr4, %eax + btr $17, %eax + mov %eax, %cr4 + + mov %cr0, %eax + btr $31, %eax + mov %eax, %cr0 + + mov $ptl5, %eax + mov %eax, pt_root + + /* Enable CR4.LA57 */ + mov %cr4, %eax + bts $12, %eax + mov %eax, %cr4 + + call enter_long_mode + jmpl $8, $lvl5 + prepare_64: lgdt gdt64_desc +enter_long_mode: mov %cr4, %eax bts $5, %eax // pae mov %eax, %cr4 - mov $ptl4, %eax + mov pt_root, %eax mov %eax, %cr3 efer = 0xc0000080 @@ -211,6 +239,19 @@ start64: mov %eax, %edi call exit +.globl setup_5level_page_table +setup_5level_page_table: + /* Check if 5-level paging has already enabled */ + mov %cr4, %rax + test $12, %eax + jnz lvl5 + + pushq $32 + pushq $switch_to_5level + lretq +lvl5: + retq + idt_descr: .word 16 * 256 - 1 .quad boot_idt