Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1396326 > unrolled thread

[PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests

Started byMario Limonciello <mario_limonciello@dell.com>
First post2016-05-07 18:00 +0200
Last post2016-05-09 16:30 +0200
Articles 3 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests Mario Limonciello <mario_limonciello@dell.com> - 2016-05-07 18:00 +0200
    Re: [PATCH v2 1/2] dell-smbios: Add a helper function for complex  SMI requests Michał Kępień <kernel@kempniu.pl> - 2016-05-09 14:10 +0200
      RE: [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI  requests <Mario_Limonciello@Dell.com> - 2016-05-09 16:30 +0200

#1396326 — [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests

FromMario Limonciello <mario_limonciello@dell.com>
Date2016-05-07 18:00 +0200
Subject[PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests
Message-ID<rwcO6-46p-5@gated-at.bofh.it>
More complex SMI requests can return data that exceeds the 4 32 byte
arguments that are traditionally part of a request.

To support more complex requests, the first input argument can be a
32 bit physical address with a buffer properly built in advance.

This helper function prepares the buffer as the BIOS will look for
it in these requests.

Signed-off-by: Mario Limonciello <mario_limonciello@dell.com>
---
 drivers/platform/x86/dell-smbios.c | 28 ++++++++++++++++++++++++++++
 drivers/platform/x86/dell-smbios.h |  1 +
 2 files changed, 29 insertions(+)

diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
index d2412ab..00b29df 100644
--- a/drivers/platform/x86/dell-smbios.c
+++ b/drivers/platform/x86/dell-smbios.c
@@ -92,6 +92,34 @@ void dell_smbios_send_request(int class, int select)
 }
 EXPORT_SYMBOL_GPL(dell_smbios_send_request);
 
+/* More complex requests are served by sending
+ * a pointer to a pre-allocated buffer
+ * Bytes 0:3 are the size of the return value
+ * Bytes 4:length are the returned value
+ *
+ * This helper function prepares it properly
+ * with the size length to be provided
+ *
+ * caller still needs to pre-allocate and clear
+ * the input buffer
+ */
+void dell_smbios_prepare_v2_call(u8 *input, size_t length)
+{
+	u32 i;
+	u32 *data = (u32 *) input;
+
+	data[0] = length - 4;
+	for (i = 4; i < length; i += 4) {
+		if (length - i > 4) {
+			input[i]   = 'D';
+			input[i+1] = 'S';
+			input[i+2] = 'C';
+			input[i+3] = 'I';
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(dell_smbios_prepare_v2_call);
+
 struct calling_interface_token *dell_smbios_find_token(int tokenid)
 {
 	int i;
diff --git a/drivers/platform/x86/dell-smbios.h b/drivers/platform/x86/dell-smbios.h
index ec7d40a..5d4184c 100644
--- a/drivers/platform/x86/dell-smbios.h
+++ b/drivers/platform/x86/dell-smbios.h
@@ -41,6 +41,7 @@ struct calling_interface_buffer *dell_smbios_get_buffer(void);
 void dell_smbios_clear_buffer(void);
 void dell_smbios_release_buffer(void);
 void dell_smbios_send_request(int class, int select);
+void dell_smbios_prepare_v2_call(u8 *input, size_t length);
 
 struct calling_interface_token *dell_smbios_find_token(int tokenid);
 #endif
-- 
2.7.4

[toc] | [next] | [standalone]


#1396990 — Re: [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests

FromMichał Kępień <kernel@kempniu.pl>
Date2016-05-09 14:10 +0200
SubjectRe: [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests
Message-ID<rwSaD-5og-41@gated-at.bofh.it>
In reply to#1396326
> More complex SMI requests can return data that exceeds the 4 32 byte

32-bit

> arguments that are traditionally part of a request.
> 
> To support more complex requests, the first input argument can be a
> 32 bit physical address with a buffer properly built in advance.
> 
> This helper function prepares the buffer as the BIOS will look for
> it in these requests.
> 
> Signed-off-by: Mario Limonciello <mario_limonciello@dell.com>
> ---
>  drivers/platform/x86/dell-smbios.c | 28 ++++++++++++++++++++++++++++
>  drivers/platform/x86/dell-smbios.h |  1 +
>  2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
> index d2412ab..00b29df 100644
> --- a/drivers/platform/x86/dell-smbios.c
> +++ b/drivers/platform/x86/dell-smbios.c
> @@ -92,6 +92,34 @@ void dell_smbios_send_request(int class, int select)
>  }
>  EXPORT_SYMBOL_GPL(dell_smbios_send_request);
>  
> +/* More complex requests are served by sending
> + * a pointer to a pre-allocated buffer
> + * Bytes 0:3 are the size of the return value
> + * Bytes 4:length are the returned value
> + *
> + * This helper function prepares it properly
> + * with the size length to be provided
> + *
> + * caller still needs to pre-allocate and clear
> + * the input buffer

Which input buffer, the original one (struct calling_interface_buffer)
or the one for "complex requests"?

If the former, pre-allocation is done by dell_smbios_init() while
dell_smbios_get_buffer() clears the buffer before use, so the comment
above may be misleading.

If the latter, then the caller in patch 2/2 doesn't clear the input
buffer, it just allocates it using __get_free_page().

> + */
> +void dell_smbios_prepare_v2_call(u8 *input, size_t length)
> +{
> +	u32 i;
> +	u32 *data = (u32 *) input;
> +
> +	data[0] = length - 4;
> +	for (i = 4; i < length; i += 4) {
> +		if (length - i > 4) {
> +			input[i]   = 'D';
> +			input[i+1] = 'S';
> +			input[i+2] = 'C';
> +			input[i+3] = 'I';

memcpy(&input[i], "DSCI", 4) or something along those lines?

Anyway, I'm confused about filling the buffer with repeating "DSCI"
strings.  The buffer's length is provided explicitly in its first four
bytes.  Some bytes at the end will always be left uninitialized.  So why
bother initializing anything besides length at all?

> +		}
> +	}
> +}
> +EXPORT_SYMBOL_GPL(dell_smbios_prepare_v2_call);
> +
>  struct calling_interface_token *dell_smbios_find_token(int tokenid)
>  {
>  	int i;
> diff --git a/drivers/platform/x86/dell-smbios.h b/drivers/platform/x86/dell-smbios.h
> index ec7d40a..5d4184c 100644
> --- a/drivers/platform/x86/dell-smbios.h
> +++ b/drivers/platform/x86/dell-smbios.h
> @@ -41,6 +41,7 @@ struct calling_interface_buffer *dell_smbios_get_buffer(void);
>  void dell_smbios_clear_buffer(void);
>  void dell_smbios_release_buffer(void);
>  void dell_smbios_send_request(int class, int select);
> +void dell_smbios_prepare_v2_call(u8 *input, size_t length);

I will send my remarks regarding the proposed changes to dell-smbios API
in response to patch 2/2.

-- 
Best regards,
Michał Kępień

[toc] | [prev] | [next] | [standalone]


#1397091 — RE: [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests

From<Mario_Limonciello@Dell.com>
Date2016-05-09 16:30 +0200
SubjectRE: [PATCH v2 1/2] dell-smbios: Add a helper function for complex SMI requests
Message-ID<rwUm6-7na-17@gated-at.bofh.it>
In reply to#1396990
> -----Original Message-----
> From: Michał Kępień [mailto:kernel@kempniu.pl]
> Sent: Monday, May 9, 2016 7:02 AM
> To: Limonciello, Mario <Mario_Limonciello@Dell.com>
> Cc: dvhart@infradead.org; LKML <linux-kernel@vger.kernel.org>; platform-
> driver-x86@vger.kernel.org
> Subject: Re: [PATCH v2 1/2] dell-smbios: Add a helper function for complex
> SMI requests
> 
> > More complex SMI requests can return data that exceeds the 4 32 byte
> 
> 32-bit

Ack, thanks.

> 
> > arguments that are traditionally part of a request.
> >
> > To support more complex requests, the first input argument can be a
> > 32 bit physical address with a buffer properly built in advance.
> >
> > This helper function prepares the buffer as the BIOS will look for it
> > in these requests.
> >
> > Signed-off-by: Mario Limonciello <mario_limonciello@dell.com>
> > ---
> >  drivers/platform/x86/dell-smbios.c | 28
> ++++++++++++++++++++++++++++
> > drivers/platform/x86/dell-smbios.h |  1 +
> >  2 files changed, 29 insertions(+)
> >
> > diff --git a/drivers/platform/x86/dell-smbios.c
> > b/drivers/platform/x86/dell-smbios.c
> > index d2412ab..00b29df 100644
> > --- a/drivers/platform/x86/dell-smbios.c
> > +++ b/drivers/platform/x86/dell-smbios.c
> > @@ -92,6 +92,34 @@ void dell_smbios_send_request(int class, int
> > select)  }  EXPORT_SYMBOL_GPL(dell_smbios_send_request);
> >
> > +/* More complex requests are served by sending
> > + * a pointer to a pre-allocated buffer
> > + * Bytes 0:3 are the size of the return value
> > + * Bytes 4:length are the returned value
> > + *
> > + * This helper function prepares it properly
> > + * with the size length to be provided
> > + *
> > + * caller still needs to pre-allocate and clear
> > + * the input buffer
> 
> Which input buffer, the original one (struct calling_interface_buffer) or the
> one for "complex requests"?
> 
> If the former, pre-allocation is done by dell_smbios_init() while
> dell_smbios_get_buffer() clears the buffer before use, so the comment
> above may be misleading.
> 
> If the latter, then the caller in patch 2/2 doesn't clear the input buffer, it just
> allocates it using __get_free_page().

Yeah this is a comment mistake.  I was meaning for  the caller to just allocated it, but as your other comment noted it's better for code re-use to have this happen in dell-smbios, so I'll try to work towards that goal in next patch attempt.

> 
> > + */
> > +void dell_smbios_prepare_v2_call(u8 *input, size_t length) {
> > +	u32 i;
> > +	u32 *data = (u32 *) input;
> > +
> > +	data[0] = length - 4;
> > +	for (i = 4; i < length; i += 4) {
> > +		if (length - i > 4) {
> > +			input[i]   = 'D';
> > +			input[i+1] = 'S';
> > +			input[i+2] = 'C';
> > +			input[i+3] = 'I';
> 
> memcpy(&input[i], "DSCI", 4) or something along those lines?
> 

Yeah that's cleaner, I'll use that, thanks.

> Anyway, I'm confused about filling the buffer with repeating "DSCI"
> strings.  The buffer's length is provided explicitly in its first four bytes.  Some
> bytes at the end will always be left uninitialized.  So why bother initializing
> anything besides length at all?
> 

The reason for any of this in the first place was some situations where memory was getting clobbered because it wasn't properly allocated by users of this interface.  So the determination was to have a the 32 bit unsigned length the first 4 bytes and then repeat that string on 4 byte alignment for the rest of the buffer.  Anything not aligned on 4 bytes isn't checked by the SMM, so it's not important to initialize.

The SMM will check the buffer for that repeating string and reject (error -5) if it's not built properly.  

> > +		}
> > +	}
> > +}
> > +EXPORT_SYMBOL_GPL(dell_smbios_prepare_v2_call);
> > +
> >  struct calling_interface_token *dell_smbios_find_token(int tokenid)
> > {
> >  	int i;
> > diff --git a/drivers/platform/x86/dell-smbios.h
> > b/drivers/platform/x86/dell-smbios.h
> > index ec7d40a..5d4184c 100644
> > --- a/drivers/platform/x86/dell-smbios.h
> > +++ b/drivers/platform/x86/dell-smbios.h
> > @@ -41,6 +41,7 @@ struct calling_interface_buffer
> > *dell_smbios_get_buffer(void);  void dell_smbios_clear_buffer(void);
> > void dell_smbios_release_buffer(void);  void
> > dell_smbios_send_request(int class, int select);
> > +void dell_smbios_prepare_v2_call(u8 *input, size_t length);
> 
> I will send my remarks regarding the proposed changes to dell-smbios API in
> response to patch 2/2.
> 
> --
> Best regards,
> Michał Kępień

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web