xref: /illumos-kvm/kvm_cache_regs.c (revision 2a9ff8dc)
1 /*
2  * GPL HEADER START
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * GPL HEADER END
18  *
19  * Copyright 2011 various Linux Kernel contributors.
20  * Copyright 2011 Joyent, Inc. All Rights Reserved.
21  */
22 
23 #include "kvm_bitops.h"
24 #include "kvm_host.h"
25 #include "kvm_cache_regs.h"
26 
27 unsigned long
kvm_register_read(struct kvm_vcpu * vcpu,enum kvm_reg reg)28 kvm_register_read(struct kvm_vcpu *vcpu, enum kvm_reg reg)
29 {
30 	if (!test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail))
31 		kvm_x86_ops->cache_reg(vcpu, reg);
32 
33 	return (vcpu->arch.regs[reg]);
34 }
35 
36 void
kvm_register_write(struct kvm_vcpu * vcpu,enum kvm_reg reg,unsigned long val)37 kvm_register_write(struct kvm_vcpu *vcpu, enum kvm_reg reg, unsigned long val)
38 {
39 	vcpu->arch.regs[reg] = val;
40 	__set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
41 	__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
42 }
43 
44 unsigned long
kvm_rip_read(struct kvm_vcpu * vcpu)45 kvm_rip_read(struct kvm_vcpu *vcpu)
46 {
47 	return (kvm_register_read(vcpu, VCPU_REGS_RIP));
48 }
49 
50 void
kvm_rip_write(struct kvm_vcpu * vcpu,unsigned long val)51 kvm_rip_write(struct kvm_vcpu *vcpu, unsigned long val)
52 {
53 	kvm_register_write(vcpu, VCPU_REGS_RIP, val);
54 }
55 
56 uint64_t
kvm_pdptr_read(struct kvm_vcpu * vcpu,int index)57 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
58 {
59 	if (!test_bit(VCPU_EXREG_PDPTR,
60 	    (unsigned long *)&vcpu->arch.regs_avail)) {
61 		kvm_x86_ops->cache_reg(vcpu, VCPU_EXREG_PDPTR);
62 	}
63 
64 	return (vcpu->arch.pdptrs[index]);
65 }
66 
67 ulong
kvm_read_cr0_bits(struct kvm_vcpu * vcpu,ulong mask)68 kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask)
69 {
70 	ulong tmask = mask & KVM_POSSIBLE_CR0_GUEST_BITS;
71 
72 	if (tmask & vcpu->arch.cr0_guest_owned_bits)
73 		kvm_x86_ops->decache_cr0_guest_bits(vcpu);
74 
75 	return (vcpu->arch.cr0 & mask);
76 }
77 
78 ulong
kvm_read_cr0(struct kvm_vcpu * vcpu)79 kvm_read_cr0(struct kvm_vcpu *vcpu)
80 {
81 	return (kvm_read_cr0_bits(vcpu, ~0UL));
82 }
83 
84 ulong
kvm_read_cr4_bits(struct kvm_vcpu * vcpu,ulong mask)85 kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask)
86 {
87 	uint64_t tmask = mask & KVM_POSSIBLE_CR4_GUEST_BITS;
88 
89 	if (tmask & vcpu->arch.cr4_guest_owned_bits)
90 		kvm_x86_ops->decache_cr4_guest_bits(vcpu);
91 
92 	return (vcpu->arch.cr4 & mask);
93 }
94 
95 ulong
kvm_read_cr4(struct kvm_vcpu * vcpu)96 kvm_read_cr4(struct kvm_vcpu *vcpu)
97 {
98 	return (kvm_read_cr4_bits(vcpu, ~0UL));
99 }
100