projects/linux·commit 1baa5efb

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

1baa5efb · Linus Torvalds <[email protected]> · 2016-01-12 13:22:12 -08:00

Pull KVM updates from Paolo Bonzini:
 "PPC changes will come next week.

   - s390: Support for runtime instrumentation within guests, support of
     248 VCPUs.

   - ARM: rewrite of the arm64 world switch in C, support for 16-bit VM
     identifiers.  Performance counter virtualization missed the boat.

   - x86: Support for more Hyper-V features (synthetic interrupt
     controller), MMU cleanups"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (115 commits)
  kvm: x86: Fix vmwrite to SECONDARY_VM_EXEC_CONTROL
  kvm/x86: Hyper-V SynIC timers tracepoints
  kvm/x86: Hyper-V SynIC tracepoints
  kvm/x86: Update SynIC timers on guest entry only
  kvm/x86: Skip SynIC vector check for QEMU side
  kvm/x86: Hyper-V fix SynIC timer disabling condition
  kvm/x86: Reorg stimer_expiration() to better control timer restart
  kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
  kvm/x86: Drop stimer_stop() function
  kvm/x86: Hyper-V timers fix incorrect logical operation
  KVM: move architecture-dependent requests to arch/
  KVM: renumber vcpu->request bits
  KVM: document which architecture uses each request bit
  KVM: Remove unused KVM_REQ_KICK to save a bit in vcpu->requests
  kvm: x86: Check kvm_write_guest return value in kvm_write_wall_clock
  KVM: s390: implement the RI support of guest
  kvm/s390: drop unpaired smp_mb
  kvm: x86: fix comment about {mmu,nested_mmu}.gva_to_gpa
  KVM: x86: MMU: Use clear_page() instead of init_shadow_page_table()
  arm/arm64: KVM: Detect vGIC presence at runtime
  ...
Commit
1baa5efbeb6eb75de697f7b5931094be33f12005
Parents
c9bed1cf · 45bdbcfd

Merge commit. Changes below are compared with the first parent: c9bed1cf.

Changes

87 files changed · +4043 −2393

