From patchwork Sat Sep 21 10:08:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Raphael Tiovalen X-Patchwork-Id: 13808872 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA0597462 for ; Sat, 21 Sep 2024 10:08:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913317; cv=none; b=YRR+wKBmkwwerJPRt1b9wtRIPR9Kwyxhn5WR2iP0JRqxDYQAx/lI/P2VQa5dL+8ayx4fX3igWp/jjdTSuLimC3g7BFU9m6QxqXyV8UJQlCyOZl1Z9sZinZJLu+oZsaGojiIaWe4johlDOgT9Y75lVo/5S9Mmxwii0P8QXrmfIEg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913317; c=relaxed/simple; bh=Yq/HGWMi01YsA33uHiv+rVVdMQiUcIdwqs4TiAA/dRE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b7Cqipdd4trm5IorstGK55rNrCJSjPaqnbmTusEtAPKCFd2cUZAIilDHB3oKV5C5wryn5pkm3Jeqp+SJ2osgrEbA1Go5LCA+gb5jCwZzCx3qmGjjIA0TPP9CqOUjEkWqrmVIawu1ziOqBFL8dFJ4HBVJT2NZqueOA6GRABp6lnw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KmwQknQA; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KmwQknQA" Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-2d86f713557so1965818a91.2 for ; Sat, 21 Sep 2024 03:08:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726913314; x=1727518114; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3+lWDZEHmN56oixuRbeFyTMvYNLchXuOs8thZyGBJ8A=; b=KmwQknQAmNRM7rsGFmdHkPvNxsFdLBhk8Rne4CwahcGoXJqZL+lUPetl7BsBj970u3 VOCl3AhzS/OuhtBo3aBqjzJJF/oTIEVmnT/tabuYyHg0+b0bknotjfcLrmROy8mAOUUW XTaE+ZOJhjTgfmp2Ck6o1cngs0OFdrOjd2A7B1goVP7QiPwAmdCw+RwOB0QJk/hn+bjZ tp07A85I2TO2jZiR96fNg71A6Gp2paXQInELaZ6gd4MznHmk/osherxPbR6bWeTJQn+I oJhuThWAkcUz+F2ie2U5CBvGHm0x1xtOptYeRRxpOM1BG3jdjDVSb+UEP13ki5A8b/Z8 3uMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726913314; x=1727518114; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3+lWDZEHmN56oixuRbeFyTMvYNLchXuOs8thZyGBJ8A=; b=HeTMQ6yB2vN6R0sRsCLSCLtP1S4wt0rbsNb6O14hS9fIwpu+moR3ocH8l73eL4a9Ho BVppkKulmNmpKNNMfXa5kjfzh4ya0OBVgiqVLqFWeshBSfDdrA21s2X+8e16N+6RbKhn xIeQlC38jDdfY4eaoeK6SKy7TH7xlr2T2wP3ag6Y+ZQiqFcVQaiiwvalsn0S0EhdgZEA qxBbP+2DqOE61JnbM5RL+P1fIk4XySHm+Q6thReLeCzpXsh8EmFIfhQYL48ycYuieK77 kQVCFy2CvTzoRfzbugs/yO+f/GubXbDPBdaH3AgySU391XKHEva4Rr9vmU+NgZn/GQd/ ZKOw== X-Gm-Message-State: AOJu0Yz6+MFLXsm00arbGCLjv5TZDIudaviKYHCy7p8sbzSto9KqtCgU +MJU8g9BRVrCTaB9Dxq1l06T1RXUgOpodwAaTR8pJNdk7LuYENKgVRu8j8/cYic= X-Google-Smtp-Source: AGHT+IGKUsffdrHxIzE3d/DHgSZsNCzr99MSQUpTOnVUppTgmwqbTml2vivywG1w9+5uvpycTOzW0Q== X-Received: by 2002:a17:90a:7e8f:b0:2d1:ca16:5555 with SMTP id 98e67ed59e1d1-2dd80ced348mr6893626a91.37.1726913314209; Sat, 21 Sep 2024 03:08:34 -0700 (PDT) Received: from JRT-PC.. ([203.116.176.98]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dd6ee7c03fsm5680024a91.11.2024.09.21.03.08.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Sep 2024 03:08:33 -0700 (PDT) From: James Raphael Tiovalen To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: andrew.jones@linux.dev, atishp@rivosinc.com, cade.richard@berkeley.edu, James Raphael Tiovalen Subject: [kvm-unit-tests PATCH v5 1/5] riscv: Rewrite hartid_to_cpu in assembly Date: Sat, 21 Sep 2024 18:08:19 +0800 Message-ID: <20240921100824.151761-2-jamestiotio@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240921100824.151761-1-jamestiotio@gmail.com> References: <20240921100824.151761-1-jamestiotio@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Andrew Jones Some SBI HSM tests run without a stack being setup so they can't run C code. Those tests still need to know the corresponding cpuid for the hartid on which they are running. Give those tests hartid_to_cpu() by reimplementing it in assembly. Signed-off-by: Andrew Jones Signed-off-by: James Raphael Tiovalen --- lib/riscv/asm-offsets.c | 5 +++++ lib/riscv/setup.c | 10 ---------- riscv/cstart.S | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/riscv/asm-offsets.c b/lib/riscv/asm-offsets.c index a2a32438..6c511c14 100644 --- a/lib/riscv/asm-offsets.c +++ b/lib/riscv/asm-offsets.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include #include +#include #include #include @@ -58,5 +59,9 @@ int main(void) OFFSET(SECONDARY_FUNC, secondary_data, func); DEFINE(SECONDARY_DATA_SIZE, sizeof(struct secondary_data)); + OFFSET(THREAD_INFO_CPU, thread_info, cpu); + OFFSET(THREAD_INFO_HARTID, thread_info, hartid); + DEFINE(THREAD_INFO_SIZE, sizeof(struct thread_info)); + return 0; } diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c index 495db041..f347ad63 100644 --- a/lib/riscv/setup.c +++ b/lib/riscv/setup.c @@ -43,16 +43,6 @@ uint64_t timebase_frequency; static struct mem_region riscv_mem_regions[NR_MEM_REGIONS + 1]; -int hartid_to_cpu(unsigned long hartid) -{ - int cpu; - - for_each_present_cpu(cpu) - if (cpus[cpu].hartid == hartid) - return cpu; - return -1; -} - static void cpu_set_fdt(int fdtnode __unused, u64 regval, void *info __unused) { int cpu = nr_cpus++; diff --git a/riscv/cstart.S b/riscv/cstart.S index 8f269997..68717370 100644 --- a/riscv/cstart.S +++ b/riscv/cstart.S @@ -109,6 +109,30 @@ halt: 1: wfi j 1b +/* + * hartid_to_cpu + * a0 is a hartid on entry + * Returns, in a0, the corresponding cpuid, or -1 if no + * thread_info struct with 'hartid' is found. + */ +.balign 4 +.global hartid_to_cpu +hartid_to_cpu: + la t0, cpus + la t1, nr_cpus + lw t1, 0(t1) + li t2, 0 +1: bne t2, t1, 2f + li a0, -1 + ret +2: REG_L t3, THREAD_INFO_HARTID(t0) + bne a0, t3, 3f + lw a0, THREAD_INFO_CPU(t0) + ret +3: addi t0, t0, THREAD_INFO_SIZE + addi t2, t2, 1 + j 1b + .balign 4 .global secondary_entry secondary_entry: From patchwork Sat Sep 21 10:08:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Raphael Tiovalen X-Patchwork-Id: 13808873 Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com [209.85.215.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFA0D7462 for ; Sat, 21 Sep 2024 10:08:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913320; cv=none; b=Vm4U2Oni6Uj4UNksEJHDC5WUJK+eMnWObFjnYirYRO7uYC2f/u9hoY/dquipMEeqX/L7kV6dPyKGUm3Em7hRojNk+cMipENIb9bsfRaUClxqSsZOLPppOtV2DzQaPoEgYsy54It6xfxn32cjWhf4NshojGziFEslSlmf0ob3umM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913320; c=relaxed/simple; bh=pnN0wsT5QO1IWAGer83Fj0sSV3v3Hf7B4cXSIPuDRcY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fjfhdlBbiOblgxS9+1vDNP6WL4wQaW+92Jnfkxn+y8XYZIRz5GGyxCKVMRfh65eAPDkNY7lKluppvMxF+GulKty+WCc2bgkSbeG+96rwOi5WB2prM2ZbdUtfTcwz41coGSi93cRCJwosDu95UKu3oZIT9Y3KI9GoSmNBXYH3jrQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BRXBgqdk; arc=none smtp.client-ip=209.85.215.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BRXBgqdk" Received: by mail-pg1-f176.google.com with SMTP id 41be03b00d2f7-7cf5e179b68so2427318a12.1 for ; Sat, 21 Sep 2024 03:08:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726913317; x=1727518117; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UJdVfx/CtG7GsoMRDoYaQc5sG4VZUAB77/RAuJ5eHsk=; b=BRXBgqdkp/j402MD2Ne927mj6p4NPGhf0gv8ZMUyvdMjZYFhuLe+6fWNWOeWqgU9MB BpT9SJU5vNaRDjqjTTzzxc1FzZ4CznkGZWvGLPkgot5zXw1Zf8JIis9gcVwurttChVHc KQwhtJKe2gG3suKJYQZQ12ziR3YX8URUVN01D9EleXzbK+1baprbIjMd3810XIIUTiMt PKtsNE8iNFpRWUBHrEt74Ti91MwLdgpPCW4908BB4GOIx0QvnRHxhNJL3Ijs0MlPF0EU rkolHfF5373VQbnFIl8Mefp4WnvW0RFcmb6VbjV8UDC8AmD6qrYaBkVH265drs6/OVEO tEeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726913317; x=1727518117; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UJdVfx/CtG7GsoMRDoYaQc5sG4VZUAB77/RAuJ5eHsk=; b=M8uG3foZZ6I5bq0hZj+2klleDCZaVcth2paQEWQWaBAy38gsbJrQ2vOzqu+Hql3649 x07+MnnMVgLozkxXyYn6pP2RMjP3hvY86Y56pU8yS08unDFJobS4V6PUw/i1LIMFcryt MrSGlZvHlcVPbYwF/feho6QQpKEReaqgsObWQrOzEDmJFCozfnXOPqMicYmeb6vUHrnv wEiHECnZYLxBK+W9ck/jng1F+4EqnyNdNpmshubtdEfR8CcKNoJL4k3lyw4xGoUGkhLf 6AiBaLJgW+SBXBPYzI7TB2loV6ZnRxYpV/EfJaOH+TLreHyNQtbL/CwjlCNkZJVxwL65 f4vA== X-Gm-Message-State: AOJu0YzZn5iaG4QoTwD8PdrQbe87KMDWS+H1hoPORE9wxOdOWHQutWzX HS7Xsg1Eq4Q9ZS7xLxZTuHLWx9xezSoaBWXW7XKMHfvZNkOUyw9F4PXsqH2GG+Y= X-Google-Smtp-Source: AGHT+IFtu3T1HLYQLvnDw2+j7zkRNFc+AqSVwVetbu/CGynIPlNRQSNPqI6+AkVybKDGMUU1fCsCZA== X-Received: by 2002:a17:90b:1286:b0:2d8:7a63:f9c8 with SMTP id 98e67ed59e1d1-2dd6ce9b501mr14726309a91.14.1726913317187; Sat, 21 Sep 2024 03:08:37 -0700 (PDT) Received: from JRT-PC.. ([203.116.176.98]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dd6ee7c03fsm5680024a91.11.2024.09.21.03.08.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Sep 2024 03:08:36 -0700 (PDT) From: James Raphael Tiovalen To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: andrew.jones@linux.dev, atishp@rivosinc.com, cade.richard@berkeley.edu, James Raphael Tiovalen Subject: [kvm-unit-tests PATCH v5 2/5] riscv: sbi: Provide entry point for HSM tests Date: Sat, 21 Sep 2024 18:08:20 +0800 Message-ID: <20240921100824.151761-3-jamestiotio@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240921100824.151761-1-jamestiotio@gmail.com> References: <20240921100824.151761-1-jamestiotio@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The HSM tests will need to test HSM start and resumption from HSM suspend. Provide an entry point written in assembly that doesn't use a stack for this. Results of the test are written to global per-hart arrays to be checked by the main SBI HSM test function. The started/resumed hart does its checks and then just loops until it gets a signal from the main SBI HSM test function to invoke HSM stop. Signed-off-by: James Raphael Tiovalen Co-developed-by: Andrew Jones Signed-off-by: Andrew Jones --- riscv/Makefile | 3 +- riscv/sbi-tests.h | 10 +++++++ riscv/sbi-asm.S | 71 +++++++++++++++++++++++++++++++++++++++++++++++ riscv/sbi.c | 5 ++++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 riscv/sbi-tests.h create mode 100644 riscv/sbi-asm.S diff --git a/riscv/Makefile b/riscv/Makefile index 2ee7c5bb..4676d262 100644 --- a/riscv/Makefile +++ b/riscv/Makefile @@ -43,6 +43,7 @@ cflatobjs += lib/riscv/timer.o ifeq ($(ARCH),riscv32) cflatobjs += lib/ldiv32.o endif +cflatobjs += riscv/sbi-asm.o ######################################## @@ -80,7 +81,7 @@ CFLAGS += -mcmodel=medany CFLAGS += -std=gnu99 CFLAGS += -ffreestanding CFLAGS += -O2 -CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/libfdt -I lib +CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/libfdt -I lib -I $(SRCDIR)/riscv asm-offsets = lib/riscv/asm-offsets.h include $(SRCDIR)/scripts/asm-offsets.mak diff --git a/riscv/sbi-tests.h b/riscv/sbi-tests.h new file mode 100644 index 00000000..f5cc8635 --- /dev/null +++ b/riscv/sbi-tests.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _RISCV_SBI_TESTS_H_ +#define _RISCV_SBI_TESTS_H_ + +#define SBI_HSM_TEST_DONE (1 << 0) +#define SBI_HSM_TEST_HARTID_A1 (1 << 1) +#define SBI_HSM_TEST_SATP (1 << 2) +#define SBI_HSM_TEST_SIE (1 << 3) + +#endif /* _RISCV_SBI_TESTS_H_ */ diff --git a/riscv/sbi-asm.S b/riscv/sbi-asm.S new file mode 100644 index 00000000..f165f9da --- /dev/null +++ b/riscv/sbi-asm.S @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Helper assembly code routines for RISC-V SBI extension tests. + * + * Copyright (C) 2024, James Raphael Tiovalen + */ +#define __ASSEMBLY__ +#include + +#include "sbi-tests.h" + +.section .text + +/* + * sbi_hsm_check + * a0 and a1 are set by SBI HSM start/suspend + * s1 is the address of the results array + * Doesn't return. + * + * This function is only called from HSM start and on resumption + * from HSM suspend which means we can do whatever we like with + * all registers. So, to avoid complicated register agreements with + * other assembly functions called, we just always use the saved + * registers for anything that should be maintained across calls. + */ +#define RESULTS_ARRAY s1 +#define RESULTS_MAP s2 +#define CPU_INDEX s3 +.balign 4 +sbi_hsm_check: + li RESULTS_MAP, 0 + bne a0, a1, 1f + ori RESULTS_MAP, RESULTS_MAP, SBI_HSM_TEST_HARTID_A1 +1: csrr t0, CSR_SATP + bnez t0, 2f + ori RESULTS_MAP, RESULTS_MAP, SBI_HSM_TEST_SATP +2: csrr t0, CSR_SSTATUS + andi t0, t0, SR_SIE + bnez t0, 3f + ori RESULTS_MAP, RESULTS_MAP, SBI_HSM_TEST_SIE +3: call hartid_to_cpu + mv CPU_INDEX, a0 + li t0, -1 + bne CPU_INDEX, t0, 5f +4: pause + j 4b +5: ori RESULTS_MAP, RESULTS_MAP, SBI_HSM_TEST_DONE + add t0, RESULTS_ARRAY, CPU_INDEX + sb RESULTS_MAP, 0(t0) + la t1, sbi_hsm_stop_hart + add t1, t1, CPU_INDEX +6: lb t0, 0(t1) + pause + beqz t0, 6b + li a7, 0x48534d /* SBI_EXT_HSM */ + li a6, 1 /* SBI_EXT_HSM_HART_STOP */ + ecall +7: pause + j 7b + +.balign 4 +.global sbi_hsm_check_hart_start +sbi_hsm_check_hart_start: + la RESULTS_ARRAY, sbi_hsm_hart_start_checks + j sbi_hsm_check + +.balign 4 +.global sbi_hsm_check_non_retentive_suspend +sbi_hsm_check_non_retentive_suspend: + la RESULTS_ARRAY, sbi_hsm_non_retentive_hart_suspend_checks + j sbi_hsm_check diff --git a/riscv/sbi.c b/riscv/sbi.c index a7abc08c..b5147dee 100644 --- a/riscv/sbi.c +++ b/riscv/sbi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -429,6 +430,10 @@ static void check_dbcn(void) report_prefix_popn(2); } +unsigned char sbi_hsm_stop_hart[NR_CPUS]; +unsigned char sbi_hsm_hart_start_checks[NR_CPUS]; +unsigned char sbi_hsm_non_retentive_hart_suspend_checks[NR_CPUS]; + int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "-h")) { From patchwork Sat Sep 21 10:08:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Raphael Tiovalen X-Patchwork-Id: 13808874 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7970716F27F for ; Sat, 21 Sep 2024 10:08:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913322; cv=none; b=fpyAxRj2S8M+n0DAUkR7CdZ5Mno04CUvkmJFDIXhwZZONHwds6gEgiHUhrk9DmJXAG4Rqi/TNxs69FD25IEOjwV8JiQ7XTJKWM2Stq1UsixJarTLVglDSHmf2sMaLx7v2kwH7ejo9sR2wyOSqOW9aUdmKJY70/nm/9QrxGS6MLM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913322; c=relaxed/simple; bh=CAOcGGebaRx1S04DKIJFc1oHsk9PnK/vZ5M7iYx42Oo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lLWVwLNBlmoh2NK8pKrieuNRh5tYtjDrEXVVxGfuNs79iswcVDpbZJ4WkLmyCQS/XhiaVtdqFyDp6V7oZgca+5y1tKuFZGKwMbGaVJwS/74rAxS41PvdYDF5ZZ8BYIwNbvnslWWebwcNjSrzBI/Xy7QeiTqTcMLr6OhKenXKS3c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=X9dMSUCs; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X9dMSUCs" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-71971d20ad9so1955694b3a.3 for ; Sat, 21 Sep 2024 03:08:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726913320; x=1727518120; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=od5yEkBBSMRl70l2ICtIaZs6wNRd82e2Lcyy8jXXe5k=; b=X9dMSUCsUW/8ErHNNrOUcGwcZV7QN3aqz2euUf10d4PQznUsMWZCJF6P8znjMmGV0g v1n8tkV6BhyMdIao8zu+zqoKqX4pxeuLa7tHs0HDx1YXFZW0KPoS1DgY9JzLybvZuMSd WlZnayP5SOS/nLyIwOMP6FrhAu81Ec/TBCXAxDNxpGguHzZKCpmh2pUP+qOtqJl58tRw STX3IlBazE51LeKx3X5SM31cp4WgHH2TDY4DGJeODxx+U9nsCjzcpv+is3qR7/ypWMpQ xPtP+ZVEkYzJ9qTvRbtGm91IiYcZiT2gDlgGg3WP7/mY65vLc8pQeNYLUt5SeX1fFGpE ih7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726913320; x=1727518120; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=od5yEkBBSMRl70l2ICtIaZs6wNRd82e2Lcyy8jXXe5k=; b=GRGf2hV+Z0XymjIz0NJEpw2+uXpT5Xp8ZjHPxiZZLu1/wkNcK0ngFDeEt5W4Lfs8xg facFbL9T3RMrLmKa/tbEfhdSq2hsi/YwUCb9UNW78HOBMARBGmGSPzQ4VVzbVDf72pH9 vmxXq1GYKTArK3xCXTVW57HrNzNRwUuQilRbOyAWmY3p5x6L1YtCWtTAUI9zb+eoPS14 ckHzNvPQQaPeu1l0QPHfyxn0H1uU9qO7fgQn+1e2GOR4wh7PRr1gv23/4gI2QJqy0+53 URSyhfyoOk4/0oWqN409ImHl5hAlTW9An51bLQiWBQXgIm75GreZltA9WERrJC7Y8zbZ OYug== X-Gm-Message-State: AOJu0YxWEKXpr1AHV7mgeYEeRs2COy1lbPWYphEoqdN2XbnmJdbZYVNB HDccyqEVxG+sjB5U/4o41qYp2MeMGsLCGm0r7VwMLm7IwgGczD5MlmcieiH/rt0= X-Google-Smtp-Source: AGHT+IGKS/E2gA+YQYbl1PX33pehG2KROtr1xdO2y1XDw/0CD4KQ3nWvvjMzor0huCIvufYAmqbyyg== X-Received: by 2002:a17:90b:3c83:b0:2cb:4c32:a7e4 with SMTP id 98e67ed59e1d1-2dd7f4270ccmr7201493a91.15.1726913320042; Sat, 21 Sep 2024 03:08:40 -0700 (PDT) Received: from JRT-PC.. ([203.116.176.98]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dd6ee7c03fsm5680024a91.11.2024.09.21.03.08.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Sep 2024 03:08:39 -0700 (PDT) From: James Raphael Tiovalen To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: andrew.jones@linux.dev, atishp@rivosinc.com, cade.richard@berkeley.edu, James Raphael Tiovalen Subject: [kvm-unit-tests PATCH v5 3/5] lib/on-cpus: Add helper method to clear the function from on_cpu_info Date: Sat, 21 Sep 2024 18:08:21 +0800 Message-ID: <20240921100824.151761-4-jamestiotio@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240921100824.151761-1-jamestiotio@gmail.com> References: <20240921100824.151761-1-jamestiotio@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When a CPU abruptly stops during some test, the CPU will not have the chance to go back to the do_idle() loop and set the on_cpu_info[cpu].func variable to NULL. Add a helper method for some test manager CPU to clear this function. This would re-enable on_cpu_async and allow future tests to use the on-cpus API again. Signed-off-by: James Raphael Tiovalen --- lib/on-cpus.h | 1 + lib/on-cpus.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/on-cpus.h b/lib/on-cpus.h index 4bc6236d..497ff9d1 100644 --- a/lib/on-cpus.h +++ b/lib/on-cpus.h @@ -13,5 +13,6 @@ void on_cpu(int cpu, void (*func)(void *data), void *data); void on_cpus(void (*func)(void *data), void *data); void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data); void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data); +void on_cpu_clear_func(int cpu); #endif /* _ON_CPUS_H_ */ diff --git a/lib/on-cpus.c b/lib/on-cpus.c index 89214933..cc73690a 100644 --- a/lib/on-cpus.c +++ b/lib/on-cpus.c @@ -171,3 +171,14 @@ void on_cpus(void (*func)(void *data), void *data) { on_cpumask(&cpu_present_mask, func, data); } + +void on_cpu_clear_func(int cpu) +{ + for (;;) { + if (get_on_cpu_info(cpu)) + break; + } + + on_cpu_info[cpu].func = NULL; + put_on_cpu_info(cpu); +} From patchwork Sat Sep 21 10:08:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Raphael Tiovalen X-Patchwork-Id: 13808875 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D139516FF45 for ; Sat, 21 Sep 2024 10:08:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913325; cv=none; b=H1x2W6yopaUZOswrLxXcFzdWy6kXZI7a5+U1S2RetEnvoJdmDtqGpEBIst6rEgldyXfuO0NpnqDdBENdfSsjEOZTQktgFQslSMQsj5jPRmhQmgGrva6Dy32g3KhxAdfDeVNJF93e5sDpP1sdvbnYQ90sSwjIigLg7rB9CUWZoKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913325; c=relaxed/simple; bh=IMfRddgxO+Ck7w1rZ7mJX/ULuUtwX0ZdE2OumGDsgHQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ODcWA90KO2AvCht4uhi+yd2mzyKsmwaPuXjsw7FKjmd8Vf/2tXvm/1wjHojFpo4rr5BBMOw3LC7oB1Rms3G4oJ53aNA4uTX8j/eNZnyuQX3ebrf9FPkjHWfE2wDV6RAfKdv7nlQV1QRJ3yuQyhPt6ib6gZ+fN52b+QubrVbcoW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=njxzkdNL; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="njxzkdNL" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-7d4f9e39c55so2030129a12.2 for ; Sat, 21 Sep 2024 03:08:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726913323; x=1727518123; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wKeR26fKWW24AqGwklYBuZ/CX5RZfiOMbUMOXvSoTdQ=; b=njxzkdNLBctPvYXNw4h2aiRnUyrxYdfjAiB7joKE3bqFA+ZyuREfqpihy0mbpyeu/l T2IbZvKej4l6WNNhJeuoiOrF8fopWLLiQCkayrPSlMHvOkGfF08fLsrk41uiFKX7m4iC u3JcJTEWFbyErOCBdF70fC3Vxj8phsodl7saWcVcM9lNA5uXGpvPuCZlTYDbNmkaqPsl Y4ZdQ4VL04oEoc57ZcQo8IMwSMi9/6+909wefdYbRmC01zIa65qfzNTmeiYOCLaxFsxd QNYStr4TkXNS2bhZUSKLlsKzzjOAHoA9LrlawcukvPKwjKKrhkyefndwpN2xVYEXjlgu PQwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726913323; x=1727518123; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wKeR26fKWW24AqGwklYBuZ/CX5RZfiOMbUMOXvSoTdQ=; b=l1cx8ybbJ7wBSNldVGK/Xcb3yAxpzq5rFSDOGXRWXwRl7qkYSE2136oSNQfJ8V3JlC R6+qQtM2I0PzBSx7FEnl3KRbaT4pStTEYE1xXFDoOM9tXNki4AO3BNFoblAHYszqkD3P k2r3BHUvjzNQClLzgr+0+nKvalvTt5tnEINT0S0CXOlZ9wsqVks3n5I65TTDiondafr6 pUyJ8Yr1bcz7zL9cMK0qWgmNfYmbW2prc+z5PHysemild3cpVwePk/xR3t4SvqXOMFEI xn2oHjzRl+Ha16Llt72dIV+GG1qkJevDqz3ShpA8FU9UoSkqRDn61cpx1e++giACdmM3 gLjg== X-Gm-Message-State: AOJu0YxbjbIOb70lL1ADwJguKJy1uiGAKAZYENyGJnsLENJ4Knvjpjj6 Ap+klAlHPtNoaMzHTCacSpCZGIPZGX1JKVWy0ShhLbnCZjUS+N25EqO7zZJR3y0= X-Google-Smtp-Source: AGHT+IFqEt+sAml1MwSoxe/AAbU+GYbDUS6+AJasT6OAnDfupYS56nbuVhq6qnLPs//IFiu9+aoRkA== X-Received: by 2002:a17:90a:62c1:b0:2d3:dca0:89b7 with SMTP id 98e67ed59e1d1-2dd7f38132fmr6611862a91.3.1726913322867; Sat, 21 Sep 2024 03:08:42 -0700 (PDT) Received: from JRT-PC.. ([203.116.176.98]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dd6ee7c03fsm5680024a91.11.2024.09.21.03.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Sep 2024 03:08:42 -0700 (PDT) From: James Raphael Tiovalen To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: andrew.jones@linux.dev, atishp@rivosinc.com, cade.richard@berkeley.edu, James Raphael Tiovalen Subject: [kvm-unit-tests PATCH v5 4/5] riscv: Add helper method to set cpu started mask Date: Sat, 21 Sep 2024 18:08:22 +0800 Message-ID: <20240921100824.151761-5-jamestiotio@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240921100824.151761-1-jamestiotio@gmail.com> References: <20240921100824.151761-1-jamestiotio@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When a CPU abruptly stops during the RISC-V SBI hart stop tests, it is considered to be offline. As such, it should be removed from the cpu_started mask so that future tests can initiate another smp_boot_secondary. Add a helper method to allow the RISC-V SBI boot hart to remove a dead CPU from the mask. Signed-off-by: James Raphael Tiovalen --- lib/riscv/asm/smp.h | 2 ++ lib/riscv/smp.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/riscv/asm/smp.h b/lib/riscv/asm/smp.h index b3ead4e8..5d379a7a 100644 --- a/lib/riscv/asm/smp.h +++ b/lib/riscv/asm/smp.h @@ -26,4 +26,6 @@ secondary_func_t secondary_cinit(struct secondary_data *data); void smp_boot_secondary(int cpu, void (*func)(void)); void smp_boot_secondary_nofail(int cpu, void (*func)(void)); +void set_cpu_started(int cpu, bool started); + #endif /* _ASMRISCV_SMP_H_ */ diff --git a/lib/riscv/smp.c b/lib/riscv/smp.c index eb7061ab..eb7cfb72 100644 --- a/lib/riscv/smp.c +++ b/lib/riscv/smp.c @@ -74,3 +74,11 @@ void smp_boot_secondary_nofail(int cpu, void (*func)(void)) while (!cpu_online(cpu)) smp_wait_for_event(); } + +void set_cpu_started(int cpu, bool started) +{ + if (started) + cpumask_set_cpu(cpu, &cpu_started); + else + cpumask_clear_cpu(cpu, &cpu_started); +} From patchwork Sat Sep 21 10:08:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Raphael Tiovalen X-Patchwork-Id: 13808876 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6EC2516EB65 for ; Sat, 21 Sep 2024 10:08:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913329; cv=none; b=kSKzDBddWerGEsAxuOFnInaNIRJp1TuTF7uA46LMIvaGZ4oZLt5x83W98uRyOVZcuhXo5IIIid5f1CADmbBWYYlNUxya9tTZ0QRRJVCn5h6obcQckbp/sseJSpEHPZ3/yaHve4Ju36uVjuWRq4tugEwAZWsizfnUpFjT7X5zRnU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726913329; c=relaxed/simple; bh=WlQf6rnK1VV2Fcd/ihNeaXW+w+TYvrWKNBMI7YjTaHU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cRUxPw7O9OCeWwGgqb1pvarIdYDQ2i9PgyGIWIGfEkXk8kYtGWm14DBmnci5xIeDS+TUaEAGuSQVb7jOK5g80LfR5IszYuEOYuwzeJooobxeaF0YO57kaQ09hHm/KbMRGbDCUDf6My1yzkA0FTlZakBKHQDRFQbiTZnAAcUyp4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZjO31WdA; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZjO31WdA" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-71971d20a95so1993939b3a.3 for ; Sat, 21 Sep 2024 03:08:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726913326; x=1727518126; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Gh0oI/atX+NM3kjZRs6CAv7WW1PdJeWlMXibH7CAlQM=; b=ZjO31WdA0u91S9VcXDZcozw9MLcKmaw+k6/6Doc6xIcsV/0agTv186cig8iq04JTLE XuECNKiLHu/Hmd1p5G4mnXpq7UlThHoYGP0qwH3dQzk4ss1r6nrPUFHUJs9HaApzwWLK YiP2S0EO5FORS+4NlOQ88hRw2ZTgYZbOOHIwbigyGyAP8F8hb2J41noYcrZjNZ4K5Aev nI6N3BqFzCe8qQr0LQrAbLpfh1tStM5j6pYSh5nD1nFsjJD8aO273fYYWYRUgCJT62Qa NSDX5eqQmK3mLBYgFu/jYnp7cKQKdpnw96t8Ofs2mkR3BytCOy0N4zdEFt87dLBLGMl7 IQPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726913326; x=1727518126; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Gh0oI/atX+NM3kjZRs6CAv7WW1PdJeWlMXibH7CAlQM=; b=ep16ZhUVmlStK2aeXyXIOsFOZZC4fmabRGkApRypkSyJnTzYXDj1i4+NMBtJtRtPTd ipCvJdcPLZUS/qRDDP7lMwfMPj7PFR89+7Xvx+jOuCVNzv9mpH2HiQU+VMrxVjp86kuI bvmNHO4tp2Q8Qzu/CmHvhpJ82IpwfguDi1Bojdn9AlvvKITYizRozH6rzlmYHlQ+pdzq t4KWYL0LLkCcM2qVzHWmXHtnId6d7IgwqZsCO4zpYTLwWUVO00SD6k6X4l+H7qU7/rEx 4IgVlbg4Weu9r2m2dloKuQDEoc7vyf7FhD6DShnjtcktKU9384zL8GJS5UONgzFum7VF qppQ== X-Gm-Message-State: AOJu0YyYB2UzJjTPDSZ7bdDg5kVwRe+srbypje9KcsDob4oakblaZ+Lz ngfWQIc8+/zDNVEFk7r+v9SPbYGn9nVUQfsujFyEPisnH2e1bNMzDsSO5uaVLU4= X-Google-Smtp-Source: AGHT+IFmQ1WIJjK7hdvJekNzrqonXR7dlnFDzaYWcvcdWQRkVPk13MzEkqtY8CWNy3VmJUEnD7d8CQ== X-Received: by 2002:a17:90b:184f:b0:2d3:db53:5577 with SMTP id 98e67ed59e1d1-2dd7f71a85emr7402814a91.36.1726913325935; Sat, 21 Sep 2024 03:08:45 -0700 (PDT) Received: from JRT-PC.. ([203.116.176.98]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dd6ee7c03fsm5680024a91.11.2024.09.21.03.08.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Sep 2024 03:08:45 -0700 (PDT) From: James Raphael Tiovalen To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: andrew.jones@linux.dev, atishp@rivosinc.com, cade.richard@berkeley.edu, James Raphael Tiovalen Subject: [kvm-unit-tests PATCH v5 5/5] riscv: sbi: Add tests for HSM extension Date: Sat, 21 Sep 2024 18:08:23 +0800 Message-ID: <20240921100824.151761-6-jamestiotio@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240921100824.151761-1-jamestiotio@gmail.com> References: <20240921100824.151761-1-jamestiotio@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add some tests for all of the HSM extension functions. These tests ensure that the HSM extension functions follow the behavior as described in the SBI specification. Signed-off-by: James Raphael Tiovalen --- riscv/sbi.c | 648 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 648 insertions(+) diff --git a/riscv/sbi.c b/riscv/sbi.c index b5147dee..cd1ed95b 100644 --- a/riscv/sbi.c +++ b/riscv/sbi.c @@ -6,6 +6,8 @@ */ #include #include +#include +#include #include #include #include @@ -16,12 +18,15 @@ #include #include #include +#include #include #include #include #include #include +#include "sbi-tests.h" + #define HIGH_ADDR_BOUNDARY ((phys_addr_t)1 << 32) static void help(void) @@ -47,6 +52,11 @@ static struct sbiret sbi_dbcn_write_byte(uint8_t byte) return sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE_BYTE, byte, 0, 0, 0, 0, 0); } +static struct sbiret sbi_hart_suspend(uint32_t suspend_type, unsigned long resume_addr, unsigned long opaque) +{ + return sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND, suspend_type, resume_addr, opaque, 0, 0, 0); +} + static void split_phys_addr(phys_addr_t paddr, unsigned long *hi, unsigned long *lo) { *lo = (unsigned long)paddr; @@ -433,6 +443,643 @@ static void check_dbcn(void) unsigned char sbi_hsm_stop_hart[NR_CPUS]; unsigned char sbi_hsm_hart_start_checks[NR_CPUS]; unsigned char sbi_hsm_non_retentive_hart_suspend_checks[NR_CPUS]; +cpumask_t sbi_hsm_started_hart_checks; +static bool sbi_hsm_invalid_hartid_check; +static bool sbi_hsm_timer_fired; +extern void sbi_hsm_check_hart_start(void); +extern void sbi_hsm_check_non_retentive_suspend(void); + +static void hsm_timer_irq_handler(struct pt_regs *regs) +{ + sbi_hsm_timer_fired = true; + timer_stop(); +} + +static void hsm_timer_setup(void) +{ + install_irq_handler(IRQ_S_TIMER, hsm_timer_irq_handler); + local_irq_enable(); + timer_irq_enable(); +} + +static void hsm_timer_teardown(void) +{ + timer_irq_disable(); + local_irq_disable(); + install_irq_handler(IRQ_S_TIMER, NULL); +} + +static void hart_empty_fn(void *data) {} + +static void hart_execute(void *data) +{ + struct sbiret ret; + unsigned long hartid = current_thread_info()->hartid; + int me = smp_processor_id(); + + ret = sbi_hart_start(hartid, virt_to_phys(&hart_empty_fn), 0); + + if (ret.error == SBI_ERR_ALREADY_AVAILABLE) + cpumask_set_cpu(me, &sbi_hsm_started_hart_checks); +} + +static void hart_start_invalid_hartid(void *data) +{ + struct sbiret ret; + + ret = sbi_hart_start(ULONG_MAX, virt_to_phys(&hart_empty_fn), 0); + + if (ret.error == SBI_ERR_INVALID_PARAM) + sbi_hsm_invalid_hartid_check = true; +} + +static void hart_stop(void *data) +{ + unsigned long hartid = current_thread_info()->hartid; + struct sbiret ret = sbi_hart_stop(); + + report_fail("failed to stop hart %ld (error=%ld)", hartid, ret.error); +} + +static void hart_retentive_suspend(void *data) +{ + unsigned long hartid = current_thread_info()->hartid; + struct sbiret ret = sbi_hart_suspend(SBI_EXT_HSM_HART_SUSPEND_RETENTIVE, 0, 0); + + if (ret.error) + report_fail("failed to retentive suspend hart %ld (error=%ld)", hartid, ret.error); +} + +static void hart_non_retentive_suspend(void *data) +{ + unsigned long hartid = current_thread_info()->hartid; + + /* Set opaque as hartid so that we can check a0 == a1, ensuring that a0 is hartid and a1 is opaque */ + struct sbiret ret = sbi_hart_suspend(SBI_EXT_HSM_HART_SUSPEND_NON_RETENTIVE, + virt_to_phys(&sbi_hsm_check_non_retentive_suspend), hartid); + + report_fail("failed to non-retentive suspend hart %ld (error=%ld)", hartid, ret.error); +} + +static void hart_retentive_suspend_with_msb_set(void *data) +{ + unsigned long hartid = current_thread_info()->hartid; + unsigned long suspend_type = SBI_EXT_HSM_HART_SUSPEND_RETENTIVE | (_AC(1, UL) << (__riscv_xlen - 1)); + struct sbiret ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND, suspend_type, 0, 0, 0, 0, 0); + + if (ret.error) + report_fail("failed to retentive suspend hart %ld with MSB set (error=%ld)", hartid, ret.error); +} + +static void hart_non_retentive_suspend_with_msb_set(void *data) +{ + unsigned long hartid = current_thread_info()->hartid; + unsigned long suspend_type = SBI_EXT_HSM_HART_SUSPEND_NON_RETENTIVE | (_AC(1, UL) << (__riscv_xlen - 1)); + + /* Set opaque as hartid so that we can check a0 == a1, ensuring that a0 is hartid and a1 is opaque */ + struct sbiret ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND, suspend_type, + virt_to_phys(&sbi_hsm_check_non_retentive_suspend), hartid, 0, 0, 0); + + report_fail("failed to non-retentive suspend hart %ld with MSB set (error=%ld)", hartid, ret.error); +} + +static bool hart_wait_on_status(unsigned long hartid, enum sbi_ext_hsm_sid status, unsigned long duration) +{ + struct sbiret ret; + + sbi_hsm_timer_fired = false; + timer_start(duration); + + ret = sbi_hart_get_status(hartid); + + while (!ret.error && ret.value == status && !sbi_hsm_timer_fired) { + cpu_relax(); + ret = sbi_hart_get_status(hartid); + } + + timer_stop(); + + if (sbi_hsm_timer_fired) + report_info("timer fired while waiting on status %u for hart %ld", status, hartid); + else if (ret.error) + report_fail("got %ld while waiting on status %u for hart %ld\n", ret.error, status, hartid); + + return sbi_hsm_timer_fired || ret.error; +} + +static void check_hsm(void) +{ + struct sbiret ret; + unsigned long hartid; + cpumask_t secondary_cpus_mask, hsm_start, hsm_stop, hsm_suspend, hsm_resume, hsm_check; + bool ipi_unavailable = false; + bool suspend_with_msb = false, resume_with_msb = false, check_with_msb = false, stop_with_msb = false; + int cpu, me = smp_processor_id(); + int max_cpus = getenv("SBI_MAX_CPUS") ? strtol(getenv("SBI_MAX_CPUS"), NULL, 0) : nr_cpus; + unsigned long hsm_timer_duration = getenv("SBI_HSM_TIMER_DURATION") + ? strtol(getenv("SBI_HSM_TIMER_DURATION"), NULL, 0) : 200000; + + max_cpus = MIN(max_cpus, nr_cpus); + + report_prefix_push("hsm"); + + if (!sbi_probe(SBI_EXT_HSM)) { + report_skip("hsm extension not available"); + report_prefix_pop(); + return; + } + + report_prefix_push("hart_get_status"); + + hartid = current_thread_info()->hartid; + ret = sbi_hart_get_status(hartid); + + if (ret.error) { + report_fail("failed to get status of current hart (error=%ld)", ret.error); + report_prefix_popn(2); + return; + } else if (ret.value != SBI_EXT_HSM_STARTED) { + report_fail("current hart is not started (ret.value=%ld)", ret.value); + report_prefix_popn(2); + return; + } + + report_pass("status of current hart is started"); + + for_each_present_cpu(cpu) { + if (sbi_hart_get_status(cpus[cpu].hartid).error == SBI_ERR_INVALID_PARAM) + set_cpu_present(cpu, false); + } + + report(cpumask_weight(&cpu_present_mask) == nr_cpus, "all present harts have valid hartids"); + + report_prefix_pop(); + + if (max_cpus < 2) { + report_skip("no other cpus to run the remaining hsm tests on"); + report_prefix_pop(); + return; + } + + report_prefix_push("hart_start"); + + cpumask_copy(&secondary_cpus_mask, &cpu_present_mask); + cpumask_clear_cpu(me, &secondary_cpus_mask); + hsm_timer_setup(); + + cpumask_clear(&hsm_start); + cpumask_clear(&hsm_check); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + /* Set opaque as hartid so that we can check a0 == a1, ensuring that a0 is hartid and a1 is opaque */ + ret = sbi_hart_start(hartid, virt_to_phys(&sbi_hsm_check_hart_start), hartid); + if (ret.error) { + report_fail("failed to start test hart %ld (error=%ld)", hartid, ret.error); + continue; + } + + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STOPPED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_START_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) { + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + continue; + } else if (ret.value != SBI_EXT_HSM_STARTED) { + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + continue; + } else { + cpumask_set_cpu(cpu, &hsm_start); + } + + sbi_hsm_timer_fired = false; + timer_start(hsm_timer_duration); + + while (!(READ_ONCE(sbi_hsm_hart_start_checks[cpu]) & SBI_HSM_TEST_DONE) && !sbi_hsm_timer_fired) + cpu_relax(); + + timer_stop(); + + if (sbi_hsm_timer_fired) { + report_info("hsm timer fired before hart %ld is done with start checks", hartid); + continue; + } + + if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_SATP)) + report_info("satp is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_SIE)) + report_info("sstatus.SIE is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_HARTID_A1)) + report_info("either a0 or a1 is not hartid for test hart %ld", hartid); + else + cpumask_set_cpu(cpu, &hsm_check); + } + + report(cpumask_weight(&hsm_start) == max_cpus - 1, "all secondary harts started"); + report(cpumask_weight(&hsm_check) == max_cpus - 1, + "all secondary harts have expected register values after hart start"); + + report_prefix_pop(); + + report_prefix_push("hart_stop"); + + memset(sbi_hsm_stop_hart, 1, sizeof(sbi_hsm_stop_hart)); + + cpumask_clear(&hsm_stop); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STOP_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STOPPED) + report_info("hart %ld status is not 'stopped' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_stop); + } + + report(cpumask_weight(&hsm_stop) == max_cpus - 1, "all secondary harts stopped"); + + /* Reset the stop flags so that we can reuse them after suspension tests */ + memset(sbi_hsm_stop_hart, 0, sizeof(sbi_hsm_stop_hart)); + + report_prefix_pop(); + + report_prefix_push("hart_start"); + + /* Select just one secondary cpu to run the invalid hartid test */ + on_cpu(cpumask_next(-1, &secondary_cpus_mask), hart_start_invalid_hartid, NULL); + + report(sbi_hsm_invalid_hartid_check, "secondary hart refuse to start with invalid hartid"); + + on_cpumask_async(&secondary_cpus_mask, hart_execute, NULL); + + cpumask_clear(&hsm_start); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STOPPED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_START_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STARTED) + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_start); + } + + report(cpumask_weight(&hsm_start) == max_cpus - 1, "all secondary harts started"); + + sbi_hsm_timer_fired = false; + timer_start(hsm_timer_duration); + + while (cpumask_weight(&cpu_idle_mask) != max_cpus - 1 && !sbi_hsm_timer_fired) + cpu_relax(); + + timer_stop(); + + if (sbi_hsm_timer_fired) + report_info("hsm timer fired before all secondary harts started"); + + report(cpumask_weight(&cpu_idle_mask) == max_cpus - 1, + "all secondary harts successfully executed code after start"); + report(cpumask_weight(&cpu_online_mask) == max_cpus, "all secondary harts online"); + report(cpumask_weight(&sbi_hsm_started_hart_checks) == max_cpus - 1, + "all secondary harts are already started"); + + report_prefix_pop(); + + report_prefix_push("hart_suspend"); + + if (!sbi_probe(SBI_EXT_IPI)) { + report_skip("skipping suspension tests since ipi extension is unavailable"); + report_prefix_pop(); + ipi_unavailable = true; + goto sbi_hsm_hart_stop_tests; + } + + on_cpumask_async(&secondary_cpus_mask, hart_retentive_suspend, NULL); + + cpumask_clear(&hsm_suspend); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPEND_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_SUSPENDED) + report_info("hart %ld status is not 'suspended' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_suspend); + } + + report(cpumask_weight(&hsm_suspend) == max_cpus - 1, "all secondary harts retentive suspended"); + + /* Ignore the return value since we check the status of each hart anyway */ + sbi_send_ipi_cpumask(&secondary_cpus_mask); + + cpumask_clear(&hsm_resume); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPENDED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_RESUME_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STARTED) + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_resume); + } + + report(cpumask_weight(&hsm_resume) == max_cpus - 1, "all secondary harts retentive resumed"); + + sbi_hsm_timer_fired = false; + timer_start(hsm_timer_duration); + + while (cpumask_weight(&cpu_idle_mask) != max_cpus - 1 && !sbi_hsm_timer_fired) + cpu_relax(); + + timer_stop(); + + if (sbi_hsm_timer_fired) + report_info("hsm timer fired before all secondary harts retentive resumed"); + + report(cpumask_weight(&cpu_idle_mask) == max_cpus - 1, + "all secondary harts successfully executed code after retentive suspend"); + report(cpumask_weight(&cpu_online_mask) == max_cpus, + "all secondary harts online"); + + on_cpumask_async(&secondary_cpus_mask, hart_non_retentive_suspend, NULL); + + cpumask_clear(&hsm_suspend); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPEND_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_SUSPENDED) + report_info("hart %ld status is not 'suspended' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_suspend); + } + + report(cpumask_weight(&hsm_suspend) == max_cpus - 1, "all secondary harts non-retentive suspended"); + + /* Ignore the return value since we check the status of each hart anyway */ + sbi_send_ipi_cpumask(&secondary_cpus_mask); + + cpumask_clear(&hsm_resume); + cpumask_clear(&hsm_check); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPENDED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_RESUME_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) { + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + continue; + } else if (ret.value != SBI_EXT_HSM_STARTED) { + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + continue; + } else { + cpumask_set_cpu(cpu, &hsm_resume); + } + + sbi_hsm_timer_fired = false; + timer_start(hsm_timer_duration); + + while (!((READ_ONCE(sbi_hsm_non_retentive_hart_suspend_checks[cpu])) & SBI_HSM_TEST_DONE) + && !sbi_hsm_timer_fired) + cpu_relax(); + + timer_stop(); + + if (sbi_hsm_timer_fired) { + report_info("hsm timer fired before hart %ld is done with non-retentive resume checks", + hartid); + continue; + } + + if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SATP)) + report_info("satp is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SIE)) + report_info("sstatus.SIE is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_HARTID_A1)) + report_info("either a0 or a1 is not hartid for test hart %ld", hartid); + else + cpumask_set_cpu(cpu, &hsm_check); + } + + report(cpumask_weight(&hsm_resume) == max_cpus - 1, "all secondary harts non-retentive resumed"); + report(cpumask_weight(&hsm_check) == max_cpus - 1, + "all secondary harts have expected register values after non-retentive resume"); + + report_prefix_pop(); + +sbi_hsm_hart_stop_tests: + report_prefix_push("hart_stop"); + + if (ipi_unavailable) + on_cpumask_async(&secondary_cpus_mask, hart_stop, NULL); + else + memset(sbi_hsm_stop_hart, 1, sizeof(sbi_hsm_stop_hart)); + + cpumask_clear(&hsm_stop); + + for_each_cpu(cpu, &secondary_cpus_mask) { + hartid = cpus[cpu].hartid; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration)) + continue; + if (hart_wait_on_status(hartid, SBI_EXT_HSM_STOP_PENDING, hsm_timer_duration)) + continue; + + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STOPPED) + report_info("hart %ld status is not 'stopped' (ret.value=%ld)", hartid, ret.value); + else + cpumask_set_cpu(cpu, &hsm_stop); + } + + report(cpumask_weight(&hsm_stop) == max_cpus - 1, "all secondary harts stopped"); + + /* Reset the state of the secondary cpus since they did not have a chance to clean up after stopping */ + for_each_cpu(cpu, &secondary_cpus_mask) { + on_cpu_clear_func(cpu); + set_cpu_online(cpu, false); + set_cpu_started(cpu, false); + } + + if (__riscv_xlen == 32 || ipi_unavailable) { + hsm_timer_teardown(); + report_prefix_popn(2); + return; + } + + report_prefix_pop(); + + report_prefix_push("hart_suspend"); + + /* Select just one secondary cpu to run suspension tests with MSB of suspend type being set */ + cpu = cpumask_next(-1, &secondary_cpus_mask); + hartid = cpus[cpu].hartid; + + /* Boot up the secondary cpu and let it proceed to the idle loop */ + on_cpu(cpu, hart_empty_fn, NULL); + + on_cpu_async(cpu, hart_retentive_suspend_with_msb_set, NULL); + + if (!hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration) && + !hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPEND_PENDING, hsm_timer_duration)) { + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_SUSPENDED) + report_info("hart %ld status is not 'suspended' (ret.value=%ld)", hartid, ret.value); + else + suspend_with_msb = true; + } + + report(suspend_with_msb, "secondary hart retentive suspended with MSB set"); + + /* Ignore the return value since we manually validate the status of the hart anyway */ + sbi_send_ipi_cpu(cpu); + + if (!hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPENDED, hsm_timer_duration) && + !hart_wait_on_status(hartid, SBI_EXT_HSM_RESUME_PENDING, hsm_timer_duration)) { + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STARTED) + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + else + resume_with_msb = true; + } + + report(resume_with_msb, "secondary hart retentive resumed with MSB set"); + + /* Reset these flags so that we can reuse them for the non-retentive suspension test */ + suspend_with_msb = false; + resume_with_msb = false; + sbi_hsm_stop_hart[cpu] = 0; + sbi_hsm_non_retentive_hart_suspend_checks[cpu] = 0; + + on_cpu_async(cpu, hart_non_retentive_suspend_with_msb_set, NULL); + + if (!hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration) && + !hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPEND_PENDING, hsm_timer_duration)) { + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_SUSPENDED) + report_info("hart %ld status is not 'suspended' (ret.value=%ld)", hartid, ret.value); + else + suspend_with_msb = true; + } + + report(suspend_with_msb, "secondary hart non-retentive suspended with MSB set"); + + /* Ignore the return value since we manually validate the status of the hart anyway */ + sbi_send_ipi_cpu(cpu); + + if (!hart_wait_on_status(hartid, SBI_EXT_HSM_SUSPENDED, hsm_timer_duration) && + !hart_wait_on_status(hartid, SBI_EXT_HSM_RESUME_PENDING, hsm_timer_duration)) { + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STARTED) + report_info("hart %ld status is not 'started' (ret.value=%ld)", hartid, ret.value); + else + resume_with_msb = true; + + sbi_hsm_timer_fired = false; + timer_start(hsm_timer_duration); + + while (!((READ_ONCE(sbi_hsm_non_retentive_hart_suspend_checks[cpu])) & SBI_HSM_TEST_DONE) + && !sbi_hsm_timer_fired) + cpu_relax(); + + timer_stop(); + + if (sbi_hsm_timer_fired) { + report_info("hsm timer fired before hart %ld is done with non-retentive resume checks", + hartid); + } else { + if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SATP)) + report_info("satp is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SIE)) + report_info("sstatus.SIE is not zero for test hart %ld", hartid); + else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_HARTID_A1)) + report_info("either a0 or a1 is not hartid for test hart %ld", hartid); + else + check_with_msb = true; + } + } + + report(resume_with_msb, "secondary hart non-retentive resumed with MSB set"); + report(check_with_msb, + "secondary hart has expected register values after non-retentive resume with MSB set"); + + report_prefix_pop(); + + report_prefix_push("hart_stop"); + + sbi_hsm_stop_hart[cpu] = 1; + + if (!hart_wait_on_status(hartid, SBI_EXT_HSM_STARTED, hsm_timer_duration) && + !hart_wait_on_status(hartid, SBI_EXT_HSM_STOP_PENDING, hsm_timer_duration)) { + ret = sbi_hart_get_status(hartid); + if (ret.error) + report_info("hart %ld get status failed (error=%ld)", hartid, ret.error); + else if (ret.value != SBI_EXT_HSM_STOPPED) + report_info("hart %ld status is not 'stopped' (ret.value=%ld)", hartid, ret.value); + else + stop_with_msb = true; + } + + report(stop_with_msb, "secondary hart stopped after suspension tests with MSB set"); + + /* Reset the state of the secondary cpu since it did not have a chance to clean up after stopping */ + on_cpu_clear_func(cpu); + set_cpu_online(cpu, false); + set_cpu_started(cpu, false); + + hsm_timer_teardown(); + report_prefix_popn(2); +} int main(int argc, char **argv) { @@ -444,6 +1091,7 @@ int main(int argc, char **argv) report_prefix_push("sbi"); check_base(); check_time(); + check_hsm(); check_dbcn(); return report_summary();