diff options
Diffstat (limited to 'usr/src/uts/i86pc/os/microcode.c')
-rw-r--r-- | usr/src/uts/i86pc/os/microcode.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/os/microcode.c b/usr/src/uts/i86pc/os/microcode.c index e59bdb8530..d07a79bf18 100644 --- a/usr/src/uts/i86pc/os/microcode.c +++ b/usr/src/uts/i86pc/os/microcode.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ #include <sys/asm_linkage.h> @@ -754,8 +755,15 @@ ucode_write(xc_arg_t arg1, xc_arg_t unused2, xc_arg_t unused3) return (0); } - if (!on_trap(&otd, OT_DATA_ACCESS)) + if (!on_trap(&otd, OT_DATA_ACCESS)) { + /* + * On some platforms a cache invalidation is required for the + * ucode update to be successful due to the parts of the + * processor that the microcode is updating. + */ + invalidate_cache(); wrmsr(ucode->write_msr, (uintptr_t)uusp->ucodep); + } no_trap(); #endif @@ -849,6 +857,12 @@ ucode_load_intel(ucode_file_t *ufp, cpu_ucode_info_t *uinfop, cpu_t *cp) uus.new_rev = uinfop->cui_rev; #else kpreempt_disable(); + /* + * On some platforms a cache invalidation is required for the + * ucode update to be successful due to the parts of the + * processor that the microcode is updating. + */ + invalidate_cache(); wrmsr(ucode->write_msr, (uintptr_t)ucodefp->uf_body); ucode->read_rev(uinfop); kpreempt_enable(); @@ -1131,8 +1145,11 @@ ucode_update(uint8_t *ucodep, int size) mutex_exit(&cpu_lock); - if (!found) + if (!found) { rc = search_rc; + } else if (rc == EM_OK) { + cpuid_post_ucodeadm(); + } return (rc); } |