Skip to content

Commit 4992eb4

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: - x86 bugfixes - Documentation fixes - Avoid performance regression due to SEV-ES patches - ARM: - Don't allow tagged pointers to point to memslots - Filter out ARMv8.1+ PMU events on v8.0 hardware - Hide PMU registers from userspace when no PMU is configured - More PMU cleanups - Don't try to handle broken PSCI firmware - More sys_reg() to reg_to_encoding() conversions * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: allow KVM_REQ_GET_NESTED_STATE_PAGES outside guest mode for VMX KVM: x86: Revert "KVM: x86: Mark GPRs dirty when written" KVM: SVM: Unconditionally sync GPRs to GHCB on VMRUN of SEV-ES guest KVM: nVMX: Sync unsync'd vmcs02 state to vmcs12 on migration kvm: tracing: Fix unmatched kvm_entry and kvm_exit events KVM: Documentation: Update description of KVM_{GET,CLEAR}_DIRTY_LOG KVM: x86: get smi pending status correctly KVM: x86/pmu: Fix HW_REF_CPU_CYCLES event pseudo-encoding in intel_arch_events[] KVM: x86/pmu: Fix UBSAN shift-out-of-bounds warning in intel_pmu_refresh() KVM: x86: Add more protection against undefined behavior in rsvd_bits() KVM: Documentation: Fix spec for KVM_CAP_ENABLE_CAP_VM KVM: Forbid the use of tagged userspace addresses for memslots KVM: arm64: Filter out v8.1+ events on v8.0 HW KVM: arm64: Compute TPIDR_EL2 ignoring MTE tag KVM: arm64: Use the reg_to_encoding() macro instead of sys_reg() KVM: arm64: Allow PSCI SYSTEM_OFF/RESET to return KVM: arm64: Simplify handling of absent PMU system registers KVM: arm64: Hide PMU registers from userspace when not available
2 parents c7230a4 + 9a78e15 commit 4992eb4

File tree

15 files changed

+172
-112
lines changed

15 files changed

+172
-112
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,9 @@ since the last call to this ioctl. Bit 0 is the first page in the
360360
memory slot. Ensure the entire structure is cleared to avoid padding
361361
issues.
362362

363-
If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies
364-
the address space for which you want to return the dirty bitmap.
365-
They must be less than the value that KVM_CHECK_EXTENSION returns for
366-
the KVM_CAP_MULTI_ADDRESS_SPACE capability.
363+
If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies
364+
the address space for which you want to return the dirty bitmap. See
365+
KVM_SET_USER_MEMORY_REGION for details on the usage of slot field.
367366

368367
The bits in the dirty bitmap are cleared before the ioctl returns, unless
369368
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled. For more information,
@@ -1281,6 +1280,9 @@ field userspace_addr, which must point at user addressable memory for
12811280
the entire memory slot size. Any object may back this memory, including
12821281
anonymous memory, ordinary files, and hugetlbfs.
12831282

1283+
On architectures that support a form of address tagging, userspace_addr must
1284+
be an untagged address.
1285+
12841286
It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
12851287
be identical. This allows large pages in the guest to be backed by large
12861288
pages in the host.
@@ -1333,7 +1335,7 @@ documentation when it pops into existence).
13331335

13341336
:Capability: KVM_CAP_ENABLE_CAP_VM
13351337
:Architectures: all
1336-
:Type: vcpu ioctl
1338+
:Type: vm ioctl
13371339
:Parameters: struct kvm_enable_cap (in)
13381340
:Returns: 0 on success; -1 on error
13391341

@@ -4432,7 +4434,7 @@ to I/O ports.
44324434
:Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
44334435
:Architectures: x86, arm, arm64, mips
44344436
:Type: vm ioctl
4435-
:Parameters: struct kvm_dirty_log (in)
4437+
:Parameters: struct kvm_clear_dirty_log (in)
44364438
:Returns: 0 on success, -1 on error
44374439

