From patchwork Tue Aug 16 07:18:15 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: 9282737 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 B75C560574 for ; Tue, 16 Aug 2016 07:19:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A1BCD2868C for ; Tue, 16 Aug 2016 07:19:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 965C528690; Tue, 16 Aug 2016 07:19:02 +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 0CE4B2868C for ; Tue, 16 Aug 2016 07:19:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752985AbcHPHS6 (ORCPT ); Tue, 16 Aug 2016 03:18:58 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:33709 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751532AbcHPHS5 (ORCPT ); Tue, 16 Aug 2016 03:18:57 -0400 Received: by mail-pf0-f193.google.com with SMTP id i6so5038233pfe.0; Tue, 16 Aug 2016 00:18:56 -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=rs5xc0CNiv1C/Go3cfL32XGzVB2Ny/Ukxc6vqbQdS2w=; b=W/WgCAErPe7VmRi9KWcG0o4wwX1FrBTRsLNTWoTXlt+eNuvF7zpGu6s3zvKJmDsIRO M9hqR5EI1lv+6WTqJ9+abTVc12h4XnRqCMCf7p5EbMESNU4AoVYTH4YiHH1IRl4b0JGX +PCnHPduv3DG4tXl+w5R8U6U1o0Z1bWAWJ8Wyb3URWvmO/n616xXclggI1W+///0bs4d tvmmhR9jkiGcbSi3pwwQUtsDErIafJzN7kQXUXUzwe6MBFk0Lj4AGwO0gYgFyfiD8dj3 +sCMOi3tQdHmiSt3jmqYKMA1ySTTixIRscqN5JWSHf8rVAvhRoyPJsk/j+3NG3795t39 Z8lg== 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=rs5xc0CNiv1C/Go3cfL32XGzVB2Ny/Ukxc6vqbQdS2w=; b=erN0PKIgCl0Bwhdtw5cYkSkB1SubE7ZAEBTO3N6wQXBPyy3uMbgje6Xvx0q61FRTDH U1VLPsvGbo2oVOc2bzA32KdDJaJntKrch4U88RmZwfY6r9H9GJpaW2fazEGM1P2pSDKy ZhBgHyaXA1FralGhklkiMmcIaJ5s6gMxOyY/3XzdVSSoVLo7y/+28SMDZXjeAtnEWI/B lz2KRBSHChp7MOcyF/btzfdiNPGtOF/aZxry6BtPSBGpFh09y5A69o/pQJu2pjHyQ4oi ++X4DOtypxUbk5N0lxaB2quZ1C51XjT+Oh7IwXCgAsKy0JF+e754Lq+ZRZpKreW1l7bR 8x+A== X-Gm-Message-State: AEkoouszeqQ/UsrjHd2mPRaYIxojm8bMXaX8tV3o9xcvE9Iy0epNZUKsOT0FAOQOprarXQ== X-Received: by 10.98.47.132 with SMTP id v126mr10817083pfv.152.1471331936012; Tue, 16 Aug 2016 00:18:56 -0700 (PDT) Received: from dyn253.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id fj19sm36452252pab.37.2016.08.16.00.18.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Aug 2016 00:18:55 -0700 (PDT) From: Suraj Jitindar Singh To: kvm@vger.kernel.org Cc: sjitindarsingh@gmail.com, pbonzini@redhat.com, rkrcmar@redhat.com, kvm-ppc@vger.kernel.org, lvivier@redhat.com, thuth@redhat.com, drjones@redhat.com Subject: [kvm-unit-tests PATCH V3 5/5] powerpc/tm: Add a test for H_CEDE while tm suspended Date: Tue, 16 Aug 2016 17:18:15 +1000 Message-Id: <1471331895-29887-5-git-send-email-sjitindarsingh@gmail.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1471331895-29887-1-git-send-email-sjitindarsingh@gmail.com> References: <1471331895-29887-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. This vulnerability has been assigned the ID CVE-2016-5412. Based on initial work done by: Cyril Bur Signed-off-by: Suraj Jitindar Singh Reviewed-by: Andrew Jones --- Change Log: V2 -> V3: - Remove get_dec() and sleep() functions as sleep functionality is now provided by a generic implementation in processor.c. - Replace TM instructions with raw machine code to support older compilers Signed-off-by: Suraj Jitindar Singh --- lib/powerpc/asm/hcall.h | 1 + powerpc/Makefile.common | 3 +- powerpc/tm.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ powerpc/unittests.cfg | 6 +++ 4 files changed, 130 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..ba01f95 --- /dev/null +++ b/powerpc/tm.c @@ -0,0 +1,121 @@ +/* + * 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 + +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: FALSE - Failure + * TRUE - Success + */ +static bool enable_tm(void) +{ + uint64_t msr = 0; + + asm volatile ("mfmsr %[msr]" : [msr] "=r" (msr)); + + msr |= (((uint64_t) 1) << 32); + + asm volatile ("mtmsrd %[msr]\n\t" + "mfmsr %[msr]" : [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 the test passes then your kernel probably has the necessary patch. + * If the test fails then the H_CEDE call was unsuccessful and the + * vulnerability wasn't tested. + * If the test hits the vulnerability then it will never complete or report and + * the qemu process will block indefinitely. RCU stalls will be detected on the + * cpu and any process scheduled on the lost cpu will also block indefinitely. + */ +static void test_h_cede_tm(int argc, char **argv) +{ + bool pass = true; + int i; + + if (argc > 2) + report_abort("Unsupported argument: '%s'", argv[2]); + + handle_exception(0x900, &dec_except_handler, NULL); + + if (!start_all_cpus(&halt, 0)) + report_abort("Failed to start secondary cpus"); + + if (!enable_tm()) + report_abort("Failed to enable tm"); + + /* + * Begin a transaction and guarantee we are in the suspend state + * before continuing + */ + asm volatile ("1: .long 0x7c00051d\n\t" /* tbegin. */ + "beq 2f\n\t" + ".long 0x7c0005dd\n\t" /* tsuspend. */ + "2: .long 0x7c00059c\n\t" /* tcheck cr0 */ + "bf 2,1b" : : : "cr0"); + + for (i = 0; i < 500 && pass; i++) { + uint64_t rval = h_cede(); + + if (rval != H_SUCCESS) + pass = false; + mdelay(5); + } + + report("H_CEDE TM", pass); +} + +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) +{ + bool all; + int i; + + report_prefix_push("tm"); + + all = argc == 1 || (argc == 2 && !strcmp(argv[1], "all")); + + for (i = 0; hctests[i].name != NULL; i++) { + if (all || strcmp(argv[1], hctests[i].name) == 0) { + report_prefix_push(hctests[i].name); + hctests[i].func(argc, argv); + report_prefix_pop(); + } + } + + return report_summary(); +} diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg index 0098cb6..20dbde6 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,h_cede_tm