diff mbox

[3/3] x86/HVM: terminate writes to PM_TMR port

Message ID 56F3DDCC02000078000E0087@prv-mh.provo.novell.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Beulich March 24, 2016, 11:30 a.m. UTC
There's no point in forwarding these to the device model.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
x86/HVM: terminate writes to PM_TMR port

There's no point in forwarding these to the device model.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -217,36 +217,30 @@ static int handle_pmt_io(
     struct vcpu *v = current;
     PMTState *s = &v->domain->arch.hvm_domain.pl_time->vpmt;
 
-    if ( bytes != 4 )
+    if ( bytes != 4 || dir != IOREQ_READ )
     {
         gdprintk(XENLOG_WARNING, "HVM_PMT bad access\n");
         *val = ~0;
-        return X86EMUL_OKAY;
     }
-    
-    if ( dir == IOREQ_READ )
+    else if ( spin_trylock(&s->lock) )
     {
-        if ( spin_trylock(&s->lock) )
-        {
-            /* We hold the lock: update timer value and return it. */
-            pmt_update_time(s);
-            *val = s->pm.tmr_val;
-            spin_unlock(&s->lock);
-        }
-        else
-        {
-            /*
-             * Someone else is updating the timer: rather than do the work
-             * again ourselves, wait for them to finish and then steal their
-             * updated value with a lock-free atomic read.
-             */
-            spin_barrier(&s->lock);
-            *val = *(volatile uint32_t *)&s->pm.tmr_val;
-        }
-        return X86EMUL_OKAY;
+        /* We hold the lock: update timer value and return it. */
+        pmt_update_time(s);
+        *val = s->pm.tmr_val;
+        spin_unlock(&s->lock);
+    }
+    else
+    {
+        /*
+         * Someone else is updating the timer: rather than do the work
+         * again ourselves, wait for them to finish and then steal their
+         * updated value with a lock-free atomic read.
+         */
+        spin_barrier(&s->lock);
+        *val = read_atomic(&s->pm.tmr_val);
     }
 
-    return X86EMUL_UNHANDLEABLE;
+    return X86EMUL_OKAY;
 }
 
 static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)

Comments

Andrew Cooper March 24, 2016, 2:08 p.m. UTC | #1
On 24/03/16 11:30, Jan Beulich wrote:
> There's no point in forwarding these to the device model.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff mbox

Patch

--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -217,36 +217,30 @@  static int handle_pmt_io(
     struct vcpu *v = current;
     PMTState *s = &v->domain->arch.hvm_domain.pl_time->vpmt;
 
-    if ( bytes != 4 )
+    if ( bytes != 4 || dir != IOREQ_READ )
     {
         gdprintk(XENLOG_WARNING, "HVM_PMT bad access\n");
         *val = ~0;
-        return X86EMUL_OKAY;
     }
-    
-    if ( dir == IOREQ_READ )
+    else if ( spin_trylock(&s->lock) )
     {
-        if ( spin_trylock(&s->lock) )
-        {
-            /* We hold the lock: update timer value and return it. */
-            pmt_update_time(s);
-            *val = s->pm.tmr_val;
-            spin_unlock(&s->lock);
-        }
-        else
-        {
-            /*
-             * Someone else is updating the timer: rather than do the work
-             * again ourselves, wait for them to finish and then steal their
-             * updated value with a lock-free atomic read.
-             */
-            spin_barrier(&s->lock);
-            *val = *(volatile uint32_t *)&s->pm.tmr_val;
-        }
-        return X86EMUL_OKAY;
+        /* We hold the lock: update timer value and return it. */
+        pmt_update_time(s);
+        *val = s->pm.tmr_val;
+        spin_unlock(&s->lock);
+    }
+    else
+    {
+        /*
+         * Someone else is updating the timer: rather than do the work
+         * again ourselves, wait for them to finish and then steal their
+         * updated value with a lock-free atomic read.
+         */
+        spin_barrier(&s->lock);
+        *val = read_atomic(&s->pm.tmr_val);
     }
 
-    return X86EMUL_UNHANDLEABLE;
+    return X86EMUL_OKAY;
 }
 
 static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)