From patchwork Fri Aug 5 07:33:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suraj Jitindar Singh X-Patchwork-Id: 9264857 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 7377D6048B for ; Fri, 5 Aug 2016 07:33:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 694D32842D for ; Fri, 5 Aug 2016 07:33:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5DD5F2842F; Fri, 5 Aug 2016 07:33:44 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 CB57D2842D for ; Fri, 5 Aug 2016 07:33:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756511AbcHEHdk (ORCPT ); Fri, 5 Aug 2016 03:33:40 -0400 Received: from mail-pa0-f66.google.com ([209.85.220.66]:35792 "EHLO mail-pa0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758169AbcHEHdi (ORCPT ); Fri, 5 Aug 2016 03:33:38 -0400 Received: by mail-pa0-f66.google.com with SMTP id cf3so18820687pad.2 for ; Fri, 05 Aug 2016 00:33:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LBlXsVs8O2DuJDkgwIB5NY62kNFRZs+5KHskO93pu2o=; b=n78Hf4S+ymeU8YEkOETO0EtC2NmxAajia9aeDrd/etr22w+PXbs9qFEBs3fbAmfZqK 9fjEetndYAFK+Vq4MqtCV7MTar2DyV6n+HPfTfrHHsI7GZGCDweWrGoF9iMU1gGhej0V u9Ly8wsZLn86b7zlNvMlxcetXFEN/85VdISnF7c3DYMQNy5E6zwzmVfB8VcB7AYM9Q7/ 10x6t1ydWJzTb8vyfLqD6QpjXXpyRihh8OzNPMLrsy1/qXYVrDM/O8FtWTzLlEtBI13Q 0s1aNDcVtQAxzLB5cxnw7LYxfbaGuSBcuoE+zc/+yEBI6DthqJCOQ0B5QoLwoVCC9566 Vc6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LBlXsVs8O2DuJDkgwIB5NY62kNFRZs+5KHskO93pu2o=; b=MwEql6V1DqT8HuzJOMuM3884K4b054OjRaaRgXxr+FXlUNTw6mc8LWSylXOVtGKD3f oVHORBXcxffIszyBWXzxOcDgOZ4R0joFBE8ixLaFhUVa7wowS7Fkbt0bz5opvSJM1y1J jLxXj6y08F4Mq6RWAfFKaW44y4yyKDRSOeQmdLDRAX+ad6mZv65qA3AubslvCamKfatp BdYtv6Wgo2gl4x1pr4RSNYWlFABNUbmJVCmtLI8EFbbWfvyoeAT9ngUlrC/tSmz70ocu FzV8Q+zkVOJXv+6H64JT6xjtYrxH7OpJURfTuWmEZM+7Ff0MRJwnZLUMPnR8SeHqkGJq ZiBQ== X-Gm-Message-State: AEkooutSgOi0hFWQo+CAiL/2PXrU4Ina9yv/hu4n8mLkRGO2c1nhHmXoXSgqcaaH3XLyDw== X-Received: by 10.66.21.137 with SMTP id v9mr53028909pae.58.1470382417563; Fri, 05 Aug 2016 00:33:37 -0700 (PDT) Received: from dyn253.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id y2sm25383787pan.31.2016.08.05.00.33.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Aug 2016 00:33:37 -0700 (PDT) From: Suraj Jitindar Singh To: kvm@vger.kernel.org Cc: sjitindarsingh@gmail.com, drjones@redhat.com, pbonzini@redhat.com Subject: [kvm-unit-tests PATCH 4/4] powerpc/tm: Add a test for H_CEDE while tm suspended Date: Fri, 5 Aug 2016 17:33:13 +1000 Message-Id: <1470382393-24209-4-git-send-email-sjitindarsingh@gmail.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1470382393-24209-1-git-send-email-sjitindarsingh@gmail.com> References: <1470382393-24209-1-git-send-email-sjitindarsingh@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Power machines if a guest cedes while a tm transaction is in the suspended state then the checkpointed state of the vcpu may be lost and we lose the cpu in the host. Add a file for tm tests "powerpc/tm.c" and add a test to check if the fix has been applied to the host kernel. If this fix hasn't been applied then the test will never complete and the cpu will be lost. Otherwise the test should succeed. Since this has the ability to mess things up in the host mark this test as don't run by default. Based on initial work done by: Cyril Bur Signed-off-by: Suraj Jitindar Singh --- lib/powerpc/asm/hcall.h | 1 + powerpc/Makefile.common | 3 +- powerpc/tm.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ powerpc/unittests.cfg | 6 ++ 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 powerpc/tm.c diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h index 99bce79..80aa3e3 100644 --- a/lib/powerpc/asm/hcall.h +++ b/lib/powerpc/asm/hcall.h @@ -18,6 +18,7 @@ #define H_SET_SPRG0 0x24 #define H_SET_DABR 0x28 #define H_PAGE_INIT 0x2c +#define H_CEDE 0xE0 #define H_PUT_TERM_CHAR 0x58 #define H_RANDOM 0x300 #define H_SET_MODE 0x31C diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index 677030a..93e4f66 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -8,7 +8,8 @@ tests-common = \ $(TEST_DIR)/selftest.elf \ $(TEST_DIR)/spapr_hcall.elf \ $(TEST_DIR)/rtas.elf \ - $(TEST_DIR)/emulator.elf + $(TEST_DIR)/emulator.elf \ + $(TEST_DIR)/tm.elf all: $(TEST_DIR)/boot_rom.bin test_cases diff --git a/powerpc/tm.c b/powerpc/tm.c new file mode 100644 index 0000000..64d2ddf --- /dev/null +++ b/powerpc/tm.c @@ -0,0 +1,159 @@ +/* + * Transactional Memory Unit Tests + * + * Copyright 2016 Suraj Jitindar Singh, IBM. + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define US_TO_CYCLES(us) (us << 9) + +/** + * Get decrementer value + */ +static uint64_t get_dec(void) +{ + uint64_t dec = 0; + + asm volatile ( " mfdec %[dec] " : [dec] "+r" (dec) : + : ); + + return dec; +} + +/** + * Sleep for micro-seconds (must be less than 4 seconds) + */ +static void sleep(uint64_t us) +{ + uint64_t expire_time, dec, cycles = US_TO_CYCLES(us); + + if (cycles > 0x7FFFFFFF) + cycles = 0x7FFFFFFF; + + if (cycles > (dec = get_dec())) { + expire_time = 0x7FFFFFFF + dec - cycles; + while (get_dec() < dec) + ; + } else { + expire_time = dec - cycles; + } + + while (get_dec() > expire_time) + ; +} + +static int h_cede(void) +{ + register uint64_t r3 asm("r3") = H_CEDE; + + asm volatile ( " sc 1 " : "+r"(r3) : + : "r0", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "xer", "ctr", "cc"); + + return r3; +} + +/** + * Enable transactional memory + * Returns: 0 - Failure + * 1 - Success + */ +static int enable_tm(void) +{ + uint64_t msr = 0; + + asm volatile ( " mfmsr %[msr] " : [msr] "+r" (msr) : + : ); + + msr |= (((uint64_t) 1) << 32); + + asm volatile ( " mtmsrd %1 \n\t" + " mfmsr %0 " : "+r" (msr) + : "r" (msr) + : ); + + return !!(msr & (((uint64_t) 1) << 32)); +} + +/** + * Test H_CEDE call while transactional memory transaction is suspended + * + * WARNING: This tests for a known vulnerability in which the host may go down. + * Probably best not to run this if your host going down is going to cause + * problems. + * + * If this test succeeds then most likely your kernel has the necessary patch. + * If it fails, you'll know about it. + */ +static void test_h_cede_tm(int argc, char **argv) +{ + int i, pass = 1; + + if (argc > 2) + report_abort("Unsupported argument: '%s'", argv[2]); + + handle_exception(0x900, &dec_except_handler, NULL); + + if (get_secondaries(&halt)) + report_abort("Failed to start secondary cpus", 0); + + if (!enable_tm()) + report_abort("Failed to enable tm", 0); + + asm volatile ( " 1: tbegin. \n\t" + " beq 2f \n\t" + " tsuspend. \n\t" + " 2: tcheck cr0 \n\t" + " bf 2,1b " : : + : "cr0"); + + for (i = 0; i < 500; i++) { + uint64_t rval = h_cede(); + + if (rval != H_SUCCESS) + pass = 0; + sleep(5000); + } + + report("%s", pass, pass ? "success" : "fail"); +} + +struct { + const char *name; + void (*func)(int argc, char **argv); +} hctests[] = { + { "h_cede_tm", test_h_cede_tm }, + { NULL, NULL } +}; + +int main(int argc, char **argv) +{ + int all = 0; + int i; + + report_prefix_push("tm"); + + if (argc == 1 || (argc == 2 && !strcmp(argv[1], "all"))) + all = 1; + + for (i = 0; hctests[i].name != NULL; i++) { + report_prefix_push(hctests[i].name); + if (all || strcmp(argv[1], hctests[i].name) == 0) { + hctests[i].func(argc, argv); + } + report_prefix_pop(); + } + + return report_summary(); +} diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg index 0098cb6..2819a89 100644 --- a/powerpc/unittests.cfg +++ b/powerpc/unittests.cfg @@ -53,3 +53,9 @@ groups = rtas [emulator] file = emulator.elf + +[h_cede_tm] +file = tm.elf +smp = 2,threads=2 +extra_params = -append "h_cede_tm" +groups = nodefault