Strangely, some timer values are not available after the swap buffers call. Calling glGetQueryObjectuiv with the GL_QUERY_RESULT_AVAILABLE parameter often returns false and I must run a while loop until it's true. I even tried calling glFinish() before retrieving the timer value, but it made little difference. The timer values themselves appear to be mostly accurate, but I wish I didn't have to slow down my program with the while loop.

I'm fairly confident that I'm otherwise using the timers correctly because I don't have any warnings when running with a debug context. I'm using an NVIDIA GTX 460 with driver version 320.18.

Why would you expect them to be available? Just because you swapped buffers doesn't mean that the CPU waited until that's done. Just like any other rendering call, it will be executed whenever the driver gets around to it.

I assumed glfwSwapBuffers would stall the CPU until the buffers finished swapping, but I can see how that assumption is faulty. However, one thing I still can't explain is having an unavailable query even when I call glFinish() right before retrieving it.

However, one thing I still can't explain is having an unavailable query even when I call glFinish() right before retrieving it.

That would seem to be a bug in the driver, although the specification isn't entirely clear on this. It may be that glFinish() returns as soon as the timer has been stopped but before the value has actually been transferred from the hardware to client memory.
Have you tried using a fence sync object instead?
In any case, there shouldn't be any need for a while loop; if you're just going to spin until the result is available, you may as well just skip the GL_QUERY_RESULT_AVAILABLE step and go straight to GL_QUERY_RESULT. GL_QUERY_RESULT_AVAILABLE is meant for the case where there are other things you can be getting on with in the meantime.