807
810
ENTER4("pool_type: %d, size: %lu, tag: 0x%x", pool_type, size, tag);
811
assert_irql(_irql_ <= DISPATCH_LEVEL);
808
812
if (size < PAGE_SIZE)
809
addr = kmalloc(size, gfp_irql());
813
addr = kmalloc(size, irql_gfp());
811
KIRQL irql = current_irql();
813
if (irql < DISPATCH_LEVEL) {
815
if (irql_gfp() & GFP_ATOMIC) {
816
addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM,
818
TRACE1("%p, %lu", addr, size);
814
820
addr = vmalloc(size);
815
821
TRACE1("%p, %lu", addr, size);
816
} else if (irql == DISPATCH_LEVEL) {
817
addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM,
819
TRACE1("%p, %lu", addr, size);
821
TRACE1("Windows driver allocating %lu bytes in "
822
"interrupt context: 0x%x", size, preempt_count());
826
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
827
/* 2.6.19+ kernels don't allow __vmalloc (even
828
* with GFP_ATOMIC) in interrupt context */
831
addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM,
835
TRACE1("%p, %lu", addr, size);
837
WARNING("couldn't allocate %lu bytes of memory "
838
"at %d", size, irql);
844
826
TRACE4("addr: %p, %lu", addr, size);
846
828
TRACE1("failed: %lu", size);
851
832
WIN_FUNC_DECL(ExAllocatePoolWithTag,3)
1144
1124
if (timeout == NULL)
1147
wait_hz = SYSTEM_TIME_TO_HZ(*timeout) + 1;
1127
wait_hz = SYSTEM_TIME_TO_HZ(*timeout);
1149
assert(current_irql() < DISPATCH_LEVEL);
1130
KIRQL irql = current_irql();
1131
if (irql >= DISPATCH_LEVEL) {
1132
TRACE2("wait in atomic context: %Lu, %lu, %d, %ld",
1133
*timeout, wait_hz, in_atomic(), in_interrupt());
1136
assert_irql(_irql_ < DISPATCH_LEVEL);
1150
1137
EVENTTRACE("%p: sleep for %ld on %p", current, wait_hz, &wait_done);
1151
1138
/* we don't honor 'alertable' - according to decription for
1152
1139
* this, even if waiting in non-alertable state, thread may be
1153
1140
* alerted in some circumstances */
1154
1141
while (wait_count) {
1155
1142
res = wait_condition(wait_done, wait_hz, TASK_INTERRUPTIBLE);
1156
nt_spin_lock_bh(&dispatcher_lock);
1143
spin_lock_bh(&dispatcher_lock);
1157
1144
EVENTTRACE("%p woke up: %d, %d", current, res, wait_done);
1158
1145
/* the event may have been set by the time
1159
1146
* wrap_wait_event returned and spinlock obtained, so
1563
1565
else if (prio == HIGH_PRIORITY)
1564
1566
set_thread_priority(task, -10);
1566
TRACE2("%d, %d", old_prio, thread_priority(task));
1568
TRACE2("%d, %d", old_prio, (int)thread_priority(task));
1567
1569
return old_prio;
1570
struct thread_trampoline_info {
1572
struct thread_trampoline {
1571
1573
void (*func)(void *) wstdcall;
1573
1575
struct nt_thread *thread;
1574
1576
struct completion started;
1577
static int thread_trampoline(void *data)
1579
static int ntdriver_thread(void *data)
1579
struct thread_trampoline_info *thread_info = data;
1581
struct thread_trampoline *thread_tramp = data;
1583
typeof(thread_tramp->func) func = thread_tramp->func;
1584
typeof(thread_tramp->ctx) ctx = thread_tramp->ctx;
1581
thread_info->thread->task = current;
1582
thread_info->thread->pid = current->pid;
1583
TRACE2("thread: %p, task: %p (%d)", thread_info->thread,
1586
thread_tramp->thread->task = current;
1587
thread_tramp->thread->pid = current->pid;
1588
TRACE2("thread: %p, task: %p (%d)", thread_tramp->thread,
1584
1589
current, current->pid);
1585
complete(&thread_info->started);
1590
complete(&thread_tramp->started);
1587
1592
#ifdef PF_NOFREEZE
1588
1593
current->flags |= PF_NOFREEZE;
1590
strncpy(current->comm, "windisdrvr", sizeof(current->comm));
1595
strncpy(current->comm, "ntdriver", sizeof(current->comm));
1591
1596
current->comm[sizeof(current->comm)-1] = 0;
1592
LIN2WIN1(thread_info->func, thread_info->ctx);
1597
LIN2WIN1(func, ctx);
1593
1598
ERROR("task: %p", current);
1597
1602
wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7)
1598
(void **phandle, ULONG access, void *obj_attr, void *process,
1603
(void **handle, ULONG access, void *obj_attr, void *process,
1599
1604
void *client_id, void (*func)(void *) wstdcall, void *ctx)
1601
struct nt_thread *thread;
1602
struct thread_trampoline_info thread_info;
1603
no_warn_unused struct task_struct *task;
1604
no_warn_unused int pid;
1606
struct thread_trampoline thread_tramp;
1606
ENTER2("phandle = %p, access = %u, obj_attr = %p, process = %p, "
1607
"client_id = %p, func = %p, context = %p", phandle, access,
1608
ENTER2("handle = %p, access = %u, obj_attr = %p, process = %p, "
1609
"client_id = %p, func = %p, context = %p", handle, access,
1608
1610
obj_attr, process, client_id, func, ctx);
1610
thread = create_nt_thread(NULL);
1612
thread_tramp.thread = create_nt_thread(NULL);
1613
if (!thread_tramp.thread) {
1612
1614
ERROR("couldn't allocate thread object");
1613
1615
EXIT2(return STATUS_RESOURCES);
1615
TRACE2("thread: %p", thread);
1616
thread_info.thread = thread;
1617
thread_info.func = func;
1618
thread_info.ctx = ctx;
1619
init_completion(&thread_info.started);
1617
TRACE2("thread: %p", thread_tramp.thread);
1618
thread_tramp.func = func;
1619
thread_tramp.ctx = ctx;
1620
init_completion(&thread_tramp.started);
1621
1622
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
1622
pid = kernel_thread(thread_trampoline, &thread_info, CLONE_SIGHAND);
1623
TRACE2("pid = %d", pid);
1625
free_object(thread_info.thread);
1623
thread_tramp.thread->pid = kernel_thread(ntdriver_thread, &thread_tramp,
1625
TRACE2("pid = %d", thread_tramp.thread->pid);
1626
if (thread_tramp.thread->pid < 0) {
1627
free_object(thread_tramp.thread);
1626
1628
EXIT2(return STATUS_FAILURE);
1628
TRACE2("created task: %d", pid);
1630
TRACE2("created task: %d", thread_tramp.thread->pid);
1630
task = kthread_run(thread_trampoline, &thread_info, "windisdrvr");
1632
free_object(thread_info.thread);
1632
thread_tramp.thread->task = kthread_run(ntdriver_thread,
1633
&thread_tramp, "ntdriver");
1634
if (IS_ERR(thread_tramp.thread->task)) {
1635
free_object(thread_tramp.thread);
1633
1636
EXIT2(return STATUS_FAILURE);
1635
TRACE2("created task: %p (%d)", task, task->pid);
1638
TRACE2("created task: %p", thread_tramp.thread->task);
1638
wait_for_completion(&thread_info.started);
1639
*phandle = OBJECT_TO_HEADER(thread_info.thread);
1640
TRACE2("created thread: %p, %p", thread_info.thread, *phandle);
1641
wait_for_completion(&thread_tramp.started);
1642
*handle = OBJECT_TO_HEADER(thread_tramp.thread);
1643
TRACE2("created thread: %p, %p", thread_tramp.thread, *handle);
1641
1644
EXIT2(return STATUS_SUCCESS);
1649
1652
TRACE2("%p, %08X", current, status);
1650
1653
thread = get_current_nt_thread();
1651
1654
TRACE2("%p", thread);
1656
KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE);
1658
struct nt_list *ent;
1661
irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);
1662
ent = RemoveHeadList(&thread->irps);
1663
nt_spin_unlock_irql(&thread->lock, irql);
1666
irp = container_of(ent, struct irp, thread_list);
1670
/* the driver may later query this status with
1671
* ZwQueryInformationThread */
1672
thread->status = status;
1653
1674
ERROR("couldn't find thread for task: %p", current);
1654
return STATUS_FAILURE;
1656
KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE);
1658
struct nt_list *ent;
1661
irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);
1662
ent = RemoveHeadList(&thread->irps);
1663
nt_spin_unlock_irql(&thread->lock, irql);
1666
irp = container_of(ent, struct irp, thread_list);
1670
/* the driver may later query this status with
1671
* ZwQueryInformationThread */
1672
thread->status = status;
1673
1676
complete_and_exit(NULL, status);
1674
1677
ERROR("oops: %p, %d", thread->task, thread->pid);
1675
1678
return STATUS_FAILURE;
1711
1715
PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type)
1714
addr = wrap_get_free_pages(gfp_irql(), size);
1715
TRACE4("%p, %lu", addr, size);
1720
ENTER2("%lu, 0x%lx, 0x%lx, 0x%lx, %d", size, (long)lowest,
1721
(long)highest, (long)boundary, cache_type);
1723
addr = wrap_get_free_pages(flags, size);
1724
TRACE2("%p, %lu, 0x%x", addr, size, flags);
1725
if (addr && ((virt_to_phys(addr) + size) <= highest))
1727
#ifdef CONFIG_X86_64
1728
/* GFP_DMA is really only 16MB even on x86-64, but there is no
1729
* other zone available */
1730
if (highest <= DMA_31BIT_MASK)
1732
else if (highest <= DMA_32BIT_MASK)
1733
flags |= __GFP_DMA32;
1735
if (highest <= DMA_24BIT_MASK)
1737
else if (highest > DMA_30BIT_MASK)
1738
flags |= __GFP_HIGHMEM;
1740
addr = wrap_get_free_pages(flags, size);
1741
TRACE2("%p, %lu, 0x%x", addr, size, flags);
1719
1745
wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3)
1720
1746
(void *base, SIZE_T size, enum memory_caching_type cache_type)
1722
TRACE4("%p, %lu", base, size);
1748
TRACE2("%p, %lu", base, size);
1723
1749
free_pages((unsigned long)base, get_order(size));
1726
1752
wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1)
1730
return virt_to_phys(base);
1755
unsigned long phy = virt_to_phys(base);
1756
TRACE2("%p, %p", base, (void *)phy);
1733
1760
/* Atheros card with pciid 168C:0014 calls this function with 0xf0000
2642
2696
if (ntos_worker_thread)
2643
2697
ObDereferenceObject(ntos_worker_thread);
2644
2698
ENTER2("freeing objects");
2645
irql = nt_spin_lock_irql(&ntoskernel_lock, DISPATCH_LEVEL);
2699
spin_lock_bh(&ntoskernel_lock);
2646
2700
while ((cur = RemoveHeadList(&object_list))) {
2647
2701
struct common_object_header *hdr;
2648
2702
hdr = container_of(cur, struct common_object_header, list);
2649
WARNING("object %p type %d was not freed, freeing it now",
2650
HEADER_TO_OBJECT(hdr), hdr->type);
2703
if (hdr->type == OBJECT_TYPE_NT_THREAD)
2704
TRACE1("object %p(%d) was not freed, freeing it now",
2705
HEADER_TO_OBJECT(hdr), hdr->type);
2707
WARNING("object %p(%d) was not freed, freeing it now",
2708
HEADER_TO_OBJECT(hdr), hdr->type);
2651
2709
ExFreePool(hdr);
2653
nt_spin_unlock_irql(&ntoskernel_lock, irql);
2711
spin_unlock_bh(&ntoskernel_lock);