From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.6 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5152C433DB for ; Mon, 18 Jan 2021 18:31:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7CC4422CAD for ; Mon, 18 Jan 2021 18:31:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436865AbhARSab (ORCPT ); Mon, 18 Jan 2021 13:30:31 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20792 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436728AbhARS31 (ORCPT ); Mon, 18 Jan 2021 13:29:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1610994480; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RO9BQ4gIYT4Y+WIqNDUp5CVyTFzspTWs4LN/9aBCM0E=; b=dyq5yCcofq5W9j2wj+6fbxsfBAQ4T7ZqovhVJ7dvcrwkKZpV8S1oNmzSZsTuH0YCqqR8cg gjzS0Ru5kc3A87MH2pJWKWPuKT4UrBYyG7o/TkMWHHaXGGTJ6CkGHbk6wM02mt/kqF+hHR 4XWAoUR1OnI5TI9VUw5jN2TooAcRjQc= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-449-KTnox24DPBmHOVNgSe1uxQ-1; Mon, 18 Jan 2021 13:27:58 -0500 X-MC-Unique: KTnox24DPBmHOVNgSe1uxQ-1 Received: by mail-wr1-f69.google.com with SMTP id m20so8725925wrh.2 for ; Mon, 18 Jan 2021 10:27:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=RO9BQ4gIYT4Y+WIqNDUp5CVyTFzspTWs4LN/9aBCM0E=; b=C9v1LcTxEmrsDaMcnkndbfwlBR3NT/Q3Q8t9kH9ldSYS1hJarI9Jz3SPG8GFmuPqJk G5rgWjDaSPdMFlS3ihFzPlIQvI/uaNyka2/CB+I9Otut8stl3I2QmjCTgaqcLUKUsd8c qoE5CWgu1Uxk5N6kGa7dKQKKuIEQWbCHVVPN+CMX1poaX2qCE/f8EoDlQ4D0Vv2miWcR /8bnB6+6kw9XJun8nCoy9aE9MQE/KTq8OUgC/2gQO4R2LKCipo3yTV29hTw9IOdFNjVM kpgBdSgI/soev9EE4ie1FQha9GcnkQwPKwwYPcgk+G2IrVKO62SRFdjMWpjQXIxueBUU 5iJQ== X-Gm-Message-State: AOAM531WUdLNYnQQBeqAHGoPMoxYC0f5iB1IsS/kgAYV/tv2qDZFHzY3 Cmz9QAWT9FGvy7A91FbyScQiZ7CAJaaZnh0toy64rP+ej06oovrcStdr4E7uFOCvV/vc/4Tof2G TLxVXHMV5zCsMJNMipdaiIpn2Y51lA4pVtZbFgHv9gidX3sVxzpsN2Qk0PXE/vGtUc6sSqDSWtZ RS X-Received: by 2002:a1c:730f:: with SMTP id d15mr579285wmb.135.1610994476882; Mon, 18 Jan 2021 10:27:56 -0800 (PST) X-Google-Smtp-Source: ABdhPJy52T6muva6uT/9VQbA/e19xDfw5pSrtXU3K2BnaH0bn9AQwT88sgb/wNBjl14VGUD8FoztSg== X-Received: by 2002:a1c:730f:: with SMTP id d15mr579259wmb.135.1610994476605; Mon, 18 Jan 2021 10:27:56 -0800 (PST) Received: from ?IPv6:2001:b07:6468:f312:c8dd:75d4:99ab:290a? ([2001:b07:6468:f312:c8dd:75d4:99ab:290a]) by smtp.gmail.com with ESMTPSA id q6sm258757wmj.32.2021.01.18.10.27.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 18 Jan 2021 10:27:55 -0800 (PST) Subject: Re: [kvm-unit-tests PATCH] x86: Add tests for PKS To: Thomas Huth , Chenyi Qiang , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Xiaoyao Li Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org References: <20201105081805.5674-1-chenyi.qiang@intel.com> <20201105081805.5674-9-chenyi.qiang@intel.com> <6174185b-25e0-f2a2-3f71-d8bbe6ca889d@redhat.com> From: Paolo Bonzini Message-ID: <7aa67008-a72f-f6e3-2de4-4b9b9e62cd86@redhat.com> Date: Mon, 18 Jan 2021 19:27:54 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 MIME-Version: 1.0 In-Reply-To: <6174185b-25e0-f2a2-3f71-d8bbe6ca889d@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 18/01/21 18:45, Thomas Huth wrote: > On 05/11/2020 09.18, Chenyi Qiang wrote: >> This unit-test is intended to test the KVM support for Protection Keys >> for Supervisor Pages (PKS). If CR4.PKS is set in long mode, supervisor >> pkeys are checked in addition to normal paging protections and Access or >> Write can be disabled via a MSR update without TLB flushes when >> permissions change. >> >> Signed-off-by: Chenyi Qiang >> --- >>   lib/x86/msr.h       |   1 + >>   lib/x86/processor.h |   2 + >>   x86/Makefile.x86_64 |   1 + >>   x86/pks.c           | 146 ++++++++++++++++++++++++++++++++++++++++++++ >>   x86/unittests.cfg   |   5 ++ >>   5 files changed, 155 insertions(+) >>   create mode 100644 x86/pks.c >> >> diff --git a/lib/x86/msr.h b/lib/x86/msr.h >> index 6ef5502..e36934b 100644 >> --- a/lib/x86/msr.h >> +++ b/lib/x86/msr.h >> @@ -209,6 +209,7 @@ >>   #define MSR_IA32_EBL_CR_POWERON        0x0000002a >>   #define MSR_IA32_FEATURE_CONTROL        0x0000003a >>   #define MSR_IA32_TSC_ADJUST        0x0000003b >> +#define MSR_IA32_PKRS            0x000006e1 >>   #define FEATURE_CONTROL_LOCKED                (1<<0) >>   #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX    (1<<1) >> diff --git a/lib/x86/processor.h b/lib/x86/processor.h >> index 74a2498..985fdd0 100644 >> --- a/lib/x86/processor.h >> +++ b/lib/x86/processor.h >> @@ -50,6 +50,7 @@ >>   #define X86_CR4_SMEP   0x00100000 >>   #define X86_CR4_SMAP   0x00200000 >>   #define X86_CR4_PKE    0x00400000 >> +#define X86_CR4_PKS    0x01000000 >>   #define X86_EFLAGS_CF    0x00000001 >>   #define X86_EFLAGS_FIXED 0x00000002 >> @@ -157,6 +158,7 @@ static inline u8 cpuid_maxphyaddr(void) >>   #define    X86_FEATURE_RDPID        (CPUID(0x7, 0, ECX, 22)) >>   #define    X86_FEATURE_SPEC_CTRL        (CPUID(0x7, 0, EDX, 26)) >>   #define    X86_FEATURE_ARCH_CAPABILITIES    (CPUID(0x7, 0, EDX, 29)) >> +#define    X86_FEATURE_PKS            (CPUID(0x7, 0, ECX, 31)) >>   #define    X86_FEATURE_NX            (CPUID(0x80000001, 0, EDX, 20)) >>   #define    X86_FEATURE_RDPRU        (CPUID(0x80000008, 0, EBX, 4)) >> diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64 >> index af61d85..3a353df 100644 >> --- a/x86/Makefile.x86_64 >> +++ b/x86/Makefile.x86_64 >> @@ -20,6 +20,7 @@ tests += $(TEST_DIR)/tscdeadline_latency.flat >>   tests += $(TEST_DIR)/intel-iommu.flat >>   tests += $(TEST_DIR)/vmware_backdoors.flat >>   tests += $(TEST_DIR)/rdpru.flat >> +tests += $(TEST_DIR)/pks.flat >>   include $(SRCDIR)/$(TEST_DIR)/Makefile.common >> diff --git a/x86/pks.c b/x86/pks.c >> new file mode 100644 >> index 0000000..a3044cf >> --- /dev/null >> +++ b/x86/pks.c >> @@ -0,0 +1,146 @@ >> +#include "libcflat.h" >> +#include "x86/desc.h" >> +#include "x86/processor.h" >> +#include "x86/vm.h" >> +#include "x86/msr.h" >> + >> +#define CR0_WP_MASK      (1UL << 16) >> +#define PTE_PKEY_BIT     59 >> +#define SUPER_BASE        (1 << 24) >> +#define SUPER_VAR(v)      (*((__typeof__(&(v))) (((unsigned long)&v) >> + SUPER_BASE))) >> + >> +volatile int pf_count = 0; >> +volatile unsigned save; >> +volatile unsigned test; >> + >> +static void set_cr0_wp(int wp) >> +{ >> +    unsigned long cr0 = read_cr0(); >> + >> +    cr0 &= ~CR0_WP_MASK; >> +    if (wp) >> +        cr0 |= CR0_WP_MASK; >> +    write_cr0(cr0); >> +} >> + >> +void do_pf_tss(unsigned long error_code); >> +void do_pf_tss(unsigned long error_code) >> +{ >> +    printf("#PF handler, error code: 0x%lx\n", error_code); >> +    pf_count++; >> +    save = test; >> +    wrmsr(MSR_IA32_PKRS, 0); >> +} >> + >> +extern void pf_tss(void); >> + >> +asm ("pf_tss: \n\t" >> +#ifdef __x86_64__ >> +    // no task on x86_64, save/restore caller-save regs >> +    "push %rax; push %rcx; push %rdx; push %rsi; push %rdi\n" >> +    "push %r8; push %r9; push %r10; push %r11\n" >> +    "mov 9*8(%rsp), %rdi\n" >> +#endif >> +    "call do_pf_tss \n\t" >> +#ifdef __x86_64__ >> +    "pop %r11; pop %r10; pop %r9; pop %r8\n" >> +    "pop %rdi; pop %rsi; pop %rdx; pop %rcx; pop %rax\n" >> +#endif >> +    "add $"S", %"R "sp\n\t" // discard error code >> +    "iret"W" \n\t" >> +    "jmp pf_tss\n\t" >> +    ); >> + >> +static void init_test(void) >> +{ >> +    pf_count = 0; >> + >> +    invlpg(&test); >> +    invlpg(&SUPER_VAR(test)); >> +    wrmsr(MSR_IA32_PKRS, 0); >> +    set_cr0_wp(0); >> +} >> + >> +int main(int ac, char **av) >> +{ >> +    unsigned long i; >> +    unsigned int pkey = 0x2; >> +    unsigned int pkrs_ad = 0x10; >> +    unsigned int pkrs_wd = 0x20; >> + >> +    if (!this_cpu_has(X86_FEATURE_PKS)) { >> +        printf("PKS not enabled\n"); >> +        return report_summary(); >> +    } >> + >> +    setup_vm(); >> +    setup_alt_stack(); >> +    set_intr_alt_stack(14, pf_tss); >> +    wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_LMA); >> + >> +    // First 16MB are user pages >> +    for (i = 0; i < SUPER_BASE; i += PAGE_SIZE) { >> +        *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) |= >> ((unsigned long)pkey << PTE_PKEY_BIT); >> +        invlpg((void *)i); >> +    } >> + >> +    // Present the same 16MB as supervisor pages in the 16MB-32MB range >> +    for (i = SUPER_BASE; i < 2 * SUPER_BASE; i += PAGE_SIZE) { >> +        *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= >> ~SUPER_BASE; >> +        *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= >> ~PT_USER_MASK; >> +        *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) |= >> ((unsigned long)pkey << PTE_PKEY_BIT); >> +        invlpg((void *)i); >> +    } >> + >> +    write_cr4(read_cr4() | X86_CR4_PKS); >> +    write_cr3(read_cr3()); >> + >> +    init_test(); >> +    set_cr0_wp(1); >> +    wrmsr(MSR_IA32_PKRS, pkrs_ad); >> +    SUPER_VAR(test) = 21; >> +    report(pf_count == 1 && test == 21 && save == 0, >> +           "write to supervisor page when pkrs is ad and wp == 1"); >> + >> +    init_test(); >> +    set_cr0_wp(0); >> +    wrmsr(MSR_IA32_PKRS, pkrs_ad); >> +    SUPER_VAR(test) = 22; >> +    report(pf_count == 1 && test == 22 && save == 21, >> +           "write to supervisor page when pkrs is ad and wp == 0"); >> + >> +    init_test(); >> +    set_cr0_wp(1); >> +    wrmsr(MSR_IA32_PKRS, pkrs_wd); >> +    SUPER_VAR(test) = 23; >> +    report(pf_count == 1 && test == 23 && save == 22, >> +           "write to supervisor page when pkrs is wd and wp == 1"); >> + >> +    init_test(); >> +    set_cr0_wp(0); >> +    wrmsr(MSR_IA32_PKRS, pkrs_wd); >> +    SUPER_VAR(test) = 24; >> +    report(pf_count == 0 && test == 24, >> +           "write to supervisor page when pkrs is wd and wp == 0"); >> + >> +    init_test(); >> +    set_cr0_wp(0); >> +    wrmsr(MSR_IA32_PKRS, pkrs_wd); >> +    test = 25; >> +    report(pf_count == 0 && test == 25, >> +           "write to user page when pkrs is wd and wp == 0"); >> + >> +    init_test(); >> +    set_cr0_wp(1); >> +    wrmsr(MSR_IA32_PKRS, pkrs_wd); >> +    test = 26; >> +    report(pf_count == 0 && test == 26, >> +           "write to user page when pkrs is wd and wp == 1"); >> + >> +    init_test(); >> +    wrmsr(MSR_IA32_PKRS, pkrs_ad); >> +    (void)((__typeof__(&(test))) (((unsigned long)&test))); >> +    report(pf_count == 0, "read from user page when pkrs is ad"); >> + >> +    return report_summary(); >> +} >> diff --git a/x86/unittests.cfg b/x86/unittests.cfg >> index 3a79151..b75419e 100644 >> --- a/x86/unittests.cfg >> +++ b/x86/unittests.cfg >> @@ -127,6 +127,11 @@ file = pku.flat >>   arch = x86_64 >>   extra_params = -cpu host >> +[pks] >> +file = pks.flat >> +arch = x86_64 >> +extra_params = -cpu host >> + >>   [asyncpf] >>   file = asyncpf.flat >>   extra_params = -m 2048 >> > > Ping? ... Paolo, I think this one fell through the cracks? > >  Thomas > No, it's just that the KVM patches haven't been merged yet (and there's no QEMU implementation yet). But I'm getting to it. Paolo