+ if (processor == PROCESSOR_NULL) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ return processor_shutdown(processor);
+}
+
+
+kern_return_t
+processor_start_from_user(
+ processor_t processor)
+{
+ kern_return_t ret;
+
+ if (processor == PROCESSOR_NULL) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ if (!cpu_can_exit(processor->cpu_id)) {
+ ret = sched_processor_enable(processor, TRUE);
+ } else {
+ ret = processor_start(processor);
+ }
+
+ return ret;
+}
+
+kern_return_t
+processor_exit_from_user(
+ processor_t processor)
+{
+ kern_return_t ret;
+
+ if (processor == PROCESSOR_NULL) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ if (!cpu_can_exit(processor->cpu_id)) {
+ ret = sched_processor_enable(processor, FALSE);
+ } else {
+ ret = processor_shutdown(processor);
+ }
+
+ return ret;
+}
+
+kern_return_t
+enable_smt_processors(bool enable)
+{
+ if (machine_info.logical_cpu_max == machine_info.physical_cpu_max) {
+ /* Not an SMT system */
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ int ncpus = machine_info.logical_cpu_max;
+
+ for (int i = 1; i < ncpus; i++) {
+ processor_t processor = processor_array[i];
+
+ if (processor->processor_primary != processor) {
+ if (enable) {
+ processor_start_from_user(processor);
+ } else { /* Disable */
+ processor_exit_from_user(processor);
+ }
+ }
+ }
+
+#define BSD_HOST 1
+ host_basic_info_data_t hinfo;
+ mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+ kern_return_t kret = host_info((host_t)BSD_HOST, HOST_BASIC_INFO, (host_info_t)&hinfo, &count);
+ if (kret != KERN_SUCCESS) {
+ return kret;
+ }