From patchwork Wed Mar 28 07:39:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 10312459 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 7C18B60467 for ; Wed, 28 Mar 2018 07:40:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6BB6B28A0F for ; Wed, 28 Mar 2018 07:40:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60BAE295E5; Wed, 28 Mar 2018 07:40:01 +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 5A49328A0F for ; Wed, 28 Mar 2018 07:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753483AbeC1Hjz (ORCPT ); Wed, 28 Mar 2018 03:39:55 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:53922 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753064AbeC1Hjy (ORCPT ); Wed, 28 Mar 2018 03:39:54 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BA2F48160F99; Wed, 28 Mar 2018 07:39:53 +0000 (UTC) Received: from thh440s.str.redhat.com (dhcp-192-189.str.redhat.com [10.33.192.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id DBC3910B2B38; Wed, 28 Mar 2018 07:39:52 +0000 (UTC) From: Thomas Huth To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Cc: kvm@vger.kernel.org, David Hildenbrand , Janosch Frank Subject: [kvm-unit-tests PULL 5/8] s390x: Add pfmf tests Date: Wed, 28 Mar 2018 09:39:41 +0200 Message-Id: <1522222784-7709-6-git-send-email-thuth@redhat.com> In-Reply-To: <1522222784-7709-1-git-send-email-thuth@redhat.com> References: <1522222784-7709-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 28 Mar 2018 07:39:53 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 28 Mar 2018 07:39:53 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Janosch Frank Perform Frame Management Functions (pfmf) is an instruction that sets storage keys or clears memory for frames in the size of 4k, 1m and 2g. Hence it's quite complex and deserves some testing. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth Signed-off-by: Thomas Huth --- s390x/Makefile | 1 + s390x/pfmf.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 ++ 3 files changed, 148 insertions(+) create mode 100644 s390x/pfmf.c diff --git a/s390x/Makefile b/s390x/Makefile index 1356246..074c32e 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -5,6 +5,7 @@ tests += $(TEST_DIR)/sieve.elf tests += $(TEST_DIR)/sthyi.elf tests += $(TEST_DIR)/skey.elf tests += $(TEST_DIR)/diag10.elf +tests += $(TEST_DIR)/pfmf.elf all: directories test_cases diff --git a/s390x/pfmf.c b/s390x/pfmf.c new file mode 100644 index 0000000..838f7bd --- /dev/null +++ b/s390x/pfmf.c @@ -0,0 +1,144 @@ +/* + * Perform Frame Management Function (pfmf) tests + * + * Copyright (c) 2018 IBM + * + * Authors: + * Janosch Frank + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License version 2. + */ +#include +#include +#include +#include +#include +#include + +#define FSC_4K 0 +#define FSC_1M 1 +#define FSC_2G 2 + +union r1 { + struct { + unsigned long pad0 : 32; + unsigned long pad1 : 12; + unsigned long pad_fmfi : 2; + unsigned long sk : 1; /* set key*/ + unsigned long cf : 1; /* clear frame */ + unsigned long ui : 1; /* usage indication */ + unsigned long fsc : 3; + unsigned long pad2 : 1; + unsigned long mr : 1; + unsigned long mc : 1; + unsigned long pad3 : 1; + unsigned long key : 8; /* storage keys */ + } reg; + unsigned long val; +}; + +static uint8_t pagebuf[PAGE_SIZE * 256] __attribute__((aligned(PAGE_SIZE * 256))); + +static inline unsigned long pfmf(unsigned long r1, unsigned long paddr) +{ + register uint64_t addr asm("1") = paddr; + + asm volatile(".insn rre,0xb9af0000,%[r1],%[addr]" + : [addr] "+a" (addr) : [r1] "d" (r1) : "memory"); + return addr; +} + +static void test_priv(void) +{ + expect_pgm_int(); + enter_pstate(); + pfmf(0, (unsigned long) pagebuf); + check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); +} + +static void test_4k_key(void) +{ + union r1 r1; + union skey skey; + + r1.val = 0; + r1.reg.sk = 1; + r1.reg.fsc = FSC_4K; + r1.reg.key = 0x30; + pfmf(r1.val, (unsigned long) pagebuf); + skey.val = get_storage_key((unsigned long) pagebuf); + report("set 4k", skey.val == 0x30); +} + +static void test_1m_key(void) +{ + int i; + union r1 r1; + + r1.val = 0; + r1.reg.sk = 1; + r1.reg.fsc = FSC_1M; + r1.reg.key = 0x30; + pfmf(r1.val, (unsigned long) pagebuf); + for (i = 0; i < 256; i++) { + if (get_storage_key((unsigned long) pagebuf + i * PAGE_SIZE) != 0x30) { + report("set 1M", false); + return; + } + } + report("set 1M", true); +} + +static void test_4k_clear(void) +{ + union r1 r1; + + r1.val = 0; + r1.reg.cf = 1; + r1.reg.fsc = FSC_4K; + + memset(pagebuf, 42, PAGE_SIZE); + pfmf(r1.val, (unsigned long) pagebuf); + report("clear 4k", !memcmp(pagebuf, pagebuf + PAGE_SIZE, PAGE_SIZE)); +} + +static void test_1m_clear(void) +{ + int i; + union r1 r1; + unsigned long sum = 0; + + r1.val = 0; + r1.reg.cf = 1; + r1.reg.fsc = FSC_1M; + + memset(pagebuf, 42, PAGE_SIZE * 256); + pfmf(r1.val, (unsigned long) pagebuf); + for (i = 0; i < PAGE_SIZE * 256; i++) + sum |= pagebuf[i]; + report("clear 1m", !sum); +} + +int main(void) +{ + bool has_edat = test_facility(8); + + report_prefix_push("pfmf"); + report_xfail("PFMF available", !has_edat, has_edat); + if (!has_edat) + goto done; + + test_priv(); + /* Force the buffer pages in */ + memset(pagebuf, 0, PAGE_SIZE * 256); + + test_4k_key(); + test_1m_key(); + test_4k_clear(); + test_1m_clear(); + +done: + report_prefix_pop(); + return report_summary(); +} diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg index d29d23e..a420457 100644 --- a/s390x/unittests.cfg +++ b/s390x/unittests.cfg @@ -43,3 +43,6 @@ file = skey.elf [diag10] file = diag10.elf + +[pfmf] +file = pfmf.elf