if ( !compat && !(flags & VGCF_in_kernel) && !c.nat->ctrlreg[1] )
return -EINVAL;
- v->arch.pv.ldt_base = c(ldt_base);
v->arch.pv.ldt_ents = c(ldt_ents);
+ v->arch.pv.ldt_base = v->arch.pv.ldt_ents
+ ? c(ldt_base)
+ : (unsigned long)ZERO_BLOCK_PTR;
}
else
{
for ( i = 0; !fail && i < nr_gdt_frames; ++i )
fail = v->arch.pv.gdt_frames[i] != c(gdt_frames[i]);
- fail |= v->arch.pv.ldt_base != c(ldt_base);
fail |= v->arch.pv.ldt_ents != c(ldt_ents);
+ if ( v->arch.pv.ldt_ents )
+ fail |= v->arch.pv.ldt_base != c(ldt_base);
if ( fail )
return -EOPNOTSUPP;
}
else
{
- c(ldt_base = v->arch.pv.ldt_base);
+ c(ldt_base = v->arch.pv.ldt_ents ? v->arch.pv.ldt_base : 0);
c(ldt_ents = v->arch.pv.ldt_ents);
for ( i = 0; i < ARRAY_SIZE(v->arch.pv.gdt_frames); ++i )
c(gdt_frames[i] = v->arch.pv.gdt_frames[i]);
case MMUEXT_SET_LDT:
{
unsigned int ents = op.arg2.nr_ents;
- unsigned long ptr = ents ? op.arg1.linear_addr : 0;
+ unsigned long ptr = ents ? op.arg1.linear_addr
+ : (unsigned long)ZERO_BLOCK_PTR;
if ( unlikely(currd != pg_owner) )
rc = -EPERM;
else if ( paging_mode_external(currd) )
rc = -EINVAL;
- else if ( ((ptr & (PAGE_SIZE - 1)) != 0) || !__addr_ok(ptr) ||
- (ents > 8192) )
+ else if ( (ents > 8192) ||
+ (ents && ((ptr & (PAGE_SIZE - 1)) || !__addr_ok(ptr))) )
{
gdprintk(XENLOG_WARNING,
"Bad args to SET_LDT: ptr=%lx, ents=%x\n", ptr, ents);