diff mbox

[2/2] efi_runtime: add UEFI runtime service QueryVariableInfo interface

Message ID 1348820809-4489-1-git-send-email-ivan.hu@canonical.com
State Accepted
Headers show

Commit Message

Ivan Hu Sept. 28, 2012, 8:26 a.m. UTC
This interface is always returned EFI_UNSUPPORTED from
virt_fei_query_variable_info on kernel driver efi.c because of checking
the runtime_version. It seems that runtime_version value always 0,
it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.

Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
---
 efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
 efi_runtime/efi_runtime.h |   11 +++++++++++
 2 files changed, 31 insertions(+)

Comments

Keng-Yu Lin Oct. 3, 2012, 8:10 a.m. UTC | #1
Hi Ivan,
  The commit log looks like a bug in the kernel you found while you
were implementing this patch.
  Do you have further analysis or idea on the cause or how it can be
potentially fixed we can probably help out here?

On Fri, Sep 28, 2012 at 4:26 PM, Ivan Hu <ivan.hu@canonical.com> wrote:
> This interface is always returned EFI_UNSUPPORTED from
> virt_fei_query_variable_info on kernel driver efi.c because of checking
> the runtime_version. It seems that runtime_version value always 0,
> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.
>
> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
> ---
>  efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>  efi_runtime/efi_runtime.h |   11 +++++++++++
>  2 files changed, 31 insertions(+)
>
> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
> index 227a910..0e66e94 100644
> --- a/efi_runtime/efi_runtime.c
> +++ b/efi_runtime/efi_runtime.c
> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>         struct efi_getnextvariablename __user *pgetnextvariablename;
>         unsigned long name_size;
>
> +       struct efi_queryvariableinfo __user *pqueryvariableinfo;
> +
>         switch (cmd) {
>         case EFI_RUNTIME_GET_VARIABLE:
>                 pgetvariable = (struct efi_getvariable __user *)arg;
> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>                                                 &vendor_guid, sizeof(EFI_GUID)))
>                         return -EFAULT;
>                 return 0;
> +
> +       case EFI_RUNTIME_QUERY_VARIABLEINFO:
> +
> +               pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
> +
> +               if (get_user(attr, &pqueryvariableinfo->Attributes))
> +                       return -EFAULT;
> +
> +               status = efi.query_variable_info(attr,
> +                               pqueryvariableinfo->MaximumVariableStorageSize,
> +                               pqueryvariableinfo->RemainingVariableStorageSize
> +                               , pqueryvariableinfo->MaximumVariableSize);
> +               if (put_user(status, pqueryvariableinfo->status))
> +                       return -EFAULT;
> +               if (status != EFI_SUCCESS)
> +                       return -EINVAL;
> +
> +               return 0;
>         }
>
>         return -ENOTTY;
> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
> index 7387406..cc33878 100644
> --- a/efi_runtime/efi_runtime.h
> +++ b/efi_runtime/efi_runtime.h
> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>         uint64_t        *status;
>  } __attribute__ ((packed));
>
> +struct efi_queryvariableinfo {
> +       uint32_t        Attributes;
> +       uint64_t        *MaximumVariableStorageSize;
> +       uint64_t        *RemainingVariableStorageSize;
> +       uint64_t        *MaximumVariableSize;
> +       uint64_t        *status;
> +} __attribute__ ((packed));
> +
>  struct efi_gettime {
>         EFI_TIME                *Time;
>         EFI_TIME_CAPABILITIES   *Capabilities;
> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>  #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>         _IOWR('p', 0x07, struct efi_getnextvariablename)
>
> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
> +       _IOR('p', 0x08, struct efi_queryvariableinfo)
> +
>  #endif /* _EFI_RUNTIME_H_ */
> --
> 1.7.9.5
>
>
> --
> fwts-devel mailing list
> fwts-devel@lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/fwts-devel
Ivan Hu Oct. 3, 2012, 9:33 a.m. UTC | #2
Hi Kengyu,

This interface will call the RT service via virt_efi_query_variable_info 
function in efi.c below:

static efi_status_t virt_efi_query_variable_info(u32 attr,
						 u64 *storage_space,
						 u64 *remaining_space,
						 u64 *max_variable_size)
{
	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
		return EFI_UNSUPPORTED;

	return efi_call_virt4(query_variable_info, attr, storage_space,
			      remaining_space, max_variable_size);
}

I dumped the value runtime_version equal 0 and it seems that the value 
of runtime_version doesn't be set. I think the kernel may not implement 
to check the version. I did a simple test as well, just removed the 
checking runtime version, directly call the efi_call_virt4, the function 
worked fine.

On 10/03/2012 04:10 PM, Keng-Yu Lin wrote:
> Hi Ivan,
>    The commit log looks like a bug in the kernel you found while you
> were implementing this patch.
>    Do you have further analysis or idea on the cause or how it can be
> potentially fixed we can probably help out here?
>
> On Fri, Sep 28, 2012 at 4:26 PM, Ivan Hu <ivan.hu@canonical.com> wrote:
>> This interface is always returned EFI_UNSUPPORTED from
>> virt_fei_query_variable_info on kernel driver efi.c because of checking
>> the runtime_version. It seems that runtime_version value always 0,
>> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.
>>
>> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
>> ---
>>   efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>>   efi_runtime/efi_runtime.h |   11 +++++++++++
>>   2 files changed, 31 insertions(+)
>>
>> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
>> index 227a910..0e66e94 100644
>> --- a/efi_runtime/efi_runtime.c
>> +++ b/efi_runtime/efi_runtime.c
>> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>>          struct efi_getnextvariablename __user *pgetnextvariablename;
>>          unsigned long name_size;
>>
>> +       struct efi_queryvariableinfo __user *pqueryvariableinfo;
>> +
>>          switch (cmd) {
>>          case EFI_RUNTIME_GET_VARIABLE:
>>                  pgetvariable = (struct efi_getvariable __user *)arg;
>> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>>                                                  &vendor_guid, sizeof(EFI_GUID)))
>>                          return -EFAULT;
>>                  return 0;
>> +
>> +       case EFI_RUNTIME_QUERY_VARIABLEINFO:
>> +
>> +               pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
>> +
>> +               if (get_user(attr, &pqueryvariableinfo->Attributes))
>> +                       return -EFAULT;
>> +
>> +               status = efi.query_variable_info(attr,
>> +                               pqueryvariableinfo->MaximumVariableStorageSize,
>> +                               pqueryvariableinfo->RemainingVariableStorageSize
>> +                               , pqueryvariableinfo->MaximumVariableSize);
>> +               if (put_user(status, pqueryvariableinfo->status))
>> +                       return -EFAULT;
>> +               if (status != EFI_SUCCESS)
>> +                       return -EINVAL;
>> +
>> +               return 0;
>>          }
>>
>>          return -ENOTTY;
>> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
>> index 7387406..cc33878 100644
>> --- a/efi_runtime/efi_runtime.h
>> +++ b/efi_runtime/efi_runtime.h
>> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>>          uint64_t        *status;
>>   } __attribute__ ((packed));
>>
>> +struct efi_queryvariableinfo {
>> +       uint32_t        Attributes;
>> +       uint64_t        *MaximumVariableStorageSize;
>> +       uint64_t        *RemainingVariableStorageSize;
>> +       uint64_t        *MaximumVariableSize;
>> +       uint64_t        *status;
>> +} __attribute__ ((packed));
>> +
>>   struct efi_gettime {
>>          EFI_TIME                *Time;
>>          EFI_TIME_CAPABILITIES   *Capabilities;
>> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>>   #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>>          _IOWR('p', 0x07, struct efi_getnextvariablename)
>>
>> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
>> +       _IOR('p', 0x08, struct efi_queryvariableinfo)
>> +
>>   #endif /* _EFI_RUNTIME_H_ */
>> --
>> 1.7.9.5
>>
>>
>> --
>> fwts-devel mailing list
>> fwts-devel@lists.ubuntu.com
>> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/fwts-devel
>
Keng-Yu Lin Oct. 3, 2012, 10:03 a.m. UTC | #3
From the same file in static int __init efi_systab_init(void *phys)

                systab64 = early_ioremap((unsigned long)phys,
                                         sizeof(*systab64));
                ...(skip)...
                efi_systab.fw_revision = systab64->fw_revision;

And later
                efi.runtime_version = efi_systab.fw_revision;

I think the error you met is just the kernel checking result. (we can
probably check other machines).

Thanks for the information, this helps the review.

On Wed, Oct 3, 2012 at 5:33 PM, IvanHu <ivan.hu@canonical.com> wrote:
> Hi Kengyu,
>
> This interface will call the RT service via virt_efi_query_variable_info
> function in efi.c below:
>
> static efi_status_t virt_efi_query_variable_info(u32 attr,
>                                                  u64 *storage_space,
>                                                  u64 *remaining_space,
>                                                  u64 *max_variable_size)
> {
>         if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
>                 return EFI_UNSUPPORTED;
>
>         return efi_call_virt4(query_variable_info, attr, storage_space,
>                               remaining_space, max_variable_size);
> }
>
> I dumped the value runtime_version equal 0 and it seems that the value of
> runtime_version doesn't be set. I think the kernel may not implement to
> check the version. I did a simple test as well, just removed the checking
> runtime version, directly call the efi_call_virt4, the function worked fine.
>
>
> On 10/03/2012 04:10 PM, Keng-Yu Lin wrote:
>>
>> Hi Ivan,
>>    The commit log looks like a bug in the kernel you found while you
>> were implementing this patch.
>>    Do you have further analysis or idea on the cause or how it can be
>> potentially fixed we can probably help out here?
>>
>> On Fri, Sep 28, 2012 at 4:26 PM, Ivan Hu <ivan.hu@canonical.com> wrote:
>>>
>>> This interface is always returned EFI_UNSUPPORTED from
>>> virt_fei_query_variable_info on kernel driver efi.c because of checking
>>> the runtime_version. It seems that runtime_version value always 0,
>>> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this
>>> interface.
>>>
>>> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
>>> ---
>>>   efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>>>   efi_runtime/efi_runtime.h |   11 +++++++++++
>>>   2 files changed, 31 insertions(+)
>>>
>>> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
>>> index 227a910..0e66e94 100644
>>> --- a/efi_runtime/efi_runtime.c
>>> +++ b/efi_runtime/efi_runtime.c
>>> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file,
>>> unsigned int cmd,
>>>          struct efi_getnextvariablename __user *pgetnextvariablename;
>>>          unsigned long name_size;
>>>
>>> +       struct efi_queryvariableinfo __user *pqueryvariableinfo;
>>> +
>>>          switch (cmd) {
>>>          case EFI_RUNTIME_GET_VARIABLE:
>>>                  pgetvariable = (struct efi_getvariable __user *)arg;
>>> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file,
>>> unsigned int cmd,
>>>                                                  &vendor_guid,
>>> sizeof(EFI_GUID)))
>>>                          return -EFAULT;
>>>                  return 0;
>>> +
>>> +       case EFI_RUNTIME_QUERY_VARIABLEINFO:
>>> +
>>> +               pqueryvariableinfo = (struct efi_queryvariableinfo __user
>>> *)arg;
>>> +
>>> +               if (get_user(attr, &pqueryvariableinfo->Attributes))
>>> +                       return -EFAULT;
>>> +
>>> +               status = efi.query_variable_info(attr,
>>> +
>>> pqueryvariableinfo->MaximumVariableStorageSize,
>>> +
>>> pqueryvariableinfo->RemainingVariableStorageSize
>>> +                               ,
>>> pqueryvariableinfo->MaximumVariableSize);
>>> +               if (put_user(status, pqueryvariableinfo->status))
>>> +                       return -EFAULT;
>>> +               if (status != EFI_SUCCESS)
>>> +                       return -EINVAL;
>>> +
>>> +               return 0;
>>>          }
>>>
>>>          return -ENOTTY;
>>> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
>>> index 7387406..cc33878 100644
>>> --- a/efi_runtime/efi_runtime.h
>>> +++ b/efi_runtime/efi_runtime.h
>>> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>>>          uint64_t        *status;
>>>   } __attribute__ ((packed));
>>>
>>> +struct efi_queryvariableinfo {
>>> +       uint32_t        Attributes;
>>> +       uint64_t        *MaximumVariableStorageSize;
>>> +       uint64_t        *RemainingVariableStorageSize;
>>> +       uint64_t        *MaximumVariableSize;
>>> +       uint64_t        *status;
>>> +} __attribute__ ((packed));
>>> +
>>>   struct efi_gettime {
>>>          EFI_TIME                *Time;
>>>          EFI_TIME_CAPABILITIES   *Capabilities;
>>> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>>>   #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>>>          _IOWR('p', 0x07, struct efi_getnextvariablename)
>>>
>>> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
>>> +       _IOR('p', 0x08, struct efi_queryvariableinfo)
>>> +
>>>   #endif /* _EFI_RUNTIME_H_ */
>>> --
>>> 1.7.9.5
>>>
>>>
>>> --
>>> fwts-devel mailing list
>>> fwts-devel@lists.ubuntu.com
>>> Modify settings or unsubscribe at:
>>> https://lists.ubuntu.com/mailman/listinfo/fwts-devel
>>
>>
>
Ivan Hu Oct. 9, 2012, 7:02 a.m. UTC | #4
yup, the patch upstream to kernel could solve this problem.

commit d6cf86d8f23253225fe2a763d627ecf7dfee9dae
efi: initialize efi.runtime_version to make 
query_variable_info/update_capsule workable

This patch should work on version 3.6, but not on the Quantal.
I also upstream to stable tree of kernel version 3.5. Hope it could be 
workable earlier.
Keng-Yu Lin Oct. 9, 2012, 7:14 a.m. UTC | #5
On Tue, Oct 9, 2012 at 3:02 PM, IvanHu <ivan.hu@canonical.com> wrote:
> yup, the patch upstream to kernel could solve this problem.
>
> commit d6cf86d8f23253225fe2a763d627ecf7dfee9dae
> efi: initialize efi.runtime_version to make
> query_variable_info/update_capsule workable
>
> This patch should work on version 3.6, but not on the Quantal.
> I also upstream to stable tree of kernel version 3.5. Hope it could be
> workable earlier.

Thanks Ivan for getting this into the 3.5.y -stable.
Keng-Yu Lin Oct. 16, 2012, 9:31 a.m. UTC | #6
On Fri, Sep 28, 2012 at 4:26 PM, Ivan Hu <ivan.hu@canonical.com> wrote:
> This interface is always returned EFI_UNSUPPORTED from
> virt_fei_query_variable_info on kernel driver efi.c because of checking
> the runtime_version. It seems that runtime_version value always 0,
> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.
>
> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
> ---
>  efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>  efi_runtime/efi_runtime.h |   11 +++++++++++
>  2 files changed, 31 insertions(+)
>
> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
> index 227a910..0e66e94 100644
> --- a/efi_runtime/efi_runtime.c
> +++ b/efi_runtime/efi_runtime.c
> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>         struct efi_getnextvariablename __user *pgetnextvariablename;
>         unsigned long name_size;
>
> +       struct efi_queryvariableinfo __user *pqueryvariableinfo;
> +
>         switch (cmd) {
>         case EFI_RUNTIME_GET_VARIABLE:
>                 pgetvariable = (struct efi_getvariable __user *)arg;
> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>                                                 &vendor_guid, sizeof(EFI_GUID)))
>                         return -EFAULT;
>                 return 0;
> +
> +       case EFI_RUNTIME_QUERY_VARIABLEINFO:
> +
> +               pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
> +
> +               if (get_user(attr, &pqueryvariableinfo->Attributes))
> +                       return -EFAULT;
> +
> +               status = efi.query_variable_info(attr,
> +                               pqueryvariableinfo->MaximumVariableStorageSize,
> +                               pqueryvariableinfo->RemainingVariableStorageSize
> +                               , pqueryvariableinfo->MaximumVariableSize);
> +               if (put_user(status, pqueryvariableinfo->status))
> +                       return -EFAULT;
> +               if (status != EFI_SUCCESS)
> +                       return -EINVAL;
> +
> +               return 0;
>         }
>
>         return -ENOTTY;
> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
> index 7387406..cc33878 100644
> --- a/efi_runtime/efi_runtime.h
> +++ b/efi_runtime/efi_runtime.h
> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>         uint64_t        *status;
>  } __attribute__ ((packed));
>
> +struct efi_queryvariableinfo {
> +       uint32_t        Attributes;
> +       uint64_t        *MaximumVariableStorageSize;
> +       uint64_t        *RemainingVariableStorageSize;
> +       uint64_t        *MaximumVariableSize;
> +       uint64_t        *status;
> +} __attribute__ ((packed));
> +
>  struct efi_gettime {
>         EFI_TIME                *Time;
>         EFI_TIME_CAPABILITIES   *Capabilities;
> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>  #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>         _IOWR('p', 0x07, struct efi_getnextvariablename)
>
> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
> +       _IOR('p', 0x08, struct efi_queryvariableinfo)
> +
>  #endif /* _EFI_RUNTIME_H_ */
> --
> 1.7.9.5
>

Acked-by: Keng-Yu Lin <kengyu@canonical.com>
Alex Hung Oct. 17, 2012, 2:44 p.m. UTC | #7
On 09/28/2012 04:26 PM, Ivan Hu wrote:
> This interface is always returned EFI_UNSUPPORTED from
> virt_fei_query_variable_info on kernel driver efi.c because of checking
> the runtime_version. It seems that runtime_version value always 0,
> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.
>
> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
> ---
>   efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>   efi_runtime/efi_runtime.h |   11 +++++++++++
>   2 files changed, 31 insertions(+)
>
> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
> index 227a910..0e66e94 100644
> --- a/efi_runtime/efi_runtime.c
> +++ b/efi_runtime/efi_runtime.c
> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>   	struct efi_getnextvariablename __user *pgetnextvariablename;
>   	unsigned long name_size;
>
> +	struct efi_queryvariableinfo __user *pqueryvariableinfo;
> +
>   	switch (cmd) {
>   	case EFI_RUNTIME_GET_VARIABLE:
>   		pgetvariable = (struct efi_getvariable __user *)arg;
> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>   						&vendor_guid, sizeof(EFI_GUID)))
>   			return -EFAULT;
>   		return 0;
> +
> +	case EFI_RUNTIME_QUERY_VARIABLEINFO:
> +
> +		pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
> +
> +		if (get_user(attr, &pqueryvariableinfo->Attributes))
> +			return -EFAULT;
> +
> +		status = efi.query_variable_info(attr,
> +				pqueryvariableinfo->MaximumVariableStorageSize,
> +				pqueryvariableinfo->RemainingVariableStorageSize
> +				, pqueryvariableinfo->MaximumVariableSize);
> +		if (put_user(status, pqueryvariableinfo->status))
> +			return -EFAULT;
> +		if (status != EFI_SUCCESS)
> +			return -EINVAL;
> +
> +		return 0;
>   	}
>
>   	return -ENOTTY;
> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
> index 7387406..cc33878 100644
> --- a/efi_runtime/efi_runtime.h
> +++ b/efi_runtime/efi_runtime.h
> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>   	uint64_t	*status;
>   } __attribute__ ((packed));
>
> +struct efi_queryvariableinfo {
> +	uint32_t	Attributes;
> +	uint64_t	*MaximumVariableStorageSize;
> +	uint64_t	*RemainingVariableStorageSize;
> +	uint64_t	*MaximumVariableSize;
> +	uint64_t	*status;
> +} __attribute__ ((packed));
> +
>   struct efi_gettime {
>   	EFI_TIME		*Time;
>   	EFI_TIME_CAPABILITIES	*Capabilities;
> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>   #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>   	_IOWR('p', 0x07, struct efi_getnextvariablename)
>
> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
> +	_IOR('p', 0x08, struct efi_queryvariableinfo)
> +
>   #endif /* _EFI_RUNTIME_H_ */
>

Acked-by: Alex Hung <alex.hung@canonical.com>
Colin Ian King Oct. 17, 2012, 2:54 p.m. UTC | #8
On 28/09/12 09:26, Ivan Hu wrote:
> This interface is always returned EFI_UNSUPPORTED from
> virt_fei_query_variable_info on kernel driver efi.c because of checking
> the runtime_version. It seems that runtime_version value always 0,
> it alway returns EFI_UNSUPPORTED. Need a patch of efi.c for this interface.
>
> Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
> ---
>   efi_runtime/efi_runtime.c |   20 ++++++++++++++++++++
>   efi_runtime/efi_runtime.h |   11 +++++++++++
>   2 files changed, 31 insertions(+)
>
> diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
> index 227a910..0e66e94 100644
> --- a/efi_runtime/efi_runtime.c
> +++ b/efi_runtime/efi_runtime.c
> @@ -117,6 +117,8 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>   	struct efi_getnextvariablename __user *pgetnextvariablename;
>   	unsigned long name_size;
>
> +	struct efi_queryvariableinfo __user *pqueryvariableinfo;
> +
>   	switch (cmd) {
>   	case EFI_RUNTIME_GET_VARIABLE:
>   		pgetvariable = (struct efi_getvariable __user *)arg;
> @@ -261,6 +263,24 @@ static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
>   						&vendor_guid, sizeof(EFI_GUID)))
>   			return -EFAULT;
>   		return 0;
> +
> +	case EFI_RUNTIME_QUERY_VARIABLEINFO:
> +
> +		pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
> +
> +		if (get_user(attr, &pqueryvariableinfo->Attributes))
> +			return -EFAULT;
> +
> +		status = efi.query_variable_info(attr,
> +				pqueryvariableinfo->MaximumVariableStorageSize,
> +				pqueryvariableinfo->RemainingVariableStorageSize
> +				, pqueryvariableinfo->MaximumVariableSize);

