From patchwork Thu Jun 15 14:39:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 693008 Delivered-To: patch@linaro.org Received: by 2002:a5d:4d91:0:0:0:0:0 with SMTP id b17csp562623wru; Thu, 15 Jun 2023 07:40:55 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5HTPo/bpwMHZSl66mcX2jc7NMfPckQDm+HpwGfcrt3VLCQ5mtXr66+u4OpXbJvCjwu+wFS X-Received: by 2002:a17:90a:4592:b0:256:d4a:ea4c with SMTP id v18-20020a17090a459200b002560d4aea4cmr4198674pjg.30.1686840055118; Thu, 15 Jun 2023 07:40:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686840055; cv=none; d=google.com; s=arc-20160816; b=YGGC20jnqSglyEYqmnsnlvGUkmCpx0NTuQ/4cyxAWnovrYchdCMDGAuBNhrBalaZJX X0ceqh3H7R5ZG8GQoMwlXbGVEiSw2zobssFBnke4+v3AF9n1ZAV5R3o/OlZWx8egr7mM QnDT8Z1FwjtmEf8wU7SxSci+lGALun4ElSXMLc2jgSt8Au8c5laZFdRRy3sDcGLcJHEY PJX9WlAYk0PqZlTeH06y2624x7+rWDxEynOP8aNxD/EVo7W8rRgTqQfr6WHD693mx6xa HtFWDi2B+zu5XTmDx9FsrSomZ4PWRwcH8OX89Z5iF28m6Gg3cY/I1jYGsFiWCMrBxu13 P5Bg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=61ie7ffeZLDrV/rQmRkAKeKsA9nIScFTAiCEvUN1jVc=; b=Jb3EbJcKfXo0fNm6hz2rxl5HjwwdBvuSk05eqNrSEkAgwfVf5v3cGwR2hlfW+F4yJN rEToJPI3jgoeZ2DgrTNL/Na5wsjHGYXNudls6RBrYxU+BerDBCBUmNFDwo6QLJ84dYcJ M+hQr2fxu50QymBjNlZsBP9xN2iv0DEWtpcKbgvyLQ1vjcO9LHAidLu5dSYtJlCUuxsI ELE6dDlW/0YdBPk0PT/DK34oZVpIhjbW5a6UimWBEHqteTEazzi6VXGRej9S5tZuh7Ae YS9sxb+d3X2n8AMMq9RCbvT1D9JdRQU8gB4PX7al7lO+mFE4uwd7GAgMizEzUtOWl4Vq /QRg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pEemA3lA; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id x16-20020a17090a789000b00253160141c7si9764615pjk.83.2023.06.15.07.40.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Jun 2023 07:40:55 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pEemA3lA; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 061CA8636A; Thu, 15 Jun 2023 16:40:06 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="pEemA3lA"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9F18B8631F; Thu, 15 Jun 2023 16:39:54 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D6CB286322 for ; Thu, 15 Jun 2023 16:39:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-3f8d0e814dfso17751315e9.3 for ; Thu, 15 Jun 2023 07:39:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1686839988; x=1689431988; 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=61ie7ffeZLDrV/rQmRkAKeKsA9nIScFTAiCEvUN1jVc=; b=pEemA3lAagUcNAWb4QqYOPDuMKJNmCoLW0qFNbBGg6oPYgpYtEHwFWj46EwufABLbp fJZ6Hy36PIpYclj94qStXXhReklbZ1v9vI7zue7G3H6GHCHeFFC+3y+SuVHKoLeKbewD NbBNoQAqqojfrFINQOWCMAQLEd69jOPpNUxd2NQvAAkJ0VA6I3iQE0Nk8iwd3gRj8shr SkN6HhLc7BRZfhF4CjBHXYShh9wALr3vNVXENR0YL4tmHWnrU7wVBwQ+Q4yQ7xo77oUb FtqZTTVikdFW/ZweK6JDj6UHW9H7WAXPvBklDc7SLFy3gqQeQXDXmc1Jo9EL2LFSIVVh fwZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686839988; x=1689431988; 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=61ie7ffeZLDrV/rQmRkAKeKsA9nIScFTAiCEvUN1jVc=; b=f9mWWJebta840cEUXV+UDqohE6JGhcSsLBRJWEK3zyq3ZdYpgRXLcFbmDfLdfL8KQo 5IxgooXV0h9lOVBmjy2gN4I2gjk55gLOXkip7ITqFTfbCLt0DqUK3iKSvyHEeEBAhxLn ctOBNws3p7Pcui1b3oUuX2zRP8JQbLAK+cTDa6p09PZk4csGt1d1QpMeqYCTjNw0VPAz C6Ui/JaKwrpMZn7leRRbltvOYF3rqQy5vfOPQWQF6DYpnps1iL6CjfR20uqVzqBmD2Hl 3katfIM8mmNnx0UQlX6YWxDLqTlM1a4CN/GfoJKOw/agxjKNxQYPIJlnrsqc7ucc1FLJ 99Iw== X-Gm-Message-State: AC+VfDzUTI25Q/5sgM1xp09x2fqLoYce2Q7/P2q6scpjdRaPzApsiaG3 i9Im1RxEkqUYrUcNMbFMqIIdRFWXw2AiJrhD6MTtAg== X-Received: by 2002:a05:600c:a3a9:b0:3f8:d79f:dadb with SMTP id hn41-20020a05600ca3a900b003f8d79fdadbmr4275708wmb.38.1686839988365; Thu, 15 Jun 2023 07:39:48 -0700 (PDT) Received: from localhost.localdomain (ppp089210114029.access.hol.gr. [89.210.114.29]) by smtp.gmail.com with ESMTPSA id w11-20020a1cf60b000000b003f7ff6b1201sm20601273wmc.29.2023.06.15.07.39.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Jun 2023 07:39:48 -0700 (PDT) From: Ilias Apalodimas To: u-boot@lists.denx.de Cc: Ilias Apalodimas , Heinrich Schuchardt Subject: [PATCH 5/5] efi_selftests: add extra testcases on controller handling Date: Thu, 15 Jun 2023 17:39:41 +0300 Message-Id: <20230615143941.416924-5-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230615143941.416924-1-ilias.apalodimas@linaro.org> References: <20230615143941.416924-1-ilias.apalodimas@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean We recently fixed a few issues wrt to controller handling. Add a few test cases to cover the new code. - add a second driver in the same controller handle which will refuse to unbind on the first protocol removal - add tests to verify controllers are reconnected when uninstalling a protocol fails - add tests to make sure EFI_NOT_FOUND is returned if a non existent interface is being removed Signed-off-by: Ilias Apalodimas --- lib/efi_selftest/efi_selftest_controllers.c | 221 ++++++++++++++++++-- 1 file changed, 198 insertions(+), 23 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c index 79bc86fb0c3a..d2a974079329 100644 --- a/lib/efi_selftest/efi_selftest_controllers.c +++ b/lib/efi_selftest/efi_selftest_controllers.c @@ -13,6 +13,8 @@ #include #define NUMBER_OF_CHILD_CONTROLLERS 4 +#define CONTROLLER1_DRIVERS (1 + NUMBER_OF_CHILD_CONTROLLERS) +#define CONTROLLER2_DRIVERS 1 static int interface1 = 1; static int interface2 = 2; @@ -22,24 +24,32 @@ const efi_guid_t guid_driver_binding_protocol = static efi_guid_t guid_controller = EFI_GUID(0xe6ab1d96, 0x6bff, 0xdb42, 0xaa, 0x05, 0xc8, 0x1f, 0x7f, 0x45, 0x26, 0x34); + +static efi_guid_t guid_controller2 = + EFI_GUID(0xe6ab1d96, 0x6bff, 0xdb42, + 0xaa, 0x50, 0x8c, 0xf1, 0xf7, 0x54, 0x62, 0x43); + static efi_guid_t guid_child_controller = EFI_GUID(0x1d41f6f5, 0x2c41, 0xddfb, 0xe2, 0x9b, 0xb8, 0x0e, 0x2e, 0xe8, 0x3a, 0x85); static efi_handle_t handle_controller; static efi_handle_t handle_child_controller[NUMBER_OF_CHILD_CONTROLLERS]; static efi_handle_t handle_driver; +static efi_handle_t handle_driver2; + +static bool allow_remove; /* - * Count child controllers + * Count controllers * - * @handle handle on which child controllers are installed + * @handle handle on which controllers and children are installed * @protocol protocol for which the child controllers were installed * @count number of child controllers + * @children: count children only * Return: status code */ -static efi_status_t count_child_controllers(efi_handle_t handle, - efi_guid_t *protocol, - efi_uintn_t *count) +static efi_status_t count_controllers(efi_handle_t handle, efi_guid_t *protocol, + efi_uintn_t *count, bool children) { efi_status_t ret; efi_uintn_t entry_count; @@ -52,10 +62,14 @@ static efi_status_t count_child_controllers(efi_handle_t handle, return ret; if (!entry_count) return EFI_SUCCESS; - while (entry_count) { - if (entry_buffer[--entry_count].attributes & - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) - ++*count; + if (!children) { + *count = entry_count; + } else { + while (entry_count) { + if (entry_buffer[--entry_count].attributes & + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) + ++*count; + } } ret = boottime->free_pool(entry_buffer); if (ret != EFI_SUCCESS) @@ -153,6 +167,22 @@ static efi_status_t EFIAPI start( return EFI_ST_FAILURE; } } + + /* Attach driver to controller */ + ret = boottime->open_protocol(controller_handle, &guid_controller2, + &interface, handle_driver2, + controller_handle, + EFI_OPEN_PROTOCOL_BY_DRIVER); + switch (ret) { + case EFI_SUCCESS: + return EFI_SUCCESS; + case EFI_ALREADY_STARTED: + case EFI_ACCESS_DENIED: + return ret; + default: + return EFI_UNSUPPORTED; + } + return ret; } @@ -249,6 +279,50 @@ static efi_status_t EFIAPI stop( return EFI_SUCCESS; } +/* + * Check if the driver supports the controller. + * + * @this driver binding protocol + * @controller_handle handle of the controller + * @remaining_device_path path specifying the child controller + * Return: status code + */ +static efi_status_t EFIAPI supported2(struct efi_driver_binding_protocol *this, + efi_handle_t controller_handle, + struct efi_device_path *remaining_dp) +{ + return EFI_SUCCESS; +} + +/* + * Refuse to disconnect the controller. + * + * @this driver binding protocol + * @controller_handle handle of the controller + * @number_of_children number of child controllers to remove + * @child_handle_buffer handles of the child controllers to remove + * Return: status code + */ +static efi_status_t EFIAPI stop2(struct efi_driver_binding_protocol *this, + efi_handle_t controller_handle, + size_t number_of_children, + efi_handle_t *child_handle_buffer) +{ + efi_status_t ret; + + if (!allow_remove) + return EFI_DEVICE_ERROR; + + /* Detach driver from controller */ + ret = boottime->close_protocol(controller_handle, &guid_controller2, + handle_driver2, controller_handle); + if (ret != EFI_SUCCESS) { + efi_st_error("Cannot close protocol\n"); + return ret; + } + return EFI_SUCCESS; +} + /* Driver binding protocol interface */ static struct efi_driver_binding_protocol binding_interface = { supported, @@ -259,6 +333,15 @@ static struct efi_driver_binding_protocol binding_interface = { NULL, }; +static struct efi_driver_binding_protocol binding_interface2 = { + supported2, + start, + stop2, + 0xffffffff, + NULL, + NULL, + }; + /* * Setup unit test. * @@ -273,6 +356,18 @@ static int setup(const efi_handle_t img_handle, boottime = systable->boottime; handle_controller = NULL; handle_driver = NULL; + handle_driver2 = NULL; + allow_remove = false; + + /* Create controller handles */ + ret = boottime->install_protocol_interface(&handle_controller, + &guid_controller2, + EFI_NATIVE_INTERFACE, + &interface1); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } /* Create controller handle */ ret = boottime->install_protocol_interface( @@ -291,6 +386,16 @@ static int setup(const efi_handle_t img_handle, return EFI_ST_FAILURE; } + /* Create driver handle which will fail on stop() */ + ret = boottime->install_protocol_interface(&handle_driver2, + &guid_driver_binding_protocol, + EFI_NATIVE_INTERFACE, + &binding_interface2); + if (ret != EFI_SUCCESS) { + efi_st_error("InstallProtocolInterface failed\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; } @@ -310,7 +415,7 @@ static int setup(const efi_handle_t img_handle, */ static int execute(void) { - efi_status_t ret; + efi_status_t ret = EFI_SUCCESS; efi_uintn_t count; /* Connect controller to driver */ @@ -319,9 +424,79 @@ static int execute(void) efi_st_error("Failed to connect controller\n"); return EFI_ST_FAILURE; } + /* Check number of drivers */ + ret = count_controllers(handle_controller, &guid_controller2, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER2_DRIVERS) { + efi_st_error("Failed to connect controller\n"); + return EFI_ST_FAILURE; + } + ret = count_controllers(handle_controller, &guid_controller, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER1_DRIVERS) { + efi_st_error("Failed to connect controller\n"); + return EFI_ST_FAILURE; + } + + /* Try to uninstall controller protocol which doesn't exist */ + ret = boottime->uninstall_protocol_interface(handle_controller, + &guid_controller2, + &interface2); + if (ret != EFI_NOT_FOUND) { + efi_st_error("Interface not checked when uninstalling protocol\n"); + return EFI_ST_FAILURE; + } + + /* Try to uninstall controller protocol which can't be stopped */ + ret = boottime->uninstall_protocol_interface(handle_controller, + &guid_controller, + &interface1); + if (ret != EFI_DEVICE_ERROR) { + efi_st_error("EFI_DRIVER_BINDING_PROTOCOL.Stop() not checked\n"); + return EFI_ST_FAILURE; + } + /* Check number of drivers again to make sure controolers reconnected */ + ret = count_controllers(handle_controller, &guid_controller2, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER2_DRIVERS) { + efi_st_error("Failed to reconnect controller\n"); + return EFI_ST_FAILURE; + } + ret = count_controllers(handle_controller, &guid_controller, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER1_DRIVERS) { + efi_st_error("Failed to reconnect controller\n"); + return EFI_ST_FAILURE; + } + + /* Try to uninstall controller protocol which can't be stopped */ + ret = boottime->uninstall_protocol_interface(handle_controller, + &guid_controller2, + &interface1); + if (ret != EFI_DEVICE_ERROR) { + efi_st_error("EFI_DRIVER_BINDING_PROTOCOL.Stop() not checked\n"); + return EFI_ST_FAILURE; + } + + /* Check number of drivers again to make sure controllers reconnected */ + ret = count_controllers(handle_controller, &guid_controller2, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER2_DRIVERS) { + efi_st_error("Failed to reconnect controller\n"); + return EFI_ST_FAILURE; + } + ret = count_controllers(handle_controller, &guid_controller, + &count, false); + if (ret != EFI_SUCCESS || count != CONTROLLER1_DRIVERS) { + efi_st_error("Failed to reconnect controller\n"); + return EFI_ST_FAILURE; + } + + allow_remove = true; + /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) { efi_st_error("Number of children %u != %u\n", (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS); @@ -335,8 +510,8 @@ static int execute(void) return EFI_ST_FAILURE; } /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS - 1) { efi_st_error("Destroying single child controller failed\n"); return EFI_ST_FAILURE; @@ -348,8 +523,8 @@ static int execute(void) return EFI_ST_FAILURE; } /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret != EFI_SUCCESS || count) { efi_st_error("Destroying child controllers failed\n"); return EFI_ST_FAILURE; @@ -362,8 +537,8 @@ static int execute(void) return EFI_ST_FAILURE; } /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) { efi_st_error("Number of children %u != %u\n", (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS); @@ -387,8 +562,8 @@ static int execute(void) return EFI_ST_FAILURE; } /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) { efi_st_error("Number of children %u != %u\n", (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS); @@ -402,14 +577,13 @@ static int execute(void) return EFI_ST_FAILURE; } /* Check number of child controllers */ - ret = count_child_controllers(handle_controller, &guid_controller, - &count); + ret = count_controllers(handle_controller, &guid_controller, + &count, true); if (ret == EFI_SUCCESS || count != 0) { efi_st_error("Uninstall failed\n"); return EFI_ST_FAILURE; } - return EFI_ST_SUCCESS; } @@ -420,6 +594,7 @@ static int execute(void) static int teardown(void) { efi_status_t ret; + /* Uninstall binding protocol */ ret = boottime->uninstall_protocol_interface(handle_driver, &guid_driver_binding_protocol,