summaryrefslogtreecommitdiffstats
path: root/lib/librte_power/power_kvm_vm.c
blob: 20659b72f9a645b574d36aa8470fd3c0458cce9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2010-2014 Intel Corporation
 */
#include <errno.h>
#include <string.h>

#include <rte_log.h>

#include "guest_channel.h"
#include "channel_commands.h"
#include "power_kvm_vm.h"
#include "power_common.h"

#define FD_PATH "/dev/virtio-ports/virtio.serial.port.poweragent"

static struct channel_packet pkt[CHANNEL_CMDS_MAX_VM_CHANNELS];


int
power_kvm_vm_init(unsigned int lcore_id)
{
	if (lcore_id >= CHANNEL_CMDS_MAX_VM_CHANNELS) {
		RTE_LOG(ERR, POWER, "Core(%u) is out of range 0...%d\n",
				lcore_id, CHANNEL_CMDS_MAX_VM_CHANNELS-1);
		return -1;
	}
	pkt[lcore_id].command = CPU_POWER;
	pkt[lcore_id].resource_id = lcore_id;
	return guest_channel_host_connect(FD_PATH, lcore_id);
}

int
power_kvm_vm_exit(unsigned int lcore_id)
{
	guest_channel_host_disconnect(lcore_id);
	return 0;
}

uint32_t
power_kvm_vm_freqs(__attribute__((unused)) unsigned int lcore_id,
		__attribute__((unused)) uint32_t *freqs,
		__attribute__((unused)) uint32_t num)
{
	RTE_LOG(ERR, POWER, "rte_power_freqs is not implemented "
			"for Virtual Machine Power Management\n");
	return -ENOTSUP;
}

uint32_t
power_kvm_vm_get_freq(__attribute__((unused)) unsigned int lcore_id)
{
	RTE_LOG(ERR, POWER, "rte_power_get_freq is not implemented "
			"for Virtual Machine Power Management\n");
	return -ENOTSUP;
}

int
power_kvm_vm_set_freq(__attribute__((unused)) unsigned int lcore_id,
		__attribute__((unused)) uint32_t index)
{
	RTE_LOG(ERR, POWER, "rte_power_set_freq is not implemented "
			"for Virtual Machine Power Management\n");
	return -ENOTSUP;
}

static inline int
send_msg(unsigned int lcore_id, uint32_t scale_direction)
{
	int ret;

	if (lcore_id >= CHANNEL_CMDS_MAX_VM_CHANNELS) {
		RTE_LOG(ERR, POWER, "Core(%u) is out of range 0...%d\n",
				lcore_id, CHANNEL_CMDS_MAX_VM_CHANNELS-1);
		return -1;
	}
	pkt[lcore_id].unit = scale_direction;
	ret = guest_channel_send_msg(&pkt[lcore_id], lcore_id);
	if (ret == 0)
		return 1;
	RTE_LOG(DEBUG, POWER, "Error sending message: %s\n",
			ret > 0 ? strerror(ret) : "channel not connected");
	return -1;
}

int
power_kvm_vm_freq_up(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_SCALE_UP);
}

int
power_kvm_vm_freq_down(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_SCALE_DOWN);
}

int
power_kvm_vm_freq_max(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_SCALE_MAX);
}

int
power_kvm_vm_freq_min(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_SCALE_MIN);
}

int
power_kvm_vm_turbo_status(__attribute__((unused)) unsigned int lcore_id)
{
	RTE_LOG(ERR, POWER, "rte_power_turbo_status is not implemented for Virtual Machine Power Management\n");
	return -ENOTSUP;
}

int
power_kvm_vm_enable_turbo(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_ENABLE_TURBO);
}

int
power_kvm_vm_disable_turbo(unsigned int lcore_id)
{
	return send_msg(lcore_id, CPU_POWER_DISABLE_TURBO);
}

struct rte_power_core_capabilities;
int power_kvm_vm_get_capabilities(__rte_unused unsigned int lcore_id,
		__rte_unused struct rte_power_core_capabilities *caps)
{
	RTE_LOG(ERR, POWER, "rte_power_get_capabilities is not implemented for Virtual Machine Power Management\n");
	return -ENOTSUP;
}