All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Ingo Molnar <mingo-X9Un+BFzKDI@public.gmane.org>
Cc: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: Re: [patch] KVM: add MSR based hypercall API
Date: Tue, 09 Jan 2007 11:58:48 +0200	[thread overview]
Message-ID: <45A36758.1000808@qumranet.com> (raw)
In-Reply-To: <20070109092705.GA8300-X9Un+BFzKDI@public.gmane.org>

Ingo Molnar wrote:
> Subject: [patch] KVM: add MSR based hypercall API
> From: Ingo Molnar <mingo-X9Un+BFzKDI@public.gmane.org>
>
> this adds a special MSR based hypercall API to KVM. This is to be used 
> by paravirtual kernels and virtual drivers.
>
> VMX-only at the moment.
>
> Signed-off-by: Ingo Molnar <mingo-X9Un+BFzKDI@public.gmane.org>
> ---
>  drivers/kvm/kvm.h        |    5 +++
>  drivers/kvm/mmu.c        |    1 
>  drivers/kvm/vmx.c        |   74 +++++++++++++++++++++++++++++++++++++++++++++--
>  include/linux/kvm_para.h |   64 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 142 insertions(+), 2 deletions(-)
>
> Index: linux/drivers/kvm/kvm.h
> ===================================================================
> --- linux.orig/drivers/kvm/kvm.h
> +++ linux/drivers/kvm/kvm.h
> @@ -14,6 +14,7 @@
>  
>  #include "vmx.h"
>  #include <linux/kvm.h>
> +#include <linux/kvm_para.h>
>  
>  #define CR0_PE_MASK (1ULL << 0)
>  #define CR0_TS_MASK (1ULL << 3)
> @@ -237,6 +238,8 @@ struct kvm_vcpu {
>  	unsigned long cr0;
>  	unsigned long cr2;
>  	unsigned long cr3;
> +	struct kvm_vcpu_para_state *para_state;
>   
Do we want this as part of kvm_vcpu or kvm?  I can see arguments for 
both views.

> +	hpa_t vm_syscall_hpa;
>   

This should be a gpa so it can be migrated, and so we can support guest 
paging.  Should also be named hypercall to avoid confusion with the 
syscall protocol.


> Index: linux/drivers/kvm/vmx.c
> ===================================================================
> --- linux.orig/drivers/kvm/vmx.c
> +++ linux/drivers/kvm/vmx.c
> @@ -406,10 +406,15 @@ static int vmx_set_msr(struct kvm_vcpu *
>  	case MSR_IA32_SYSENTER_ESP:
>  		vmcs_write32(GUEST_SYSENTER_ESP, data);
>  		break;
> -	case MSR_IA32_TIME_STAMP_COUNTER: {
> +	case MSR_IA32_TIME_STAMP_COUNTER:
>  		guest_write_tsc(data);
>  		break;
> -	}
> +	/*
> +	 * This is the 'probe whether the host is KVM' logic:
> +	 */
> +	case MSR_KVM_API_MAGIC:
> +		return vcpu_register_para(vcpu, data);
> +
>   

Why not move this to kvm_set_msr_common()?  That will get svm support 
for free.

>  	default:
>  		msr = find_msr_entry(vcpu, msr_index);
>  		if (msr) {
> @@ -1448,6 +1453,71 @@ static int handle_io(struct kvm_vcpu *vc
>  	return 0;
>  }
>  
> +/*
> + * Register the para guest with the host:
> + */
> +int vcpu_register_para(struct kvm_vcpu *vcpu, gpa_t para_state_gpa)
> +{
> +	struct kvm_vcpu_para_state *para_state;
> +	hpa_t para_state_hpa, vm_syscall_hpa;
> +	unsigned char *vm_syscall;
> +
> +	printk("KVM: guest trying to enter paravirtual mode\n");
> +	printk(".... para_state_gpa: %08Lx\n", para_state_gpa);
> +
> +	/*
> +	 * Needs to be page aligned:
> +	 */
> +	if (para_state_gpa != PAGE_ALIGN(para_state_gpa))
> +		goto err_gp;
> +
> +	para_state_hpa = gpa_to_hpa(vcpu, para_state_gpa);
> +	printk(".... para_state_hpa: %08Lx\n", para_state_hpa);
> +	if (is_error_hpa(para_state_hpa))
> +		goto err_gp;
> +
> +	para_state = (void *)__va(para_state_hpa);
> +	printk(".... para_state_hva: %p\n", para_state);
> +
> +	printk("....  guest version: %d\n", para_state->guest_version);
> +	printk("....           size: %d\n", para_state->size);
> +
> +	para_state->host_version = KVM_PARA_API_VERSION;
> +	/*
> +	 * We cannot support guests that try to register themselves
> +	 * with a newer API version than the host supports:
> +	 */
> +	if (para_state->guest_version > KVM_PARA_API_VERSION) {
> +		para_state->ret = -EINVAL;
>   

EINVAL may be different or nonexistent on the guest.  We need to define 
kvm-specific error codes.

> +		goto err_skip;
> +	}
> +
> +	vm_syscall_hpa = gpa_to_hpa(vcpu, para_state->vm_syscall_addr);
> +	printk(".... vm_syscall_hpa: %08Lx\n", vm_syscall_hpa);
> +	if (is_error_hpa(vm_syscall_hpa)) {
> +		para_state->ret = -EINVAL;
> +		goto err_skip;
> +	}
> +
> +	printk("KVM: para guest successfully registered.\n");
> +	vcpu->para_state = para_state;
> +	vcpu->vm_syscall_hpa = vm_syscall_hpa;
> +
> +	vm_syscall = __va(vm_syscall_hpa);
>   

kmap() is needed here (guest pages are not GFP_KERNEL).

> +	/*
> +	 * Patch in the VMCALL instruction:
> +	 */
> +	vm_syscall[0] = 0x0f;
> +	vm_syscall[1] = 0x01;
> +	vm_syscall[2] = 0xc1;
>   

This should be an arch op, and the rest of the function moved to kvm_main.c.

> +
> +	para_state->ret = 0;
> +err_skip:
> +	return 0;
> +err_gp:
> +	return 1;
> +}
> +
>  static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
>  {
>  	u64 exit_qualification;
> Index: linux/include/linux/kvm_para.h
> ===================================================================
> --- /dev/null
> +++ linux/include/linux/kvm_para.h
> @@ -0,0 +1,64 @@
> +#ifndef __LINUX_KVM_PARA_H
> +#define __LINUX_KVM_PARA_H
> +
> +/*
> + * Guest OS interface for KVM paravirtualization
> + *
> + * Note: this interface is considered experimental and may change without
> + *       notice.
> + */
> +
> +#define KVM_CR3_CACHE_SIZE	4
> +
> +struct kvm_cr3_cache_entry {
> +	u64 guest_cr3;
> +	u64 host_cr3;
> +};
> +
> +struct kvm_cr3_cache {
> +	struct kvm_cr3_cache_entry entry[KVM_CR3_CACHE_SIZE];
> +	u32 max_idx;
> +};
>   

This will require an api version bump whenever KVM_CR3_CACHE_SIZE changes.

Better to advertise the gpa of the cache, so it can be unlimited.

> +
> +/*
> + * Per-VCPU descriptor area shared between guest and host. Writable to
> + * both guest and host. Registered with the host by the guest when
> + * a guest acknowledges paravirtual mode.
> + */
> +struct kvm_vcpu_para_state {
> +	/*
> +	 * API version information for compatibility. If there's any support
> +	 * mismatch (too old host trying to execute too new guest) then
> +	 * the host will deny entry into paravirtual mode. Any other
> +	 * combination (new host + old guest and new host + new guest)
> +	 * is supposed to work - new host versions will support all old
> +	 * guest API versions.
> +	 */
> +	u32 guest_version;
> +	u32 host_version;
> +	u32 size;
> +	u32 ret;
> +
> +	/*
> +	 * The address of the vm exit instruction (VMCALL or VMMCALL),
> +	 * which the host will patch according to the CPU model the
> +	 * VM runs on:
> +	 */
> +	u64 vm_syscall_addr;
>   

Please rename to hypercall, and make it explicit that it is not a 
virtual address.

> +
> +	struct kvm_cr3_cache cr3_cache;
> +
> +} __attribute__ ((aligned(PAGE_SIZE)));
>   

Perhaps packed too, to avoid 32/64 ambiguity.  Or even better, pad it 
explicitly to avoid unaligned fields.

> +
> +#define KVM_PARA_API_VERSION 1
> +
> +/*
> + * This is used for an RDMSR's ECX parameter to probe for a KVM host.
> + * Hopefully no CPU vendor will use up this number. This is placed well
> + * out of way of the typical space occupied by CPU vendors' MSR indices,
> + * and we think (or at least hope) it wont be occupied in the future
> + * either.
> + */
> +#define MSR_KVM_API_MAGIC 0x87655678
> +
> +#endif
>   


-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

  parent reply	other threads:[~2007-01-09  9:58 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-09  9:27 [patch] KVM: add MSR based hypercall API Ingo Molnar
     [not found] ` <20070109092705.GA8300-X9Un+BFzKDI@public.gmane.org>
2007-01-09  9:58   ` Avi Kivity [this message]
     [not found]     ` <45A36758.1000808-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 10:38       ` Ingo Molnar
     [not found]         ` <20070109103809.GA24515-X9Un+BFzKDI@public.gmane.org>
2007-01-09 11:24           ` Avi Kivity
     [not found]             ` <45A37B7A.8020709-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 11:36               ` Ingo Molnar
     [not found]                 ` <20070109113628.GA4421-X9Un+BFzKDI@public.gmane.org>
2007-01-09 12:54                   ` Avi Kivity
     [not found]                     ` <45A39095.80005-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 13:17                       ` Ingo Molnar
     [not found]                         ` <20070109131733.GA28431-X9Un+BFzKDI@public.gmane.org>
2007-01-09 13:30                           ` Ingo Molnar
2007-01-09 13:41                           ` Avi Kivity
     [not found]                             ` <45A39B90.6070908-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 13:53                               ` Ingo Molnar
     [not found]                                 ` <20070109135318.GA3084-X9Un+BFzKDI@public.gmane.org>
2007-01-09 14:08                                   ` Avi Kivity
     [not found]                                     ` <45A3A1C6.201-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 14:22                                       ` Ingo Molnar
     [not found]                                         ` <20070109142203.GA6645-X9Un+BFzKDI@public.gmane.org>
2007-01-09 14:35                                           ` Avi Kivity
     [not found]                                             ` <45A3A816.6010308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 14:38                                               ` Ingo Molnar
     [not found]                                                 ` <20070109143832.GA10735-X9Un+BFzKDI@public.gmane.org>
2007-01-09 14:44                                                   ` Ingo Molnar
     [not found]                                                     ` <20070109144434.GA12152-X9Un+BFzKDI@public.gmane.org>
2007-01-09 14:50                                                       ` Avi Kivity
     [not found]                                                         ` <45A3ABAF.90208-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-01-09 15:04                                                           ` Ingo Molnar
     [not found]                                                             ` <20070109150424.GA16535-X9Un+BFzKDI@public.gmane.org>
2007-01-09 16:20                                                               ` [patchset] KVM: paravirt/hypercall queue Ingo Molnar
     [not found]                                                                 ` <20070109162028.GA764-X9Un+BFzKDI@public.gmane.org>
2007-01-09 16:23                                                                   ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45A36758.1000808@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=mingo-X9Un+BFzKDI@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.