1 /****************************************************************************
2  *
3  *        File: xc_rt.c
4  *      Author: Sisu Xi
5  *              Meng Xu
6  *
7  * Description: XC Interface to the rtds scheduler
8  * Note: VCPU's parameter (period, budget) is in microsecond (us).
9  *       All VCPUs of the same domain have same period and budget.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation;
14  * version 2.1 of the License.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #include "xc_private.h"
26 
xc_sched_rtds_domain_set(xc_interface * xch,uint32_t domid,struct xen_domctl_sched_rtds * sdom)27 int xc_sched_rtds_domain_set(xc_interface *xch,
28                            uint32_t domid,
29                            struct xen_domctl_sched_rtds *sdom)
30 {
31     int rc;
32     DECLARE_DOMCTL;
33 
34     domctl.cmd = XEN_DOMCTL_scheduler_op;
35     domctl.domain = domid;
36     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS;
37     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
38     domctl.u.scheduler_op.u.rtds.period = sdom->period;
39     domctl.u.scheduler_op.u.rtds.budget = sdom->budget;
40 
41     rc = do_domctl(xch, &domctl);
42 
43     return rc;
44 }
45 
xc_sched_rtds_domain_get(xc_interface * xch,uint32_t domid,struct xen_domctl_sched_rtds * sdom)46 int xc_sched_rtds_domain_get(xc_interface *xch,
47                            uint32_t domid,
48                            struct xen_domctl_sched_rtds *sdom)
49 {
50     int rc;
51     DECLARE_DOMCTL;
52 
53     domctl.cmd = XEN_DOMCTL_scheduler_op;
54     domctl.domain = domid;
55     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS;
56     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
57 
58     rc = do_domctl(xch, &domctl);
59 
60     if ( rc == 0 )
61         *sdom = domctl.u.scheduler_op.u.rtds;
62 
63     return rc;
64 }
65 
xc_sched_rtds_vcpu_set(xc_interface * xch,uint32_t domid,struct xen_domctl_schedparam_vcpu * vcpus,uint32_t num_vcpus)66 int xc_sched_rtds_vcpu_set(xc_interface *xch,
67                            uint32_t domid,
68                            struct xen_domctl_schedparam_vcpu *vcpus,
69                            uint32_t num_vcpus)
70 {
71     int rc = 0;
72     unsigned processed = 0;
73     DECLARE_DOMCTL;
74     DECLARE_HYPERCALL_BOUNCE(vcpus, sizeof(*vcpus) * num_vcpus,
75                              XC_HYPERCALL_BUFFER_BOUNCE_IN);
76 
77     if ( xc_hypercall_bounce_pre(xch, vcpus) )
78         return -1;
79 
80     domctl.cmd = XEN_DOMCTL_scheduler_op;
81     domctl.domain = domid;
82     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS;
83     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putvcpuinfo;
84 
85     while ( processed < num_vcpus )
86     {
87         domctl.u.scheduler_op.u.v.nr_vcpus = num_vcpus - processed;
88         set_xen_guest_handle_offset(domctl.u.scheduler_op.u.v.vcpus, vcpus,
89                                     processed);
90         if ( (rc = do_domctl(xch, &domctl)) != 0 )
91             break;
92         processed += domctl.u.scheduler_op.u.v.nr_vcpus;
93     }
94 
95     xc_hypercall_bounce_post(xch, vcpus);
96 
97     return rc;
98 }
99 
xc_sched_rtds_vcpu_get(xc_interface * xch,uint32_t domid,struct xen_domctl_schedparam_vcpu * vcpus,uint32_t num_vcpus)100 int xc_sched_rtds_vcpu_get(xc_interface *xch,
101                            uint32_t domid,
102                            struct xen_domctl_schedparam_vcpu *vcpus,
103                            uint32_t num_vcpus)
104 {
105     int rc = 0;
106     unsigned processed = 0;
107     DECLARE_DOMCTL;
108     DECLARE_HYPERCALL_BOUNCE(vcpus, sizeof(*vcpus) * num_vcpus,
109                              XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
110 
111     if ( xc_hypercall_bounce_pre(xch, vcpus) )
112         return -1;
113 
114     domctl.cmd = XEN_DOMCTL_scheduler_op;
115     domctl.domain = domid;
116     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS;
117     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getvcpuinfo;
118 
119     while ( processed < num_vcpus )
120     {
121         domctl.u.scheduler_op.u.v.nr_vcpus = num_vcpus - processed;
122         set_xen_guest_handle_offset(domctl.u.scheduler_op.u.v.vcpus, vcpus,
123                                     processed);
124         if ( (rc = do_domctl(xch, &domctl)) != 0 )
125             break;
126         processed += domctl.u.scheduler_op.u.v.nr_vcpus;
127     }
128 
129     xc_hypercall_bounce_post(xch, vcpus);
130 
131     return rc;
132 }
133