diff options
Diffstat (limited to 'arch/mips/kvm/mips.c')
| -rw-r--r-- | arch/mips/kvm/mips.c | 121 | 
1 files changed, 44 insertions, 77 deletions
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 1109924560d8..71244bf87c3a 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -156,7 +156,7 @@ void kvm_mips_free_vcpus(struct kvm *kvm)  	struct kvm_vcpu *vcpu;  	kvm_for_each_vcpu(i, vcpu, kvm) { -		kvm_arch_vcpu_free(vcpu); +		kvm_vcpu_destroy(vcpu);  	}  	mutex_lock(&kvm->lock); @@ -280,25 +280,43 @@ static inline void dump_handler(const char *symbol, void *start, void *end)  	pr_debug("\tEND(%s)\n", symbol);  } -struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) +/* low level hrtimer wake routine */ +static enum hrtimer_restart kvm_mips_comparecount_wakeup(struct hrtimer *timer) +{ +	struct kvm_vcpu *vcpu; + +	vcpu = container_of(timer, struct kvm_vcpu, arch.comparecount_timer); + +	kvm_mips_callbacks->queue_timer_int(vcpu); + +	vcpu->arch.wait = 0; +	if (swq_has_sleeper(&vcpu->wq)) +		swake_up_one(&vcpu->wq); + +	return kvm_mips_count_timeout(vcpu); +} + +int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) +{ +	return 0; +} + +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)  {  	int err, size;  	void *gebase, *p, *handler, *refill_start, *refill_end;  	int i; -	struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL); - -	if (!vcpu) { -		err = -ENOMEM; -		goto out; -	} - -	err = kvm_vcpu_init(vcpu, kvm, id); +	kvm_debug("kvm @ %p: create cpu %d at %p\n", +		  vcpu->kvm, vcpu->vcpu_id, vcpu); +	err = kvm_mips_callbacks->vcpu_init(vcpu);  	if (err) -		goto out_free_cpu; +		return err; -	kvm_debug("kvm @ %p: create cpu %d at %p\n", kvm, id, vcpu); +	hrtimer_init(&vcpu->arch.comparecount_timer, CLOCK_MONOTONIC, +		     HRTIMER_MODE_REL); +	vcpu->arch.comparecount_timer.function = kvm_mips_comparecount_wakeup;  	/*  	 * Allocate space for host mode exception handlers that handle @@ -313,7 +331,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)  	if (!gebase) {  		err = -ENOMEM; -		goto out_uninit_cpu; +		goto out_uninit_vcpu;  	}  	kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",  		  ALIGN(size, PAGE_SIZE), gebase); @@ -392,38 +410,33 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)  	vcpu->arch.last_sched_cpu = -1;  	vcpu->arch.last_exec_cpu = -1; -	return vcpu; +	/* Initial guest state */ +	err = kvm_mips_callbacks->vcpu_setup(vcpu); +	if (err) +		goto out_free_commpage; + +	return 0; +out_free_commpage: +	kfree(vcpu->arch.kseg0_commpage);  out_free_gebase:  	kfree(gebase); - -out_uninit_cpu: -	kvm_vcpu_uninit(vcpu); - -out_free_cpu: -	kfree(vcpu); - -out: -	return ERR_PTR(err); +out_uninit_vcpu: +	kvm_mips_callbacks->vcpu_uninit(vcpu); +	return err;  } -void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) +void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)  {  	hrtimer_cancel(&vcpu->arch.comparecount_timer); -	kvm_vcpu_uninit(vcpu); -  	kvm_mips_dump_stats(vcpu);  	kvm_mmu_free_memory_caches(vcpu);  	kfree(vcpu->arch.guest_ebase);  	kfree(vcpu->arch.kseg0_commpage); -	kfree(vcpu); -} -void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) -{ -	kvm_arch_vcpu_free(vcpu); +	kvm_mips_callbacks->vcpu_uninit(vcpu);  }  int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, @@ -1212,58 +1225,12 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)  	return 0;  } -static void kvm_mips_comparecount_func(unsigned long data) -{ -	struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; - -	kvm_mips_callbacks->queue_timer_int(vcpu); - -	vcpu->arch.wait = 0; -	if (swq_has_sleeper(&vcpu->wq)) -		swake_up_one(&vcpu->wq); -} - -/* low level hrtimer wake routine */ -static enum hrtimer_restart kvm_mips_comparecount_wakeup(struct hrtimer *timer) -{ -	struct kvm_vcpu *vcpu; - -	vcpu = container_of(timer, struct kvm_vcpu, arch.comparecount_timer); -	kvm_mips_comparecount_func((unsigned long) vcpu); -	return kvm_mips_count_timeout(vcpu); -} - -int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) -{ -	int err; - -	err = kvm_mips_callbacks->vcpu_init(vcpu); -	if (err) -		return err; - -	hrtimer_init(&vcpu->arch.comparecount_timer, CLOCK_MONOTONIC, -		     HRTIMER_MODE_REL); -	vcpu->arch.comparecount_timer.function = kvm_mips_comparecount_wakeup; -	return 0; -} - -void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) -{ -	kvm_mips_callbacks->vcpu_uninit(vcpu); -} -  int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,  				  struct kvm_translation *tr)  {  	return 0;  } -/* Initial guest state */ -int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) -{ -	return kvm_mips_callbacks->vcpu_setup(vcpu); -} -  static void kvm_mips_set_c0_status(void)  {  	u32 status = read_c0_status();  |