1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 #include <errno.h> 5 #include <string.h> 6 7 #include <rte_log.h> 8 9 #include "rte_power_guest_channel.h" 10 #include "guest_channel.h" 11 #include "power_common.h" 12 #include "kvm_vm.h" 13 14 #define FD_PATH "/dev/virtio-ports/virtio.serial.port.poweragent" 15 16 static struct rte_power_channel_packet pkt[RTE_MAX_LCORE]; 17 18 int 19 power_kvm_vm_check_supported(void) 20 { 21 return guest_channel_host_check_exists(FD_PATH); 22 } 23 24 int 25 power_kvm_vm_init(unsigned int lcore_id) 26 { 27 if (lcore_id >= RTE_MAX_LCORE) { 28 POWER_LOG(ERR, "Core(%u) is out of range 0...%d", 29 lcore_id, RTE_MAX_LCORE-1); 30 return -1; 31 } 32 pkt[lcore_id].command = RTE_POWER_CPU_POWER; 33 pkt[lcore_id].resource_id = lcore_id; 34 return guest_channel_host_connect(FD_PATH, lcore_id); 35 } 36 37 int 38 power_kvm_vm_exit(unsigned int lcore_id) 39 { 40 guest_channel_host_disconnect(lcore_id); 41 return 0; 42 } 43 44 uint32_t 45 power_kvm_vm_freqs(__rte_unused unsigned int lcore_id, 46 __rte_unused uint32_t *freqs, 47 __rte_unused uint32_t num) 48 { 49 POWER_LOG(ERR, "rte_power_freqs is not implemented " 50 "for Virtual Machine Power Management"); 51 return -ENOTSUP; 52 } 53 54 uint32_t 55 power_kvm_vm_get_freq(__rte_unused unsigned int lcore_id) 56 { 57 POWER_LOG(ERR, "rte_power_get_freq is not implemented " 58 "for Virtual Machine Power Management"); 59 return -ENOTSUP; 60 } 61 62 int 63 power_kvm_vm_set_freq(__rte_unused unsigned int lcore_id, 64 __rte_unused uint32_t index) 65 { 66 POWER_LOG(ERR, "rte_power_set_freq is not implemented " 67 "for Virtual Machine Power Management"); 68 return -ENOTSUP; 69 } 70 71 static inline int 72 send_msg(unsigned int lcore_id, uint32_t scale_direction) 73 { 74 int ret; 75 76 if (lcore_id >= RTE_MAX_LCORE) { 77 POWER_LOG(ERR, "Core(%u) is out of range 0...%d", 78 lcore_id, RTE_MAX_LCORE-1); 79 return -1; 80 } 81 pkt[lcore_id].unit = scale_direction; 82 ret = guest_channel_send_msg(&pkt[lcore_id], lcore_id); 83 if (ret == 0) 84 return 1; 85 POWER_LOG(DEBUG, "Error sending message: %s", 86 ret > 0 ? strerror(ret) : "channel not connected"); 87 return -1; 88 } 89 90 int 91 power_kvm_vm_freq_up(unsigned int lcore_id) 92 { 93 return send_msg(lcore_id, RTE_POWER_SCALE_UP); 94 } 95 96 int 97 power_kvm_vm_freq_down(unsigned int lcore_id) 98 { 99 return send_msg(lcore_id, RTE_POWER_SCALE_DOWN); 100 } 101 102 int 103 power_kvm_vm_freq_max(unsigned int lcore_id) 104 { 105 return send_msg(lcore_id, RTE_POWER_SCALE_MAX); 106 } 107 108 int 109 power_kvm_vm_freq_min(unsigned int lcore_id) 110 { 111 return send_msg(lcore_id, RTE_POWER_SCALE_MIN); 112 } 113 114 int 115 power_kvm_vm_turbo_status(__rte_unused unsigned int lcore_id) 116 { 117 POWER_LOG(ERR, "rte_power_turbo_status is not implemented for Virtual Machine Power Management"); 118 return -ENOTSUP; 119 } 120 121 int 122 power_kvm_vm_enable_turbo(unsigned int lcore_id) 123 { 124 return send_msg(lcore_id, RTE_POWER_ENABLE_TURBO); 125 } 126 127 int 128 power_kvm_vm_disable_turbo(unsigned int lcore_id) 129 { 130 return send_msg(lcore_id, RTE_POWER_DISABLE_TURBO); 131 } 132 133 struct rte_power_core_capabilities; 134 int power_kvm_vm_get_capabilities(__rte_unused unsigned int lcore_id, 135 __rte_unused struct rte_power_core_capabilities *caps) 136 { 137 POWER_LOG(ERR, "rte_power_get_capabilities is not implemented for Virtual Machine Power Management"); 138 return -ENOTSUP; 139 } 140 141 static struct rte_power_cpufreq_ops kvm_vm_ops = { 142 .name = "kvm-vm", 143 .init = power_kvm_vm_init, 144 .exit = power_kvm_vm_exit, 145 .check_env_support = power_kvm_vm_check_supported, 146 .get_avail_freqs = power_kvm_vm_freqs, 147 .get_freq = power_kvm_vm_get_freq, 148 .set_freq = power_kvm_vm_set_freq, 149 .freq_down = power_kvm_vm_freq_down, 150 .freq_up = power_kvm_vm_freq_up, 151 .freq_max = power_kvm_vm_freq_max, 152 .freq_min = power_kvm_vm_freq_min, 153 .turbo_status = power_kvm_vm_turbo_status, 154 .enable_turbo = power_kvm_vm_enable_turbo, 155 .disable_turbo = power_kvm_vm_disable_turbo, 156 .get_caps = power_kvm_vm_get_capabilities 157 }; 158 159 RTE_POWER_REGISTER_CPUFREQ_OPS(kvm_vm_ops); 160