~n-muench/ubuntu/maverick/open-vm-tools/open-vm-tools.fix-632101

« back to all changes in this revision

Viewing changes to modules/freebsd/vmmemctl/os.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-10-18 12:28:19 UTC
  • mfrom: (1.1.7 upstream) (2.4.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091018122819-00vqew6m0ztpqcqp
Tags: 2009.10.15-201664-1
MergingĀ upstreamĀ versionĀ 2009.10.15-201664.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 *
17
17
 *********************************************************/
18
18
 
19
 
/* 
 
19
/*
20
20
 * os.c --
21
21
 *
22
 
 *      Wrappers for FreeBSD system functions required by "vmmemctl".
23
 
 *      This allows customers to build their own vmmemctl driver for
24
 
 *      custom FreeBSD kernels without the need for source code.
 
22
 *      Wrappers for FreeBSD system functions required by "vmmemctl".
25
23
 */
26
24
 
27
25
/*
28
26
 * Compile-Time Options
29
27
 */
30
28
 
31
 
#define OS_DISABLE_UNLOAD       (0)
32
 
#define OS_DEBUG                (1)
 
29
#define OS_DISABLE_UNLOAD   0
 
30
#define OS_DEBUG            1
33
31
 
34
32
/*
35
33
 * Includes
56
54
#include <machine/stdarg.h>
57
55
 
58
56
#include "os.h"
59
 
 
60
 
/*
61
 
 * Constants
62
 
 */
 
57
#include "vmballoon.h"
63
58
 
64
59
/*
65
60
 * Types
73
68
   volatile int stop;
74
69
 
75
70
   /* registered state */
76
 
   os_timer_handler handler;
 
71
   OSTimerHandler *handler;
77
72
   void *data;
78
73
   int period;
79
74
} os_timer;
80
75
 
81
76
typedef struct {
82
77
   /* registered state */
83
 
   os_status_handler handler;
 
78
   OSStatusHandler *handler;
84
79
   const char *name_verbose;
85
80
   const char *name;
86
81
} os_status;
109
104
static void vmmemctl_init_sysctl(void);
110
105
static void vmmemctl_deinit_sysctl(void);
111
106
 
112
 
/*
113
 
 * Simple Wrappers
114
 
 */
115
 
 
116
 
void *os_kmalloc_nosleep(unsigned int size)
117
 
{
118
 
   return(malloc(size, M_VMMEMCTL, M_NOWAIT));
119
 
}
120
 
 
121
 
void os_kfree(void *obj, unsigned int size)
122
 
{
123
 
   free(obj, M_VMMEMCTL);
124
 
}
125
 
 
126
 
void os_bzero(void *b, unsigned int len)
127
 
{
128
 
   bzero(b, len);
129
 
}
130
 
 
131
 
void os_memcpy(void *dest, const void *src, unsigned int size)
 
107
 
 
108
/*
 
109
 *-----------------------------------------------------------------------------
 
110
 *
 
111
 * OS_Malloc --
 
112
 *
 
113
 *      Allocates kernel memory.
 
114
 *
 
115
 * Results:
 
116
 *      On success: Pointer to allocated memory
 
117
 *      On failure: NULL
 
118
 *
 
119
 * Side effects:
 
120
 *      None
 
121
 *
 
122
 *-----------------------------------------------------------------------------
 
123
 */
 
124
 
 
125
void *
 
126
OS_Malloc(size_t size) // IN
 
127
{
 
128
   return malloc(size, M_VMMEMCTL, M_NOWAIT);
 
129
}
 
130
 
 
131
 
 
132
/*
 
133
 *-----------------------------------------------------------------------------
 
134
 *
 
135
 * OS_Free --
 
136
 *
 
137
 *      Free allocated kernel memory.
 
138
 *
 
139
 * Results:
 
140
 *      None
 
141
 *
 
142
 * Side effects:
 
143
 *      None
 
144
 *
 
145
 *-----------------------------------------------------------------------------
 
146
 */
 
147
 
 
148
void
 
149
OS_Free(void *ptr,   // IN
 
150
        size_t size) // IN
 
151
{
 
152
   free(ptr, M_VMMEMCTL);
 
153
}
 
154
 
 
155
 
 
156
/*
 
157
 *-----------------------------------------------------------------------------
 
158
 *
 
159
 * OS_MemZero --
 
160
 *
 
161
 *      Fill a memory location with 0s.
 
162
 *
 
163
 * Results:
 
164
 *      None
 
165
 *
 
166
 * Side effects:
 
167
 *      None
 
168
 *
 
169
 *-----------------------------------------------------------------------------
 
170
 */
 
