From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A851C2D0CD for ; Thu, 15 May 2025 18:24:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 084088D0009; Thu, 15 May 2025 14:23:49 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EFAD58D0001; Thu, 15 May 2025 14:23:48 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C67EE8D0009; Thu, 15 May 2025 14:23:48 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 979788D0001 for ; Thu, 15 May 2025 14:23:48 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 9FA811A048A for ; Thu, 15 May 2025 18:23:49 +0000 (UTC) X-FDA: 83445965778.05.5DE47A1 Received: from mail-qk1-f178.google.com (mail-qk1-f178.google.com [209.85.222.178]) by imf28.hostedemail.com (Postfix) with ESMTP id CA77EC000E for ; Thu, 15 May 2025 18:23:47 +0000 (UTC) Authentication-Results: imf28.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=UJn6sW7I; spf=pass (imf28.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.178 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1747333427; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=OgbqJ8uAFqaQzUPM6Yfuc1QdySf2ZJmkbP3YXxkM1A8=; b=RZA5PwN1UphhLuvwp9pLwPzJEwiUHmrFHrKSDuCchaIpqn7pMVDGEGA1ISwQCyYfN8m+GH GjL/6lzbQvL5bk8z23hgvmfjJRcsT23ACVrzC9yHSehWIJ6FXeoYo250dCS5lguFvid7me F8uesZ4uPvWQfbu05zlSJ+9Ll58WnaI= ARC-Authentication-Results: i=1; imf28.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=UJn6sW7I; spf=pass (imf28.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.178 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1747333427; a=rsa-sha256; cv=none; b=uu2tox3IfkDPynbppYz3ELxsz6BaNofgX0jrnYC97TygMB4XHroP7y3XAhmM0IeNEVaonP nI++Oxkuiu204J36HSxvVKg9v6YBa1WjKKMDjcisjCLVv2uosOG6WZofOtGXEcBEtGoygf 2E9LyG2VzU7F9LWlF0OpWhkqotA6aqo= Received: by mail-qk1-f178.google.com with SMTP id af79cd13be357-7c5b2472969so126981085a.1 for ; Thu, 15 May 2025 11:23:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1747333427; x=1747938227; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=OgbqJ8uAFqaQzUPM6Yfuc1QdySf2ZJmkbP3YXxkM1A8=; b=UJn6sW7Ic2kX4fONasHt4LldFXIrz/FuEnOLlKiAsEQ4+Cj+eD6izvQWiB8/jt99yU bI5ULmxwSlRgqX7fZf86BgT4LyXXfjU9yVJ6LxIQeXSmMRUyVmpJ+vP4v6YEv4f5Ri2x SU5uqAsIP4fONAD2e14z0JxDsUG1+WKYJNHCoiokWrUk2/FVdD1U1ZHnYU8jfkv5TLIk nlKzTZQNswo0kRnHCDyYmVgldXZuuoOlZoShjqcTlgVqO2IFEBgoH3gIWfyPtW67tlAy GJ45/EVyI7GbnTT7A5G1KTVTnHWHmmgBAVjdXDxfR6E3tCMapD197XNhye6Wkw2UnfAp P07g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747333427; x=1747938227; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OgbqJ8uAFqaQzUPM6Yfuc1QdySf2ZJmkbP3YXxkM1A8=; b=IhE2Bl21qA5rnQNu6c+ruIFjuTN6qJIeDAxxJiML924nLLb3fqC/m1K95GOyrmixX7 qUZCoWAS9Xs0kq1Mma/EusFt9J2JXKfdyeRBdmYMPoSEMzx4YYSAuXeJ692J8teCRlWi 8cep8QV3jbC/og1uNbxqFhbnfe7bJF4JTDchxbxyGu6vIG+Ev/P1H36T0ucmS8mtLx1j bd+ABNf7G7kBgHUGLJGqLgfWWcqrQMmfhHQbCv9ASNqoT+4syKCGURlweKFAT6Il6yyP N032nvK/UkZacmzFZ+Qz4ZXo5KU4uEl1ixVc9w1Q1yvDDJES3N4WvPyzKv3AKWcrrm2s Ps4g== X-Forwarded-Encrypted: i=1; AJvYcCUpQa5/Gl5W60DNpy89dSGbahUFpt6D4GEIMvAXQaBgPuTsLKvu6p4+GGUn0QHx+e8smP6mxDn/LQ==@kvack.org X-Gm-Message-State: AOJu0YxIoiyhRHeJXJ3agB5mBTOnp1kvyC8LNk9/P3O4SCJoGFilY+69 LpcmCSCUzAnoxJlYaWmgmqupqK/EyVKa50/uoK+/ad/fJVobet7KMezVJvTCI6YUppo= X-Gm-Gg: ASbGncvHtTAVZ9GzjHgCuo3qhbOJAaFApNYP8swqmfm42v6ry+ZXgoSIsGaBAdhxtQi kQ76l0LVQxJA8IZPOrs2lkooQq06w1Thil2C4Cj7MB4v4ZdFdr5Dm0+vb5h7oZNQ0YFCubfJ6ZN tt2dSk18PemonLsSWmIA8nBHGZv68wdT0GnewEK0oKRh3L0G0IbK52lBh5KAeIh2pxeDXkas4aQ wtdyfJax0H/qTAH6ZJ5OzFga6WXwI52SIc/H82W34Q4RMqb8VgNcFKzU9sN5UM0snXxKrwE2I0S xkvPBgjILT4sPl97YK+61m9f7lzWA5zO2Oe4HqSlgNtQ/Q9QOFVse/K5kjD20do5jyL/E5Cod34 OL376EW5KWQyXxHO3IALc2mx7Ijaql4ULs0pKkaofUKZi X-Google-Smtp-Source: AGHT+IHbo0BqjSV7553DLTOcjGLoeCOmefHo9uBHE4Z501wh+amUmwMVZNZST76DsyUEX0+3rFyCYg== X-Received: by 2002:a05:620a:2886:b0:7c5:562d:ccf8 with SMTP id af79cd13be357-7cd46707fe4mr91925285a.8.1747333426761; Thu, 15 May 2025 11:23:46 -0700 (PDT) Received: from soleen.c.googlers.com.com (138.200.150.34.bc.googleusercontent.com. [34.150.200.138]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7cd466fc2afsm18218685a.0.2025.05.15.11.23.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 May 2025 11:23:46 -0700 (PDT) From: Pasha Tatashin To: pratyush@kernel.org, jasonmiu@google.com, graf@amazon.com, changyuanl@google.com, pasha.tatashin@soleen.com, rppt@kernel.org, dmatlack@google.com, rientjes@google.com, corbet@lwn.net, rdunlap@infradead.org, ilpo.jarvinen@linux.intel.com, kanie@linux.alibaba.com, ojeda@kernel.org, aliceryhl@google.com, masahiroy@kernel.org, akpm@linux-foundation.org, tj@kernel.org, yoann.congal@smile.fr, mmaurer@google.com, roman.gushchin@linux.dev, chenridong@huawei.com, axboe@kernel.dk, mark.rutland@arm.com, jannh@google.com, vincent.guittot@linaro.org, hannes@cmpxchg.org, dan.j.williams@intel.com, david@redhat.com, joel.granados@kernel.org, rostedt@goodmis.org, anna.schumaker@oracle.com, song@kernel.org, zhangguopeng@kylinos.cn, linux@weissschuh.net, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, gregkh@linuxfoundation.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, rafael@kernel.org, dakr@kernel.org, bartosz.golaszewski@linaro.org, cw00.choi@samsung.com, myungjoo.ham@samsung.com, yesanishhere@gmail.com, Jonathan.Cameron@huawei.com, quic_zijuhu@quicinc.com, aleksander.lobakin@intel.com, ira.weiny@intel.com, andriy.shevchenko@linux.intel.com, leon@kernel.org, lukas@wunner.de, bhelgaas@google.com, wagi@kernel.org, djeffery@redhat.com, stuart.w.hayes@gmail.com, ptyadav@amazon.de Subject: [RFC v2 14/16] selftests/liveupdate: add subsystem/state tests Date: Thu, 15 May 2025 18:23:18 +0000 Message-ID: <20250515182322.117840-15-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.49.0.1101.gccaa498523-goog In-Reply-To: <20250515182322.117840-1-pasha.tatashin@soleen.com> References: <20250515182322.117840-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: CA77EC000E X-Rspam-User: X-Rspamd-Server: rspam11 X-Stat-Signature: 1h1aryksmkyqcr97q55rbemfzsdjroji X-HE-Tag: 1747333427-334635 X-HE-Meta: U2FsdGVkX1/w6LFgnlOnQlcm63r5BoK0KeIKU6A4kvtjj2t6+/BbZ0KcpkDEHdgT9pPO2rwFiCt1NHT+mNwJiqDj12Sb6GTTgMUHU8x6PgnuAQ5e+IUKONDmhfteil20lW8A5xtdWVNV90bUZSRmFr7AAAFODdubQSjbc8sSWFRUBbX1x9HtCcHEttv9eNYPpGleDSt6IxAJLHUHnb40vRlIK+gTxZ4hwR8HgttaqV254C7CiQrlN5KF+43gj3drXC057ihAzpNjE06uHC4aTHDaUueqkIy8oejUl16+HxLyM++K5FLwHCloAvN4DErfBToAryrCdAjB6wIwwEb0l31diWDwzKg7ZeuijA/5IizIayvCYgCNZbytqLrLAlrZ48F57SWPrfpwCBI831LxCsq7vKDP6bdva3PrIB4R6084f+3HsiNDJGcBGLG2G01YeU6o7drwd37NgTrm2cKsCSyihKCxh1Duc8bJQ9bPprBsO0qY2cTN1DupeKOTbYDa8EZDg3inyy/zohAiek+UbYPNSoS4lfQp6+OYdzCSL/J4nPGMwTzQjkMwoiL9ucXXPO2grpcr8dX3F34xvCxRr1SCbpYDtO4fgsHKEuCYhjaF40fZOWbupgbuAX2BUsseEKBLDEcEwoFt18AzRkaf79zBMXAGfwb9dM0xA5cL96+xEbr2vn2wqM47/fMKa61Uc0L8rt6N19hPUVvq/5A/LyXRn7WpRjNpZyPcyXSd+gstC3Ti3DVWGXKCfOhUKz7FB1YnyQKeR9PwtxIxSrYimpS/36TnxZnfN47Zr10oVbnSAe5YDMg7mQv4cJGoS+w47hBiq661Hb3QJdGs7Gjkcnu0Br4sboitNInjlFC+WcwajU67CjuQpDXRSiVl196AqqPQx01TsDaJpOaRTcLvnggCuywYF/TfAT5uHSbmVzQXByIUrm9utQClwxKgULh3NE69mJYVETQjyIOTNu+ s45zcNcR GC5lHOxB06oVHvYZsZF+Z4TqZHdw1z+4jT8XKKNj8SNP3qzJbsw7+ZmYpw+wSVU65Ix5QQeq9ITRy3StMMDyPNsVYxcTifJZ07kC/sXdr9u2Z7RJEUOUEsLbRksyjXSiClqZO0X1qYqI3IVyA91P2JY2FfMKnfIQEY1w0ijQJzS2/0M4GGJ41Z4dTBju4iLcwHPKA35+yC00rqFkFIbnkbzSnXqT+f57mS/LiId9x5er1SbqULOlfYnzzQaDpu/WlV0NGWJFn0cVfKi8/MQEsXy2be9b1dboDuvwuuUN1mTTy+KMC8vyzfpvv5o/ZaPpvjKIRBz2skqYYHFTjIr6i8sPtiFEWZXY3W20ocCSsqw/QtVijKWyvR48pCGxEZzVITKQ6TTQsL+S7L7OTAQkfBHFftTSrykwQpgHonr1cKilYxQ5Uyv6OdunaNq2cxnHUD6LU4co+lLquvZo= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Introduces a new set of userspace selftests for the LUO. These tests verify the functionality LUO by using the kernel-side selftest ioctls provided by the LUO module, primarily focusing on subsystem management and basic LUO state transitions. Signed-off-by: Pasha Tatashin --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/liveupdate/.gitignore | 1 + tools/testing/selftests/liveupdate/Makefile | 7 + tools/testing/selftests/liveupdate/config | 6 + .../testing/selftests/liveupdate/liveupdate.c | 440 ++++++++++++++++++ 5 files changed, 455 insertions(+) create mode 100644 tools/testing/selftests/liveupdate/.gitignore create mode 100644 tools/testing/selftests/liveupdate/Makefile create mode 100644 tools/testing/selftests/liveupdate/config create mode 100644 tools/testing/selftests/liveupdate/liveupdate.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 80fb84fa3cfc..1a96e806a5dd 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -52,6 +52,7 @@ TARGETS += kvm TARGETS += landlock TARGETS += lib TARGETS += livepatch +TARGETS += liveupdate TARGETS += lkdtm TARGETS += lsm TARGETS += membarrier diff --git a/tools/testing/selftests/liveupdate/.gitignore b/tools/testing/selftests/liveupdate/.gitignore new file mode 100644 index 000000000000..af6e773cf98f --- /dev/null +++ b/tools/testing/selftests/liveupdate/.gitignore @@ -0,0 +1 @@ +/liveupdate diff --git a/tools/testing/selftests/liveupdate/Makefile b/tools/testing/selftests/liveupdate/Makefile new file mode 100644 index 000000000000..2a573c36016e --- /dev/null +++ b/tools/testing/selftests/liveupdate/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +CFLAGS += -Wall -O2 -Wno-unused-function +CFLAGS += $(KHDR_INCLUDES) + +TEST_GEN_PROGS += liveupdate + +include ../lib.mk diff --git a/tools/testing/selftests/liveupdate/config b/tools/testing/selftests/liveupdate/config new file mode 100644 index 000000000000..382c85b89570 --- /dev/null +++ b/tools/testing/selftests/liveupdate/config @@ -0,0 +1,6 @@ +CONFIG_KEXEC_FILE=y +CONFIG_KEXEC_HANDOVER=y +CONFIG_KEXEC_HANDOVER_DEBUG=y +CONFIG_LIVEUPDATE=y +CONFIG_LIVEUPDATE_SYSFS_API=y +CONFIG_LIVEUPDATE_SELFTESTS=y diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testing/selftests/liveupdate/liveupdate.c new file mode 100644 index 000000000000..0007085e2b96 --- /dev/null +++ b/tools/testing/selftests/liveupdate/liveupdate.c @@ -0,0 +1,440 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) 2025, Google LLC. + * Pasha Tatashin + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "../kselftest.h" +#include "../kselftest_harness.h" +#include "../../../../drivers/misc/liveupdate/luo_selftests.h" + +struct subsystem_info { + void *data_page; + void *verify_page; + char test_name[LUO_NAME_LENGTH]; + bool registered; +}; + +FIXTURE(subsystem) { + enum liveupdate_state state; + int fd; + struct subsystem_info si[LUO_MAX_SUBSYSTEMS]; +}; + +FIXTURE(state) { + enum liveupdate_state state; + int fd; +}; + +#define LUO_DEVICE "/dev/liveupdate" +#define LUO_SYSFS_STATE "/sys/kernel/liveupdate/state" +static size_t page_size; + +const char *const luo_state_str[] = { + [LIVEUPDATE_STATE_NORMAL] = "normal", + [LIVEUPDATE_STATE_PREPARED] = "prepared", + [LIVEUPDATE_STATE_FROZEN] = "frozen", + [LIVEUPDATE_STATE_UPDATED] = "updated", +}; + +static int run_luo_selftest_cmd(int fd, __u64 cmd_code, + struct luo_arg_subsystem *subsys_arg) +{ + struct liveupdate_selftest k_arg; + + if (fd < 0) { + errno = EBADF; + return -1; + } + + k_arg.cmd = cmd_code; + k_arg.arg = (__u64)(unsigned long)subsys_arg; + + return ioctl(fd, LIVEUPDATE_IOCTL_SELFTESTS, &k_arg); +} + +static int __register_subsystem(int fd, char *name, void *data_page) +{ + struct luo_arg_subsystem subsys_arg; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", name); + subsys_arg.data_page = data_page; + + return run_luo_selftest_cmd(fd, LUO_CMD_SUBSYSTEM_REGISTER, + &subsys_arg); +} + +static int __unregister_subsystem(int fd, char *name) +{ + struct luo_arg_subsystem subsys_arg; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", name); + + return run_luo_selftest_cmd(fd, LUO_CMD_SUBSYSTEM_UNREGISTER, + &subsys_arg); +} + +static int get_sysfs_state(void) +{ + char buf[64]; + ssize_t len; + int fd, i; + + fd = open(LUO_SYSFS_STATE, O_RDONLY); + if (fd < 0) { + ksft_print_msg("Failed to open sysfs state file '%s': %s\n", + LUO_SYSFS_STATE, strerror(errno)); + return -errno; + } + + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + + if (len <= 0) { + ksft_print_msg("Failed to read sysfs state file '%s': %s\n", + LUO_SYSFS_STATE, strerror(errno)); + return -errno; + } + if (buf[len - 1] == '\n') + buf[len - 1] = '\0'; + else + buf[len] = '\0'; + + for (i = 0; i < ARRAY_SIZE(luo_state_str); i++) { + if (!strcmp(buf, luo_state_str[i])) + return i; + } + + return -EIO; +} + +FIXTURE_SETUP(state) +{ + page_size = sysconf(_SC_PAGE_SIZE); + self->fd = open(LUO_DEVICE, O_RDWR); + if (self->fd < 0) { + ksft_exit_skip("Setup: Cannot open %s (errno %d).\n", + LUO_DEVICE, errno); + } + self->state = LIVEUPDATE_STATE_NORMAL; +} + +FIXTURE_TEARDOWN(state) +{ + page_size = sysconf(_SC_PAGE_SIZE); + if (self->state != LIVEUPDATE_STATE_NORMAL) + ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + close(self->fd); +} + +FIXTURE_SETUP(subsystem) +{ + int i; + + page_size = sysconf(_SC_PAGE_SIZE); + memset(&self->si, 0, sizeof(self->si)); + self->fd = open(LUO_DEVICE, O_RDWR); + if (self->fd < 0) { + ksft_exit_skip("Setup: Cannot open %s (errno %d).\n", + LUO_DEVICE, errno); + } + self->state = LIVEUPDATE_STATE_NORMAL; + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + snprintf(self->si[i].test_name, LUO_NAME_LENGTH, + "ksft_luo_%d.%d", getpid(), i); + + self->si[i].data_page = mmap(NULL, page_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + + if (self->si[i].data_page == MAP_FAILED) { + ksft_print_msg("Setup: mmap data_page failed\n"); + goto exit_fail; + } + memset(self->si[i].data_page, 'A' + i, page_size); + + self->si[i].verify_page = mmap(NULL, page_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + if (self->si[i].verify_page == MAP_FAILED) { + ksft_print_msg("Setup: mmap verify_page failed\n"); + goto exit_fail; + } + memset(self->si[i].verify_page, 0, page_size); + } + + return; +exit_fail: + close(self->fd); + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + void *page; + + page = self->si[i].data_page; + if (page && page != MAP_FAILED) + munmap(page, page_size); + + page = self->si[i].verify_page; + if (page && page != MAP_FAILED) + munmap(page, page_size); + } + ksft_exit_fail(); +} + +FIXTURE_TEARDOWN(subsystem) +{ + int i; + + if (self->state != LIVEUPDATE_STATE_NORMAL) + ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + if (self->si[i].registered) { + struct luo_arg_subsystem subsys_arg; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", + self->si[i].test_name); + subsys_arg.data_page = NULL; + run_luo_selftest_cmd(self->fd, LUO_CMD_SUBSYSTEM_UNREGISTER, + &subsys_arg); + } + munmap(self->si[i].data_page, page_size); + munmap(self->si[i].verify_page, page_size); + } + + close(self->fd); +} + +TEST_F(state, normal) +{ + enum liveupdate_state state; + int ret; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + ASSERT_EQ(0, ret); + ASSERT_EQ(state, LIVEUPDATE_STATE_NORMAL); +} + +TEST_F(state, prepared) +{ + enum liveupdate_state state; + int ret; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_PREPARE, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_PREPARED; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + ASSERT_EQ(0, ret); + ASSERT_EQ(state, LIVEUPDATE_STATE_PREPARED); + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_NORMAL; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + ASSERT_EQ(0, ret); + ASSERT_EQ(state, LIVEUPDATE_STATE_NORMAL); +} + +TEST_F(state, sysfs_normal) +{ + int state = get_sysfs_state(); + + if (state < 0) { + if (state == -ENOENT || state == -EACCES) { + ksft_test_result_skip("Sysfs state file not accessible (%d)\n", + state); + return; + } + } + + ASSERT_EQ(LIVEUPDATE_STATE_NORMAL, state); +} + +TEST_F(state, sysfs_prepared) +{ + int ret, state; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_PREPARE, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_PREPARED; + + state = get_sysfs_state(); + if (state < 0) { + if (state == -ENOENT || state == -EACCES) { + ksft_test_result_skip("Sysfs state file not accessible (%d)\n", + state); + ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + self->state = LIVEUPDATE_STATE_NORMAL; + return; + } + } + ASSERT_EQ(LIVEUPDATE_STATE_PREPARED, state); + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_NORMAL; + state = get_sysfs_state(); + ASSERT_EQ(LIVEUPDATE_STATE_NORMAL, state); +} + +TEST_F(state, sysfs_frozen) +{ + int ret, state; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_PREPARE, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_PREPARED; + + state = get_sysfs_state(); + if (state < 0) { + if (state == -ENOENT || state == -EACCES) { + ksft_test_result_skip("Sysfs state file not accessible (%d)\n", state); + ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + self->state = LIVEUPDATE_STATE_NORMAL; + return; + } + } + ASSERT_EQ(LIVEUPDATE_STATE_PREPARED, state); + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_FREEZE, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_FROZEN; + state = get_sysfs_state(); + ASSERT_EQ(LIVEUPDATE_STATE_FROZEN, state); + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_NORMAL; + state = get_sysfs_state(); + ASSERT_EQ(LIVEUPDATE_STATE_NORMAL, state); +} + +TEST_F(subsystem, register_unregister) +{ + int ret; + + ret = __register_subsystem(self->fd, self->si[0].test_name, + self->si[0].data_page); + ASSERT_EQ(0, ret); + self->si[0].registered = true; + + ret = __unregister_subsystem(self->fd, self->si[0].test_name); + ASSERT_EQ(0, ret); + self->si[0].registered = false; +} + +TEST_F(subsystem, double_unregister) +{ + int ret; + + ret = __register_subsystem(self->fd, self->si[0].test_name, + self->si[0].data_page); + ASSERT_EQ(0, ret); + self->si[0].registered = true; + + ret = __unregister_subsystem(self->fd, self->si[0].test_name); + ASSERT_EQ(0, ret); + self->si[0].registered = false; + + ret = __unregister_subsystem(self->fd, self->si[0].test_name); + EXPECT_NE(0, ret); + EXPECT_TRUE(errno == EINVAL || errno == ENOENT); + self->si[0].registered = false; +} + +TEST_F(subsystem, register_unregister_many) +{ + int ret; + int i; + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + ret = __register_subsystem(self->fd, self->si[i].test_name, + self->si[i].data_page); + ASSERT_EQ(0, ret); + self->si[i].registered = true; + } + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + ret = __unregister_subsystem(self->fd, self->si[i].test_name); + ASSERT_EQ(0, ret); + self->si[i].registered = false; + } + +} + +TEST_F(subsystem, getdata_verify) +{ + enum liveupdate_state state; + int ret; + int i; + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + ret = __register_subsystem(self->fd, self->si[i].test_name, + self->si[i].data_page); + ASSERT_EQ(0, ret); + self->si[i].registered = true; + } + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_PREPARE, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_PREPARED; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + ASSERT_EQ(0, ret); + ASSERT_EQ(state, LIVEUPDATE_STATE_PREPARED); + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + struct luo_arg_subsystem subsys_arg; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", + self->si[i].test_name); + subsys_arg.data_page = self->si[i].verify_page; + + ret = run_luo_selftest_cmd(self->fd, LUO_CMD_SUBSYSTEM_GETDATA, + &subsys_arg); + + ASSERT_EQ(0, ret); + ASSERT_EQ(0, memcmp(self->si[i].data_page, + self->si[i].verify_page, + page_size)); + } + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_EVENT_CANCEL, NULL); + ASSERT_EQ(0, ret); + self->state = LIVEUPDATE_STATE_NORMAL; + + ret = ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + ASSERT_EQ(0, ret); + ASSERT_EQ(state, LIVEUPDATE_STATE_NORMAL); + + for (i = 0; i < LUO_MAX_SUBSYSTEMS; i++) { + ret = __unregister_subsystem(self->fd, self->si[i].test_name); + ASSERT_EQ(0, ret); + self->si[i].registered = false; + } +} + +TEST_HARNESS_MAIN -- 2.49.0.1101.gccaa498523-goog