From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>
Cc: Thomas.Lendacky@amd.com, keir@xen.org,
Suravee.Suthikulpanit@amd.com, jbeulich@suse.com,
xen-devel@lists.xen.org
Subject: Re: [PATCH] x86, amd_ucode: Verify max allowed patch size before apply
Date: Thu, 24 Apr 2014 21:26:50 +0100 [thread overview]
Message-ID: <5359738A.6050607@citrix.com> (raw)
In-Reply-To: <1398369287-2501-1-git-send-email-aravind.gopalakrishnan@amd.com>
On 24/04/14 20:54, Aravind Gopalakrishnan wrote:
> Each family has a stipulated max patch_size. Use this as
> additional sanity check before we apply it.
>
> Also, if we find current patch level equal or higher, then we
> return early from microcode_fits, but we don't do anything about it.
> This means we waste a bit of boot time needlessly parsing remainder
> of firmware image.
>
> This patch returns EEXIST when above situation occurs so that-
> If we do apply patch during presmp_init, then we save bit of time
> when these routines are invoked during microcode_init.
> If there is nothing to apply during presmp_init, then we flush
> out ucode_blob.size and ucode_blob.data anyway since we are
> already at required level.
>
> Since 'microcode_fits' returns int now, modify error machinery
> to return EINVAL for error and '0' for success.
>
> While at it, fix comment at very top to indicate we support ucode
> patch loading from fam10h and higher.
>
> Signed-off-by: Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>
> Reviewed-by: Tom Lendacky <Thomas.Lendacky@amd.com>
> Reviewed-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> ---
> xen/arch/x86/microcode_amd.c | 70 +++++++++++++++++++++++++++++++++++-------
> 1 file changed, 59 insertions(+), 11 deletions(-)
>
> diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
> index b227173..6fafe85 100644
> --- a/xen/arch/x86/microcode_amd.c
> +++ b/xen/arch/x86/microcode_amd.c
> @@ -8,7 +8,7 @@
> * Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
> *
> * This driver allows to upgrade microcode on AMD
> - * family 0x10 and 0x11 processors.
> + * family 0x10 and later.
> *
> * Licensed unter the terms of the GNU General Public
> * License version 2. See file COPYING for details.
> @@ -94,7 +94,40 @@ static int collect_cpu_info(int cpu, struct cpu_signature *csig)
> return 0;
> }
>
> -static bool_t microcode_fits(const struct microcode_amd *mc_amd, int cpu)
> +static bool_t verify_patch_size(uint32_t patch_size)
> +{
> + uint8_t family;
> + uint32_t max_size;
> +
> +#define F1XH_MPB_MAX_SIZE 2048
> +#define F14H_MPB_MAX_SIZE 1824
> +#define F15H_MPB_MAX_SIZE 4096
> +#define F16H_MPB_MAX_SIZE 3458
> +
> + family = boot_cpu_data.x86;
> + switch (family)
You can drop the family variable and just switch on boot_cpu_data.x86
> + {
> + case 0x14:
> + max_size = F14H_MPB_MAX_SIZE;
> + break;
> + case 0x15:
> + max_size = F15H_MPB_MAX_SIZE;
> + break;
> + case 0x16:
> + max_size = F16H_MPB_MAX_SIZE;
> + break;
> + default:
> + max_size = F1XH_MPB_MAX_SIZE;
> + break;
> + }
> +
> + if ( patch_size > max_size )
> + return 0;
> +
> + return 1;
> +}
> +
> +static int microcode_fits(const struct microcode_amd *mc_amd, int cpu)
> {
> struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
> const struct microcode_header_amd *mc_header = mc_amd->mpb;
> @@ -118,19 +151,25 @@ static bool_t microcode_fits(const struct microcode_amd *mc_amd, int cpu)
> }
>
> if ( !equiv_cpu_id )
> - return 0;
> + return -EINVAL;
>
> if ( (mc_header->processor_rev_id) != equiv_cpu_id )
> - return 0;
> + return -EINVAL;
> +
> + if ( !verify_patch_size(mc_amd->mpb_size) )
> + {
> + printk(KERN_ERR "microcode: patch size mismatch\n");
> + return -EINVAL;
XENLOG_ERR "microcode patch size too large"
return -E2BIG;
And is this really worth being an error as opposed to a warning, or
frankly even just debug? It is presumably one of N possible blobs in the
hypercall.
> + }
>
> if ( mc_header->patch_id <= uci->cpu_sig.rev )
> - return 0;
> + return -EEXIST;
>
> printk(KERN_DEBUG "microcode: CPU%d found a matching microcode "
> "update with version %#x (current=%#x)\n",
> cpu, mc_header->patch_id, uci->cpu_sig.rev);
>
> - return 1;
> + return 0;
> }
>
> static int apply_microcode(int cpu)
> @@ -319,7 +358,8 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
> while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, bufsize,
> &offset)) == 0 )
> {
> - if ( microcode_fits(mc_amd, cpu) )
> + error = microcode_fits(mc_amd, cpu);
> + if ( !error )
> {
> error = apply_microcode(cpu);
> if ( error )
> @@ -329,6 +369,11 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
>
> last_offset = offset;
>
> + if ( error == -EEXIST ) {
> + printk(KERN_DEBUG "microcode: patch is already at required level or greater.\n");
> + break;
You can't break from the loop here. What if a subsequent blob in the
buffer contains a newer piece of microcode?
~Andrew
> + }
> +
> if ( offset >= bufsize )
> break;
> }
> @@ -370,9 +415,11 @@ static int microcode_resume_match(int cpu, const void *mc)
> struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
> struct microcode_amd *mc_amd = uci->mc.mc_amd;
> const struct microcode_amd *src = mc;
> + int error;
>
> - if ( !microcode_fits(src, cpu) )
> - return 0;
> + error = microcode_fits(src, cpu);
> + if ( error )
> + return error;
>
> if ( src != mc_amd )
> {
> @@ -383,10 +430,11 @@ static int microcode_resume_match(int cpu, const void *mc)
> xfree(mc_amd);
> }
>
> + error = -ENOMEM;
> mc_amd = xmalloc(struct microcode_amd);
> uci->mc.mc_amd = mc_amd;
> if ( !mc_amd )
> - return -ENOMEM;
> + return error;
> mc_amd->equiv_cpu_table = xmalloc_bytes(src->equiv_cpu_table_size);
> if ( !mc_amd->equiv_cpu_table )
> goto err1;
> @@ -408,7 +456,7 @@ err2:
> err1:
> xfree(mc_amd);
> uci->mc.mc_amd = NULL;
> - return -ENOMEM;
> + return error;
> }
>
> static int start_update(void)
next prev parent reply other threads:[~2014-04-24 20:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-24 19:54 [PATCH] x86, amd_ucode: Verify max allowed patch size before apply Aravind Gopalakrishnan
2014-04-24 20:26 ` Andrew Cooper [this message]
2014-04-25 19:48 ` Aravind Gopalakrishnan
2014-04-25 20:30 ` Andrew Cooper
2014-04-28 8:49 ` Jan Beulich
2014-04-28 15:48 ` Aravind Gopalakrishnan
2014-04-25 7:00 ` Jan Beulich
2014-04-25 19:48 ` Aravind Gopalakrishnan
2014-04-28 7:21 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5359738A.6050607@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=Suravee.Suthikulpanit@amd.com \
--cc=Thomas.Lendacky@amd.com \
--cc=aravind.gopalakrishnan@amd.com \
--cc=jbeulich@suse.com \
--cc=keir@xen.org \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).