All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>
To: Andrew Cooper <andrew.cooper3@citrix.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: Fri, 25 Apr 2014 14:48:06 -0500	[thread overview]
Message-ID: <535ABBF6.1060303@amd.com> (raw)
In-Reply-To: <5359738A.6050607@citrix.com>

On 4/24/2014 3:26 PM, Andrew Cooper wrote:
> On 24/04/14 20:54, Aravind Gopalakrishnan wrote:
>>   
>> -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

Noted.
>> +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.

Right. Modified it to use XENLOG_DEBUG instead.
>>   
>>   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?
>     

Right. Didn't think about that. Sorry..

But I ran into larger issues here:
Since we don't break on the first match and continue to parse the entire 
fw image till the very end;
*and* since I modified the error handling around 'microcode_fits' thus:

if ( (mc_header->processor_rev_id) != equiv_cpu_id )

-return 0;

+return -EINVAL;

+

The last returned error val is '-22' which is bubbled up to microcode.c. 
'microcode_presmp_init' as a result
flushes out ucode_blob or NULL-ifies ucode_mod_map.

Which means 'microcode_init' returns early as it can't validate 
ucode_mod.mod_end or ucode_blob.size
Now, this breaks original functionality (sorry for catching this late), 
*but*
doesn't cause any problem to updating(,applying) ucode patches to cpus 
as we apply the patches during
'microcode_resume_cpu' anyway.  (which is why I thought at first all is 
fine)

Could someone please help me understand why there are two initcalls - 
'microcode_presmp_init' && 'microcode_init'
that perform the same tasks?

It results in these functions - 'collect_cpu_info', 
'cpu_request_microcode' to run a second time through 'microcode_init'
when we have already accomplished the job of updating cpu with microcode 
patches
through 'microcode_presmp_init' and 'microcode_resume_cpu'

If there is particular reason for 'microcode_init''s existence, then 
I'll modify the patch so that the error handling around 'microcode_fits'
is not altered. But if not, then I simply have to just remove the 
'break' statement.

Thanks,
-Aravind.

  reply	other threads:[~2014-04-25 19:48 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
2014-04-25 19:48   ` Aravind Gopalakrishnan [this message]
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=535ABBF6.1060303@amd.com \
    --to=aravind.gopalakrishnan@amd.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=andrew.cooper3@citrix.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.