FileStatusAddDelContent
Documentation/virtual/kvm/api.txtmodified+41−0View file
Documentation/virtual/kvm/devices/vm.txtmodified+2−1View file
Documentation/virtual/kvm/mmu.txtmodified+2−2View file
MAINTAINERSmodified+1−0View file
arch/arm/include/asm/kvm_arm.hmodified+17−17View file
arch/arm/include/asm/kvm_host.hmodified+6−0View file
arch/arm/include/asm/kvm_mmu.hmodified+5−0View file
arch/arm/kvm/arm.cmodified+36−4View file
arch/arm/kvm/emulate.cmodified+38−36View file
arch/arm/kvm/guest.cmodified+6−0View file
arch/arm/kvm/handle_exit.cmodified+3−0View file
arch/arm/kvm/mmio.cmodified+3−0View file
arch/arm/kvm/mmu.cmodified+3−3View file
arch/arm64/include/asm/kvm_arm.hmodified+2−1View file
arch/arm64/include/asm/kvm_asm.hmodified+0−76View file
arch/arm64/include/asm/kvm_emulate.hmodified+0−1View file
arch/arm64/include/asm/kvm_host.hmodified+86−1View file
arch/arm64/include/asm/kvm_mmio.hmodified+0−1View file
arch/arm64/include/asm/kvm_mmu.hmodified+8−1View file
arch/arm64/include/asm/sysreg.hmodified+21−0View file
arch/arm64/kernel/asm-offsets.cmodified+1−39View file
arch/arm64/kvm/Makefilemodified+1−2View file
arch/arm64/kvm/guest.cmodified+9−1View file
arch/arm64/kvm/handle_exit.cmodified+4−0View file
arch/arm64/kvm/hyp-init.Smodified+9−0View file
arch/arm64/kvm/hyp.Smodified+1−1080View file
arch/arm64/kvm/hyp/Makefileadded+14−0View file
arch/arm64/kvm/hyp/debug-sr.cadded+140−0View file
arch/arm64/kvm/hyp/entry.Sadded+160−0View file
arch/arm64/kvm/hyp/fpsimd.Sadded+33−0View file
arch/arm64/kvm/hyp/hyp-entry.Sadded+212−0View file
arch/arm64/kvm/hyp/hyp.hadded+90−0View file
arch/arm64/kvm/hyp/switch.cadded+175−0View file
arch/arm64/kvm/hyp/sysreg-sr.cadded+138−0View file
arch/arm64/kvm/hyp/timer-sr.cadded+71−0View file
arch/arm64/kvm/hyp/tlb.cadded+80−0View file
arch/arm64/kvm/hyp/vgic-v2-sr.cadded+84−0View file
arch/arm64/kvm/hyp/vgic-v3-sr.cadded+228−0View file
arch/arm64/kvm/sys_regs.cmodified+30−29View file
arch/arm64/kvm/vgic-v2-switch.Sdeleted+0−134View before deletion
arch/arm64/kvm/vgic-v3-switch.Sdeleted+0−269View before deletion
arch/powerpc/include/asm/kvm_host.hmodified+4−0View file
arch/powerpc/kvm/book3s_hv.cmodified+2−8View file
arch/powerpc/kvm/book3s_pr.cmodified+2−2View file
arch/s390/include/asm/elf.hmodified+7−0View file
arch/s390/include/asm/kvm_host.hmodified+50−7View file
arch/s390/include/asm/sclp.hmodified+7−1View file
arch/s390/include/uapi/asm/kvm.hmodified+5−0View file
arch/s390/kernel/processor.cmodified+6−0View file
arch/s390/kernel/setup.cmodified+9−0View file
arch/s390/kvm/diag.cmodified+3−8View file
arch/s390/kvm/gaccess.cmodified+27−11View file
arch/s390/kvm/intercept.cmodified+3−4View file
arch/s390/kvm/interrupt.cmodified+106−27View file
arch/s390/kvm/kvm-s390.cmodified+219−81View file
arch/s390/kvm/kvm-s390.hmodified+7−0View file
arch/s390/kvm/trace-s390.hmodified+3−3View file
arch/s390/mm/pgtable.cmodified+2−2View file
arch/x86/include/asm/kvm_host.hmodified+70−5View file
arch/x86/include/uapi/asm/hyperv.hmodified+92−0View file
arch/x86/kvm/hyperv.cmodified+704−4View file
arch/x86/kvm/hyperv.hmodified+55−0View file
arch/x86/kvm/ioapic.cmodified+2−2View file
arch/x86/kvm/ioapic.hmodified+4−3View file
arch/x86/kvm/irq.cmodified+1−1View file
arch/x86/kvm/irq_comm.cmodified+38−3View file
arch/x86/kvm/lapic.cmodified+23−17View file
arch/x86/kvm/lapic.hmodified+7−2View file
arch/x86/kvm/mmu.cmodified+183−214View file
arch/x86/kvm/mmu_audit.cmodified+8−7View file
arch/x86/kvm/paging_tmpl.hmodified+9−11View file
arch/x86/kvm/svm.cmodified+32−5View file
arch/x86/kvm/trace.hmodified+264−1View file
arch/x86/kvm/vmx.cmodified+131−71View file
arch/x86/kvm/x86.cmodified+96−14View file
drivers/hv/hyperv_vmbus.hmodified+1−87View file
drivers/s390/char/sclp_early.cmodified+14−2View file
include/clocksource/arm_arch_timer.hmodified+6−0View file
include/kvm/arm_vgic.hmodified+6−0View file
include/linux/kvm_host.hmodified+24−42View file
include/linux/kvm_para.hmodified+2−4View file
include/uapi/linux/kvm.hmodified+26−0View file
virt/kvm/arm/vgic-v3.cmodified+3−8View file
virt/kvm/arm/vgic.cmodified+1−1View file
virt/kvm/async_pf.cmodified+1−2View file
virt/kvm/irqchip.cmodified+6−1View file
virt/kvm/kvm_main.cmodified+12−34View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/virtual/kvm/api.txt

