# HG changeset patch # User mwilli2@equilibrium.research # Date 1096577154 0 # Node ID 4ecd18756ef8ebe93653c1f9a7815ae3ebb4651b # Parent 82cab392896d28abe019e67eae1ec88728925052# Parent 1293cc819fed210df2780b2057424c5b18a2b1ba bitkeeper revision 1.1159.1.192 (415c7082v4eKZkH-NXLbAR9bU6B8hg) Merge ssh://srg//auto/groups/xeno/BK/xeno-unstable.bk into equilibrium.research:/export/scratch/xeno-blkscripts.bk diff -r 82cab392896d -r 4ecd18756ef8 linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c Tue Sep 28 14:47:51 2004 +0000 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c Thu Sep 30 20:45:54 2004 +0000 @@ -126,14 +126,14 @@ u64 processed_system_time; /* System t (_tv).tv_sec++; \ } \ } while (0) -static inline void __normalize_time(time_t *sec, s64 *usec) +static inline void __normalize_time(time_t *sec, s64 *nsec) { - while (*usec >= NSEC_PER_SEC) { - (*usec) -= NSEC_PER_SEC; + while (*nsec >= NSEC_PER_SEC) { + (*nsec) -= NSEC_PER_SEC; (*sec)++; } - while (*usec < NSEC_PER_SEC) { - (*usec) += NSEC_PER_SEC; + while (*nsec < 0) { + (*nsec) += NSEC_PER_SEC; (*sec)--; } } diff -r 82cab392896d -r 4ecd18756ef8 linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Sep 28 14:47:51 2004 +0000 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Sep 30 20:45:54 2004 +0000 @@ -554,6 +554,8 @@ int blkif_ioctl(struct inode *inode, str struct gendisk *gd; struct hd_struct *part; int i; + unsigned short cylinders; + byte heads, sectors; /* NB. No need to check permissions. That is done for us. */ @@ -598,23 +600,39 @@ int blkif_ioctl(struct inode *inode, str break; case HDIO_GETGEO: - /* note: these values are complete garbage */ DPRINTK_IOCTL(" HDIO_GETGEO: %x\n", HDIO_GETGEO); if (!argument) return -EINVAL; + + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + + heads = 0xff; + sectors = 0x3f; + cylinders = part->nr_sects / (heads * sectors); + if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT; - if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT; - if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT; - if (put_user(0x106, (unsigned short *)&geo->cylinders)) return -EFAULT; + if (put_user(heads, (byte *)&geo->heads)) return -EFAULT; + if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT; + if (put_user(cylinders, (unsigned short *)&geo->cylinders)) return -EFAULT; + return 0; case HDIO_GETGEO_BIG: - /* note: these values are complete garbage */ DPRINTK_IOCTL(" HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG); if (!argument) return -EINVAL; + + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + + heads = 0xff; + sectors = 0x3f; + cylinders = part->nr_sects / (heads * sectors); + if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT; - if (put_user(0xff, (byte *)&geo->heads)) return -EFAULT; - if (put_user(0x3f, (byte *)&geo->sectors)) return -EFAULT; - if (put_user(0x106, (unsigned int *) &geo->cylinders)) return -EFAULT; + if (put_user(heads, (byte *)&geo->heads)) return -EFAULT; + if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT; + if (put_user(cylinders, (unsigned int *) &geo->cylinders)) return -EFAULT; + return 0; case CDROMMULTISESSION: diff -r 82cab392896d -r 4ecd18756ef8 linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c Tue Sep 28 14:47:51 2004 +0000 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c Thu Sep 30 20:45:54 2004 +0000 @@ -31,22 +31,6 @@ #define DEBUG 0 -#if DEBUG -#define DPRINTK(fmt, args...) \ - printk(KERN_INFO "[XEN] %s" fmt, __FUNCTION__, ##args) -#else -#define DPRINTK(fmt, args...) ((void)0) -#endif - -#define IPRINTK(fmt, args...) \ - printk(KERN_INFO "[XEN]" fmt, ##args) - -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "[XEN]" fmt, ##args) - -#define EPRINTK(fmt, args...) \ - printk(KERN_ERROR "[XEN]" fmt, ##args) - #ifndef __GFP_NOWARN #define __GFP_NOWARN 0 #endif @@ -114,6 +98,12 @@ struct net_private #define UST_OPEN 1 unsigned int user_state; + /* Receive-ring batched refills. */ +#define RX_MIN_TARGET 8 +#define RX_MAX_TARGET NETIF_RX_RING_SIZE + int rx_target; + struct sk_buff_head rx_batch; + /* * {tx,rx}_skbs store outstanding skbuffs. The first entry in each * array is an index into a chain of free entries. @@ -122,24 +112,6 @@ struct net_private struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; }; -char * status_name[] = { - [NETIF_INTERFACE_STATUS_CLOSED] = "closed", - [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", - [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", - [NETIF_INTERFACE_STATUS_CHANGED] = "changed", -}; - -char * be_state_name[] = { - [BEST_CLOSED] = "closed", - [BEST_DISCONNECTED] = "disconnected", - [BEST_CONNECTED] = "connected", -}; - -char * user_state_name[] = { - [UST_CLOSED] = "closed", - [UST_OPEN] = "open", -}; - /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ #define ADD_ID_TO_FREELIST(_list, _id) \ (_list)[(_id)] = (_list)[0]; \ @@ -149,6 +121,30 @@ char * user_state_name[] = { (_list)[0] = (_list)[_id]; \ (unsigned short)_id; }) +static char *status_name[] = { + [NETIF_INTERFACE_STATUS_CLOSED] = "closed", + [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", + [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", + [NETIF_INTERFACE_STATUS_CHANGED] = "changed", +}; + +static char *be_state_name[] = { + [BEST_CLOSED] = "closed", + [BEST_DISCONNECTED] = "disconnected", + [BEST_CONNECTED] = "connected", +}; + +#if DEBUG +#define DPRINTK(fmt, args...) \ + printk(KERN_ALERT "[XEN] (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args) +#else +#define DPRINTK(fmt, args...) ((void)0) +#endif +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "[XEN] " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "[XEN] " fmt, ##args) + static struct net_device *find_dev_by_handle(unsigned int handle) { struct list_head *ent; @@ -185,9 +181,8 @@ static void netctrl_init(void) */ static int netctrl_err(int err) { - if ( (err < 0) && !netctrl.err ){ + if ( (err < 0) && !netctrl.err ) netctrl.err = err; - } return netctrl.err; } @@ -197,13 +192,15 @@ static int netctrl_err(int err) */ static int netctrl_connected(void) { - int ok = 0; + int ok; - if(netctrl.err){ + if ( netctrl.err ) ok = netctrl.err; - } else if(netctrl.up == NETIF_DRIVER_STATUS_UP){ + else if ( netctrl.up == NETIF_DRIVER_STATUS_UP ) ok = (netctrl.connected_n == netctrl.interface_n); - } + else + ok = 0; + return ok; } @@ -222,9 +219,8 @@ static int netctrl_connected_count(void) list_for_each(ent, &dev_list) { np = list_entry(ent, struct net_private, list); - if (np->backend_state == BEST_CONNECTED){ + if (np->backend_state == BEST_CONNECTED) connected++; - } } netctrl.connected_n = connected; @@ -326,17 +322,34 @@ static void network_alloc_rx_buffers(str unsigned short id; struct net_private *np = dev->priv; struct sk_buff *skb; - NETIF_RING_IDX i = np->rx->req_prod; - int nr_pfns = 0; + int i, batch_target; + NETIF_RING_IDX req_prod = np->rx->req_prod; - /* Make sure the batch is large enough to be worthwhile (1/2 ring). */ - if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) || - unlikely(np->backend_state != BEST_CONNECTED) ) + if ( unlikely(np->backend_state != BEST_CONNECTED) ) return; - do { + /* + * Allocate skbuffs greedily, even though we batch updates to the + * receive ring. This creates a less bursty demand on the memory allocator, + * so should reduce the chance of failed allocation requests both for + * ourself and for other kernel subsystems. + */ + batch_target = np->rx_target - (req_prod - np->rx_resp_cons); + for ( i = skb_queue_len(&np->rx_batch); i < batch_target; i++ ) + { if ( unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL) ) break; + __skb_queue_tail(&np->rx_batch, skb); + } + + /* Is the batch large enough to be worthwhile? */ + if ( i < (np->rx_target/2) ) + return; + + for ( i = 0; ; i++ ) + { + if ( (skb = __skb_dequeue(&np->rx_batch)) == NULL ) + break; skb->dev = dev; @@ -344,25 +357,19 @@ static void network_alloc_rx_buffers(str np->rx_skbs[id] = skb; - np->rx->ring[MASK_NETIF_RX_IDX(i)].req.id = id; + np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id; - rx_pfn_array[nr_pfns] = virt_to_machine(skb->head) >> PAGE_SHIFT; + rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT; /* Remove this page from pseudo phys map before passing back to Xen. */ phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] = INVALID_P2M_ENTRY; - rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping; - rx_mcl[nr_pfns].args[0] = (unsigned long)skb->head >> PAGE_SHIFT; - rx_mcl[nr_pfns].args[1] = 0; - rx_mcl[nr_pfns].args[2] = 0; - - nr_pfns++; + rx_mcl[i].op = __HYPERVISOR_update_va_mapping; + rx_mcl[i].args[0] = (unsigned long)skb->head >> PAGE_SHIFT; + rx_mcl[i].args[1] = 0; + rx_mcl[i].args[2] = 0; } - while ( (++i - np->rx_resp_cons) != NETIF_RX_RING_SIZE ); - - if ( unlikely(nr_pfns == 0) ) - return; /* * We may have allocated buffers which have entries outstanding in the page @@ -371,25 +378,30 @@ static void network_alloc_rx_buffers(str flush_page_update_queue(); /* After all PTEs have been zapped we blow away stale TLB entries. */ - rx_mcl[nr_pfns-1].args[2] = UVMF_FLUSH_TLB; + rx_mcl[i-1].args[2] = UVMF_FLUSH_TLB; /* Give away a batch of pages. */ - rx_mcl[nr_pfns].op = __HYPERVISOR_dom_mem_op; - rx_mcl[nr_pfns].args[0] = MEMOP_decrease_reservation; - rx_mcl[nr_pfns].args[1] = (unsigned long)rx_pfn_array; - rx_mcl[nr_pfns].args[2] = (unsigned long)nr_pfns; - rx_mcl[nr_pfns].args[3] = 0; - rx_mcl[nr_pfns].args[4] = DOMID_SELF; + rx_mcl[i].op = __HYPERVISOR_dom_mem_op; + rx_mcl[i].args[0] = MEMOP_decrease_reservation; + rx_mcl[i].args[1] = (unsigned long)rx_pfn_array; + rx_mcl[i].args[2] = (unsigned long)i; + rx_mcl[i].args[3] = 0; + rx_mcl[i].args[4] = DOMID_SELF; /* Zap PTEs and give away pages in one big multicall. */ - (void)HYPERVISOR_multicall(rx_mcl, nr_pfns+1); + (void)HYPERVISOR_multicall(rx_mcl, i+1); /* Check return status of HYPERVISOR_dom_mem_op(). */ - if ( rx_mcl[nr_pfns].args[5] != nr_pfns ) + if ( unlikely(rx_mcl[i].args[5] != i) ) panic("Unable to reduce memory reservation\n"); /* Above is a suitable barrier to ensure backend will see requests. */ - np->rx->req_prod = i; + np->rx->req_prod = req_prod + i; + + /* Adjust our floating fill target if we risked running out of buffers. */ + if ( ((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) && + ((np->rx_target *= 2) > RX_MAX_TARGET) ) + np->rx_target = RX_MAX_TARGET; } @@ -627,6 +639,12 @@ static int netif_poll(struct net_device np->rx_resp_cons = i; + /* If we get a callback with very few responses, reduce fill target. */ + /* NB. Note exponential increase, linear decrease. */ + if ( ((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) && + (--np->rx_target < RX_MIN_TARGET) ) + np->rx_target = RX_MIN_TARGET; + network_alloc_rx_buffers(dev); *pbudget -= work_done; @@ -755,10 +773,10 @@ static void vif_show(struct net_private { #if DEBUG if (np) { - IPRINTK(" \n", + IPRINTK("\n", np->handle, be_state_name[np->backend_state], - user_state_name[np->user_state], + np->user_state ? "open" : "closed", np->evtchn, np->irq, np->tx, @@ -806,13 +824,13 @@ static int send_driver_status(int ok) /* Stop network device and free tx/rx queues and irq. */ -static void vif_release(struct net_private *np){ - +static void vif_release(struct net_private *np) +{ /* Stop old i/f to prevent errors whilst we rebuild the state. */ spin_lock_irq(&np->tx_lock); spin_lock(&np->rx_lock); netif_stop_queue(np->dev); - //np->backend_state = BEST_DISCONNECTED; + /* np->backend_state = BEST_DISCONNECTED; */ spin_unlock(&np->rx_lock); spin_unlock_irq(&np->tx_lock); @@ -827,18 +845,18 @@ static void vif_release(struct net_priva np->tx = NULL; np->rx = NULL; } - } /* Release vif resources and close it down completely. */ -static void vif_close(struct net_private *np){ +static void vif_close(struct net_private *np) +{ DPRINTK(">\n"); vif_show(np); - WPRINTK(" Unexpected netif-CLOSED message in state %s\n", + WPRINTK("Unexpected netif-CLOSED message in state %s\n", be_state_name[np->backend_state]); vif_release(np); np->backend_state = BEST_CLOSED; - //todo: take dev down and free. + /* todo: take dev down and free. */ vif_show(np); DPRINTK("<\n"); } @@ -873,11 +891,13 @@ static void vif_disconnect(struct net_pr * is initiated by a special "RESET" message - disconnect could * just mean we're not allowed to use this interface any more. */ -static void vif_reset(struct net_private *np){ +static void +vif_reset( + struct net_private *np) +{ DPRINTK(">\n"); - IPRINTK(" Attempting to reconnect network interface: handle=%u\n", - np->handle); - + IPRINTK("Attempting to reconnect network interface: handle=%u\n", + np->handle); vif_release(np); vif_disconnect(np); vif_show(np); DPRINTK("<\n"); @@ -887,7 +907,10 @@ static void vif_reset(struct net_private * Sets the mac and event channel from the message. * Binds the irq to the event channel. */ -static void vif_connect(struct net_private *np, netif_fe_interface_status_t *status){ +static void +vif_connect( + struct net_private *np, netif_fe_interface_status_t *status) +{ struct net_device *dev = np->dev; DPRINTK(">\n"); memcpy(dev->dev_addr, status->mac, ETH_ALEN); @@ -927,13 +950,14 @@ static int create_netdev(int handle, str spin_lock_init(&np->tx_lock); spin_lock_init(&np->rx_lock); + skb_queue_head_init(&np->rx_batch); + np->rx_target = RX_MIN_TARGET; + /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ - for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ){ + for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ) np->tx_skbs[i] = (void *)(i+1); - } - for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ){ + for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ) np->rx_skbs[i] = (void *)(i+1); - } dev->open = network_open; dev->hard_start_xmit = network_start_xmit; @@ -951,11 +975,10 @@ static int create_netdev(int handle, str list_add(&np->list, &dev_list); exit: - if ( (err != 0) && (dev != NULL ) ){ + if ( (err != 0) && (dev != NULL ) ) kfree(dev); - } else if ( val != NULL ) { + else if ( val != NULL ) *val = dev; - } return err; } @@ -967,44 +990,42 @@ static int create_netdev(int handle, str * @param np return parameter for interface state * @return 0 on success, error code otherwise */ -static int target_vif(netif_fe_interface_status_t *status, struct net_private **np) +static int +target_vif( + netif_fe_interface_status_t *status, struct net_private **np) { int err = 0; struct net_device *dev; DPRINTK("> handle=%d\n", status->handle); - if(status->handle < 0) { + if ( status->handle < 0 ) + { err = -EINVAL; goto exit; } - dev = find_dev_by_handle(status->handle); - DPRINTK("> dev=%p\n", dev); - if(dev) goto exit; - // No good - give up. - if(status->status == NETIF_INTERFACE_STATUS_CLOSED) goto exit; - if(status->status == NETIF_INTERFACE_STATUS_CHANGED) goto exit; - // It's a new interface in a good state - create it. + + if ( (dev = find_dev_by_handle(status->handle)) != NULL ) + goto exit; + + if ( status->status == NETIF_INTERFACE_STATUS_CLOSED ) + goto exit; + if ( status->status == NETIF_INTERFACE_STATUS_CHANGED ) + goto exit; + + /* It's a new interface in a good state - create it. */ DPRINTK("> create device...\n"); - err = create_netdev(status->handle, &dev); - if(err) goto exit; + if ( (err = create_netdev(status->handle, &dev)) != 0 ) + goto exit; + netctrl.interface_n++; + exit: - if(np){ + if ( np != NULL ) *np = ((dev && !err) ? dev->priv : NULL); - } DPRINTK("< err=%d\n", err); return err; } -/* Warn about an unexpected status. */ -static void unexpected(struct net_private *np, - netif_fe_interface_status_t *status) -{ - WPRINTK(" Unexpected netif status %s in state %s\n", - status_name[status->status], - be_state_name[np->backend_state]); -} - /* Handle an interface status message. */ static void netif_interface_status(netif_fe_interface_status_t *status) { @@ -1012,22 +1033,25 @@ static void netif_interface_status(netif struct net_private *np = NULL; DPRINTK(">\n"); - DPRINTK("> status=%s handle=%d\n", status_name[status->status], status->handle); + DPRINTK("> status=%s handle=%d\n", + status_name[status->status], status->handle); - err = target_vif(status, &np); - if(err){ - WPRINTK(" Invalid netif: handle=%u\n", status->handle); + if ( (err = target_vif(status, &np)) != 0 ) + { + WPRINTK("Invalid netif: handle=%u\n", status->handle); return; } - if(np == NULL){ + + if ( np == NULL ) + { DPRINTK("> no vif\n"); return; } DPRINTK(">\n"); vif_show(np); - switch (status->status) { - + switch ( status->status ) + { case NETIF_INTERFACE_STATUS_CLOSED: switch ( np->backend_state ) { @@ -1056,7 +1080,9 @@ static void netif_interface_status(netif switch ( np->backend_state ) { case BEST_CLOSED: - unexpected(np, status); + WPRINTK("Unexpected netif status %s in state %s\n", + status_name[status->status], + be_state_name[np->backend_state]); vif_disconnect(np); vif_connect(np, status); break; @@ -1074,7 +1100,7 @@ static void netif_interface_status(netif break; default: - WPRINTK(" Invalid netif status code %d\n", status->status); + WPRINTK("Invalid netif status code %d\n", status->status); break; } vif_show(np); @@ -1135,7 +1161,8 @@ static int probe_interfaces(void) DPRINTK(">\n"); - for ( wait_i = 0; wait_i < wait_n; wait_i++) { + for ( wait_i = 0; wait_i < wait_n; wait_i++) + { DPRINTK("> wait_i=%d\n", wait_i); conn = netctrl_connected(); if(conn) break; @@ -1145,9 +1172,10 @@ static int probe_interfaces(void) } DPRINTK("> wait finished...\n"); - if ( conn <= 0 ) { + if ( conn <= 0 ) + { err = netctrl_err(-ENETDOWN); - WPRINTK(" Failed to connect all virtual interfaces: err=%d\n", err); + WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); } DPRINTK("< err=%d\n", err); @@ -1177,7 +1205,8 @@ static int probe_interfaces(void) DPRINTK(">\n"); netctrl.interface_n = 0; - for (wait_i = 0; wait_i < wait_n; wait_i++) { + for ( wait_i = 0; wait_i < wait_n; wait_i++ ) + { DPRINTK("> wait_i=%d query=%d\n", wait_i, query); msg.handle = query; memcpy(cmsg.msg, &msg, sizeof(msg)); @@ -1199,9 +1228,10 @@ static int probe_interfaces(void) } exit: - if (err) { + if ( err ) + { err = netctrl_err(-ENETDOWN); - WPRINTK(" Connecting virtual network interfaces failed: err=%d\n", err); + WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err); } DPRINTK("< err=%d\n", err); @@ -1218,7 +1248,7 @@ static int __init netif_init(void) (start_info.flags & SIF_NET_BE_DOMAIN) ) return 0; - IPRINTK(" Initialising virtual ethernet driver.\n"); + IPRINTK("Initialising virtual ethernet driver.\n"); INIT_LIST_HEAD(&dev_list); netctrl_init(); (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, @@ -1277,7 +1307,8 @@ void netif_resume(void) struct net_private *np; DPRINTK(">\n"); - list_for_each(ent, &dev_list){ + list_for_each ( ent, &dev_list ) + { np = list_entry(ent, struct net_private, list); vif_resume(np); } diff -r 82cab392896d -r 4ecd18756ef8 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Tue Sep 28 14:47:51 2004 +0000 +++ b/xen/arch/x86/traps.c Thu Sep 30 20:45:54 2004 +0000 @@ -344,18 +344,6 @@ asmlinkage void do_page_fault(struct pt_ ASSERT_no_criticalregion(); - if ( unlikely(addr >= LDT_VIRT_START) && - (addr < (LDT_VIRT_START + (d->mm.ldt_ents*LDT_ENTRY_SIZE))) ) - { - /* - * Copy a mapping from the guest's LDT, if it is valid. Otherwise we - * send the fault up to the guest OS to be handled. - */ - off = addr - LDT_VIRT_START; - addr = d->mm.ldt_base + off; - if ( likely(map_ldt_shadow_page(off >> PAGE_SHIFT)) ) - return; /* successfully copied the mapping */ - } if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) ) { @@ -377,6 +365,19 @@ asmlinkage void do_page_fault(struct pt_ (addr < PAGE_OFFSET) && shadow_fault(addr, error_code) ) return; /* Returns TRUE if fault was handled. */ + if ( unlikely(addr >= LDT_VIRT_START) && + (addr < (LDT_VIRT_START + (d->mm.ldt_ents*LDT_ENTRY_SIZE))) ) + { + /* + * Copy a mapping from the guest's LDT, if it is valid. Otherwise we + * send the fault up to the guest OS to be handled. + */ + off = addr - LDT_VIRT_START; + addr = d->mm.ldt_base + off; + if ( likely(map_ldt_shadow_page(off >> PAGE_SHIFT)) ) + return; /* successfully copied the mapping */ + } + if ( unlikely(!(regs->xcs & 3)) ) goto xen_fault;