diff options
author | kib <kib@FreeBSD.org> | 2018-01-12 10:54:00 +0000 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2018-02-19 14:50:11 -0300 |
commit | baf97fd773b0e19536ce41d9325f923f68da228e (patch) | |
tree | c3c45c35c60444ecedde435499693ae809a38111 /sys | |
parent | 3fc6a8b162a129fe68141c503b32e15a57320907 (diff) | |
download | FreeBSD-src-baf97fd773b0e19536ce41d9325f923f68da228e.zip FreeBSD-src-baf97fd773b0e19536ce41d9325f923f68da228e.tar.gz |
MFC r327597:
Make it possible to re-evaluate cpu_features.
(cherry picked from commit a586b974f77aedb619baf0454435fa4016339161)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 2 | ||||
-rw-r--r-- | sys/dev/cpuctl/cpuctl.c | 30 | ||||
-rw-r--r-- | sys/sys/cpuctl.h | 1 | ||||
-rw-r--r-- | sys/x86/include/x86_var.h | 3 | ||||
-rw-r--r-- | sys/x86/x86/identcpu.c | 46 |
5 files changed, 59 insertions, 23 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 3ed29e0..8e508c3 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1559,7 +1559,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) kmdp = init_ops.parse_preload_data(modulep); - identify_cpu(); + identify_cpu1(); identify_hypervisor(); /* Init basic tunables, hz etc */ diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c index 5351d8ed..6a854e4 100644 --- a/sys/dev/cpuctl/cpuctl.c +++ b/sys/dev/cpuctl/cpuctl.c @@ -71,6 +71,7 @@ static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td); static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data, struct thread *td); +static int cpuctl_do_eval_cpu_features(int cpu, struct thread *td); static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data, struct thread *td); static int update_intel(int cpu, cpuctl_update_args_t *args, @@ -157,7 +158,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, } /* Require write flag for "write" requests. */ if ((cmd == CPUCTL_MSRCBIT || cmd == CPUCTL_MSRSBIT || - cmd == CPUCTL_UPDATE || cmd == CPUCTL_WRMSR) && + cmd == CPUCTL_UPDATE || cmd == CPUCTL_WRMSR || + cmd == CPUCTL_EVAL_CPU_FEATURES) && (flags & FWRITE) == 0) return (EPERM); switch (cmd) { @@ -185,6 +187,9 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, ret = cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_count_args_t *)data, td); break; + case CPUCTL_EVAL_CPU_FEATURES: + ret = cpuctl_do_eval_cpu_features(cpu, td); + break; default: ret = EINVAL; break; @@ -502,6 +507,29 @@ fail: return (ret); } +static int +cpuctl_do_eval_cpu_features(int cpu, struct thread *td) +{ + int is_bound = 0; + int oldcpu; + + KASSERT(cpu >= 0 && cpu <= mp_maxid, + ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu)); + +#ifdef __i386__ + if (cpu_id == 0) + return (ENODEV); +#endif + oldcpu = td->td_oncpu; + is_bound = cpu_sched_is_bound(td); + set_cpu(cpu, td); + identify_cpu1(); + identify_cpu2(); + restore_cpu(oldcpu, is_bound, td); + return (0); +} + + int cpuctl_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) { diff --git a/sys/sys/cpuctl.h b/sys/sys/cpuctl.h index 30af524..65556ec 100644 --- a/sys/sys/cpuctl.h +++ b/sys/sys/cpuctl.h @@ -57,5 +57,6 @@ typedef struct { #define CPUCTL_MSRSBIT _IOWR('c', 5, cpuctl_msr_args_t) #define CPUCTL_MSRCBIT _IOWR('c', 6, cpuctl_msr_args_t) #define CPUCTL_CPUID_COUNT _IOWR('c', 7, cpuctl_cpuid_count_args_t) +#define CPUCTL_EVAL_CPU_FEATURES _IO('c', 8) #endif /* _CPUCTL_H_ */ diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index 7705a1c..ffdf2f0 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -116,7 +116,8 @@ void cpu_setregs(void); void dump_add_page(vm_paddr_t); void dump_drop_page(vm_paddr_t); void finishidentcpu(void); -void identify_cpu(void); +void identify_cpu1(void); +void identify_cpu2(void); void identify_hypervisor(void); void initializecpu(void); void initializecpucache(void); diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c index c0cc2a6..ab7214c 100644 --- a/sys/x86/x86/identcpu.c +++ b/sys/x86/x86/identcpu.c @@ -1370,9 +1370,8 @@ fix_cpuid(void) return (false); } -#ifdef __amd64__ void -identify_cpu(void) +identify_cpu1(void) { u_int regs[4]; @@ -1389,7 +1388,29 @@ identify_cpu(void) cpu_feature = regs[3]; cpu_feature2 = regs[2]; } -#endif + +void +identify_cpu2(void) +{ + u_int regs[4], cpu_stdext_disable; + + if (cpu_high >= 7) { + cpuid_count(7, 0, regs); + cpu_stdext_feature = regs[1]; + + /* + * Some hypervisors failed to filter out unsupported + * extended features. Allow to disable the + * extensions, activation of which requires setting a + * bit in CR4, and which VM monitors do not support. + */ + cpu_stdext_disable = 0; + TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable); + cpu_stdext_feature &= ~cpu_stdext_disable; + + cpu_stdext_feature2 = regs[2]; + } +} /* * Final stage of CPU identification. @@ -1397,7 +1418,7 @@ identify_cpu(void) void finishidentcpu(void) { - u_int regs[4], cpu_stdext_disable; + u_int regs[4]; #ifdef __i386__ u_char ccr3; #endif @@ -1416,22 +1437,7 @@ finishidentcpu(void) cpu_mon_max_size = regs[1] & CPUID5_MON_MAX_SIZE; } - if (cpu_high >= 7) { - cpuid_count(7, 0, regs); - cpu_stdext_feature = regs[1]; - - /* - * Some hypervisors failed to filter out unsupported - * extended features. Allow to disable the - * extensions, activation of which requires setting a - * bit in CR4, and which VM monitors do not support. - */ - cpu_stdext_disable = 0; - TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable); - cpu_stdext_feature &= ~cpu_stdext_disable; - - cpu_stdext_feature2 = regs[2]; - } + identify_cpu2(); #ifdef __i386__ if (cpu_high > 0 && |