View file
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 092ee9f..053f613 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1451,6 +1451,7 @@ struct kvm_irq_routing_entry {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
struct kvm_irq_routing_s390_adapter adapter;
+ struct kvm_irq_routing_hv_sint hv_sint;
__u32 pad[8];
} u;
};
@@ -1459,6 +1460,7 @@ struct kvm_irq_routing_entry {
#define KVM_IRQ_ROUTING_IRQCHIP 1
#define KVM_IRQ_ROUTING_MSI 2
#define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
No flags are specified so far, the corresponding field must be set to zero.
@@ -1482,6 +1484,10 @@ struct kvm_irq_routing_s390_adapter {
__u32 adapter_id;
};
+struct kvm_irq_routing_hv_sint {
+ __u32 vcpu;
+ __u32 sint;
+};
4.53 KVM_ASSIGN_SET_MSIX_NR (deprecated)
@@ -3331,6 +3337,28 @@ the userspace IOAPIC should process the EOI and retrigger the interrupt if
it is still asserted. Vector is the LAPIC interrupt vector for which the
EOI was received.
+ struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC 1
+ __u32 type;
+ union {
+ struct {
+ __u32 msr;
+ __u64 control;
+ __u64 evt_page;
+ __u64 msg_page;
+ } synic;
+ } u;
+ };
+ /* KVM_EXIT_HYPERV */
+ struct kvm_hyperv_exit hyperv;
+Indicates that the VCPU exits into userspace to process some tasks
+related to Hyper-V emulation.
+Valid values for 'type' are:
+ KVM_EXIT_HYPERV_SYNIC -- synchronously notify user-space about
+Hyper-V SynIC state change. Notification is used to remap SynIC
+event/message pages and to enable/disable SynIC messages/events processing
+in userspace.
+
/* Fix the size of the union. */
char padding[256];
};
@@ -3685,3 +3713,16 @@ available, means that that the kernel has an implementation of the
H_RANDOM hypercall backed by a hardware random-number generator.
If present, the kernel H_RANDOM handler can be enabled for guest use
with the KVM_CAP_PPC_ENABLE_HCALL capability.
+
+8.2 KVM_CAP_HYPERV_SYNIC
+
+Architectures: x86
+This capability, if KVM_CHECK_EXTENSION indicates that it is
+available, means that that the kernel has an implementation of the
+Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is
+used to support Windows Hyper-V based guest paravirt drivers(VMBus).
+
+In order to use SynIC, it has to be activated by setting this
+capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
+will disable the use of APIC hardware virtualization even if supported
+by the CPU, as it's incompatible with SynIC auto-EOI behavior.

Documentation/virtual/kvm/devices/vm.txt

View file
diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt
index 2d09d1e..f083a16 100644
--- a/Documentation/virtual/kvm/devices/vm.txt
+++ b/Documentation/virtual/kvm/devices/vm.txt
@@ -37,7 +37,8 @@ Returns: -EFAULT if the given address is not accessible
Allows userspace to query the actual limit and set a new limit for
the maximum guest memory size. The limit will be rounded up to
2048 MB, 4096 GB, 8192 TB respectively, as this limit is governed by
-the number of page table levels.
+the number of page table levels. In the case that there is no limit we will set
+the limit to KVM_S390_NO_MEM_LIMIT (U64_MAX).
2. GROUP: KVM_S390_VM_CPU_MODEL
Architectures: s390

Documentation/virtual/kvm/mmu.txt

