Without looking more deeply at this code, it produces a banded matrix. As such, it is best stored/returned in sparse form, especially important when the matrix may potentially be large. Since the sparse form of the matrix can be generated using a single call to sparse, I'd strongly recommend that alternative. The eventual matrix multiplications would of course be much more efficient too. The sparse code might look like this (please add the necessary additional code to make it friendly)

function M = convmtx(x,nh)
n = length(x);
M = sparse(bsxfun(@plus,(1:n)',0:(nh-1)), ...
repmat(1:nh,n,1),repmat(x,1,nh),n+nh-1,nh);

Note that it could have been done easily without bsxfun, for users of older Matlab releases. See how it does for efficiency on a large matrix.

x = (1:5)';
timeit(@() conv_mtx(x,500))
ans =
0.012447

timeit(@() convmtx(x,500))
ans =
0.0029383

Thus for large convolutions, generating the full matrix is too much work. Plus, simply storing it will be impossible for larger convolutions unless you use a sparse form.