Skip to content

Commit

Permalink
Merge branch 'kvm-updates/2.6.33' of git://git.kernel.org/pub/scm/vir…
Browse files Browse the repository at this point in the history
…t/kvm/kvm

* 'kvm-updates/2.6.33' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: get rid of kvm_create_vm() unused label warning on s390
  KVM: powerpc: Fix mtsrin in book3s_64 mmu
  KVM: ia64: fix build breakage due to host spinlock change
  KVM: x86: Extend KVM_SET_VCPU_EVENTS with selective updates
  KVM: LAPIC: make sure IRR bitmap is scanned after vm load
  KVM: Fix possible circular locking in kvm_vm_ioctl_assign_device()
  KVM: MMU: remove prefault from invlpg handler
  • Loading branch information
Linus Torvalds committed Dec 30, 2009
2 parents 8fa4d87 + b4329db commit b07d41b
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 34 deletions.
10 changes: 9 additions & 1 deletion Documentation/kvm/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ struct kvm_vcpu_events {
__u8 pad;
} nmi;
__u32 sipi_vector;
__u32 flags; /* must be zero */
__u32 flags;
};

4.30 KVM_SET_VCPU_EVENTS
Expand All @@ -701,6 +701,14 @@ vcpu.

See KVM_GET_VCPU_EVENTS for the data structure.

Fields that may be modified asynchronously by running VCPUs can be excluded
from the update. These fields are nmi.pending and sipi_vector. Keep the
corresponding bits in the flags field cleared to suppress overwriting the
current in-kernel state. The bits are:

KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel
KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector


5. The kvm_run structure

Expand Down
9 changes: 6 additions & 3 deletions arch/ia64/kvm/vcpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ static inline u64 __gpfn_is_io(u64 gpfn)
#define _vmm_raw_spin_lock(x) do {}while(0)
#define _vmm_raw_spin_unlock(x) do {}while(0)
#else
typedef struct {
volatile unsigned int lock;
} vmm_spinlock_t;
#define _vmm_raw_spin_lock(x) \
do { \
__u32 *ia64_spinlock_ptr = (__u32 *) (x); \
Expand All @@ -405,12 +408,12 @@ static inline u64 __gpfn_is_io(u64 gpfn)

#define _vmm_raw_spin_unlock(x) \
do { barrier(); \
((spinlock_t *)x)->raw_lock.lock = 0; } \
((vmm_spinlock_t *)x)->lock = 0; } \
while (0)
#endif

void vmm_spin_lock(spinlock_t *lock);
void vmm_spin_unlock(spinlock_t *lock);
void vmm_spin_lock(vmm_spinlock_t *lock);
void vmm_spin_unlock(vmm_spinlock_t *lock);
enum {
I_TLB = 1,
D_TLB = 2
Expand Down
4 changes: 2 additions & 2 deletions arch/ia64/kvm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ static void __exit kvm_vmm_exit(void)
return ;
}

void vmm_spin_lock(spinlock_t *lock)
void vmm_spin_lock(vmm_spinlock_t *lock)
{
_vmm_raw_spin_lock(lock);
}

void vmm_spin_unlock(spinlock_t *lock)
void vmm_spin_unlock(vmm_spinlock_t *lock)
{
_vmm_raw_spin_unlock(lock);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/kvm/vtlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void mark_pages_dirty(struct kvm_vcpu *v, u64 pte, u64 ps)
{
u64 i, dirty_pages = 1;
u64 base_gfn = (pte&_PAGE_PPN_MASK) >> PAGE_SHIFT;
spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa);
vmm_spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa);
void *dirty_bitmap = (void *)KVM_MEM_DIRTY_LOG_BASE;

dirty_pages <<= ps <= PAGE_SHIFT ? 0 : ps - PAGE_SHIFT;
Expand Down
22 changes: 21 additions & 1 deletion arch/powerpc/kvm/book3s_64_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,26 @@ static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
{
u64 rb = 0, rs = 0;

/*
* According to Book3 2.01 mtsrin is implemented as:
*
* The SLB entry specified by (RB)32:35 is loaded from register
* RS, as follows.
*
* SLBE Bit Source SLB Field
*
* 0:31 0x0000_0000 ESID-0:31
* 32:35 (RB)32:35 ESID-32:35
* 36 0b1 V
* 37:61 0x00_0000|| 0b0 VSID-0:24
* 62:88 (RS)37:63 VSID-25:51
* 89:91 (RS)33:35 Ks Kp N
* 92 (RS)36 L ((RS)36 must be 0b0)
* 93 0b0 C
*/

dprintk("KVM MMU: mtsrin(0x%x, 0x%lx)\n", srnum, value);

/* ESID = srnum */
rb |= (srnum & 0xf) << 28;
/* Set the valid bit */
Expand All @@ -400,7 +420,7 @@ static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
/* VSID = VSID */
rs |= (value & 0xfffffff) << 12;
/* flags = flags */
rs |= ((value >> 27) & 0xf) << 9;
rs |= ((value >> 28) & 0x7) << 9;

kvmppc_mmu_book3s_64_slbmte(vcpu, rs, rb);
}
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/include/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ struct kvm_reinject_control {
__u8 reserved[31];
};