View file
diff --git a/Documentation/virtual/kvm/mmu.txt b/Documentation/virtual/kvm/mmu.txt
index 3a4d681..daf9c0f 100644
--- a/Documentation/virtual/kvm/mmu.txt
+++ b/Documentation/virtual/kvm/mmu.txt
@@ -203,10 +203,10 @@ Shadow pages contain the following information:
page cannot be destroyed. See role.invalid.
parent_ptes:
The reverse mapping for the pte/ptes pointing at this page's spt. If
- parent_ptes bit 0 is zero, only one spte points at this pages and
+ parent_ptes bit 0 is zero, only one spte points at this page and
parent_ptes points at this single spte, otherwise, there exists multiple
sptes pointing at this page and (parent_ptes & ~0x1) points at a data
- structure with a list of parent_ptes.
+ structure with a list of parent sptes.
unsync:
If true, then the translations in this page may not match the guest's
translation. This is equivalent to the state of the tlb when a pte is

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index 020a3be..e99a7b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6089,6 +6089,7 @@ M: Marc Zyngier <[email protected]>
L: [email protected] (moderated for non-subscribers)
W: http://systems.cs.columbia.edu/projects/kvm-arm
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git
S: Supported
F: arch/arm/include/uapi/asm/kvm*
F: arch/arm/include/asm/kvm*

arch/arm/include/asm/kvm_arm.h

View file
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index dc641dd..e22089f 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -19,6 +19,7 @@
#ifndef __ARM_KVM_ARM_H__
#define __ARM_KVM_ARM_H__
+#include <linux/const.h>
#include <linux/types.h>
/* Hyp Configuration Register (HCR) bits */
@@ -132,10 +133,9 @@
* space.
*/
#define KVM_PHYS_SHIFT (40)
-#define KVM_PHYS_SIZE (1ULL << KVM_PHYS_SHIFT)
-#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL)
-#define PTRS_PER_S2_PGD (1ULL << (KVM_PHYS_SHIFT - 30))
-#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
+#define KVM_PHYS_SIZE (_AC(1, ULL) << KVM_PHYS_SHIFT)
+#define KVM_PHYS_MASK (KVM_PHYS_SIZE - _AC(1, ULL))
+#define PTRS_PER_S2_PGD (_AC(1, ULL) << (KVM_PHYS_SHIFT - 30))
/* Virtualization Translation Control Register (VTCR) bits */
#define VTCR_SH0 (3 << 12)
@@ -162,17 +162,17 @@
#define VTTBR_X (5 - KVM_T0SZ)
#endif
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
-#define VTTBR_VMID_SHIFT (48LLU)
-#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT)
+#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_VMID_SHIFT _AC(48, ULL)
+#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
/* Hyp Syndrome Register (HSR) bits */
#define HSR_EC_SHIFT (26)
-#define HSR_EC (0x3fU << HSR_EC_SHIFT)
-#define HSR_IL (1U << 25)
+#define HSR_EC (_AC(0x3f, UL) << HSR_EC_SHIFT)
+#define HSR_IL (_AC(1, UL) << 25)
#define HSR_ISS (HSR_IL - 1)
#define HSR_ISV_SHIFT (24)
-#define HSR_ISV (1U << HSR_ISV_SHIFT)
+#define HSR_ISV (_AC(1, UL) << HSR_ISV_SHIFT)
#define HSR_SRT_SHIFT (16)
#define HSR_SRT_MASK (0xf << HSR_SRT_SHIFT)
#define HSR_FSC (0x3f)
@@ -180,9 +180,9 @@
#define HSR_SSE (1 << 21)
#define HSR_WNR (1 << 6)
#define HSR_CV_SHIFT (24)
-#define HSR_CV (1U << HSR_CV_SHIFT)
+#define HSR_CV (_AC(1, UL) << HSR_CV_SHIFT)
#define HSR_COND_SHIFT (20)
-#define HSR_COND (0xfU << HSR_COND_SHIFT)
+#define HSR_COND (_AC(0xf, UL) << HSR_COND_SHIFT)
#define FSC_FAULT (0x04)
#define FSC_ACCESS (0x08)
@@ -210,13 +210,13 @@
#define HSR_EC_DABT (0x24)
#define HSR_EC_DABT_HYP (0x25)
-#define HSR_WFI_IS_WFE (1U << 0)
+#define HSR_WFI_IS_WFE (_AC(1, UL) << 0)
-#define HSR_HVC_IMM_MASK ((1UL << 16) - 1)
+#define HSR_HVC_IMM_MASK ((_AC(1, UL) << 16) - 1)
-#define HSR_DABT_S1PTW (1U << 7)
-#define HSR_DABT_CM (1U << 8)
-#define HSR_DABT_EA (1U << 9)
+#define HSR_DABT_S1PTW (_AC(1, UL) << 7)
+#define HSR_DABT_CM (_AC(1, UL) << 8)
+#define HSR_DABT_EA (_AC(1, UL) << 9)
#define kvm_arm_exception_type \
{0, "RESET" }, \

