bitkeeper revision 1.1030 (40e1c7ecu4wKzzQZ32aoNCXtRj9smw)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/hp.bk
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2004-06-29 19:50:04 +00:00
commit 1c94e4bb76
15 files changed
+709 -609

No files matched your search

+3 -1
View File
@@ -454,18 +454,20 @@
3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/include/asm-x86/smp.h
3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-x86/smpboot.h
3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-x86/spinlock.h
3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/string.h
40e1966akOHWvvunCED7x3HPv35QvQ xen/include/asm-x86/string.h
3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-x86/system.h
3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-x86/types.h
40cf1596saFaHD5DC5zvrSn7CDCWGQ xen/include/asm-x86/uaccess.h
3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h
3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/ptrace.h
3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
404f1bb1LSCqrMDSfRAti5NdMQPJBQ xen/include/asm-x86/x86_64/page.h
404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/ptrace.h
40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
400304fcmRQmDdFYEzDh0wcBba9alg xen/include/hypervisor-ifs/COPYING
404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/hypervisor-ifs/arch-x86_32.h
@@ -28,12 +28,6 @@ static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
static void net_rx_action(unsigned long unused);
static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0);
typedef struct {
u16 id;
unsigned long old_mach_ptr;
unsigned long new_mach_pfn;
netif_t *netif;
} rx_info_t;
static struct sk_buff_head rx_queue;
static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2];
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE*3];
@@ -48,8 +42,10 @@ static unsigned long mmap_vstart;
#define PKT_PROT_LEN (ETH_HLEN + 20)
static u16 pending_id[MAX_PENDING_REQS];
static netif_t *pending_netif[MAX_PENDING_REQS];
static struct {
netif_tx_request_t req;
netif_t *netif;
} pending_tx_info[MAX_PENDING_REQS];
static u16 pending_ring[MAX_PENDING_REQS];
typedef unsigned int PEND_RING_IDX;
#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
@@ -61,11 +57,6 @@ static u16 dealloc_ring[MAX_PENDING_REQS];
static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED;
static PEND_RING_IDX dealloc_prod, dealloc_cons;
typedef struct {
u16 idx;
netif_tx_request_t req;
netif_t *netif;
} tx_info_t;
static struct sk_buff_head tx_queue;
static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
@@ -127,6 +118,8 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
netif_t *netif = (netif_t *)dev->priv;
ASSERT(skb->dev == dev);
/* Drop the packet if the target domain has no receive buffers. */
if ( (netif->rx_req_cons == netif->rx->req_prod) ||
((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
@@ -152,15 +145,14 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb_reserve(nskb, hlen);
__skb_put(nskb, skb->len);
(void)skb_copy_bits(skb, -hlen, nskb->head, hlen + skb->len);
nskb->dev = skb->dev;
dev_kfree_skb(skb);
skb = nskb;
}
((rx_info_t *)&skb->cb[0])->id =
netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_req_cons++)].req.id;
((rx_info_t *)&skb->cb[0])->netif = netif;
__skb_queue_tail(&rx_queue, skb);
netif->rx_req_cons++;
skb_queue_tail(&rx_queue, skb);
tasklet_schedule(&net_rx_tasklet);
return 0;
@@ -195,7 +187,7 @@ static void net_rx_action(unsigned long unused)
netif_t *netif;
s8 status;
u16 size, id, evtchn;
mmu_update_t *mmu = rx_mmu;
mmu_update_t *mmu;
multicall_entry_t *mcl;
unsigned long vdata, mdata, new_mfn;
struct sk_buff_head rxq;
@@ -206,9 +198,10 @@ static void net_rx_action(unsigned long unused)
skb_queue_head_init(&rxq);
mcl = rx_mcl;
while ( (skb = __skb_dequeue(&rx_queue)) != NULL )
mmu = rx_mmu;
while ( (skb = skb_dequeue(&rx_queue)) != NULL )
{
netif = ((rx_info_t *)&skb->cb[0])->netif;
netif = (netif_t *)skb->dev->priv;
vdata = (unsigned long)skb->data;
mdata = virt_to_machine(vdata);
new_mfn = get_new_mfn();
@@ -231,11 +224,9 @@ static void net_rx_action(unsigned long unused)
mcl[1].args[1] = 3;
mcl[1].args[2] = 0;
mmu += 3;
mcl += 2;
mmu += 3;
((rx_info_t *)&skb->cb[0])->old_mach_ptr = mdata;
((rx_info_t *)&skb->cb[0])->new_mach_pfn = new_mfn;
__skb_queue_tail(&rxq, skb);
/* Filled the batch queue? */
@@ -250,14 +241,17 @@ static void net_rx_action(unsigned long unused)
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
mcl = rx_mcl;
mmu = rx_mmu;
while ( (skb = __skb_dequeue(&rxq)) != NULL )
{
netif = ((rx_info_t *)&skb->cb[0])->netif;
netif = (netif_t *)skb->dev->priv;
size = skb->tail - skb->data;
id = ((rx_info_t *)&skb->cb[0])->id;
new_mfn = ((rx_info_t *)&skb->cb[0])->new_mach_pfn;
mdata = ((rx_info_t *)&skb->cb[0])->old_mach_ptr;
/* Rederive the machine addresses. */
new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
mdata = ((mmu[2].ptr & PAGE_MASK) |
((unsigned long)skb->data & ~PAGE_MASK));
/* Check the reassignment error code. */
if ( unlikely(mcl[1].args[5] != 0) )
{
@@ -285,6 +279,7 @@ static void net_rx_action(unsigned long unused)
}
evtchn = netif->evtchn;
id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
if ( make_rx_response(netif, id, status, mdata, size) &&
(rx_notify[evtchn] == 0) )
{
@@ -295,6 +290,7 @@ static void net_rx_action(unsigned long unused)
dev_kfree_skb(skb);
mcl += 2;
mmu += 3;
}
while ( notify_nr != 0 )
@@ -406,10 +402,11 @@ static void net_tx_action(unsigned long unused)
{
pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
netif = pending_netif[pending_idx];
netif = pending_tx_info[pending_idx].netif;
spin_lock(&netif->tx_lock);
make_tx_response(netif, pending_id[pending_idx], NETIF_RSP_OKAY);
make_tx_response(netif, pending_tx_info[pending_idx].req.id,
NETIF_RSP_OKAY);
spin_unlock(&netif->tx_lock);
pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
@@ -512,10 +509,11 @@ static void net_tx_action(unsigned long unused)
mcl[0].args[2] = 0;
mcl[0].args[3] = netif->domid;
mcl++;
((tx_info_t *)&skb->cb[0])->idx = pending_idx;
((tx_info_t *)&skb->cb[0])->netif = netif;
memcpy(&((tx_info_t *)&skb->cb[0])->req, &txreq, sizeof(txreq));
memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
pending_tx_info[pending_idx].netif = netif;
*((u16 *)skb->data) = pending_idx;
__skb_queue_tail(&tx_queue, skb);
pending_cons++;
@@ -533,9 +531,9 @@ static void net_tx_action(unsigned long unused)
mcl = tx_mcl;
while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
{
pending_idx = ((tx_info_t *)&skb->cb[0])->idx;
netif = ((tx_info_t *)&skb->cb[0])->netif;
memcpy(&txreq, &((tx_info_t *)&skb->cb[0])->req, sizeof(txreq));
pending_idx = *((u16 *)skb->data);
netif = pending_tx_info[pending_idx].netif;
memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
/* Check the remap error code. */
if ( unlikely(mcl[0].args[5] != 0) )
@@ -581,8 +579,6 @@ static void net_tx_action(unsigned long unused)
*/
page->mapping = (struct address_space *)netif_page_release;
atomic_set(&page->count, 1);
pending_id[pending_idx] = txreq.id;
pending_netif[pending_idx] = netif;
netif->stats.tx_bytes += txreq.size;
netif->stats.tx_packets++;
@@ -99,8 +99,6 @@ static struct net_device *find_dev_by_handle(unsigned int handle)
return NULL;
}
#define MULTIVIF
/** Network interface info. */
struct netif_ctrl {
/** Number of interfaces. */
@@ -385,14 +383,8 @@ static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
unsigned long flags;
spin_lock_irqsave(&np->tx_lock, flags);
if( !netif_carrier_ok(dev) )
{
spin_unlock_irqrestore(&np->tx_lock, flags);
return;
}
network_tx_buf_gc(dev);
if ( likely(netif_carrier_ok(dev)) )
network_tx_buf_gc(dev);
spin_unlock_irqrestore(&np->tx_lock, flags);
if ( np->rx_resp_cons != np->rx->resp_prod )
@@ -414,7 +406,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
spin_lock(&np->rx_lock);
/* if the device is undergoing recovery then don't do anything */
/* If the device is undergoing recovery then don't do anything. */
if ( !netif_carrier_ok(dev) )
{
spin_unlock(&np->rx_lock);
@@ -721,20 +713,17 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
memcpy(dev->dev_addr, status->mac, ETH_ALEN);
if(netif_carrier_ok(dev)){
if ( netif_carrier_ok(dev) )
np->state = NETIF_STATE_CONNECTED;
} else {
else
network_reconnect(dev, status);
}
np->evtchn = status->evtchn;
np->irq = bind_evtchn_to_irq(np->evtchn);
(void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM,
dev->name, dev);
#ifdef MULTIVIF
netctrl_connected_count();
#endif
break;
default:
@@ -744,13 +733,13 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
}
}
/** Create a network devices.
*
/** Create a network device.
* @param handle device handle
* @param val return parameter for created device
* @return 0 on success, error code otherwise
*/
static int create_netdev(int handle, struct net_device **val){
static int create_netdev(int handle, struct net_device **val)
{
int err = 0;
struct net_device *dev = NULL;
struct net_private *np = NULL;
@@ -847,11 +836,7 @@ static int __init init_module(void)
{
ctrl_msg_t cmsg;
netif_fe_driver_status_changed_t st;
int err = 0;
#ifdef MULTIVIF
int wait_n = 20;
int wait_i;
#endif
int err = 0, wait_i, wait_n = 20;
if ( (start_info.flags & SIF_INITDOMAIN) ||
(start_info.flags & SIF_NET_BE_DOMAIN) )
@@ -860,9 +845,8 @@ static int __init init_module(void)
printk("Initialising Xen virtual ethernet frontend driver");
INIT_LIST_HEAD(&dev_list);
#ifdef MULTIVIF
netctrl_init();
#endif
(void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
CALLBACK_IN_BLOCKING_CONTEXT);
@@ -876,7 +860,6 @@ static int __init init_module(void)
memcpy(cmsg.msg, &st, sizeof(st));
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
#ifdef MULTIVIF
/* Wait for all interfaces to be connected. */
for ( wait_i = 0; ; wait_i++)
{
@@ -888,7 +871,6 @@ static int __init init_module(void)
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
#endif
if ( err )
ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
+2 -2
View File
@@ -101,7 +101,7 @@ continue_boot_cpu:
mov 0x4(%eax),%eax /* %eax = mod[mod_count-1]->end */
mov %eax,%ecx
sub %ebx,%ecx /* %ecx = byte len of all mods */
mov $(MAX_DIRECTMAP_ADDRESS), %edi
mov $(DIRECTMAP_PHYS_END), %edi
add %ecx, %edi /* %edi = src + length */
shr $2,%ecx /* %ecx = length/4 */
1: sub $4,%eax /* %eax = src, %edi = dst */
@@ -117,7 +117,7 @@ skip_dom0_copy:
1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
stosl /* low mapping */
add $(1<<L2_PAGETABLE_SHIFT),%eax
cmp $MAX_DIRECTMAP_ADDRESS+0x1e3,%eax
cmp $DIRECTMAP_PHYS_END+0x1e3,%eax
jne 1b
call start_paging
+1 -1
View File
@@ -347,7 +347,7 @@ void *memguard_init(void *heap_start)
PAGE_MASK);
/* Memory guarding is incompatible with super pages. */
for ( i = 0; i < (MAX_XENHEAP_ADDRESS >> L2_PAGETABLE_SHIFT); i++ )
for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
{
l1 = (l1_pgentry_t *)heap_start;
heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
+61 -28
View File
@@ -27,6 +27,8 @@
#include <asm/domain_page.h>
#include <hypervisor-ifs/dom0_ops.h>
unsigned long xenheap_phys_end;
kmem_cache_t *domain_struct_cachep;
struct e820entry {
@@ -69,6 +71,11 @@ char opt_physdev_dom0_hide[200] = "";
/* level- or edge-triggered. */
/* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
char opt_leveltrigger[30] = "", opt_edgetrigger[30] = "";
/*
* opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
* pfn_info table and allocation bitmap.
*/
unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
static struct {
unsigned char *name;
@@ -91,6 +98,7 @@ static struct {
{ "physdev_dom0_hide", OPT_STR, &opt_physdev_dom0_hide },
{ "leveltrigger", OPT_STR, &opt_leveltrigger },
{ "edgetrigger", OPT_STR, &opt_edgetrigger },
{ "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
{ NULL, 0, NULL }
};
@@ -180,52 +188,78 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
for ( ; ; ) ;
}
max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
/* The array of pfn_info structures must fit into the reserved area. */
if ( (sizeof(struct pfn_info) * max_page) >
(FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) )
if ( opt_xenheap_megabytes < 4 )
{
unsigned long new_max =
(FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) /
sizeof(struct pfn_info);
printk("Truncating available memory to %lu/%luMB\n",
new_max >> (20 - PAGE_SHIFT), max_page >> (20 - PAGE_SHIFT));
max_page = new_max;
printk("Xen heap size is too small to safely continue!\n");
for ( ; ; ) ;
}
set_current(&idle0_task);
init_frametable(max_page);
printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
max_page >> (20-PAGE_SHIFT), max_page,
max_mem >> (20-PAGE_SHIFT));
xenheap_phys_end = opt_xenheap_megabytes << 20;
initial_images_start = MAX_DIRECTMAP_ADDRESS;
max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
#if defined(__i386__)
if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
{
printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
for ( ; ; ) ;
}
ASSERT((sizeof(struct pfn_info) << 20) >
(FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
/* Initial images stashed away above DIRECTMAP area in boot.S. */
initial_images_start = DIRECTMAP_PHYS_END;
initial_images_end = initial_images_start +
(mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
#elif defined(__x86_64__)
init_frametable(__va(xenheap_phys_end), max_page);
initial_images_start = __pa(frame_table) + frame_table_size;
initial_images_end = initial_images_start +
(mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
if ( initial_images_end > (max_page << PAGE_SHIFT) )
{
printk("Not enough memory to stash the DOM0 kernel image.\n");
for ( ; ; ) ;
}
memmove(__va(initial_images_start),
__va(mod[0].mod_start),
mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
#endif
dom0_memory_start = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10);
dom0_memory_end = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
/* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
if ( (dom0_memory_end + (8<<20)) > (max_page<<PAGE_SHIFT) )
panic("Not enough memory to craete initial domain!\n");
if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
{
printk("Not enough memory for DOM0 memory reservation.\n");
for ( ; ; ) ;
}
printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
max_page >> (20-PAGE_SHIFT), max_page,
max_mem >> (20-PAGE_SHIFT));
add_to_domain_alloc_list(dom0_memory_end, max_page << PAGE_SHIFT);
heap_start = memguard_init(&_end);
printk("Xen heap size is %luKB\n",
(MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024 );
(xenheap_phys_end-__pa(heap_start))/1024 );
if ( ((MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024) <= 4096 )
{
printk("Xen heap size is too small to safely continue!\n");
for ( ; ; ) ;
}
init_page_allocator(__pa(heap_start), MAX_XENHEAP_ADDRESS);
init_page_allocator(__pa(heap_start), xenheap_phys_end);
/* Initialise the slab allocator. */
kmem_cache_init();
@@ -253,8 +287,7 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
/*
* We're going to setup domain0 using the module(s) that we stashed safely
* above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if
* present, is an initrd ramdisk.
* above our heap. The second module, if present, is an initrd ramdisk.
*/
if ( construct_dom0(new_dom, dom0_memory_start, dom0_memory_end,
(char *)initial_images_start,
+12 -9
View File
@@ -144,7 +144,7 @@ static struct {
#define GPS (percpu_info[smp_processor_id()].gps ? : current)
void __init init_frametable(unsigned long nr_pages)
void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
{
unsigned long mfn;
@@ -153,22 +153,23 @@ void __init init_frametable(unsigned long nr_pages)
max_page = nr_pages;
frame_table_size = nr_pages * sizeof(struct pfn_info);
frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START;
frame_table = frametable_vstart;
if ( (__pa(frame_table) + frame_table_size) > (max_page << PAGE_SHIFT) )
panic("Not enough memory for frame table - reduce Xen heap size?\n");
memset(frame_table, 0, frame_table_size);
spin_lock_init(&free_list_lock);
INIT_LIST_HEAD(&free_list);
free_pfns = 0;
/* initialise to a magic of 0x55555555 so easier to spot bugs later */
memset( machine_to_phys_mapping, 0x55, 4*1024*1024 );
/* The array is sized for a 4GB machine regardless of actuall mem size.
This costs 4MB -- may want to fix some day */
/* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
memset(machine_to_phys_mapping, 0x55, 4<<20);
/* Pin the ownership of the MP table so that DOM0 can map it later. */
for ( mfn = virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
mfn < virt_to_phys(&machine_to_phys_mapping[1024*1024])>>PAGE_SHIFT;
for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
mfn++ )
{
frame_table[mfn].count_and_flags = 1 | PGC_allocated;
@@ -471,6 +472,7 @@ static int alloc_l2_table(struct pfn_info *page)
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
goto fail;
#if defined(__i386__)
/* Now we add our private high mappings. */
memcpy(&pl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -480,6 +482,7 @@ static int alloc_l2_table(struct pfn_info *page)
pl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(page->u.domain->mm.perdomain_pt) |
__PAGE_HYPERVISOR);
#endif
unmap_domain_mem(pl2e);
return 1;
+5 -1
View File
@@ -151,7 +151,9 @@ static inline int shadow_page_op( struct mm_struct *m, unsigned int op,
PGT_l2_page_table )
{
unsigned long * spl1e = map_domain_mem( spfn<<PAGE_SHIFT );
memset( spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e) );
#ifdef __i386__
memset(spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e));
#endif
unmap_domain_mem( spl1e );
}
}
@@ -574,6 +576,7 @@ unsigned long shadow_l2_table(
// we need to do this before the linear map is set up
spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT);
#ifdef __i386__
// get hypervisor and 2x linear PT mapings installed
memcpy(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -585,6 +588,7 @@ unsigned long shadow_l2_table(
spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) |
__PAGE_HYPERVISOR);
#endif
// can't use the linear map as we may not be in the right PT
gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT);
+10 -5
View File
@@ -93,6 +93,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#if defined(__x86_64__)
#define XENHEAP_DEFAULT_MB (16)
#define PML4_ENTRY_BITS 39
#define PML4_ENTRY_BYTES (1UL<<PML4_ENTRY_BITS)
@@ -158,9 +160,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#elif defined(__i386__)
/* The following are machine addresses. */
#define MAX_XENHEAP_ADDRESS (12*1024*1024)
#define MAX_DIRECTMAP_ADDRESS (40*1024*1024)
#define XENHEAP_DEFAULT_MB (12)
#define DIRECTMAP_PHYS_END (40*1024*1024)
/* Hypervisor owns top 64MB of virtual address space. */
#define HYPERVISOR_VIRT_START (0xFC000000UL)
@@ -173,9 +174,9 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#define RO_MPT_VIRT_END (RO_MPT_VIRT_START + (4*1024*1024))
/* The virtual addresses for the 40MB direct-map region. */
#define DIRECTMAP_VIRT_START (RO_MPT_VIRT_END)
#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + DIRECTMAP_PHYS_END)
#define XENHEAP_VIRT_START (DIRECTMAP_VIRT_START)
#define XENHEAP_VIRT_END (XENHEAP_VIRT_START + MAX_XENHEAP_ADDRESS)
#define XENHEAP_VIRT_END (XENHEAP_VIRT_START + (XENHEAP_DEFAULT_MB<<20))
#define RDWR_MPT_VIRT_START (XENHEAP_VIRT_END)
#define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (4*1024*1024))
#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
@@ -207,6 +208,10 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#endif /* __i386__ */
#ifndef __ASSEMBLY__
extern unsigned long xenheap_phys_end; /* user-configurable */
#endif
#define GDT_VIRT_START (PERDOMAIN_VIRT_START)
#define GDT_VIRT_END (GDT_VIRT_START + (64*1024))
#define LDT_VIRT_START (GDT_VIRT_END)
+8 -8
View File
@@ -95,12 +95,12 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
extern void paging_init(void);
#define __flush_tlb() \
do { \
__asm__ __volatile__ ( \
"movl %%cr3, %%eax; movl %%eax, %%cr3" \
: : : "memory", "eax" ); \
tlb_clocktick(); \
#define __flush_tlb() \
do { \
__asm__ __volatile__ ( \
"mov %%cr3, %%"__OP"ax; mov %%"__OP"ax, %%cr3" \
: : : "memory", __OP"ax" ); \
tlb_clocktick(); \
} while ( 0 )
/* Flush global pages as well. */
@@ -108,14 +108,14 @@ extern void paging_init(void);
#define __pge_off() \
do { \
__asm__ __volatile__( \
"movl %0, %%cr4; # turn off PGE " \
"mov %0, %%cr4; # turn off PGE " \
:: "r" (mmu_cr4_features & ~X86_CR4_PGE)); \
} while (0)
#define __pge_on() \
do { \
__asm__ __volatile__( \
"movl %0, %%cr4; # turn off PGE " \
"mov %0, %%cr4; # turn off PGE " \
:: "r" (mmu_cr4_features)); \
} while (0)
+4 -484
View File
@@ -1,485 +1,5 @@
#ifndef _I386_STRING_H_
#define _I386_STRING_H_
#include <xen/config.h>
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* NO Copyright (C) 1991, 1992 Linus Torvalds,
* consider these trivial functions to be PD.
*/
#define __HAVE_ARCH_STRCPY
static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
:"0" (src),"1" (dest) : "memory");
return dest;
}
#define __HAVE_ARCH_STRNCPY
static inline char * strncpy(char * dest,const char *src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"1:\tdecl %2\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"rep\n\t"
"stosb\n"
"2:"
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
:"0" (src),"1" (dest),"2" (count) : "memory");
return dest;
}
#define __HAVE_ARCH_STRCAT
static inline char * strcat(char * dest,const char * src)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"decl %1\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
return dest;
}
#define __HAVE_ARCH_STRNCAT
static inline char * strncat(char * dest,const char * src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"decl %1\n\t"
"movl %8,%3\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %2,%2\n\t"
"stosb"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
: "memory");
return dest;
}
#define __HAVE_ARCH_STRCMP
static inline int strcmp(const char * cs,const char * ct)
{
int d0, d1;
register int __res;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"scasb\n\t"
"jne 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"jmp 3f\n"
"2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"3:"
:"=a" (__res), "=&S" (d0), "=&D" (d1)
:"1" (cs),"2" (ct));
return __res;
}
#define __HAVE_ARCH_STRNCMP
static inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
int d0, d1, d2;
__asm__ __volatile__(
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
:"1" (cs),"2" (ct),"3" (count));
return __res;
}
#define __HAVE_ARCH_STRCHR
static inline char * strchr(const char * s, int c)
{
int d0;
register char * __res;
__asm__ __volatile__(
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"movl $1,%1\n"
"2:\tmovl %1,%0\n\t"
"decl %0"
:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
return __res;
}
#define __HAVE_ARCH_STRRCHR
static inline char * strrchr(const char * s, int c)
{
int d0, d1;
register char * __res;
__asm__ __volatile__(
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"jne 2f\n\t"
"leal -1(%%esi),%0\n"
"2:\ttestb %%al,%%al\n\t"
"jne 1b"
:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
return __res;
}
#define __HAVE_ARCH_STRLEN
static inline size_t strlen(const char * s)
{
int d0;
register int __res;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
return __res;
}
static inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
static inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
return to;
case 1:
*(unsigned char *)to = *(const unsigned char *)from;
return to;
case 2:
*(unsigned short *)to = *(const unsigned short *)from;
return to;
case 3:
*(unsigned short *)to = *(const unsigned short *)from;
*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
return to;
case 4:
*(unsigned long *)to = *(const unsigned long *)from;
return to;
case 6: /* for Ethernet addresses */
*(unsigned long *)to = *(const unsigned long *)from;
*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
return to;
case 8:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
return to;
case 12:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
return to;
case 16:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
return to;
case 20:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
return to;
}
#define COMMON(x) \
__asm__ __volatile__( \
"rep ; movsl" \
x \
: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
: "0" (n/4),"1" ((long) to),"2" ((long) from) \
: "memory");
{
int d0, d1, d2;
switch (n % 4) {
case 0: COMMON(""); return to;
case 1: COMMON("\n\tmovsb"); return to;
case 2: COMMON("\n\tmovsw"); return to;
default: COMMON("\n\tmovsw\n\tmovsb"); return to;
}
}
#undef COMMON
}
#define __HAVE_ARCH_MEMCPY
#define memcpy(t, f, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy((t),(f),(n)) : \
__memcpy((t),(f),(n)))
/*
* struct_cpy(x,y), copy structure *x into (matching structure) *y.
*
* We get link-time errors if the structure sizes do not match.
* There is no runtime overhead, it's all optimized away at
* compile time.
*/
//extern void __struct_cpy_bug (void);
/*
#define struct_cpy(x,y) \
({ \
if (sizeof(*(x)) != sizeof(*(y))) \
__struct_cpy_bug; \
memcpy(x, y, sizeof(*(x))); \
})
*/
#define __HAVE_ARCH_MEMMOVE
static inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
__asm__ __volatile__(
"rep\n\t"
"movsb"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),"1" (src),"2" (dest)
: "memory");
else
__asm__ __volatile__(
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),
"1" (n-1+(const char *)src),
"2" (n-1+(char *)dest)
:"memory");
return dest;
}
#define __HAVE_ARCH_MEMCMP
#define memcmp __builtin_memcmp
#define __HAVE_ARCH_MEMCHR
static inline void * memchr(const void * cs,int c,size_t count)
{
int d0;
register void * __res;
if (!count)
return NULL;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
return __res;
}
static inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
:"a" (c),"1" (s),"0" (count)
:"memory");
return s;
}
/* we might want to write optimized versions of these later */
#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
/*
* memset(x,0,y) is a reasonably common thing to do, so we want to fill
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep ; stosl\n\t"
"testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
"1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
: "=&c" (d0), "=&D" (d1)
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
:"memory");
return (s);
}
/* Added by Gertjan van Wingerde to make minix and sysv module work */
#define __HAVE_ARCH_STRNLEN
static inline size_t strnlen(const char * s, size_t count)
{
int d0;
register int __res;
__asm__ __volatile__(
"movl %2,%0\n\t"
"jmp 2f\n"
"1:\tcmpb $0,(%0)\n\t"
"je 3f\n\t"
"incl %0\n"
"2:\tdecl %1\n\t"
"cmpl $-1,%1\n\t"
"jne 1b\n"
"3:\tsubl %2,%0"
:"=a" (__res), "=&d" (d0)
:"c" (s),"1" (count));
return __res;
}
/* end of additional stuff */
//#define __HAVE_ARCH_STRSTR
//extern char *strstr(const char *cs, const char *ct);
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
return s;
case 1:
*(unsigned char *)s = pattern;
return s;
case 2:
*(unsigned short *)s = pattern;
return s;
case 3:
*(unsigned short *)s = pattern;
*(2+(unsigned char *)s) = pattern;
return s;
case 4:
*(unsigned long *)s = pattern;
return s;
}
#define COMMON(x) \
__asm__ __volatile__( \
"rep ; stosl" \
x \
: "=&c" (d0), "=&D" (d1) \
: "a" (pattern),"0" (count/4),"1" ((long) s) \
: "memory")
{
int d0, d1;
switch (count % 4) {
case 0: COMMON(""); return s;
case 1: COMMON("\n\tstosb"); return s;
case 2: COMMON("\n\tstosw"); return s;
default: COMMON("\n\tstosw\n\tstosb"); return s;
}
}
#undef COMMON
}
#define __constant_c_x_memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_c_and_count_memset((s),(c),(count)) : \
__constant_c_memset((s),(c),(count)))
#define __memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_count_memset((s),(c),(count)) : \
__memset_generic((s),(c),(count)))
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
__memset((s),(c),(count)))
/*
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
static inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
return addr;
__asm__("repnz; scasb\n\t"
"jnz 1f\n\t"
"dec %%edi\n"
"1:"
: "=D" (addr), "=c" (size)
: "0" (addr), "1" (size), "a" (c));
return addr;
}
#ifdef __x86_64__
#include <asm/x86_64/string.h>
#else
#include <asm/x86_32/string.h>
#endif
+2 -1
View File
@@ -3,7 +3,6 @@
typedef unsigned short umode_t;
typedef unsigned int size_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -44,10 +43,12 @@ typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#define BITS_PER_LONG 32
typedef unsigned int size_t;
#elif defined(__x86_64__)
typedef signed long s64;
typedef unsigned long u64;
#define BITS_PER_LONG 64
typedef unsigned long size_t;
#endif
/* DMA addresses come in generic and 64-bit flavours. */
+485
View File
@@ -0,0 +1,485 @@
#ifndef _I386_STRING_H_
#define _I386_STRING_H_
#include <xen/config.h>
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* NO Copyright (C) 1991, 1992 Linus Torvalds,
* consider these trivial functions to be PD.
*/
#define __HAVE_ARCH_STRCPY
static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
:"0" (src),"1" (dest) : "memory");
return dest;
}
#define __HAVE_ARCH_STRNCPY
static inline char * strncpy(char * dest,const char *src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"1:\tdecl %2\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"rep\n\t"
"stosb\n"
"2:"
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
:"0" (src),"1" (dest),"2" (count) : "memory");
return dest;
}
#define __HAVE_ARCH_STRCAT
static inline char * strcat(char * dest,const char * src)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"decl %1\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
return dest;
}
#define __HAVE_ARCH_STRNCAT
static inline char * strncat(char * dest,const char * src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"decl %1\n\t"
"movl %8,%3\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %2,%2\n\t"
"stosb"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
: "memory");
return dest;
}
#define __HAVE_ARCH_STRCMP
static inline int strcmp(const char * cs,const char * ct)
{
int d0, d1;
register int __res;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"scasb\n\t"
"jne 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"jmp 3f\n"
"2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"3:"
:"=a" (__res), "=&S" (d0), "=&D" (d1)
:"1" (cs),"2" (ct));
return __res;
}
#define __HAVE_ARCH_STRNCMP
static inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
int d0, d1, d2;
__asm__ __volatile__(
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
:"1" (cs),"2" (ct),"3" (count));
return __res;
}
#define __HAVE_ARCH_STRCHR
static inline char * strchr(const char * s, int c)
{
int d0;
register char * __res;
__asm__ __volatile__(
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"movl $1,%1\n"
"2:\tmovl %1,%0\n\t"
"decl %0"
:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
return __res;
}
#define __HAVE_ARCH_STRRCHR
static inline char * strrchr(const char * s, int c)
{
int d0, d1;
register char * __res;
__asm__ __volatile__(
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"jne 2f\n\t"
"leal -1(%%esi),%0\n"
"2:\ttestb %%al,%%al\n\t"
"jne 1b"
:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
return __res;
}
#define __HAVE_ARCH_STRLEN
static inline size_t strlen(const char * s)
{
int d0;
register int __res;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
return __res;
}
static inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
static inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
return to;
case 1:
*(unsigned char *)to = *(const unsigned char *)from;
return to;
case 2:
*(unsigned short *)to = *(const unsigned short *)from;
return to;
case 3:
*(unsigned short *)to = *(const unsigned short *)from;
*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
return to;
case 4:
*(unsigned long *)to = *(const unsigned long *)from;
return to;
case 6: /* for Ethernet addresses */
*(unsigned long *)to = *(const unsigned long *)from;
*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
return to;
case 8:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
return to;
case 12:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
return to;
case 16:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
return to;
case 20:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
return to;
}
#define COMMON(x) \
__asm__ __volatile__( \
"rep ; movsl" \
x \
: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
: "0" (n/4),"1" ((long) to),"2" ((long) from) \
: "memory");
{
int d0, d1, d2;
switch (n % 4) {
case 0: COMMON(""); return to;
case 1: COMMON("\n\tmovsb"); return to;
case 2: COMMON("\n\tmovsw"); return to;
default: COMMON("\n\tmovsw\n\tmovsb"); return to;
}
}
#undef COMMON
}
#define __HAVE_ARCH_MEMCPY
#define memcpy(t, f, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy((t),(f),(n)) : \
__memcpy((t),(f),(n)))
/*
* struct_cpy(x,y), copy structure *x into (matching structure) *y.
*
* We get link-time errors if the structure sizes do not match.
* There is no runtime overhead, it's all optimized away at
* compile time.
*/
//extern void __struct_cpy_bug (void);
/*
#define struct_cpy(x,y) \
({ \
if (sizeof(*(x)) != sizeof(*(y))) \
__struct_cpy_bug; \
memcpy(x, y, sizeof(*(x))); \
})
*/
#define __HAVE_ARCH_MEMMOVE
static inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
__asm__ __volatile__(
"rep\n\t"
"movsb"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),"1" (src),"2" (dest)
: "memory");
else
__asm__ __volatile__(
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),
"1" (n-1+(const char *)src),
"2" (n-1+(char *)dest)
:"memory");
return dest;
}
#define __HAVE_ARCH_MEMCMP
#define memcmp __builtin_memcmp
#define __HAVE_ARCH_MEMCHR
static inline void * memchr(const void * cs,int c,size_t count)
{
int d0;
register void * __res;
if (!count)
return NULL;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
return __res;
}
static inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
:"a" (c),"1" (s),"0" (count)
:"memory");
return s;
}
/* we might want to write optimized versions of these later */
#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
/*
* memset(x,0,y) is a reasonably common thing to do, so we want to fill
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep ; stosl\n\t"
"testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
"1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
: "=&c" (d0), "=&D" (d1)
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
:"memory");
return (s);
}
/* Added by Gertjan van Wingerde to make minix and sysv module work */
#define __HAVE_ARCH_STRNLEN
static inline size_t strnlen(const char * s, size_t count)
{
int d0;
register int __res;
__asm__ __volatile__(
"movl %2,%0\n\t"
"jmp 2f\n"
"1:\tcmpb $0,(%0)\n\t"
"je 3f\n\t"
"incl %0\n"
"2:\tdecl %1\n\t"
"cmpl $-1,%1\n\t"
"jne 1b\n"
"3:\tsubl %2,%0"
:"=a" (__res), "=&d" (d0)
:"c" (s),"1" (count));
return __res;
}
/* end of additional stuff */
//#define __HAVE_ARCH_STRSTR
//extern char *strstr(const char *cs, const char *ct);
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
return s;
case 1:
*(unsigned char *)s = pattern;
return s;
case 2:
*(unsigned short *)s = pattern;
return s;
case 3:
*(unsigned short *)s = pattern;
*(2+(unsigned char *)s) = pattern;
return s;
case 4:
*(unsigned long *)s = pattern;
return s;
}
#define COMMON(x) \
__asm__ __volatile__( \
"rep ; stosl" \
x \
: "=&c" (d0), "=&D" (d1) \
: "a" (pattern),"0" (count/4),"1" ((long) s) \
: "memory")
{
int d0, d1;
switch (count % 4) {
case 0: COMMON(""); return s;
case 1: COMMON("\n\tstosb"); return s;
case 2: COMMON("\n\tstosw"); return s;
default: COMMON("\n\tstosw\n\tstosb"); return s;
}
}
#undef COMMON
}
#define __constant_c_x_memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_c_and_count_memset((s),(c),(count)) : \
__constant_c_memset((s),(c),(count)))
#define __memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_count_memset((s),(c),(count)) : \
__memset_generic((s),(c),(count)))
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
__memset((s),(c),(count)))
/*
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
static inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
return addr;
__asm__("repnz; scasb\n\t"
"jnz 1f\n\t"
"dec %%edi\n"
"1:"
: "=D" (addr), "=c" (size)
: "0" (addr), "1" (size), "a" (c));
return addr;
}
#endif
+69
View File
@@ -0,0 +1,69 @@
#ifndef _X86_64_STRING_H_
#define _X86_64_STRING_H_
#ifdef __KERNEL__
#define struct_cpy(x,y) (*(x)=*(y))
/* Written 2002 by Andi Kleen */
/* Only used for special circumstances. Stolen from i386/string.h */
static inline void * __inline_memcpy(void * to, const void * from, size_t n)
{
unsigned long d0, d1, d2;
__asm__ __volatile__(
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
/* Even with __builtin_ the compiler may decide to use the out of line
function. */
#define __HAVE_ARCH_MEMCPY 1
extern void *__memcpy(void *to, const void *from, size_t len);
#define memcpy(dst,src,len) \
({ size_t __len = (len); \
void *__ret; \
if (__builtin_constant_p(len) && __len >= 64) \
__ret = __memcpy((dst),(src),__len); \
else \
__ret = __builtin_memcpy((dst),(src),__len); \
__ret; })
#define __HAVE_ARCH_MEMSET
#define memset __builtin_memset
#define __HAVE_ARCH_MEMMOVE
void * memmove(void * dest,const void *src,size_t count);
/* Use C out of line version for memcmp */
#define memcmp __builtin_memcmp
int memcmp(const void * cs,const void * ct,size_t count);
/* out of line string functions use always C versions */
#define strlen __builtin_strlen
size_t strlen(const char * s);
#define strcpy __builtin_strcpy
char * strcpy(char * dest,const char *src);
#define strcat __builtin_strcat
char * strcat(char * dest, const char * src);
#define strcmp __builtin_strcmp
int strcmp(const char * cs,const char * ct);
#endif /* __KERNEL__ */
#endif
+2 -2
View File
@@ -86,7 +86,7 @@ struct pfn_info
#define PageSetSlab(page) ((void)0)
#define PageClearSlab(page) ((void)0)
#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < MAX_XENHEAP_ADDRESS)
#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom) \
do { \
@@ -104,7 +104,7 @@ extern struct list_head free_list;
extern spinlock_t free_list_lock;
extern unsigned int free_pfns;
extern unsigned long max_page;
void init_frametable(unsigned long nr_pages);
void init_frametable(void *frametable_vstart, unsigned long nr_pages);
void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
struct pfn_info *alloc_domain_page(struct domain *p);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.