mirror of
https://github.com/ipxe/ipxe
synced 2026-02-14 02:31:26 +03:00
[ucode] Remove userptr_t from microcode update mechanism
Simplify the microcode update mechanism by assuming that status reports are accessible via direct pointer dereferences. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -149,41 +149,38 @@ static const char * ucode_vendor_name ( const union ucode_vendor_id *vendor ) {
|
|||||||
*
|
*
|
||||||
* @v update Microcode update
|
* @v update Microcode update
|
||||||
* @v control Microcode update control
|
* @v control Microcode update control
|
||||||
|
* @v status Microcode update status
|
||||||
* @v summary Microcode update summary
|
* @v summary Microcode update summary
|
||||||
* @v id APIC ID
|
* @v id APIC ID
|
||||||
* @v optional Status report is optional
|
* @v optional Status report is optional
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int ucode_status ( struct ucode_update *update,
|
static int ucode_status ( const struct ucode_update *update,
|
||||||
struct ucode_control *control,
|
const struct ucode_control *control,
|
||||||
|
const struct ucode_status *status,
|
||||||
struct ucode_summary *summary,
|
struct ucode_summary *summary,
|
||||||
unsigned int id, int optional ) {
|
unsigned int id, int optional ) {
|
||||||
struct ucode_status status;
|
|
||||||
struct ucode_descriptor *desc;
|
struct ucode_descriptor *desc;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert ( id <= control->apic_max );
|
assert ( id <= control->apic_max );
|
||||||
|
|
||||||
/* Read status report */
|
|
||||||
copy_from_user ( &status, phys_to_virt ( control->status ),
|
|
||||||
( id * sizeof ( status ) ), sizeof ( status ) );
|
|
||||||
|
|
||||||
/* Ignore empty optional status reports */
|
/* Ignore empty optional status reports */
|
||||||
if ( optional && ( ! status.signature ) )
|
if ( optional && ( ! status->signature ) )
|
||||||
return 0;
|
return 0;
|
||||||
DBGC ( update, "UCODE %#08x signature %#08x ucode %#08x->%#08x\n",
|
DBGC ( update, "UCODE %#08x signature %#08x ucode %#08x->%#08x\n",
|
||||||
id, status.signature, status.before, status.after );
|
id, status->signature, status->before, status->after );
|
||||||
|
|
||||||
/* Check CPU signature */
|
/* Check CPU signature */
|
||||||
if ( ! status.signature ) {
|
if ( ! status->signature ) {
|
||||||
DBGC2 ( update, "UCODE %#08x has no signature\n", id );
|
DBGC2 ( update, "UCODE %#08x has no signature\n", id );
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check APIC ID is correct */
|
/* Check APIC ID is correct */
|
||||||
if ( status.id != id ) {
|
if ( status->id != id ) {
|
||||||
DBGC ( update, "UCODE %#08x wrong APIC ID %#08x\n",
|
DBGC ( update, "UCODE %#08x wrong APIC ID %#08x\n",
|
||||||
id, status.id );
|
id, status->id );
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,29 +192,29 @@ static int ucode_status ( struct ucode_update *update,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check microcode was not downgraded */
|
/* Check microcode was not downgraded */
|
||||||
if ( status.after < status.before ) {
|
if ( status->after < status->before ) {
|
||||||
DBGC ( update, "UCODE %#08x was downgraded %#08x->%#08x\n",
|
DBGC ( update, "UCODE %#08x was downgraded %#08x->%#08x\n",
|
||||||
id, status.before, status.after );
|
id, status->before, status->after );
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that expected updates (if any) were applied */
|
/* Check that expected updates (if any) were applied */
|
||||||
for ( desc = update->desc ; desc->signature ; desc++ ) {
|
for ( desc = update->desc ; desc->signature ; desc++ ) {
|
||||||
if ( ( desc->signature == status.signature ) &&
|
if ( ( desc->signature == status->signature ) &&
|
||||||
( status.after < desc->version ) ) {
|
( status->after < desc->version ) ) {
|
||||||
DBGC ( update, "UCODE %#08x failed update %#08x->%#08x "
|
DBGC ( update, "UCODE %#08x failed update %#08x->%#08x "
|
||||||
"(wanted %#08x)\n", id, status.before,
|
"(wanted %#08x)\n", id, status->before,
|
||||||
status.after, desc->version );
|
status->after, desc->version );
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update summary */
|
/* Update summary */
|
||||||
summary->count++;
|
summary->count++;
|
||||||
if ( status.before < summary->low )
|
if ( status->before < summary->low )
|
||||||
summary->low = status.before;
|
summary->low = status->before;
|
||||||
if ( status.after > summary->high )
|
if ( status->after > summary->high )
|
||||||
summary->high = status.after;
|
summary->high = status->after;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -231,13 +228,13 @@ static int ucode_status ( struct ucode_update *update,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int ucode_update_all ( struct image *image,
|
static int ucode_update_all ( struct image *image,
|
||||||
struct ucode_update *update,
|
const struct ucode_update *update,
|
||||||
struct ucode_summary *summary ) {
|
struct ucode_summary *summary ) {
|
||||||
struct ucode_control control;
|
struct ucode_control control;
|
||||||
struct ucode_vendor *vendor;
|
struct ucode_vendor *vendor;
|
||||||
userptr_t status;
|
struct ucode_status *status;
|
||||||
unsigned int max;
|
unsigned int max;
|
||||||
unsigned int i;
|
unsigned int id;
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -248,7 +245,7 @@ static int ucode_update_all ( struct image *image,
|
|||||||
|
|
||||||
/* Allocate status reports */
|
/* Allocate status reports */
|
||||||
max = mp_max_cpuid();
|
max = mp_max_cpuid();
|
||||||
len = ( ( max + 1 ) * sizeof ( struct ucode_status ) );
|
len = ( ( max + 1 ) * sizeof ( *status ) );
|
||||||
status = umalloc ( len );
|
status = umalloc ( len );
|
||||||
if ( ! status ) {
|
if ( ! status ) {
|
||||||
DBGC ( image, "UCODE %s could not allocate %d status reports\n",
|
DBGC ( image, "UCODE %s could not allocate %d status reports\n",
|
||||||
@@ -274,8 +271,9 @@ static int ucode_update_all ( struct image *image,
|
|||||||
|
|
||||||
/* Update microcode on boot processor */
|
/* Update microcode on boot processor */
|
||||||
mp_exec_boot ( ucode_update, &control );
|
mp_exec_boot ( ucode_update, &control );
|
||||||
if ( ( rc = ucode_status ( update, &control, summary,
|
id = mp_boot_cpuid();
|
||||||
mp_boot_cpuid(), 0 ) ) != 0 ) {
|
if ( ( rc = ucode_status ( update, &control, &status[id],
|
||||||
|
summary, id, 0 ) ) != 0 ) {
|
||||||
DBGC ( image, "UCODE %s failed on boot processor: %s\n",
|
DBGC ( image, "UCODE %s failed on boot processor: %s\n",
|
||||||
image->name, strerror ( rc ) );
|
image->name, strerror ( rc ) );
|
||||||
goto err_boot;
|
goto err_boot;
|
||||||
@@ -293,9 +291,9 @@ static int ucode_update_all ( struct image *image,
|
|||||||
|
|
||||||
/* Check status reports */
|
/* Check status reports */
|
||||||
summary->count = 0;
|
summary->count = 0;
|
||||||
for ( i = 0 ; i <= max ; i++ ) {
|
for ( id = 0 ; id <= max ; id++ ) {
|
||||||
if ( ( rc = ucode_status ( update, &control, summary,
|
if ( ( rc = ucode_status ( update, &control, &status[id],
|
||||||
i, 1 ) ) != 0 ) {
|
summary, id, 1 ) ) != 0 ) {
|
||||||
goto err_status;
|
goto err_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user