arch/arm/include/asm/kvm_host.h

View file
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 6692982..f9f2779 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -150,6 +150,12 @@ struct kvm_vcpu_stat {
u32 halt_successful_poll;
u32 halt_attempted_poll;
u32 halt_wakeup;
+ u32 hvc_exit_stat;
+ u64 wfe_exit_stat;
+ u64 wfi_exit_stat;
+ u64 mmio_exit_user;
+ u64 mmio_exit_kernel;
+ u64 exits;
};
int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);

arch/arm/include/asm/kvm_mmu.h

View file
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 405aa18..9203c21 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -279,6 +279,11 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
pgd_t *merged_hyp_pgd,
unsigned long hyp_idmap_start) { }
+static inline unsigned int kvm_get_vmid_bits(void)
+{
+ return 8;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* __ARM_KVM_MMU_H__ */

arch/arm/kvm/arm.c

View file
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index e06fd29..dda1959 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -44,6 +44,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_psci.h>
+#include <asm/sections.h>
#ifdef REQUIRES_VIRT
__asm__(".arch_extension virt");
@@ -58,9 +59,12 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
/* The VMID used in the VTTBR */
static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
-static u8 kvm_next_vmid;
+static u32 kvm_next_vmid;
+static unsigned int kvm_vmid_bits __read_mostly;
static DEFINE_SPINLOCK(kvm_vmid_lock);
+static bool vgic_present;
+
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
{
BUG_ON(preemptible());
@@ -132,7 +136,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.vmid_gen = 0;
/* The maximum number of VCPUs is limited by the host's GIC model */
- kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
+ kvm->arch.max_vcpus = vgic_present ?
+ kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
return ret;
out_free_stage2_pgd:
@@ -172,6 +177,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int r;
switch (ext) {
case KVM_CAP_IRQCHIP:
+ r = vgic_present;
+ break;
case KVM_CAP_IOEVENTFD:
case KVM_CAP_DEVICE_CTRL:
case KVM_CAP_USER_MEMORY:
@@ -433,11 +440,12 @@ static void update_vttbr(struct kvm *kvm)
kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
kvm->arch.vmid = kvm_next_vmid;
kvm_next_vmid++;
+ kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
/* update vttbr to be used with the new vmid */
pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm));
BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
- vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
+ vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
kvm->arch.vttbr = pgd_phys | vmid;
spin_unlock(&kvm_vmid_lock);
@@ -603,6 +611,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
+ vcpu->stat.exits++;
/*
* Back from guest
*************************************************************/
@@ -913,6 +922,8 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
switch (dev_id) {
case KVM_ARM_DEVICE_VGIC_V2:
+ if (!vgic_present)
+ return -ENXIO;
return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
default:
return -ENODEV;
@@ -927,6 +938,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
switch (ioctl) {
case KVM_CREATE_IRQCHIP: {
+ if (!vgic_present)
+ return -ENXIO;
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
}
case KVM_ARM_SET_DEVICE_ADDR: {
@@ -1067,6 +1080,12 @@ static int init_hyp_mode(void)
goto out_free_mappings;
}
+ err = create_hyp_mappings(__start_rodata, __end_rodata);
+ if (err) {
+ kvm_err("Cannot map rodata section\n");
+ goto out_free_mappings;
+ }
+
/*
* Map the Hyp stack pages
*/
@@ -1111,8 +1130,17 @@ static int init_hyp_mode(void)
* Init HYP view of VGIC
*/
err = kvm_vgic_hyp_init();
- if (err)
+ switch (err) {
+ case 0:
+ vgic_present = true;
+ break;
+ case -ENODEV:
+ case -ENXIO:
+ vgic_present = false;
+ break;
+ default:
goto out_free_context;
+ }
/*
* Init HYP architected timer support
@@ -1127,6 +1155,10 @@ static int init_hyp_mode(void)
kvm_perf_init();
+ /* set size of VMID supported by CPU */
+ kvm_vmid_bits = kvm_get_vmid_bits();
+ kvm_info("%d-bit VMID\n", kvm_vmid_bits);
+
kvm_info("Hyp mode initialized successfully\n");
return 0;

arch/arm/kvm/emulate.c

View file
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index d6c0052..dc99159 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -275,6 +275,40 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
return vbar;
}
+/*
+ * Switch to an exception mode, updating both CPSR and SPSR. Follow
+ * the logic described in AArch32.EnterMode() from the ARMv8 ARM.
+ */
+static void kvm_update_psr(struct kvm_vcpu *vcpu, unsigned long mode)
+{
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
+
+ *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | mode;
+
+ switch (mode) {
+ case FIQ_MODE:
+ *vcpu_cpsr(vcpu) |= PSR_F_BIT;
+ /* Fall through */
+ case ABT_MODE:
+ case IRQ_MODE:
+ *vcpu_cpsr(vcpu) |= PSR_A_BIT;
+ /* Fall through */
+ default:
+ *vcpu_cpsr(vcpu) |= PSR_I_BIT;
+ }
+
+ *vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
+
+ if (sctlr & SCTLR_TE)
+ *vcpu_cpsr(vcpu) |= PSR_T_BIT;
+ if (sctlr & SCTLR_EE)
+ *vcpu_cpsr(vcpu) |= PSR_E_BIT;
+
+ /* Note: These now point to the mode banked copies */
+ *vcpu_spsr(vcpu) = cpsr;
+}
+
/**
* kvm_inject_undefined - inject an undefined exception into the guest
* @vcpu: The VCPU to receive the undefined exception
@@ -286,29 +320,13 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
*/
void kvm_inject_undefined(struct kvm_vcpu *vcpu)
{
- unsigned long new_lr_value;
- unsigned long new_spsr_value;
unsigned long cpsr = *vcpu_cpsr(vcpu);
- u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
bool is_thumb = (cpsr & PSR_T_BIT);
u32 vect_offset = 4;
u32 return_offset = (is_thumb) ? 2 : 4;
- new_spsr_value = cpsr;
- new_lr_value = *vcpu_pc(vcpu) - return_offset;
-
- *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | UND_MODE;
- *vcpu_cpsr(vcpu) |= PSR_I_BIT;
- *vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
-
- if (sctlr & SCTLR_TE)
- *vcpu_cpsr(vcpu) |= PSR_T_BIT;
- if (sctlr & SCTLR_EE)
- *vcpu_cpsr(vcpu) |= PSR_E_BIT;
-
- /* Note: These now point to UND banked copies */
- *vcpu_spsr(vcpu) = cpsr;
- *vcpu_reg(vcpu, 14) = new_lr_value;
+ kvm_update_psr(vcpu, UND_MODE);
+ *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) - return_offset;
/* Branch to exception vector */
*vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
@@ -320,30 +338,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
*/
static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr)
{
- unsigned long new_lr_value;
- unsigned long new_spsr_value;
unsigned long cpsr = *vcpu_cpsr(vcpu);
- u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
bool is_thumb = (cpsr & PSR_T_BIT);
u32 vect_offset;
u32 return_offset = (is_thumb) ? 4 : 0;
bool is_lpae;
- new_spsr_value = cpsr;
- new_lr_value = *vcpu_pc(vcpu) + return_offset;
-
- *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | ABT_MODE;
- *vcpu_cpsr(vcpu) |= PSR_I_BIT | PSR_A_BIT;
- *vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
-
- if (sctlr & SCTLR_TE)
- *vcpu_cpsr(vcpu) |= PSR_T_BIT;
- if (sctlr & SCTLR_EE)
- *vcpu_cpsr(vcpu) |= PSR_E_BIT;
-
- /* Note: These now point to ABT banked copies */
- *vcpu_spsr(vcpu) = cpsr;
- *vcpu_reg(vcpu, 14) = new_lr_value;
+ kvm_update_psr(vcpu, ABT_MODE);
+ *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
if (is_pabt)
vect_offset = 12;

arch/arm/kvm/guest.c

View file
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 96e935b..5fa69d7 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -33,6 +33,12 @@
#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
struct kvm_stats_debugfs_item debugfs_entries[] = {
+ VCPU_STAT(hvc_exit_stat),
+ VCPU_STAT(wfe_exit_stat),
+ VCPU_STAT(wfi_exit_stat),
+ VCPU_STAT(mmio_exit_user),
+ VCPU_STAT(mmio_exit_kernel),
+ VCPU_STAT(exits),
{ NULL }
};

arch/arm/kvm/handle_exit.c

View file
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 95f12b2..3ede90d 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -42,6 +42,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
kvm_vcpu_hvc_get_imm(vcpu));
+ vcpu->stat.hvc_exit_stat++;
ret = kvm_psci_call(vcpu);
if (ret < 0) {
@@ -89,9 +90,11 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) {
trace_kvm_wfx(*vcpu_pc(vcpu), true);
+ vcpu->stat.wfe_exit_stat++;
kvm_vcpu_on_spin(vcpu);
} else {
trace_kvm_wfx(*vcpu_pc(vcpu), false);
+ vcpu->stat.wfi_exit_stat++;
kvm_vcpu_block(vcpu);
}

arch/arm/kvm/mmio.c

View file
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index 3a10c9f..7f33b20 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -210,8 +210,11 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
if (!ret) {
/* We handled the access successfully in the kernel. */
+ vcpu->stat.mmio_exit_kernel++;
kvm_handle_mmio_return(vcpu, run);
return 1;
+ } else {
+ vcpu->stat.mmio_exit_user++;
}
run->exit_reason = KVM_EXIT_MMIO;

arch/arm/kvm/mmu.c

View file
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 61d96a6..22f7fa0 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -656,9 +656,9 @@ static void *kvm_alloc_hwpgd(void)
* kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
* @kvm: The KVM struct pointer for the VM.
*
- * Allocates the 1st level table only of size defined by S2_PGD_ORDER (can
- * support either full 40-bit input addresses or limited to 32-bit input
- * addresses). Clears the allocated pages.
+ * Allocates only the stage-2 HW PGD level table(s) (can support either full
+ * 40-bit input addresses or limited to 32-bit input addresses). Clears the
+ * allocated pages.
*
* Note we don't need locking here as this is only called when the VM is
* created, which can only be done once.

arch/arm64/include/asm/kvm_arm.h

View file
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 5e6857b..738a95f 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -125,6 +125,7 @@
#define VTCR_EL2_SL0_LVL1 (1 << 6)
#define VTCR_EL2_T0SZ_MASK 0x3f
#define VTCR_EL2_T0SZ_40B 24
+#define VTCR_EL2_VS 19
/*
* We configure the Stage-2 page tables to always restrict the IPA space to be
@@ -169,7 +170,7 @@
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
#define VTTBR_VMID_SHIFT (UL(48))
-#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT)
+#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
/* Hyp System Trap Register */
#define HSTR_EL2_T(x) (1 << x)

arch/arm64/include/asm/kvm_asm.h

View file
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 5e37710..52b777b 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -20,82 +20,6 @@
#include <asm/virt.h>
-/*
- * 0 is reserved as an invalid value.
- * Order *must* be kept in sync with the hyp switch code.
- */
-#define MPIDR_EL1 1 /* MultiProcessor Affinity Register */
-#define CSSELR_EL1 2 /* Cache Size Selection Register */
-#define SCTLR_EL1 3 /* System Control Register */
-#define ACTLR_EL1 4 /* Auxiliary Control Register */
-#define CPACR_EL1 5 /* Coprocessor Access Control */
-#define TTBR0_EL1 6 /* Translation Table Base Register 0 */
-#define TTBR1_EL1 7 /* Translation Table Base Register 1 */
-#define TCR_EL1 8 /* Translation Control Register */
-#define ESR_EL1 9 /* Exception Syndrome Register */
-#define AFSR0_EL1 10 /* Auxilary Fault Status Register 0 */
-#define AFSR1_EL1 11 /* Auxilary Fault Status Register 1 */
-#define FAR_EL1 12 /* Fault Address Register */
-#define MAIR_EL1 13 /* Memory Attribute Indirection Register */
-#define VBAR_EL1 14 /* Vector Base Address Register */
-#define CONTEXTIDR_EL1 15 /* Context ID Register */
-#define TPIDR_EL0 16 /* Thread ID, User R/W */
-#define TPIDRRO_EL0 17 /* Thread ID, User R/O */
-#define TPIDR_EL1 18 /* Thread ID, Privileged */
-#define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */
-#define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */
-#define PAR_EL1 21 /* Physical Address Register */

This diff is incomplete. Download the complete patch.

arch/arm64/include/asm/kvm_emulate.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/include/asm/kvm_host.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/include/asm/kvm_mmio.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/include/asm/kvm_mmu.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/include/asm/sysreg.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kernel/asm-offsets.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/Makefile

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/guest.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/handle_exit.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp-init.S

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp.S

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/Makefile

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/debug-sr.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/entry.S

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/fpsimd.S

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/hyp-entry.S

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/hyp.h

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/switch.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/sysreg-sr.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/timer-sr.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/tlb.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/vgic-v2-sr.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/hyp/vgic-v3-sr.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/sys_regs.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/vgic-v2-switch.S

View before deletion

This diff is incomplete. Download the complete patch.

arch/arm64/kvm/vgic-v3-switch.S

View before deletion

This diff is incomplete. Download the complete patch.

arch/powerpc/include/asm/kvm_host.h

View file

This diff is incomplete. Download the complete patch.

arch/powerpc/kvm/book3s_hv.c

View file

This diff is incomplete. Download the complete patch.

arch/powerpc/kvm/book3s_pr.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/include/asm/elf.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/include/asm/kvm_host.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/include/asm/sclp.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/include/uapi/asm/kvm.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/kernel/processor.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kernel/setup.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/diag.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/gaccess.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/intercept.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/interrupt.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/kvm-s390.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/kvm-s390.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/kvm/trace-s390.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/mm/pgtable.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/kvm_host.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/uapi/asm/hyperv.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/hyperv.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/hyperv.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/ioapic.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/ioapic.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/irq.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/irq_comm.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/lapic.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/lapic.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/mmu.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/mmu_audit.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/paging_tmpl.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/svm.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/trace.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/vmx.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/x86.c

View file

This diff is incomplete. Download the complete patch.

drivers/hv/hyperv_vmbus.h

View file

This diff is incomplete. Download the complete patch.

drivers/s390/char/sclp_early.c

View file

This diff is incomplete. Download the complete patch.

include/clocksource/arm_arch_timer.h

View file

This diff is incomplete. Download the complete patch.

include/kvm/arm_vgic.h

View file

This diff is incomplete. Download the complete patch.

include/linux/kvm_host.h

View file

This diff is incomplete. Download the complete patch.

include/linux/kvm_para.h

View file

This diff is incomplete. Download the complete patch.

include/uapi/linux/kvm.h

View file

This diff is incomplete. Download the complete patch.

virt/kvm/arm/vgic-v3.c

View file

This diff is incomplete. Download the complete patch.

virt/kvm/arm/vgic.c

View file

This diff is incomplete. Download the complete patch.

virt/kvm/async_pf.c

View file

This diff is incomplete. Download the complete patch.

virt/kvm/irqchip.c

View file

This diff is incomplete. Download the complete patch.

virt/kvm/kvm_main.c

View file

This diff is incomplete. Download the complete patch.