Lines 18-23
Link Here
|
18 |
#include "compat_page.h" |
18 |
#include "compat_page.h" |
19 |
#include <linux/binfmts.h> |
19 |
#include <linux/binfmts.h> |
20 |
#include <linux/fs.h> |
20 |
#include <linux/fs.h> |
|
|
21 |
#include <linux/kthread.h> |
21 |
#include "compat_sched.h" |
22 |
#include "compat_sched.h" |
22 |
#include <linux/file.h> |
23 |
#include <linux/file.h> |
23 |
#ifdef KERNEL_2_2 |
24 |
#ifdef KERNEL_2_2 |
Lines 70-79
Link Here
|
70 |
#include "compat_timer.h" |
71 |
#include "compat_timer.h" |
71 |
#include "x86.h" |
72 |
#include "x86.h" |
72 |
|
73 |
|
73 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
|
|
74 |
#include <linux/kthread.h> |
75 |
#include <linux/mutex.h> |
76 |
#endif |
77 |
static COMPAT_DECLARE_COMPLETION(fastClockExited); |
74 |
static COMPAT_DECLARE_COMPLETION(fastClockExited); |
78 |
|
75 |
|
79 |
/* |
76 |
/* |
Lines 140-234
Link Here
|
140 |
#define HOST_ISTRACKED_PFN(_vm, _pfn) (PhysTrack_Test(_vm->physTracker, _pfn)) |
137 |
#define HOST_ISTRACKED_PFN(_vm, _pfn) (PhysTrack_Test(_vm->physTracker, _pfn)) |
141 |
|
138 |
|
142 |
|
139 |
|
143 |
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) |
|
|
144 |
/* |
145 |
*----------------------------------------------------------------------------- |
146 |
* |
147 |
* MutexInit -- |
148 |
* |
149 |
* Initialize a Mutex. --hpreg |
150 |
* |
151 |
* Results: |
152 |
* None |
153 |
* |
154 |
* Side effects: |
155 |
* None |
156 |
* |
157 |
*----------------------------------------------------------------------------- |
158 |
*/ |
159 |
|
160 |
#define MutexInit(_mutex, _name) mutex_init(_mutex) |
161 |
/* |
162 |
*----------------------------------------------------------------------------- |
163 |
* |
164 |
* MutexIsLocked -- |
165 |
* |
166 |
* Determine if a Mutex is locked by the current thread. --hpreg |
167 |
* |
168 |
* Results: |
169 |
* TRUE if yes |
170 |
* FALSE if no |
171 |
* |
172 |
* Side effects: |
173 |
* None |
174 |
* |
175 |
*----------------------------------------------------------------------------- |
176 |
*/ |
177 |
|
178 |
#define MutexIsLocked(_mutex) mutex_is_locked(_mutex) |
179 |
|
180 |
/* |
181 |
*----------------------------------------------------------------------------- |
182 |
* |
183 |
* MutexLock -- |
184 |
* |
185 |
* Acquire a Mutex. --hpreg |
186 |
* |
187 |
* Results: |
188 |
* None |
189 |
* |
190 |
* Side effects: |
191 |
* None |
192 |
* |
193 |
*----------------------------------------------------------------------------- |
194 |
*/ |
195 |
|
196 |
#define MutexLock(_mutex, _callerID) mutex_lock(_mutex) |
197 |
|
198 |
/* |
199 |
*----------------------------------------------------------------------------- |
200 |
* |
201 |
* MutexUnlock -- |
202 |
* |
203 |
* Release a Mutex. --hpreg |
204 |
* |
205 |
* Results: |
206 |
* None |
207 |
* |
208 |
* Side effects: |
209 |
* None |
210 |
* |
211 |
*----------------------------------------------------------------------------- |
212 |
*/ |
213 |
|
214 |
#define MutexUnlock(_mutex, _callerID) mutex_unlock(_mutex) |
215 |
|
216 |
/* This mutex protects the driver-wide state. --hpreg */ |
217 |
static DEFINE_MUTEX(globalMutex); |
218 |
|
219 |
/* |
220 |
* This mutex protects the fast clock rate and is held while |
221 |
* creating/destroying the fastClockThread. It ranks below |
222 |
* globalMutex. We can't use globalMutex for this purpose because the |
223 |
* fastClockThread itself acquires the globalMutex, so trying to hold |
224 |
* the mutex while destroying the thread can cause a deadlock. |
225 |
*/ |
226 |
static DEFINE_MUTEX(fastClockMutex); |
227 |
|
228 |
/* This mutex protects linuxState.pollList. */ |
229 |
static DEFINE_MUTEX(pollListMutex); |
230 |
|
231 |
#else |
232 |
/* |
140 |
/* |
233 |
*----------------------------------------------------------------------------- |
141 |
*----------------------------------------------------------------------------- |
234 |
* |
142 |
* |
Lines 371-377
Link Here
|
371 |
/* This mutex protects linuxState.pollList. */ |
279 |
/* This mutex protects linuxState.pollList. */ |
372 |
static Mutex pollListMutex; |
280 |
static Mutex pollListMutex; |
373 |
|
281 |
|
374 |
#endif /* USE_KTHREAD */ |
|
|
375 |
|
282 |
|
376 |
/* |
283 |
/* |
377 |
*----------------------------------------------------------------------------- |
284 |
*----------------------------------------------------------------------------- |
Lines 444-450
Link Here
|
444 |
MutexUnlock(&globalMutex, callerID); |
351 |
MutexUnlock(&globalMutex, callerID); |
445 |
} |
352 |
} |
446 |
|
353 |
|
447 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) |
354 |
|
448 |
#ifdef VMX86_DEBUG |
355 |
#ifdef VMX86_DEBUG |
449 |
/* |
356 |
/* |
450 |
*----------------------------------------------------------------------------- |
357 |
*----------------------------------------------------------------------------- |
Lines 469-475
Link Here
|
469 |
return MutexIsLocked(&globalMutex); |
376 |
return MutexIsLocked(&globalMutex); |
470 |
} |
377 |
} |
471 |
#endif |
378 |
#endif |
472 |
#endif |
|
|
473 |
|
379 |
|
474 |
|
380 |
|
475 |
/* |
381 |
/* |
Lines 564-570
Link Here
|
564 |
MutexUnlock(&pollListMutex, callerID); |
470 |
MutexUnlock(&pollListMutex, callerID); |
565 |
} |
471 |
} |
566 |
|
472 |
|
567 |
|
|
|
568 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 3) |
473 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 3) |
569 |
static INLINE void |
474 |
static INLINE void |
570 |
down_write_mmap(void) |
475 |
down_write_mmap(void) |
Lines 620-626
Link Here
|
620 |
up_write_mmap(); |
525 |
up_write_mmap(); |
621 |
} |
526 |
} |
622 |
#endif |
527 |
#endif |
623 |
|
|
|
624 |
/* |
528 |
/* |
625 |
*---------------------------------------------------------------------- |
529 |
*---------------------------------------------------------------------- |
626 |
* |
530 |
* |
Lines 678-684
Link Here
|
678 |
#else |
582 |
#else |
679 |
pte_val(*pte) &= ~_PAGE_NX; |
583 |
pte_val(*pte) &= ~_PAGE_NX; |
680 |
#endif |
584 |
#endif |
681 |
compat_smp_call_function (TLBInvalidatePage, (void *)vaddr, 1, 1); |
585 |
smp_call_function (TLBInvalidatePage, (void *)vaddr, 1); |
682 |
TLBInvalidatePage((void *)vaddr); |
586 |
TLBInvalidatePage((void *)vaddr); |
683 |
} |
587 |
} |
684 |
if (ptemap) { |
588 |
if (ptemap) { |
Lines 2911-2917
Link Here
|
2911 |
if (targetHostCpu != INVALID_HOST_CPU) { |
2815 |
if (targetHostCpu != INVALID_HOST_CPU) { |
2912 |
ASSERT(targetHostCpu < MAX_PROCESSORS); |
2816 |
ASSERT(targetHostCpu < MAX_PROCESSORS); |
2913 |
(void) compat_smp_call_function(LinuxDriverIPIHandler, |
2817 |
(void) compat_smp_call_function(LinuxDriverIPIHandler, |
2914 |
NULL, 1, 1); |
2818 |
NULL, 1); |
2915 |
return TRUE; |
2819 |
return TRUE; |
2916 |
} |
2820 |
} |
2917 |
} |
2821 |
} |
Lines 3099-3105
Link Here
|
3099 |
{ |
3003 |
{ |
3100 |
compat_preempt_disable(); |
3004 |
compat_preempt_disable(); |
3101 |
HostIFFillCPUID((void*)info); |
3005 |
HostIFFillCPUID((void*)info); |
3102 |
(void)compat_smp_call_function(HostIFFillCPUID, (void*)info, 1, 1); |
3006 |
(void)compat_smp_call_function(HostIFFillCPUID, (void*)info, 1); |
3103 |
compat_preempt_enable(); |
3007 |
compat_preempt_enable(); |
3104 |
} |
3008 |
} |
3105 |
|
3009 |
|
Lines 3136-3142
Link Here
|
3136 |
compat_preempt_disable(); |
3040 |
compat_preempt_disable(); |
3137 |
HostIFBrokenCPUHelper((void*)&badcpumask); // run on this machine CPU |
3041 |
HostIFBrokenCPUHelper((void*)&badcpumask); // run on this machine CPU |
3138 |
(void)compat_smp_call_function(HostIFBrokenCPUHelper, (void*)&badcpumask, |
3042 |
(void)compat_smp_call_function(HostIFBrokenCPUHelper, (void*)&badcpumask, |
3139 |
1, 1); // run on all other machine CPUs |
3043 |
1); // run on all other machine CPUs |
3140 |
compat_preempt_enable(); |
3044 |
compat_preempt_enable(); |
3141 |
|
3045 |
|
3142 |
return badcpumask; |
3046 |
return badcpumask; |
Lines 3335-3380
Link Here
|
3335 |
/* |
3239 |
/* |
3336 |
*---------------------------------------------------------------------- |
3240 |
*---------------------------------------------------------------------- |
3337 |
* |
3241 |
* |
3338 |
* HostIFDoIoctl -- |
|
|
3339 |
* |
3340 |
* Issue ioctl. Assume kernel is not locked. It is not true now, |
3341 |
* but it makes things easier to understand, and won't surprise us |
3342 |
* later when we get rid of kernel lock from our code. |
3343 |
* |
3344 |
* Results: |
3345 |
* Same as ioctl method. |
3346 |
* |
3347 |
* Side effects: |
3348 |
* none. |
3349 |
* |
3350 |
*---------------------------------------------------------------------- |
3351 |
*/ |
3352 |
|
3353 |
static long |
3354 |
HostIFDoIoctl(struct file *filp, |
3355 |
u_int iocmd, |
3356 |
unsigned long ioarg) |
3357 |
{ |
3358 |
#ifdef HAVE_UNLOCKED_IOCTL |
3359 |
if (filp->f_op->unlocked_ioctl) { |
3360 |
return filp->f_op->unlocked_ioctl(filp, iocmd, ioarg); |
3361 |
} |
3362 |
#endif |
3363 |
if (filp->f_op->ioctl) { |
3364 |
long err; |
3365 |
|
3366 |
lock_kernel(); |
3367 |
err = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, iocmd, ioarg); |
3368 |
unlock_kernel(); |
3369 |
return err; |
3370 |
} |
3371 |
return -ENOIOCTLCMD; |
3372 |
} |
3373 |
|
3374 |
|
3375 |
/* |
3376 |
*---------------------------------------------------------------------- |
3377 |
* |
3378 |
* HostIFFastClockThread -- |
3242 |
* HostIFFastClockThread -- |
3379 |
* |
3243 |
* |
3380 |
* Kernel thread that provides finer-grained wakeups than the |
3244 |
* Kernel thread that provides finer-grained wakeups than the |
Lines 3399-3413
Link Here
|
3399 |
int res; |
3263 |
int res; |
3400 |
mm_segment_t oldFS; |
3264 |
mm_segment_t oldFS; |
3401 |
unsigned rate = 0; |
3265 |
unsigned rate = 0; |
|
|
3266 |
struct cred *cred; |
3402 |
|
3267 |
|
3403 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) |
|
|
3404 |
compat_daemonize("vmware-rtc"); |
3268 |
compat_daemonize("vmware-rtc"); |
3405 |
#endif |
|
|
3406 |
oldFS = get_fs(); |
3269 |
oldFS = get_fs(); |
3407 |
set_fs(KERNEL_DS); |
3270 |
set_fs(KERNEL_DS); |
3408 |
compat_allow_signal(SIGKILL); |
3271 |
compat_allow_signal(SIGKILL); |
3409 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3272 |
cred = prepare_creds(); |
3410 |
compat_set_user_nice(current, -20); |
3273 |
if(!cred) |
|
|
3274 |
return -ENOMEM; |
3275 |
cap_raise(cred->cap_effective, CAP_SYS_RESOURCE); |
3276 |
commit_creds(cred); |
3277 |
|
3278 |
//compat_set_user_nice(current, -20); |
3411 |
|
3279 |
|
3412 |
while (linuxState.fastClockRate > HZ + HZ/16) { |
3280 |
while (linuxState.fastClockRate > HZ + HZ/16) { |
3413 |
unsigned long buf; |
3281 |
unsigned long buf; |
Lines 3423-3429
Link Here
|
3423 |
p2rate <<= 1; |
3291 |
p2rate <<= 1; |
3424 |
} |
3292 |
} |
3425 |
|
3293 |
|
3426 |
res = HostIFDoIoctl(filp, RTC_IRQP_SET, p2rate); |
3294 |
res = filp->f_op->ioctl(filp->f_dentry->d_inode, |
|
|
3295 |
filp, RTC_IRQP_SET, p2rate); |
3427 |
if (res < 0) { |
3296 |
if (res < 0) { |
3428 |
Warning("/dev/rtc set rate %d failed: %d\n", p2rate, res); |
3297 |
Warning("/dev/rtc set rate %d failed: %d\n", p2rate, res); |
3429 |
goto out; |
3298 |
goto out; |
Lines 3526-3556
Link Here
|
3526 |
if (rate > HZ + HZ/16) { |
3395 |
if (rate > HZ + HZ/16) { |
3527 |
if (!linuxState.fastClockThread) { |
3396 |
if (!linuxState.fastClockThread) { |
3528 |
struct file *filp; |
3397 |
struct file *filp; |
|
|
3398 |
struct cred *cred; |
3529 |
int fsuid, res; |
3399 |
int fsuid, res; |
3530 |
Bool cap; |
3400 |
Bool cap; |
3531 |
struct task_struct *t; |
3401 |
struct task_struct *t; |
3532 |
|
3402 |
|
3533 |
fsuid = current->fsuid; |
3403 |
/*fsuid = current->fsuid; |
3534 |
current->fsuid = 0; |
3404 |
current->fsuid = 0; |
|
|
3405 |
*/ |
3406 |
cred = prepare_creds(); |
3407 |
fsuid = cred->fsuid; |
3408 |
cred->fsuid = 0; |
3409 |
commit_creds(cred); |
3535 |
filp = filp_open("/dev/rtc", O_RDONLY, 0); |
3410 |
filp = filp_open("/dev/rtc", O_RDONLY, 0); |
3536 |
current->fsuid = fsuid; |
3411 |
cred = prepare_creds(); |
|
|
3412 |
cred->fsuid = fsuid; |
3413 |
commit_creds(cred); |
3414 |
//current->fsuid = fsuid; |
3537 |
if (IS_ERR(filp) || !filp) { |
3415 |
if (IS_ERR(filp) || !filp) { |
3538 |
Warning("/dev/rtc open failed: %d\n", (int)(VA)filp); |
3416 |
Warning("/dev/rtc open failed: %d\n", (int)(VA)filp); |
3539 |
return -(int)(VA)filp; |
3417 |
return -(int)(VA)filp; |
3540 |
} |
3418 |
} |
3541 |
cap = cap_raised(current->cap_effective, CAP_SYS_RESOURCE); |
3419 |
/* cap = cap_raised(current->cap_effective, CAP_SYS_RESOURCE); |
3542 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3420 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3543 |
res = HostIFDoIoctl(filp, RTC_PIE_ON, 0); |
3421 |
*/ |
|
|
3422 |
cred = prepare_creds(); |
3423 |
cap = cap_raised(cred->cap_effective, CAP_SYS_RESOURCE); |
3424 |
cap_raise(cred->cap_effective, CAP_SYS_RESOURCE); |
3425 |
commit_creds(cred); |
3426 |
if (filp->f_op->ioctl) { |
3427 |
lock_kernel(); |
3428 |
res = filp->f_op->ioctl(filp->f_path.dentry->d_inode, filp, RTC_PIE_ON, 0); |
3429 |
unlock_kernel(); |
3430 |
} |
3431 |
else |
3432 |
res = -1; |
3544 |
if (!cap) { |
3433 |
if (!cap) { |
3545 |
cap_lower(current->cap_effective, CAP_SYS_RESOURCE); |
3434 |
cred = prepare_creds(); |
|
|
3435 |
// cap_lower(current->cap_effective, CAP_SYS_RESOURCE); |
3436 |
cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); |
3437 |
commit_creds(cred); |
3546 |
} |
3438 |
} |
3547 |
if (res < 0) { |
3439 |
if (res < 0) { |
3548 |
Warning("/dev/rtc enable interrupt failed: %d\n", res); |
3440 |
Warning("/dev/rtc enable interrupt failed: %d\n", res); |
3549 |
compat_filp_close(filp, current->files); |
3441 |
compat_filp_close(filp, current->files); |
3550 |
return -res; |
3442 |
return -res; |
3551 |
} |
3443 |
} |
3552 |
t = kthread_create(HostIFFastClockThread, filp, "vmware-rtc"); |
3444 |
t = kthread_create(HostIFFastClockThread, filp, "vmware-rtc"); |
3553 |
if (IS_ERR(t)) { |
3445 |
if (IS_ERR(t)) { |
3554 |
/* |
3446 |
/* |
3555 |
* Ignore ERESTARTNOINTR silently, it occurs when signal is |
3447 |
* Ignore ERESTARTNOINTR silently, it occurs when signal is |
3556 |
* pending, and syscall layer automatically reissues operation |
3448 |
* pending, and syscall layer automatically reissues operation |
Lines 3563-3573
Link Here
|
3563 |
return -PTR_ERR(t); |
3455 |
return -PTR_ERR(t); |
3564 |
} |
3456 |
} |
3565 |
linuxState.fastClockThread = t; |
3457 |
linuxState.fastClockThread = t; |
3566 |
wake_up_process(t); |
3458 |
wake_up_process(t); |
3567 |
} |
3459 |
} |
3568 |
} else { |
3460 |
} else { |
3569 |
if (linuxState.fastClockThread) { |
3461 |
if (linuxState.fastClockThread) { |
3570 |
send_sig(SIGKILL, linuxState.fastClockThread, 1); |
3462 |
send_sig(SIGKILL, linuxState.fastClockThread, 1); |
3571 |
compat_wait_for_completion(&fastClockExited); |
3463 |
compat_wait_for_completion(&fastClockExited); |
3572 |
linuxState.fastClockThread = NULL; |
3464 |
linuxState.fastClockThread = NULL; |
3573 |
} |
3465 |
} |