Skip to content

Commit 36b68d3

Browse files
committed
Merge tag 'kvm-x86-misc-6.5' of https://github.com/kvm-x86/linux into HEAD
KVM x86 changes for 6.5: * Move handling of PAT out of MTRR code and dedup SVM+VMX code * Fix output of PIC poll command emulation when there's an interrupt * Add a maintainer's handbook to document KVM x86 processes, preferred coding style, testing expectations, etc. * Misc cleanups
2 parents d74669e + 63e2f55 commit 36b68d3

14 files changed

Lines changed: 493 additions & 86 deletions

File tree

Documentation/process/maintainer-handbooks.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ Contents:
1717

1818
maintainer-tip
1919
maintainer-netdev
20+
maintainer-kvm-x86

Documentation/process/maintainer-kvm-x86.rst

Lines changed: 390 additions & 0 deletions
Large diffs are not rendered by default.

Documentation/process/maintainer-tip.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ and can be added to an existing kernel config by running:
452452
Some of these options are x86-specific and can be left out when testing
453453
on other architectures.
454454

455+
.. _maintainer-tip-coding-style:
456+
455457
Coding style notes
456458
------------------
457459

Documentation/virt/kvm/x86/mmu.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ Shadow pages contain the following information:
205205
role.passthrough:
206206
The page is not backed by a guest page table, but its first entry
207207
points to one. This is set if NPT uses 5-level page tables (host
208-
CR4.LA57=1) and is shadowing L1's 4-level NPT (L1 CR4.LA57=1).
208+
CR4.LA57=1) and is shadowing L1's 4-level NPT (L1 CR4.LA57=0).
209209
gfn:
210210
Either the guest page table containing the translations shadowed by this
211211
page, or the base page frame for linear translations. See role.direct.

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11436,6 +11436,7 @@ M: Sean Christopherson <seanjc@google.com>
1143611436
M: Paolo Bonzini <pbonzini@redhat.com>
1143711437
L: kvm@vger.kernel.org
1143811438
S: Supported
11439+
P: Documentation/process/maintainer-kvm-x86.rst
1143911440
T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
1144011441
F: arch/x86/include/asm/kvm*
1144111442
F: arch/x86/include/asm/svm.h

arch/x86/kvm/cpuid.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -501,20 +501,15 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
501501
struct kvm_cpuid2 *cpuid,
502502
struct kvm_cpuid_entry2 __user *entries)
503503
{
504-
int r;
505-
506-
r = -E2BIG;
507504
if (cpuid->nent < vcpu->arch.cpuid_nent)
508-
goto out;
509-
r = -EFAULT;
505+
return -E2BIG;
506+
510507
if (copy_to_user(entries, vcpu->arch.cpuid_entries,
511508
vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
512-
goto out;
513-
return 0;
509+
return -EFAULT;
514510

515-
out:
516511
cpuid->nent = vcpu->arch.cpuid_nent;
517-
return r;
512+
return 0;
518513
}
519514

520515
/* Mask kvm_cpu_caps for @leaf with the raw CPUID capabilities of this CPU. */

arch/x86/kvm/i8259.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,10 @@ static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1)
411411
pic_clear_isr(s, ret);
412412
if (addr1 >> 7 || ret != 2)
413413
pic_update_irq(s->pics_state);
414+
/* Bit 7 is 1, means there's an interrupt */
415+
ret |= 0x80;
414416
} else {
417+
/* Bit 7 is 0, means there's no interrupt */
415418
ret = 0x07;
416419
pic_update_irq(s->pics_state);
417420
}

arch/x86/kvm/lapic.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@
5151
#define mod_64(x, y) ((x) % (y))
5252
#endif
5353

54-
#define PRId64 "d"
55-
#define PRIx64 "llx"
56-
#define PRIu64 "u"
57-
#define PRIo64 "o"
58-
5954
/* 14 is the version for Xeon and Pentium 8.4.8*/
6055
#define APIC_VERSION 0x14UL
6156
#define LAPIC_MMIO_LENGTH (1 << 12)

