mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
KVM updates for v4.9-rc1
All architectures:
Move `make kvmconfig` stubs from x86; use 64 bits for debugfs stats.
ARM:
Important fixes for not using an in-kernel irqchip; handle SError
exceptions and present them to guests if appropriate; proxying of GICV
access at EL2 if guest mappings are unsafe; GICv3 on AArch32 on ARMv8;
preparations for GICv3 save/restore, including ABI docs; cleanups and
a bit of optimizations.
MIPS:
A couple of fixes in preparation for supporting MIPS EVA host kernels;
MIPS SMP host & TLB invalidation fixes.
PPC:
Fix the bug which caused guests to falsely report lockups; other minor
fixes; a small optimization.
s390:
Lazy enablement of runtime instrumentation; up to 255 CPUs for nested
guests; rework of machine check deliver; cleanups and fixes.
x86:
IOMMU part of AMD's AVIC for vmexit-less interrupt delivery; Hyper-V
TSC page; per-vcpu tsc_offset in debugfs; accelerated INS/OUTS in
nVMX; cleanups and fixes.
-----BEGIN PGP SIGNATURE-----
iQEcBAABCAAGBQJX9iDrAAoJEED/6hsPKofoOPoIAIUlgojkb9l2l1XVDgsXdgQL
sRVhYSVv7/c8sk9vFImrD5ElOPZd+CEAIqFOu45+NM3cNi7gxip9yftUVs7wI5aC
eDZRWm1E4trDZLe54ZM9ThcqZzZZiELVGMfR1+ZndUycybwyWzafpXYsYyaXp3BW
hyHM3qVkoWO3dxBWFwHIoO/AUJrWYkRHEByKyvlC6KPxSdBPSa5c1AQwMCoE0Mo4
K/xUj4gBn9eMelNhg4Oqu/uh49/q+dtdoP2C+sVM8bSdquD+PmIeOhPFIcuGbGFI
B+oRpUhIuntN39gz8wInJ4/GRSeTuR2faNPxMn4E1i1u4LiuJvipcsOjPfe0a18=
=fZRB
-----END PGP SIGNATURE-----
Merge tag 'kvm-4.9-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Radim Krčmář:
"All architectures:
- move `make kvmconfig` stubs from x86
- use 64 bits for debugfs stats
ARM:
- Important fixes for not using an in-kernel irqchip
- handle SError exceptions and present them to guests if appropriate
- proxying of GICV access at EL2 if guest mappings are unsafe
- GICv3 on AArch32 on ARMv8
- preparations for GICv3 save/restore, including ABI docs
- cleanups and a bit of optimizations
MIPS:
- A couple of fixes in preparation for supporting MIPS EVA host
kernels
- MIPS SMP host & TLB invalidation fixes
PPC:
- Fix the bug which caused guests to falsely report lockups
- other minor fixes
- a small optimization
s390:
- Lazy enablement of runtime instrumentation
- up to 255 CPUs for nested guests
- rework of machine check deliver
- cleanups and fixes
x86:
- IOMMU part of AMD's AVIC for vmexit-less interrupt delivery
- Hyper-V TSC page
- per-vcpu tsc_offset in debugfs
- accelerated INS/OUTS in nVMX
- cleanups and fixes"
* tag 'kvm-4.9-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (140 commits)
KVM: MIPS: Drop dubious EntryHi optimisation
KVM: MIPS: Invalidate TLB by regenerating ASIDs
KVM: MIPS: Split kernel/user ASID regeneration
KVM: MIPS: Drop other CPU ASIDs on guest MMU changes
KVM: arm/arm64: vgic: Don't flush/sync without a working vgic
KVM: arm64: Require in-kernel irqchip for PMU support
KVM: PPC: Book3s PR: Allow access to unprivileged MMCR2 register
KVM: PPC: Book3S PR: Support 64kB page size on POWER8E and POWER8NVL
KVM: PPC: Book3S: Remove duplicate setting of the B field in tlbie
KVM: PPC: BookE: Fix a sanity check
KVM: PPC: Book3S HV: Take out virtual core piggybacking code
KVM: PPC: Book3S: Treat VTB as a per-subcore register, not per-thread
ARM: gic-v3: Work around definition of gic_write_bpr1
KVM: nVMX: Fix the NMI IDT-vectoring handling
KVM: VMX: Enable MSR-BASED TPR shadow even if APICv is inactive
KVM: nVMX: Fix reload apic access page warning
kvmconfig: add virtio-gpu to config fragment
config: move x86 kvm_guest.config to a common location
arm64: KVM: Remove duplicating init code for setting VMID
ARM: KVM: Support vgic-v3
...
This commit is contained in:
commit
6218590bcb
127 changed files with 4540 additions and 1635 deletions
|
|
@ -107,35 +107,49 @@
|
|||
#define KVM_INVALID_INST 0xdeadbeef
|
||||
#define KVM_INVALID_ADDR 0xdeadbeef
|
||||
|
||||
/*
|
||||
* EVA has overlapping user & kernel address spaces, so user VAs may be >
|
||||
* PAGE_OFFSET. For this reason we can't use the default KVM_HVA_ERR_BAD of
|
||||
* PAGE_OFFSET.
|
||||
*/
|
||||
|
||||
#define KVM_HVA_ERR_BAD (-1UL)
|
||||
#define KVM_HVA_ERR_RO_BAD (-2UL)
|
||||
|
||||
static inline bool kvm_is_error_hva(unsigned long addr)
|
||||
{
|
||||
return IS_ERR_VALUE(addr);
|
||||
}
|
||||
|
||||
extern atomic_t kvm_mips_instance;
|
||||
|
||||
struct kvm_vm_stat {
|
||||
u32 remote_tlb_flush;
|
||||
ulong remote_tlb_flush;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_stat {
|
||||
u32 wait_exits;
|
||||
u32 cache_exits;
|
||||
u32 signal_exits;
|
||||
u32 int_exits;
|
||||
u32 cop_unusable_exits;
|
||||
u32 tlbmod_exits;
|
||||
u32 tlbmiss_ld_exits;
|
||||
u32 tlbmiss_st_exits;
|
||||
u32 addrerr_st_exits;
|
||||
u32 addrerr_ld_exits;
|
||||
u32 syscall_exits;
|
||||
u32 resvd_inst_exits;
|
||||
u32 break_inst_exits;
|
||||
u32 trap_inst_exits;
|
||||
u32 msa_fpe_exits;
|
||||
u32 fpe_exits;
|
||||
u32 msa_disabled_exits;
|
||||
u32 flush_dcache_exits;
|
||||
u32 halt_successful_poll;
|
||||
u32 halt_attempted_poll;
|
||||
u32 halt_poll_invalid;
|
||||
u32 halt_wakeup;
|
||||
u64 wait_exits;
|
||||
u64 cache_exits;
|
||||
u64 signal_exits;
|
||||
u64 int_exits;
|
||||
u64 cop_unusable_exits;
|
||||
u64 tlbmod_exits;
|
||||
u64 tlbmiss_ld_exits;
|
||||
u64 tlbmiss_st_exits;
|
||||
u64 addrerr_st_exits;
|
||||
u64 addrerr_ld_exits;
|
||||
u64 syscall_exits;
|
||||
u64 resvd_inst_exits;
|
||||
u64 break_inst_exits;
|
||||
u64 trap_inst_exits;
|
||||
u64 msa_fpe_exits;
|
||||
u64 fpe_exits;
|
||||
u64 msa_disabled_exits;
|
||||
u64 flush_dcache_exits;
|
||||
u64 halt_successful_poll;
|
||||
u64 halt_attempted_poll;
|
||||
u64 halt_poll_invalid;
|
||||
u64 halt_wakeup;
|
||||
};
|
||||
|
||||
struct kvm_arch_memory_slot {
|
||||
|
|
@ -314,6 +328,9 @@ struct kvm_vcpu_arch {
|
|||
u32 guest_kernel_asid[NR_CPUS];
|
||||
struct mm_struct guest_kernel_mm, guest_user_mm;
|
||||
|
||||
/* Guest ASID of last user mode execution */
|
||||
unsigned int last_user_gasid;
|
||||
|
||||
int last_sched_cpu;
|
||||
|
||||
/* WAIT executed */
|
||||
|
|
|
|||
|
|
@ -846,6 +846,47 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)
|
|||
return EMULATE_FAIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map.
|
||||
* @vcpu: VCPU with changed mappings.
|
||||
* @tlb: TLB entry being removed.
|
||||
*
|
||||
* This is called to indicate a single change in guest MMU mappings, so that we
|
||||
* can arrange TLB flushes on this and other CPUs.
|
||||
*/
|
||||
static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
|
||||
struct kvm_mips_tlb *tlb)
|
||||
{
|
||||
int cpu, i;
|
||||
bool user;
|
||||
|
||||
/* No need to flush for entries which are already invalid */
|
||||
if (!((tlb->tlb_lo[0] | tlb->tlb_lo[1]) & ENTRYLO_V))
|
||||
return;
|
||||
/* User address space doesn't need flushing for KSeg2/3 changes */
|
||||
user = tlb->tlb_hi < KVM_GUEST_KSEG0;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
/*
|
||||
* Probe the shadow host TLB for the entry being overwritten, if one
|
||||
* matches, invalidate it
|
||||
*/
|
||||
kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
|
||||
|
||||
/* Invalidate the whole ASID on other CPUs */
|
||||
cpu = smp_processor_id();
|
||||
for_each_possible_cpu(i) {
|
||||
if (i == cpu)
|
||||
continue;
|
||||
if (user)
|
||||
vcpu->arch.guest_user_asid[i] = 0;
|
||||
vcpu->arch.guest_kernel_asid[i] = 0;
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
/* Write Guest TLB Entry @ Index */
|
||||
enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
|
@ -865,11 +906,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
|
|||
}
|
||||
|
||||
tlb = &vcpu->arch.guest_tlb[index];
|
||||
/*
|
||||
* Probe the shadow host TLB for the entry being overwritten, if one
|
||||
* matches, invalidate it
|
||||
*/
|
||||
kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
|
||||
|
||||
kvm_mips_invalidate_guest_tlb(vcpu, tlb);
|
||||
|
||||
tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
|
||||
tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
|
||||
|
|
@ -898,11 +936,7 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu)
|
|||
|
||||
tlb = &vcpu->arch.guest_tlb[index];
|
||||
|
||||
/*
|
||||
* Probe the shadow host TLB for the entry being overwritten, if one
|
||||
* matches, invalidate it
|
||||
*/
|
||||
kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
|
||||
kvm_mips_invalidate_guest_tlb(vcpu, tlb);
|
||||
|
||||
tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
|
||||
tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
|
||||
|
|
@ -1026,6 +1060,7 @@ enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
|
|||
enum emulation_result er = EMULATE_DONE;
|
||||
u32 rt, rd, sel;
|
||||
unsigned long curr_pc;
|
||||
int cpu, i;
|
||||
|
||||
/*
|
||||
* Update PC and hold onto current PC in case there is
|
||||
|
|
@ -1127,16 +1162,31 @@ enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
|
|||
} else if (rd == MIPS_CP0_TLB_HI && sel == 0) {
|
||||
u32 nasid =
|
||||
vcpu->arch.gprs[rt] & KVM_ENTRYHI_ASID;
|
||||
if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) &&
|
||||
((kvm_read_c0_guest_entryhi(cop0) &
|
||||
if (((kvm_read_c0_guest_entryhi(cop0) &
|
||||
KVM_ENTRYHI_ASID) != nasid)) {
|
||||
trace_kvm_asid_change(vcpu,
|
||||
kvm_read_c0_guest_entryhi(cop0)
|
||||
& KVM_ENTRYHI_ASID,
|
||||
nasid);
|
||||
|
||||
/* Blow away the shadow host TLBs */
|
||||
kvm_mips_flush_host_tlb(1);
|
||||
/*
|
||||
* Regenerate/invalidate kernel MMU
|
||||
* context.
|
||||
* The user MMU context will be
|
||||
* regenerated lazily on re-entry to
|
||||
* guest user if the guest ASID actually
|
||||
* changes.
|
||||
*/
|
||||
preempt_disable();
|
||||
cpu = smp_processor_id();
|
||||
kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm,
|
||||
cpu, vcpu);
|
||||
vcpu->arch.guest_kernel_asid[cpu] =
|
||||
vcpu->arch.guest_kernel_mm.context.asid[cpu];
|
||||
for_each_possible_cpu(i)
|
||||
if (i != cpu)
|
||||
vcpu->arch.guest_kernel_asid[i] = 0;
|
||||
preempt_enable();
|
||||
}
|
||||
kvm_write_c0_guest_entryhi(cop0,
|
||||
vcpu->arch.gprs[rt]);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool kvm_arch_has_vcpu_debugfs(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_mips_free_vcpus(struct kvm *kvm)
|
||||
{
|
||||
unsigned int i;
|
||||
|
|
@ -411,6 +421,31 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
|
|||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
/* Must be called with preemption disabled, just before entering guest */
|
||||
static void kvm_mips_check_asids(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct mips_coproc *cop0 = vcpu->arch.cop0;
|
||||
int cpu = smp_processor_id();
|
||||
unsigned int gasid;
|
||||
|
||||
/*
|
||||
* Lazy host ASID regeneration for guest user mode.
|
||||
* If the guest ASID has changed since the last guest usermode
|
||||
* execution, regenerate the host ASID so as to invalidate stale TLB
|
||||
* entries.
|
||||
*/
|
||||
if (!KVM_GUEST_KERNEL_MODE(vcpu)) {
|
||||
gasid = kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID;
|
||||
if (gasid != vcpu->arch.last_user_gasid) {
|
||||
kvm_get_new_mmu_context(&vcpu->arch.guest_user_mm, cpu,
|
||||
vcpu);
|
||||
vcpu->arch.guest_user_asid[cpu] =
|
||||
vcpu->arch.guest_user_mm.context.asid[cpu];
|
||||
vcpu->arch.last_user_gasid = gasid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
int r = 0;
|
||||
|
|
@ -438,6 +473,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||
htw_stop();
|
||||
|
||||
trace_kvm_enter(vcpu);
|
||||
|
||||
kvm_mips_check_asids(vcpu);
|
||||
|
||||
r = vcpu->arch.vcpu_run(run, vcpu);
|
||||
trace_kvm_out(vcpu);
|
||||
|
||||
|
|
@ -1551,6 +1589,8 @@ skip_emul:
|
|||
if (ret == RESUME_GUEST) {
|
||||
trace_kvm_reenter(vcpu);
|
||||
|
||||
kvm_mips_check_asids(vcpu);
|
||||
|
||||
/*
|
||||
* If FPU / MSA are enabled (i.e. the guest's FPU / MSA context
|
||||
* is live), restore FCR31 / MSACSR.
|
||||
|
|
|
|||
|
|
@ -250,15 +250,27 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
|||
kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
|
||||
vcpu->arch.guest_kernel_asid[cpu] =
|
||||
vcpu->arch.guest_kernel_mm.context.asid[cpu];
|
||||
kvm_get_new_mmu_context(&vcpu->arch.guest_user_mm, cpu, vcpu);
|
||||
vcpu->arch.guest_user_asid[cpu] =
|
||||
vcpu->arch.guest_user_mm.context.asid[cpu];
|
||||
newasid++;
|
||||
|
||||
kvm_debug("[%d]: cpu_context: %#lx\n", cpu,
|
||||
cpu_context(cpu, current->mm));
|
||||
kvm_debug("[%d]: Allocated new ASID for Guest Kernel: %#x\n",
|
||||
cpu, vcpu->arch.guest_kernel_asid[cpu]);
|
||||
}
|
||||
|
||||
if ((vcpu->arch.guest_user_asid[cpu] ^ asid_cache(cpu)) &
|
||||
asid_version_mask(cpu)) {
|
||||
u32 gasid = kvm_read_c0_guest_entryhi(vcpu->arch.cop0) &
|
||||
KVM_ENTRYHI_ASID;
|
||||
|
||||
kvm_get_new_mmu_context(&vcpu->arch.guest_user_mm, cpu, vcpu);
|
||||
vcpu->arch.guest_user_asid[cpu] =
|
||||
vcpu->arch.guest_user_mm.context.asid[cpu];
|
||||
vcpu->arch.last_user_gasid = gasid;
|
||||
newasid++;
|
||||
|
||||
kvm_debug("[%d]: cpu_context: %#lx\n", cpu,
|
||||
cpu_context(cpu, current->mm));
|
||||
kvm_debug("[%d]: Allocated new ASID for Guest User: %#x\n", cpu,
|
||||
vcpu->arch.guest_user_asid[cpu]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,6 +175,24 @@ static int kvm_trap_emul_handle_tlb_miss(struct kvm_vcpu *vcpu, bool store)
|
|||
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
ret = RESUME_HOST;
|
||||
}
|
||||
} else if (KVM_GUEST_KERNEL_MODE(vcpu)
|
||||
&& (KSEGX(badvaddr) == CKSEG0 || KSEGX(badvaddr) == CKSEG1)) {
|
||||
/*
|
||||
* With EVA we may get a TLB exception instead of an address
|
||||
* error when the guest performs MMIO to KSeg1 addresses.
|
||||
*/
|
||||
kvm_debug("Emulate %s MMIO space\n",
|
||||
store ? "Store to" : "Load from");
|
||||
er = kvm_mips_emulate_inst(cause, opc, run, vcpu);
|
||||
if (er == EMULATE_FAIL) {
|
||||
kvm_err("Emulate %s MMIO space failed\n",
|
||||
store ? "Store to" : "Load from");
|
||||
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
ret = RESUME_HOST;
|
||||
} else {
|
||||
run->exit_reason = KVM_EXIT_MMIO;
|
||||
ret = RESUME_HOST;
|
||||
}
|
||||
} else {
|
||||
kvm_err("Illegal TLB %s fault address , cause %#x, PC: %p, BadVaddr: %#lx\n",
|
||||
store ? "ST" : "LD", cause, opc, badvaddr);
|
||||
|
|
|
|||
Loading…
Reference in a new issue