mirror of https://gitee.com/openkylin/linux.git
Patch queue for 3.13 - 2013-12-18
This fixes some grave issues we've only found after 3.13-rc1: - Make the modularized HV/PR book3s kvm work well as modules - Fix some race conditions - Fix compilation with certain compilers (booke) - Fix THP for book3s_hv - Fix preemption for book3s_pr Alexander Graf (4): KVM: PPC: Book3S: PR: Don't clobber our exit handler id KVM: PPC: Book3S: PR: Export kvmppc_copy_to|from_svcpu KVM: PPC: Book3S: PR: Make svcpu -> vcpu store preempt savvy KVM: PPC: Book3S: PR: Enable interrupts earlier Aneesh Kumar K.V (1): powerpc: book3s: kvm: Don't abuse host r2 in exit path Paul Mackerras (5): KVM: PPC: Book3S HV: Fix physical address calculations KVM: PPC: Book3S HV: Refine barriers in guest entry/exit KVM: PPC: Book3S HV: Make tbacct_lock irq-safe KVM: PPC: Book3S HV: Take SRCU read lock around kvm_read_guest() call KVM: PPC: Book3S HV: Don't drop low-order page address bits Scott Wood (1): powerpc/kvm/booke: Fix build break due to stack frame size warning pingfan liu (1): powerpc: kvm: fix rare but potential deadlock scene -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJSscYdAAoJECszeR4D/txgcqAP/1hztHJ+QVwOovEmHSkd6s9G A9Ib48U3r/YX5Xugp3VeJQEoSvvRQQDvi1lcu20YO7HRFL3AZBnq2/EgXaMSfu0s kKWZiadlpYNkSfjcipuia1yu2auAVWyGTMjuwWhKSH7WJnTrQD17vTNaOhnfrEvY wfUTCux7JSUlDnAuNBPHjtWgPsNXZ9U5ODThLVKMuXUceFxse/pRER+RM8/sGwGD h5uQicwPAD4bp2epg7zG7NgFs9np1U/WZvwHn3LGlb/eHJW0lB/lqdCFMtBFaDiA 3GS3AOIJCtWhEPzghUJMyId8Yc7E5Bi27ur+8fOKHddbM+NFR154hTzoOuVZgvmq HdNhcjTDfhimKl+aPaQyFpnePBLk2hZ5zEyxr5eMocyvZ+uRL7ghhUBjnNFNXk1k FAlzyEWXirdumN2sS9u9/PUhoETL13yhghxXzDq35/rjWxPuLtjvVlmroQfPI5cl 0AW5d3G5lEnb/vNo/dUFG8EAxunX26sgaro6XxLA3Y/tZ4691S9mNaeyLv/w4VDS T9IcLUIhnpkR6HPkXci1mRrX13GC1uBB74jhBJvgJs91UmgLZN3W3VEcS5ulXxxb UoLsDSO1qo2Md2KrRltsRcMJAaAjbbcTzApudpN24d6zMCUxxfnjNW9Q8h2+eaoi ST9nIxzK3a9HHnnJ6AsJ =kveZ -----END PGP SIGNATURE----- Merge tag 'signed-for-3.13' of git://github.com/agraf/linux-2.6 into kvm-master Patch queue for 3.13 - 2013-12-18 This fixes some grave issues we've only found after 3.13-rc1: - Make the modularized HV/PR book3s kvm work well as modules - Fix some race conditions - Fix compilation with certain compilers (booke) - Fix THP for book3s_hv - Fix preemption for book3s_pr Alexander Graf (4): KVM: PPC: Book3S: PR: Don't clobber our exit handler id KVM: PPC: Book3S: PR: Export kvmppc_copy_to|from_svcpu KVM: PPC: Book3S: PR: Make svcpu -> vcpu store preempt savvy KVM: PPC: Book3S: PR: Enable interrupts earlier Aneesh Kumar K.V (1): powerpc: book3s: kvm: Don't abuse host r2 in exit path Paul Mackerras (5): KVM: PPC: Book3S HV: Fix physical address calculations KVM: PPC: Book3S HV: Refine barriers in guest entry/exit KVM: PPC: Book3S HV: Make tbacct_lock irq-safe KVM: PPC: Book3S HV: Take SRCU read lock around kvm_read_guest() call KVM: PPC: Book3S HV: Don't drop low-order page address bits Scott Wood (1): powerpc/kvm/booke: Fix build break due to stack frame size warning pingfan liu (1): powerpc: kvm: fix rare but potential deadlock scene
This commit is contained in:
commit
5e6d26cf48
|
@ -192,6 +192,10 @@ extern void kvmppc_load_up_vsx(void);
|
||||||
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
|
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
|
||||||
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
|
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
|
||||||
extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
|
extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
|
||||||
|
extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu,
|
||||||
|
struct kvm_vcpu *vcpu);
|
||||||
|
extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
|
||||||
|
struct kvmppc_book3s_shadow_vcpu *svcpu);
|
||||||
|
|
||||||
static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
|
static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,7 @@ struct kvmppc_host_state {
|
||||||
ulong vmhandler;
|
ulong vmhandler;
|
||||||
ulong scratch0;
|
ulong scratch0;
|
||||||
ulong scratch1;
|
ulong scratch1;
|
||||||
|
ulong scratch2;
|
||||||
u8 in_guest;
|
u8 in_guest;
|
||||||
u8 restore_hid5;
|
u8 restore_hid5;
|
||||||
u8 napping;
|
u8 napping;
|
||||||
|
@ -106,6 +107,7 @@ struct kvmppc_host_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kvmppc_book3s_shadow_vcpu {
|
struct kvmppc_book3s_shadow_vcpu {
|
||||||
|
bool in_use;
|
||||||
ulong gpr[14];
|
ulong gpr[14];
|
||||||
u32 cr;
|
u32 cr;
|
||||||
u32 xer;
|
u32 xer;
|
||||||
|
|
|
@ -35,7 +35,7 @@ extern void giveup_vsx(struct task_struct *);
|
||||||
extern void enable_kernel_spe(void);
|
extern void enable_kernel_spe(void);
|
||||||
extern void giveup_spe(struct task_struct *);
|
extern void giveup_spe(struct task_struct *);
|
||||||
extern void load_up_spe(struct task_struct *);
|
extern void load_up_spe(struct task_struct *);
|
||||||
extern void switch_booke_debug_regs(struct thread_struct *new_thread);
|
extern void switch_booke_debug_regs(struct debug_reg *new_debug);
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
extern void discard_lazy_cpu_state(void);
|
extern void discard_lazy_cpu_state(void);
|
||||||
|
|
|
@ -576,6 +576,7 @@ int main(void)
|
||||||
HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
|
HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
|
||||||
HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
|
HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
|
||||||
HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
|
HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
|
||||||
|
HSTATE_FIELD(HSTATE_SCRATCH2, scratch2);
|
||||||
HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
|
HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
|
||||||
HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
|
HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
|
||||||
HSTATE_FIELD(HSTATE_NAPPING, napping);
|
HSTATE_FIELD(HSTATE_NAPPING, napping);
|
||||||
|
|
|
@ -339,7 +339,7 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prime_debug_regs(struct thread_struct *thread)
|
static void prime_debug_regs(struct debug_reg *debug)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We could have inherited MSR_DE from userspace, since
|
* We could have inherited MSR_DE from userspace, since
|
||||||
|
@ -348,22 +348,22 @@ static void prime_debug_regs(struct thread_struct *thread)
|
||||||
*/
|
*/
|
||||||
mtmsr(mfmsr() & ~MSR_DE);
|
mtmsr(mfmsr() & ~MSR_DE);
|
||||||
|
|
||||||
mtspr(SPRN_IAC1, thread->debug.iac1);
|
mtspr(SPRN_IAC1, debug->iac1);
|
||||||
mtspr(SPRN_IAC2, thread->debug.iac2);
|
mtspr(SPRN_IAC2, debug->iac2);
|
||||||
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
|
||||||
mtspr(SPRN_IAC3, thread->debug.iac3);
|
mtspr(SPRN_IAC3, debug->iac3);
|
||||||
mtspr(SPRN_IAC4, thread->debug.iac4);
|
mtspr(SPRN_IAC4, debug->iac4);
|
||||||
#endif
|
#endif
|
||||||
mtspr(SPRN_DAC1, thread->debug.dac1);
|
mtspr(SPRN_DAC1, debug->dac1);
|
||||||
mtspr(SPRN_DAC2, thread->debug.dac2);
|
mtspr(SPRN_DAC2, debug->dac2);
|
||||||
#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
|
#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
|
||||||
mtspr(SPRN_DVC1, thread->debug.dvc1);
|
mtspr(SPRN_DVC1, debug->dvc1);
|
||||||
mtspr(SPRN_DVC2, thread->debug.dvc2);
|
mtspr(SPRN_DVC2, debug->dvc2);
|
||||||
#endif
|
#endif
|
||||||
mtspr(SPRN_DBCR0, thread->debug.dbcr0);
|
mtspr(SPRN_DBCR0, debug->dbcr0);
|
||||||
mtspr(SPRN_DBCR1, thread->debug.dbcr1);
|
mtspr(SPRN_DBCR1, debug->dbcr1);
|
||||||
#ifdef CONFIG_BOOKE
|
#ifdef CONFIG_BOOKE
|
||||||
mtspr(SPRN_DBCR2, thread->debug.dbcr2);
|
mtspr(SPRN_DBCR2, debug->dbcr2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -371,11 +371,11 @@ static void prime_debug_regs(struct thread_struct *thread)
|
||||||
* debug registers, set the debug registers from the values
|
* debug registers, set the debug registers from the values
|
||||||
* stored in the new thread.
|
* stored in the new thread.
|
||||||
*/
|
*/
|
||||||
void switch_booke_debug_regs(struct thread_struct *new_thread)
|
void switch_booke_debug_regs(struct debug_reg *new_debug)
|
||||||
{
|
{
|
||||||
if ((current->thread.debug.dbcr0 & DBCR0_IDM)
|
if ((current->thread.debug.dbcr0 & DBCR0_IDM)
|
||||||
|| (new_thread->debug.dbcr0 & DBCR0_IDM))
|
|| (new_debug->dbcr0 & DBCR0_IDM))
|
||||||
prime_debug_regs(new_thread);
|
prime_debug_regs(new_debug);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
|
EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
|
||||||
#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
|
#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
|
||||||
|
@ -683,7 +683,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
switch_booke_debug_regs(&new->thread);
|
switch_booke_debug_regs(&new->thread.debug);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
|
* For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
|
||||||
|
|
|
@ -469,11 +469,14 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||||
slb_v = vcpu->kvm->arch.vrma_slb_v;
|
slb_v = vcpu->kvm->arch.vrma_slb_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
/* Find the HPTE in the hash table */
|
/* Find the HPTE in the hash table */
|
||||||
index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v,
|
index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v,
|
||||||
HPTE_V_VALID | HPTE_V_ABSENT);
|
HPTE_V_VALID | HPTE_V_ABSENT);
|
||||||
if (index < 0)
|
if (index < 0) {
|
||||||
|
preempt_enable();
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
}
|
||||||
hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4));
|
hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4));
|
||||||
v = hptep[0] & ~HPTE_V_HVLOCK;
|
v = hptep[0] & ~HPTE_V_HVLOCK;
|
||||||
gr = kvm->arch.revmap[index].guest_rpte;
|
gr = kvm->arch.revmap[index].guest_rpte;
|
||||||
|
@ -481,6 +484,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||||
/* Unlock the HPTE */
|
/* Unlock the HPTE */
|
||||||
asm volatile("lwsync" : : : "memory");
|
asm volatile("lwsync" : : : "memory");
|
||||||
hptep[0] = v;
|
hptep[0] = v;
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
gpte->eaddr = eaddr;
|
gpte->eaddr = eaddr;
|
||||||
gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff);
|
gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff);
|
||||||
|
@ -665,6 +669,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
} else {
|
} else {
|
||||||
page = pages[0];
|
page = pages[0];
|
||||||
|
pfn = page_to_pfn(page);
|
||||||
if (PageHuge(page)) {
|
if (PageHuge(page)) {
|
||||||
page = compound_head(page);
|
page = compound_head(page);
|
||||||
pte_size <<= compound_order(page);
|
pte_size <<= compound_order(page);
|
||||||
|
@ -689,7 +694,6 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||||
}
|
}
|
||||||
rcu_read_unlock_sched();
|
rcu_read_unlock_sched();
|
||||||
}
|
}
|
||||||
pfn = page_to_pfn(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
@ -707,8 +711,14 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||||
r = (r & ~(HPTE_R_W|HPTE_R_I|HPTE_R_G)) | HPTE_R_M;
|
r = (r & ~(HPTE_R_W|HPTE_R_I|HPTE_R_G)) | HPTE_R_M;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the HPTE to point to pfn */
|
/*
|
||||||
r = (r & ~(HPTE_R_PP0 - pte_size)) | (pfn << PAGE_SHIFT);
|
* Set the HPTE to point to pfn.
|
||||||
|
* Since the pfn is at PAGE_SIZE granularity, make sure we
|
||||||
|
* don't mask out lower-order bits if psize < PAGE_SIZE.
|
||||||
|
*/
|
||||||
|
if (psize < PAGE_SIZE)
|
||||||
|
psize = PAGE_SIZE;
|
||||||
|
r = (r & ~(HPTE_R_PP0 - psize)) | ((pfn << PAGE_SHIFT) & ~(psize - 1));
|
||||||
if (hpte_is_writable(r) && !write_ok)
|
if (hpte_is_writable(r) && !write_ok)
|
||||||
r = hpte_make_readonly(r);
|
r = hpte_make_readonly(r);
|
||||||
ret = RESUME_GUEST;
|
ret = RESUME_GUEST;
|
||||||
|
|
|
@ -131,8 +131,9 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
|
||||||
static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
|
static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
|
||||||
{
|
{
|
||||||
struct kvmppc_vcore *vc = vcpu->arch.vcore;
|
struct kvmppc_vcore *vc = vcpu->arch.vcore;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock(&vcpu->arch.tbacct_lock);
|
spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
|
||||||
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE &&
|
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE &&
|
||||||
vc->preempt_tb != TB_NIL) {
|
vc->preempt_tb != TB_NIL) {
|
||||||
vc->stolen_tb += mftb() - vc->preempt_tb;
|
vc->stolen_tb += mftb() - vc->preempt_tb;
|
||||||
|
@ -143,19 +144,20 @@ static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
|
||||||
vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt;
|
vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt;
|
||||||
vcpu->arch.busy_preempt = TB_NIL;
|
vcpu->arch.busy_preempt = TB_NIL;
|
||||||
}
|
}
|
||||||
spin_unlock(&vcpu->arch.tbacct_lock);
|
spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
|
static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvmppc_vcore *vc = vcpu->arch.vcore;
|
struct kvmppc_vcore *vc = vcpu->arch.vcore;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock(&vcpu->arch.tbacct_lock);
|
spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
|
||||||
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
|
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
|
||||||
vc->preempt_tb = mftb();
|
vc->preempt_tb = mftb();
|
||||||
if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST)
|
if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST)
|
||||||
vcpu->arch.busy_preempt = mftb();
|
vcpu->arch.busy_preempt = mftb();
|
||||||
spin_unlock(&vcpu->arch.tbacct_lock);
|
spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
|
static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
|
||||||
|
@ -486,11 +488,11 @@ static u64 vcore_stolen_time(struct kvmppc_vcore *vc, u64 now)
|
||||||
*/
|
*/
|
||||||
if (vc->vcore_state != VCORE_INACTIVE &&
|
if (vc->vcore_state != VCORE_INACTIVE &&
|
||||||
vc->runner->arch.run_task != current) {
|
vc->runner->arch.run_task != current) {
|
||||||
spin_lock(&vc->runner->arch.tbacct_lock);
|
spin_lock_irq(&vc->runner->arch.tbacct_lock);
|
||||||
p = vc->stolen_tb;
|
p = vc->stolen_tb;
|
||||||
if (vc->preempt_tb != TB_NIL)
|
if (vc->preempt_tb != TB_NIL)
|
||||||
p += now - vc->preempt_tb;
|
p += now - vc->preempt_tb;
|
||||||
spin_unlock(&vc->runner->arch.tbacct_lock);
|
spin_unlock_irq(&vc->runner->arch.tbacct_lock);
|
||||||
} else {
|
} else {
|
||||||
p = vc->stolen_tb;
|
p = vc->stolen_tb;
|
||||||
}
|
}
|
||||||
|
@ -512,10 +514,10 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu,
|
||||||
core_stolen = vcore_stolen_time(vc, now);
|
core_stolen = vcore_stolen_time(vc, now);
|
||||||
stolen = core_stolen - vcpu->arch.stolen_logged;
|
stolen = core_stolen - vcpu->arch.stolen_logged;
|
||||||
vcpu->arch.stolen_logged = core_stolen;
|
vcpu->arch.stolen_logged = core_stolen;
|
||||||
spin_lock(&vcpu->arch.tbacct_lock);
|
spin_lock_irq(&vcpu->arch.tbacct_lock);
|
||||||
stolen += vcpu->arch.busy_stolen;
|
stolen += vcpu->arch.busy_stolen;
|
||||||
vcpu->arch.busy_stolen = 0;
|
vcpu->arch.busy_stolen = 0;
|
||||||
spin_unlock(&vcpu->arch.tbacct_lock);
|
spin_unlock_irq(&vcpu->arch.tbacct_lock);
|
||||||
if (!dt || !vpa)
|
if (!dt || !vpa)
|
||||||
return;
|
return;
|
||||||
memset(dt, 0, sizeof(struct dtl_entry));
|
memset(dt, 0, sizeof(struct dtl_entry));
|
||||||
|
@ -589,7 +591,9 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
|
||||||
if (list_empty(&vcpu->kvm->arch.rtas_tokens))
|
if (list_empty(&vcpu->kvm->arch.rtas_tokens))
|
||||||
return RESUME_HOST;
|
return RESUME_HOST;
|
||||||
|
|
||||||
|
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||||
rc = kvmppc_rtas_hcall(vcpu);
|
rc = kvmppc_rtas_hcall(vcpu);
|
||||||
|
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||||
|
|
||||||
if (rc == -ENOENT)
|
if (rc == -ENOENT)
|
||||||
return RESUME_HOST;
|
return RESUME_HOST;
|
||||||
|
@ -1115,13 +1119,13 @@ static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
|
||||||
|
|
||||||
if (vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
|
if (vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
|
||||||
return;
|
return;
|
||||||
spin_lock(&vcpu->arch.tbacct_lock);
|
spin_lock_irq(&vcpu->arch.tbacct_lock);
|
||||||
now = mftb();
|
now = mftb();
|
||||||
vcpu->arch.busy_stolen += vcore_stolen_time(vc, now) -
|
vcpu->arch.busy_stolen += vcore_stolen_time(vc, now) -
|
||||||
vcpu->arch.stolen_logged;
|
vcpu->arch.stolen_logged;
|
||||||
vcpu->arch.busy_preempt = now;
|
vcpu->arch.busy_preempt = now;
|
||||||
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
|
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
|
||||||
spin_unlock(&vcpu->arch.tbacct_lock);
|
spin_unlock_irq(&vcpu->arch.tbacct_lock);
|
||||||
--vc->n_runnable;
|
--vc->n_runnable;
|
||||||
list_del(&vcpu->arch.run_list);
|
list_del(&vcpu->arch.run_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,6 +225,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
|
||||||
is_io = pa & (HPTE_R_I | HPTE_R_W);
|
is_io = pa & (HPTE_R_I | HPTE_R_W);
|
||||||
pte_size = PAGE_SIZE << (pa & KVMPPC_PAGE_ORDER_MASK);
|
pte_size = PAGE_SIZE << (pa & KVMPPC_PAGE_ORDER_MASK);
|
||||||
pa &= PAGE_MASK;
|
pa &= PAGE_MASK;
|
||||||
|
pa |= gpa & ~PAGE_MASK;
|
||||||
} else {
|
} else {
|
||||||
/* Translate to host virtual address */
|
/* Translate to host virtual address */
|
||||||
hva = __gfn_to_hva_memslot(memslot, gfn);
|
hva = __gfn_to_hva_memslot(memslot, gfn);
|
||||||
|
@ -238,13 +239,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
|
||||||
ptel = hpte_make_readonly(ptel);
|
ptel = hpte_make_readonly(ptel);
|
||||||
is_io = hpte_cache_bits(pte_val(pte));
|
is_io = hpte_cache_bits(pte_val(pte));
|
||||||
pa = pte_pfn(pte) << PAGE_SHIFT;
|
pa = pte_pfn(pte) << PAGE_SHIFT;
|
||||||
|
pa |= hva & (pte_size - 1);
|
||||||
|
pa |= gpa & ~PAGE_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pte_size < psize)
|
if (pte_size < psize)
|
||||||
return H_PARAMETER;
|
return H_PARAMETER;
|
||||||
if (pa && pte_size > psize)
|
|
||||||
pa |= gpa & (pte_size - 1);
|
|
||||||
|
|
||||||
ptel &= ~(HPTE_R_PP0 - psize);
|
ptel &= ~(HPTE_R_PP0 - psize);
|
||||||
ptel |= pa;
|
ptel |= pa;
|
||||||
|
@ -749,6 +750,10 @@ static int slb_base_page_shift[4] = {
|
||||||
20, /* 1M, unsupported */
|
20, /* 1M, unsupported */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* When called from virtmode, this func should be protected by
|
||||||
|
* preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK
|
||||||
|
* can trigger deadlock issue.
|
||||||
|
*/
|
||||||
long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
|
long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
|
||||||
unsigned long valid)
|
unsigned long valid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,7 +153,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
|
||||||
|
|
||||||
13: b machine_check_fwnmi
|
13: b machine_check_fwnmi
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We come in here when wakened from nap mode on a secondary hw thread.
|
* We come in here when wakened from nap mode on a secondary hw thread.
|
||||||
* Relocation is off and most register values are lost.
|
* Relocation is off and most register values are lost.
|
||||||
|
@ -224,6 +223,11 @@ kvm_start_guest:
|
||||||
/* Clear our vcpu pointer so we don't come back in early */
|
/* Clear our vcpu pointer so we don't come back in early */
|
||||||
li r0, 0
|
li r0, 0
|
||||||
std r0, HSTATE_KVM_VCPU(r13)
|
std r0, HSTATE_KVM_VCPU(r13)
|
||||||
|
/*
|
||||||
|
* Make sure we clear HSTATE_KVM_VCPU(r13) before incrementing
|
||||||
|
* the nap_count, because once the increment to nap_count is
|
||||||
|
* visible we could be given another vcpu.
|
||||||
|
*/
|
||||||
lwsync
|
lwsync
|
||||||
/* Clear any pending IPI - we're an offline thread */
|
/* Clear any pending IPI - we're an offline thread */
|
||||||
ld r5, HSTATE_XICS_PHYS(r13)
|
ld r5, HSTATE_XICS_PHYS(r13)
|
||||||
|
@ -241,7 +245,6 @@ kvm_start_guest:
|
||||||
/* increment the nap count and then go to nap mode */
|
/* increment the nap count and then go to nap mode */
|
||||||
ld r4, HSTATE_KVM_VCORE(r13)
|
ld r4, HSTATE_KVM_VCORE(r13)
|
||||||
addi r4, r4, VCORE_NAP_COUNT
|
addi r4, r4, VCORE_NAP_COUNT
|
||||||
lwsync /* make previous updates visible */
|
|
||||||
51: lwarx r3, 0, r4
|
51: lwarx r3, 0, r4
|
||||||
addi r3, r3, 1
|
addi r3, r3, 1
|
||||||
stwcx. r3, 0, r4
|
stwcx. r3, 0, r4
|
||||||
|
@ -751,15 +754,14 @@ kvmppc_interrupt_hv:
|
||||||
* guest CR, R12 saved in shadow VCPU SCRATCH1/0
|
* guest CR, R12 saved in shadow VCPU SCRATCH1/0
|
||||||
* guest R13 saved in SPRN_SCRATCH0
|
* guest R13 saved in SPRN_SCRATCH0
|
||||||
*/
|
*/
|
||||||
/* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */
|
std r9, HSTATE_SCRATCH2(r13)
|
||||||
std r9, HSTATE_HOST_R2(r13)
|
|
||||||
|
|
||||||
lbz r9, HSTATE_IN_GUEST(r13)
|
lbz r9, HSTATE_IN_GUEST(r13)
|
||||||
cmpwi r9, KVM_GUEST_MODE_HOST_HV
|
cmpwi r9, KVM_GUEST_MODE_HOST_HV
|
||||||
beq kvmppc_bad_host_intr
|
beq kvmppc_bad_host_intr
|
||||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||||
cmpwi r9, KVM_GUEST_MODE_GUEST
|
cmpwi r9, KVM_GUEST_MODE_GUEST
|
||||||
ld r9, HSTATE_HOST_R2(r13)
|
ld r9, HSTATE_SCRATCH2(r13)
|
||||||
beq kvmppc_interrupt_pr
|
beq kvmppc_interrupt_pr
|
||||||
#endif
|
#endif
|
||||||
/* We're now back in the host but in guest MMU context */
|
/* We're now back in the host but in guest MMU context */
|
||||||
|
@ -779,7 +781,7 @@ kvmppc_interrupt_hv:
|
||||||
std r6, VCPU_GPR(R6)(r9)
|
std r6, VCPU_GPR(R6)(r9)
|
||||||
std r7, VCPU_GPR(R7)(r9)
|
std r7, VCPU_GPR(R7)(r9)
|
||||||
std r8, VCPU_GPR(R8)(r9)
|
std r8, VCPU_GPR(R8)(r9)
|
||||||
ld r0, HSTATE_HOST_R2(r13)
|
ld r0, HSTATE_SCRATCH2(r13)
|
||||||
std r0, VCPU_GPR(R9)(r9)
|
std r0, VCPU_GPR(R9)(r9)
|
||||||
std r10, VCPU_GPR(R10)(r9)
|
std r10, VCPU_GPR(R10)(r9)
|
||||||
std r11, VCPU_GPR(R11)(r9)
|
std r11, VCPU_GPR(R11)(r9)
|
||||||
|
@ -990,14 +992,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
|
||||||
*/
|
*/
|
||||||
/* Increment the threads-exiting-guest count in the 0xff00
|
/* Increment the threads-exiting-guest count in the 0xff00
|
||||||
bits of vcore->entry_exit_count */
|
bits of vcore->entry_exit_count */
|
||||||
lwsync
|
|
||||||
ld r5,HSTATE_KVM_VCORE(r13)
|
ld r5,HSTATE_KVM_VCORE(r13)
|
||||||
addi r6,r5,VCORE_ENTRY_EXIT
|
addi r6,r5,VCORE_ENTRY_EXIT
|
||||||
41: lwarx r3,0,r6
|
41: lwarx r3,0,r6
|
||||||
addi r0,r3,0x100
|
addi r0,r3,0x100
|
||||||
stwcx. r0,0,r6
|
stwcx. r0,0,r6
|
||||||
bne 41b
|
bne 41b
|
||||||
lwsync
|
isync /* order stwcx. vs. reading napping_threads */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point we have an interrupt that we have to pass
|
* At this point we have an interrupt that we have to pass
|
||||||
|
@ -1030,6 +1031,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
|
||||||
sld r0,r0,r4
|
sld r0,r0,r4
|
||||||
andc. r3,r3,r0 /* no sense IPI'ing ourselves */
|
andc. r3,r3,r0 /* no sense IPI'ing ourselves */
|
||||||
beq 43f
|
beq 43f
|
||||||
|
/* Order entry/exit update vs. IPIs */
|
||||||
|
sync
|
||||||
mulli r4,r4,PACA_SIZE /* get paca for thread 0 */
|
mulli r4,r4,PACA_SIZE /* get paca for thread 0 */
|
||||||
subf r6,r4,r13
|
subf r6,r4,r13
|
||||||
42: andi. r0,r3,1
|
42: andi. r0,r3,1
|
||||||
|
@ -1638,10 +1641,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
|
||||||
bge kvm_cede_exit
|
bge kvm_cede_exit
|
||||||
stwcx. r4,0,r6
|
stwcx. r4,0,r6
|
||||||
bne 31b
|
bne 31b
|
||||||
|
/* order napping_threads update vs testing entry_exit_count */
|
||||||
|
isync
|
||||||
li r0,1
|
li r0,1
|
||||||
stb r0,HSTATE_NAPPING(r13)
|
stb r0,HSTATE_NAPPING(r13)
|
||||||
/* order napping_threads update vs testing entry_exit_count */
|
|
||||||
lwsync
|
|
||||||
mr r4,r3
|
mr r4,r3
|
||||||
lwz r7,VCORE_ENTRY_EXIT(r5)
|
lwz r7,VCORE_ENTRY_EXIT(r5)
|
||||||
cmpwi r7,0x100
|
cmpwi r7,0x100
|
||||||
|
|
|
@ -129,29 +129,32 @@ kvm_start_lightweight:
|
||||||
* R12 = exit handler id
|
* R12 = exit handler id
|
||||||
* R13 = PACA
|
* R13 = PACA
|
||||||
* SVCPU.* = guest *
|
* SVCPU.* = guest *
|
||||||
|
* MSR.EE = 1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
PPC_LL r3, GPR4(r1) /* vcpu pointer */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kvmppc_copy_from_svcpu can clobber volatile registers, save
|
||||||
|
* the exit handler id to the vcpu and restore it from there later.
|
||||||
|
*/
|
||||||
|
stw r12, VCPU_TRAP(r3)
|
||||||
|
|
||||||
/* Transfer reg values from shadow vcpu back to vcpu struct */
|
/* Transfer reg values from shadow vcpu back to vcpu struct */
|
||||||
/* On 64-bit, interrupts are still off at this point */
|
/* On 64-bit, interrupts are still off at this point */
|
||||||
PPC_LL r3, GPR4(r1) /* vcpu pointer */
|
|
||||||
GET_SHADOW_VCPU(r4)
|
GET_SHADOW_VCPU(r4)
|
||||||
bl FUNC(kvmppc_copy_from_svcpu)
|
bl FUNC(kvmppc_copy_from_svcpu)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S_64
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
/* Re-enable interrupts */
|
|
||||||
ld r3, HSTATE_HOST_MSR(r13)
|
|
||||||
ori r3, r3, MSR_EE
|
|
||||||
MTMSR_EERI(r3)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reload kernel SPRG3 value.
|
* Reload kernel SPRG3 value.
|
||||||
* No need to save guest value as usermode can't modify SPRG3.
|
* No need to save guest value as usermode can't modify SPRG3.
|
||||||
*/
|
*/
|
||||||
ld r3, PACA_SPRG3(r13)
|
ld r3, PACA_SPRG3(r13)
|
||||||
mtspr SPRN_SPRG3, r3
|
mtspr SPRN_SPRG3, r3
|
||||||
|
|
||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||||
|
|
||||||
/* R7 = vcpu */
|
/* R7 = vcpu */
|
||||||
|
@ -177,7 +180,7 @@ kvm_start_lightweight:
|
||||||
PPC_STL r31, VCPU_GPR(R31)(r7)
|
PPC_STL r31, VCPU_GPR(R31)(r7)
|
||||||
|
|
||||||
/* Pass the exit number as 3rd argument to kvmppc_handle_exit */
|
/* Pass the exit number as 3rd argument to kvmppc_handle_exit */
|
||||||
mr r5, r12
|
lwz r5, VCPU_TRAP(r7)
|
||||||
|
|
||||||
/* Restore r3 (kvm_run) and r4 (vcpu) */
|
/* Restore r3 (kvm_run) and r4 (vcpu) */
|
||||||
REST_2GPRS(3, r1)
|
REST_2GPRS(3, r1)
|
||||||
|
|
|
@ -66,6 +66,7 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu)
|
||||||
struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
|
struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
|
||||||
memcpy(svcpu->slb, to_book3s(vcpu)->slb_shadow, sizeof(svcpu->slb));
|
memcpy(svcpu->slb, to_book3s(vcpu)->slb_shadow, sizeof(svcpu->slb));
|
||||||
svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
|
svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
|
||||||
|
svcpu->in_use = 0;
|
||||||
svcpu_put(svcpu);
|
svcpu_put(svcpu);
|
||||||
#endif
|
#endif
|
||||||
vcpu->cpu = smp_processor_id();
|
vcpu->cpu = smp_processor_id();
|
||||||
|
@ -78,6 +79,9 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PPC_BOOK3S_64
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
|
struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
|
||||||
|
if (svcpu->in_use) {
|
||||||
|
kvmppc_copy_from_svcpu(vcpu, svcpu);
|
||||||
|
}
|
||||||
memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
|
memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
|
||||||
to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
|
to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
|
||||||
svcpu_put(svcpu);
|
svcpu_put(svcpu);
|
||||||
|
@ -110,12 +114,26 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu,
|
||||||
svcpu->ctr = vcpu->arch.ctr;
|
svcpu->ctr = vcpu->arch.ctr;
|
||||||
svcpu->lr = vcpu->arch.lr;
|
svcpu->lr = vcpu->arch.lr;
|
||||||
svcpu->pc = vcpu->arch.pc;
|
svcpu->pc = vcpu->arch.pc;
|
||||||
|
svcpu->in_use = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy data touched by real-mode code from shadow vcpu back to vcpu */
|
/* Copy data touched by real-mode code from shadow vcpu back to vcpu */
|
||||||
void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
|
void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
|
||||||
struct kvmppc_book3s_shadow_vcpu *svcpu)
|
struct kvmppc_book3s_shadow_vcpu *svcpu)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* vcpu_put would just call us again because in_use hasn't
|
||||||
|
* been updated yet.
|
||||||
|
*/
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maybe we were already preempted and synced the svcpu from
|
||||||
|
* our preempt notifiers. Don't bother touching this svcpu then.
|
||||||
|
*/
|
||||||
|
if (!svcpu->in_use)
|
||||||
|
goto out;
|
||||||
|
|
||||||
vcpu->arch.gpr[0] = svcpu->gpr[0];
|
vcpu->arch.gpr[0] = svcpu->gpr[0];
|
||||||
vcpu->arch.gpr[1] = svcpu->gpr[1];
|
vcpu->arch.gpr[1] = svcpu->gpr[1];
|
||||||
vcpu->arch.gpr[2] = svcpu->gpr[2];
|
vcpu->arch.gpr[2] = svcpu->gpr[2];
|
||||||
|
@ -139,6 +157,10 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
|
||||||
vcpu->arch.fault_dar = svcpu->fault_dar;
|
vcpu->arch.fault_dar = svcpu->fault_dar;
|
||||||
vcpu->arch.fault_dsisr = svcpu->fault_dsisr;
|
vcpu->arch.fault_dsisr = svcpu->fault_dsisr;
|
||||||
vcpu->arch.last_inst = svcpu->last_inst;
|
vcpu->arch.last_inst = svcpu->last_inst;
|
||||||
|
svcpu->in_use = false;
|
||||||
|
|
||||||
|
out:
|
||||||
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
|
static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
|
||||||
|
|
|
@ -153,15 +153,11 @@ _GLOBAL(kvmppc_entry_trampoline)
|
||||||
|
|
||||||
li r6, MSR_IR | MSR_DR
|
li r6, MSR_IR | MSR_DR
|
||||||
andc r6, r5, r6 /* Clear DR and IR in MSR value */
|
andc r6, r5, r6 /* Clear DR and IR in MSR value */
|
||||||
#ifdef CONFIG_PPC_BOOK3S_32
|
|
||||||
/*
|
/*
|
||||||
* Set EE in HOST_MSR so that it's enabled when we get into our
|
* Set EE in HOST_MSR so that it's enabled when we get into our
|
||||||
* C exit handler function. On 64-bit we delay enabling
|
* C exit handler function.
|
||||||
* interrupts until we have finished transferring stuff
|
|
||||||
* to or from the PACA.
|
|
||||||
*/
|
*/
|
||||||
ori r5, r5, MSR_EE
|
ori r5, r5, MSR_EE
|
||||||
#endif
|
|
||||||
mtsrr0 r7
|
mtsrr0 r7
|
||||||
mtsrr1 r6
|
mtsrr1 r6
|
||||||
RFI
|
RFI
|
||||||
|
|
|
@ -681,7 +681,7 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
|
||||||
int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
|
int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
int ret, s;
|
int ret, s;
|
||||||
struct thread_struct thread;
|
struct debug_reg debug;
|
||||||
#ifdef CONFIG_PPC_FPU
|
#ifdef CONFIG_PPC_FPU
|
||||||
struct thread_fp_state fp;
|
struct thread_fp_state fp;
|
||||||
int fpexc_mode;
|
int fpexc_mode;
|
||||||
|
@ -723,9 +723,9 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Switch to guest debug context */
|
/* Switch to guest debug context */
|
||||||
thread.debug = vcpu->arch.shadow_dbg_reg;
|
debug = vcpu->arch.shadow_dbg_reg;
|
||||||
switch_booke_debug_regs(&thread);
|
switch_booke_debug_regs(&debug);
|
||||||
thread.debug = current->thread.debug;
|
debug = current->thread.debug;
|
||||||
current->thread.debug = vcpu->arch.shadow_dbg_reg;
|
current->thread.debug = vcpu->arch.shadow_dbg_reg;
|
||||||
|
|
||||||
kvmppc_fix_ee_before_entry();
|
kvmppc_fix_ee_before_entry();
|
||||||
|
@ -736,8 +736,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
|
||||||
We also get here with interrupts enabled. */
|
We also get here with interrupts enabled. */
|
||||||
|
|
||||||
/* Switch back to user space debug context */
|
/* Switch back to user space debug context */
|
||||||
switch_booke_debug_regs(&thread);
|
switch_booke_debug_regs(&debug);
|
||||||
current->thread.debug = thread.debug;
|
current->thread.debug = debug;
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_FPU
|
#ifdef CONFIG_PPC_FPU
|
||||||
kvmppc_save_guest_fp(vcpu);
|
kvmppc_save_guest_fp(vcpu);
|
||||||
|
|
Loading…
Reference in New Issue