Minor formatting issue          ^  comma should be end of previous line 
if possible.

> +		if (put_user(status, pqueryvariableinfo->status))
> +			return -EFAULT;
> +		if (status != EFI_SUCCESS)
> +			return -EINVAL;
> +
> +		return 0;
>   	}
>
>   	return -ENOTTY;
> diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
> index 7387406..cc33878 100644
> --- a/efi_runtime/efi_runtime.h
> +++ b/efi_runtime/efi_runtime.h
> @@ -73,6 +73,14 @@ struct efi_getnextvariablename {
>   	uint64_t	*status;
>   } __attribute__ ((packed));
>
> +struct efi_queryvariableinfo {
> +	uint32_t	Attributes;
> +	uint64_t	*MaximumVariableStorageSize;
> +	uint64_t	*RemainingVariableStorageSize;
> +	uint64_t	*MaximumVariableSize;
> +	uint64_t	*status;
> +} __attribute__ ((packed));
> +
>   struct efi_gettime {
>   	EFI_TIME		*Time;
>   	EFI_TIME_CAPABILITIES	*Capabilities;
> @@ -116,4 +124,7 @@ struct efi_setwakeuptime {
>   #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
>   	_IOWR('p', 0x07, struct efi_getnextvariablename)
>
> +#define EFI_RUNTIME_QUERY_VARIABLEINFO \
> +	_IOR('p', 0x08, struct efi_queryvariableinfo)
> +
>   #endif /* _EFI_RUNTIME_H_ */
>
diff mbox

Patch

diff --git a/efi_runtime/efi_runtime.c b/efi_runtime/efi_runtime.c
index 227a910..0e66e94 100644
--- a/efi_runtime/efi_runtime.c
+++ b/efi_runtime/efi_runtime.c
@@ -117,6 +117,8 @@  static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
 	struct efi_getnextvariablename __user *pgetnextvariablename;
 	unsigned long name_size;
 
+	struct efi_queryvariableinfo __user *pqueryvariableinfo;
+
 	switch (cmd) {
 	case EFI_RUNTIME_GET_VARIABLE:
 		pgetvariable = (struct efi_getvariable __user *)arg;
@@ -261,6 +263,24 @@  static long efi_runtime_ioctl(struct file *file, unsigned int cmd,
 						&vendor_guid, sizeof(EFI_GUID)))
 			return -EFAULT;
 		return 0;
+
+	case EFI_RUNTIME_QUERY_VARIABLEINFO:
+
+		pqueryvariableinfo = (struct efi_queryvariableinfo __user *)arg;
+
+		if (get_user(attr, &pqueryvariableinfo->Attributes))
+			return -EFAULT;
+
+		status = efi.query_variable_info(attr,
+				pqueryvariableinfo->MaximumVariableStorageSize,
+				pqueryvariableinfo->RemainingVariableStorageSize
+				, pqueryvariableinfo->MaximumVariableSize);
+		if (put_user(status, pqueryvariableinfo->status))
+			return -EFAULT;
+		if (status != EFI_SUCCESS)
+			return -EINVAL;
+
+		return 0;
 	}
 
 	return -ENOTTY;
diff --git a/efi_runtime/efi_runtime.h b/efi_runtime/efi_runtime.h
index 7387406..cc33878 100644
--- a/efi_runtime/efi_runtime.h
+++ b/efi_runtime/efi_runtime.h
@@ -73,6 +73,14 @@  struct efi_getnextvariablename {
 	uint64_t	*status;
 } __attribute__ ((packed));
 
+struct efi_queryvariableinfo {
+	uint32_t	Attributes;
+	uint64_t	*MaximumVariableStorageSize;
+	uint64_t	*RemainingVariableStorageSize;
+	uint64_t	*MaximumVariableSize;
+	uint64_t	*status;
+} __attribute__ ((packed));
+
 struct efi_gettime {
 	EFI_TIME		*Time;
 	EFI_TIME_CAPABILITIES	*Capabilities;
@@ -116,4 +124,7 @@  struct efi_setwakeuptime {
 #define EFI_RUNTIME_GET_NEXTVARIABLENAME \
 	_IOWR('p', 0x07, struct efi_getnextvariablename)
 
+#define EFI_RUNTIME_QUERY_VARIABLEINFO \
+	_IOR('p', 0x08, struct efi_queryvariableinfo)
+
 #endif /* _EFI_RUNTIME_H_ */