Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cpuctl/cpuctl.c
Show First 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
uint32_t tmp[4]; | uint32_t tmp[4]; | ||||
wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)ucode_ptr); | wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)ucode_ptr); | ||||
do_cpuid(0, tmp); | do_cpuid(0, tmp); | ||||
} | } | ||||
static int | static int | ||||
update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td) | update_amd(int cpu __unused, cpuctl_update_args_t *args, struct thread *td) | ||||
{ | { | ||||
cpuset_t cpus; | |||||
void *ptr; | void *ptr; | ||||
int ret; | int i, ret; | ||||
if (args->size == 0 || args->data == NULL) { | if (args->size == 0 || args->data == NULL) { | ||||
DPRINTF("[cpuctl,%d]: zero-sized firmware image", __LINE__); | DPRINTF("[cpuctl,%d]: zero-sized firmware image", __LINE__); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (args->size > UCODE_SIZE_MAX) { | if (args->size > UCODE_SIZE_MAX) { | ||||
DPRINTF("[cpuctl,%d]: firmware image too large", __LINE__); | DPRINTF("[cpuctl,%d]: firmware image too large", __LINE__); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* | /* | ||||
* 16 byte alignment required. Rely on the fact that | * 16 byte alignment required. Rely on the fact that | ||||
* malloc(9) always returns the pointer aligned at least on | * malloc(9) always returns the pointer aligned at least on | ||||
* the size of the allocation. | * the size of the allocation. | ||||
*/ | */ | ||||
ptr = malloc(args->size + 16, M_CPUCTL, M_ZERO | M_WAITOK); | ptr = malloc(args->size + 16, M_CPUCTL, M_ZERO | M_WAITOK); | ||||
if (copyin(args->data, ptr, args->size) != 0) { | if (copyin(args->data, ptr, args->size) != 0) { | ||||
DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed", | DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed", | ||||
__LINE__, args->data, ptr, args->size); | __LINE__, args->data, ptr, args->size); | ||||
ret = EFAULT; | ret = EFAULT; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
smp_rendezvous(NULL, amd_ucode_wrmsr, NULL, ptr); | |||||
/* | |||||
* Update microcode on each physical CPU. | |||||
*/ | |||||
#ifdef SMP | |||||
CPU_ZERO(&cpus); | |||||
CPU_FOREACH(i) { | |||||
if (!CPU_ISSET(i, &logical_cpus_mask)) | |||||
CPU_SET(i, &cpus); | |||||
} | |||||
#else | |||||
CPU_FILL(&cpus); | |||||
(void)i; | |||||
#endif | |||||
smp_rendezvous_cpus(cpus, NULL, amd_ucode_wrmsr, NULL, ptr); | |||||
ret = 0; | ret = 0; | ||||
fail: | fail: | ||||
free(ptr, M_CPUCTL); | free(ptr, M_CPUCTL); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static int | static int | ||||
update_via(int cpu, cpuctl_update_args_t *args, struct thread *td) | update_via(int cpu, cpuctl_update_args_t *args, struct thread *td) | ||||
▲ Show 20 Lines • Show All 147 Lines • Show Last 20 Lines |