From patchwork Fri Nov 30 10:18:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Hu X-Patchwork-Id: 202919 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 5C36D2C0087 for ; Fri, 30 Nov 2012 21:18:28 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TeNfv-0003i8-KE; Fri, 30 Nov 2012 10:18:27 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TeNfu-0003hy-4B for fwts-devel@lists.ubuntu.com; Fri, 30 Nov 2012 10:18:26 +0000 Received: from [175.41.48.77] (helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1TeNfs-0004gH-Sz; Fri, 30 Nov 2012 10:18:26 +0000 From: Ivan Hu To: fwts-devel@lists.ubuntu.com Subject: [PATCH][Resend2] uefirtvariable: Add new test for UEFI runtime GetVariable Date: Fri, 30 Nov 2012 18:18:20 +0800 Message-Id: <1354270700-30714-1-git-send-email-ivan.hu@canonical.com> X-Mailer: git-send-email 1.7.10.4 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com This tests the UEFI runtime service GetVariable interface by checking data, datasize and different attributes of variable. Signed-off-by: Ivan Hu Acked-by: Colin Ian King Acked-by: Alex Hung --- src/Makefile.am | 3 +- src/uefi/uefirtvariable/uefirtvariable.c | 194 ++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 src/uefi/uefirtvariable/uefirtvariable.c diff --git a/src/Makefile.am b/src/Makefile.am index 478c522..f192b56 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,7 +68,8 @@ fwts_SOURCES = main.c \ kernel/oops/oops.c \ uefi/csm/csm.c \ uefi/uefidump/uefidump.c \ - uefi/uefirttime/uefirttime.c + uefi/uefirttime/uefirttime.c \ + uefi/uefirtvariable/uefirtvariable.c fwts_LDFLAGS = -ljson -lm diff --git a/src/uefi/uefirtvariable/uefirtvariable.c b/src/uefi/uefirtvariable/uefirtvariable.c new file mode 100644 index 0000000..181d41a --- /dev/null +++ b/src/uefi/uefirtvariable/uefirtvariable.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2012 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "fwts.h" +#include "fwts_uefi.h" +#include "efi_runtime.h" +#include "fwts_efi_module.h" + +#define TEST_GUID1 \ +{ \ + 0xF6FAB04F, 0xACAF, 0x4af3, {0xB9, 0xFA, 0xDC, \ + 0xF9, 0x7F, 0xB4, 0x42, 0x6F} \ +} + +#define EFI_SUCCESS 0 + +#define MAX_DATA_LENGTH 1024 + +static int fd; +EFI_GUID gtestguid1 = TEST_GUID1; +uint32_t attributesarray[] = { FWTS_UEFI_VAR_BOOTSERVICE_ACCESS, + FWTS_UEFI_VAR_NON_VOLATILE | FWTS_UEFI_VAR_BOOTSERVICE_ACCESS, + FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | FWTS_UEFI_VAR_RUNTIME_ACCESS, + FWTS_UEFI_VAR_NON_VOLATILE | FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | FWTS_UEFI_VAR_RUNTIME_ACCESS}; + +uint16_t variablenametest[] = {'T', 'e', 's', 't', 'v', 'a', 'r', '\0'}; + +static int uefirtvariable_init(fwts_framework *fw) +{ + if (fwts_firmware_detect() != FWTS_FIRMWARE_UEFI) { + fwts_log_info(fw, "Cannot detect any UEFI firmware. Aborted."); + return FWTS_ABORTED; + } + + if (fwts_lib_efi_runtime_load_module(fw) != FWTS_OK) { + fwts_log_info(fw, "Cannot load efi_runtime module. Aborted."); + return FWTS_ABORTED; + } + + fd = open("/dev/efi_runtime", O_RDONLY); + if (fd == -1) { + fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + return FWTS_ABORTED; + } + + return FWTS_OK; +} + +static int uefirtvariable_deinit(fwts_framework *fw) +{ + FWTS_UNUSED(fw); + + close(fd); + fwts_lib_efi_runtime_unload_module(fw); + + return FWTS_OK; +} + +static int getvariable_test(fwts_framework *fw, uint32_t attributes, uint64_t datasize, uint16_t *varname) +{ + long ioret; + struct efi_getvariable getvariable; + struct efi_setvariable setvariable; + + uint64_t status; + uint8_t testdata[MAX_DATA_LENGTH]; + uint64_t dataindex; + uint64_t getdatasize; + uint32_t attributestest; + + uint8_t data[datasize+1]; + for (dataindex = 0; dataindex < datasize; dataindex++) + data[dataindex] = (uint8_t)dataindex; + data[dataindex] = '0'; + + setvariable.VariableName = varname; + setvariable.VendorGuid = >estguid1; + setvariable.Attributes = attributes; + setvariable.DataSize = datasize; + setvariable.Data = data; + setvariable.status = &status; + + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); + + if (ioret == -1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeSetVariable", + "Failed to set variable with UEFI runtime service."); + + return FWTS_ERROR; + } + + getvariable.VariableName = varname; + getvariable.VendorGuid = >estguid1; + getvariable.Attributes = &attributestest; + getvariable.DataSize = &getdatasize; + getvariable.Data = testdata; + getvariable.status = &status; + + ioret = ioctl(fd, EFI_RUNTIME_GET_VARIABLE, &getvariable); + if (ioret == -1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeGetVariable", + "Failed to get variable with UEFI runtime service."); + return FWTS_ERROR; + } + + if (*getvariable.status != EFI_SUCCESS) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeGetVariableStatus", + "Failed to get variable, return status isn't EFI_SUCCESS."); + return FWTS_ERROR; + } else if (*getvariable.Attributes != attributes) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeGetVariableAttributes", + "Failed to get variable with right attributes, " + "attributes we got is %" PRIu32 + ", but it should be %" PRIu32".", + *getvariable.Attributes, attributes); + return FWTS_ERROR; + } else if (*getvariable.DataSize != datasize) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeGetVariableDataSize", + "Failed to get variable with correct datasize."); + return FWTS_ERROR; + } else { + for (dataindex = 0; dataindex < datasize; dataindex++) { + if (data[dataindex] != (uint8_t)dataindex) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeGetVariableData", + "Failed to get variable with correct data."); + return FWTS_ERROR; + } + } + } + + /* delete the variable */ + setvariable.DataSize = 0; + + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); + + if (ioret == -1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "UEFIRuntimeSetVariable", + "Failed to set variable with UEFI runtime service."); + return FWTS_ERROR; + } + + return FWTS_OK; +} + +static int uefirtvariable_test1(fwts_framework *fw) +{ + uint64_t index; + uint64_t datasize = 10; + + for (index = 0; index < (sizeof(attributesarray)/(sizeof attributesarray[0])); index++) { + if (getvariable_test(fw, attributesarray[index], datasize, variablenametest) == FWTS_ERROR) + return FWTS_ERROR; + } + + fwts_passed(fw, "UEFI runtime service GetVariable interface test passed."); + + return FWTS_OK; +} + +static fwts_framework_minor_test uefirtvariable_tests[] = { + { uefirtvariable_test1, "Test UEFI RT service get variable interface." }, + { NULL, NULL } +}; + +static fwts_framework_ops uefirtvariable_ops = { + .description = "UEFI Runtime service variable interface tests.", + .init = uefirtvariable_init, + .deinit = uefirtvariable_deinit, + .minor_tests = uefirtvariable_tests +}; + +FWTS_REGISTER(uefirtvariable, &uefirtvariable_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_UNSAFE | FWTS_FLAG_ROOT_PRIV);