Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/common/multicall.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * multicall.c
3
 */
4
5
#include <xen/types.h>
6
#include <xen/lib.h>
7
#include <xen/mm.h>
8
#include <xen/sched.h>
9
#include <xen/event.h>
10
#include <xen/multicall.h>
11
#include <xen/guest_access.h>
12
#include <xen/perfc.h>
13
#include <xen/trace.h>
14
#include <asm/current.h>
15
#include <asm/hardirq.h>
16
17
#ifndef COMPAT
18
typedef long ret_t;
19
#define xlat_multicall_entry(mcs)
20
21
static void __trace_multicall_call(multicall_entry_t *call)
22
0
{
23
0
    __trace_hypercall(TRC_PV_HYPERCALL_SUBCALL, call->op, call->args);
24
0
}
25
#endif
26
27
static void trace_multicall_call(multicall_entry_t *call)
28
0
{
29
0
    if ( !tb_init_done )
30
0
        return;
31
0
32
0
    __trace_multicall_call(call);
33
0
}
34
35
ret_t
36
do_multicall(
37
    XEN_GUEST_HANDLE_PARAM(multicall_entry_t) call_list, uint32_t nr_calls)
38
0
{
39
0
    struct vcpu *curr = current;
40
0
    struct mc_state *mcs = &curr->mc_state;
41
0
    uint32_t         i;
42
0
    int              rc = 0;
43
0
    enum mc_disposition disp = mc_continue;
44
0
45
0
    if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
46
0
    {
47
0
        gdprintk(XENLOG_INFO, "Multicall reentry is disallowed.\n");
48
0
        return -EINVAL;
49
0
    }
50
0
51
0
    if ( unlikely(!guest_handle_okay(call_list, nr_calls)) )
52
0
        rc = -EFAULT;
53
0
54
0
    for ( i = 0; !rc && disp == mc_continue && i < nr_calls; i++ )
55
0
    {
56
0
        if ( i && hypercall_preempt_check() )
57
0
            goto preempted;
58
0
59
0
        if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
60
0
        {
61
0
            rc = -EFAULT;
62
0
            break;
63
0
        }
64
0
65
0
        trace_multicall_call(&mcs->call);
66
0
67
0
        disp = arch_do_multicall_call(mcs);
68
0
69
0
#ifndef NDEBUG
70
0
        {
71
0
            /*
72
0
             * Deliberately corrupt the contents of the multicall structure.
73
0
             * The caller must depend only on the 'result' field on return.
74
0
             */
75
0
            struct multicall_entry corrupt;
76
0
            memset(&corrupt, 0xAA, sizeof(corrupt));
77
0
            (void)__copy_to_guest(call_list, &corrupt, 1);
78
0
        }
79
0
#endif
80
0
81
0
        if ( unlikely(disp == mc_exit) )
82
0
        {
83
0
            if ( __copy_field_to_guest(call_list, &mcs->call, result) )
84
0
                /* nothing, best effort only */;
85
0
            rc = mcs->call.result;
86
0
        }
87
0
        else if ( unlikely(__copy_field_to_guest(call_list, &mcs->call,
88
0
                                                 result)) )
89
0
            rc = -EFAULT;
90
0
        else if ( curr->hcall_preempted )
91
0
        {
92
0
            /* Translate sub-call continuation to guest layout */
93
0
            xlat_multicall_entry(mcs);
94
0
95
0
            /* Copy the sub-call continuation. */
96
0
            if ( likely(!__copy_to_guest(call_list, &mcs->call, 1)) )
97
0
                goto preempted;
98
0
            else
99
0
                hypercall_cancel_continuation(curr);
100
0
            rc = -EFAULT;
101
0
        }
102
0
        else
103
0
            guest_handle_add_offset(call_list, 1);
104
0
    }
105
0
106
0
    if ( unlikely(disp == mc_preempt) && i < nr_calls )
107
0
        goto preempted;
108
0
109
0
    perfc_incr(calls_to_multicall);
110
0
    perfc_add(calls_from_multicall, i);
111
0
    mcs->flags = 0;
112
0
    return rc;
113
0
114
0
 preempted:
115
0
    perfc_add(calls_from_multicall, i);
116
0
    mcs->flags = 0;
117
0
    return hypercall_create_continuation(
118
0
        __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
119
0
}
Unexecuted instantiation: do_multicall
Unexecuted instantiation: compat_multicall
120
121
/*
122
 * Local variables:
123
 * mode: C
124
 * c-file-style: "BSD"
125
 * c-basic-offset: 4
126
 * tab-width: 4
127
 * indent-tabs-mode: nil
128
 * End:
129
 */