Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/pv/emulate.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * arch/x86/pv/emulate.c
3
 *
4
 * Common PV emulation code
5
 *
6
 * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include <xen/guest_access.h>
23
24
#include <asm/debugreg.h>
25
26
#include "emulate.h"
27
28
int pv_emul_read_descriptor(unsigned int sel, const struct vcpu *v,
29
                            unsigned long *base, unsigned long *limit,
30
                            unsigned int *ar, bool insn_fetch)
31
0
{
32
0
    struct desc_struct desc;
33
0
34
0
    if ( sel < 4)
35
0
        desc.b = desc.a = 0;
36
0
    else if ( __get_user(desc,
37
0
                         (const struct desc_struct *)(!(sel & 4)
38
0
                                                      ? GDT_VIRT_START(v)
39
0
                                                      : LDT_VIRT_START(v))
40
0
                         + (sel >> 3)) )
41
0
        return 0;
42
0
    if ( !insn_fetch )
43
0
        desc.b &= ~_SEGMENT_L;
44
0
45
0
    *ar = desc.b & 0x00f0ff00;
46
0
    if ( !(desc.b & _SEGMENT_L) )
47
0
    {
48
0
        *base = ((desc.a >> 16) + ((desc.b & 0xff) << 16) +
49
0
                 (desc.b & 0xff000000));
50
0
        *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000);
51
0
        if ( desc.b & _SEGMENT_G )
52
0
            *limit = ((*limit + 1) << 12) - 1;
53
0
#ifndef NDEBUG
54
0
        if ( sel > 3 )
55
0
        {
56
0
            unsigned int a, l;
57
0
            unsigned char valid;
58
0
59
0
            asm volatile (
60
0
                "larl %2,%0 ; setz %1"
61
0
                : "=r" (a), "=qm" (valid) : "rm" (sel));
62
0
            BUG_ON(valid && ((a & 0x00f0ff00) != *ar));
63
0
            asm volatile (
64
0
                "lsll %2,%0 ; setz %1"
65
0
                : "=r" (l), "=qm" (valid) : "rm" (sel));
66
0
            BUG_ON(valid && (l != *limit));
67
0
        }
68
0
#endif
69
0
    }
70
0
    else
71
0
    {
72
0
        *base = 0UL;
73
0
        *limit = ~0UL;
74
0
    }
75
0
76
0
    return 1;
77
0
}
78
79
void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip)
80
0
{
81
0
    regs->rip = rip;
82
0
    regs->eflags &= ~X86_EFLAGS_RF;
83
0
    if ( regs->eflags & X86_EFLAGS_TF )
84
0
    {
85
0
        current->arch.debugreg[6] |= DR_STEP | DR_STATUS_RESERVED_ONE;
86
0
        pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
87
0
    }
88
0
}
89
90
/*
91
 * Local variables:
92
 * mode: C
93
 * c-file-style: "BSD"
94
 * c-basic-offset: 4
95
 * tab-width: 4
96
 * indent-tabs-mode: nil
97
 * End:
98
 */