From patchwork Wed May 13 01:55:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Rutherford X-Patchwork-Id: 6393241 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C37F59F32B for ; Wed, 13 May 2015 01:55:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A5147203FB for ; Wed, 13 May 2015 01:55:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7FC7B203F7 for ; Wed, 13 May 2015 01:55:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965094AbbEMBzw (ORCPT ); Tue, 12 May 2015 21:55:52 -0400 Received: from mail-ig0-f172.google.com ([209.85.213.172]:33715 "EHLO mail-ig0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965083AbbEMBzv (ORCPT ); Tue, 12 May 2015 21:55:51 -0400 Received: by igbpi8 with SMTP id pi8so106226812igb.0 for ; Tue, 12 May 2015 18:55:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=5a4wkfw/FlDOfKATqtGkNuUqnKPcjqLQsXaHh1GL4j8=; b=SjYBAjk80iLh7d2kwgTYPudCEtQx09jvmoS/sh+RJQeIWsF8htgfW5dlFHX02yj6fm nJBDE9vhpsMDNn7qZgYaZNfpv9+v0yBRGMQCYem2VrPW+EkZ5EsInhmu+d0ka58SrWOn N0AW615r+k5oUj4yrimnSxRlRrLRU0VQB3NOTofKj6vszFwmlv8B+yBTX2mt3ELTNQG/ axtBnIxBwceWQ/pfR9TTa+ohjFWUJi0l/WtAwpcDHxtii4foBYkL7t6Y9PqnUWRHepiy uI/uQ5T5jHiSCqkoVveJ3sUhhO7+0uwtI7p473cagUzjnAh/oJ0fO+z11cpySuWS9tvC 1d0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=5a4wkfw/FlDOfKATqtGkNuUqnKPcjqLQsXaHh1GL4j8=; b=kfX/39TTomOYTwfe8fJRGPl8bFBl/pfi2/ODfrKc+cBqgkZY5CyRZvedTFevdMgQvq j4JQ0vfnact1K4ERPpN323Ii1xDptkx/9nb9Fz8xHictjrtXb4O0xKJ2DdUF9ieExWvd 4aYLaBQJ7bhYrUNdtfTji1TjHmzrkX+BFm3jIhNGm+kMM2Y4cfNT39y2yuhQdi5MoYFr m4QhtgDrOZKYglD8efyDwwJugYODGWDSdJcShJb+SZhp7CorraQX+KDiJLNTdNOALkIi Gq3FDVYuyiX6t6cELbSKzi65MtvMC4JkrAZ3QTZB5OnGJkp1PVsqRI7R4swYLeQNG5N5 kTbg== X-Gm-Message-State: ALoCoQn3CeXwI38zgJoZMbZwoEwssCbXNEiqgQ3a6HIq4pj2jB7pGBZctsVGO6yRq0IUlVgk3x9W X-Received: by 10.42.67.80 with SMTP id s16mr6218228ici.25.1431482150382; Tue, 12 May 2015 18:55:50 -0700 (PDT) Received: from entropic.kir.corp.google.com ([172.31.8.128]) by mx.google.com with ESMTPSA id lq3sm2543064igb.3.2015.05.12.18.55.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 12 May 2015 18:55:49 -0700 (PDT) From: Steve Rutherford To: kvm@vger.kernel.org Subject: [PATCH 2/2] x86: extend IOAPIC tests Date: Tue, 12 May 2015 18:55:43 -0700 Message-Id: <1431482143-28018-2-git-send-email-srutherford@google.com> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c In-Reply-To: <1431482143-28018-1-git-send-email-srutherford@google.com> References: <1431482143-28018-1-git-send-email-srutherford@google.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add tests for fundamental behaviors of the IOAPIC: Edge & level triggered interrupts Level triggered interrupt coalescing Level triggered EOIs Interrupt masking Passes with most recent version of KVM on Intel x86. Signed-off-by: Steve Rutherford --- config/config-x86_64.mak | 4 +- x86/ioapic.c | 186 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 9 deletions(-) diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak index dfdeed6..7d4eb34 100644 --- a/config/config-x86_64.mak +++ b/config/config-x86_64.mak @@ -6,10 +6,10 @@ CFLAGS += -mno-red-zone tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \ $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \ $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \ - $(TEST_DIR)/pcid.flat $(TEST_DIR)/debug.flat + $(TEST_DIR)/pcid.flat $(TEST_DIR)/debug.flat \ + $(TEST_DIR)/ioapic.flat tests += $(TEST_DIR)/svm.flat tests += $(TEST_DIR)/vmx.flat tests += $(TEST_DIR)/tscdeadline_latency.flat -tests += $(TEST_DIR)/ioapic.flat include config/config-x86-common.mak diff --git a/x86/ioapic.c b/x86/ioapic.c index 2afdaa2..1fcf67e 100644 --- a/x86/ioapic.c +++ b/x86/ioapic.c @@ -30,21 +30,87 @@ static void toggle_irq_line(unsigned line) set_irq_line(line, 0); } +static void ioapic_reg_version(void) +{ + u8 version_offset; + uint32_t data_read, data_write; + + version_offset = 0x01; + data_read = ioapic_read_reg(version_offset); + data_write = data_read ^ 0xffffffff; + + ioapic_write_reg(version_offset, data_write); + report("version register read only test", + data_read == ioapic_read_reg(version_offset)); +} + +static void ioapic_reg_id(void) +{ + u8 id_offset; + uint32_t data_read, data_write, diff; + + id_offset = 0x0; + data_read = ioapic_read_reg(id_offset); + data_write = data_read ^ 0xffffffff; + + ioapic_write_reg(id_offset, data_write); + + diff = data_read ^ ioapic_read_reg(id_offset); + report("id register only bits [24:27] writable", + diff == 0x0f000000); +} + +static void ioapic_arbitration_id(void) +{ + u8 id_offset, arb_offset; + uint32_t write; + + id_offset = 0x0; + arb_offset = 0x2; + write = 0x0f000000; + + ioapic_write_reg(id_offset, write); + report("arbitration register set by id", + ioapic_read_reg(arb_offset) == write); + + ioapic_write_reg(arb_offset, 0x0); + report("arbtration register read only", + ioapic_read_reg(arb_offset) == write); +} + +static volatile int g_isr_76; + +static void ioapic_isr_76(isr_regs_t *regs) +{ + ++g_isr_76; + eoi(); +} + +static void test_ioapic_edge_intr(void) +{ + handle_irq(0x76, ioapic_isr_76); + set_ioapic_redir(0x0e, 0x76, EDGE_TRIGGERED); + toggle_irq_line(0x0e); + asm volatile ("nop"); + report("edge triggered intr", g_isr_76 == 1); +} + static volatile int g_isr_77; static void ioapic_isr_77(isr_regs_t *regs) { ++g_isr_77; + set_irq_line(0x0e, 0); eoi(); } -static void test_ioapic_intr(void) +static void test_ioapic_level_intr(void) { handle_irq(0x77, ioapic_isr_77); - set_ioapic_redir(0x0e, 0x77, EDGE_TRIGGERED); - toggle_irq_line(0x0e); + set_ioapic_redir(0x0e, 0x77, LEVEL_TRIGGERED); + set_irq_line(0x0e, 1); asm volatile ("nop"); - report("ioapic interrupt", g_isr_77 == 1); + report("level triggered intr", g_isr_77 == 1); } static int g_78, g_66, g_66_after_78; @@ -77,10 +143,106 @@ static void test_ioapic_simultaneous(void) toggle_irq_line(0x0e); irq_enable(); asm volatile ("nop"); - report("ioapic simultaneous interrupt", - g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip); + report("ioapic simultaneous edge interrupts", + g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip); } +static int g_isr_98; + +static void ioapic_isr_98(isr_regs_t *regs) +{ + ++g_isr_98; + if (g_isr_98 == 1) { + set_irq_line(0x0e, 0); + set_irq_line(0x0e, 1); + } + set_irq_line(0x0e, 0); + eoi(); +} + +static void test_ioapic_level_coalesce(void) +{ + handle_irq(0x98, ioapic_isr_98); + set_ioapic_redir(0x0e, 0x98, LEVEL_TRIGGERED); + set_irq_line(0x0e, 1); + asm volatile ("nop"); + report("coalesce simultaneous level interrupts", g_isr_98 == 1); +} + +static int g_isr_99; + +static void ioapic_isr_99(isr_regs_t *regs) +{ + ++g_isr_99; + set_irq_line(0x0e, 0); + eoi(); +} + +static void test_ioapic_level_sequential(void) +{ + handle_irq(0x99, ioapic_isr_99); + set_ioapic_redir(0x0e, 0x99, LEVEL_TRIGGERED); + set_irq_line(0x0e, 1); + set_irq_line(0x0e, 1); + asm volatile ("nop"); + report("sequential level interrupts", g_isr_99 == 2); +} + +static volatile int g_isr_81; + +static void ioapic_isr_81(isr_regs_t *regs) +{ + ++g_isr_81; + set_irq_line(0x0e, 0); + eoi(); +} + +static void test_ioapic_edge_mask(void) +{ + handle_irq(0x81, ioapic_isr_81); + set_ioapic_redir(0x0e, 0x81, EDGE_TRIGGERED); + + set_mask(0x0e, true); + set_irq_line(0x0e, 1); + set_irq_line(0x0e, 0); + + asm volatile ("nop"); + report("masked level interrupt", g_isr_81 == 0); + + set_mask(0x0e, false); + set_irq_line(0x0e, 1); + + asm volatile ("nop"); + report("unmasked level interrupt", g_isr_81 == 1); +} + +static volatile int g_isr_82; + +static void ioapic_isr_82(isr_regs_t *regs) +{ + ++g_isr_82; + set_irq_line(0x0e, 0); + eoi(); +} + +static void test_ioapic_level_mask(void) +{ + handle_irq(0x82, ioapic_isr_82); + set_ioapic_redir(0x0e, 0x82, LEVEL_TRIGGERED); + + set_mask(0x0e, true); + set_irq_line(0x0e, 1); + + asm volatile ("nop"); + report("masked level interrupt", g_isr_82 == 0); + + set_mask(0x0e, false); + + asm volatile ("nop"); + report("unmasked level interrupt", g_isr_82 == 1); +} + + int main(void) { setup_vm(); @@ -92,8 +254,18 @@ int main(void) irq_enable(); - test_ioapic_intr(); + ioapic_reg_version(); + ioapic_reg_id(); + ioapic_arbitration_id(); + + test_ioapic_edge_intr(); + test_ioapic_level_intr(); test_ioapic_simultaneous(); + test_ioapic_level_coalesce(); + test_ioapic_level_sequential(); + + test_ioapic_edge_mask(); + test_ioapic_level_mask(); return report_summary(); }