171
 
 
172
void
 
173
OS_MemZero(void *ptr,   // OUT
 
174
           size_t size) // IN
 
175
{
 
176
   bzero(ptr, size);
 
177
}
 
178
 
 
179
 
 
180
/*
 
181
 *-----------------------------------------------------------------------------
 
182
 *
 
183
 * OS_MemCopy --
 
184
 *
 
185
 *      Copy a memory portion into another location.
 
186
 *
 
187
 * Results:
 
188
 *      None
 
189
 *
 
190
 * Side effects:
 
191
 *      None
 
192
 *
 
193
 *-----------------------------------------------------------------------------
 
194
 */
 
195
 
 
196
void
 
197
OS_MemCopy(void *dest,      // OUT
 
198
           const void *src, // IN
 
199
           size_t size)     // IN
132
200
{
133
201
   memcpy(dest, src, size);
134
202
}
148
216
   return word;
149
217
}
150
218
 
151
 
int os_sprintf(char *str, const char *format, ...)
 
219
 
 
220
/*
 
221
 *-----------------------------------------------------------------------------
 
222
 *
 
223
 * OS_Snprintf --
 
224
 *
 
225
 *      Print a string into a bounded memory location.
 
226
 *
 
227
 * Results:
 
228
 *      Number of character printed including trailing \0.
 
229
 *
 
230
 * Side effects:
 
231
 *      None
 
232
 *
 
233
 *-----------------------------------------------------------------------------
 
234
 */
 
235
 
 
236
int
 
237
OS_Snprintf(char *buf,          // OUT
 
238
            size_t size,        // IN
 
239
            const char *format, // IN
 
240
            ...)                // IN
152
241
{
 
242
   int result;
153
243
   va_list args;
 
244
 
154
245
   va_start(args, format);
155
 
   return(vsprintf(str, format, args));
156
 
}
157
 
 
158
 
/*
159
 
 * System-Dependent Operations
160
 
 */
161
 
 
162
 
char *os_identity(void)
163
 
{
164
 
   return("bsd");
165
 
}
166
 
 
167
 
/*
168
 
 * Predict the maximum achievable balloon size.
169
 
 *
170
 
 * Currently we just return the total memory pages.
171
 
 */
172
 
unsigned int os_predict_max_balloon_pages(void)
173
 
{
174
 
   return(cnt.v_page_count);
175
 
}
176
 
 
177
 
unsigned long os_addr_to_ppn(unsigned long addr)
178
 
{
179
 
   return (((vm_page_t)addr)->phys_addr) >> PAGE_SHIFT;
180
 
}
181
 
 
182
 
static void os_pmap_alloc(os_pmap *p)
 
246
   result = vsnprintf(buf, size, format, args);
 
247
   va_end(args);
 
248
 
 
249
   return result;
 
250
}
 
251
 
 
252
 
 
253
/*
 
254
 *-----------------------------------------------------------------------------
 
255
 *
 
256
 * OS_Identity --
 
257
 *
 
258
 *      Returns an identifier for the guest OS family.
 
259
 *
 
260
 * Results:
 
261
 *      The identifier
 
262
 *
 
263
 * Side effects:
 
264
 *      None
 
265
 *
 
266
 *-----------------------------------------------------------------------------
 
267
 */
 
268
 
 
269
BalloonGuest
 
270
OS_Identity(void)
 
271
{
 
272
   return BALLOON_GUEST_BSD;
 
273
}
 
274
 
 
275
 
 
276
/*
 
277
 *-----------------------------------------------------------------------------
 
278
 *
 
279
 * OS_ReservedPageGetLimit --
 
280
 *
 
281
 *      Predict the maximum achievable balloon size.
 
282
 *
 
283
 * Results:
 
284
 *      Total memory pages.
 
285
 *
 
286
 * Side effects:
 
287
 *      None
 
288
 *
 
289
 *-----------------------------------------------------------------------------
 
290
 */
 
291
 
 
292
unsigned long
 
293
OS_ReservedPageGetLimit(void)
 
294
{
 
295
   return cnt.v_page_count;
 
296
}
 
297
 
 
298
 
 
299
/*
 
300
 *-----------------------------------------------------------------------------
 
301
 *
 
302
 * OS_ReservedPageGetPPN --
 
303
 *
 
304
 *      Convert a page handle (of a physical page previously reserved with
 
305
 *      OS_ReservedPageAlloc()) to a ppn.
 
306
 *
 
307
 * Results:
 
308
 *      The ppn.
 
309
 *
 
310
 * Side effects:
 
311
 *      None.
 
312
 *
 
313
 *-----------------------------------------------------------------------------
 
314
 */
 