44384440
::
@@ -4459,10 +4461,9 @@ in KVM's dirty bitmap, and dirty tracking is re-enabled for that page
44594461
(for example via write-protection, or by clearing the dirty bit in
44604462
a page table entry).
44614463

4462-
If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies
4463-
the address space for which you want to return the dirty bitmap.
4464-
They must be less than the value that KVM_CHECK_EXTENSION returns for
4465-
the KVM_CAP_MULTI_ADDRESS_SPACE capability.
4464+
If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies
4465+
the address space for which you want to clear the dirty status. See
4466+
KVM_SET_USER_MEMORY_REGION for details on the usage of slot field.
44664467

44674468
This ioctl is mostly useful when KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
44684469
is enabled; for more information, see the description of the capability.

arch/arm64/kvm/arm.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1396,8 +1396,9 @@ static void cpu_init_hyp_mode(void)
13961396
* Calculate the raw per-cpu offset without a translation from the
13971397
* kernel's mapping to the linear mapping, and store it in tpidr_el2
13981398
* so that we can use adr_l to access per-cpu variables in EL2.
1399+
* Also drop the KASAN tag which gets in the way...
13991400
*/
1400-
params->tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) -
1401+
params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) -
14011402
(unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start));
14021403

14031404
params->mair_el2 = read_sysreg(mair_el1);

arch/arm64/kvm/hyp/nvhe/psci-relay.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,6 @@ static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt)
7777
cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3));
7878
}
7979

