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:
Linus Torvalds 2017-10-06 11:28:34 -07:00
commit 8d473320ee
7 changed files with 20 additions and 13 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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: