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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.