80-
static __noreturn unsigned long psci_forward_noreturn(struct kvm_cpu_context *host_ctxt)
81-
{
82-
psci_forward(host_ctxt);
83-
hyp_panic(); /* unreachable */
84-
}
85-
8680
static unsigned int find_cpu_id(u64 mpidr)
8781
{
8882
unsigned int i;
@@ -251,10 +245,13 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_
251245
case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
252246
case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
253247
return psci_forward(host_ctxt);
248+
/*
249+
* SYSTEM_OFF/RESET should not return according to the spec.
250+
* Allow it so as to stay robust to broken firmware.
251+
*/
254252
case PSCI_0_2_FN_SYSTEM_OFF:
255253
case PSCI_0_2_FN_SYSTEM_RESET:
256-
psci_forward_noreturn(host_ctxt);
257-
unreachable();
254+
return psci_forward(host_ctxt);
258255
case PSCI_0_2_FN64_CPU_SUSPEND:
259256
return psci_cpu_suspend(func_id, host_ctxt);
260257
case PSCI_0_2_FN64_CPU_ON:

arch/arm64/kvm/pmu-emul.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
788788
{
789789
unsigned long *bmap = vcpu->kvm->arch.pmu_filter;
790790
u64 val, mask = 0;
791-
int base, i;
791+
int base, i, nr_events;
792792

793793
if (!pmceid1) {
794794
val = read_sysreg(pmceid0_el0);
@@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
801801
if (!bmap)
802802
return val;
803803

804+
nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
805+
804806
for (i = 0; i < 32; i += 8) {
805807
u64 byte;
806808

807809
byte = bitmap_get_value8(bmap, base + i);
808810
mask |= byte << i;
809-
byte = bitmap_get_value8(bmap, 0x4000 + base + i);
810-
mask |= byte << (32 + i);
811+
if (nr_events >= (0x4000 + base + 32)) {
812+
byte = bitmap_get_value8(bmap, 0x4000 + base + i);
813+
mask |= byte << (32 + i);
814+
}
811815
}
812816

813817
return val & mask;

arch/arm64/kvm/sys_regs.c

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
* 64bit interface.
4444
*/
4545

46+
#define reg_to_encoding(x) \
47+
sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
48+
(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
49+
4650
static bool read_from_write_only(struct kvm_vcpu *vcpu,
4751
struct sys_reg_params *params,
4852
const struct sys_reg_desc *r)
@@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
273277
const struct sys_reg_desc *r)
274278
{
275279
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
276-
u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1,
277-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
280+
u32 sr = reg_to_encoding(r);
278281

279282
if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
280283
kvm_inject_undefined(vcpu);
@@ -590,6 +593,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
590593
vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1);
591594
}
592595

596+
static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
597+
const struct sys_reg_desc *r)
598+
{
599+
if (kvm_vcpu_has_pmu(vcpu))
600+
return 0;
601+
602+
return REG_HIDDEN;
603+
}
604+
593605
static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
594606
{
595607
u64 pmcr, val;
@@ -613,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
613625
static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags)
614626
{
615627
u64 reg = __vcpu_sys_reg(vcpu, PMUSERENR_EL0);
616-
bool enabled = kvm_vcpu_has_pmu(vcpu);
628+
bool enabled = (reg & flags) || vcpu_mode_priv(vcpu);
617629

618-
enabled &= (reg & flags) || vcpu_mode_priv(vcpu);
619630
if (!enabled)
620631
kvm_inject_undefined(vcpu);
621632

@@ -900,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
900911
static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
901912
const struct sys_reg_desc *r)
902913
{
903-
if (!kvm_vcpu_has_pmu(vcpu)) {
904-
kvm_inject_undefined(vcpu);
905-
return false;
906-
}
907-
908914
if (p->is_write) {
909915
if (!vcpu_mode_priv(vcpu)) {
910916
kvm_inject_undefined(vcpu);
@@ -921,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
921927
return true;
922928
}
923929

924-
#define reg_to_encoding(x) \
925-
sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
926-
(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
927-
928930
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
929931
#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
930932
{ SYS_DESC(SYS_DBGBVRn_EL1(n)), \
@@ -936,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
936938
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
937939
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
938940

941+
#define PMU_SYS_REG(r) \
942+
SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility
943+
939944
/* Macro to expand the PMEVCNTRn_EL0 register */
940945
#define PMU_PMEVCNTR_EL0(n) \
941-
{ SYS_DESC(SYS_PMEVCNTRn_EL0(n)), \
942-
access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
946+
{ PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \
947+
.access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
943948

944949
/* Macro to expand the PMEVTYPERn_EL0 register */
945950
#define PMU_PMEVTYPER_EL0(n) \
946-
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
947-
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
951+
{ PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \
952+
.access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
948953

949954
static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
950955
const struct sys_reg_desc *r)
@@ -1020,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
10201025
static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10211026
struct sys_reg_desc const *r, bool raz)
10221027
{
1023-
u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
1024-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
1028+
u32 id = reg_to_encoding(r);
10251029
u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
10261030

10271031
if (id == SYS_ID_AA64PFR0_EL1) {
@@ -1062,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10621066
static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
10631067
const struct sys_reg_desc *r)
10641068
{
1065-
u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
1066-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
1069+
u32 id = reg_to_encoding(r);
10671070

10681071
switch (id) {
10691072
case SYS_ID_AA64ZFR0_EL1:
@@ -1486,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
14861489
{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
14871490
{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
14881491

1489-
{ SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
1490-
{ SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
1492+
{ PMU_SYS_REG(SYS_PMINTENSET_EL1),
1493+
.access = access_pminten, .reg = PMINTENSET_EL1 },
1494+
{ PMU_SYS_REG(SYS_PMINTENCLR_EL1),
1495+
.access = access_pminten, .reg = PMINTENSET_EL1 },
14911496

14921497
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
14931498
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
@@ -1526,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15261531
{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
15271532
{ SYS_DESC(SYS_CTR_EL0), access_ctr },
15281533

1529-
{ SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 },
1530-
{ SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
1531-
{ SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
1532-
{ SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
1533-
{ SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 },
1534-
{ SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 },
1535-
{ SYS_DESC(SYS_PMCEID0_EL0), access_pmceid },
1536-
{ SYS_DESC(SYS_PMCEID1_EL0), access_pmceid },
1537-
{ SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 },
1538-
{ SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper },
1539-
{ SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr },
1534+
{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
1535+
.reset = reset_pmcr, .reg = PMCR_EL0 },
1536+
{ PMU_SYS_REG(SYS_PMCNTENSET_EL0),
1537+
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
1538+
{ PMU_SYS_REG(SYS_PMCNTENCLR_EL0),
1539+
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
1540+
{ PMU_SYS_REG(SYS_PMOVSCLR_EL0),
1541+
.access = access_pmovs, .reg = PMOVSSET_EL0 },
1542+
{ PMU_SYS_REG(SYS_PMSWINC_EL0),
1543+
.access = access_pmswinc, .reg = PMSWINC_EL0 },
1544+
{ PMU_SYS_REG(SYS_PMSELR_EL0),
1545+
.access = access_pmselr, .reg = PMSELR_EL0 },
1546+
{ PMU_SYS_REG(SYS_PMCEID0_EL0),
1547+
.access = access_pmceid, .reset = NULL },
1548+
{ PMU_SYS_REG(SYS_PMCEID1_EL0),
1549+
.access = access_pmceid, .reset = NULL },
1550+
{ PMU_SYS_REG(SYS_PMCCNTR_EL0),
1551+
.access = access_pmu_evcntr, .reg = PMCCNTR_EL0 },
1552+
{ PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
1553+
.access = access_pmu_evtyper, .reset = NULL },
1554+
{ PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
1555+
.access = access_pmu_evcntr, .reset = NULL },
15401556
/*
15411557
* PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
15421558
* in 32bit mode. Here we choose to reset it as zero for consistency.
15431559
*/
1544-
{ SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 },
1545-
{ SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
1560+
{ PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr,
1561+
.reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 },
1562+
{ PMU_SYS_REG(SYS_PMOVSSET_EL0),
1563+
.access = access_pmovs, .reg = PMOVSSET_EL0 },
15461564

15471565
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
15481566
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
@@ -1694,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
16941712
* PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
16951713
* in 32bit mode. Here we choose to reset it as zero for consistency.
16961714
*/
1697-
{ SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 },
1715+
{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
1716+
.reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
16981717

16991718
{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
17001719
{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },

arch/x86/kvm/kvm_cache_regs.h

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,6 @@
99
(X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \
1010
| X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE)
1111

12-
static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu,
13-
enum kvm_reg reg)
14-
{
15-
return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
16-
}
17-
18-
static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu,
19-
enum kvm_reg reg)
20-
{
21-
return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
22-
}
23-
24-
static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu,
25-
enum kvm_reg reg)
26-
{
27-
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
28-
}
29-
30-
static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu,
31-
enum kvm_reg reg)
32-
{
33-
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
34-
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
35-
}
36-
3712
#define BUILD_KVM_GPR_ACCESSORS(lname, uname) \
3813
static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\
3914
{ \
@@ -43,7 +18,6 @@ static __always_inline void kvm_##lname##_write(struct kvm_vcpu *vcpu, \
4318
unsigned long val) \
4419
{ \
4520
vcpu->arch.regs[VCPU_REGS_##uname] = val; \
46-
kvm_register_mark_dirty(vcpu, VCPU_REGS_##uname); \
4721
}
4822
BUILD_KVM_GPR_ACCESSORS(rax, RAX)
4923
BUILD_KVM_GPR_ACCESSORS(rbx, RBX)
@@ -63,6 +37,31 @@ BUILD_KVM_GPR_ACCESSORS(r14, R14)
6337
BUILD_KVM_GPR_ACCESSORS(r15, R15)
6438
#endif
6539

40+
static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu,
41+
enum kvm_reg reg)
42+
{
43+
return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
44+
}
45+
46+
static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu,
47+
enum kvm_reg reg)
48+
{
49+
return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
50+
}
51+
52+
static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu,
53+
enum kvm_reg reg)
54+
{
55+
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
56+
}
57+
58+
static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu,
59+
enum kvm_reg reg)
60+
{
61+
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
62+
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
63+
}
64+
6665
static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg)
6766
{
6867
if (WARN_ON_ONCE((unsigned int)reg >= NR_VCPU_REGS))

0 commit comments

Comments
 (0)