315
 
 
316
unsigned long
 
317
OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
 
318
{
 
319
   return (((vm_page_t)handle)->phys_addr) >> PAGE_SHIFT;
 
320
}
 
321
 
 
322
 
 
323
static void
 
324
os_pmap_alloc(os_pmap *p) // IN
183
325
{
184
326
   /* number of pages (div. 8) */
185
327
   p->size = (cnt.v_page_count + 7) / 8;
186
328
 
187
 
   /* 
 
329
   /*
188
330
    * expand to nearest word boundary 
189
331
    * XXX: bitmap can be greater than total number of pages in system 
190
332
    */
194
336
   p->bitmap = (unsigned long *)kmem_alloc(kernel_map, p->size);
195
337
}
196
338
 
197
 
static void os_pmap_free(os_pmap *p)
 
339
 
 
340
static void
 
341
os_pmap_free(os_pmap *p) // IN
198
342
{
199
343
   kmem_free(kernel_map, (vm_offset_t)p->bitmap, p->size);
200
344
   p->size = 0;
201
345
   p->bitmap = NULL;
202
346
}
203
347
 
204
 
static void os_pmap_init(os_pmap *p)
 
348
 
 
349
static void
 
350
os_pmap_init(os_pmap *p) // IN
205
351
{
206
352
   /* alloc bitmap for pages in system */
207
 
   os_pmap_alloc(p); 
 
353
   os_pmap_alloc(p);
208
354
   if (!p->bitmap) {
209
355
      p->size = 0;
210
356
      p->bitmap = NULL;
216
362
   p->hint = 0;
217
363
}
218
364
 
219
 
static vm_pindex_t os_pmap_getindex(os_pmap *p)
 
365
 
 
366
static vm_pindex_t
 
367
os_pmap_getindex(os_pmap *p) // IN
220
368
{
221
369
   int i;
222
370
   unsigned long bitidx, wordidx;
248
396
   return (vm_pindex_t)-1;
249
397
}
250
398
 
251
 
static void os_pmap_putindex(os_pmap *p, vm_pindex_t pindex)
 
399
 
 
400
static void
 
401
os_pmap_putindex(os_pmap *p,         // IN
 
402
                 vm_pindex_t pindex) // IN
252
403
{
253
404
   /* unset bit */
254
 
   p->bitmap[pindex / (8*sizeof(unsigned long))] &= 
 
405
   p->bitmap[pindex / (8*sizeof(unsigned long))] &=
255
406
                             ~(1<<(pindex % (8*sizeof(unsigned long))));
256
407
}
257
408
 
258
 
static void os_kmem_free(vm_page_t page)
 
409
 
 
410
static void
 
411
os_kmem_free(vm_page_t page) // IN
259
412
{
260
413
   os_state *state = &global_state;
261
414
   os_pmap *pmap = &state->pmap;
268
421
   vm_page_free(page);
269
422
}
270
423
 
271
 
static vm_page_t os_kmem_alloc(int alloc_normal_failed)
 
424
 
 
425
static vm_page_t
 
426
os_kmem_alloc(int alloc_normal_failed) // IN
272
427
{
273
428
   vm_page_t page;
274
429
   vm_pindex_t pindex;
301
456
   return page;
302
457
}
303
458
 
304
 
static void os_balloonobject_delete(void)
 
459
 
 
460
static void
 
461
os_balloonobject_delete(void)
305
462
{
306
463
   vm_object_deallocate(global_state.vmobject);
307
464
}
308
465
 
309
 
static void os_balloonobject_create(void)
 
466
 
 
467
static void
 
468
os_balloonobject_create(void)
310
469
{
311
 
   global_state.vmobject = vm_object_allocate(OBJT_DEFAULT, 
 
470
   global_state.vmobject = vm_object_allocate(OBJT_DEFAULT,
312
471
                  OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS));
313
472
}
314
473
 
315
 
unsigned long os_alloc_reserved_page(int can_sleep)
316
 
{
317
 
   return (unsigned long)os_kmem_alloc(can_sleep);
318
 
}
319
 
 
320
 
void os_free_reserved_page(unsigned long page)
321
 
{
322
 
   os_kmem_free((vm_page_t)page);
323
 
}
324
 
 
325
 
static void os_timer_internal(void *data)
 
474
 
 
475
/*
 
476
 *-----------------------------------------------------------------------------
 
477
 *
 
478
 * OS_ReservedPageAlloc --
 
479
 *
 
480
 *      Reserve a physical page for the exclusive use of this driver.
 
481
 *
 
482
 * Results:
 
483
 *      On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
 
484
 *                  or OS_ReservedPageFree().
 
485
 *      On failure: PAGE_HANDLE_INVALID
 
486
 *
 
487
 * Side effects:
 
488
 *      None.
 
489
 *
 
490
 *-----------------------------------------------------------------------------
 
491
 */
 
492
 
 
493
PageHandle
 
494
OS_ReservedPageAlloc(int canSleep) // IN
 
495
{
 
496
   vm_page_t page;
 
497
 
 
498
   page = os_kmem_alloc(canSleep);
 
499
   if (page == NULL) {
 
500
      return PAGE_HANDLE_INVALID;
 
501
   }
 
502
 
 
503
   return (PageHandle)page;
 
504
}
 
505
 
 
506
 
 
507
/*
 
508
 *-----------------------------------------------------------------------------
 
509
 *
 
510
 * OS_ReservedPageFree --
 
511
 *
 
512
 *      Unreserve a physical page previously reserved with OS_ReservedPageAlloc().
 
513
 *
 
514
 * Results:
 
515
 *      None.
 
516
 *
 
517
 * Side effects:
 
518
 *      None.
 
519
 *
 
520
 *-----------------------------------------------------------------------------
 
521
 */
 
522
 
 
523
void
 
524
OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle
 
525
{
 
526
   os_kmem_free((vm_page_t)handle);
 
527
}
 
528
 
 
529
 
 
530
static void
 
531
os_timer_internal(void *data) // IN
326
532
{
327
533
   os_timer *t = (os_timer *) data;
328
534
 
333
539
   }
334
540
}
335
541
 