/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
#define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001
#define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002

/* for KVM_GET/SET_VCPU_EVENTS */
struct kvm_vcpu_events {
struct {
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kvm/lapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
hrtimer_cancel(&apic->lapic_timer.timer);
update_divide_count(apic);
start_apic_timer(apic);
apic->irr_pending = true;
}

void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
Expand Down
18 changes: 0 additions & 18 deletions arch/x86/kvm/paging_tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
{
struct kvm_shadow_walk_iterator iterator;
pt_element_t gpte;
gpa_t pte_gpa = -1;
int level;
u64 *sptep;
int need_flush = 0;
Expand All @@ -470,10 +468,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
if (level == PT_PAGE_TABLE_LEVEL ||
((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) ||
((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) {
struct kvm_mmu_page *sp = page_header(__pa(sptep));

pte_gpa = (sp->gfn << PAGE_SHIFT);
pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);

if (is_shadow_present_pte(*sptep)) {
rmap_remove(vcpu->kvm, sptep);
Expand All @@ -492,18 +486,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
if (need_flush)
kvm_flush_remote_tlbs(vcpu->kvm);
spin_unlock(&vcpu->kvm->mmu_lock);

if (pte_gpa == -1)
return;
if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
sizeof(pt_element_t)))
return;
if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) {
if (mmu_topup_memory_caches(vcpu))
return;
kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
sizeof(pt_element_t), 0);
}
}

static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
Expand Down
12 changes: 8 additions & 4 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1913,15 +1913,17 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,

events->sipi_vector = vcpu->arch.sipi_vector;

events->flags = 0;
events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
| KVM_VCPUEVENT_VALID_SIPI_VECTOR);

vcpu_put(vcpu);
}

static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events)
{
if (events->flags)
if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING
| KVM_VCPUEVENT_VALID_SIPI_VECTOR))
return -EINVAL;

vcpu_load(vcpu);
Expand All @@ -1938,10 +1940,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
kvm_pic_clear_isr_ack(vcpu->kvm);

vcpu->arch.nmi_injected = events->nmi.injected;
vcpu->arch.nmi_pending = events->nmi.pending;
if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING)
vcpu->arch.nmi_pending = events->nmi.pending;
kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);

vcpu->arch.sipi_vector = events->sipi_vector;
if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
vcpu->arch.sipi_vector = events->sipi_vector;

vcpu_put(vcpu);

Expand Down
6 changes: 3 additions & 3 deletions virt/kvm/assigned-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *match;
struct pci_dev *dev;

down_read(&kvm->slots_lock);
mutex_lock(&kvm->lock);
down_read(&kvm->slots_lock);

match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
assigned_dev->assigned_dev_id);
Expand Down Expand Up @@ -573,8 +573,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
}

out:
mutex_unlock(&kvm->lock);
up_read(&kvm->slots_lock);
mutex_unlock(&kvm->lock);
return r;
out_list_del:
list_del(&match->list);
Expand All @@ -585,8 +585,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
pci_dev_put(dev);
out_free:
kfree(match);
mutex_unlock(&kvm->lock);
up_read(&kvm->slots_lock);
mutex_unlock(&kvm->lock);
return r;
}

Expand Down
5 changes: 4 additions & 1 deletion virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ MODULE_LICENSE("GPL");
/*
* Ordering of locks:
*
* kvm->slots_lock --> kvm->lock --> kvm->irq_lock
* kvm->lock --> kvm->slots_lock --> kvm->irq_lock
*/

DEFINE_SPINLOCK(kvm_lock);
Expand Down Expand Up @@ -406,8 +406,11 @@ static struct kvm *kvm_create_vm(void)
out:
return kvm;

#if defined(KVM_COALESCED_MMIO_PAGE_OFFSET) || \
(defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER))
out_err:
hardware_disable_all();
#endif
out_err_nodisable:
kfree(kvm);
return ERR_PTR(r);
Expand Down

0 comments on commit b07d41b

Please sign in to comment.