- ret = kmem_alloc(kernel_map,
- (vm_offset_t *) &cdp->cpu_ldtp,
- sizeof(struct real_descriptor) * LDTSZ);
- if (ret != KERN_SUCCESS) {
- printf("cpu_data_alloc() ldt failed, ret=%d\n", ret);
- goto abort;
+ if (do_ldt_alloc) {
+ boolean_t do_ldt_free = FALSE;
+ vm_offset_t sldtoffset = 0;
+ /*
+ * Allocate LDT
+ */
+ vm_offset_t ldtalloc = 0, ldtallocsz = round_page_64(MAX_CPUS * sizeof(struct real_descriptor) * LDTSZ);
+ ret = kmem_alloc(kernel_map, (vm_offset_t *) &ldtalloc, ldtallocsz, VM_KERN_MEMORY_CPU);
+ if (ret != KERN_SUCCESS) {
+ panic("cpu_data_alloc() ldt failed, kmem_alloc=%d\n", ret);
+ }
+
+ simple_lock(&ncpus_lock);
+ if (dyn_ldts == NULL) {
+ dyn_ldts = (cldt_t *)ldtalloc;
+ } else {
+ do_ldt_free = TRUE;
+ }
+ simple_unlock(&ncpus_lock);
+
+ if (do_ldt_free) {
+ kmem_free(kernel_map, ldtalloc, ldtallocsz);
+ } else {
+ /* CPU registration and startup are expected to execute
+ * serially, as invoked by the platform driver.
+ * Create trampoline alias of LDT region.
+ */
+ sldtoffset = dyn_dblmap(ldtalloc, ldtallocsz);
+ ldt_alias_offset = sldtoffset;
+ }