[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Support 1000 HZ guests



- Support guests with 1000 Hz
- cleanup the trailing garbage in vmx_virtpit.h
- Don't queue up pending timer interrupts before the first interrupt is injected
        - This fixes the low bogomips problem
- Protect xen against guests programming a bad value for the counter

Signed-off-by: Edwin Zhai <edwin.zhai@xxxxxxxxx>
Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>

--- 1.2/xen/arch/x86/vmx_intercept.c    2005-02-17 13:11:51 -08:00
+++ edited/xen/arch/x86/vmx_intercept.c 2005-02-24 14:24:56 -08:00
@@ -203,7 +203,7 @@
 
 
 /* Only some PIT operations such as load init counter need a hypervisor hook.
- * leave many other operations in user space DM
+ * leave all other operations in user space DM
  */
 void vmx_hooks_assist(struct exec_domain *d)
 {
@@ -213,11 +213,20 @@
     struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit);
     int rw_mode;
 
-    if (p->state == STATE_IORESP_HOOK) { /*load init count*/
-        vpit->init_val = (p->u.data & 0xFFFF) ; /* frequency(ms) of pit */
-        vpit->period = (vpit->init_val) * 1000 / PIT_FREQ; /* frequency(ms) of 
pit */
+    /* load init count*/
+    if (p->state == STATE_IORESP_HOOK) { 
+        /* init count for this channel */
+        vpit->init_val = (p->u.data & 0xFFFF) ; 
+        /* frequency(ms) of pit */
+        vpit->period = DIV_ROUND(((vpit->init_val) * 1000), PIT_FREQ); 
+        if (vpit->period < 1) {
+            printk("VMX_PIT: guest programmed too small an init_val: %lx\n",
+                   vpit->init_val);
+            vpit->period = 1;
+        }
         vpit->vector = ((p->u.data >> 16) & 0xFF);
         vpit->channel = ((p->u.data >> 24) & 0x3);
+        vpit->first_injected = 0;
 
        vpit->count_LSB_latched = 0;
        vpit->count_MSB_latched = 0;
===== xen/arch/x86/vmx_io.c 1.13 vs edited =====
--- 1.13/xen/arch/x86/vmx_io.c  2005-02-24 02:46:33 -08:00
+++ edited/xen/arch/x86/vmx_io.c        2005-02-24 12:11:35 -08:00
@@ -367,6 +367,12 @@
     else
         clear_highest_bit(d, highest_vector); 
 
+    /* close the window between guest PIT initialization and sti */
+    if (highest_vector == vpit->vector && !vpit->first_injected){
+        vpit->first_injected = 1;
+        vpit->pending_intr_nr = 0;
+    }
+
     intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR | highest_vector);
     __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
 
===== xen/include/asm-x86/vmx_virpit.h 1.1 vs edited =====
--- 1.1/xen/include/asm-x86/vmx_virpit.h        2005-02-08 15:57:16 -08:00
+++ edited/xen/include/asm-x86/vmx_virpit.h     2005-02-24 12:12:18 -08:00
@@ -1,4 +1,3 @@
-
 #ifndef _VMX_VIRPIT_H
 #define _VMX_VIRPIT_H
 #include <xen/config.h>
@@ -25,6 +24,7 @@
     unsigned int pending_intr_nr;      /* the couner for pending timer 
interrupts */
     unsigned long long inject_point;   /* the time inject virt intr */
     struct ac_timer pit_timer;         /* periodic timer for mode 2*/
+    int first_injected;                 /* flag to prevent shadow window */
 
     /* virtual PIT state for handle related I/O */
     int read_state;
@@ -38,44 +38,5 @@
 
 /* to hook the ioreq packet to get the PIT initializaiton info */
 extern void vmx_hooks_assist(struct exec_domain *d);
-
-#endif /* _VMX_VIRPIT_H_ */
-
-#ifndef _VMX_VIRPIT_H
-#define _VMX_VIRPIT_H
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/lib.h>
-#include <xen/time.h>
-#include <xen/errno.h>
-#include <xen/ac_timer.h>
-#include <asm/vmx_vmcs.h>
-
-#define PIT_FREQ 1193181
-
-#define LSByte 0
-#define MSByte 1
-#define LSByte_multiple 2
-#define MSByte_multiple 3
-
-struct vmx_virpit_t {
-    /* for simulation of counter 0 in mode 2*/
-    int vector;                                /* the pit irq vector */
-    unsigned int period;               /* the frequency. e.g. 10ms*/
-    unsigned int channel;              /* the pit channel, counter 0~2 */
-    unsigned long *intr_bitmap;
-    unsigned int pending_intr_nr;      /* the couner for pending timer 
interrupts */
-    unsigned long long inject_point;   /* the time inject virt intr */
-    struct ac_timer pit_timer;         /* periodic timer for mode 2*/
-
-    /* virtual PIT state for handle related I/O */
-    int read_state;
-    int count_LSB_latched;
-    int count_MSB_latched;
-
-    unsigned int count;                /* the 16 bit channel count */
-    unsigned int init_val;     /* the init value for the counter */
-
-} ;
 
 #endif /* _VMX_VIRPIT_H_ */
===== xen/include/xen/lib.h 1.21 vs edited =====
--- 1.21/xen/include/xen/lib.h  2005-02-19 19:28:20 -08:00
+++ edited/xen/include/xen/lib.h        2005-02-24 14:02:53 -08:00
@@ -23,6 +23,8 @@
 #define SWAP(_a, _b) \
    do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 )
 
+#define DIV_ROUND(x, y) (((x) + (y) - 1) / (y))
+
 #define reserve_bootmem(_p,_l) ((void)0)
 
 struct domain;


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.