336
 
void os_timer_init(os_timer_handler handler, void *data, int period)
 
542
 
 
543
/*
 
544
 *-----------------------------------------------------------------------------
 
545
 *
 
546
 * OS_TimerStart --
 
547
 *
 
548
 *      Setup the timer callback function, then start it.
 
549
 *
 
550
 * Results:
 
551
 *      Always TRUE, cannot fail.
 
552
 *
 
553
 * Side effects:
 
554
 *      None
 
555
 *
 
556
 *-----------------------------------------------------------------------------
 
557
 */
 
558
 
 
559
Bool
 
560
OS_TimerStart(OSTimerHandler *handler, // IN
 
561
              void *clientData)        // IN
337
562
{
338
563
   os_timer *t = &global_state.timer;
339
564
 
 
565
   /* setup the timer structure */
340
566
   callout_handle_init(&t->callout_handle);
341
567
   t->handler = handler;
342
 
   t->data = data;
343
 
   t->period = period;
344
 
   t->stop = 0;
345
 
}
346
 
 
347
 
void os_timer_start(void)
348
 
{
349
 
   os_timer *t = &global_state.timer;
 
568
   t->data = clientData;
 
569
   t->period = hz;
350
570
 
351
571
   /* clear termination flag */
352
572
   t->stop = 0;
353
573
 
354
574
   /* scheduler timer handler */
355
575
   t->callout_handle = timeout(os_timer_internal, t, t->period);
 
576
 
 
577
   return TRUE;
356
578
}
357
579
 
358
 
void os_timer_stop(void)
 
580
 
 
581
/*
 
582
 *-----------------------------------------------------------------------------
 
583
 *
 
584
 * OS_TimerStop --
 
585
 *
 
586
 *      Stop the timer.
 
587
 *
 
588
 * Results:
 
589
 *      None
 
590
 *
 
591
 * Side effects:
 
592
 *      None
 
593
 *
 
594
 *-----------------------------------------------------------------------------
 
595
 */
 
596
 
 
597
void
 
598
OS_TimerStop(void)
359
599
{
360
600
   os_timer *t = &global_state.timer;
361
601
 
366
606
   untimeout(os_timer_internal, t, t->callout_handle);
367
607
}
368
608
 
369
 
unsigned int os_timer_hz(void)
370
 
{
371
 
   return hz;
372
 
}
373
 
 
374
 
void os_yield(void)
 
