public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: "Dong, Eddie" <eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: apic+ioapiuc patch
Date: Fri, 13 Jul 2007 15:51:25 +0300	[thread overview]
Message-ID: <4697754D.7000003@qumranet.com> (raw)
In-Reply-To: <10EA09EFD8728347A513008B6B0DA77A01C2514E-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>

Dong, Eddie wrote:
> Avi:
> 	Per our discussion, we will only support all user level irqchip
> or all kernel level irqchip.  
> Here is the patch against lapic2 that passed RHEL5U test. Please give
> comments.
>
>
> thx,eddie
>
>   

General comments:

 - please split into a hlt patch, lapic patch, and ioapic patch.  the
last patch can enable the irqchip capability, but intermediate results
have to be compilable.
 - document files that were taken from Xen or qemu; specify what
revision was used as base


More comments below.

>
>
>
> diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
> index 952dff3..b29651b 100644
> --- a/drivers/kvm/Makefile
> +++ b/drivers/kvm/Makefile
> @@ -2,7 +2,7 @@
>  # Makefile for Kernel-based Virtual Machine module
>  #
>  
> -kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o
> +kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o kvm_irq.o lapic.o
> ioapic.o
>   

irq.c was renamed to kvm_irq.c? why?

> +
> +static void ioapic_inj_irq(struct kvm_ioapic *ioapic,
> +			   struct kvm_lapic *target,
> +			   u8 vector, u8 trig_mode, u8 delivery_mode)
> +{
> +	ioapic_debug("irq %d trig %d deliv %d", vector, trig_mode,
> +		     delivery_mode);
> +
> +	ASSERT((delivery_mode == dest_Fixed) ||
> +	       (delivery_mode == dest_LowestPrio));
> +
> +	if (kvm_apic_set_irq(target, vector, trig_mode))
> +		kvm_vcpu_kick(target->vcpu);
> +}
>   

Put kvm_vcpu_kick() into kvm_apic_set_irq() so that callers need not do
that themselves.

> +
> +	switch (delivery_mode) {
> +	case dest_LowestPrio:
>   

Wierd constant.  How about IOAPIC_DEST_LOWEST_PRIO?

> +		target =
> +		    kvm_apic_round_robin(ioapic->kvm, vector,
> deliver_bitmask);
> +		if (target != NULL) {
> +			ioapic_inj_irq(ioapic, target, vector,
> +				       trig_mode, delivery_mode);
> +		} else {
> +			ioapic_debug("null round robin: "
> +				     "mask=%x vector=%x
> delivery_mode=%x",
> +				     deliver_bitmask, vector,
> dest_LowestPrio);
> +		}
>   

Unnecessary {}.

> +
> +static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector)
> +{
> +	int i;
> +
> +	for (i = 0; i < IOAPIC_NUM_PINS; i++)
> +		if (ioapic->redirtbl[i].fields.vector == vector)
> +			return i;
> +
> +	return -1;
> +}
>   

blank line.

> +void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
> +{
> +	struct kvm_ioapic *ioapic = kvm->vioapic;
> +	union ioapic_redir_entry *ent;
> +	int gsi;
> +
> +	gsi = get_eoi_gsi(ioapic, vector);
> +	if (gsi == -1) {
> +		printk(KERN_WARNING "Can't find redir item for %d
> EOI\n",
> +		       vector);
> +		return;
> +	}
> +
> +	ent = &ioapic->redirtbl[gsi];
> +	ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
> +
> +	ent->fields.remote_irr = 0;
> +	if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) {
> +		ioapic_deliver(ioapic, gsi);
> +	}
>   

excess braces.