arch/x86/kvm/mtrr.c

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,24 @@
2525
#define IA32_MTRR_DEF_TYPE_FE (1ULL << 10)
2626
#define IA32_MTRR_DEF_TYPE_TYPE_MASK (0xff)
2727

28+
static bool is_mtrr_base_msr(unsigned int msr)
29+
{
30+
/* MTRR base MSRs use even numbers, masks use odd numbers. */
31+
return !(msr & 0x1);
32+
}
33+
34+
static struct kvm_mtrr_range *var_mtrr_msr_to_range(struct kvm_vcpu *vcpu,
35+
unsigned int msr)
36+
{
37+
int index = (msr - MTRRphysBase_MSR(0)) / 2;
38+
39+
return &vcpu->arch.mtrr_state.var_ranges[index];
40+
}
41+
2842
static bool msr_mtrr_valid(unsigned msr)
2943
{
3044
switch (msr) {
31-
case 0x200 ... 0x200 + 2 * KVM_NR_VAR_MTRR - 1:
45+
case MTRRphysBase_MSR(0) ... MTRRphysMask_MSR(KVM_NR_VAR_MTRR - 1):
3246
case MSR_MTRRfix64K_00000:
3347
case MSR_MTRRfix16K_80000:
3448
case MSR_MTRRfix16K_A0000:
@@ -41,7 +55,6 @@ static bool msr_mtrr_valid(unsigned msr)
4155
case MSR_MTRRfix4K_F0000:
4256
case MSR_MTRRfix4K_F8000:
4357
case MSR_MTRRdefType:
44-
case MSR_IA32_CR_PAT:
4558
return true;
4659
}
4760
return false;
@@ -52,17 +65,15 @@ static bool valid_mtrr_type(unsigned t)
5265
return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */
5366
}
5467

