debuggers.hg
changeset 3726:88957a238191
bitkeeper revision 1.1159.1.544 (4207248crq3YxiyLWjUehtHv_Yd3tg)
Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
line diff
1.1 --- a/.rootkeys Fri Feb 04 19:26:10 2005 +0000 1.2 +++ b/.rootkeys Mon Feb 07 08:19:24 2005 +0000 1.3 @@ -882,8 +882,6 @@ 3ddb79bdHe6_Uij4-glW91vInNtBYQ xen/arch/ 1.4 3ddb79bcZ_2FxINljqNSkqa17ISyJw xen/arch/x86/pci-pc.c 1.5 3ddb79bdeJ7_86z03yTAPIeeywOg3Q xen/arch/x86/pci-x86.c 1.6 3ddb79bdIKgipvGoqExEQ7jawfVowA xen/arch/x86/pci-x86.h 1.7 -40a4dfced2dnSzbKgJFlD3chKHexjQ xen/arch/x86/pdb-linux.c 1.8 -4022a73czgX7d-2zfF_cb33oVemApQ xen/arch/x86/pdb-stub.c 1.9 3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c 1.10 3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c 1.11 405b8599xI_PoEr3zZoJ2on-jdn7iw xen/arch/x86/shadow.c 1.12 @@ -914,8 +912,6 @@ 40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/ 1.13 40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds 1.14 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile 1.15 3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c 1.16 -4022a73c_BbDFd2YJ_NQYVvKX5Oz7w xen/common/debug-linux.c 1.17 -3fa152581E5KhrAtqZef2Sr5NKTz4w xen/common/debug.c 1.18 3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c 1.19 3e6377e4i0c9GtKN65e99OtRbw3AZw xen/common/dom_mem_ops.c 1.20 3ddb79bdYO5D8Av12NHqPeSviav7cg xen/common/domain.c 1.21 @@ -925,7 +921,6 @@ 41262590gGIOn-1pvF5KpUu8Wb6_JA xen/commo 1.22 3ddb79bd9drcFPVxd4w2GPOIjLlXpA xen/common/kernel.c 1.23 3e4cd9d8LAAghUY0hNIK72uc2ch_Nw xen/common/keyhandler.c 1.24 3ddb79bduhSEZI8xa7IbGQCpap5y2A xen/common/lib.c 1.25 -4200cf14XGr26_PCC8NxREDhr7Hk5Q xen/common/malloc.c 1.26 41a61536SZbR6cj1ukWTb0DYU-vz9w xen/common/multicall.c 1.27 3ddb79bdD4SLmmdMD7yLW5HcUWucXw xen/common/page_alloc.c 1.28 3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c 1.29 @@ -935,11 +930,11 @@ 4064773cJ31vZt-zhbSoxqft1Jaw0w xen/commo 1.30 40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c 1.31 40589968be_t_n0-w6ggceW7h-sx0w xen/common/sched_rrobin.c 1.32 3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c 1.33 -3ddb79bdB9RNMnkQnUyZ5C9hhMSQQw xen/common/slab.c 1.34 3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c 1.35 3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c 1.36 403a3edbejm33XLTGMuinKEwQBrOIg xen/common/trace.c 1.37 3ddb79bd3zgV33PHdt-cgh3sxcb1hw xen/common/vsprintf.c 1.38 +4203fb92Qcy7mGpauBdq09J-WAqfoA xen/common/xmalloc.c 1.39 3ddb79c0ppNeJtjC4va8j41ADCnchA xen/drivers/Makefile 1.40 40715b2bi9gU43-cYzlmPDgreYQchw xen/drivers/acpi/Makefile 1.41 40715b2bDxNCz5LFV8FAXihmYJZFUQ xen/drivers/acpi/acpi_ksyms.c 1.42 @@ -1004,12 +999,14 @@ 3ddb79c2jFkPAZTDmU35L6IUssYMgQ xen/inclu 1.43 3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h 1.44 3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h 1.45 40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h 1.46 +4204e7acwzqgXyTAPKa1nM-L7Ec0Qw xen/include/asm-x86/domain.h 1.47 41febc4bBKTKHhnAu_KPYwgNkHjFlg xen/include/asm-x86/domain_page.h 1.48 41d3eaaeIBzW621S1oa0c2yk7X43qQ xen/include/asm-x86/e820.h 1.49 3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h 1.50 3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h 1.51 3ddb79c39o75zPP0T1aQQ4mNrCAN2w xen/include/asm-x86/hardirq.h 1.52 3ddb79c3TMDjkxVndKFKnGiwY0HzDg xen/include/asm-x86/i387.h 1.53 +4204e7acwXDo-5iAAiO2eQbtDeYZXA xen/include/asm-x86/init.h 1.54 3ddb79c3fQ_O3o5NHK2N8AJdk0Ea4Q xen/include/asm-x86/io.h 1.55 3ddb79c2TKeScYHQZreTdHqYNLbehQ xen/include/asm-x86/io_apic.h 1.56 3ddb79c2L7rTlFzazOLW1XuSZefpFw xen/include/asm-x86/irq.h 1.57 @@ -1022,7 +1019,6 @@ 41aaf567Mi3OishhvrCtET1y-mxQBg xen/inclu 1.58 41a61536MFhNalgbVmYGXAhQsPTZNw xen/include/asm-x86/multicall.h 1.59 3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h 1.60 3ddb79c3ysKUbxZuwKBRK3WXU2TlEg xen/include/asm-x86/pci.h 1.61 -4022a73diKn2Ax4-R4gzk59lm1YdDg xen/include/asm-x86/pdb.h 1.62 3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h 1.63 40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/regs.h 1.64 3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/include/asm-x86/rwlock.h
2.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c Fri Feb 04 19:26:10 2005 +0000 2.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c Mon Feb 07 08:19:24 2005 +0000 2.3 @@ -129,7 +129,7 @@ void __iomem * __ioremap(unsigned long p 2.4 if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr, 2.5 size, __pgprot(_PAGE_PRESENT | _PAGE_RW | 2.6 _PAGE_DIRTY | _PAGE_ACCESSED 2.7 - | flags), DOMID_IO)) { 2.8 + | flags), domid)) { 2.9 vunmap((void __force *) addr); 2.10 return NULL; 2.11 }
3.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/common.h Fri Feb 04 19:26:10 2005 +0000 3.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/common.h Mon Feb 07 08:19:24 2005 +0000 3.3 @@ -38,10 +38,8 @@ struct usbif_priv_st { 3.4 unsigned long shmem_frame; 3.5 unsigned int evtchn; 3.6 int irq; 3.7 - /* Comms information. */ 3.8 - usbif_t *usb_ring_base; /* ioremap()'ed ptr to shmem_frame. */ 3.9 - USBIF_RING_IDX usb_req_cons; /* Request consumer. */ 3.10 - USBIF_RING_IDX usb_resp_prod; /* Private version of resp. producer. */ 3.11 + /* Comms Information */ 3.12 + usbif_back_ring_t usb_ring; 3.13 /* Private fields. */ 3.14 enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; 3.15 /* 3.16 @@ -49,11 +47,10 @@ struct usbif_priv_st { 3.17 * We therefore need to store the id from the original request. 3.18 */ 3.19 u8 disconnect_rspid; 3.20 - usbif_priv_t *hash_next; 3.21 + usbif_priv_t *hash_next; 3.22 struct list_head usbif_list; 3.23 spinlock_t usb_ring_lock; 3.24 atomic_t refcnt; 3.25 - atomic_t work_scheduled; 3.26 3.27 struct work_struct work; 3.28 }; 3.29 @@ -80,7 +77,8 @@ usbif_priv_t *usbif_find(domid_t domid); 3.30 void usbif_interface_init(void); 3.31 void usbif_ctrlif_init(void); 3.32 3.33 -void usbif_deschedule(usbif_priv_t *usbif); 3.34 +void usbif_deschedule(usbif_priv_t *up); 3.35 +void remove_from_usbif_list(usbif_priv_t *up); 3.36 3.37 irqreturn_t usbif_be_int(int irq, void *dev_id, struct pt_regs *regs); 3.38
4.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/interface.c Fri Feb 04 19:26:10 2005 +0000 4.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/interface.c Mon Feb 07 08:19:24 2005 +0000 4.3 @@ -43,7 +43,7 @@ static void __usbif_disconnect_complete( 4.4 * must still be notified to the remote driver. 4.5 */ 4.6 unbind_evtchn_from_irq(usbif->evtchn); 4.7 - vfree(usbif->usb_ring_base); 4.8 + vfree(usbif->usb_ring.sring); 4.9 4.10 /* Construct the deferred response message. */ 4.11 cmsg.type = CMSG_USBIF_BE; 4.12 @@ -153,6 +153,7 @@ void usbif_connect(usbif_be_connect_t *c 4.13 pgprot_t prot; 4.14 int error; 4.15 usbif_priv_t *up; 4.16 + usbif_sring_t *sring; 4.17 4.18 up = usbif_find(domid); 4.19 if ( unlikely(up == NULL) ) 4.20 @@ -192,10 +193,13 @@ void usbif_connect(usbif_be_connect_t *c 4.21 return; 4.22 } 4.23 4.24 + sring = (usbif_sring_t *)vma->addr; 4.25 + SHARED_RING_INIT(USBIF_RING, sring); 4.26 + BACK_RING_INIT(USBIF_RING, &up->usb_ring, sring); 4.27 + 4.28 up->evtchn = evtchn; 4.29 up->irq = bind_evtchn_to_irq(evtchn); 4.30 up->shmem_frame = shmem_frame; 4.31 - up->usb_ring_base = (usbif_t *)vma->addr; 4.32 up->status = CONNECTED; 4.33 usbif_get(up); 4.34
5.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c Fri Feb 04 19:26:10 2005 +0000 5.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c Mon Feb 07 08:19:24 2005 +0000 5.3 @@ -86,7 +86,7 @@ static pending_req_t pending_reqs[MAX_PE 5.4 static unsigned char pending_ring[MAX_PENDING_REQS]; 5.5 static spinlock_t pend_prod_lock; 5.6 5.7 -/* NB. We use a different index type to differentiate from shared blk rings. */ 5.8 +/* NB. We use a different index type to differentiate from shared usb rings. */ 5.9 typedef unsigned int PEND_RING_IDX; 5.10 #define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) 5.11 static PEND_RING_IDX pending_prod, pending_cons; 5.12 @@ -391,17 +391,17 @@ irqreturn_t usbif_be_int(int irq, void * 5.13 5.14 static int do_usb_io_op(usbif_priv_t *up, int max_to_do) 5.15 { 5.16 - usbif_t *usb_ring = up->usb_ring_base; 5.17 + usbif_back_ring_t *usb_ring = &up->usb_ring; 5.18 usbif_request_t *req; 5.19 - USBIF_RING_IDX i, rp; 5.20 + RING_IDX i, rp; 5.21 int more_to_do = 0; 5.22 5.23 - rp = usb_ring->req_prod; 5.24 + rp = usb_ring->sring->req_prod; 5.25 rmb(); /* Ensure we see queued requests up to 'rp'. */ 5.26 5.27 /* Take items off the comms ring, taking care not to overflow. */ 5.28 - for ( i = up->usb_req_cons; 5.29 - (i != rp) && ((i-up->usb_resp_prod) != USBIF_RING_SIZE); 5.30 + for ( i = usb_ring->req_cons; 5.31 + (i != rp) && !RING_REQUEST_CONS_OVERFLOW(USBIF_RING, usb_ring, i); 5.32 i++ ) 5.33 { 5.34 if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) ) 5.35 @@ -410,7 +410,7 @@ static int do_usb_io_op(usbif_priv_t *up 5.36 break; 5.37 } 5.38 5.39 - req = &usb_ring->ring[MASK_USBIF_IDX(i)].req; 5.40 + req = RING_GET_REQUEST(USBIF_RING, usb_ring, i); 5.41 5.42 switch ( req->operation ) 5.43 { 5.44 @@ -435,7 +435,7 @@ static int do_usb_io_op(usbif_priv_t *up 5.45 } 5.46 } 5.47 5.48 - up->usb_req_cons = i; 5.49 + usb_ring->req_cons = i; 5.50 5.51 return more_to_do; 5.52 } 5.53 @@ -783,11 +783,11 @@ static void make_response(usbif_priv_t * 5.54 { 5.55 usbif_response_t *resp; 5.56 unsigned long flags; 5.57 + usbif_back_ring_t *usb_ring = &up->usb_ring; 5.58 5.59 /* Place on the response ring for the relevant domain. */ 5.60 spin_lock_irqsave(&up->usb_ring_lock, flags); 5.61 - resp = &up->usb_ring_base-> 5.62 - ring[MASK_USBIF_IDX(up->usb_resp_prod)].resp; 5.63 + resp = RING_GET_RESPONSE(USBIF_RING, usb_ring, usb_ring->rsp_prod_pvt); 5.64 resp->id = id; 5.65 resp->operation = op; 5.66 resp->status = st; 5.67 @@ -797,7 +797,8 @@ static void make_response(usbif_priv_t * 5.68 5.69 dump_response(resp); 5.70 5.71 - up->usb_ring_base->resp_prod = ++up->usb_resp_prod; 5.72 + usb_ring->rsp_prod_pvt++; 5.73 + RING_PUSH_RESPONSES(USBIF_RING, usb_ring); 5.74 spin_unlock_irqrestore(&up->usb_ring_lock, flags); 5.75 5.76 /* Kick the relevant domain. */
6.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c Fri Feb 04 19:26:10 2005 +0000 6.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c Mon Feb 07 08:19:24 2005 +0000 6.3 @@ -119,7 +119,7 @@ static void xhci_drain_ring(void); 6.4 6.5 #define MAX_URB_LOOP 2048 /* Maximum number of linked URB's */ 6.6 6.7 -struct xhci *xhci; 6.8 +static struct xhci *xhci; 6.9 6.10 enum { USBIF_STATE_CONNECTED = 2, 6.11 USBIF_STATE_DISCONNECTED = 1, 6.12 @@ -128,10 +128,60 @@ enum { USBIF_STATE_CONNECTED = 2, 6.13 6.14 static int awaiting_reset = 0; 6.15 6.16 +#ifdef DEBUG 6.17 + 6.18 +static void dump_urb(struct urb *urb) 6.19 +{ 6.20 + printk(KERN_DEBUG "dumping urb @ %p\n" 6.21 + " hcpriv = %p\n" 6.22 + " next = %p\n" 6.23 + " dev = %p\n" 6.24 + " pipe = 0x%lx\n" 6.25 + " status = %d\n" 6.26 + " transfer_flags = 0x%lx\n" 6.27 + " transfer_buffer = %p\n" 6.28 + " transfer_buffer_length = %d\n" 6.29 + " actual_length = %d\n" 6.30 + " bandwidth = %d\n" 6.31 + " setup_packet = %p\n", 6.32 + urb, urb->hcpriv, urb->next, urb->dev, urb->pipe, urb->status, 6.33 + urb->transfer_flags, urb->transfer_buffer, urb->transfer_buffer_length, 6.34 + urb->actual_length, urb->bandwidth, urb->setup_packet); 6.35 + if ( urb->setup_packet != NULL ) 6.36 + printk(KERN_DEBUG 6.37 + "setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n", 6.38 + urb->setup_packet[0], urb->setup_packet[1], urb->setup_packet[2], urb->setup_packet[3], 6.39 + urb->setup_packet[4], urb->setup_packet[5], urb->setup_packet[6], urb->setup_packet[7]); 6.40 + printk(KERN_DEBUG "complete = %p\n" 6.41 + "interval = %d\n", urb->complete, urb->interval); 6.42 + 6.43 +} 6.44 + 6.45 +static void xhci_show_resp(usbif_response_t *r) 6.46 +{ 6.47 + printk(KERN_DEBUG "dumping response @ %p\n" 6.48 + " id=0x%lx\n" 6.49 + " op=0x%x\n" 6.50 + " data=0x%x\n" 6.51 + " status=0x%x\n" 6.52 + " length=0x%lx\n", 6.53 + r->id, r->operation, r->data, r->status, r->length); 6.54 +} 6.55 + 6.56 +#define DPRINK(...) printk(KERN_DEBUG __VA_ARGS__) 6.57 + 6.58 +#else /* DEBUG */ 6.59 + 6.60 +#define dump_urb(blah) ((void)0) 6.61 +#define xhci_show_resp(blah) ((void)0) 6.62 +#define DPRINTK(blah,...) ((void)0) 6.63 + 6.64 +#endif /* DEBUG */ 6.65 + 6.66 /** 6.67 * xhci_construct_isoc - add isochronous information to a request 6.68 */ 6.69 -int xhci_construct_isoc(usbif_request_t *req, struct urb *urb) 6.70 +static int xhci_construct_isoc(usbif_request_t *req, struct urb *urb) 6.71 { 6.72 usbif_iso_t *schedule; 6.73 int i; 6.74 @@ -155,56 +205,28 @@ int xhci_construct_isoc(usbif_request_t 6.75 return 0; 6.76 } 6.77 6.78 -#define USBIF_RING_FULL ((xhci->usbif->req_prod - xhci->usb_resp_cons) == USBIF_RING_SIZE) 6.79 - 6.80 -static void dump_urb(struct urb *urb) 6.81 -{ 6.82 - printk("dumping urb @ %p\n", urb); 6.83 - 6.84 - printk("hcpriv = %p\n", urb->hcpriv); 6.85 - printk("next = %p\n", urb->next); 6.86 - printk("dev = %p\n", urb->dev); 6.87 - printk("pipe = 0x%lx\n", urb->pipe); 6.88 - printk("status = %d\n", urb->status); 6.89 - printk("transfer_flags = 0x%lx\n", urb->transfer_flags); 6.90 - printk("transfer_buffer = %p\n", urb->transfer_buffer); 6.91 - printk("transfer_buffer_length = %d\n", urb->transfer_buffer_length); 6.92 - printk("actual_length = %d\n", urb->actual_length); 6.93 - printk("bandwidth = %d\n", urb->bandwidth); 6.94 - printk("setup_packet = %p\n", urb->setup_packet); 6.95 - if ( urb->setup_packet != NULL ) 6.96 - printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 6.97 - urb->setup_packet[0], urb->setup_packet[1], urb->setup_packet[2], urb->setup_packet[3], 6.98 - urb->setup_packet[4], urb->setup_packet[5], urb->setup_packet[6], urb->setup_packet[7]); 6.99 - printk("complete = %p\n", urb->complete); 6.100 - printk("interval = %d\n", urb->interval); 6.101 - 6.102 -} 6.103 - 6.104 - 6.105 -static int 6.106 -xhci_queue_req(struct urb *urb) 6.107 +static int xhci_queue_req(struct urb *urb) 6.108 { 6.109 usbif_request_t *req; 6.110 - usbif_t *usbif = xhci->usbif; 6.111 + usbif_front_ring_t *usb_ring = &xhci->usb_ring; 6.112 6.113 -#if 0 6.114 - printk("usbif = %p, req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 6.115 +#if DEBUG 6.116 + printk(KERN_DEBUG 6.117 + "usbif = %p, req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 6.118 usbif, usbif->req_prod, virt_to_machine(&usbif->req_prod), 6.119 usbif->resp_prod, xhci->usb_resp_cons); 6.120 #endif 6.121 6.122 6.123 -/* printk("Usbif_priv %p, want IO at 0x%lx\n", urb->hcpriv, virt_to_machine(urb->transfer_buffer)); */ 6.124 - 6.125 - if ( USBIF_RING_FULL ) 6.126 + if ( RING_FULL(USBIF_RING, usb_ring) ) 6.127 { 6.128 - printk("xhci_queue_req(): USB ring full, not queuing request\n"); 6.129 + printk(KERN_WARNING 6.130 + "xhci_queue_req(): USB ring full, not queuing request\n"); 6.131 return -ENOBUFS; 6.132 } 6.133 6.134 /* Stick something in the shared communications ring. */ 6.135 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 6.136 + req = RING_GET_REQUEST(USBIF_RING, usb_ring, usb_ring->req_prod_pvt); 6.137 6.138 req->operation = USBIF_OP_IO; 6.139 req->port = 0; /* We don't care what the port is. */ 6.140 @@ -232,37 +254,38 @@ xhci_queue_req(struct urb *urb) 6.141 else 6.142 memset(req->setup, 0, 8); 6.143 6.144 - wmb(); 6.145 - 6.146 - usbif->req_prod++; 6.147 + usb_ring->req_prod_pvt++; 6.148 + RING_PUSH_REQUESTS(USBIF_RING, usb_ring); 6.149 6.150 notify_via_evtchn(xhci->evtchn); 6.151 6.152 - // dump_urb(urb); 6.153 + DPRINTK("Queued request for an URB.\n"); 6.154 + dump_urb(urb); 6.155 6.156 return -EINPROGRESS; 6.157 } 6.158 6.159 -static inline usbif_request_t * 6.160 -xhci_queue_probe(usbif_vdev_t port) 6.161 +static inline usbif_request_t *xhci_queue_probe(usbif_vdev_t port) 6.162 { 6.163 usbif_request_t *req; 6.164 - usbif_t *usbif = xhci->usbif; 6.165 + usbif_front_ring_t *usb_ring = &xhci->usb_ring; 6.166 6.167 -#if 0 6.168 - printk("queuing probe: req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 6.169 +#if DEBUG 6.170 + printk(KERN_DEBUG 6.171 + "queuing probe: req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 6.172 usbif->req_prod, virt_to_machine(&usbif->req_prod), 6.173 usbif->resp_prod, xhci->usb_resp_cons); 6.174 #endif 6.175 6.176 - if ( USBIF_RING_FULL ) 6.177 + if ( RING_FULL(USBIF_RING, usb_ring) ) 6.178 { 6.179 - printk("xhci_queue_probe(): USB ring full, not queuing request\n"); 6.180 + printk(KERN_WARNING 6.181 + "xhci_queue_probe(): USB ring full, not queuing request\n"); 6.182 return NULL; 6.183 } 6.184 6.185 /* Stick something in the shared communications ring. */ 6.186 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 6.187 + req = RING_GET_REQUEST(USBIF_RING, usb_ring, usb_ring->req_prod_pvt); 6.188 6.189 req->operation = USBIF_OP_PROBE; 6.190 req->port = port; 6.191 @@ -277,34 +300,31 @@ xhci_queue_probe(usbif_vdev_t port) 6.192 req->endpoint = 0; 6.193 req->speed = 0; 6.194 6.195 - wmb(); 6.196 - 6.197 - usbif->req_prod++; 6.198 + usb_ring->req_prod_pvt++; 6.199 + RING_PUSH_REQUESTS(USBIF_RING, usb_ring); 6.200 6.201 notify_via_evtchn(xhci->evtchn); 6.202 6.203 return req; 6.204 } 6.205 6.206 -static int 6.207 -xhci_port_reset(usbif_vdev_t port) 6.208 +static int xhci_port_reset(usbif_vdev_t port) 6.209 { 6.210 usbif_request_t *req; 6.211 - usbif_t *usbif = xhci->usbif; 6.212 + usbif_front_ring_t *usb_ring = &xhci->usb_ring; 6.213 6.214 /* We only reset one port at a time, so we only need one variable per 6.215 * hub. */ 6.216 awaiting_reset = 1; 6.217 6.218 /* Stick something in the shared communications ring. */ 6.219 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 6.220 + req = RING_GET_REQUEST(USBIF_RING, usb_ring, usb_ring->req_prod_pvt); 6.221 6.222 req->operation = USBIF_OP_RESET; 6.223 req->port = port; 6.224 6.225 - wmb(); 6.226 - 6.227 - usbif->req_prod++; 6.228 + usb_ring->req_prod_pvt++; 6.229 + RING_PUSH_REQUESTS(USBIF_RING, usb_ring); 6.230 6.231 notify_via_evtchn(xhci->evtchn); 6.232 6.233 @@ -317,12 +337,6 @@ xhci_port_reset(usbif_vdev_t port) 6.234 return awaiting_reset; 6.235 } 6.236 6.237 -static void xhci_show_resp(usbif_response_t *r) 6.238 -{ 6.239 - printk("id=0x%lx, op=0x%x, data=0x%x, status=0x%x, length=0x%lx\n", 6.240 - r->id, r->operation, r->data, r->status, r->length); 6.241 -} 6.242 - 6.243 6.244 /* 6.245 * Only the USB core should call xhci_alloc_dev and xhci_free_dev 6.246 @@ -457,10 +471,8 @@ static int xhci_submit_urb(struct urb *u 6.247 struct urb *eurb; 6.248 int bustime; 6.249 6.250 -#if 0 6.251 - printk("submitting urb @ %p for dev @ %p, devnum = %d path %s\n", 6.252 - urb, urb->dev, urb->dev->devnum, urb->dev->devpath); 6.253 -#endif 6.254 + DPRINTK("URB submitted to XHCI driver.\n"); 6.255 + dump_urb(urb); 6.256 6.257 if (!urb) 6.258 return -EINVAL; 6.259 @@ -471,12 +483,7 @@ static int xhci_submit_urb(struct urb *u 6.260 } 6.261 6.262 if ( urb->dev->devpath == NULL ) 6.263 - { 6.264 - printk("BARF!\n"); 6.265 BUG(); 6.266 - } 6.267 - 6.268 - 6.269 6.270 usb_inc_dev_use(urb->dev); 6.271 6.272 @@ -517,10 +524,6 @@ static int xhci_submit_urb(struct urb *u 6.273 goto out; 6.274 } 6.275 6.276 - if ( usb_pipedevice(urb->pipe) == 1 ) 6.277 - printk("dev = %p, dev->path = %s, rh.dev = %p, rh.dev.devnum = %d rh.dev->path = %s!\n", 6.278 - urb->dev, urb->dev->devpath, xhci->rh.dev, xhci->rh.dev->devnum, xhci->rh.dev->devpath); 6.279 - 6.280 switch (usb_pipetype(urb->pipe)) { 6.281 case PIPE_CONTROL: 6.282 ret = xhci_queue_req(urb); 6.283 @@ -768,7 +771,7 @@ static int xhci_unlink_urb(struct urb *u 6.284 } 6.285 6.286 6.287 -struct usb_operations xhci_device_operations = { 6.288 +static struct usb_operations xhci_device_operations = { 6.289 .allocate = xhci_alloc_dev, 6.290 .deallocate = xhci_free_dev, 6.291 /* It doesn't look like any drivers actually care what the frame number 6.292 @@ -1094,7 +1097,6 @@ static int rh_submit_urb(struct urb *urb 6.293 } 6.294 break; 6.295 case RH_SET_ADDRESS: 6.296 - printk("setting root hub device to %d\n", wValue); 6.297 xhci->rh.devnum = wValue; 6.298 OK(0); 6.299 case RH_GET_DESCRIPTOR: 6.300 @@ -1266,14 +1268,14 @@ static void xhci_finish_completion(void) 6.301 spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 6.302 } 6.303 6.304 -void receive_usb_reset(usbif_response_t *resp) 6.305 +static void receive_usb_reset(usbif_response_t *resp) 6.306 { 6.307 awaiting_reset = resp->status; 6.308 rmb(); 6.309 6.310 } 6.311 6.312 -void receive_usb_probe(usbif_response_t *resp) 6.313 +static void receive_usb_probe(usbif_response_t *resp) 6.314 { 6.315 spin_lock(&xhci->rh.port_state_lock); 6.316 6.317 @@ -1281,8 +1283,6 @@ void receive_usb_probe(usbif_response_t 6.318 { 6.319 if ( resp->status == 1 ) 6.320 { 6.321 -/* printk("hey hey, there's a device on port %d\n", resp->data); */ 6.322 - 6.323 /* If theres a device there and there wasn't one before there must 6.324 * have been a connection status change. */ 6.325 if( xhci->rh.ports[resp->data].cs == 0 ) 6.326 @@ -1290,20 +1290,19 @@ void receive_usb_probe(usbif_response_t 6.327 xhci->rh.ports[resp->data].cs = 1; 6.328 xhci->rh.ports[resp->data].ccs = 1; 6.329 xhci->rh.ports[resp->data].cs_chg = 1; 6.330 -/* printk("Look at device on port %d that wasn't there before\n", resp->data); */ 6.331 } 6.332 } 6.333 else 6.334 - printk("receive_usb_probe(): unexpected status %d for port %d\n", 6.335 + printk(KERN_WARNING "receive_usb_probe(): unexpected status %d for port %d\n", 6.336 resp->status, resp->data); 6.337 } 6.338 else if ( resp->status < 0) 6.339 - printk("receive_usb_probe(): got error status %d\n", resp->status); 6.340 + printk(KERN_WARNING "receive_usb_probe(): got error status %d\n", resp->status); 6.341 6.342 spin_unlock(&xhci->rh.port_state_lock); 6.343 } 6.344 6.345 -void receive_usb_io(usbif_response_t *resp) 6.346 +static void receive_usb_io(usbif_response_t *resp) 6.347 { 6.348 struct urb_priv *urbp = (struct urb_priv *)resp->id; 6.349 struct urb *urb = urbp->urb; 6.350 @@ -1333,33 +1332,25 @@ void receive_usb_io(usbif_response_t *re 6.351 static void xhci_drain_ring(void) 6.352 { 6.353 struct list_head *tmp, *head; 6.354 - usbif_t *usb_ring = xhci->usbif; 6.355 + usbif_front_ring_t *usb_ring = &xhci->usb_ring; 6.356 usbif_response_t *resp; 6.357 - USBIF_RING_IDX i, rp; 6.358 + RING_IDX i, rp; 6.359 6.360 /* Walk the ring here to get responses, updating URBs to show what 6.361 * completed. */ 6.362 6.363 - rp = usb_ring->resp_prod; 6.364 + rp = usb_ring->sring->rsp_prod; 6.365 rmb(); /* Ensure we see queued requests up to 'rp'. */ 6.366 6.367 /* Take items off the comms ring, taking care not to overflow. */ 6.368 - for ( i = xhci->usb_resp_cons; 6.369 - (i != rp) && ((i-usb_ring->req_prod) != USBIF_RING_SIZE); 6.370 - i++ ) 6.371 + for ( i = usb_ring->rsp_cons; i != rp; i++ ) 6.372 { 6.373 - resp = &usb_ring->ring[MASK_USBIF_IDX(i)].resp; 6.374 + resp = RING_GET_RESPONSE(USBIF_RING, usb_ring, i); 6.375 6.376 /* May need to deal with batching and with putting a ceiling on 6.377 the number dispatched for performance and anti-dos reasons */ 6.378 6.379 -#if 0 6.380 - printk("usbfront: Processing response:\n"); 6.381 - printk(" id = 0x%x\n", resp->id); 6.382 - printk(" op = %d\n", resp->operation); 6.383 - printk(" status = %d\n", resp->status); 6.384 - printk(" length = %d\n", resp->length); 6.385 -#endif 6.386 + xhci_show_resp(resp); 6.387 6.388 switch ( resp->operation ) 6.389 { 6.390 @@ -1376,13 +1367,14 @@ static void xhci_drain_ring(void) 6.391 break; 6.392 6.393 default: 6.394 - printk("error: unknown USB io operation response [%d]\n", 6.395 - usb_ring->ring[i].req.operation); 6.396 + printk(KERN_WARNING 6.397 + "error: unknown USB io operation response [%d]\n", 6.398 + resp->operation); 6.399 break; 6.400 } 6.401 } 6.402 6.403 - xhci->usb_resp_cons = i; 6.404 + usb_ring->rsp_cons = i; 6.405 6.406 /* Walk the list of pending URB's to see which ones completed and do 6.407 * callbacks, etc. */ 6.408 @@ -1414,22 +1406,6 @@ static void free_xhci(struct xhci *xhci) 6.409 kfree(xhci); 6.410 } 6.411 6.412 -/* /\* */ 6.413 -/* * De-allocate all resources.. */ 6.414 -/* *\/ */ 6.415 -/* static void release_xhci(struct xhci *xhci) */ 6.416 -/* { */ 6.417 -/* if (xhci->irq >= 0) { */ 6.418 -/* free_irq(xhci->irq, xhci); */ 6.419 -/* xhci->irq = -1; */ 6.420 -/* } */ 6.421 - 6.422 -/* /\* Get the ring back from the backend domain. Then free it. Hmmmm. */ 6.423 -/* * Lets ignore this for now - not particularly useful. *\/ */ 6.424 - 6.425 -/* free_xhci(xhci); */ 6.426 -/* } */ 6.427 - 6.428 /** 6.429 * Initialise a new virtual root hub for a new USB device channel. 6.430 */ 6.431 @@ -1500,10 +1476,6 @@ static int alloc_xhci(void) 6.432 /* 6.433 * error exits: 6.434 */ 6.435 -err_start_root_hub: 6.436 - free_irq(xhci->irq, xhci); 6.437 - xhci->irq = -1; 6.438 - 6.439 err_alloc_root_hub: 6.440 usb_free_bus(xhci->bus); 6.441 xhci->bus = NULL; 6.442 @@ -1520,7 +1492,7 @@ static void usbif_status_change(usbif_fe 6.443 ctrl_msg_t cmsg; 6.444 usbif_fe_interface_connect_t up; 6.445 long rc; 6.446 - usbif_t *usbif; 6.447 + usbif_sring_t *sring; 6.448 6.449 switch ( status->status ) 6.450 { 6.451 @@ -1540,15 +1512,16 @@ static void usbif_status_change(usbif_fe 6.452 } 6.453 6.454 /* Move from CLOSED to DISCONNECTED state. */ 6.455 - xhci->usbif = usbif = (usbif_t *)__get_free_page(GFP_KERNEL); 6.456 - usbif->req_prod = usbif->resp_prod = 0; 6.457 + sring = (usbif_sring_t *)__get_free_page(GFP_KERNEL); 6.458 + SHARED_RING_INIT(USBIF_RING, sring); 6.459 + FRONT_RING_INIT(USBIF_RING, &xhci->usb_ring, sring); 6.460 xhci->state = USBIF_STATE_DISCONNECTED; 6.461 6.462 /* Construct an interface-CONNECT message for the domain controller. */ 6.463 cmsg.type = CMSG_USBIF_FE; 6.464 cmsg.subtype = CMSG_USBIF_FE_INTERFACE_CONNECT; 6.465 cmsg.length = sizeof(usbif_fe_interface_connect_t); 6.466 - up.shmem_frame = virt_to_machine(usbif) >> PAGE_SHIFT; 6.467 + up.shmem_frame = virt_to_machine(sring) >> PAGE_SHIFT; 6.468 memcpy(cmsg.msg, &up, sizeof(up)); 6.469 6.470 /* Tell the controller to bring up the interface. */ 6.471 @@ -1571,8 +1544,6 @@ static void usbif_status_change(usbif_fe 6.472 xhci->rh.ports = kmalloc (sizeof(xhci_port_t) * xhci->rh.numports, GFP_KERNEL); 6.473 memset(xhci->rh.ports, 0, sizeof(xhci_port_t) * xhci->rh.numports); 6.474 6.475 - printk("rh.dev @ %p\n", xhci->rh.dev); 6.476 - 6.477 usb_connect(xhci->rh.dev); 6.478 6.479 if (usb_new_device(xhci->rh.dev) != 0) { 6.480 @@ -1589,8 +1560,8 @@ static void usbif_status_change(usbif_fe 6.481 SA_SAMPLE_RANDOM, "usbif", xhci)) ) 6.482 printk(KERN_ALERT"usbfront request_irq failed (%ld)\n",rc); 6.483 6.484 - printk(KERN_INFO __FILE__ ": USB XHCI: SHM at %p (0x%lx), EVTCHN %d IRQ %d\n", 6.485 - xhci->usbif, virt_to_machine(xhci->usbif), xhci->evtchn, xhci->irq); 6.486 + DPRINTK(KERN_INFO __FILE__ ": USB XHCI: SHM at %p (0x%lx), EVTCHN %d IRQ %d\n", 6.487 + xhci->usb_ring.sring, virt_to_machine(xhci->usbif), xhci->evtchn, xhci->irq); 6.488 6.489 xhci->state = USBIF_STATE_CONNECTED; 6.490 6.491 @@ -1685,7 +1656,7 @@ static int __init xhci_hcd_init(void) 6.492 } 6.493 6.494 if (xhci->state != USBIF_STATE_CONNECTED) 6.495 - printk(KERN_INFO "Timeout connecting USB frontend driver!\n"); 6.496 + printk(KERN_WARNING "Timeout connecting USB frontend driver!\n"); 6.497 6.498 return 0; 6.499 6.500 @@ -1702,7 +1673,7 @@ errbuf_failed: 6.501 static void __exit xhci_hcd_cleanup(void) 6.502 { 6.503 if (kmem_cache_destroy(xhci_up_cachep)) 6.504 - printk(KERN_INFO "xhci: not all urb_priv's were freed\n"); 6.505 + printk(KERN_WARNING "xhci: not all urb_priv's were freed\n"); 6.506 6.507 // release_xhci(); do some calls here 6.508
7.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h Fri Feb 04 19:26:10 2005 +0000 7.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h Mon Feb 07 08:19:24 2005 +0000 7.3 @@ -104,7 +104,7 @@ struct xhci { 7.4 7.5 spinlock_t response_lock; 7.6 7.7 - usbif_t *usbif; 7.8 + usbif_front_ring_t usb_ring; 7.9 int usb_resp_cons; 7.10 }; 7.11
8.1 --- a/tools/libxc/Makefile Fri Feb 04 19:26:10 2005 +0000 8.2 +++ b/tools/libxc/Makefile Mon Feb 07 08:19:24 2005 +0000 8.3 @@ -1,3 +1,12 @@ 8.4 + 8.5 +ifndef BUILD_PIC_LIBS 8.6 +ifeq ($(wildcard /etc/debian_version),) 8.7 +BUILD_PIC_LIBS=n 8.8 +else 8.9 +BUILD_PIC_LIBS=y 8.10 +endif 8.11 +endif 8.12 + 8.13 INSTALL = install 8.14 INSTALL_PROG = $(INSTALL) -m0755 8.15 INSTALL_DATA = $(INSTALL) -m0644 8.16 @@ -5,7 +14,6 @@ INSTALL_DIR = $(INSTALL) -d -m0755 8.17 8.18 MAJOR = 3.0 8.19 MINOR = 0 8.20 -SONAME = libxc.so.$(MAJOR) 8.21 8.22 CC = gcc 8.23 8.24 @@ -40,9 +48,10 @@ CFLAGS += $(INCLUDES) -I. 8.25 CFLAGS += -Wp,-MD,.$(@F).d 8.26 DEPS = .*.d 8.27 8.28 -OBJS = $(patsubst %.c,%.o,$(SRCS)) 8.29 +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) 8.30 +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) 8.31 8.32 -LIB = libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) 8.33 +LIB := libxc.a libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) 8.34 8.35 all: check-for-zlib mk-symlinks 8.36 $(MAKE) $(LIB) 8.37 @@ -70,12 +79,13 @@ install: all 8.38 [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib 8.39 [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include 8.40 $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib 8.41 + $(INSTALL_DATA) libxc.a $(DESTDIR)/usr/lib 8.42 ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) 8.43 ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so 8.44 $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include 8.45 8.46 clean: 8.47 - rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) xen 8.48 + rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen 8.49 8.50 rpm: all 8.51 rm -rf staging 8.52 @@ -86,11 +96,23 @@ rpm: all 8.53 mv staging/i386/*.rpm . 8.54 rm -rf staging 8.55 8.56 -libxc.so: 8.57 - ln -sf libxc.so.$(MAJOR) $@ 8.58 -libxc.so.$(MAJOR): 8.59 - ln -sf libxc.so.$(MAJOR).$(MINOR) $@ 8.60 -libxc.so.$(MAJOR).$(MINOR): $(OBJS) 8.61 - $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -L../libxutil -lxutil -lz 8.62 +$(PIC_OBJS): %.opic: %.c 8.63 + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< 8.64 + 8.65 +libxc.a: $(OBJS) 8.66 + $(AR) rc $@ $^ 8.67 + 8.68 +libxc.so: libxc.so.$(MAJOR) 8.69 + ln -sf $< $@ 8.70 +libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR) 8.71 + ln -sf $< $@ 8.72 + 8.73 +ifeq ($(BUILD_PIC_LIBS),y) 8.74 +libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS) 8.75 + $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz 8.76 +else 8.77 +libxc.so.$(MAJOR).$(MINOR): $(LIB_OBJS) 8.78 + $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz 8.79 +endif 8.80 8.81 -include $(DEPS)
9.1 --- a/tools/libxutil/Makefile Fri Feb 04 19:26:10 2005 +0000 9.2 +++ b/tools/libxutil/Makefile Mon Feb 07 08:19:24 2005 +0000 9.3 @@ -1,3 +1,12 @@ 9.4 + 9.5 +ifndef BUILD_PIC_LIBS 9.6 +ifeq ($(wildcard /etc/debian_version),) 9.7 +BUILD_PIC_LIBS=n 9.8 +else 9.9 +BUILD_PIC_LIBS=y 9.10 +endif 9.11 +endif 9.12 + 9.13 XEN_ROOT = ../.. 9.14 INSTALL = install 9.15 INSTALL_DATA = $(INSTALL) -m0644 9.16 @@ -24,6 +33,7 @@ LIB_SRCS += sys_string.c 9.17 LIB_SRCS += util.c 9.18 9.19 LIB_OBJS := $(LIB_SRCS:.c=.o) 9.20 +PIC_OBJS := $(LIB_SRCS:.c=.opic) 9.21 9.22 CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing 9.23 9.24 @@ -33,25 +43,32 @@ DEPS = .*.d 9.25 9.26 MAJOR := 3.0 9.27 MINOR := 0 9.28 -LIB_NAME := libxutil 9.29 -LIB := $(LIB_NAME).so 9.30 -LIB += $(LIB_NAME).so.$(MAJOR) 9.31 -LIB += $(LIB_NAME).so.$(MAJOR).$(MINOR) 9.32 -LIB += $(LIB_NAME).a 9.33 +LIB := libxutil.so 9.34 +LIB += libxutil.so.$(MAJOR) 9.35 +LIB += libxutil.so.$(MAJOR).$(MINOR) 9.36 +LIB += libxutil.a 9.37 9.38 all: check-for-zlib 9.39 $(MAKE) $(LIB) 9.40 9.41 -$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) 9.42 +$(PIC_OBJS): %.opic: %.c 9.43 + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< 9.44 + 9.45 +libxutil.so: libxutil.so.$(MAJOR) 9.46 + ln -sf $^ $@ 9.47 + 9.48 +libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) 9.49 ln -sf $^ $@ 9.50 9.51 -$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) 9.52 - ln -sf $^ $@ 9.53 +ifeq ($(BUILD_PIC_LIBS),y) 9.54 +libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) 9.55 + $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ 9.56 +else 9.57 +libxutil.so.$(MAJOR).$(MINOR): $(LIB_OBJS) 9.58 + $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ 9.59 +endif 9.60 9.61 -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_OBJS) 9.62 - $(CC) -Wl,-soname -Wl,$(LIB_NAME).so.$(MAJOR) -shared -o $@ $^ 9.63 - 9.64 -$(LIB_NAME).a: $(LIB_OBJS) 9.65 +libxutil.a: $(LIB_OBJS) 9.66 $(AR) rc $@ $^ 9.67 9.68 check-for-zlib: 9.69 @@ -64,12 +81,13 @@ check-for-zlib: 9.70 9.71 install: all 9.72 [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib 9.73 - $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib 9.74 - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) 9.75 - ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so 9.76 + $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib 9.77 + $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/lib 9.78 + ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxutil.so.$(MAJOR) 9.79 + ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/lib/libxutil.so 9.80 9.81 clean: 9.82 - $(RM) *.a *.so *.so.* *.o *.rpm 9.83 + $(RM) *.a *.so* *.o *.opic *.rpm 9.84 $(RM) *~ 9.85 $(RM) $(DEPS) 9.86
10.1 --- a/tools/misc/Makefile Fri Feb 04 19:26:10 2005 +0000 10.2 +++ b/tools/misc/Makefile Mon Feb 07 08:19:24 2005 +0000 10.3 @@ -34,5 +34,8 @@ clean: 10.4 $(RM) *.o $(TARGETS) *~ 10.5 $(MAKE) -C miniterm clean 10.6 10.7 -%: %.c $(HDRS) Makefile 10.8 +%.o: %.c $(HDRS) Makefile 10.9 + $(CC) -c $(CFLAGS) -o $@ $< 10.10 + 10.11 +$(TARGETS): %: %.o Makefile 10.12 $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil
11.1 --- a/xen/Makefile Fri Feb 04 19:26:10 2005 +0000 11.2 +++ b/xen/Makefile Mon Feb 07 08:19:24 2005 +0000 11.3 @@ -54,8 +54,9 @@ clean: 11.4 $(MAKE) -C drivers 11.5 $(MAKE) -C arch/$(TARGET_ARCH) 11.6 11.7 +# drivers/char/console.o may contain static banner/compile info. Blow it away. 11.8 delete-unfresh-files: 11.9 - rm -f include/xen/banner.h include/xen/compile.h 11.10 + rm -f include/xen/banner.h include/xen/compile.h drivers/char/console.o 11.11 $(MAKE) -C arch/$(TARGET_ARCH) delete-unfresh-files 11.12 11.13 # compile.h contains dynamic build info. Rebuilt on every 'make' invocation.
12.1 --- a/xen/Rules.mk Fri Feb 04 19:26:10 2005 +0000 12.2 +++ b/xen/Rules.mk Mon Feb 07 08:19:24 2005 +0000 12.3 @@ -54,9 +54,9 @@ else 12.4 CFLAGS += -DVERBOSE 12.5 endif 12.6 12.7 -ifeq ($(debugger),y) 12.8 -CFLAGS += -DXEN_DEBUGGER 12.9 -endif 12.10 +#ifeq ($(debugger),y) 12.11 +#CFLAGS += -DXEN_DEBUGGER 12.12 +#endif 12.13 12.14 ifeq ($(perfc),y) 12.15 CFLAGS += -DPERF_COUNTERS
13.1 --- a/xen/arch/x86/Makefile Fri Feb 04 19:26:10 2005 +0000 13.2 +++ b/xen/arch/x86/Makefile Mon Feb 07 08:19:24 2005 +0000 13.3 @@ -1,11 +1,6 @@ 13.4 13.5 include $(BASEDIR)/Rules.mk 13.6 13.7 -ifneq ($(debugger),y) 13.8 -OBJS := $(subst pdb-linux.o,,$(OBJS)) 13.9 -OBJS := $(subst pdb-stub.o,,$(OBJS)) 13.10 -endif 13.11 - 13.12 OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S)) 13.13 OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c)) 13.14 OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c)) 13.15 @@ -41,9 +36,9 @@ clean: 13.16 rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32 13.17 rm -f x86_32/*.o x86_32/*~ x86_32/core 13.18 rm -f x86_64/*.o x86_64/*~ x86_64/core 13.19 + rm -f mtrr/*.o mtrr/*~ mtrr/core 13.20 13.21 -# setup.o contains bits of compile.h so it must be blown away 13.22 delete-unfresh-files: 13.23 - rm -f setup.o 13.24 + # nothing 13.25 13.26 .PHONY: default clean delete-unfresh-files
14.1 --- a/xen/arch/x86/boot/x86_32.S Fri Feb 04 19:26:10 2005 +0000 14.2 +++ b/xen/arch/x86/boot/x86_32.S Mon Feb 07 08:19:24 2005 +0000 14.3 @@ -169,7 +169,7 @@ 1: jmp 1b 14.4 /*** STACK LOCATION ***/ 14.5 14.6 ENTRY(stack_start) 14.7 - .long SYMBOL_NAME(cpu0_stack) + 8100 - __PAGE_OFFSET 14.8 + .long SYMBOL_NAME(cpu0_stack) + STACK_SIZE - 200 - __PAGE_OFFSET 14.9 .long __HYPERVISOR_DS 14.10 14.11 /*** DESCRIPTOR TABLES ***/
15.1 --- a/xen/arch/x86/boot/x86_64.S Fri Feb 04 19:26:10 2005 +0000 15.2 +++ b/xen/arch/x86/boot/x86_64.S Mon Feb 07 08:19:24 2005 +0000 15.3 @@ -211,7 +211,7 @@ SYMBOL_NAME(idt): 15.4 .quad SYMBOL_NAME(idt_table) 15.5 15.6 ENTRY(stack_start) 15.7 - .quad SYMBOL_NAME(cpu0_stack) + 8000 15.8 + .quad SYMBOL_NAME(cpu0_stack) + STACK_SIZE - 200 15.9 15.10 high_start: 15.11 .quad __high_start 15.12 @@ -248,12 +248,3 @@ ENTRY(cpu0_stack) # Initial stack is 15.13 .org 0x6000 15.14 ENTRY(stext) 15.15 ENTRY(_stext) 15.16 - 15.17 -.globl copy_from_user, copy_to_user, copy_user_generic 15.18 -copy_from_user: 15.19 -copy_to_user: 15.20 -copy_user_generic: 15.21 -.globl __get_user_1, __get_user_4, __get_user_8 15.22 -__get_user_1: 15.23 -__get_user_4: 15.24 -__get_user_8:
16.1 --- a/xen/arch/x86/dom0_ops.c Fri Feb 04 19:26:10 2005 +0000 16.2 +++ b/xen/arch/x86/dom0_ops.c Mon Feb 07 08:19:24 2005 +0000 16.3 @@ -15,7 +15,6 @@ 16.4 #include <xen/event.h> 16.5 #include <asm/domain_page.h> 16.6 #include <asm/msr.h> 16.7 -#include <asm/pdb.h> 16.8 #include <xen/trace.h> 16.9 #include <xen/console.h> 16.10 #include <asm/shadow.h> 16.11 @@ -216,7 +215,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 16.12 domid_t dom = op->u.getpageframeinfo2.domain; 16.13 unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array; 16.14 struct domain *d; 16.15 - unsigned long l_arr[GPF2_BATCH]; 16.16 + unsigned long *l_arr; 16.17 ret = -ESRCH; 16.18 16.19 if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) 16.20 @@ -227,6 +226,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 16.21 ret = -E2BIG; 16.22 break; 16.23 } 16.24 + 16.25 + l_arr = (unsigned long *)alloc_xenheap_page(); 16.26 16.27 ret = 0; 16.28 for( n = 0; n < num; ) 16.29 @@ -291,6 +292,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 16.30 n += j; 16.31 } 16.32 16.33 + free_xenheap_page((unsigned long)l_arr); 16.34 + 16.35 put_domain(d); 16.36 } 16.37 break; 16.38 @@ -341,49 +344,50 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 16.39 return ret; 16.40 } 16.41 16.42 -void arch_getdomaininfo_ctxt(struct exec_domain *d, full_execution_context_t *c) 16.43 +void arch_getdomaininfo_ctxt( 16.44 + struct exec_domain *ed, full_execution_context_t *c) 16.45 { 16.46 int i; 16.47 16.48 c->flags = 0; 16.49 memcpy(&c->cpu_ctxt, 16.50 - &d->thread.user_ctxt, 16.51 - sizeof(d->thread.user_ctxt)); 16.52 - if ( test_bit(EDF_DONEFPUINIT, &d->ed_flags) ) 16.53 + &ed->arch.user_ctxt, 16.54 + sizeof(ed->arch.user_ctxt)); 16.55 + if ( test_bit(EDF_DONEFPUINIT, &ed->ed_flags) ) 16.56 c->flags |= ECF_I387_VALID; 16.57 memcpy(&c->fpu_ctxt, 16.58 - &d->thread.i387, 16.59 - sizeof(d->thread.i387)); 16.60 + &ed->arch.i387, 16.61 + sizeof(ed->arch.i387)); 16.62 memcpy(&c->trap_ctxt, 16.63 - d->thread.traps, 16.64 - sizeof(d->thread.traps)); 16.65 + ed->arch.traps, 16.66 + sizeof(ed->arch.traps)); 16.67 #ifdef ARCH_HAS_FAST_TRAP 16.68 - if ( (d->thread.fast_trap_desc.a == 0) && 16.69 - (d->thread.fast_trap_desc.b == 0) ) 16.70 + if ( (ed->arch.fast_trap_desc.a == 0) && 16.71 + (ed->arch.fast_trap_desc.b == 0) ) 16.72 c->fast_trap_idx = 0; 16.73 else 16.74 c->fast_trap_idx = 16.75 - d->thread.fast_trap_idx; 16.76 + ed->arch.fast_trap_idx; 16.77 #endif 16.78 - c->ldt_base = d->mm.ldt_base; 16.79 - c->ldt_ents = d->mm.ldt_ents; 16.80 + c->ldt_base = ed->arch.ldt_base; 16.81 + c->ldt_ents = ed->arch.ldt_ents; 16.82 c->gdt_ents = 0; 16.83 - if ( GET_GDT_ADDRESS(d) == GDT_VIRT_START(d) ) 16.84 + if ( GET_GDT_ADDRESS(ed) == GDT_VIRT_START(ed) ) 16.85 { 16.86 for ( i = 0; i < 16; i++ ) 16.87 c->gdt_frames[i] = 16.88 - l1_pgentry_to_pagenr(d->mm.perdomain_ptes[i]); 16.89 - c->gdt_ents = GET_GDT_ENTRIES(d); 16.90 + l1_pgentry_to_pagenr(ed->arch.perdomain_ptes[i]); 16.91 + c->gdt_ents = GET_GDT_ENTRIES(ed); 16.92 } 16.93 - c->guestos_ss = d->thread.guestos_ss; 16.94 - c->guestos_esp = d->thread.guestos_sp; 16.95 + c->guestos_ss = ed->arch.guestos_ss; 16.96 + c->guestos_esp = ed->arch.guestos_sp; 16.97 c->pt_base = 16.98 - pagetable_val(d->mm.pagetable); 16.99 + pagetable_val(ed->arch.pagetable); 16.100 memcpy(c->debugreg, 16.101 - d->thread.debugreg, 16.102 - sizeof(d->thread.debugreg)); 16.103 - c->event_callback_cs = d->thread.event_selector; 16.104 - c->event_callback_eip = d->thread.event_address; 16.105 - c->failsafe_callback_cs = d->thread.failsafe_selector; 16.106 - c->failsafe_callback_eip = d->thread.failsafe_address; 16.107 + ed->arch.debugreg, 16.108 + sizeof(ed->arch.debugreg)); 16.109 + c->event_callback_cs = ed->arch.event_selector; 16.110 + c->event_callback_eip = ed->arch.event_address; 16.111 + c->failsafe_callback_cs = ed->arch.failsafe_selector; 16.112 + c->failsafe_callback_eip = ed->arch.failsafe_address; 16.113 }
17.1 --- a/xen/arch/x86/domain.c Fri Feb 04 19:26:10 2005 +0000 17.2 +++ b/xen/arch/x86/domain.c Mon Feb 07 08:19:24 2005 +0000 17.3 @@ -1,3 +1,4 @@ 17.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 17.5 /****************************************************************************** 17.6 * arch/x86/domain.c 17.7 * 17.8 @@ -231,7 +232,7 @@ void arch_free_exec_domain_struct(struct 17.9 17.10 void free_perdomain_pt(struct domain *d) 17.11 { 17.12 - free_xenheap_page((unsigned long)d->mm_perdomain_pt); 17.13 + free_xenheap_page((unsigned long)d->arch.mm_perdomain_pt); 17.14 } 17.15 17.16 static void continue_idle_task(struct exec_domain *ed) 17.17 @@ -248,15 +249,15 @@ void arch_do_createdomain(struct exec_do 17.18 { 17.19 struct domain *d = ed->domain; 17.20 17.21 - SET_DEFAULT_FAST_TRAP(&ed->thread); 17.22 + SET_DEFAULT_FAST_TRAP(&ed->arch); 17.23 17.24 if ( d->id == IDLE_DOMAIN_ID ) 17.25 { 17.26 - ed->thread.schedule_tail = continue_idle_task; 17.27 + ed->arch.schedule_tail = continue_idle_task; 17.28 } 17.29 else 17.30 { 17.31 - ed->thread.schedule_tail = continue_nonidle_task; 17.32 + ed->arch.schedule_tail = continue_nonidle_task; 17.33 17.34 d->shared_info = (void *)alloc_xenheap_page(); 17.35 memset(d->shared_info, 0, PAGE_SIZE); 17.36 @@ -265,29 +266,37 @@ void arch_do_createdomain(struct exec_do 17.37 machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 17.38 PAGE_SHIFT] = INVALID_P2M_ENTRY; 17.39 17.40 - d->mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page(); 17.41 - memset(d->mm_perdomain_pt, 0, PAGE_SIZE); 17.42 - machine_to_phys_mapping[virt_to_phys(d->mm_perdomain_pt) >> 17.43 + d->arch.mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page(); 17.44 + memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE); 17.45 + machine_to_phys_mapping[virt_to_phys(d->arch.mm_perdomain_pt) >> 17.46 PAGE_SHIFT] = INVALID_P2M_ENTRY; 17.47 - ed->mm.perdomain_ptes = d->mm_perdomain_pt; 17.48 + ed->arch.perdomain_ptes = d->arch.mm_perdomain_pt; 17.49 } 17.50 } 17.51 17.52 +void arch_do_boot_vcpu(struct exec_domain *ed) 17.53 +{ 17.54 + struct domain *d = ed->domain; 17.55 + ed->arch.schedule_tail = d->exec_domain[0]->arch.schedule_tail; 17.56 + ed->arch.perdomain_ptes = 17.57 + d->arch.mm_perdomain_pt + (ed->eid << PDPT_VCPU_SHIFT); 17.58 +} 17.59 + 17.60 #ifdef CONFIG_VMX 17.61 void arch_vmx_do_resume(struct exec_domain *ed) 17.62 { 17.63 - u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->thread.arch_vmx.vmcs); 17.64 + u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->arch.arch_vmx.vmcs); 17.65 17.66 - load_vmcs(&ed->thread.arch_vmx, vmcs_phys_ptr); 17.67 + load_vmcs(&ed->arch.arch_vmx, vmcs_phys_ptr); 17.68 vmx_do_resume(ed); 17.69 reset_stack_and_jump(vmx_asm_do_resume); 17.70 } 17.71 17.72 void arch_vmx_do_launch(struct exec_domain *ed) 17.73 { 17.74 - u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->thread.arch_vmx.vmcs); 17.75 + u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->arch.arch_vmx.vmcs); 17.76 17.77 - load_vmcs(&ed->thread.arch_vmx, vmcs_phys_ptr); 17.78 + load_vmcs(&ed->arch.arch_vmx, vmcs_phys_ptr); 17.79 vmx_do_launch(ed); 17.80 reset_stack_and_jump(vmx_asm_do_launch); 17.81 } 17.82 @@ -297,7 +306,6 @@ static void monitor_mk_pagetable(struct 17.83 unsigned long mpfn; 17.84 l2_pgentry_t *mpl2e; 17.85 struct pfn_info *mpfn_info; 17.86 - struct mm_struct *m = &ed->mm; 17.87 struct domain *d = ed->domain; 17.88 17.89 mpfn_info = alloc_domheap_page(NULL); 17.90 @@ -311,11 +319,11 @@ static void monitor_mk_pagetable(struct 17.91 &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 17.92 HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t)); 17.93 17.94 - m->monitor_table = mk_pagetable(mpfn << L1_PAGETABLE_SHIFT); 17.95 - m->shadow_mode = SHM_full_32; 17.96 + ed->arch.monitor_table = mk_pagetable(mpfn << L1_PAGETABLE_SHIFT); 17.97 + d->arch.shadow_mode = SHM_full_32; 17.98 17.99 mpl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = 17.100 - mk_l2_pgentry((__pa(d->mm_perdomain_pt) & PAGE_MASK) 17.101 + mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK) 17.102 | __PAGE_HYPERVISOR); 17.103 17.104 unmap_domain_mem(mpl2e); 17.105 @@ -326,13 +334,12 @@ static void monitor_mk_pagetable(struct 17.106 */ 17.107 static void monitor_rm_pagetable(struct exec_domain *ed) 17.108 { 17.109 - struct mm_struct *m = &ed->mm; 17.110 l2_pgentry_t *mpl2e; 17.111 unsigned long mpfn; 17.112 17.113 - ASSERT( pagetable_val(m->monitor_table) ); 17.114 + ASSERT( pagetable_val(ed->arch.monitor_table) ); 17.115 17.116 - mpl2e = (l2_pgentry_t *) map_domain_mem(pagetable_val(m->monitor_table)); 17.117 + mpl2e = (l2_pgentry_t *) map_domain_mem(pagetable_val(ed->arch.monitor_table)); 17.118 /* 17.119 * First get the pfn for guest_pl2e_cache by looking at monitor_table 17.120 */ 17.121 @@ -345,10 +352,10 @@ static void monitor_rm_pagetable(struct 17.122 /* 17.123 * Then free monitor_table. 17.124 */ 17.125 - mpfn = (pagetable_val(m->monitor_table)) >> PAGE_SHIFT; 17.126 + mpfn = (pagetable_val(ed->arch.monitor_table)) >> PAGE_SHIFT; 17.127 free_domheap_page(&frame_table[mpfn]); 17.128 17.129 - m->monitor_table = mk_pagetable(0); 17.130 + ed->arch.monitor_table = mk_pagetable(0); 17.131 } 17.132 17.133 static int vmx_final_setup_guestos(struct exec_domain *ed, 17.134 @@ -368,21 +375,21 @@ static int vmx_final_setup_guestos(struc 17.135 return -ENOMEM; 17.136 } 17.137 17.138 - memset(&ed->thread.arch_vmx, 0, sizeof (struct arch_vmx_struct)); 17.139 + memset(&ed->arch.arch_vmx, 0, sizeof (struct arch_vmx_struct)); 17.140 17.141 - ed->thread.arch_vmx.vmcs = vmcs; 17.142 - error = construct_vmcs(&ed->thread.arch_vmx, context, full_context, VMCS_USE_HOST_ENV); 17.143 + ed->arch.arch_vmx.vmcs = vmcs; 17.144 + error = construct_vmcs(&ed->arch.arch_vmx, context, full_context, VMCS_USE_HOST_ENV); 17.145 if (error < 0) { 17.146 printk("Failed to construct a new VMCS\n"); 17.147 goto out; 17.148 } 17.149 17.150 monitor_mk_pagetable(ed); 17.151 - ed->thread.schedule_tail = arch_vmx_do_launch; 17.152 - clear_bit(VMX_CPU_STATE_PG_ENABLED, &ed->thread.arch_vmx.cpu_state); 17.153 + ed->arch.schedule_tail = arch_vmx_do_launch; 17.154 + clear_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state); 17.155 17.156 #if defined (__i386) 17.157 - ed->thread.arch_vmx.vmx_platform.real_mode_data = 17.158 + ed->arch.arch_vmx.vmx_platform.real_mode_data = 17.159 (unsigned long *) context->esi; 17.160 #endif 17.161 17.162 @@ -399,12 +406,13 @@ static int vmx_final_setup_guestos(struc 17.163 17.164 out: 17.165 free_vmcs(vmcs); 17.166 - ed->thread.arch_vmx.vmcs = 0; 17.167 + ed->arch.arch_vmx.vmcs = 0; 17.168 return error; 17.169 } 17.170 #endif 17.171 17.172 -int arch_final_setup_guestos(struct exec_domain *d, full_execution_context_t *c) 17.173 +int arch_final_setup_guestos( 17.174 + struct exec_domain *d, full_execution_context_t *c) 17.175 { 17.176 unsigned long phys_basetab; 17.177 int i, rc; 17.178 @@ -413,13 +421,13 @@ int arch_final_setup_guestos(struct exec 17.179 if ( c->flags & ECF_I387_VALID ) 17.180 set_bit(EDF_DONEFPUINIT, &d->ed_flags); 17.181 17.182 - memcpy(&d->thread.user_ctxt, 17.183 + memcpy(&d->arch.user_ctxt, 17.184 &c->cpu_ctxt, 17.185 - sizeof(d->thread.user_ctxt)); 17.186 + sizeof(d->arch.user_ctxt)); 17.187 17.188 /* Clear IOPL for unprivileged domains. */ 17.189 if (!IS_PRIV(d->domain)) 17.190 - d->thread.user_ctxt.eflags &= 0xffffcfff; 17.191 + d->arch.user_ctxt.eflags &= 0xffffcfff; 17.192 17.193 /* 17.194 * This is sufficient! If the descriptor DPL differs from CS RPL then we'll 17.195 @@ -427,37 +435,37 @@ int arch_final_setup_guestos(struct exec 17.196 * If SS RPL or DPL differs from CS RPL then we'll #GP. 17.197 */ 17.198 if (!(c->flags & ECF_VMX_GUEST)) 17.199 - if ( ((d->thread.user_ctxt.cs & 3) == 0) || 17.200 - ((d->thread.user_ctxt.ss & 3) == 0) ) 17.201 + if ( ((d->arch.user_ctxt.cs & 3) == 0) || 17.202 + ((d->arch.user_ctxt.ss & 3) == 0) ) 17.203 return -EINVAL; 17.204 17.205 - memcpy(&d->thread.i387, 17.206 + memcpy(&d->arch.i387, 17.207 &c->fpu_ctxt, 17.208 - sizeof(d->thread.i387)); 17.209 + sizeof(d->arch.i387)); 17.210 17.211 - memcpy(d->thread.traps, 17.212 + memcpy(d->arch.traps, 17.213 &c->trap_ctxt, 17.214 - sizeof(d->thread.traps)); 17.215 + sizeof(d->arch.traps)); 17.216 17.217 if ( (rc = (int)set_fast_trap(d, c->fast_trap_idx)) != 0 ) 17.218 return rc; 17.219 17.220 - d->mm.ldt_base = c->ldt_base; 17.221 - d->mm.ldt_ents = c->ldt_ents; 17.222 + d->arch.ldt_base = c->ldt_base; 17.223 + d->arch.ldt_ents = c->ldt_ents; 17.224 17.225 - d->thread.guestos_ss = c->guestos_ss; 17.226 - d->thread.guestos_sp = c->guestos_esp; 17.227 + d->arch.guestos_ss = c->guestos_ss; 17.228 + d->arch.guestos_sp = c->guestos_esp; 17.229 17.230 for ( i = 0; i < 8; i++ ) 17.231 (void)set_debugreg(d, i, c->debugreg[i]); 17.232 17.233 - d->thread.event_selector = c->event_callback_cs; 17.234 - d->thread.event_address = c->event_callback_eip; 17.235 - d->thread.failsafe_selector = c->failsafe_callback_cs; 17.236 - d->thread.failsafe_address = c->failsafe_callback_eip; 17.237 + d->arch.event_selector = c->event_callback_cs; 17.238 + d->arch.event_address = c->event_callback_eip; 17.239 + d->arch.failsafe_selector = c->failsafe_callback_cs; 17.240 + d->arch.failsafe_address = c->failsafe_callback_eip; 17.241 17.242 phys_basetab = c->pt_base; 17.243 - d->mm.pagetable = mk_pagetable(phys_basetab); 17.244 + d->arch.pagetable = mk_pagetable(phys_basetab); 17.245 if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d->domain, 17.246 PGT_base_page_table) ) 17.247 return -EINVAL; 17.248 @@ -487,7 +495,7 @@ void new_thread(struct exec_domain *d, 17.249 unsigned long start_stack, 17.250 unsigned long start_info) 17.251 { 17.252 - execution_context_t *ec = &d->thread.user_ctxt; 17.253 + execution_context_t *ec = &d->arch.user_ctxt; 17.254 17.255 /* 17.256 * Initial register values: 17.257 @@ -512,19 +520,18 @@ void new_thread(struct exec_domain *d, 17.258 /* 17.259 * This special macro can be used to load a debugging register 17.260 */ 17.261 -#define loaddebug(thread,register) \ 17.262 - __asm__("mov %0,%%db" #register \ 17.263 +#define loaddebug(_ed,_reg) \ 17.264 + __asm__("mov %0,%%db" #_reg \ 17.265 : /* no output */ \ 17.266 - :"r" (thread->debugreg[register])) 17.267 + :"r" ((_ed)->debugreg[_reg])) 17.268 17.269 void switch_to(struct exec_domain *prev_p, struct exec_domain *next_p) 17.270 { 17.271 - struct thread_struct *next = &next_p->thread; 17.272 struct tss_struct *tss = init_tss + smp_processor_id(); 17.273 execution_context_t *stack_ec = get_execution_context(); 17.274 int i; 17.275 #ifdef CONFIG_VMX 17.276 - unsigned long vmx_domain = next_p->thread.arch_vmx.flags; 17.277 + unsigned long vmx_domain = next_p->arch.arch_vmx.flags; 17.278 #endif 17.279 17.280 __cli(); 17.281 @@ -532,73 +539,73 @@ void switch_to(struct exec_domain *prev_ 17.282 /* Switch guest general-register state. */ 17.283 if ( !is_idle_task(prev_p->domain) ) 17.284 { 17.285 - memcpy(&prev_p->thread.user_ctxt, 17.286 + memcpy(&prev_p->arch.user_ctxt, 17.287 stack_ec, 17.288 sizeof(*stack_ec)); 17.289 unlazy_fpu(prev_p); 17.290 - CLEAR_FAST_TRAP(&prev_p->thread); 17.291 + CLEAR_FAST_TRAP(&prev_p->arch); 17.292 } 17.293 17.294 if ( !is_idle_task(next_p->domain) ) 17.295 { 17.296 memcpy(stack_ec, 17.297 - &next_p->thread.user_ctxt, 17.298 + &next_p->arch.user_ctxt, 17.299 sizeof(*stack_ec)); 17.300 17.301 /* Maybe switch the debug registers. */ 17.302 - if ( unlikely(next->debugreg[7]) ) 17.303 + if ( unlikely(next_p->arch.debugreg[7]) ) 17.304 { 17.305 - loaddebug(next, 0); 17.306 - loaddebug(next, 1); 17.307 - loaddebug(next, 2); 17.308 - loaddebug(next, 3); 17.309 + loaddebug(&next_p->arch, 0); 17.310 + loaddebug(&next_p->arch, 1); 17.311 + loaddebug(&next_p->arch, 2); 17.312 + loaddebug(&next_p->arch, 3); 17.313 /* no 4 and 5 */ 17.314 - loaddebug(next, 6); 17.315 - loaddebug(next, 7); 17.316 + loaddebug(&next_p->arch, 6); 17.317 + loaddebug(&next_p->arch, 7); 17.318 } 17.319 17.320 #ifdef CONFIG_VMX 17.321 if ( vmx_domain ) 17.322 { 17.323 /* Switch page tables. */ 17.324 - write_ptbase(&next_p->mm); 17.325 + write_ptbase(next_p); 17.326 17.327 set_current(next_p); 17.328 /* Switch GDT and LDT. */ 17.329 - __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->mm.gdt)); 17.330 + __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->arch.gdt)); 17.331 17.332 __sti(); 17.333 return; 17.334 } 17.335 #endif 17.336 17.337 - SET_FAST_TRAP(&next_p->thread); 17.338 + SET_FAST_TRAP(&next_p->arch); 17.339 17.340 #ifdef __i386__ 17.341 /* Switch the guest OS ring-1 stack. */ 17.342 - tss->esp1 = next->guestos_sp; 17.343 - tss->ss1 = next->guestos_ss; 17.344 + tss->esp1 = next_p->arch.guestos_sp; 17.345 + tss->ss1 = next_p->arch.guestos_ss; 17.346 #endif 17.347 17.348 /* Switch page tables. */ 17.349 - write_ptbase(&next_p->mm); 17.350 + write_ptbase(next_p); 17.351 } 17.352 17.353 - if ( unlikely(prev_p->thread.io_bitmap != NULL) ) 17.354 + if ( unlikely(prev_p->arch.io_bitmap != NULL) ) 17.355 { 17.356 - for ( i = 0; i < sizeof(prev_p->thread.io_bitmap_sel) * 8; i++ ) 17.357 - if ( !test_bit(i, &prev_p->thread.io_bitmap_sel) ) 17.358 + for ( i = 0; i < sizeof(prev_p->arch.io_bitmap_sel) * 8; i++ ) 17.359 + if ( !test_bit(i, &prev_p->arch.io_bitmap_sel) ) 17.360 memset(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT], 17.361 ~0U, IOBMP_BYTES_PER_SELBIT); 17.362 tss->bitmap = IOBMP_INVALID_OFFSET; 17.363 } 17.364 17.365 - if ( unlikely(next_p->thread.io_bitmap != NULL) ) 17.366 + if ( unlikely(next_p->arch.io_bitmap != NULL) ) 17.367 { 17.368 - for ( i = 0; i < sizeof(next_p->thread.io_bitmap_sel) * 8; i++ ) 17.369 - if ( !test_bit(i, &next_p->thread.io_bitmap_sel) ) 17.370 + for ( i = 0; i < sizeof(next_p->arch.io_bitmap_sel) * 8; i++ ) 17.371 + if ( !test_bit(i, &next_p->arch.io_bitmap_sel) ) 17.372 memcpy(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT], 17.373 - &next_p->thread.io_bitmap[i * IOBMP_BYTES_PER_SELBIT], 17.374 + &next_p->arch.io_bitmap[i * IOBMP_BYTES_PER_SELBIT], 17.375 IOBMP_BYTES_PER_SELBIT); 17.376 tss->bitmap = IOBMP_OFFSET; 17.377 } 17.378 @@ -606,7 +613,7 @@ void switch_to(struct exec_domain *prev_ 17.379 set_current(next_p); 17.380 17.381 /* Switch GDT and LDT. */ 17.382 - __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->mm.gdt)); 17.383 + __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->arch.gdt)); 17.384 load_LDT(next_p); 17.385 17.386 __sti(); 17.387 @@ -724,9 +731,9 @@ static void vmx_domain_relinquish_memory 17.388 /* 17.389 * Free VMCS 17.390 */ 17.391 - ASSERT(ed->thread.arch_vmx.vmcs); 17.392 - free_vmcs(ed->thread.arch_vmx.vmcs); 17.393 - ed->thread.arch_vmx.vmcs = 0; 17.394 + ASSERT(ed->arch.arch_vmx.vmcs); 17.395 + free_vmcs(ed->arch.arch_vmx.vmcs); 17.396 + ed->arch.arch_vmx.vmcs = 0; 17.397 17.398 monitor_rm_pagetable(ed); 17.399 17.400 @@ -737,7 +744,7 @@ static void vmx_domain_relinquish_memory 17.401 for (i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++) { 17.402 unsigned long l1e; 17.403 17.404 - l1e = l1_pgentry_val(d->mm_perdomain_pt[i]); 17.405 + l1e = l1_pgentry_val(d->arch.mm_perdomain_pt[i]); 17.406 if (l1e & _PAGE_PRESENT) { 17.407 pfn = l1e >> PAGE_SHIFT; 17.408 free_domheap_page(&frame_table[pfn]); 17.409 @@ -761,8 +768,8 @@ void domain_relinquish_memory(struct dom 17.410 /* Drop the in-use reference to the page-table base. */ 17.411 for_each_exec_domain ( d, ed ) 17.412 { 17.413 - if ( pagetable_val(ed->mm.pagetable) != 0 ) 17.414 - put_page_and_type(&frame_table[pagetable_val(ed->mm.pagetable) >> 17.415 + if ( pagetable_val(ed->arch.pagetable) != 0 ) 17.416 + put_page_and_type(&frame_table[pagetable_val(ed->arch.pagetable) >> 17.417 PAGE_SHIFT]); 17.418 } 17.419
18.1 --- a/xen/arch/x86/i387.c Fri Feb 04 19:26:10 2005 +0000 18.2 +++ b/xen/arch/x86/i387.c Mon Feb 07 08:19:24 2005 +0000 18.3 @@ -1,3 +1,4 @@ 18.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 18.5 /* 18.6 * linux/arch/i386/kernel/i387.c 18.7 * 18.8 @@ -24,10 +25,10 @@ static inline void __save_init_fpu( stru 18.9 { 18.10 if ( cpu_has_fxsr ) { 18.11 asm volatile( "fxsave %0 ; fnclex" 18.12 - : "=m" (tsk->thread.i387) ); 18.13 + : "=m" (tsk->arch.i387) ); 18.14 } else { 18.15 asm volatile( "fnsave %0 ; fwait" 18.16 - : "=m" (tsk->thread.i387) ); 18.17 + : "=m" (tsk->arch.i387) ); 18.18 } 18.19 clear_bit(EDF_USEDFPU, &tsk->ed_flags); 18.20 } 18.21 @@ -48,9 +49,9 @@ void restore_fpu( struct exec_domain *ts 18.22 { 18.23 if ( cpu_has_fxsr ) { 18.24 asm volatile( "fxrstor %0" 18.25 - : : "m" (tsk->thread.i387) ); 18.26 + : : "m" (tsk->arch.i387) ); 18.27 } else { 18.28 asm volatile( "frstor %0" 18.29 - : : "m" (tsk->thread.i387) ); 18.30 + : : "m" (tsk->arch.i387) ); 18.31 } 18.32 }
19.1 --- a/xen/arch/x86/idle0_task.c Fri Feb 04 19:26:10 2005 +0000 19.2 +++ b/xen/arch/x86/idle0_task.c Mon Feb 07 08:19:24 2005 +0000 19.3 @@ -1,24 +1,19 @@ 19.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 19.5 + 19.6 #include <xen/config.h> 19.7 #include <xen/sched.h> 19.8 #include <asm/desc.h> 19.9 19.10 -#define IDLE0_EXEC_DOMAIN(_ed,_d) \ 19.11 -{ \ 19.12 - processor: 0, \ 19.13 - mm: IDLE0_MM, \ 19.14 - thread: INIT_THREAD, \ 19.15 - domain: (_d) \ 19.16 -} 19.17 +struct domain idle0_domain = { 19.18 + id: IDLE_DOMAIN_ID, 19.19 + d_flags: 1<<DF_IDLETASK, 19.20 + refcnt: ATOMIC_INIT(1) 19.21 +}; 19.22 19.23 -#define IDLE0_DOMAIN(_t) \ 19.24 -{ \ 19.25 - id: IDLE_DOMAIN_ID, \ 19.26 - d_flags: 1<<DF_IDLETASK, \ 19.27 - refcnt: ATOMIC_INIT(1) \ 19.28 -} 19.29 - 19.30 -struct domain idle0_domain = IDLE0_DOMAIN(idle0_domain); 19.31 -struct exec_domain idle0_exec_domain = IDLE0_EXEC_DOMAIN(idle0_exec_domain, 19.32 - &idle0_domain); 19.33 +struct exec_domain idle0_exec_domain = { 19.34 + processor: 0, 19.35 + domain: &idle0_domain, 19.36 + arch: IDLE0_ARCH_EXEC_DOMAIN 19.37 +}; 19.38 19.39 struct tss_struct init_tss[NR_CPUS];
20.1 --- a/xen/arch/x86/memory.c Fri Feb 04 19:26:10 2005 +0000 20.2 +++ b/xen/arch/x86/memory.c Mon Feb 07 08:19:24 2005 +0000 20.3 @@ -1,3 +1,4 @@ 20.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 20.5 /****************************************************************************** 20.6 * arch/x86/memory.c 20.7 * 20.8 @@ -193,19 +194,41 @@ void arch_init_memory(void) 20.9 subarch_init_memory(dom_xen); 20.10 } 20.11 20.12 +void write_ptbase(struct exec_domain *ed) 20.13 +{ 20.14 + struct domain *d = ed->domain; 20.15 + unsigned long pa; 20.16 + 20.17 +#ifdef CONFIG_VMX 20.18 + if ( unlikely(d->arch.shadow_mode) ) 20.19 + pa = ((d->arch.shadow_mode == SHM_full_32) ? 20.20 + pagetable_val(ed->arch.monitor_table) : 20.21 + pagetable_val(ed->arch.shadow_table)); 20.22 + else 20.23 + pa = pagetable_val(ed->arch.pagetable); 20.24 +#else 20.25 + if ( unlikely(d->arch.shadow_mode) ) 20.26 + pa = pagetable_val(ed->arch.shadow_table); 20.27 + else 20.28 + pa = pagetable_val(ed->arch.pagetable); 20.29 +#endif 20.30 + 20.31 + write_cr3(pa); 20.32 +} 20.33 + 20.34 static void __invalidate_shadow_ldt(struct exec_domain *d) 20.35 { 20.36 int i; 20.37 unsigned long pfn; 20.38 struct pfn_info *page; 20.39 20.40 - d->mm.shadow_ldt_mapcnt = 0; 20.41 + d->arch.shadow_ldt_mapcnt = 0; 20.42 20.43 for ( i = 16; i < 32; i++ ) 20.44 { 20.45 - pfn = l1_pgentry_to_pagenr(d->mm.perdomain_ptes[i]); 20.46 + pfn = l1_pgentry_to_pagenr(d->arch.perdomain_ptes[i]); 20.47 if ( pfn == 0 ) continue; 20.48 - d->mm.perdomain_ptes[i] = mk_l1_pgentry(0); 20.49 + d->arch.perdomain_ptes[i] = mk_l1_pgentry(0); 20.50 page = &frame_table[pfn]; 20.51 ASSERT_PAGE_IS_TYPE(page, PGT_ldt_page); 20.52 ASSERT_PAGE_IS_DOMAIN(page, d->domain); 20.53 @@ -219,7 +242,7 @@ static void __invalidate_shadow_ldt(stru 20.54 20.55 static inline void invalidate_shadow_ldt(struct exec_domain *d) 20.56 { 20.57 - if ( d->mm.shadow_ldt_mapcnt != 0 ) 20.58 + if ( d->arch.shadow_ldt_mapcnt != 0 ) 20.59 __invalidate_shadow_ldt(d); 20.60 } 20.61 20.62 @@ -252,7 +275,7 @@ int map_ldt_shadow_page(unsigned int off 20.63 if ( unlikely(in_irq()) ) 20.64 BUG(); 20.65 20.66 - __get_user(l1e, (unsigned long *)&linear_pg_table[(ed->mm.ldt_base >> 20.67 + __get_user(l1e, (unsigned long *)&linear_pg_table[(ed->arch.ldt_base >> 20.68 PAGE_SHIFT) + off]); 20.69 20.70 if ( unlikely(!(l1e & _PAGE_PRESENT)) || 20.71 @@ -260,8 +283,8 @@ int map_ldt_shadow_page(unsigned int off 20.72 d, PGT_ldt_page)) ) 20.73 return 0; 20.74 20.75 - ed->mm.perdomain_ptes[off + 16] = mk_l1_pgentry(l1e | _PAGE_RW); 20.76 - ed->mm.shadow_ldt_mapcnt++; 20.77 + ed->arch.perdomain_ptes[off + 16] = mk_l1_pgentry(l1e | _PAGE_RW); 20.78 + ed->arch.shadow_ldt_mapcnt++; 20.79 20.80 return 1; 20.81 } 20.82 @@ -512,7 +535,7 @@ static int alloc_l2_table(struct pfn_inf 20.83 pl2e[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = 20.84 mk_l2_pgentry((page_nr << PAGE_SHIFT) | __PAGE_HYPERVISOR); 20.85 pl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = 20.86 - mk_l2_pgentry(__pa(page_get_owner(page)->mm_perdomain_pt) | 20.87 + mk_l2_pgentry(__pa(page_get_owner(page)->arch.mm_perdomain_pt) | 20.88 __PAGE_HYPERVISOR); 20.89 #endif 20.90 20.91 @@ -747,11 +770,11 @@ void free_page_type(struct pfn_info *pag 20.92 BUG(); 20.93 } 20.94 20.95 - if ( unlikely(d->exec_domain[0]->mm.shadow_mode) && 20.96 - (get_shadow_status(&d->exec_domain[0]->mm, page_to_pfn(page)) & PSH_shadowed) ) 20.97 + if ( unlikely(d->arch.shadow_mode) && 20.98 + (get_shadow_status(d, page_to_pfn(page)) & PSH_shadowed) ) 20.99 { 20.100 unshadow_table(page_to_pfn(page), type); 20.101 - put_shadow_status(&d->exec_domain[0]->mm); 20.102 + put_shadow_status(d); 20.103 } 20.104 } 20.105 20.106 @@ -922,12 +945,12 @@ int new_guest_cr3(unsigned long pfn) 20.107 invalidate_shadow_ldt(ed); 20.108 20.109 percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB; 20.110 - old_base_pfn = pagetable_val(ed->mm.pagetable) >> PAGE_SHIFT; 20.111 - ed->mm.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 20.112 + old_base_pfn = pagetable_val(ed->arch.pagetable) >> PAGE_SHIFT; 20.113 + ed->arch.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 20.114 20.115 - shadow_mk_pagetable(&ed->mm); 20.116 + shadow_mk_pagetable(ed); 20.117 20.118 - write_ptbase(&ed->mm); 20.119 + write_ptbase(ed); 20.120 20.121 put_page_and_type(&frame_table[old_base_pfn]); 20.122 } 20.123 @@ -1038,12 +1061,12 @@ static int do_extended_command(unsigned 20.124 okay = 0; 20.125 MEM_LOG("Bad args to SET_LDT: ptr=%08lx, ents=%08lx", ptr, ents); 20.126 } 20.127 - else if ( (ed->mm.ldt_ents != ents) || 20.128 - (ed->mm.ldt_base != ptr) ) 20.129 + else if ( (ed->arch.ldt_ents != ents) || 20.130 + (ed->arch.ldt_base != ptr) ) 20.131 { 20.132 invalidate_shadow_ldt(ed); 20.133 - ed->mm.ldt_base = ptr; 20.134 - ed->mm.ldt_ents = ents; 20.135 + ed->arch.ldt_base = ptr; 20.136 + ed->arch.ldt_ents = ents; 20.137 load_LDT(ed); 20.138 percpu_info[cpu].deferred_ops &= ~DOP_RELOAD_LDT; 20.139 if ( ents != 0 ) 20.140 @@ -1409,13 +1432,13 @@ int do_mmu_update( 20.141 okay = mod_l1_entry((l1_pgentry_t *)va, 20.142 mk_l1_pgentry(req.val)); 20.143 20.144 - if ( unlikely(ed->mm.shadow_mode) && okay && 20.145 - (get_shadow_status(&ed->mm, page-frame_table) & 20.146 + if ( unlikely(d->arch.shadow_mode) && okay && 20.147 + (get_shadow_status(d, page-frame_table) & 20.148 PSH_shadowed) ) 20.149 { 20.150 shadow_l1_normal_pt_update( 20.151 req.ptr, req.val, &prev_spfn, &prev_spl1e); 20.152 - put_shadow_status(&ed->mm); 20.153 + put_shadow_status(d); 20.154 } 20.155 20.156 put_page_type(page); 20.157 @@ -1428,12 +1451,12 @@ int do_mmu_update( 20.158 mk_l2_pgentry(req.val), 20.159 pfn); 20.160 20.161 - if ( unlikely(ed->mm.shadow_mode) && okay && 20.162 - (get_shadow_status(&ed->mm, page-frame_table) & 20.163 + if ( unlikely(d->arch.shadow_mode) && okay && 20.164 + (get_shadow_status(d, page-frame_table) & 20.165 PSH_shadowed) ) 20.166 { 20.167 shadow_l2_normal_pt_update(req.ptr, req.val); 20.168 - put_shadow_status(&ed->mm); 20.169 + put_shadow_status(d); 20.170 } 20.171 20.172 put_page_type(page); 20.173 @@ -1466,9 +1489,9 @@ int do_mmu_update( 20.174 * If in log-dirty mode, mark the corresponding pseudo-physical 20.175 * page as dirty. 20.176 */ 20.177 - if ( unlikely(ed->mm.shadow_mode == SHM_logdirty) && 20.178 - mark_dirty(&ed->mm, pfn) ) 20.179 - ed->mm.shadow_dirty_block_count++; 20.180 + if ( unlikely(d->arch.shadow_mode == SHM_logdirty) && 20.181 + mark_dirty(d, pfn) ) 20.182 + d->arch.shadow_dirty_block_count++; 20.183 20.184 put_page(&frame_table[pfn]); 20.185 break; 20.186 @@ -1555,11 +1578,11 @@ int do_update_va_mapping(unsigned long p 20.187 mk_l1_pgentry(val))) ) 20.188 err = -EINVAL; 20.189 20.190 - if ( unlikely(ed->mm.shadow_mode) ) 20.191 + if ( unlikely(d->arch.shadow_mode) ) 20.192 { 20.193 unsigned long sval; 20.194 20.195 - l1pte_propagate_from_guest(&ed->mm, &val, &sval); 20.196 + l1pte_propagate_from_guest(d, &val, &sval); 20.197 20.198 if ( unlikely(__put_user(sval, ((unsigned long *)( 20.199 &shadow_linear_pg_table[page_nr])))) ) 20.200 @@ -1576,10 +1599,10 @@ int do_update_va_mapping(unsigned long p 20.201 * the PTE in the PT-holding page. We need the machine frame number 20.202 * for this. 20.203 */ 20.204 - if ( ed->mm.shadow_mode == SHM_logdirty ) 20.205 - mark_dirty(¤t->mm, va_to_l1mfn(page_nr << PAGE_SHIFT)); 20.206 + if ( d->arch.shadow_mode == SHM_logdirty ) 20.207 + mark_dirty(d, va_to_l1mfn(page_nr << PAGE_SHIFT)); 20.208 20.209 - check_pagetable(&ed->mm, ed->mm.pagetable, "va"); /* debug */ 20.210 + check_pagetable(d, ed->arch.pagetable, "va"); /* debug */ 20.211 } 20.212 20.213 deferred_ops = percpu_info[cpu].deferred_ops; 20.214 @@ -1673,15 +1696,15 @@ void ptwr_flush(const int which) 20.215 PTWR_PRINT_WHICH, ptep, pte); 20.216 pte &= ~_PAGE_RW; 20.217 20.218 - if ( unlikely(ed->mm.shadow_mode) ) 20.219 + if ( unlikely(d->arch.shadow_mode) ) 20.220 { 20.221 /* Write-protect the p.t. page in the shadow page table. */ 20.222 - l1pte_propagate_from_guest(&ed->mm, &pte, &spte); 20.223 + l1pte_propagate_from_guest(d, &pte, &spte); 20.224 __put_user( 20.225 spte, (unsigned long *)&shadow_linear_pg_table[l1va>>PAGE_SHIFT]); 20.226 20.227 /* Is the p.t. page itself shadowed? Map it into Xen space if so. */ 20.228 - sstat = get_shadow_status(&ed->mm, pte >> PAGE_SHIFT); 20.229 + sstat = get_shadow_status(d, pte >> PAGE_SHIFT); 20.230 if ( sstat & PSH_shadowed ) 20.231 sl1e = map_domain_mem((sstat & PSH_pfn_mask) << PAGE_SHIFT); 20.232 } 20.233 @@ -1730,7 +1753,7 @@ void ptwr_flush(const int which) 20.234 { 20.235 if ( unlikely(sl1e != NULL) ) 20.236 l1pte_propagate_from_guest( 20.237 - &ed->mm, &l1_pgentry_val(nl1e), 20.238 + d, &l1_pgentry_val(nl1e), 20.239 &l1_pgentry_val(sl1e[i])); 20.240 put_page_type(&frame_table[l1_pgentry_to_pagenr(nl1e)]); 20.241 } 20.242 @@ -1754,7 +1777,7 @@ void ptwr_flush(const int which) 20.243 20.244 if ( unlikely(sl1e != NULL) ) 20.245 l1pte_propagate_from_guest( 20.246 - &ed->mm, &l1_pgentry_val(nl1e), &l1_pgentry_val(sl1e[i])); 20.247 + d, &l1_pgentry_val(nl1e), &l1_pgentry_val(sl1e[i])); 20.248 20.249 if ( unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT) ) 20.250 put_page_from_l1e(ol1e, d); 20.251 @@ -1765,7 +1788,7 @@ void ptwr_flush(const int which) 20.252 * STEP 3. Reattach the L1 p.t. page into the current address space. 20.253 */ 20.254 20.255 - if ( (which == PTWR_PT_ACTIVE) && likely(!ed->mm.shadow_mode) ) 20.256 + if ( (which == PTWR_PT_ACTIVE) && likely(!d->arch.shadow_mode) ) 20.257 { 20.258 pl2e = &linear_l2_table[ptwr_info[cpu].ptinfo[which].l2_idx]; 20.259 *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); 20.260 @@ -1780,7 +1803,7 @@ void ptwr_flush(const int which) 20.261 if ( unlikely(sl1e != NULL) ) 20.262 { 20.263 unmap_domain_mem(sl1e); 20.264 - put_shadow_status(&ed->mm); 20.265 + put_shadow_status(d); 20.266 } 20.267 } 20.268 20.269 @@ -1868,7 +1891,8 @@ int ptwr_do_page_fault(unsigned long add 20.270 ptwr_info[cpu].ptinfo[which].l2_idx = l2_idx; 20.271 20.272 /* For safety, disconnect the L1 p.t. page from current space. */ 20.273 - if ( (which == PTWR_PT_ACTIVE) && likely(!current->mm.shadow_mode) ) 20.274 + if ( (which == PTWR_PT_ACTIVE) && 20.275 + likely(!current->domain->arch.shadow_mode) ) 20.276 { 20.277 *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT); 20.278 #if 1 20.279 @@ -2059,7 +2083,7 @@ void audit_domain(struct domain *d) 20.280 synchronise_pagetables(~0UL); 20.281 20.282 printk("pt base=%lx sh_info=%x\n", 20.283 - pagetable_val(d->exec_domain[0]->mm.pagetable)>>PAGE_SHIFT, 20.284 + pagetable_val(d->exec_domain[0]->arch.pagetable)>>PAGE_SHIFT, 20.285 virt_to_page(d->shared_info)-frame_table); 20.286 20.287 spin_lock(&d->page_alloc_lock); 20.288 @@ -2109,7 +2133,7 @@ void audit_domain(struct domain *d) 20.289 20.290 /* PHASE 1 */ 20.291 20.292 - adjust(&frame_table[pagetable_val(d->exec_domain[0]->mm.pagetable)>>PAGE_SHIFT], -1, 1); 20.293 + adjust(&frame_table[pagetable_val(d->exec_domain[0]->arch.pagetable)>>PAGE_SHIFT], -1, 1); 20.294 20.295 list_ent = d->page_list.next; 20.296 for ( i = 0; (list_ent != &d->page_list); i++ ) 20.297 @@ -2353,7 +2377,8 @@ void audit_domain(struct domain *d) 20.298 20.299 spin_unlock(&d->page_alloc_lock); 20.300 20.301 - adjust(&frame_table[pagetable_val(d->exec_domain[0]->mm.pagetable)>>PAGE_SHIFT], 1, 1); 20.302 + adjust(&frame_table[pagetable_val( 20.303 + d->exec_domain[0]->arch.pagetable)>>PAGE_SHIFT], 1, 1); 20.304 20.305 printk("Audit %d: Done. ctot=%d ttot=%d\n", d->id, ctot, ttot ); 20.306
21.1 --- a/xen/arch/x86/pci-pc.c Fri Feb 04 19:26:10 2005 +0000 21.2 +++ b/xen/arch/x86/pci-pc.c Mon Feb 07 08:19:24 2005 +0000 21.3 @@ -1,3 +1,4 @@ 21.4 +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 21.5 /* 21.6 * Low-Level PCI Support for PC 21.7 * 21.8 @@ -445,8 +446,9 @@ static struct pci_ops pci_direct_conf2 = 21.9 static int __devinit pci_sanity_check(struct pci_ops *o) 21.10 { 21.11 u16 x; 21.12 - struct pci_bus bus; /* Fake bus and device */ 21.13 - struct pci_dev dev; 21.14 + /* XEN: static is important to prevent stack overflow! */ 21.15 + static struct pci_bus bus; /* Fake bus and device */ 21.16 + static struct pci_dev dev; 21.17 21.18 if (pci_probe & PCI_NO_CHECKS) 21.19 return 1; 21.20 @@ -1131,8 +1133,9 @@ static void __devinit pcibios_fixup_ghos 21.21 static void __devinit pcibios_fixup_peer_bridges(void) 21.22 { 21.23 int n; 21.24 - struct pci_bus bus; 21.25 - struct pci_dev dev; 21.26 + /* XEN: static is important to prevent stack overflow! */ 21.27 + static struct pci_bus bus; 21.28 + static struct pci_dev dev; 21.29 u16 l; 21.30 21.31 if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
22.1 --- a/xen/arch/x86/pdb-linux.c Fri Feb 04 19:26:10 2005 +0000 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,100 +0,0 @@ 22.4 - 22.5 -/* 22.6 - * pervasive debugger 22.7 - * www.cl.cam.ac.uk/netos/pdb 22.8 - * 22.9 - * alex ho 22.10 - * 2004 22.11 - * university of cambridge computer laboratory 22.12 - * 22.13 - * linux & i386 dependent code. bleech. 22.14 - */ 22.15 - 22.16 -#include <asm/pdb.h> 22.17 - 22.18 -/* offset to the first instruction in the linux system call code 22.19 - where we can safely set a breakpoint */ 22.20 -unsigned int pdb_linux_syscall_enter_bkpt_offset = 20; 22.21 - 22.22 -/* offset to eflags saved on the stack after an int 80 */ 22.23 -unsigned int pdb_linux_syscall_eflags_offset = 48; 22.24 - 22.25 -/* offset to the instruction pointer saved on the stack after an int 80 */ 22.26 -unsigned int pdb_linux_syscall_eip_offset = 40; 22.27 - 22.28 -unsigned char 22.29 -pdb_linux_set_bkpt (unsigned long addr) 22.30 -{ 22.31 - unsigned char old_instruction = *(unsigned char *)addr; 22.32 - *(unsigned char *)addr = 0xcc; 22.33 - return old_instruction; 22.34 -} 22.35 - 22.36 -void 22.37 -pdb_linux_clr_bkpt (unsigned long addr, unsigned char value) 22.38 -{ 22.39 - *(unsigned char *)addr = value; 22.40 -} 22.41 - 22.42 -void 22.43 -pdb_linux_syscall_enter_bkpt (struct xen_regs *regs, long error_code, 22.44 - trap_info_t *ti) 22.45 -{ 22.46 - /* set at breakpoint at the beginning of the 22.47 - system call in the target domain */ 22.48 - 22.49 - pdb_system_call_enter_instr = pdb_linux_set_bkpt(ti->address + 22.50 - pdb_linux_syscall_enter_bkpt_offset); 22.51 - pdb_system_call = 1; 22.52 -} 22.53 - 22.54 -void 22.55 -pdb_linux_syscall_exit_bkpt (struct xen_regs *regs, struct pdb_context *pdb_ctx) 22.56 -{ 22.57 - /* 22.58 - we've hit an int 0x80 in a user's program, jumped into xen 22.59 - (traps.c::do_general_protection()) which re-wrote the next 22.60 - instruction in the os kernel to 0xcc, and then hit that 22.61 - exception. 22.62 - 22.63 - we need to re-write the return instruction in the user's 22.64 - program so that we know when we have finished the system call 22.65 - and are back in the user's program. 22.66 - 22.67 - at this point our stack should look something like this: 22.68 - 22.69 - esp = 0x80a59f0 22.70 - esp + 4 = 0x0 22.71 - esp + 8 = 0x80485a0 22.72 - esp + 12 = 0x2d 22.73 - esp + 16 = 0x80485f4 22.74 - esp + 20 = 0xbffffa48 22.75 - esp + 24 = 0xd 22.76 - esp + 28 = 0xc00a0833 22.77 - esp + 32 = 0x833 22.78 - esp + 36 = 0xd 22.79 - esp + 40 = 0x804dcdd saved eip 22.80 - esp + 44 = 0x82b saved cs 22.81 - esp + 48 = 0x213392 saved eflags 22.82 - esp + 52 = 0xbffffa2c saved esp 22.83 - esp + 56 = 0x833 saved ss 22.84 - esp + 60 = 0x1000000 22.85 - */ 22.86 - 22.87 - /* restore the entry instruction for the system call */ 22.88 - pdb_linux_clr_bkpt(regs->eip - 1, pdb_system_call_enter_instr); 22.89 - 22.90 - /* save the address of eflags that was saved on the stack */ 22.91 - pdb_system_call_eflags_addr = (regs->esp + 22.92 - pdb_linux_syscall_eflags_offset); 22.93 - 22.94 - /* muck with the return instruction so that we trap back into the 22.95 - debugger when re-entering user space */ 22.96 - pdb_system_call_next_addr = *(unsigned long *)(regs->esp + 22.97 - pdb_linux_syscall_eip_offset); 22.98 - pdb_linux_get_values (&pdb_system_call_leave_instr, 1, 22.99 - pdb_system_call_next_addr, 22.100 - pdb_ctx->process, pdb_ctx->ptbr); 22.101 - pdb_linux_set_values ("cc", 1, pdb_system_call_next_addr, 22.102 - pdb_ctx->process, pdb_ctx->ptbr); 22.103 -}
23.1 --- a/xen/arch/x86/pdb-stub.c Fri Feb 04 19:26:10 2005 +0000 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,1280 +0,0 @@ 23.4 - 23.5 -/* 23.6 - * pervasive debugger 23.7 - * www.cl.cam.ac.uk/netos/pdb 23.8 - * 23.9 - * alex ho 23.10 - * 2004 23.11 - * university of cambridge computer laboratory 23.12 - * 23.13 - * code adapted originally from kgdb, nemesis, & gdbserver 23.14 - */ 23.15 - 23.16 -#include <xen/lib.h> 23.17 -#include <xen/sched.h> 23.18 -#include <asm/regs.h> 23.19 -#include <xen/keyhandler.h> 23.20 -#include <asm/apic.h> 23.21 -#include <asm/domain_page.h> /* [un]map_domain_mem */ 23.22 -#include <asm/processor.h> 23.23 -#include <asm/pdb.h> 23.24 -#include <xen/list.h> 23.25 -#include <xen/serial.h> 23.26 -#include <xen/softirq.h> 23.27 -#include <xen/init.h> 23.28 - 23.29 -/* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */ 23.30 -static unsigned char opt_pdb[10] = "none"; 23.31 -string_param("pdb", opt_pdb); 23.32 - 23.33 -#define PDB_DEBUG_TRACE 23.34 -#ifdef PDB_DEBUG_TRACE 23.35 -#define TRC(_x) _x 23.36 -#else 23.37 -#define TRC(_x) 23.38 -#endif 23.39 - 23.40 -#define DEBUG_EXCEPTION 0x01 23.41 -#define BREAKPT_EXCEPTION 0x03 23.42 -#define PDB_LIVE_EXCEPTION 0x58 23.43 -#define KEYPRESS_EXCEPTION 0x88 23.44 - 23.45 -#define BUFMAX 400 23.46 - 23.47 -static const char hexchars[] = "0123456789abcdef"; 23.48 - 23.49 -static int remote_debug; 23.50 - 23.51 -#define PDB_BUFMAX 1024 23.52 -static char pdb_in_buffer[PDB_BUFMAX]; 23.53 -static char pdb_out_buffer[PDB_BUFMAX]; 23.54 -static char pdb_buffer[PDB_BUFMAX]; 23.55 - 23.56 -struct pdb_context pdb_ctx; 23.57 -int pdb_continue_thread = 0; 23.58 -int pdb_general_thread = 0; 23.59 - 23.60 -void pdb_put_packet (unsigned char *buffer, int ack); 23.61 -void pdb_bkpt_check (u_char *buffer, int length, 23.62 - unsigned long cr3, unsigned long addr); 23.63 - 23.64 -int pdb_initialized = 0; 23.65 -int pdb_page_fault_possible = 0; 23.66 -int pdb_page_fault_scratch = 0; /* just a handy variable */ 23.67 -int pdb_page_fault = 0; 23.68 -static int pdb_serhnd = -1; 23.69 -static int pdb_stepping = 0; 23.70 - 23.71 -int pdb_system_call = 0; 23.72 -unsigned char pdb_system_call_enter_instr = 0; /* original enter instr */ 23.73 -unsigned char pdb_system_call_leave_instr = 0; /* original next instr */ 23.74 -unsigned long pdb_system_call_next_addr = 0; /* instr after int 0x80 */ 23.75 -unsigned long pdb_system_call_eflags_addr = 0; /* saved eflags on stack */ 23.76 - 23.77 -static inline void pdb_put_char(unsigned char c) 23.78 -{ 23.79 - serial_putc(pdb_serhnd, c); 23.80 -} 23.81 - 23.82 -static inline unsigned char pdb_get_char(void) 23.83 -{ 23.84 - return serial_getc(pdb_serhnd); 23.85 -} 23.86 - 23.87 -int 23.88 -get_char (char *addr) 23.89 -{ 23.90 - return *addr; 23.91 -} 23.92 - 23.93 -void 23.94 -set_char (char *addr, int val) 23.95 -{ 23.96 - *addr = val; 23.97 -} 23.98 - 23.99 -void 23.100 -pdb_process_query (char *ptr) 23.101 -{ 23.102 - if (strcmp(ptr, "C") == 0) 23.103 - { 23.104 - /* empty string */ 23.105 - } 23.106 - else if (strcmp(ptr, "fThreadInfo") == 0) 23.107 - { 23.108 -#ifdef PDB_PAST 23.109 - struct domain *p; 23.110 -#endif /* PDB_PAST */ 23.111 - 23.112 - int buf_idx = 0; 23.113 - 23.114 - pdb_out_buffer[buf_idx++] = 'l'; 23.115 - pdb_out_buffer[buf_idx++] = 0; 23.116 - 23.117 -#ifdef PDB_PAST 23.118 - switch (pdb_level) 23.119 - { 23.120 - case PDB_LVL_XEN: /* return a list of domains */ 23.121 - { 23.122 - int count = 0; 23.123 - 23.124 - read_lock(&domlist_lock); 23.125 - 23.126 - pdb_out_buffer[buf_idx++] = 'm'; 23.127 - for_each_domain ( p ) 23.128 - { 23.129 - domid_t domain = p->domain + PDB_ID_OFFSET; 23.130 - 23.131 - if (count > 0) 23.132 - { 23.133 - pdb_out_buffer[buf_idx++] = ','; 23.134 - } 23.135 - if (domain > 15) 23.136 - { 23.137 - pdb_out_buffer[buf_idx++] = hexchars[domain >> 4]; 23.138 - } 23.139 - pdb_out_buffer[buf_idx++] = hexchars[domain % 16]; 23.140 - count++; 23.141 - } 23.142 - pdb_out_buffer[buf_idx++] = 0; 23.143 - 23.144 - read_unlock(&domlist_lock); 23.145 - break; 23.146 - } 23.147 - case PDB_LVL_GUESTOS: /* return a list of processes */ 23.148 - { 23.149 - int foobar[20]; 23.150 - int loop, total; 23.151 - 23.152 - /* this cr3 is wrong! */ 23.153 - total = pdb_linux_process_list(pdb_ctx[pdb_level].info_cr3, 23.154 - foobar, 20); 23.155 - 23.156 - pdb_out_buffer[buf_idx++] = 'm'; 23.157 - pdb_out_buffer[buf_idx++] = '1'; /* 1 is to go back */ 23.158 - for (loop = 0; loop < total; loop++) 23.159 - { 23.160 - int pid = foobar[loop] + PDB_ID_OFFSET; 23.161 - 23.162 - pdb_out_buffer[buf_idx++] = ','; 23.163 - if (pid > 15) 23.164 - { 23.165 - pdb_out_buffer[buf_idx++] = hexchars[pid >> 4]; 23.166 - } 23.167 - pdb_out_buffer[buf_idx++] = hexchars[pid % 16]; 23.168 - } 23.169 - pdb_out_buffer[buf_idx++] = 0; 23.170 - break; 23.171 - } 23.172 - case PDB_LVL_PROCESS: /* hmmm... */ 23.173 - { 23.174 - pdb_out_buffer[buf_idx++] = 'm'; 23.175 - pdb_out_buffer[buf_idx++] = '1'; /* 1 is to go back */ 23.176 - break; 23.177 - } 23.178 - default: 23.179 - break; 23.180 - } 23.181 -#endif /* PDB_PAST */ 23.182 - 23.183 - } 23.184 - else if (strcmp(ptr, "sThreadInfo") == 0) 23.185 - { 23.186 - int buf_idx = 0; 23.187 - 23.188 - pdb_out_buffer[buf_idx++] = 'l'; 23.189 - pdb_out_buffer[buf_idx++] = 0; 23.190 - } 23.191 - else if (strncmp(ptr, "ThreadExtraInfo,", 16) == 0) 23.192 - { 23.193 - int thread = 0; 23.194 - char *message = "foobar ?"; 23.195 - 23.196 - ptr += 16; 23.197 - if (hexToInt (&ptr, &thread)) 23.198 - { 23.199 - mem2hex (message, pdb_out_buffer, strlen(message) + 1); 23.200 - } 23.201 - 23.202 -#ifdef PDB_PAST 23.203 - int thread = 0; 23.204 - char message[16]; 23.205 - struct domain *p; 23.206 - 23.207 - strncpy (message, dom0->name, 16); 23.208 - 23.209 - ptr += 16; 23.210 - if (hexToInt (&ptr, &thread)) 23.211 - { 23.212 - mem2hex ((char *)message, pdb_out_buffer, strlen(message) + 1); 23.213 - } 23.214 -#endif /* PDB_PAST */ 23.215 - 23.216 -#ifdef PDB_FUTURE 23.217 - { 23.218 - char string[task_struct_comm_length]; 23.219 - 23.220 - string[0] = 0; 23.221 - pdb_linux_process_details (cr3, pid, string); 23.222 - printk (" (%s)", string); 23.223 - } 23.224 -#endif /* PDB_FUTURE*/ 23.225 - 23.226 - } 23.227 - else if (strcmp(ptr, "Offsets") == 0) 23.228 - { 23.229 - /* empty string */ 23.230 - } 23.231 - else if (strncmp(ptr, "Symbol", 6) == 0) 23.232 - { 23.233 - strcpy (pdb_out_buffer, "OK"); 23.234 - } 23.235 - else 23.236 - { 23.237 - printk("pdb: error, unknown query [%s]\n", ptr); 23.238 - } 23.239 -} 23.240 - 23.241 -void 23.242 -pdb_x86_to_gdb_regs (char *buffer, struct xen_regs *regs) 23.243 -{ 23.244 - int idx = 0; 23.245 - 23.246 - mem2hex ((char *)®s->eax, &buffer[idx], sizeof(regs->eax)); 23.247 - idx += sizeof(regs->eax) * 2; 23.248 - mem2hex ((char *)®s->ecx, &buffer[idx], sizeof(regs->ecx)); 23.249 - idx += sizeof(regs->ecx) * 2; 23.250 - mem2hex ((char *)®s->edx, &buffer[idx], sizeof(regs->edx)); 23.251 - idx += sizeof(regs->edx) * 2; 23.252 - mem2hex ((char *)®s->ebx, &buffer[idx], sizeof(regs->ebx)); 23.253 - idx += sizeof(regs->ebx) * 2; 23.254 - mem2hex ((char *)®s->esp, &buffer[idx], sizeof(regs->esp)); 23.255 - idx += sizeof(regs->esp) * 2; 23.256 - mem2hex ((char *)®s->ebp, &buffer[idx], sizeof(regs->ebp)); 23.257 - idx += sizeof(regs->ebp) * 2; 23.258 - mem2hex ((char *)®s->esi, &buffer[idx], sizeof(regs->esi)); 23.259 - idx += sizeof(regs->esi) * 2; 23.260 - mem2hex ((char *)®s->edi, &buffer[idx], sizeof(regs->edi)); 23.261 - idx += sizeof(regs->edi) * 2; 23.262 - mem2hex ((char *)®s->eip, &buffer[idx], sizeof(regs->eip)); 23.263 - idx += sizeof(regs->eip) * 2; 23.264 - mem2hex ((char *)®s->eflags, &buffer[idx], sizeof(regs->eflags)); 23.265 - idx += sizeof(regs->eflags) * 2; 23.266 - mem2hex ((char *)®s->cs, &buffer[idx], sizeof(regs->cs)); 23.267 - idx += sizeof(regs->cs) * 2; 23.268 - mem2hex ((char *)®s->ss, &buffer[idx], sizeof(regs->ss)); 23.269 - idx += sizeof(regs->ss) * 2; 23.270 - mem2hex ((char *)®s->ds, &buffer[idx], sizeof(regs->ds)); 23.271 - idx += sizeof(regs->ds) * 2; 23.272 - mem2hex ((char *)®s->es, &buffer[idx], sizeof(regs->es)); 23.273 - idx += sizeof(regs->es) * 2; 23.274 - mem2hex ((char *)®s->fs, &buffer[idx], sizeof(regs->fs)); 23.275 - idx += sizeof(regs->fs) * 2; 23.276 - mem2hex ((char *)®s->gs, &buffer[idx], sizeof(regs->gs)); 23.277 -} 23.278 - 23.279 -/* at this point we allow any register to be changed, caveat emptor */ 23.280 -void 23.281 -pdb_gdb_to_x86_regs (struct xen_regs *regs, char *buffer) 23.282 -{ 23.283 - hex2mem(buffer, (char *)®s->eax, sizeof(regs->eax)); 23.284 - buffer += sizeof(regs->eax) * 2; 23.285 - hex2mem(buffer, (char *)®s->ecx, sizeof(regs->ecx)); 23.286 - buffer += sizeof(regs->ecx) * 2; 23.287 - hex2mem(buffer, (char *)®s->edx, sizeof(regs->edx)); 23.288 - buffer += sizeof(regs->edx) * 2; 23.289 - hex2mem(buffer, (char *)®s->ebx, sizeof(regs->ebx)); 23.290 - buffer += sizeof(regs->ebx) * 2; 23.291 - hex2mem(buffer, (char *)®s->esp, sizeof(regs->esp)); 23.292 - buffer += sizeof(regs->esp) * 2; 23.293 - hex2mem(buffer, (char *)®s->ebp, sizeof(regs->ebp)); 23.294 - buffer += sizeof(regs->ebp) * 2; 23.295 - hex2mem(buffer, (char *)®s->esi, sizeof(regs->esi)); 23.296 - buffer += sizeof(regs->esi) * 2; 23.297 - hex2mem(buffer, (char *)®s->edi, sizeof(regs->edi)); 23.298 - buffer += sizeof(regs->edi) * 2; 23.299 - hex2mem(buffer, (char *)®s->eip, sizeof(regs->eip)); 23.300 - buffer += sizeof(regs->eip) * 2; 23.301 - hex2mem(buffer, (char *)®s->eflags, sizeof(regs->eflags)); 23.302 - buffer += sizeof(regs->eflags) * 2; 23.303 - hex2mem(buffer, (char *)®s->cs, sizeof(regs->cs)); 23.304 - buffer += sizeof(regs->cs) * 2; 23.305 - hex2mem(buffer, (char *)®s->ss, sizeof(regs->ss)); 23.306 - buffer += sizeof(regs->ss) * 2; 23.307 - hex2mem(buffer, (char *)®s->ds, sizeof(regs->ds)); 23.308 - buffer += sizeof(regs->ds) * 2; 23.309 - hex2mem(buffer, (char *)®s->es, sizeof(regs->es)); 23.310 - buffer += sizeof(regs->es) * 2; 23.311 - hex2mem(buffer, (char *)®s->fs, sizeof(regs->fs)); 23.312 - buffer += sizeof(regs->fs) * 2; 23.313 - hex2mem(buffer, (char *)®s->gs, sizeof(regs->gs)); 23.314 -} 23.315 - 23.316 -int 23.317 -pdb_process_command (char *ptr, struct xen_regs *regs, unsigned long cr3, 23.318 - int sigval) 23.319 -{ 23.320 - int length; 23.321 - unsigned long addr; 23.322 - int ack = 1; /* wait for ack in pdb_put_packet */ 23.323 - int go = 0; 23.324 - 23.325 - TRC(printf("pdb: [%s]\n", ptr)); 23.326 - 23.327 - pdb_out_buffer[0] = 0; 23.328 - 23.329 - if (pdb_ctx.valid == 1) 23.330 - { 23.331 - if (pdb_ctx.domain == -1) /* pdb context: xen */ 23.332 - { 23.333 - struct domain *p; 23.334 - 23.335 - p = &idle0_task; 23.336 - if (p->mm.shadow_mode) 23.337 - pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table); 23.338 - else 23.339 - pdb_ctx.ptbr = pagetable_val(p->mm.pagetable); 23.340 - } 23.341 - else if (pdb_ctx.process == -1) /* pdb context: guest os */ 23.342 - { 23.343 - struct domain *p; 23.344 - 23.345 - if (pdb_ctx.domain == -2) 23.346 - { 23.347 - p = find_last_domain(); 23.348 - } 23.349 - else 23.350 - { 23.351 - p = find_domain_by_id(pdb_ctx.domain); 23.352 - } 23.353 - if (p == NULL) 23.354 - { 23.355 - printk ("pdb error: unknown domain [0x%x]\n", pdb_ctx.domain); 23.356 - strcpy (pdb_out_buffer, "E01"); 23.357 - pdb_ctx.domain = -1; 23.358 - goto exit; 23.359 - } 23.360 - if (p->mm.shadow_mode) 23.361 - pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table); 23.362 - else 23.363 - pdb_ctx.ptbr = pagetable_val(p->mm.pagetable); 23.364 - put_domain(p); 23.365 - } 23.366 - else /* pdb context: process */ 23.367 - { 23.368 - struct domain *p; 23.369 - unsigned long domain_ptbr; 23.370 - 23.371 - p = find_domain_by_id(pdb_ctx.domain); 23.372 - if (p == NULL) 23.373 - { 23.374 - printk ("pdb error: unknown domain [0x%x][0x%x]\n", 23.375 - pdb_ctx.domain, pdb_ctx.process); 23.376 - strcpy (pdb_out_buffer, "E01"); 23.377 - pdb_ctx.domain = -1; 23.378 - goto exit; 23.379 - } 23.380 - if (p->mm.shadow_mode) 23.381 - domain_ptbr = pagetable_val(p->mm.shadow_table); 23.382 - else 23.383 - domain_ptbr = pagetable_val(p->mm.pagetable); 23.384 - put_domain(p); 23.385 - 23.386 - pdb_ctx.ptbr = domain_ptbr; 23.387 - /*pdb_ctx.ptbr=pdb_linux_pid_ptbr(domain_ptbr, pdb_ctx.process);*/ 23.388 - } 23.389 - 23.390 - pdb_ctx.valid = 0; 23.391 - TRC(printk ("pdb change context (dom:%d, proc:%d) now 0x%lx\n", 23.392 - pdb_ctx.domain, pdb_ctx.process, pdb_ctx.ptbr)); 23.393 - } 23.394 - 23.395 - switch (*ptr++) 23.396 - { 23.397 - case '?': 23.398 - pdb_out_buffer[0] = 'S'; 23.399 - pdb_out_buffer[1] = hexchars[sigval >> 4]; 23.400 - pdb_out_buffer[2] = hexchars[sigval % 16]; 23.401 - pdb_out_buffer[3] = 0; 23.402 - break; 23.403 - case 'S': /* step with signal */ 23.404 - case 's': /* step */ 23.405 - { 23.406 - if ( pdb_system_call_eflags_addr != 0 ) 23.407 - { 23.408 - unsigned long eflags; 23.409 - char eflags_buf[sizeof(eflags)*2]; /* STUPID STUPID STUPID */ 23.410 - 23.411 - pdb_linux_get_values((u_char*)&eflags, sizeof(eflags), 23.412 - pdb_system_call_eflags_addr, 23.413 - pdb_ctx.process, pdb_ctx.ptbr); 23.414 - eflags |= X86_EFLAGS_TF; 23.415 - mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags)); 23.416 - pdb_linux_set_values(eflags_buf, sizeof(eflags), 23.417 - pdb_system_call_eflags_addr, 23.418 - pdb_ctx.process, pdb_ctx.ptbr); 23.419 - } 23.420 - 23.421 - regs->eflags |= X86_EFLAGS_TF; 23.422 - pdb_stepping = 1; 23.423 - return 1; 23.424 - /* not reached */ 23.425 - } 23.426 - case 'C': /* continue with signal */ 23.427 - case 'c': /* continue */ 23.428 - { 23.429 - if ( pdb_system_call_eflags_addr != 0 ) 23.430 - { 23.431 - unsigned long eflags; 23.432 - char eflags_buf[sizeof(eflags)*2]; /* STUPID STUPID STUPID */ 23.433 - 23.434 - pdb_linux_get_values((u_char*)&eflags, sizeof(eflags), 23.435 - pdb_system_call_eflags_addr, 23.436 - pdb_ctx.process, pdb_ctx.ptbr); 23.437 - eflags &= ~X86_EFLAGS_TF; 23.438 - mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags)); 23.439 - pdb_linux_set_values(eflags_buf, sizeof(eflags), 23.440 - pdb_system_call_eflags_addr, 23.441 - pdb_ctx.process, pdb_ctx.ptbr); 23.442 - } 23.443 - 23.444 - regs->eflags &= ~X86_EFLAGS_TF; 23.445 - return 1; /* jump out before replying to gdb */ 23.446 - /* not reached */ 23.447 - } 23.448 - case 'd': 23.449 - remote_debug = !(remote_debug); /* toggle debug flag */ 23.450 - break; 23.451 - case 'D': /* detach */ 23.452 - return go; 23.453 - /* not reached */ 23.454 - case 'g': /* return the value of the CPU registers */ 23.455 - { 23.456 - pdb_x86_to_gdb_regs (pdb_out_buffer, regs); 23.457 - break; 23.458 - } 23.459 - case 'G': /* set the value of the CPU registers - return OK */ 23.460 - { 23.461 - pdb_gdb_to_x86_regs (regs, ptr); 23.462 - break; 23.463 - } 23.464 - case 'H': 23.465 - { 23.466 - int thread; 23.467 - char *next = &ptr[1]; 23.468 - 23.469 - if (hexToInt (&next, &thread)) 23.470 - { 23.471 - if (*ptr == 'c') 23.472 - { 23.473 - pdb_continue_thread = thread; 23.474 - } 23.475 - else if (*ptr == 'g') 23.476 - { 23.477 - pdb_general_thread = thread; 23.478 - } 23.479 - else 23.480 - { 23.481 - printk ("pdb error: unknown set thread command %c (%d)\n", 23.482 - *ptr, thread); 23.483 - strcpy (pdb_out_buffer, "E00"); 23.484 - break; 23.485 - } 23.486 - } 23.487 - strcpy (pdb_out_buffer, "OK"); 23.488 - break; 23.489 - } 23.490 - case 'k': /* kill request */ 23.491 - { 23.492 - strcpy (pdb_out_buffer, "OK"); /* ack for fun */ 23.493 - printk ("don't kill bill...\n"); 23.494 - ack = 0; 23.495 - break; 23.496 - } 23.497 - 23.498 - case 'q': 23.499 - { 23.500 - pdb_process_query(ptr); 23.501 - break; 23.502 - } 23.503 - 23.504 - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 23.505 - case 'm': 23.506 - { 23.507 - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ 23.508 - if (hexToInt (&ptr, (int *)&addr)) 23.509 - if (*(ptr++) == ',') 23.510 - if (hexToInt (&ptr, &length)) 23.511 - { 23.512 - ptr = 0; 23.513 - 23.514 - pdb_page_fault_possible = 1; 23.515 - pdb_page_fault = 0; 23.516 - if (addr >= PAGE_OFFSET) 23.517 - { 23.518 - mem2hex ((char *) addr, pdb_out_buffer, length); 23.519 - } 23.520 - else if (pdb_ctx.process != -1) 23.521 - { 23.522 - pdb_linux_get_values(pdb_buffer, length, addr, 23.523 - pdb_ctx.process, pdb_ctx.ptbr); 23.524 - mem2hex (pdb_buffer, pdb_out_buffer, length); 23.525 - } 23.526 - else 23.527 - { 23.528 - pdb_get_values (pdb_buffer, length, 23.529 - pdb_ctx.ptbr, addr); 23.530 - mem2hex (pdb_buffer, pdb_out_buffer, length); 23.531 - } 23.532 - 23.533 - pdb_page_fault_possible = 0; 23.534 - if (pdb_page_fault) 23.535 - { 23.536 - strcpy (pdb_out_buffer, "E03"); 23.537 - } 23.538 - } 23.539 - 23.540 - if (ptr) 23.541 - { 23.542 - strcpy (pdb_out_buffer, "E01"); 23.543 - } 23.544 - break; 23.545 - } 23.546 - 23.547 - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ 23.548 - case 'M': 23.549 - { 23.550 - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ 23.551 - if (hexToInt (&ptr, (int *)&addr)) 23.552 - if (*(ptr++) == ',') 23.553 - if (hexToInt (&ptr, &length)) 23.554 - if (*(ptr++) == ':') 23.555 - { 23.556 - 23.557 - pdb_page_fault_possible = 1; 23.558 - pdb_page_fault = 0; 23.559 - if (addr >= PAGE_OFFSET) 23.560 - { 23.561 - hex2mem (ptr, (char *)addr, length); 23.562 - pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr); 23.563 - } 23.564 - else if (pdb_ctx.process != -1) 23.565 - { 23.566 - pdb_linux_set_values(ptr, length, addr, 23.567 - pdb_ctx.process, 23.568 - pdb_ctx.ptbr); 23.569 - pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr); 23.570 - } 23.571 - else 23.572 - { 23.573 - pdb_set_values (ptr, length, 23.574 - pdb_ctx.ptbr, addr); 23.575 - pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr); 23.576 - } 23.577 - pdb_page_fault_possible = 0; 23.578 - if (pdb_page_fault) 23.579 - { 23.580 - strcpy (pdb_out_buffer, "E03"); 23.581 - } 23.582 - else 23.583 - { 23.584 - strcpy (pdb_out_buffer, "OK"); 23.585 - } 23.586 - 23.587 - ptr = 0; 23.588 - } 23.589 - if (ptr) 23.590 - { 23.591 - strcpy (pdb_out_buffer, "E02"); 23.592 - } 23.593 - break; 23.594 - } 23.595 - case 'T': 23.596 - { 23.597 - int id; 23.598 - 23.599 - if (hexToInt (&ptr, &id)) 23.600 - { 23.601 - strcpy (pdb_out_buffer, "E00"); 23.602 - 23.603 -#ifdef PDB_PAST 23.604 - 23.605 - switch (pdb_level) /* previous level */ 23.606 - { 23.607 - case PDB_LVL_XEN: 23.608 - { 23.609 - struct domain *p; 23.610 - id -= PDB_ID_OFFSET; 23.611 - if ( (p = find_domain_by_id(id)) == NULL) 23.612 - strcpy (pdb_out_buffer, "E00"); 23.613 - else 23.614 - strcpy (pdb_out_buffer, "OK"); 23.615 - put_domain(p); 23.616 - 23.617 - pdb_level = PDB_LVL_GUESTOS; 23.618 - pdb_ctx[pdb_level].ctrl = id; 23.619 - pdb_ctx[pdb_level].info = id; 23.620 - break; 23.621 - } 23.622 - case PDB_LVL_GUESTOS: 23.623 - { 23.624 - if (pdb_level == -1) 23.625 - { 23.626 - pdb_level = PDB_LVL_XEN; 23.627 - } 23.628 - else 23.629 - { 23.630 - pdb_level = PDB_LVL_PROCESS; 23.631 - pdb_ctx[pdb_level].ctrl = id; 23.632 - pdb_ctx[pdb_level].info = id; 23.633 - } 23.634 - break; 23.635 - } 23.636 - case PDB_LVL_PROCESS: 23.637 - { 23.638 - if (pdb_level == -1) 23.639 - { 23.640 - pdb_level = PDB_LVL_GUESTOS; 23.641 - } 23.642 - break; 23.643 - } 23.644 - default: 23.645 - { 23.646 - printk ("pdb internal error: invalid level [%d]\n", 23.647 - pdb_level); 23.648 - } 23.649 - } 23.650 - 23.651 -#endif /* PDB_PAST */ 23.652 - } 23.653 - break; 23.654 - } 23.655 - } 23.656 - 23.657 -exit: 23.658 - /* reply to the request */ 23.659 - pdb_put_packet (pdb_out_buffer, ack); 23.660 - 23.661 - return go; 23.662 -} 23.663 - 23.664 -/* 23.665 - * process an input character from the serial line. 23.666 - * 23.667 - * return "1" if the character is a gdb debug string 23.668 - * (and hence shouldn't be further processed). 23.669 - */ 23.670 - 23.671 -int pdb_debug_state = 0; /* small parser state machine */ 23.672 - 23.673 -int hex(char ch) 23.674 -{ 23.675 - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); 23.676 - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); 23.677 - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); 23.678 - return (-1); 23.679 -} 23.680 - 23.681 -/* convert the memory pointed to by mem into hex, placing result in buf */ 23.682 -/* return a pointer to the last char put in buf (null) */ 23.683 -char * 23.684 -mem2hex (mem, buf, count) 23.685 - char *mem; 23.686 - char *buf; 23.687 - int count; 23.688 -{ 23.689 - int i; 23.690 - unsigned char ch; 23.691 - 23.692 - for (i = 0; i < count; i++) 23.693 - { 23.694 - ch = get_char (mem++); 23.695 - *buf++ = hexchars[ch >> 4]; 23.696 - *buf++ = hexchars[ch % 16]; 23.697 - } 23.698 - *buf = 0; 23.699 - return (buf); 23.700 -} 23.701 - 23.702 -/* convert the hex array pointed to by buf into binary to be placed in mem */ 23.703 -/* return a pointer to the character AFTER the last byte written */ 23.704 -char * 23.705 -hex2mem (buf, mem, count) 23.706 - char *buf; 23.707 - char *mem; 23.708 - int count; 23.709 -{ 23.710 - int i; 23.711 - unsigned char ch; 23.712 - 23.713 - for (i = 0; i < count; i++) 23.714 - { 23.715 - ch = hex (*buf++) << 4; 23.716 - ch = ch + hex (*buf++); 23.717 - set_char (mem++, ch); 23.718 - } 23.719 - return (mem); 23.720 -} 23.721 - 23.722 -int 23.723 -hexToInt (char **ptr, int *intValue) 23.724 -{ 23.725 - int numChars = 0; 23.726 - int hexValue; 23.727 - int negative = 0; 23.728 - 23.729 - *intValue = 0; 23.730 - 23.731 - if (**ptr == '-') 23.732 - { 23.733 - negative = 1; 23.734 - numChars++; 23.735 - (*ptr)++; 23.736 - } 23.737 - 23.738 - while (**ptr) 23.739 - { 23.740 - hexValue = hex (**ptr); 23.741 - if (hexValue >= 0) 23.742 - { 23.743 - *intValue = (*intValue << 4) | hexValue; 23.744 - numChars++; 23.745 - } 23.746 - else 23.747 - break; 23.748 - 23.749 - (*ptr)++; 23.750 - } 23.751 - 23.752 - if ( negative ) 23.753 - *intValue *= -1; 23.754 - 23.755 - return (numChars); 23.756 -} 23.757 - 23.758 -/***********************************************************************/ 23.759 -/***********************************************************************/ 23.760 - 23.761 - 23.762 -/* 23.763 - * Add a breakpoint to the list of known breakpoints. 23.764 - * For now there should only be two or three breakpoints so 23.765 - * we use a simple linked list. In the future, maybe a red-black tree? 23.766 - */ 23.767 -struct pdb_breakpoint breakpoints; 23.768 - 23.769 -void pdb_bkpt_add (unsigned long cr3, unsigned long address) 23.770 -{ 23.771 - struct pdb_breakpoint *bkpt = xmalloc(sizeof(*bkpt)); 23.772 - bkpt->cr3 = cr3; 23.773 - bkpt->address = address; 23.774 - list_add(&bkpt->list, &breakpoints.list); 23.775 -} 23.776 - 23.777 -/* 23.778 - * Check to see of the breakpoint is in the list of known breakpoints 23.779 - * Return 1 if it has been set, NULL otherwise. 23.780 - */ 23.781 -struct pdb_breakpoint* pdb_bkpt_search (unsigned long cr3, 23.782 - unsigned long address) 23.783 -{ 23.784 - struct pdb_breakpoint *bkpt; 23.785 - 23.786 - list_for_each_entry ( bkpt, &breakpoints.list, list ) 23.787 - { 23.788 - if ( bkpt->cr3 == cr3 && bkpt->address == address ) 23.789 - return bkpt; 23.790 - } 23.791 - 23.792 - return NULL; 23.793 -} 23.794 - 23.795 -/* 23.796 - * Remove a breakpoint to the list of known breakpoints. 23.797 - * Return 1 if the element was not found, otherwise 0. 23.798 - */ 23.799 -int pdb_bkpt_remove (unsigned long cr3, unsigned long address) 23.800 -{ 23.801 - struct pdb_breakpoint *bkpt; 23.802 - 23.803 - list_for_each_entry ( bkpt, &breakpoints.list, list ) 23.804 - { 23.805 - if ( bkpt->cr3 == cr3 && bkpt->address == address ) 23.806 - { 23.807 - list_del(&bkpt->list); 23.808 - xfree(bkpt); 23.809 - return 0; 23.810 - } 23.811 - } 23.812 - 23.813 - return 1; 23.814 -} 23.815 - 23.816 -/* 23.817 - * Check to see if a memory write is really gdb setting a breakpoint 23.818 - */ 23.819 -void pdb_bkpt_check (u_char *buffer, int length, 23.820 - unsigned long cr3, unsigned long addr) 23.821 -{ 23.822 - if (length == 1 && buffer[0] == 'c' && buffer[1] == 'c') 23.823 - { 23.824 - /* inserting a new breakpoint */ 23.825 - pdb_bkpt_add(cr3, addr); 23.826 - TRC(printk("pdb breakpoint detected at 0x%lx:0x%lx\n", cr3, addr)); 23.827 - } 23.828 - else if ( pdb_bkpt_remove(cr3, addr) == 0 ) 23.829 - { 23.830 - /* removing a breakpoint */ 23.831 - TRC(printk("pdb breakpoint cleared at 0x%lx:0x%lx\n", cr3, addr)); 23.832 - } 23.833 -} 23.834 - 23.835 -/***********************************************************************/ 23.836 - 23.837 -int pdb_change_values(u_char *buffer, int length, 23.838 - unsigned long cr3, unsigned long addr, int rw); 23.839 -int pdb_change_values_one_page(u_char *buffer, int length, 23.840 - unsigned long cr3, unsigned long addr, int rw); 23.841 - 23.842 -#define __PDB_GET_VAL 1 23.843 -#define __PDB_SET_VAL 2 23.844 - 23.845 -/* 23.846 - * Set memory in a domain's address space 23.847 - * Set "length" bytes at "address" from "domain" to the values in "buffer". 23.848 - * Return the number of bytes set, 0 if there was a problem. 23.849 - */ 23.850 - 23.851 -int pdb_set_values(u_char *buffer, int length, 23.852 - unsigned long cr3, unsigned long addr) 23.853 -{ 23.854 - int count = pdb_change_values(buffer, length, cr3, addr, __PDB_SET_VAL); 23.855 - return count; 23.856 -} 23.857 - 23.858 -/* 23.859 - * Read memory from a domain's address space. 23.860 - * Fetch "length" bytes at "address" from "domain" into "buffer". 23.861 - * Return the number of bytes read, 0 if there was a problem. 23.862 - */ 23.863 - 23.864 -int pdb_get_values(u_char *buffer, int length, 23.865 - unsigned long cr3, unsigned long addr) 23.866 -{ 23.867 - return pdb_change_values(buffer, length, cr3, addr, __PDB_GET_VAL); 23.868 -} 23.869 - 23.870 -/* 23.871 - * Read or write memory in an address space 23.872 - */ 23.873 -int pdb_change_values(u_char *buffer, int length, 23.874 - unsigned long cr3, unsigned long addr, int rw) 23.875 -{ 23.876 - int remaining; /* number of bytes to touch past this page */ 23.877 - int bytes = 0; 23.878 - 23.879 - while ( (remaining = (addr + length - 1) - (addr | (PAGE_SIZE - 1))) > 0) 23.880 - { 23.881 - bytes += pdb_change_values_one_page(buffer, length - remaining, 23.882 - cr3, addr, rw); 23.883 - buffer = buffer + (2 * (length - remaining)); 23.884 - length = remaining; 23.885 - addr = (addr | (PAGE_SIZE - 1)) + 1; 23.886 - } 23.887 - 23.888 - bytes += pdb_change_values_one_page(buffer, length, cr3, addr, rw); 23.889 - return bytes; 23.890 -} 23.891 - 23.892 -/* 23.893 - * Change memory in a process' address space in one page 23.894 - * Read or write "length" bytes at "address" into/from "buffer" 23.895 - * from the virtual address space referenced by "cr3". 23.896 - * Return the number of bytes read, 0 if there was a problem. 23.897 - */ 23.898 - 23.899 -int pdb_change_values_one_page(u_char *buffer, int length, 23.900 - unsigned long cr3, unsigned long addr, int rw) 23.901 -{ 23.902 - l2_pgentry_t* l2_table = NULL; /* page directory */ 23.903 - l1_pgentry_t* l1_table = NULL; /* page table */ 23.904 - u_char *page; /* 4k page */ 23.905 - int bytes = 0; 23.906 - 23.907 - l2_table = map_domain_mem(cr3); 23.908 - l2_table += l2_table_offset(addr); 23.909 - if (!(l2_pgentry_val(*l2_table) & _PAGE_PRESENT)) 23.910 - { 23.911 - if (pdb_page_fault_possible == 1) 23.912 - { 23.913 - pdb_page_fault = 1; 23.914 - TRC(printk("pdb: L2 error (0x%lx)\n", addr)); 23.915 - } 23.916 - else 23.917 - { 23.918 - printk ("pdb error: cr3: 0x%lx dom0cr3: 0x%lx\n", cr3, 23.919 - dom0->mm.shadow_mode ? pagetable_val(dom0->mm.shadow_table) 23.920 - : pagetable_val(dom0->mm.pagetable)); 23.921 - printk ("pdb error: L2:0x%p (0x%lx)\n", 23.922 - l2_table, l2_pgentry_val(*l2_table)); 23.923 - } 23.924 - goto exit2; 23.925 - } 23.926 - 23.927 - if (l2_pgentry_val(*l2_table) & _PAGE_PSE) 23.928 - { 23.929 -#define PSE_PAGE_SHIFT L2_PAGETABLE_SHIFT 23.930 -#define PSE_PAGE_SIZE (1UL << PSE_PAGE_SHIFT) 23.931 -#define PSE_PAGE_MASK (~(PSE_PAGE_SIZE-1)) 23.932 - 23.933 -#define L1_PAGE_BITS ( (ENTRIES_PER_L1_PAGETABLE - 1) << L1_PAGETABLE_SHIFT ) 23.934 - 23.935 -#define pse_pgentry_to_phys(_x) (l2_pgentry_val(_x) & PSE_PAGE_MASK) 23.936 - 23.937 - page = map_domain_mem(pse_pgentry_to_phys(*l2_table) + /* 10 bits */ 23.938 - (addr & L1_PAGE_BITS)); /* 10 bits */ 23.939 - page += addr & (PAGE_SIZE - 1); /* 12 bits */ 23.940 - } 23.941 - else 23.942 - { 23.943 - l1_table = map_domain_mem(l2_pgentry_to_phys(*l2_table)); 23.944 - l1_table += l1_table_offset(addr); 23.945 - if (!(l1_pgentry_val(*l1_table) & _PAGE_PRESENT)) 23.946 - { 23.947 - if (pdb_page_fault_possible == 1) 23.948 - { 23.949 - pdb_page_fault = 1; 23.950 - TRC(printk ("pdb: L1 error (0x%lx)\n", addr)); 23.951 - } 23.952 - else 23.953 - { 23.954 - printk ("L2:0x%p (0x%lx) L1:0x%p (0x%lx)\n", 23.955 - l2_table, l2_pgentry_val(*l2_table), 23.956 - l1_table, l1_pgentry_val(*l1_table)); 23.957 - } 23.958 - goto exit1; 23.959 - } 23.960 - 23.961 - page = map_domain_mem(l1_pgentry_to_phys(*l1_table)); 23.962 - page += addr & (PAGE_SIZE - 1); 23.963 - } 23.964 - 23.965 - switch (rw) 23.966 - { 23.967 - case __PDB_GET_VAL: /* read */ 23.968 - memcpy (buffer, page, length); 23.969 - bytes = length; 23.970 - break; 23.971 - case __PDB_SET_VAL: /* write */ 23.972 - hex2mem (buffer, page, length); 23.973 - bytes = length; 23.974 - break; 23.975 - default: /* unknown */ 23.976 - printk ("error: unknown RW flag: %d\n", rw); 23.977 - return 0; 23.978 - } 23.979 - 23.980 - unmap_domain_mem((void *)page); 23.981 -exit1: 23.982 - if (l1_table != NULL) 23.983 - unmap_domain_mem((void *)l1_table); 23.984 -exit2: 23.985 - unmap_domain_mem((void *)l2_table); 23.986 - 23.987 - return bytes; 23.988 -} 23.989 - 23.990 -/***********************************************************************/ 23.991 - 23.992 -void breakpoint(void); 23.993 - 23.994 -/* send the packet in buffer. */ 23.995 -void pdb_put_packet (unsigned char *buffer, int ack) 23.996 -{ 23.997 - unsigned char checksum; 23.998 - int count; 23.999 - char ch; 23.1000 - 23.1001 - /* $<packet info>#<checksum> */ 23.1002 - /* do */ 23.1003 - { 23.1004 - pdb_put_char ('$'); 23.1005 - checksum = 0; 23.1006 - count = 0; 23.1007 - 23.1008 - while ((ch = buffer[count])) 23.1009 - { 23.1010 - pdb_put_char (ch); 23.1011 - checksum += ch; 23.1012 - count += 1; 23.1013 - } 23.1014 - 23.1015 - pdb_put_char('#'); 23.1016 - pdb_put_char(hexchars[checksum >> 4]); 23.1017 - pdb_put_char(hexchars[checksum % 16]); 23.1018 - } 23.1019 - 23.1020 - if (ack) 23.1021 - { 23.1022 - if ((ch = pdb_get_char()) != '+') 23.1023 - { 23.1024 - printk(" pdb return error: %c 0x%x [%s]\n", ch, ch, buffer); 23.1025 - } 23.1026 - } 23.1027 -} 23.1028 - 23.1029 -void pdb_get_packet(char *buffer) 23.1030 -{ 23.1031 - int count; 23.1032 - char ch; 23.1033 - unsigned char checksum = 0; 23.1034 - unsigned char xmitcsum = 0; 23.1035 - 23.1036 - do 23.1037 - { 23.1038 - while ((ch = pdb_get_char()) != '$'); 23.1039 - 23.1040 - count = 0; 23.1041 - checksum = 0; 23.1042 - 23.1043 - while (count < BUFMAX) 23.1044 - { 23.1045 - ch = pdb_get_char(); 23.1046 - if (ch == '#') break; 23.1047 - checksum += ch; 23.1048 - buffer[count] = ch; 23.1049 - count++; 23.1050 - } 23.1051 - buffer[count] = 0; 23.1052 - 23.1053 - if (ch == '#') 23.1054 - { 23.1055 - xmitcsum = hex(pdb_get_char()) << 4; 23.1056 - xmitcsum += hex(pdb_get_char()); 23.1057 - 23.1058 - if (xmitcsum == checksum) 23.1059 - { 23.1060 - pdb_put_char('+'); 23.1061 - if (buffer[2] == ':') 23.1062 - { 23.1063 - printk ("pdb: obsolete gdb packet (sequence ID)\n"); 23.1064 - } 23.1065 - } 23.1066 - else 23.1067 - { 23.1068 - pdb_put_char('-'); 23.1069 - } 23.1070 - } 23.1071 - } while (checksum != xmitcsum); 23.1072 - 23.1073 - return; 23.1074 -} 23.1075 - 23.1076 -/* 23.1077 - * process a machine interrupt or exception 23.1078 - * Return 1 if pdb is not interested in the exception; it should 23.1079 - * be propagated to the guest os. 23.1080 - */ 23.1081 - 23.1082 -int pdb_handle_exception(int exceptionVector, 23.1083 - struct xen_regs *xen_regs) 23.1084 -{ 23.1085 - int signal = 0; 23.1086 - struct pdb_breakpoint* bkpt; 23.1087 - int watchdog_save; 23.1088 - unsigned long cr3 = read_cr3(); 23.1089 - 23.1090 - /* No vm86 handling here as yet. */ 23.1091 - if ( VM86_MODE(xen_regs) ) 23.1092 - return 1; 23.1093 - 23.1094 - /* If the exception is an int3 from user space then pdb is only 23.1095 - interested if it re-wrote an instruction set the breakpoint. 23.1096 - This occurs when leaving a system call from a domain. 23.1097 - */ 23.1098 - if ( (exceptionVector == 3) && 23.1099 - RING_3(xen_regs) && 23.1100 - (xen_regs->eip != (pdb_system_call_next_addr + 1)) ) 23.1101 - { 23.1102 - TRC(printf("pdb: user bkpt (0x%x) at 0x%x:0x%lx:0x%x\n", 23.1103 - exceptionVector, xen_regs->cs & 3, cr3, xen_regs->eip)); 23.1104 - return 1; 23.1105 - } 23.1106 - 23.1107 - /* 23.1108 - * If PDB didn't set the breakpoint, is not single stepping, 23.1109 - * is not entering a system call in a domain, 23.1110 - * the user didn't press the magic debug key, 23.1111 - * then we don't handle the exception. 23.1112 - */ 23.1113 - bkpt = pdb_bkpt_search(cr3, xen_regs->eip - 1); 23.1114 - if ( (bkpt == NULL) && 23.1115 - !pdb_stepping && 23.1116 - !pdb_system_call && 23.1117 - xen_regs->eip != pdb_system_call_next_addr + 1 && 23.1118 - (exceptionVector != KEYPRESS_EXCEPTION) && 23.1119 - xen_regs->eip < 0xc0000000) /* Linux-specific for now! */ 23.1120 - { 23.1121 - TRC(printf("pdb: user bkpt (0x%x) at 0x%lx:0x%x\n", 23.1122 - exceptionVector, cr3, xen_regs->eip)); 23.1123 - return 1; 23.1124 - } 23.1125 - 23.1126 - printk("pdb_handle_exception [0x%x][0x%lx:0x%x]\n", 23.1127 - exceptionVector, cr3, xen_regs->eip); 23.1128 - 23.1129 - if ( pdb_stepping ) 23.1130 - { 23.1131 - /* Stepped one instruction; now return to normal execution. */ 23.1132 - xen_regs->eflags &= ~X86_EFLAGS_TF; 23.1133 - pdb_stepping = 0; 23.1134 - } 23.1135 - 23.1136 - if ( pdb_system_call ) 23.1137 - { 23.1138 - pdb_system_call = 0; 23.1139 - 23.1140 - pdb_linux_syscall_exit_bkpt (xen_regs, &pdb_ctx); 23.1141 - 23.1142 - /* we don't have a saved breakpoint so we need to rewind eip */ 23.1143 - xen_regs->eip--; 23.1144 - 23.1145 - /* if ther user doesn't care about breaking when entering a 23.1146 - system call then we'll just ignore the exception */ 23.1147 - if ( (pdb_ctx.system_call & 0x01) == 0 ) 23.1148 - { 23.1149 - return 0; 23.1150 - } 23.1151 - } 23.1152 - 23.1153 - if ( exceptionVector == BREAKPT_EXCEPTION && bkpt != NULL) 23.1154 - { 23.1155 - /* Executed Int3: replace breakpoint byte with real program byte. */ 23.1156 - xen_regs->eip--; 23.1157 - } 23.1158 - 23.1159 - /* returning to user space after a system call */ 23.1160 - if ( xen_regs->eip == pdb_system_call_next_addr + 1) 23.1161 - { 23.1162 - u_char instr[2]; /* REALLY REALLY REALLY STUPID */ 23.1163 - 23.1164 - mem2hex (&pdb_system_call_leave_instr, instr, sizeof(instr)); 23.1165 - 23.1166 - pdb_linux_set_values (instr, 1, pdb_system_call_next_addr, 23.1167 - pdb_ctx.process, pdb_ctx.ptbr); 23.1168 - 23.1169 - pdb_system_call_next_addr = 0; 23.1170 - pdb_system_call_leave_instr = 0; 23.1171 - 23.1172 - /* manually rewind eip */ 23.1173 - xen_regs->eip--; 23.1174 - 23.1175 - /* if the user doesn't care about breaking when returning 23.1176 - to user space after a system call then we'll just ignore 23.1177 - the exception */ 23.1178 - if ( (pdb_ctx.system_call & 0x02) == 0 ) 23.1179 - { 23.1180 - return 0; 23.1181 - } 23.1182 - } 23.1183 - 23.1184 - /* Generate a signal for GDB. */ 23.1185 - switch ( exceptionVector ) 23.1186 - { 23.1187 - case KEYPRESS_EXCEPTION: 23.1188 - signal = 2; break; /* SIGINT */ 23.1189 - case DEBUG_EXCEPTION: 23.1190 - signal = 5; break; /* SIGTRAP */ 23.1191 - case BREAKPT_EXCEPTION: 23.1192 - signal = 5; break; /* SIGTRAP */ 23.1193 - default: 23.1194 - printk("pdb: can't generate signal for unknown exception vector %d\n", 23.1195 - exceptionVector); 23.1196 - break; 23.1197 - } 23.1198 - 23.1199 - pdb_out_buffer[0] = 'S'; 23.1200 - pdb_out_buffer[1] = hexchars[signal >> 4]; 23.1201 - pdb_out_buffer[2] = hexchars[signal % 16]; 23.1202 - pdb_out_buffer[3] = 0; 23.1203 - pdb_put_packet(pdb_out_buffer, 1); 23.1204 - 23.1205 - watchdog_save = watchdog_on; 23.1206 - watchdog_on = 0; 23.1207 - 23.1208 - do { 23.1209 - pdb_out_buffer[0] = 0; 23.1210 - pdb_get_packet(pdb_in_buffer); 23.1211 - } 23.1212 - while ( pdb_process_command(pdb_in_buffer, xen_regs, cr3, signal) == 0 ); 23.1213 - 23.1214 - watchdog_on = watchdog_save; 23.1215 - 23.1216 - return 0; 23.1217 -} 23.1218 - 23.1219 -void pdb_key_pressed(unsigned char key) 23.1220 -{ 23.1221 - struct xen_regs *regs = (struct xen_regs *)get_execution_context(); 23.1222 - pdb_handle_exception(KEYPRESS_EXCEPTION, regs); 23.1223 -} 23.1224 - 23.1225 -void pdb_handle_debug_trap(struct xen_regs *regs, long error_code) 23.1226 -{ 23.1227 - unsigned int condition; 23.1228 - struct domain *d = current; 23.1229 - struct trap_bounce *tb = &d->thread.trap_bounce; 23.1230 - 23.1231 - __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); 23.1232 - if ( (condition & (1 << 14)) != (1 << 14) ) 23.1233 - printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition); 23.1234 - __asm__("movl %0,%%db6" : : "r" (0)); 23.1235 - 23.1236 - if ( pdb_handle_exception(1, regs) != 0 ) 23.1237 - { 23.1238 - d->thread.debugreg[6] = condition; 23.1239 - 23.1240 - tb->flags = TBF_EXCEPTION; 23.1241 - tb->cs = d->thread.traps[1].cs; 23.1242 - tb->eip = d->thread.traps[1].address; 23.1243 - } 23.1244 -} 23.1245 - 23.1246 -void initialize_pdb() 23.1247 -{ 23.1248 - /* Certain state must be initialised even when PDB will not be used. */ 23.1249 - memset((void *) &breakpoints, 0, sizeof(breakpoints)); 23.1250 - INIT_LIST_HEAD(&breakpoints.list); 23.1251 - pdb_stepping = 0; 23.1252 - 23.1253 - if ( strcmp(opt_pdb, "none") == 0 ) 23.1254 - return; 23.1255 - 23.1256 - if ( (pdb_serhnd = parse_serial_handle(opt_pdb)) == -1 ) 23.1257 - { 23.1258 - printk("error: failed to initialize PDB on port %s\n", opt_pdb); 23.1259 - return; 23.1260 - } 23.1261 - 23.1262 - pdb_ctx.valid = 1; 23.1263 - pdb_ctx.domain = -1; 23.1264 - pdb_ctx.process = -1; 23.1265 - pdb_ctx.system_call = 0; 23.1266 - pdb_ctx.ptbr = 0; 23.1267 - 23.1268 - printk("pdb: pervasive debugger (%s) www.cl.cam.ac.uk/netos/pdb\n", 23.1269 - opt_pdb); 23.1270 - 23.1271 - /* Acknowledge any spurious GDB packets. */ 23.1272 - pdb_put_char('+'); 23.1273 - 23.1274 - register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger"); 23.1275 - 23.1276 - pdb_initialized = 1; 23.1277 -} 23.1278 - 23.1279 -void breakpoint(void) 23.1280 -{ 23.1281 - if ( pdb_initialized ) 23.1282 - asm("int $3"); 23.1283 -}
24.1 --- a/xen/arch/x86/setup.c Fri Feb 04 19:26:10 2005 +0000 24.2 +++ b/xen/arch/x86/setup.c Mon Feb 07 08:19:24 2005 +0000 24.3 @@ -1,3 +1,4 @@ 24.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 24.5 24.6 #include <xen/config.h> 24.7 #include <xen/init.h> 24.8 @@ -17,7 +18,6 @@ 24.9 #include <asm/apic.h> 24.10 #include <asm/desc.h> 24.11 #include <asm/domain_page.h> 24.12 -#include <asm/pdb.h> 24.13 #include <asm/shadow.h> 24.14 #include <asm/e820.h> 24.15 24.16 @@ -309,7 +309,7 @@ void __init cpu_init(void) 24.17 /* Set up GDT and IDT. */ 24.18 SET_GDT_ENTRIES(current, DEFAULT_GDT_ENTRIES); 24.19 SET_GDT_ADDRESS(current, DEFAULT_GDT_ADDRESS); 24.20 - __asm__ __volatile__ ( "lgdt %0" : "=m" (*current->mm.gdt) ); 24.21 + __asm__ __volatile__ ( "lgdt %0" : "=m" (*current->arch.gdt) ); 24.22 __asm__ __volatile__ ( "lidt %0" : "=m" (idt_descr) ); 24.23 24.24 /* No nested task. */ 24.25 @@ -339,7 +339,7 @@ void __init cpu_init(void) 24.26 percpu_traps_init(); 24.27 24.28 /* Install correct page table. */ 24.29 - write_ptbase(¤t->mm); 24.30 + write_ptbase(current); 24.31 24.32 init_idle_task(); 24.33 } 24.34 @@ -360,7 +360,7 @@ static void __init start_of_day(void) 24.35 #ifdef MEMORY_GUARD 24.36 /* Unmap the first page of CPU0's stack. */ 24.37 extern unsigned long cpu0_stack[]; 24.38 - memguard_guard_range(cpu0_stack, PAGE_SIZE); 24.39 + memguard_guard_stack(cpu0_stack); 24.40 #endif 24.41 24.42 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period); 24.43 @@ -427,10 +427,6 @@ static void __init start_of_day(void) 24.44 24.45 serial_init_stage2(); 24.46 24.47 -#ifdef XEN_DEBUGGER 24.48 - initialize_pdb(); /* pervasive debugger */ 24.49 -#endif 24.50 - 24.51 if ( !cpu_has_apic ) 24.52 { 24.53 do_timer_lists_from_pit = 1; 24.54 @@ -597,10 +593,6 @@ void __init __start_xen(multiboot_info_t 24.55 24.56 early_boot = 0; 24.57 24.58 - /* Initialise the slab allocator. */ 24.59 - xmem_cache_init(); 24.60 - xmem_cache_sizes_init(max_page); 24.61 - 24.62 start_of_day(); 24.63 24.64 grant_table_init();
25.1 --- a/xen/arch/x86/shadow.c Fri Feb 04 19:26:10 2005 +0000 25.2 +++ b/xen/arch/x86/shadow.c Mon Feb 07 08:19:24 2005 +0000 25.3 @@ -1,4 +1,4 @@ 25.4 -/* -*- Mode:C++; c-file-style:BSD; c-basic-offset:4; tab-width:4 -*- */ 25.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 25.6 25.7 #include <xen/config.h> 25.8 #include <xen/types.h> 25.9 @@ -28,9 +28,9 @@ hypercall lock anyhow (at least initiall 25.10 ********/ 25.11 25.12 static inline void free_shadow_page( 25.13 - struct mm_struct *m, struct pfn_info *page) 25.14 + struct domain *d, struct pfn_info *page) 25.15 { 25.16 - m->shadow_page_count--; 25.17 + d->arch.shadow_page_count--; 25.18 25.19 switch ( page->u.inuse.type_info & PGT_type_mask ) 25.20 { 25.21 @@ -51,7 +51,7 @@ static inline void free_shadow_page( 25.22 free_domheap_page(page); 25.23 } 25.24 25.25 -static void free_shadow_state(struct mm_struct *m) 25.26 +static void free_shadow_state(struct domain *d) 25.27 { 25.28 int i, free = 0; 25.29 struct shadow_status *x, *n; 25.30 @@ -61,19 +61,19 @@ static void free_shadow_state(struct mm_ 25.31 * e.g., You are expected to have paused the domain and synchronized CR3. 25.32 */ 25.33 25.34 - shadow_audit(m, 1); 25.35 + shadow_audit(d, 1); 25.36 25.37 /* Free each hash chain in turn. */ 25.38 for ( i = 0; i < shadow_ht_buckets; i++ ) 25.39 { 25.40 /* Skip empty buckets. */ 25.41 - x = &m->shadow_ht[i]; 25.42 + x = &d->arch.shadow_ht[i]; 25.43 if ( x->pfn == 0 ) 25.44 continue; 25.45 25.46 /* Free the head page. */ 25.47 free_shadow_page( 25.48 - m, &frame_table[x->spfn_and_flags & PSH_pfn_mask]); 25.49 + d, &frame_table[x->spfn_and_flags & PSH_pfn_mask]); 25.50 25.51 /* Reinitialise the head node. */ 25.52 x->pfn = 0; 25.53 @@ -88,7 +88,7 @@ static void free_shadow_state(struct mm_ 25.54 { 25.55 /* Free the shadow page. */ 25.56 free_shadow_page( 25.57 - m, &frame_table[x->spfn_and_flags & PSH_pfn_mask]); 25.58 + d, &frame_table[x->spfn_and_flags & PSH_pfn_mask]); 25.59 25.60 /* Re-initialise the chain node. */ 25.61 x->pfn = 0; 25.62 @@ -96,20 +96,20 @@ static void free_shadow_state(struct mm_ 25.63 25.64 /* Add to the free list. */ 25.65 n = x->next; 25.66 - x->next = m->shadow_ht_free; 25.67 - m->shadow_ht_free = x; 25.68 + x->next = d->arch.shadow_ht_free; 25.69 + d->arch.shadow_ht_free = x; 25.70 25.71 free++; 25.72 } 25.73 25.74 - shadow_audit(m, 0); 25.75 + shadow_audit(d, 0); 25.76 } 25.77 25.78 SH_LOG("Free shadow table. Freed=%d.", free); 25.79 } 25.80 25.81 static inline int clear_shadow_page( 25.82 - struct mm_struct *m, struct shadow_status *x) 25.83 + struct domain *d, struct shadow_status *x) 25.84 { 25.85 unsigned long *p; 25.86 int restart = 0; 25.87 @@ -120,7 +120,7 @@ static inline int clear_shadow_page( 25.88 /* We clear L2 pages by zeroing the guest entries. */ 25.89 case PGT_l2_page_table: 25.90 p = map_domain_mem((spage - frame_table) << PAGE_SHIFT); 25.91 - if (m->shadow_mode == SHM_full_32) 25.92 + if (d->arch.shadow_mode == SHM_full_32) 25.93 memset(p, 0, ENTRIES_PER_L2_PAGETABLE * sizeof(*p)); 25.94 else 25.95 memset(p, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*p)); 25.96 @@ -129,8 +129,8 @@ static inline int clear_shadow_page( 25.97 25.98 /* We clear L1 pages by freeing them: no benefit from zeroing them. */ 25.99 case PGT_l1_page_table: 25.100 - delete_shadow_status(m, x->pfn); 25.101 - free_shadow_page(m, spage); 25.102 + delete_shadow_status(d, x->pfn); 25.103 + free_shadow_page(d, spage); 25.104 restart = 1; /* We need to go to start of list again. */ 25.105 break; 25.106 } 25.107 @@ -138,29 +138,29 @@ static inline int clear_shadow_page( 25.108 return restart; 25.109 } 25.110 25.111 -static void clear_shadow_state(struct mm_struct *m) 25.112 +static void clear_shadow_state(struct domain *d) 25.113 { 25.114 int i; 25.115 struct shadow_status *x; 25.116 25.117 - shadow_audit(m, 1); 25.118 + shadow_audit(d, 1); 25.119 25.120 for ( i = 0; i < shadow_ht_buckets; i++ ) 25.121 { 25.122 retry: 25.123 /* Skip empty buckets. */ 25.124 - x = &m->shadow_ht[i]; 25.125 + x = &d->arch.shadow_ht[i]; 25.126 if ( x->pfn == 0 ) 25.127 continue; 25.128 25.129 - if ( clear_shadow_page(m, x) ) 25.130 + if ( clear_shadow_page(d, x) ) 25.131 goto retry; 25.132 25.133 for ( x = x->next; x != NULL; x = x->next ) 25.134 - if ( clear_shadow_page(m, x) ) 25.135 + if ( clear_shadow_page(d, x) ) 25.136 goto retry; 25.137 25.138 - shadow_audit(m, 0); 25.139 + shadow_audit(d, 0); 25.140 } 25.141 25.142 SH_VLOG("Scan shadow table. l1=%d l2=%d", 25.143 @@ -172,119 +172,118 @@ void shadow_mode_init(void) 25.144 { 25.145 } 25.146 25.147 -int shadow_mode_enable(struct domain *p, unsigned int mode) 25.148 +int shadow_mode_enable(struct domain *d, unsigned int mode) 25.149 { 25.150 - struct mm_struct *m = &p->exec_domain[0]->mm; 25.151 - 25.152 - m->shadow_ht = xmalloc_array(struct shadow_status, shadow_ht_buckets); 25.153 - if ( m->shadow_ht == NULL ) 25.154 + d->arch.shadow_ht = xmalloc_array(struct shadow_status, shadow_ht_buckets); 25.155 + if ( d->arch.shadow_ht == NULL ) 25.156 goto nomem; 25.157 - memset(m->shadow_ht, 0, shadow_ht_buckets * sizeof(struct shadow_status)); 25.158 + memset(d->arch.shadow_ht, 0, 25.159 + shadow_ht_buckets * sizeof(struct shadow_status)); 25.160 25.161 if ( mode == SHM_logdirty ) 25.162 { 25.163 - m->shadow_dirty_bitmap_size = (p->max_pages + 63) & ~63; 25.164 - m->shadow_dirty_bitmap = 25.165 - xmalloc_array(unsigned long, m->shadow_dirty_bitmap_size / 25.166 + d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63; 25.167 + d->arch.shadow_dirty_bitmap = 25.168 + xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size / 25.169 (8 * sizeof(unsigned long))); 25.170 - if ( m->shadow_dirty_bitmap == NULL ) 25.171 + if ( d->arch.shadow_dirty_bitmap == NULL ) 25.172 { 25.173 - m->shadow_dirty_bitmap_size = 0; 25.174 + d->arch.shadow_dirty_bitmap_size = 0; 25.175 goto nomem; 25.176 } 25.177 - memset(m->shadow_dirty_bitmap, 0, m->shadow_dirty_bitmap_size/8); 25.178 + memset(d->arch.shadow_dirty_bitmap, 0, 25.179 + d->arch.shadow_dirty_bitmap_size/8); 25.180 } 25.181 25.182 - m->shadow_mode = mode; 25.183 + d->arch.shadow_mode = mode; 25.184 25.185 - __shadow_mk_pagetable(m); 25.186 + __shadow_mk_pagetable(d->exec_domain[0]); /* XXX SMP */ 25.187 return 0; 25.188 25.189 nomem: 25.190 - if ( m->shadow_ht != NULL ) 25.191 - xfree( m->shadow_ht ); 25.192 - m->shadow_ht = NULL; 25.193 + if ( d->arch.shadow_ht != NULL ) 25.194 + xfree(d->arch.shadow_ht); 25.195 + d->arch.shadow_ht = NULL; 25.196 return -ENOMEM; 25.197 } 25.198 25.199 void __shadow_mode_disable(struct domain *d) 25.200 { 25.201 - struct mm_struct *m = &d->exec_domain[0]->mm; 25.202 struct shadow_status *x, *n; 25.203 25.204 - free_shadow_state(m); 25.205 - m->shadow_mode = 0; 25.206 + free_shadow_state(d); 25.207 + d->arch.shadow_mode = 0; 25.208 25.209 SH_VLOG("freed tables count=%d l1=%d l2=%d", 25.210 - m->shadow_page_count, perfc_value(shadow_l1_pages), 25.211 + d->arch.shadow_page_count, perfc_value(shadow_l1_pages), 25.212 perfc_value(shadow_l2_pages)); 25.213 25.214 - n = m->shadow_ht_extras; 25.215 + n = d->arch.shadow_ht_extras; 25.216 while ( (x = n) != NULL ) 25.217 { 25.218 - m->shadow_extras_count--; 25.219 + d->arch.shadow_extras_count--; 25.220 n = *((struct shadow_status **)(&x[shadow_ht_extra_size])); 25.221 xfree(x); 25.222 } 25.223 25.224 - m->shadow_ht_extras = NULL; 25.225 - ASSERT(m->shadow_extras_count == 0); 25.226 - SH_LOG("freed extras, now %d", m->shadow_extras_count); 25.227 + d->arch.shadow_ht_extras = NULL; 25.228 + ASSERT(d->arch.shadow_extras_count == 0); 25.229 + SH_LOG("freed extras, now %d", d->arch.shadow_extras_count); 25.230 25.231 - if ( m->shadow_dirty_bitmap != NULL ) 25.232 + if ( d->arch.shadow_dirty_bitmap != NULL ) 25.233 { 25.234 - xfree(m->shadow_dirty_bitmap); 25.235 - m->shadow_dirty_bitmap = 0; 25.236 - m->shadow_dirty_bitmap_size = 0; 25.237 + xfree(d->arch.shadow_dirty_bitmap); 25.238 + d->arch.shadow_dirty_bitmap = 0; 25.239 + d->arch.shadow_dirty_bitmap_size = 0; 25.240 } 25.241 25.242 - xfree(m->shadow_ht); 25.243 - m->shadow_ht = NULL; 25.244 + xfree(d->arch.shadow_ht); 25.245 + d->arch.shadow_ht = NULL; 25.246 } 25.247 25.248 static int shadow_mode_table_op( 25.249 struct domain *d, dom0_shadow_control_t *sc) 25.250 { 25.251 unsigned int op = sc->op; 25.252 - struct mm_struct *m = &d->exec_domain[0]->mm; 25.253 int i, rc = 0; 25.254 25.255 - ASSERT(spin_is_locked(&m->shadow_lock)); 25.256 + ASSERT(spin_is_locked(&d->arch.shadow_lock)); 25.257 25.258 SH_VLOG("shadow mode table op %08lx %08lx count %d", 25.259 - pagetable_val(m->pagetable), pagetable_val(m->shadow_table), 25.260 - m->shadow_page_count); 25.261 + pagetable_val(d->exec_domain[0]->arch.pagetable), /* XXX SMP */ 25.262 + pagetable_val(d->exec_domain[0]->arch.shadow_table), /* XXX SMP */ 25.263 + d->arch.shadow_page_count); 25.264 25.265 - shadow_audit(m, 1); 25.266 + shadow_audit(d, 1); 25.267 25.268 switch ( op ) 25.269 { 25.270 case DOM0_SHADOW_CONTROL_OP_FLUSH: 25.271 - free_shadow_state(m); 25.272 + free_shadow_state(d); 25.273 25.274 - m->shadow_fault_count = 0; 25.275 - m->shadow_dirty_count = 0; 25.276 - m->shadow_dirty_net_count = 0; 25.277 - m->shadow_dirty_block_count = 0; 25.278 + d->arch.shadow_fault_count = 0; 25.279 + d->arch.shadow_dirty_count = 0; 25.280 + d->arch.shadow_dirty_net_count = 0; 25.281 + d->arch.shadow_dirty_block_count = 0; 25.282 25.283 break; 25.284 25.285 case DOM0_SHADOW_CONTROL_OP_CLEAN: 25.286 - clear_shadow_state(m); 25.287 + clear_shadow_state(d); 25.288 25.289 - sc->stats.fault_count = m->shadow_fault_count; 25.290 - sc->stats.dirty_count = m->shadow_dirty_count; 25.291 - sc->stats.dirty_net_count = m->shadow_dirty_net_count; 25.292 - sc->stats.dirty_block_count = m->shadow_dirty_block_count; 25.293 + sc->stats.fault_count = d->arch.shadow_fault_count; 25.294 + sc->stats.dirty_count = d->arch.shadow_dirty_count; 25.295 + sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count; 25.296 + sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count; 25.297 25.298 - m->shadow_fault_count = 0; 25.299 - m->shadow_dirty_count = 0; 25.300 - m->shadow_dirty_net_count = 0; 25.301 - m->shadow_dirty_block_count = 0; 25.302 + d->arch.shadow_fault_count = 0; 25.303 + d->arch.shadow_dirty_count = 0; 25.304 + d->arch.shadow_dirty_net_count = 0; 25.305 + d->arch.shadow_dirty_block_count = 0; 25.306 25.307 if ( (d->max_pages > sc->pages) || 25.308 (sc->dirty_bitmap == NULL) || 25.309 - (m->shadow_dirty_bitmap == NULL) ) 25.310 + (d->arch.shadow_dirty_bitmap == NULL) ) 25.311 { 25.312 rc = -EINVAL; 25.313 break; 25.314 @@ -300,34 +299,35 @@ static int shadow_mode_table_op( 25.315 25.316 if (copy_to_user( 25.317 sc->dirty_bitmap + (i/(8*sizeof(unsigned long))), 25.318 - m->shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), 25.319 + d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))), 25.320 bytes)) 25.321 { 25.322 // copy_to_user can fail when copying to guest app memory. 25.323 // app should zero buffer after mallocing, and pin it 25.324 rc = -EINVAL; 25.325 memset( 25.326 - m->shadow_dirty_bitmap + (i/(8*sizeof(unsigned long))), 25.327 + d->arch.shadow_dirty_bitmap + 25.328 + (i/(8*sizeof(unsigned long))), 25.329 0, (d->max_pages/8) - (i/(8*sizeof(unsigned long)))); 25.330 break; 25.331 } 25.332 25.333 memset( 25.334 - m->shadow_dirty_bitmap + (i/(8*sizeof(unsigned long))), 25.335 + d->arch.shadow_dirty_bitmap + (i/(8*sizeof(unsigned long))), 25.336 0, bytes); 25.337 } 25.338 25.339 break; 25.340 25.341 case DOM0_SHADOW_CONTROL_OP_PEEK: 25.342 - sc->stats.fault_count = m->shadow_fault_count; 25.343 - sc->stats.dirty_count = m->shadow_dirty_count; 25.344 - sc->stats.dirty_net_count = m->shadow_dirty_net_count; 25.345 - sc->stats.dirty_block_count = m->shadow_dirty_block_count; 25.346 + sc->stats.fault_count = d->arch.shadow_fault_count; 25.347 + sc->stats.dirty_count = d->arch.shadow_dirty_count; 25.348 + sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count; 25.349 + sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count; 25.350 25.351 if ( (d->max_pages > sc->pages) || 25.352 (sc->dirty_bitmap == NULL) || 25.353 - (m->shadow_dirty_bitmap == NULL) ) 25.354 + (d->arch.shadow_dirty_bitmap == NULL) ) 25.355 { 25.356 rc = -EINVAL; 25.357 break; 25.358 @@ -335,7 +335,7 @@ static int shadow_mode_table_op( 25.359 25.360 sc->pages = d->max_pages; 25.361 if (copy_to_user( 25.362 - sc->dirty_bitmap, m->shadow_dirty_bitmap, (d->max_pages+7)/8)) 25.363 + sc->dirty_bitmap, d->arch.shadow_dirty_bitmap, (d->max_pages+7)/8)) 25.364 { 25.365 rc = -EINVAL; 25.366 break; 25.367 @@ -348,9 +348,9 @@ static int shadow_mode_table_op( 25.368 break; 25.369 } 25.370 25.371 - SH_VLOG("shadow mode table op : page count %d", m->shadow_page_count); 25.372 - shadow_audit(m, 1); 25.373 - __shadow_mk_pagetable(m); 25.374 + SH_VLOG("shadow mode table op : page count %d", d->arch.shadow_page_count); 25.375 + shadow_audit(d, 1); 25.376 + __shadow_mk_pagetable(d->exec_domain[0]); /* XXX SMP */ 25.377 return rc; 25.378 } 25.379 25.380 @@ -368,7 +368,7 @@ int shadow_mode_control(struct domain *d 25.381 domain_pause(d); 25.382 synchronise_pagetables(~0UL); 25.383 25.384 - shadow_lock(&d->exec_domain[0]->mm); 25.385 + shadow_lock(d); 25.386 25.387 switch ( op ) 25.388 { 25.389 @@ -387,27 +387,27 @@ int shadow_mode_control(struct domain *d 25.390 break; 25.391 25.392 default: 25.393 - rc = shadow_mode(d->exec_domain[0]) ? shadow_mode_table_op(d, sc) : -EINVAL; 25.394 + rc = shadow_mode(d) ? shadow_mode_table_op(d, sc) : -EINVAL; 25.395 break; 25.396 } 25.397 25.398 - shadow_unlock(&d->exec_domain[0]->mm); 25.399 + shadow_unlock(d); 25.400 25.401 domain_unpause(d); 25.402 25.403 return rc; 25.404 } 25.405 25.406 -static inline struct pfn_info *alloc_shadow_page(struct mm_struct *m) 25.407 +static inline struct pfn_info *alloc_shadow_page(struct domain *d) 25.408 { 25.409 struct pfn_info *page = alloc_domheap_page(NULL); 25.410 25.411 - m->shadow_page_count++; 25.412 + d->arch.shadow_page_count++; 25.413 25.414 if ( unlikely(page == NULL) ) 25.415 { 25.416 printk("Couldn't alloc shadow page! count=%d\n", 25.417 - m->shadow_page_count); 25.418 + d->arch.shadow_page_count); 25.419 SH_VLOG("Shadow tables l1=%d l2=%d", 25.420 perfc_value(shadow_l1_pages), 25.421 perfc_value(shadow_l2_pages)); 25.422 @@ -431,35 +431,35 @@ void unshadow_table(unsigned long gpfn, 25.423 * guests there won't be a race here as this CPU was the one that 25.424 * cmpxchg'ed the page to invalid. 25.425 */ 25.426 - spfn = __shadow_status(&d->exec_domain[0]->mm, gpfn) & PSH_pfn_mask; 25.427 - delete_shadow_status(&d->exec_domain[0]->mm, gpfn); 25.428 - free_shadow_page(&d->exec_domain[0]->mm, &frame_table[spfn]); 25.429 + spfn = __shadow_status(d, gpfn) & PSH_pfn_mask; 25.430 + delete_shadow_status(d, gpfn); 25.431 + free_shadow_page(d, &frame_table[spfn]); 25.432 } 25.433 25.434 #ifdef CONFIG_VMX 25.435 -void vmx_shadow_clear_state(struct mm_struct *m) 25.436 +void vmx_shadow_clear_state(struct domain *d) 25.437 { 25.438 SH_VVLOG("vmx_clear_shadow_state: \n"); 25.439 - clear_shadow_state(m); 25.440 + clear_shadow_state(d); 25.441 } 25.442 #endif 25.443 25.444 25.445 unsigned long shadow_l2_table( 25.446 - struct mm_struct *m, unsigned long gpfn) 25.447 + struct domain *d, unsigned long gpfn) 25.448 { 25.449 struct pfn_info *spfn_info; 25.450 unsigned long spfn; 25.451 l2_pgentry_t *spl2e = 0; 25.452 unsigned long guest_gpfn; 25.453 25.454 - __get_machine_to_phys(m, guest_gpfn, gpfn); 25.455 + __get_machine_to_phys(d, guest_gpfn, gpfn); 25.456 25.457 SH_VVLOG("shadow_l2_table( %08lx )", gpfn); 25.458 25.459 perfc_incrc(shadow_l2_table_count); 25.460 25.461 - if ( (spfn_info = alloc_shadow_page(m)) == NULL ) 25.462 + if ( (spfn_info = alloc_shadow_page(d)) == NULL ) 25.463 BUG(); /* XXX Deal gracefully with failure. */ 25.464 25.465 spfn_info->u.inuse.type_info = PGT_l2_page_table; 25.466 @@ -467,13 +467,13 @@ unsigned long shadow_l2_table( 25.467 25.468 spfn = spfn_info - frame_table; 25.469 /* Mark pfn as being shadowed; update field to point at shadow. */ 25.470 - set_shadow_status(m, guest_gpfn, spfn | PSH_shadowed); 25.471 + set_shadow_status(d, guest_gpfn, spfn | PSH_shadowed); 25.472 25.473 #ifdef __i386__ 25.474 /* Install hypervisor and 2x linear p.t. mapings. */ 25.475 - if ( m->shadow_mode == SHM_full_32 ) 25.476 + if ( d->arch.shadow_mode == SHM_full_32 ) 25.477 { 25.478 - vmx_update_shadow_state(m, gpfn, spfn); 25.479 + vmx_update_shadow_state(d->exec_domain[0], gpfn, spfn); 25.480 } 25.481 else 25.482 { 25.483 @@ -494,12 +494,12 @@ unsigned long shadow_l2_table( 25.484 spl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = 25.485 mk_l2_pgentry((spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 25.486 spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = 25.487 - mk_l2_pgentry(__pa(page_get_owner(&frame_table[gpfn])->mm_perdomain_pt) | 25.488 - __PAGE_HYPERVISOR); 25.489 + mk_l2_pgentry(__pa(page_get_owner(&frame_table[gpfn])->arch.mm_perdomain_pt) | 25.490 + __PAGE_HYPERVISOR); 25.491 } 25.492 #endif 25.493 25.494 - if ( m->shadow_mode != SHM_full_32 ) 25.495 + if ( d->arch.shadow_mode != SHM_full_32 ) 25.496 unmap_domain_mem(spl2e); 25.497 25.498 SH_VLOG("shadow_l2_table( %08lx -> %08lx)", gpfn, spfn); 25.499 @@ -508,22 +508,23 @@ unsigned long shadow_l2_table( 25.500 25.501 static void shadow_map_l1_into_current_l2(unsigned long va) 25.502 { 25.503 - struct mm_struct *m = ¤t->mm; 25.504 + struct exec_domain *ed = current; 25.505 + struct domain *d = ed->domain; 25.506 unsigned long *gpl1e, *spl1e, gpl2e, spl2e, gl1pfn, sl1pfn=0, sl1ss; 25.507 struct pfn_info *sl1pfn_info; 25.508 int i; 25.509 25.510 - __guest_get_pl2e(m, va, &gpl2e); 25.511 + __guest_get_pl2e(ed, va, &gpl2e); 25.512 25.513 gl1pfn = gpl2e >> PAGE_SHIFT; 25.514 25.515 - sl1ss = __shadow_status(m, gl1pfn); 25.516 + sl1ss = __shadow_status(d, gl1pfn); 25.517 if ( !(sl1ss & PSH_shadowed) ) 25.518 { 25.519 /* This L1 is NOT already shadowed so we need to shadow it. */ 25.520 SH_VVLOG("4a: l1 not shadowed ( %08lx )", sl1pfn); 25.521 25.522 - sl1pfn_info = alloc_shadow_page(m); 25.523 + sl1pfn_info = alloc_shadow_page(d); 25.524 sl1pfn_info->u.inuse.type_info = PGT_l1_page_table; 25.525 25.526 sl1pfn = sl1pfn_info - frame_table; 25.527 @@ -531,12 +532,12 @@ static void shadow_map_l1_into_current_l 25.528 perfc_incrc(shadow_l1_table_count); 25.529 perfc_incr(shadow_l1_pages); 25.530 25.531 - set_shadow_status(m, gl1pfn, PSH_shadowed | sl1pfn); 25.532 + set_shadow_status(d, gl1pfn, PSH_shadowed | sl1pfn); 25.533 25.534 - l2pde_general(m, &gpl2e, &spl2e, sl1pfn); 25.535 + l2pde_general(d, &gpl2e, &spl2e, sl1pfn); 25.536 25.537 - __guest_set_pl2e(m, va, gpl2e); 25.538 - __shadow_set_pl2e(m, va, spl2e); 25.539 + __guest_set_pl2e(ed, va, gpl2e); 25.540 + __shadow_set_pl2e(ed, va, spl2e); 25.541 25.542 gpl1e = (unsigned long *) &(linear_pg_table[ 25.543 (va>>L1_PAGETABLE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)]); 25.544 @@ -545,7 +546,7 @@ static void shadow_map_l1_into_current_l 25.545 (va>>L1_PAGETABLE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)]); 25.546 25.547 for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) 25.548 - l1pte_propagate_from_guest(m, &gpl1e[i], &spl1e[i]); 25.549 + l1pte_propagate_from_guest(d, &gpl1e[i], &spl1e[i]); 25.550 } 25.551 else 25.552 { 25.553 @@ -553,20 +554,20 @@ static void shadow_map_l1_into_current_l 25.554 SH_VVLOG("4b: was shadowed, l2 missing ( %08lx )", sl1pfn); 25.555 25.556 sl1pfn = sl1ss & PSH_pfn_mask; 25.557 - l2pde_general(m, &gpl2e, &spl2e, sl1pfn); 25.558 - __guest_set_pl2e(m, va, gpl2e); 25.559 - __shadow_set_pl2e(m, va, spl2e); 25.560 + l2pde_general(d, &gpl2e, &spl2e, sl1pfn); 25.561 + __guest_set_pl2e(ed, va, gpl2e); 25.562 + __shadow_set_pl2e(ed, va, spl2e); 25.563 } 25.564 } 25.565 25.566 #ifdef CONFIG_VMX 25.567 -void vmx_shadow_invlpg(struct mm_struct *m, unsigned long va) 25.568 +void vmx_shadow_invlpg(struct domain *d, unsigned long va) 25.569 { 25.570 unsigned long gpte, spte, host_pfn; 25.571 25.572 if (__put_user(0L, (unsigned long *) 25.573 &shadow_linear_pg_table[va >> PAGE_SHIFT])) { 25.574 - vmx_shadow_clear_state(m); 25.575 + vmx_shadow_clear_state(d); 25.576 return; 25.577 } 25.578 25.579 @@ -588,11 +589,12 @@ void vmx_shadow_invlpg(struct mm_struct 25.580 int shadow_fault(unsigned long va, long error_code) 25.581 { 25.582 unsigned long gpte, spte; 25.583 - struct mm_struct *m = ¤t->mm; 25.584 + struct exec_domain *ed = current; 25.585 + struct domain *d = ed->domain; 25.586 25.587 SH_VVLOG("shadow_fault( va=%08lx, code=%ld )", va, error_code ); 25.588 25.589 - check_pagetable(m, current->mm.pagetable, "pre-sf"); 25.590 + check_pagetable(d, ed->arch.pagetable, "pre-sf"); 25.591 25.592 /* 25.593 * STEP 1. A fast-reject set of checks with no locking. 25.594 @@ -621,20 +623,20 @@ int shadow_fault(unsigned long va, long 25.595 * STEP 2. Take the shadow lock and re-check the guest PTE. 25.596 */ 25.597 25.598 - shadow_lock(m); 25.599 + shadow_lock(d); 25.600 25.601 if ( unlikely(__get_user(gpte, (unsigned long *) 25.602 &linear_pg_table[va >> PAGE_SHIFT])) ) 25.603 { 25.604 SH_VVLOG("shadow_fault - EXIT: read gpte faulted" ); 25.605 - shadow_unlock(m); 25.606 + shadow_unlock(d); 25.607 return 0; 25.608 } 25.609 25.610 if ( unlikely(!(gpte & _PAGE_PRESENT)) ) 25.611 { 25.612 SH_VVLOG("shadow_fault - EXIT: gpte not present (%lx)",gpte ); 25.613 - shadow_unlock(m); 25.614 + shadow_unlock(d); 25.615 return 0; 25.616 } 25.617 25.618 @@ -645,15 +647,15 @@ int shadow_fault(unsigned long va, long 25.619 { 25.620 /* Write fault on a read-only mapping. */ 25.621 SH_VVLOG("shadow_fault - EXIT: wr fault on RO page (%lx)", gpte); 25.622 - shadow_unlock(m); 25.623 + shadow_unlock(d); 25.624 return 0; 25.625 } 25.626 25.627 - l1pte_write_fault(m, &gpte, &spte); 25.628 + l1pte_write_fault(d, &gpte, &spte); 25.629 } 25.630 else 25.631 { 25.632 - l1pte_read_fault(m, &gpte, &spte); 25.633 + l1pte_read_fault(d, &gpte, &spte); 25.634 } 25.635 25.636 /* 25.637 @@ -678,11 +680,11 @@ int shadow_fault(unsigned long va, long 25.638 } 25.639 25.640 perfc_incrc(shadow_fixup_count); 25.641 - m->shadow_fault_count++; 25.642 + d->arch.shadow_fault_count++; 25.643 25.644 - shadow_unlock(m); 25.645 + shadow_unlock(d); 25.646 25.647 - check_pagetable(m, current->mm.pagetable, "post-sf"); 25.648 + check_pagetable(d, ed->arch.pagetable, "post-sf"); 25.649 return EXCRET_fault_fixed; 25.650 } 25.651 25.652 @@ -700,7 +702,7 @@ void shadow_l1_normal_pt_update( 25.653 "prev_spfn=%08lx, prev_spl1e=%p\n", 25.654 pa, gpte, prev_spfn, prev_spl1e); 25.655 25.656 - spfn = __shadow_status(¤t->mm, pa >> PAGE_SHIFT) & PSH_pfn_mask; 25.657 + spfn = __shadow_status(current->domain, pa >> PAGE_SHIFT) & PSH_pfn_mask; 25.658 25.659 if ( spfn == prev_spfn ) 25.660 { 25.661 @@ -715,7 +717,7 @@ void shadow_l1_normal_pt_update( 25.662 *prev_spl1e_ptr = spl1e; 25.663 } 25.664 25.665 - l1pte_propagate_from_guest(¤t->mm, &gpte, &spte); 25.666 + l1pte_propagate_from_guest(current->domain, &gpte, &spte); 25.667 spl1e[(pa & ~PAGE_MASK) / sizeof(l1_pgentry_t)] = mk_l1_pgentry(spte); 25.668 } 25.669 25.670 @@ -728,13 +730,13 @@ void shadow_l2_normal_pt_update(unsigned 25.671 /* N.B. To get here, we know the l2 page *must* be shadowed. */ 25.672 SH_VVLOG("shadow_l2_normal_pt_update pa=%08lx, gpte=%08lx",pa,gpte); 25.673 25.674 - spfn = __shadow_status(¤t->mm, pa >> PAGE_SHIFT) & PSH_pfn_mask; 25.675 + spfn = __shadow_status(current->domain, pa >> PAGE_SHIFT) & PSH_pfn_mask; 25.676 25.677 s_sh = (gpte & _PAGE_PRESENT) ? 25.678 - __shadow_status(¤t->mm, gpte >> PAGE_SHIFT) : 0; 25.679 + __shadow_status(current->domain, gpte >> PAGE_SHIFT) : 0; 25.680 25.681 /* XXXX Should mark guest pte as DIRTY and ACCESSED too! */ 25.682 - l2pde_general(¤t->mm, &gpte, &spte, s_sh); 25.683 + l2pde_general(current->domain, &gpte, &spte, s_sh); 25.684 spl2e = (l2_pgentry_t *)map_domain_mem(spfn << PAGE_SHIFT); 25.685 spl2e[(pa & ~PAGE_MASK) / sizeof(l2_pgentry_t)] = mk_l2_pgentry(spte); 25.686 unmap_domain_mem(spl2e); 25.687 @@ -761,13 +763,11 @@ char * sh_check_name; 25.688 } while ( 0 ) 25.689 25.690 static int check_pte( 25.691 - struct mm_struct *m, unsigned long gpte, unsigned long spte, 25.692 + struct domain *d, unsigned long gpte, unsigned long spte, 25.693 int level, int i) 25.694 { 25.695 unsigned long mask, gpfn, spfn; 25.696 -#ifdef CONFIG_VMX 25.697 unsigned long guest_gpfn; 25.698 -#endif 25.699 25.700 if ( (spte == 0) || (spte == 0xdeadface) || (spte == 0x00000E00) ) 25.701 return 1; /* always safe */ 25.702 @@ -811,18 +811,18 @@ static int check_pte( 25.703 if ( level < 2 ) 25.704 FAIL("Shadow in L1 entry?"); 25.705 25.706 - if (m->shadow_mode == SHM_full_32) { 25.707 + if (d->arch.shadow_mode == SHM_full_32) { 25.708 25.709 guest_gpfn = phys_to_machine_mapping[gpfn]; 25.710 25.711 - if ( __shadow_status(m, guest_gpfn) != (PSH_shadowed | spfn) ) 25.712 + if ( __shadow_status(d, guest_gpfn) != (PSH_shadowed | spfn) ) 25.713 FAIL("spfn problem g.sf=%08lx", 25.714 - __shadow_status(m, guest_gpfn) ); 25.715 + __shadow_status(d, guest_gpfn) ); 25.716 25.717 } else { 25.718 - if ( __shadow_status(m, gpfn) != (PSH_shadowed | spfn) ) 25.719 + if ( __shadow_status(d, gpfn) != (PSH_shadowed | spfn) ) 25.720 FAIL("spfn problem g.sf=%08lx", 25.721 - __shadow_status(m, gpfn) ); 25.722 + __shadow_status(d, gpfn) ); 25.723 } 25.724 25.725 } 25.726 @@ -832,7 +832,7 @@ static int check_pte( 25.727 25.728 25.729 static int check_l1_table( 25.730 - struct mm_struct *m, unsigned long va, 25.731 + struct domain *d, unsigned long va, 25.732 unsigned long g2, unsigned long s2) 25.733 { 25.734 int i; 25.735 @@ -842,7 +842,7 @@ static int check_l1_table( 25.736 spl1e = map_domain_mem(s2 << PAGE_SHIFT); 25.737 25.738 for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) 25.739 - check_pte(m, gpl1e[i], spl1e[i], 1, i); 25.740 + check_pte(d, gpl1e[i], spl1e[i], 1, i); 25.741 25.742 unmap_domain_mem(spl1e); 25.743 unmap_domain_mem(gpl1e); 25.744 @@ -856,11 +856,11 @@ static int check_l1_table( 25.745 BUG(); \ 25.746 } while ( 0 ) 25.747 25.748 -int check_pagetable(struct mm_struct *m, pagetable_t pt, char *s) 25.749 +int check_pagetable(struct domain *d, pagetable_t pt, char *s) 25.750 { 25.751 unsigned long gptbase = pagetable_val(pt); 25.752 unsigned long gpfn, spfn; 25.753 - int i; 25.754 + unsigned long i; 25.755 l2_pgentry_t *gpl2e, *spl2e; 25.756 unsigned long host_gpfn = 0; 25.757 25.758 @@ -872,22 +872,22 @@ int check_pagetable(struct mm_struct *m, 25.759 25.760 gpfn = gptbase >> PAGE_SHIFT; 25.761 25.762 - __get_phys_to_machine(m, host_gpfn, gpfn); 25.763 + __get_phys_to_machine(d, host_gpfn, gpfn); 25.764 25.765 - if ( ! (__shadow_status(m, gpfn) & PSH_shadowed) ) 25.766 + if ( ! (__shadow_status(d, gpfn) & PSH_shadowed) ) 25.767 { 25.768 printk("%s-PT %08lx not shadowed\n", s, gptbase); 25.769 25.770 - if( __shadow_status(m, gpfn) != 0 ) BUG(); 25.771 + if( __shadow_status(d, gpfn) != 0 ) BUG(); 25.772 return 0; 25.773 } 25.774 25.775 - spfn = __shadow_status(m, gpfn) & PSH_pfn_mask; 25.776 + spfn = __shadow_status(d, gpfn) & PSH_pfn_mask; 25.777 25.778 - if ( ! __shadow_status(m, gpfn) == (PSH_shadowed | spfn) ) 25.779 + if ( ! __shadow_status(d, gpfn) == (PSH_shadowed | spfn) ) 25.780 FAILPT("ptbase shadow inconsistent1"); 25.781 25.782 - if (m->shadow_mode == SHM_full_32) 25.783 + if (d->arch.shadow_mode == SHM_full_32) 25.784 { 25.785 host_gpfn = phys_to_machine_mapping[gpfn]; 25.786 gpl2e = (l2_pgentry_t *) map_domain_mem( host_gpfn << PAGE_SHIFT ); 25.787 @@ -922,23 +922,23 @@ int check_pagetable(struct mm_struct *m, 25.788 L2_PAGETABLE_SHIFT]), 25.789 (spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 25.790 25.791 - if (m->shadow_mode != SHM_full_32) { 25.792 + if (d->arch.shadow_mode != SHM_full_32) { 25.793 if ( (l2_pgentry_val(spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT]) != 25.794 - ((__pa(page_get_owner(&frame_table[gpfn])->mm.perdomain_pt) | 25.795 + ((__pa(page_get_owner(&frame_table[gpfn])->arch.mm_perdomain_pt) | 25.796 __PAGE_HYPERVISOR))) ) 25.797 FAILPT("hypervisor per-domain map inconsistent"); 25.798 } 25.799 25.800 /* Check the whole L2. */ 25.801 for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) 25.802 - check_pte(m, l2_pgentry_val(gpl2e[i]), l2_pgentry_val(spl2e[i]), 2, i); 25.803 + check_pte(d, l2_pgentry_val(gpl2e[i]), l2_pgentry_val(spl2e[i]), 2, i); 25.804 25.805 /* Go back and recurse. */ 25.806 for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) 25.807 { 25.808 if ( l2_pgentry_val(spl2e[i]) != 0 ) 25.809 check_l1_table( 25.810 - m, i << L2_PAGETABLE_SHIFT, 25.811 + d, i << L2_PAGETABLE_SHIFT, 25.812 l2_pgentry_val(gpl2e[i]) >> PAGE_SHIFT, 25.813 l2_pgentry_val(spl2e[i]) >> PAGE_SHIFT); 25.814 }
26.1 --- a/xen/arch/x86/smpboot.c Fri Feb 04 19:26:10 2005 +0000 26.2 +++ b/xen/arch/x86/smpboot.c Mon Feb 07 08:19:24 2005 +0000 26.3 @@ -1,3 +1,4 @@ 26.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 26.5 /* 26.6 * x86 SMP booting functions 26.7 * 26.8 @@ -662,7 +663,7 @@ static void __init do_boot_cpu (int apic 26.9 26.10 set_bit(DF_IDLETASK, &idle->d_flags); 26.11 26.12 - ed->mm.pagetable = mk_pagetable(__pa(idle_pg_table)); 26.13 + ed->arch.pagetable = mk_pagetable(__pa(idle_pg_table)); 26.14 26.15 map_cpu_to_boot_apicid(cpu, apicid); 26.16 26.17 @@ -674,7 +675,7 @@ static void __init do_boot_cpu (int apic 26.18 /* So we see what's up. */ 26.19 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); 26.20 26.21 - stack = (void *)alloc_xenheap_pages(1); 26.22 + stack = (void *)alloc_xenheap_pages(STACK_ORDER); 26.23 #if defined(__i386__) 26.24 stack_start.esp = __pa(stack) + STACK_SIZE - STACK_RESERVED; 26.25 #elif defined(__x86_64__) 26.26 @@ -682,7 +683,7 @@ static void __init do_boot_cpu (int apic 26.27 #endif 26.28 26.29 /* Debug build: detect stack overflow by setting up a guard page. */ 26.30 - memguard_guard_range(stack, PAGE_SIZE); 26.31 + memguard_guard_stack(stack); 26.32 26.33 /* 26.34 * This grunge runs the startup process for
27.1 --- a/xen/arch/x86/time.c Fri Feb 04 19:26:10 2005 +0000 27.2 +++ b/xen/arch/x86/time.c Mon Feb 07 08:19:24 2005 +0000 27.3 @@ -1,4 +1,4 @@ 27.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 27.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- 27.6 **************************************************************************** 27.7 * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge 27.8 * (C) 2002-2003 University of Cambridge
28.1 --- a/xen/arch/x86/traps.c Fri Feb 04 19:26:10 2005 +0000 28.2 +++ b/xen/arch/x86/traps.c Mon Feb 07 08:19:24 2005 +0000 28.3 @@ -1,3 +1,4 @@ 28.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 28.5 /****************************************************************************** 28.6 * arch/x86/traps.c 28.7 * 28.8 @@ -139,7 +140,7 @@ static inline int do_trap(int trapnr, ch 28.9 int use_error_code) 28.10 { 28.11 struct exec_domain *ed = current; 28.12 - struct trap_bounce *tb = &ed->thread.trap_bounce; 28.13 + struct trap_bounce *tb = &ed->arch.trap_bounce; 28.14 trap_info_t *ti; 28.15 unsigned long fixup; 28.16 28.17 @@ -148,7 +149,7 @@ static inline int do_trap(int trapnr, ch 28.18 if ( !GUEST_FAULT(regs) ) 28.19 goto xen_fault; 28.20 28.21 - ti = current->thread.traps + trapnr; 28.22 + ti = current->arch.traps + trapnr; 28.23 tb->flags = TBF_EXCEPTION; 28.24 tb->cs = ti->cs; 28.25 tb->eip = ti->address; 28.26 @@ -206,7 +207,7 @@ DO_ERROR_NOCODE(19, "simd error", simd_c 28.27 asmlinkage int do_int3(struct xen_regs *regs) 28.28 { 28.29 struct exec_domain *ed = current; 28.30 - struct trap_bounce *tb = &ed->thread.trap_bounce; 28.31 + struct trap_bounce *tb = &ed->arch.trap_bounce; 28.32 trap_info_t *ti; 28.33 28.34 DEBUGGER_trap_entry(TRAP_int3, regs); 28.35 @@ -218,7 +219,7 @@ asmlinkage int do_int3(struct xen_regs * 28.36 panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id()); 28.37 } 28.38 28.39 - ti = current->thread.traps + 3; 28.40 + ti = current->arch.traps + 3; 28.41 tb->flags = TBF_EXCEPTION; 28.42 tb->cs = ti->cs; 28.43 tb->eip = ti->address; 28.44 @@ -237,9 +238,9 @@ void propagate_page_fault(unsigned long 28.45 { 28.46 trap_info_t *ti; 28.47 struct exec_domain *ed = current; 28.48 - struct trap_bounce *tb = &ed->thread.trap_bounce; 28.49 + struct trap_bounce *tb = &ed->arch.trap_bounce; 28.50 28.51 - ti = ed->thread.traps + 14; 28.52 + ti = ed->arch.traps + 14; 28.53 tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2; 28.54 tb->cr2 = addr; 28.55 tb->error_code = error_code; 28.56 @@ -248,7 +249,7 @@ void propagate_page_fault(unsigned long 28.57 if ( TI_GET_IF(ti) ) 28.58 ed->vcpu_info->evtchn_upcall_mask = 1; 28.59 28.60 - ed->mm.guest_cr2 = addr; 28.61 + ed->arch.guest_cr2 = addr; 28.62 } 28.63 28.64 asmlinkage int do_page_fault(struct xen_regs *regs) 28.65 @@ -282,7 +283,7 @@ asmlinkage int do_page_fault(struct xen_ 28.66 ((regs->error_code & 3) == 3) && /* write-protection fault */ 28.67 ptwr_do_page_fault(addr) ) 28.68 { 28.69 - if ( unlikely(ed->mm.shadow_mode) ) 28.70 + if ( unlikely(d->arch.shadow_mode) ) 28.71 (void)shadow_fault(addr, regs->error_code); 28.72 UNLOCK_BIGLOCK(d); 28.73 return EXCRET_fault_fixed; 28.74 @@ -290,12 +291,12 @@ asmlinkage int do_page_fault(struct xen_ 28.75 UNLOCK_BIGLOCK(d); 28.76 } 28.77 28.78 - if ( unlikely(ed->mm.shadow_mode) && 28.79 + if ( unlikely(d->arch.shadow_mode) && 28.80 (addr < PAGE_OFFSET) && shadow_fault(addr, regs->error_code) ) 28.81 return EXCRET_fault_fixed; 28.82 28.83 if ( unlikely(addr >= LDT_VIRT_START(ed)) && 28.84 - (addr < (LDT_VIRT_START(ed) + (ed->mm.ldt_ents*LDT_ENTRY_SIZE))) ) 28.85 + (addr < (LDT_VIRT_START(ed) + (ed->arch.ldt_ents*LDT_ENTRY_SIZE))) ) 28.86 { 28.87 /* 28.88 * Copy a mapping from the guest's LDT, if it is valid. Otherwise we 28.89 @@ -303,7 +304,7 @@ asmlinkage int do_page_fault(struct xen_ 28.90 */ 28.91 LOCK_BIGLOCK(d); 28.92 off = addr - LDT_VIRT_START(ed); 28.93 - addr = ed->mm.ldt_base + off; 28.94 + addr = ed->arch.ldt_base + off; 28.95 ret = map_ldt_shadow_page(off >> PAGE_SHIFT); 28.96 UNLOCK_BIGLOCK(d); 28.97 if ( likely(ret) ) 28.98 @@ -321,7 +322,7 @@ asmlinkage int do_page_fault(struct xen_ 28.99 if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) 28.100 { 28.101 perfc_incrc(copy_user_faults); 28.102 - if ( !ed->mm.shadow_mode ) 28.103 + if ( !d->arch.shadow_mode ) 28.104 DPRINTK("Page fault: %p -> %p\n", regs->eip, fixup); 28.105 regs->eip = fixup; 28.106 return 0; 28.107 @@ -388,11 +389,11 @@ static int emulate_privileged_op(struct 28.108 break; 28.109 28.110 case 2: /* Read CR2 */ 28.111 - *reg = ed->mm.guest_cr2; 28.112 + *reg = ed->arch.guest_cr2; 28.113 break; 28.114 28.115 case 3: /* Read CR3 */ 28.116 - *reg = pagetable_val(ed->mm.pagetable); 28.117 + *reg = pagetable_val(ed->arch.pagetable); 28.118 break; 28.119 28.120 default: 28.121 @@ -415,7 +416,7 @@ static int emulate_privileged_op(struct 28.122 break; 28.123 28.124 case 2: /* Write CR2 */ 28.125 - ed->mm.guest_cr2 = *reg; 28.126 + ed->arch.guest_cr2 = *reg; 28.127 break; 28.128 28.129 case 3: /* Write CR3 */ 28.130 @@ -465,7 +466,7 @@ static int emulate_privileged_op(struct 28.131 asmlinkage int do_general_protection(struct xen_regs *regs) 28.132 { 28.133 struct exec_domain *ed = current; 28.134 - struct trap_bounce *tb = &ed->thread.trap_bounce; 28.135 + struct trap_bounce *tb = &ed->arch.trap_bounce; 28.136 trap_info_t *ti; 28.137 unsigned long fixup; 28.138 28.139 @@ -500,7 +501,7 @@ asmlinkage int do_general_protection(str 28.140 if ( (regs->error_code & 3) == 2 ) 28.141 { 28.142 /* This fault must be due to <INT n> instruction. */ 28.143 - ti = current->thread.traps + (regs->error_code>>3); 28.144 + ti = current->arch.traps + (regs->error_code>>3); 28.145 if ( TI_GET_DPL(ti) >= (VM86_MODE(regs) ? 3 : (regs->cs & 3)) ) 28.146 { 28.147 tb->flags = TBF_EXCEPTION; 28.148 @@ -523,7 +524,7 @@ asmlinkage int do_general_protection(str 28.149 #endif 28.150 28.151 /* Pass on GPF as is. */ 28.152 - ti = current->thread.traps + 13; 28.153 + ti = current->arch.traps + 13; 28.154 tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE; 28.155 tb->error_code = regs->error_code; 28.156 finish_propagation: 28.157 @@ -567,14 +568,14 @@ asmlinkage void io_check_error(struct xe 28.158 fatal_trap(TRAP_nmi, regs); 28.159 } 28.160 28.161 -static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs) 28.162 +static void unknown_nmi_error(unsigned char reason) 28.163 { 28.164 printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); 28.165 printk("Dazed and confused, but trying to continue\n"); 28.166 printk("Do you have a strange power saving mode enabled?\n"); 28.167 } 28.168 28.169 -asmlinkage void do_nmi(struct xen_regs * regs, unsigned long reason) 28.170 +asmlinkage void do_nmi(struct xen_regs *regs, unsigned long reason) 28.171 { 28.172 ++nmi_count(smp_processor_id()); 28.173 28.174 @@ -583,7 +584,7 @@ asmlinkage void do_nmi(struct xen_regs * 28.175 nmi_watchdog_tick(regs); 28.176 else 28.177 #endif 28.178 - unknown_nmi_error((unsigned char)(reason&0xff), regs); 28.179 + unknown_nmi_error((unsigned char)(reason&0xff)); 28.180 } 28.181 28.182 unsigned long nmi_softirq_reason; 28.183 @@ -615,10 +616,10 @@ asmlinkage int math_state_restore(struct 28.184 28.185 if ( test_and_clear_bit(EDF_GUEST_STTS, ¤t->ed_flags) ) 28.186 { 28.187 - struct trap_bounce *tb = ¤t->thread.trap_bounce; 28.188 + struct trap_bounce *tb = ¤t->arch.trap_bounce; 28.189 tb->flags = TBF_EXCEPTION; 28.190 - tb->cs = current->thread.traps[7].cs; 28.191 - tb->eip = current->thread.traps[7].address; 28.192 + tb->cs = current->arch.traps[7].cs; 28.193 + tb->eip = current->arch.traps[7].address; 28.194 } 28.195 28.196 return EXCRET_fault_fixed; 28.197 @@ -628,7 +629,7 @@ asmlinkage int do_debug(struct xen_regs 28.198 { 28.199 unsigned long condition; 28.200 struct exec_domain *d = current; 28.201 - struct trap_bounce *tb = &d->thread.trap_bounce; 28.202 + struct trap_bounce *tb = &d->arch.trap_bounce; 28.203 28.204 DEBUGGER_trap_entry(TRAP_debug, regs); 28.205 28.206 @@ -636,7 +637,7 @@ asmlinkage int do_debug(struct xen_regs 28.207 28.208 /* Mask out spurious debug traps due to lazy DR7 setting */ 28.209 if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) && 28.210 - (d->thread.debugreg[7] == 0) ) 28.211 + (d->arch.debugreg[7] == 0) ) 28.212 { 28.213 __asm__("mov %0,%%db7" : : "r" (0UL)); 28.214 goto out; 28.215 @@ -656,11 +657,11 @@ asmlinkage int do_debug(struct xen_regs 28.216 } 28.217 28.218 /* Save debug status register where guest OS can peek at it */ 28.219 - d->thread.debugreg[6] = condition; 28.220 + d->arch.debugreg[6] = condition; 28.221 28.222 tb->flags = TBF_EXCEPTION; 28.223 - tb->cs = d->thread.traps[1].cs; 28.224 - tb->eip = d->thread.traps[1].address; 28.225 + tb->cs = d->arch.traps[1].cs; 28.226 + tb->eip = d->arch.traps[1].address; 28.227 28.228 out: 28.229 return EXCRET_not_a_fault; 28.230 @@ -671,6 +672,13 @@ asmlinkage int do_spurious_interrupt_bug 28.231 return EXCRET_not_a_fault; 28.232 } 28.233 28.234 +BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi) 28.235 +asmlinkage void smp_deferred_nmi(struct xen_regs regs) 28.236 +{ 28.237 + ack_APIC_irq(); 28.238 + do_nmi(®s, 0); 28.239 +} 28.240 + 28.241 void set_intr_gate(unsigned int n, void *addr) 28.242 { 28.243 _set_gate(idt_table+n,14,0,addr); 28.244 @@ -728,7 +736,7 @@ void __init trap_init(void) 28.245 set_intr_gate(TRAP_alignment_check,&alignment_check); 28.246 set_intr_gate(TRAP_machine_check,&machine_check); 28.247 set_intr_gate(TRAP_simd_error,&simd_coprocessor_error); 28.248 - set_intr_gate(TRAP_deferred_nmi,&nmi); 28.249 + set_intr_gate(TRAP_deferred_nmi,&deferred_nmi); 28.250 28.251 #if defined(__i386__) 28.252 _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall); 28.253 @@ -752,7 +760,7 @@ void __init trap_init(void) 28.254 long do_set_trap_table(trap_info_t *traps) 28.255 { 28.256 trap_info_t cur; 28.257 - trap_info_t *dst = current->thread.traps; 28.258 + trap_info_t *dst = current->arch.traps; 28.259 28.260 LOCK_BIGLOCK(current->domain); 28.261 28.262 @@ -791,10 +799,10 @@ long do_set_callbacks(unsigned long even 28.263 if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) ) 28.264 return -EPERM; 28.265 28.266 - d->thread.event_selector = event_selector; 28.267 - d->thread.event_address = event_address; 28.268 - d->thread.failsafe_selector = failsafe_selector; 28.269 - d->thread.failsafe_address = failsafe_address; 28.270 + d->arch.event_selector = event_selector; 28.271 + d->arch.event_address = event_address; 28.272 + d->arch.failsafe_selector = failsafe_selector; 28.273 + d->arch.failsafe_address = failsafe_address; 28.274 28.275 return 0; 28.276 } 28.277 @@ -869,7 +877,7 @@ long set_debugreg(struct exec_domain *p, 28.278 return -EINVAL; 28.279 } 28.280 28.281 - p->thread.debugreg[reg] = value; 28.282 + p->arch.debugreg[reg] = value; 28.283 return 0; 28.284 } 28.285 28.286 @@ -881,5 +889,5 @@ long do_set_debugreg(int reg, unsigned l 28.287 unsigned long do_get_debugreg(int reg) 28.288 { 28.289 if ( (reg < 0) || (reg > 7) ) return -EINVAL; 28.290 - return current->thread.debugreg[reg]; 28.291 + return current->arch.debugreg[reg]; 28.292 }
29.1 --- a/xen/arch/x86/vmx.c Fri Feb 04 19:26:10 2005 +0000 29.2 +++ b/xen/arch/x86/vmx.c Mon Feb 07 08:19:24 2005 +0000 29.3 @@ -1,3 +1,4 @@ 29.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 29.5 /* 29.6 * vmx.c: handling VMX architecture-related VM exits 29.7 * Copyright (c) 2004, Intel Corporation. 29.8 @@ -110,7 +111,6 @@ static int vmx_do_page_fault(unsigned lo 29.9 unsigned long gpde = 0, gpte, gpa; 29.10 int result; 29.11 struct exec_domain *ed = current; 29.12 - struct mm_struct *m = &ed->mm; 29.13 29.14 #if VMX_DEBUG 29.15 { 29.16 @@ -123,18 +123,18 @@ static int vmx_do_page_fault(unsigned lo 29.17 /* 29.18 * Set up guest page directory cache to make linear_pt_table[] work. 29.19 */ 29.20 - __guest_get_pl2e(m, va, &gpde); 29.21 + __guest_get_pl2e(ed, va, &gpde); 29.22 if (!(gpde & _PAGE_PRESENT)) 29.23 return 0; 29.24 29.25 index = (va >> L2_PAGETABLE_SHIFT); 29.26 - if (!l2_pgentry_val(m->guest_pl2e_cache[index])) { 29.27 + if (!l2_pgentry_val(ed->arch.guest_pl2e_cache[index])) { 29.28 pfn = phys_to_machine_mapping[gpde >> PAGE_SHIFT]; 29.29 29.30 VMX_DBG_LOG(DBG_LEVEL_VMMU, "vmx_do_page_fault: pagetable = %lx\n", 29.31 - pagetable_val(m->pagetable)); 29.32 + pagetable_val(ed->arch.pagetable)); 29.33 29.34 - m->guest_pl2e_cache[index] = 29.35 + ed->arch.guest_pl2e_cache[index] = 29.36 mk_l2_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 29.37 } 29.38 29.39 @@ -246,18 +246,18 @@ static void vmx_dr_access (unsigned long 29.40 case TYPE_MOV_TO_DR: 29.41 /* don't need to check the range */ 29.42 if (reg != REG_ESP) 29.43 - ed->thread.debugreg[reg] = *reg_p; 29.44 + ed->arch.debugreg[reg] = *reg_p; 29.45 else { 29.46 unsigned long value; 29.47 __vmread(GUEST_ESP, &value); 29.48 - ed->thread.debugreg[reg] = value; 29.49 + ed->arch.debugreg[reg] = value; 29.50 } 29.51 break; 29.52 case TYPE_MOV_FROM_DR: 29.53 if (reg != REG_ESP) 29.54 - *reg_p = ed->thread.debugreg[reg]; 29.55 + *reg_p = ed->arch.debugreg[reg]; 29.56 else { 29.57 - __vmwrite(GUEST_ESP, ed->thread.debugreg[reg]); 29.58 + __vmwrite(GUEST_ESP, ed->arch.debugreg[reg]); 29.59 } 29.60 break; 29.61 } 29.62 @@ -270,7 +270,7 @@ static void vmx_dr_access (unsigned long 29.63 static void vmx_vmexit_do_invlpg(unsigned long va) 29.64 { 29.65 unsigned long eip; 29.66 - struct exec_domain *d = current; 29.67 + struct exec_domain *ed = current; 29.68 unsigned int index; 29.69 29.70 __vmread(GUEST_EIP, &eip); 29.71 @@ -282,31 +282,31 @@ static void vmx_vmexit_do_invlpg(unsigne 29.72 * We do the safest things first, then try to update the shadow 29.73 * copying from guest 29.74 */ 29.75 - vmx_shadow_invlpg(&d->mm, va); 29.76 + vmx_shadow_invlpg(ed->domain, va); 29.77 index = (va >> L2_PAGETABLE_SHIFT); 29.78 - d->mm.guest_pl2e_cache[index] = mk_l2_pgentry(0); /* invalidate pgd cache */ 29.79 + ed->arch.guest_pl2e_cache[index] = 29.80 + mk_l2_pgentry(0); /* invalidate pgd cache */ 29.81 } 29.82 29.83 -static inline void guest_pl2e_cache_invalidate(struct mm_struct *m) 29.84 +static inline void guest_pl2e_cache_invalidate(struct exec_domain *ed) 29.85 { 29.86 /* 29.87 * Need to optimize this 29.88 */ 29.89 - memset(m->guest_pl2e_cache, 0, PAGE_SIZE); 29.90 + memset(ed->arch.guest_pl2e_cache, 0, PAGE_SIZE); 29.91 } 29.92 29.93 inline unsigned long gva_to_gpa(unsigned long gva) 29.94 { 29.95 unsigned long gpde, gpte, pfn, index; 29.96 - struct exec_domain *d = current; 29.97 - struct mm_struct *m = &d->mm; 29.98 + struct exec_domain *ed = current; 29.99 29.100 - __guest_get_pl2e(m, gva, &gpde); 29.101 + __guest_get_pl2e(ed, gva, &gpde); 29.102 index = (gva >> L2_PAGETABLE_SHIFT); 29.103 29.104 pfn = phys_to_machine_mapping[gpde >> PAGE_SHIFT]; 29.105 29.106 - m->guest_pl2e_cache[index] = 29.107 + ed->arch.guest_pl2e_cache[index] = 29.108 mk_l2_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 29.109 29.110 if ( unlikely(__get_user(gpte, (unsigned long *) 29.111 @@ -350,14 +350,14 @@ static void vmx_io_instruction(struct xe 29.112 return; 29.113 } 29.114 29.115 - vio = (vcpu_iodata_t *) d->thread.arch_vmx.vmx_platform.shared_page_va; 29.116 + vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; 29.117 if (vio == 0) { 29.118 VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx\n", (unsigned long) vio); 29.119 domain_crash(); 29.120 } 29.121 p = &vio->vp_ioreq; 29.122 p->dir = test_bit(3, &exit_qualification); 29.123 - set_bit(ARCH_VMX_IO_WAIT, &d->thread.arch_vmx.flags); 29.124 + set_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags); 29.125 29.126 p->pdata_valid = 0; 29.127 p->count = 1; 29.128 @@ -443,40 +443,40 @@ static void mov_to_cr(int gp, int cr, st 29.129 __vmwrite(CR0_READ_SHADOW, value); 29.130 29.131 if (value & (X86_CR0_PE | X86_CR0_PG) && 29.132 - !test_bit(VMX_CPU_STATE_PG_ENABLED, &d->thread.arch_vmx.cpu_state)) { 29.133 + !test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) { 29.134 /* 29.135 * Enable paging 29.136 */ 29.137 - set_bit(VMX_CPU_STATE_PG_ENABLED, &d->thread.arch_vmx.cpu_state); 29.138 + set_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state); 29.139 /* 29.140 * The guest CR3 must be pointing to the guest physical. 29.141 */ 29.142 if (!(pfn = phys_to_machine_mapping[ 29.143 - d->thread.arch_vmx.cpu_cr3 >> PAGE_SHIFT])) 29.144 + d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT])) 29.145 { 29.146 VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx\n", 29.147 - d->thread.arch_vmx.cpu_cr3); 29.148 + d->arch.arch_vmx.cpu_cr3); 29.149 domain_crash(); /* need to take a clean path */ 29.150 } 29.151 - old_base_pfn = pagetable_val(d->mm.pagetable) >> PAGE_SHIFT; 29.152 + old_base_pfn = pagetable_val(d->arch.pagetable) >> PAGE_SHIFT; 29.153 /* 29.154 * Now mm.pagetable points to machine physical. 29.155 */ 29.156 - d->mm.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 29.157 + d->arch.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 29.158 29.159 VMX_DBG_LOG(DBG_LEVEL_VMMU, "New mm.pagetable = %lx\n", 29.160 (unsigned long) (pfn << PAGE_SHIFT)); 29.161 29.162 - shadow_lock(&d->mm); 29.163 + shadow_lock(d->domain); 29.164 shadow_mode_enable(d->domain, SHM_full_32); 29.165 - shadow_unlock(&d->mm); 29.166 + shadow_unlock(d->domain); 29.167 29.168 - __vmwrite(GUEST_CR3, pagetable_val(d->mm.shadow_table)); 29.169 + __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table)); 29.170 /* 29.171 * mm->shadow_table should hold the next CR3 for shadow 29.172 */ 29.173 VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, pfn = %lx\n", 29.174 - d->thread.arch_vmx.cpu_cr3, pfn); 29.175 + d->arch.arch_vmx.cpu_cr3, pfn); 29.176 put_page_and_type(&frame_table[old_base_pfn]); 29.177 29.178 } 29.179 @@ -489,26 +489,26 @@ static void mov_to_cr(int gp, int cr, st 29.180 /* 29.181 * If paging is not enabled yet, simply copy the valut to CR3. 29.182 */ 29.183 - if (!test_bit(VMX_CPU_STATE_PG_ENABLED, &d->thread.arch_vmx.cpu_state)) { 29.184 - d->thread.arch_vmx.cpu_cr3 = value; 29.185 + if (!test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) { 29.186 + d->arch.arch_vmx.cpu_cr3 = value; 29.187 return; 29.188 } 29.189 29.190 - guest_pl2e_cache_invalidate(&d->mm); 29.191 + guest_pl2e_cache_invalidate(d); 29.192 /* 29.193 * We make a new one if the shadow does not exist. 29.194 */ 29.195 - if (value == d->thread.arch_vmx.cpu_cr3) { 29.196 + if (value == d->arch.arch_vmx.cpu_cr3) { 29.197 /* 29.198 * This is simple TLB flush, implying the guest has 29.199 * removed some translation or changed page attributes. 29.200 * We simply invalidate the shadow. 29.201 */ 29.202 pfn = phys_to_machine_mapping[value >> PAGE_SHIFT]; 29.203 - if ((pfn << PAGE_SHIFT) != pagetable_val(d->mm.pagetable)) 29.204 + if ((pfn << PAGE_SHIFT) != pagetable_val(d->arch.pagetable)) 29.205 __vmx_bug(regs); 29.206 - vmx_shadow_clear_state(&d->mm); 29.207 - shadow_invalidate(&d->mm); 29.208 + vmx_shadow_clear_state(d->domain); 29.209 + shadow_invalidate(d); 29.210 } else { 29.211 /* 29.212 * If different, make a shadow. Check if the PDBR is valid 29.213 @@ -522,16 +522,16 @@ static void mov_to_cr(int gp, int cr, st 29.214 domain_crash(); /* need to take a clean path */ 29.215 } 29.216 pfn = phys_to_machine_mapping[value >> PAGE_SHIFT]; 29.217 - vmx_shadow_clear_state(&d->mm); 29.218 - d->mm.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 29.219 - shadow_mk_pagetable(&d->mm); 29.220 + vmx_shadow_clear_state(d->domain); 29.221 + d->arch.pagetable = mk_pagetable(pfn << PAGE_SHIFT); 29.222 + shadow_mk_pagetable(d); 29.223 /* 29.224 * mm->shadow_table should hold the next CR3 for shadow 29.225 */ 29.226 - d->thread.arch_vmx.cpu_cr3 = value; 29.227 + d->arch.arch_vmx.cpu_cr3 = value; 29.228 VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx\n", 29.229 value); 29.230 - __vmwrite(GUEST_CR3, pagetable_val(d->mm.shadow_table)); 29.231 + __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table)); 29.232 } 29.233 break; 29.234 } 29.235 @@ -549,9 +549,9 @@ static void mov_to_cr(int gp, int cr, st 29.236 * all TLB entries except global entries. 29.237 */ 29.238 if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE)) { 29.239 - vmx_shadow_clear_state(&d->mm); 29.240 - shadow_invalidate(&d->mm); 29.241 - guest_pl2e_cache_invalidate(&d->mm); 29.242 + vmx_shadow_clear_state(d->domain); 29.243 + shadow_invalidate(d); 29.244 + guest_pl2e_cache_invalidate(d); 29.245 } 29.246 break; 29.247 default: 29.248 @@ -576,7 +576,7 @@ static void mov_from_cr(int cr, int gp, 29.249 if (cr != 3) 29.250 __vmx_bug(regs); 29.251 29.252 - value = (unsigned long) d->thread.arch_vmx.cpu_cr3; 29.253 + value = (unsigned long) d->arch.arch_vmx.cpu_cr3; 29.254 ASSERT(value); 29.255 29.256 switch (gp) { 29.257 @@ -799,7 +799,7 @@ asmlinkage void vmx_vmexit_handler(struc 29.258 "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx\n", 29.259 regs.eax, regs.ebx, regs.ecx, regs.edx, regs.esi, 29.260 regs.edi); 29.261 - d->thread.arch_vmx.vmx_platform.mpci.inst_decoder_regs = ®s; 29.262 + d->arch.arch_vmx.vmx_platform.mpci.inst_decoder_regs = ®s; 29.263 29.264 if (!(error = vmx_do_page_fault(va, error_code))) { 29.265 /* 29.266 @@ -813,7 +813,7 @@ asmlinkage void vmx_vmexit_handler(struc 29.267 VECTOR_PG); 29.268 __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); 29.269 __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); 29.270 - d->thread.arch_vmx.cpu_cr2 = va; 29.271 + d->arch.arch_vmx.cpu_cr2 = va; 29.272 } 29.273 break; 29.274 } 29.275 @@ -935,5 +935,5 @@ asmlinkage void load_cr2(void) 29.276 struct exec_domain *d = current; 29.277 29.278 local_irq_disable(); 29.279 - asm volatile("movl %0,%%cr2": :"r" (d->thread.arch_vmx.cpu_cr2)); 29.280 + asm volatile("movl %0,%%cr2": :"r" (d->arch.arch_vmx.cpu_cr2)); 29.281 }
30.1 --- a/xen/arch/x86/vmx_io.c Fri Feb 04 19:26:10 2005 +0000 30.2 +++ b/xen/arch/x86/vmx_io.c Mon Feb 07 08:19:24 2005 +0000 30.3 @@ -1,3 +1,4 @@ 30.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 30.5 /* 30.6 * vmx_io.c: handling I/O, interrupts related VMX entry/exit 30.7 * Copyright (c) 2004, Intel Corporation. 30.8 @@ -178,7 +179,7 @@ void vmx_io_assist(struct exec_domain *e 30.9 struct mi_per_cpu_info *mpci_p; 30.10 struct xen_regs *inst_decoder_regs; 30.11 30.12 - mpci_p = &ed->thread.arch_vmx.vmx_platform.mpci; 30.13 + mpci_p = &ed->arch.arch_vmx.vmx_platform.mpci; 30.14 inst_decoder_regs = mpci_p->inst_decoder_regs; 30.15 30.16 /* clear the pending event */ 30.17 @@ -187,7 +188,7 @@ void vmx_io_assist(struct exec_domain *e 30.18 clear_bit(IOPACKET_PORT>>5, &ed->vcpu_info->evtchn_pending_sel); 30.19 clear_bit(IOPACKET_PORT, &d->shared_info->evtchn_pending[0]); 30.20 30.21 - vio = (vcpu_iodata_t *) ed->thread.arch_vmx.vmx_platform.shared_page_va; 30.22 + vio = (vcpu_iodata_t *) ed->arch.arch_vmx.vmx_platform.shared_page_va; 30.23 if (vio == 0) { 30.24 VMX_DBG_LOG(DBG_LEVEL_1, 30.25 "bad shared page: %lx\n", (unsigned long) vio); 30.26 @@ -195,14 +196,14 @@ void vmx_io_assist(struct exec_domain *e 30.27 } 30.28 p = &vio->vp_ioreq; 30.29 /* clear IO wait VMX flag */ 30.30 - if (test_bit(ARCH_VMX_IO_WAIT, &ed->thread.arch_vmx.flags)) { 30.31 + if (test_bit(ARCH_VMX_IO_WAIT, &ed->arch.arch_vmx.flags)) { 30.32 if (p->state != STATE_IORESP_READY) { 30.33 printk("got a false I/O reponse\n"); 30.34 do_block(); 30.35 } else { 30.36 p->state = STATE_INVALID; 30.37 } 30.38 - clear_bit(ARCH_VMX_IO_WAIT, &ed->thread.arch_vmx.flags); 30.39 + clear_bit(ARCH_VMX_IO_WAIT, &ed->arch.arch_vmx.flags); 30.40 } else { 30.41 return; 30.42 } 30.43 @@ -218,10 +219,10 @@ void vmx_io_assist(struct exec_domain *e 30.44 } 30.45 int size = -1, index = -1; 30.46 30.47 - size = operand_size(ed->thread.arch_vmx.vmx_platform.mpci.mmio_target); 30.48 - index = operand_index(ed->thread.arch_vmx.vmx_platform.mpci.mmio_target); 30.49 + size = operand_size(ed->arch.arch_vmx.vmx_platform.mpci.mmio_target); 30.50 + index = operand_index(ed->arch.arch_vmx.vmx_platform.mpci.mmio_target); 30.51 30.52 - if (ed->thread.arch_vmx.vmx_platform.mpci.mmio_target & WZEROEXTEND) { 30.53 + if (ed->arch.arch_vmx.vmx_platform.mpci.mmio_target & WZEROEXTEND) { 30.54 p->u.data = p->u.data & 0xffff; 30.55 } 30.56 set_reg_value(size, index, 0, (struct xen_regs *)ec, p->u.data); 30.57 @@ -301,7 +302,7 @@ static inline int find_highest_pending_i 30.58 { 30.59 vcpu_iodata_t *vio; 30.60 30.61 - vio = (vcpu_iodata_t *) d->thread.arch_vmx.vmx_platform.shared_page_va; 30.62 + vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; 30.63 if (vio == 0) { 30.64 VMX_DBG_LOG(DBG_LEVEL_1, 30.65 "bad shared page: %lx\n", (unsigned long) vio); 30.66 @@ -315,7 +316,7 @@ static inline void clear_highest_bit(str 30.67 { 30.68 vcpu_iodata_t *vio; 30.69 30.70 - vio = (vcpu_iodata_t *) d->thread.arch_vmx.vmx_platform.shared_page_va; 30.71 + vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; 30.72 if (vio == 0) { 30.73 VMX_DBG_LOG(DBG_LEVEL_1, 30.74 "bad shared page: %lx\n", (unsigned long) vio); 30.75 @@ -363,15 +364,15 @@ void vmx_intr_assist(struct exec_domain 30.76 30.77 void vmx_do_resume(struct exec_domain *d) 30.78 { 30.79 - __vmwrite(HOST_CR3, pagetable_val(d->mm.monitor_table)); 30.80 - __vmwrite(GUEST_CR3, pagetable_val(d->mm.shadow_table)); 30.81 + __vmwrite(HOST_CR3, pagetable_val(d->arch.monitor_table)); 30.82 + __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table)); 30.83 __vmwrite(HOST_ESP, (unsigned long) get_stack_top()); 30.84 30.85 if (event_pending(d)) { 30.86 if (test_bit(IOPACKET_PORT, &d->domain->shared_info->evtchn_pending[0])) 30.87 vmx_io_assist(d); 30.88 30.89 - else if (test_bit(ARCH_VMX_IO_WAIT, &d->thread.arch_vmx.flags)) { 30.90 + else if (test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) { 30.91 printk("got an event while blocked on I/O\n"); 30.92 do_block(); 30.93 } 30.94 @@ -382,6 +383,6 @@ void vmx_do_resume(struct exec_domain *d 30.95 * a response to ioreq_t is not ok. 30.96 */ 30.97 } 30.98 - if (!test_bit(ARCH_VMX_IO_WAIT, &d->thread.arch_vmx.flags)) 30.99 + if (!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) 30.100 vmx_intr_assist(d); 30.101 }
31.1 --- a/xen/arch/x86/vmx_platform.c Fri Feb 04 19:26:10 2005 +0000 31.2 +++ b/xen/arch/x86/vmx_platform.c Mon Feb 07 08:19:24 2005 +0000 31.3 @@ -1,3 +1,4 @@ 31.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 31.5 /* 31.6 * vmx_platform.c: handling x86 platform related MMIO instructions 31.7 * Copyright (c) 2004, Intel Corporation. 31.8 @@ -420,9 +421,9 @@ static void send_mmio_req(unsigned long 31.9 extern long evtchn_send(int lport); 31.10 extern long do_block(void); 31.11 31.12 - mpci_p = ¤t->thread.arch_vmx.vmx_platform.mpci; 31.13 + mpci_p = ¤t->arch.arch_vmx.vmx_platform.mpci; 31.14 inst_decoder_regs = mpci_p->inst_decoder_regs; 31.15 - vio = (vcpu_iodata_t *) d->thread.arch_vmx.vmx_platform.shared_page_va; 31.16 + vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; 31.17 31.18 if (vio == NULL) { 31.19 printk("bad shared page\n"); 31.20 @@ -430,7 +431,7 @@ static void send_mmio_req(unsigned long 31.21 } 31.22 p = &vio->vp_ioreq; 31.23 31.24 - set_bit(ARCH_VMX_IO_WAIT, &d->thread.arch_vmx.flags); 31.25 + set_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags); 31.26 p->dir = dir; 31.27 p->pdata_valid = pvalid; 31.28 p->count = 1; 31.29 @@ -470,7 +471,7 @@ void handle_mmio(unsigned long va, unsig 31.30 unsigned char inst[MAX_INST_LEN]; 31.31 int ret; 31.32 31.33 - mpci_p = ¤t->thread.arch_vmx.vmx_platform.mpci; 31.34 + mpci_p = ¤t->arch.arch_vmx.vmx_platform.mpci; 31.35 inst_decoder_regs = mpci_p->inst_decoder_regs; 31.36 31.37 __vmread(GUEST_EIP, &eip);
32.1 --- a/xen/arch/x86/vmx_vmcs.c Fri Feb 04 19:26:10 2005 +0000 32.2 +++ b/xen/arch/x86/vmx_vmcs.c Mon Feb 07 08:19:24 2005 +0000 32.3 @@ -1,3 +1,4 @@ 32.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 32.5 /* 32.6 * vmx_vmcs.c: VMCS management 32.7 * Copyright (c) 2004, Intel Corporation. 32.8 @@ -137,7 +138,7 @@ int vmx_setup_platform(struct exec_domai 32.9 32.10 mpfn = phys_to_machine_mapping[gpfn]; 32.11 p = map_domain_mem(mpfn << PAGE_SHIFT); 32.12 - d->thread.arch_vmx.vmx_platform.shared_page_va = (unsigned long) p; 32.13 + d->arch.arch_vmx.vmx_platform.shared_page_va = (unsigned long) p; 32.14 32.15 return 0; 32.16 } 32.17 @@ -159,7 +160,7 @@ static int add_mapping_perdomain(struct 32.18 if (gpfn > ENTRIES_PER_L2_PAGETABLE * ENTRIES_PER_L1_PAGETABLE) 32.19 return -1; 32.20 32.21 - if (!(l1_pgentry_val(d->domain->mm_perdomain_pt[ 32.22 + if (!(l1_pgentry_val(d->domain->arch.mm_perdomain_pt[ 32.23 gpfn >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]) & _PAGE_PRESENT)) 32.24 { 32.25 page = (struct pfn_info *) alloc_domheap_page(NULL); 32.26 @@ -168,7 +169,7 @@ static int add_mapping_perdomain(struct 32.27 } 32.28 32.29 pfn = (unsigned long) (page - frame_table); 32.30 - d->domain->mm_perdomain_pt[gpfn >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)] = 32.31 + d->domain->arch.mm_perdomain_pt[gpfn >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)] = 32.32 mk_l1_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 32.33 } 32.34 phys_to_machine_mapping[gpfn] = mpfn; 32.35 @@ -190,18 +191,18 @@ void vmx_do_launch(struct exec_domain *e 32.36 struct domain *d = ed->domain; 32.37 32.38 cpu = smp_processor_id(); 32.39 - ed->mm.min_pfn = ed->mm.max_pfn = 0; 32.40 + d->arch.min_pfn = d->arch.max_pfn = 0; 32.41 32.42 spin_lock(&d->page_alloc_lock); 32.43 list_ent = d->page_list.next; 32.44 32.45 - mpl2e = (l2_pgentry_t *)map_domain_mem(pagetable_val(ed->mm.monitor_table)); 32.46 + mpl2e = (l2_pgentry_t *)map_domain_mem(pagetable_val(ed->arch.monitor_table)); 32.47 32.48 for ( i = 0; list_ent != &d->page_list; i++ ) 32.49 { 32.50 pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 32.51 - ed->mm.min_pfn = min(ed->mm.min_pfn, pfn); 32.52 - ed->mm.max_pfn = max(ed->mm.max_pfn, pfn); 32.53 + d->arch.min_pfn = min(d->arch.min_pfn, pfn); 32.54 + d->arch.max_pfn = max(d->arch.max_pfn, pfn); 32.55 list_ent = frame_table[pfn].list.next; 32.56 add_mapping_perdomain(ed, i, pfn); 32.57 } 32.58 @@ -219,7 +220,7 @@ void vmx_do_launch(struct exec_domain *e 32.59 32.60 guest_pl2e_cache = map_domain_mem(pfn << PAGE_SHIFT); 32.61 memset(guest_pl2e_cache, 0, PAGE_SIZE); /* clean it up */ 32.62 - ed->mm.guest_pl2e_cache = guest_pl2e_cache; 32.63 + ed->arch.guest_pl2e_cache = guest_pl2e_cache; 32.64 32.65 unmap_domain_mem(mpl2e); 32.66 32.67 @@ -245,12 +246,12 @@ void vmx_do_launch(struct exec_domain *e 32.68 error |= __vmwrite(GUEST_TR_BASE, 0); 32.69 error |= __vmwrite(GUEST_TR_LIMIT, 0xff); 32.70 32.71 - ed->mm.shadow_table = ed->mm.pagetable; 32.72 - __vmwrite(GUEST_CR3, pagetable_val(ed->mm.pagetable)); 32.73 - __vmwrite(HOST_CR3, pagetable_val(ed->mm.monitor_table)); 32.74 + ed->arch.shadow_table = ed->arch.pagetable; 32.75 + __vmwrite(GUEST_CR3, pagetable_val(ed->arch.pagetable)); 32.76 + __vmwrite(HOST_CR3, pagetable_val(ed->arch.monitor_table)); 32.77 __vmwrite(HOST_ESP, (unsigned long) get_stack_top()); 32.78 32.79 - ed->thread.schedule_tail = arch_vmx_do_resume; 32.80 + ed->arch.schedule_tail = arch_vmx_do_resume; 32.81 } 32.82 32.83 /*
33.1 --- a/xen/arch/x86/x86_32/asm-offsets.c Fri Feb 04 19:26:10 2005 +0000 33.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c Mon Feb 07 08:19:24 2005 +0000 33.3 @@ -39,12 +39,12 @@ void __dummy__(void) 33.4 33.5 OFFSET(EDOMAIN_processor, struct exec_domain, processor); 33.6 OFFSET(EDOMAIN_vcpu_info, struct exec_domain, vcpu_info); 33.7 - OFFSET(EDOMAIN_event_sel, struct exec_domain, thread.event_selector); 33.8 - OFFSET(EDOMAIN_event_addr, struct exec_domain, thread.event_address); 33.9 - OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, thread.failsafe_selector); 33.10 - OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, thread.failsafe_address); 33.11 - OFFSET(EDOMAIN_trap_bounce, struct exec_domain, thread.trap_bounce); 33.12 - OFFSET(EDOMAIN_thread_flags, struct exec_domain, thread.flags); 33.13 + OFFSET(EDOMAIN_event_sel, struct exec_domain, arch.event_selector); 33.14 + OFFSET(EDOMAIN_event_addr, struct exec_domain, arch.event_address); 33.15 + OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, arch.failsafe_selector); 33.16 + OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, arch.failsafe_address); 33.17 + OFFSET(EDOMAIN_trap_bounce, struct exec_domain, arch.trap_bounce); 33.18 + OFFSET(EDOMAIN_thread_flags, struct exec_domain, arch.flags); 33.19 BLANK(); 33.20 33.21 OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
34.1 --- a/xen/arch/x86/x86_32/domain_build.c Fri Feb 04 19:26:10 2005 +0000 34.2 +++ b/xen/arch/x86/x86_32/domain_build.c Mon Feb 07 08:19:24 2005 +0000 34.3 @@ -1,3 +1,4 @@ 34.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 34.5 /****************************************************************************** 34.6 * domain_build.c 34.7 * 34.8 @@ -216,11 +217,11 @@ int construct_dom0(struct domain *d, 34.9 * We're basically forcing default RPLs to 1, so that our "what privilege 34.10 * level are we returning to?" logic works. 34.11 */ 34.12 - ed->thread.failsafe_selector = FLAT_GUESTOS_CS; 34.13 - ed->thread.event_selector = FLAT_GUESTOS_CS; 34.14 - ed->thread.guestos_ss = FLAT_GUESTOS_SS; 34.15 + ed->arch.failsafe_selector = FLAT_GUESTOS_CS; 34.16 + ed->arch.event_selector = FLAT_GUESTOS_CS; 34.17 + ed->arch.guestos_ss = FLAT_GUESTOS_SS; 34.18 for ( i = 0; i < 256; i++ ) 34.19 - ed->thread.traps[i].cs = FLAT_GUESTOS_CS; 34.20 + ed->arch.traps[i].cs = FLAT_GUESTOS_CS; 34.21 34.22 /* WARNING: The new domain must have its 'processor' field filled in! */ 34.23 l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE; 34.24 @@ -228,8 +229,8 @@ int construct_dom0(struct domain *d, 34.25 l2tab[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = 34.26 mk_l2_pgentry((unsigned long)l2start | __PAGE_HYPERVISOR); 34.27 l2tab[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = 34.28 - mk_l2_pgentry(__pa(d->mm_perdomain_pt) | __PAGE_HYPERVISOR); 34.29 - ed->mm.pagetable = mk_pagetable((unsigned long)l2start); 34.30 + mk_l2_pgentry(__pa(d->arch.mm_perdomain_pt) | __PAGE_HYPERVISOR); 34.31 + ed->arch.pagetable = mk_pagetable((unsigned long)l2start); 34.32 34.33 l2tab += l2_table_offset(dsi.v_start); 34.34 mfn = alloc_start >> PAGE_SHIFT; 34.35 @@ -307,7 +308,7 @@ int construct_dom0(struct domain *d, 34.36 34.37 /* Install the new page tables. */ 34.38 __cli(); 34.39 - write_ptbase(&ed->mm); 34.40 + write_ptbase(ed); 34.41 34.42 /* Copy the OS image. */ 34.43 (void)loadelfimage(image_start); 34.44 @@ -360,7 +361,7 @@ int construct_dom0(struct domain *d, 34.45 *dst = '\0'; 34.46 34.47 /* Reinstate the caller's page tables. */ 34.48 - write_ptbase(¤t->mm); 34.49 + write_ptbase(current); 34.50 __sti(); 34.51 34.52 /* Destroy low mappings - they were only for our convenience. */
35.1 --- a/xen/arch/x86/x86_32/mm.c Fri Feb 04 19:26:10 2005 +0000 35.2 +++ b/xen/arch/x86/x86_32/mm.c Mon Feb 07 08:19:24 2005 +0000 35.3 @@ -1,3 +1,4 @@ 35.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 35.5 /****************************************************************************** 35.6 * arch/x86/x86_32/mm.c 35.7 * 35.8 @@ -184,7 +185,7 @@ static void __synchronise_pagetables(voi 35.9 struct exec_domain *ed = current; 35.10 if ( ((unsigned long)mask & (1 << ed->processor)) && 35.11 is_idle_task(ed->domain) ) 35.12 - write_ptbase(&ed->mm); 35.13 + write_ptbase(ed); 35.14 } 35.15 void synchronise_pagetables(unsigned long cpu_mask) 35.16 { 35.17 @@ -201,8 +202,8 @@ long do_stack_switch(unsigned long ss, u 35.18 if ( (ss & 3) == 0 ) 35.19 return -EPERM; 35.20 35.21 - current->thread.guestos_ss = ss; 35.22 - current->thread.guestos_sp = esp; 35.23 + current->arch.guestos_ss = ss; 35.24 + current->arch.guestos_sp = esp; 35.25 t->ss1 = ss; 35.26 t->esp1 = esp; 35.27 35.28 @@ -316,9 +317,9 @@ void destroy_gdt(struct exec_domain *ed) 35.29 35.30 for ( i = 0; i < 16; i++ ) 35.31 { 35.32 - if ( (pfn = l1_pgentry_to_pagenr(ed->mm.perdomain_ptes[i])) != 0 ) 35.33 + if ( (pfn = l1_pgentry_to_pagenr(ed->arch.perdomain_ptes[i])) != 0 ) 35.34 put_page_and_type(&frame_table[pfn]); 35.35 - ed->mm.perdomain_ptes[i] = mk_l1_pgentry(0); 35.36 + ed->arch.perdomain_ptes[i] = mk_l1_pgentry(0); 35.37 } 35.38 } 35.39 35.40 @@ -372,7 +373,7 @@ long set_gdt(struct exec_domain *ed, 35.41 35.42 /* Install the new GDT. */ 35.43 for ( i = 0; i < nr_pages; i++ ) 35.44 - ed->mm.perdomain_ptes[i] = 35.45 + ed->arch.perdomain_ptes[i] = 35.46 mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR); 35.47 35.48 SET_GDT_ADDRESS(ed, GDT_VIRT_START(ed)); 35.49 @@ -404,7 +405,7 @@ long do_set_gdt(unsigned long *frame_lis 35.50 if ( (ret = set_gdt(current, frames, entries)) == 0 ) 35.51 { 35.52 local_flush_tlb(); 35.53 - __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt)); 35.54 + __asm__ __volatile__ ("lgdt %0" : "=m" (*current->arch.gdt)); 35.55 } 35.56 35.57 UNLOCK_BIGLOCK(current->domain); 35.58 @@ -443,7 +444,7 @@ long do_update_descriptor( 35.59 case PGT_gdt_page: 35.60 /* Disallow updates of Xen-reserved descriptors in the current GDT. */ 35.61 for_each_exec_domain(current->domain, ed) { 35.62 - if ( (l1_pgentry_to_pagenr(ed->mm.perdomain_ptes[0]) == pfn) && 35.63 + if ( (l1_pgentry_to_pagenr(ed->arch.perdomain_ptes[0]) == pfn) && 35.64 (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) && 35.65 (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) ) 35.66 goto out; 35.67 @@ -531,6 +532,11 @@ static void __memguard_change_range(void 35.68 } 35.69 } 35.70 35.71 +void memguard_guard_stack(void *p) 35.72 +{ 35.73 + memguard_guard_range(p, PAGE_SIZE); 35.74 +} 35.75 + 35.76 void memguard_guard_range(void *p, unsigned long l) 35.77 { 35.78 __memguard_change_range(p, l, 1);
36.1 --- a/xen/arch/x86/x86_32/seg_fixup.c Fri Feb 04 19:26:10 2005 +0000 36.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c Mon Feb 07 08:19:24 2005 +0000 36.3 @@ -1,3 +1,4 @@ 36.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 36.5 /****************************************************************************** 36.6 * arch/x86/x86_32/seg_fixup.c 36.7 * 36.8 @@ -114,7 +115,7 @@ int get_baselimit(u16 seg, unsigned long 36.9 if ( ldt ) 36.10 { 36.11 table = (unsigned long *)LDT_VIRT_START(d); 36.12 - if ( idx >= d->mm.ldt_ents ) 36.13 + if ( idx >= d->arch.ldt_ents ) 36.14 goto fail; 36.15 } 36.16 else /* gdt */ 36.17 @@ -180,10 +181,10 @@ int fixup_seg(u16 seg, unsigned long off 36.18 if ( ldt ) 36.19 { 36.20 table = (unsigned long *)LDT_VIRT_START(d); 36.21 - if ( idx >= d->mm.ldt_ents ) 36.22 + if ( idx >= d->arch.ldt_ents ) 36.23 { 36.24 DPRINTK("Segment %04x out of LDT range (%ld)\n", 36.25 - seg, d->mm.ldt_ents); 36.26 + seg, d->arch.ldt_ents); 36.27 goto fail; 36.28 } 36.29 } 36.30 @@ -466,8 +467,8 @@ int gpf_emulate_4gb(struct xen_regs *reg 36.31 /* If requested, give a callback on otherwise unused vector 15. */ 36.32 if ( VM_ASSIST(d->domain, VMASST_TYPE_4gb_segments_notify) ) 36.33 { 36.34 - ti = &d->thread.traps[15]; 36.35 - tb = &d->thread.trap_bounce; 36.36 + ti = &d->arch.traps[15]; 36.37 + tb = &d->arch.trap_bounce; 36.38 tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE; 36.39 tb->error_code = pb - eip; 36.40 tb->cs = ti->cs;
37.1 --- a/xen/arch/x86/x86_32/traps.c Fri Feb 04 19:26:10 2005 +0000 37.2 +++ b/xen/arch/x86/x86_32/traps.c Mon Feb 07 08:19:24 2005 +0000 37.3 @@ -1,3 +1,4 @@ 37.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 37.5 37.6 #include <xen/config.h> 37.7 #include <xen/init.h> 37.8 @@ -148,6 +149,8 @@ asmlinkage void do_double_fault(void) 37.9 /* Disable the NMI watchdog. It's useless now. */ 37.10 watchdog_on = 0; 37.11 37.12 + console_force_unlock(); 37.13 + 37.14 /* Find information saved during fault and dump it to the console. */ 37.15 tss = &init_tss[cpu]; 37.16 printk("CPU: %d\nEIP: %04x:[<%08x>] \nEFLAGS: %08x\n", 37.17 @@ -208,8 +211,8 @@ long set_fast_trap(struct exec_domain *p 37.18 if ( idx == 0 ) 37.19 { 37.20 if ( p == current ) 37.21 - CLEAR_FAST_TRAP(&p->thread); 37.22 - SET_DEFAULT_FAST_TRAP(&p->thread); 37.23 + CLEAR_FAST_TRAP(&p->arch); 37.24 + SET_DEFAULT_FAST_TRAP(&p->arch); 37.25 return 0; 37.26 } 37.27 37.28 @@ -221,7 +224,7 @@ long set_fast_trap(struct exec_domain *p 37.29 if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) ) 37.30 return -1; 37.31 37.32 - ti = p->thread.traps + idx; 37.33 + ti = p->arch.traps + idx; 37.34 37.35 /* 37.36 * We can't virtualise interrupt gates, as there's no way to get 37.37 @@ -231,15 +234,15 @@ long set_fast_trap(struct exec_domain *p 37.38 return -1; 37.39 37.40 if ( p == current ) 37.41 - CLEAR_FAST_TRAP(&p->thread); 37.42 + CLEAR_FAST_TRAP(&p->arch); 37.43 37.44 - p->thread.fast_trap_idx = idx; 37.45 - p->thread.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff); 37.46 - p->thread.fast_trap_desc.b = 37.47 + p->arch.fast_trap_idx = idx; 37.48 + p->arch.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff); 37.49 + p->arch.fast_trap_desc.b = 37.50 (ti->address & 0xffff0000) | 0x8f00 | (TI_GET_DPL(ti)&3)<<13; 37.51 37.52 if ( p == current ) 37.53 - SET_FAST_TRAP(&p->thread); 37.54 + SET_FAST_TRAP(&p->arch); 37.55 37.56 return 0; 37.57 }
38.1 --- a/xen/arch/x86/x86_32/usercopy.c Fri Feb 04 19:26:10 2005 +0000 38.2 +++ b/xen/arch/x86/x86_32/usercopy.c Mon Feb 07 08:19:24 2005 +0000 38.3 @@ -9,8 +9,6 @@ 38.4 #include <xen/mm.h> 38.5 #include <asm/uaccess.h> 38.6 38.7 -#define might_sleep() ((void)0) 38.8 - 38.9 static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n) 38.10 { 38.11 #ifdef CONFIG_X86_INTEL_USERCOPY 38.12 @@ -22,93 +20,6 @@ static inline int __movsl_is_ok(unsigned 38.13 #define movsl_is_ok(a1,a2,n) \ 38.14 __movsl_is_ok((unsigned long)(a1),(unsigned long)(a2),(n)) 38.15 38.16 -/* 38.17 - * Copy a null terminated string from userspace. 38.18 - */ 38.19 - 38.20 -#define __do_strncpy_from_user(dst,src,count,res) \ 38.21 -do { \ 38.22 - int __d0, __d1, __d2; \ 38.23 - __asm__ __volatile__( \ 38.24 - " testl %1,%1\n" \ 38.25 - " jz 2f\n" \ 38.26 - "0: lodsb\n" \ 38.27 - " stosb\n" \ 38.28 - " testb %%al,%%al\n" \ 38.29 - " jz 1f\n" \ 38.30 - " decl %1\n" \ 38.31 - " jnz 0b\n" \ 38.32 - "1: subl %1,%0\n" \ 38.33 - "2:\n" \ 38.34 - ".section .fixup,\"ax\"\n" \ 38.35 - "3: movl %5,%0\n" \ 38.36 - " jmp 2b\n" \ 38.37 - ".previous\n" \ 38.38 - ".section __ex_table,\"a\"\n" \ 38.39 - " .align 4\n" \ 38.40 - " .long 0b,3b\n" \ 38.41 - ".previous" \ 38.42 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ 38.43 - "=&D" (__d2) \ 38.44 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ 38.45 - : "memory"); \ 38.46 -} while (0) 38.47 - 38.48 -/** 38.49 - * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. 38.50 - * @dst: Destination address, in kernel space. This buffer must be at 38.51 - * least @count bytes long. 38.52 - * @src: Source address, in user space. 38.53 - * @count: Maximum number of bytes to copy, including the trailing NUL. 38.54 - * 38.55 - * Copies a NUL-terminated string from userspace to kernel space. 38.56 - * Caller must check the specified block with access_ok() before calling 38.57 - * this function. 38.58 - * 38.59 - * On success, returns the length of the string (not including the trailing 38.60 - * NUL). 38.61 - * 38.62 - * If access to userspace fails, returns -EFAULT (some data may have been 38.63 - * copied). 38.64 - * 38.65 - * If @count is smaller than the length of the string, copies @count bytes 38.66 - * and returns @count. 38.67 - */ 38.68 -long 38.69 -__strncpy_from_user(char *dst, const char __user *src, long count) 38.70 -{ 38.71 - long res; 38.72 - __do_strncpy_from_user(dst, src, count, res); 38.73 - return res; 38.74 -} 38.75 - 38.76 -/** 38.77 - * strncpy_from_user: - Copy a NUL terminated string from userspace. 38.78 - * @dst: Destination address, in kernel space. This buffer must be at 38.79 - * least @count bytes long. 38.80 - * @src: Source address, in user space. 38.81 - * @count: Maximum number of bytes to copy, including the trailing NUL. 38.82 - * 38.83 - * Copies a NUL-terminated string from userspace to kernel space. 38.84 - * 38.85 - * On success, returns the length of the string (not including the trailing 38.86 - * NUL). 38.87 - * 38.88 - * If access to userspace fails, returns -EFAULT (some data may have been 38.89 - * copied). 38.90 - * 38.91 - * If @count is smaller than the length of the string, copies @count bytes 38.92 - * and returns @count. 38.93 - */ 38.94 -long 38.95 -strncpy_from_user(char *dst, const char __user *src, long count) 38.96 -{ 38.97 - long res = -EFAULT; 38.98 - if (access_ok(VERIFY_READ, src, 1)) 38.99 - __do_strncpy_from_user(dst, src, count, res); 38.100 - return res; 38.101 -} 38.102 - 38.103 38.104 /* 38.105 * Zero Userspace 38.106 @@ -148,7 +59,6 @@ do { \ 38.107 unsigned long 38.108 clear_user(void __user *to, unsigned long n) 38.109 { 38.110 - might_sleep(); 38.111 if (access_ok(VERIFY_WRITE, to, n)) 38.112 __do_clear_user(to, n); 38.113 return n; 38.114 @@ -172,49 +82,6 @@ unsigned long 38.115 return n; 38.116 } 38.117 38.118 -/** 38.119 - * strlen_user: - Get the size of a string in user space. 38.120 - * @s: The string to measure. 38.121 - * @n: The maximum valid length 38.122 - * 38.123 - * Get the size of a NUL-terminated string in user space. 38.124 - * 38.125 - * Returns the size of the string INCLUDING the terminating NUL. 38.126 - * On exception, returns 0. 38.127 - * If the string is too long, returns a value greater than @n. 38.128 - */ 38.129 -long strnlen_user(const char __user *s, long n) 38.130 -{ 38.131 - unsigned long mask = -__addr_ok(s); 38.132 - unsigned long res, tmp; 38.133 - 38.134 - might_sleep(); 38.135 - 38.136 - __asm__ __volatile__( 38.137 - " testl %0, %0\n" 38.138 - " jz 3f\n" 38.139 - " andl %0,%%ecx\n" 38.140 - "0: repne; scasb\n" 38.141 - " setne %%al\n" 38.142 - " subl %%ecx,%0\n" 38.143 - " addl %0,%%eax\n" 38.144 - "1:\n" 38.145 - ".section .fixup,\"ax\"\n" 38.146 - "2: xorl %%eax,%%eax\n" 38.147 - " jmp 1b\n" 38.148 - "3: movb $1,%%al\n" 38.149 - " jmp 1b\n" 38.150 - ".previous\n" 38.151 - ".section __ex_table,\"a\"\n" 38.152 - " .align 4\n" 38.153 - " .long 0b,2b\n" 38.154 - ".previous" 38.155 - :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) 38.156 - :"0" (n), "1" (s), "2" (0), "3" (mask) 38.157 - :"cc"); 38.158 - return res & mask; 38.159 -} 38.160 - 38.161 #ifdef CONFIG_X86_INTEL_USERCOPY 38.162 static unsigned long 38.163 __copy_user_intel(void __user *to, const void *from, unsigned long size) 38.164 @@ -543,12 +410,10 @@ unsigned long 38.165 unsigned long 38.166 copy_to_user(void __user *to, const void *from, unsigned long n) 38.167 { 38.168 - might_sleep(); 38.169 if (access_ok(VERIFY_WRITE, to, n)) 38.170 n = __copy_to_user(to, from, n); 38.171 return n; 38.172 } 38.173 -EXPORT_SYMBOL(copy_to_user); 38.174 38.175 /** 38.176 * copy_from_user: - Copy a block of data from user space. 38.177 @@ -569,11 +434,9 @@ EXPORT_SYMBOL(copy_to_user); 38.178 unsigned long 38.179 copy_from_user(void *to, const void __user *from, unsigned long n) 38.180 { 38.181 - might_sleep(); 38.182 if (access_ok(VERIFY_READ, from, n)) 38.183 n = __copy_from_user(to, from, n); 38.184 else 38.185 memset(to, 0, n); 38.186 return n; 38.187 } 38.188 -EXPORT_SYMBOL(copy_from_user);
39.1 --- a/xen/arch/x86/x86_64/asm-offsets.c Fri Feb 04 19:26:10 2005 +0000 39.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c Mon Feb 07 08:19:24 2005 +0000 39.3 @@ -41,12 +41,12 @@ void __dummy__(void) 39.4 39.5 OFFSET(EDOMAIN_processor, struct exec_domain, processor); 39.6 OFFSET(EDOMAIN_vcpu_info, struct exec_domain, vcpu_info); 39.7 - OFFSET(EDOMAIN_event_sel, struct exec_domain, thread.event_selector); 39.8 - OFFSET(EDOMAIN_event_addr, struct exec_domain, thread.event_address); 39.9 - OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, thread.failsafe_selector); 39.10 - OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, thread.failsafe_address); 39.11 - OFFSET(EDOMAIN_trap_bounce, struct exec_domain, thread.trap_bounce); 39.12 - OFFSET(EDOMAIN_thread_flags, struct exec_domain, thread.flags); 39.13 + OFFSET(EDOMAIN_event_sel, struct exec_domain, arch.event_selector); 39.14 + OFFSET(EDOMAIN_event_addr, struct exec_domain, arch.event_address); 39.15 + OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, arch.failsafe_selector); 39.16 + OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, arch.failsafe_address); 39.17 + OFFSET(EDOMAIN_trap_bounce, struct exec_domain, arch.trap_bounce); 39.18 + OFFSET(EDOMAIN_thread_flags, struct exec_domain, arch.flags); 39.19 BLANK(); 39.20 39.21 OFFSET(SHINFO_upcall_pending, shared_info_t,
40.1 --- a/xen/arch/x86/x86_64/domain_build.c Fri Feb 04 19:26:10 2005 +0000 40.2 +++ b/xen/arch/x86/x86_64/domain_build.c Mon Feb 07 08:19:24 2005 +0000 40.3 @@ -1,3 +1,4 @@ 40.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 40.5 /****************************************************************************** 40.6 * domain_build.c 40.7 * 40.8 @@ -224,11 +225,11 @@ int construct_dom0(struct domain *d, 40.9 * We're basically forcing default RPLs to 1, so that our "what privilege 40.10 * level are we returning to?" logic works. 40.11 */ 40.12 - ed->thread.failsafe_selector = FLAT_GUESTOS_CS; 40.13 - ed->thread.event_selector = FLAT_GUESTOS_CS; 40.14 - ed->thread.guestos_ss = FLAT_GUESTOS_SS; 40.15 + ed->arch.failsafe_selector = FLAT_GUESTOS_CS; 40.16 + ed->arch.event_selector = FLAT_GUESTOS_CS; 40.17 + ed->arch.guestos_ss = FLAT_GUESTOS_SS; 40.18 for ( i = 0; i < 256; i++ ) 40.19 - ed->thread.traps[i].cs = FLAT_GUESTOS_CS; 40.20 + ed->arch.traps[i].cs = FLAT_GUESTOS_CS; 40.21 40.22 /* WARNING: The new domain must have its 'processor' field filled in! */ 40.23 phys_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; 40.24 @@ -237,8 +238,8 @@ int construct_dom0(struct domain *d, 40.25 l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = 40.26 mk_l4_pgentry(__pa(l4start) | __PAGE_HYPERVISOR); 40.27 l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = 40.28 - mk_l4_pgentry(__pa(d->mm_perdomain_pt) | __PAGE_HYPERVISOR); 40.29 - ed->mm.pagetable = mk_pagetable(__pa(l4start)); 40.30 + mk_l4_pgentry(__pa(d->arch.mm_perdomain_pt) | __PAGE_HYPERVISOR); 40.31 + ed->arch.pagetable = mk_pagetable(__pa(l4start)); 40.32 40.33 l4tab += l4_table_offset(dsi.v_start); 40.34 mfn = alloc_start >> PAGE_SHIFT; 40.35 @@ -329,7 +330,7 @@ int construct_dom0(struct domain *d, 40.36 40.37 /* Install the new page tables. */ 40.38 __cli(); 40.39 - write_ptbase(&ed->mm); 40.40 + write_ptbase(ed); 40.41 40.42 /* Copy the OS image. */ 40.43 (void)loadelfimage(image_start); 40.44 @@ -382,7 +383,7 @@ int construct_dom0(struct domain *d, 40.45 *dst = '\0'; 40.46 40.47 /* Reinstate the caller's page tables. */ 40.48 - write_ptbase(¤t->mm); 40.49 + write_ptbase(current); 40.50 __sti(); 40.51 40.52 /* DOM0 gets access to everything. */
41.1 --- a/xen/arch/x86/x86_64/entry.S Fri Feb 04 19:26:10 2005 +0000 41.2 +++ b/xen/arch/x86/x86_64/entry.S Mon Feb 07 08:19:24 2005 +0000 41.3 @@ -133,7 +133,7 @@ ENTRY(double_fault) 41.4 jmp error_code 41.5 41.6 ENTRY(nmi) 41.7 - iret 41.8 + iretq 41.9 41.10 .data 41.11
42.1 --- a/xen/arch/x86/x86_64/mm.c Fri Feb 04 19:26:10 2005 +0000 42.2 +++ b/xen/arch/x86/x86_64/mm.c Mon Feb 07 08:19:24 2005 +0000 42.3 @@ -1,3 +1,4 @@ 42.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 42.5 /****************************************************************************** 42.6 * arch/x86/x86_64/mm.c 42.7 * 42.8 @@ -220,7 +221,7 @@ static void __synchronise_pagetables(voi 42.9 struct exec_domain *ed = current; 42.10 if ( ((unsigned long)mask & (1 << ed->processor)) && 42.11 is_idle_task(ed->domain) ) 42.12 - write_ptbase(&ed->mm); 42.13 + write_ptbase(ed); 42.14 } 42.15 void synchronise_pagetables(unsigned long cpu_mask) 42.16 { 42.17 @@ -232,8 +233,8 @@ long do_stack_switch(unsigned long ss, u 42.18 { 42.19 if ( (ss & 3) != 3 ) 42.20 return -EPERM; 42.21 - current->thread.guestos_ss = ss; 42.22 - current->thread.guestos_sp = esp; 42.23 + current->arch.guestos_ss = ss; 42.24 + current->arch.guestos_sp = esp; 42.25 return 0; 42.26 } 42.27 42.28 @@ -346,9 +347,9 @@ void destroy_gdt(struct exec_domain *ed) 42.29 42.30 for ( i = 0; i < 16; i++ ) 42.31 { 42.32 - if ( (pfn = l1_pgentry_to_pagenr(ed->mm.perdomain_ptes[i])) != 0 ) 42.33 + if ( (pfn = l1_pgentry_to_pagenr(ed->arch.perdomain_ptes[i])) != 0 ) 42.34 put_page_and_type(&frame_table[pfn]); 42.35 - ed->mm.perdomain_ptes[i] = mk_l1_pgentry(0); 42.36 + ed->arch.perdomain_ptes[i] = mk_l1_pgentry(0); 42.37 } 42.38 } 42.39 42.40 @@ -402,7 +403,7 @@ long set_gdt(struct exec_domain *ed, 42.41 42.42 /* Install the new GDT. */ 42.43 for ( i = 0; i < nr_pages; i++ ) 42.44 - ed->mm.perdomain_ptes[i] = 42.45 + ed->arch.perdomain_ptes[i] = 42.46 mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR); 42.47 42.48 SET_GDT_ADDRESS(ed, GDT_VIRT_START(ed)); 42.49 @@ -432,7 +433,7 @@ long do_set_gdt(unsigned long *frame_lis 42.50 if ( (ret = set_gdt(current, frames, entries)) == 0 ) 42.51 { 42.52 local_flush_tlb(); 42.53 - __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt)); 42.54 + __asm__ __volatile__ ("lgdt %0" : "=m" (*current->arch.gdt)); 42.55 } 42.56 42.57 return ret; 42.58 @@ -461,7 +462,7 @@ long do_update_descriptor( 42.59 { 42.60 case PGT_gdt_page: 42.61 /* Disallow updates of Xen-reserved descriptors in the current GDT. */ 42.62 - if ( (l1_pgentry_to_pagenr(current->mm.perdomain_ptes[0]) == pfn) && 42.63 + if ( (l1_pgentry_to_pagenr(current->arch.perdomain_ptes[0]) == pfn) && 42.64 (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) && 42.65 (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) ) 42.66 goto out; 42.67 @@ -494,18 +495,19 @@ long do_update_descriptor( 42.68 42.69 #ifdef MEMORY_GUARD 42.70 42.71 -#if 1 42.72 - 42.73 -void *memguard_init(void *heap_start) { return heap_start; } 42.74 -void memguard_guard_range(void *p, unsigned long l) {} 42.75 -void memguard_unguard_range(void *p, unsigned long l) {} 42.76 - 42.77 -#else 42.78 - 42.79 +#define ALLOC_PT(_level) \ 42.80 +do { \ 42.81 + (_level) = (_level ## _pgentry_t *)heap_start; \ 42.82 + heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE); \ 42.83 + clear_page(_level); \ 42.84 +} while ( 0 ) 42.85 void *memguard_init(void *heap_start) 42.86 { 42.87 - l1_pgentry_t *l1; 42.88 - int i, j; 42.89 + l1_pgentry_t *l1 = NULL; 42.90 + l2_pgentry_t *l2 = NULL; 42.91 + l3_pgentry_t *l3 = NULL; 42.92 + l4_pgentry_t *l4 = &idle_pg_table[l4_table_offset(PAGE_OFFSET)]; 42.93 + unsigned long i, j; 42.94 42.95 /* Round the allocation pointer up to a page boundary. */ 42.96 heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) & 42.97 @@ -514,14 +516,22 @@ void *memguard_init(void *heap_start) 42.98 /* Memory guarding is incompatible with super pages. */ 42.99 for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ ) 42.100 { 42.101 - l1 = (l1_pgentry_t *)heap_start; 42.102 - heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE); 42.103 + ALLOC_PT(l1); 42.104 for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ ) 42.105 l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) | 42.106 (j << L1_PAGETABLE_SHIFT) | 42.107 __PAGE_HYPERVISOR); 42.108 - idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] = 42.109 - mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR); 42.110 + if ( !((unsigned long)l2 & (PAGE_SIZE-1)) ) 42.111 + { 42.112 + ALLOC_PT(l2); 42.113 + if ( !((unsigned long)l3 & (PAGE_SIZE-1)) ) 42.114 + { 42.115 + ALLOC_PT(l3); 42.116 + *l4++ = mk_l4_pgentry(virt_to_phys(l3) | __PAGE_HYPERVISOR); 42.117 + } 42.118 + *l3++ = mk_l3_pgentry(virt_to_phys(l2) | __PAGE_HYPERVISOR); 42.119 + } 42.120 + *l2++ = mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR); 42.121 } 42.122 42.123 return heap_start; 42.124 @@ -531,6 +541,8 @@ static void __memguard_change_range(void 42.125 { 42.126 l1_pgentry_t *l1; 42.127 l2_pgentry_t *l2; 42.128 + l3_pgentry_t *l3; 42.129 + l4_pgentry_t *l4; 42.130 unsigned long _p = (unsigned long)p; 42.131 unsigned long _l = (unsigned long)l; 42.132 42.133 @@ -542,8 +554,10 @@ static void __memguard_change_range(void 42.134 42.135 while ( _l != 0 ) 42.136 { 42.137 - l2 = &idle_pg_table[l2_table_offset(_p)]; 42.138 - l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); 42.139 + l4 = &idle_pg_table[l4_table_offset(_p)]; 42.140 + l3 = l4_pgentry_to_l3(*l4) + l3_table_offset(_p); 42.141 + l2 = l3_pgentry_to_l2(*l3) + l2_table_offset(_p); 42.142 + l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); 42.143 if ( guard ) 42.144 *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT); 42.145 else 42.146 @@ -553,6 +567,12 @@ static void __memguard_change_range(void 42.147 } 42.148 } 42.149 42.150 +void memguard_guard_stack(void *p) 42.151 +{ 42.152 + p = (void *)((unsigned long)p + PAGE_SIZE); 42.153 + memguard_guard_range(p, 2 * PAGE_SIZE); 42.154 +} 42.155 + 42.156 void memguard_guard_range(void *p, unsigned long l) 42.157 { 42.158 __memguard_change_range(p, l, 1); 42.159 @@ -565,5 +585,3 @@ void memguard_unguard_range(void *p, uns 42.160 } 42.161 42.162 #endif 42.163 - 42.164 -#endif
43.1 --- a/xen/arch/x86/x86_64/traps.c Fri Feb 04 19:26:10 2005 +0000 43.2 +++ b/xen/arch/x86/x86_64/traps.c Mon Feb 07 08:19:24 2005 +0000 43.3 @@ -138,6 +138,8 @@ asmlinkage void do_double_fault(struct x 43.4 /* Disable the NMI watchdog. It's useless now. */ 43.5 watchdog_on = 0; 43.6 43.7 + console_force_unlock(); 43.8 + 43.9 /* Find information saved during fault and dump it to the console. */ 43.10 printk("************************************\n"); 43.11 printk("EIP: %04lx:[<%p>] \nEFLAGS: %p\n",
44.1 --- a/xen/arch/x86/x86_64/usercopy.c Fri Feb 04 19:26:10 2005 +0000 44.2 +++ b/xen/arch/x86/x86_64/usercopy.c Mon Feb 07 08:19:24 2005 +0000 44.3 @@ -8,55 +8,6 @@ 44.4 #include <asm/uaccess.h> 44.5 44.6 /* 44.7 - * Copy a null terminated string from userspace. 44.8 - */ 44.9 - 44.10 -#define __do_strncpy_from_user(dst,src,count,res) \ 44.11 -do { \ 44.12 - long __d0, __d1, __d2; \ 44.13 - __asm__ __volatile__( \ 44.14 - " testq %1,%1\n" \ 44.15 - " jz 2f\n" \ 44.16 - "0: lodsb\n" \ 44.17 - " stosb\n" \ 44.18 - " testb %%al,%%al\n" \ 44.19 - " jz 1f\n" \ 44.20 - " decq %1\n" \ 44.21 - " jnz 0b\n" \ 44.22 - "1: subq %1,%0\n" \ 44.23 - "2:\n" \ 44.24 - ".section .fixup,\"ax\"\n" \ 44.25 - "3: movq %5,%0\n" \ 44.26 - " jmp 2b\n" \ 44.27 - ".previous\n" \ 44.28 - ".section __ex_table,\"a\"\n" \ 44.29 - " .align 8\n" \ 44.30 - " .quad 0b,3b\n" \ 44.31 - ".previous" \ 44.32 - : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ 44.33 - "=&D" (__d2) \ 44.34 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ 44.35 - : "memory"); \ 44.36 -} while (0) 44.37 - 44.38 -long 44.39 -__strncpy_from_user(char *dst, const char *src, long count) 44.40 -{ 44.41 - long res; 44.42 - __do_strncpy_from_user(dst, src, count, res); 44.43 - return res; 44.44 -} 44.45 - 44.46 -long 44.47 -strncpy_from_user(char *dst, const char *src, long count) 44.48 -{ 44.49 - long res = -EFAULT; 44.50 - if (access_ok(VERIFY_READ, src, 1)) 44.51 - __do_strncpy_from_user(dst, src, count, res); 44.52 - return res; 44.53 -} 44.54 - 44.55 -/* 44.56 * Zero Userspace 44.57 */ 44.58 44.59 @@ -93,6 +44,86 @@ unsigned long __clear_user(void *addr, u 44.60 return size; 44.61 } 44.62 44.63 +unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned n) 44.64 +{ 44.65 + unsigned long __d0, __d1, __d2, __n = n; 44.66 + __asm__ __volatile__( 44.67 + " cmpq $15,%0\n" 44.68 + " jbe 1f\n" 44.69 + " mov %1,%0\n" 44.70 + " neg %0\n" 44.71 + " and $7,%0\n" 44.72 + " sub %0,%3\n" 44.73 + "4: rep; movsb\n" /* make 'to' address aligned */ 44.74 + " mov %3,%0\n" 44.75 + " shr $3,%0\n" 44.76 + " and $7,%3\n" 44.77 + " .align 2,0x90\n" 44.78 + "0: rep; movsq\n" /* as many quadwords as possible... */ 44.79 + " mov %3,%0\n" 44.80 + "1: rep; movsb\n" /* ...remainder copied as bytes */ 44.81 + "2:\n" 44.82 + ".section .fixup,\"ax\"\n" 44.83 + "5: add %3,%0\n" 44.84 + " jmp 2b\n" 44.85 + "3: lea 0(%3,%0,8),%0\n" 44.86 + " jmp 2b\n" 44.87 + ".previous\n" 44.88 + ".section __ex_table,\"a\"\n" 44.89 + " .align 8\n" 44.90 + " .quad 4b,5b\n" 44.91 + " .quad 0b,3b\n" 44.92 + " .quad 1b,2b\n" 44.93 + ".previous" 44.94 + : "=&c"(__n), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) 44.95 + : "3"(__n), "0"(__n), "1"(to), "2"(from) 44.96 + : "memory"); 44.97 + return (unsigned)__n; 44.98 +} 44.99 + 44.100 +unsigned long 44.101 +__copy_from_user_ll(void *to, const void __user *from, unsigned n) 44.102 +{ 44.103 + unsigned long __d0, __d1, __d2, __n = n; 44.104 + __asm__ __volatile__( 44.105 + " cmp $15,%0\n" 44.106 + " jbe 1f\n" 44.107 + " mov %1,%0\n" 44.108 + " neg %0\n" 44.109 + " and $7,%0\n" 44.110 + " sub %0,%3\n" 44.111 + "4: rep; movsb\n" /* make 'to' address aligned */ 44.112 + " mov %3,%0\n" 44.113 + " shr $3,%0\n" 44.114 + " and $7,%3\n" 44.115 + " .align 2,0x90\n" 44.116 + "0: rep; movsq\n" /* as many quadwords as possible... */ 44.117 + " mov %3,%0\n" 44.118 + "1: rep; movsb\n" /* ...remainder copied as bytes */ 44.119 + "2:\n" 44.120 + ".section .fixup,\"ax\"\n" 44.121 + "5: add %3,%0\n" 44.122 + " jmp 6f\n" 44.123 + "3: lea 0(%3,%0,8),%0\n" 44.124 + "6: push %0\n" 44.125 + " push %%rax\n" 44.126 + " xor %%rax,%%rax\n" 44.127 + " rep; stosb\n" 44.128 + " pop %%rax\n" 44.129 + " pop %0\n" 44.130 + " jmp 2b\n" 44.131 + ".previous\n" 44.132 + ".section __ex_table,\"a\"\n" 44.133 + " .align 8\n" 44.134 + " .quad 4b,5b\n" 44.135 + " .quad 0b,3b\n" 44.136 + " .quad 1b,6b\n" 44.137 + ".previous" 44.138 + : "=&c"(__n), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) 44.139 + : "3"(__n), "0"(__n), "1"(to), "2"(from) 44.140 + : "memory"); 44.141 + return (unsigned)__n; 44.142 +} 44.143 44.144 unsigned long clear_user(void *to, unsigned long n) 44.145 { 44.146 @@ -101,36 +132,49 @@ unsigned long clear_user(void *to, unsig 44.147 return n; 44.148 } 44.149 44.150 -/* 44.151 - * Return the size of a string (including the ending 0) 44.152 +/** 44.153 + * copy_to_user: - Copy a block of data into user space. 44.154 + * @to: Destination address, in user space. 44.155 + * @from: Source address, in kernel space. 44.156 + * @n: Number of bytes to copy. 44.157 + * 44.158 + * Context: User context only. This function may sleep. 44.159 * 44.160 - * Return 0 on exception, a value greater than N if too long 44.161 + * Copy data from kernel space to user space. 44.162 + * 44.163 + * Returns number of bytes that could not be copied. 44.164 + * On success, this will be zero. 44.165 */ 44.166 - 44.167 -long strnlen_user(const char *s, long n) 44.168 +unsigned long 44.169 +copy_to_user(void __user *to, const void *from, unsigned n) 44.170 { 44.171 - unsigned long res = 0; 44.172 - char c; 44.173 - 44.174 - if (!access_ok(VERIFY_READ, s, n)) 44.175 - return 0; 44.176 - 44.177 - while (1) { 44.178 - if (get_user(c, s)) 44.179 - return 0; 44.180 - if (!c) 44.181 - return res+1; 44.182 - if (res>n) 44.183 - return n+1; 44.184 - res++; 44.185 - s++; 44.186 - } 44.187 + if (access_ok(VERIFY_WRITE, to, n)) 44.188 + n = __copy_to_user(to, from, n); 44.189 + return n; 44.190 } 44.191 44.192 -unsigned long copy_in_user(void *to, const void *from, unsigned len) 44.193 +/** 44.194 + * copy_from_user: - Copy a block of data from user space. 44.195 + * @to: Destination address, in kernel space. 44.196 + * @from: Source address, in user space. 44.197 + * @n: Number of bytes to copy. 44.198 + * 44.199 + * Context: User context only. This function may sleep. 44.200 + * 44.201 + * Copy data from user space to kernel space. 44.202 + * 44.203 + * Returns number of bytes that could not be copied. 44.204 + * On success, this will be zero. 44.205 + * 44.206 + * If some data could not be copied, this function will pad the copied 44.207 + * data to the requested size using zero bytes. 44.208 + */ 44.209 +unsigned long 44.210 +copy_from_user(void *to, const void __user *from, unsigned n) 44.211 { 44.212 - if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 44.213 - return copy_user_generic(to, from, len); 44.214 - } 44.215 - return len; 44.216 + if (access_ok(VERIFY_READ, from, n)) 44.217 + n = __copy_from_user(to, from, n); 44.218 + else 44.219 + memset(to, 0, n); 44.220 + return n; 44.221 }
45.1 --- a/xen/common/Makefile Fri Feb 04 19:26:10 2005 +0000 45.2 +++ b/xen/common/Makefile Mon Feb 07 08:19:24 2005 +0000 45.3 @@ -6,12 +6,7 @@ OBJS := $(subst dom_mem_ops.o,,$(OBJS)) 45.4 OBJS := $(subst grant_table.o,,$(OBJS)) 45.5 OBJS := $(subst page_alloc.o,,$(OBJS)) 45.6 OBJS := $(subst physdev.o,,$(OBJS)) 45.7 -OBJS := $(subst slab.o,,$(OBJS)) 45.8 -endif 45.9 - 45.10 -ifneq ($(debugger),y) 45.11 -OBJS := $(subst debug.o,,$(OBJS)) 45.12 -OBJS := $(subst debug-linux.o,,$(OBJS)) 45.13 +OBJS := $(subst xmalloc.o,,$(OBJS)) 45.14 endif 45.15 45.16 ifneq ($(perfc),y)
46.1 --- a/xen/common/ac_timer.c Fri Feb 04 19:26:10 2005 +0000 46.2 +++ b/xen/common/ac_timer.c Mon Feb 07 08:19:24 2005 +0000 46.3 @@ -1,4 +1,4 @@ 46.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 46.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- 46.6 **************************************************************************** 46.7 * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge 46.8 * (C) 2002-2003 University of Cambridge
47.1 --- a/xen/common/debug-linux.c Fri Feb 04 19:26:10 2005 +0000 47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 47.3 @@ -1,267 +0,0 @@ 47.4 - 47.5 -/* 47.6 - * pervasive debugger 47.7 - * www.cl.cam.ac.uk/netos/pdb 47.8 - * 47.9 - * alex ho 47.10 - * 2004 47.11 - * university of cambridge computer laboratory 47.12 - * 47.13 - * linux specific pdb stuff 47.14 - */ 47.15 - 47.16 -#include <xen/config.h> 47.17 -#include <xen/types.h> 47.18 -#include <xen/lib.h> 47.19 -#include <public/dom0_ops.h> 47.20 -#include <asm/pdb.h> 47.21 - 47.22 -/* from linux/sched.h */ 47.23 -#define PIDHASH_SZ (4096 >> 2) 47.24 -#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) 47.25 - 47.26 -/* from asm-xen/pgtable-2level.h */ 47.27 -#define PGDIR_SHIFT 22 47.28 -#define PTRS_PER_PGD 1024 47.29 - 47.30 -/* from asm-xen/page.h */ 47.31 -#define PAGE_SHIFT 12 47.32 -#define PAGE_SIZE (1UL << PAGE_SHIFT) 47.33 -#define PAGE_MASK (~(PAGE_SIZE-1)) 47.34 - 47.35 -#define __PAGE_OFFSET (0xC0000000) 47.36 -#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) 47.37 -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) 47.38 -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 47.39 - 47.40 -/* from debug.h */ 47.41 -#define ENTRIES_PER_L1_PAGETABLE 1024 47.42 -#define L1_PAGE_BITS ( (ENTRIES_PER_L1_PAGETABLE - 1) << PAGE_SHIFT ) 47.43 - 47.44 -void pdb_linux_process_details (unsigned long cr3, int pid, char *buffer); 47.45 - 47.46 -/* adapted from asm-xen/page.h */ 47.47 -static inline unsigned long machine_to_phys(unsigned long cr3, 47.48 - unsigned long machine) 47.49 -{ 47.50 - unsigned long phys; 47.51 - pdb_get_values((u_char *) &phys, sizeof(phys), cr3, 47.52 - (unsigned long) machine_to_phys_mapping + 47.53 - (machine >> PAGE_SHIFT) * 4); 47.54 - phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); 47.55 - return phys; 47.56 -} 47.57 - 47.58 -unsigned long pdb_pidhash_addr = 0xc01971e0UL; 47.59 -unsigned long pdb_init_task_union_addr = 0xc0182000UL; 47.60 - 47.61 - 47.62 -unsigned int task_struct_mm_offset = 0x2c; 47.63 -unsigned int task_struct_next_task_offset = 0x48; 47.64 -unsigned int task_struct_pid_offset = 0x7c; 47.65 -unsigned int task_struct_pidhash_next_offset = 0xb0; 47.66 -unsigned int task_struct_comm_offset = 0x23e; 47.67 -unsigned int task_struct_comm_length = 0x10; 47.68 - 47.69 -unsigned int mm_struct_pgd_offset = 0x0c; 47.70 - 47.71 -/* 47.72 - * find the task structure of a process (pid) 47.73 - * given the cr3 of the guest os. 47.74 - */ 47.75 -unsigned long pdb_linux_pid_task_struct (unsigned long cr3, int pid) 47.76 -{ 47.77 - unsigned long task_struct_p = (unsigned long) NULL; 47.78 - unsigned long task_struct_pid; 47.79 - 47.80 - /* find the task_struct of the given process */ 47.81 - pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p), 47.82 - cr3, pdb_pidhash_addr + pid_hashfn(pid) * 4); 47.83 - 47.84 - /* find the correct task struct */ 47.85 - while (task_struct_p != (unsigned long)NULL) 47.86 - { 47.87 - pdb_get_values((u_char *) &task_struct_pid, sizeof(task_struct_pid), 47.88 - cr3, task_struct_p + task_struct_pid_offset); 47.89 - if (task_struct_pid == pid) 47.90 - { 47.91 - break; 47.92 - } 47.93 - 47.94 - pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p), 47.95 - cr3, task_struct_p + task_struct_pidhash_next_offset); 47.96 - } 47.97 - if (task_struct_p == (unsigned long) NULL) 47.98 - { 47.99 - /* oops */ 47.100 - printk ("pdb error: couldn't find process 0x%x (0x%lx)\n", pid, cr3); 47.101 - } 47.102 - 47.103 - return task_struct_p; 47.104 -} 47.105 - 47.106 -/* 47.107 - * find the ptbr of a process (pid) 47.108 - * given the cr3 of the guest os. 47.109 - */ 47.110 -unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid) 47.111 -{ 47.112 - unsigned long task_struct_p; 47.113 - unsigned long mm_p, pgd; 47.114 - 47.115 - task_struct_p = pdb_linux_pid_task_struct(cr3, pid); 47.116 - if (task_struct_p == (unsigned long) NULL) 47.117 - { 47.118 - return (unsigned long) NULL; 47.119 - } 47.120 - 47.121 - /* get the mm_struct within the task_struct */ 47.122 - pdb_get_values((u_char *) &mm_p, sizeof(mm_p), 47.123 - cr3, task_struct_p + task_struct_mm_offset); 47.124 - /* get the page global directory (cr3) within the mm_struct */ 47.125 - pdb_get_values((u_char *) &pgd, sizeof(pgd), 47.126 - cr3, mm_p + mm_struct_pgd_offset); 47.127 - 47.128 - return pgd; 47.129 -} 47.130 - 47.131 - 47.132 - 47.133 -/* read a byte from a process 47.134 - * 47.135 - * in: pid: process id 47.136 - * cr3: ptbr for the process' domain 47.137 - * addr: address to read 47.138 - */ 47.139 - 47.140 -u_char pdb_linux_get_value(int pid, unsigned long cr3, unsigned long addr) 47.141 -{ 47.142 - u_char result = 0; 47.143 - unsigned long pgd; 47.144 - unsigned long l2tab, page; 47.145 - 47.146 - /* get the process' pgd */ 47.147 - pgd = pdb_linux_pid_ptbr(cr3, pid); 47.148 - 47.149 - /* get the l2 table entry */ 47.150 - pdb_get_values((u_char *) &l2tab, sizeof(l2tab), 47.151 - cr3, pgd + (addr >> PGDIR_SHIFT) * 4); 47.152 - l2tab = (unsigned long)__va(machine_to_phys(cr3, l2tab) & PAGE_MASK); 47.153 - 47.154 - /* get the page table entry */ 47.155 - pdb_get_values((u_char *) &page, sizeof(page), 47.156 - cr3, l2tab + ((addr & L1_PAGE_BITS) >> PAGE_SHIFT) * 4); 47.157 - page = (unsigned long)__va(machine_to_phys(cr3, page) & PAGE_MASK); 47.158 - 47.159 - /* get the byte */ 47.160 - pdb_get_values((u_char *) &result, sizeof(result), 47.161 - cr3, page + (addr & ~PAGE_MASK)); 47.162 - 47.163 - return result; 47.164 -} 47.165 - 47.166 -void pdb_linux_get_values(char *buffer, int length, unsigned long address, 47.167 - int pid, unsigned long cr3) 47.168 -{ 47.169 - int loop; 47.170 - 47.171 - /* yes, this can be optimized... a lot */ 47.172 - for (loop = 0; loop < length; loop++) 47.173 - { 47.174 - buffer[loop] = pdb_linux_get_value(pid, cr3, address + loop); 47.175 - } 47.176 -} 47.177 - 47.178 - 47.179 -void pdb_linux_set_value(int pid, unsigned long cr3, unsigned long addr, 47.180 - u_char *value) 47.181 -{ 47.182 - unsigned long pgd; 47.183 - unsigned long l2tab, page; 47.184 - 47.185 - /* get the process' pgd */ 47.186 - pgd = pdb_linux_pid_ptbr(cr3, pid); 47.187 - 47.188 - /* get the l2 table entry */ 47.189 - pdb_get_values((u_char *) &l2tab, sizeof(l2tab), 47.190 - cr3, pgd + (addr >> PGDIR_SHIFT) * 4); 47.191 - l2tab = (unsigned long)__va(machine_to_phys(cr3, l2tab) & PAGE_MASK); 47.192 - 47.193 - /* get the page table entry */ 47.194 - pdb_get_values((u_char *) &page, sizeof(page), 47.195 - cr3, l2tab + ((addr & L1_PAGE_BITS) >> PAGE_SHIFT) * 4); 47.196 - page = (unsigned long)__va(machine_to_phys(cr3, page) & PAGE_MASK); 47.197 - 47.198 - /* set the byte */ 47.199 - pdb_set_values(value, sizeof(u_char), cr3, page + (addr & ~PAGE_MASK)); 47.200 -} 47.201 - 47.202 -void pdb_linux_set_values(char *buffer, int length, unsigned long address, 47.203 - int pid, unsigned long cr3) 47.204 -{ 47.205 - int loop; 47.206 - 47.207 - /* it's difficult to imagine a more inefficient algorithm */ 47.208 - for (loop = 0; loop < length; loop++) 47.209 - { 47.210 - pdb_linux_set_value(pid, cr3, address + loop, &buffer[loop * 2]); 47.211 - } 47.212 -} 47.213 - 47.214 -/**********************************************************************/ 47.215 - 47.216 -/* 47.217 - * return 1 if is the virtual address is in the operating system's 47.218 - * address space, else 0 47.219 - */ 47.220 -int pdb_linux_address_space (unsigned long addr) 47.221 -{ 47.222 - return (addr > PAGE_OFFSET); 47.223 -} 47.224 - 47.225 -/* get a list of at most "max" processes 47.226 - * return: number of threads found 47.227 - * 47.228 - * init_task -> init_task_union.task 47.229 - * while (next_task != init_task) {} 47.230 - */ 47.231 -int pdb_linux_process_list (unsigned long cr3, int array[], int max) 47.232 -{ 47.233 - unsigned long task_p, next_p; 47.234 - int pid; 47.235 - int count = 0; 47.236 - 47.237 - /* task_p = init_task->next_task */ 47.238 - pdb_get_values((u_char *) &task_p, sizeof(task_p), 47.239 - cr3, pdb_init_task_union_addr + task_struct_next_task_offset); 47.240 - 47.241 - while (task_p != pdb_init_task_union_addr) 47.242 - { 47.243 - pdb_get_values((u_char *) &pid, sizeof(pid), 47.244 - cr3, task_p + task_struct_pid_offset); 47.245 - 47.246 - array[count % max] = pid; 47.247 - count++; 47.248 - 47.249 - pdb_get_values((u_char *) &next_p, sizeof(next_p), 47.250 - cr3, task_p + task_struct_next_task_offset); 47.251 - task_p = next_p; 47.252 - } 47.253 - 47.254 - return count; 47.255 -} 47.256 - 47.257 -/* 47.258 - * get additional details about a particular process 47.259 - */ 47.260 -void pdb_linux_process_details (unsigned long cr3, int pid, char *buffer) 47.261 -{ 47.262 - unsigned long task_struct_p; 47.263 - 47.264 - task_struct_p = pdb_linux_pid_task_struct(cr3, pid); 47.265 - 47.266 - pdb_get_values((u_char *) buffer, task_struct_comm_length, 47.267 - cr3, task_struct_p + task_struct_comm_offset); 47.268 - return; 47.269 -} 47.270 -
48.1 --- a/xen/common/debug.c Fri Feb 04 19:26:10 2005 +0000 48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 48.3 @@ -1,113 +0,0 @@ 48.4 -/* 48.5 - * debug.c 48.6 - * 48.7 - * xen pervasive debugger 48.8 - */ 48.9 - 48.10 -#include <xen/config.h> 48.11 -#include <xen/types.h> 48.12 -#include <xen/lib.h> 48.13 -#include <public/dom0_ops.h> 48.14 -#include <xen/sched.h> 48.15 -#include <xen/event.h> 48.16 -#include <asm/page.h> 48.17 -#include <asm/pdb.h> 48.18 -#include <asm/shadow.h> 48.19 - 48.20 -#undef DEBUG_TRACE 48.21 -#ifdef DEBUG_TRACE 48.22 -#define TRC(_x) _x 48.23 -#else 48.24 -#define TRC(_x) 48.25 -#endif 48.26 - 48.27 -/****************************************************************************/ 48.28 - 48.29 -extern u_char pdb_linux_get_value(int pid, unsigned long cr3, 48.30 - unsigned long addr); 48.31 - 48.32 -/* 48.33 - * interactively call pervasive debugger from a privileged domain 48.34 - */ 48.35 -void pdb_do_debug (dom0_op_t *op) 48.36 -{ 48.37 - op->u.debug.status = 0; 48.38 - 48.39 - TRC(printk("PDB: op:%c, dom:%llu, in1:%x, in2:%x, in3:%x, in4:%x\n", 48.40 - op->u.debug.opcode, op->u.debug.domain, 48.41 - op->u.debug.in1, op->u.debug.in2, 48.42 - op->u.debug.in3, op->u.debug.in4)); 48.43 - 48.44 - /* NOT NOW 48.45 - if (op->u.debug.domain == 0) 48.46 - { 48.47 - op->u.debug.status = 1; 48.48 - return; 48.49 - } 48.50 - */ 48.51 - 48.52 - switch (op->u.debug.opcode) 48.53 - { 48.54 - case 'c' : 48.55 - { 48.56 - struct domain *d = find_domain_by_id(op->u.debug.domain); 48.57 - if ( d != NULL ) 48.58 - { 48.59 - domain_unpause_by_systemcontroller(d); 48.60 - put_domain(d); 48.61 - } 48.62 - else 48.63 - { 48.64 - op->u.debug.status = 2; /* invalid domain */ 48.65 - } 48.66 - break; 48.67 - } 48.68 - case 'r' : 48.69 - { 48.70 - int loop; 48.71 - u_char x; 48.72 - unsigned long cr3; 48.73 - struct domain *d; 48.74 - 48.75 - d = find_domain_by_id(op->u.debug.domain); 48.76 - if ( shadow_mode(d) ) 48.77 - cr3 = pagetable_val(d->mm.shadow_table); 48.78 - else 48.79 - cr3 = pagetable_val(d->mm.pagetable); 48.80 - 48.81 - for (loop = 0; loop < op->u.debug.in2; loop++) /* length */ 48.82 - { 48.83 - if (loop % 8 == 0) 48.84 - { 48.85 - printk ("\n%08x ", op->u.debug.in1 + loop); 48.86 - } 48.87 - x = pdb_linux_get_value(op->u.debug.in3, 48.88 - cr3, op->u.debug.in1 + loop); 48.89 - printk (" %02x", x); 48.90 - } 48.91 - printk ("\n"); 48.92 - put_domain(d); 48.93 - break; 48.94 - } 48.95 - case 's' : 48.96 - { 48.97 - struct domain *d = find_domain_by_id(op->u.debug.domain); 48.98 - 48.99 - if ( d != NULL ) 48.100 - { 48.101 - domain_pause_by_systemcontroller(d); 48.102 - put_domain(d); 48.103 - } 48.104 - else 48.105 - { 48.106 - op->u.debug.status = 2; /* invalid domain */ 48.107 - } 48.108 - break; 48.109 - } 48.110 - default : 48.111 - { 48.112 - printk("PDB error: unknown debug opcode %c (0x%x)\n", 48.113 - op->u.debug.opcode, op->u.debug.opcode); 48.114 - } 48.115 - } 48.116 -}
49.1 --- a/xen/common/dom0_ops.c Fri Feb 04 19:26:10 2005 +0000 49.2 +++ b/xen/common/dom0_ops.c Mon Feb 07 08:19:24 2005 +0000 49.3 @@ -1,3 +1,4 @@ 49.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 49.5 /****************************************************************************** 49.6 * dom0_ops.c 49.7 * 49.8 @@ -14,7 +15,6 @@ 49.9 #include <xen/sched.h> 49.10 #include <xen/event.h> 49.11 #include <asm/domain_page.h> 49.12 -#include <asm/pdb.h> 49.13 #include <xen/trace.h> 49.14 #include <xen/console.h> 49.15 #include <asm/shadow.h> 49.16 @@ -374,16 +374,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 49.17 } 49.18 break; 49.19 49.20 -#ifdef XEN_DEBUGGER 49.21 - case DOM0_DEBUG: 49.22 - { 49.23 - pdb_do_debug(op); 49.24 - copy_to_user(u_dom0_op, op, sizeof(*op)); 49.25 - ret = 0; 49.26 - } 49.27 - break; 49.28 -#endif 49.29 - 49.30 case DOM0_SETTIME: 49.31 { 49.32 do_settime(op->u.settime.secs,
50.1 --- a/xen/common/dom_mem_ops.c Fri Feb 04 19:26:10 2005 +0000 50.2 +++ b/xen/common/dom_mem_ops.c Mon Feb 07 08:19:24 2005 +0000 50.3 @@ -1,3 +1,4 @@ 50.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 50.5 /****************************************************************************** 50.6 * dom_mem_ops.c 50.7 * 50.8 @@ -34,7 +35,7 @@ static long 50.9 alloc_dom_mem(struct domain *d, 50.10 unsigned long *extent_list, 50.11 unsigned long start_extent, 50.12 - unsigned long nr_extents, 50.13 + unsigned int nr_extents, 50.14 unsigned int extent_order) 50.15 { 50.16 struct pfn_info *page; 50.17 @@ -72,7 +73,7 @@ static long 50.18 free_dom_mem(struct domain *d, 50.19 unsigned long *extent_list, 50.20 unsigned long start_extent, 50.21 - unsigned long nr_extents, 50.22 + unsigned int nr_extents, 50.23 unsigned int extent_order) 50.24 { 50.25 struct pfn_info *page; 50.26 @@ -133,7 +134,7 @@ do_dom_mem_op(unsigned long op, 50.27 op &= (1 << START_EXTENT_SHIFT) - 1; 50.28 50.29 if ( unlikely(start_extent > nr_extents) || 50.30 - unlikely(nr_extents > (~0UL >> START_EXTENT_SHIFT)) ) 50.31 + unlikely(nr_extents > ~0U) ) /* can pack into a uint? */ 50.32 return -EINVAL; 50.33 50.34 if ( likely(domid == DOMID_SELF) ) 50.35 @@ -141,7 +142,7 @@ do_dom_mem_op(unsigned long op, 50.36 else if ( unlikely(!IS_PRIV(current->domain)) ) 50.37 return -EPERM; 50.38 else if ( unlikely((d = find_domain_by_id(domid)) == NULL) ) 50.39 - return -ESRCH; 50.40 + return -ESRCH; 50.41 50.42 LOCK_BIGLOCK(d); 50.43 50.44 @@ -149,19 +150,21 @@ do_dom_mem_op(unsigned long op, 50.45 { 50.46 case MEMOP_increase_reservation: 50.47 rc = alloc_dom_mem( 50.48 - d, extent_list, start_extent, nr_extents, extent_order); 50.49 - break; 50.50 + d, extent_list, start_extent, 50.51 + (unsigned int)nr_extents, extent_order); 50.52 + break; 50.53 case MEMOP_decrease_reservation: 50.54 rc = free_dom_mem( 50.55 - d, extent_list, start_extent, nr_extents, extent_order); 50.56 - break; 50.57 + d, extent_list, start_extent, 50.58 + (unsigned int)nr_extents, extent_order); 50.59 + break; 50.60 default: 50.61 rc = -ENOSYS; 50.62 break; 50.63 } 50.64 50.65 if ( unlikely(domid != DOMID_SELF) ) 50.66 - put_domain(d); 50.67 + put_domain(d); 50.68 50.69 UNLOCK_BIGLOCK(d); 50.70
51.1 --- a/xen/common/domain.c Fri Feb 04 19:26:10 2005 +0000 51.2 +++ b/xen/common/domain.c Mon Feb 07 08:19:24 2005 +0000 51.3 @@ -1,3 +1,4 @@ 51.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 51.5 /****************************************************************************** 51.6 * domain.c 51.7 * 51.8 @@ -38,13 +39,13 @@ struct domain *do_createdomain(domid_t d 51.9 atomic_set(&d->refcnt, 1); 51.10 atomic_set(&ed->pausecnt, 0); 51.11 51.12 - shadow_lock_init(ed); 51.13 + shadow_lock_init(d); 51.14 51.15 d->id = dom_id; 51.16 - ed->processor = cpu; 51.17 + ed->processor = cpu; 51.18 d->create_time = NOW(); 51.19 51.20 - memcpy(&ed->thread, &idle0_exec_domain.thread, sizeof(ed->thread)); 51.21 + memcpy(&ed->arch, &idle0_exec_domain.arch, sizeof(ed->arch)); 51.22 51.23 spin_lock_init(&d->time_lock); 51.24 51.25 @@ -326,13 +327,11 @@ long do_boot_vcpu(unsigned long vcpu, fu 51.26 ed = d->exec_domain[vcpu]; 51.27 51.28 atomic_set(&ed->pausecnt, 0); 51.29 - shadow_lock_init(ed); 51.30 - 51.31 - memcpy(&ed->thread, &idle0_exec_domain.thread, sizeof(ed->thread)); 51.32 + shadow_lock_init(d); 51.33 51.34 - /* arch_do_createdomain */ 51.35 - ed->thread.schedule_tail = d->exec_domain[0]->thread.schedule_tail; 51.36 - ed->mm.perdomain_ptes = d->mm_perdomain_pt + (ed->eid << PDPT_VCPU_SHIFT); 51.37 + memcpy(&ed->arch, &idle0_exec_domain.arch, sizeof(ed->arch)); 51.38 + 51.39 + arch_do_boot_vcpu(ed); 51.40 51.41 sched_add_domain(ed); 51.42
52.1 --- a/xen/common/elf.c Fri Feb 04 19:26:10 2005 +0000 52.2 +++ b/xen/common/elf.c Mon Feb 07 08:19:24 2005 +0000 52.3 @@ -1,3 +1,4 @@ 52.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 52.5 /****************************************************************************** 52.6 * elf.c 52.7 *
53.1 --- a/xen/common/event_channel.c Fri Feb 04 19:26:10 2005 +0000 53.2 +++ b/xen/common/event_channel.c Mon Feb 07 08:19:24 2005 +0000 53.3 @@ -1,3 +1,4 @@ 53.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 53.5 /****************************************************************************** 53.6 * event_channel.c 53.7 *
54.1 --- a/xen/common/grant_table.c Fri Feb 04 19:26:10 2005 +0000 54.2 +++ b/xen/common/grant_table.c Mon Feb 07 08:19:24 2005 +0000 54.3 @@ -1,3 +1,4 @@ 54.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 54.5 /****************************************************************************** 54.6 * common/grant_table.c 54.7 * 54.8 @@ -574,7 +575,7 @@ grant_table_create( 54.9 54.10 /* Active grant table. */ 54.11 if ( (t->active = xmalloc_array(active_grant_entry_t, NR_GRANT_ENTRIES)) 54.12 - == NULL ) 54.13 + == NULL ) 54.14 goto no_mem; 54.15 memset(t->active, 0, sizeof(active_grant_entry_t) * NR_GRANT_ENTRIES); 54.16
55.1 --- a/xen/common/kernel.c Fri Feb 04 19:26:10 2005 +0000 55.2 +++ b/xen/common/kernel.c Mon Feb 07 08:19:24 2005 +0000 55.3 @@ -1,3 +1,4 @@ 55.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 55.5 /****************************************************************************** 55.6 * kernel.c 55.7 *
56.1 --- a/xen/common/keyhandler.c Fri Feb 04 19:26:10 2005 +0000 56.2 +++ b/xen/common/keyhandler.c Mon Feb 07 08:19:24 2005 +0000 56.3 @@ -1,3 +1,4 @@ 56.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 56.5 /****************************************************************************** 56.6 * keyhandler.c 56.7 */
57.1 --- a/xen/common/lib.c Fri Feb 04 19:26:10 2005 +0000 57.2 +++ b/xen/common/lib.c Mon Feb 07 08:19:24 2005 +0000 57.3 @@ -1,3 +1,4 @@ 57.4 +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 57.5 57.6 #include <xen/ctype.h> 57.7 #include <xen/lib.h> 57.8 @@ -394,9 +395,9 @@ u64 57.9 */ 57.10 u64 __umoddi3(u64 a, u64 b) 57.11 { 57.12 - u64 rem; 57.13 - __qdivrem(a, b, &rem); 57.14 - return rem; 57.15 + u64 rem; 57.16 + __qdivrem(a, b, &rem); 57.17 + return rem; 57.18 } 57.19 57.20 /* 57.21 @@ -425,19 +426,18 @@ s64 __moddi3(s64 a, s64 b) 57.22 ub = b, neg2 = 0; 57.23 __qdivrem(ua, ub, &urem); 57.24 57.25 - /* There 4 different cases: */ 57.26 - if(neg1) 57.27 - { 57.28 - if(neg2) 57.29 - return -urem; 57.30 - else 57.31 - return ub - urem; 57.32 - } 57.33 - else 57.34 - if(neg2) 57.35 - return -ub + urem; 57.36 - else 57.37 - return urem; 57.38 + /* There 4 different cases: */ 57.39 + if (neg1) { 57.40 + if (neg2) 57.41 + return -urem; 57.42 + else 57.43 + return ub - urem; 57.44 + } else { 57.45 + if (neg2) 57.46 + return -ub + urem; 57.47 + else 57.48 + return urem; 57.49 + } 57.50 } 57.51 57.52 #endif /* BITS_PER_LONG == 32 */
59.1 --- a/xen/common/multicall.c Fri Feb 04 19:26:10 2005 +0000 59.2 +++ b/xen/common/multicall.c Mon Feb 07 08:19:24 2005 +0000 59.3 @@ -1,3 +1,4 @@ 59.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 59.5 /****************************************************************************** 59.6 * multicall.c 59.7 */
60.1 --- a/xen/common/page_alloc.c Fri Feb 04 19:26:10 2005 +0000 60.2 +++ b/xen/common/page_alloc.c Mon Feb 07 08:19:24 2005 +0000 60.3 @@ -1,3 +1,4 @@ 60.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 60.5 /****************************************************************************** 60.6 * page_alloc.c 60.7 * 60.8 @@ -262,8 +263,8 @@ struct pfn_info *alloc_heap_pages(unsign 60.9 60.10 /* Find smallest order which can satisfy the request. */ 60.11 for ( i = order; i <= MAX_ORDER; i++ ) 60.12 - if ( !list_empty(&heap[zone][i]) ) 60.13 - goto found; 60.14 + if ( !list_empty(&heap[zone][i]) ) 60.15 + goto found; 60.16 60.17 /* No suitable memory blocks. Fail the request. */ 60.18 spin_unlock(&heap_lock); 60.19 @@ -403,9 +404,8 @@ unsigned long alloc_xenheap_pages(unsign 60.20 { 60.21 unsigned long flags; 60.22 struct pfn_info *pg; 60.23 - int i, attempts = 0; 60.24 + int i; 60.25 60.26 - retry: 60.27 local_irq_save(flags); 60.28 pg = alloc_heap_pages(MEMZONE_XEN, order); 60.29 local_irq_restore(flags); 60.30 @@ -425,14 +425,7 @@ unsigned long alloc_xenheap_pages(unsign 60.31 return (unsigned long)page_to_virt(pg); 60.32 60.33 no_memory: 60.34 - if ( attempts++ < 8 ) 60.35 - { 60.36 - xmem_cache_reap(); 60.37 - goto retry; 60.38 - } 60.39 - 60.40 printk("Cannot handle page request order %d!\n", order); 60.41 - dump_slabinfo(); 60.42 return 0; 60.43 } 60.44
61.1 --- a/xen/common/perfc.c Fri Feb 04 19:26:10 2005 +0000 61.2 +++ b/xen/common/perfc.c Mon Feb 07 08:19:24 2005 +0000 61.3 @@ -1,3 +1,4 @@ 61.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 61.5 61.6 #include <xen/lib.h> 61.7 #include <xen/smp.h> 61.8 @@ -22,7 +23,7 @@ 61.9 static struct { 61.10 char *name; 61.11 enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY, 61.12 - TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY 61.13 + TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY 61.14 } type; 61.15 int nr_elements; 61.16 } perfc_info[] = { 61.17 @@ -92,19 +93,19 @@ void perfc_reset(unsigned char key) 61.18 switch ( perfc_info[i].type ) 61.19 { 61.20 case TYPE_SINGLE: 61.21 - atomic_set(&counters[0],0); 61.22 + atomic_set(&counters[0],0); 61.23 case TYPE_S_SINGLE: 61.24 counters += 1; 61.25 break; 61.26 case TYPE_CPU: 61.27 for ( j = sum = 0; j < smp_num_cpus; j++ ) 61.28 - atomic_set(&counters[j],0); 61.29 + atomic_set(&counters[j],0); 61.30 case TYPE_S_CPU: 61.31 counters += NR_CPUS; 61.32 break; 61.33 case TYPE_ARRAY: 61.34 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ ) 61.35 - atomic_set(&counters[j],0); 61.36 + atomic_set(&counters[j],0); 61.37 case TYPE_S_ARRAY: 61.38 counters += perfc_info[i].nr_elements; 61.39 break;
62.1 --- a/xen/common/physdev.c Fri Feb 04 19:26:10 2005 +0000 62.2 +++ b/xen/common/physdev.c Mon Feb 07 08:19:24 2005 +0000 62.3 @@ -1,4 +1,4 @@ 62.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 62.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- 62.6 **************************************************************************** 62.7 * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge 62.8 * (c) 2004 - Keir Fraser - University of Cambridge 62.9 @@ -150,9 +150,9 @@ int physdev_pci_access_modify( 62.10 62.11 /* Make the domain privileged. */ 62.12 set_bit(DF_PHYSDEV, &p->d_flags); 62.13 - /* FIXME: MAW for now make the domain REALLY privileged so that it 62.14 - * can run a backend driver (hw access should work OK otherwise) */ 62.15 - set_bit(DF_PRIVILEGED, &p->d_flags); 62.16 + /* FIXME: MAW for now make the domain REALLY privileged so that it 62.17 + * can run a backend driver (hw access should work OK otherwise) */ 62.18 + set_bit(DF_PRIVILEGED, &p->d_flags); 62.19 62.20 /* Grant write access to the specified device. */ 62.21 if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL ) 62.22 @@ -172,21 +172,21 @@ int physdev_pci_access_modify( 62.23 62.24 /* Now, setup access to the IO ports and memory regions for the device. */ 62.25 62.26 - if ( ed->thread.io_bitmap == NULL ) 62.27 + if ( ed->arch.io_bitmap == NULL ) 62.28 { 62.29 - if ( (ed->thread.io_bitmap = xmalloc_array(u8, IOBMP_BYTES)) == NULL ) 62.30 + if ( (ed->arch.io_bitmap = xmalloc_array(u8, IOBMP_BYTES)) == NULL ) 62.31 { 62.32 rc = -ENOMEM; 62.33 goto out; 62.34 } 62.35 - memset(ed->thread.io_bitmap, 0xFF, IOBMP_BYTES); 62.36 + memset(ed->arch.io_bitmap, 0xFF, IOBMP_BYTES); 62.37 62.38 - ed->thread.io_bitmap_sel = ~0ULL; 62.39 + ed->arch.io_bitmap_sel = ~0ULL; 62.40 62.41 for_each_exec_domain(p, edc) { 62.42 if (edc == ed) 62.43 continue; 62.44 - edc->thread.io_bitmap = ed->thread.io_bitmap; 62.45 + edc->arch.io_bitmap = ed->arch.io_bitmap; 62.46 } 62.47 } 62.48 62.49 @@ -204,8 +204,8 @@ int physdev_pci_access_modify( 62.50 "for device %s\n", dom, r->start, r->end, pdev->slot_name); 62.51 for ( j = r->start; j < r->end + 1; j++ ) 62.52 { 62.53 - clear_bit(j, ed->thread.io_bitmap); 62.54 - clear_bit(j / IOBMP_BITS_PER_SELBIT, &ed->thread.io_bitmap_sel); 62.55 + clear_bit(j, ed->arch.io_bitmap); 62.56 + clear_bit(j / IOBMP_BITS_PER_SELBIT, &ed->arch.io_bitmap_sel); 62.57 } 62.58 } 62.59 62.60 @@ -215,7 +215,7 @@ int physdev_pci_access_modify( 62.61 for_each_exec_domain(p, edc) { 62.62 if (edc == ed) 62.63 continue; 62.64 - edc->thread.io_bitmap_sel = ed->thread.io_bitmap_sel; 62.65 + edc->arch.io_bitmap_sel = ed->arch.io_bitmap_sel; 62.66 } 62.67 62.68 out:
63.1 --- a/xen/common/resource.c Fri Feb 04 19:26:10 2005 +0000 63.2 +++ b/xen/common/resource.c Mon Feb 07 08:19:24 2005 +0000 63.3 @@ -1,3 +1,4 @@ 63.4 +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 63.5 /* 63.6 * linux/kernel/resource.c 63.7 *
64.1 --- a/xen/common/sched_atropos.c Fri Feb 04 19:26:10 2005 +0000 64.2 +++ b/xen/common/sched_atropos.c Mon Feb 07 08:19:24 2005 +0000 64.3 @@ -1,3 +1,4 @@ 64.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 64.5 /* 64.6 * atropos.c 64.7 * ---------
65.1 --- a/xen/common/sched_bvt.c Fri Feb 04 19:26:10 2005 +0000 65.2 +++ b/xen/common/sched_bvt.c Mon Feb 07 08:19:24 2005 +0000 65.3 @@ -1,4 +1,4 @@ 65.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 65.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- 65.6 **************************************************************************** 65.7 * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge 65.8 * (C) 2002-2003 University of Cambridge
66.1 --- a/xen/common/sched_rrobin.c Fri Feb 04 19:26:10 2005 +0000 66.2 +++ b/xen/common/sched_rrobin.c Mon Feb 07 08:19:24 2005 +0000 66.3 @@ -1,3 +1,4 @@ 66.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 66.5 /**************************************************************************** 66.6 * Round Robin Scheduler for Xen 66.7 *
67.1 --- a/xen/common/schedule.c Fri Feb 04 19:26:10 2005 +0000 67.2 +++ b/xen/common/schedule.c Mon Feb 07 08:19:24 2005 +0000 67.3 @@ -1,4 +1,4 @@ 67.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 67.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- 67.6 **************************************************************************** 67.7 * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge 67.8 * (C) 2002-2003 University of Cambridge 67.9 @@ -373,13 +373,6 @@ void __enter_scheduler(void) 67.10 task_slice_t next_slice; 67.11 s32 r_time; /* time for new dom to run */ 67.12 67.13 - if ( !is_idle_task(current->domain) ) 67.14 - { 67.15 - LOCK_BIGLOCK(current->domain); 67.16 - cleanup_writable_pagetable(prev->domain); 67.17 - UNLOCK_BIGLOCK(current->domain); 67.18 - } 67.19 - 67.20 perfc_incrc(sched_run); 67.21 67.22 spin_lock_irq(&schedule_data[cpu].schedule_lock); 67.23 @@ -429,6 +422,13 @@ void __enter_scheduler(void) 67.24 67.25 perfc_incrc(sched_ctx); 67.26 67.27 + if ( !is_idle_task(prev->domain) ) 67.28 + { 67.29 + LOCK_BIGLOCK(prev->domain); 67.30 + cleanup_writable_pagetable(prev->domain); 67.31 + UNLOCK_BIGLOCK(prev->domain); 67.32 + } 67.33 + 67.34 #if defined(WAKE_HISTO) 67.35 if ( !is_idle_task(next) && next->wokenup ) { 67.36 ulong diff = (ulong)(now - next->wokenup);
68.1 --- a/xen/common/slab.c Fri Feb 04 19:26:10 2005 +0000 68.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 68.3 @@ -1,1844 +0,0 @@ 68.4 -/* 68.5 - * linux/mm/slab.c 68.6 - * Written by Mark Hemment, 1996/97. 68.7 - * (markhe@nextd.demon.co.uk) 68.8 - * 68.9 - * xmem_cache_destroy() + some cleanup - 1999 Andrea Arcangeli 68.10 - * 68.11 - * Major cleanup, different bufctl logic, per-cpu arrays 68.12 - * (c) 2000 Manfred Spraul 68.13 - * 68.14 - * An implementation of the Slab Allocator as described in outline in; 68.15 - * UNIX Internals: The New Frontiers by Uresh Vahalia 68.16 - * Pub: Prentice Hall ISBN 0-13-101908-2 68.17 - * or with a little more detail in; 68.18 - * The Slab Allocator: An Object-Caching Kernel Memory Allocator 68.19 - * Jeff Bonwick (Sun Microsystems). 68.20 - * Presented at: USENIX Summer 1994 Technical Conference 68.21 - * 68.22 - * 68.23 - * The memory is organized in caches, one cache for each object type. 68.24 - * (e.g. inode_cache, dentry_cache, buffer_head, vm_area_struct) 68.25 - * Each cache consists out of many slabs (they are small (usually one 68.26 - * page long) and always contiguous), and each slab contains multiple 68.27 - * initialized objects. 68.28 - * 68.29 - * In order to reduce fragmentation, the slabs are sorted in 3 groups: 68.30 - * full slabs with 0 free objects 68.31 - * partial slabs 68.32 - * empty slabs with no allocated objects 68.33 - * 68.34 - * If partial slabs exist, then new allocations come from these slabs, 68.35 - * otherwise from empty slabs or new slabs are allocated. 68.36 - * 68.37 - * xmem_cache_destroy() CAN CRASH if you try to allocate from the cache 68.38 - * during xmem_cache_destroy(). The caller must prevent concurrent allocs. 68.39 - * 68.40 - * On SMP systems, each cache has a short per-cpu head array, most allocs 68.41 - * and frees go into that array, and if that array overflows, then 1/2 68.42 - * of the entries in the array are given back into the global cache. 68.43 - * This reduces the number of spinlock operations. 68.44 - * 68.45 - * The c_cpuarray may not be read with enabled local interrupts. 68.46 - * 68.47 - * SMP synchronization: 68.48 - * constructors and destructors are called without any locking. 68.49 - * Several members in xmem_cache_t and slab_t never change, they 68.50 - * are accessed without any locking. 68.51 - * The per-cpu arrays are never accessed from the wrong cpu, no locking. 68.52 - * The non-constant members are protected with a per-cache irq spinlock. 68.53 - */ 68.54 - 68.55 -#include <xen/config.h> 68.56 -#include <xen/init.h> 68.57 -#include <xen/types.h> 68.58 -#include <xen/lib.h> 68.59 -#include <xen/slab.h> 68.60 -#include <xen/list.h> 68.61 -#include <xen/spinlock.h> 68.62 -#include <xen/errno.h> 68.63 -#include <xen/smp.h> 68.64 -#include <xen/sched.h> 68.65 - 68.66 -/* 68.67 - * DEBUG - 1 for xmem_cache_create() to honour; SLAB_DEBUG_INITIAL, 68.68 - * SLAB_RED_ZONE & SLAB_POISON. 68.69 - * 0 for faster, smaller code (especially in the critical paths). 68.70 - * 68.71 - * STATS - 1 to collect stats for /proc/slabinfo. 68.72 - * 0 for faster, smaller code (especially in the critical paths). 68.73 - * 68.74 - * FORCED_DEBUG - 1 enables SLAB_RED_ZONE and SLAB_POISON (if possible) 68.75 - */ 68.76 -#ifdef CONFIG_DEBUG_SLAB 68.77 -#define DEBUG 1 68.78 -#define STATS 1 68.79 -#define FORCED_DEBUG 1 68.80 -#else 68.81 -#define DEBUG 0 68.82 -#define STATS 0 68.83 -#define FORCED_DEBUG 0 68.84 -#endif 68.85 - 68.86 -/* 68.87 - * Parameters for xmem_cache_reap 68.88 - */ 68.89 -#define REAP_SCANLEN 10 68.90 -#define REAP_PERFECT 10 68.91 - 68.92 -/* Shouldn't this be in a header file somewhere? */ 68.93 -#define BYTES_PER_WORD sizeof(void *) 68.94 - 68.95 -/* Legal flag mask for xmem_cache_create(). */ 68.96 -#if DEBUG 68.97 -#define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ 68.98 - SLAB_POISON | SLAB_HWCACHE_ALIGN | \ 68.99 - SLAB_NO_REAP) 68.100 -#else 68.101 -#define CREATE_MASK (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP) 68.102 -#endif 68.103 - 68.104 -/* 68.105 - * xmem_bufctl_t: 68.106 - * 68.107 - * Bufctl's are used for linking objs within a slab 68.108 - * linked offsets. 68.109 - * 68.110 - * This implementaion relies on "struct page" for locating the cache & 68.111 - * slab an object belongs to. 68.112 - * This allows the bufctl structure to be small (one int), but limits 68.113 - * the number of objects a slab (not a cache) can contain when off-slab 68.114 - * bufctls are used. The limit is the size of the largest general cache 68.115 - * that does not use off-slab slabs. 68.116 - * For 32bit archs with 4 kB pages, is this 56. 68.117 - * This is not serious, as it is only for large objects, when it is unwise 68.118 - * to have too many per slab. 68.119 - * Note: This limit can be raised by introducing a general cache whose size 68.120 - * is less than 512 (PAGE_SIZE<<3), but greater than 256. 68.121 - */ 68.122 - 68.123 -#define BUFCTL_END (((xmem_bufctl_t)(~0U))-0) 68.124 -#define BUFCTL_FREE (((xmem_bufctl_t)(~0U))-1) 68.125 -#define SLAB_LIMIT (((xmem_bufctl_t)(~0U))-2) 68.126 - 68.127 -/* Max number of objs-per-slab for caches which use off-slab slabs. 68.128 - * Needed to avoid a possible looping condition in xmem_cache_grow(). 68.129 - */ 68.130 -static unsigned long offslab_limit; 68.131 - 68.132 -/* 68.133 - * slab_t 68.134 - * 68.135 - * Manages the objs in a slab. Placed either at the beginning of mem allocated 68.136 - * for a slab, or allocated from an general cache. 68.137 - * Slabs are chained into three list: fully used, partial, fully free slabs. 68.138 - */ 68.139 -typedef struct slab_s { 68.140 - struct list_head list; 68.141 - unsigned long colouroff; 68.142 - void *s_mem; /* including colour offset */ 68.143 - unsigned int inuse; /* num of objs active in slab */ 68.144 - xmem_bufctl_t free; 68.145 -} slab_t; 68.146 - 68.147 -#define slab_bufctl(slabp) \ 68.148 - ((xmem_bufctl_t *)(((slab_t*)slabp)+1)) 68.149 - 68.150 -/* 68.151 - * cpucache_t 68.152 - * 68.153 - * Per cpu structures 68.154 - * The limit is stored in the per-cpu structure to reduce the data cache 68.155 - * footprint. 68.156 - */ 68.157 -typedef struct cpucache_s { 68.158 - unsigned int avail; 68.159 - unsigned int limit; 68.160 -} cpucache_t; 68.161 - 68.162 -#define cc_entry(cpucache) \ 68.163 - ((void **)(((cpucache_t*)(cpucache))+1)) 68.164 -#define cc_data(cachep) \ 68.165 - ((cachep)->cpudata[smp_processor_id()]) 68.166 -/* 68.167 - * xmem_cache_t 68.168 - * 68.169 - * manages a cache. 68.170 - */ 68.171 - 68.172 -#define CACHE_NAMELEN 20 /* max name length for a slab cache */ 68.173 - 68.174 -struct xmem_cache_s { 68.175 -/* 1) each alloc & free */ 68.176 - /* full, partial first, then free */ 68.177 - struct list_head slabs_full; 68.178 - struct list_head slabs_partial; 68.179 - struct list_head slabs_free; 68.180 - unsigned int objsize; 68.181 - unsigned int flags; /* constant flags */ 68.182 - unsigned int num; /* # of objs per slab */ 68.183 - spinlock_t spinlock; 68.184 -#ifdef CONFIG_SMP 68.185 - unsigned int batchcount; 68.186 -#endif 68.187 - 68.188 -/* 2) slab additions /removals */ 68.189 - /* order of pgs per slab (2^n) */ 68.190 - unsigned int gfporder; 68.191 - size_t colour; /* cache colouring range */ 68.192 - unsigned int colour_off; /* colour offset */ 68.193 - unsigned int colour_next; /* cache colouring */ 68.194 - xmem_cache_t *slabp_cache; 68.195 - unsigned int growing; 68.196 - unsigned int dflags; /* dynamic flags */ 68.197 - 68.198 - /* constructor func */ 68.199 - void (*ctor)(void *, xmem_cache_t *, unsigned long); 68.200 - 68.201 - /* de-constructor func */ 68.202 - void (*dtor)(void *, xmem_cache_t *, unsigned long); 68.203 - 68.204 - unsigned long failures; 68.205 - 68.206 -/* 3) cache creation/removal */ 68.207 - char name[CACHE_NAMELEN]; 68.208 - struct list_head next; 68.209 -#ifdef CONFIG_SMP 68.210 -/* 4) per-cpu data */ 68.211 - cpucache_t *cpudata[NR_CPUS]; 68.212 -#endif 68.213 -#if STATS 68.214 - unsigned long num_active; 68.215 - unsigned long num_allocations; 68.216 - unsigned long high_mark; 68.217 - unsigned long grown; 68.218 - unsigned long reaped; 68.219 - unsigned long errors; 68.220 -#ifdef CONFIG_SMP 68.221 - atomic_t allochit; 68.222 - atomic_t allocmiss; 68.223 - atomic_t freehit; 68.224 - atomic_t freemiss; 68.225 -#endif 68.226 -#endif 68.227 -}; 68.228 - 68.229 -/* internal c_flags */ 68.230 -#define CFLGS_OFF_SLAB 0x010000UL /* slab management in own cache */ 68.231 -#define CFLGS_OPTIMIZE 0x020000UL /* optimized slab lookup */ 68.232 - 68.233 -/* c_dflags (dynamic flags). Need to hold the spinlock to access this member */ 68.234 -#define DFLGS_GROWN 0x000001UL /* don't reap a recently grown */ 68.235 - 68.236 -#define OFF_SLAB(x) ((x)->flags & CFLGS_OFF_SLAB) 68.237 -#define OPTIMIZE(x) ((x)->flags & CFLGS_OPTIMIZE) 68.238 -#define GROWN(x) ((x)->dlags & DFLGS_GROWN) 68.239 - 68.240 -#if STATS 68.241 -#define STATS_INC_ACTIVE(x) ((x)->num_active++) 68.242 -#define STATS_DEC_ACTIVE(x) ((x)->num_active--) 68.243 -#define STATS_INC_ALLOCED(x) ((x)->num_allocations++) 68.244 -#define STATS_INC_GROWN(x) ((x)->grown++) 68.245 -#define STATS_INC_REAPED(x) ((x)->reaped++) 68.246 -#define STATS_SET_HIGH(x) do { if ((x)->num_active > (x)->high_mark) \ 68.247 - (x)->high_mark = (x)->num_active; \ 68.248 - } while (0) 68.249 -#define STATS_INC_ERR(x) ((x)->errors++) 68.250 -#else 68.251 -#define STATS_INC_ACTIVE(x) do { } while (0) 68.252 -#define STATS_DEC_ACTIVE(x) do { } while (0) 68.253 -#define STATS_INC_ALLOCED(x) do { } while (0) 68.254 -#define STATS_INC_GROWN(x) do { } while (0) 68.255 -#define STATS_INC_REAPED(x) do { } while (0) 68.256 -#define STATS_SET_HIGH(x) do { } while (0) 68.257 -#define STATS_INC_ERR(x) do { } while (0) 68.258 -#endif 68.259 - 68.260 -#if STATS && defined(CONFIG_SMP) 68.261 -#define STATS_INC_ALLOCHIT(x) atomic_inc(&(x)->allochit) 68.262 -#define STATS_INC_ALLOCMISS(x) atomic_inc(&(x)->allocmiss) 68.263 -#define STATS_INC_FREEHIT(x) atomic_inc(&(x)->freehit) 68.264 -#define STATS_INC_FREEMISS(x) atomic_inc(&(x)->freemiss) 68.265 -#else 68.266 -#define STATS_INC_ALLOCHIT(x) do { } while (0) 68.267 -#define STATS_INC_ALLOCMISS(x) do { } while (0) 68.268 -#define STATS_INC_FREEHIT(x) do { } while (0) 68.269 -#define STATS_INC_FREEMISS(x) do { } while (0) 68.270 -#endif 68.271 - 68.272 -#if DEBUG 68.273 -/* Magic nums for obj red zoning. 68.274 - * Placed in the first word before and the first word after an obj. 68.275 - */ 68.276 -#define RED_MAGIC1 0x5A2CF071UL /* when obj is active */ 68.277 -#define RED_MAGIC2 0x170FC2A5UL /* when obj is inactive */ 68.278 - 68.279 -/* ...and for poisoning */ 68.280 -#define POISON_BYTE 0x5a /* byte value for poisoning */ 68.281 -#define POISON_END 0xa5 /* end-byte of poisoning */ 68.282 - 68.283 -#endif 68.284 - 68.285 -/* maximum size of an obj (in 2^order pages) */ 68.286 -#define MAX_OBJ_ORDER 5 /* 32 pages */ 68.287 - 68.288 -/* 68.289 - * Do not go above this order unless 0 objects fit into the slab. 68.290 - */ 68.291 -#define BREAK_GFP_ORDER_HI 2 68.292 -#define BREAK_GFP_ORDER_LO 1 68.293 -static int slab_break_gfp_order = BREAK_GFP_ORDER_LO; 68.294 - 68.295 -/* 68.296 - * Absolute limit for the gfp order 68.297 - */ 68.298 -#define MAX_GFP_ORDER 5 /* 32 pages */ 68.299 - 68.300 - 68.301 -/* Macros for storing/retrieving the cachep and or slab from the 68.302 - * global 'mem_map'. These are used to find the slab an obj belongs to. 68.303 - * With xfree(), these are used to find the cache which an obj belongs to. 68.304 - */ 68.305 -#define SET_PAGE_CACHE(pg,x) ((pg)->list.next = (struct list_head *)(x)) 68.306 -#define GET_PAGE_CACHE(pg) ((xmem_cache_t *)(pg)->list.next) 68.307 -#define SET_PAGE_SLAB(pg,x) ((pg)->list.prev = (struct list_head *)(x)) 68.308 -#define GET_PAGE_SLAB(pg) ((slab_t *)(pg)->list.prev) 68.309 - 68.310 -/* Size description struct for general caches. */ 68.311 -typedef struct cache_sizes { 68.312 - size_t cs_size; 68.313 - xmem_cache_t *cs_cachep; 68.314 -} cache_sizes_t; 68.315 - 68.316 -static cache_sizes_t cache_sizes[] = { 68.317 - { 32, NULL}, 68.318 - { 64, NULL}, 68.319 - { 128, NULL}, 68.320 - { 256, NULL}, 68.321 - { 512, NULL}, 68.322 - { 1024, NULL}, 68.323 - { 2048, NULL}, 68.324 - { 4096, NULL}, 68.325 - { 8192, NULL}, 68.326 - { 16384, NULL}, 68.327 - { 32768, NULL}, 68.328 - { 65536, NULL}, 68.329 - { 0, NULL} 68.330 -}; 68.331 - 68.332 -/* internal cache of cache description objs */ 68.333 -static xmem_cache_t cache_cache = { 68.334 - slabs_full: LIST_HEAD_INIT(cache_cache.slabs_full), 68.335 - slabs_partial: LIST_HEAD_INIT(cache_cache.slabs_partial), 68.336 - slabs_free: LIST_HEAD_INIT(cache_cache.slabs_free), 68.337 - objsize: sizeof(xmem_cache_t), 68.338 - flags: SLAB_NO_REAP, 68.339 - spinlock: SPIN_LOCK_UNLOCKED, 68.340 - colour_off: L1_CACHE_BYTES, 68.341 - name: "xmem_cache" 68.342 -}; 68.343 - 68.344 -/* Guard access to the cache-chain. */ 68.345 -/* KAF: No semaphores, as we'll never wait around for I/O. */ 68.346 -static spinlock_t cache_chain_sem; 68.347 -#define init_MUTEX(_m) spin_lock_init(_m) 68.348 -#define down(_m) spin_lock_irqsave(_m,spin_flags) 68.349 -#define up(_m) spin_unlock_irqrestore(_m,spin_flags) 68.350 - 68.351 -/* Place maintainer for reaping. */ 68.352 -static xmem_cache_t *clock_searchp = &cache_cache; 68.353 - 68.354 -#define cache_chain (cache_cache.next) 68.355 - 68.356 -#ifdef CONFIG_SMP 68.357 -/* 68.358 - * chicken and egg problem: delay the per-cpu array allocation 68.359 - * until the general caches are up. 68.360 - */ 68.361 -static int g_cpucache_up; 68.362 - 68.363 -static void enable_cpucache (xmem_cache_t *cachep); 68.364 -static void enable_all_cpucaches (void); 68.365 -#endif 68.366 - 68.367 -/* Cal the num objs, wastage, and bytes left over for a given slab size. */ 68.368 -static void xmem_cache_estimate (unsigned long gfporder, size_t size, 68.369 - int flags, size_t *left_over, unsigned int *num) 68.370 -{ 68.371 - int i; 68.372 - size_t wastage = PAGE_SIZE<<gfporder; 68.373 - size_t extra = 0; 68.374 - size_t base = 0; 68.375 - 68.376 - if (!(flags & CFLGS_OFF_SLAB)) { 68.377 - base = sizeof(slab_t); 68.378 - extra = sizeof(xmem_bufctl_t); 68.379 - } 68.380 - i = 0; 68.381 - while (i*size + L1_CACHE_ALIGN(base+i*extra) <= wastage) 68.382 - i++; 68.383 - if (i > 0) 68.384 - i--; 68.385 - 68.386 - if (i > SLAB_LIMIT) 68.387 - i = SLAB_LIMIT; 68.388 - 68.389 - *num = i; 68.390 - wastage -= i*size; 68.391 - wastage -= L1_CACHE_ALIGN(base+i*extra); 68.392 - *left_over = wastage; 68.393 -} 68.394 - 68.395 -/* Initialisation - setup the `cache' cache. */ 68.396 -void __init xmem_cache_init(void) 68.397 -{ 68.398 - size_t left_over; 68.399 - 68.400 - init_MUTEX(&cache_chain_sem); 68.401 - INIT_LIST_HEAD(&cache_chain); 68.402 - 68.403 - xmem_cache_estimate(0, cache_cache.objsize, 0, 68.404 - &left_over, &cache_cache.num); 68.405 - if (!cache_cache.num) 68.406 - BUG(); 68.407 - 68.408 - cache_cache.colour = left_over/cache_cache.colour_off; 68.409 - cache_cache.colour_next = 0; 68.410 -} 68.411 - 68.412 - 68.413 -/* Initialisation - setup remaining internal and general caches. 68.414 - * Called after the gfp() functions have been enabled, and before smp_init(). 68.415 - */ 68.416 -void __init xmem_cache_sizes_init(unsigned long num_physpages) 68.417 -{ 68.418 - cache_sizes_t *sizes = cache_sizes; 68.419 - char name[20]; 68.420 - /* 68.421 - * Fragmentation resistance on low memory - only use bigger 68.422 - * page orders on machines with more than 32MB of memory. 68.423 - */ 68.424 - if (num_physpages > (32 << 20) >> PAGE_SHIFT) 68.425 - slab_break_gfp_order = BREAK_GFP_ORDER_HI; 68.426 - do { 68.427 - /* For performance, all the general caches are L1 aligned. 68.428 - * This should be particularly beneficial on SMP boxes, as it 68.429 - * eliminates "false sharing". 68.430 - * Note for systems short on memory removing the alignment will 68.431 - * allow tighter packing of the smaller caches. */ 68.432 - sprintf(name,"size-%Zd",sizes->cs_size); 68.433 - if (!(sizes->cs_cachep = 68.434 - xmem_cache_create(name, sizes->cs_size, 68.435 - 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) { 68.436 - BUG(); 68.437 - } 68.438 - 68.439 - /* Inc off-slab bufctl limit until the ceiling is hit. */ 68.440 - if (!(OFF_SLAB(sizes->cs_cachep))) { 68.441 - offslab_limit = sizes->cs_size-sizeof(slab_t); 68.442 - offslab_limit /= 2; 68.443 - } 68.444 - sizes++; 68.445 - } while (sizes->cs_size); 68.446 -} 68.447 - 68.448 -int __init xmem_cpucache_init(void) 68.449 -{ 68.450 -#ifdef CONFIG_SMP 68.451 - g_cpucache_up = 1; 68.452 - enable_all_cpucaches(); 68.453 -#endif 68.454 - return 0; 68.455 -} 68.456 - 68.457 -/*__initcall(xmem_cpucache_init);*/ 68.458 - 68.459 -/* Interface to system's page allocator. No need to hold the cache-lock. 68.460 - */ 68.461 -static inline void *xmem_getpages(xmem_cache_t *cachep) 68.462 -{ 68.463 - void *addr; 68.464 - 68.465 - addr = (void*) alloc_xenheap_pages(cachep->gfporder); 68.466 - /* Assume that now we have the pages no one else can legally 68.467 - * messes with the 'struct page's. 68.468 - * However vm_scan() might try to test the structure to see if 68.469 - * it is a named-page or buffer-page. The members it tests are 68.470 - * of no interest here..... 68.471 - */ 68.472 - return addr; 68.473 -} 68.474 - 68.475 -/* Interface to system's page release. */ 68.476 -static inline void xmem_freepages (xmem_cache_t *cachep, void *addr) 68.477 -{ 68.478 - unsigned long i = (1<<cachep->gfporder); 68.479 - struct pfn_info *page = virt_to_page(addr); 68.480 - 68.481 - /* free_xenheap_pages() does not clear the type bit - we do that. 68.482 - * The pages have been unlinked from their cache-slab, 68.483 - * but their 'struct page's might be accessed in 68.484 - * vm_scan(). Shouldn't be a worry. 68.485 - */ 68.486 - while (i--) { 68.487 - PageClearSlab(page); 68.488 - page++; 68.489 - } 68.490 - 68.491 - free_xenheap_pages((unsigned long)addr, cachep->gfporder); 68.492 -} 68.493 - 68.494 -#if DEBUG 68.495 -static inline void xmem_poison_obj (xmem_cache_t *cachep, void *addr) 68.496 -{ 68.497 - int size = cachep->objsize; 68.498 - if (cachep->flags & SLAB_RED_ZONE) { 68.499 - addr += BYTES_PER_WORD; 68.500 - size -= 2*BYTES_PER_WORD; 68.501 - } 68.502 - memset(addr, POISON_BYTE, size); 68.503 - *(unsigned char *)(addr+size-1) = POISON_END; 68.504 -} 68.505 - 68.506 -static inline int xmem_check_poison_obj (xmem_cache_t *cachep, void *addr) 68.507 -{ 68.508 - int size = cachep->objsize; 68.509 - void *end; 68.510 - if (cachep->flags & SLAB_RED_ZONE) { 68.511 - addr += BYTES_PER_WORD; 68.512 - size -= 2*BYTES_PER_WORD; 68.513 - } 68.514 - end = memchr(addr, POISON_END, size); 68.515 - if (end != (addr+size-1)) 68.516 - return 1; 68.517 - return 0; 68.518 -} 68.519 -#endif 68.520 - 68.521 -/* Destroy all the objs in a slab, and release the mem back to the system. 68.522 - * Before calling the slab must have been unlinked from the cache. 68.523 - * The cache-lock is not held/needed. 68.524 - */ 68.525 -static void xmem_slab_destroy (xmem_cache_t *cachep, slab_t *slabp) 68.526 -{ 68.527 - if (cachep->dtor 68.528 -#if DEBUG 68.529 - || cachep->flags & (SLAB_POISON | SLAB_RED_ZONE) 68.530 -#endif 68.531 - ) { 68.532 - int i; 68.533 - for (i = 0; i < cachep->num; i++) { 68.534 - void* objp = slabp->s_mem+cachep->objsize*i; 68.535 -#if DEBUG 68.536 - if (cachep->flags & SLAB_RED_ZONE) { 68.537 - if (*((unsigned long*)(objp)) != RED_MAGIC1) 68.538 - BUG(); 68.539 - if (*((unsigned long*)(objp + cachep->objsize 68.540 - -BYTES_PER_WORD)) != RED_MAGIC1) 68.541 - BUG(); 68.542 - objp += BYTES_PER_WORD; 68.543 - } 68.544 -#endif 68.545 - if (cachep->dtor) 68.546 - (cachep->dtor)(objp, cachep, 0); 68.547 -#if DEBUG 68.548 - if (cachep->flags & SLAB_RED_ZONE) { 68.549 - objp -= BYTES_PER_WORD; 68.550 - } 68.551 - if ((cachep->flags & SLAB_POISON) && 68.552 - xmem_check_poison_obj(cachep, objp)) 68.553 - BUG(); 68.554 -#endif 68.555 - } 68.556 - } 68.557 - 68.558 - xmem_freepages(cachep, slabp->s_mem-slabp->colouroff); 68.559 - if (OFF_SLAB(cachep)) 68.560 - xmem_cache_free(cachep->slabp_cache, slabp); 68.561 -} 68.562 - 68.563 -/** 68.564 - * xmem_cache_create - Create a cache. 68.565 - * @name: A string which is used in /proc/slabinfo to identify this cache. 68.566 - * @size: The size of objects to be created in this cache. 68.567 - * @offset: The offset to use within the page. 68.568 - * @flags: SLAB flags 68.569 - * @ctor: A constructor for the objects. 68.570 - * @dtor: A destructor for the objects. 68.571 - * 68.572 - * Returns a ptr to the cache on success, NULL on failure. 68.573 - * Cannot be called within a int, but can be interrupted. 68.574 - * The @ctor is run when new pages are allocated by the cache 68.575 - * and the @dtor is run before the pages are handed back. 68.576 - * The flags are 68.577 - * 68.578 - * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) 68.579 - * to catch references to uninitialised memory. 68.580 - * 68.581 - * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check 68.582 - * for buffer overruns. 68.583 - * 68.584 - * %SLAB_NO_REAP - Don't automatically reap this cache when we're under 68.585 - * memory pressure. 68.586 - * 68.587 - * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware 68.588 - * cacheline. This can be beneficial if you're counting cycles as closely 68.589 - * as davem. 68.590 - */ 68.591 -xmem_cache_t * 68.592 -xmem_cache_create (const char *name, size_t size, size_t offset, 68.593 - unsigned long flags, 68.594 - void (*ctor)(void*, xmem_cache_t *, unsigned long), 68.595 - void (*dtor)(void*, xmem_cache_t *, unsigned long)) 68.596 -{ 68.597 - const char *func_nm = KERN_ERR "xmem_create: "; 68.598 - size_t left_over, align, slab_size; 68.599 - xmem_cache_t *cachep = NULL; 68.600 - unsigned long spin_flags; 68.601 - 68.602 - /* 68.603 - * Sanity checks... these are all serious usage bugs. 68.604 - */ 68.605 - if ((!name) || 68.606 - ((strlen(name) >= CACHE_NAMELEN - 1)) || 68.607 - (size < BYTES_PER_WORD) || 68.608 - (size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) || 68.609 - (dtor && !ctor) || 68.610 - (offset < 0 || offset > size)) 68.611 - BUG(); 68.612 - 68.613 -#if DEBUG 68.614 - if ((flags & SLAB_DEBUG_INITIAL) && !ctor) { 68.615 - /* No constructor, but inital state check requested */ 68.616 - printk("%sNo con, but init state check requested - %s\n", 68.617 - func_nm, name); 68.618 - flags &= ~SLAB_DEBUG_INITIAL; 68.619 - } 68.620 - 68.621 - if ((flags & SLAB_POISON) && ctor) { 68.622 - /* request for poisoning, but we can't do that with a constructor */ 68.623 - printk("%sPoisoning requested, but con given - %s\n", 68.624 - func_nm, name); 68.625 - flags &= ~SLAB_POISON; 68.626 - } 68.627 -#if FORCED_DEBUG 68.628 - if (size < (PAGE_SIZE>>3)) 68.629 - /* 68.630 - * do not red zone large object, causes severe 68.631 - * fragmentation. 68.632 - */ 68.633 - flags |= SLAB_RED_ZONE; 68.634 - if (!ctor) 68.635 - flags |= SLAB_POISON; 68.636 -#endif 68.637 -#endif 68.638 - 68.639 - /* 68.640 - * Always checks flags, a caller might be expecting debug 68.641 - * support which isn't available. 68.642 - */ 68.643 - if (flags & ~CREATE_MASK) 68.644 - BUG(); 68.645 - 68.646 - /* Get cache's description obj. */ 68.647 - cachep = (xmem_cache_t *)xmem_cache_alloc(&cache_cache); 68.648 - if (!cachep) 68.649 - goto opps; 68.650 - memset(cachep, 0, sizeof(xmem_cache_t)); 68.651 - 68.652 - /* Check that size is in terms of words. This is needed to avoid 68.653 - * unaligned accesses for some archs when redzoning is used, and makes 68.654 - * sure any on-slab bufctl's are also correctly aligned. 68.655 - */ 68.656 - if (size & (BYTES_PER_WORD-1)) { 68.657 - size += (BYTES_PER_WORD-1); 68.658 - size &= ~(BYTES_PER_WORD-1); 68.659 - printk("%sForcing size word alignment - %s\n", func_nm, name); 68.660 - } 68.661 - 68.662 -#if DEBUG 68.663 - if (flags & SLAB_RED_ZONE) { 68.664 - /* 68.665 - * There is no point trying to honour cache alignment 68.666 - * when redzoning. 68.667 - */ 68.668 - flags &= ~SLAB_HWCACHE_ALIGN; 68.669 - size += 2*BYTES_PER_WORD; /* words for redzone */ 68.670 - } 68.671 -#endif 68.672 - align = BYTES_PER_WORD; 68.673 - if (flags & SLAB_HWCACHE_ALIGN) 68.674 - align = L1_CACHE_BYTES; 68.675 - 68.676 - /* Determine if the slab management is 'on' or 'off' slab. */ 68.677 - if (size >= (PAGE_SIZE>>3)) 68.678 - /* 68.679 - * Size is large, assume best to place the slab management obj 68.680 - * off-slab (should allow better packing of objs). 68.681 - */ 68.682 - flags |= CFLGS_OFF_SLAB; 68.683 - 68.684 - if (flags & SLAB_HWCACHE_ALIGN) { 68.685 - /* Need to adjust size so that objs are cache aligned. */ 68.686 - /* Small obj size, can get at least two per cache line. */ 68.687 - /* FIXME: only power of 2 supported, was better */ 68.688 - while (size < align/2) 68.689 - align /= 2; 68.690 - size = (size+align-1)&(~(align-1)); 68.691 - } 68.692 - 68.693 - /* Cal size (in pages) of slabs, and the num of objs per slab. 68.694 - * This could be made much more intelligent. For now, try to avoid 68.695 - * using high page-orders for slabs. When the gfp() funcs are more 68.696 - * friendly towards high-order requests, this should be changed. 68.697 - */ 68.698 - do { 68.699 - unsigned int break_flag = 0; 68.700 - cal_wastage: 68.701 - xmem_cache_estimate(cachep->gfporder, size, flags, 68.702 - &left_over, &cachep->num); 68.703 - if (break_flag) 68.704 - break; 68.705 - if (cachep->gfporder >= MAX_GFP_ORDER) 68.706 - break; 68.707 - if (!cachep->num) 68.708 - goto next; 68.709 - if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) { 68.710 - /* Oops, this num of objs will cause problems. */ 68.711 - cachep->gfporder--; 68.712 - break_flag++; 68.713 - goto cal_wastage; 68.714 - } 68.715 - 68.716 - /* 68.717 - * Large num of objs is good, but v. large slabs are currently 68.718 - * bad for the gfp()s. 68.719 - */ 68.720 - if (cachep->gfporder >= slab_break_gfp_order) 68.721 - break; 68.722 - 68.723 - if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder)) 68.724 - break; /* Acceptable internal fragmentation. */ 68.725 - next: 68.726 - cachep->gfporder++; 68.727 - } while (1); 68.728 - 68.729 - if (!cachep->num) { 68.730 - printk("xmem_cache_create: couldn't create cache %s.\n", name); 68.731 - xmem_cache_free(&cache_cache, cachep); 68.732 - cachep = NULL; 68.733 - goto opps; 68.734 - } 68.735 - slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(xmem_bufctl_t) + 68.736 - sizeof(slab_t)); 68.737 - 68.738 - /* 68.739 - * If the slab has been placed off-slab, and we have enough space then 68.740 - * move it on-slab. This is at the expense of any extra colouring. 68.741 - */ 68.742 - if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) { 68.743 - flags &= ~CFLGS_OFF_SLAB; 68.744 - left_over -= slab_size; 68.745 - } 68.746 - 68.747 - /* Offset must be a multiple of the alignment. */ 68.748 - offset += (align-1); 68.749 - offset &= ~(align-1); 68.750 - if (!offset) 68.751 - offset = L1_CACHE_BYTES; 68.752 - cachep->colour_off = offset; 68.753 - cachep->colour = left_over/offset; 68.754 - 68.755 - /* init remaining fields */ 68.756 - if (!cachep->gfporder && !(flags & CFLGS_OFF_SLAB)) 68.757 - flags |= CFLGS_OPTIMIZE; 68.758 - 68.759 - cachep->flags = flags; 68.760 - spin_lock_init(&cachep->spinlock); 68.761 - cachep->objsize = size; 68.762 - INIT_LIST_HEAD(&cachep->slabs_full); 68.763 - INIT_LIST_HEAD(&cachep->slabs_partial); 68.764 - INIT_LIST_HEAD(&cachep->slabs_free); 68.765 - 68.766 - if (flags & CFLGS_OFF_SLAB) 68.767 - cachep->slabp_cache = xmem_find_general_cachep(slab_size); 68.768 - cachep->ctor = ctor; 68.769 - cachep->dtor = dtor; 68.770 - /* Copy name over so we don't have problems with unloaded modules */ 68.771 - strcpy(cachep->name, name); 68.772 - 68.773 -#ifdef CONFIG_SMP 68.774 - if (g_cpucache_up) 68.775 - enable_cpucache(cachep); 68.776 -#endif 68.777 - /* Need the semaphore to access the chain. */ 68.778 - down(&cache_chain_sem); 68.779 - { 68.780 - xmem_cache_t *pc; 68.781 - 68.782 - list_for_each_entry(pc, &cache_chain, next) { 68.783 - /* The name field is constant - no lock needed. */ 68.784 - if (!strcmp(pc->name, name)) 68.785 - BUG(); 68.786 - } 68.787 - } 68.788 - 68.789 - /* There is no reason to lock our new cache before we 68.790 - * link it in - no one knows about it yet... 68.791 - */ 68.792 - list_add(&cachep->next, &cache_chain); 68.793 - up(&cache_chain_sem); 68.794 - opps: 68.795 - return cachep; 68.796 -} 68.797 - 68.798 - 68.799 -#if DEBUG 68.800 -/* 68.801 - * This check if the xmem_cache_t pointer is chained in the cache_cache 68.802 - * list. -arca 68.803 - */ 68.804 -static int is_chained_xmem_cache(xmem_cache_t * cachep) 68.805 -{ 68.806 - xmem_cache_t *pc; 68.807 - int ret = 0; 68.808 - unsigned long spin_flags; 68.809 - 68.810 - /* Find the cache in the chain of caches. */ 68.811 - down(&cache_chain_sem); 68.812 - list_for_each_entry(pc, &cache_chain, next) { 68.813 - if (pc == &cachep) { 68.814 - ret = 1; 68.815 - break; 68.816 - } 68.817 - } 68.818 - up(&cache_chain_sem); 68.819 - 68.820 - return ret; 68.821 -} 68.822 -#else 68.823 -#define is_chained_xmem_cache(x) 1 68.824 -#endif 68.825 - 68.826 -#ifdef CONFIG_SMP 68.827 -/* 68.828 - * Waits for all CPUs to execute func(). 68.829 - */ 68.830 -static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg) 68.831 -{ 68.832 - local_irq_disable(); 68.833 - func(arg); 68.834 - local_irq_enable(); 68.835 - 68.836 - if (smp_call_function(func, arg, 1, 1)) 68.837 - BUG(); 68.838 -} 68.839 -typedef struct ccupdate_struct_s 68.840 -{ 68.841 - xmem_cache_t *cachep; 68.842 - cpucache_t *new[NR_CPUS]; 68.843 -} ccupdate_struct_t; 68.844 - 68.845 -static void do_ccupdate_local(void *info) 68.846 -{ 68.847 - ccupdate_struct_t *new = (ccupdate_struct_t *)info; 68.848 - cpucache_t *old = cc_data(new->cachep); 68.849 - 68.850 - cc_data(new->cachep) = new->new[smp_processor_id()]; 68.851 - new->new[smp_processor_id()] = old; 68.852 -} 68.853 - 68.854 -static void free_block (xmem_cache_t* cachep, void** objpp, int len); 68.855 - 68.856 -static void drain_cpu_caches(xmem_cache_t *cachep) 68.857 -{ 68.858 - ccupdate_struct_t new; 68.859 - int i; 68.860 - unsigned long spin_flags; 68.861 - 68.862 - memset(&new.new,0,sizeof(new.new)); 68.863 - 68.864 - new.cachep = cachep; 68.865 - 68.866 - down(&cache_chain_sem); 68.867 - smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); 68.868 - 68.869 - for (i = 0; i < smp_num_cpus; i++) { 68.870 - cpucache_t* ccold = new.new[cpu_logical_map(i)]; 68.871 - if (!ccold || (ccold->avail == 0)) 68.872 - continue; 68.873 - local_irq_disable(); 68.874 - free_block(cachep, cc_entry(ccold), ccold->avail); 68.875 - local_irq_enable(); 68.876 - ccold->avail = 0; 68.877 - } 68.878 - smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); 68.879 - up(&cache_chain_sem); 68.880 -} 68.881 - 68.882 -#else 68.883 -#define drain_cpu_caches(cachep) do { } while (0) 68.884 -#endif 68.885 - 68.886 -static int __xmem_cache_shrink(xmem_cache_t *cachep) 68.887 -{ 68.888 - slab_t *slabp; 68.889 - int ret; 68.890 - 68.891 - drain_cpu_caches(cachep); 68.892 - 68.893 - spin_lock_irq(&cachep->spinlock); 68.894 - 68.895 - /* If the cache is growing, stop shrinking. */ 68.896 - while (!cachep->growing) { 68.897 - struct list_head *p; 68.898 - 68.899 - p = cachep->slabs_free.prev; 68.900 - if (p == &cachep->slabs_free) 68.901 - break; 68.902 - 68.903 - slabp = list_entry(cachep->slabs_free.prev, slab_t, list); 68.904 -#if DEBUG 68.905 - if (slabp->inuse) 68.906 - BUG(); 68.907 -#endif 68.908 - list_del(&slabp->list); 68.909 - 68.910 - spin_unlock_irq(&cachep->spinlock); 68.911 - xmem_slab_destroy(cachep, slabp); 68.912 - spin_lock_irq(&cachep->spinlock); 68.913 - } 68.914 - ret = (!list_empty(&cachep->slabs_full) || 68.915 - !list_empty(&cachep->slabs_partial)); 68.916 - spin_unlock_irq(&cachep->spinlock); 68.917 - return ret; 68.918 -} 68.919 - 68.920 -/** 68.921 - * xmem_cache_shrink - Shrink a cache. 68.922 - * @cachep: The cache to shrink. 68.923 - * 68.924 - * Releases as many slabs as possible for a cache. 68.925 - * To help debugging, a zero exit status indicates all slabs were released. 68.926 - */ 68.927 -int xmem_cache_shrink(xmem_cache_t *cachep) 68.928 -{ 68.929 - if (!cachep || !is_chained_xmem_cache(cachep)) 68.930 - BUG(); 68.931 - 68.932 - return __xmem_cache_shrink(cachep); 68.933 -} 68.934 - 68.935 -/** 68.936 - * xmem_cache_destroy - delete a cache 68.937 - * @cachep: the cache to destroy 68.938 - * 68.939 - * Remove a xmem_cache_t object from the slab cache. 68.940 - * Returns 0 on success. 68.941 - * 68.942 - * It is expected this function will be called by a module when it is 68.943 - * unloaded. This will remove the cache completely, and avoid a duplicate 68.944 - * cache being allocated each time a module is loaded and unloaded, if the 68.945 - * module doesn't have persistent in-kernel storage across loads and unloads. 68.946 - * 68.947 - * The caller must guarantee that noone will allocate memory from the cache 68.948 - * during the xmem_cache_destroy(). 68.949 - */ 68.950 -int xmem_cache_destroy (xmem_cache_t * cachep) 68.951 -{ 68.952 - unsigned long spin_flags; 68.953 - 68.954 - if (!cachep || cachep->growing) 68.955 - BUG(); 68.956 - 68.957 - /* Find the cache in the chain of caches. */ 68.958 - down(&cache_chain_sem); 68.959 - /* the chain is never empty, cache_cache is never destroyed */ 68.960 - if (clock_searchp == cachep) 68.961 - clock_searchp = list_entry(cachep->next.next, 68.962 - xmem_cache_t, next); 68.963 - list_del(&cachep->next); 68.964 - up(&cache_chain_sem); 68.965 - 68.966 - if (__xmem_cache_shrink(cachep)) { 68.967 - printk(KERN_ERR "xmem_cache_destroy: Can't free all objects %p\n", 68.968 - cachep); 68.969 - down(&cache_chain_sem); 68.970 - list_add(&cachep->next,&cache_chain); 68.971 - up(&cache_chain_sem); 68.972 - return 1; 68.973 - } 68.974 -#ifdef CONFIG_SMP 68.975 - { 68.976 - int i; 68.977 - for (i = 0; i < NR_CPUS; i++) 68.978 - xfree(cachep->cpudata[i]); 68.979 - } 68.980 -#endif 68.981 - xmem_cache_free(&cache_cache, cachep); 68.982 - 68.983 - return 0; 68.984 -} 68.985 - 68.986 -/* Get the memory for a slab management obj. */ 68.987 -static inline slab_t *xmem_cache_slabmgmt(xmem_cache_t *cachep, 68.988 - void *objp, int colour_off, 68.989 - int local_flags) 68.990 -{ 68.991 - slab_t *slabp; 68.992 - 68.993 - if (OFF_SLAB(cachep)) { 68.994 - /* Slab management obj is off-slab. */ 68.995 - slabp = xmem_cache_alloc(cachep->slabp_cache); 68.996 - if (!slabp) 68.997 - return NULL; 68.998 - } else { 68.999 - /* FIXME: change to 68.1000 - slabp = objp 68.1001 - * if you enable OPTIMIZE 68.1002 - */ 68.1003 - slabp = objp+colour_off; 68.1004 - colour_off += L1_CACHE_ALIGN(cachep->num * 68.1005 - sizeof(xmem_bufctl_t) + sizeof(slab_t)); 68.1006 - } 68.1007 - slabp->inuse = 0; 68.1008 - slabp->colouroff = colour_off; 68.1009 - slabp->s_mem = objp+colour_off; 68.1010 - 68.1011 - return slabp; 68.1012 -} 68.1013 - 68.1014 -static inline void xmem_cache_init_objs(xmem_cache_t *cachep, 68.1015 - slab_t *slabp, 68.1016 - unsigned long ctor_flags) 68.1017 -{ 68.1018 - int i; 68.1019 - 68.1020 - for (i = 0; i < cachep->num; i++) { 68.1021 - void* objp = slabp->s_mem+cachep->objsize*i; 68.1022 -#if DEBUG 68.1023 - if (cachep->flags & SLAB_RED_ZONE) { 68.1024 - *((unsigned long*)(objp)) = RED_MAGIC1; 68.1025 - *((unsigned long*)(objp + cachep->objsize - 68.1026 - BYTES_PER_WORD)) = RED_MAGIC1; 68.1027 - objp += BYTES_PER_WORD; 68.1028 - } 68.1029 -#endif 68.1030 - 68.1031 - /* 68.1032 - * Constructors are not allowed to allocate memory from 68.1033 - * the same cache which they are a constructor for. 68.1034 - * Otherwise, deadlock. They must also be threaded. 68.1035 - */ 68.1036 - if (cachep->ctor) 68.1037 - cachep->ctor(objp, cachep, ctor_flags); 68.1038 -#if DEBUG 68.1039 - if (cachep->flags & SLAB_RED_ZONE) 68.1040 - objp -= BYTES_PER_WORD; 68.1041 - if (cachep->flags & SLAB_POISON) 68.1042 - /* need to poison the objs */ 68.1043 - xmem_poison_obj(cachep, objp); 68.1044 - if (cachep->flags & SLAB_RED_ZONE) { 68.1045 - if (*((unsigned long*)(objp)) != RED_MAGIC1) 68.1046 - BUG(); 68.1047 - if (*((unsigned long*)(objp + cachep->objsize - 68.1048 - BYTES_PER_WORD)) != RED_MAGIC1) 68.1049 - BUG(); 68.1050 - } 68.1051 -#endif 68.1052 - slab_bufctl(slabp)[i] = i+1; 68.1053 - } 68.1054 - slab_bufctl(slabp)[i-1] = BUFCTL_END; 68.1055 - slabp->free = 0; 68.1056 -} 68.1057 - 68.1058 -/* 68.1059 - * Grow (by 1) the number of slabs within a cache. This is called by 68.1060 - * xmem_cache_alloc() when there are no active objs left in a cache. 68.1061 - */ 68.1062 -static int xmem_cache_grow(xmem_cache_t * cachep) 68.1063 -{ 68.1064 - slab_t *slabp; 68.1065 - struct pfn_info *page; unsigned int i; 68.1066 - void *objp; 68.1067 - size_t offset; 68.1068 - unsigned long ctor_flags; 68.1069 - unsigned long save_flags; 68.1070 - 68.1071 - ctor_flags = SLAB_CTOR_CONSTRUCTOR; 68.1072 - 68.1073 - /* About to mess with non-constant members - lock. */ 68.1074 - spin_lock_irqsave(&cachep->spinlock, save_flags); 68.1075 - 68.1076 - /* Get colour for the slab, and cal the next value. */ 68.1077 - offset = cachep->colour_next; 68.1078 - cachep->colour_next++; 68.1079 - if (cachep->colour_next >= cachep->colour) 68.1080 - cachep->colour_next = 0; 68.1081 - offset *= cachep->colour_off; 68.1082 - cachep->dflags |= DFLGS_GROWN; 68.1083 - 68.1084 - cachep->growing++; 68.1085 - spin_unlock_irqrestore(&cachep->spinlock, save_flags); 68.1086 - 68.1087 - /* A series of memory allocations for a new slab. 68.1088 - * Neither the cache-chain semaphore, or cache-lock, are 68.1089 - * held, but the incrementing c_growing prevents this 68.1090 - * cache from being reaped or shrunk. 68.1091 - * Note: The cache could be selected in for reaping in 68.1092 - * xmem_cache_reap(), but when the final test is made the 68.1093 - * growing value will be seen. 68.1094 - */ 68.1095 - 68.1096 - /* Get mem for the objs. */ 68.1097 - if (!(objp = xmem_getpages(cachep))) 68.1098 - goto failed; 68.1099 - 68.1100 - /* Get slab management. */ 68.1101 - if (!(slabp = xmem_cache_slabmgmt(cachep, objp, offset, 0))) 68.1102 - goto opps1; 68.1103 - 68.1104 - /* Nasty!!!!!! I hope this is OK. */ 68.1105 - i = 1 << cachep->gfporder; 68.1106 - page = virt_to_page(objp); 68.1107 - do { 68.1108 - SET_PAGE_CACHE(page, cachep); 68.1109 - SET_PAGE_SLAB(page, slabp); 68.1110 - PageSetSlab(page); 68.1111 - page++; 68.1112 - } while (--i); 68.1113 - 68.1114 - xmem_cache_init_objs(cachep, slabp, ctor_flags); 68.1115 - 68.1116 - spin_lock_irqsave(&cachep->spinlock, save_flags); 68.1117 - cachep->growing--; 68.1118 - 68.1119 - /* Make slab active. */ 68.1120 - list_add_tail(&slabp->list, &cachep->slabs_free); 68.1121 - STATS_INC_GROWN(cachep); 68.1122 - cachep->failures = 0; 68.1123 - 68.1124 - spin_unlock_irqrestore(&cachep->spinlock, save_flags); 68.1125 - return 1; 68.1126 - opps1: 68.1127 - xmem_freepages(cachep, objp); 68.1128 - failed: 68.1129 - spin_lock_irqsave(&cachep->spinlock, save_flags); 68.1130 - cachep->growing--; 68.1131 - spin_unlock_irqrestore(&cachep->spinlock, save_flags); 68.1132 - return 0; 68.1133 -} 68.1134 - 68.1135 -/* 68.1136 - * Perform extra freeing checks: 68.1137 - * - detect double free 68.1138 - * - detect bad pointers. 68.1139 - * Called with the cache-lock held. 68.1140 - */ 68.1141 - 68.1142 -#if DEBUG 68.1143 -static int xmem_extra_free_checks (xmem_cache_t * cachep, 68.1144 - slab_t *slabp, void * objp) 68.1145 -{ 68.1146 - int i; 68.1147 - unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize; 68.1148 - 68.1149 - if (objnr >= cachep->num) 68.1150 - BUG(); 68.1151 - if (objp != slabp->s_mem + objnr*cachep->objsize) 68.1152 - BUG(); 68.1153 - 68.1154 - /* Check slab's freelist to see if this obj is there. */ 68.1155 - for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { 68.1156 - if (i == objnr) 68.1157 - BUG(); 68.1158 - } 68.1159 - return 0; 68.1160 -} 68.1161 -#endif 68.1162 - 68.1163 -static inline void * xmem_cache_alloc_one_tail (xmem_cache_t *cachep, 68.1164 - slab_t *slabp) 68.1165 -{ 68.1166 - void *objp; 68.1167 - 68.1168 - STATS_INC_ALLOCED(cachep); 68.1169 - STATS_INC_ACTIVE(cachep); 68.1170 - STATS_SET_HIGH(cachep); 68.1171 - 68.1172 - /* get obj pointer */ 68.1173 - slabp->inuse++; 68.1174 - objp = slabp->s_mem + slabp->free*cachep->objsize; 68.1175 - slabp->free=slab_bufctl(slabp)[slabp->free]; 68.1176 - 68.1177 - if (unlikely(slabp->free == BUFCTL_END)) { 68.1178 - list_del(&slabp->list); 68.1179 - list_add(&slabp->list, &cachep->slabs_full); 68.1180 - } 68.1181 -#if DEBUG 68.1182 - if (cachep->flags & SLAB_POISON) 68.1183 - if (xmem_check_poison_obj(cachep, objp)) 68.1184 - BUG(); 68.1185 - if (cachep->flags & SLAB_RED_ZONE) { 68.1186 - /* Set alloc red-zone, and check old one. */ 68.1187 - if (xchg((unsigned long *)objp, RED_MAGIC2) != 68.1188 - RED_MAGIC1) 68.1189 - BUG(); 68.1190 - if (xchg((unsigned long *)(objp+cachep->objsize - 68.1191 - BYTES_PER_WORD), RED_MAGIC2) != RED_MAGIC1) 68.1192 - BUG(); 68.1193 - objp += BYTES_PER_WORD; 68.1194 - } 68.1195 -#endif 68.1196 - return objp; 68.1197 -} 68.1198 - 68.1199 -/* 68.1200 - * Returns a ptr to an obj in the given cache. 68.1201 - * caller must guarantee synchronization 68.1202 - * #define for the goto optimization 8-) 68.1203 - */ 68.1204 -#define xmem_cache_alloc_one(cachep) \ 68.1205 -({ \ 68.1206 - struct list_head * slabs_partial, * entry; \ 68.1207 - slab_t *slabp; \ 68.1208 - \ 68.1209 - slabs_partial = &(cachep)->slabs_partial; \ 68.1210 - entry = slabs_partial->next; \ 68.1211 - if (unlikely(entry == slabs_partial)) { \ 68.1212 - struct list_head * slabs_free; \ 68.1213 - slabs_free = &(cachep)->slabs_free; \ 68.1214 - entry = slabs_free->next; \ 68.1215 - if (unlikely(entry == slabs_free)) \ 68.1216 - goto alloc_new_slab; \ 68.1217 - list_del(entry); \ 68.1218 - list_add(entry, slabs_partial); \ 68.1219 - } \ 68.1220 - \ 68.1221 - slabp = list_entry(entry, slab_t, list); \ 68.1222 - xmem_cache_alloc_one_tail(cachep, slabp); \ 68.1223 -}) 68.1224 - 68.1225 -#ifdef CONFIG_SMP 68.1226 -void* xmem_cache_alloc_batch(xmem_cache_t* cachep) 68.1227 -{ 68.1228 - int batchcount = cachep->batchcount; 68.1229 - cpucache_t* cc = cc_data(cachep); 68.1230 - 68.1231 - spin_lock(&cachep->spinlock); 68.1232 - while (batchcount--) { 68.1233 - struct list_head * slabs_partial, * entry; 68.1234 - slab_t *slabp; 68.1235 - /* Get slab alloc is to come from. */ 68.1236 - slabs_partial = &(cachep)->slabs_partial; 68.1237 - entry = slabs_partial->next; 68.1238 - if (unlikely(entry == slabs_partial)) { 68.1239 - struct list_head * slabs_free; 68.1240 - slabs_free = &(cachep)->slabs_free; 68.1241 - entry = slabs_free->next; 68.1242 - if (unlikely(entry == slabs_free)) 68.1243 - break; 68.1244 - list_del(entry); 68.1245 - list_add(entry, slabs_partial); 68.1246 - } 68.1247 - 68.1248 - slabp = list_entry(entry, slab_t, list); 68.1249 - cc_entry(cc)[cc->avail++] = 68.1250 - xmem_cache_alloc_one_tail(cachep, slabp); 68.1251 - } 68.1252 - spin_unlock(&cachep->spinlock); 68.1253 - 68.1254 - if (cc->avail) 68.1255 - return cc_entry(cc)[--cc->avail]; 68.1256 - return NULL; 68.1257 -} 68.1258 -#endif 68.1259 - 68.1260 -static inline void *__xmem_cache_alloc(xmem_cache_t *cachep) 68.1261 -{ 68.1262 - unsigned long flags; 68.1263 - void* objp; 68.1264 - 68.1265 - try_again: 68.1266 - local_irq_save(flags); 68.1267 -#ifdef CONFIG_SMP 68.1268 - { 68.1269 - cpucache_t *cc = cc_data(cachep); 68.1270 - 68.1271 - if (cc) { 68.1272 - if (cc->avail) { 68.1273 - STATS_INC_ALLOCHIT(cachep); 68.1274 - objp = cc_entry(cc)[--cc->avail]; 68.1275 - } else { 68.1276 - STATS_INC_ALLOCMISS(cachep); 68.1277 - objp = xmem_cache_alloc_batch(cachep); 68.1278 - if (!objp) 68.1279 - goto alloc_new_slab_nolock; 68.1280 - } 68.1281 - } else { 68.1282 - spin_lock(&cachep->spinlock); 68.1283 - objp = xmem_cache_alloc_one(cachep); 68.1284 - spin_unlock(&cachep->spinlock); 68.1285 - } 68.1286 - } 68.1287 -#else 68.1288 - objp = xmem_cache_alloc_one(cachep); 68.1289 -#endif 68.1290 - local_irq_restore(flags); 68.1291 - return objp; 68.1292 - alloc_new_slab: 68.1293 -#ifdef CONFIG_SMP 68.1294 - spin_unlock(&cachep->spinlock); 68.1295 - alloc_new_slab_nolock: 68.1296 -#endif 68.1297 - local_irq_restore(flags); 68.1298 - if (xmem_cache_grow(cachep)) 68.1299 - /* Someone may have stolen our objs. Doesn't matter, we'll 68.1300 - * just come back here again. 68.1301 - */ 68.1302 - goto try_again; 68.1303 - return NULL; 68.1304 -} 68.1305 - 68.1306 -/* 68.1307 - * Release an obj back to its cache. If the obj has a constructed 68.1308 - * state, it should be in this state _before_ it is released. 68.1309 - * - caller is responsible for the synchronization 68.1310 - */ 68.1311 - 68.1312 -#if DEBUG 68.1313 -# define CHECK_NR(pg) \ 68.1314 - do { \ 68.1315 - if (!VALID_PAGE(pg)) { \ 68.1316 - printk(KERN_ERR "xfree: out of range ptr %lxh.\n", \ 68.1317 - (unsigned long)objp); \ 68.1318 - BUG(); \ 68.1319 - } \ 68.1320 - } while (0) 68.1321 -# define CHECK_PAGE(page) \ 68.1322 - do { \ 68.1323 - CHECK_NR(page); \ 68.1324 - if (!PageSlab(page)) { \ 68.1325 - printk(KERN_ERR "xfree: bad ptr %lxh.\n", \ 68.1326 - (unsigned long)objp); \ 68.1327 - BUG(); \ 68.1328 - } \ 68.1329 - } while (0) 68.1330 - 68.1331 -#else 68.1332 -# define CHECK_PAGE(pg) do { } while (0) 68.1333 -#endif 68.1334 - 68.1335 -static inline void xmem_cache_free_one(xmem_cache_t *cachep, void *objp) 68.1336 -{ 68.1337 - slab_t* slabp; 68.1338 - 68.1339 - CHECK_PAGE(virt_to_page(objp)); 68.1340 - /* reduces memory footprint 68.1341 - * 68.1342 - if (OPTIMIZE(cachep)) 68.1343 - slabp = (void*)((unsigned long)objp&(~(PAGE_SIZE-1))); 68.1344 - else 68.1345 - */ 68.1346 - slabp = GET_PAGE_SLAB(virt_to_page(objp)); 68.1347 - 68.1348 -#if DEBUG 68.1349 - if (cachep->flags & SLAB_DEBUG_INITIAL) 68.1350 - /* Need to call the slab's constructor so the 68.1351 - * caller can perform a verify of its state (debugging). 68.1352 - * Called without the cache-lock held. 68.1353 - */ 68.1354 - cachep->ctor(objp, cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY); 68.1355 - 68.1356 - if (cachep->flags & SLAB_RED_ZONE) { 68.1357 - objp -= BYTES_PER_WORD; 68.1358 - if (xchg((unsigned long *)objp, RED_MAGIC1) != RED_MAGIC2) 68.1359 - /* Either write before start, or a double free. */ 68.1360 - BUG(); 68.1361 - if (xchg((unsigned long *)(objp+cachep->objsize - 68.1362 - BYTES_PER_WORD), RED_MAGIC1) != RED_MAGIC2) 68.1363 - /* Either write past end, or a double free. */ 68.1364 - BUG(); 68.1365 - } 68.1366 - if (cachep->flags & SLAB_POISON) 68.1367 - xmem_poison_obj(cachep, objp); 68.1368 - if (xmem_extra_free_checks(cachep, slabp, objp)) 68.1369 - return; 68.1370 -#endif 68.1371 - { 68.1372 - unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize; 68.1373 - 68.1374 - slab_bufctl(slabp)[objnr] = slabp->free; 68.1375 - slabp->free = objnr; 68.1376 - } 68.1377 - STATS_DEC_ACTIVE(cachep); 68.1378 - 68.1379 - /* fixup slab chains */ 68.1380 - { 68.1381 - int inuse = slabp->inuse; 68.1382 - if (unlikely(!--slabp->inuse)) { 68.1383 - /* Was partial or full, now empty. */ 68.1384 - list_del(&slabp->list); 68.1385 - list_add(&slabp->list, &cachep->slabs_free); 68.1386 - } else if (unlikely(inuse == cachep->num)) { 68.1387 - /* Was full. */ 68.1388 - list_del(&slabp->list); 68.1389 - list_add(&slabp->list, &cachep->slabs_partial); 68.1390 - } 68.1391 - } 68.1392 -} 68.1393 - 68.1394 -#ifdef CONFIG_SMP 68.1395 -static inline void __free_block (xmem_cache_t* cachep, 68.1396 - void** objpp, int len) 68.1397 -{ 68.1398 - for ( ; len > 0; len--, objpp++) 68.1399 - xmem_cache_free_one(cachep, *objpp); 68.1400 -} 68.1401 - 68.1402 -static void free_block (xmem_cache_t* cachep, void** objpp, int len) 68.1403 -{ 68.1404 - spin_lock(&cachep->spinlock); 68.1405 - __free_block(cachep, objpp, len); 68.1406 - spin_unlock(&cachep->spinlock); 68.1407 -} 68.1408 -#endif 68.1409 - 68.1410 -/* 68.1411 - * __xmem_cache_free 68.1412 - * called with disabled ints 68.1413 - */ 68.1414 -static inline void __xmem_cache_free (xmem_cache_t *cachep, void* objp) 68.1415 -{ 68.1416 -#ifdef CONFIG_SMP 68.1417 - cpucache_t *cc = cc_data(cachep); 68.1418 - 68.1419 - CHECK_PAGE(virt_to_page(objp)); 68.1420 - if (cc) { 68.1421 - int batchcount; 68.1422 - if (cc->avail < cc->limit) { 68.1423 - STATS_INC_FREEHIT(cachep); 68.1424 - cc_entry(cc)[cc->avail++] = objp; 68.1425 - return; 68.1426 - } 68.1427 - STATS_INC_FREEMISS(cachep); 68.1428 - batchcount = cachep->batchcount; 68.1429 - cc->avail -= batchcount; 68.1430 - free_block(cachep, 68.1431 - &cc_entry(cc)[cc->avail],batchcount); 68.1432 - cc_entry(cc)[cc->avail++] = objp; 68.1433 - return; 68.1434 - } else { 68.1435 - free_block(cachep, &objp, 1); 68.1436 - } 68.1437 -#else 68.1438 - xmem_cache_free_one(cachep, objp); 68.1439 -#endif 68.1440 -} 68.1441 - 68.1442 -/** 68.1443 - * xmem_cache_alloc - Allocate an object 68.1444 - * @cachep: The cache to allocate from. 68.1445 - * 68.1446 - * Allocate an object from this cache. The flags are only relevant 68.1447 - * if the cache has no available objects. 68.1448 - */ 68.1449 -void *xmem_cache_alloc(xmem_cache_t *cachep) 68.1450 -{ 68.1451 - return __xmem_cache_alloc(cachep); 68.1452 -} 68.1453 - 68.1454 -/** 68.1455 - * _xmalloc - allocate memory 68.1456 - * @size: how many bytes of memory are required. 68.1457 - */ 68.1458 -void *_xmalloc(size_t size) 68.1459 -{ 68.1460 - cache_sizes_t *csizep = cache_sizes; 68.1461 - 68.1462 - for (; csizep->cs_size; csizep++) { 68.1463 - if (size > csizep->cs_size) 68.1464 - continue; 68.1465 - return __xmem_cache_alloc(csizep->cs_cachep); 68.1466 - } 68.1467 - return NULL; 68.1468 -} 68.1469 - 68.1470 -/** 68.1471 - * xmem_cache_free - Deallocate an object 68.1472 - * @cachep: The cache the allocation was from. 68.1473 - * @objp: The previously allocated object. 68.1474 - * 68.1475 - * Free an object which was previously allocated from this 68.1476 - * cache. 68.1477 - */ 68.1478 -void xmem_cache_free (xmem_cache_t *cachep, void *objp) 68.1479 -{ 68.1480 - unsigned long flags; 68.1481 -#if DEBUG 68.1482 - CHECK_PAGE(virt_to_page(objp)); 68.1483 - if (cachep != GET_PAGE_CACHE(virt_to_page(objp))) 68.1484 - BUG(); 68.1485 -#endif 68.1486 - 68.1487 - local_irq_save(flags); 68.1488 - __xmem_cache_free(cachep, objp); 68.1489 - local_irq_restore(flags); 68.1490 -} 68.1491 - 68.1492 -/** 68.1493 - * xfree - free previously allocated memory 68.1494 - * @objp: pointer returned by xmalloc. 68.1495 - * 68.1496 - * Don't free memory not originally allocated by xmalloc() 68.1497 - * or you will run into trouble. 68.1498 - */ 68.1499 -void xfree (const void *objp) 68.1500 -{ 68.1501 - xmem_cache_t *c; 68.1502 - unsigned long flags; 68.1503 - 68.1504 - if (!objp) 68.1505 - return; 68.1506 - local_irq_save(flags); 68.1507 - CHECK_PAGE(virt_to_page(objp)); 68.1508 - c = GET_PAGE_CACHE(virt_to_page(objp)); 68.1509 - __xmem_cache_free(c, (void*)objp); 68.1510 - local_irq_restore(flags); 68.1511 -} 68.1512 - 68.1513 -xmem_cache_t *xmem_find_general_cachep(size_t size) 68.1514 -{ 68.1515 - cache_sizes_t *csizep = cache_sizes; 68.1516 - 68.1517 - /* This function could be moved to the header file, and 68.1518 - * made inline so consumers can quickly determine what 68.1519 - * cache pointer they require. 68.1520 - */ 68.1521 - for ( ; csizep->cs_size; csizep++) { 68.1522 - if (size > csizep->cs_size) 68.1523 - continue; 68.1524 - break; 68.1525 - } 68.1526 - return csizep->cs_cachep; 68.1527 -} 68.1528 - 68.1529 -#ifdef CONFIG_SMP 68.1530 - 68.1531 -/* called with cache_chain_sem acquired. */ 68.1532 -static int xmem_tune_cpucache (xmem_cache_t* cachep, int limit, int batchcount) 68.1533 -{ 68.1534 - ccupdate_struct_t new; 68.1535 - int i; 68.1536 - 68.1537 - /* 68.1538 - * These are admin-provided, so we are more graceful. 68.1539 - */ 68.1540 - if (limit < 0) 68.1541 - return -EINVAL; 68.1542 - if (batchcount < 0) 68.1543 - return -EINVAL; 68.1544 - if (batchcount > limit) 68.1545 - return -EINVAL; 68.1546 - if (limit != 0 && !batchcount) 68.1547 - return -EINVAL; 68.1548 - 68.1549 - memset(&new.new,0,sizeof(new.new)); 68.1550 - if (limit) { 68.1551 - for (i = 0; i< smp_num_cpus; i++) { 68.1552 - cpucache_t* ccnew; 68.1553 - 68.1554 - ccnew = _xmalloc(sizeof(void*)*limit+sizeof(cpucache_t)); 68.1555 - if (!ccnew) 68.1556 - goto oom; 68.1557 - ccnew->limit = limit; 68.1558 - ccnew->avail = 0; 68.1559 - new.new[cpu_logical_map(i)] = ccnew; 68.1560 - } 68.1561 - } 68.1562 - new.cachep = cachep; 68.1563 - spin_lock_irq(&cachep->spinlock); 68.1564 - cachep->batchcount = batchcount; 68.1565 - spin_unlock_irq(&cachep->spinlock); 68.1566 - 68.1567 - smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); 68.1568 - 68.1569 - for (i = 0; i < smp_num_cpus; i++) { 68.1570 - cpucache_t* ccold = new.new[cpu_logical_map(i)]; 68.1571 - if (!ccold) 68.1572 - continue; 68.1573 - local_irq_disable(); 68.1574 - free_block(cachep, cc_entry(ccold), ccold->avail); 68.1575 - local_irq_enable(); 68.1576 - xfree(ccold); 68.1577 - } 68.1578 - return 0; 68.1579 - oom: 68.1580 - for (i--; i >= 0; i--) 68.1581 - xfree(new.new[cpu_logical_map(i)]); 68.1582 - return -ENOMEM; 68.1583 -} 68.1584 - 68.1585 -static void enable_cpucache (xmem_cache_t *cachep) 68.1586 -{ 68.1587 - int err; 68.1588 - int limit; 68.1589 - 68.1590 - /* FIXME: optimize */ 68.1591 - if (cachep->objsize > PAGE_SIZE) 68.1592 - return; 68.1593 - if (cachep->objsize > 1024) 68.1594 - limit = 60; 68.1595 - else if (cachep->objsize > 256) 68.1596 - limit = 124; 68.1597 - else 68.1598 - limit = 252; 68.1599 - 68.1600 - err = xmem_tune_cpucache(cachep, limit, limit/2); 68.1601 - if (err) 68.1602 - printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n", 68.1603 - cachep->name, -err); 68.1604 -} 68.1605 - 68.1606 -static void enable_all_cpucaches (void) 68.1607 -{ 68.1608 - struct list_head* p; 68.1609 - unsigned long spin_flags; 68.1610 - 68.1611 - down(&cache_chain_sem); 68.1612 - 68.1613 - p = &cache_cache.next; 68.1614 - do { 68.1615 - xmem_cache_t* cachep = list_entry(p, xmem_cache_t, next); 68.1616 - 68.1617 - enable_cpucache(cachep); 68.1618 - p = cachep->next.next; 68.1619 - } while (p != &cache_cache.next); 68.1620 - 68.1621 - up(&cache_chain_sem); 68.1622 -} 68.1623 -#endif 68.1624 - 68.1625 -/** 68.1626 - * xmem_cache_reap - Reclaim memory from caches. 68.1627 - */ 68.1628 -int xmem_cache_reap(void) 68.1629 -{ 68.1630 - slab_t *slabp; 68.1631 - xmem_cache_t *searchp; 68.1632 - xmem_cache_t *best_cachep; 68.1633 - unsigned int best_pages; 68.1634 - unsigned int best_len; 68.1635 - unsigned int scan; 68.1636 - int ret = 0; 68.1637 - unsigned long spin_flags; 68.1638 - 68.1639 - down(&cache_chain_sem); 68.1640 - 68.1641 - scan = REAP_SCANLEN; 68.1642 - best_len = 0; 68.1643 - best_pages = 0; 68.1644 - best_cachep = NULL; 68.1645 - searchp = clock_searchp; 68.1646 - do { 68.1647 - unsigned int pages; 68.1648 - struct list_head* p; 68.1649 - unsigned int full_free; 68.1650 - 68.1651 - /* It's safe to test this without holding the cache-lock. */ 68.1652 - if (searchp->flags & SLAB_NO_REAP) 68.1653 - goto next; 68.1654 - spin_lock_irq(&searchp->spinlock); 68.1655 - if (searchp->growing) 68.1656 - goto next_unlock; 68.1657 - if (searchp->dflags & DFLGS_GROWN) { 68.1658 - searchp->dflags &= ~DFLGS_GROWN; 68.1659 - goto next_unlock; 68.1660 - } 68.1661 -#ifdef CONFIG_SMP 68.1662 - { 68.1663 - cpucache_t *cc = cc_data(searchp); 68.1664 - if (cc && cc->avail) { 68.1665 - __free_block(searchp, cc_entry(cc), cc->avail); 68.1666 - cc->avail = 0; 68.1667 - } 68.1668 - } 68.1669 -#endif 68.1670 - 68.1671 - full_free = 0; 68.1672 - p = searchp->slabs_free.next; 68.1673 - while (p != &searchp->slabs_free) { 68.1674 - slabp = list_entry(p, slab_t, list); 68.1675 -#if DEBUG 68.1676 - if (slabp->inuse) 68.1677 - BUG(); 68.1678 -#endif 68.1679 - full_free++; 68.1680 - p = p->next; 68.1681 - } 68.1682 - 68.1683 - /* 68.1684 - * Try to avoid slabs with constructors and/or 68.1685 - * more than one page per slab (as it can be difficult 68.1686 - * to get high orders from gfp()). 68.1687 - */ 68.1688 - pages = full_free * (1<<searchp->gfporder); 68.1689 - if (searchp->ctor) 68.1690 - pages = (pages*4+1)/5; 68.1691 - if (searchp->gfporder) 68.1692 - pages = (pages*4+1)/5; 68.1693 - if (pages > best_pages) { 68.1694 - best_cachep = searchp; 68.1695 - best_len = full_free; 68.1696 - best_pages = pages; 68.1697 - if (pages >= REAP_PERFECT) { 68.1698 - clock_searchp = list_entry(searchp->next.next, 68.1699 - xmem_cache_t,next); 68.1700 - goto perfect; 68.1701 - } 68.1702 - } 68.1703 - next_unlock: 68.1704 - spin_unlock_irq(&searchp->spinlock); 68.1705 - next: 68.1706 - searchp = list_entry(searchp->next.next,xmem_cache_t,next); 68.1707 - } while (--scan && searchp != clock_searchp); 68.1708 - 68.1709 - clock_searchp = searchp; 68.1710 - 68.1711 - if (!best_cachep) 68.1712 - /* couldn't find anything to reap */ 68.1713 - goto out; 68.1714 - 68.1715 - spin_lock_irq(&best_cachep->spinlock); 68.1716 - perfect: 68.1717 - /* free only 50% of the free slabs */ 68.1718 - best_len = (best_len + 1)/2; 68.1719 - for (scan = 0; scan < best_len; scan++) { 68.1720 - struct list_head *p; 68.1721 - 68.1722 - if (best_cachep->growing) 68.1723 - break; 68.1724 - p = best_cachep->slabs_free.prev; 68.1725 - if (p == &best_cachep->slabs_free) 68.1726 - break; 68.1727 - slabp = list_entry(p,slab_t,list); 68.1728 -#if DEBUG 68.1729 - if (slabp->inuse) 68.1730 - BUG(); 68.1731 -#endif 68.1732 - list_del(&slabp->list); 68.1733 - STATS_INC_REAPED(best_cachep); 68.1734 - 68.1735 - /* Safe to drop the lock. The slab is no longer linked to the 68.1736 - * cache. 68.1737 - */ 68.1738 - spin_unlock_irq(&best_cachep->spinlock); 68.1739 - xmem_slab_destroy(best_cachep, slabp); 68.1740 - spin_lock_irq(&best_cachep->spinlock); 68.1741 - } 68.1742 - spin_unlock_irq(&best_cachep->spinlock); 68.1743 - ret = scan * (1 << best_cachep->gfporder); 68.1744 - out: 68.1745 - up(&cache_chain_sem); 68.1746 - return ret; 68.1747 -} 68.1748 - 68.1749 -void dump_slabinfo() 68.1750 -{ 68.1751 - struct list_head *p; 68.1752 - unsigned long spin_flags; 68.1753 - 68.1754 - /* Output format version, so at least we can change it without _too_ 68.1755 - * many complaints. 68.1756 - */ 68.1757 - printk( "slabinfo - version: 1.1" 68.1758 -#if STATS 68.1759 - " (statistics)" 68.1760 -#endif 68.1761 -#ifdef CONFIG_SMP 68.1762 - " (SMP)" 68.1763 -#endif 68.1764 - "\n"); 68.1765 - down(&cache_chain_sem); 68.1766 - p = &cache_cache.next; 68.1767 - do { 68.1768 - xmem_cache_t *cachep; 68.1769 - slab_t *slabp; 68.1770 - unsigned long active_objs; 68.1771 - unsigned long num_objs; 68.1772 - unsigned long active_slabs = 0; 68.1773 - unsigned long num_slabs; 68.1774 - cachep = list_entry(p, xmem_cache_t, next); 68.1775 - 68.1776 - spin_lock_irq(&cachep->spinlock); 68.1777 - active_objs = 0; 68.1778 - num_slabs = 0; 68.1779 - list_for_each_entry(slabp, &cachep->slabs_full, list) { 68.1780 - if (slabp->inuse != cachep->num) 68.1781 - BUG(); 68.1782 - active_objs += cachep->num; 68.1783 - active_slabs++; 68.1784 - } 68.1785 - list_for_each_entry(slabp, &cachep->slabs_partial, list) { 68.1786 - if (slabp->inuse == cachep->num || !slabp->inuse) 68.1787 - BUG(); 68.1788 - active_objs += slabp->inuse; 68.1789 - active_slabs++; 68.1790 - } 68.1791 - list_for_each_entry(slabp, &cachep->slabs_free, list) { 68.1792 - if (slabp->inuse) 68.1793 - BUG(); 68.1794 - num_slabs++; 68.1795 - } 68.1796 - num_slabs+=active_slabs; 68.1797 - num_objs = num_slabs*cachep->num; 68.1798 - 68.1799 - printk("%-17s %6lu %6lu %6u %4lu %4lu %4u", 68.1800 - cachep->name, active_objs, num_objs, cachep->objsize, 68.1801 - active_slabs, num_slabs, (1<<cachep->gfporder)); 68.1802 - 68.1803 -#if STATS 68.1804 - { 68.1805 - unsigned long errors = cachep->errors; 68.1806 - unsigned long high = cachep->high_mark; 68.1807 - unsigned long grown = cachep->grown; 68.1808 - unsigned long reaped = cachep->reaped; 68.1809 - unsigned long allocs = cachep->num_allocations; 68.1810 - 68.1811 - printk(" : %6lu %7lu %5lu %4lu %4lu", 68.1812 - high, allocs, grown, reaped, errors); 68.1813 - } 68.1814 -#endif 68.1815 -#ifdef CONFIG_SMP 68.1816 - { 68.1817 - unsigned int batchcount = cachep->batchcount; 68.1818 - unsigned int limit; 68.1819 - 68.1820 - if (cc_data(cachep)) 68.1821 - limit = cc_data(cachep)->limit; 68.1822 - else 68.1823 - limit = 0; 68.1824 - printk(" : %4u %4u", 68.1825 - limit, batchcount); 68.1826 - } 68.1827 -#endif 68.1828 -#if STATS && defined(CONFIG_SMP) 68.1829 - { 68.1830 - unsigned long allochit = atomic_read(&cachep->allochit); 68.1831 - unsigned long allocmiss = atomic_read(&cachep->allocmiss); 68.1832 - unsigned long freehit = atomic_read(&cachep->freehit); 68.1833 - unsigned long freemiss = atomic_read(&cachep->freemiss); 68.1834 - printk(" : %6lu %6lu %6lu %6lu", 68.1835 - allochit, allocmiss, freehit, freemiss); 68.1836 - } 68.1837 -#endif 68.1838 - printk("\n"); 68.1839 - spin_unlock_irq(&cachep->spinlock); 68.1840 - 68.1841 - p = cachep->next.next; 68.1842 - } while (p != &cache_cache.next); 68.1843 - 68.1844 - up(&cache_chain_sem); 68.1845 - 68.1846 - return; 68.1847 -}
69.1 --- a/xen/common/softirq.c Fri Feb 04 19:26:10 2005 +0000 69.2 +++ b/xen/common/softirq.c Mon Feb 07 08:19:24 2005 +0000 69.3 @@ -1,3 +1,4 @@ 69.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 69.5 /****************************************************************************** 69.6 * common/softirq.c 69.7 *
70.1 --- a/xen/common/string.c Fri Feb 04 19:26:10 2005 +0000 70.2 +++ b/xen/common/string.c Mon Feb 07 08:19:24 2005 +0000 70.3 @@ -1,3 +1,4 @@ 70.4 +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 70.5 /* 70.6 * linux/lib/string.c 70.7 *
71.1 --- a/xen/common/trace.c Fri Feb 04 19:26:10 2005 +0000 71.2 +++ b/xen/common/trace.c Mon Feb 07 08:19:24 2005 +0000 71.3 @@ -1,3 +1,4 @@ 71.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 71.5 /****************************************************************************** 71.6 * common/trace.c 71.7 *
72.1 --- a/xen/common/vsprintf.c Fri Feb 04 19:26:10 2005 +0000 72.2 +++ b/xen/common/vsprintf.c Mon Feb 07 08:19:24 2005 +0000 72.3 @@ -1,3 +1,4 @@ 72.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 72.5 /* 72.6 * linux/lib/vsprintf.c 72.7 * 72.8 @@ -115,13 +116,13 @@ static int skip_atoi(const char **s) 72.9 return i; 72.10 } 72.11 72.12 -#define ZEROPAD 1 /* pad with zero */ 72.13 -#define SIGN 2 /* unsigned/signed long */ 72.14 -#define PLUS 4 /* show plus */ 72.15 -#define SPACE 8 /* space if plus */ 72.16 -#define LEFT 16 /* left justified */ 72.17 -#define SPECIAL 32 /* 0x */ 72.18 -#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ 72.19 +#define ZEROPAD 1 /* pad with zero */ 72.20 +#define SIGN 2 /* unsigned/signed long */ 72.21 +#define PLUS 4 /* show plus */ 72.22 +#define SPACE 8 /* space if plus */ 72.23 +#define LEFT 16 /* left justified */ 72.24 +#define SPECIAL 32 /* 0x */ 72.25 +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ 72.26 72.27 static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) 72.28 { 72.29 @@ -239,14 +240,14 @@ int vsnprintf(char *buf, size_t size, co 72.30 char *str, *end, c; 72.31 const char *s; 72.32 72.33 - int flags; /* flags to number() */ 72.34 + int flags; /* flags to number() */ 72.35 72.36 - int field_width; /* width of output field */ 72.37 - int precision; /* min. # of digits for integers; max 72.38 - number of chars for from string */ 72.39 - int qualifier; /* 'h', 'l', or 'L' for integer fields */ 72.40 - /* 'z' support added 23/7/1999 S.H. */ 72.41 - /* 'z' changed to 'Z' --davidm 1/25/99 */ 72.42 + int field_width; /* width of output field */ 72.43 + int precision; /* min. # of digits for integers; max 72.44 + number of chars for from string */ 72.45 + int qualifier; /* 'h', 'l', or 'L' for integer fields */ 72.46 + /* 'z' support added 23/7/1999 S.H. */ 72.47 + /* 'z' changed to 'Z' --davidm 1/25/99 */ 72.48 72.49 str = buf; 72.50 end = buf + size - 1; 72.51 @@ -267,7 +268,7 @@ int vsnprintf(char *buf, size_t size, co 72.52 /* process flags */ 72.53 flags = 0; 72.54 repeat: 72.55 - ++fmt; /* this also skips first '%' */ 72.56 + ++fmt; /* this also skips first '%' */ 72.57 switch (*fmt) { 72.58 case '-': flags |= LEFT; goto repeat; 72.59 case '+': flags |= PLUS; goto repeat; 72.60 @@ -293,12 +294,12 @@ int vsnprintf(char *buf, size_t size, co 72.61 /* get the precision */ 72.62 precision = -1; 72.63 if (*fmt == '.') { 72.64 - ++fmt; 72.65 + ++fmt; 72.66 if (isdigit(*fmt)) 72.67 precision = skip_atoi(&fmt); 72.68 else if (*fmt == '*') { 72.69 ++fmt; 72.70 - /* it's the next argument */ 72.71 + /* it's the next argument */ 72.72 precision = va_arg(args, int); 72.73 } 72.74 if (precision < 0) 72.75 @@ -381,8 +382,8 @@ int vsnprintf(char *buf, size_t size, co 72.76 72.77 72.78 case 'n': 72.79 - /* FIXME: 72.80 - * What does C99 say about the overflow case here? */ 72.81 + /* FIXME: 72.82 + * What does C99 say about the overflow case here? */ 72.83 if (qualifier == 'l') { 72.84 long * ip = va_arg(args, long *); 72.85 *ip = (str - buf); 72.86 @@ -401,7 +402,7 @@ int vsnprintf(char *buf, size_t size, co 72.87 ++str; 72.88 continue; 72.89 72.90 - /* integer number formats - set up the flags and "break" */ 72.91 + /* integer number formats - set up the flags and "break" */ 72.92 case 'o': 72.93 base = 8; 72.94 break;
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/xen/common/xmalloc.c Mon Feb 07 08:19:24 2005 +0000 73.3 @@ -0,0 +1,173 @@ 73.4 +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 73.5 +/****************************************************************************** 73.6 + * Simple allocator for Xen. If larger than a page, simply use the 73.7 + * page-order allocator. 73.8 + * 73.9 + * Copyright (C) 2005 Rusty Russell IBM Corporation 73.10 + * 73.11 + * This program is free software; you can redistribute it and/or modify 73.12 + * it under the terms of the GNU General Public License as published by 73.13 + * the Free Software Foundation; either version 2 of the License, or 73.14 + * (at your option) any later version. 73.15 + * 73.16 + * This program is distributed in the hope that it will be useful, 73.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 73.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 73.19 + * GNU General Public License for more details. 73.20 + * 73.21 + * You should have received a copy of the GNU General Public License 73.22 + * along with this program; if not, write to the Free Software 73.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 73.24 + */ 73.25 + 73.26 +#include <xen/mm.h> 73.27 +#include <xen/spinlock.h> 73.28 +#include <xen/ac_timer.h> 73.29 +#include <xen/cache.h> 73.30 + 73.31 +#define BUG_ON(x) do { if (x) BUG(); }while(0) 73.32 + 73.33 +static LIST_HEAD(freelist); 73.34 +static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED; 73.35 + 73.36 +struct xmalloc_hdr 73.37 +{ 73.38 + /* Total including this hdr. */ 73.39 + size_t size; 73.40 + struct list_head freelist; 73.41 +} __attribute__((__aligned__(SMP_CACHE_BYTES))); 73.42 + 73.43 +static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block) 73.44 +{ 73.45 + size_t leftover = block - size; 73.46 + 73.47 + /* If enough left to make a block, put it on free list. */ 73.48 + if (leftover >= sizeof(struct xmalloc_hdr)) { 73.49 + struct xmalloc_hdr *extra; 73.50 + 73.51 + extra = (void *)hdr + size; 73.52 + extra->size = leftover; 73.53 + list_add(&extra->freelist, &freelist); 73.54 + } else 73.55 + size = block; 73.56 + 73.57 + hdr->size = size; 73.58 + /* Debugging aid. */ 73.59 + hdr->freelist.next = hdr->freelist.prev = NULL; 73.60 +} 73.61 + 73.62 +static void *xmalloc_new_page(size_t size) 73.63 +{ 73.64 + struct xmalloc_hdr *hdr; 73.65 + unsigned long flags; 73.66 + 73.67 + hdr = (void *)alloc_xenheap_pages(0); 73.68 + if (!hdr) 73.69 + return NULL; 73.70 + 73.71 + spin_lock_irqsave(&freelist_lock, flags); 73.72 + maybe_split(hdr, size, PAGE_SIZE); 73.73 + spin_unlock_irqrestore(&freelist_lock, flags); 73.74 + return hdr+1; 73.75 +} 73.76 + 73.77 +/* Big object? Just use page allocator. */ 73.78 +static void *xmalloc_whole_pages(size_t size) 73.79 +{ 73.80 + struct xmalloc_hdr *hdr; 73.81 + unsigned int pageorder = get_order(size); 73.82 + 73.83 + hdr = (void *)alloc_xenheap_pages(pageorder); 73.84 + if (!hdr) 73.85 + return NULL; 73.86 + 73.87 + hdr->size = (1 << (pageorder + PAGE_SHIFT)); 73.88 + /* Debugging aid. */ 73.89 + hdr->freelist.next = hdr->freelist.prev = NULL; 73.90 + return hdr+1; 73.91 +} 73.92 + 73.93 +/* Return size, increased to alignment with align. */ 73.94 +static inline size_t align_up(size_t size, size_t align) 73.95 +{ 73.96 + return (size + align-1) & ~(align - 1); 73.97 +} 73.98 + 73.99 +void *_xmalloc(size_t size, size_t align) 73.100 +{ 73.101 + struct xmalloc_hdr *i; 73.102 + unsigned long flags; 73.103 + 73.104 + /* We currently always return cacheline aligned. */ 73.105 + BUG_ON(align > SMP_CACHE_BYTES); 73.106 + 73.107 + /* Add room for header, pad to align next header. */ 73.108 + size += sizeof(struct xmalloc_hdr); 73.109 + size = align_up(size, __alignof__(struct xmalloc_hdr)); 73.110 + 73.111 + /* For big allocs, give them whole pages. */ 73.112 + if (size >= PAGE_SIZE) 73.113 + return xmalloc_whole_pages(size); 73.114 + 73.115 + /* Search free list */ 73.116 + spin_lock_irqsave(&freelist_lock, flags); 73.117 + list_for_each_entry(i, &freelist, freelist) { 73.118 + if (i->size >= size) { 73.119 + list_del(&i->freelist); 73.120 + maybe_split(i, size, i->size); 73.121 + spin_unlock_irqrestore(&freelist_lock, flags); 73.122 + return i+1; 73.123 + } 73.124 + } 73.125 + spin_unlock_irqrestore(&freelist_lock, flags); 73.126 + 73.127 + /* Alloc a new page and return from that. */ 73.128 + return xmalloc_new_page(size); 73.129 +} 73.130 + 73.131 +void xfree(const void *p) 73.132 +{ 73.133 + unsigned long flags; 73.134 + struct xmalloc_hdr *i, *tmp, *hdr; 73.135 + 73.136 + if (!p) 73.137 + return; 73.138 + 73.139 + hdr = (struct xmalloc_hdr *)p - 1; 73.140 + 73.141 + /* We know hdr will be on same page. */ 73.142 + BUG_ON(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK)); 73.143 + 73.144 + /* Not previously freed. */ 73.145 + BUG_ON(hdr->freelist.next || hdr->freelist.prev); 73.146 + 73.147 + /* Big allocs free directly. */ 73.148 + if (hdr->size >= PAGE_SIZE) { 73.149 + free_xenheap_pages((unsigned long)hdr, get_order(hdr->size)); 73.150 + return; 73.151 + } 73.152 + 73.153 + /* Merge with other free block, or put in list. */ 73.154 + spin_lock_irqsave(&freelist_lock, flags); 73.155 + list_for_each_entry_safe(i, tmp, &freelist, freelist) { 73.156 + /* We follow this block? Swallow it. */ 73.157 + if ((void *)i + i->size == (void *)hdr) { 73.158 + list_del(&i->freelist); 73.159 + i->size += hdr->size; 73.160 + hdr = i; 73.161 + } 73.162 + /* It follows us? Delete it and add it to us. */ 73.163 + if ((void *)hdr + hdr->size == (void *)i) { 73.164 + list_del(&i->freelist); 73.165 + hdr->size += i->size; 73.166 + } 73.167 + } 73.168 + 73.169 + /* Did we free entire page? */ 73.170 + if (hdr->size == PAGE_SIZE) { 73.171 + BUG_ON((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0); 73.172 + free_xenheap_pages((unsigned long)hdr, 0); 73.173 + } else 73.174 + list_add(&hdr->freelist, &freelist); 73.175 + spin_unlock_irqrestore(&freelist_lock, flags); 73.176 +}
74.1 --- a/xen/drivers/char/console.c Fri Feb 04 19:26:10 2005 +0000 74.2 +++ b/xen/drivers/char/console.c Mon Feb 07 08:19:24 2005 +0000 74.3 @@ -1,3 +1,4 @@ 74.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 74.5 /****************************************************************************** 74.6 * console.c 74.7 *
75.1 --- a/xen/drivers/char/serial.c Fri Feb 04 19:26:10 2005 +0000 75.2 +++ b/xen/drivers/char/serial.c Mon Feb 07 08:19:24 2005 +0000 75.3 @@ -1,3 +1,4 @@ 75.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 75.5 /****************************************************************************** 75.6 * serial.c 75.7 * 75.8 @@ -12,7 +13,6 @@ 75.9 #include <xen/init.h> 75.10 #include <xen/irq.h> 75.11 #include <xen/keyhandler.h> 75.12 -#include <asm/pdb.h> 75.13 #include <xen/reboot.h> 75.14 #include <xen/sched.h> 75.15 #include <xen/serial.h> 75.16 @@ -33,14 +33,14 @@ string_param("com2", opt_com2); 75.17 #define MCR 0x04 /* Modem control */ 75.18 #define LSR 0x05 /* line status */ 75.19 #define MSR 0x06 /* Modem status */ 75.20 -#define DLL 0x00 /* divisor latch (ls) ( DLAB=1) */ 75.21 -#define DLM 0x01 /* divisor latch (ms) ( DLAB=1) */ 75.22 +#define DLL 0x00 /* divisor latch (ls) (DLAB=1) */ 75.23 +#define DLM 0x01 /* divisor latch (ms) (DLAB=1) */ 75.24 75.25 /* Interrupt Enable Register */ 75.26 #define IER_ERDAI 0x01 /* rx data recv'd */ 75.27 #define IER_ETHREI 0x02 /* tx reg. empty */ 75.28 #define IER_ELSI 0x04 /* rx line status */ 75.29 -#define IER_EMSI 0x08 /* MODEM status */ 75.30 +#define IER_EMSI 0x08 /* MODEM status */ 75.31 75.32 /* FIFO control register */ 75.33 #define FCR_ENABLE 0x01 /* enable FIFO */
76.1 --- a/xen/include/asm-x86/config.h Fri Feb 04 19:26:10 2005 +0000 76.2 +++ b/xen/include/asm-x86/config.h Mon Feb 07 08:19:24 2005 +0000 76.3 @@ -83,7 +83,15 @@ 76.4 76.5 #ifndef NDEBUG 76.6 #define MEMORY_GUARD 76.7 +#ifdef __x86_64__ 76.8 +#define STACK_ORDER 2 76.9 #endif 76.10 +#endif 76.11 + 76.12 +#ifndef STACK_ORDER 76.13 +#define STACK_ORDER 1 76.14 +#endif 76.15 +#define STACK_SIZE (PAGE_SIZE << STACK_ORDER) 76.16 76.17 #ifndef __ASSEMBLY__ 76.18 extern unsigned long _end; /* standard ELF symbol */
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/xen/include/asm-x86/domain.h Mon Feb 07 08:19:24 2005 +0000 77.3 @@ -0,0 +1,119 @@ 77.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 77.5 + 77.6 +#ifndef __ASM_DOMAIN_H__ 77.7 +#define __ASM_DOMAIN_H__ 77.8 + 77.9 +struct trap_bounce { 77.10 + unsigned long error_code; 77.11 + unsigned long cr2; 77.12 + unsigned short flags; /* TBF_ */ 77.13 + unsigned short cs; 77.14 + unsigned long eip; 77.15 +}; 77.16 + 77.17 +struct arch_domain 77.18 +{ 77.19 + l1_pgentry_t *mm_perdomain_pt; 77.20 + 77.21 + /* shadow mode status and controls */ 77.22 + unsigned int shadow_mode; /* flags to control shadow table operation */ 77.23 + spinlock_t shadow_lock; 77.24 + unsigned long min_pfn; /* min host physical */ 77.25 + unsigned long max_pfn; /* max host physical */ 77.26 + 77.27 + /* shadow hashtable */ 77.28 + struct shadow_status *shadow_ht; 77.29 + struct shadow_status *shadow_ht_free; 77.30 + struct shadow_status *shadow_ht_extras; /* extra allocation units */ 77.31 + unsigned int shadow_extras_count; 77.32 + 77.33 + /* shadow dirty bitmap */ 77.34 + unsigned long *shadow_dirty_bitmap; 77.35 + unsigned int shadow_dirty_bitmap_size; /* in pages, bit per page */ 77.36 + 77.37 + /* shadow mode stats */ 77.38 + unsigned int shadow_page_count; 77.39 + unsigned int shadow_fault_count; 77.40 + unsigned int shadow_dirty_count; 77.41 + unsigned int shadow_dirty_net_count; 77.42 + unsigned int shadow_dirty_block_count; 77.43 +} __cacheline_aligned; 77.44 + 77.45 +struct arch_exec_domain 77.46 +{ 77.47 + unsigned long guestos_sp; 77.48 + unsigned long guestos_ss; 77.49 + 77.50 + unsigned long flags; /* TF_ */ 77.51 + 77.52 + /* Hardware debugging registers */ 77.53 + unsigned long debugreg[8]; /* %%db0-7 debug registers */ 77.54 + 77.55 + /* floating point info */ 77.56 + struct i387_state i387; 77.57 + 77.58 + /* general user-visible register state */ 77.59 + execution_context_t user_ctxt; 77.60 + 77.61 + void (*schedule_tail) (struct exec_domain *); 77.62 + 77.63 + /* 77.64 + * Return vectors pushed to us by guest OS. 77.65 + * The stack frame for events is exactly that of an x86 hardware interrupt. 77.66 + * The stack frame for a failsafe callback is augmented with saved values 77.67 + * for segment registers %ds, %es, %fs and %gs: 77.68 + * %ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss] 77.69 + */ 77.70 + unsigned long event_selector; /* entry CS */ 77.71 + unsigned long event_address; /* entry EIP */ 77.72 + 77.73 + unsigned long failsafe_selector; /* entry CS */ 77.74 + unsigned long failsafe_address; /* entry EIP */ 77.75 + 77.76 + /* Bounce information for propagating an exception to guest OS. */ 77.77 + struct trap_bounce trap_bounce; 77.78 + 77.79 + /* I/O-port access bitmap. */ 77.80 + u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are 77.81 + * "interesting" (i.e. have clear bits) */ 77.82 + u8 *io_bitmap; /* Pointer to task's IO bitmap or NULL */ 77.83 + 77.84 + /* Trap info. */ 77.85 +#ifdef ARCH_HAS_FAST_TRAP 77.86 + int fast_trap_idx; 77.87 + struct desc_struct fast_trap_desc; 77.88 +#endif 77.89 + trap_info_t traps[256]; 77.90 +#ifdef CONFIG_VMX 77.91 + struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ 77.92 +#endif 77.93 + 77.94 + /* 77.95 + * Every domain has a L1 pagetable of its own. Per-domain mappings 77.96 + * are put in this table (eg. the current GDT is mapped here). 77.97 + */ 77.98 + l1_pgentry_t *perdomain_ptes; 77.99 + pagetable_t pagetable; 77.100 + 77.101 + pagetable_t monitor_table; 77.102 + pagetable_t shadow_table; 77.103 + l2_pgentry_t *vpagetable; /* virtual address of pagetable */ 77.104 + l2_pgentry_t *shadow_vtable; /* virtual address of shadow_table */ 77.105 + l2_pgentry_t *guest_pl2e_cache; /* guest page directory cache */ 77.106 + 77.107 + /* Virtual CR2 value. Can be read/written by guest. */ 77.108 + unsigned long guest_cr2; 77.109 + 77.110 + /* Current LDT details. */ 77.111 + unsigned long ldt_base, ldt_ents, shadow_ldt_mapcnt; 77.112 + /* Next entry is passed to LGDT on domain switch. */ 77.113 + char gdt[10]; /* NB. 10 bytes needed for x86_64. Use 6 bytes for x86_32. */ 77.114 +} __cacheline_aligned; 77.115 + 77.116 +#define IDLE0_ARCH_EXEC_DOMAIN \ 77.117 +{ \ 77.118 + perdomain_ptes: 0, \ 77.119 + pagetable: mk_pagetable(__pa(idle_pg_table)) \ 77.120 +} 77.121 + 77.122 +#endif /* __ASM_DOMAIN_H__ */
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/xen/include/asm-x86/init.h Mon Feb 07 08:19:24 2005 +0000 78.3 @@ -0,0 +1,29 @@ 78.4 +#ifndef _XEN_ASM_INIT_H 78.5 +#define _XEN_ASM_INIT_H 78.6 + 78.7 +/* 78.8 + * Mark functions and data as being only used at initialization 78.9 + * or exit time. 78.10 + */ 78.11 +#define __init \ 78.12 + __attribute__ ((__section__ (".init.text"))) 78.13 +#define __exit \ 78.14 + __attribute_used__ __attribute__ ((__section__(".text.exit"))) 78.15 +#define __initdata \ 78.16 + __attribute__ ((__section__ (".init.data"))) 78.17 +#define __exitdata \ 78.18 + __attribute_used__ __attribute__ ((__section__ (".data.exit"))) 78.19 +#define __initsetup \ 78.20 + __attribute_used__ __attribute__ ((__section__ (".setup.init"))) 78.21 +#define __init_call \ 78.22 + __attribute_used__ __attribute__ ((__section__ (".initcall.init"))) 78.23 +#define __exit_call \ 78.24 + __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) 78.25 + 78.26 +/* For assembly routines 78.27 +#define __INIT .section ".text.init","ax" 78.28 +#define __FINIT .previous 78.29 +#define __INITDATA .section ".data.init","aw" 78.30 +*/ 78.31 + 78.32 +#endif /* _XEN_ASM_INIT_H */
79.1 --- a/xen/include/asm-x86/ldt.h Fri Feb 04 19:26:10 2005 +0000 79.2 +++ b/xen/include/asm-x86/ldt.h Mon Feb 07 08:19:24 2005 +0000 79.3 @@ -1,25 +1,27 @@ 79.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 79.5 + 79.6 #ifndef __ARCH_LDT_H 79.7 #define __ARCH_LDT_H 79.8 79.9 #ifndef __ASSEMBLY__ 79.10 79.11 -static inline void load_LDT(struct exec_domain *p) 79.12 +static inline void load_LDT(struct exec_domain *ed) 79.13 { 79.14 unsigned int cpu; 79.15 struct desc_struct *desc; 79.16 unsigned long ents; 79.17 - 79.18 - if ( (ents = p->mm.ldt_ents) == 0 ) 79.19 + 79.20 + if ( (ents = ed->arch.ldt_ents) == 0 ) 79.21 { 79.22 __asm__ __volatile__ ( "lldt %%ax" : : "a" (0) ); 79.23 } 79.24 else 79.25 { 79.26 cpu = smp_processor_id(); 79.27 - desc = (struct desc_struct *)GET_GDT_ADDRESS(p) + __LDT(cpu); 79.28 - desc->a = ((LDT_VIRT_START(p)&0xffff)<<16) | (ents*8-1); 79.29 - desc->b = (LDT_VIRT_START(p)&(0xff<<24)) | 0x8200 | 79.30 - ((LDT_VIRT_START(p)&0xff0000)>>16); 79.31 + desc = (struct desc_struct *)GET_GDT_ADDRESS(ed) + __LDT(cpu); 79.32 + desc->a = ((LDT_VIRT_START(ed)&0xffff)<<16) | (ents*8-1); 79.33 + desc->b = (LDT_VIRT_START(ed)&(0xff<<24)) | 0x8200 | 79.34 + ((LDT_VIRT_START(ed)&0xff0000)>>16); 79.35 __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) ); 79.36 } 79.37 }
80.1 --- a/xen/include/asm-x86/mm.h Fri Feb 04 19:26:10 2005 +0000 80.2 +++ b/xen/include/asm-x86/mm.h Mon Feb 07 08:19:24 2005 +0000 80.3 @@ -250,10 +250,12 @@ void synchronise_pagetables(unsigned lon 80.4 80.5 #ifdef MEMORY_GUARD 80.6 void *memguard_init(void *heap_start); 80.7 +void memguard_guard_stack(void *p); 80.8 void memguard_guard_range(void *p, unsigned long l); 80.9 void memguard_unguard_range(void *p, unsigned long l); 80.10 #else 80.11 #define memguard_init(_s) (_s) 80.12 +#define memguard_guard_stack(_p) ((void)0) 80.13 #define memguard_guard_range(_p,_l) ((void)0) 80.14 #define memguard_unguard_range(_p,_l) ((void)0) 80.15 #endif
81.1 --- a/xen/include/asm-x86/page.h Fri Feb 04 19:26:10 2005 +0000 81.2 +++ b/xen/include/asm-x86/page.h Mon Feb 07 08:19:24 2005 +0000 81.3 @@ -34,7 +34,11 @@ 81.4 #endif 81.5 81.6 #define PAGE_SHIFT L1_PAGETABLE_SHIFT 81.7 +#ifndef __ASSEMBLY__ 81.8 #define PAGE_SIZE (1UL << PAGE_SHIFT) 81.9 +#else 81.10 +#define PAGE_SIZE (1 << PAGE_SHIFT) 81.11 +#endif 81.12 #define PAGE_MASK (~(PAGE_SIZE-1)) 81.13 81.14 #define clear_page(_p) memset((void *)(_p), 0, PAGE_SIZE)
82.1 --- a/xen/include/asm-x86/pdb.h Fri Feb 04 19:26:10 2005 +0000 82.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 82.3 @@ -1,89 +0,0 @@ 82.4 - 82.5 -/* 82.6 - * pervasive debugger 82.7 - * www.cl.cam.ac.uk/netos/pdb 82.8 - * 82.9 - * alex ho 82.10 - * 2004 82.11 - * university of cambridge computer laboratory 82.12 - */ 82.13 - 82.14 - 82.15 -#ifndef __PDB_H__ 82.16 -#define __PDB_H__ 82.17 - 82.18 -#include <asm/regs.h> 82.19 -#include <xen/list.h> 82.20 -#include <public/dom0_ops.h> 82.21 -#include <public/xen.h> /* for domain id */ 82.22 - 82.23 -extern int pdb_initialized; 82.24 -extern int pdb_com_port; 82.25 -extern int pdb_high_bit; 82.26 -extern int pdb_page_fault_possible; 82.27 -extern int pdb_page_fault_scratch; 82.28 -extern int pdb_page_fault; 82.29 - 82.30 -extern void initialize_pdb(void); 82.31 - 82.32 -/* Get/set values from generic debug interface. */ 82.33 -extern int pdb_set_values(u_char *buffer, int length, 82.34 - unsigned long cr3, unsigned long addr); 82.35 -extern int pdb_get_values(u_char *buffer, int length, 82.36 - unsigned long cr3, unsigned long addr); 82.37 - 82.38 -/* External entry points. */ 82.39 -extern int pdb_handle_exception(int exceptionVector, 82.40 - struct xen_regs *xen_regs); 82.41 -extern void pdb_do_debug(dom0_op_t *op); 82.42 - 82.43 -/* PDB Context. */ 82.44 -struct pdb_context 82.45 -{ 82.46 - int valid; 82.47 - int domain; 82.48 - int process; 82.49 - int system_call; /* 0x01 break on enter, 0x02 break on exit */ 82.50 - unsigned long ptbr; 82.51 -}; 82.52 -extern struct pdb_context pdb_ctx; 82.53 - 82.54 -/* Breakpoints. */ 82.55 -struct pdb_breakpoint 82.56 -{ 82.57 - struct list_head list; 82.58 - unsigned long address; 82.59 - unsigned long cr3; 82.60 - domid_t domain; 82.61 -}; 82.62 -extern void pdb_bkpt_add (unsigned long cr3, unsigned long address); 82.63 -extern struct pdb_breakpoint* pdb_bkpt_search (unsigned long cr3, 82.64 - unsigned long address); 82.65 -extern int pdb_bkpt_remove (unsigned long cr3, unsigned long address); 82.66 - 82.67 -/* Conversions. */ 82.68 -extern int hex (char); 82.69 -extern char *mem2hex (char *, char *, int); 82.70 -extern char *hex2mem (char *, char *, int); 82.71 -extern int hexToInt (char **ptr, int *intValue); 82.72 - 82.73 -/* Temporary Linux specific definitions */ 82.74 -extern int pdb_system_call; 82.75 -extern unsigned char pdb_system_call_enter_instr; /* original enter instr */ 82.76 -extern unsigned char pdb_system_call_leave_instr; /* original next instr */ 82.77 -extern unsigned long pdb_system_call_next_addr; /* instr after int 0x80 */ 82.78 -extern unsigned long pdb_system_call_eflags_addr; /* saved eflags on stack */ 82.79 - 82.80 -unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid); 82.81 -void pdb_linux_get_values(char *buffer, int length, unsigned long address, 82.82 - int pid, unsigned long cr3); 82.83 -void pdb_linux_set_values(char *buffer, int length, unsigned long address, 82.84 - int pid, unsigned long cr3); 82.85 -void pdb_linux_syscall_enter_bkpt (struct xen_regs *regs, long error_code, 82.86 - trap_info_t *ti); 82.87 -void pdb_linux_syscall_exit_bkpt (struct xen_regs *regs, 82.88 - struct pdb_context *pdb_ctx); 82.89 - 82.90 -void pdb_handle_debug_trap(struct xen_regs *regs, long error_code); 82.91 - 82.92 -#endif /* __PDB_H__ */
83.1 --- a/xen/include/asm-x86/processor.h Fri Feb 04 19:26:10 2005 +0000 83.2 +++ b/xen/include/asm-x86/processor.h Mon Feb 07 08:19:24 2005 +0000 83.3 @@ -1,8 +1,6 @@ 83.4 -/* 83.5 - * include/asm-x86/processor.h 83.6 - * 83.7 - * Copyright (C) 1994 Linus Torvalds 83.8 - */ 83.9 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 83.10 + 83.11 +/* Portions are: Copyright (c) 1994 Linus Torvalds */ 83.12 83.13 #ifndef __ASM_X86_PROCESSOR_H 83.14 #define __ASM_X86_PROCESSOR_H 83.15 @@ -13,7 +11,6 @@ 83.16 #include <asm/cpufeature.h> 83.17 #include <asm/desc.h> 83.18 #include <asm/flushtlb.h> 83.19 -#include <asm/pdb.h> 83.20 #include <xen/config.h> 83.21 #include <xen/spinlock.h> 83.22 #include <xen/cache.h> 83.23 @@ -381,63 +378,6 @@ struct tss_struct { 83.24 u8 __cacheline_filler[23]; 83.25 } __cacheline_aligned PACKED; 83.26 83.27 -struct trap_bounce { 83.28 - unsigned long error_code; 83.29 - unsigned long cr2; 83.30 - unsigned short flags; /* TBF_ */ 83.31 - unsigned short cs; 83.32 - unsigned long eip; 83.33 -}; 83.34 - 83.35 -struct thread_struct { 83.36 - unsigned long guestos_sp; 83.37 - unsigned long guestos_ss; 83.38 - 83.39 - unsigned long flags; /* TF_ */ 83.40 - 83.41 - /* Hardware debugging registers */ 83.42 - unsigned long debugreg[8]; /* %%db0-7 debug registers */ 83.43 - 83.44 - /* floating point info */ 83.45 - struct i387_state i387; 83.46 - 83.47 - /* general user-visible register state */ 83.48 - execution_context_t user_ctxt; 83.49 - 83.50 - void (*schedule_tail) (struct exec_domain *); 83.51 - 83.52 - /* 83.53 - * Return vectors pushed to us by guest OS. 83.54 - * The stack frame for events is exactly that of an x86 hardware interrupt. 83.55 - * The stack frame for a failsafe callback is augmented with saved values 83.56 - * for segment registers %ds, %es, %fs and %gs: 83.57 - * %ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss] 83.58 - */ 83.59 - unsigned long event_selector; /* entry CS */ 83.60 - unsigned long event_address; /* entry EIP */ 83.61 - 83.62 - unsigned long failsafe_selector; /* entry CS */ 83.63 - unsigned long failsafe_address; /* entry EIP */ 83.64 - 83.65 - /* Bounce information for propagating an exception to guest OS. */ 83.66 - struct trap_bounce trap_bounce; 83.67 - 83.68 - /* I/O-port access bitmap. */ 83.69 - u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are 83.70 - * "interesting" (i.e. have clear bits) */ 83.71 - u8 *io_bitmap; /* Pointer to task's IO bitmap or NULL */ 83.72 - 83.73 - /* Trap info. */ 83.74 -#ifdef ARCH_HAS_FAST_TRAP 83.75 - int fast_trap_idx; 83.76 - struct desc_struct fast_trap_desc; 83.77 -#endif 83.78 - trap_info_t traps[256]; 83.79 -#ifdef CONFIG_VMX 83.80 - struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ 83.81 -#endif 83.82 -} __cacheline_aligned; 83.83 - 83.84 #define IDT_ENTRIES 256 83.85 extern idt_entry_t idt_table[]; 83.86 extern idt_entry_t *idt_tables[]; 83.87 @@ -453,16 +393,9 @@ extern idt_entry_t *idt_tables[]; 83.88 (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \ 83.89 0, 8)) 83.90 83.91 -#ifdef XEN_DEBUGGER 83.92 -#define SET_FAST_TRAP(_p) \ 83.93 - (pdb_initialized ? (void *) 0 : \ 83.94 - (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \ 83.95 - &((_p)->fast_trap_desc), 8))) 83.96 -#else 83.97 #define SET_FAST_TRAP(_p) \ 83.98 (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \ 83.99 &((_p)->fast_trap_desc), 8)) 83.100 -#endif 83.101 83.102 long set_fast_trap(struct exec_domain *p, int idx); 83.103 83.104 @@ -475,91 +408,18 @@ long set_fast_trap(struct exec_domain *p 83.105 83.106 #endif 83.107 83.108 -#define INIT_THREAD { 0 } 83.109 - 83.110 extern int gpf_emulate_4gb(struct xen_regs *regs); 83.111 83.112 -struct mm_struct { 83.113 - /* 83.114 - * Every domain has a L1 pagetable of its own. Per-domain mappings 83.115 - * are put in this table (eg. the current GDT is mapped here). 83.116 - */ 83.117 - l1_pgentry_t *perdomain_ptes; 83.118 - pagetable_t pagetable; 83.119 - 83.120 - pagetable_t monitor_table; 83.121 - l2_pgentry_t *vpagetable; /* virtual address of pagetable */ 83.122 - l2_pgentry_t *shadow_vtable; /* virtual address of shadow_table */ 83.123 - l2_pgentry_t *guest_pl2e_cache; /* guest page directory cache */ 83.124 - unsigned long min_pfn; /* min host physical */ 83.125 - unsigned long max_pfn; /* max host physical */ 83.126 - 83.127 - /* Virtual CR2 value. Can be read/written by guest. */ 83.128 - unsigned long guest_cr2; 83.129 - 83.130 - /* shadow mode status and controls */ 83.131 - unsigned int shadow_mode; /* flags to control shadow table operation */ 83.132 - pagetable_t shadow_table; 83.133 - spinlock_t shadow_lock; 83.134 - unsigned int shadow_max_page_count; // currently unused 83.135 - 83.136 - /* shadow hashtable */ 83.137 - struct shadow_status *shadow_ht; 83.138 - struct shadow_status *shadow_ht_free; 83.139 - struct shadow_status *shadow_ht_extras; /* extra allocation units */ 83.140 - unsigned int shadow_extras_count; 83.141 - 83.142 - /* shadow dirty bitmap */ 83.143 - unsigned long *shadow_dirty_bitmap; 83.144 - unsigned int shadow_dirty_bitmap_size; /* in pages, bit per page */ 83.145 - 83.146 - /* shadow mode stats */ 83.147 - unsigned int shadow_page_count; 83.148 - unsigned int shadow_fault_count; 83.149 - unsigned int shadow_dirty_count; 83.150 - unsigned int shadow_dirty_net_count; 83.151 - unsigned int shadow_dirty_block_count; 83.152 +extern void write_ptbase(struct exec_domain *ed); 83.153 83.154 - /* Current LDT details. */ 83.155 - unsigned long ldt_base, ldt_ents, shadow_ldt_mapcnt; 83.156 - /* Next entry is passed to LGDT on domain switch. */ 83.157 - char gdt[10]; /* NB. 10 bytes needed for x86_64. Use 6 bytes for x86_32. */ 83.158 -}; 83.159 - 83.160 -#define SHM_full_32 (8) /* full virtualization for 32-bit */ 83.161 - 83.162 -static inline void write_ptbase(struct mm_struct *mm) 83.163 -{ 83.164 - unsigned long pa; 83.165 - 83.166 -#ifdef CONFIG_VMX 83.167 - if ( unlikely(mm->shadow_mode) ) { 83.168 - if (mm->shadow_mode == SHM_full_32) 83.169 - pa = pagetable_val(mm->monitor_table); 83.170 - else 83.171 - pa = pagetable_val(mm->shadow_table); 83.172 - } 83.173 -#else 83.174 - if ( unlikely(mm->shadow_mode) ) 83.175 - pa = pagetable_val(mm->shadow_table); 83.176 -#endif 83.177 - else 83.178 - pa = pagetable_val(mm->pagetable); 83.179 - 83.180 - write_cr3(pa); 83.181 -} 83.182 - 83.183 -#define IDLE0_MM \ 83.184 -{ \ 83.185 - perdomain_ptes: 0, \ 83.186 - pagetable: mk_pagetable(__pa(idle_pg_table)) \ 83.187 -} 83.188 - 83.189 -/* Convenient accessor for mm.gdt. */ 83.190 -#define SET_GDT_ENTRIES(_p, _e) ((*(u16 *)((_p)->mm.gdt + 0)) = (((_e)<<3)-1)) 83.191 -#define SET_GDT_ADDRESS(_p, _a) ((*(unsigned long *)((_p)->mm.gdt + 2)) = (_a)) 83.192 -#define GET_GDT_ENTRIES(_p) (((*(u16 *)((_p)->mm.gdt + 0))+1)>>3) 83.193 -#define GET_GDT_ADDRESS(_p) (*(unsigned long *)((_p)->mm.gdt + 2)) 83.194 +#define SET_GDT_ENTRIES(_p, _e) \ 83.195 + ((*(u16 *)((_p)->arch.gdt + 0)) = (((_e)<<3)-1)) 83.196 +#define SET_GDT_ADDRESS(_p, _a) \ 83.197 + ((*(unsigned long *)((_p)->arch.gdt + 2)) = (_a)) 83.198 +#define GET_GDT_ENTRIES(_p) \ 83.199 + (((*(u16 *)((_p)->arch.gdt + 0))+1)>>3) 83.200 +#define GET_GDT_ADDRESS(_p) \ 83.201 + (*(unsigned long *)((_p)->arch.gdt + 2)) 83.202 83.203 void destroy_gdt(struct exec_domain *d); 83.204 long set_gdt(struct exec_domain *d,
84.1 --- a/xen/include/asm-x86/shadow.h Fri Feb 04 19:26:10 2005 +0000 84.2 +++ b/xen/include/asm-x86/shadow.h Mon Feb 07 08:19:24 2005 +0000 84.3 @@ -1,4 +1,4 @@ 84.4 -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 84.5 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 84.6 84.7 #ifndef _XEN_SHADOW_H 84.8 #define _XEN_SHADOW_H 84.9 @@ -12,7 +12,7 @@ 84.10 #define PSH_shadowed (1<<31) /* page has a shadow. PFN points to shadow */ 84.11 #define PSH_pfn_mask ((1<<21)-1) 84.12 84.13 -/* Shadow PT operation mode : shadowmode variable in mm_struct */ 84.14 +/* Shadow PT operation mode : shadow-mode variable in arch_domain. */ 84.15 #define SHM_test (1) /* just run domain on shadow PTs */ 84.16 #define SHM_logdirty (2) /* log pages that are dirtied */ 84.17 #define SHM_translate (3) /* lookup machine pages in translation table */ 84.18 @@ -23,10 +23,10 @@ 84.19 #define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START + \ 84.20 (SH_LINEAR_PT_VIRT_START >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))) 84.21 84.22 -#define shadow_mode(_d) ((_d)->mm.shadow_mode) 84.23 -#define shadow_lock_init(_d) spin_lock_init(&(_d)->mm.shadow_lock) 84.24 -#define shadow_lock(_m) spin_lock(&(_m)->shadow_lock) 84.25 -#define shadow_unlock(_m) spin_unlock(&(_m)->shadow_lock) 84.26 +#define shadow_mode(_d) ((_d)->arch.shadow_mode) 84.27 +#define shadow_lock_init(_d) spin_lock_init(&(_d)->arch.shadow_lock) 84.28 +#define shadow_lock(_d) spin_lock(&(_d)->arch.shadow_lock) 84.29 +#define shadow_unlock(_d) spin_unlock(&(_d)->arch.shadow_lock) 84.30 84.31 extern void shadow_mode_init(void); 84.32 extern int shadow_mode_control(struct domain *p, dom0_shadow_control_t *sc); 84.33 @@ -39,18 +39,18 @@ extern void unshadow_table(unsigned long 84.34 extern int shadow_mode_enable(struct domain *p, unsigned int mode); 84.35 84.36 #ifdef CONFIG_VMX 84.37 -extern void vmx_shadow_clear_state(struct mm_struct *); 84.38 -extern void vmx_shadow_invlpg(struct mm_struct *, unsigned long); 84.39 +extern void vmx_shadow_clear_state(struct domain *); 84.40 +extern void vmx_shadow_invlpg(struct domain *, unsigned long); 84.41 #endif 84.42 84.43 -#define __get_machine_to_phys(m, guest_gpfn, gpfn) \ 84.44 - if ((m)->shadow_mode == SHM_full_32) \ 84.45 +#define __get_machine_to_phys(_d, guest_gpfn, gpfn) \ 84.46 + if ((_d)->arch.shadow_mode == SHM_full_32) \ 84.47 (guest_gpfn) = machine_to_phys_mapping[(gpfn)]; \ 84.48 else \ 84.49 (guest_gpfn) = (gpfn); 84.50 84.51 -#define __get_phys_to_machine(m, host_gpfn, gpfn) \ 84.52 - if ((m)->shadow_mode == SHM_full_32) \ 84.53 +#define __get_phys_to_machine(_d, host_gpfn, gpfn) \ 84.54 + if ((_d)->arch.shadow_mode == SHM_full_32) \ 84.55 (host_gpfn) = phys_to_machine_mapping[(gpfn)]; \ 84.56 else \ 84.57 (host_gpfn) = (gpfn); 84.58 @@ -58,21 +58,21 @@ extern void vmx_shadow_invlpg(struct mm_ 84.59 extern void __shadow_mode_disable(struct domain *d); 84.60 static inline void shadow_mode_disable(struct domain *d) 84.61 { 84.62 - if ( shadow_mode(d->exec_domain[0]) ) 84.63 + if ( shadow_mode(d) ) 84.64 __shadow_mode_disable(d); 84.65 } 84.66 84.67 extern unsigned long shadow_l2_table( 84.68 - struct mm_struct *m, unsigned long gpfn); 84.69 + struct domain *d, unsigned long gpfn); 84.70 84.71 -static inline void shadow_invalidate(struct mm_struct *m) { 84.72 - if (m->shadow_mode != SHM_full_32) 84.73 +static inline void shadow_invalidate(struct exec_domain *ed) { 84.74 + if ( ed->domain->arch.shadow_mode != SHM_full_32 ) 84.75 BUG(); 84.76 - memset(m->shadow_vtable, 0, PAGE_SIZE); 84.77 + memset(ed->arch.shadow_vtable, 0, PAGE_SIZE); 84.78 } 84.79 84.80 -#define SHADOW_DEBUG 0 84.81 -#define SHADOW_HASH_DEBUG 0 84.82 +#define SHADOW_DEBUG 1 84.83 +#define SHADOW_HASH_DEBUG 1 84.84 84.85 struct shadow_status { 84.86 unsigned long pfn; /* Guest pfn. */ 84.87 @@ -94,7 +94,7 @@ printk("DOM%u: (file=shadow.c, line=%d) 84.88 #if SHADOW_DEBUG 84.89 #define SH_VLOG(_f, _a...) \ 84.90 printk("DOM%u: (file=shadow.c, line=%d) " _f "\n", \ 84.91 - current->id , __LINE__ , ## _a ) 84.92 + current->domain->id , __LINE__ , ## _a ) 84.93 #else 84.94 #define SH_VLOG(_f, _a...) 84.95 #endif 84.96 @@ -102,67 +102,64 @@ printk("DOM%u: (file=shadow.c, line=%d) 84.97 #if 0 84.98 #define SH_VVLOG(_f, _a...) \ 84.99 printk("DOM%u: (file=shadow.c, line=%d) " _f "\n", \ 84.100 - current->id , __LINE__ , ## _a ) 84.101 + current->domain->id , __LINE__ , ## _a ) 84.102 #else 84.103 #define SH_VVLOG(_f, _a...) 84.104 #endif 84.105 84.106 -static inline void __shadow_get_pl2e(struct mm_struct *m, 84.107 - unsigned long va, unsigned long *sl2e) 84.108 +static inline void __shadow_get_pl2e( 84.109 + struct exec_domain *ed, unsigned long va, unsigned long *sl2e) 84.110 { 84.111 - if (m->shadow_mode == SHM_full_32) { 84.112 - *sl2e = l2_pgentry_val(m->shadow_vtable[va >> L2_PAGETABLE_SHIFT]); 84.113 - } 84.114 - else 84.115 - *sl2e = l2_pgentry_val(linear_l2_table[va >> L2_PAGETABLE_SHIFT]); 84.116 + *sl2e = (ed->domain->arch.shadow_mode == SHM_full_32) ? 84.117 + l2_pgentry_val(ed->arch.shadow_vtable[l2_table_offset(va)]) : 84.118 + l2_pgentry_val(linear_l2_table[l2_table_offset(va)]); 84.119 } 84.120 84.121 -static inline void __shadow_set_pl2e(struct mm_struct *m, 84.122 - unsigned long va, unsigned long value) 84.123 +static inline void __shadow_set_pl2e( 84.124 + struct exec_domain *ed, unsigned long va, unsigned long value) 84.125 { 84.126 - if (m->shadow_mode == SHM_full_32) { 84.127 - m->shadow_vtable[va >> L2_PAGETABLE_SHIFT] = mk_l2_pgentry(value); 84.128 - } 84.129 + if ( ed->domain->arch.shadow_mode == SHM_full_32 ) 84.130 + ed->arch.shadow_vtable[l2_table_offset(va)] = mk_l2_pgentry(value); 84.131 else 84.132 - linear_l2_table[va >> L2_PAGETABLE_SHIFT] = mk_l2_pgentry(value); 84.133 + linear_l2_table[l2_table_offset(va)] = mk_l2_pgentry(value); 84.134 } 84.135 84.136 -static inline void __guest_get_pl2e(struct mm_struct *m, 84.137 - unsigned long va, unsigned long *l2e) 84.138 +static inline void __guest_get_pl2e( 84.139 + struct exec_domain *ed, unsigned long va, unsigned long *l2e) 84.140 { 84.141 - if (m->shadow_mode == SHM_full_32) { 84.142 - *l2e = l2_pgentry_val(m->vpagetable[va >> L2_PAGETABLE_SHIFT]); 84.143 - } 84.144 - else 84.145 - *l2e = l2_pgentry_val(linear_l2_table[va >> L2_PAGETABLE_SHIFT]); 84.146 + *l2e = (ed->domain->arch.shadow_mode == SHM_full_32) ? 84.147 + l2_pgentry_val(ed->arch.vpagetable[l2_table_offset(va)]) : 84.148 + l2_pgentry_val(linear_l2_table[l2_table_offset(va)]); 84.149 } 84.150 84.151 -static inline void __guest_set_pl2e(struct mm_struct *m, 84.152 - unsigned long va, unsigned long value) 84.153 +static inline void __guest_set_pl2e( 84.154 + struct exec_domain *ed, unsigned long va, unsigned long value) 84.155 { 84.156 - if (m->shadow_mode == SHM_full_32) { 84.157 + if ( ed->domain->arch.shadow_mode == SHM_full_32 ) 84.158 + { 84.159 unsigned long pfn; 84.160 84.161 pfn = phys_to_machine_mapping[value >> PAGE_SHIFT]; 84.162 - m->guest_pl2e_cache[va >> L2_PAGETABLE_SHIFT] = 84.163 - mk_l2_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 84.164 + ed->arch.guest_pl2e_cache[l2_table_offset(va)] = 84.165 + mk_l2_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 84.166 84.167 - m->vpagetable[va >> L2_PAGETABLE_SHIFT] = mk_l2_pgentry(value); 84.168 + ed->arch.vpagetable[l2_table_offset(va)] = mk_l2_pgentry(value); 84.169 } 84.170 else 84.171 - linear_l2_table[va >> L2_PAGETABLE_SHIFT] = mk_l2_pgentry(value); 84.172 - 84.173 + { 84.174 + linear_l2_table[l2_table_offset(va)] = mk_l2_pgentry(value); 84.175 + } 84.176 } 84.177 84.178 /************************************************************************/ 84.179 84.180 -static inline int __mark_dirty( struct mm_struct *m, unsigned int mfn) 84.181 +static inline int __mark_dirty(struct domain *d, unsigned int mfn) 84.182 { 84.183 unsigned long pfn; 84.184 int rc = 0; 84.185 84.186 - ASSERT(spin_is_locked(&m->shadow_lock)); 84.187 - ASSERT(m->shadow_dirty_bitmap != NULL); 84.188 + ASSERT(spin_is_locked(&d->arch.shadow_lock)); 84.189 + ASSERT(d->arch.shadow_dirty_bitmap != NULL); 84.190 84.191 pfn = machine_to_phys_mapping[mfn]; 84.192 84.193 @@ -174,20 +171,20 @@ static inline int __mark_dirty( struct m 84.194 if ( unlikely(pfn & 0x80000000UL) ) 84.195 return rc; 84.196 84.197 - if ( likely(pfn < m->shadow_dirty_bitmap_size) ) 84.198 + if ( likely(pfn < d->arch.shadow_dirty_bitmap_size) ) 84.199 { 84.200 /* N.B. Can use non-atomic TAS because protected by shadow_lock. */ 84.201 - if ( !__test_and_set_bit(pfn, m->shadow_dirty_bitmap) ) 84.202 + if ( !__test_and_set_bit(pfn, d->arch.shadow_dirty_bitmap) ) 84.203 { 84.204 - m->shadow_dirty_count++; 84.205 + d->arch.shadow_dirty_count++; 84.206 rc = 1; 84.207 } 84.208 } 84.209 #ifndef NDEBUG 84.210 else if ( mfn < max_page ) 84.211 { 84.212 - SH_LOG("mark_dirty OOR! mfn=%x pfn=%lx max=%x (mm %p)", 84.213 - mfn, pfn, m->shadow_dirty_bitmap_size, m ); 84.214 + SH_LOG("mark_dirty OOR! mfn=%x pfn=%lx max=%x (dom %p)", 84.215 + mfn, pfn, d->arch.shadow_dirty_bitmap_size, d); 84.216 SH_LOG("dom=%p caf=%08x taf=%08x\n", 84.217 page_get_owner(&frame_table[mfn]), 84.218 frame_table[mfn].count_info, 84.219 @@ -199,12 +196,12 @@ static inline int __mark_dirty( struct m 84.220 } 84.221 84.222 84.223 -static inline int mark_dirty(struct mm_struct *m, unsigned int mfn) 84.224 +static inline int mark_dirty(struct domain *d, unsigned int mfn) 84.225 { 84.226 int rc; 84.227 - shadow_lock(m); 84.228 - rc = __mark_dirty(m, mfn); 84.229 - shadow_unlock(m); 84.230 + shadow_lock(d); 84.231 + rc = __mark_dirty(d, mfn); 84.232 + shadow_unlock(d); 84.233 return rc; 84.234 } 84.235 84.236 @@ -212,7 +209,7 @@ static inline int mark_dirty(struct mm_s 84.237 /************************************************************************/ 84.238 84.239 static inline void l1pte_write_fault( 84.240 - struct mm_struct *m, unsigned long *gpte_p, unsigned long *spte_p) 84.241 + struct domain *d, unsigned long *gpte_p, unsigned long *spte_p) 84.242 { 84.243 unsigned long gpte = *gpte_p; 84.244 unsigned long spte = *spte_p; 84.245 @@ -220,7 +217,7 @@ static inline void l1pte_write_fault( 84.246 ASSERT(gpte & _PAGE_RW); 84.247 gpte |= _PAGE_DIRTY | _PAGE_ACCESSED; 84.248 84.249 - switch ( m->shadow_mode ) 84.250 + switch ( d->arch.shadow_mode ) 84.251 { 84.252 case SHM_test: 84.253 spte = gpte | _PAGE_RW; 84.254 @@ -228,7 +225,7 @@ static inline void l1pte_write_fault( 84.255 84.256 case SHM_logdirty: 84.257 spte = gpte | _PAGE_RW; 84.258 - __mark_dirty(m, gpte >> PAGE_SHIFT); 84.259 + __mark_dirty(d, gpte >> PAGE_SHIFT); 84.260 84.261 case SHM_full_32: 84.262 { 84.263 @@ -247,14 +244,14 @@ static inline void l1pte_write_fault( 84.264 } 84.265 84.266 static inline void l1pte_read_fault( 84.267 - struct mm_struct *m, unsigned long *gpte_p, unsigned long *spte_p) 84.268 + struct domain *d, unsigned long *gpte_p, unsigned long *spte_p) 84.269 { 84.270 unsigned long gpte = *gpte_p; 84.271 unsigned long spte = *spte_p; 84.272 84.273 gpte |= _PAGE_ACCESSED; 84.274 84.275 - switch ( m->shadow_mode ) 84.276 + switch ( d->arch.shadow_mode ) 84.277 { 84.278 case SHM_test: 84.279 spte = (gpte & _PAGE_DIRTY) ? gpte : (gpte & ~_PAGE_RW); 84.280 @@ -281,12 +278,13 @@ static inline void l1pte_read_fault( 84.281 } 84.282 84.283 static inline void l1pte_propagate_from_guest( 84.284 - struct mm_struct *m, unsigned long *gpte_p, unsigned long *spte_p) 84.285 + struct domain *d, unsigned long *gpte_p, unsigned long *spte_p) 84.286 { 84.287 unsigned long gpte = *gpte_p; 84.288 unsigned long spte = *spte_p; 84.289 + unsigned long host_pfn, host_gpte; 84.290 84.291 - switch ( m->shadow_mode ) 84.292 + switch ( d->arch.shadow_mode ) 84.293 { 84.294 case SHM_test: 84.295 spte = 0; 84.296 @@ -303,11 +301,10 @@ static inline void l1pte_propagate_from_ 84.297 break; 84.298 84.299 case SHM_full_32: 84.300 - { 84.301 - unsigned long host_pfn, host_gpte; 84.302 spte = 0; 84.303 84.304 - if (mmio_space(gpte & 0xFFFFF000)) { 84.305 + if ( mmio_space(gpte & 0xFFFFF000) ) 84.306 + { 84.307 *spte_p = spte; 84.308 return; 84.309 } 84.310 @@ -317,8 +314,9 @@ static inline void l1pte_propagate_from_ 84.311 84.312 if ( (host_gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 84.313 (_PAGE_PRESENT|_PAGE_ACCESSED) ) 84.314 - spte = (host_gpte & _PAGE_DIRTY) ? host_gpte : (host_gpte & ~_PAGE_RW); 84.315 - } 84.316 + spte = (host_gpte & _PAGE_DIRTY) ? 84.317 + host_gpte : (host_gpte & ~_PAGE_RW); 84.318 + 84.319 break; 84.320 } 84.321 84.322 @@ -327,7 +325,7 @@ static inline void l1pte_propagate_from_ 84.323 } 84.324 84.325 static inline void l2pde_general( 84.326 - struct mm_struct *m, 84.327 + struct domain *d, 84.328 unsigned long *gpde_p, 84.329 unsigned long *spde_p, 84.330 unsigned long sl1pfn) 84.331 @@ -347,7 +345,7 @@ static inline void l2pde_general( 84.332 if ( (frame_table[sl1pfn].u.inuse.type_info & PGT_type_mask) == 84.333 PGT_l2_page_table ) 84.334 { 84.335 - if (m->shadow_mode != SHM_full_32) 84.336 + if ( d->arch.shadow_mode != SHM_full_32 ) 84.337 spde = gpde & ~_PAGE_RW; 84.338 84.339 } 84.340 @@ -360,14 +358,14 @@ static inline void l2pde_general( 84.341 /*********************************************************************/ 84.342 84.343 #if SHADOW_HASH_DEBUG 84.344 -static void shadow_audit(struct mm_struct *m, int print) 84.345 +static void shadow_audit(struct domain *d, int print) 84.346 { 84.347 int live = 0, free = 0, j = 0, abs; 84.348 struct shadow_status *a; 84.349 84.350 for ( j = 0; j < shadow_ht_buckets; j++ ) 84.351 { 84.352 - a = &m->shadow_ht[j]; 84.353 + a = &d->arch.shadow_ht[j]; 84.354 if ( a->pfn ) { live++; ASSERT(a->spfn_and_flags & PSH_pfn_mask); } 84.355 ASSERT(a->pfn < 0x00100000UL); 84.356 a = a->next; 84.357 @@ -387,7 +385,7 @@ static void shadow_audit(struct mm_struc 84.358 ASSERT(live < 9999); 84.359 } 84.360 84.361 - for ( a = m->shadow_ht_free; a != NULL; a = a->next ) 84.362 + for ( a = d->arch.shadow_ht_free; a != NULL; a = a->next ) 84.363 free++; 84.364 84.365 if ( print) 84.366 @@ -406,24 +404,23 @@ static void shadow_audit(struct mm_struc 84.367 #endif 84.368 84.369 84.370 - 84.371 static inline struct shadow_status *hash_bucket( 84.372 - struct mm_struct *m, unsigned int gpfn) 84.373 + struct domain *d, unsigned int gpfn) 84.374 { 84.375 - return &m->shadow_ht[gpfn % shadow_ht_buckets]; 84.376 + return &d->arch.shadow_ht[gpfn % shadow_ht_buckets]; 84.377 } 84.378 84.379 84.380 static inline unsigned long __shadow_status( 84.381 - struct mm_struct *m, unsigned int gpfn) 84.382 + struct domain *d, unsigned int gpfn) 84.383 { 84.384 struct shadow_status *p, *x, *head; 84.385 84.386 - x = head = hash_bucket(m, gpfn); 84.387 + x = head = hash_bucket(d, gpfn); 84.388 p = NULL; 84.389 84.390 SH_VVLOG("lookup gpfn=%08x bucket=%p", gpfn, x); 84.391 - shadow_audit(m, 0); 84.392 + shadow_audit(d, 0); 84.393 84.394 do 84.395 { 84.396 @@ -461,11 +458,11 @@ static inline unsigned long __shadow_sta 84.397 * anyway it's probably not worth being too clever. 84.398 */ 84.399 static inline unsigned long get_shadow_status( 84.400 - struct mm_struct *m, unsigned int gpfn ) 84.401 + struct domain *d, unsigned int gpfn ) 84.402 { 84.403 unsigned long res; 84.404 84.405 - ASSERT(m->shadow_mode); 84.406 + ASSERT(d->arch.shadow_mode); 84.407 84.408 /* 84.409 * If we get here we know that some sort of update has happened to the 84.410 @@ -475,37 +472,37 @@ static inline unsigned long get_shadow_s 84.411 * N.B. The VA update path doesn't use this and is handled independently. 84.412 */ 84.413 84.414 - shadow_lock(m); 84.415 + shadow_lock(d); 84.416 84.417 - if ( m->shadow_mode == SHM_logdirty ) 84.418 - __mark_dirty( m, gpfn ); 84.419 + if ( d->arch.shadow_mode == SHM_logdirty ) 84.420 + __mark_dirty(d, gpfn); 84.421 84.422 - if ( !(res = __shadow_status(m, gpfn)) ) 84.423 - shadow_unlock(m); 84.424 + if ( !(res = __shadow_status(d, gpfn)) ) 84.425 + shadow_unlock(d); 84.426 84.427 return res; 84.428 } 84.429 84.430 84.431 static inline void put_shadow_status( 84.432 - struct mm_struct *m) 84.433 + struct domain *d) 84.434 { 84.435 - shadow_unlock(m); 84.436 + shadow_unlock(d); 84.437 } 84.438 84.439 84.440 static inline void delete_shadow_status( 84.441 - struct mm_struct *m, unsigned int gpfn) 84.442 + struct domain *d, unsigned int gpfn) 84.443 { 84.444 struct shadow_status *p, *x, *n, *head; 84.445 84.446 - ASSERT(spin_is_locked(&m->shadow_lock)); 84.447 + ASSERT(spin_is_locked(&d->arch.shadow_lock)); 84.448 ASSERT(gpfn != 0); 84.449 84.450 - head = hash_bucket(m, gpfn); 84.451 + head = hash_bucket(d, gpfn); 84.452 84.453 SH_VVLOG("delete gpfn=%08x bucket=%p", gpfn, head); 84.454 - shadow_audit(m, 0); 84.455 + shadow_audit(d, 0); 84.456 84.457 /* Match on head item? */ 84.458 if ( head->pfn == gpfn ) 84.459 @@ -522,8 +519,8 @@ static inline void delete_shadow_status( 84.460 /* Add deleted node to the free list. */ 84.461 n->pfn = 0; 84.462 n->spfn_and_flags = 0; 84.463 - n->next = m->shadow_ht_free; 84.464 - m->shadow_ht_free = n; 84.465 + n->next = d->arch.shadow_ht_free; 84.466 + d->arch.shadow_ht_free = n; 84.467 } 84.468 else 84.469 { 84.470 @@ -548,8 +545,8 @@ static inline void delete_shadow_status( 84.471 /* Add deleted node to the free list. */ 84.472 x->pfn = 0; 84.473 x->spfn_and_flags = 0; 84.474 - x->next = m->shadow_ht_free; 84.475 - m->shadow_ht_free = x; 84.476 + x->next = d->arch.shadow_ht_free; 84.477 + d->arch.shadow_ht_free = x; 84.478 84.479 goto found; 84.480 } 84.481 @@ -563,24 +560,24 @@ static inline void delete_shadow_status( 84.482 BUG(); 84.483 84.484 found: 84.485 - shadow_audit(m, 0); 84.486 + shadow_audit(d, 0); 84.487 } 84.488 84.489 84.490 static inline void set_shadow_status( 84.491 - struct mm_struct *m, unsigned int gpfn, unsigned long s) 84.492 + struct domain *d, unsigned int gpfn, unsigned long s) 84.493 { 84.494 struct shadow_status *x, *head, *extra; 84.495 int i; 84.496 84.497 - ASSERT(spin_is_locked(&m->shadow_lock)); 84.498 + ASSERT(spin_is_locked(&d->arch.shadow_lock)); 84.499 ASSERT(gpfn != 0); 84.500 ASSERT(s & PSH_shadowed); 84.501 84.502 - x = head = hash_bucket(m, gpfn); 84.503 + x = head = hash_bucket(d, gpfn); 84.504 84.505 SH_VVLOG("set gpfn=%08x s=%08lx bucket=%p(%p)", gpfn, s, x, x->next); 84.506 - shadow_audit(m, 0); 84.507 + shadow_audit(d, 0); 84.508 84.509 /* 84.510 * STEP 1. If page is already in the table, update it in place. 84.511 @@ -612,7 +609,7 @@ static inline void set_shadow_status( 84.512 } 84.513 84.514 /* We need to allocate a new node. Ensure the quicklist is non-empty. */ 84.515 - if ( unlikely(m->shadow_ht_free == NULL) ) 84.516 + if ( unlikely(d->arch.shadow_ht_free == NULL) ) 84.517 { 84.518 SH_LOG("Allocate more shadow hashtable blocks."); 84.519 84.520 @@ -626,10 +623,10 @@ static inline void set_shadow_status( 84.521 memset(extra, 0, sizeof(void *) + (shadow_ht_extra_size * sizeof(*x))); 84.522 84.523 /* Record the allocation block so it can be correctly freed later. */ 84.524 - m->shadow_extras_count++; 84.525 + d->arch.shadow_extras_count++; 84.526 *((struct shadow_status **)&extra[shadow_ht_extra_size]) = 84.527 - m->shadow_ht_extras; 84.528 - m->shadow_ht_extras = &extra[0]; 84.529 + d->arch.shadow_ht_extras; 84.530 + d->arch.shadow_ht_extras = &extra[0]; 84.531 84.532 /* Thread a free chain through the newly-allocated nodes. */ 84.533 for ( i = 0; i < (shadow_ht_extra_size - 1); i++ ) 84.534 @@ -637,12 +634,12 @@ static inline void set_shadow_status( 84.535 extra[i].next = NULL; 84.536 84.537 /* Add the new nodes to the free list. */ 84.538 - m->shadow_ht_free = &extra[0]; 84.539 + d->arch.shadow_ht_free = &extra[0]; 84.540 } 84.541 84.542 /* Allocate a new node from the quicklist. */ 84.543 - x = m->shadow_ht_free; 84.544 - m->shadow_ht_free = x->next; 84.545 + x = d->arch.shadow_ht_free; 84.546 + d->arch.shadow_ht_free = x->next; 84.547 84.548 /* Initialise the new node and insert directly after the head item. */ 84.549 x->pfn = gpfn; 84.550 @@ -651,50 +648,51 @@ static inline void set_shadow_status( 84.551 head->next = x; 84.552 84.553 done: 84.554 - shadow_audit(m, 0); 84.555 + shadow_audit(d, 0); 84.556 } 84.557 84.558 #ifdef CONFIG_VMX 84.559 #include <asm/domain_page.h> 84.560 84.561 static inline void vmx_update_shadow_state( 84.562 - struct mm_struct *mm, unsigned long gpfn, unsigned long spfn) 84.563 + struct exec_domain *ed, unsigned long gpfn, unsigned long spfn) 84.564 { 84.565 84.566 l2_pgentry_t *mpl2e = 0; 84.567 l2_pgentry_t *gpl2e, *spl2e; 84.568 84.569 /* unmap the old mappings */ 84.570 - if (mm->shadow_vtable) 84.571 - unmap_domain_mem(mm->shadow_vtable); 84.572 - if (mm->vpagetable) 84.573 - unmap_domain_mem(mm->vpagetable); 84.574 + if ( ed->arch.shadow_vtable ) 84.575 + unmap_domain_mem(ed->arch.shadow_vtable); 84.576 + if ( ed->arch.vpagetable ) 84.577 + unmap_domain_mem(ed->arch.vpagetable); 84.578 84.579 /* new mapping */ 84.580 - mpl2e = (l2_pgentry_t *) 84.581 - map_domain_mem(pagetable_val(mm->monitor_table)); 84.582 + mpl2e = (l2_pgentry_t *) 84.583 + map_domain_mem(pagetable_val(ed->arch.monitor_table)); 84.584 84.585 - mpl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = 84.586 + mpl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] = 84.587 mk_l2_pgentry((spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR); 84.588 __flush_tlb_one(SH_LINEAR_PT_VIRT_START); 84.589 84.590 - spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT); 84.591 - gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT); 84.592 + spl2e = (l2_pgentry_t *)map_domain_mem(spfn << PAGE_SHIFT); 84.593 + gpl2e = (l2_pgentry_t *)map_domain_mem(gpfn << PAGE_SHIFT); 84.594 memset(spl2e, 0, ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t)); 84.595 84.596 - mm->shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.597 - mm->shadow_vtable = spl2e; 84.598 - mm->vpagetable = gpl2e; /* expect the guest did clean this up */ 84.599 + ed->arch.shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.600 + ed->arch.shadow_vtable = spl2e; 84.601 + ed->arch.vpagetable = gpl2e; /* expect the guest did clean this up */ 84.602 unmap_domain_mem(mpl2e); 84.603 } 84.604 84.605 -static inline void __shadow_mk_pagetable( struct mm_struct *mm ) 84.606 +static inline void __shadow_mk_pagetable(struct exec_domain *ed) 84.607 { 84.608 - unsigned long gpfn = pagetable_val(mm->pagetable) >> PAGE_SHIFT; 84.609 + struct domain *d = ed->domain; 84.610 + unsigned long gpfn = pagetable_val(ed->arch.pagetable) >> PAGE_SHIFT; 84.611 unsigned long spfn; 84.612 SH_VLOG("0: __shadow_mk_pagetable(gpfn=%08lx\n", gpfn); 84.613 84.614 - if (mm->shadow_mode == SHM_full_32) 84.615 + if (d->arch.shadow_mode == SHM_full_32) 84.616 { 84.617 unsigned long guest_gpfn; 84.618 guest_gpfn = machine_to_phys_mapping[gpfn]; 84.619 @@ -702,59 +700,59 @@ static inline void __shadow_mk_pagetable 84.620 SH_VVLOG("__shadow_mk_pagetable(guest_gpfn=%08lx, gpfn=%08lx\n", 84.621 guest_gpfn, gpfn); 84.622 84.623 - spfn = __shadow_status(mm, guest_gpfn) & PSH_pfn_mask; 84.624 + spfn = __shadow_status(d, guest_gpfn) & PSH_pfn_mask; 84.625 if ( unlikely(spfn == 0) ) { 84.626 - spfn = shadow_l2_table(mm, gpfn); 84.627 - mm->shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.628 + spfn = shadow_l2_table(d, gpfn); 84.629 + ed->arch.shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.630 } else { 84.631 - vmx_update_shadow_state(mm, gpfn, spfn); 84.632 + vmx_update_shadow_state(ed, gpfn, spfn); 84.633 } 84.634 } else { 84.635 - spfn = __shadow_status(mm, gpfn) & PSH_pfn_mask; 84.636 + spfn = __shadow_status(d, gpfn) & PSH_pfn_mask; 84.637 84.638 if ( unlikely(spfn == 0) ) { 84.639 - spfn = shadow_l2_table(mm, gpfn); 84.640 + spfn = shadow_l2_table(d, gpfn); 84.641 } 84.642 - mm->shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.643 + ed->arch.shadow_table = mk_pagetable(spfn<<PAGE_SHIFT); 84.644 } 84.645 } 84.646 #else 84.647 -static inline void __shadow_mk_pagetable(struct mm_struct *mm) 84.648 +static inline void __shadow_mk_pagetable(struct exec_domain *ed) 84.649 { 84.650 - unsigned long gpfn = pagetable_val(mm->pagetable) >> PAGE_SHIFT; 84.651 - unsigned long spfn = __shadow_status(mm, gpfn); 84.652 + unsigned long gpfn = pagetable_val(ed->arch.pagetable) >> PAGE_SHIFT; 84.653 + unsigned long spfn = __shadow_status(ed->domain, gpfn); 84.654 84.655 if ( unlikely(spfn == 0) ) 84.656 - spfn = shadow_l2_table(mm, gpfn); 84.657 + spfn = shadow_l2_table(ed->domain, gpfn); 84.658 84.659 - mm->shadow_table = mk_pagetable(spfn << PAGE_SHIFT); 84.660 + ed->arch.shadow_table = mk_pagetable(spfn << PAGE_SHIFT); 84.661 } 84.662 #endif /* CONFIG_VMX */ 84.663 84.664 -static inline void shadow_mk_pagetable(struct mm_struct *mm) 84.665 +static inline void shadow_mk_pagetable(struct exec_domain *ed) 84.666 { 84.667 - if ( unlikely(mm->shadow_mode) ) 84.668 + if ( unlikely(ed->domain->arch.shadow_mode) ) 84.669 { 84.670 SH_VVLOG("shadow_mk_pagetable( gptbase=%08lx, mode=%d )", 84.671 - pagetable_val(mm->pagetable), mm->shadow_mode ); 84.672 + pagetable_val(ed->arch.pagetable), 84.673 + ed->domain->arch.shadow_mode); 84.674 84.675 - shadow_lock(mm); 84.676 - __shadow_mk_pagetable(mm); 84.677 - shadow_unlock(mm); 84.678 + shadow_lock(ed->domain); 84.679 + __shadow_mk_pagetable(ed); 84.680 + shadow_unlock(ed->domain); 84.681 84.682 - SH_VVLOG("leaving shadow_mk_pagetable:\n"); 84.683 - 84.684 - SH_VVLOG("( gptbase=%08lx, mode=%d ) sh=%08lx", 84.685 - pagetable_val(mm->pagetable), mm->shadow_mode, 84.686 - pagetable_val(mm->shadow_table) ); 84.687 - 84.688 - } 84.689 + SH_VVLOG("leaving shadow_mk_pagetable:\n" 84.690 + "( gptbase=%08lx, mode=%d ) sh=%08lx", 84.691 + pagetable_val(ed->arch.pagetable), 84.692 + ed->domain->arch.shadow_mode, 84.693 + pagetable_val(ed->arch.shadow_table) ); 84.694 + } 84.695 } 84.696 84.697 #if SHADOW_DEBUG 84.698 -extern int check_pagetable(struct mm_struct *m, pagetable_t pt, char *s); 84.699 +extern int check_pagetable(struct domain *d, pagetable_t pt, char *s); 84.700 #else 84.701 -#define check_pagetable(m, pt, s) ((void)0) 84.702 +#define check_pagetable(d, pt, s) ((void)0) 84.703 #endif 84.704 84.705 #endif /* XEN_SHADOW_H */
85.1 --- a/xen/include/asm-x86/vmx_platform.h Fri Feb 04 19:26:10 2005 +0000 85.2 +++ b/xen/include/asm-x86/vmx_platform.h Mon Feb 07 08:19:24 2005 +0000 85.3 @@ -19,7 +19,8 @@ 85.4 #ifndef __ASM_X86_VMX_PLATFORM_H__ 85.5 #define __ASM_X86_VMX_PLATFORM_H__ 85.6 85.7 -#include <asm/e820.h> /* from Linux */ 85.8 +#include <public/xen.h> 85.9 +#include <asm/e820.h> 85.10 85.11 #define MAX_OPERAND_NUM 3 85.12 #define I_NAME_LEN 16
86.1 --- a/xen/include/asm-x86/vmx_vmcs.h Fri Feb 04 19:26:10 2005 +0000 86.2 +++ b/xen/include/asm-x86/vmx_vmcs.h Mon Feb 07 08:19:24 2005 +0000 86.3 @@ -1,3 +1,4 @@ 86.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 86.5 /* 86.6 * vmx_vmcs.h: VMCS related definitions 86.7 * Copyright (c) 2004, Intel Corporation. 86.8 @@ -59,7 +60,7 @@ struct arch_vmx_struct { 86.9 #define vmx_schedule_tail(next) \ 86.10 (next)->thread.arch_vmx.arch_vmx_schedule_tail((next)) 86.11 86.12 -#define VMX_DOMAIN(d) d->thread.arch_vmx.flags 86.13 +#define VMX_DOMAIN(d) d->arch.arch_vmx.flags 86.14 86.15 #define ARCH_VMX_VMCS_LOADED 0 /* VMCS has been loaded and active */ 86.16 #define ARCH_VMX_VMCS_LAUNCH 1 /* Needs VMCS launch */
87.1 --- a/xen/include/asm-x86/x86_32/current.h Fri Feb 04 19:26:10 2005 +0000 87.2 +++ b/xen/include/asm-x86/x86_32/current.h Mon Feb 07 08:19:24 2005 +0000 87.3 @@ -1,3 +1,5 @@ 87.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ 87.5 + 87.6 #ifndef _X86_CURRENT_H 87.7 #define _X86_CURRENT_H 87.8 87.9 @@ -50,6 +52,6 @@ static inline unsigned long get_stack_to 87.10 "movl %0,%%esp; jmp "STR(__fn) \ 87.11 : : "r" (get_execution_context()) ) 87.12 87.13 -#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d) 87.14 +#define schedule_tail(_ed) ((_ed)->arch.schedule_tail)(_ed) 87.15 87.16 #endif /* _X86_CURRENT_H */
88.1 --- a/xen/include/asm-x86/x86_32/uaccess.h Fri Feb 04 19:26:10 2005 +0000 88.2 +++ b/xen/include/asm-x86/x86_32/uaccess.h Mon Feb 07 08:19:24 2005 +0000 88.3 @@ -10,9 +10,7 @@ 88.4 #include <xen/string.h> 88.5 #include <xen/sched.h> 88.6 88.7 -/* No user-pointer checking. */ 88.8 #define __user 88.9 -#define __chk_user_ptr(_p) ((void)0) 88.10 88.11 #define VERIFY_READ 0 88.12 #define VERIFY_WRITE 1 88.13 @@ -22,7 +20,7 @@ 88.14 */ 88.15 #ifdef CONFIG_X86_INTEL_USERCOPY 88.16 extern struct movsl_mask { 88.17 - int mask; 88.18 + int mask; 88.19 } __cacheline_aligned movsl_mask; 88