From patchwork Mon Dec 16 14:02:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 1210439 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="AIylJovt"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47c3BP27PRz9sPn for ; Tue, 17 Dec 2019 01:12:27 +1100 (AEDT) Received: from localhost ([::1]:54382 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1igr6l-0006zK-Mm for incoming@patchwork.ozlabs.org; Mon, 16 Dec 2019 09:12:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:58752) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1igqzA-0004lX-Ho for qemu-devel@nongnu.org; Mon, 16 Dec 2019 09:04:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1igqz8-00041M-VX for qemu-devel@nongnu.org; Mon, 16 Dec 2019 09:04:32 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:21369 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1igqz8-000411-Oo for qemu-devel@nongnu.org; Mon, 16 Dec 2019 09:04:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1576505069; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oEODYmr2qU023nvtVQu7D64kTuPbyxsd5COA3rYdVjg=; b=AIylJovtuFyC3lK3zyGuwKMhrzNIViQO1pcfFMCoz2IWstoigMlnzcDaH0zQYPpTF+Zs+j tHiL87yaRNxHDN+z3b2rfLu34ojqgvK+YkqIDEwJGCDxqr0paFb//VU98AoGSrnX80HZtx zB7m8WD2xnMlz3CDeg90+VAwv4fN1Rg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-384-n_HoM9aQPTiBfhJ9ttW-PQ-1; Mon, 16 Dec 2019 09:04:27 -0500 X-MC-Unique: n_HoM9aQPTiBfhJ9ttW-PQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2BCF41854351; Mon, 16 Dec 2019 14:04:26 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-117.ams2.redhat.com [10.36.116.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id 26470675B9; Mon, 16 Dec 2019 14:04:22 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, maz@kernel.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, qemu-devel@nongnu.org, qemu-arm@nongnu.org Subject: [kvm-unit-tests PATCH 13/16] arm/arm64: ITS: INT functional tests Date: Mon, 16 Dec 2019 15:02:32 +0100 Message-Id: <20191216140235.10751-14-eric.auger@redhat.com> In-Reply-To: <20191216140235.10751-1-eric.auger@redhat.com> References: <20191216140235.10751-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, drjones@redhat.com, andre.przywara@arm.com, thuth@redhat.com, yuzenghui@huawei.com, alexandru.elisei@arm.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Triggers LPIs through the INT command. the test checks the LPI hits the right CPU and triggers the right LPI intid, ie. the translation is correct. Updates to the config table also are tested, along with inv and invall commands. Signed-off-by: Eric Auger --- arm/gic.c | 174 +++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 6 ++ lib/arm/asm/gic-v3-its.h | 14 ++++ 3 files changed, 194 insertions(+) diff --git a/arm/gic.c b/arm/gic.c index 8b56fce..6b73258 100644 --- a/arm/gic.c +++ b/arm/gic.c @@ -34,6 +34,7 @@ static struct gic *gic; static int acked[NR_CPUS], spurious[NR_CPUS]; static int bad_sender[NR_CPUS], bad_irq[NR_CPUS]; static cpumask_t ready; +static struct its_stats lpi_stats; static void nr_cpu_check(int nr) { @@ -158,6 +159,54 @@ static void ipi_handler(struct pt_regs *regs __unused) } } +static void lpi_handler(struct pt_regs *regs __unused) +{ + u32 irqstat = gic_read_iar(); + int irqnr = gic_iar_irqnr(irqstat); + + gic_write_eoir(irqstat); + if (irqnr < 8192) + report(false, "Unexpected non LPI interrupt received"); + smp_rmb(); /* pairs with wmb in lpi_stats_expect */ + lpi_stats.observed.cpu_id = smp_processor_id(); + lpi_stats.observed.lpi_id = irqnr; + smp_wmb(); /* pairs with rmb in check_lpi_stats */ +} + +static void lpi_stats_expect(int exp_cpu_id, int exp_lpi_id) +{ + lpi_stats.expected.cpu_id = exp_cpu_id; + lpi_stats.expected.lpi_id = exp_lpi_id; + lpi_stats.observed.cpu_id = -1; + lpi_stats.observed.lpi_id = -1; + smp_wmb(); /* pairs with rmb in handler */ +} + +static void check_lpi_stats(void) +{ + mdelay(100); + smp_rmb(); /* pairs with wmb in lpi_handler */ + if ((lpi_stats.observed.cpu_id != lpi_stats.expected.cpu_id) || + (lpi_stats.observed.lpi_id != lpi_stats.expected.lpi_id)) { + if (lpi_stats.observed.cpu_id == -1 && + lpi_stats.observed.lpi_id == -1) { + report(false, + "No LPI received whereas (cpuid=%d, intid=%d) " + "was expected", lpi_stats.expected.cpu_id, + lpi_stats.expected.lpi_id); + } else { + report(false, "Unexpected LPI (cpuid=%d, intid=%d)", + lpi_stats.observed.cpu_id, + lpi_stats.observed.lpi_id); + } + } else if (lpi_stats.expected.lpi_id != -1) { + report(true, "LPI %d on CPU %d", lpi_stats.observed.lpi_id, + lpi_stats.observed.cpu_id); + } else { + report(true, "no LPI received, as expected"); + } +} + static void gicv2_ipi_send_self(void) { writel(2 << 24 | IPI_IRQ, gicv2_dist_base() + GICD_SGIR); @@ -241,6 +290,14 @@ static void ipi_test(void *data __unused) ipi_recv(); } +static void secondary_lpi_test(void) +{ + setup_irq(lpi_handler); + cpumask_set_cpu(smp_processor_id(), &ready); + while (1) + wfi(); +} + static struct gic gicv2 = { .ipi = { .send_self = gicv2_ipi_send_self, @@ -552,6 +609,120 @@ static void test_its_baser(void) report_info("collection baser entry_size = 0x%x", dev_baser->esz); } +static int its_prerequisites(int nb_cpus) +{ + int cpu; + + if (!gicv3_its_base()) { + report_skip("No ITS, skip ..."); + return -1; + } + + if (nr_cpus < 4) { + report_skip("Test requires at least %d vcpus", nb_cpus); + return -1; + } + + stats_reset(); + + setup_irq(lpi_handler); + + for_each_present_cpu(cpu) { + if (cpu == 0) + continue; + smp_boot_secondary(cpu, secondary_lpi_test); + } + wait_on_ready(); + + its_enable_defaults(); + + lpi_stats_expect(-1, -1); + check_lpi_stats(); + + return 0; +} + +static void test_its_trigger(void) +{ + struct its_collection *col3, *col2; + struct its_device *dev2, *dev7; + + if (its_prerequisites(4)) + return; + + dev2 = its_create_device(2 /* dev id */, 8 /* nb_ites */); + dev7 = its_create_device(7 /* dev id */, 8 /* nb_ites */); + + col3 = its_create_collection(3 /* col id */, 3/* target PE */); + col2 = its_create_collection(2 /* col id */, 2/* target PE */); + + set_lpi_config(8195, LPI_PROP_DEFAULT); + set_lpi_config(8196, LPI_PROP_DEFAULT); + + its_send_invall(col2); + its_send_invall(col3); + + report_prefix_push("int"); + + its_send_mapd(dev2, true); + its_send_mapd(dev7, true); + + its_send_mapc(col3, true); + its_send_mapc(col2, true); + + its_send_mapti(dev2, 8195 /* lpi id */, + 20 /* event id */, col3); + its_send_mapti(dev7, 8196 /* lpi id */, + 255 /* event id */, col2); + + lpi_stats_expect(3, 8195); + its_send_int(dev2, 20); + check_lpi_stats(); + + lpi_stats_expect(2, 8196); + its_send_int(dev7, 255); + check_lpi_stats(); + + report_prefix_pop(); + + report_prefix_push("inv/invall"); + + /* disable 8195 */ + set_lpi_config(8195, LPI_PROP_DEFAULT & ~0x1); + its_send_inv(dev2, 20); + + lpi_stats_expect(-1, -1); + its_send_int(dev2, 20); + check_lpi_stats(); + + set_lpi_config(8195, LPI_PROP_DEFAULT); + /* willingly forget the INVALL*/ + lpi_stats_expect(-1, -1); + its_send_int(dev2, 20); + check_lpi_stats(); + + its_send_invall(col3); + lpi_stats_expect(3, 8195); + its_send_int(dev2, 20); + check_lpi_stats(); + + report_prefix_pop(); + + report_prefix_push("mapd valid=false"); + its_send_mapd(dev2, false); + lpi_stats_expect(-1, -1); + its_send_int(dev2, 20); + check_lpi_stats(); + report_prefix_pop(); + + report_prefix_push("mapc valid=false"); + its_send_mapc(col2, false); + lpi_stats_expect(-1, -1); + its_send_int(dev7, 255); + check_lpi_stats(); +} + + int main(int argc, char **argv) { if (!gic_init()) { @@ -582,6 +753,9 @@ int main(int argc, char **argv) } else if (strcmp(argv[1], "mmio") == 0) { report_prefix_push(argv[1]); gic_test_mmio(); + } else if (!strcmp(argv[1], "its-trigger")) { + report_prefix_push(argv[1]); + test_its_trigger(); report_prefix_pop(); } else if (strcmp(argv[1], "its-introspection") == 0) { report_prefix_push(argv[1]); diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 2234a0f..80a1d27 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -134,6 +134,12 @@ smp = $MAX_SMP extra_params = -machine gic-version=3 -append 'its-baser' groups = its +[its-trigger] +file = gic.flat +smp = $MAX_SMP +extra_params = -machine gic-version=3 -append 'its-trigger' +groups = its + # Test PSCI emulation [psci] file = psci.flat diff --git a/lib/arm/asm/gic-v3-its.h b/lib/arm/asm/gic-v3-its.h index d074c17..d4fd799 100644 --- a/lib/arm/asm/gic-v3-its.h +++ b/lib/arm/asm/gic-v3-its.h @@ -162,6 +162,16 @@ struct its_data { u32 nb_collections; /* Allocated Collections */ }; +struct its_event { + int cpu_id; + int lpi_id; +}; + +struct its_stats { + struct its_event expected; + struct its_event observed; +}; + extern struct its_data its_data; #define gicv3_its_base() (its_data.base) @@ -178,6 +188,10 @@ extern void gicv3_rdist_ctrl_lpi(u32 redist, bool set); extern void its_enable_defaults(void); extern struct its_device *its_create_device(u32 dev_id, int nr_ites); extern struct its_collection *its_create_collection(u32 col_id, u32 target_pe); +extern struct its_collection *its_create_collection(u32 col_id, u32 target); + +extern void set_lpi_config(int n, u8 val); +extern u8 get_lpi_config(int n); extern void its_send_mapd(struct its_device *dev, int valid); extern void its_send_mapc(struct its_collection *col, int valid);