Received: by 10.223.185.116 with SMTP id b49csp4947750wrg; Wed, 7 Mar 2018 03:58:38 -0800 (PST) X-Google-Smtp-Source: AG47ELtv/tjUQo86aFwGu7H8/bJM7K3B1Vf49zGUnscLXpmxWvSDmIwFMjgeu5e4l0nZXlDLqQa/ X-Received: by 2002:a17:902:864b:: with SMTP id y11-v6mr20024446plt.380.1520423918736; Wed, 07 Mar 2018 03:58:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520423918; cv=none; d=google.com; s=arc-20160816; b=Mi0Cfh0Q203+3M2GP1aPNCM0qHoIbrjz480uVpg4gN4WFsjejy2Wfesqi5u/b6S1yB zhC3lM0URJoJcItJbnKVq3WjwtgaAykF1CkwM9uXik9IYSMChtrRP+zahAotM8WhIKHT B96BJFdHvSRehVJdl3jWByfmwQrgXTPGml4cxlKj4mP1voq7OjSiEzoboUR2QUcMtWwV jbl3A7e+V/Pc8b2ZfY0z5U0r94ZUoYLtfWObAsJ4Gsdrk+LFln5wmxrVqKIcMvIItzbT OdoZ/LuqXaVEzNkgjdhkmBBPn71Q5N+wC71MlG/WhTWiNWwi2e3lqdS1exYnRyqTgVVC nkyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=0Wqo3ef1ePiG5cvjbw/rPNJ2Q4q2QRMxKNGFid7S74Q=; b=ew6vd5zdCaFJP3n0Od2oGB4bHRS0s8qlWaLSx69G3W5zkz1fojpbmFW0Uw9j0O6VTU glNfmnRYDto2ZZ/9Tp2BoCpt4ihhWF74vymkm+hDsBeX3mVnmxiyiSalqMInSq9AQT2B XhF+ymDIoWM3dROu7b03EPyeBzwW7b1Nj87MjLV1wsxnOLhIxB2Blk+IfEZ9ciKkqSJX ycmNZupuzFbant2O1qTq3jv0Ogml1oaU1WIG3vQAe5bC1T5S1ujnm4Oh+H+l/ZzQhlXL nGM1oDEFbxqzaua+kOXXGt/D1q4M7mNVgoT4HBT6nFoauXUO1YaHCAJJscVql8DSflsp H/KQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=t9Q4Kaac; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m16si11267526pgn.290.2018.03.07.03.58.24; Wed, 07 Mar 2018 03:58:38 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=t9Q4Kaac; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754382AbeCGLz1 (ORCPT + 99 others); Wed, 7 Mar 2018 06:55:27 -0500 Received: from mail-qt0-f196.google.com ([209.85.216.196]:39378 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754279AbeCGLzW (ORCPT ); Wed, 7 Mar 2018 06:55:22 -0500 Received: by mail-qt0-f196.google.com with SMTP id n9so2226617qtk.6; Wed, 07 Mar 2018 03:55:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=0Wqo3ef1ePiG5cvjbw/rPNJ2Q4q2QRMxKNGFid7S74Q=; b=t9Q4Kaacz3Z4WjH+xbEnoYo8KL7YPUvlyj2w2HXRGCjhSgwW77U8V9Nn6gzeIJnmdB 0LmbHD+8Qb8d14cVgbx7C8Ig9PaOOc4h4rk4jsUCzWvITysQOPfOon7rHkOseYOcCQ97 Y8sAKWLjaK/vkDGjHVMRB4DRU8EPIPClxB4XHDMvIMnNFDolG9ht4bfSsDJGqQewgSMs qXtvCvSdrZDLmcTLCjoelfkUwTAs0If5lSveIja/76PJHzVtKG279cmVtVPWtXu90uM/ D3ev7DiZHTxmVDdxQKU7MojJzT8KmlhGvizGfHnKyFy8a/Eh5wSnxoS5/gxQB029sGhU +QyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=0Wqo3ef1ePiG5cvjbw/rPNJ2Q4q2QRMxKNGFid7S74Q=; b=Ukg1k3S/7x7RTeGtLPJDaskmAZu12es+vUaQ2aNRZ7fw38tS3IHQr3MkBUAwEHd26B Vi7682q1ASrzxefpO7mg+xXkyFcu4YheAW0WnEYwEJgiNeNbuST9+Ovpbd3n0Jia8BDr IiBqLwrS5vLSKaSIECFa8WQahq3NGpQGVG6FL3oHB3QpCapwJUz0tGCTeAn5ZVjw4R9Q zYFCFXhqGrhyqR6Fiy00AUzD7WyxtcRs+WO6E9+89+ay/g0p1nxZM4ZfwdNZk6uOtl/t 8IbmoaGnt+xL3CZbA/yriqvmhRBqvS7CAqOYX83s+8HljWLhw8IEcENlv8MZQt1EXrWA Vm0g== X-Gm-Message-State: AElRT7ERSLg6o7C4m30uSXPxKbHscWRqUHsRfxjdjxYtzdX+5exfrFqw Nzhi7QzxOgurOLvcRUNj/LUNN96esP6fSd48oWY= X-Received: by 10.237.36.170 with SMTP id t39mr34781693qtc.136.1520423721071; Wed, 07 Mar 2018 03:55:21 -0800 (PST) MIME-Version: 1.0 Received: by 10.200.52.247 with HTTP; Wed, 7 Mar 2018 03:55:00 -0800 (PST) In-Reply-To: <1520292190-5027-3-git-send-email-sai.praneeth.prakhya@intel.com> References: <1520292190-5027-1-git-send-email-sai.praneeth.prakhya@intel.com> <1520292190-5027-3-git-send-email-sai.praneeth.prakhya@intel.com> From: Miguel Ojeda Date: Wed, 7 Mar 2018 12:55:00 +0100 Message-ID: Subject: Re: [PATCH V2 2/3] efi: Introduce efi_rts_workqueue and some infrastructure to invoke all efi_runtime_services() To: Sai Praneeth Prakhya Cc: linux-efi@vger.kernel.org, linux-kernel , Lee@vger.kernel.org, Chun-Yi , Borislav Petkov , Tony Luck , Will Deacon , Dave Hansen , Mark Rutland , Bhupesh Sharma , Ricardo Neri , Ravi Shankar , Matt Fleming , Peter Zijlstra , Ard Biesheuvel , Dan Williams Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 6, 2018 at 12:23 AM, Sai Praneeth Prakhya wrote: > From: Sai Praneeth > > When a process requests the kernel to execute any efi_runtime_service(), > the requested efi_runtime_service (represented as an identifier) and its > arguments are packed into a struct named efi_runtime_work and queued > onto work queue named efi_rts_wq. The caller then waits until the work > is completed. > > Introduce some infrastructure: > 1. Creating workqueue named efi_rts_wq > 2. A macro (efi_queue_work()) that > a. populates efi_runtime_work > b. queues work onto efi_rts_wq and > c. waits until worker thread returns > > The caller thread has to wait until the worker thread returns, because > it's dependent on the return status of efi_runtime_service() and, in > specific cases, the arguments populated by efi_runtime_service(). Some > efi_runtime_services() takes a pointer to buffer as an argument and > fills up the buffer with requested data. For instance, > efi_get_variable() and efi_get_next_variable(). Hence, caller process > cannot just post the work and get going. > > Some facts about efi_runtime_services(): > 1. A quick look at all the efi_runtime_services() shows that any > efi_runtime_service() has five or less arguments. > 2. An argument of efi_runtime_service() can be a value (of any type) > or a pointer (of any type). > Hence, efi_runtime_work has five void pointers to store these arguments. > > Signed-off-by: Sai Praneeth Prakhya > Suggested-by: Andy Lutomirski > Cc: Lee, Chun-Yi > Cc: Borislav Petkov > Cc: Tony Luck > Cc: Will Deacon > Cc: Dave Hansen > Cc: Mark Rutland > Cc: Bhupesh Sharma > Cc: Ricardo Neri > Cc: Ravi Shankar > Cc: Matt Fleming > Cc: Peter Zijlstra > Cc: Ard Biesheuvel > Cc: Dan Williams > --- > drivers/firmware/efi/efi.c | 15 ++++++++ > drivers/firmware/efi/runtime-wrappers.c | 61 +++++++++++++++++++++++++++++++++ > include/linux/efi.h | 20 +++++++++++ > 3 files changed, 96 insertions(+) > > diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c > index 838b8efe639c..04b46c62f3ce 100644 > --- a/drivers/firmware/efi/efi.c > +++ b/drivers/firmware/efi/efi.c > @@ -75,6 +75,8 @@ static unsigned long *efi_tables[] = { > &efi.mem_attr_table, > }; > > +struct workqueue_struct *efi_rts_wq; > + > static bool disable_runtime; > static int __init setup_noefi(char *arg) > { > @@ -329,6 +331,19 @@ static int __init efisubsys_init(void) > return 0; > > /* > + * Since we process only one efi_runtime_service() at a time, an > + * ordered workqueue (which creates only one execution context) > + * should suffice all our needs. > + */ > + efi_rts_wq = alloc_ordered_workqueue("efi_rts_workqueue", 0); efi_rts_wq or efi_rts_workqueue? > + if (!efi_rts_wq) { > + pr_err("Failed to create efi_rts_workqueue, EFI runtime services " Same here. > + "disabled.\n"); > + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); > + return 0; > + } > + > + /* > * Clean DUMMY object calls EFI Runtime Service, set_variable(), so > * it should be invoked only after efi_rts_workqueue is ready. > */ > diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c > index ae54870b2788..649763171439 100644 > --- a/drivers/firmware/efi/runtime-wrappers.c > +++ b/drivers/firmware/efi/runtime-wrappers.c > @@ -1,6 +1,14 @@ > /* > * runtime-wrappers.c - Runtime Services function call wrappers > * > + * Implementation summary: > + * ----------------------- > + * 1. When user/kernel thread requests to execute efi_runtime_service(), > + * enqueue work to efi_rts_workqueue. > + * 2. Caller thread waits until the work is finished because it's > + * dependent on the return status and execution of efi_runtime_service(). > + * For instance, get_variable() and get_next_variable(). > + * > * Copyright (C) 2014 Linaro Ltd. > * > * Split off from arch/x86/platform/efi/efi.c > @@ -22,6 +30,8 @@ > #include > #include > #include > +#include > + > #include > > /* > @@ -33,6 +43,57 @@ > #define __efi_call_virt(f, args...) \ > __efi_call_virt_pointer(efi.systab->runtime, f, args) > > +/* efi_runtime_service() function identifiers */ > +enum { > + GET_TIME, > + SET_TIME, > + GET_WAKEUP_TIME, > + SET_WAKEUP_TIME, > + GET_VARIABLE, > + GET_NEXT_VARIABLE, > + SET_VARIABLE, > + SET_VARIABLE_NONBLOCKING, > + QUERY_VARIABLE_INFO, > + QUERY_VARIABLE_INFO_NONBLOCKING, > + GET_NEXT_HIGH_MONO_COUNT, > + RESET_SYSTEM, > + UPDATE_CAPSULE, > + QUERY_CAPSULE_CAPS, > +}; Much cleaner now :-) > + > +/* > + * efi_queue_work: Queue efi_runtime_service() and wait until it's done > + * @rts: efi_runtime_service() function identifier > + * @rts_arg<1-5>: efi_runtime_service() function arguments > + * > + * Accesses to efi_runtime_services() are serialized by a binary > + * semaphore (efi_runtime_lock) and caller waits until the work is > + * finished, hence _only_ one work is queued at a time and the queued > + * work gets flushed. > + */ > +#define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5) \ > +({ \ > + struct efi_runtime_work efi_rts_work; \ > + \ > + INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts); \ > + efi_rts_work.func = _rts; \ > + efi_rts_work.arg1 = _arg1; \ > + efi_rts_work.arg2 = _arg2; \ > + efi_rts_work.arg3 = _arg3; \ > + efi_rts_work.arg4 = _arg4; \ > + efi_rts_work.arg5 = _arg5; \ > + /* \ > + * queue_work() returns 0 if work was already on queue, \ > + * _ideally_ this should never happen. \ > + */ \ > + if (queue_work(efi_rts_wq, &efi_rts_work.work)) \ > + flush_work(&efi_rts_work.work); \ > + else \ > + BUG(); \ Thanks for the change! One remark, I would just do: > + if (!queue_work(efi_rts_wq, &efi_rts_work.work)) \ > + BUG(); \ And then you can unindent: > + flush_work(&efi_rts_work.work); \ > + \ > + efi_rts_work.status; \ > +}) > + > void efi_call_virt_check_flags(unsigned long flags, const char *call) > { > unsigned long cur_flags, mismatch; > diff --git a/include/linux/efi.h b/include/linux/efi.h > index c4efb3ef0dfa..bb06b71af55c 100644 > --- a/include/linux/efi.h > +++ b/include/linux/efi.h > @@ -1652,4 +1652,24 @@ struct linux_efi_tpm_eventlog { > > extern int efi_tpm_eventlog_init(void); > > +/* > + * efi_runtime_work: Details of EFI Runtime Service work > + * @func: EFI Runtime Service function identifier > + * @arg<1-5>: EFI Runtime Service function arguments > + * @status: Status of executing EFI Runtime Service > + */ > +struct efi_runtime_work { > + u8 func; > + void *arg1; > + void *arg2; > + void *arg3; > + void *arg4; > + void *arg5; > + efi_status_t status; > + struct work_struct work; > +}; Why is efi_runtime_work in the .h at all? Please CC me for the next version! :-) Cheers, Miguel > + > +/* Workqueue to queue EFI Runtime Services */ > +extern struct workqueue_struct *efi_rts_wq; > + > #endif /* _LINUX_EFI_H */ > -- > 2.7.4 >