ia64/xen-unstable

changeset 15901:b658296982ee

[IA64] make vacpi SMP-safe by adding lock similar to x86 pmtimer

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Sep 27 09:03:43 2007 -0600 (2007-09-27)
parents 51f4a0e0b554
children 764d33505b98
files xen/arch/ia64/vmx/vacpi.c xen/include/asm-ia64/hvm/vacpi.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vacpi.c	Thu Sep 27 09:01:42 2007 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vacpi.c	Thu Sep 27 09:03:43 2007 -0600
     1.3 @@ -4,6 +4,9 @@
     1.4   *
     1.5   * Copyright (c) 2007, FUJITSU LIMITED
     1.6   *      Kouya Shimura <kouya at jp fujitsu com>
     1.7 + * Copyright (c) 2007 VA Linux Systems Japan K.K
     1.8 + *      Isaku Yamahata <yamahata at valinux co jp>
     1.9 + *      SMP support
    1.10   *
    1.11   * Copyright (c) 2007, XenSource inc.
    1.12   * Copyright (c) 2006, Intel Corporation.
    1.13 @@ -49,9 +52,14 @@
    1.14  #define TMR_VAL_MASK  (0xffffffff)
    1.15  #define TMR_VAL_MSB   (0x80000000)
    1.16  
    1.17 +/*
    1.18 + * Locking order: vacpi->lock => viosapic->lock
    1.19 + * pmt_update_sci() => viosapic_set_irq() => viosapic->lock
    1.20 + */
    1.21  /* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */
    1.22  static void pmt_update_sci(struct domain *d, struct vacpi *s)
    1.23  {
    1.24 +	ASSERT(spin_is_locked(&s->lock));
    1.25  	if (s->regs.pm1a_en & s->regs.pm1a_sts & SCI_MASK)
    1.26  		viosapic_set_irq(d, SCI_IRQ, 1);  /* Assert */
    1.27  	else
    1.28 @@ -67,6 +75,8 @@ static void pmt_update_time(struct domai
    1.29  	unsigned long delta;
    1.30  	uint32_t msb = s->regs.tmr_val & TMR_VAL_MSB;
    1.31  
    1.32 +	ASSERT(spin_is_locked(&s->lock));
    1.33 +	
    1.34  	/* Update the timer */
    1.35  	curr_gtime = NOW();
    1.36  	delta = curr_gtime - s->last_gtime;
    1.37 @@ -91,6 +101,8 @@ static void pmt_timer_callback(void *opa
    1.38  	struct vacpi *s = &d->arch.hvm_domain.vacpi;
    1.39  	uint64_t cycles, time_flip;
    1.40  
    1.41 +	spin_lock(&s->lock);
    1.42 +
    1.43  	/* Recalculate the timer and make sure we get an SCI if we need one */
    1.44  	pmt_update_time(d);
    1.45  
    1.46 @@ -102,6 +114,8 @@ static void pmt_timer_callback(void *opa
    1.47  
    1.48  	/* Wake up again near the next bit-flip */
    1.49  	set_timer(&s->timer, NOW() + time_flip + MILLISECS(1));
    1.50 +
    1.51 +	spin_unlock(&s->lock);
    1.52  }
    1.53  
    1.54  int vacpi_intercept(ioreq_t * iop, u64 * val)
    1.55 @@ -113,6 +127,7 @@ int vacpi_intercept(ioreq_t * iop, u64 *
    1.56  	if (addr_off < 4) {	/* Access to PM1a_STS and PM1a_EN registers */
    1.57  		void *p = (void *)&s->regs.evt_blk + addr_off;
    1.58  
    1.59 +		spin_lock(&s->lock);
    1.60  		if (iop->dir == 1) {	/* Read */
    1.61  			if (iop->size == 1)
    1.62  				*val = *(uint8_t *) p;
    1.63 @@ -137,6 +152,7 @@ int vacpi_intercept(ioreq_t * iop, u64 *
    1.64  			/* Fix the SCI state to match the new register state */
    1.65  			pmt_update_sci(d, s);
    1.66  		}
    1.67 +		spin_unlock(&s->lock);
    1.68  
    1.69  		iop->state = STATE_IORESP_READY;
    1.70  		vmx_io_assist(current);
    1.71 @@ -147,8 +163,10 @@ int vacpi_intercept(ioreq_t * iop, u64 *
    1.72  		if (iop->size != 4)
    1.73  			panic_domain(NULL, "wrong ACPI PM timer access\n");
    1.74  		if (iop->dir == 1) {	/* Read */
    1.75 +			spin_lock(&s->lock);
    1.76  			pmt_update_time(d);
    1.77  			*val = s->regs.tmr_val;
    1.78 +			spin_unlock(&s->lock);
    1.79  		}
    1.80  		/* PM_TMR_BLK is read-only */
    1.81  		iop->state = STATE_IORESP_READY;
    1.82 @@ -163,6 +181,8 @@ void vacpi_init(struct domain *d)
    1.83  {
    1.84  	struct vacpi *s = &d->arch.hvm_domain.vacpi;
    1.85  
    1.86 +	spin_lock_init(&s->lock);
    1.87 +
    1.88  	s->regs.tmr_val = 0;
    1.89  	s->regs.evt_blk = 0;
    1.90  	s->last_gtime = NOW();
     2.1 --- a/xen/include/asm-ia64/hvm/vacpi.h	Thu Sep 27 09:01:42 2007 -0600
     2.2 +++ b/xen/include/asm-ia64/hvm/vacpi.h	Thu Sep 27 09:03:43 2007 -0600
     2.3 @@ -46,6 +46,7 @@ struct vacpi {
     2.4  	struct vacpi_regs regs;
     2.5  	s_time_t last_gtime;
     2.6  	struct timer timer;
     2.7 +	spinlock_t lock;
     2.8  };
     2.9  
    2.10  int vacpi_intercept(ioreq_t * p, u64 * val);