> +
> +}
> +
> +static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
> +{
> +	struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
> +
> +	return ((addr >= ioapic->base_address &&
> +		 (addr < ioapic->base_address + IOAPIC_MEM_LENGTH)));
> +}
> +
> +static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr,
> int len,
> +			     void *val)
> +{
> +	struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
> +	u32 result;
> +
> +	ioapic_debug("addr %lx", (unsigned long)addr);
> +	ASSERT(!(addr & 0xf));	/* check alignment */
> +
> +	addr &= 0xff;
> +
> +	switch (addr) {
> +	case IOAPIC_REG_SELECT:
> +		result = ioapic->ioregsel;
> +		break;
> +
> +	case IOAPIC_REG_WINDOW:
> +		result = ioapic_read_indirect(ioapic, addr, len);
> +		break;
> +
> +	default:
> +		result = 0;
> +		break;
> +	}
> +	switch (len) {
> +	case 1:
> +	case 2:
> +	case 4:
> +	case 8:
> +		memcpy(val, (char *)&result, len);
>   

If len == 8, you're copying a bit of kernel stack into the guest.  While
it's hardly a security hole, we'd better not do that.

> +static void vcpu_kick_intr(void *info)
> +{
> +#ifdef DEBUG
> +	struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
> +	printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
> +#endif
> +}
> +
> +void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
> +{
> +	int ipi_pcpu = vcpu->cpu;
> +
> +	if (vcpu->guest_mode)
> +		smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu,
> 0, 0);
> +}
>   

What if it's in hlt state?

> +
> diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
> index a6b3869..4b1b4b7 100644
> --- a/drivers/kvm/irq.h
> +++ b/drivers/kvm/irq.h
> @@ -26,12 +26,11 @@
>  
>  typedef void irq_request_func(void *opaque, int level);
>  
> -struct kvm_pic;
>  struct kvm_pic_state {
> -	u8 last_irr;	/* edge detection */
> -	u8 irr;		/* interrupt request register */
> -	u8 imr;		/* interrupt mask register */
> -	u8 isr;		/* interrupt service register */
> +	u8 last_irr;		/* edge detection */
> +	u8 irr;			/* interrupt request register */
> +	u8 imr;			/* interrupt mask register */
> +	u8 isr;			/* interrupt service register */
>  	u8 priority_add;	/* highest irq priority */
>  	u8 irq_base;
>  	u8 read_reg_select;
> @@ -48,7 +47,7 @@ struct kvm_pic_state {
>  };
>  
>  struct kvm_pic {
> -	struct kvm_pic_state pics[2]; /* 0 is master pic, 1 is slave pic
> */
> +	struct kvm_pic_state pics[2];	/* 0 is master pic, 1 is slave
> pic */
>  	irq_request_func *irq_request;
>  	void *irq_request_opaque;
>  	int output;		/* intr from master PIC */
>   

Please separate the pic changes so I can fold them into the existing pic
patch.

> +
> +struct kvm_ioapic {
> +	struct kvm_io_device dev;
> +	unsigned long base_address;
> +	struct kvm *kvm;
> +	u32 ioregsel;
> +	u32 id;
> +	u32 irr;
> +	union ioapic_redir_entry {
> +		u64 bits;
> +		struct {
> +			u8 vector;
> +			u8 delivery_mode:3;
> +			u8 dest_mode:1;
> +			u8 delivery_status:1;
> +			u8 polarity:1;
> +			u8 remote_irr:1;
> +			u8 trig_mode:1;
> +			u8 mask:1;
> +			u8 reserve:7;
> +			u8 reserved[4];
> +			u8 dest_id;
> +		} fields;
> +	} redirtbl[IOAPIC_NUM_PINS];
> +};
>   

Which lock protects this?

> +
> +struct kvm_lapic {
> +	spinlock_t lock;	/* TODO: need? */
>   

I think not.  Maybe when we have msi support?

> +
> +#ifdef DEBUG
> +#define ASSERT(x)
> \
> +	if (!(x)) {
> \
> +		printk(KERN_EMERG "assertion failed %s: %d: %s\n",
> \
> +		       __FILE__, __LINE__, #x);
> \
> +		BUG();
> \
> +	}
>   

Wrap in a do { } while (0) to avoid surprises.


>  #endif
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> index f1a6773..a886ba9 100644
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -334,15 +334,13 @@ struct kvm_vcpu {
>  	};
>  	struct mutex mutex;
>  	int   cpu;
> -	int   launched;
> +	char  vcpu_id;
>   

There is already a vcpu_id in kvm.git...

> +	char  launched;
>   


???

>  
> +unsigned long get_cr8(struct kvm_vcpu *vcpu)
> +{
> +	if (irqchip_in_kernel(vcpu->kvm))
> +		return kvm_lapic_get_cr8(vcpu);
> +	else
> +		return vcpu->cr8;
> +}
> +EXPORT_SYMBOL_GPL(get_cr8);
>   

How about keep vcpu->cr8 even with kernel lapic?  then we don't need this.

> +
> +u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
> +{
> +	if (irqchip_in_kernel(vcpu->kvm))
> +		return vcpu->apic->base_msr;
> +	else
> +		return vcpu->apic_base;
> +}
> +EXPORT_SYMBOL_GPL(kvm_get_apic_base);
>   

ditto.

> +
> +#define VEC_POS(v) ((v) & (32 - 1))
> +#define REG_POS(v) (((v) >> 5) << 4)
> +#define apic_test_and_set_vector(vec, bitmap)                 \
> +    test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
> +#define apic_test_and_clear_vector(vec, bitmap)               \
> +    test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
> +#define apic_set_vector(vec, bitmap)                          \
> +    set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
> +#define apic_clear_vector(vec, bitmap)                        \
> +    clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
> +
> +#define apic_hw_enabled(apic)	((apic)->base_msr &
> MSR_IA32_APICBASE_ENABLE)
> +#define apic_sw_enabled(apic)	(!((apic)->status & APIC_SW_DISABLE))
> +#define apic_enabled(apic)	(apic_sw_enabled(apic) &&	\
> +	apic_hw_enabled(apic))
>   

These would be better as inline functions (type checking, etc.)

> +
> +#define KVM_APIC_ID(apic)	\
> +	(GET_APIC_ID(apic_get_reg(apic, APIC_ID)))
> +
> +#define apic_lvt_enabled(apic, lvt_type)	\
> +	(!(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED))
> +
> +#define apic_lvt_vector(apic, lvt_type)		\
> +	(apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK)
> +
> +#define apic_lvt_dm(apic, lvt_type)	\
> +	(apic_get_reg(apic, lvt_type) & APIC_MODE_MASK)
> +
> +#define apic_lvtt_period(apic)	\
> +	(apic_get_reg(apic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC)
>   

more functions


Where are the state save/restore?  they can be added later, so long as
the capability is enabled only after everything is working.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

  parent reply	other threads:[~2007-07-13 12:51 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-13  9:29 apic+ioapiuc patch Dong, Eddie
     [not found] ` <10EA09EFD8728347A513008B6B0DA77A01C2514E-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-13 12:51   ` Avi Kivity [this message]
     [not found]     ` <4697754D.7000003-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-17  3:37       ` Dong, Eddie
     [not found]         ` <10EA09EFD8728347A513008B6B0DA77A01C7272B-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-17  6:46           ` Dor Laor
     [not found]             ` <64F9B87B6B770947A9F8391472E032160CC162E8-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
2007-07-17  7:36               ` Dong, Eddie
     [not found]                 ` <10EA09EFD8728347A513008B6B0DA77A01C72915-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-17  8:04                   ` Avi Kivity
2007-07-17  8:03           ` Avi Kivity
     [not found]             ` <469C77D1.6010003-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-17 15:15               ` Dong, Eddie
     [not found]                 ` <10EA09EFD8728347A513008B6B0DA77A01C72AAE-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18  2:24                   ` Dong, Eddie
     [not found]                     ` <10EA09EFD8728347A513008B6B0DA77A01C72CD4-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18  9:01                       ` Avi Kivity
2007-07-18  9:07                       ` Avi Kivity
     [not found]                         ` <469DD843.4040904-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-18  9:38                           ` Dong, Eddie
     [not found]                             ` <10EA09EFD8728347A513008B6B0DA77A01C73018-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18  9:43                               ` Avi Kivity
     [not found]                                 ` <469DE0B1.6020101-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-18  9:46                                   ` Dong, Eddie
     [not found]                                     ` <10EA09EFD8728347A513008B6B0DA77A01C7301C-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18 10:29                                       ` Avi Kivity
2007-07-18  2:27                   ` Dong, Eddie
     [not found]                     ` <10EA09EFD8728347A513008B6B0DA77A01C72CDD-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18  2:28                       ` Dong, Eddie
     [not found]                         ` <10EA09EFD8728347A513008B6B0DA77A01C72CE1-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-18  9:04                           ` Avi Kivity
2007-07-18  9:07                           ` Avi Kivity
2007-07-18  8:36                   ` Avi Kivity

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=4697754D.7000003@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=eddie.dong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox