From: Paolo Bonzini <pbonzini@redhat.com>
To: Steve Rutherford <srutherford@google.com>, kvm@vger.kernel.org
Subject: Re: [PATCH 1/2] x86: Split APIC tests into IOAPIC/APIC tests
Date: Wed, 13 May 2015 10:07:49 +0200 [thread overview]
Message-ID: <55530655.50606@redhat.com> (raw)
In-Reply-To: <1431482143-28018-1-git-send-email-srutherford@google.com>
On 13/05/2015 03:55, Steve Rutherford wrote:
> Split apart the APIC tests into constituent parts (IOAPIC and APIC tests).
>
> Signed-off-by: Steve Rutherford <srutherford@google.com>
> ---
> config/config-x86-common.mak | 2 +
> config/config-x86_64.mak | 1 +
> lib/x86/apic.c | 29 +++++++++++++
> lib/x86/apic.h | 6 +++
> x86/apic.c | 80 -----------------------------------
> x86/eventinj.c | 5 ---
> x86/ioapic.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
> x86/unittests.cfg | 5 +++
> 8 files changed, 142 insertions(+), 85 deletions(-)
> create mode 100644 x86/ioapic.c
>
> diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
> index 8fc3490..d45c9a8 100644
> --- a/config/config-x86-common.mak
> +++ b/config/config-x86-common.mak
> @@ -69,6 +69,8 @@ $(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
>
> $(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
>
> +$(TEST_DIR)/ioapic.elf: $(cstart.o) $(TEST_DIR)/ioapic.o
> +
> $(TEST_DIR)/tscdeadline_latency.elf: $(cstart.o) $(TEST_DIR)/tscdeadline_latency.o
>
> $(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
> diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak
> index d62c1e9..dfdeed6 100644
> --- a/config/config-x86_64.mak
> +++ b/config/config-x86_64.mak
> @@ -10,5 +10,6 @@ tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.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/lib/x86/apic.c b/lib/x86/apic.c
> index 9c42c4d..80b96d8 100644
> --- a/lib/x86/apic.c
> +++ b/lib/x86/apic.c
> @@ -17,6 +17,11 @@ static void outb(unsigned char data, unsigned short port)
> asm volatile ("out %0, %1" : : "a"(data), "d"(port));
> }
>
> +void eoi(void)
> +{
> + apic_write(APIC_EOI, 0);
> +}
> +
> static u32 xapic_read(unsigned reg)
> {
> return *(volatile u32 *)(g_apic + reg);
> @@ -117,6 +122,12 @@ int enable_x2apic(void)
> }
> }
>
> +u32 ioapic_read_reg(unsigned reg)
> +{
> + *(volatile u32 *)g_ioapic = reg;
> + return *(volatile u32 *)(g_ioapic + 0x10);
> +}
> +
> void ioapic_write_reg(unsigned reg, u32 value)
> {
> *(volatile u32 *)g_ioapic = reg;
> @@ -129,6 +140,24 @@ void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
> ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
> }
>
> +ioapic_redir_entry_t ioapic_read_redir(unsigned line)
> +{
> + ioapic_redir_entry_t e;
> +
> + ((u32 *)&e)[0] = ioapic_read_reg(0x10 + line * 2 + 0);
> + ((u32 *)&e)[1] = ioapic_read_reg(0x10 + line * 2 + 1);
> + return e;
> +
> +}
> +
> +void set_mask(unsigned line, int mask)
> +{
> + ioapic_redir_entry_t e = ioapic_read_redir(line);
> +
> + e.mask = mask;
> + ioapic_write_redir(line, e);
> +}
> +
> void enable_apic(void)
> {
> printf("enabling apic\n");
> diff --git a/lib/x86/apic.h b/lib/x86/apic.h
> index e325e9a..216b98d 100644
> --- a/lib/x86/apic.h
> +++ b/lib/x86/apic.h
> @@ -20,8 +20,14 @@ typedef struct {
>
> void mask_pic_interrupts(void);
>
> +void eoi(void);
> +
> void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
> void ioapic_write_reg(unsigned reg, uint32_t value);
> +ioapic_redir_entry_t ioapic_read_redir(unsigned line);
> +uint32_t ioapic_read_reg(unsigned reg);
> +
> +void set_mask(unsigned line, int mask);
>
> void enable_apic(void);
> uint32_t apic_read(unsigned reg);
> diff --git a/x86/apic.c b/x86/apic.c
> index 365c281..d4eec52 100644
> --- a/x86/apic.c
> +++ b/x86/apic.c
> @@ -140,11 +140,6 @@ static void test_apicbase(void)
> report_prefix_pop();
> }
>
> -static void eoi(void)
> -{
> - apic_write(APIC_EOI, 0);
> -}
> -
> static int ipi_count;
>
> static void self_ipi_isr(isr_regs_t *regs)
> @@ -165,79 +160,6 @@ static void test_self_ipi(void)
> report("self ipi", ipi_count == 1);
> }
>
> -static void set_ioapic_redir(unsigned line, unsigned vec)
> -{
> - ioapic_redir_entry_t e = {
> - .vector = vec,
> - .delivery_mode = 0,
> - .trig_mode = 0,
> - };
> -
> - ioapic_write_redir(line, e);
> -}
> -
> -static void set_irq_line(unsigned line, int val)
> -{
> - asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
> -}
> -
> -static void toggle_irq_line(unsigned line)
> -{
> - set_irq_line(line, 1);
> - set_irq_line(line, 0);
> -}
> -
> -static int g_isr_77;
> -
> -static void ioapic_isr_77(isr_regs_t *regs)
> -{
> - ++g_isr_77;
> - eoi();
> -}
> -
> -static void test_ioapic_intr(void)
> -{
> - handle_irq(0x77, ioapic_isr_77);
> - set_ioapic_redir(0x0e, 0x77);
> - toggle_irq_line(0x0e);
> - asm volatile ("nop");
> - report("ioapic interrupt", g_isr_77 == 1);
> -}
> -
> -static int g_78, g_66, g_66_after_78;
> -static ulong g_66_rip, g_78_rip;
> -
> -static void ioapic_isr_78(isr_regs_t *regs)
> -{
> - ++g_78;
> - g_78_rip = regs->rip;
> - eoi();
> -}
> -
> -static void ioapic_isr_66(isr_regs_t *regs)
> -{
> - ++g_66;
> - if (g_78)
> - ++g_66_after_78;
> - g_66_rip = regs->rip;
> - eoi();
> -}
> -
> -static void test_ioapic_simultaneous(void)
> -{
> - handle_irq(0x78, ioapic_isr_78);
> - handle_irq(0x66, ioapic_isr_66);
> - set_ioapic_redir(0x0e, 0x78);
> - set_ioapic_redir(0x0f, 0x66);
> - irq_disable();
> - toggle_irq_line(0x0f);
> - 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);
> -}
> -
> volatile int nmi_counter_private, nmi_counter, nmi_hlt_counter, sti_loop_active;
>
> void sti_nop(char *p)
> @@ -390,8 +312,6 @@ int main()
>
> test_self_ipi();
>
> - test_ioapic_intr();
> - test_ioapic_simultaneous();
> test_sti_nmi();
> test_multiple_nmi();
>
> diff --git a/x86/eventinj.c b/x86/eventinj.c
> index 32de6f0..bddedce 100644
> --- a/x86/eventinj.c
> +++ b/x86/eventinj.c
> @@ -32,11 +32,6 @@ void apic_self_nmi(void)
> apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
> }
>
> -static void eoi(void)
> -{
> - apic_write(APIC_EOI, 0);
> -}
> -
> #define flush_phys_addr(__s) outl(0xe4, __s)
> #define flush_stack() do { \
> int __l; \
> diff --git a/x86/ioapic.c b/x86/ioapic.c
> new file mode 100644
> index 0000000..2afdaa2
> --- /dev/null
> +++ b/x86/ioapic.c
> @@ -0,0 +1,99 @@
> +#include "libcflat.h"
> +#include "apic.h"
> +#include "vm.h"
> +#include "smp.h"
> +#include "desc.h"
> +#include "isr.h"
> +
> +#define EDGE_TRIGGERED 0
> +#define LEVEL_TRIGGERED 1
> +
> +static void set_ioapic_redir(unsigned line, unsigned vec, unsigned trig_mode)
> +{
> + ioapic_redir_entry_t e = {
> + .vector = vec,
> + .delivery_mode = 0,
> + .trig_mode = trig_mode,
> + };
> +
> + ioapic_write_redir(line, e);
> +}
> +
> +static void set_irq_line(unsigned line, int val)
> +{
> + asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
> +}
> +
> +static void toggle_irq_line(unsigned line)
> +{
> + set_irq_line(line, 1);
> + set_irq_line(line, 0);
> +}
> +
> +static volatile int g_isr_77;
> +
> +static void ioapic_isr_77(isr_regs_t *regs)
> +{
> + ++g_isr_77;
> + eoi();
> +}
> +
> +static void test_ioapic_intr(void)
> +{
> + handle_irq(0x77, ioapic_isr_77);
> + set_ioapic_redir(0x0e, 0x77, EDGE_TRIGGERED);
> + toggle_irq_line(0x0e);
> + asm volatile ("nop");
> + report("ioapic interrupt", g_isr_77 == 1);
> +}
> +
> +static int g_78, g_66, g_66_after_78;
> +static ulong g_66_rip, g_78_rip;
> +
> +static void ioapic_isr_78(isr_regs_t *regs)
> +{
> + ++g_78;
> + g_78_rip = regs->rip;
> + eoi();
> +}
> +
> +static void ioapic_isr_66(isr_regs_t *regs)
> +{
> + ++g_66;
> + if (g_78)
> + ++g_66_after_78;
> + g_66_rip = regs->rip;
> + eoi();
> +}
> +
> +static void test_ioapic_simultaneous(void)
> +{
> + handle_irq(0x78, ioapic_isr_78);
> + handle_irq(0x66, ioapic_isr_66);
> + set_ioapic_redir(0x0e, 0x78, EDGE_TRIGGERED);
> + set_ioapic_redir(0x0f, 0x66, EDGE_TRIGGERED);
> + irq_disable();
> + toggle_irq_line(0x0f);
> + 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);
> +}
> +
> +int main(void)
> +{
> + setup_vm();
> + smp_init();
> + setup_idt();
> +
> + mask_pic_interrupts();
> + enable_apic();
> +
> + irq_enable();
> +
> + test_ioapic_intr();
> + test_ioapic_simultaneous();
> +
> + return report_summary();
> +}
> diff --git a/x86/unittests.cfg b/x86/unittests.cfg
> index badb08a..a38544f 100644
> --- a/x86/unittests.cfg
> +++ b/x86/unittests.cfg
> @@ -12,6 +12,11 @@ smp = 2
> extra_params = -cpu qemu64,+x2apic,+tsc-deadline
> arch = x86_64
>
> +[ioapic]
> +file = ioapic.flat
> +extra_params = -cpu qemu64
> +arch = x86_64
> +
> [smptest]
> file = smptest.flat
> smp = 2
>
Applying these two, thanks!
Paolo
prev parent reply other threads:[~2015-05-13 8:07 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 ` [PATCH 2/2] x86: extend IOAPIC tests Steve Rutherford
2015-05-13 8:07 ` Paolo Bonzini [this message]
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=55530655.50606@redhat.com \
--to=pbonzini@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=srutherford@google.com \
/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