From: Steve Rutherford <srutherford@google.com>
To: kvm@vger.kernel.org
Subject: [PATCH 2/2] x86: extend IOAPIC tests
Date: Tue, 12 May 2015 18:55:43 -0700 [thread overview]
Message-ID: <1431482143-28018-2-git-send-email-srutherford@google.com> (raw)
In-Reply-To: <1431482143-28018-1-git-send-email-srutherford@google.com>
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 <srutherford@google.com>
---
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();
}
--
2.2.0.rc0.207.ga3a616c
next prev parent reply other threads:[~2015-05-13 1:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-13 1:55 [PATCH 1/2] x86: Split APIC tests into IOAPIC/APIC tests Steve Rutherford
2015-05-13 1:55 ` Steve Rutherford [this message]
2015-05-13 8:07 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1431482143-28018-2-git-send-email-srutherford@google.com \
--to=srutherford@google.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox