From nobody Sun Oct 5 09:21:59 2025 Received: from mail-qt1-f173.google.com (mail-qt1-f173.google.com [209.85.160.173]) (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 98CB5264614 for ; Mon, 29 Sep 2025 01:04:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759107883; cv=none; b=qWe4lX4GdUEZvwAUHlWQIVM1KdsQ8ffNWQGAyHUZ2v8Fahv3Xs6xuNFZI/eZMZxU3HquMkcnTTMqG+8CxmxPQSO/yHWlOLwVXtT9duNOyAOM9BYYse5riikdAxCLEMfGHoDdbkpEV0t6DXuJcm6QAHNpKmfiVV5cl07b69Ke+PY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759107883; c=relaxed/simple; bh=L6ao1Nu+sGNUW1SHO/j5boKkbrSZSkTVDZP0p9xXls8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o/s6aawhqSWQvBiBCrx/xzHEJLn/yEJ3tqQhUkD1itANFEeUPvn6PQpImH3Lt1SDOpKk6Rjs7AON7C1YaAl9zdVuIeBFpy8jdMPJ3RWS4S1fYZzAb60SjRhTalkGkaVi6K9HVFx2d9FdYvaxyHraogiERUo8yQPVSTGU4fIkWZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=MZStL5Ln; arc=none smtp.client-ip=209.85.160.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="MZStL5Ln" Received: by mail-qt1-f173.google.com with SMTP id d75a77b69052e-4da37f6e64cso34636761cf.2 for ; Sun, 28 Sep 2025 18:04:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759107879; x=1759712679; darn=vger.kernel.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=hWJ63KeQmpqYfuZrXZOnIQWXyJkptFNNQr+9KCQ8c70=; b=MZStL5LnjrV0W2GN+iOHhhY4L2HZXuX/F5JU41Om2kidaQ71QBWs9X5CvEDewVfCBK lgr5sshX22zCiRELuHlkd2aCVRKAvUWvzq1JOCwmh4E1t2blWthE8JiLTUjB1Hyv2KsH /GqQFC9VZnv7wnL2U4BO5ZFlOj4u4Lsimv8W0pL+EuUSmMjHEn0ohuYbrPm3F5m+6YG9 Ay3FgHeEYj4v2TBfziFlI9MiMV+R9kfHvZ3w0PWr3GnQ+DLG3KQIsG1hOH5piRuESQSm Yj1DUKALslbFAVD8orwy/W9XYme/lzpSE8S9q1ZTEVvDovXXiF1jKSylW5OCT1MD5h6p eY9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759107879; x=1759712679; 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=hWJ63KeQmpqYfuZrXZOnIQWXyJkptFNNQr+9KCQ8c70=; b=QAfesWfvQNSrET/JQTkA9oDF1mPku25wbH5/6RzVUvdY11uXxB3dcgqR+KQ863EFLJ 7gs4ukWWZCeuXJ9wxzKPM8x0k65gXeuUkbpavq89lWdX0rUMTIBq2Ku01bqmcy9owwNJ 5K1fkB1NwYIp+41CqO6dECSeJnB0ND8T9H013dHa/ilZKtjddY+JaWHYi8tYDMCG4Qs0 fpb3fCcg3+7H8veXQvtEqqKe4anuZePoYqu9y6bIR16/Kce53mWpPFuOTgD825bCmcVD VDzVh5ouKu4LfyIr5bk7hzZoNpg1+hHQWD68rMWR+Eb6HCbMFOhsZmmUVgFcneERBKri UTlw== X-Forwarded-Encrypted: i=1; AJvYcCWVpWcdH4j4qlHwwdtxLOMZTve2aewKxT5bsNt8LiaMspb9CD9fYLcHUhh13uN2RtJF3K+kou8FfJ4LRKA=@vger.kernel.org X-Gm-Message-State: AOJu0YyuLNJhauN+uD0/fBfQG/jal9GBTq6aAJ4A8k+cCnrI+ms42VuN vxoshQpOAEW0VuPhltDdNT9/zDsSkJmQ71AAt5QwYn2VeeiH+RLyPlhndtkn4f+v/y0= X-Gm-Gg: ASbGnctU1sTBge8qdmeSfXPoNZI7LjqkjY2thog07cFeikf/VdaLpb7RqWBVsIMM12V 2fei/Q+mJNLrbuZAYuQxR683Jk4wFUYV7FDZDCCvZ93VCyOoYf6bvIdi35+WEV1QeuEsUhgnFpu enohHCcOVDGwoIEHFtSVFJrnc8TiNJnunjKqC6Gc2Xn7S3jmd63bTwFyQSbDixT5r7d0XeIiCCd 6HhnErsEHP9eFuRsvT6kSh7MmpEMnT52jexMVSebHOUdjihrltdqrDjLhVDM+1AHJ3SfB1ZeRy6 /vcQU6cLgPHIbSjOyOsrxg8eLIVtEE4J3KhtckLSiOZzK0TX+MEYcdvgc8J5TQXsMB/XWws9eGC t2xkfg+oW5lorOTtOyG3JY4a/adZyYI75PqcG9w2G8m33zgESwiq48NvH/rIbhrTRUwDmy9v0lh vDuns3XL4= X-Google-Smtp-Source: AGHT+IGQ9JesfWQ9VOblraXsGcOaxMqov/TZFk+utQcihiAURpdIQFxS9/FIvzoyuC4KA4xQDrrIxg== X-Received: by 2002:a05:622a:5c8:b0:4e0:b5ef:2ba3 with SMTP id d75a77b69052e-4e0b5ef2f60mr33124721cf.37.1759107879208; Sun, 28 Sep 2025 18:04:39 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-4db0c0fbe63sm64561521cf.23.2025.09.28.18.04.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Sep 2025 18:04:38 -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, lennart@poettering.net, brauner@kernel.org, linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org, saeedm@nvidia.com, ajayachandra@nvidia.com, jgg@nvidia.com, parav@nvidia.com, leonro@nvidia.com, witu@nvidia.com, hughd@google.com, skhawaja@google.com, chrisl@kernel.org, steven.sistare@oracle.com Subject: [PATCH v4 18/30] selftests/liveupdate: add subsystem/state tests Date: Mon, 29 Sep 2025 01:03:09 +0000 Message-ID: <20250929010321.3462457-19-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog In-Reply-To: <20250929010321.3462457-1-pasha.tatashin@soleen.com> References: <20250929010321.3462457-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 | 348 ++++++++++++++++++ 5 files changed, 363 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/Mak= efile index c46ebdb9b8ef..56e44a98d6a5 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -54,6 +54,7 @@ TARGETS +=3D kvm TARGETS +=3D landlock TARGETS +=3D lib TARGETS +=3D livepatch +TARGETS +=3D liveupdate TARGETS +=3D lkdtm TARGETS +=3D lsm TARGETS +=3D 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/se= lftests/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 +=3D -Wall -O2 -Wno-unused-function +CFLAGS +=3D $(KHDR_INCLUDES) + +TEST_GEN_PROGS +=3D liveupdate + +include ../lib.mk diff --git a/tools/testing/selftests/liveupdate/config b/tools/testing/self= tests/liveupdate/config new file mode 100644 index 000000000000..382c85b89570 --- /dev/null +++ b/tools/testing/selftests/liveupdate/config @@ -0,0 +1,6 @@ +CONFIG_KEXEC_FILE=3Dy +CONFIG_KEXEC_HANDOVER=3Dy +CONFIG_KEXEC_HANDOVER_DEBUG=3Dy +CONFIG_LIVEUPDATE=3Dy +CONFIG_LIVEUPDATE_SYSFS_API=3Dy +CONFIG_LIVEUPDATE_SELFTESTS=3Dy diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testin= g/selftests/liveupdate/liveupdate.c new file mode 100644 index 000000000000..7c0ceaac0283 --- /dev/null +++ b/tools/testing/selftests/liveupdate/liveupdate.c @@ -0,0 +1,348 @@ +// 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 "../../../../kernel/liveupdate/luo_selftests.h" + +struct subsystem_info { + void *data_page; + void *verify_page; + char test_name[LUO_NAME_LENGTH]; + bool registered; +}; + +FIXTURE(subsystem) { + int fd; + int fd_dbg; + struct subsystem_info si[LUO_MAX_SUBSYSTEMS]; +}; + +FIXTURE(state) { + int fd; + int fd_dbg; +}; + +#define LUO_DEVICE "/dev/liveupdate" +#define LUO_DBG_DEVICE "/sys/kernel/debug/liveupdate/luo_selftest" +static size_t page_size; + +const char *const luo_state_str[] =3D { + [LIVEUPDATE_STATE_UNDEFINED] =3D "undefined", + [LIVEUPDATE_STATE_NORMAL] =3D "normal", + [LIVEUPDATE_STATE_PREPARED] =3D "prepared", + [LIVEUPDATE_STATE_FROZEN] =3D "frozen", + [LIVEUPDATE_STATE_UPDATED] =3D "updated", +}; + +static int run_luo_selftest_cmd(int fd_dbg, __u64 cmd_code, + struct luo_arg_subsystem *subsys_arg) +{ + struct liveupdate_selftest k_arg; + + k_arg.cmd =3D cmd_code; + k_arg.arg =3D (__u64)(unsigned long)subsys_arg; + + return ioctl(fd_dbg, LIVEUPDATE_IOCTL_SELFTESTS, &k_arg); +} + +static int register_subsystem(int fd_dbg, struct subsystem_info *si) +{ + struct luo_arg_subsystem subsys_arg; + int ret; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", si->test_name); + subsys_arg.data_page =3D si->data_page; + + ret =3D run_luo_selftest_cmd(fd_dbg, LUO_CMD_SUBSYSTEM_REGISTER, + &subsys_arg); + if (!ret) + si->registered =3D true; + + return ret; +} + +static int unregister_subsystem(int fd_dbg, struct subsystem_info *si) +{ + struct luo_arg_subsystem subsys_arg; + int ret; + + memset(&subsys_arg, 0, sizeof(subsys_arg)); + snprintf(subsys_arg.name, LUO_NAME_LENGTH, "%s", si->test_name); + + ret =3D run_luo_selftest_cmd(fd_dbg, LUO_CMD_SUBSYSTEM_UNREGISTER, + &subsys_arg); + if (!ret) + si->registered =3D false; + + return ret; +} + +FIXTURE_SETUP(state) +{ + page_size =3D sysconf(_SC_PAGE_SIZE); + self->fd =3D open(LUO_DEVICE, O_RDWR); + if (self->fd < 0) + SKIP(return, "open(%s) failed [%d]", LUO_DEVICE, errno); + + self->fd_dbg =3D open(LUO_DBG_DEVICE, O_RDWR); + ASSERT_GE(self->fd_dbg, 0); +} + +FIXTURE_TEARDOWN(state) +{ + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + struct liveupdate_ioctl_get_state ligs =3D {.size =3D sizeof(ligs)}; + + ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs); + if (ligs.state !=3D LIVEUPDATE_STATE_NORMAL) + ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel); + close(self->fd); +} + +FIXTURE_SETUP(subsystem) +{ + int i; + + page_size =3D sysconf(_SC_PAGE_SIZE); + memset(&self->si, 0, sizeof(self->si)); + self->fd =3D open(LUO_DEVICE, O_RDWR); + if (self->fd < 0) + SKIP(return, "open(%s) failed [%d]", LUO_DEVICE, errno); + + self->fd_dbg =3D open(LUO_DBG_DEVICE, O_RDWR); + ASSERT_GE(self->fd_dbg, 0); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) { + snprintf(self->si[i].test_name, LUO_NAME_LENGTH, + NAME_NORMAL ".%d", i); + + self->si[i].data_page =3D mmap(NULL, page_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + ASSERT_NE(MAP_FAILED, self->si[i].data_page); + memset(self->si[i].data_page, 'A' + i, page_size); + + self->si[i].verify_page =3D mmap(NULL, page_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + ASSERT_NE(MAP_FAILED, self->si[i].verify_page); + memset(self->si[i].verify_page, 0, page_size); + } +} + +FIXTURE_TEARDOWN(subsystem) +{ + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + enum liveupdate_state state =3D LIVEUPDATE_STATE_NORMAL; + int i; + + ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &state); + if (state !=3D LIVEUPDATE_STATE_NORMAL) + ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) { + if (self->si[i].registered) + unregister_subsystem(self->fd_dbg, &self->si[i]); + munmap(self->si[i].data_page, page_size); + munmap(self->si[i].verify_page, page_size); + } + + close(self->fd); +} + +TEST_F(state, normal) +{ + struct liveupdate_ioctl_get_state ligs =3D {.size =3D sizeof(ligs)}; + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs)); + ASSERT_EQ(ligs.state, LIVEUPDATE_STATE_NORMAL); +} + +TEST_F(state, prepared) +{ + struct liveupdate_ioctl_get_state ligs =3D {.size =3D sizeof(ligs)}; + struct liveupdate_ioctl_set_event prepare =3D { + .size =3D sizeof(prepare), + .event =3D LIVEUPDATE_PREPARE, + }; + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs)); + ASSERT_EQ(ligs.state, LIVEUPDATE_STATE_PREPARED); + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel)); + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs)); + ASSERT_EQ(ligs.state, LIVEUPDATE_STATE_NORMAL); +} + +TEST_F(state, sysfs_prepared) +{ + struct liveupdate_ioctl_set_event prepare =3D { + .size =3D sizeof(prepare), + .event =3D LIVEUPDATE_PREPARE, + }; + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel)); +} + +TEST_F(state, sysfs_frozen) +{ + struct liveupdate_ioctl_set_event prepare =3D { + .size =3D sizeof(prepare), + .event =3D LIVEUPDATE_PREPARE, + }; + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + ASSERT_EQ(0, ioctl(self->fd_dbg, LIVEUPDATE_IOCTL_FREEZE, NULL)); + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel)); +} + +TEST_F(subsystem, register_unregister) +{ + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[0])); + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[0])); +} + +TEST_F(subsystem, double_unregister) +{ + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[0])); + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[0])); + EXPECT_NE(0, unregister_subsystem(self->fd_dbg, &self->si[0])); + EXPECT_TRUE(errno =3D=3D EINVAL || errno =3D=3D ENOENT); +} + +TEST_F(subsystem, register_unregister_many) +{ + int i; + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[i])); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[i])); +} + +TEST_F(subsystem, getdata_verify) +{ + struct liveupdate_ioctl_get_state ligs =3D {.size =3D sizeof(ligs), .stat= e =3D 0}; + struct liveupdate_ioctl_set_event prepare =3D { + .size =3D sizeof(prepare), + .event =3D LIVEUPDATE_PREPARE, + }; + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + int i; + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[i])); + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs)); + ASSERT_EQ(ligs.state, LIVEUPDATE_STATE_PREPARED); + + for (i =3D 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 =3D self->si[i].verify_page; + + ASSERT_EQ(0, run_luo_selftest_cmd(self->fd_dbg, + LUO_CMD_SUBSYSTEM_GETDATA, + &subsys_arg)); + ASSERT_EQ(0, memcmp(self->si[i].data_page, + self->si[i].verify_page, + page_size)); + } + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel)); + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_GET_STATE, &ligs)); + ASSERT_EQ(ligs.state, LIVEUPDATE_STATE_NORMAL); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[i])); +} + +TEST_F(subsystem, prepare_fail) +{ + struct liveupdate_ioctl_set_event prepare =3D { + .size =3D sizeof(prepare), + .event =3D LIVEUPDATE_PREPARE, + }; + struct liveupdate_ioctl_set_event cancel =3D { + .size =3D sizeof(cancel), + .event =3D LIVEUPDATE_CANCEL, + }; + int i; + + snprintf(self->si[LUO_MAX_SUBSYSTEMS - 1].test_name, LUO_NAME_LENGTH, + NAME_PREPARE_FAIL ".%d", LUO_MAX_SUBSYSTEMS - 1); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[i])); + + ASSERT_EQ(-1, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[i])); + + snprintf(self->si[LUO_MAX_SUBSYSTEMS - 1].test_name, LUO_NAME_LENGTH, + NAME_NORMAL ".%d", LUO_MAX_SUBSYSTEMS - 1); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, register_subsystem(self->fd_dbg, &self->si[i])); + + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &prepare)); + ASSERT_EQ(0, ioctl(self->fd_dbg, LIVEUPDATE_IOCTL_FREEZE, NULL)); + ASSERT_EQ(0, ioctl(self->fd, LIVEUPDATE_IOCTL_SET_EVENT, &cancel)); + + for (i =3D 0; i < LUO_MAX_SUBSYSTEMS; i++) + ASSERT_EQ(0, unregister_subsystem(self->fd_dbg, &self->si[i])); +} + +TEST_HARNESS_MAIN --=20 2.51.0.536.g15c5d4f767-goog