diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
index ef3133e..44dc050 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
@@ -82,55 +82,77 @@ void
 nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
 			struct nouveau_mem *mem)
 {
+	/*
+	 * XXX Should the "12" in a couple of places here be replaced
+	 * with vmm->spg_shift for correctness ? Might help if we ever
+	 * support 64k card pages on 64k PAGE_SIZE systems
+	 */
 	struct nouveau_vm *vm = vma->vm;
 	struct nouveau_vmmgr *vmm = vm->vmm;
-	int big = vma->node->type != vmm->spg_shift;
 	u32 offset = vma->node->offset + (delta >> 12);
-	u32 bits = vma->node->type - 12;
-	u32 num  = length >> vma->node->type;
+	u32 shift = vma->node->type;
+	u32 order = PAGE_SHIFT - shift;
+	u32 num  = length >> PAGE_SHIFT;
 	u32 pde  = (offset >> vmm->pgt_bits) - vm->fpde;
-	u32 pte  = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
-	u32 max  = 1 << (vmm->pgt_bits - bits);
-	unsigned m, sglen;
-	u32 end, len;
+	u32 pte  = offset & ((1 << vmm->pgt_bits) - 1);
+	u32 max  = 1 << vmm->pgt_bits;
+	u32 end, len, cardlen;
 	int i;
 	struct scatterlist *sg;
 
-	for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) {
-		struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
-		sglen = sg_dma_len(sg) >> PAGE_SHIFT;
+	/* We don't handle "big" pages here */
+	if (WARN_ON(shift != vmm->spg_shift || shift > PAGE_SHIFT))
+		return;
 
-		end = pte + sglen;
-		if (unlikely(end >= max))
-			end = max;
-		len = end - pte;
+	/* We dont' handle objects that aren't PAGE_SIZE aligned either */
+	if (WARN_ON((offset << 12) & ~PAGE_MASK))
+		return;
 
-		for (m = 0; m < len; m++) {
-			dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
+	/* Iterate sglist elements */
+	for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) {
+		struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[0];
+		unsigned long m, sglen;
+		dma_addr_t addr;
 
-			vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
-			num--;
-			pte++;
+		/* Number of system pages and base address */
+		sglen = sg_dma_len(sg) >> PAGE_SHIFT;
+		addr = sg_dma_address(sg);
+
+		/* Iterate over system pages in the segment and
+		 * covered PDEs
+		 */
+		while(sglen) {
+			/* Number of card PTEs */
+			cardlen = sglen << order;
+			end = pte + cardlen;
+			if (unlikely(end > max))
+				end = max;
+			cardlen = end - pte;
 
-			if (num == 0)
-				goto finish;
-		}
-		if (unlikely(end >= max)) {
-			pde++;
-			pte = 0;
-		}
-		if (m < sglen) {
-			for (; m < sglen; m++) {
-				dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
+			/* Convert back to system pages after cropping */
+			len = cardlen >> order;
+
+			/* Ensure this fits system pages */
+			if (WARN_ON((len << order) != cardlen))
+				break;
 
+			/* For each system page in the segment */
+			for (m = 0; m < len; m++) {
 				vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
+				addr += PAGE_SIZE;
 				num--;
-				pte++;
+				pte += (1u << order);
 				if (num == 0)
 					goto finish;
 			}
-		}
+			sglen -= len;
 
+			/* Wrap to next PDE ? */
+			if (unlikely(end >= max)) {
+				pde++;
+				pte = 0;
+			}
+		}
 	}
 finish:
 	vmm->flush(vm);
@@ -143,28 +165,44 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
 	struct nouveau_vm *vm = vma->vm;
 	struct nouveau_vmmgr *vmm = vm->vmm;
 	dma_addr_t *list = mem->pages;
-	int big = vma->node->type != vmm->spg_shift;
 	u32 offset = vma->node->offset + (delta >> 12);
-	u32 bits = vma->node->type - 12;
-	u32 num  = length >> vma->node->type;
+	u32 shift = vma->node->type;
+	u32 order = PAGE_SHIFT - shift;
+	u32 num  = length >> PAGE_SHIFT;
 	u32 pde  = (offset >> vmm->pgt_bits) - vm->fpde;
-	u32 pte  = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
-	u32 max  = 1 << (vmm->pgt_bits - bits);
-	u32 end, len;
+	u32 pte  = offset & ((1 << vmm->pgt_bits) - 1);
+	u32 max  = 1 << vmm->pgt_bits;
+	u32 end, len, cardlen;
+
+	/* We don't handle "big" pages here */
+	if (WARN_ON(shift != vmm->spg_shift || shift > PAGE_SHIFT))
+		return;
+
+	/* We dont' handle objects that aren't PAGE_SIZE aligned either */
+	if (WARN_ON((offset << 12) & ~PAGE_MASK))
+		return;
 
 	while (num) {
-		struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
+		struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[0];
 
-		end = (pte + num);
-		if (unlikely(end >= max))
+		/* "num" is remaining system pages, check how many fit
+		 * in the PDE
+		 */
+		end = (pte + (num << order));
+		if (unlikely(end > max))
 			end = max;
-		len = end - pte;
+		cardlen = end - pte;
+		len = cardlen >> order;
+
+		/* Ensure this fits system pages */
+		if (WARN_ON((len << order) != cardlen))
+			break;
 
 		vmm->map_sg(vma, pgt, mem, pte, len, list);
 
 		num  -= len;
-		pte  += len;
 		list += len;
+		pte  += cardlen;
 		if (unlikely(end >= max)) {
 			pde++;
 			pte = 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
index ed45437..c1e7c11 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
@@ -38,14 +38,13 @@ nv04_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 	       struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
 {
 	pte = 0x00008 + (pte * 4);
-	while (cnt) {
+	while (cnt--) {
 		u32 page = PAGE_SIZE / NV04_PDMA_PAGE;
 		u32 phys = (u32)*list++;
-		while (cnt && page--) {
+		while (page--) {
 			nv_wo32(pgt, pte, phys | 3);
 			phys += NV04_PDMA_PAGE;
 			pte += 4;
-			cnt -= 1;
 		}
 	}
 }
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
index 064c762..09570d7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
@@ -42,14 +42,13 @@ nv41_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 	       struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
 {
 	pte = pte * 4;
-	while (cnt) {
+	while (cnt--) {
 		u32 page = PAGE_SIZE / NV41_GART_PAGE;
 		u64 phys = (u64)*list++;
-		while (cnt && page--) {
+		while (page--) {
 			nv_wo32(pgt, pte, (phys >> 7) | 1);
 			phys += NV41_GART_PAGE;
 			pte += 4;
-			cnt -= 1;
 		}
 	}
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index c0fde6b..16dce89 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -178,7 +178,7 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
 		*size = roundup(*size, (1 << nvbo->page_shift));
 		*align = max((1 <<  nvbo->page_shift), *align);
 	}
-
+	*align = roundup(*align, PAGE_SIZE);
 	*size = roundup(*size, PAGE_SIZE);
 }
 
@@ -221,7 +221,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
 	nvbo->page_shift = 12;
 	if (drm->client.base.vm) {
 		if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024)
-			nvbo->page_shift = drm->client.base.vm->vmm->lpg_shift;
+			nvbo->page_shift = lpg_shift;
 	}
 
 	nouveau_bo_fixup_align(nvbo, flags, &align, &size);
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 0843ebc..f255ff8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -31,7 +31,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
 {
 	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
 	struct nouveau_mem *node = mem->mm_node;
-	u64 size = mem->num_pages << 12;
+	u64 size = mem->num_pages << PAGE_SHIFT;
 
 	if (ttm->sg) {
 		node->sg = ttm->sg;
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 19e3757..b7fc456 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -252,8 +252,9 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man,
 
 	node->page_shift = 12;
 
-	ret = nouveau_vm_get(man->priv, mem->num_pages << 12, node->page_shift,
-			     NV_MEM_ACCESS_RW, &node->vma[0]);
+	ret = nouveau_vm_get(man->priv, mem->num_pages << PAGE_SHIFT,
+			     node->page_shift, NV_MEM_ACCESS_RW,
+			     &node->vma[0]);
 	if (ret) {
 		kfree(node);
 		return ret;