609
 
 
610
/*
 
611
 *-----------------------------------------------------------------------------
 
612
 *
 
613
 * OS_Yield --
 
614
 *
 
615
 *      Yield the CPU, if needed.
 
616
 *
 
617
 * Results:
 
618
 *      None
 
619
 *
 
620
 * Side effects:
 
621
 *      None
 
622
 *
 
623
 *-----------------------------------------------------------------------------
 
624
 */
 
625
 
 
626
void
 
627
OS_Yield(void)
375
628
{
376
629
   /* Do nothing. */
377
630
}
378
631
 
379
 
void os_init(const char *name,
380
 
             const char *name_verbose,
381
 
             os_status_handler handler)
 
632
 
 
633
/*
 
634
 *-----------------------------------------------------------------------------
 
635
 *
 
636
 * OS_Init --
 
637
 *
 
638
 *      Called at driver startup, initializes the balloon state and structures.
 
639
 *
 
640
 * Results:
 
641
 *      On success: TRUE
 
642
 *      On failure: FALSE
 
643
 *
 
644
 * Side effects:
 
645
 *      None
 
646
 *
 
647
 *-----------------------------------------------------------------------------
 
648
 */
 
649
 
 
650
Bool
 
651
OS_Init(const char *name,         // IN
 
652
        const char *nameVerbose,  // IN
 
653
        OSStatusHandler *handler) // IN
382
654
{
383
655
   os_state *state = &global_state;
384
656
   os_pmap *pmap = &state->pmap;
386
658
 
387
659
   /* initialize only once */
388
660
   if (initialized++) {
389
 
      return;
 
661
      return FALSE;
390
662
   }
391
663
 
392
664
   /* zero global state */
398
670
   /* initialize status state */
399
671
   state->status.handler = handler;
400
672
   state->status.name = name;
401
 
   state->status.name_verbose = name_verbose;
 
673
   state->status.name_verbose = nameVerbose;
402
674
 
403
675
   os_pmap_init(pmap);
404
676
   os_balloonobject_create();
407
679
 
408
680
   /* log device load */
409
681
   printf("%s initialized\n", state->status.name_verbose);
 
682
   return TRUE;
410
683
}
411
684
 
412
 
void os_cleanup(void)
 
685
 
 
686
/*
 
687
 *-----------------------------------------------------------------------------
 
688
 *
 
689
 * OS_Cleanup --
 
690
 *
 
691
 *      Called when the driver is terminating, cleanup initialized structures.
 
692
 *
 
693
 * Results:
 
694
 *      None
 
695
 *
 
696
 * Side effects:
 
697
 *      None
 
698
 *
 
699
 *-----------------------------------------------------------------------------
 
700
 */
 
701
 
 
702
void
 
703
OS_Cleanup(void)
413
704
{
414
705
   os_state *state = &global_state;
415
706
   os_pmap *pmap = &state->pmap;
424
715
   printf("%s unloaded\n", status->name_verbose);
425
716
}
426
717
 
 
718
 
427
719
/*
428
720
 * Module Load/Unload Operations
429
721
 */
430
722
 
431
 
extern int  init_module(void);
432
 
extern void cleanup_module(void);
433
723
 
434
 
static int vmmemctl_load(module_t mod, int cmd, void *arg)
 
724
static int
 
725
vmmemctl_load(module_t mod, // IN: Unused
 
726
              int cmd,      // IN
 
727
              void *arg)    // IN: Unused
435
728
{
436
729
   int err = 0;
437
730
 
438
731
   switch (cmd) {
439
732
   case MOD_LOAD:
440
 
      (void) init_module();
 
733
      if (Balloon_ModuleInit() != BALLOON_SUCCESS) {
 
734
         err = EAGAIN;
 
735
      }
441
736
      break;
442
737
 
443
738
    case MOD_UNLOAD:
444
739
       if (OS_DISABLE_UNLOAD) {
445
 
          /* prevent moudle unload */
 
740
          /* prevent module unload */
446
741
          err = EBUSY;
447
742
       } else {
448
 
          cleanup_module();
 
743
          Balloon_ModuleCleanup();
449
744
       }
450
745
       break;
451
746
 
454
749
      break;
455
750
   }
456
751
 
457
 
   return(err);
 
752
   return err;
458
753
}
459
754
 
460
755
/* All these interfaces got added in 4.x, so we support 5.0 and above with them */
485
780
   char stats[PAGE_SIZE];
486
781
   size_t len;
487
782
 
488
 
   len = 1 + global_state.status.handler(stats);
 
783
   len = 1 + global_state.status.handler(stats, PAGE_SIZE);
489
784
 
490
785
   return SYSCTL_OUT(req, stats, len);
491
786
}