KVM fixes for v4.14-rc4
- fix PPC XIVE interrupt delivery - fix x86 RCU breakage from asynchronous page faults when built without PREEMPT_COUNT - fix x86 build with -frecord-gcc-switches - fix x86 build without X86_LOCAL_APIC -----BEGIN PGP SIGNATURE----- iQEcBAABCAAGBQJZ18AmAAoJEED/6hsPKofoPEwH+waDVIeS+s38G8HkiB8PoVww bAhAV6Aj3muOI49KtwBt+qyC8nOQHpwPCNqjmagOv1GEYSwJ4gKKoJ6Xl9rOsxau GT0xDgVDbrzIb/PTFL+7bDjsyMxf89utIfoBL8i37uznzB35+QFlvy4mLgKntAh0 1/tYDzgrQxuxH5RF4DbFstoPFjw1kdxpXRzHdngsV13bS87PAG9j7A0l7orLtXZg qxlTh2SvCSr4B0hOZGG/Pc0aIAxLh8kRD6NaU05raKgzQLJa5sxJ0Yr+RbskfqQb 7B98X1Ygb1BjBOFxy+Je5IamKt4ICTY1B0v1ivs0qZ+mgxG59FWuQlR0pww/8Ug= =ay5S -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm Pull KVM fixes from Radim Krčmář: - fix PPC XIVE interrupt delivery - fix x86 RCU breakage from asynchronous page faults when built without PREEMPT_COUNT - fix x86 build with -frecord-gcc-switches - fix x86 build without X86_LOCAL_APIC * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: add X86_LOCAL_APIC dependency x86/kvm: Move kvm_fastop_exception to .fixup section kvm/x86: Avoid async PF preempting the kernel incorrectly KVM: PPC: Book3S: Fix server always zero from kvmppc_xive_get_xive()
This commit is contained in:
commit
8d473320ee
|
@ -622,7 +622,7 @@ int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
state = &sb->irq_state[idx];
|
state = &sb->irq_state[idx];
|
||||||
arch_spin_lock(&sb->lock);
|
arch_spin_lock(&sb->lock);
|
||||||
*server = state->guest_server;
|
*server = state->act_server;
|
||||||
*priority = state->guest_priority;
|
*priority = state->guest_priority;
|
||||||
arch_spin_unlock(&sb->lock);
|
arch_spin_unlock(&sb->lock);
|
||||||
|
|
||||||
|
@ -1331,7 +1331,7 @@ static int xive_get_source(struct kvmppc_xive *xive, long irq, u64 addr)
|
||||||
xive->saved_src_count++;
|
xive->saved_src_count++;
|
||||||
|
|
||||||
/* Convert saved state into something compatible with xics */
|
/* Convert saved state into something compatible with xics */
|
||||||
val = state->guest_server;
|
val = state->act_server;
|
||||||
prio = state->saved_scan_prio;
|
prio = state->saved_scan_prio;
|
||||||
|
|
||||||
if (prio == MASKED) {
|
if (prio == MASKED) {
|
||||||
|
@ -1507,7 +1507,6 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr)
|
||||||
/* First convert prio and mark interrupt as untargetted */
|
/* First convert prio and mark interrupt as untargetted */
|
||||||
act_prio = xive_prio_from_guest(guest_prio);
|
act_prio = xive_prio_from_guest(guest_prio);
|
||||||
state->act_priority = MASKED;
|
state->act_priority = MASKED;
|
||||||
state->guest_server = server;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to drop the lock due to the mutex below. Hopefully
|
* We need to drop the lock due to the mutex below. Hopefully
|
||||||
|
|
|
@ -35,7 +35,6 @@ struct kvmppc_xive_irq_state {
|
||||||
struct xive_irq_data *pt_data; /* XIVE Pass-through associated data */
|
struct xive_irq_data *pt_data; /* XIVE Pass-through associated data */
|
||||||
|
|
||||||
/* Targetting as set by guest */
|
/* Targetting as set by guest */
|
||||||
u32 guest_server; /* Current guest selected target */
|
|
||||||
u8 guest_priority; /* Guest set priority */
|
u8 guest_priority; /* Guest set priority */
|
||||||
u8 saved_priority; /* Saved priority when masking */
|
u8 saved_priority; /* Saved priority when masking */
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
|
||||||
bool kvm_para_available(void);
|
bool kvm_para_available(void);
|
||||||
unsigned int kvm_arch_para_features(void);
|
unsigned int kvm_arch_para_features(void);
|
||||||
void __init kvm_guest_init(void);
|
void __init kvm_guest_init(void);
|
||||||
void kvm_async_pf_task_wait(u32 token);
|
void kvm_async_pf_task_wait(u32 token, int interrupt_kernel);
|
||||||
void kvm_async_pf_task_wake(u32 token);
|
void kvm_async_pf_task_wake(u32 token);
|
||||||
u32 kvm_read_and_reset_pf_reason(void);
|
u32 kvm_read_and_reset_pf_reason(void);
|
||||||
extern void kvm_disable_steal_time(void);
|
extern void kvm_disable_steal_time(void);
|
||||||
|
@ -103,7 +103,7 @@ static inline void kvm_spinlock_init(void)
|
||||||
|
|
||||||
#else /* CONFIG_KVM_GUEST */
|
#else /* CONFIG_KVM_GUEST */
|
||||||
#define kvm_guest_init() do {} while (0)
|
#define kvm_guest_init() do {} while (0)
|
||||||
#define kvm_async_pf_task_wait(T) do {} while(0)
|
#define kvm_async_pf_task_wait(T, I) do {} while(0)
|
||||||
#define kvm_async_pf_task_wake(T) do {} while(0)
|
#define kvm_async_pf_task_wake(T) do {} while(0)
|
||||||
|
|
||||||
static inline bool kvm_para_available(void)
|
static inline bool kvm_para_available(void)
|
||||||
|
|
|
@ -117,7 +117,11 @@ static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_async_pf_task_wait(u32 token)
|
/*
|
||||||
|
* @interrupt_kernel: Is this called from a routine which interrupts the kernel
|
||||||
|
* (other than user space)?
|
||||||
|
*/
|
||||||
|
void kvm_async_pf_task_wait(u32 token, int interrupt_kernel)
|
||||||
{
|
{
|
||||||
u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
|
u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
|
||||||
struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
|
struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
|
||||||
|
@ -140,8 +144,10 @@ void kvm_async_pf_task_wait(u32 token)
|
||||||
|
|
||||||
n.token = token;
|
n.token = token;
|
||||||
n.cpu = smp_processor_id();
|
n.cpu = smp_processor_id();
|
||||||
n.halted = is_idle_task(current) || preempt_count() > 1 ||
|
n.halted = is_idle_task(current) ||
|
||||||
rcu_preempt_depth();
|
(IS_ENABLED(CONFIG_PREEMPT_COUNT)
|
||||||
|
? preempt_count() > 1 || rcu_preempt_depth()
|
||||||
|
: interrupt_kernel);
|
||||||
init_swait_queue_head(&n.wq);
|
init_swait_queue_head(&n.wq);
|
||||||
hlist_add_head(&n.link, &b->list);
|
hlist_add_head(&n.link, &b->list);
|
||||||
raw_spin_unlock(&b->lock);
|
raw_spin_unlock(&b->lock);
|
||||||
|
@ -269,7 +275,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||||
case KVM_PV_REASON_PAGE_NOT_PRESENT:
|
case KVM_PV_REASON_PAGE_NOT_PRESENT:
|
||||||
/* page is swapped out by the host. */
|
/* page is swapped out by the host. */
|
||||||
prev_state = exception_enter();
|
prev_state = exception_enter();
|
||||||
kvm_async_pf_task_wait((u32)read_cr2());
|
kvm_async_pf_task_wait((u32)read_cr2(), !user_mode(regs));
|
||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
break;
|
break;
|
||||||
case KVM_PV_REASON_PAGE_READY:
|
case KVM_PV_REASON_PAGE_READY:
|
||||||
|
|
|
@ -23,6 +23,7 @@ config KVM
|
||||||
depends on HIGH_RES_TIMERS
|
depends on HIGH_RES_TIMERS
|
||||||
# for TASKSTATS/TASK_DELAY_ACCT:
|
# for TASKSTATS/TASK_DELAY_ACCT:
|
||||||
depends on NET && MULTIUSER
|
depends on NET && MULTIUSER
|
||||||
|
depends on X86_LOCAL_APIC
|
||||||
select PREEMPT_NOTIFIERS
|
select PREEMPT_NOTIFIERS
|
||||||
select MMU_NOTIFIER
|
select MMU_NOTIFIER
|
||||||
select ANON_INODES
|
select ANON_INODES
|
||||||
|
|
|
@ -425,8 +425,10 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *));
|
||||||
#op " %al \n\t" \
|
#op " %al \n\t" \
|
||||||
FOP_RET
|
FOP_RET
|
||||||
|
|
||||||
asm(".global kvm_fastop_exception \n"
|
asm(".pushsection .fixup, \"ax\"\n"
|
||||||
"kvm_fastop_exception: xor %esi, %esi; ret");
|
".global kvm_fastop_exception \n"
|
||||||
|
"kvm_fastop_exception: xor %esi, %esi; ret\n"
|
||||||
|
".popsection");
|
||||||
|
|
||||||
FOP_START(setcc)
|
FOP_START(setcc)
|
||||||
FOP_SETCC(seto)
|
FOP_SETCC(seto)
|
||||||
|
|
|
@ -3837,7 +3837,7 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code,
|
||||||
case KVM_PV_REASON_PAGE_NOT_PRESENT:
|
case KVM_PV_REASON_PAGE_NOT_PRESENT:
|
||||||
vcpu->arch.apf.host_apf_reason = 0;
|
vcpu->arch.apf.host_apf_reason = 0;
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
kvm_async_pf_task_wait(fault_address);
|
kvm_async_pf_task_wait(fault_address, 0);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
break;
|
break;
|
||||||
case KVM_PV_REASON_PAGE_READY:
|
case KVM_PV_REASON_PAGE_READY:
|
||||||
|
|
Loading…
Reference in New Issue