55-
bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
68+
static bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
5669
{
5770
int i;
5871
u64 mask;
5972

6073
if (!msr_mtrr_valid(msr))
6174
return false;
6275

63-
if (msr == MSR_IA32_CR_PAT) {
64-
return kvm_pat_valid(data);
65-
} else if (msr == MSR_MTRRdefType) {
76+
if (msr == MSR_MTRRdefType) {
6677
if (data & ~0xcff)
6778
return false;
6879
return valid_mtrr_type(data & 0xff);
@@ -74,7 +85,8 @@ bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
7485
}
7586

7687
/* variable MTRRs */
77-
WARN_ON(!(msr >= 0x200 && msr < 0x200 + 2 * KVM_NR_VAR_MTRR));
88+
WARN_ON(!(msr >= MTRRphysBase_MSR(0) &&
89+
msr <= MTRRphysMask_MSR(KVM_NR_VAR_MTRR - 1)));
7890

7991
mask = kvm_vcpu_reserved_gpa_bits_raw(vcpu);
8092
if ((msr & 1) == 0) {
@@ -88,7 +100,6 @@ bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
88100

89101
return (data & mask) == 0;
90102
}
91-
EXPORT_SYMBOL_GPL(kvm_mtrr_valid);
92103

93104
static bool mtrr_is_enabled(struct kvm_mtrr *mtrr_state)
94105
{
@@ -308,10 +319,8 @@ static void update_mtrr(struct kvm_vcpu *vcpu, u32 msr)
308319
{
309320
struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
310321
gfn_t start, end;
311-
int index;
312322

313-
if (msr == MSR_IA32_CR_PAT || !tdp_enabled ||
314-
!kvm_arch_has_noncoherent_dma(vcpu->kvm))
323+
if (!tdp_enabled || !kvm_arch_has_noncoherent_dma(vcpu->kvm))
315324
return;
316325

317326
if (!mtrr_is_enabled(mtrr_state) && msr != MSR_MTRRdefType)
@@ -326,8 +335,7 @@ static void update_mtrr(struct kvm_vcpu *vcpu, u32 msr)
326335
end = ~0ULL;
327336
} else {
328337
/* variable range MTRRs. */
329-
index = (msr - 0x200) / 2;
330-
var_mtrr_range(&mtrr_state->var_ranges[index], &start, &end);
338+
var_mtrr_range(var_mtrr_msr_to_range(vcpu, msr), &start, &end);
331339
}
332340

333341
kvm_zap_gfn_range(vcpu->kvm, gpa_to_gfn(start), gpa_to_gfn(end));
@@ -342,21 +350,18 @@ static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
342350
{
343351
struct kvm_mtrr *mtrr_state = &vcpu->arch.mtrr_state;
344352
struct kvm_mtrr_range *tmp, *cur;
345-
int index, is_mtrr_mask;
346353

347-
index = (msr - 0x200) / 2;
348-
is_mtrr_mask = msr - 0x200 - 2 * index;
349-
cur = &mtrr_state->var_ranges[index];
354+
cur = var_mtrr_msr_to_range(vcpu, msr);
350355

351356
/* remove the entry if it's in the list. */
352357
if (var_mtrr_range_is_valid(cur))
353-
list_del(&mtrr_state->var_ranges[index].node);
358+
list_del(&cur->node);
354359

355360
/*
356361
* Set all illegal GPA bits in the mask, since those bits must
357362
* implicitly be 0. The bits are then cleared when reading them.
358363
*/
359-
if (!is_mtrr_mask)
364+
if (is_mtrr_base_msr(msr))
360365
cur->base = data;
361366
else
362367
cur->mask = data | kvm_vcpu_reserved_gpa_bits_raw(vcpu);
@@ -382,8 +387,6 @@ int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
382387
*(u64 *)&vcpu->arch.mtrr_state.fixed_ranges[index] = data;
383388
else if (msr == MSR_MTRRdefType)
384389
vcpu->arch.mtrr_state.deftype = data;
385-
else if (msr == MSR_IA32_CR_PAT)
386-
vcpu->arch.pat = data;
387390
else
388391
set_var_mtrr_msr(vcpu, msr, data);
389392

@@ -411,21 +414,16 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
411414
return 1;
412415

413416
index = fixed_msr_to_range_index(msr);
414-
if (index >= 0)
417+
if (index >= 0) {
415418
*pdata = *(u64 *)&vcpu->arch.mtrr_state.fixed_ranges[index];
416-
else if (msr == MSR_MTRRdefType)
419+
} else if (msr == MSR_MTRRdefType) {
417420
*pdata = vcpu->arch.mtrr_state.deftype;
418-
else if (msr == MSR_IA32_CR_PAT)
419-
*pdata = vcpu->arch.pat;
420-
else { /* Variable MTRRs */
421-
int is_mtrr_mask;
422-
423-
index = (msr - 0x200) / 2;
424-
is_mtrr_mask = msr - 0x200 - 2 * index;
425-
if (!is_mtrr_mask)
426-
*pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
421+
} else {
422+
/* Variable MTRRs */
423+
if (is_mtrr_base_msr(msr))
424+
*pdata = var_mtrr_msr_to_range(vcpu, msr)->base;
427425
else
428-
*pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
426+
*pdata = var_mtrr_msr_to_range(vcpu, msr)->mask;
429427

430428
*pdata &= ~kvm_vcpu_reserved_gpa_bits_raw(vcpu);
431429
}

arch/x86/kvm/svm/svm.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
752752

753753
BUG_ON(offset == MSR_INVALID);
754754

755-
return !!test_bit(bit_write, &tmp);
755+
return test_bit(bit_write, &tmp);
756756
}
757757

758758
static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm,
@@ -2939,9 +2939,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
29392939

29402940
break;
29412941
case MSR_IA32_CR_PAT:
2942-
if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
2943-
return 1;
2944-
vcpu->arch.pat = data;
2942+
ret = kvm_set_msr_common(vcpu, msr);
2943+
if (ret)
2944+
break;
2945+
29452946
svm->vmcb01.ptr->save.g_pat = data;
29462947
if (is_guest_mode(vcpu))
29472948
nested_vmcb02_compute_g_pat(svm);

0 commit comments

Comments
 (0)